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