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/URL.hpp>
62 #include <com/sun/star/util/URLTransformer.hpp>
64 using namespace ::std
;
65 using namespace ::rtl
;
66 using namespace ::com::sun::star
;
67 using namespace ::com::sun::star::io
;
68 using namespace ::com::sun::star::awt
;
69 using namespace ::com::sun::star::uno
;
70 using namespace ::com::sun::star::lang
;
71 using namespace ::com::sun::star::util
;
72 using namespace ::com::sun::star::frame
;
73 using namespace ::com::sun::star::beans
;
74 using namespace ::com::sun::star::drawing
;
75 using namespace ::com::sun::star::graphic
;
76 using namespace ::com::sun::star::document
;
77 using namespace ::com::sun::star::container
;
78 using namespace ::com::sun::star::presentation
;
80 void ImpExtractCustomShow( const Reference
< XModel
>& rxModel
, const OUString
& rCustomShowName
)
82 vector
< Reference
< XDrawPage
> > vNonUsedPageList
;
85 PageCollector::CollectNonCustomShowPages( rxModel
, rCustomShowName
, vNonUsedPageList
);
86 Reference
< XDrawPagesSupplier
> xDrawPagesSupplier( rxModel
, UNO_QUERY_THROW
);
87 Reference
< XDrawPages
> xDrawPages( xDrawPagesSupplier
->getDrawPages(), UNO_QUERY_THROW
);
88 vector
< Reference
< XDrawPage
> >::iterator
aIter( vNonUsedPageList
.begin() );
89 while( aIter
!= vNonUsedPageList
.end() )
90 xDrawPages
->remove( *aIter
++ );
98 void ImpDeleteUnusedMasterPages( const Reference
< XModel
>& rxModel
)
100 vector
< PageCollector::MasterPageEntity
> aMasterPageList
;
101 PageCollector::CollectMasterPages( rxModel
, aMasterPageList
);
103 // now master pages that are not marked can be deleted
104 Reference
< XMasterPagesSupplier
> xMasterPagesSupplier( rxModel
, UNO_QUERY_THROW
);
105 Reference
< XDrawPages
> xMasterPages( xMasterPagesSupplier
->getMasterPages(), UNO_QUERY_THROW
);
106 vector
< PageCollector::MasterPageEntity
>::iterator
aIter( aMasterPageList
.begin() );
107 while( aIter
!= aMasterPageList
.end() )
110 xMasterPages
->remove( aIter
->xMasterPage
);
115 void ImpDeleteHiddenSlides( const Reference
< XModel
>& rxModel
)
119 Reference
< XDrawPagesSupplier
> xDrawPagesSupplier( rxModel
, UNO_QUERY_THROW
);
120 Reference
< XDrawPages
> xDrawPages( xDrawPagesSupplier
->getDrawPages(), UNO_QUERY_THROW
);
121 for( sal_Int32 i
= 0; i
< xDrawPages
->getCount(); i
++ )
123 Reference
< XDrawPage
> xDrawPage( xDrawPages
->getByIndex( i
), UNO_QUERY_THROW
);
124 Reference
< XPropertySet
> xPropSet( xDrawPage
, UNO_QUERY_THROW
);
126 sal_Bool bVisible
= sal_True
;
127 const OUString
sVisible( "Visible" );
128 if ( xPropSet
->getPropertyValue( sVisible
) >>= bVisible
)
132 xDrawPages
->remove( xDrawPage
);
143 void ImpDeleteNotesPages( const Reference
< XModel
>& rxModel
)
147 Reference
< XDrawPagesSupplier
> xDrawPagesSupplier( rxModel
, UNO_QUERY_THROW
);
148 Reference
< XDrawPages
> xDrawPages( xDrawPagesSupplier
->getDrawPages(), UNO_QUERY_THROW
);
149 sal_Int32 i
, nPages
= xDrawPages
->getCount();
150 for( i
= 0; i
< nPages
; i
++ )
152 Reference
< XPresentationPage
> xPresentationPage( xDrawPages
->getByIndex( i
), UNO_QUERY_THROW
);
153 Reference
< XPropertySet
> xPropSet( xPresentationPage
->getNotesPage(), UNO_QUERY_THROW
);
154 Reference
< XShapes
> xShapes( xPropSet
, UNO_QUERY_THROW
);
155 while( xShapes
->getCount() )
156 xShapes
->remove( Reference
< XShape
>( xShapes
->getByIndex( xShapes
->getCount() - 1 ), UNO_QUERY_THROW
) );
158 const OUString
sLayout( "Layout" );
159 xPropSet
->setPropertyValue( sLayout
, Any( (sal_Int16
)21 ) );
167 void ImpConvertOLE( const Reference
< XModel
>& rxModel
, sal_Int32 nOLEOptimizationType
)
171 Reference
< XDrawPagesSupplier
> xDrawPagesSupplier( rxModel
, UNO_QUERY_THROW
);
172 Reference
< XDrawPages
> xDrawPages( xDrawPagesSupplier
->getDrawPages(), UNO_QUERY_THROW
);
173 for ( sal_Int32 i
= 0; i
< xDrawPages
->getCount(); i
++ )
175 Reference
< XShapes
> xShapes( xDrawPages
->getByIndex( i
), UNO_QUERY_THROW
);
176 for ( sal_Int32 j
= 0; j
< xShapes
->getCount(); j
++ )
178 const OUString
sOLE2Shape( "com.sun.star.drawing.OLE2Shape" );
179 Reference
< XShape
> xShape( xShapes
->getByIndex( j
), UNO_QUERY_THROW
);
180 if ( xShape
->getShapeType() == sOLE2Shape
)
182 Reference
< XPropertySet
> xPropSet( xShape
, UNO_QUERY_THROW
);
184 sal_Bool bConvertOLE
= nOLEOptimizationType
== 0;
185 if ( nOLEOptimizationType
== 1 )
187 sal_Bool bIsInternal
= sal_True
;
188 xPropSet
->getPropertyValue( TKGet( TK_IsInternal
) ) >>= bIsInternal
;
189 bConvertOLE
= !bIsInternal
;
193 Reference
< XGraphic
> xGraphic
;
194 if ( xPropSet
->getPropertyValue( TKGet( TK_Graphic
) ) >>= xGraphic
)
196 const OUString
sGraphicShape( "com.sun.star.drawing.GraphicObjectShape" );
197 Reference
< XMultiServiceFactory
> xFact( rxModel
, UNO_QUERY_THROW
);
198 Reference
< XShape
> xShape2( xFact
->createInstance( sGraphicShape
), UNO_QUERY_THROW
);
199 xShapes
->add( xShape2
);
200 xShape2
->setPosition( xShape
->getPosition() );
201 xShape2
->setSize( xShape
->getSize() );
202 Reference
< XPropertySet
> xPropSet2( xShape2
, UNO_QUERY_THROW
);
203 xPropSet2
->setPropertyValue( TKGet( TK_Graphic
), Any( xGraphic
) );
204 xShapes
->remove( xShape
);
205 xPropSet2
->setPropertyValue( TKGet( TK_ZOrder
), Any( j
) );
217 void ImpCompressGraphic( Reference
< XGraphicProvider
>& rxGraphicProvider
, const Reference
< XGraphic
>& rxGraphic
, Reference
< XOutputStream
>& rxOutputStream
,
218 const OUString
& rDestMimeType
, const awt::Size
& rLogicalSize
, sal_Int32 nJPEGQuality
, sal_Int32 nImageResolution
, sal_Bool bRemoveCropping
, const text::GraphicCrop
& rGraphicCropLogic
)
222 if ( rxGraphicProvider
.is() && rxOutputStream
.is() )
224 Sequence
< PropertyValue
> aFilterData( 8 );
225 aFilterData
[ 0 ].Name
= TKGet( TK_ImageResolution
);
226 aFilterData
[ 0 ].Value
<<= nImageResolution
;
227 aFilterData
[ 1 ].Name
= TKGet( TK_ColorMode
); // todo: jpeg color mode (0->true color, 1->greyscale)
228 aFilterData
[ 1 ].Value
<<= (sal_Int32
)0;
229 aFilterData
[ 2 ].Name
= TKGet( TK_Quality
); // quality that is used if we export to jpeg
230 aFilterData
[ 2 ].Value
<<= nJPEGQuality
;
231 aFilterData
[ 3 ].Name
= TKGet( TK_Compression
); // compression that is used if we export to png
232 aFilterData
[ 3 ].Value
<<= (sal_Int32
)6;
233 aFilterData
[ 4 ].Name
= TKGet( TK_Interlaced
); // interlaced is turned off if we export to png
234 aFilterData
[ 4 ].Value
<<= (sal_Int32
)0;
235 aFilterData
[ 5 ].Name
= TKGet( TK_LogicalSize
);
236 aFilterData
[ 5 ].Value
<<= rLogicalSize
;
237 aFilterData
[ 6 ].Name
= TKGet( TK_RemoveCropArea
);
238 aFilterData
[ 6 ].Value
<<= bRemoveCropping
;
239 aFilterData
[ 7 ].Name
= TKGet( TK_GraphicCropLogic
);
240 aFilterData
[ 7 ].Value
<<= rGraphicCropLogic
;
242 Sequence
< PropertyValue
> aArgs( 3 );
243 aArgs
[ 0 ].Name
= TKGet( TK_MimeType
); // the GraphicProvider is using "MimeType", the GraphicExporter "MediaType"...
244 aArgs
[ 0 ].Value
<<= rDestMimeType
;
245 aArgs
[ 1 ].Name
= TKGet( TK_OutputStream
);
246 aArgs
[ 1 ].Value
<<= rxOutputStream
;
247 aArgs
[ 2 ].Name
= TKGet( TK_FilterData
);
248 aArgs
[ 2 ].Value
<<= aFilterData
;
250 rxGraphicProvider
->storeGraphic( rxGraphic
, aArgs
);
258 Reference
< XGraphic
> ImpCompressGraphic( const Reference
< XComponentContext
>& rxMSF
,
259 const Reference
< XGraphic
>& xGraphic
, const awt::Size
& aLogicalSize
, const text::GraphicCrop
& aGraphicCropLogic
,
260 const GraphicSettings
& rGraphicSettings
)
262 Reference
< XGraphic
> xNewGraphic
;
265 OUString aSourceMimeType
;
266 Reference
< XPropertySet
> xGraphicPropertySet( xGraphic
, UNO_QUERY_THROW
);
267 if ( xGraphicPropertySet
->getPropertyValue( TKGet( TK_MimeType
) ) >>= aSourceMimeType
)
269 sal_Int8
nGraphicType( xGraphic
->getType() );
270 if ( nGraphicType
== com::sun::star::graphic::GraphicType::PIXEL
)
272 sal_Bool bTransparent
= sal_False
;
273 sal_Bool bAlpha
= sal_False
;
274 sal_Bool bAnimated
= sal_False
;
276 awt::Size
aSourceSizePixel( 0, 0 );
277 text::GraphicCrop
aGraphicCropPixel( 0, 0, 0, 0 );
279 if ( ( xGraphicPropertySet
->getPropertyValue( TKGet( TK_SizePixel
) ) >>= aSourceSizePixel
) &&
280 ( xGraphicPropertySet
->getPropertyValue( TKGet( TK_Transparent
) ) >>= bTransparent
) &&
281 ( xGraphicPropertySet
->getPropertyValue( TKGet( TK_Alpha
) ) >>= bAlpha
) &&
282 ( xGraphicPropertySet
->getPropertyValue( TKGet( TK_Animated
) ) >>= bAnimated
) )
284 awt::Size
aDestSizePixel( aSourceSizePixel
);
287 sal_Bool bNeedsOptimizing
= sal_False
;
288 sal_Bool
bRemoveCropArea( rGraphicSettings
.mbRemoveCropArea
);
290 // cropping has to be removed from SourceSizePixel
291 if ( aGraphicCropLogic
.Left
|| aGraphicCropLogic
.Top
|| aGraphicCropLogic
.Right
|| aGraphicCropLogic
.Bottom
)
293 const awt::Size
aSize100thMM( GraphicCollector::GetOriginalSize( rxMSF
, xGraphic
) );
295 if ( bRemoveCropArea
)
296 bNeedsOptimizing
= sal_True
;
298 if ( aSize100thMM
.Width
&& aSize100thMM
.Height
)
300 aGraphicCropPixel
.Left
= static_cast< sal_Int32
>( ( (double)aSourceSizePixel
.Width
* aGraphicCropLogic
.Left
) / aSize100thMM
.Width
);
301 aGraphicCropPixel
.Top
= static_cast< sal_Int32
>( ( (double)aSourceSizePixel
.Height
* aGraphicCropLogic
.Top
) / aSize100thMM
.Height
);
302 aGraphicCropPixel
.Right
= static_cast< sal_Int32
>( ( (double)aSourceSizePixel
.Width
* ( aSize100thMM
.Width
- aGraphicCropLogic
.Right
) ) / aSize100thMM
.Width
);
303 aGraphicCropPixel
.Bottom
= static_cast< sal_Int32
>( ( (double)aSourceSizePixel
.Height
* ( aSize100thMM
.Height
- aGraphicCropLogic
.Bottom
) ) / aSize100thMM
.Height
);
305 // first calculating new SourceSizePixel by removing the cropped area
306 aSourceSizePixel
.Width
= aGraphicCropPixel
.Right
- aGraphicCropPixel
.Left
;
307 aSourceSizePixel
.Height
= aGraphicCropPixel
.Bottom
- aGraphicCropPixel
.Top
;
311 bRemoveCropArea
= sal_False
;
314 if ( ( aSourceSizePixel
.Width
> 0 ) && ( aSourceSizePixel
.Height
> 0 ) )
316 OUString
aDestMimeType( "image/png" );
317 if ( rGraphicSettings
.mbJPEGCompression
&& !bTransparent
&& !bAlpha
&& !bAnimated
)
319 aDestMimeType
= OUString( "image/jpeg" );
320 // if( aSourceMimeType != aDestMimeType )
321 bNeedsOptimizing
= sal_True
;
323 if ( bRemoveCropArea
)
324 aDestSizePixel
= aSourceSizePixel
;
325 if ( rGraphicSettings
.mnImageResolution
&& aLogicalSize
.Width
&& aLogicalSize
.Height
)
327 const double fSourceDPIX
= ((double)aSourceSizePixel
.Width
/ ((double)aLogicalSize
.Width
/ 2540.0 ));
328 const double fSourceDPIY
= ((double)aSourceSizePixel
.Height
/ ((double)aLogicalSize
.Height
/ 2540.0 ));
330 // check, if the bitmap DPI exceeds the maximum DPI
331 if( ( fSourceDPIX
> rGraphicSettings
.mnImageResolution
) || ( fSourceDPIY
> rGraphicSettings
.mnImageResolution
) )
333 const double fNewSizePixelX
= ((double)aDestSizePixel
.Width
* rGraphicSettings
.mnImageResolution
) / fSourceDPIX
;
334 const double fNewSizePixelY
= ((double)aDestSizePixel
.Height
* rGraphicSettings
.mnImageResolution
) / fSourceDPIY
;
336 aDestSizePixel
= awt::Size( (sal_Int32
)fNewSizePixelX
, (sal_Int32
)fNewSizePixelY
);
337 bNeedsOptimizing
= sal_True
;
340 if ( bNeedsOptimizing
&& aDestSizePixel
.Width
&& aDestSizePixel
.Height
)
342 Reference
< XStream
> xTempFile( io::TempFile::create(rxMSF
), UNO_QUERY_THROW
);
343 Reference
< XOutputStream
> xOutputStream( xTempFile
->getOutputStream() );
344 Reference
< XGraphicProvider
> xGraphicProvider( GraphicProvider::create( rxMSF
) );
346 ImpCompressGraphic( xGraphicProvider
, xGraphic
, xOutputStream
, aDestMimeType
, aLogicalSize
, rGraphicSettings
.mnJPEGQuality
, rGraphicSettings
.mnImageResolution
, bRemoveCropArea
, aGraphicCropLogic
);
347 Reference
< XInputStream
> xInputStream( xTempFile
->getInputStream() );
348 Reference
< XSeekable
> xSeekable( xInputStream
, UNO_QUERY_THROW
);
349 xSeekable
->seek( 0 );
350 Sequence
< PropertyValue
> aArgs( 1 );
351 aArgs
[ 0 ].Name
= TKGet( TK_InputStream
);
352 aArgs
[ 0 ].Value
<<= xInputStream
;
353 xNewGraphic
= xGraphicProvider
->queryGraphic( aArgs
);
359 else // this is a metafile
361 OUString
aDestMimeType( aSourceMimeType
);
362 Reference
< XStream
> xTempFile( io::TempFile::create(rxMSF
), UNO_QUERY_THROW
);
363 Reference
< XOutputStream
> xOutputStream( xTempFile
->getOutputStream() );
364 Reference
< XGraphicProvider
> xGraphicProvider( GraphicProvider::create( rxMSF
) );
365 ImpCompressGraphic( xGraphicProvider
, xGraphic
, xOutputStream
, aDestMimeType
, aLogicalSize
, rGraphicSettings
.mnJPEGQuality
, rGraphicSettings
.mnImageResolution
, sal_False
, aGraphicCropLogic
);
366 Reference
< XInputStream
> xInputStream( xTempFile
->getInputStream() );
367 Reference
< XSeekable
> xSeekable( xInputStream
, UNO_QUERY_THROW
);
368 xSeekable
->seek( 0 );
369 Sequence
< PropertyValue
> aArgs( 1 );
370 aArgs
[ 0 ].Name
= TKGet( TK_InputStream
);
371 aArgs
[ 0 ].Value
<<= xInputStream
;
372 xNewGraphic
= xGraphicProvider
->queryGraphic( aArgs
);
382 void CompressGraphics( ImpOptimizer
& rOptimizer
, const Reference
< XComponentContext
>& rxMSF
, const GraphicSettings
& rGraphicSettings
,
383 std::vector
< GraphicCollector::GraphicEntity
>& rGraphicList
)
387 std::vector
< GraphicCollector::GraphicEntity
>::iterator
aGraphicIter( rGraphicList
.begin() );
388 std::vector
< GraphicCollector::GraphicEntity
>::iterator
aGraphicIEnd( rGraphicList
.end() );
390 while( aGraphicIter
!= aGraphicIEnd
)
393 sal_Int32 nProgress
= static_cast< sal_Int32
>( 40.0 * ( i
/ static_cast< double >( rGraphicList
.size() ) ) ) + 50;
394 rOptimizer
.SetStatusValue( TK_Progress
, Any( static_cast< sal_Int32
>( nProgress
) ) );
395 rOptimizer
.DispatchStatus();
397 if ( aGraphicIter
->maUser
.size() )
399 GraphicSettings
aGraphicSettings( rGraphicSettings
);
400 aGraphicSettings
.mbRemoveCropArea
= aGraphicIter
->mbRemoveCropArea
;
402 Reference
< XGraphic
> xGraphic
;
403 if ( aGraphicIter
->maUser
[ 0 ].mbFillBitmap
&& aGraphicIter
->maUser
[ 0 ].mxPropertySet
.is() )
405 Reference
< XBitmap
> xFillBitmap
;
406 if ( aGraphicIter
->maUser
[ 0 ].mxPropertySet
->getPropertyValue( TKGet( TK_FillBitmap
) ) >>= xFillBitmap
)
407 xGraphic
= Reference
< XGraphic
>( xFillBitmap
, UNO_QUERY_THROW
);
409 else if ( aGraphicIter
->maUser
[ 0 ].mxShape
.is() )
411 Reference
< XPropertySet
> xShapePropertySet( aGraphicIter
->maUser
[ 0 ].mxShape
, UNO_QUERY_THROW
);
412 xShapePropertySet
->getPropertyValue( TKGet( TK_Graphic
) ) >>= xGraphic
;
416 Reference
< XPropertySet
> xNewGraphicPropertySet( xGraphic
, UNO_QUERY_THROW
);
417 awt::Size
aSize100thMM( GraphicCollector::GetOriginalSize( rxMSF
, xGraphic
) );
418 Reference
< XGraphic
> xNewGraphic( ImpCompressGraphic( rxMSF
, xGraphic
, aGraphicIter
->maLogicalSize
, aGraphicIter
->maGraphicCropLogic
, aGraphicSettings
) );
419 if ( xNewGraphic
.is() )
421 // applying graphic to each user
422 std::vector
< GraphicCollector::GraphicUser
>::iterator
aGraphicUserIter( aGraphicIter
->maUser
.begin() );
423 while( aGraphicUserIter
!= aGraphicIter
->maUser
.end() )
425 if ( aGraphicUserIter
->mxShape
.is() )
427 OUString sEmptyGraphicURL
;
428 Reference
< XPropertySet
> xShapePropertySet( aGraphicUserIter
->mxShape
, UNO_QUERY_THROW
);
429 xShapePropertySet
->setPropertyValue( TKGet( TK_GraphicURL
), Any( sEmptyGraphicURL
) );
430 xShapePropertySet
->setPropertyValue( TKGet( TK_Graphic
), Any( xNewGraphic
) );
432 if ( aGraphicUserIter
->maGraphicCropLogic
.Left
|| aGraphicUserIter
->maGraphicCropLogic
.Top
433 || aGraphicUserIter
->maGraphicCropLogic
.Right
|| aGraphicUserIter
->maGraphicCropLogic
.Bottom
)
434 { // removing crop area was not possible or should't been applied
435 text::GraphicCrop
aGraphicCropLogic( 0, 0, 0, 0 );
436 if ( !aGraphicSettings
.mbRemoveCropArea
)
438 awt::Size
aNewSize( GraphicCollector::GetOriginalSize( rxMSF
, xNewGraphic
) );
439 aGraphicCropLogic
.Left
= (sal_Int32
)((double)aGraphicUserIter
->maGraphicCropLogic
.Left
* ((double)aNewSize
.Width
/ (double)aSize100thMM
.Width
));
440 aGraphicCropLogic
.Top
= (sal_Int32
)((double)aGraphicUserIter
->maGraphicCropLogic
.Top
* ((double)aNewSize
.Height
/ (double)aSize100thMM
.Height
));
441 aGraphicCropLogic
.Right
= (sal_Int32
)((double)aGraphicUserIter
->maGraphicCropLogic
.Right
* ((double)aNewSize
.Width
/ (double)aSize100thMM
.Width
));
442 aGraphicCropLogic
.Bottom
= (sal_Int32
)((double)aGraphicUserIter
->maGraphicCropLogic
.Bottom
* ((double)aNewSize
.Height
/ (double)aSize100thMM
.Height
));
444 xShapePropertySet
->setPropertyValue( TKGet( TK_GraphicCrop
), Any( aGraphicCropLogic
) );
447 else if ( aGraphicUserIter
->mxPropertySet
.is() )
449 Reference
< XBitmap
> xFillBitmap( xNewGraphic
, UNO_QUERY
);
450 if ( xFillBitmap
.is() )
453 sal_Bool bLogicalSize
;
455 Reference
< XPropertySet
>& rxPropertySet( aGraphicUserIter
->mxPropertySet
);
456 rxPropertySet
->setPropertyValue( TKGet( TK_FillBitmap
), Any( xFillBitmap
) );
457 if ( ( rxPropertySet
->getPropertyValue( TKGet( TK_FillBitmapLogicalSize
) ) >>= bLogicalSize
)
458 && ( rxPropertySet
->getPropertyValue( TKGet( TK_FillBitmapSizeX
) ) >>= aSize
.Width
)
459 && ( rxPropertySet
->getPropertyValue( TKGet( TK_FillBitmapSizeY
) ) >>= aSize
.Height
) )
461 if ( !aSize
.Width
|| !aSize
.Height
)
463 rxPropertySet
->setPropertyValue( TKGet( TK_FillBitmapLogicalSize
), Any( sal_True
) );
464 rxPropertySet
->setPropertyValue( TKGet( TK_FillBitmapSizeX
), Any( aGraphicUserIter
->maLogicalSize
.Width
) );
465 rxPropertySet
->setPropertyValue( TKGet( TK_FillBitmapSizeY
), Any( aGraphicUserIter
->maLogicalSize
.Height
) );
468 if ( aGraphicUserIter
->mxPagePropertySet
.is() )
469 aGraphicUserIter
->mxPagePropertySet
->setPropertyValue( TKGet( TK_Background
), Any( rxPropertySet
) );
489 ImpOptimizer::ImpOptimizer( const Reference
< XComponentContext
>& rxMSF
, const Reference
< XModel
>& rxModel
) :
492 mbJPEGCompression ( sal_False
),
493 mnJPEGQuality ( 90 ),
494 mbRemoveCropArea ( sal_False
),
495 mnImageResolution ( 0 ),
496 mbEmbedLinkedGraphics ( sal_True
),
497 mbOLEOptimization ( sal_False
),
498 mnOLEOptimizationType ( 0 ),
499 mbDeleteUnusedMasterPages ( sal_False
),
500 mbDeleteHiddenSlides ( sal_False
),
501 mbDeleteNotesPages ( sal_False
),
502 mbOpenNewDocument ( sal_True
)
506 // -----------------------------------------------------------------------------
508 ImpOptimizer::~ImpOptimizer()
512 // -----------------------------------------------------------------------------
514 void ImpOptimizer::DispatchStatus()
516 if ( mxStatusDispatcher
.is() )
519 aURL
.Protocol
= OUString( "vnd.com.sun.star.comp.SunPresentationMinimizer:" );
520 aURL
.Path
= OUString( "statusupdate" );
521 mxStatusDispatcher
->dispatch( aURL
, GetStatusSequence() );
525 // -----------------------------------------------------------------------------
527 sal_Bool
ImpOptimizer::Optimize()
530 if ( !maCustomShowName
.isEmpty() )
531 ImpExtractCustomShow( mxModel
, maCustomShowName
);
533 if ( mbDeleteUnusedMasterPages
)
535 SetStatusValue( TK_Progress
, Any( static_cast< sal_Int32
>( 40 ) ) );
536 SetStatusValue( TK_Status
, Any( TKGet( STR_DELETING_SLIDES
) ) );
538 ImpDeleteUnusedMasterPages( mxModel
);
541 if ( mbDeleteHiddenSlides
)
543 SetStatusValue( TK_Progress
, Any( static_cast< sal_Int32
>( 40 ) ) );
544 SetStatusValue( TK_Status
, Any( TKGet( STR_DELETING_SLIDES
) ) );
546 ImpDeleteHiddenSlides( mxModel
);
549 if ( mbDeleteNotesPages
)
551 SetStatusValue( TK_Status
, Any( TKGet( STR_DELETING_SLIDES
) ) );
553 ImpDeleteNotesPages( mxModel
);
556 if ( mbOLEOptimization
)
558 SetStatusValue( TK_Progress
, Any( static_cast< sal_Int32
>( 45 ) ) );
559 SetStatusValue( TK_Status
, Any( TKGet( STR_CREATING_OLE_REPLACEMENTS
) ) );
561 ImpConvertOLE( mxModel
, mnOLEOptimizationType
);
564 if ( mbJPEGCompression
|| mbRemoveCropArea
|| mnImageResolution
)
566 SetStatusValue( TK_Progress
, Any( static_cast< sal_Int32
>( 50 ) ) );
567 SetStatusValue( TK_Status
, Any( TKGet( STR_OPTIMIZING_GRAPHICS
) ) );
570 std::vector
< GraphicCollector::GraphicEntity
> aGraphicList
;
571 GraphicSettings
aGraphicSettings( mbJPEGCompression
, mnJPEGQuality
, mbRemoveCropArea
, mnImageResolution
, mbEmbedLinkedGraphics
);
572 GraphicCollector::CollectGraphics( mxMSF
, mxModel
, aGraphicSettings
, aGraphicList
);
573 CompressGraphics( *this, mxMSF
, aGraphicSettings
, aGraphicList
);
575 SetStatusValue( TK_Progress
, Any( static_cast< sal_Int32
>( 100 ) ) );
580 static void DispatchURL( Reference
< XComponentContext
> xContext
, OUString sURL
, Reference
< XFrame
> xFrame
)
584 Reference
< XURLTransformer
> xURLTransformer( URLTransformer::create(xContext
) );
586 aUrl
.Complete
= sURL
;
587 xURLTransformer
->parseStrict( aUrl
);
588 Sequence
< PropertyValue
> aArgs
;
589 Reference
< XDispatchProvider
> xDispatchProvider( xFrame
, UNO_QUERY_THROW
);
590 Reference
< XDispatch
> xDispatch
= xDispatchProvider
->queryDispatch( aUrl
, OUString(), 0 ); // "_self"
591 if ( xDispatch
.is() )
592 xDispatch
->dispatch( aUrl
, aArgs
);
599 // -----------------------------------------------------------------------------
601 sal_Bool
ImpOptimizer::Optimize( const Sequence
< PropertyValue
>& rArguments
)
603 sal_Bool bRet
= sal_True
;
607 sal_Int64 nEstimatedFileSize
= 0;
608 SetStatusValue( TK_Progress
, Any( static_cast< sal_Int32
>( 0 ) ) );
612 for ( i
= 0, nICount
= rArguments
.getLength(); i
< nICount
; i
++ )
614 switch( TKGet( rArguments
[ i
].Name
) )
616 case TK_StatusDispatcher
: rArguments
[ i
].Value
>>= mxStatusDispatcher
; break;
617 case TK_InformationDialog
: rArguments
[ i
].Value
>>= mxInformationDialog
; break;
620 com::sun::star::uno::Sequence
< com::sun::star::beans::PropertyValue
> aSettings
;
622 rArguments
[ i
].Value
>>= aSettings
;
623 for ( j
= 0, nJCount
= aSettings
.getLength(); j
< nJCount
; j
++ )
625 switch( TKGet( aSettings
[ j
].Name
) )
627 case TK_JPEGCompression
: aSettings
[ j
].Value
>>= mbJPEGCompression
; break;
628 case TK_JPEGQuality
: aSettings
[ j
].Value
>>= mnJPEGQuality
; break;
629 case TK_RemoveCropArea
: aSettings
[ j
].Value
>>= mbRemoveCropArea
; break;
630 case TK_ImageResolution
: aSettings
[ j
].Value
>>= mnImageResolution
; break;
631 case TK_EmbedLinkedGraphics
: aSettings
[ j
].Value
>>= mbEmbedLinkedGraphics
; break;
632 case TK_OLEOptimization
: aSettings
[ j
].Value
>>= mbOLEOptimization
; break;
633 case TK_OLEOptimizationType
: aSettings
[ j
].Value
>>= mnOLEOptimizationType
; break;
634 case TK_CustomShowName
: aSettings
[ j
].Value
>>= maCustomShowName
; break;
635 case TK_DeleteUnusedMasterPages
: aSettings
[ j
].Value
>>= mbDeleteUnusedMasterPages
; break;
636 case TK_DeleteHiddenSlides
: aSettings
[ j
].Value
>>= mbDeleteHiddenSlides
; break;
637 case TK_DeleteNotesPages
: aSettings
[ j
].Value
>>= mbDeleteNotesPages
; break;
638 case TK_SaveAsURL
: aSettings
[ j
].Value
>>= maSaveAsURL
; break;
639 case TK_FilterName
: aSettings
[ j
].Value
>>= maFilterName
; break;
640 case TK_OpenNewDocument
: aSettings
[ j
].Value
>>= mbOpenNewDocument
; break;
641 case TK_EstimatedFileSize
: aSettings
[ j
].Value
>>= nEstimatedFileSize
; break;
651 sal_Int64 nSourceSize
= 0;
652 sal_Int64 nDestSize
= 0;
654 Reference
< XFrame
> xSelf
;
655 if ( !maSaveAsURL
.isEmpty() )
658 SetStatusValue( TK_Progress
, Any( static_cast< sal_Int32
>( 10 ) ) );
659 SetStatusValue( TK_Status
, Any( TKGet( STR_DUPLICATING_PRESENTATION
) ) );
662 Reference
< XStorable
>xStorable( mxModel
, UNO_QUERY
);
663 if ( xStorable
.is() )
665 if ( xStorable
->hasLocation() )
666 nSourceSize
= PPPOptimizer::GetFileSize( xStorable
->getLocation() );
668 Sequence
< PropertyValue
> aArguments
;
669 if ( !maFilterName
.isEmpty() )
671 int nLength
= aArguments
.getLength();
672 aArguments
.realloc( nLength
+ 1 );
673 aArguments
[ nLength
].Name
= TKGet( TK_FilterName
);
674 aArguments
[ nLength
].Value
<<= maFilterName
;
676 xStorable
->storeToURL( maSaveAsURL
, aArguments
);
678 nSourceSize
= PPPOptimizer::GetFileSize( maSaveAsURL
);
680 SetStatusValue( TK_Progress
, Any( static_cast< sal_Int32
>( 30 ) ) );
681 SetStatusValue( TK_Status
, Any( TKGet( STR_DUPLICATING_PRESENTATION
) ) );
684 Reference
< XDesktop2
> xDesktop
= Desktop::create( mxMSF
);
685 xSelf
= xDesktop
->findFrame( TKGet( TK__blank
), FrameSearchFlag::CREATE
);
686 Reference
< XComponentLoader
> xComponentLoader( xSelf
, UNO_QUERY
);
688 Sequence
< PropertyValue
> aLoadProps( 1 );
689 aLoadProps
[ 0 ].Name
= TKGet( TK_Hidden
);
690 aLoadProps
[ 0 ].Value
<<= (sal_Bool
)( sal_True
);
691 mxModel
= Reference
< XModel
>( xComponentLoader
->loadComponentFromURL(
692 maSaveAsURL
, TKGet( TK__self
), 0, aLoadProps
), UNO_QUERY
);
696 // check if the document is ReadOnly -> error
697 Reference
< XStorable
> xStorable( mxModel
, UNO_QUERY
);
698 if ( xStorable
.is() && !xStorable
->isReadonly() )
700 mxModel
->lockControllers();
702 mxModel
->unlockControllers();
704 // clearing undo stack:
705 Reference
< XFrame
> xFrame( xSelf
.is() ? xSelf
: mxInformationDialog
);
708 const OUString
sSlot( "slot:27115" );
709 DispatchURL( mxMSF
, sSlot
, xFrame
);
713 if ( !maSaveAsURL
.isEmpty() )
715 if ( xStorable
.is() )
718 nDestSize
= PPPOptimizer::GetFileSize( maSaveAsURL
);
722 if ( mxInformationDialog
.is() )
724 InformationDialog
aInformationDialog( mxMSF
, mxInformationDialog
, maSaveAsURL
, mbOpenNewDocument
, nSourceSize
, nDestSize
, nEstimatedFileSize
);
725 aInformationDialog
.execute();
726 SetStatusValue( TK_OpenNewDocument
, Any( mbOpenNewDocument
) );
730 if ( !maSaveAsURL
.isEmpty() )
732 if ( mbOpenNewDocument
&& xSelf
.is() )
734 Reference
< awt::XWindow
> xContainerWindow( xSelf
->getContainerWindow() );
735 xContainerWindow
->setVisible( sal_True
);
739 Reference
< XComponent
> xComponent( mxModel
, UNO_QUERY
);
740 xComponent
->dispose();
743 if ( nSourceSize
&& nDestSize
)
745 SetStatusValue( TK_FileSizeSource
, Any( nSourceSize
) );
746 SetStatusValue( TK_FileSizeDestination
, Any( nDestSize
) );
755 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */