Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 :
21 : #ifdef _MSC_VER
22 : #pragma warning (disable:4190)
23 : #endif
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>
29 :
30 : #include <unotools/localfilehelper.hxx>
31 : #include <tools/errinf.hxx>
32 : #include <vcl/msgbox.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>
40 :
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"
46 :
47 : #include "comphelper/anytostring.hxx"
48 : #include "cppuhelper/exc_hlp.hxx"
49 :
50 : // --
51 : #include <comphelper/processfactory.hxx>
52 : #include <unotools/pathoptions.hxx>
53 : #include <sfx2/filedlghelper.hxx>
54 : #include <svtools/filter.hxx>
55 : #include <svx/xoutbmp.hxx>
56 :
57 : // --
58 :
59 : #include "sdpage.hxx"
60 : #include "drawdoc.hxx"
61 : #include "sdresid.hxx"
62 : #include "sdgrffilter.hxx"
63 : #include "../../ui/inc/ViewShellBase.hxx"
64 : #include <com/sun/star/uno/Sequence.h>
65 : #include <com/sun/star/beans/PropertyValue.hpp>
66 : #include <com/sun/star/beans/PropertyValues.hpp>
67 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
68 : #include <com/sun/star/lang/XComponent.hpp>
69 : #include <com/sun/star/document/XFilter.hpp>
70 : #include <com/sun/star/document/XExporter.hpp>
71 : #include <com/sun/star/view/XSelectionSupplier.hpp>
72 : #include <com/sun/star/drawing/XDrawView.hpp>
73 : #include "../../ui/inc/DrawController.hxx"
74 : #include <cppuhelper/implbase2.hxx>
75 : #include <com/sun/star/drawing/XShape.hpp>
76 : #include <com/sun/star/task/XInteractionHandler.hpp>
77 : #include <com/sun/star/task/XInteractionRequest.hpp>
78 : #include <com/sun/star/drawing/GraphicFilterRequest.hpp>
79 :
80 : using namespace ::com::sun::star;
81 : using namespace ::com::sun::star::uno;
82 : using namespace ::com::sun::star::lang;
83 : using namespace ::com::sun::star::beans;
84 : using namespace ::com::sun::star::graphic;
85 : using namespace ::com::sun::star::io;
86 : using namespace ::com::sun::star::ucb;
87 : using namespace com::sun::star::ui::dialogs;
88 : using rtl::OUString;
89 : using namespace ::sfx2;
90 :
91 :
92 : // -----------------------------------------------------------------------------
93 :
94 : class SdGRFFilter_ImplInteractionHdl : public ::cppu::WeakImplHelper1< com::sun::star::task::XInteractionHandler >
95 : {
96 : com::sun::star::uno::Reference< com::sun::star::task::XInteractionHandler > m_xInter;
97 : sal_uInt16 nFilterError;
98 :
99 : public:
100 :
101 0 : SdGRFFilter_ImplInteractionHdl( com::sun::star::uno::Reference< com::sun::star::task::XInteractionHandler > xInteraction ) :
102 : m_xInter( xInteraction ),
103 0 : nFilterError( GRFILTER_OK )
104 0 : {}
105 :
106 : ~SdGRFFilter_ImplInteractionHdl();
107 :
108 0 : sal_uInt16 GetErrorCode() const { return nFilterError; };
109 :
110 : virtual void SAL_CALL handle( const com::sun::star::uno::Reference< com::sun::star::task::XInteractionRequest >& )
111 : throw( com::sun::star::uno::RuntimeException );
112 : };
113 :
114 0 : SdGRFFilter_ImplInteractionHdl::~SdGRFFilter_ImplInteractionHdl()
115 : {
116 0 : }
117 :
118 0 : void SdGRFFilter_ImplInteractionHdl::handle( const com::sun::star::uno::Reference< com::sun::star::task::XInteractionRequest >& xRequest )
119 : throw( com::sun::star::uno::RuntimeException )
120 : {
121 0 : if( !m_xInter.is() )
122 0 : return;
123 :
124 0 : com::sun::star::drawing::GraphicFilterRequest aErr;
125 0 : if ( xRequest->getRequest() >>= aErr )
126 0 : nFilterError = (sal_uInt16)aErr.ErrCode;
127 : else
128 0 : m_xInter->handle( xRequest );
129 : }
130 :
131 :
132 : // ---------------
133 : // - SdPPTFilter -
134 : // ---------------
135 :
136 0 : SdGRFFilter::SdGRFFilter( SfxMedium& rMedium, ::sd::DrawDocShell& rDocShell ) :
137 0 : SdFilter( rMedium, rDocShell, sal_True )
138 : {
139 0 : }
140 :
141 : // -----------------------------------------------------------------------------
142 :
143 0 : SdGRFFilter::~SdGRFFilter()
144 : {
145 0 : }
146 :
147 : // -----------------------------------------------------------------------------
148 :
149 0 : void SdGRFFilter::HandleGraphicFilterError( sal_uInt16 nFilterError, sal_uLong nStreamError )
150 : {
151 : sal_uInt16 nId;
152 :
153 0 : switch( nFilterError )
154 : {
155 : case GRFILTER_OPENERROR:
156 0 : nId = STR_IMPORT_GRFILTER_OPENERROR;
157 0 : break;
158 : case GRFILTER_IOERROR:
159 0 : nId = STR_IMPORT_GRFILTER_IOERROR;
160 0 : break;
161 : case GRFILTER_FORMATERROR:
162 0 : nId = STR_IMPORT_GRFILTER_FORMATERROR;
163 0 : break;
164 : case GRFILTER_VERSIONERROR:
165 0 : nId = STR_IMPORT_GRFILTER_VERSIONERROR;
166 0 : break;
167 : case GRFILTER_TOOBIG:
168 0 : nId = STR_IMPORT_GRFILTER_TOOBIG;
169 0 : break;
170 : case 0 :
171 0 : nId = 0;
172 0 : break;
173 :
174 : default:
175 : case GRFILTER_FILTERERROR:
176 0 : nId = STR_IMPORT_GRFILTER_FILTERERROR;
177 0 : break;
178 : }
179 :
180 0 : if( ERRCODE_NONE != nStreamError )
181 0 : ErrorHandler::HandleError( nStreamError );
182 0 : else if( STR_IMPORT_GRFILTER_IOERROR == nId )
183 0 : ErrorHandler::HandleError( ERRCODE_IO_GENERAL );
184 : else
185 : {
186 0 : ErrorBox aErrorBox( NULL, WB_OK, String( SdResId( nId ) ) );
187 0 : aErrorBox.Execute();
188 : }
189 0 : }
190 :
191 : // -----------------------------------------------------------------------------
192 :
193 0 : sal_Bool SdGRFFilter::Import()
194 : {
195 0 : Graphic aGraphic;
196 0 : const String aFileName( mrMedium.GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) );
197 0 : GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter();
198 0 : const sal_uInt16 nFilter = rGraphicFilter.GetImportFormatNumberForTypeName( mrMedium.GetFilter()->GetTypeName() );
199 0 : sal_Bool bRet = sal_False;
200 :
201 0 : SvStream* pIStm = mrMedium.GetInStream();
202 0 : sal_uInt16 nReturn = pIStm ? rGraphicFilter.ImportGraphic( aGraphic, aFileName, *pIStm, nFilter ) : 1;
203 :
204 0 : if( nReturn )
205 0 : HandleGraphicFilterError( nReturn, rGraphicFilter.GetLastError().nStreamError );
206 : else
207 : {
208 0 : if( mrDocument.GetPageCount() == 0L )
209 0 : mrDocument.CreateFirstPages();
210 :
211 0 : SdPage* pPage = mrDocument.GetSdPage( 0, PK_STANDARD );
212 0 : Point aPos;
213 0 : Size aPagSize( pPage->GetSize() );
214 : Size aGrfSize( OutputDevice::LogicToLogic( aGraphic.GetPrefSize(),
215 0 : aGraphic.GetPrefMapMode(), MAP_100TH_MM ) );
216 :
217 0 : aPagSize.Width() -= pPage->GetLftBorder() + pPage->GetRgtBorder();
218 0 : aPagSize.Height() -= pPage->GetUppBorder() + pPage->GetLwrBorder();
219 :
220 : // scale to fit page
221 0 : if ( ( ( aGrfSize.Height() > aPagSize.Height() ) || ( aGrfSize.Width() > aPagSize.Width() ) ) &&
222 0 : aGrfSize.Height() && aPagSize.Height() )
223 : {
224 0 : double fGrfWH = (double) aGrfSize.Width() / aGrfSize.Height();
225 0 : double fWinWH = (double) aPagSize.Width() / aPagSize.Height();
226 :
227 : // Grafik an Pagesize anpassen (skaliert)
228 0 : if( fGrfWH < fWinWH )
229 : {
230 0 : aGrfSize.Width() = (long) ( aPagSize.Height() * fGrfWH );
231 0 : aGrfSize.Height() = aPagSize.Height();
232 : }
233 0 : else if( fGrfWH > 0.F )
234 : {
235 0 : aGrfSize.Width() = aPagSize.Width();
236 0 : aGrfSize.Height()= (long) ( aPagSize.Width() / fGrfWH );
237 : }
238 : }
239 :
240 : // Ausgaberechteck fuer Grafik setzen
241 0 : aPos.X() = ( ( aPagSize.Width() - aGrfSize.Width() ) >> 1 ) + pPage->GetLftBorder();
242 0 : aPos.Y() = ( ( aPagSize.Height() - aGrfSize.Height() ) >> 1 ) + pPage->GetUppBorder();
243 :
244 0 : pPage->InsertObject( new SdrGrafObj( aGraphic, Rectangle( aPos, aGrfSize ) ) );
245 0 : bRet = sal_True;
246 : }
247 0 : return bRet;
248 : }
249 :
250 : // -----------------------------------------------------------------------------
251 :
252 0 : sal_Bool SdGRFFilter::Export()
253 : {
254 : // SJ: todo: error handling, the GraphicExportFilter does not support proper errorhandling
255 :
256 0 : sal_Bool bRet = sal_False;
257 :
258 : uno::Reference< lang::XMultiServiceFactory >
259 0 : xSMgr( ::comphelper::getProcessServiceFactory() );
260 : uno::Reference< uno::XInterface > xComponent
261 0 : ( xSMgr->createInstance( "com.sun.star.drawing.GraphicExportFilter" ),
262 0 : uno::UNO_QUERY );
263 0 : if ( xComponent.is() )
264 : {
265 : uno::Reference< document::XExporter > xExporter
266 0 : ( xComponent, uno::UNO_QUERY );
267 : uno::Reference< document::XFilter > xFilter
268 0 : ( xComponent, uno::UNO_QUERY );
269 0 : if ( xExporter.is() && xFilter.is() )
270 : {
271 0 : SdPage* pPage = NULL;
272 : sd::DrawViewShell* pDrawViewShell = static_cast< ::sd::DrawViewShell* >
273 0 : ( ( ( mrDocShell.GetViewShell() && mrDocShell.GetViewShell()->ISA(::sd::DrawViewShell ) ) ? mrDocShell.GetViewShell() : NULL ) );
274 :
275 0 : PageKind ePageKind = PK_STANDARD;
276 0 : if( pDrawViewShell )
277 : {
278 0 : ePageKind = pDrawViewShell->GetPageKind();
279 0 : if( PK_HANDOUT == ePageKind )
280 0 : pPage = mrDocument.GetSdPage( 0, PK_HANDOUT );
281 : else
282 0 : pPage = pDrawViewShell->GetActualPage();
283 : }
284 : else
285 0 : pPage = mrDocument.GetSdPage( 0, PK_STANDARD );
286 :
287 0 : if ( pPage )
288 : {
289 : // taking the 'correct' page number, seems that there might exist a better method to archive this
290 0 : pPage = mrDocument.GetSdPage( pPage->GetPageNum() ? ( pPage->GetPageNum() - 1 ) >> 1 : 0, ePageKind );
291 0 : if ( pPage )
292 : {
293 0 : uno::Reference< lang::XComponent > xSource( pPage->getUnoPage(), uno::UNO_QUERY );
294 0 : SfxItemSet* pSet = mrMedium.GetItemSet();
295 0 : if ( pSet && xSource.is() )
296 : {
297 0 : const String aTypeName( mrMedium.GetFilter()->GetTypeName() );
298 0 : GraphicFilter &rGraphicFilter = GraphicFilter::GetGraphicFilter();
299 0 : const sal_uInt16 nFilter = rGraphicFilter.GetExportFormatNumberForTypeName( aTypeName );
300 0 : if ( nFilter != GRFILTER_FORMAT_NOTFOUND )
301 : {
302 0 : uno::Reference< task::XInteractionHandler > mXInteractionHandler;
303 :
304 0 : beans::PropertyValues aArgs;
305 0 : TransformItems( SID_SAVEASDOC, *pSet, aArgs );
306 :
307 0 : rtl::OUString sInteractionHandler( "InteractionHandler" );
308 0 : rtl::OUString sFilterName( "FilterName" );
309 0 : rtl::OUString sShortName( rGraphicFilter.GetExportFormatShortName( nFilter ) );
310 :
311 0 : sal_Bool bFilterNameFound = sal_False;
312 : sal_Int32 i, nCount;
313 0 : for ( i = 0, nCount = aArgs.getLength(); i < nCount; i++ )
314 : {
315 0 : rtl::OUString& rStr = aArgs[ i ].Name;
316 0 : if ( rStr == sFilterName )
317 : {
318 0 : bFilterNameFound = sal_True;
319 0 : aArgs[ i ].Name = sFilterName;
320 0 : aArgs[ i ].Value <<= sShortName;
321 : }
322 0 : else if ( rStr == sInteractionHandler )
323 : {
324 0 : uno::Reference< task::XInteractionHandler > xHdl;
325 0 : if ( aArgs[ i ].Value >>= xHdl )
326 : {
327 0 : mXInteractionHandler = new SdGRFFilter_ImplInteractionHdl( xHdl );
328 0 : aArgs[ i ].Value <<= mXInteractionHandler;
329 0 : }
330 : }
331 : }
332 0 : if ( !bFilterNameFound )
333 : {
334 0 : aArgs.realloc( ++nCount );
335 0 : aArgs[ i ].Name = sFilterName;
336 0 : aArgs[ i ].Value <<= sShortName;
337 : }
338 :
339 : // take selection if needed
340 0 : if( ( SFX_ITEM_SET == pSet->GetItemState( SID_SELECTION ) )
341 0 : && static_cast< const SfxBoolItem& >( pSet->Get( SID_SELECTION ) ).GetValue()
342 : && pDrawViewShell )
343 : {
344 : uno::Reference< view::XSelectionSupplier > xSelectionSupplier(
345 0 : pDrawViewShell->GetViewShellBase().GetController(), uno::UNO_QUERY );
346 0 : if ( xSelectionSupplier.is() )
347 : {
348 0 : uno::Any aSelection( xSelectionSupplier->getSelection() );
349 0 : uno::Reference< lang::XComponent > xSelection;
350 0 : if ( aSelection >>= xSelection )
351 0 : xSource = xSelection;
352 0 : }
353 : }
354 0 : xExporter->setSourceDocument( xSource );
355 0 : bRet = xFilter->filter( aArgs );
356 0 : if ( !bRet && mXInteractionHandler.is() )
357 : SdGRFFilter::HandleGraphicFilterError(
358 0 : static_cast< SdGRFFilter_ImplInteractionHdl* >( mXInteractionHandler.get() )->GetErrorCode(),
359 0 : rGraphicFilter.GetLastError().nStreamError );
360 0 : }
361 0 : }
362 : }
363 : }
364 0 : }
365 : }
366 0 : return bRet;
367 : }
368 :
369 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|