bump product version to 5.0.4.1
[LibreOffice.git] / sd / source / filter / grf / sdgrffilter.cxx
blobc8ec3ee85e245cb7b87559a76287e98e77a03b77
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 #ifdef _MSC_VER
21 #pragma warning (disable:4190)
22 #endif
23 #include <com/sun/star/drawing/GraphicExportFilter.hpp>
24 #include <com/sun/star/graphic/GraphicProvider.hpp>
25 #include <com/sun/star/graphic/XGraphicProvider.hpp>
26 #include <com/sun/star/graphic/GraphicType.hpp>
27 #include <com/sun/star/ucb/SimpleFileAccess.hpp>
28 #include <com/sun/star/ucb/XSimpleFileAccess2.hpp>
30 #include <unotools/localfilehelper.hxx>
31 #include <tools/errinf.hxx>
32 #include <vcl/layout.hxx>
33 #include <vcl/metaact.hxx>
34 #include <vcl/virdev.hxx>
35 #include <sfx2/docfile.hxx>
36 #include <sfx2/docfilt.hxx>
37 #include <sfx2/frame.hxx>
38 #include <svx/svdograf.hxx>
39 #include <svx/svdpagv.hxx>
41 #include "../../ui/inc/strings.hrc"
42 #include "../../ui/inc/DrawViewShell.hxx"
43 #include "../../ui/inc/DrawDocShell.hxx"
44 #include "../../ui/inc/ClientView.hxx"
45 #include "../../ui/inc/FrameView.hxx"
47 #include "comphelper/anytostring.hxx"
48 #include "cppuhelper/exc_hlp.hxx"
50 #include <comphelper/processfactory.hxx>
51 #include <unotools/pathoptions.hxx>
52 #include <sfx2/filedlghelper.hxx>
53 #include <vcl/graphicfilter.hxx>
54 #include <svx/xoutbmp.hxx>
56 #include "sdpage.hxx"
57 #include "drawdoc.hxx"
58 #include "sdresid.hxx"
59 #include "sdgrffilter.hxx"
60 #include "../../ui/inc/ViewShellBase.hxx"
61 #include <com/sun/star/uno/Sequence.h>
62 #include <com/sun/star/beans/PropertyValue.hpp>
63 #include <com/sun/star/beans/PropertyValues.hpp>
64 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
65 #include <com/sun/star/lang/XComponent.hpp>
66 #include <com/sun/star/document/XFilter.hpp>
67 #include <com/sun/star/document/XExporter.hpp>
68 #include <com/sun/star/view/XSelectionSupplier.hpp>
69 #include <com/sun/star/drawing/XDrawView.hpp>
70 #include "../../ui/inc/DrawController.hxx"
71 #include <cppuhelper/implbase2.hxx>
72 #include <com/sun/star/drawing/XShape.hpp>
73 #include <com/sun/star/task/XInteractionHandler.hpp>
74 #include <com/sun/star/task/XInteractionRequest.hpp>
75 #include <com/sun/star/drawing/GraphicFilterRequest.hpp>
77 using namespace ::com::sun::star;
78 using namespace ::com::sun::star::uno;
79 using namespace ::com::sun::star::lang;
80 using namespace ::com::sun::star::beans;
81 using namespace ::com::sun::star::graphic;
82 using namespace ::com::sun::star::io;
83 using namespace ::com::sun::star::ucb;
84 using namespace com::sun::star::ui::dialogs;
85 using namespace ::sfx2;
87 class SdGRFFilter_ImplInteractionHdl : public ::cppu::WeakImplHelper1< com::sun::star::task::XInteractionHandler >
89 com::sun::star::uno::Reference< com::sun::star::task::XInteractionHandler > m_xInter;
90 sal_uInt16 nFilterError;
92 public:
94 SdGRFFilter_ImplInteractionHdl( com::sun::star::uno::Reference< com::sun::star::task::XInteractionHandler > xInteraction ) :
95 m_xInter( xInteraction ),
96 nFilterError( GRFILTER_OK )
99 virtual ~SdGRFFilter_ImplInteractionHdl();
101 sal_uInt16 GetErrorCode() const { return nFilterError; };
103 virtual void SAL_CALL handle( const com::sun::star::uno::Reference< com::sun::star::task::XInteractionRequest >& )
104 throw( com::sun::star::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
107 SdGRFFilter_ImplInteractionHdl::~SdGRFFilter_ImplInteractionHdl()
111 void SdGRFFilter_ImplInteractionHdl::handle( const com::sun::star::uno::Reference< com::sun::star::task::XInteractionRequest >& xRequest )
112 throw( com::sun::star::uno::RuntimeException, std::exception )
114 if( !m_xInter.is() )
115 return;
117 com::sun::star::drawing::GraphicFilterRequest aErr;
118 if ( xRequest->getRequest() >>= aErr )
119 nFilterError = (sal_uInt16)aErr.ErrCode;
120 else
121 m_xInter->handle( xRequest );
124 // - SdPPTFilter -
126 SdGRFFilter::SdGRFFilter( SfxMedium& rMedium, ::sd::DrawDocShell& rDocShell ) :
127 SdFilter( rMedium, rDocShell, true )
131 SdGRFFilter::~SdGRFFilter()
135 void SdGRFFilter::HandleGraphicFilterError( sal_uInt16 nFilterError, sal_uLong nStreamError )
137 sal_uInt16 nId;
139 switch( nFilterError )
141 case GRFILTER_OPENERROR:
142 nId = STR_IMPORT_GRFILTER_OPENERROR;
143 break;
144 case GRFILTER_IOERROR:
145 nId = STR_IMPORT_GRFILTER_IOERROR;
146 break;
147 case GRFILTER_FORMATERROR:
148 nId = STR_IMPORT_GRFILTER_FORMATERROR;
149 break;
150 case GRFILTER_VERSIONERROR:
151 nId = STR_IMPORT_GRFILTER_VERSIONERROR;
152 break;
153 case GRFILTER_TOOBIG:
154 nId = STR_IMPORT_GRFILTER_TOOBIG;
155 break;
156 case 0 :
157 nId = 0;
158 break;
160 default:
161 case GRFILTER_FILTERERROR:
162 nId = STR_IMPORT_GRFILTER_FILTERERROR;
163 break;
166 if( ERRCODE_NONE != nStreamError )
167 ErrorHandler::HandleError( nStreamError );
168 else if( STR_IMPORT_GRFILTER_IOERROR == nId )
169 ErrorHandler::HandleError( ERRCODE_IO_GENERAL );
170 else
172 ScopedVclPtrInstance< MessageDialog > aErrorBox(nullptr, SD_RESSTR(nId));
173 aErrorBox->Execute();
177 bool SdGRFFilter::Import()
179 Graphic aGraphic;
180 const OUString aFileName( mrMedium.GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) );
181 GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter();
182 const sal_uInt16 nFilter = rGraphicFilter.GetImportFormatNumberForTypeName( mrMedium.GetFilter()->GetTypeName() );
183 bool bRet = false;
185 SvStream* pIStm = mrMedium.GetInStream();
186 sal_uInt16 nReturn = pIStm ? rGraphicFilter.ImportGraphic( aGraphic, aFileName, *pIStm, nFilter ) : 1;
188 if( nReturn )
189 HandleGraphicFilterError( nReturn, rGraphicFilter.GetLastError().nStreamError );
190 else
192 if( mrDocument.GetPageCount() == 0L )
193 mrDocument.CreateFirstPages();
195 SdPage* pPage = mrDocument.GetSdPage( 0, PK_STANDARD );
196 Point aPos;
197 Size aPagSize( pPage->GetSize() );
198 Size aGrfSize( OutputDevice::LogicToLogic( aGraphic.GetPrefSize(),
199 aGraphic.GetPrefMapMode(), MAP_100TH_MM ) );
201 aPagSize.Width() -= pPage->GetLftBorder() + pPage->GetRgtBorder();
202 aPagSize.Height() -= pPage->GetUppBorder() + pPage->GetLwrBorder();
204 // scale to fit page
205 if ( ( ( aGrfSize.Height() > aPagSize.Height() ) || ( aGrfSize.Width() > aPagSize.Width() ) ) &&
206 aGrfSize.Height() && aPagSize.Height() )
208 double fGrfWH = (double) aGrfSize.Width() / aGrfSize.Height();
209 double fWinWH = (double) aPagSize.Width() / aPagSize.Height();
211 // adjust graphic to page size (scales)
212 if( fGrfWH < fWinWH )
214 aGrfSize.Width() = (long) ( aPagSize.Height() * fGrfWH );
215 aGrfSize.Height() = aPagSize.Height();
217 else if( fGrfWH > 0.F )
219 aGrfSize.Width() = aPagSize.Width();
220 aGrfSize.Height()= (long) ( aPagSize.Width() / fGrfWH );
224 // set output rectangle for graphic
225 aPos.X() = ( ( aPagSize.Width() - aGrfSize.Width() ) >> 1 ) + pPage->GetLftBorder();
226 aPos.Y() = ( ( aPagSize.Height() - aGrfSize.Height() ) >> 1 ) + pPage->GetUppBorder();
228 pPage->InsertObject( new SdrGrafObj( aGraphic, Rectangle( aPos, aGrfSize ) ) );
229 bRet = true;
231 return bRet;
234 bool SdGRFFilter::Export()
236 // SJ: todo: error handling, the GraphicExportFilter does not support proper errorhandling
238 bool bRet = false;
240 uno::Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
241 uno::Reference< drawing::XGraphicExportFilter > xExporter = drawing::GraphicExportFilter::create( xContext );
243 SdPage* pPage = NULL;
244 sd::DrawViewShell* pDrawViewShell = static_cast< ::sd::DrawViewShell* >
245 ( ( ( mrDocShell.GetViewShell() && mrDocShell.GetViewShell()->ISA(::sd::DrawViewShell ) ) ? mrDocShell.GetViewShell() : NULL ) );
247 PageKind ePageKind = PK_STANDARD;
248 if( pDrawViewShell )
250 ePageKind = pDrawViewShell->GetPageKind();
251 if( PK_HANDOUT == ePageKind )
252 pPage = mrDocument.GetSdPage( 0, PK_HANDOUT );
253 else
254 pPage = pDrawViewShell->GetActualPage();
256 else
257 pPage = mrDocument.GetSdPage( 0, PK_STANDARD );
259 if ( pPage )
261 // taking the 'correct' page number, seems that there might exist a better method to archive this
262 pPage = mrDocument.GetSdPage( pPage->GetPageNum() ? ( pPage->GetPageNum() - 1 ) >> 1 : 0, ePageKind );
263 if ( pPage )
265 uno::Reference< lang::XComponent > xSource( pPage->getUnoPage(), uno::UNO_QUERY );
266 SfxItemSet* pSet = mrMedium.GetItemSet();
267 if ( pSet && xSource.is() )
269 const OUString aTypeName( mrMedium.GetFilter()->GetTypeName() );
270 GraphicFilter &rGraphicFilter = GraphicFilter::GetGraphicFilter();
271 const sal_uInt16 nFilter = rGraphicFilter.GetExportFormatNumberForTypeName( aTypeName );
272 if ( nFilter != GRFILTER_FORMAT_NOTFOUND )
274 uno::Reference< task::XInteractionHandler > mXInteractionHandler;
276 beans::PropertyValues aArgs;
277 TransformItems( SID_SAVEASDOC, *pSet, aArgs );
279 OUString sInteractionHandler( "InteractionHandler" );
280 OUString sFilterName( "FilterName" );
281 OUString sShortName( rGraphicFilter.GetExportFormatShortName( nFilter ) );
283 bool bFilterNameFound = false;
284 sal_Int32 i, nCount;
285 for ( i = 0, nCount = aArgs.getLength(); i < nCount; i++ )
287 OUString& rStr = aArgs[ i ].Name;
288 if ( rStr == sFilterName )
290 bFilterNameFound = true;
291 aArgs[ i ].Name = sFilterName;
292 aArgs[ i ].Value <<= sShortName;
294 else if ( rStr == sInteractionHandler )
296 uno::Reference< task::XInteractionHandler > xHdl;
297 if ( aArgs[ i ].Value >>= xHdl )
299 mXInteractionHandler = new SdGRFFilter_ImplInteractionHdl( xHdl );
300 aArgs[ i ].Value <<= mXInteractionHandler;
304 if ( !bFilterNameFound )
306 aArgs.realloc( ++nCount );
307 aArgs[ i ].Name = sFilterName;
308 aArgs[ i ].Value <<= sShortName;
311 // take selection if needed
312 if( ( SfxItemState::SET == pSet->GetItemState( SID_SELECTION ) )
313 && static_cast< const SfxBoolItem& >( pSet->Get( SID_SELECTION ) ).GetValue()
314 && pDrawViewShell )
316 uno::Reference< view::XSelectionSupplier > xSelectionSupplier(
317 pDrawViewShell->GetViewShellBase().GetController(), uno::UNO_QUERY );
318 if ( xSelectionSupplier.is() )
320 uno::Any aSelection( xSelectionSupplier->getSelection() );
321 uno::Reference< lang::XComponent > xSelection;
322 if ( aSelection >>= xSelection )
323 xSource = xSelection;
326 xExporter->setSourceDocument( xSource );
327 bRet = xExporter->filter( aArgs );
328 if ( !bRet && mXInteractionHandler.is() )
329 SdGRFFilter::HandleGraphicFilterError(
330 static_cast< SdGRFFilter_ImplInteractionHdl* >( mXInteractionHandler.get() )->GetErrorCode(),
331 rGraphicFilter.GetLastError().nStreamError );
336 return bRet;
339 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */