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