| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_sdext.hxx" |
| |
| #include "impoptimizer.hxx" |
| #include "pppoptimizer.hxx" |
| #include "graphiccollector.hxx" |
| #include "pagecollector.hxx" |
| #include "informationdialog.hxx" |
| |
| #include "minimizer.hrc" |
| |
| #include <vector> |
| #include "com/sun/star/util/URL.hpp" |
| #include "com/sun/star/util/XURLTransformer.hpp" |
| #include <com/sun/star/beans/XPropertySet.hpp> |
| #include <com/sun/star/awt/Rectangle.hpp> |
| #include <com/sun/star/awt/Size.hpp> |
| #include <com/sun/star/util/MeasureUnit.hpp> |
| #include <com/sun/star/frame/XModel.hpp> |
| #include <com/sun/star/frame/XDesktop.hpp> |
| #include <com/sun/star/awt/XWindow.hpp> |
| #include <com/sun/star/frame/XStorable.hpp> |
| #include <com/sun/star/frame/FrameSearchFlag.hpp> |
| #include <com/sun/star/frame/XDispatchProvider.hpp> |
| #include <com/sun/star/graphic/XGraphicProvider.hpp> |
| #include <com/sun/star/lang/XServiceInfo.hpp> |
| #include <com/sun/star/container/XNamed.hpp> |
| #include <com/sun/star/drawing/XShapes.hpp> |
| #include <com/sun/star/drawing/XMasterPageTarget.hpp> |
| #include <com/sun/star/drawing/XDrawPagesSupplier.hpp> |
| #include <com/sun/star/drawing/XMasterPagesSupplier.hpp> |
| #include <com/sun/star/presentation/XPresentationSupplier.hpp> |
| #include <com/sun/star/container/XNameAccess.hpp> |
| #include <com/sun/star/presentation/XPresentation.hpp> |
| #include <com/sun/star/presentation/XPresentationPage.hpp> |
| #include <com/sun/star/document/XFilter.hpp> |
| #include <com/sun/star/document/XExporter.hpp> |
| #include <com/sun/star/uno/RuntimeException.hpp> |
| #include <com/sun/star/lang/XMultiServiceFactory.hpp> |
| #include <com/sun/star/graphic/XGraphicProvider.hpp> |
| #include <com/sun/star/graphic/GraphicType.hpp> |
| #include <com/sun/star/io/XStream.hpp> |
| #include <com/sun/star/io/XSeekable.hpp> |
| #include <com/sun/star/frame/XComponentLoader.hpp> |
| #include <com/sun/star/util/URL.hpp> |
| |
| using namespace ::std; |
| using namespace ::com::sun::star; |
| using namespace ::com::sun::star::io; |
| using namespace ::com::sun::star::awt; |
| using namespace ::com::sun::star::uno; |
| using namespace ::com::sun::star::lang; |
| using namespace ::com::sun::star::util; |
| using namespace ::com::sun::star::frame; |
| using namespace ::com::sun::star::beans; |
| using namespace ::com::sun::star::drawing; |
| using namespace ::com::sun::star::graphic; |
| using namespace ::com::sun::star::document; |
| using namespace ::com::sun::star::container; |
| using namespace ::com::sun::star::presentation; |
| |
| using ::rtl::OUString; |
| |
| void ImpExtractCustomShow( const Reference< XModel >& rxModel, const OUString& rCustomShowName ) |
| { |
| vector< Reference< XDrawPage > > vNonUsedPageList; |
| try |
| { |
| PageCollector::CollectNonCustomShowPages( rxModel, rCustomShowName, vNonUsedPageList ); |
| Reference< XDrawPagesSupplier > xDrawPagesSupplier( rxModel, UNO_QUERY_THROW ); |
| Reference< XDrawPages > xDrawPages( xDrawPagesSupplier->getDrawPages(), UNO_QUERY_THROW ); |
| vector< Reference< XDrawPage > >::iterator aIter( vNonUsedPageList.begin() ); |
| while( aIter != vNonUsedPageList.end() ) |
| xDrawPages->remove( *aIter++ ); |
| } |
| catch( Exception& ) |
| { |
| |
| } |
| } |
| |
| void ImpDeleteUnusedMasterPages( const Reference< XModel >& rxModel ) |
| { |
| vector< PageCollector::MasterPageEntity > aMasterPageList; |
| PageCollector::CollectMasterPages( rxModel, aMasterPageList ); |
| |
| // now master pages that are not marked can be deleted |
| Reference< XMasterPagesSupplier > xMasterPagesSupplier( rxModel, UNO_QUERY_THROW ); |
| Reference< XDrawPages > xMasterPages( xMasterPagesSupplier->getMasterPages(), UNO_QUERY_THROW ); |
| vector< PageCollector::MasterPageEntity >::iterator aIter( aMasterPageList.begin() ); |
| while( aIter != aMasterPageList.end() ) |
| { |
| if ( !aIter->bUsed ) |
| xMasterPages->remove( aIter->xMasterPage ); |
| aIter++; |
| } |
| } |
| |
| void ImpDeleteHiddenSlides( const Reference< XModel >& rxModel ) |
| { |
| try |
| { |
| Reference< XDrawPagesSupplier > xDrawPagesSupplier( rxModel, UNO_QUERY_THROW ); |
| Reference< XDrawPages > xDrawPages( xDrawPagesSupplier->getDrawPages(), UNO_QUERY_THROW ); |
| for( sal_Int32 i = 0; i < xDrawPages->getCount(); i++ ) |
| { |
| Reference< XDrawPage > xDrawPage( xDrawPages->getByIndex( i ), UNO_QUERY_THROW ); |
| Reference< XPropertySet > xPropSet( xDrawPage, UNO_QUERY_THROW ); |
| |
| sal_Bool bVisible = sal_True; |
| const OUString sVisible( RTL_CONSTASCII_USTRINGPARAM( "Visible" ) ); |
| if ( xPropSet->getPropertyValue( sVisible ) >>= bVisible ) |
| { |
| if (!bVisible ) |
| { |
| xDrawPages->remove( xDrawPage ); |
| i--; |
| } |
| } |
| } |
| } |
| catch( Exception& ) |
| { |
| } |
| } |
| |
| void ImpDeleteNotesPages( const Reference< XModel >& rxModel ) |
| { |
| try |
| { |
| Reference< XDrawPagesSupplier > xDrawPagesSupplier( rxModel, UNO_QUERY_THROW ); |
| Reference< XDrawPages > xDrawPages( xDrawPagesSupplier->getDrawPages(), UNO_QUERY_THROW ); |
| sal_Int32 i, nPages = xDrawPages->getCount(); |
| for( i = 0; i < nPages; i++ ) |
| { |
| Reference< XPresentationPage > xPresentationPage( xDrawPages->getByIndex( i ), UNO_QUERY_THROW ); |
| Reference< XPropertySet > xPropSet( xPresentationPage->getNotesPage(), UNO_QUERY_THROW ); |
| Reference< XShapes > xShapes( xPropSet, UNO_QUERY_THROW ); |
| while( xShapes->getCount() ) |
| xShapes->remove( Reference< XShape >( xShapes->getByIndex( xShapes->getCount() - 1 ), UNO_QUERY_THROW ) ); |
| |
| const OUString sLayout( RTL_CONSTASCII_USTRINGPARAM( "Layout" ) ); |
| xPropSet->setPropertyValue( sLayout, Any( (sal_Int16)21 ) ); |
| } |
| } |
| catch( Exception& ) |
| { |
| } |
| } |
| |
| void ImpConvertOLE( const Reference< XModel >& rxModel, sal_Int32 nOLEOptimizationType ) |
| { |
| try |
| { |
| Reference< XDrawPagesSupplier > xDrawPagesSupplier( rxModel, UNO_QUERY_THROW ); |
| Reference< XDrawPages > xDrawPages( xDrawPagesSupplier->getDrawPages(), UNO_QUERY_THROW ); |
| for ( sal_Int32 i = 0; i < xDrawPages->getCount(); i++ ) |
| { |
| Reference< XShapes > xShapes( xDrawPages->getByIndex( i ), UNO_QUERY_THROW ); |
| for ( sal_Int32 j = 0; j < xShapes->getCount(); j++ ) |
| { |
| const OUString sOLE2Shape( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.OLE2Shape" ) ); |
| Reference< XShape > xShape( xShapes->getByIndex( j ), UNO_QUERY_THROW ); |
| if ( xShape->getShapeType() == sOLE2Shape ) |
| { |
| Reference< XPropertySet > xPropSet( xShape, UNO_QUERY_THROW ); |
| |
| sal_Bool bConvertOLE = nOLEOptimizationType == 0; |
| if ( nOLEOptimizationType == 1 ) |
| { |
| sal_Bool bIsInternal = sal_True; |
| xPropSet->getPropertyValue( TKGet( TK_IsInternal ) ) >>= bIsInternal; |
| bConvertOLE = !bIsInternal; |
| } |
| if ( bConvertOLE ) |
| { |
| Reference< XGraphic > xGraphic; |
| if ( xPropSet->getPropertyValue( TKGet( TK_Graphic ) ) >>= xGraphic ) |
| { |
| const OUString sGraphicShape( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.GraphicObjectShape" ) ); |
| Reference< XMultiServiceFactory > xFact( rxModel, UNO_QUERY_THROW ); |
| Reference< XShape > xShape2( xFact->createInstance( sGraphicShape ), UNO_QUERY_THROW ); |
| xShapes->add( xShape2 ); |
| xShape2->setPosition( xShape->getPosition() ); |
| xShape2->setSize( xShape->getSize() ); |
| Reference< XPropertySet > xPropSet2( xShape2, UNO_QUERY_THROW ); |
| xPropSet2->setPropertyValue( TKGet( TK_Graphic ), Any( xGraphic ) ); |
| xShapes->remove( xShape ); |
| xPropSet2->setPropertyValue( TKGet( TK_ZOrder ), Any( j ) ); |
| } |
| } |
| } |
| } |
| } |
| } |
| catch( Exception& ) |
| { |
| } |
| } |
| |
| void ImpCompressGraphic( Reference< XGraphicProvider >& rxGraphicProvider, const Reference< XGraphic >& rxGraphic, Reference< XOutputStream >& rxOutputStream, |
| const OUString& rDestMimeType, const awt::Size& rLogicalSize, sal_Int32 nJPEGQuality, sal_Int32 nImageResolution, sal_Bool bRemoveCropping, const text::GraphicCrop& rGraphicCropLogic ) |
| { |
| try |
| { |
| if ( rxGraphicProvider.is() && rxOutputStream.is() ) |
| { |
| Sequence< PropertyValue > aFilterData( 8 ); |
| aFilterData[ 0 ].Name = TKGet( TK_ImageResolution ); |
| aFilterData[ 0 ].Value <<= nImageResolution; |
| aFilterData[ 1 ].Name = TKGet( TK_ColorMode ); // todo: jpeg color mode (0->true color, 1->greyscale) |
| aFilterData[ 1 ].Value <<= (sal_Int32)0; |
| aFilterData[ 2 ].Name = TKGet( TK_Quality ); // quality that is used if we export to jpeg |
| aFilterData[ 2 ].Value <<= nJPEGQuality; |
| aFilterData[ 3 ].Name = TKGet( TK_Compression ); // compression that is used if we export to png |
| aFilterData[ 3 ].Value <<= (sal_Int32)6; |
| aFilterData[ 4 ].Name = TKGet( TK_Interlaced ); // interlaced is turned off if we export to png |
| aFilterData[ 4 ].Value <<= (sal_Int32)0; |
| aFilterData[ 5 ].Name = TKGet( TK_LogicalSize ); |
| aFilterData[ 5 ].Value <<= rLogicalSize; |
| aFilterData[ 6 ].Name = TKGet( TK_RemoveCropArea ); |
| aFilterData[ 6 ].Value <<= bRemoveCropping; |
| aFilterData[ 7 ].Name = TKGet( TK_GraphicCropLogic ); |
| aFilterData[ 7 ].Value <<= rGraphicCropLogic; |
| |
| Sequence< PropertyValue > aArgs( 3 ); |
| aArgs[ 0 ].Name = TKGet( TK_MimeType ); // the GraphicProvider is using "MimeType", the GraphicExporter "MediaType"... |
| aArgs[ 0 ].Value <<= rDestMimeType; |
| aArgs[ 1 ].Name = TKGet( TK_OutputStream ); |
| aArgs[ 1 ].Value <<= rxOutputStream; |
| aArgs[ 2 ].Name = TKGet( TK_FilterData ); |
| aArgs[ 2 ].Value <<= aFilterData; |
| |
| rxGraphicProvider->storeGraphic( rxGraphic, aArgs ); |
| } |
| } |
| catch( Exception& ) |
| { |
| } |
| } |
| |
| Reference< XGraphic > ImpCompressGraphic( const Reference< XComponentContext >& rxContext, |
| const Reference< XGraphic >& xGraphic, const awt::Size& aLogicalSize, const text::GraphicCrop& aGraphicCropLogic, |
| const GraphicSettings& rGraphicSettings ) |
| { |
| Reference< XGraphic > xNewGraphic; |
| try |
| { |
| OUString aSourceMimeType; |
| Reference< XPropertySet > xGraphicPropertySet( xGraphic, UNO_QUERY_THROW ); |
| if ( xGraphicPropertySet->getPropertyValue( TKGet( TK_MimeType ) ) >>= aSourceMimeType ) |
| { |
| sal_Int8 nGraphicType( xGraphic->getType() ); |
| if ( nGraphicType == com::sun::star::graphic::GraphicType::PIXEL ) |
| { |
| sal_Bool bTransparent = sal_False; |
| sal_Bool bAlpha = sal_False; |
| sal_Bool bAnimated = sal_False; |
| |
| awt::Size aSourceSizePixel( 0, 0 ); |
| text::GraphicCrop aGraphicCropPixel( 0, 0, 0, 0 ); |
| |
| if ( ( xGraphicPropertySet->getPropertyValue( TKGet( TK_SizePixel ) ) >>= aSourceSizePixel ) && |
| ( xGraphicPropertySet->getPropertyValue( TKGet( TK_Transparent ) ) >>= bTransparent ) && |
| ( xGraphicPropertySet->getPropertyValue( TKGet( TK_Alpha ) ) >>= bAlpha ) && |
| ( xGraphicPropertySet->getPropertyValue( TKGet( TK_Animated ) ) >>= bAnimated ) ) |
| { |
| awt::Size aDestSizePixel( aSourceSizePixel ); |
| if ( !bAnimated ) |
| { |
| sal_Bool bNeedsOptimizing = sal_False; |
| sal_Bool bRemoveCropArea( rGraphicSettings.mbRemoveCropArea ); |
| |
| // cropping has to be removed from SourceSizePixel |
| if ( aGraphicCropLogic.Left || aGraphicCropLogic.Top || aGraphicCropLogic.Right || aGraphicCropLogic.Bottom ) |
| { |
| const awt::Size aSize100thMM( GraphicCollector::GetOriginalSize( rxContext, xGraphic ) ); |
| |
| if ( bRemoveCropArea ) |
| bNeedsOptimizing = sal_True; |
| |
| if ( aSize100thMM.Width && aSize100thMM.Height ) |
| { |
| aGraphicCropPixel.Left = static_cast< sal_Int32 >( ( (double)aSourceSizePixel.Width * aGraphicCropLogic.Left ) / aSize100thMM.Width ); |
| aGraphicCropPixel.Top = static_cast< sal_Int32 >( ( (double)aSourceSizePixel.Height* aGraphicCropLogic.Top ) / aSize100thMM.Height ); |
| aGraphicCropPixel.Right = static_cast< sal_Int32 >( ( (double)aSourceSizePixel.Width * ( aSize100thMM.Width - aGraphicCropLogic.Right ) ) / aSize100thMM.Width ); |
| aGraphicCropPixel.Bottom = static_cast< sal_Int32 >( ( (double)aSourceSizePixel.Height* ( aSize100thMM.Height - aGraphicCropLogic.Bottom ) ) / aSize100thMM.Height ); |
| |
| // first calculating new SourceSizePixel by removing the cropped area |
| aSourceSizePixel.Width = aGraphicCropPixel.Right - aGraphicCropPixel.Left; |
| aSourceSizePixel.Height= aGraphicCropPixel.Bottom - aGraphicCropPixel.Top; |
| } |
| else |
| { |
| bRemoveCropArea = sal_False; |
| } |
| } |
| if ( ( aSourceSizePixel.Width > 0 ) && ( aSourceSizePixel.Height > 0 ) ) |
| { |
| OUString aDestMimeType( RTL_CONSTASCII_USTRINGPARAM( "image/png" ) ); |
| if ( rGraphicSettings.mbJPEGCompression && !bTransparent && !bAlpha && !bAnimated ) |
| { |
| aDestMimeType = OUString( RTL_CONSTASCII_USTRINGPARAM( "image/jpeg" ) ); |
| // if( aSourceMimeType != aDestMimeType ) |
| bNeedsOptimizing = sal_True; |
| } |
| if ( bRemoveCropArea ) |
| aDestSizePixel = aSourceSizePixel; |
| if ( rGraphicSettings.mnImageResolution && aLogicalSize.Width && aLogicalSize.Height ) |
| { |
| const double fSourceDPIX = ((double)aSourceSizePixel.Width / ((double)aLogicalSize.Width / 2540.0 )); |
| const double fSourceDPIY = ((double)aSourceSizePixel.Height/ ((double)aLogicalSize.Height/ 2540.0 )); |
| |
| // check, if the bitmap DPI exceeds the maximum DPI |
| if( ( fSourceDPIX > rGraphicSettings.mnImageResolution ) || ( fSourceDPIY > rGraphicSettings.mnImageResolution ) ) |
| { |
| const double fNewSizePixelX = ((double)aDestSizePixel.Width * rGraphicSettings.mnImageResolution ) / fSourceDPIX; |
| const double fNewSizePixelY = ((double)aDestSizePixel.Height* rGraphicSettings.mnImageResolution ) / fSourceDPIY; |
| |
| aDestSizePixel = awt::Size( (sal_Int32)fNewSizePixelX, (sal_Int32)fNewSizePixelY ); |
| bNeedsOptimizing = sal_True; |
| } |
| } |
| if ( bNeedsOptimizing && aDestSizePixel.Width && aDestSizePixel.Height ) |
| { |
| Reference< XStream > xTempFile( rxContext->getServiceManager()->createInstanceWithContext( OUString::createFromAscii( "com.sun.star.io.TempFile" ), rxContext ), UNO_QUERY_THROW ); |
| Reference< XOutputStream > xOutputStream( xTempFile->getOutputStream() ); |
| Reference< XGraphicProvider > xGraphicProvider( rxContext->getServiceManager()->createInstanceWithContext( OUString::createFromAscii( "com.sun.star.graphic.GraphicProvider" ), rxContext ), UNO_QUERY_THROW ); |
| |
| ImpCompressGraphic( xGraphicProvider, xGraphic, xOutputStream, aDestMimeType, aLogicalSize, rGraphicSettings.mnJPEGQuality, rGraphicSettings.mnImageResolution, bRemoveCropArea, aGraphicCropLogic ); |
| Reference< XInputStream > xInputStream( xTempFile->getInputStream() ); |
| Reference< XSeekable > xSeekable( xInputStream, UNO_QUERY_THROW ); |
| xSeekable->seek( 0 ); |
| Sequence< PropertyValue > aArgs( 1 ); |
| aArgs[ 0 ].Name = TKGet( TK_InputStream ); |
| aArgs[ 0 ].Value <<= xInputStream; |
| xNewGraphic = xGraphicProvider->queryGraphic( aArgs ); |
| } |
| } |
| } |
| } |
| } |
| else // this is a metafile |
| { |
| rtl::OUString aDestMimeType( aSourceMimeType ); |
| Reference< XStream > xTempFile( rxContext->getServiceManager()->createInstanceWithContext( OUString::createFromAscii( "com.sun.star.io.TempFile" ), rxContext ), UNO_QUERY_THROW ); |
| Reference< XOutputStream > xOutputStream( xTempFile->getOutputStream() ); |
| Reference< XGraphicProvider > xGraphicProvider( rxContext->getServiceManager()->createInstanceWithContext( OUString::createFromAscii( "com.sun.star.graphic.GraphicProvider" ), rxContext ), UNO_QUERY_THROW ); |
| ImpCompressGraphic( xGraphicProvider, xGraphic, xOutputStream, aDestMimeType, aLogicalSize, rGraphicSettings.mnJPEGQuality, rGraphicSettings.mnImageResolution, sal_False, aGraphicCropLogic ); |
| Reference< XInputStream > xInputStream( xTempFile->getInputStream() ); |
| Reference< XSeekable > xSeekable( xInputStream, UNO_QUERY_THROW ); |
| xSeekable->seek( 0 ); |
| Sequence< PropertyValue > aArgs( 1 ); |
| aArgs[ 0 ].Name = TKGet( TK_InputStream ); |
| aArgs[ 0 ].Value <<= xInputStream; |
| xNewGraphic = xGraphicProvider->queryGraphic( aArgs ); |
| } |
| } |
| } |
| catch( Exception& ) |
| { |
| } |
| return xNewGraphic; |
| } |
| |
| void CompressGraphics( ImpOptimizer& rOptimizer, const Reference< XComponentContext >& rxContext, const GraphicSettings& rGraphicSettings, |
| std::vector< GraphicCollector::GraphicEntity >& rGraphicList ) |
| { |
| try |
| { |
| std::vector< GraphicCollector::GraphicEntity >::iterator aGraphicIter( rGraphicList.begin() ); |
| std::vector< GraphicCollector::GraphicEntity >::iterator aGraphicIEnd( rGraphicList.end() ); |
| double i = 0; |
| while( aGraphicIter != aGraphicIEnd ) |
| { |
| i++; |
| sal_Int32 nProgress = static_cast< sal_Int32 >( 40.0 * ( i / static_cast< double >( rGraphicList.size() ) ) ) + 50; |
| rOptimizer.SetStatusValue( TK_Progress, Any( static_cast< sal_Int32 >( nProgress ) ) ); |
| rOptimizer.DispatchStatus(); |
| |
| if ( aGraphicIter->maUser.size() ) |
| { |
| GraphicSettings aGraphicSettings( rGraphicSettings ); |
| aGraphicSettings.mbRemoveCropArea = aGraphicIter->mbRemoveCropArea; |
| |
| Reference< XGraphic > xGraphic; |
| if ( aGraphicIter->maUser[ 0 ].mbFillBitmap && aGraphicIter->maUser[ 0 ].mxPropertySet.is() ) |
| { |
| Reference< XBitmap > xFillBitmap; |
| if ( aGraphicIter->maUser[ 0 ].mxPropertySet->getPropertyValue( TKGet( TK_FillBitmap ) ) >>= xFillBitmap ) |
| xGraphic = Reference< XGraphic >( xFillBitmap, UNO_QUERY_THROW ); |
| } |
| else if ( aGraphicIter->maUser[ 0 ].mxShape.is() ) |
| { |
| Reference< XPropertySet > xShapePropertySet( aGraphicIter->maUser[ 0 ].mxShape, UNO_QUERY_THROW ); |
| xShapePropertySet->getPropertyValue( TKGet( TK_Graphic ) ) >>= xGraphic; |
| } |
| if ( xGraphic.is() ) |
| { |
| Reference< XPropertySet > xNewGraphicPropertySet( xGraphic, UNO_QUERY_THROW ); |
| awt::Size aSize100thMM( GraphicCollector::GetOriginalSize( rxContext, xGraphic ) ); |
| Reference< XGraphic > xNewGraphic( ImpCompressGraphic( rxContext, xGraphic, aGraphicIter->maLogicalSize, aGraphicIter->maGraphicCropLogic, aGraphicSettings ) ); |
| if ( xNewGraphic.is() ) |
| { |
| // applying graphic to each user |
| std::vector< GraphicCollector::GraphicUser >::iterator aGraphicUserIter( aGraphicIter->maUser.begin() ); |
| while( aGraphicUserIter != aGraphicIter->maUser.end() ) |
| { |
| if ( aGraphicUserIter->mxShape.is() ) |
| { |
| rtl::OUString sEmptyGraphicURL; |
| Reference< XPropertySet > xShapePropertySet( aGraphicUserIter->mxShape, UNO_QUERY_THROW ); |
| xShapePropertySet->setPropertyValue( TKGet( TK_GraphicURL ), Any( sEmptyGraphicURL ) ); |
| xShapePropertySet->setPropertyValue( TKGet( TK_Graphic ), Any( xNewGraphic ) ); |
| |
| if ( aGraphicUserIter->maGraphicCropLogic.Left || aGraphicUserIter->maGraphicCropLogic.Top |
| || aGraphicUserIter->maGraphicCropLogic.Right || aGraphicUserIter->maGraphicCropLogic.Bottom ) |
| { // removing crop area was not possible or should't been applied |
| text::GraphicCrop aGraphicCropLogic( 0, 0, 0, 0 ); |
| if ( !aGraphicSettings.mbRemoveCropArea ) |
| { |
| awt::Size aNewSize( GraphicCollector::GetOriginalSize( rxContext, xNewGraphic ) ); |
| aGraphicCropLogic.Left = (sal_Int32)((double)aGraphicUserIter->maGraphicCropLogic.Left * ((double)aNewSize.Width / (double)aSize100thMM.Width)); |
| aGraphicCropLogic.Top = (sal_Int32)((double)aGraphicUserIter->maGraphicCropLogic.Top * ((double)aNewSize.Height / (double)aSize100thMM.Height)); |
| aGraphicCropLogic.Right = (sal_Int32)((double)aGraphicUserIter->maGraphicCropLogic.Right * ((double)aNewSize.Width / (double)aSize100thMM.Width)); |
| aGraphicCropLogic.Bottom = (sal_Int32)((double)aGraphicUserIter->maGraphicCropLogic.Bottom * ((double)aNewSize.Height / (double)aSize100thMM.Height)); |
| } |
| xShapePropertySet->setPropertyValue( TKGet( TK_GraphicCrop ), Any( aGraphicCropLogic ) ); |
| } |
| } |
| else if ( aGraphicUserIter->mxPropertySet.is() ) |
| { |
| Reference< XBitmap > xFillBitmap( xNewGraphic, UNO_QUERY ); |
| if ( xFillBitmap.is() ) |
| { |
| awt::Size aSize; |
| sal_Bool bLogicalSize; |
| |
| Reference< XPropertySet >& rxPropertySet( aGraphicUserIter->mxPropertySet ); |
| rxPropertySet->setPropertyValue( TKGet( TK_FillBitmap ), Any( xFillBitmap ) ); |
| if ( ( rxPropertySet->getPropertyValue( TKGet( TK_FillBitmapLogicalSize ) ) >>= bLogicalSize ) |
| && ( rxPropertySet->getPropertyValue( TKGet( TK_FillBitmapSizeX ) ) >>= aSize.Width ) |
| && ( rxPropertySet->getPropertyValue( TKGet( TK_FillBitmapSizeY ) ) >>= aSize.Height ) ) |
| { |
| if ( !aSize.Width || !aSize.Height ) |
| { |
| rxPropertySet->setPropertyValue( TKGet( TK_FillBitmapLogicalSize ), Any( sal_True ) ); |
| rxPropertySet->setPropertyValue( TKGet( TK_FillBitmapSizeX ), Any( aGraphicUserIter->maLogicalSize.Width ) ); |
| rxPropertySet->setPropertyValue( TKGet( TK_FillBitmapSizeY ), Any( aGraphicUserIter->maLogicalSize.Height ) ); |
| } |
| } |
| if ( aGraphicUserIter->mxPagePropertySet.is() ) |
| aGraphicUserIter->mxPagePropertySet->setPropertyValue( TKGet( TK_Background ), Any( rxPropertySet ) ); |
| } |
| } |
| aGraphicUserIter++; |
| } |
| } |
| } |
| } |
| aGraphicIter++; |
| } |
| } |
| catch ( Exception& ) |
| { |
| } |
| } |
| |
| // ---------------- |
| // - ImpOptimizer - |
| // ---------------- |
| |
| ImpOptimizer::ImpOptimizer( const Reference< XComponentContext >& rxContext, const Reference< XModel >& rxModel ) : |
| mxContext ( rxContext ), |
| mxModel ( rxModel ), |
| mbJPEGCompression ( sal_False ), |
| mnJPEGQuality ( 90 ), |
| mbRemoveCropArea ( sal_False ), |
| mnImageResolution ( 0 ), |
| mbEmbedLinkedGraphics ( sal_True ), |
| mbOLEOptimization ( sal_False ), |
| mnOLEOptimizationType ( 0 ), |
| mbDeleteUnusedMasterPages ( sal_False ), |
| mbDeleteHiddenSlides ( sal_False ), |
| mbDeleteNotesPages ( sal_False ), |
| mbOpenNewDocument ( sal_True ) |
| { |
| OSL_TRACE("ImpOptimizer::ImpOptimizer"); |
| Reference< XController > xController( mxModel->getCurrentController() ); |
| if (xController.is() ) |
| mxFrame.set( xController->getFrame() ); |
| } |
| |
| // ----------------------------------------------------------------------------- |
| |
| ImpOptimizer::~ImpOptimizer() |
| { |
| OSL_TRACE("ImpOptimizer::~ImpOptimizer"); |
| } |
| |
| // ----------------------------------------------------------------------------- |
| |
| void ImpOptimizer::DispatchStatus() |
| { |
| if ( mxStatusListener.is() ) |
| { |
| FeatureStateEvent aState; |
| aState.IsEnabled = sal_True; |
| aState.State <<= GetStatusSequence(); |
| mxStatusListener->statusChanged( aState ); |
| } |
| } |
| |
| // ----------------------------------------------------------------------------- |
| |
| sal_Bool ImpOptimizer::ImplOptimize() |
| { |
| |
| if ( maCustomShowName.getLength() ) |
| ImpExtractCustomShow( mxModel, maCustomShowName ); |
| |
| if ( mbDeleteUnusedMasterPages ) |
| { |
| SetStatusValue( TK_Progress, Any( static_cast< sal_Int32 >( 40 ) ) ); |
| SetStatusValue( TK_Status, Any( ConfigurationAccess::getString( STR_DELETING_SLIDES ) ) ); |
| DispatchStatus(); |
| ImpDeleteUnusedMasterPages( mxModel ); |
| } |
| |
| if ( mbDeleteHiddenSlides ) |
| { |
| SetStatusValue( TK_Progress, Any( static_cast< sal_Int32 >( 40 ) ) ); |
| SetStatusValue( TK_Status, Any( ConfigurationAccess::getString( STR_DELETING_SLIDES ) ) ); |
| DispatchStatus(); |
| ImpDeleteHiddenSlides( mxModel ); |
| } |
| |
| if ( mbDeleteNotesPages ) |
| { |
| SetStatusValue( TK_Status, Any( ConfigurationAccess::getString( STR_DELETING_SLIDES ) ) ); |
| DispatchStatus(); |
| ImpDeleteNotesPages( mxModel ); |
| } |
| |
| if ( mbOLEOptimization ) |
| { |
| SetStatusValue( TK_Progress, Any( static_cast< sal_Int32 >( 45 ) ) ); |
| SetStatusValue( TK_Status, Any( ConfigurationAccess::getString( STR_CREATING_OLE_REPLACEMENTS ) ) ); |
| DispatchStatus(); |
| ImpConvertOLE( mxModel, mnOLEOptimizationType ); |
| } |
| |
| if ( mbJPEGCompression || mbRemoveCropArea || mnImageResolution ) |
| { |
| SetStatusValue( TK_Progress, Any( static_cast< sal_Int32 >( 50 ) ) ); |
| SetStatusValue( TK_Status, Any( ConfigurationAccess::getString( STR_OPTIMIZING_GRAPHICS ) ) ); |
| DispatchStatus(); |
| |
| std::vector< GraphicCollector::GraphicEntity > aGraphicList; |
| GraphicSettings aGraphicSettings( mbJPEGCompression, mnJPEGQuality, mbRemoveCropArea, mnImageResolution, mbEmbedLinkedGraphics ); |
| GraphicCollector::CollectGraphics( mxContext, mxModel, aGraphicSettings, aGraphicList ); |
| CompressGraphics( *this, mxContext, aGraphicSettings, aGraphicList ); |
| } |
| SetStatusValue( TK_Progress, Any( static_cast< sal_Int32 >( 100 ) ) ); |
| DispatchStatus(); |
| return sal_True; |
| } |
| |
| static void DispatchURL( Reference< XComponentContext > xMSF, OUString sURL, Reference< XFrame > xFrame ) |
| { |
| try |
| { |
| Reference< XURLTransformer > xURLTransformer( xMSF->getServiceManager()->createInstanceWithContext( |
| OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ) ), xMSF ), UNO_QUERY_THROW ); |
| util::URL aUrl; |
| aUrl.Complete = sURL; |
| xURLTransformer->parseStrict( aUrl ); |
| Sequence< PropertyValue > aArgs; |
| Reference< XDispatchProvider > xDispatchProvider( xFrame, UNO_QUERY_THROW ); |
| Reference< XDispatch > xDispatch = xDispatchProvider->queryDispatch( aUrl, OUString(), 0 ); // "_self" |
| if ( xDispatch.is() ) |
| xDispatch->dispatch( aUrl, aArgs ); |
| } |
| catch( Exception& ) |
| { |
| } |
| } |
| |
| // ----------------------------------------------------------------------------- |
| |
| sal_Bool ImpOptimizer::Optimize( const Sequence< PropertyValue >& rArguments ) |
| { |
| OSL_TRACE("ImpOptimizer::Optimize"); |
| sal_Bool bRet = sal_True; |
| |
| if ( mxModel.is() ) |
| { |
| Reference< XWindowPeer > xParentWindow; |
| sal_Int64 nEstimatedFileSize = 0; |
| SetStatusValue( TK_Progress, Any( static_cast< sal_Int32 >( 0 ) ) ); |
| DispatchStatus(); |
| |
| int i, nICount; |
| for ( i = 0, nICount = rArguments.getLength(); i < nICount; i++ ) |
| { |
| switch( TKGet( rArguments[ i ].Name ) ) |
| { |
| case TK_StatusListener : rArguments[ i ].Value >>= mxStatusListener; break; |
| case TK_ParentWindow: rArguments[ i ].Value >>= xParentWindow; break; |
| case TK_Settings : |
| { |
| com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > aSettings; |
| int j, nJCount; |
| rArguments[ i ].Value >>= aSettings; |
| for ( j = 0, nJCount = aSettings.getLength(); j < nJCount; j++ ) |
| { |
| switch( TKGet( aSettings[ j ].Name ) ) |
| { |
| case TK_JPEGCompression : aSettings[ j ].Value >>= mbJPEGCompression; break; |
| case TK_JPEGQuality : aSettings[ j ].Value >>= mnJPEGQuality; break; |
| case TK_RemoveCropArea : aSettings[ j ].Value >>= mbRemoveCropArea; break; |
| case TK_ImageResolution : aSettings[ j ].Value >>= mnImageResolution; break; |
| case TK_EmbedLinkedGraphics : aSettings[ j ].Value >>= mbEmbedLinkedGraphics; break; |
| case TK_OLEOptimization : aSettings[ j ].Value >>= mbOLEOptimization; break; |
| case TK_OLEOptimizationType : aSettings[ j ].Value >>= mnOLEOptimizationType; break; |
| case TK_CustomShowName : aSettings[ j ].Value >>= maCustomShowName; break; |
| case TK_DeleteUnusedMasterPages : aSettings[ j ].Value >>= mbDeleteUnusedMasterPages; break; |
| case TK_DeleteHiddenSlides : aSettings[ j ].Value >>= mbDeleteHiddenSlides; break; |
| case TK_DeleteNotesPages : aSettings[ j ].Value >>= mbDeleteNotesPages; break; |
| case TK_SaveAsURL : aSettings[ j ].Value >>= maSaveAsURL; break; |
| case TK_FilterName : aSettings[ j ].Value >>= maFilterName; break; |
| case TK_OpenNewDocument : aSettings[ j ].Value >>= mbOpenNewDocument; break; |
| case TK_EstimatedFileSize : aSettings[ j ].Value >>= nEstimatedFileSize; break; |
| default: break; |
| } |
| } |
| } |
| break; |
| default: break; |
| } |
| } |
| |
| sal_Int64 nSourceSize = 0; |
| sal_Int64 nDestSize = 0; |
| |
| Reference< XFrame > xSelf; |
| if ( maSaveAsURL.getLength() ) |
| { |
| |
| SetStatusValue( TK_Progress, Any( static_cast< sal_Int32 >( 10 ) ) ); |
| SetStatusValue( TK_Status, Any( ConfigurationAccess::getString( STR_DUPLICATING_PRESENTATION ) ) ); |
| DispatchStatus(); |
| |
| Reference< XStorable >xStorable( mxModel, UNO_QUERY ); |
| if ( xStorable.is() ) |
| { |
| if ( xStorable->hasLocation() ) |
| nSourceSize = PPPOptimizer::GetFileSize( xStorable->getLocation() ); |
| |
| Sequence< PropertyValue > aArguments; |
| if ( maFilterName.getLength() ) |
| { |
| int nLength = aArguments.getLength(); |
| aArguments.realloc( nLength + 1 ); |
| aArguments[ nLength ].Name = TKGet( TK_FilterName ); |
| aArguments[ nLength ].Value <<= maFilterName; |
| } |
| xStorable->storeToURL( maSaveAsURL, aArguments ); |
| if ( !nSourceSize ) |
| nSourceSize = PPPOptimizer::GetFileSize( maSaveAsURL ); |
| |
| SetStatusValue( TK_Progress, Any( static_cast< sal_Int32 >( 30 ) ) ); |
| SetStatusValue( TK_Status, Any( ConfigurationAccess::getString( STR_DUPLICATING_PRESENTATION ) ) ); |
| DispatchStatus(); |
| |
| Reference< XDesktop > xDesktop( mxContext->getServiceManager()->createInstanceWithContext( |
| OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ) ), mxContext ), UNO_QUERY ); |
| Reference< XFrame > xFrame( xDesktop, UNO_QUERY ); |
| xSelf = xFrame->findFrame( TKGet( TK__blank ), FrameSearchFlag::CREATE ); |
| Reference< XComponentLoader > xComponentLoader( xSelf, UNO_QUERY ); |
| |
| Sequence< PropertyValue > aLoadProps( 1 ); |
| aLoadProps[ 0 ].Name = TKGet( TK_Hidden ); |
| aLoadProps[ 0 ].Value <<= (sal_Bool)( sal_True ); |
| mxModel = Reference< XModel >( xComponentLoader->loadComponentFromURL( |
| maSaveAsURL, TKGet( TK__self ), 0, aLoadProps ), UNO_QUERY ); |
| } |
| } |
| |
| // check if the document is ReadOnly -> error |
| Reference< XStorable > xStorable( mxModel, UNO_QUERY ); |
| if ( xStorable.is() && !xStorable->isReadonly() ) |
| { |
| mxModel->lockControllers(); |
| bRet = ImplOptimize(); |
| mxModel->unlockControllers(); |
| |
| // clearing undo stack: |
| Reference< XFrame > xFrame( mxFrame ); |
| if ( xFrame.is() ) |
| { |
| const OUString sSlot( RTL_CONSTASCII_USTRINGPARAM( "slot:27115" ) ); |
| DispatchURL( mxContext, sSlot, xFrame ); |
| } |
| } |
| |
| if ( maSaveAsURL.getLength() ) |
| { |
| if ( xStorable.is() ) |
| { |
| xStorable->store(); |
| nDestSize = PPPOptimizer::GetFileSize( maSaveAsURL ); |
| } |
| } |
| |
| if ( xParentWindow.is() ) |
| { |
| InformationDialog aInformationDialog( |
| mxContext, xParentWindow, maSaveAsURL, mbOpenNewDocument, |
| nSourceSize, nDestSize, nEstimatedFileSize ); |
| aInformationDialog.execute(); |
| SetStatusValue( TK_OpenNewDocument, Any( mbOpenNewDocument ) ); |
| DispatchStatus(); |
| } |
| |
| if ( maSaveAsURL.getLength() ) |
| { |
| if ( mbOpenNewDocument && xSelf.is() ) |
| { |
| Reference< awt::XWindow > xContainerWindow( xSelf->getContainerWindow() ); |
| xContainerWindow->setVisible( sal_True ); |
| } |
| else |
| { |
| Reference< XComponent > xComponent( mxModel, UNO_QUERY ); |
| xComponent->dispose(); |
| } |
| } |
| if ( nSourceSize && nDestSize ) |
| { |
| SetStatusValue( TK_FileSizeSource, Any( nSourceSize ) ); |
| SetStatusValue( TK_FileSizeDestination, Any( nDestSize ) ); |
| DispatchStatus(); |
| } |
| } |
| else |
| bRet = sal_False; |
| return bRet; |
| } |
| |