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