bump product version to 6.4.0.3
[LibreOffice.git] / sd / source / filter / grf / sdgrffilter.cxx
blobd16491dff288fa56f6e8bc2173384ad0c7c7b1c2
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 <vcl/errinf.hxx>
23 #include <vcl/weld.hxx>
24 #include <sfx2/sfxsids.hrc>
25 #include <sfx2/docfile.hxx>
26 #include <sfx2/docfilt.hxx>
27 #include <sfx2/sfxuno.hxx>
28 #include <svx/svdograf.hxx>
30 #include <strings.hrc>
31 #include <DrawViewShell.hxx>
32 #include <DrawDocShell.hxx>
34 #include <comphelper/processfactory.hxx>
35 #include <vcl/graphicfilter.hxx>
36 #include <vcl/svapp.hxx>
38 #include <sdpage.hxx>
39 #include <drawdoc.hxx>
40 #include <sdresid.hxx>
41 #include <sdgrffilter.hxx>
42 #include <ViewShellBase.hxx>
43 #include <com/sun/star/beans/PropertyValue.hpp>
44 #include <com/sun/star/beans/PropertyValues.hpp>
45 #include <com/sun/star/lang/XComponent.hpp>
46 #include <com/sun/star/view/XSelectionSupplier.hpp>
47 #include <cppuhelper/implbase.hxx>
48 #include <com/sun/star/task/XInteractionHandler.hpp>
49 #include <com/sun/star/task/XInteractionRequest.hpp>
50 #include <com/sun/star/drawing/GraphicFilterRequest.hpp>
52 using namespace ::com::sun::star;
53 using namespace ::com::sun::star::uno;
54 using namespace ::com::sun::star::lang;
55 using namespace ::com::sun::star::beans;
56 using namespace ::com::sun::star::graphic;
57 using namespace ::com::sun::star::io;
58 using namespace ::com::sun::star::ucb;
59 using namespace com::sun::star::ui::dialogs;
60 using namespace ::sfx2;
62 class SdGRFFilter_ImplInteractionHdl : public ::cppu::WeakImplHelper< css::task::XInteractionHandler >
64 css::uno::Reference< css::task::XInteractionHandler > m_xInter;
65 ErrCode nFilterError;
67 public:
69 explicit SdGRFFilter_ImplInteractionHdl( css::uno::Reference< css::task::XInteractionHandler > const & xInteraction ) :
70 m_xInter( xInteraction ),
71 nFilterError( ERRCODE_NONE )
74 ErrCode const & GetErrorCode() const { return nFilterError; };
76 virtual void SAL_CALL handle( const css::uno::Reference< css::task::XInteractionRequest >& ) override;
79 void SdGRFFilter_ImplInteractionHdl::handle( const css::uno::Reference< css::task::XInteractionRequest >& xRequest )
81 if( !m_xInter.is() )
82 return;
84 css::drawing::GraphicFilterRequest aErr;
85 if ( xRequest->getRequest() >>= aErr )
86 nFilterError = ErrCode(aErr.ErrCode);
87 else
88 m_xInter->handle( xRequest );
92 SdGRFFilter::SdGRFFilter( SfxMedium& rMedium, ::sd::DrawDocShell& rDocShell ) :
93 SdFilter( rMedium, rDocShell )
97 SdGRFFilter::~SdGRFFilter()
101 void SdGRFFilter::HandleGraphicFilterError( ErrCode nFilterError, ErrCode nStreamError )
103 if (ERRCODE_NONE != nStreamError)
105 ErrorHandler::HandleError(nStreamError);
106 return;
109 const char* pId;
111 if( nFilterError == ERRCODE_GRFILTER_OPENERROR )
112 pId = STR_IMPORT_GRFILTER_OPENERROR;
113 else if( nFilterError == ERRCODE_GRFILTER_IOERROR )
114 pId = STR_IMPORT_GRFILTER_IOERROR;
115 else if( nFilterError == ERRCODE_GRFILTER_FORMATERROR )
116 pId = STR_IMPORT_GRFILTER_FORMATERROR;
117 else if( nFilterError == ERRCODE_GRFILTER_VERSIONERROR )
118 pId = STR_IMPORT_GRFILTER_VERSIONERROR;
119 else if( nFilterError == ERRCODE_GRFILTER_TOOBIG )
120 pId = STR_IMPORT_GRFILTER_TOOBIG;
121 else if( nFilterError == ERRCODE_NONE )
122 pId = nullptr;
123 else
124 pId = STR_IMPORT_GRFILTER_FILTERERROR;
126 if (pId && strcmp(pId, STR_IMPORT_GRFILTER_IOERROR) == 0)
127 ErrorHandler::HandleError( ERRCODE_IO_GENERAL );
128 else
130 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(nullptr,
131 VclMessageType::Warning, VclButtonsType::Ok, pId ? SdResId(pId) : OUString()));
132 xErrorBox->run();
136 bool SdGRFFilter::Import()
138 Graphic aGraphic;
139 const OUString aFileName( mrMedium.GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
140 GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter();
141 const sal_uInt16 nFilter = rGraphicFilter.GetImportFormatNumberForTypeName( mrMedium.GetFilter()->GetTypeName() );
142 bool bRet = false;
144 SvStream* pIStm = mrMedium.GetInStream();
145 ErrCode nReturn = pIStm ? rGraphicFilter.ImportGraphic( aGraphic, aFileName, *pIStm, nFilter ) : ErrCode(1);
147 if( nReturn )
148 HandleGraphicFilterError( nReturn, rGraphicFilter.GetLastError().nStreamError );
149 else
151 if( mrDocument.GetPageCount() == 0 )
152 mrDocument.CreateFirstPages();
154 SdPage* pPage = mrDocument.GetSdPage( 0, PageKind::Standard );
155 Point aPos;
156 Size aPagSize( pPage->GetSize() );
157 Size aGrfSize( OutputDevice::LogicToLogic( aGraphic.GetPrefSize(),
158 aGraphic.GetPrefMapMode(), MapMode(MapUnit::Map100thMM)));
160 aPagSize.AdjustWidth( -(pPage->GetLeftBorder() + pPage->GetRightBorder()) );
161 aPagSize.AdjustHeight( -(pPage->GetUpperBorder() + pPage->GetLowerBorder()) );
163 // scale to fit page
164 if ( ( ( aGrfSize.Height() > aPagSize.Height() ) || ( aGrfSize.Width() > aPagSize.Width() ) ) &&
165 aGrfSize.Height() && aPagSize.Height() )
167 double fGrfWH = static_cast<double>(aGrfSize.Width()) / aGrfSize.Height();
168 double fWinWH = static_cast<double>(aPagSize.Width()) / aPagSize.Height();
170 // adjust graphic to page size (scales)
171 if( fGrfWH < fWinWH )
173 aGrfSize.setWidth( static_cast<long>( aPagSize.Height() * fGrfWH ) );
174 aGrfSize.setHeight( aPagSize.Height() );
176 else if( fGrfWH > 0.F )
178 aGrfSize.setWidth( aPagSize.Width() );
179 aGrfSize.setHeight( static_cast<long>( aPagSize.Width() / fGrfWH ) );
183 // set output rectangle for graphic
184 aPos.setX( ( ( aPagSize.Width() - aGrfSize.Width() ) >> 1 ) + pPage->GetLeftBorder() );
185 aPos.setY( ( ( aPagSize.Height() - aGrfSize.Height() ) >> 1 ) + pPage->GetUpperBorder() );
187 pPage->InsertObject(
188 new SdrGrafObj(
189 pPage->getSdrModelFromSdrPage(),
190 aGraphic,
191 ::tools::Rectangle(aPos, aGrfSize)));
192 bRet = true;
195 return bRet;
198 bool SdGRFFilter::Export()
200 // SJ: todo: error handling, the GraphicExportFilter does not support proper errorhandling
201 bool bRet = false;
203 uno::Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
204 uno::Reference< drawing::XGraphicExportFilter > xExporter = drawing::GraphicExportFilter::create( xContext );
206 SdPage* pPage = nullptr;
207 sd::DrawViewShell* pDrawViewShell = dynamic_cast<::sd::DrawViewShell* >(mrDocShell.GetViewShell() );
209 PageKind ePageKind = PageKind::Standard;
210 if( pDrawViewShell )
212 ePageKind = pDrawViewShell->GetPageKind();
213 if( PageKind::Handout == ePageKind )
214 pPage = mrDocument.GetSdPage( 0, PageKind::Handout );
215 else
216 pPage = pDrawViewShell->GetActualPage();
218 else
219 pPage = mrDocument.GetSdPage( 0, PageKind::Standard );
221 if ( pPage )
223 // taking the 'correct' page number, seems that there might exist a better method to archive this
224 pPage = mrDocument.GetSdPage( pPage->GetPageNum() ? ( pPage->GetPageNum() - 1 ) >> 1 : 0, ePageKind );
225 if ( pPage )
227 uno::Reference< lang::XComponent > xSource( pPage->getUnoPage(), uno::UNO_QUERY );
228 SfxItemSet* pSet = mrMedium.GetItemSet();
229 if ( pSet && xSource.is() )
231 const OUString aTypeName( mrMedium.GetFilter()->GetTypeName() );
232 GraphicFilter &rGraphicFilter = GraphicFilter::GetGraphicFilter();
233 const sal_uInt16 nFilter = rGraphicFilter.GetExportFormatNumberForTypeName( aTypeName );
234 if ( nFilter != GRFILTER_FORMAT_NOTFOUND )
236 uno::Reference< task::XInteractionHandler > xInteractionHandler;
238 beans::PropertyValues aArgs;
239 TransformItems( SID_SAVEASDOC, *pSet, aArgs );
241 const OUString sFilterName( "FilterName" );
242 OUString sShortName( rGraphicFilter.GetExportFormatShortName( nFilter ) );
244 bool bFilterNameFound = false;
245 for ( auto& rArg : aArgs )
247 OUString& rStr = rArg.Name;
248 if ( rStr == sFilterName )
250 bFilterNameFound = true;
251 rArg.Value <<= sShortName;
253 else if ( rStr == "InteractionHandler" )
255 uno::Reference< task::XInteractionHandler > xHdl;
256 if ( rArg.Value >>= xHdl )
258 xInteractionHandler = new SdGRFFilter_ImplInteractionHdl( xHdl );
259 rArg.Value <<= xInteractionHandler;
263 if ( !bFilterNameFound )
265 sal_Int32 nCount = aArgs.getLength();
266 aArgs.realloc( nCount + 1 );
267 aArgs[ nCount ].Name = sFilterName;
268 aArgs[ nCount ].Value <<= sShortName;
271 // take selection if needed
272 if( ( SfxItemState::SET == pSet->GetItemState( SID_SELECTION ) )
273 && pSet->Get( SID_SELECTION ).GetValue()
274 && pDrawViewShell )
276 uno::Reference< view::XSelectionSupplier > xSelectionSupplier(
277 pDrawViewShell->GetViewShellBase().GetController(), uno::UNO_QUERY );
278 if ( xSelectionSupplier.is() )
280 uno::Any aSelection( xSelectionSupplier->getSelection() );
281 uno::Reference< lang::XComponent > xSelection;
282 if ( aSelection >>= xSelection )
283 xSource = xSelection;
286 xExporter->setSourceDocument( xSource );
287 bRet = xExporter->filter( aArgs );
288 if ( !bRet && xInteractionHandler.is() )
289 SdGRFFilter::HandleGraphicFilterError(
290 static_cast< SdGRFFilter_ImplInteractionHdl* >( xInteractionHandler.get() )->GetErrorCode(),
291 rGraphicFilter.GetLastError().nStreamError );
296 return bRet;
299 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */