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 : #include <vector>
21 : #include <osl/mutex.hxx>
22 : #include <com/sun/star/io/XOutputStream.hpp>
23 : #include <com/sun/star/container/XChild.hpp>
24 : #include <com/sun/star/frame/XModel.hpp>
25 : #include <com/sun/star/lang/XServiceInfo.hpp>
26 : #include <com/sun/star/lang/XComponent.hpp>
27 : #include <com/sun/star/drawing/XShape.hpp>
28 : #include <com/sun/star/drawing/XDrawPage.hpp>
29 : #include <com/sun/star/drawing/XGraphicExportFilter.hpp>
30 : #include <com/sun/star/graphic/XGraphic.hpp>
31 : #include <com/sun/star/graphic/XGraphicRenderer.hpp>
32 : #include <com/sun/star/task/XStatusIndicator.hpp>
33 : #include <com/sun/star/task/XInteractionHandler.hpp>
34 : #include <com/sun/star/task/XInteractionContinuation.hpp>
35 :
36 : #include <rtl/logfile.hxx>
37 : #include <comphelper/interaction.hxx>
38 : #include <framework/interaction.hxx>
39 : #include <com/sun/star/drawing/GraphicFilterRequest.hpp>
40 : #include <com/sun/star/util/URL.hpp>
41 : #include <cppuhelper/implbase4.hxx>
42 : #include <osl/diagnose.h>
43 : #include <vcl/metaact.hxx>
44 : #include <vcl/svapp.hxx>
45 : #include <vcl/virdev.hxx>
46 : #include <vcl/FilterConfigItem.hxx>
47 : #include <svl/outstrm.hxx>
48 : #include <svx/sdr/contact/objectcontactofobjlistpainter.hxx>
49 : #include <svx/sdr/contact/viewobjectcontact.hxx>
50 : #include <svx/sdr/contact/viewcontact.hxx>
51 : #include <svx/sdr/contact/displayinfo.hxx>
52 : #include <svx/sdr/contact/viewcontactofsdrobj.hxx>
53 : #include <editeng/numitem.hxx>
54 : #include <svx/svdpagv.hxx>
55 : #include <svx/svdograf.hxx>
56 : #include "svx/xoutbmp.hxx"
57 : #include <vcl/graphicfilter.hxx>
58 : #include "svx/unoapi.hxx"
59 : #include <svx/svdpage.hxx>
60 : #include <svx/svdmodel.hxx>
61 : #include <svx/fmview.hxx>
62 : #include <svx/fmmodel.hxx>
63 : #include <svx/unopage.hxx>
64 : #include <svx/pageitem.hxx>
65 : #include <editeng/eeitem.hxx>
66 : #include <svx/svdoutl.hxx>
67 : #include <editeng/flditem.hxx>
68 :
69 : #include "boost/scoped_ptr.hpp"
70 :
71 : #define MAX_EXT_PIX 2048
72 :
73 : using namespace ::comphelper;
74 : using namespace ::osl;
75 : using namespace ::cppu;
76 : using namespace ::com::sun::star;
77 : using namespace ::com::sun::star::uno;
78 : using namespace ::com::sun::star::util;
79 : using namespace ::com::sun::star::container;
80 : using namespace ::com::sun::star::drawing;
81 : using namespace ::com::sun::star::lang;
82 : using namespace ::com::sun::star::document;
83 : using namespace ::com::sun::star::frame;
84 : using namespace ::com::sun::star::beans;
85 : using namespace ::com::sun::star::task;
86 : #include <svx/sdr/contact/viewobjectcontactredirector.hxx>
87 :
88 : // #i102251#
89 : #include <editeng/editstat.hxx>
90 :
91 : //////////////////////////////////////////////////////////////////////////////
92 :
93 : namespace svx
94 : {
95 0 : struct ExportSettings
96 : {
97 : OUString maFilterName;
98 : OUString maMediaType;
99 : URL maURL;
100 : com::sun::star::uno::Reference< com::sun::star::io::XOutputStream > mxOutputStream;
101 : com::sun::star::uno::Reference< com::sun::star::graphic::XGraphicRenderer > mxGraphicRenderer;
102 : com::sun::star::uno::Reference< com::sun::star::task::XStatusIndicator > mxStatusIndicator;
103 : com::sun::star::uno::Reference< com::sun::star::task::XInteractionHandler > mxInteractionHandler;
104 :
105 : sal_Int32 mnWidth;
106 : sal_Int32 mnHeight;
107 : sal_Bool mbExportOnlyBackground;
108 : sal_Bool mbScrollText;
109 : sal_Bool mbUseHighContrast;
110 : sal_Bool mbTranslucent;
111 :
112 : Sequence< PropertyValue > maFilterData;
113 :
114 : Fraction maScaleX;
115 : Fraction maScaleY;
116 :
117 : ExportSettings( SdrModel* pDoc );
118 : };
119 :
120 0 : ExportSettings::ExportSettings( SdrModel* pDoc )
121 : : mnWidth( 0 )
122 : , mnHeight( 0 )
123 : , mbExportOnlyBackground( false )
124 : , mbScrollText( false )
125 : , mbUseHighContrast( false )
126 : , mbTranslucent( sal_False )
127 : , maScaleX( 1, 1 )
128 0 : , maScaleY( 1, 1 )
129 : {
130 0 : if( pDoc )
131 : {
132 0 : maScaleX = pDoc->GetScaleFraction();
133 0 : maScaleY = pDoc->GetScaleFraction();
134 : }
135 0 : }
136 :
137 : /** implements a component to export shapes or pages to external graphic formats.
138 :
139 : @implements com.sun.star.drawing.GraphicExportFilter
140 : */
141 : class GraphicExporter : public WeakImplHelper2< XGraphicExportFilter, XServiceInfo >
142 : {
143 : public:
144 : GraphicExporter();
145 : virtual ~GraphicExporter();
146 :
147 : // XFilter
148 : virtual sal_Bool SAL_CALL filter( const Sequence< PropertyValue >& aDescriptor ) throw(RuntimeException);
149 : virtual void SAL_CALL cancel( ) throw(RuntimeException);
150 :
151 : // XExporter
152 : virtual void SAL_CALL setSourceDocument( const Reference< XComponent >& xDoc ) throw(IllegalArgumentException, RuntimeException);
153 :
154 : // XServiceInfo
155 : virtual OUString SAL_CALL getImplementationName( ) throw(RuntimeException);
156 : virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(RuntimeException);
157 : virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw(RuntimeException);
158 :
159 : // XMimeTypeInfo
160 : virtual sal_Bool SAL_CALL supportsMimeType( const OUString& MimeTypeName ) throw (RuntimeException);
161 : virtual Sequence< OUString > SAL_CALL getSupportedMimeTypeNames( ) throw (RuntimeException);
162 :
163 : VirtualDevice* CreatePageVDev( SdrPage* pPage, sal_uIntPtr nWidthPixel, sal_uIntPtr nHeightPixel ) const;
164 :
165 : DECL_LINK( CalcFieldValueHdl, EditFieldInfo* );
166 :
167 : void ParseSettings( const Sequence< PropertyValue >& aDescriptor, ExportSettings& rSettings );
168 : bool GetGraphic( ExportSettings& rSettings, Graphic& aGraphic, sal_Bool bVectorType );
169 :
170 : private:
171 : Reference< XShape > mxShape;
172 : Reference< XDrawPage > mxPage;
173 : Reference< XShapes > mxShapes;
174 :
175 : SvxDrawPage* mpUnoPage;
176 :
177 : Link maOldCalcFieldValueHdl;
178 : sal_Int32 mnPageNumber;
179 : SdrPage* mpCurrentPage;
180 : SdrModel* mpDoc;
181 : };
182 :
183 0 : SVX_DLLPUBLIC Reference< XInterface > SAL_CALL GraphicExporter_createInstance(const Reference< XMultiServiceFactory > & )
184 : throw( Exception )
185 : {
186 0 : return (XWeak*)new GraphicExporter();
187 : }
188 :
189 0 : SVX_DLLPUBLIC Sequence< OUString > SAL_CALL GraphicExporter_getSupportedServiceNames()
190 : throw()
191 : {
192 0 : Sequence< OUString > aSupportedServiceNames( 1 );
193 0 : aSupportedServiceNames[0] = OUString( "com.sun.star.drawing.GraphicExportFilter" );
194 0 : return aSupportedServiceNames;
195 : }
196 :
197 42 : SVX_DLLPUBLIC OUString SAL_CALL GraphicExporter_getImplementationName()
198 : throw()
199 : {
200 42 : return OUString( "com.sun.star.comp.Draw.GraphicExporter" );
201 : }
202 :
203 : /** creates a bitmap that is optionaly transparent from a metafile
204 : */
205 0 : BitmapEx GetBitmapFromMetaFile( const GDIMetaFile& rMtf, sal_Bool bTransparent, const Size* pSize )
206 : {
207 0 : BitmapEx aBmpEx;
208 :
209 0 : if(bTransparent)
210 : {
211 : // use new primitive conversion tooling
212 0 : basegfx::B2DRange aRange(basegfx::B2DPoint(0.0, 0.0));
213 :
214 0 : if(pSize)
215 : {
216 : // use 100th mm for primitive bitmap converter tool, input is pixel
217 : // use a real OutDev to get the correct DPI, the static LogicToLogic assumes 72dpi which is wrong (!)
218 0 : const Size aSize100th(Application::GetDefaultDevice()->PixelToLogic(*pSize, MapMode(MAP_100TH_MM)));
219 :
220 0 : aRange.expand(basegfx::B2DPoint(aSize100th.Width(), aSize100th.Height()));
221 : }
222 : else
223 : {
224 : // use 100th mm for primitive bitmap converter tool
225 0 : const Size aSize100th(Application::GetDefaultDevice()->LogicToLogic(rMtf.GetPrefSize(), rMtf.GetPrefMapMode(), MapMode(MAP_100TH_MM)));
226 :
227 0 : aRange.expand(basegfx::B2DPoint(aSize100th.Width(), aSize100th.Height()));
228 : }
229 :
230 0 : aBmpEx = convertMetafileToBitmapEx(rMtf, aRange);
231 : }
232 : else
233 : {
234 0 : const SvtOptionsDrawinglayer aDrawinglayerOpt;
235 : const GraphicConversionParameters aParameters(
236 : pSize ? *pSize : Size(0, 0),
237 : true, // allow unlimited size
238 0 : aDrawinglayerOpt.IsAntiAliasing(),
239 0 : aDrawinglayerOpt.IsSnapHorVerLinesToDiscrete());
240 0 : const Graphic aGraphic(rMtf);
241 :
242 0 : aBmpEx = BitmapEx(aGraphic.GetBitmap(aParameters));
243 0 : aBmpEx.SetPrefMapMode( rMtf.GetPrefMapMode() );
244 0 : aBmpEx.SetPrefSize( rMtf.GetPrefSize() );
245 : }
246 :
247 0 : return aBmpEx;
248 : }
249 :
250 0 : Size* CalcSize( sal_Int32 nWidth, sal_Int32 nHeight, const Size& aBoundSize, Size& aOutSize )
251 : {
252 0 : if( (nWidth == 0) && (nHeight == 0) )
253 0 : return NULL;
254 :
255 0 : if( (nWidth == 0) && (nHeight != 0) && (aBoundSize.Height() != 0) )
256 : {
257 0 : nWidth = ( nHeight * aBoundSize.Width() ) / aBoundSize.Height();
258 : }
259 0 : else if( (nWidth != 0) && (nHeight == 0) && (aBoundSize.Width() != 0) )
260 : {
261 0 : nHeight = ( nWidth * aBoundSize.Height() ) / aBoundSize.Width();
262 : }
263 :
264 0 : aOutSize.Width() = nWidth;
265 0 : aOutSize.Height() = nHeight;
266 :
267 0 : return &aOutSize;
268 : }
269 : }
270 :
271 : class ImplExportCheckVisisbilityRedirector : public ::sdr::contact::ViewObjectContactRedirector
272 : {
273 : public:
274 : ImplExportCheckVisisbilityRedirector( SdrPage* pCurrentPage );
275 : virtual ~ImplExportCheckVisisbilityRedirector();
276 :
277 : virtual drawinglayer::primitive2d::Primitive2DSequence createRedirectedPrimitive2DSequence(
278 : const sdr::contact::ViewObjectContact& rOriginal,
279 : const sdr::contact::DisplayInfo& rDisplayInfo);
280 :
281 : private:
282 : SdrPage* mpCurrentPage;
283 : };
284 :
285 0 : ImplExportCheckVisisbilityRedirector::ImplExportCheckVisisbilityRedirector( SdrPage* pCurrentPage )
286 0 : : ViewObjectContactRedirector(), mpCurrentPage( pCurrentPage )
287 : {
288 0 : }
289 :
290 0 : ImplExportCheckVisisbilityRedirector::~ImplExportCheckVisisbilityRedirector()
291 : {
292 0 : }
293 :
294 0 : drawinglayer::primitive2d::Primitive2DSequence ImplExportCheckVisisbilityRedirector::createRedirectedPrimitive2DSequence(
295 : const sdr::contact::ViewObjectContact& rOriginal,
296 : const sdr::contact::DisplayInfo& rDisplayInfo)
297 : {
298 0 : SdrObject* pObject = rOriginal.GetViewContact().TryToGetSdrObject();
299 :
300 0 : if(pObject)
301 : {
302 0 : SdrPage* pPage = mpCurrentPage;
303 0 : if( pPage == 0 )
304 0 : pPage = pObject->GetPage();
305 :
306 0 : if( (pPage == 0) || pPage->checkVisibility(rOriginal, rDisplayInfo, false) )
307 : {
308 0 : return ::sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(rOriginal, rDisplayInfo);
309 : }
310 :
311 0 : return drawinglayer::primitive2d::Primitive2DSequence();
312 : }
313 : else
314 : {
315 : // not an object, maybe a page
316 0 : return ::sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(rOriginal, rDisplayInfo);
317 : }
318 : }
319 :
320 : using namespace ::svx;
321 :
322 0 : GraphicExporter::GraphicExporter()
323 0 : : mpUnoPage( NULL ), mnPageNumber(-1), mpCurrentPage(0), mpDoc( NULL )
324 : {
325 0 : }
326 :
327 0 : GraphicExporter::~GraphicExporter()
328 : {
329 0 : }
330 :
331 0 : IMPL_LINK(GraphicExporter, CalcFieldValueHdl, EditFieldInfo*, pInfo)
332 : {
333 0 : if( pInfo )
334 : {
335 0 : if( mpCurrentPage )
336 : {
337 0 : pInfo->SetSdrPage( mpCurrentPage );
338 : }
339 0 : else if( mnPageNumber != -1 )
340 : {
341 0 : const SvxFieldData* pField = pInfo->GetField().GetField();
342 0 : if( pField && pField->ISA( SvxPageField ) )
343 : {
344 0 : String aPageNumValue;
345 0 : sal_Bool bUpper = sal_False;
346 :
347 0 : switch(mpDoc->GetPageNumType())
348 : {
349 : case SVX_CHARS_UPPER_LETTER:
350 0 : aPageNumValue += (sal_Unicode)(char)((mnPageNumber - 1) % 26 + 'A');
351 0 : break;
352 : case SVX_CHARS_LOWER_LETTER:
353 0 : aPageNumValue += (sal_Unicode)(char)((mnPageNumber - 1) % 26 + 'a');
354 0 : break;
355 : case SVX_ROMAN_UPPER:
356 0 : bUpper = sal_True;
357 : case SVX_ROMAN_LOWER:
358 0 : aPageNumValue += SvxNumberFormat::CreateRomanString(mnPageNumber, bUpper);
359 0 : break;
360 : case SVX_NUMBER_NONE:
361 0 : aPageNumValue.Erase();
362 0 : aPageNumValue += sal_Unicode(' ');
363 0 : break;
364 : default:
365 0 : aPageNumValue += OUString::number( (sal_Int32)mnPageNumber );
366 : }
367 :
368 0 : pInfo->SetRepresentation( aPageNumValue );
369 :
370 0 : return(0);
371 : }
372 : }
373 : }
374 :
375 0 : long nRet = maOldCalcFieldValueHdl.Call( pInfo );
376 :
377 0 : if( pInfo && mpCurrentPage )
378 0 : pInfo->SetSdrPage( 0 );
379 :
380 0 : return nRet;
381 : }
382 :
383 : /** creates an virtual device for the given page
384 :
385 : @return the returned VirtualDevice is owned by the caller
386 : */
387 0 : VirtualDevice* GraphicExporter::CreatePageVDev( SdrPage* pPage, sal_uIntPtr nWidthPixel, sal_uIntPtr nHeightPixel ) const
388 : {
389 0 : VirtualDevice* pVDev = new VirtualDevice();
390 0 : MapMode aMM( MAP_100TH_MM );
391 :
392 0 : Point aPoint( 0, 0 );
393 0 : Size aPageSize(pPage->GetSize());
394 :
395 : // use scaling?
396 0 : if( nWidthPixel )
397 : {
398 0 : const Fraction aFrac( (long) nWidthPixel, pVDev->LogicToPixel( aPageSize, aMM ).Width() );
399 :
400 0 : aMM.SetScaleX( aFrac );
401 :
402 0 : if( nHeightPixel == 0 )
403 0 : aMM.SetScaleY( aFrac );
404 : }
405 :
406 0 : if( nHeightPixel )
407 : {
408 0 : const Fraction aFrac( (long) nHeightPixel, pVDev->LogicToPixel( aPageSize, aMM ).Height() );
409 :
410 0 : if( nWidthPixel == 0 )
411 0 : aMM.SetScaleX( aFrac );
412 :
413 0 : aMM.SetScaleY( aFrac );
414 : }
415 :
416 0 : pVDev->SetMapMode( aMM );
417 : #ifdef DBG_UTIL
418 : bool bAbort = !
419 : #endif
420 0 : pVDev->SetOutputSize(aPageSize);
421 : DBG_ASSERT(!bAbort, "virt. Device nicht korrekt erzeugt");
422 :
423 0 : SdrView* pView = new SdrView(mpDoc, pVDev);
424 0 : pView->SetPageVisible( sal_False );
425 0 : pView->SetBordVisible( sal_False );
426 0 : pView->SetGridVisible( sal_False );
427 0 : pView->SetHlplVisible( sal_False );
428 0 : pView->SetGlueVisible( sal_False );
429 0 : pView->ShowSdrPage(pPage);
430 0 : Region aRegion (Rectangle( aPoint, aPageSize ) );
431 :
432 0 : ImplExportCheckVisisbilityRedirector aRedirector( mpCurrentPage );
433 :
434 0 : pView->CompleteRedraw(pVDev, aRegion, &aRedirector);
435 :
436 0 : delete pView;
437 0 : return pVDev;
438 : }
439 :
440 0 : void GraphicExporter::ParseSettings( const Sequence< PropertyValue >& aDescriptor, ExportSettings& rSettings )
441 : {
442 0 : sal_Int32 nArgs = aDescriptor.getLength();
443 0 : const PropertyValue* pValues = aDescriptor.getConstArray();
444 0 : while( nArgs-- )
445 : {
446 0 : if ( pValues->Name == "FilterName" )
447 : {
448 0 : pValues->Value >>= rSettings.maFilterName;
449 : }
450 0 : else if ( pValues->Name == "MediaType" )
451 : {
452 0 : pValues->Value >>= rSettings.maMediaType;
453 : }
454 0 : else if ( pValues->Name == "URL" )
455 : {
456 0 : if( !( pValues->Value >>= rSettings.maURL ) )
457 : {
458 0 : pValues->Value >>= rSettings.maURL.Complete;
459 : }
460 : }
461 0 : else if ( pValues->Name == "OutputStream" )
462 : {
463 0 : pValues->Value >>= rSettings.mxOutputStream;
464 : }
465 0 : else if ( pValues->Name == "GraphicRenderer" )
466 : {
467 0 : pValues->Value >>= rSettings.mxGraphicRenderer;
468 : }
469 0 : else if ( pValues->Name == "StatusIndicator" )
470 : {
471 0 : pValues->Value >>= rSettings.mxStatusIndicator;
472 : }
473 0 : else if ( pValues->Name == "InteractionHandler" )
474 : {
475 0 : pValues->Value >>= rSettings.mxInteractionHandler;
476 : }
477 0 : else if( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Width" ) ) ) // for compatibility reasons, deprecated
478 : {
479 0 : pValues->Value >>= rSettings.mnWidth;
480 : }
481 0 : else if( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Height" ) ) ) // for compatibility reasons, deprecated
482 : {
483 0 : pValues->Value >>= rSettings.mnHeight;
484 : }
485 0 : else if( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ExportOnlyBackground" ) ) ) // for compatibility reasons, deprecated
486 : {
487 0 : pValues->Value >>= rSettings.mbExportOnlyBackground;
488 : }
489 0 : else if ( pValues->Name == "FilterData" )
490 : {
491 0 : pValues->Value >>= rSettings.maFilterData;
492 :
493 0 : sal_Int32 nFilterArgs = rSettings.maFilterData.getLength();
494 0 : PropertyValue* pDataValues = rSettings.maFilterData.getArray();
495 0 : while( nFilterArgs-- )
496 : {
497 0 : if ( pDataValues->Name == "Translucent" )
498 : {
499 0 : if ( !( pDataValues->Value >>= rSettings.mbTranslucent ) ) // SJ: TODO: The GIF Transparency is stored as int32 in
500 : { // configuration files, this has to be changed to boolean
501 0 : sal_Int32 nTranslucent = 0;
502 0 : if ( pDataValues->Value >>= nTranslucent )
503 0 : rSettings.mbTranslucent = nTranslucent != 0;
504 : }
505 : }
506 0 : else if ( pDataValues->Name == "PixelWidth" )
507 : {
508 0 : pDataValues->Value >>= rSettings.mnWidth;
509 : }
510 0 : else if ( pDataValues->Name == "PixelHeight" )
511 : {
512 0 : pDataValues->Value >>= rSettings.mnHeight;
513 : }
514 0 : else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Width" ) ) ) // for compatibility reasons, deprecated
515 : {
516 0 : pDataValues->Value >>= rSettings.mnWidth;
517 0 : pDataValues->Name = OUString( "PixelWidth" );
518 : }
519 0 : else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Height" ) ) ) // for compatibility reasons, deprecated
520 : {
521 0 : pDataValues->Value >>= rSettings.mnHeight;
522 0 : pDataValues->Name = OUString( "PixelHeight" );
523 : }
524 0 : else if ( pDataValues->Name == "ExportOnlyBackground" )
525 : {
526 0 : pDataValues->Value >>= rSettings.mbExportOnlyBackground;
527 : }
528 0 : else if ( pDataValues->Name == "HighContrast" )
529 : {
530 0 : pDataValues->Value >>= rSettings.mbUseHighContrast;
531 : }
532 0 : else if ( pDataValues->Name == "PageNumber" )
533 : {
534 0 : pDataValues->Value >>= mnPageNumber;
535 : }
536 0 : else if ( pDataValues->Name == "ScrollText" )
537 : {
538 : // #110496# Read flag solitary scroll text metafile
539 0 : pDataValues->Value >>= rSettings.mbScrollText;
540 : }
541 0 : else if ( pDataValues->Name == "CurrentPage" )
542 : {
543 0 : Reference< XDrawPage > xPage;
544 0 : pDataValues->Value >>= xPage;
545 0 : if( xPage.is() )
546 : {
547 0 : SvxDrawPage* pUnoPage = SvxDrawPage::getImplementation( xPage );
548 0 : if( pUnoPage && pUnoPage->GetSdrPage() )
549 0 : mpCurrentPage = pUnoPage->GetSdrPage();
550 0 : }
551 : }
552 0 : else if ( pDataValues->Name == "ScaleXNumerator" )
553 : {
554 0 : sal_Int32 nVal = 1;
555 0 : if( pDataValues->Value >>= nVal )
556 0 : rSettings.maScaleX = Fraction( nVal, rSettings.maScaleX.GetDenominator() );
557 : }
558 0 : else if ( pDataValues->Name == "ScaleXDenominator" )
559 : {
560 0 : sal_Int32 nVal = 1;
561 0 : if( pDataValues->Value >>= nVal )
562 0 : rSettings.maScaleX = Fraction( rSettings.maScaleX.GetNumerator(), nVal );
563 : }
564 0 : else if ( pDataValues->Name == "ScaleYNumerator" )
565 : {
566 0 : sal_Int32 nVal = 1;
567 0 : if( pDataValues->Value >>= nVal )
568 0 : rSettings.maScaleY = Fraction( nVal, rSettings.maScaleY.GetDenominator() );
569 : }
570 0 : else if ( pDataValues->Name == "ScaleYDenominator" )
571 : {
572 0 : sal_Int32 nVal = 1;
573 0 : if( pDataValues->Value >>= nVal )
574 0 : rSettings.maScaleY = Fraction( rSettings.maScaleY.GetNumerator(), nVal );
575 : }
576 :
577 0 : pDataValues++;
578 : }
579 : }
580 :
581 0 : pValues++;
582 : }
583 :
584 : // putting the StatusIndicator that we got from the MediaDescriptor into our local FilterData copy
585 0 : if ( rSettings.mxStatusIndicator.is() )
586 : {
587 0 : OUString sStatusIndicator( "StatusIndicator" );
588 0 : int i = rSettings.maFilterData.getLength();
589 0 : rSettings.maFilterData.realloc( i + 1 );
590 0 : rSettings.maFilterData[ i ].Name = sStatusIndicator;
591 0 : rSettings.maFilterData[ i ].Value <<= rSettings.mxStatusIndicator;
592 : }
593 0 : }
594 :
595 0 : bool GraphicExporter::GetGraphic( ExportSettings& rSettings, Graphic& aGraphic, sal_Bool bVectorType )
596 : {
597 : RTL_LOGFILE_CONTEXT( aLog, "UnoGraphicExporter::GetGraphic (thb)" );
598 :
599 0 : if( !mpDoc || !mpUnoPage )
600 0 : return false;
601 :
602 0 : SdrPage* pPage = mpUnoPage->GetSdrPage();
603 0 : if( !pPage )
604 0 : return false;
605 :
606 0 : VirtualDevice aVDev;
607 0 : const MapMode aMap( mpDoc->GetScaleUnit(), Point(), rSettings.maScaleX, rSettings.maScaleY );
608 :
609 0 : SdrOutliner& rOutl=mpDoc->GetDrawOutliner(NULL);
610 0 : maOldCalcFieldValueHdl = rOutl.GetCalcFieldValueHdl();
611 0 : rOutl.SetCalcFieldValueHdl( LINK(this, GraphicExporter, CalcFieldValueHdl) );
612 0 : rOutl.SetBackgroundColor( pPage->GetPageBackgroundColor() );
613 :
614 : // #i102251#
615 0 : const sal_uInt32 nOldCntrl(rOutl.GetControlWord());
616 0 : sal_uInt32 nCntrl = nOldCntrl & ~EE_CNTRL_ONLINESPELLING;
617 0 : rOutl.SetControlWord(nCntrl);
618 :
619 0 : SdrObject* pTempBackgroundShape = 0;
620 0 : std::vector< SdrObject* > aShapes;
621 0 : bool bRet = true;
622 :
623 : // export complete page?
624 0 : if ( !mxShape.is() )
625 : {
626 0 : if( rSettings.mbExportOnlyBackground )
627 : {
628 0 : const SdrPageProperties* pCorrectProperties = pPage->getCorrectSdrPageProperties();
629 :
630 0 : if(pCorrectProperties)
631 : {
632 0 : pTempBackgroundShape = new SdrRectObj(Rectangle(Point(0,0), pPage->GetSize()));
633 0 : pTempBackgroundShape->SetMergedItemSet(pCorrectProperties->GetItemSet());
634 0 : pTempBackgroundShape->SetMergedItem(XLineStyleItem(XLINE_NONE));
635 0 : pTempBackgroundShape->NbcSetStyleSheet(pCorrectProperties->GetStyleSheet(), true);
636 0 : aShapes.push_back(pTempBackgroundShape);
637 : }
638 : }
639 : else
640 : {
641 0 : const Size aSize( pPage->GetSize() );
642 :
643 : // generate a bitmap to convert it to a pixel format.
644 : // For gif pictures there can also be a vector format used (bTranslucent)
645 0 : if ( !bVectorType && !rSettings.mbTranslucent )
646 : {
647 0 : long nWidthPix = 0;
648 0 : long nHeightPix = 0;
649 0 : if ( rSettings.mnWidth > 0 && rSettings.mnHeight > 0 )
650 : {
651 0 : nWidthPix = rSettings.mnWidth;
652 0 : nHeightPix = rSettings.mnHeight;
653 : }
654 : else
655 : {
656 0 : const Size aSizePix( Application::GetDefaultDevice()->LogicToPixel( aSize, aMap ) );
657 0 : if (aSizePix.Width() > MAX_EXT_PIX || aSizePix.Height() > MAX_EXT_PIX)
658 : {
659 0 : if (aSizePix.Width() > MAX_EXT_PIX)
660 0 : nWidthPix = MAX_EXT_PIX;
661 : else
662 0 : nWidthPix = aSizePix.Width();
663 0 : if (aSizePix.Height() > MAX_EXT_PIX)
664 0 : nHeightPix = MAX_EXT_PIX;
665 : else
666 0 : nHeightPix = aSizePix.Height();
667 :
668 0 : double fWidthDif = aSizePix.Width() / nWidthPix;
669 0 : double fHeightDif = aSizePix.Height() / nHeightPix;
670 :
671 0 : if (fWidthDif > fHeightDif)
672 0 : nHeightPix = static_cast<long>(aSizePix.Height() / fWidthDif);
673 : else
674 0 : nWidthPix = static_cast<long>(aSizePix.Width() / fHeightDif);
675 : }
676 : else
677 : {
678 0 : nWidthPix = aSizePix.Width();
679 0 : nHeightPix = aSizePix.Height();
680 : }
681 : }
682 :
683 0 : boost::scoped_ptr< SdrView > pLocalView;
684 0 : if( PTR_CAST( FmFormModel, mpDoc ) )
685 : {
686 0 : pLocalView.reset( new FmFormView( PTR_CAST( FmFormModel, mpDoc ), &aVDev ) );
687 : }
688 : else
689 : {
690 0 : pLocalView.reset( new SdrView( mpDoc, &aVDev ) );
691 : }
692 :
693 :
694 0 : VirtualDevice* pVDev = CreatePageVDev( pPage, nWidthPix, nHeightPix );
695 :
696 0 : if( pVDev )
697 : {
698 0 : aGraphic = pVDev->GetBitmap( Point(), pVDev->GetOutputSize() );
699 0 : aGraphic.SetPrefMapMode( aMap );
700 0 : aGraphic.SetPrefSize( aSize );
701 0 : delete pVDev;
702 0 : }
703 : }
704 : // create a metafile to export a vector format
705 : else
706 : {
707 0 : GDIMetaFile aMtf;
708 :
709 0 : aVDev.SetMapMode( aMap );
710 0 : if( rSettings.mbUseHighContrast )
711 0 : aVDev.SetDrawMode( aVDev.GetDrawMode() | DRAWMODE_SETTINGSLINE | DRAWMODE_SETTINGSFILL | DRAWMODE_SETTINGSTEXT | DRAWMODE_SETTINGSGRADIENT );
712 0 : aVDev.EnableOutput( sal_False );
713 0 : aMtf.Record( &aVDev );
714 0 : Size aNewSize;
715 :
716 : // create a view
717 0 : boost::scoped_ptr< SdrView > pView;
718 0 : if( PTR_CAST( FmFormModel, mpDoc ) )
719 : {
720 0 : pView.reset(new FmFormView( PTR_CAST( FmFormModel, mpDoc ), &aVDev ));
721 : }
722 : else
723 : {
724 0 : pView.reset(new SdrView( mpDoc, &aVDev ));
725 : }
726 :
727 0 : pView->SetBordVisible( sal_False );
728 0 : pView->SetPageVisible( sal_False );
729 0 : pView->ShowSdrPage( pPage );
730 :
731 0 : const Point aNewOrg( pPage->GetLftBorder(), pPage->GetUppBorder() );
732 0 : aNewSize = Size( aSize.Width() - pPage->GetLftBorder() - pPage->GetRgtBorder(),
733 0 : aSize.Height() - pPage->GetUppBorder() - pPage->GetLwrBorder() );
734 0 : const Rectangle aClipRect( aNewOrg, aNewSize );
735 0 : MapMode aVMap( aMap );
736 :
737 0 : aVDev.Push();
738 0 : aVMap.SetOrigin( Point( -aNewOrg.X(), -aNewOrg.Y() ) );
739 0 : aVDev.SetRelativeMapMode( aVMap );
740 0 : aVDev.IntersectClipRegion( aClipRect );
741 :
742 : // Use new StandardCheckVisisbilityRedirector
743 0 : ImplExportCheckVisisbilityRedirector aRedirector( mpCurrentPage );
744 :
745 0 : pView->CompleteRedraw(&aVDev, Region(Rectangle(Point(), aNewSize)), &aRedirector);
746 :
747 0 : aVDev.Pop();
748 :
749 0 : aMtf.Stop();
750 0 : aMtf.WindStart();
751 0 : aMtf.SetPrefMapMode( aMap );
752 0 : aMtf.SetPrefSize( aNewSize );
753 :
754 : // AW: Here the current version was filtering out the META_CLIPREGION_ACTIONs
755 : // from the metafile. I asked some other developers why this was done, but no
756 : // one knew a direct reason. Since it's in for long time, it may be an old
757 : // piece of code. MetaFiles save and load ClipRegions with polygons with preserving
758 : // the polygons, so a resolution-indepent roundtrip is supported. Removed this
759 : // code since it destroys some MetaFiles where ClipRegions are used. Anyways,
760 : // just filtering them out is a hack, at least the encapsulated content would need
761 : // to be clipped geometrically.
762 0 : aGraphic = Graphic(aMtf);
763 :
764 0 : pView->HideSdrPage();
765 :
766 0 : if( rSettings.mbTranslucent )
767 : {
768 0 : Size aOutSize;
769 0 : aGraphic = GetBitmapFromMetaFile( aGraphic.GetGDIMetaFile(), sal_True, CalcSize( rSettings.mnWidth, rSettings.mnHeight, aNewSize, aOutSize ) );
770 0 : }
771 : }
772 : }
773 : }
774 :
775 : // export only single shape or shape collection
776 : else
777 : {
778 : // build list of SdrObject
779 0 : if( mxShapes.is() )
780 : {
781 0 : Reference< XShape > xShape;
782 0 : const sal_Int32 nCount = mxShapes->getCount();
783 :
784 0 : for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
785 : {
786 0 : mxShapes->getByIndex( nIndex ) >>= xShape;
787 0 : SdrObject* pObj = GetSdrObjectFromXShape( xShape );
788 0 : if( pObj )
789 0 : aShapes.push_back( pObj );
790 0 : }
791 : }
792 : else
793 : {
794 : // only one shape
795 0 : SdrObject* pObj = GetSdrObjectFromXShape( mxShape );
796 0 : if( pObj )
797 0 : aShapes.push_back( pObj );
798 : }
799 :
800 0 : if( aShapes.empty() )
801 0 : bRet = false;
802 : }
803 :
804 0 : if( bRet && !aShapes.empty() )
805 : {
806 : // special treatment for only one SdrGrafObj that has text
807 0 : bool bSingleGraphic = false;
808 :
809 0 : if( 1 == aShapes.size() )
810 : {
811 0 : if( !bVectorType )
812 : {
813 0 : SdrObject* pObj = aShapes.front();
814 0 : if( pObj && pObj->ISA( SdrGrafObj ) && !( (SdrGrafObj*) pObj )->HasText() )
815 : {
816 0 : aGraphic = ( (SdrGrafObj*) pObj )->GetTransformedGraphic();
817 0 : if ( aGraphic.GetType() == GRAPHIC_BITMAP )
818 : {
819 0 : Size aSizePixel( aGraphic.GetSizePixel() );
820 0 : if( rSettings.mnWidth && rSettings.mnHeight &&
821 0 : ( ( rSettings.mnWidth != aSizePixel.Width() ) ||
822 0 : ( rSettings.mnHeight != aSizePixel.Height() ) ) )
823 : {
824 0 : BitmapEx aBmpEx( aGraphic.GetBitmapEx() );
825 : // export: use highest quality
826 0 : aBmpEx.Scale( Size( rSettings.mnWidth, rSettings.mnHeight ), BMP_SCALE_LANCZOS );
827 0 : aGraphic = aBmpEx;
828 : }
829 :
830 : // #118804# only accept for bitmap graphics, else the
831 : // conversion to bitmap will happen anywhere without size control
832 : // as evtl. defined in rSettings.mnWidth/mnHeight
833 0 : bSingleGraphic = true;
834 : }
835 : }
836 : }
837 0 : else if( rSettings.mbScrollText )
838 : {
839 0 : SdrObject* pObj = aShapes.front();
840 0 : if( pObj && pObj->ISA( SdrTextObj )
841 0 : && ( (SdrTextObj*) pObj )->HasText() )
842 : {
843 0 : Rectangle aScrollRectangle;
844 0 : Rectangle aPaintRectangle;
845 :
846 : const boost::scoped_ptr< GDIMetaFile > pMtf(
847 : ( (SdrTextObj*) pObj )->GetTextScrollMetaFileAndRectangle(
848 0 : aScrollRectangle, aPaintRectangle ) );
849 :
850 : // take the larger one of the two rectangles (that
851 : // should be the bound rect of the retrieved
852 : // metafile)
853 0 : Rectangle aTextRect;
854 :
855 0 : if( aScrollRectangle.IsInside( aPaintRectangle ) )
856 0 : aTextRect = aScrollRectangle;
857 : else
858 0 : aTextRect = aPaintRectangle;
859 :
860 : // setup pref size and mapmode
861 0 : pMtf->SetPrefSize( aTextRect.GetSize() );
862 :
863 : // set actual origin (mtf is at actual shape
864 : // output position)
865 0 : MapMode aLocalMapMode( aMap );
866 : aLocalMapMode.SetOrigin(
867 0 : Point( -aPaintRectangle.Left(),
868 0 : -aPaintRectangle.Top() ) );
869 0 : pMtf->SetPrefMapMode( aLocalMapMode );
870 :
871 : pMtf->AddAction( new MetaCommentAction(
872 : "XTEXT_SCROLLRECT", 0,
873 : reinterpret_cast<sal_uInt8 const*>(&aScrollRectangle),
874 0 : sizeof( Rectangle ) ) );
875 : pMtf->AddAction( new MetaCommentAction(
876 : "XTEXT_PAINTRECT", 0,
877 : reinterpret_cast<sal_uInt8 const*>(&aPaintRectangle),
878 0 : sizeof( Rectangle ) ) );
879 :
880 0 : aGraphic = Graphic( *pMtf );
881 :
882 0 : bSingleGraphic = true;
883 : }
884 : }
885 : }
886 :
887 0 : if( !bSingleGraphic )
888 : {
889 : // create a metafile for all shapes
890 0 : VirtualDevice aOut;
891 :
892 : // calculate bound rect for all shapes
893 0 : Rectangle aBound;
894 :
895 : {
896 0 : std::vector< SdrObject* >::iterator aIter = aShapes.begin();
897 0 : const std::vector< SdrObject* >::iterator aEnd = aShapes.end();
898 :
899 0 : while( aIter != aEnd )
900 : {
901 0 : SdrObject* pObj = (*aIter++);
902 0 : Rectangle aR1(pObj->GetCurrentBoundRect());
903 0 : if (aBound.IsEmpty())
904 0 : aBound=aR1;
905 : else
906 0 : aBound.Union(aR1);
907 : }
908 : }
909 :
910 0 : aOut.EnableOutput( sal_False );
911 0 : aOut.SetMapMode( aMap );
912 0 : if( rSettings.mbUseHighContrast )
913 0 : aOut.SetDrawMode( aVDev.GetDrawMode() | DRAWMODE_SETTINGSLINE | DRAWMODE_SETTINGSFILL | DRAWMODE_SETTINGSTEXT | DRAWMODE_SETTINGSGRADIENT );
914 :
915 0 : GDIMetaFile aMtf;
916 0 : aMtf.Clear();
917 0 : aMtf.Record( &aOut );
918 :
919 0 : MapMode aOutMap( aMap );
920 0 : aOutMap.SetOrigin( Point( -aBound.TopLeft().X(), -aBound.TopLeft().Y() ) );
921 0 : aOut.SetRelativeMapMode( aOutMap );
922 :
923 0 : sdr::contact::DisplayInfo aDisplayInfo;
924 :
925 0 : if(mpCurrentPage)
926 : {
927 0 : if(mpCurrentPage->TRG_HasMasterPage() && pPage->IsMasterPage())
928 : {
929 : // MasterPage is processed as another page's SubContent
930 0 : aDisplayInfo.SetProcessLayers(mpCurrentPage->TRG_GetMasterPageVisibleLayers());
931 0 : aDisplayInfo.SetSubContentActive(true);
932 : }
933 : }
934 :
935 0 : if(!aShapes.empty())
936 : {
937 : // more effective way to paint a vector of SdrObjects. Hand over the processed page
938 : // to have it in the
939 0 : sdr::contact::ObjectContactOfObjListPainter aMultiObjectPainter(aOut, aShapes, mpCurrentPage);
940 0 : ImplExportCheckVisisbilityRedirector aCheckVisibilityRedirector(mpCurrentPage);
941 0 : aMultiObjectPainter.SetViewObjectContactRedirector(&aCheckVisibilityRedirector);
942 :
943 0 : aMultiObjectPainter.ProcessDisplay(aDisplayInfo);
944 : }
945 :
946 0 : aMtf.Stop();
947 0 : aMtf.WindStart();
948 :
949 0 : const Size aExtSize( aOut.PixelToLogic( Size( 0, 0 ) ) );
950 0 : Size aBoundSize( aBound.GetWidth() + ( aExtSize.Width() ),
951 0 : aBound.GetHeight() + ( aExtSize.Height() ) );
952 :
953 0 : aMtf.SetPrefMapMode( aMap );
954 0 : aMtf.SetPrefSize( aBoundSize );
955 :
956 0 : if( !bVectorType )
957 : {
958 0 : Size aOutSize;
959 0 : aGraphic = GetBitmapFromMetaFile( aMtf, rSettings.mbTranslucent, CalcSize( rSettings.mnWidth, rSettings.mnHeight, aBoundSize, aOutSize ) );
960 : }
961 : else
962 : {
963 0 : aGraphic = aMtf;
964 0 : }
965 : }
966 : }
967 :
968 0 : if(pTempBackgroundShape)
969 : {
970 0 : SdrObject::Free(pTempBackgroundShape);
971 : }
972 :
973 0 : rOutl.SetCalcFieldValueHdl( maOldCalcFieldValueHdl );
974 :
975 : // #i102251#
976 0 : rOutl.SetControlWord(nOldCntrl);
977 :
978 0 : return bRet;
979 :
980 : }
981 :
982 : // XFilter
983 0 : sal_Bool SAL_CALL GraphicExporter::filter( const Sequence< PropertyValue >& aDescriptor )
984 : throw(RuntimeException)
985 : {
986 : RTL_LOGFILE_CONTEXT( aLog, "UnoGraphicExporter::export (thb)" );
987 :
988 0 : ::SolarMutexGuard aGuard;
989 :
990 0 : if( NULL == mpUnoPage )
991 0 : return sal_False;
992 :
993 0 : if( NULL == mpUnoPage->GetSdrPage() || NULL == mpDoc )
994 0 : return sal_False;
995 :
996 0 : GraphicFilter &rFilter = GraphicFilter::GetGraphicFilter();
997 :
998 : // get the arguments from the descriptor
999 0 : ExportSettings aSettings( mpDoc );
1000 0 : ParseSettings( aDescriptor, aSettings );
1001 :
1002 0 : const sal_uInt16 nFilter = !aSettings.maMediaType.isEmpty()
1003 0 : ? rFilter.GetExportFormatNumberForMediaType( aSettings.maMediaType )
1004 0 : : rFilter.GetExportFormatNumberForShortName( aSettings.maFilterName );
1005 0 : sal_Bool bVectorType = !rFilter.IsExportPixelFormat( nFilter );
1006 :
1007 : // create the output stuff
1008 0 : Graphic aGraphic;
1009 :
1010 0 : sal_uInt16 nStatus = GetGraphic( aSettings, aGraphic, bVectorType ) ? GRFILTER_OK : GRFILTER_FILTERERROR;
1011 :
1012 0 : if( nStatus == GRFILTER_OK )
1013 : {
1014 : // export graphic only if it has a size
1015 0 : const Size aGraphSize( aGraphic.GetPrefSize() );
1016 0 : if ( ( aGraphSize.Width() == 0 ) || ( aGraphSize.Height() == 0 ) )
1017 : {
1018 0 : nStatus = GRFILTER_FILTERERROR;
1019 : }
1020 : else
1021 : {
1022 : // now we have a graphic, so export it
1023 0 : if( aSettings.mxGraphicRenderer.is() )
1024 : {
1025 : // render graphic directly into given renderer
1026 0 : aSettings.mxGraphicRenderer->render( aGraphic.GetXGraphic() );
1027 : }
1028 0 : else if( aSettings.mxOutputStream.is() )
1029 : {
1030 : // TODO: Either utilize optional XSeekable functionality for the
1031 : // SvOutputStream, or adapt the graphic filter to not seek anymore.
1032 0 : SvMemoryStream aStream( 1024, 1024 );
1033 :
1034 0 : nStatus = rFilter.ExportGraphic( aGraphic, String(), aStream, nFilter, &aSettings.maFilterData );
1035 :
1036 : // copy temp stream to XOutputStream
1037 0 : SvOutputStream aOutputStream( aSettings.mxOutputStream );
1038 0 : aStream.Seek(0);
1039 0 : aOutputStream << aStream;
1040 : }
1041 : else
1042 : {
1043 0 : INetURLObject aURLObject( aSettings.maURL.Complete );
1044 : DBG_ASSERT( aURLObject.GetProtocol() != INET_PROT_NOT_VALID, "invalid URL" );
1045 :
1046 0 : nStatus = XOutBitmap::ExportGraphic( aGraphic, aURLObject, rFilter, nFilter, &aSettings.maFilterData );
1047 : }
1048 : }
1049 : }
1050 :
1051 0 : if ( aSettings.mxInteractionHandler.is() && ( nStatus != GRFILTER_OK ) )
1052 : {
1053 0 : Any aInteraction;
1054 0 : Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation > > lContinuations(1);
1055 0 : ::comphelper::OInteractionApprove* pApprove = new ::comphelper::OInteractionApprove();
1056 0 : lContinuations[0] = Reference< XInteractionContinuation >(static_cast< XInteractionContinuation* >(pApprove), UNO_QUERY);
1057 :
1058 0 : GraphicFilterRequest aErrorCode;
1059 0 : aErrorCode.ErrCode = nStatus;
1060 0 : aInteraction <<= aErrorCode;
1061 0 : aSettings.mxInteractionHandler->handle( framework::InteractionRequest::CreateRequest( aInteraction, lContinuations ) );
1062 : }
1063 0 : return nStatus == GRFILTER_OK;
1064 : }
1065 :
1066 0 : void SAL_CALL GraphicExporter::cancel()
1067 : throw(RuntimeException)
1068 : {
1069 0 : }
1070 :
1071 : // XExporter
1072 :
1073 : /** the source 'document' could be a XDrawPage, a XShape or a generic XShapes */
1074 0 : void SAL_CALL GraphicExporter::setSourceDocument( const Reference< lang::XComponent >& xComponent )
1075 : throw(IllegalArgumentException, RuntimeException)
1076 : {
1077 0 : ::SolarMutexGuard aGuard;
1078 :
1079 0 : mxShapes = NULL;
1080 0 : mpUnoPage = NULL;
1081 :
1082 : try
1083 : {
1084 : // any break inside this one loop while will throw a IllegalArgumentException
1085 : do
1086 : {
1087 0 : mxPage = Reference< XDrawPage >::query( xComponent );
1088 0 : mxShapes = Reference< XShapes >::query( xComponent );
1089 0 : mxShape = Reference< XShape >::query( xComponent );
1090 :
1091 : // Step 1: try a generic XShapes
1092 0 : if( !mxPage.is() && !mxShape.is() && mxShapes.is() )
1093 : {
1094 : // we do not support empty shape collections
1095 0 : if( 0 == mxShapes->getCount() )
1096 0 : break;
1097 :
1098 : // get first shape to detect corresponding page and model
1099 0 : mxShapes->getByIndex(0) >>= mxShape;
1100 : }
1101 : else
1102 : {
1103 0 : mxShapes = NULL;
1104 : }
1105 :
1106 : // Step 2: try a shape
1107 0 : if( mxShape.is() )
1108 : {
1109 0 : if( NULL == GetSdrObjectFromXShape( mxShape ) )
1110 0 : break;
1111 :
1112 : // get page for this shape
1113 0 : Reference< XChild > xChild( mxShape, UNO_QUERY );
1114 0 : if( !xChild.is() )
1115 0 : break;
1116 :
1117 0 : Reference< XInterface > xInt;
1118 0 : do
1119 : {
1120 0 : xInt = xChild->getParent();
1121 0 : mxPage = Reference< XDrawPage >::query( xInt );
1122 0 : if( !mxPage.is() )
1123 0 : xChild = Reference< XChild >::query( xInt );
1124 : }
1125 0 : while( !mxPage.is() && xChild.is() );
1126 :
1127 0 : if( !mxPage.is() )
1128 0 : break;
1129 : }
1130 :
1131 : // Step 3: check the page
1132 0 : if( !mxPage.is() )
1133 0 : break;
1134 :
1135 0 : mpUnoPage = SvxDrawPage::getImplementation( mxPage );
1136 :
1137 0 : if( NULL == mpUnoPage || NULL == mpUnoPage->GetSdrPage() )
1138 0 : break;
1139 :
1140 0 : mpDoc = mpUnoPage->GetSdrPage()->GetModel();
1141 :
1142 : // Step 4: If we got a generic XShapes test all contained shapes
1143 : // if they belong to the same XDrawPage
1144 :
1145 0 : if( mxShapes.is() )
1146 : {
1147 0 : SdrPage* pPage = mpUnoPage->GetSdrPage();
1148 : SdrObject* pObj;
1149 0 : Reference< XShape > xShape;
1150 :
1151 0 : bool bOk = true;
1152 :
1153 0 : const sal_Int32 nCount = mxShapes->getCount();
1154 :
1155 : // test all but the first shape if they have the same page than
1156 : // the first shape
1157 0 : for( sal_Int32 nIndex = 1; bOk && ( nIndex < nCount ); nIndex++ )
1158 : {
1159 0 : mxShapes->getByIndex( nIndex ) >>= xShape;
1160 0 : pObj = GetSdrObjectFromXShape( xShape );
1161 0 : bOk = pObj && pObj->GetPage() == pPage;
1162 : }
1163 :
1164 0 : if( !bOk )
1165 0 : break;
1166 : }
1167 :
1168 : // no errors so far
1169 0 : return;
1170 : }
1171 : while( 0 );
1172 : }
1173 0 : catch( Exception& )
1174 : {
1175 : }
1176 :
1177 0 : throw IllegalArgumentException();
1178 : }
1179 :
1180 : // XServiceInfo
1181 0 : OUString SAL_CALL GraphicExporter::getImplementationName( )
1182 : throw(RuntimeException)
1183 : {
1184 0 : return GraphicExporter_getImplementationName();
1185 : }
1186 :
1187 0 : sal_Bool SAL_CALL GraphicExporter::supportsService( const OUString& ServiceName )
1188 : throw(RuntimeException)
1189 : {
1190 0 : Sequence< OUString > aSeq( GraphicExporter_getSupportedServiceNames() );
1191 0 : sal_Int32 nArgs = aSeq.getLength();
1192 0 : const OUString* pService = aSeq.getConstArray();
1193 0 : while( nArgs-- )
1194 0 : if( *pService++ == ServiceName )
1195 0 : return sal_True;
1196 :
1197 0 : return sal_False;
1198 : }
1199 :
1200 0 : Sequence< OUString > SAL_CALL GraphicExporter::getSupportedServiceNames( )
1201 : throw(RuntimeException)
1202 : {
1203 0 : return GraphicExporter_getSupportedServiceNames();
1204 : }
1205 :
1206 : // XMimeTypeInfo
1207 0 : sal_Bool SAL_CALL GraphicExporter::supportsMimeType( const OUString& MimeTypeName ) throw (RuntimeException)
1208 : {
1209 0 : const String aMimeTypeName( MimeTypeName );
1210 :
1211 0 : GraphicFilter &rFilter = GraphicFilter::GetGraphicFilter();
1212 0 : sal_uInt16 nCount = rFilter.GetExportFormatCount();
1213 : sal_uInt16 nFilter;
1214 0 : for( nFilter = 0; nFilter < nCount; nFilter++ )
1215 : {
1216 0 : if( aMimeTypeName.Equals( rFilter.GetExportFormatMediaType( nFilter ) ) )
1217 : {
1218 0 : return sal_True;
1219 : }
1220 : }
1221 :
1222 0 : return sal_False;
1223 : }
1224 :
1225 0 : Sequence< OUString > SAL_CALL GraphicExporter::getSupportedMimeTypeNames( ) throw (RuntimeException)
1226 : {
1227 0 : GraphicFilter &rFilter = GraphicFilter::GetGraphicFilter();
1228 0 : sal_uInt16 nCount = rFilter.GetExportFormatCount();
1229 : sal_uInt16 nFilter;
1230 0 : sal_uInt16 nFound = 0;
1231 :
1232 0 : Sequence< OUString > aSeq( nCount );
1233 0 : OUString* pStr = aSeq.getArray();
1234 :
1235 0 : for( nFilter = 0; nFilter < nCount; nFilter++ )
1236 : {
1237 0 : OUString aMimeType( rFilter.GetExportFormatMediaType( nFilter ) );
1238 0 : if( !aMimeType.isEmpty() )
1239 : {
1240 0 : *pStr++ = aMimeType;
1241 0 : nFound++;
1242 : }
1243 0 : }
1244 :
1245 0 : if( nFound < nCount )
1246 0 : aSeq.realloc( nFound );
1247 :
1248 0 : return aSeq;
1249 : }
1250 :
1251 0 : Graphic SvxGetGraphicForShape( SdrObject& rShape, bool bVector )
1252 : {
1253 0 : Graphic aGraphic;
1254 : try
1255 : {
1256 0 : rtl::Reference< GraphicExporter > xExporter( new GraphicExporter() );
1257 0 : Reference< XComponent > xComp( rShape.getUnoShape(), UNO_QUERY_THROW );
1258 0 : xExporter->setSourceDocument( xComp );
1259 0 : ExportSettings aSettings( rShape.GetModel() );
1260 0 : xExporter->GetGraphic( aSettings, aGraphic, bVector );
1261 : }
1262 0 : catch( Exception& )
1263 : {
1264 : OSL_FAIL("SvxGetGraphicForShape(), exception caught!");
1265 : }
1266 0 : return aGraphic;
1267 258 : }
1268 :
1269 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|