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