1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: impoptimizer.cxx,v $
13 * This file is part of OpenOffice.org.
15 * OpenOffice.org is free software: you can redistribute it and/or modify
16 * it under the terms of the GNU Lesser General Public License version 3
17 * only, as published by the Free Software Foundation.
19 * OpenOffice.org is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Lesser General Public License version 3 for more details
23 * (a copy is included in the LICENSE file that accompanied this code).
25 * You should have received a copy of the GNU Lesser General Public License
26 * version 3 along with OpenOffice.org. If not, see
27 * <http://www.openoffice.org/license.html>
28 * for a copy of the LGPLv3 License.
30 ************************************************************************/
32 // MARKER(update_precomp.py): autogen include statement, do not remove
33 #include "precompiled_sdext.hxx"
35 #include "impoptimizer.hxx"
36 #include "pppoptimizer.hxx"
37 #include "graphiccollector.hxx"
38 #include "pagecollector.hxx"
39 #include "informationdialog.hxx"
41 #include <unotools/localfilehelper.hxx>
42 #include <unotools/processfactory.hxx>
44 #include "com/sun/star/util/URL.hpp"
45 #include "com/sun/star/util/XURLTransformer.hpp"
46 #include <com/sun/star/beans/XPropertySet.hpp>
47 #include <com/sun/star/awt/Rectangle.hpp>
48 #include <com/sun/star/awt/Size.hpp>
49 #include <com/sun/star/util/MeasureUnit.hpp>
50 #include <com/sun/star/frame/XModel.hpp>
51 #include <com/sun/star/frame/XDesktop.hpp>
52 #include <com/sun/star/awt/XWindow.hpp>
53 #include <com/sun/star/frame/XStorable.hpp>
54 #ifndef _COM_SUN_STAR_FRAME_FrameSearchFlag_HPP_
55 #include <com/sun/star/frame/FrameSearchFlag.hpp>
57 #include <com/sun/star/frame/XDispatchProvider.hpp>
58 #include <com/sun/star/graphic/XGraphicProvider.hpp>
59 #include <unotools/configmgr.hxx>
60 #include <com/sun/star/lang/XServiceInfo.hpp>
61 #include <com/sun/star/container/XNamed.hpp>
62 #include <com/sun/star/drawing/XShapes.hpp>
63 #include <com/sun/star/drawing/XMasterPageTarget.hpp>
64 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
65 #include <com/sun/star/drawing/XMasterPagesSupplier.hpp>
66 #include <com/sun/star/presentation/XPresentationSupplier.hpp>
67 #include <com/sun/star/container/XNameAccess.hpp>
68 #include <com/sun/star/presentation/XPresentation.hpp>
69 #include <com/sun/star/presentation/XPresentationPage.hpp>
70 #include <com/sun/star/document/XFilter.hpp>
71 #include <com/sun/star/document/XExporter.hpp>
72 #ifndef _COM_SUN_STAR_UNO_RUNTIME_EXCEPTION_HPP_
73 #include <com/sun/star/uno/RuntimeException.hpp>
75 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
76 #include <com/sun/star/graphic/XGraphicProvider.hpp>
77 #include <com/sun/star/graphic/GraphicType.hpp>
78 #include <com/sun/star/io/XStream.hpp>
79 #include <com/sun/star/io/XSeekable.hpp>
80 #include <com/sun/star/frame/XComponentLoader.hpp>
81 #include <com/sun/star/util/URL.hpp>
83 using namespace ::std
;
84 using namespace ::rtl
;
85 using namespace ::com::sun::star
;
86 using namespace ::com::sun::star::io
;
87 using namespace ::com::sun::star::awt
;
88 using namespace ::com::sun::star::uno
;
89 using namespace ::com::sun::star::lang
;
90 using namespace ::com::sun::star::util
;
91 using namespace ::com::sun::star::frame
;
92 using namespace ::com::sun::star::beans
;
93 using namespace ::com::sun::star::drawing
;
94 using namespace ::com::sun::star::graphic
;
95 using namespace ::com::sun::star::document
;
96 using namespace ::com::sun::star::container
;
97 using namespace ::com::sun::star::presentation
;
99 void ImpExtractCustomShow( const Reference
< XModel
>& rxModel
, const OUString
& rCustomShowName
)
101 vector
< Reference
< XDrawPage
> > vNonUsedPageList
;
104 PageCollector::CollectNonCustomShowPages( rxModel
, rCustomShowName
, vNonUsedPageList
);
105 Reference
< XDrawPagesSupplier
> xDrawPagesSupplier( rxModel
, UNO_QUERY_THROW
);
106 Reference
< XDrawPages
> xDrawPages( xDrawPagesSupplier
->getDrawPages(), UNO_QUERY_THROW
);
107 vector
< Reference
< XDrawPage
> >::iterator
aIter( vNonUsedPageList
.begin() );
108 while( aIter
!= vNonUsedPageList
.end() )
109 xDrawPages
->remove( *aIter
++ );
117 void ImpDeleteUnusedMasterPages( const Reference
< XModel
>& rxModel
)
119 vector
< PageCollector::MasterPageEntity
> aMasterPageList
;
120 PageCollector::CollectMasterPages( rxModel
, aMasterPageList
);
122 // now master pages that are not marked can be deleted
123 Reference
< XMasterPagesSupplier
> xMasterPagesSupplier( rxModel
, UNO_QUERY_THROW
);
124 Reference
< XDrawPages
> xMasterPages( xMasterPagesSupplier
->getMasterPages(), UNO_QUERY_THROW
);
125 vector
< PageCollector::MasterPageEntity
>::iterator
aIter( aMasterPageList
.begin() );
126 while( aIter
!= aMasterPageList
.end() )
129 xMasterPages
->remove( aIter
->xMasterPage
);
134 void ImpDeleteHiddenSlides( const Reference
< XModel
>& rxModel
)
138 Reference
< XDrawPagesSupplier
> xDrawPagesSupplier( rxModel
, UNO_QUERY_THROW
);
139 Reference
< XDrawPages
> xDrawPages( xDrawPagesSupplier
->getDrawPages(), UNO_QUERY_THROW
);
140 for( sal_Int32 i
= 0; i
< xDrawPages
->getCount(); i
++ )
142 Reference
< XDrawPage
> xDrawPage( xDrawPages
->getByIndex( i
), UNO_QUERY_THROW
);
143 Reference
< XPropertySet
> xPropSet( xDrawPage
, UNO_QUERY_THROW
);
145 sal_Bool bVisible
= sal_True
;
146 const OUString
sVisible( RTL_CONSTASCII_USTRINGPARAM( "Visible" ) );
147 if ( xPropSet
->getPropertyValue( sVisible
) >>= bVisible
)
151 xDrawPages
->remove( xDrawPage
);
162 void ImpDeleteNotesPages( const Reference
< XModel
>& rxModel
)
166 Reference
< XDrawPagesSupplier
> xDrawPagesSupplier( rxModel
, UNO_QUERY_THROW
);
167 Reference
< XDrawPages
> xDrawPages( xDrawPagesSupplier
->getDrawPages(), UNO_QUERY_THROW
);
168 sal_Int32 i
, nPages
= xDrawPages
->getCount();
169 for( i
= 0; i
< nPages
; i
++ )
171 Reference
< XPresentationPage
> xPresentationPage( xDrawPages
->getByIndex( i
), UNO_QUERY_THROW
);
172 Reference
< XPropertySet
> xPropSet( xPresentationPage
->getNotesPage(), UNO_QUERY_THROW
);
173 Reference
< XShapes
> xShapes( xPropSet
, UNO_QUERY_THROW
);
174 while( xShapes
->getCount() )
175 xShapes
->remove( Reference
< XShape
>( xShapes
->getByIndex( xShapes
->getCount() - 1 ), UNO_QUERY_THROW
) );
177 const OUString
sLayout( RTL_CONSTASCII_USTRINGPARAM( "Layout" ) );
178 xPropSet
->setPropertyValue( sLayout
, Any( (sal_Int16
)21 ) );
186 void ImpConvertOLE( const Reference
< XModel
>& rxModel
, sal_Int32 nOLEOptimizationType
)
190 Reference
< XDrawPagesSupplier
> xDrawPagesSupplier( rxModel
, UNO_QUERY_THROW
);
191 Reference
< XDrawPages
> xDrawPages( xDrawPagesSupplier
->getDrawPages(), UNO_QUERY_THROW
);
192 for ( sal_Int32 i
= 0; i
< xDrawPages
->getCount(); i
++ )
194 Reference
< XShapes
> xShapes( xDrawPages
->getByIndex( i
), UNO_QUERY_THROW
);
195 for ( sal_Int32 j
= 0; j
< xShapes
->getCount(); j
++ )
197 const OUString
sOLE2Shape( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.OLE2Shape" ) );
198 Reference
< XShape
> xShape( xShapes
->getByIndex( j
), UNO_QUERY_THROW
);
199 if ( xShape
->getShapeType() == sOLE2Shape
)
201 Reference
< XPropertySet
> xPropSet( xShape
, UNO_QUERY_THROW
);
203 sal_Bool bConvertOLE
= nOLEOptimizationType
== 0;
204 if ( nOLEOptimizationType
== 1 )
206 sal_Bool bIsInternal
= sal_True
;
207 xPropSet
->getPropertyValue( TKGet( TK_IsInternal
) ) >>= bIsInternal
;
208 bConvertOLE
= !bIsInternal
;
212 Reference
< XGraphic
> xGraphic
;
213 if ( xPropSet
->getPropertyValue( TKGet( TK_Graphic
) ) >>= xGraphic
)
215 const OUString
sGraphicShape( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.GraphicObjectShape" ) );
216 Reference
< XMultiServiceFactory
> xFact( rxModel
, UNO_QUERY_THROW
);
217 Reference
< XShape
> xShape2( xFact
->createInstance( sGraphicShape
), UNO_QUERY_THROW
);
218 xShapes
->add( xShape2
);
219 xShape2
->setPosition( xShape
->getPosition() );
220 xShape2
->setSize( xShape
->getSize() );
221 Reference
< XPropertySet
> xPropSet2( xShape2
, UNO_QUERY_THROW
);
222 xPropSet2
->setPropertyValue( TKGet( TK_Graphic
), Any( xGraphic
) );
223 xShapes
->remove( xShape
);
224 xPropSet2
->setPropertyValue( TKGet( TK_ZOrder
), Any( j
) );
236 void ImpCompressGraphic( Reference
< XGraphicProvider
>& rxGraphicProvider
, const Reference
< XGraphic
>& rxGraphic
, Reference
< XOutputStream
>& rxOutputStream
,
237 const OUString
& rDestMimeType
, const awt::Size
& rLogicalSize
, sal_Int32 nJPEGQuality
, sal_Int32 nImageResolution
, sal_Bool bRemoveCropping
, const text::GraphicCrop
& rGraphicCropLogic
)
241 if ( rxGraphicProvider
.is() && rxOutputStream
.is() )
243 Sequence
< PropertyValue
> aFilterData( 8 );
244 aFilterData
[ 0 ].Name
= TKGet( TK_ImageResolution
);
245 aFilterData
[ 0 ].Value
<<= nImageResolution
;
246 aFilterData
[ 1 ].Name
= TKGet( TK_ColorMode
); // todo: jpeg color mode (0->true color, 1->greyscale)
247 aFilterData
[ 1 ].Value
<<= (sal_Int32
)0;
248 aFilterData
[ 2 ].Name
= TKGet( TK_Quality
); // quality that is used if we export to jpeg
249 aFilterData
[ 2 ].Value
<<= nJPEGQuality
;
250 aFilterData
[ 3 ].Name
= TKGet( TK_Compression
); // compression that is used if we export to png
251 aFilterData
[ 3 ].Value
<<= (sal_Int32
)6;
252 aFilterData
[ 4 ].Name
= TKGet( TK_Interlaced
); // interlaced is turned off if we export to png
253 aFilterData
[ 4 ].Value
<<= (sal_Int32
)0;
254 aFilterData
[ 5 ].Name
= TKGet( TK_LogicalSize
);
255 aFilterData
[ 5 ].Value
<<= rLogicalSize
;
256 aFilterData
[ 6 ].Name
= TKGet( TK_RemoveCropArea
);
257 aFilterData
[ 6 ].Value
<<= bRemoveCropping
;
258 aFilterData
[ 7 ].Name
= TKGet( TK_GraphicCropLogic
);
259 aFilterData
[ 7 ].Value
<<= rGraphicCropLogic
;
261 Sequence
< PropertyValue
> aArgs( 3 );
262 aArgs
[ 0 ].Name
= TKGet( TK_MimeType
); // the GraphicProvider is using "MimeType", the GraphicExporter "MediaType"...
263 aArgs
[ 0 ].Value
<<= rDestMimeType
;
264 aArgs
[ 1 ].Name
= TKGet( TK_OutputStream
);
265 aArgs
[ 1 ].Value
<<= rxOutputStream
;
266 aArgs
[ 2 ].Name
= TKGet( TK_FilterData
);
267 aArgs
[ 2 ].Value
<<= aFilterData
;
269 rxGraphicProvider
->storeGraphic( rxGraphic
, aArgs
);
277 Reference
< XGraphic
> ImpCompressGraphic( const Reference
< XComponentContext
>& rxMSF
,
278 const Reference
< XGraphic
>& xGraphic
, const awt::Size
& aLogicalSize
, const text::GraphicCrop
& aGraphicCropLogic
,
279 const GraphicSettings
& rGraphicSettings
)
281 Reference
< XGraphic
> xNewGraphic
;
284 OUString aSourceMimeType
;
285 Reference
< XPropertySet
> xGraphicPropertySet( xGraphic
, UNO_QUERY_THROW
);
286 if ( xGraphicPropertySet
->getPropertyValue( TKGet( TK_MimeType
) ) >>= aSourceMimeType
)
288 sal_Int8
nGraphicType( xGraphic
->getType() );
289 if ( nGraphicType
== com::sun::star::graphic::GraphicType::PIXEL
)
291 sal_Bool bTransparent
= sal_False
;
292 sal_Bool bAlpha
= sal_False
;
293 sal_Bool bAnimated
= sal_False
;
295 awt::Size
aSourceSizePixel( 0, 0 );
296 text::GraphicCrop
aGraphicCropPixel( 0, 0, 0, 0 );
298 if ( ( xGraphicPropertySet
->getPropertyValue( TKGet( TK_SizePixel
) ) >>= aSourceSizePixel
) &&
299 ( xGraphicPropertySet
->getPropertyValue( TKGet( TK_Transparent
) ) >>= bTransparent
) &&
300 ( xGraphicPropertySet
->getPropertyValue( TKGet( TK_Alpha
) ) >>= bAlpha
) &&
301 ( xGraphicPropertySet
->getPropertyValue( TKGet( TK_Animated
) ) >>= bAnimated
) )
303 awt::Size
aDestSizePixel( aSourceSizePixel
);
306 sal_Bool bNeedsOptimizing
= sal_False
;
307 sal_Bool
bRemoveCropArea( rGraphicSettings
.mbRemoveCropArea
);
309 // cropping has to be removed from SourceSizePixel
310 if ( aGraphicCropLogic
.Left
|| aGraphicCropLogic
.Top
|| aGraphicCropLogic
.Right
|| aGraphicCropLogic
.Bottom
)
312 const awt::Size
aSize100thMM( GraphicCollector::GetOriginalSize( rxMSF
, xGraphic
) );
314 if ( bRemoveCropArea
)
315 bNeedsOptimizing
= sal_True
;
317 if ( aSize100thMM
.Width
&& aSize100thMM
.Height
)
319 aGraphicCropPixel
.Left
= static_cast< sal_Int32
>( ( (double)aSourceSizePixel
.Width
* aGraphicCropLogic
.Left
) / aSize100thMM
.Width
);
320 aGraphicCropPixel
.Top
= static_cast< sal_Int32
>( ( (double)aSourceSizePixel
.Height
* aGraphicCropLogic
.Top
) / aSize100thMM
.Height
);
321 aGraphicCropPixel
.Right
= static_cast< sal_Int32
>( ( (double)aSourceSizePixel
.Width
* ( aSize100thMM
.Width
- aGraphicCropLogic
.Right
) ) / aSize100thMM
.Width
);
322 aGraphicCropPixel
.Bottom
= static_cast< sal_Int32
>( ( (double)aSourceSizePixel
.Height
* ( aSize100thMM
.Height
- aGraphicCropLogic
.Bottom
) ) / aSize100thMM
.Height
);
324 // first calculating new SourceSizePixel by removing the cropped area
325 aSourceSizePixel
.Width
= aGraphicCropPixel
.Right
- aGraphicCropPixel
.Left
;
326 aSourceSizePixel
.Height
= aGraphicCropPixel
.Bottom
- aGraphicCropPixel
.Top
;
330 bRemoveCropArea
= sal_False
;
333 if ( ( aSourceSizePixel
.Width
> 0 ) && ( aSourceSizePixel
.Height
> 0 ) )
335 OUString
aDestMimeType( RTL_CONSTASCII_USTRINGPARAM( "image/png" ) );
336 if ( rGraphicSettings
.mbJPEGCompression
&& !bTransparent
&& !bAlpha
&& !bAnimated
)
338 aDestMimeType
= OUString( RTL_CONSTASCII_USTRINGPARAM( "image/jpeg" ) );
339 // if( aSourceMimeType != aDestMimeType )
340 bNeedsOptimizing
= sal_True
;
342 if ( bRemoveCropArea
)
343 aDestSizePixel
= aSourceSizePixel
;
344 if ( rGraphicSettings
.mnImageResolution
&& aLogicalSize
.Width
&& aLogicalSize
.Height
)
346 const double fSourceDPIX
= ((double)aSourceSizePixel
.Width
/ ((double)aLogicalSize
.Width
/ 2540.0 ));
347 const double fSourceDPIY
= ((double)aSourceSizePixel
.Height
/ ((double)aLogicalSize
.Height
/ 2540.0 ));
349 // check, if the bitmap DPI exceeds the maximum DPI
350 if( ( fSourceDPIX
> rGraphicSettings
.mnImageResolution
) || ( fSourceDPIY
> rGraphicSettings
.mnImageResolution
) )
352 const double fNewSizePixelX
= ((double)aDestSizePixel
.Width
* rGraphicSettings
.mnImageResolution
) / fSourceDPIX
;
353 const double fNewSizePixelY
= ((double)aDestSizePixel
.Height
* rGraphicSettings
.mnImageResolution
) / fSourceDPIY
;
355 aDestSizePixel
= awt::Size( (sal_Int32
)fNewSizePixelX
, (sal_Int32
)fNewSizePixelY
);
356 bNeedsOptimizing
= sal_True
;
359 if ( bNeedsOptimizing
&& aDestSizePixel
.Width
&& aDestSizePixel
.Height
)
361 Reference
< XStream
> xTempFile( rxMSF
->getServiceManager()->createInstanceWithContext( OUString::createFromAscii( "com.sun.star.io.TempFile" ), rxMSF
), UNO_QUERY_THROW
);
362 Reference
< XOutputStream
> xOutputStream( xTempFile
->getOutputStream() );
363 Reference
< XGraphicProvider
> xGraphicProvider( rxMSF
->getServiceManager()->createInstanceWithContext( OUString::createFromAscii( "com.sun.star.graphic.GraphicProvider" ), rxMSF
), UNO_QUERY_THROW
);
365 ImpCompressGraphic( xGraphicProvider
, xGraphic
, xOutputStream
, aDestMimeType
, aLogicalSize
, rGraphicSettings
.mnJPEGQuality
, rGraphicSettings
.mnImageResolution
, bRemoveCropArea
, 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
);
378 else // this is a metafile
380 rtl::OUString
aDestMimeType( aSourceMimeType
);
381 Reference
< XStream
> xTempFile( rxMSF
->getServiceManager()->createInstanceWithContext( OUString::createFromAscii( "com.sun.star.io.TempFile" ), rxMSF
), UNO_QUERY_THROW
);
382 Reference
< XOutputStream
> xOutputStream( xTempFile
->getOutputStream() );
383 Reference
< XGraphicProvider
> xGraphicProvider( rxMSF
->getServiceManager()->createInstanceWithContext( OUString::createFromAscii( "com.sun.star.graphic.GraphicProvider" ), rxMSF
), UNO_QUERY_THROW
);
384 ImpCompressGraphic( xGraphicProvider
, xGraphic
, xOutputStream
, aDestMimeType
, aLogicalSize
, rGraphicSettings
.mnJPEGQuality
, rGraphicSettings
.mnImageResolution
, sal_False
, aGraphicCropLogic
);
385 Reference
< XInputStream
> xInputStream( xTempFile
->getInputStream() );
386 Reference
< XSeekable
> xSeekable( xInputStream
, UNO_QUERY_THROW
);
387 xSeekable
->seek( 0 );
388 Sequence
< PropertyValue
> aArgs( 1 );
389 aArgs
[ 0 ].Name
= TKGet( TK_InputStream
);
390 aArgs
[ 0 ].Value
<<= xInputStream
;
391 xNewGraphic
= xGraphicProvider
->queryGraphic( aArgs
);
401 void CompressGraphics( ImpOptimizer
& rOptimizer
, const Reference
< XComponentContext
>& rxMSF
, const GraphicSettings
& rGraphicSettings
,
402 std::vector
< GraphicCollector::GraphicEntity
>& rGraphicList
)
406 std::vector
< GraphicCollector::GraphicEntity
>::iterator
aGraphicIter( rGraphicList
.begin() );
407 std::vector
< GraphicCollector::GraphicEntity
>::iterator
aGraphicIEnd( rGraphicList
.end() );
409 while( aGraphicIter
!= aGraphicIEnd
)
412 sal_Int32 nProgress
= static_cast< sal_Int32
>( 40.0 * ( i
/ static_cast< double >( rGraphicList
.size() ) ) ) + 50;
413 rOptimizer
.SetStatusValue( TK_Progress
, Any( static_cast< sal_Int32
>( nProgress
) ) );
414 rOptimizer
.DispatchStatus();
416 GraphicSettings
aGraphicSettings( rGraphicSettings
);
417 aGraphicSettings
.mbRemoveCropArea
= aGraphicIter
->mbRemoveCropArea
;
419 Reference
< XPropertySet
> xNewGraphicPropertySet( aGraphicIter
->mxGraphic
, UNO_QUERY_THROW
);
420 awt::Size
aSize100thMM( GraphicCollector::GetOriginalSize( rxMSF
, aGraphicIter
->mxGraphic
) );
421 Reference
< XGraphic
> xNewGraphic( ImpCompressGraphic( rxMSF
, aGraphicIter
->mxGraphic
, aGraphicIter
->maLogicalSize
, aGraphicIter
->maGraphicCropLogic
, aGraphicSettings
) );
422 if ( xNewGraphic
.is() )
424 // applying graphic to each user
425 std::vector
< GraphicCollector::GraphicUser
>::iterator
aGraphicUserIter( aGraphicIter
->maUser
.begin() );
426 while( aGraphicUserIter
!= aGraphicIter
->maUser
.end() )
428 if ( aGraphicUserIter
->mxShape
.is() )
430 rtl::OUString sEmptyGraphicURL
;
431 Reference
< XPropertySet
> xShapePropertySet( aGraphicUserIter
->mxShape
, UNO_QUERY_THROW
);
432 xShapePropertySet
->setPropertyValue( TKGet( TK_GraphicURL
), Any( sEmptyGraphicURL
) );
433 xShapePropertySet
->setPropertyValue( TKGet( TK_Graphic
), Any( xNewGraphic
) );
435 if ( aGraphicUserIter
->maGraphicCropLogic
.Left
|| aGraphicUserIter
->maGraphicCropLogic
.Top
436 || aGraphicUserIter
->maGraphicCropLogic
.Right
|| aGraphicUserIter
->maGraphicCropLogic
.Bottom
)
437 { // removing crop area was not possible or should't been applied
438 text::GraphicCrop
aGraphicCropLogic( 0, 0, 0, 0 );
439 if ( !aGraphicSettings
.mbRemoveCropArea
)
441 awt::Size
aNewSize( GraphicCollector::GetOriginalSize( rxMSF
, xNewGraphic
) );
442 aGraphicCropLogic
.Left
= (sal_Int32
)((double)aGraphicUserIter
->maGraphicCropLogic
.Left
* ((double)aNewSize
.Width
/ (double)aSize100thMM
.Width
));
443 aGraphicCropLogic
.Top
= (sal_Int32
)((double)aGraphicUserIter
->maGraphicCropLogic
.Top
* ((double)aNewSize
.Height
/ (double)aSize100thMM
.Height
));
444 aGraphicCropLogic
.Right
= (sal_Int32
)((double)aGraphicUserIter
->maGraphicCropLogic
.Right
* ((double)aNewSize
.Width
/ (double)aSize100thMM
.Width
));
445 aGraphicCropLogic
.Bottom
= (sal_Int32
)((double)aGraphicUserIter
->maGraphicCropLogic
.Bottom
* ((double)aNewSize
.Height
/ (double)aSize100thMM
.Height
));
447 xShapePropertySet
->setPropertyValue( TKGet( TK_GraphicCrop
), Any( aGraphicCropLogic
) );
450 else if ( aGraphicUserIter
->mxPropertySet
.is() )
452 Reference
< XBitmap
> xFillBitmap( xNewGraphic
, UNO_QUERY
);
453 if ( xFillBitmap
.is() )
456 sal_Bool bLogicalSize
;
458 Reference
< XPropertySet
>& rxPropertySet( aGraphicUserIter
->mxPropertySet
);
459 rxPropertySet
->setPropertyValue( TKGet( TK_FillBitmap
), Any( xFillBitmap
) );
460 if ( ( rxPropertySet
->getPropertyValue( TKGet( TK_FillBitmapLogicalSize
) ) >>= bLogicalSize
)
461 && ( rxPropertySet
->getPropertyValue( TKGet( TK_FillBitmapSizeX
) ) >>= aSize
.Width
)
462 && ( rxPropertySet
->getPropertyValue( TKGet( TK_FillBitmapSizeY
) ) >>= aSize
.Height
) )
464 if ( !aSize
.Width
|| !aSize
.Height
)
466 rxPropertySet
->setPropertyValue( TKGet( TK_FillBitmapLogicalSize
), Any( sal_True
) );
467 rxPropertySet
->setPropertyValue( TKGet( TK_FillBitmapSizeX
), Any( aGraphicUserIter
->maLogicalSize
.Width
) );
468 rxPropertySet
->setPropertyValue( TKGet( TK_FillBitmapSizeY
), Any( aGraphicUserIter
->maLogicalSize
.Height
) );
471 if ( aGraphicUserIter
->mxPagePropertySet
.is() )
472 aGraphicUserIter
->mxPagePropertySet
->setPropertyValue( TKGet( TK_Background
), Any( rxPropertySet
) );
490 ImpOptimizer::ImpOptimizer( const Reference
< XComponentContext
>& rxMSF
, const Reference
< XModel
>& rxModel
) :
493 mbJPEGCompression ( sal_False
),
494 mnJPEGQuality ( 90 ),
495 mbRemoveCropArea ( sal_False
),
496 mnImageResolution ( 0 ),
497 mbEmbedLinkedGraphics ( sal_True
),
498 mbOLEOptimization ( sal_False
),
499 mnOLEOptimizationType ( 0 ),
500 mbDeleteUnusedMasterPages ( sal_False
),
501 mbDeleteHiddenSlides ( sal_False
),
502 mbDeleteNotesPages ( sal_False
),
503 mbOpenNewDocument ( sal_True
)
507 // -----------------------------------------------------------------------------
509 ImpOptimizer::~ImpOptimizer()
513 // -----------------------------------------------------------------------------
515 void ImpOptimizer::DispatchStatus()
517 if ( mxStatusDispatcher
.is() )
520 aURL
.Protocol
= OUString( RTL_CONSTASCII_USTRINGPARAM( "vnd.com.sun.star.comp.SunPresentationMinimizer:" ) );
521 aURL
.Path
= OUString( RTL_CONSTASCII_USTRINGPARAM( "statusupdate" ) );
522 mxStatusDispatcher
->dispatch( aURL
, GetStatusSequence() );
526 // -----------------------------------------------------------------------------
528 sal_Bool
ImpOptimizer::Optimize()
531 if ( maCustomShowName
.getLength() )
532 ImpExtractCustomShow( mxModel
, maCustomShowName
);
534 if ( mbDeleteUnusedMasterPages
)
536 SetStatusValue( TK_Progress
, Any( static_cast< sal_Int32
>( 40 ) ) );
537 SetStatusValue( TK_Status
, Any( TKGet( STR_DELETING_SLIDES
) ) );
539 ImpDeleteUnusedMasterPages( mxModel
);
542 if ( mbDeleteHiddenSlides
)
544 SetStatusValue( TK_Progress
, Any( static_cast< sal_Int32
>( 40 ) ) );
545 SetStatusValue( TK_Status
, Any( TKGet( STR_DELETING_SLIDES
) ) );
547 ImpDeleteHiddenSlides( mxModel
);
550 if ( mbDeleteNotesPages
)
552 SetStatusValue( TK_Status
, Any( TKGet( STR_DELETING_SLIDES
) ) );
554 ImpDeleteNotesPages( mxModel
);
557 if ( mbOLEOptimization
)
559 SetStatusValue( TK_Progress
, Any( static_cast< sal_Int32
>( 45 ) ) );
560 SetStatusValue( TK_Status
, Any( TKGet( STR_CREATING_OLE_REPLACEMENTS
) ) );
562 ImpConvertOLE( mxModel
, mnOLEOptimizationType
);
565 if ( mbJPEGCompression
|| mbRemoveCropArea
|| mnImageResolution
)
567 SetStatusValue( TK_Progress
, Any( static_cast< sal_Int32
>( 50 ) ) );
568 SetStatusValue( TK_Status
, Any( TKGet( STR_OPTIMIZING_GRAPHICS
) ) );
571 std::vector
< GraphicCollector::GraphicEntity
> aGraphicList
;
572 GraphicSettings
aGraphicSettings( mbJPEGCompression
, mnJPEGQuality
, mbRemoveCropArea
, mnImageResolution
, mbEmbedLinkedGraphics
);
573 GraphicCollector::CollectGraphics( mxMSF
, mxModel
, aGraphicSettings
, aGraphicList
);
574 CompressGraphics( *this, mxMSF
, aGraphicSettings
, aGraphicList
);
576 SetStatusValue( TK_Progress
, Any( static_cast< sal_Int32
>( 100 ) ) );
581 static void DispatchURL( Reference
< XComponentContext
> xMSF
, OUString sURL
, Reference
< XFrame
> xFrame
)
585 Reference
< XURLTransformer
> xURLTransformer( xMSF
->getServiceManager()->createInstanceWithContext(
586 OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ) ), xMSF
), UNO_QUERY_THROW
);
588 aUrl
.Complete
= sURL
;
589 xURLTransformer
->parseStrict( aUrl
);
590 Sequence
< PropertyValue
> aArgs
;
591 Reference
< XDispatchProvider
> xDispatchProvider( xFrame
, UNO_QUERY_THROW
);
592 Reference
< XDispatch
> xDispatch
= xDispatchProvider
->queryDispatch( aUrl
, OUString(), 0 ); // "_self"
593 if ( xDispatch
.is() )
594 xDispatch
->dispatch( aUrl
, aArgs
);
601 // -----------------------------------------------------------------------------
603 sal_Bool
ImpOptimizer::Optimize( const Sequence
< PropertyValue
>& rArguments
)
605 sal_Bool bRet
= sal_True
;
609 sal_Int64 nEstimatedFileSize
= 0;
610 SetStatusValue( TK_Progress
, Any( static_cast< sal_Int32
>( 0 ) ) );
614 for ( i
= 0, nICount
= rArguments
.getLength(); i
< nICount
; i
++ )
616 switch( TKGet( rArguments
[ i
].Name
) )
618 case TK_StatusDispatcher
: rArguments
[ i
].Value
>>= mxStatusDispatcher
; break;
619 case TK_InformationDialog
: rArguments
[ i
].Value
>>= mxInformationDialog
; break;
622 com::sun::star::uno::Sequence
< com::sun::star::beans::PropertyValue
> aSettings
;
624 rArguments
[ i
].Value
>>= aSettings
;
625 for ( j
= 0, nJCount
= aSettings
.getLength(); j
< nJCount
; j
++ )
627 switch( TKGet( aSettings
[ j
].Name
) )
629 case TK_JPEGCompression
: aSettings
[ j
].Value
>>= mbJPEGCompression
; break;
630 case TK_JPEGQuality
: aSettings
[ j
].Value
>>= mnJPEGQuality
; break;
631 case TK_RemoveCropArea
: aSettings
[ j
].Value
>>= mbRemoveCropArea
; break;
632 case TK_ImageResolution
: aSettings
[ j
].Value
>>= mnImageResolution
; break;
633 case TK_EmbedLinkedGraphics
: aSettings
[ j
].Value
>>= mbEmbedLinkedGraphics
; break;
634 case TK_OLEOptimization
: aSettings
[ j
].Value
>>= mbOLEOptimization
; break;
635 case TK_OLEOptimizationType
: aSettings
[ j
].Value
>>= mnOLEOptimizationType
; break;
636 case TK_CustomShowName
: aSettings
[ j
].Value
>>= maCustomShowName
; break;
637 case TK_DeleteUnusedMasterPages
: aSettings
[ j
].Value
>>= mbDeleteUnusedMasterPages
; break;
638 case TK_DeleteHiddenSlides
: aSettings
[ j
].Value
>>= mbDeleteHiddenSlides
; break;
639 case TK_DeleteNotesPages
: aSettings
[ j
].Value
>>= mbDeleteNotesPages
; break;
640 case TK_SaveAsURL
: aSettings
[ j
].Value
>>= maSaveAsURL
; break;
641 case TK_FilterName
: aSettings
[ j
].Value
>>= maFilterName
; break;
642 case TK_OpenNewDocument
: aSettings
[ j
].Value
>>= mbOpenNewDocument
; break;
643 case TK_EstimatedFileSize
: aSettings
[ j
].Value
>>= nEstimatedFileSize
; break;
653 sal_Int64 nSourceSize
= 0;
654 sal_Int64 nDestSize
= 0;
656 Reference
< XFrame
> xSelf
;
657 if ( maSaveAsURL
.getLength() )
660 SetStatusValue( TK_Progress
, Any( static_cast< sal_Int32
>( 10 ) ) );
661 SetStatusValue( TK_Status
, Any( TKGet( STR_DUPLICATING_PRESENTATION
) ) );
664 Reference
< XStorable
>xStorable( mxModel
, UNO_QUERY
);
665 if ( xStorable
.is() )
667 if ( xStorable
->hasLocation() )
668 nSourceSize
= PPPOptimizer::GetFileSize( xStorable
->getLocation() );
670 Sequence
< PropertyValue
> aArguments
;
671 if ( maFilterName
.getLength() )
673 int nLength
= aArguments
.getLength();
674 aArguments
.realloc( nLength
+ 1 );
675 aArguments
[ nLength
].Name
= TKGet( TK_FilterName
);
676 aArguments
[ nLength
].Value
<<= maFilterName
;
678 xStorable
->storeToURL( maSaveAsURL
, aArguments
);
680 nSourceSize
= PPPOptimizer::GetFileSize( maSaveAsURL
);
682 SetStatusValue( TK_Progress
, Any( static_cast< sal_Int32
>( 30 ) ) );
683 SetStatusValue( TK_Status
, Any( TKGet( STR_DUPLICATING_PRESENTATION
) ) );
686 Reference
< XDesktop
> xDesktop( mxMSF
->getServiceManager()->createInstanceWithContext(
687 OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ) ), mxMSF
), UNO_QUERY
);
688 Reference
< XFrame
> xFrame( xDesktop
, UNO_QUERY
);
689 xSelf
= xFrame
->findFrame( TKGet( TK__blank
), FrameSearchFlag::CREATE
);
690 Reference
< XComponentLoader
> xComponentLoader( xSelf
, UNO_QUERY
);
692 Sequence
< PropertyValue
> aLoadProps( 1 );
693 aLoadProps
[ 0 ].Name
= TKGet( TK_Hidden
);
694 aLoadProps
[ 0 ].Value
<<= (sal_Bool
)( sal_True
);
695 mxModel
= Reference
< XModel
>( xComponentLoader
->loadComponentFromURL(
696 maSaveAsURL
, TKGet( TK__self
), 0, aLoadProps
), UNO_QUERY
);
700 // check if the document is ReadOnly -> error
701 Reference
< XStorable
> xStorable( mxModel
, UNO_QUERY
);
702 if ( xStorable
.is() && !xStorable
->isReadonly() )
704 mxModel
->lockControllers();
706 mxModel
->unlockControllers();
708 // clearing undo stack:
709 Reference
< XFrame
> xFrame( xSelf
.is() ? xSelf
: mxInformationDialog
);
712 const OUString
sSlot( RTL_CONSTASCII_USTRINGPARAM( "slot:27115" ) );
713 DispatchURL( mxMSF
, sSlot
, xFrame
);
717 if ( maSaveAsURL
.getLength() )
719 if ( xStorable
.is() )
722 nDestSize
= PPPOptimizer::GetFileSize( maSaveAsURL
);
726 if ( mxInformationDialog
.is() )
728 InformationDialog
aInformationDialog( mxMSF
, mxInformationDialog
, maSaveAsURL
, mbOpenNewDocument
, nSourceSize
, nDestSize
, nEstimatedFileSize
);
729 aInformationDialog
.execute();
730 SetStatusValue( TK_OpenNewDocument
, Any( mbOpenNewDocument
) );
734 if ( maSaveAsURL
.getLength() )
736 if ( mbOpenNewDocument
&& xSelf
.is() )
738 Reference
< awt::XWindow
> xContainerWindow( xSelf
->getContainerWindow() );
739 xContainerWindow
->setVisible( sal_True
);
743 Reference
< XComponent
> xComponent( mxModel
, UNO_QUERY
);
744 xComponent
->dispose();
747 if ( nSourceSize
&& nDestSize
)
749 SetStatusValue( TK_FileSizeSource
, Any( nSourceSize
) );
750 SetStatusValue( TK_FileSizeDestination
, Any( nDestSize
) );