sdext: adapt xpdfwrapper to poppler 24.12
[LibreOffice.git] / sd / source / filter / grf / sdgrffilter.cxx
blobea437dfb2ee0ba5a40e0b495af8595aa371feb86
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/drawing/GraphicExportFilter.hpp>
22 #include <utility>
23 #include <vcl/errinf.hxx>
24 #include <vcl/weld.hxx>
25 #include <sfx2/sfxsids.hrc>
26 #include <sfx2/docfile.hxx>
27 #include <sfx2/docfilt.hxx>
28 #include <sfx2/sfxuno.hxx>
29 #include <svx/svdograf.hxx>
31 #include <strings.hrc>
32 #include <DrawViewShell.hxx>
33 #include <DrawDocShell.hxx>
35 #include <comphelper/processfactory.hxx>
36 #include <vcl/graphicfilter.hxx>
37 #include <vcl/svapp.hxx>
39 #include <sdpage.hxx>
40 #include <drawdoc.hxx>
41 #include <sdresid.hxx>
42 #include <sdgrffilter.hxx>
43 #include <ViewShellBase.hxx>
44 #include <com/sun/star/beans/PropertyValue.hpp>
45 #include <com/sun/star/beans/PropertyValues.hpp>
46 #include <com/sun/star/lang/XComponent.hpp>
47 #include <com/sun/star/view/XSelectionSupplier.hpp>
48 #include <cppuhelper/implbase.hxx>
49 #include <com/sun/star/task/XInteractionHandler.hpp>
50 #include <com/sun/star/task/XInteractionRequest.hpp>
51 #include <com/sun/star/drawing/GraphicFilterRequest.hpp>
52 #include <DrawController.hxx>
54 using namespace ::com::sun::star;
55 using namespace ::com::sun::star::uno;
56 using namespace ::com::sun::star::lang;
57 using namespace ::com::sun::star::beans;
58 using namespace ::com::sun::star::graphic;
59 using namespace ::com::sun::star::io;
60 using namespace ::com::sun::star::ucb;
61 using namespace com::sun::star::ui::dialogs;
63 namespace {
65 class SdGRFFilter_ImplInteractionHdl : public ::cppu::WeakImplHelper< css::task::XInteractionHandler >
67 css::uno::Reference< css::task::XInteractionHandler > m_xInter;
68 ErrCode nFilterError;
70 public:
72 explicit SdGRFFilter_ImplInteractionHdl( css::uno::Reference< css::task::XInteractionHandler > xInteraction ) :
73 m_xInter(std::move( xInteraction )),
74 nFilterError( ERRCODE_NONE )
77 ErrCode const & GetErrorCode() const { return nFilterError; };
79 virtual void SAL_CALL handle( const css::uno::Reference< css::task::XInteractionRequest >& ) override;
84 void SdGRFFilter_ImplInteractionHdl::handle( const css::uno::Reference< css::task::XInteractionRequest >& xRequest )
86 if( !m_xInter.is() )
87 return;
89 css::drawing::GraphicFilterRequest aErr;
90 if ( xRequest->getRequest() >>= aErr )
91 nFilterError = ErrCode(aErr.ErrCode);
92 else
93 m_xInter->handle( xRequest );
97 SdGRFFilter::SdGRFFilter( SfxMedium& rMedium, ::sd::DrawDocShell& rDocShell ) :
98 SdFilter( rMedium, rDocShell )
102 SdGRFFilter::~SdGRFFilter()
106 void SdGRFFilter::HandleGraphicFilterError( ErrCode nFilterError, ErrCode nStreamError )
108 if (ERRCODE_NONE != nStreamError)
110 ErrorHandler::HandleError(nStreamError);
111 return;
114 TranslateId pId;
116 if( nFilterError == ERRCODE_GRFILTER_OPENERROR )
117 pId = STR_IMPORT_GRFILTER_OPENERROR;
118 else if( nFilterError == ERRCODE_GRFILTER_IOERROR )
119 pId = STR_IMPORT_GRFILTER_IOERROR;
120 else if( nFilterError == ERRCODE_GRFILTER_FORMATERROR )
121 pId = STR_IMPORT_GRFILTER_FORMATERROR;
122 else if( nFilterError == ERRCODE_GRFILTER_VERSIONERROR )
123 pId = STR_IMPORT_GRFILTER_VERSIONERROR;
124 else if( nFilterError == ERRCODE_GRFILTER_TOOBIG )
125 pId = STR_IMPORT_GRFILTER_TOOBIG;
126 else if( nFilterError == ERRCODE_NONE )
128 else
129 pId = STR_IMPORT_GRFILTER_FILTERERROR;
131 if (pId && pId == STR_IMPORT_GRFILTER_IOERROR)
132 ErrorHandler::HandleError( ERRCODE_IO_GENERAL );
133 else
135 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(nullptr,
136 VclMessageType::Warning, VclButtonsType::Ok, pId ? SdResId(pId) : OUString()));
137 xErrorBox->run();
141 bool SdGRFFilter::Import()
143 Graphic aGraphic;
144 const OUString aFileName( mrMedium.GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
145 GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter();
146 const sal_uInt16 nFilter = rGraphicFilter.GetImportFormatNumberForTypeName( mrMedium.GetFilter()->GetTypeName() );
147 bool bRet = false;
149 SvStream* pIStm = mrMedium.GetInStream();
150 ErrCode nReturn = pIStm ? rGraphicFilter.ImportGraphic( aGraphic, aFileName, *pIStm, nFilter ) : ErrCode(1);
152 if( nReturn )
153 HandleGraphicFilterError( nReturn, rGraphicFilter.GetLastError() );
154 else
156 if( mrDocument.GetPageCount() == 0 )
157 mrDocument.CreateFirstPages();
159 GfxLink aGfxLink = aGraphic.GetGfxLink();
160 if( aGfxLink.GetType() == GfxLinkType::NativeTif && aGraphic.IsAnimated() )
162 Animation aAnim( aGraphic.GetAnimation() );
163 const auto nImages = aAnim.Count();
164 for (size_t i = 0; i < nImages - 1; ++i)
166 mrDocument.DuplicatePage(0);
168 for (size_t nPageIndex = 0; nPageIndex < nImages; ++nPageIndex)
170 InsertSdrGrafObj(aAnim.Get(nPageIndex).maBitmapEx,
171 mrDocument.GetSdPage(nPageIndex, PageKind::Standard));
174 else
176 SdPage* pPage = mrDocument.GetSdPage(0, PageKind::Standard);
177 InsertSdrGrafObj(aGraphic, pPage);
179 bRet = true;
182 return bRet;
185 void SdGRFFilter::InsertSdrGrafObj(const Graphic& rGraphic, SdPage* pPage)
187 Point aPos;
188 Size aPagSize(pPage->GetSize());
189 Size aGrfSize(OutputDevice::LogicToLogic(rGraphic.GetPrefSize(), rGraphic.GetPrefMapMode(),
190 MapMode(MapUnit::Map100thMM)));
192 aPagSize.AdjustWidth(-(pPage->GetLeftBorder() + pPage->GetRightBorder()));
193 aPagSize.AdjustHeight(-(pPage->GetUpperBorder() + pPage->GetLowerBorder()));
195 // scale to fit page
196 if (((aGrfSize.Height() > aPagSize.Height()) || (aGrfSize.Width() > aPagSize.Width()))
197 && aGrfSize.Height() && aPagSize.Height())
199 double fGrfWH = static_cast<double>(aGrfSize.Width()) / aGrfSize.Height();
200 double fWinWH = static_cast<double>(aPagSize.Width()) / aPagSize.Height();
202 // adjust graphic to page size (scales)
203 if (fGrfWH < fWinWH)
205 aGrfSize.setWidth(static_cast<tools::Long>(aPagSize.Height() * fGrfWH));
206 aGrfSize.setHeight(aPagSize.Height());
208 else if (fGrfWH > 0.F)
210 aGrfSize.setWidth(aPagSize.Width());
211 aGrfSize.setHeight(static_cast<tools::Long>(aPagSize.Width() / fGrfWH));
215 // set output rectangle for graphic
216 aPos.setX(((aPagSize.Width() - aGrfSize.Width()) >> 1) + pPage->GetLeftBorder());
217 aPos.setY(((aPagSize.Height() - aGrfSize.Height()) >> 1) + pPage->GetUpperBorder());
219 pPage->InsertObject(new SdrGrafObj(pPage->getSdrModelFromSdrPage(), rGraphic,
220 ::tools::Rectangle(aPos, aGrfSize)));
223 bool SdGRFFilter::Export()
225 // SJ: todo: error handling, the GraphicExportFilter does not support proper errorhandling
226 bool bRet = false;
228 const uno::Reference< uno::XComponentContext >& xContext = ::comphelper::getProcessComponentContext();
229 uno::Reference< drawing::XGraphicExportFilter > xExporter = drawing::GraphicExportFilter::create( xContext );
231 SdPage* pPage = nullptr;
232 sd::DrawViewShell* pDrawViewShell = dynamic_cast<::sd::DrawViewShell* >(mrDocShell.GetViewShell() );
234 PageKind ePageKind = PageKind::Standard;
235 if( pDrawViewShell )
237 ePageKind = pDrawViewShell->GetPageKind();
238 if( PageKind::Handout == ePageKind )
239 pPage = mrDocument.GetSdPage( 0, PageKind::Handout );
240 else
241 pPage = pDrawViewShell->GetActualPage();
243 else
244 pPage = mrDocument.GetSdPage( 0, PageKind::Standard );
246 if ( pPage )
248 // taking the 'correct' page number, seems that there might exist a better method to archive this
249 pPage = mrDocument.GetSdPage( pPage->GetPageNum() ? ( pPage->GetPageNum() - 1 ) >> 1 : 0, ePageKind );
250 if ( pPage )
252 uno::Reference< lang::XComponent > xSource( pPage->getUnoPage(), uno::UNO_QUERY );
253 if (xSource.is())
255 SfxItemSet& rSet = mrMedium.GetItemSet();
256 const OUString aTypeName( mrMedium.GetFilter()->GetTypeName() );
257 GraphicFilter &rGraphicFilter = GraphicFilter::GetGraphicFilter();
258 const sal_uInt16 nFilter = rGraphicFilter.GetExportFormatNumberForTypeName( aTypeName );
259 if ( nFilter != GRFILTER_FORMAT_NOTFOUND )
261 uno::Reference< task::XInteractionHandler > xInteractionHandler;
263 beans::PropertyValues aArgs;
264 TransformItems( SID_SAVEASDOC, rSet, aArgs );
266 static constexpr OUString sFilterName( u"FilterName"_ustr );
267 OUString sShortName( rGraphicFilter.GetExportFormatShortName( nFilter ) );
269 bool bFilterNameFound = false;
270 for ( auto& rArg : asNonConstRange(aArgs) )
272 OUString& rStr = rArg.Name;
273 if ( rStr == sFilterName )
275 bFilterNameFound = true;
276 rArg.Value <<= sShortName;
278 else if ( rStr == "InteractionHandler" )
280 uno::Reference< task::XInteractionHandler > xHdl;
281 if ( rArg.Value >>= xHdl )
283 xInteractionHandler = new SdGRFFilter_ImplInteractionHdl( xHdl );
284 rArg.Value <<= xInteractionHandler;
288 if ( !bFilterNameFound )
290 sal_Int32 nCount = aArgs.getLength();
291 aArgs.realloc( nCount + 1 );
292 auto pArgs = aArgs.getArray();
293 pArgs[ nCount ].Name = sFilterName;
294 pArgs[ nCount ].Value <<= sShortName;
297 // take selection if needed
298 if( ( SfxItemState::SET == rSet.GetItemState( SID_SELECTION ) )
299 && rSet.Get( SID_SELECTION ).GetValue()
300 && pDrawViewShell )
302 ::sd::DrawController* pDrawController =
303 pDrawViewShell->GetViewShellBase().GetDrawController();
304 if ( pDrawController )
306 uno::Any aSelection( pDrawController->getSelection() );
307 uno::Reference< lang::XComponent > xSelection;
308 if ( aSelection >>= xSelection )
309 xSource = std::move(xSelection);
312 xExporter->setSourceDocument( xSource );
313 bRet = xExporter->filter( aArgs );
314 if ( !bRet && xInteractionHandler.is() )
315 SdGRFFilter::HandleGraphicFilterError(
316 static_cast< SdGRFFilter_ImplInteractionHdl* >( xInteractionHandler.get() )->GetErrorCode(),
317 rGraphicFilter.GetLastError() );
322 return bRet;
325 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */