bump product version to 4.1.6.2
[LibreOffice.git] / sd / source / filter / grf / sdgrffilter.cxx
blob8c9af66a08c40b7da6ea0effea13923a0d1485b1
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 .
21 #ifdef _MSC_VER
22 #pragma warning (disable:4190)
23 #endif
24 #include <com/sun/star/drawing/GraphicExportFilter.hpp>
25 #include <com/sun/star/graphic/GraphicProvider.hpp>
26 #include <com/sun/star/graphic/XGraphicProvider.hpp>
27 #include <com/sun/star/graphic/GraphicType.hpp>
28 #include <com/sun/star/ucb/SimpleFileAccess.hpp>
29 #include <com/sun/star/ucb/XSimpleFileAccess2.hpp>
31 #include <unotools/localfilehelper.hxx>
32 #include <tools/errinf.hxx>
33 #include <vcl/msgbox.hxx>
34 #include <vcl/metaact.hxx>
35 #include <vcl/virdev.hxx>
36 #include <sfx2/docfile.hxx>
37 #include <sfx2/docfilt.hxx>
38 #include <sfx2/frame.hxx>
39 #include <svx/svdograf.hxx>
40 #include <svx/svdpagv.hxx>
42 #include "../../ui/inc/strings.hrc"
43 #include "../../ui/inc/DrawViewShell.hxx"
44 #include "../../ui/inc/DrawDocShell.hxx"
45 #include "../../ui/inc/ClientView.hxx"
46 #include "../../ui/inc/FrameView.hxx"
48 #include "comphelper/anytostring.hxx"
49 #include "cppuhelper/exc_hlp.hxx"
51 // --
52 #include <comphelper/processfactory.hxx>
53 #include <unotools/pathoptions.hxx>
54 #include <sfx2/filedlghelper.hxx>
55 #include <vcl/graphicfilter.hxx>
56 #include <svx/xoutbmp.hxx>
58 // --
60 #include "sdpage.hxx"
61 #include "drawdoc.hxx"
62 #include "sdresid.hxx"
63 #include "sdgrffilter.hxx"
64 #include "../../ui/inc/ViewShellBase.hxx"
65 #include <com/sun/star/uno/Sequence.h>
66 #include <com/sun/star/beans/PropertyValue.hpp>
67 #include <com/sun/star/beans/PropertyValues.hpp>
68 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
69 #include <com/sun/star/lang/XComponent.hpp>
70 #include <com/sun/star/document/XFilter.hpp>
71 #include <com/sun/star/document/XExporter.hpp>
72 #include <com/sun/star/view/XSelectionSupplier.hpp>
73 #include <com/sun/star/drawing/XDrawView.hpp>
74 #include "../../ui/inc/DrawController.hxx"
75 #include <cppuhelper/implbase2.hxx>
76 #include <com/sun/star/drawing/XShape.hpp>
77 #include <com/sun/star/task/XInteractionHandler.hpp>
78 #include <com/sun/star/task/XInteractionRequest.hpp>
79 #include <com/sun/star/drawing/GraphicFilterRequest.hpp>
81 using namespace ::com::sun::star;
82 using namespace ::com::sun::star::uno;
83 using namespace ::com::sun::star::lang;
84 using namespace ::com::sun::star::beans;
85 using namespace ::com::sun::star::graphic;
86 using namespace ::com::sun::star::io;
87 using namespace ::com::sun::star::ucb;
88 using namespace com::sun::star::ui::dialogs;
89 using namespace ::sfx2;
92 // -----------------------------------------------------------------------------
94 class SdGRFFilter_ImplInteractionHdl : public ::cppu::WeakImplHelper1< com::sun::star::task::XInteractionHandler >
96 com::sun::star::uno::Reference< com::sun::star::task::XInteractionHandler > m_xInter;
97 sal_uInt16 nFilterError;
99 public:
101 SdGRFFilter_ImplInteractionHdl( com::sun::star::uno::Reference< com::sun::star::task::XInteractionHandler > xInteraction ) :
102 m_xInter( xInteraction ),
103 nFilterError( GRFILTER_OK )
106 ~SdGRFFilter_ImplInteractionHdl();
108 sal_uInt16 GetErrorCode() const { return nFilterError; };
110 virtual void SAL_CALL handle( const com::sun::star::uno::Reference< com::sun::star::task::XInteractionRequest >& )
111 throw( com::sun::star::uno::RuntimeException );
114 SdGRFFilter_ImplInteractionHdl::~SdGRFFilter_ImplInteractionHdl()
118 void SdGRFFilter_ImplInteractionHdl::handle( const com::sun::star::uno::Reference< com::sun::star::task::XInteractionRequest >& xRequest )
119 throw( com::sun::star::uno::RuntimeException )
121 if( !m_xInter.is() )
122 return;
124 com::sun::star::drawing::GraphicFilterRequest aErr;
125 if ( xRequest->getRequest() >>= aErr )
126 nFilterError = (sal_uInt16)aErr.ErrCode;
127 else
128 m_xInter->handle( xRequest );
132 // ---------------
133 // - SdPPTFilter -
134 // ---------------
136 SdGRFFilter::SdGRFFilter( SfxMedium& rMedium, ::sd::DrawDocShell& rDocShell ) :
137 SdFilter( rMedium, rDocShell, sal_True )
141 // -----------------------------------------------------------------------------
143 SdGRFFilter::~SdGRFFilter()
147 // -----------------------------------------------------------------------------
149 void SdGRFFilter::HandleGraphicFilterError( sal_uInt16 nFilterError, sal_uLong nStreamError )
151 sal_uInt16 nId;
153 switch( nFilterError )
155 case GRFILTER_OPENERROR:
156 nId = STR_IMPORT_GRFILTER_OPENERROR;
157 break;
158 case GRFILTER_IOERROR:
159 nId = STR_IMPORT_GRFILTER_IOERROR;
160 break;
161 case GRFILTER_FORMATERROR:
162 nId = STR_IMPORT_GRFILTER_FORMATERROR;
163 break;
164 case GRFILTER_VERSIONERROR:
165 nId = STR_IMPORT_GRFILTER_VERSIONERROR;
166 break;
167 case GRFILTER_TOOBIG:
168 nId = STR_IMPORT_GRFILTER_TOOBIG;
169 break;
170 case 0 :
171 nId = 0;
172 break;
174 default:
175 case GRFILTER_FILTERERROR:
176 nId = STR_IMPORT_GRFILTER_FILTERERROR;
177 break;
180 if( ERRCODE_NONE != nStreamError )
181 ErrorHandler::HandleError( nStreamError );
182 else if( STR_IMPORT_GRFILTER_IOERROR == nId )
183 ErrorHandler::HandleError( ERRCODE_IO_GENERAL );
184 else
186 ErrorBox aErrorBox( NULL, WB_OK, String( SdResId( nId ) ) );
187 aErrorBox.Execute();
191 // -----------------------------------------------------------------------------
193 sal_Bool SdGRFFilter::Import()
195 Graphic aGraphic;
196 const String aFileName( mrMedium.GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) );
197 GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter();
198 const sal_uInt16 nFilter = rGraphicFilter.GetImportFormatNumberForTypeName( mrMedium.GetFilter()->GetTypeName() );
199 sal_Bool bRet = sal_False;
201 SvStream* pIStm = mrMedium.GetInStream();
202 sal_uInt16 nReturn = pIStm ? rGraphicFilter.ImportGraphic( aGraphic, aFileName, *pIStm, nFilter ) : 1;
204 if( nReturn )
205 HandleGraphicFilterError( nReturn, rGraphicFilter.GetLastError().nStreamError );
206 else
208 if( mrDocument.GetPageCount() == 0L )
209 mrDocument.CreateFirstPages();
211 SdPage* pPage = mrDocument.GetSdPage( 0, PK_STANDARD );
212 Point aPos;
213 Size aPagSize( pPage->GetSize() );
214 Size aGrfSize( OutputDevice::LogicToLogic( aGraphic.GetPrefSize(),
215 aGraphic.GetPrefMapMode(), MAP_100TH_MM ) );
217 aPagSize.Width() -= pPage->GetLftBorder() + pPage->GetRgtBorder();
218 aPagSize.Height() -= pPage->GetUppBorder() + pPage->GetLwrBorder();
220 // scale to fit page
221 if ( ( ( aGrfSize.Height() > aPagSize.Height() ) || ( aGrfSize.Width() > aPagSize.Width() ) ) &&
222 aGrfSize.Height() && aPagSize.Height() )
224 double fGrfWH = (double) aGrfSize.Width() / aGrfSize.Height();
225 double fWinWH = (double) aPagSize.Width() / aPagSize.Height();
227 // adjust graphic to page size (scales)
228 if( fGrfWH < fWinWH )
230 aGrfSize.Width() = (long) ( aPagSize.Height() * fGrfWH );
231 aGrfSize.Height() = aPagSize.Height();
233 else if( fGrfWH > 0.F )
235 aGrfSize.Width() = aPagSize.Width();
236 aGrfSize.Height()= (long) ( aPagSize.Width() / fGrfWH );
240 // set output rectangle for graphic
241 aPos.X() = ( ( aPagSize.Width() - aGrfSize.Width() ) >> 1 ) + pPage->GetLftBorder();
242 aPos.Y() = ( ( aPagSize.Height() - aGrfSize.Height() ) >> 1 ) + pPage->GetUppBorder();
244 pPage->InsertObject( new SdrGrafObj( aGraphic, Rectangle( aPos, aGrfSize ) ) );
245 bRet = sal_True;
247 return bRet;
250 // -----------------------------------------------------------------------------
252 sal_Bool SdGRFFilter::Export()
254 // SJ: todo: error handling, the GraphicExportFilter does not support proper errorhandling
256 sal_Bool bRet = sal_False;
258 uno::Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
259 uno::Reference< drawing::XGraphicExportFilter > xExporter = drawing::GraphicExportFilter::create( xContext );
261 SdPage* pPage = NULL;
262 sd::DrawViewShell* pDrawViewShell = static_cast< ::sd::DrawViewShell* >
263 ( ( ( mrDocShell.GetViewShell() && mrDocShell.GetViewShell()->ISA(::sd::DrawViewShell ) ) ? mrDocShell.GetViewShell() : NULL ) );
265 PageKind ePageKind = PK_STANDARD;
266 if( pDrawViewShell )
268 ePageKind = pDrawViewShell->GetPageKind();
269 if( PK_HANDOUT == ePageKind )
270 pPage = mrDocument.GetSdPage( 0, PK_HANDOUT );
271 else
272 pPage = pDrawViewShell->GetActualPage();
274 else
275 pPage = mrDocument.GetSdPage( 0, PK_STANDARD );
277 if ( pPage )
279 // taking the 'correct' page number, seems that there might exist a better method to archive this
280 pPage = mrDocument.GetSdPage( pPage->GetPageNum() ? ( pPage->GetPageNum() - 1 ) >> 1 : 0, ePageKind );
281 if ( pPage )
283 uno::Reference< lang::XComponent > xSource( pPage->getUnoPage(), uno::UNO_QUERY );
284 SfxItemSet* pSet = mrMedium.GetItemSet();
285 if ( pSet && xSource.is() )
287 const String aTypeName( mrMedium.GetFilter()->GetTypeName() );
288 GraphicFilter &rGraphicFilter = GraphicFilter::GetGraphicFilter();
289 const sal_uInt16 nFilter = rGraphicFilter.GetExportFormatNumberForTypeName( aTypeName );
290 if ( nFilter != GRFILTER_FORMAT_NOTFOUND )
292 uno::Reference< task::XInteractionHandler > mXInteractionHandler;
294 beans::PropertyValues aArgs;
295 TransformItems( SID_SAVEASDOC, *pSet, aArgs );
297 OUString sInteractionHandler( "InteractionHandler" );
298 OUString sFilterName( "FilterName" );
299 OUString sShortName( rGraphicFilter.GetExportFormatShortName( nFilter ) );
301 sal_Bool bFilterNameFound = sal_False;
302 sal_Int32 i, nCount;
303 for ( i = 0, nCount = aArgs.getLength(); i < nCount; i++ )
305 OUString& rStr = aArgs[ i ].Name;
306 if ( rStr == sFilterName )
308 bFilterNameFound = sal_True;
309 aArgs[ i ].Name = sFilterName;
310 aArgs[ i ].Value <<= sShortName;
312 else if ( rStr == sInteractionHandler )
314 uno::Reference< task::XInteractionHandler > xHdl;
315 if ( aArgs[ i ].Value >>= xHdl )
317 mXInteractionHandler = new SdGRFFilter_ImplInteractionHdl( xHdl );
318 aArgs[ i ].Value <<= mXInteractionHandler;
322 if ( !bFilterNameFound )
324 aArgs.realloc( ++nCount );
325 aArgs[ i ].Name = sFilterName;
326 aArgs[ i ].Value <<= sShortName;
329 // take selection if needed
330 if( ( SFX_ITEM_SET == pSet->GetItemState( SID_SELECTION ) )
331 && static_cast< const SfxBoolItem& >( pSet->Get( SID_SELECTION ) ).GetValue()
332 && pDrawViewShell )
334 uno::Reference< view::XSelectionSupplier > xSelectionSupplier(
335 pDrawViewShell->GetViewShellBase().GetController(), uno::UNO_QUERY );
336 if ( xSelectionSupplier.is() )
338 uno::Any aSelection( xSelectionSupplier->getSelection() );
339 uno::Reference< lang::XComponent > xSelection;
340 if ( aSelection >>= xSelection )
341 xSource = xSelection;
344 xExporter->setSourceDocument( xSource );
345 bRet = xExporter->filter( aArgs );
346 if ( !bRet && mXInteractionHandler.is() )
347 SdGRFFilter::HandleGraphicFilterError(
348 static_cast< SdGRFFilter_ImplInteractionHdl* >( mXInteractionHandler.get() )->GetErrorCode(),
349 rGraphicFilter.GetLastError().nStreamError );
354 return bRet;
357 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */