Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include "impoptimizer.hxx"
31 : : #include "pppoptimizer.hxx"
32 : : #include "graphiccollector.hxx"
33 : : #include "pagecollector.hxx"
34 : : #include "informationdialog.hxx"
35 : :
36 : : #include <unotools/localfilehelper.hxx>
37 : : #include <vector>
38 : : #include "com/sun/star/util/URL.hpp"
39 : : #include "com/sun/star/util/XURLTransformer.hpp"
40 : : #include <com/sun/star/beans/XPropertySet.hpp>
41 : : #include <com/sun/star/awt/Rectangle.hpp>
42 : : #include <com/sun/star/awt/Size.hpp>
43 : : #include <com/sun/star/util/MeasureUnit.hpp>
44 : : #include <com/sun/star/frame/XModel.hpp>
45 : : #include <com/sun/star/frame/XDesktop.hpp>
46 : : #include <com/sun/star/awt/XWindow.hpp>
47 : : #include <com/sun/star/frame/XStorable.hpp>
48 : : #include <com/sun/star/frame/FrameSearchFlag.hpp>
49 : : #include <com/sun/star/frame/XDispatchProvider.hpp>
50 : : #include <com/sun/star/graphic/GraphicProvider.hpp>
51 : : #include <com/sun/star/graphic/XGraphicProvider.hpp>
52 : : #include <unotools/configmgr.hxx>
53 : : #include <com/sun/star/lang/XServiceInfo.hpp>
54 : : #include <com/sun/star/container/XNamed.hpp>
55 : : #include <com/sun/star/drawing/XShapes.hpp>
56 : : #include <com/sun/star/drawing/XMasterPageTarget.hpp>
57 : : #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
58 : : #include <com/sun/star/drawing/XMasterPagesSupplier.hpp>
59 : : #include <com/sun/star/presentation/XPresentationSupplier.hpp>
60 : : #include <com/sun/star/container/XNameAccess.hpp>
61 : : #include <com/sun/star/presentation/XPresentation.hpp>
62 : : #include <com/sun/star/presentation/XPresentationPage.hpp>
63 : : #include <com/sun/star/document/XFilter.hpp>
64 : : #include <com/sun/star/document/XExporter.hpp>
65 : : #include <com/sun/star/uno/RuntimeException.hpp>
66 : : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
67 : : #include <com/sun/star/graphic/GraphicType.hpp>
68 : : #include <com/sun/star/io/XStream.hpp>
69 : : #include <com/sun/star/io/XSeekable.hpp>
70 : : #include <com/sun/star/frame/XComponentLoader.hpp>
71 : : #include <com/sun/star/util/URL.hpp>
72 : : #include <com/sun/star/util/URLTransformer.hpp>
73 : : #include <comphelper/componentcontext.hxx>
74 : :
75 : : using namespace ::std;
76 : : using namespace ::rtl;
77 : : using namespace ::com::sun::star;
78 : : using namespace ::com::sun::star::io;
79 : : using namespace ::com::sun::star::awt;
80 : : using namespace ::com::sun::star::uno;
81 : : using namespace ::com::sun::star::lang;
82 : : using namespace ::com::sun::star::util;
83 : : using namespace ::com::sun::star::frame;
84 : : using namespace ::com::sun::star::beans;
85 : : using namespace ::com::sun::star::drawing;
86 : : using namespace ::com::sun::star::graphic;
87 : : using namespace ::com::sun::star::document;
88 : : using namespace ::com::sun::star::container;
89 : : using namespace ::com::sun::star::presentation;
90 : :
91 : 0 : void ImpExtractCustomShow( const Reference< XModel >& rxModel, const OUString& rCustomShowName )
92 : : {
93 : 0 : vector< Reference< XDrawPage > > vNonUsedPageList;
94 : : try
95 : : {
96 : 0 : PageCollector::CollectNonCustomShowPages( rxModel, rCustomShowName, vNonUsedPageList );
97 : 0 : Reference< XDrawPagesSupplier > xDrawPagesSupplier( rxModel, UNO_QUERY_THROW );
98 : 0 : Reference< XDrawPages > xDrawPages( xDrawPagesSupplier->getDrawPages(), UNO_QUERY_THROW );
99 : 0 : vector< Reference< XDrawPage > >::iterator aIter( vNonUsedPageList.begin() );
100 : 0 : while( aIter != vNonUsedPageList.end() )
101 : 0 : xDrawPages->remove( *aIter++ );
102 : : }
103 : 0 : catch( Exception& )
104 : : {
105 : :
106 : 0 : }
107 : 0 : }
108 : :
109 : 0 : void ImpDeleteUnusedMasterPages( const Reference< XModel >& rxModel )
110 : : {
111 : 0 : vector< PageCollector::MasterPageEntity > aMasterPageList;
112 : 0 : PageCollector::CollectMasterPages( rxModel, aMasterPageList );
113 : :
114 : : // now master pages that are not marked can be deleted
115 : 0 : Reference< XMasterPagesSupplier > xMasterPagesSupplier( rxModel, UNO_QUERY_THROW );
116 : 0 : Reference< XDrawPages > xMasterPages( xMasterPagesSupplier->getMasterPages(), UNO_QUERY_THROW );
117 : 0 : vector< PageCollector::MasterPageEntity >::iterator aIter( aMasterPageList.begin() );
118 : 0 : while( aIter != aMasterPageList.end() )
119 : : {
120 : 0 : if ( !aIter->bUsed )
121 : 0 : xMasterPages->remove( aIter->xMasterPage );
122 : 0 : ++aIter;
123 : 0 : }
124 : 0 : }
125 : :
126 : 0 : void ImpDeleteHiddenSlides( const Reference< XModel >& rxModel )
127 : : {
128 : : try
129 : : {
130 : 0 : Reference< XDrawPagesSupplier > xDrawPagesSupplier( rxModel, UNO_QUERY_THROW );
131 : 0 : Reference< XDrawPages > xDrawPages( xDrawPagesSupplier->getDrawPages(), UNO_QUERY_THROW );
132 : 0 : for( sal_Int32 i = 0; i < xDrawPages->getCount(); i++ )
133 : : {
134 : 0 : Reference< XDrawPage > xDrawPage( xDrawPages->getByIndex( i ), UNO_QUERY_THROW );
135 : 0 : Reference< XPropertySet > xPropSet( xDrawPage, UNO_QUERY_THROW );
136 : :
137 : 0 : sal_Bool bVisible = sal_True;
138 : 0 : const OUString sVisible( "Visible" );
139 : 0 : if ( xPropSet->getPropertyValue( sVisible ) >>= bVisible )
140 : : {
141 : 0 : if (!bVisible )
142 : : {
143 : 0 : xDrawPages->remove( xDrawPage );
144 : 0 : i--;
145 : : }
146 : : }
147 : 0 : }
148 : : }
149 : 0 : catch( Exception& )
150 : : {
151 : : }
152 : 0 : }
153 : :
154 : 0 : void ImpDeleteNotesPages( const Reference< XModel >& rxModel )
155 : : {
156 : : try
157 : : {
158 : 0 : Reference< XDrawPagesSupplier > xDrawPagesSupplier( rxModel, UNO_QUERY_THROW );
159 : 0 : Reference< XDrawPages > xDrawPages( xDrawPagesSupplier->getDrawPages(), UNO_QUERY_THROW );
160 : 0 : sal_Int32 i, nPages = xDrawPages->getCount();
161 : 0 : for( i = 0; i < nPages; i++ )
162 : : {
163 : 0 : Reference< XPresentationPage > xPresentationPage( xDrawPages->getByIndex( i ), UNO_QUERY_THROW );
164 : 0 : Reference< XPropertySet > xPropSet( xPresentationPage->getNotesPage(), UNO_QUERY_THROW );
165 : 0 : Reference< XShapes > xShapes( xPropSet, UNO_QUERY_THROW );
166 : 0 : while( xShapes->getCount() )
167 : 0 : xShapes->remove( Reference< XShape >( xShapes->getByIndex( xShapes->getCount() - 1 ), UNO_QUERY_THROW ) );
168 : :
169 : 0 : const OUString sLayout( "Layout" );
170 : 0 : xPropSet->setPropertyValue( sLayout, Any( (sal_Int16)21 ) );
171 : 0 : }
172 : : }
173 : 0 : catch( Exception& )
174 : : {
175 : : }
176 : 0 : }
177 : :
178 : 0 : void ImpConvertOLE( const Reference< XModel >& rxModel, sal_Int32 nOLEOptimizationType )
179 : : {
180 : : try
181 : : {
182 : 0 : Reference< XDrawPagesSupplier > xDrawPagesSupplier( rxModel, UNO_QUERY_THROW );
183 : 0 : Reference< XDrawPages > xDrawPages( xDrawPagesSupplier->getDrawPages(), UNO_QUERY_THROW );
184 : 0 : for ( sal_Int32 i = 0; i < xDrawPages->getCount(); i++ )
185 : : {
186 : 0 : Reference< XShapes > xShapes( xDrawPages->getByIndex( i ), UNO_QUERY_THROW );
187 : 0 : for ( sal_Int32 j = 0; j < xShapes->getCount(); j++ )
188 : : {
189 : 0 : const OUString sOLE2Shape( "com.sun.star.drawing.OLE2Shape" );
190 : 0 : Reference< XShape > xShape( xShapes->getByIndex( j ), UNO_QUERY_THROW );
191 : 0 : if ( xShape->getShapeType() == sOLE2Shape )
192 : : {
193 : 0 : Reference< XPropertySet > xPropSet( xShape, UNO_QUERY_THROW );
194 : :
195 : 0 : sal_Bool bConvertOLE = nOLEOptimizationType == 0;
196 : 0 : if ( nOLEOptimizationType == 1 )
197 : : {
198 : 0 : sal_Bool bIsInternal = sal_True;
199 : 0 : xPropSet->getPropertyValue( TKGet( TK_IsInternal ) ) >>= bIsInternal;
200 : 0 : bConvertOLE = !bIsInternal;
201 : : }
202 : 0 : if ( bConvertOLE )
203 : : {
204 : 0 : Reference< XGraphic > xGraphic;
205 : 0 : if ( xPropSet->getPropertyValue( TKGet( TK_Graphic ) ) >>= xGraphic )
206 : : {
207 : 0 : const OUString sGraphicShape( "com.sun.star.drawing.GraphicObjectShape" );
208 : 0 : Reference< XMultiServiceFactory > xFact( rxModel, UNO_QUERY_THROW );
209 : 0 : Reference< XShape > xShape2( xFact->createInstance( sGraphicShape ), UNO_QUERY_THROW );
210 : 0 : xShapes->add( xShape2 );
211 : 0 : xShape2->setPosition( xShape->getPosition() );
212 : 0 : xShape2->setSize( xShape->getSize() );
213 : 0 : Reference< XPropertySet > xPropSet2( xShape2, UNO_QUERY_THROW );
214 : 0 : xPropSet2->setPropertyValue( TKGet( TK_Graphic ), Any( xGraphic ) );
215 : 0 : xShapes->remove( xShape );
216 : 0 : xPropSet2->setPropertyValue( TKGet( TK_ZOrder ), Any( j ) );
217 : 0 : }
218 : 0 : }
219 : : }
220 : 0 : }
221 : 0 : }
222 : : }
223 : 0 : catch( Exception& )
224 : : {
225 : : }
226 : 0 : }
227 : :
228 : 0 : void ImpCompressGraphic( Reference< XGraphicProvider >& rxGraphicProvider, const Reference< XGraphic >& rxGraphic, Reference< XOutputStream >& rxOutputStream,
229 : : const OUString& rDestMimeType, const awt::Size& rLogicalSize, sal_Int32 nJPEGQuality, sal_Int32 nImageResolution, sal_Bool bRemoveCropping, const text::GraphicCrop& rGraphicCropLogic )
230 : : {
231 : : try
232 : : {
233 : 0 : if ( rxGraphicProvider.is() && rxOutputStream.is() )
234 : : {
235 : 0 : Sequence< PropertyValue > aFilterData( 8 );
236 : 0 : aFilterData[ 0 ].Name = TKGet( TK_ImageResolution );
237 : 0 : aFilterData[ 0 ].Value <<= nImageResolution;
238 : 0 : aFilterData[ 1 ].Name = TKGet( TK_ColorMode ); // todo: jpeg color mode (0->true color, 1->greyscale)
239 : 0 : aFilterData[ 1 ].Value <<= (sal_Int32)0;
240 : 0 : aFilterData[ 2 ].Name = TKGet( TK_Quality ); // quality that is used if we export to jpeg
241 : 0 : aFilterData[ 2 ].Value <<= nJPEGQuality;
242 : 0 : aFilterData[ 3 ].Name = TKGet( TK_Compression ); // compression that is used if we export to png
243 : 0 : aFilterData[ 3 ].Value <<= (sal_Int32)6;
244 : 0 : aFilterData[ 4 ].Name = TKGet( TK_Interlaced ); // interlaced is turned off if we export to png
245 : 0 : aFilterData[ 4 ].Value <<= (sal_Int32)0;
246 : 0 : aFilterData[ 5 ].Name = TKGet( TK_LogicalSize );
247 : 0 : aFilterData[ 5 ].Value <<= rLogicalSize;
248 : 0 : aFilterData[ 6 ].Name = TKGet( TK_RemoveCropArea );
249 : 0 : aFilterData[ 6 ].Value <<= bRemoveCropping;
250 : 0 : aFilterData[ 7 ].Name = TKGet( TK_GraphicCropLogic );
251 : 0 : aFilterData[ 7 ].Value <<= rGraphicCropLogic;
252 : :
253 : 0 : Sequence< PropertyValue > aArgs( 3 );
254 : 0 : aArgs[ 0 ].Name = TKGet( TK_MimeType ); // the GraphicProvider is using "MimeType", the GraphicExporter "MediaType"...
255 : 0 : aArgs[ 0 ].Value <<= rDestMimeType;
256 : 0 : aArgs[ 1 ].Name = TKGet( TK_OutputStream );
257 : 0 : aArgs[ 1 ].Value <<= rxOutputStream;
258 : 0 : aArgs[ 2 ].Name = TKGet( TK_FilterData );
259 : 0 : aArgs[ 2 ].Value <<= aFilterData;
260 : :
261 : 0 : rxGraphicProvider->storeGraphic( rxGraphic, aArgs );
262 : : }
263 : : }
264 : 0 : catch( Exception& )
265 : : {
266 : : }
267 : 0 : }
268 : :
269 : 0 : Reference< XGraphic > ImpCompressGraphic( const Reference< XComponentContext >& rxMSF,
270 : : const Reference< XGraphic >& xGraphic, const awt::Size& aLogicalSize, const text::GraphicCrop& aGraphicCropLogic,
271 : : const GraphicSettings& rGraphicSettings )
272 : : {
273 : 0 : Reference< XGraphic > xNewGraphic;
274 : : try
275 : : {
276 : 0 : OUString aSourceMimeType;
277 : 0 : Reference< XPropertySet > xGraphicPropertySet( xGraphic, UNO_QUERY_THROW );
278 : 0 : if ( xGraphicPropertySet->getPropertyValue( TKGet( TK_MimeType ) ) >>= aSourceMimeType )
279 : : {
280 : 0 : sal_Int8 nGraphicType( xGraphic->getType() );
281 : 0 : if ( nGraphicType == com::sun::star::graphic::GraphicType::PIXEL )
282 : : {
283 : 0 : sal_Bool bTransparent = sal_False;
284 : 0 : sal_Bool bAlpha = sal_False;
285 : 0 : sal_Bool bAnimated = sal_False;
286 : :
287 : 0 : awt::Size aSourceSizePixel( 0, 0 );
288 : 0 : text::GraphicCrop aGraphicCropPixel( 0, 0, 0, 0 );
289 : :
290 : 0 : if ( ( xGraphicPropertySet->getPropertyValue( TKGet( TK_SizePixel ) ) >>= aSourceSizePixel ) &&
291 : 0 : ( xGraphicPropertySet->getPropertyValue( TKGet( TK_Transparent ) ) >>= bTransparent ) &&
292 : 0 : ( xGraphicPropertySet->getPropertyValue( TKGet( TK_Alpha ) ) >>= bAlpha ) &&
293 : 0 : ( xGraphicPropertySet->getPropertyValue( TKGet( TK_Animated ) ) >>= bAnimated ) )
294 : : {
295 : 0 : awt::Size aDestSizePixel( aSourceSizePixel );
296 : 0 : if ( !bAnimated )
297 : : {
298 : 0 : sal_Bool bNeedsOptimizing = sal_False;
299 : 0 : sal_Bool bRemoveCropArea( rGraphicSettings.mbRemoveCropArea );
300 : :
301 : : // cropping has to be removed from SourceSizePixel
302 : 0 : if ( aGraphicCropLogic.Left || aGraphicCropLogic.Top || aGraphicCropLogic.Right || aGraphicCropLogic.Bottom )
303 : : {
304 : 0 : const awt::Size aSize100thMM( GraphicCollector::GetOriginalSize( rxMSF, xGraphic ) );
305 : :
306 : 0 : if ( bRemoveCropArea )
307 : 0 : bNeedsOptimizing = sal_True;
308 : :
309 : 0 : if ( aSize100thMM.Width && aSize100thMM.Height )
310 : : {
311 : 0 : aGraphicCropPixel.Left = static_cast< sal_Int32 >( ( (double)aSourceSizePixel.Width * aGraphicCropLogic.Left ) / aSize100thMM.Width );
312 : 0 : aGraphicCropPixel.Top = static_cast< sal_Int32 >( ( (double)aSourceSizePixel.Height* aGraphicCropLogic.Top ) / aSize100thMM.Height );
313 : 0 : aGraphicCropPixel.Right = static_cast< sal_Int32 >( ( (double)aSourceSizePixel.Width * ( aSize100thMM.Width - aGraphicCropLogic.Right ) ) / aSize100thMM.Width );
314 : 0 : aGraphicCropPixel.Bottom = static_cast< sal_Int32 >( ( (double)aSourceSizePixel.Height* ( aSize100thMM.Height - aGraphicCropLogic.Bottom ) ) / aSize100thMM.Height );
315 : :
316 : : // first calculating new SourceSizePixel by removing the cropped area
317 : 0 : aSourceSizePixel.Width = aGraphicCropPixel.Right - aGraphicCropPixel.Left;
318 : 0 : aSourceSizePixel.Height= aGraphicCropPixel.Bottom - aGraphicCropPixel.Top;
319 : : }
320 : : else
321 : : {
322 : 0 : bRemoveCropArea = sal_False;
323 : : }
324 : : }
325 : 0 : if ( ( aSourceSizePixel.Width > 0 ) && ( aSourceSizePixel.Height > 0 ) )
326 : : {
327 : 0 : OUString aDestMimeType( "image/png" );
328 : 0 : if ( rGraphicSettings.mbJPEGCompression && !bTransparent && !bAlpha && !bAnimated )
329 : : {
330 : 0 : aDestMimeType = OUString( "image/jpeg" );
331 : : // if( aSourceMimeType != aDestMimeType )
332 : 0 : bNeedsOptimizing = sal_True;
333 : : }
334 : 0 : if ( bRemoveCropArea )
335 : 0 : aDestSizePixel = aSourceSizePixel;
336 : 0 : if ( rGraphicSettings.mnImageResolution && aLogicalSize.Width && aLogicalSize.Height )
337 : : {
338 : 0 : const double fSourceDPIX = ((double)aSourceSizePixel.Width / ((double)aLogicalSize.Width / 2540.0 ));
339 : 0 : const double fSourceDPIY = ((double)aSourceSizePixel.Height/ ((double)aLogicalSize.Height/ 2540.0 ));
340 : :
341 : : // check, if the bitmap DPI exceeds the maximum DPI
342 : 0 : if( ( fSourceDPIX > rGraphicSettings.mnImageResolution ) || ( fSourceDPIY > rGraphicSettings.mnImageResolution ) )
343 : : {
344 : 0 : const double fNewSizePixelX = ((double)aDestSizePixel.Width * rGraphicSettings.mnImageResolution ) / fSourceDPIX;
345 : 0 : const double fNewSizePixelY = ((double)aDestSizePixel.Height* rGraphicSettings.mnImageResolution ) / fSourceDPIY;
346 : :
347 : 0 : aDestSizePixel = awt::Size( (sal_Int32)fNewSizePixelX, (sal_Int32)fNewSizePixelY );
348 : 0 : bNeedsOptimizing = sal_True;
349 : : }
350 : : }
351 : 0 : if ( bNeedsOptimizing && aDestSizePixel.Width && aDestSizePixel.Height )
352 : : {
353 : 0 : Reference< XStream > xTempFile( rxMSF->getServiceManager()->createInstanceWithContext( OUString("com.sun.star.io.TempFile"), rxMSF ), UNO_QUERY_THROW );
354 : 0 : Reference< XOutputStream > xOutputStream( xTempFile->getOutputStream() );
355 : 0 : Reference< XGraphicProvider > xGraphicProvider( GraphicProvider::create( rxMSF ) );
356 : :
357 : 0 : ImpCompressGraphic( xGraphicProvider, xGraphic, xOutputStream, aDestMimeType, aLogicalSize, rGraphicSettings.mnJPEGQuality, rGraphicSettings.mnImageResolution, bRemoveCropArea, aGraphicCropLogic );
358 : 0 : Reference< XInputStream > xInputStream( xTempFile->getInputStream() );
359 : 0 : Reference< XSeekable > xSeekable( xInputStream, UNO_QUERY_THROW );
360 : 0 : xSeekable->seek( 0 );
361 : 0 : Sequence< PropertyValue > aArgs( 1 );
362 : 0 : aArgs[ 0 ].Name = TKGet( TK_InputStream );
363 : 0 : aArgs[ 0 ].Value <<= xInputStream;
364 : 0 : xNewGraphic = xGraphicProvider->queryGraphic( aArgs );
365 : 0 : }
366 : : }
367 : : }
368 : : }
369 : : }
370 : : else // this is a metafile
371 : : {
372 : 0 : rtl::OUString aDestMimeType( aSourceMimeType );
373 : 0 : Reference< XStream > xTempFile( rxMSF->getServiceManager()->createInstanceWithContext( OUString("com.sun.star.io.TempFile"), rxMSF ), UNO_QUERY_THROW );
374 : 0 : Reference< XOutputStream > xOutputStream( xTempFile->getOutputStream() );
375 : 0 : Reference< XGraphicProvider > xGraphicProvider( GraphicProvider::create( rxMSF ) );
376 : 0 : ImpCompressGraphic( xGraphicProvider, xGraphic, xOutputStream, aDestMimeType, aLogicalSize, rGraphicSettings.mnJPEGQuality, rGraphicSettings.mnImageResolution, sal_False, aGraphicCropLogic );
377 : 0 : Reference< XInputStream > xInputStream( xTempFile->getInputStream() );
378 : 0 : Reference< XSeekable > xSeekable( xInputStream, UNO_QUERY_THROW );
379 : 0 : xSeekable->seek( 0 );
380 : 0 : Sequence< PropertyValue > aArgs( 1 );
381 : 0 : aArgs[ 0 ].Name = TKGet( TK_InputStream );
382 : 0 : aArgs[ 0 ].Value <<= xInputStream;
383 : 0 : xNewGraphic = xGraphicProvider->queryGraphic( aArgs );
384 : : }
385 : 0 : }
386 : : }
387 : 0 : catch( Exception& )
388 : : {
389 : : }
390 : 0 : return xNewGraphic;
391 : : }
392 : :
393 : 0 : void CompressGraphics( ImpOptimizer& rOptimizer, const Reference< XComponentContext >& rxMSF, const GraphicSettings& rGraphicSettings,
394 : : std::vector< GraphicCollector::GraphicEntity >& rGraphicList )
395 : : {
396 : : try
397 : : {
398 : 0 : std::vector< GraphicCollector::GraphicEntity >::iterator aGraphicIter( rGraphicList.begin() );
399 : 0 : std::vector< GraphicCollector::GraphicEntity >::iterator aGraphicIEnd( rGraphicList.end() );
400 : 0 : double i = 0;
401 : 0 : while( aGraphicIter != aGraphicIEnd )
402 : : {
403 : 0 : i++;
404 : 0 : sal_Int32 nProgress = static_cast< sal_Int32 >( 40.0 * ( i / static_cast< double >( rGraphicList.size() ) ) ) + 50;
405 : 0 : rOptimizer.SetStatusValue( TK_Progress, Any( static_cast< sal_Int32 >( nProgress ) ) );
406 : 0 : rOptimizer.DispatchStatus();
407 : :
408 : 0 : if ( aGraphicIter->maUser.size() )
409 : : {
410 : 0 : GraphicSettings aGraphicSettings( rGraphicSettings );
411 : 0 : aGraphicSettings.mbRemoveCropArea = aGraphicIter->mbRemoveCropArea;
412 : :
413 : 0 : Reference< XGraphic > xGraphic;
414 : 0 : if ( aGraphicIter->maUser[ 0 ].mbFillBitmap && aGraphicIter->maUser[ 0 ].mxPropertySet.is() )
415 : : {
416 : 0 : Reference< XBitmap > xFillBitmap;
417 : 0 : if ( aGraphicIter->maUser[ 0 ].mxPropertySet->getPropertyValue( TKGet( TK_FillBitmap ) ) >>= xFillBitmap )
418 : 0 : xGraphic = Reference< XGraphic >( xFillBitmap, UNO_QUERY_THROW );
419 : : }
420 : 0 : else if ( aGraphicIter->maUser[ 0 ].mxShape.is() )
421 : : {
422 : 0 : Reference< XPropertySet > xShapePropertySet( aGraphicIter->maUser[ 0 ].mxShape, UNO_QUERY_THROW );
423 : 0 : xShapePropertySet->getPropertyValue( TKGet( TK_Graphic ) ) >>= xGraphic;
424 : : }
425 : 0 : if ( xGraphic.is() )
426 : : {
427 : 0 : Reference< XPropertySet > xNewGraphicPropertySet( xGraphic, UNO_QUERY_THROW );
428 : 0 : awt::Size aSize100thMM( GraphicCollector::GetOriginalSize( rxMSF, xGraphic ) );
429 : 0 : Reference< XGraphic > xNewGraphic( ImpCompressGraphic( rxMSF, xGraphic, aGraphicIter->maLogicalSize, aGraphicIter->maGraphicCropLogic, aGraphicSettings ) );
430 : 0 : if ( xNewGraphic.is() )
431 : : {
432 : : // applying graphic to each user
433 : 0 : std::vector< GraphicCollector::GraphicUser >::iterator aGraphicUserIter( aGraphicIter->maUser.begin() );
434 : 0 : while( aGraphicUserIter != aGraphicIter->maUser.end() )
435 : : {
436 : 0 : if ( aGraphicUserIter->mxShape.is() )
437 : : {
438 : 0 : rtl::OUString sEmptyGraphicURL;
439 : 0 : Reference< XPropertySet > xShapePropertySet( aGraphicUserIter->mxShape, UNO_QUERY_THROW );
440 : 0 : xShapePropertySet->setPropertyValue( TKGet( TK_GraphicURL ), Any( sEmptyGraphicURL ) );
441 : 0 : xShapePropertySet->setPropertyValue( TKGet( TK_Graphic ), Any( xNewGraphic ) );
442 : :
443 : 0 : if ( aGraphicUserIter->maGraphicCropLogic.Left || aGraphicUserIter->maGraphicCropLogic.Top
444 : 0 : || aGraphicUserIter->maGraphicCropLogic.Right || aGraphicUserIter->maGraphicCropLogic.Bottom )
445 : : { // removing crop area was not possible or should't been applied
446 : 0 : text::GraphicCrop aGraphicCropLogic( 0, 0, 0, 0 );
447 : 0 : if ( !aGraphicSettings.mbRemoveCropArea )
448 : : {
449 : 0 : awt::Size aNewSize( GraphicCollector::GetOriginalSize( rxMSF, xNewGraphic ) );
450 : 0 : aGraphicCropLogic.Left = (sal_Int32)((double)aGraphicUserIter->maGraphicCropLogic.Left * ((double)aNewSize.Width / (double)aSize100thMM.Width));
451 : 0 : aGraphicCropLogic.Top = (sal_Int32)((double)aGraphicUserIter->maGraphicCropLogic.Top * ((double)aNewSize.Height / (double)aSize100thMM.Height));
452 : 0 : aGraphicCropLogic.Right = (sal_Int32)((double)aGraphicUserIter->maGraphicCropLogic.Right * ((double)aNewSize.Width / (double)aSize100thMM.Width));
453 : 0 : aGraphicCropLogic.Bottom = (sal_Int32)((double)aGraphicUserIter->maGraphicCropLogic.Bottom * ((double)aNewSize.Height / (double)aSize100thMM.Height));
454 : : }
455 : 0 : xShapePropertySet->setPropertyValue( TKGet( TK_GraphicCrop ), Any( aGraphicCropLogic ) );
456 : 0 : }
457 : : }
458 : 0 : else if ( aGraphicUserIter->mxPropertySet.is() )
459 : : {
460 : 0 : Reference< XBitmap > xFillBitmap( xNewGraphic, UNO_QUERY );
461 : 0 : if ( xFillBitmap.is() )
462 : : {
463 : 0 : awt::Size aSize;
464 : : sal_Bool bLogicalSize;
465 : :
466 : 0 : Reference< XPropertySet >& rxPropertySet( aGraphicUserIter->mxPropertySet );
467 : 0 : rxPropertySet->setPropertyValue( TKGet( TK_FillBitmap ), Any( xFillBitmap ) );
468 : 0 : if ( ( rxPropertySet->getPropertyValue( TKGet( TK_FillBitmapLogicalSize ) ) >>= bLogicalSize )
469 : 0 : && ( rxPropertySet->getPropertyValue( TKGet( TK_FillBitmapSizeX ) ) >>= aSize.Width )
470 : 0 : && ( rxPropertySet->getPropertyValue( TKGet( TK_FillBitmapSizeY ) ) >>= aSize.Height ) )
471 : : {
472 : 0 : if ( !aSize.Width || !aSize.Height )
473 : : {
474 : 0 : rxPropertySet->setPropertyValue( TKGet( TK_FillBitmapLogicalSize ), Any( sal_True ) );
475 : 0 : rxPropertySet->setPropertyValue( TKGet( TK_FillBitmapSizeX ), Any( aGraphicUserIter->maLogicalSize.Width ) );
476 : 0 : rxPropertySet->setPropertyValue( TKGet( TK_FillBitmapSizeY ), Any( aGraphicUserIter->maLogicalSize.Height ) );
477 : : }
478 : : }
479 : 0 : if ( aGraphicUserIter->mxPagePropertySet.is() )
480 : 0 : aGraphicUserIter->mxPagePropertySet->setPropertyValue( TKGet( TK_Background ), Any( rxPropertySet ) );
481 : 0 : }
482 : : }
483 : 0 : ++aGraphicUserIter;
484 : : }
485 : 0 : }
486 : 0 : }
487 : : }
488 : 0 : ++aGraphicIter;
489 : : }
490 : : }
491 : 0 : catch ( Exception& )
492 : : {
493 : : }
494 : 0 : }
495 : :
496 : : // ----------------
497 : : // - ImpOptimizer -
498 : : // ----------------
499 : :
500 : 0 : ImpOptimizer::ImpOptimizer( const Reference< XComponentContext >& rxMSF, const Reference< XModel >& rxModel ) :
501 : : mxMSF ( rxMSF ),
502 : : mxModel ( rxModel ),
503 : : mbJPEGCompression ( sal_False ),
504 : : mnJPEGQuality ( 90 ),
505 : : mbRemoveCropArea ( sal_False ),
506 : : mnImageResolution ( 0 ),
507 : : mbEmbedLinkedGraphics ( sal_True ),
508 : : mbOLEOptimization ( sal_False ),
509 : : mnOLEOptimizationType ( 0 ),
510 : : mbDeleteUnusedMasterPages ( sal_False ),
511 : : mbDeleteHiddenSlides ( sal_False ),
512 : : mbDeleteNotesPages ( sal_False ),
513 : 0 : mbOpenNewDocument ( sal_True )
514 : : {
515 : 0 : }
516 : :
517 : : // -----------------------------------------------------------------------------
518 : :
519 : 0 : ImpOptimizer::~ImpOptimizer()
520 : : {
521 : 0 : }
522 : :
523 : : // -----------------------------------------------------------------------------
524 : :
525 : 0 : void ImpOptimizer::DispatchStatus()
526 : : {
527 : 0 : if ( mxStatusDispatcher.is() )
528 : : {
529 : 0 : URL aURL;
530 : 0 : aURL.Protocol = OUString( "vnd.com.sun.star.comp.SunPresentationMinimizer:" );
531 : 0 : aURL.Path = OUString( "statusupdate" );
532 : 0 : mxStatusDispatcher->dispatch( aURL, GetStatusSequence() );
533 : : }
534 : 0 : }
535 : :
536 : : // -----------------------------------------------------------------------------
537 : :
538 : 0 : sal_Bool ImpOptimizer::Optimize()
539 : : {
540 : :
541 : 0 : if ( !maCustomShowName.isEmpty() )
542 : 0 : ImpExtractCustomShow( mxModel, maCustomShowName );
543 : :
544 : 0 : if ( mbDeleteUnusedMasterPages )
545 : : {
546 : 0 : SetStatusValue( TK_Progress, Any( static_cast< sal_Int32 >( 40 ) ) );
547 : 0 : SetStatusValue( TK_Status, Any( TKGet( STR_DELETING_SLIDES ) ) );
548 : 0 : DispatchStatus();
549 : 0 : ImpDeleteUnusedMasterPages( mxModel );
550 : : }
551 : :
552 : 0 : if ( mbDeleteHiddenSlides )
553 : : {
554 : 0 : SetStatusValue( TK_Progress, Any( static_cast< sal_Int32 >( 40 ) ) );
555 : 0 : SetStatusValue( TK_Status, Any( TKGet( STR_DELETING_SLIDES ) ) );
556 : 0 : DispatchStatus();
557 : 0 : ImpDeleteHiddenSlides( mxModel );
558 : : }
559 : :
560 : 0 : if ( mbDeleteNotesPages )
561 : : {
562 : 0 : SetStatusValue( TK_Status, Any( TKGet( STR_DELETING_SLIDES ) ) );
563 : 0 : DispatchStatus();
564 : 0 : ImpDeleteNotesPages( mxModel );
565 : : }
566 : :
567 : 0 : if ( mbOLEOptimization )
568 : : {
569 : 0 : SetStatusValue( TK_Progress, Any( static_cast< sal_Int32 >( 45 ) ) );
570 : 0 : SetStatusValue( TK_Status, Any( TKGet( STR_CREATING_OLE_REPLACEMENTS ) ) );
571 : 0 : DispatchStatus();
572 : 0 : ImpConvertOLE( mxModel, mnOLEOptimizationType );
573 : : }
574 : :
575 : 0 : if ( mbJPEGCompression || mbRemoveCropArea || mnImageResolution )
576 : : {
577 : 0 : SetStatusValue( TK_Progress, Any( static_cast< sal_Int32 >( 50 ) ) );
578 : 0 : SetStatusValue( TK_Status, Any( TKGet( STR_OPTIMIZING_GRAPHICS ) ) );
579 : 0 : DispatchStatus();
580 : :
581 : 0 : std::vector< GraphicCollector::GraphicEntity > aGraphicList;
582 : 0 : GraphicSettings aGraphicSettings( mbJPEGCompression, mnJPEGQuality, mbRemoveCropArea, mnImageResolution, mbEmbedLinkedGraphics );
583 : 0 : GraphicCollector::CollectGraphics( mxMSF, mxModel, aGraphicSettings, aGraphicList );
584 : 0 : CompressGraphics( *this, mxMSF, aGraphicSettings, aGraphicList );
585 : : }
586 : 0 : SetStatusValue( TK_Progress, Any( static_cast< sal_Int32 >( 100 ) ) );
587 : 0 : DispatchStatus();
588 : 0 : return sal_True;
589 : : }
590 : :
591 : 0 : static void DispatchURL( Reference< XComponentContext > xContext, OUString sURL, Reference< XFrame > xFrame )
592 : : {
593 : : try
594 : : {
595 : 0 : Reference< XURLTransformer > xURLTransformer( URLTransformer::create(xContext) );
596 : 0 : util::URL aUrl;
597 : 0 : aUrl.Complete = sURL;
598 : 0 : xURLTransformer->parseStrict( aUrl );
599 : 0 : Sequence< PropertyValue > aArgs;
600 : 0 : Reference< XDispatchProvider > xDispatchProvider( xFrame, UNO_QUERY_THROW );
601 : 0 : Reference< XDispatch > xDispatch = xDispatchProvider->queryDispatch( aUrl, OUString(), 0 ); // "_self"
602 : 0 : if ( xDispatch.is() )
603 : 0 : xDispatch->dispatch( aUrl, aArgs );
604 : : }
605 : 0 : catch( Exception& )
606 : : {
607 : : }
608 : 0 : }
609 : :
610 : : // -----------------------------------------------------------------------------
611 : :
612 : 0 : sal_Bool ImpOptimizer::Optimize( const Sequence< PropertyValue >& rArguments )
613 : : {
614 : 0 : sal_Bool bRet = sal_True;
615 : :
616 : 0 : if ( mxModel.is() )
617 : : {
618 : 0 : sal_Int64 nEstimatedFileSize = 0;
619 : 0 : SetStatusValue( TK_Progress, Any( static_cast< sal_Int32 >( 0 ) ) );
620 : 0 : DispatchStatus();
621 : :
622 : : int i, nICount;
623 : 0 : for ( i = 0, nICount = rArguments.getLength(); i < nICount; i++ )
624 : : {
625 : 0 : switch( TKGet( rArguments[ i ].Name ) )
626 : : {
627 : 0 : case TK_StatusDispatcher : rArguments[ i ].Value >>= mxStatusDispatcher; break;
628 : 0 : case TK_InformationDialog: rArguments[ i ].Value >>= mxInformationDialog; break;
629 : : case TK_Settings :
630 : : {
631 : 0 : com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > aSettings;
632 : : int j, nJCount;
633 : 0 : rArguments[ i ].Value >>= aSettings;
634 : 0 : for ( j = 0, nJCount = aSettings.getLength(); j < nJCount; j++ )
635 : : {
636 : 0 : switch( TKGet( aSettings[ j ].Name ) )
637 : : {
638 : 0 : case TK_JPEGCompression : aSettings[ j ].Value >>= mbJPEGCompression; break;
639 : 0 : case TK_JPEGQuality : aSettings[ j ].Value >>= mnJPEGQuality; break;
640 : 0 : case TK_RemoveCropArea : aSettings[ j ].Value >>= mbRemoveCropArea; break;
641 : 0 : case TK_ImageResolution : aSettings[ j ].Value >>= mnImageResolution; break;
642 : 0 : case TK_EmbedLinkedGraphics : aSettings[ j ].Value >>= mbEmbedLinkedGraphics; break;
643 : 0 : case TK_OLEOptimization : aSettings[ j ].Value >>= mbOLEOptimization; break;
644 : 0 : case TK_OLEOptimizationType : aSettings[ j ].Value >>= mnOLEOptimizationType; break;
645 : 0 : case TK_CustomShowName : aSettings[ j ].Value >>= maCustomShowName; break;
646 : 0 : case TK_DeleteUnusedMasterPages : aSettings[ j ].Value >>= mbDeleteUnusedMasterPages; break;
647 : 0 : case TK_DeleteHiddenSlides : aSettings[ j ].Value >>= mbDeleteHiddenSlides; break;
648 : 0 : case TK_DeleteNotesPages : aSettings[ j ].Value >>= mbDeleteNotesPages; break;
649 : 0 : case TK_SaveAsURL : aSettings[ j ].Value >>= maSaveAsURL; break;
650 : 0 : case TK_FilterName : aSettings[ j ].Value >>= maFilterName; break;
651 : 0 : case TK_OpenNewDocument : aSettings[ j ].Value >>= mbOpenNewDocument; break;
652 : 0 : case TK_EstimatedFileSize : aSettings[ j ].Value >>= nEstimatedFileSize; break;
653 : 0 : default: break;
654 : : }
655 : 0 : }
656 : : }
657 : 0 : break;
658 : 0 : default: break;
659 : : }
660 : : }
661 : :
662 : 0 : sal_Int64 nSourceSize = 0;
663 : 0 : sal_Int64 nDestSize = 0;
664 : :
665 : 0 : Reference< XFrame > xSelf;
666 : 0 : if ( !maSaveAsURL.isEmpty() )
667 : : {
668 : :
669 : 0 : SetStatusValue( TK_Progress, Any( static_cast< sal_Int32 >( 10 ) ) );
670 : 0 : SetStatusValue( TK_Status, Any( TKGet( STR_DUPLICATING_PRESENTATION ) ) );
671 : 0 : DispatchStatus();
672 : :
673 : 0 : Reference< XStorable >xStorable( mxModel, UNO_QUERY );
674 : 0 : if ( xStorable.is() )
675 : : {
676 : 0 : if ( xStorable->hasLocation() )
677 : 0 : nSourceSize = PPPOptimizer::GetFileSize( xStorable->getLocation() );
678 : :
679 : 0 : Sequence< PropertyValue > aArguments;
680 : 0 : if ( !maFilterName.isEmpty() )
681 : : {
682 : 0 : int nLength = aArguments.getLength();
683 : 0 : aArguments.realloc( nLength + 1 );
684 : 0 : aArguments[ nLength ].Name = TKGet( TK_FilterName );
685 : 0 : aArguments[ nLength ].Value <<= maFilterName;
686 : : }
687 : 0 : xStorable->storeToURL( maSaveAsURL, aArguments );
688 : 0 : if ( !nSourceSize )
689 : 0 : nSourceSize = PPPOptimizer::GetFileSize( maSaveAsURL );
690 : :
691 : 0 : SetStatusValue( TK_Progress, Any( static_cast< sal_Int32 >( 30 ) ) );
692 : 0 : SetStatusValue( TK_Status, Any( TKGet( STR_DUPLICATING_PRESENTATION ) ) );
693 : 0 : DispatchStatus();
694 : :
695 : 0 : Reference< XDesktop > xDesktop( mxMSF->getServiceManager()->createInstanceWithContext(
696 : 0 : OUString( "com.sun.star.frame.Desktop" ), mxMSF ), UNO_QUERY );
697 : 0 : Reference< XFrame > xFrame( xDesktop, UNO_QUERY );
698 : 0 : xSelf = xFrame->findFrame( TKGet( TK__blank ), FrameSearchFlag::CREATE );
699 : 0 : Reference< XComponentLoader > xComponentLoader( xSelf, UNO_QUERY );
700 : :
701 : 0 : Sequence< PropertyValue > aLoadProps( 1 );
702 : 0 : aLoadProps[ 0 ].Name = TKGet( TK_Hidden );
703 : 0 : aLoadProps[ 0 ].Value <<= (sal_Bool)( sal_True );
704 : 0 : mxModel = Reference< XModel >( xComponentLoader->loadComponentFromURL(
705 : 0 : maSaveAsURL, TKGet( TK__self ), 0, aLoadProps ), UNO_QUERY );
706 : 0 : }
707 : : }
708 : :
709 : : // check if the document is ReadOnly -> error
710 : 0 : Reference< XStorable > xStorable( mxModel, UNO_QUERY );
711 : 0 : if ( xStorable.is() && !xStorable->isReadonly() )
712 : : {
713 : 0 : mxModel->lockControllers();
714 : 0 : bRet = Optimize();
715 : 0 : mxModel->unlockControllers();
716 : :
717 : : // clearing undo stack:
718 : 0 : Reference< XFrame > xFrame( xSelf.is() ? xSelf : mxInformationDialog );
719 : 0 : if ( xFrame.is() )
720 : : {
721 : 0 : const OUString sSlot( "slot:27115" );
722 : 0 : DispatchURL( mxMSF, sSlot, xFrame );
723 : 0 : }
724 : : }
725 : :
726 : 0 : if ( !maSaveAsURL.isEmpty() )
727 : : {
728 : 0 : if ( xStorable.is() )
729 : : {
730 : 0 : xStorable->store();
731 : 0 : nDestSize = PPPOptimizer::GetFileSize( maSaveAsURL );
732 : : }
733 : : }
734 : :
735 : 0 : if ( mxInformationDialog.is() )
736 : : {
737 : 0 : InformationDialog aInformationDialog( mxMSF, mxInformationDialog, maSaveAsURL, mbOpenNewDocument, nSourceSize, nDestSize, nEstimatedFileSize );
738 : 0 : aInformationDialog.execute();
739 : 0 : SetStatusValue( TK_OpenNewDocument, Any( mbOpenNewDocument ) );
740 : 0 : DispatchStatus();
741 : : }
742 : :
743 : 0 : if ( !maSaveAsURL.isEmpty() )
744 : : {
745 : 0 : if ( mbOpenNewDocument && xSelf.is() )
746 : : {
747 : 0 : Reference< awt::XWindow > xContainerWindow( xSelf->getContainerWindow() );
748 : 0 : xContainerWindow->setVisible( sal_True );
749 : : }
750 : : else
751 : : {
752 : 0 : Reference< XComponent > xComponent( mxModel, UNO_QUERY );
753 : 0 : xComponent->dispose();
754 : : }
755 : : }
756 : 0 : if ( nSourceSize && nDestSize )
757 : : {
758 : 0 : SetStatusValue( TK_FileSizeSource, Any( nSourceSize ) );
759 : 0 : SetStatusValue( TK_FileSizeDestination, Any( nDestSize ) );
760 : 0 : DispatchStatus();
761 : 0 : }
762 : : }
763 : : else
764 : 0 : bRet = sal_False;
765 : 0 : return bRet;
766 : : }
767 : :
768 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|