1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "impoptimizer.hxx"
22 #include "pppoptimizer.hxx"
23 #include "graphiccollector.hxx"
24 #include "pagecollector.hxx"
25 #include "informationdialog.hxx"
28 #include "com/sun/star/util/URL.hpp"
29 #include "com/sun/star/util/XURLTransformer.hpp"
30 #include <com/sun/star/beans/XPropertySet.hpp>
31 #include <com/sun/star/awt/Rectangle.hpp>
32 #include <com/sun/star/awt/Size.hpp>
33 #include <com/sun/star/util/MeasureUnit.hpp>
34 #include <com/sun/star/frame/XModel.hpp>
35 #include <com/sun/star/frame/Desktop.hpp>
36 #include <com/sun/star/awt/XWindow.hpp>
37 #include <com/sun/star/frame/XStorable.hpp>
38 #include <com/sun/star/frame/FrameSearchFlag.hpp>
39 #include <com/sun/star/frame/XDispatchProvider.hpp>
40 #include <com/sun/star/graphic/GraphicProvider.hpp>
41 #include <com/sun/star/graphic/XGraphicProvider.hpp>
42 #include <com/sun/star/lang/XServiceInfo.hpp>
43 #include <com/sun/star/container/XNamed.hpp>
44 #include <com/sun/star/drawing/XShapes.hpp>
45 #include <com/sun/star/drawing/XMasterPageTarget.hpp>
46 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
47 #include <com/sun/star/drawing/XMasterPagesSupplier.hpp>
48 #include <com/sun/star/presentation/XPresentationSupplier.hpp>
49 #include <com/sun/star/container/XNameAccess.hpp>
50 #include <com/sun/star/presentation/XPresentation.hpp>
51 #include <com/sun/star/presentation/XPresentationPage.hpp>
52 #include <com/sun/star/document/XFilter.hpp>
53 #include <com/sun/star/document/XExporter.hpp>
54 #include <com/sun/star/uno/RuntimeException.hpp>
55 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
56 #include <com/sun/star/graphic/GraphicType.hpp>
57 #include <com/sun/star/io/XStream.hpp>
58 #include <com/sun/star/io/XSeekable.hpp>
59 #include <com/sun/star/io/TempFile.hpp>
60 #include <com/sun/star/frame/XComponentLoader.hpp>
61 #include <com/sun/star/util/URLTransformer.hpp>
63 using namespace ::std
;
64 using namespace ::com::sun::star
;
65 using namespace ::com::sun::star::io
;
66 using namespace ::com::sun::star::awt
;
67 using namespace ::com::sun::star::uno
;
68 using namespace ::com::sun::star::lang
;
69 using namespace ::com::sun::star::util
;
70 using namespace ::com::sun::star::frame
;
71 using namespace ::com::sun::star::beans
;
72 using namespace ::com::sun::star::drawing
;
73 using namespace ::com::sun::star::graphic
;
74 using namespace ::com::sun::star::document
;
75 using namespace ::com::sun::star::container
;
76 using namespace ::com::sun::star::presentation
;
78 void ImpExtractCustomShow( const Reference
< XModel
>& rxModel
, const OUString
& rCustomShowName
)
80 vector
< Reference
< XDrawPage
> > vNonUsedPageList
;
83 PageCollector::CollectNonCustomShowPages( rxModel
, rCustomShowName
, vNonUsedPageList
);
84 Reference
< XDrawPagesSupplier
> xDrawPagesSupplier( rxModel
, UNO_QUERY_THROW
);
85 Reference
< XDrawPages
> xDrawPages( xDrawPagesSupplier
->getDrawPages(), UNO_QUERY_THROW
);
86 vector
< Reference
< XDrawPage
> >::iterator
aIter( vNonUsedPageList
.begin() );
87 while( aIter
!= vNonUsedPageList
.end() )
88 xDrawPages
->remove( *aIter
++ );
96 void ImpDeleteUnusedMasterPages( const Reference
< XModel
>& rxModel
)
98 vector
< PageCollector::MasterPageEntity
> aMasterPageList
;
99 PageCollector::CollectMasterPages( rxModel
, aMasterPageList
);
101 // now master pages that are not marked can be deleted
102 Reference
< XMasterPagesSupplier
> xMasterPagesSupplier( rxModel
, UNO_QUERY_THROW
);
103 Reference
< XDrawPages
> xMasterPages( xMasterPagesSupplier
->getMasterPages(), UNO_QUERY_THROW
);
104 vector
< PageCollector::MasterPageEntity
>::iterator
aIter( aMasterPageList
.begin() );
105 while( aIter
!= aMasterPageList
.end() )
108 xMasterPages
->remove( aIter
->xMasterPage
);
113 void ImpDeleteHiddenSlides( const Reference
< XModel
>& rxModel
)
117 Reference
< XDrawPagesSupplier
> xDrawPagesSupplier( rxModel
, UNO_QUERY_THROW
);
118 Reference
< XDrawPages
> xDrawPages( xDrawPagesSupplier
->getDrawPages(), UNO_QUERY_THROW
);
119 for( sal_Int32 i
= 0; i
< xDrawPages
->getCount(); i
++ )
121 Reference
< XDrawPage
> xDrawPage( xDrawPages
->getByIndex( i
), UNO_QUERY_THROW
);
122 Reference
< XPropertySet
> xPropSet( xDrawPage
, UNO_QUERY_THROW
);
124 bool bVisible
= true;
125 const OUString
sVisible( "Visible" );
126 if ( xPropSet
->getPropertyValue( sVisible
) >>= bVisible
)
130 xDrawPages
->remove( xDrawPage
);
141 void ImpDeleteNotesPages( const Reference
< XModel
>& rxModel
)
145 Reference
< XDrawPagesSupplier
> xDrawPagesSupplier( rxModel
, UNO_QUERY_THROW
);
146 Reference
< XDrawPages
> xDrawPages( xDrawPagesSupplier
->getDrawPages(), UNO_QUERY_THROW
);
147 sal_Int32 i
, nPages
= xDrawPages
->getCount();
148 for( i
= 0; i
< nPages
; i
++ )
150 Reference
< XPresentationPage
> xPresentationPage( xDrawPages
->getByIndex( i
), UNO_QUERY_THROW
);
151 Reference
< XPropertySet
> xPropSet( xPresentationPage
->getNotesPage(), UNO_QUERY_THROW
);
152 Reference
< XShapes
> xShapes( xPropSet
, UNO_QUERY_THROW
);
153 while( xShapes
->getCount() )
154 xShapes
->remove( Reference
< XShape
>( xShapes
->getByIndex( xShapes
->getCount() - 1 ), UNO_QUERY_THROW
) );
156 const OUString
sLayout( "Layout" );
157 xPropSet
->setPropertyValue( sLayout
, Any( (sal_Int16
)21 ) );
165 void ImpConvertOLE( const Reference
< XModel
>& rxModel
, sal_Int32 nOLEOptimizationType
)
169 Reference
< XDrawPagesSupplier
> xDrawPagesSupplier( rxModel
, UNO_QUERY_THROW
);
170 Reference
< XDrawPages
> xDrawPages( xDrawPagesSupplier
->getDrawPages(), UNO_QUERY_THROW
);
171 for ( sal_Int32 i
= 0; i
< xDrawPages
->getCount(); i
++ )
173 Reference
< XShapes
> xShapes( xDrawPages
->getByIndex( i
), UNO_QUERY_THROW
);
174 for ( sal_Int32 j
= 0; j
< xShapes
->getCount(); j
++ )
176 const OUString
sOLE2Shape( "com.sun.star.drawing.OLE2Shape" );
177 Reference
< XShape
> xShape( xShapes
->getByIndex( j
), UNO_QUERY_THROW
);
178 if ( xShape
->getShapeType() == sOLE2Shape
)
180 Reference
< XPropertySet
> xPropSet( xShape
, UNO_QUERY_THROW
);
182 bool bConvertOLE
= nOLEOptimizationType
== 0;
183 if ( nOLEOptimizationType
== 1 )
185 bool bIsInternal
= true;
186 xPropSet
->getPropertyValue( "IsInternal" ) >>= bIsInternal
;
187 bConvertOLE
= !bIsInternal
;
191 Reference
< XGraphic
> xGraphic
;
192 if ( xPropSet
->getPropertyValue( "Graphic" ) >>= xGraphic
)
194 const OUString
sGraphicShape( "com.sun.star.drawing.GraphicObjectShape" );
195 Reference
< XMultiServiceFactory
> xFact( rxModel
, UNO_QUERY_THROW
);
196 Reference
< XShape
> xShape2( xFact
->createInstance( sGraphicShape
), UNO_QUERY_THROW
);
197 xShapes
->add( xShape2
);
198 xShape2
->setPosition( xShape
->getPosition() );
199 xShape2
->setSize( xShape
->getSize() );
200 Reference
< XPropertySet
> xPropSet2( xShape2
, UNO_QUERY_THROW
);
201 xPropSet2
->setPropertyValue( "Graphic", Any( xGraphic
) );
202 xShapes
->remove( xShape
);
203 xPropSet2
->setPropertyValue( "ZOrder", Any( j
) );
215 void ImpCompressGraphic( Reference
< XGraphicProvider
>& rxGraphicProvider
, const Reference
< XGraphic
>& rxGraphic
, Reference
< XOutputStream
>& rxOutputStream
,
216 const OUString
& rDestMimeType
, const awt::Size
& rLogicalSize
, sal_Int32 nJPEGQuality
, sal_Int32 nImageResolution
, bool bRemoveCropping
, const text::GraphicCrop
& rGraphicCropLogic
)
220 if ( rxGraphicProvider
.is() && rxOutputStream
.is() )
222 Sequence
< PropertyValue
> aFilterData( 8 );
223 aFilterData
[ 0 ].Name
= "ImageResolution";
224 aFilterData
[ 0 ].Value
<<= nImageResolution
;
225 aFilterData
[ 1 ].Name
= "ColorMode"; // todo: jpeg color mode (0->true color, 1->greyscale)
226 aFilterData
[ 1 ].Value
<<= (sal_Int32
)0;
227 aFilterData
[ 2 ].Name
= "Quality"; // quality that is used if we export to jpeg
228 aFilterData
[ 2 ].Value
<<= nJPEGQuality
;
229 aFilterData
[ 3 ].Name
= "Compression"; // compression that is used if we export to png
230 aFilterData
[ 3 ].Value
<<= (sal_Int32
)6;
231 aFilterData
[ 4 ].Name
= "Interlaced"; // interlaced is turned off if we export to png
232 aFilterData
[ 4 ].Value
<<= (sal_Int32
)0;
233 aFilterData
[ 5 ].Name
= "LogicalSize";
234 aFilterData
[ 5 ].Value
<<= rLogicalSize
;
235 aFilterData
[ 6 ].Name
= "RemoveCropArea";
236 aFilterData
[ 6 ].Value
<<= bRemoveCropping
;
237 aFilterData
[ 7 ].Name
= "GraphicCropLogic";
238 aFilterData
[ 7 ].Value
<<= rGraphicCropLogic
;
240 Sequence
< PropertyValue
> aArgs( 3 );
241 aArgs
[ 0 ].Name
= "MimeType"; // the GraphicProvider is using "MimeType", the GraphicExporter "MediaType"...
242 aArgs
[ 0 ].Value
<<= rDestMimeType
;
243 aArgs
[ 1 ].Name
= "OutputStream";
244 aArgs
[ 1 ].Value
<<= rxOutputStream
;
245 aArgs
[ 2 ].Name
= "FilterData";
246 aArgs
[ 2 ].Value
<<= aFilterData
;
248 rxGraphicProvider
->storeGraphic( rxGraphic
, aArgs
);
256 Reference
< XGraphic
> ImpCompressGraphic( const Reference
< XComponentContext
>& rxContext
,
257 const Reference
< XGraphic
>& xGraphic
, const awt::Size
& aLogicalSize
, const text::GraphicCrop
& aGraphicCropLogic
,
258 const GraphicSettings
& rGraphicSettings
)
260 Reference
< XGraphic
> xNewGraphic
;
263 OUString aSourceMimeType
;
264 Reference
< XPropertySet
> xGraphicPropertySet( xGraphic
, UNO_QUERY_THROW
);
265 if ( xGraphicPropertySet
->getPropertyValue( "MimeType" ) >>= aSourceMimeType
)
267 sal_Int8
nGraphicType( xGraphic
->getType() );
268 if ( nGraphicType
== com::sun::star::graphic::GraphicType::PIXEL
)
270 bool bTransparent
= false;
272 bool bAnimated
= false;
274 awt::Size
aSourceSizePixel( 0, 0 );
275 text::GraphicCrop
aGraphicCropPixel( 0, 0, 0, 0 );
277 if ( ( xGraphicPropertySet
->getPropertyValue( "SizePixel" ) >>= aSourceSizePixel
) &&
278 ( xGraphicPropertySet
->getPropertyValue( "Transparent" ) >>= bTransparent
) &&
279 ( xGraphicPropertySet
->getPropertyValue( "Alpha" ) >>= bAlpha
) &&
280 ( xGraphicPropertySet
->getPropertyValue( "Animated" ) >>= bAnimated
) )
282 awt::Size
aDestSizePixel( aSourceSizePixel
);
285 bool bNeedsOptimizing
= false;
286 bool bRemoveCropArea( rGraphicSettings
.mbRemoveCropArea
);
288 // cropping has to be removed from SourceSizePixel
289 if ( aGraphicCropLogic
.Left
|| aGraphicCropLogic
.Top
|| aGraphicCropLogic
.Right
|| aGraphicCropLogic
.Bottom
)
291 const awt::Size
aSize100thMM( GraphicCollector::GetOriginalSize( rxContext
, xGraphic
) );
293 if ( bRemoveCropArea
)
294 bNeedsOptimizing
= true;
296 if ( aSize100thMM
.Width
&& aSize100thMM
.Height
)
298 aGraphicCropPixel
.Left
= static_cast< sal_Int32
>( ( (double)aSourceSizePixel
.Width
* aGraphicCropLogic
.Left
) / aSize100thMM
.Width
);
299 aGraphicCropPixel
.Top
= static_cast< sal_Int32
>( ( (double)aSourceSizePixel
.Height
* aGraphicCropLogic
.Top
) / aSize100thMM
.Height
);
300 aGraphicCropPixel
.Right
= static_cast< sal_Int32
>( ( (double)aSourceSizePixel
.Width
* ( aSize100thMM
.Width
- aGraphicCropLogic
.Right
) ) / aSize100thMM
.Width
);
301 aGraphicCropPixel
.Bottom
= static_cast< sal_Int32
>( ( (double)aSourceSizePixel
.Height
* ( aSize100thMM
.Height
- aGraphicCropLogic
.Bottom
) ) / aSize100thMM
.Height
);
303 // first calculating new SourceSizePixel by removing the cropped area
304 aSourceSizePixel
.Width
= aGraphicCropPixel
.Right
- aGraphicCropPixel
.Left
;
305 aSourceSizePixel
.Height
= aGraphicCropPixel
.Bottom
- aGraphicCropPixel
.Top
;
309 bRemoveCropArea
= false;
312 if ( ( aSourceSizePixel
.Width
> 0 ) && ( aSourceSizePixel
.Height
> 0 ) )
314 OUString
aDestMimeType( "image/png" );
315 if ( rGraphicSettings
.mbJPEGCompression
&& !bTransparent
&& !bAlpha
&& !bAnimated
)
317 aDestMimeType
= "image/jpeg";
318 // if( aSourceMimeType != aDestMimeType )
319 bNeedsOptimizing
= true;
321 if ( bRemoveCropArea
)
322 aDestSizePixel
= aSourceSizePixel
;
323 if ( rGraphicSettings
.mnImageResolution
&& aLogicalSize
.Width
&& aLogicalSize
.Height
)
325 const double fSourceDPIX
= ((double)aSourceSizePixel
.Width
/ ((double)aLogicalSize
.Width
/ 2540.0 ));
326 const double fSourceDPIY
= ((double)aSourceSizePixel
.Height
/ ((double)aLogicalSize
.Height
/ 2540.0 ));
328 // check, if the bitmap DPI exceeds the maximum DPI
329 if( ( fSourceDPIX
> rGraphicSettings
.mnImageResolution
) || ( fSourceDPIY
> rGraphicSettings
.mnImageResolution
) )
331 const double fNewSizePixelX
= ((double)aDestSizePixel
.Width
* rGraphicSettings
.mnImageResolution
) / fSourceDPIX
;
332 const double fNewSizePixelY
= ((double)aDestSizePixel
.Height
* rGraphicSettings
.mnImageResolution
) / fSourceDPIY
;
334 aDestSizePixel
= awt::Size( (sal_Int32
)fNewSizePixelX
, (sal_Int32
)fNewSizePixelY
);
335 bNeedsOptimizing
= true;
338 if ( bNeedsOptimizing
&& aDestSizePixel
.Width
&& aDestSizePixel
.Height
)
340 Reference
< XStream
> xTempFile( io::TempFile::create(rxContext
), UNO_QUERY_THROW
);
341 Reference
< XOutputStream
> xOutputStream( xTempFile
->getOutputStream() );
342 Reference
< XGraphicProvider
> xGraphicProvider( GraphicProvider::create( rxContext
) );
344 ImpCompressGraphic( xGraphicProvider
, xGraphic
, xOutputStream
, aDestMimeType
, aLogicalSize
, rGraphicSettings
.mnJPEGQuality
, rGraphicSettings
.mnImageResolution
, bRemoveCropArea
, aGraphicCropLogic
);
345 Reference
< XInputStream
> xInputStream( xTempFile
->getInputStream() );
346 Reference
< XSeekable
> xSeekable( xInputStream
, UNO_QUERY_THROW
);
347 xSeekable
->seek( 0 );
348 Sequence
< PropertyValue
> aArgs( 1 );
349 aArgs
[ 0 ].Name
= "InputStream";
350 aArgs
[ 0 ].Value
<<= xInputStream
;
351 xNewGraphic
= xGraphicProvider
->queryGraphic( aArgs
);
357 else // this is a metafile
359 OUString
aDestMimeType( aSourceMimeType
);
360 Reference
< XStream
> xTempFile( io::TempFile::create(rxContext
), UNO_QUERY_THROW
);
361 Reference
< XOutputStream
> xOutputStream( xTempFile
->getOutputStream() );
362 Reference
< XGraphicProvider
> xGraphicProvider( GraphicProvider::create( rxContext
) );
363 ImpCompressGraphic( xGraphicProvider
, xGraphic
, xOutputStream
, aDestMimeType
, aLogicalSize
, rGraphicSettings
.mnJPEGQuality
, rGraphicSettings
.mnImageResolution
, false, aGraphicCropLogic
);
364 Reference
< XInputStream
> xInputStream( xTempFile
->getInputStream() );
365 Reference
< XSeekable
> xSeekable( xInputStream
, UNO_QUERY_THROW
);
366 xSeekable
->seek( 0 );
367 Sequence
< PropertyValue
> aArgs( 1 );
368 aArgs
[ 0 ].Name
= "InputStream";
369 aArgs
[ 0 ].Value
<<= xInputStream
;
370 xNewGraphic
= xGraphicProvider
->queryGraphic( aArgs
);
380 void CompressGraphics( ImpOptimizer
& rOptimizer
, const Reference
< XComponentContext
>& rxContext
, const GraphicSettings
& rGraphicSettings
,
381 std::vector
< GraphicCollector::GraphicEntity
>& rGraphicList
)
385 std::vector
< GraphicCollector::GraphicEntity
>::iterator
aGraphicIter( rGraphicList
.begin() );
386 std::vector
< GraphicCollector::GraphicEntity
>::iterator
aGraphicIEnd( rGraphicList
.end() );
388 while( aGraphicIter
!= aGraphicIEnd
)
391 sal_Int32 nProgress
= static_cast< sal_Int32
>( 40.0 * ( i
/ static_cast< double >( rGraphicList
.size() ) ) ) + 50;
392 rOptimizer
.SetStatusValue( TK_Progress
, Any( static_cast< sal_Int32
>( nProgress
) ) );
393 rOptimizer
.DispatchStatus();
395 if ( aGraphicIter
->maUser
.size() )
397 GraphicSettings
aGraphicSettings( rGraphicSettings
);
398 aGraphicSettings
.mbRemoveCropArea
= aGraphicIter
->mbRemoveCropArea
;
400 Reference
< XGraphic
> xGraphic
;
401 if ( aGraphicIter
->maUser
[ 0 ].mbFillBitmap
&& aGraphicIter
->maUser
[ 0 ].mxPropertySet
.is() )
403 Reference
< XBitmap
> xFillBitmap
;
404 if ( aGraphicIter
->maUser
[ 0 ].mxPropertySet
->getPropertyValue( "FillBitmap" ) >>= xFillBitmap
)
405 xGraphic
= Reference
< XGraphic
>( xFillBitmap
, UNO_QUERY_THROW
);
407 else if ( aGraphicIter
->maUser
[ 0 ].mxShape
.is() )
409 Reference
< XPropertySet
> xShapePropertySet( aGraphicIter
->maUser
[ 0 ].mxShape
, UNO_QUERY_THROW
);
410 xShapePropertySet
->getPropertyValue( "Graphic" ) >>= xGraphic
;
414 Reference
< XPropertySet
> xNewGraphicPropertySet( xGraphic
, UNO_QUERY_THROW
);
415 awt::Size
aSize100thMM( GraphicCollector::GetOriginalSize( rxContext
, xGraphic
) );
416 Reference
< XGraphic
> xNewGraphic( ImpCompressGraphic( rxContext
, xGraphic
, aGraphicIter
->maLogicalSize
, aGraphicIter
->maGraphicCropLogic
, aGraphicSettings
) );
417 if ( xNewGraphic
.is() )
419 // applying graphic to each user
420 std::vector
< GraphicCollector::GraphicUser
>::iterator
aGraphicUserIter( aGraphicIter
->maUser
.begin() );
421 while( aGraphicUserIter
!= aGraphicIter
->maUser
.end() )
423 if ( aGraphicUserIter
->mxShape
.is() )
425 OUString sEmptyGraphicURL
;
426 Reference
< XPropertySet
> xShapePropertySet( aGraphicUserIter
->mxShape
, UNO_QUERY_THROW
);
427 xShapePropertySet
->setPropertyValue( "GraphicURL", Any( sEmptyGraphicURL
) );
428 xShapePropertySet
->setPropertyValue( "Graphic", Any( xNewGraphic
) );
430 if ( aGraphicUserIter
->maGraphicCropLogic
.Left
|| aGraphicUserIter
->maGraphicCropLogic
.Top
431 || aGraphicUserIter
->maGraphicCropLogic
.Right
|| aGraphicUserIter
->maGraphicCropLogic
.Bottom
)
432 { // removing crop area was not possible or should't been applied
433 text::GraphicCrop
aGraphicCropLogic( 0, 0, 0, 0 );
434 if ( !aGraphicSettings
.mbRemoveCropArea
)
436 awt::Size
aNewSize( GraphicCollector::GetOriginalSize( rxContext
, xNewGraphic
) );
437 aGraphicCropLogic
.Left
= (sal_Int32
)((double)aGraphicUserIter
->maGraphicCropLogic
.Left
* ((double)aNewSize
.Width
/ (double)aSize100thMM
.Width
));
438 aGraphicCropLogic
.Top
= (sal_Int32
)((double)aGraphicUserIter
->maGraphicCropLogic
.Top
* ((double)aNewSize
.Height
/ (double)aSize100thMM
.Height
));
439 aGraphicCropLogic
.Right
= (sal_Int32
)((double)aGraphicUserIter
->maGraphicCropLogic
.Right
* ((double)aNewSize
.Width
/ (double)aSize100thMM
.Width
));
440 aGraphicCropLogic
.Bottom
= (sal_Int32
)((double)aGraphicUserIter
->maGraphicCropLogic
.Bottom
* ((double)aNewSize
.Height
/ (double)aSize100thMM
.Height
));
442 xShapePropertySet
->setPropertyValue( "GraphicCrop", Any( aGraphicCropLogic
) );
445 else if ( aGraphicUserIter
->mxPropertySet
.is() )
447 Reference
< XBitmap
> xFillBitmap( xNewGraphic
, UNO_QUERY
);
448 if ( xFillBitmap
.is() )
453 Reference
< XPropertySet
>& rxPropertySet( aGraphicUserIter
->mxPropertySet
);
454 rxPropertySet
->setPropertyValue( "FillBitmap", Any( xFillBitmap
) );
455 if ( ( rxPropertySet
->getPropertyValue( "FillBitmapLogicalSize" ) >>= bLogicalSize
)
456 && ( rxPropertySet
->getPropertyValue( "FillBitmapSizeX" ) >>= aSize
.Width
)
457 && ( rxPropertySet
->getPropertyValue( "FillBitmapSizeY" ) >>= aSize
.Height
) )
459 if ( !aSize
.Width
|| !aSize
.Height
)
461 rxPropertySet
->setPropertyValue( "FillBitmapLogicalSize", Any( sal_True
) );
462 rxPropertySet
->setPropertyValue( "FillBitmapSizeX", Any( aGraphicUserIter
->maLogicalSize
.Width
) );
463 rxPropertySet
->setPropertyValue( "FillBitmapSizeY", Any( aGraphicUserIter
->maLogicalSize
.Height
) );
466 if ( aGraphicUserIter
->mxPagePropertySet
.is() )
467 aGraphicUserIter
->mxPagePropertySet
->setPropertyValue( "Background", Any( rxPropertySet
) );
487 ImpOptimizer::ImpOptimizer( const Reference
< XComponentContext
>& rxContext
, const Reference
< XModel
>& rxModel
) :
488 mxContext ( rxContext
),
490 mbJPEGCompression ( false ),
491 mnJPEGQuality ( 90 ),
492 mbRemoveCropArea ( false ),
493 mnImageResolution ( 0 ),
494 mbEmbedLinkedGraphics ( true ),
495 mbOLEOptimization ( false ),
496 mnOLEOptimizationType ( 0 ),
497 mbDeleteUnusedMasterPages ( false ),
498 mbDeleteHiddenSlides ( false ),
499 mbDeleteNotesPages ( false ),
500 mbOpenNewDocument ( true )
506 ImpOptimizer::~ImpOptimizer()
512 void ImpOptimizer::DispatchStatus()
514 if ( mxStatusDispatcher
.is() )
517 aURL
.Protocol
= "vnd.com.sun.star.comp.PresentationMinimizer:";
518 aURL
.Path
= "statusupdate";
519 mxStatusDispatcher
->dispatch( aURL
, GetStatusSequence() );
525 bool ImpOptimizer::Optimize()
528 if ( !maCustomShowName
.isEmpty() )
529 ImpExtractCustomShow( mxModel
, maCustomShowName
);
531 if ( mbDeleteUnusedMasterPages
)
533 SetStatusValue( TK_Progress
, Any( static_cast< sal_Int32
>( 40 ) ) );
534 SetStatusValue( TK_Status
, Any( OUString("STR_DELETING_SLIDES") ) );
536 ImpDeleteUnusedMasterPages( mxModel
);
539 if ( mbDeleteHiddenSlides
)
541 SetStatusValue( TK_Progress
, Any( static_cast< sal_Int32
>( 40 ) ) );
542 SetStatusValue( TK_Status
, Any( OUString("STR_DELETING_SLIDES") ) );
544 ImpDeleteHiddenSlides( mxModel
);
547 if ( mbDeleteNotesPages
)
549 SetStatusValue( TK_Status
, Any( OUString("STR_DELETING_SLIDES") ) );
551 ImpDeleteNotesPages( mxModel
);
554 if ( mbOLEOptimization
)
556 SetStatusValue( TK_Progress
, Any( static_cast< sal_Int32
>( 45 ) ) );
557 SetStatusValue( TK_Status
, Any( OUString("STR_CREATING_OLE_REPLACEMENTS") ) );
559 ImpConvertOLE( mxModel
, mnOLEOptimizationType
);
562 if ( mbJPEGCompression
|| mbRemoveCropArea
|| mnImageResolution
)
564 SetStatusValue( TK_Progress
, Any( static_cast< sal_Int32
>( 50 ) ) );
565 SetStatusValue( TK_Status
, Any( OUString("STR_OPTIMIZING_GRAPHICS") ) );
568 std::vector
< GraphicCollector::GraphicEntity
> aGraphicList
;
569 GraphicSettings
aGraphicSettings( mbJPEGCompression
, mnJPEGQuality
, mbRemoveCropArea
, mnImageResolution
, mbEmbedLinkedGraphics
);
570 GraphicCollector::CollectGraphics( mxContext
, mxModel
, aGraphicSettings
, aGraphicList
);
571 CompressGraphics( *this, mxContext
, aGraphicSettings
, aGraphicList
);
573 SetStatusValue( TK_Progress
, Any( static_cast< sal_Int32
>( 100 ) ) );
578 static void DispatchURL( Reference
< XComponentContext
> xContext
, const OUString
& sURL
, Reference
< XFrame
> xFrame
)
582 Reference
< XURLTransformer
> xURLTransformer( URLTransformer::create(xContext
) );
584 aUrl
.Complete
= sURL
;
585 xURLTransformer
->parseStrict( aUrl
);
586 Sequence
< PropertyValue
> aArgs
;
587 Reference
< XDispatchProvider
> xDispatchProvider( xFrame
, UNO_QUERY_THROW
);
588 Reference
< XDispatch
> xDispatch
= xDispatchProvider
->queryDispatch( aUrl
, OUString(), 0 ); // "_self"
589 if ( xDispatch
.is() )
590 xDispatch
->dispatch( aUrl
, aArgs
);
599 bool ImpOptimizer::Optimize( const Sequence
< PropertyValue
>& rArguments
)
605 sal_Int64 nEstimatedFileSize
= 0;
606 SetStatusValue( TK_Progress
, Any( static_cast< sal_Int32
>( 0 ) ) );
610 for ( i
= 0, nICount
= rArguments
.getLength(); i
< nICount
; i
++ )
612 switch( TKGet( rArguments
[ i
].Name
) )
614 case TK_StatusDispatcher
: rArguments
[ i
].Value
>>= mxStatusDispatcher
; break;
615 case TK_InformationDialog
: rArguments
[ i
].Value
>>= mxInformationDialog
; break;
618 com::sun::star::uno::Sequence
< com::sun::star::beans::PropertyValue
> aSettings
;
620 rArguments
[ i
].Value
>>= aSettings
;
621 for ( j
= 0, nJCount
= aSettings
.getLength(); j
< nJCount
; j
++ )
623 switch( TKGet( aSettings
[ j
].Name
) )
625 case TK_JPEGCompression
: aSettings
[ j
].Value
>>= mbJPEGCompression
; break;
626 case TK_JPEGQuality
: aSettings
[ j
].Value
>>= mnJPEGQuality
; break;
627 case TK_RemoveCropArea
: aSettings
[ j
].Value
>>= mbRemoveCropArea
; break;
628 case TK_ImageResolution
: aSettings
[ j
].Value
>>= mnImageResolution
; break;
629 case TK_EmbedLinkedGraphics
: aSettings
[ j
].Value
>>= mbEmbedLinkedGraphics
; break;
630 case TK_OLEOptimization
: aSettings
[ j
].Value
>>= mbOLEOptimization
; break;
631 case TK_OLEOptimizationType
: aSettings
[ j
].Value
>>= mnOLEOptimizationType
; break;
632 case TK_CustomShowName
: aSettings
[ j
].Value
>>= maCustomShowName
; break;
633 case TK_DeleteUnusedMasterPages
: aSettings
[ j
].Value
>>= mbDeleteUnusedMasterPages
; break;
634 case TK_DeleteHiddenSlides
: aSettings
[ j
].Value
>>= mbDeleteHiddenSlides
; break;
635 case TK_DeleteNotesPages
: aSettings
[ j
].Value
>>= mbDeleteNotesPages
; break;
636 case TK_SaveAsURL
: aSettings
[ j
].Value
>>= maSaveAsURL
; break;
637 case TK_FilterName
: aSettings
[ j
].Value
>>= maFilterName
; break;
638 case TK_OpenNewDocument
: aSettings
[ j
].Value
>>= mbOpenNewDocument
; break;
639 case TK_EstimatedFileSize
: aSettings
[ j
].Value
>>= nEstimatedFileSize
; break;
649 sal_Int64 nSourceSize
= 0;
650 sal_Int64 nDestSize
= 0;
652 Reference
< XFrame
> xSelf
;
653 if ( !maSaveAsURL
.isEmpty() )
656 SetStatusValue( TK_Progress
, Any( static_cast< sal_Int32
>( 10 ) ) );
657 SetStatusValue( TK_Status
, Any( OUString("STR_DUPLICATING_PRESENTATION") ) );
660 Reference
< XStorable
>xStorable( mxModel
, UNO_QUERY
);
661 if ( xStorable
.is() )
663 if ( xStorable
->hasLocation() )
664 nSourceSize
= PPPOptimizer::GetFileSize( xStorable
->getLocation() );
666 Sequence
< PropertyValue
> aArguments
;
667 if ( !maFilterName
.isEmpty() )
669 int nLength
= aArguments
.getLength();
670 aArguments
.realloc( nLength
+ 1 );
671 aArguments
[ nLength
].Name
= "FilterName";
672 aArguments
[ nLength
].Value
<<= maFilterName
;
674 xStorable
->storeToURL( maSaveAsURL
, aArguments
);
676 nSourceSize
= PPPOptimizer::GetFileSize( maSaveAsURL
);
678 SetStatusValue( TK_Progress
, Any( static_cast< sal_Int32
>( 30 ) ) );
679 SetStatusValue( TK_Status
, Any( OUString("STR_DUPLICATING_PRESENTATION") ) );
682 Reference
< XDesktop2
> xDesktop
= Desktop::create( mxContext
);
683 xSelf
= xDesktop
->findFrame( "_blank", FrameSearchFlag::CREATE
);
684 Reference
< XComponentLoader
> xComponentLoader( xSelf
, UNO_QUERY
);
686 Sequence
< PropertyValue
> aLoadProps( 1 );
687 aLoadProps
[ 0 ].Name
= "Hidden";
688 aLoadProps
[ 0 ].Value
<<= true;
689 mxModel
= Reference
< XModel
>( xComponentLoader
->loadComponentFromURL(
690 maSaveAsURL
, "_self", 0, aLoadProps
), UNO_QUERY
);
694 // check if the document is ReadOnly -> error
695 Reference
< XStorable
> xStorable( mxModel
, UNO_QUERY
);
696 if ( xStorable
.is() && !xStorable
->isReadonly() )
698 mxModel
->lockControllers();
700 mxModel
->unlockControllers();
702 // clearing undo stack:
703 Reference
< XFrame
> xFrame( xSelf
.is() ? xSelf
: mxInformationDialog
);
706 const OUString
sSlot( "slot:27115" );
707 DispatchURL( mxContext
, sSlot
, xFrame
);
711 if ( !maSaveAsURL
.isEmpty() )
713 if ( xStorable
.is() )
716 nDestSize
= PPPOptimizer::GetFileSize( maSaveAsURL
);
720 if ( mxInformationDialog
.is() )
722 InformationDialog
aInformationDialog( mxContext
, mxInformationDialog
, maSaveAsURL
, mbOpenNewDocument
, nSourceSize
, nDestSize
, nEstimatedFileSize
);
723 aInformationDialog
.execute();
724 SetStatusValue( TK_OpenNewDocument
, Any( mbOpenNewDocument
) );
728 if ( !maSaveAsURL
.isEmpty() )
730 if ( mbOpenNewDocument
&& xSelf
.is() )
732 Reference
< awt::XWindow
> xContainerWindow( xSelf
->getContainerWindow() );
733 xContainerWindow
->setVisible( sal_True
);
737 Reference
< XComponent
> xComponent( mxModel
, UNO_QUERY
);
738 xComponent
->dispose();
741 if ( nSourceSize
&& nDestSize
)
743 SetStatusValue( TK_FileSizeSource
, Any( nSourceSize
) );
744 SetStatusValue( TK_FileSizeDestination
, Any( nDestSize
) );
753 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */