Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/sdext/source/minimizer/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 33 kB image not shown  

Quelle  impoptimizer.cxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   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 .
 */



#include "impoptimizer.hxx"
#include "pppoptimizer.hxx"
#include "graphiccollector.hxx"
#include "pagecollector.hxx"
#include "informationdialog.hxx"

#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/Size.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/frame/Desktop.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/GraphicProvider.hpp>
#include <com/sun/star/graphic/XGraphicProvider.hpp>
#include <com/sun/star/drawing/XShapes.hpp>
#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
#include <com/sun/star/drawing/XMasterPagesSupplier.hpp>
#include <com/sun/star/presentation/XPresentationPage.hpp>
#include <com/sun/star/rendering/XBitmap.hpp>
#include <com/sun/star/document/XFilter.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.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/io/TempFile.hpp>
#include <com/sun/star/frame/XComponentLoader.hpp>
#include <com/sun/star/util/URLTransformer.hpp>

#include <comphelper/propertyvalue.hxx>

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::container;
using namespace ::com::sun::star::presentation;

static void ImpExtractCustomShow( const Reference< XModel >& rxModel, std::u16string_view rCustomShowName )
{
    std::vector< Reference< XDrawPage > > vNonUsedPageList;
    try
    {
        PageCollector::CollectNonCustomShowPages( rxModel, rCustomShowName, vNonUsedPageList );
        Reference< XDrawPagesSupplier > xDrawPagesSupplier( rxModel, UNO_QUERY_THROW );
        Reference< XDrawPages > xDrawPages( xDrawPagesSupplier->getDrawPages(), UNO_SET_THROW );
        forconst auto& rxPage : vNonUsedPageList )
            xDrawPages->remove( rxPage );
    }
    catch( Exception& )
    {

    }
}

static void ImpDeleteUnusedMasterPages( const Reference< XModel >& rxModel )
{
    std::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_SET_THROW );
    forconst auto& rMasterPage : aMasterPageList )
    {
        if ( !rMasterPage.bUsed )
            xMasterPages->remove( rMasterPage.xMasterPage );
    }
}

static void ImpDeleteHiddenSlides(  const Reference< XModel >& rxModel )
{
    try
    {
        Reference< XDrawPagesSupplier > xDrawPagesSupplier( rxModel, UNO_QUERY_THROW );
        Reference< XDrawPages > xDrawPages( xDrawPagesSupplier->getDrawPages(), UNO_SET_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 );

            bool bVisible = true;
            if ( xPropSet->getPropertyValue( u"Visible"_ustr ) >>= bVisible )
            {
                if (!bVisible )
                {
                    xDrawPages->remove( xDrawPage );
                    i--;
                }
            }
        }
    }
    catch( Exception& )
    {
    }
}

static void ImpDeleteNotesPages( const Reference< XModel >& rxModel )
{
    try
    {
        Reference< XDrawPagesSupplier > xDrawPagesSupplier( rxModel, UNO_QUERY_THROW );
        Reference< XDrawPages > xDrawPages( xDrawPagesSupplier->getDrawPages(), UNO_SET_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 ) );

            xPropSet->setPropertyValue( u"Layout"_ustr, Any( sal_Int16(21) ) );
        }
    }
    catch( Exception& )
    {
    }
}

static void ImpConvertOLE( const Reference< XModel >& rxModel, sal_Int32 nOLEOptimizationType )
{
    try
    {
        Reference< XDrawPagesSupplier > xDrawPagesSupplier( rxModel, UNO_QUERY_THROW );
        Reference< XDrawPages > xDrawPages( xDrawPagesSupplier->getDrawPages(), UNO_SET_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++ )
            {
                Reference< XShape > xShape( xShapes->getByIndex( j ), UNO_QUERY_THROW );
                if ( xShape->getShapeType() == "com.sun.star.drawing.OLE2Shape" )
                {
                    Reference< XPropertySet > xPropSet( xShape, UNO_QUERY_THROW );

                    bool bConvertOLE = nOLEOptimizationType == 0;
                    if ( nOLEOptimizationType == 1 )
                    {
                        bool bIsInternal = true;
                        xPropSet->getPropertyValue( u"IsInternal"_ustr ) >>= bIsInternal;
                        bConvertOLE = !bIsInternal;
                    }
                    if ( bConvertOLE )
                    {
                        Reference< XGraphic > xGraphic;
                        if ( xPropSet->getPropertyValue( u"Graphic"_ustr ) >>= xGraphic )
                        {
                            Reference< XMultiServiceFactory > xFact( rxModel, UNO_QUERY_THROW );
                            Reference< XShape > xShape2( xFact->createInstance( u"com.sun.star.drawing.GraphicObjectShape"_ustr ), UNO_QUERY_THROW );
                            xShapes->add( xShape2 );
                            xShape2->setPosition( xShape->getPosition() );
                            xShape2->setSize( xShape->getSize() );
                            Reference< XPropertySet > xPropSet2( xShape2, UNO_QUERY_THROW );
                            xPropSet2->setPropertyValue( u"Graphic"_ustr, Any( xGraphic ) );
                            xShapes->remove( xShape );
                            xPropSet2->setPropertyValue( u"ZOrder"_ustr, Any( j ) );
                        }
                    }
                }
            }
        }
    }
    catch( Exception& )
    {
    }
}

static void ImpCompressGraphic( Reference< XGraphicProvider > const & rxGraphicProvider, const Reference< XGraphic >& rxGraphic, Reference< XOutputStream > const & rxOutputStream,
    const OUString& rDestMimeType, const awt::Size& rLogicalSize, sal_Int32 nJPEGQuality, sal_Int32 nImageResolution, bool bRemoveCropping, const text::GraphicCrop& rGraphicCropLogic )
{
    try
    {
        if ( rxGraphicProvider.is() && rxOutputStream.is() )
        {
            Sequence< PropertyValue > aFilterData{
                comphelper::makePropertyValue(u"ImageResolution"_ustr, nImageResolution),
                comphelper::makePropertyValue(u"ColorMode"_ustr, sal_Int32(0)), // todo: jpeg color mode (0->true color, 1->greyscale)
                comphelper::makePropertyValue(u"Quality"_ustr, nJPEGQuality), // quality that is used if we export to jpeg
                comphelper::makePropertyValue(u"Compression"_ustr, sal_Int32(6)), // compression that is used if we export to png
                comphelper::makePropertyValue(u"Interlaced"_ustr, sal_Int32(0)), // interlaced is turned off if we export to png
                comphelper::makePropertyValue(u"LogicalSize"_ustr, rLogicalSize),
                comphelper::makePropertyValue(u"RemoveCropArea"_ustr, bRemoveCropping),
                comphelper::makePropertyValue(u"GraphicCropLogic"_ustr, rGraphicCropLogic)
            };

            Sequence< PropertyValue > aArgs{
                comphelper::makePropertyValue(u"MimeType"_ustr, rDestMimeType), // the GraphicProvider is using "MimeType", the GraphicExporter "MediaType"...
                comphelper::makePropertyValue(u"OutputStream"_ustr, rxOutputStream),
                comphelper::makePropertyValue(u"FilterData"_ustr, aFilterData)
            };

            rxGraphicProvider->storeGraphic( rxGraphic, aArgs );
        }
    }
    catch( Exception& )
    {
    }
}

static 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( u"MimeType"_ustr ) >>= aSourceMimeType )
        {
            sal_Int8 nGraphicType( xGraphic->getType() );
            if ( nGraphicType == css::graphic::GraphicType::PIXEL )
            {
                bool bTransparent = false;
                bool bAlpha       = false;
                bool bAnimated    = false;

                awt::Size aSourceSizePixel( 0, 0 );
                text::GraphicCrop aGraphicCropPixel( 0, 0, 0, 0 );

                if ( ( xGraphicPropertySet->getPropertyValue( u"SizePixel"_ustr ) >>= aSourceSizePixel ) &&
                    ( xGraphicPropertySet->getPropertyValue( u"Transparent"_ustr ) >>= bTransparent ) &&
                    ( xGraphicPropertySet->getPropertyValue( u"Alpha"_ustr ) >>= bAlpha ) &&
                    ( xGraphicPropertySet->getPropertyValue( u"Animated"_ustr ) >>= bAnimated ) )
                {
                    awt::Size aDestSizePixel( aSourceSizePixel );
                    if ( !bAnimated )
                    {
                        bool bNeedsOptimizing = false;
                        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 = true;

                            if ( aSize100thMM.Width && aSize100thMM.Height )
                            {
                                aGraphicCropPixel.Left = static_cast< sal_Int32 >( ( static_cast<double>(aSourceSizePixel.Width) * aGraphicCropLogic.Left ) / aSize100thMM.Width );
                                aGraphicCropPixel.Top = static_cast< sal_Int32 >( ( static_cast<double>(aSourceSizePixel.Height)* aGraphicCropLogic.Top ) / aSize100thMM.Height );
                                aGraphicCropPixel.Right = static_cast< sal_Int32 >( ( static_cast<double>(aSourceSizePixel.Width) * ( aSize100thMM.Width - aGraphicCropLogic.Right ) ) / aSize100thMM.Width );
                                aGraphicCropPixel.Bottom = static_cast< sal_Int32 >( ( static_cast<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 = false;
                            }
                        }
                        if ( ( aSourceSizePixel.Width > 0 ) && ( aSourceSizePixel.Height > 0 ) )
                        {
                            OUString aDestMimeType( u"image/png"_ustr  );
                            if (rGraphicSettings.mbJPEGCompression && !bTransparent && !bAlpha)
                            {
                                aDestMimeType = "image/jpeg";
//                                      if( aSourceMimeType != aDestMimeType )
                                bNeedsOptimizing = true;
                            }
                            if ( bRemoveCropArea )
                                aDestSizePixel = aSourceSizePixel;
                            if ( rGraphicSettings.mnImageResolution && aLogicalSize.Width && aLogicalSize.Height )
                            {
                                const double fSourceDPIX = static_cast<double>(aSourceSizePixel.Width) / (static_cast<double>(aLogicalSize.Width) / 2540.0 );
                                const double fSourceDPIY = static_cast<double>(aSourceSizePixel.Height)/ (static_cast<double>(aLogicalSize.Height)/ 2540.0 );

                                // check, if the bitmap DPI exceeds the maximum DPI
                                if( ( fSourceDPIX > rGraphicSettings.mnImageResolution ) || ( fSourceDPIY > rGraphicSettings.mnImageResolution ) )
                                {
                                    const double fNewSizePixelX = (static_cast<double>(aDestSizePixel.Width) * rGraphicSettings.mnImageResolution ) / fSourceDPIX;
                                    const double fNewSizePixelY = (static_cast<double>(aDestSizePixel.Height)* rGraphicSettings.mnImageResolution ) / fSourceDPIY;

                                    aDestSizePixel = awt::Size( static_cast<sal_Int32>(fNewSizePixelX), static_cast<sal_Int32>(fNewSizePixelY) );
                                    bNeedsOptimizing = true;
                                }
                            }
                            if ( bNeedsOptimizing && aDestSizePixel.Width && aDestSizePixel.Height )
                            {
                                Reference< XStream > xTempFile( io::TempFile::create(rxContext), UNO_QUERY_THROW );
                                Reference< XOutputStream > xOutputStream( xTempFile->getOutputStream() );
                                Reference< XGraphicProvider > xGraphicProvider( GraphicProvider::create( rxContext ) );

                                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{ comphelper::makePropertyValue(
                                    u"InputStream"_ustr, xInputStream) };
                                xNewGraphic = xGraphicProvider->queryGraphic( aArgs );
                            }
                        }
                    }
                }
            }
            else // this is a metafile
            {
                const OUString& aDestMimeType( aSourceMimeType );
                Reference< XStream > xTempFile( io::TempFile::create(rxContext), UNO_QUERY_THROW );
                Reference< XOutputStream > xOutputStream( xTempFile->getOutputStream() );
                Reference< XGraphicProvider > xGraphicProvider( GraphicProvider::create( rxContext ) );
                ImpCompressGraphic( xGraphicProvider, xGraphic, xOutputStream, aDestMimeType, aLogicalSize, rGraphicSettings.mnJPEGQuality, rGraphicSettings.mnImageResolution, false, aGraphicCropLogic );
                Reference< XInputStream > xInputStream( xTempFile->getInputStream() );
                Reference< XSeekable > xSeekable( xInputStream, UNO_QUERY_THROW );
                xSeekable->seek( 0 );
                Sequence< PropertyValue > aArgs{ comphelper::makePropertyValue(u"InputStream"_ustr,
                                                                               xInputStream) };
                xNewGraphic = xGraphicProvider->queryGraphic( aArgs );
            }
        }
    }
    catch( Exception& )
    {
    }
    return xNewGraphic;
}

static void CompressGraphics( ImpOptimizer& rOptimizer, const Reference< XComponentContext >& rxContext, const GraphicSettings& rGraphicSettings,
    std::vector< GraphicCollector::GraphicEntity >& rGraphicList )
{
    try
    {
        double i = 0;
        forauto& rGraphic : rGraphicList )
        {
            i++;
            sal_Int32 nProgress = static_cast< sal_Int32 >( 40.0 * ( i / static_castdouble >( rGraphicList.size() ) ) ) + 50;
            rOptimizer.SetStatusValue( TK_Progress, Any( nProgress ) );
            rOptimizer.DispatchStatus();

            if ( !rGraphic.maUser.empty() )
            {
                GraphicSettings aGraphicSettings( rGraphicSettings );
                aGraphicSettings.mbRemoveCropArea = rGraphic.mbRemoveCropArea;

                Reference< XGraphic > xGraphic;
                if ( rGraphic.maUser[ 0 ].mbFillBitmap && rGraphic.maUser[ 0 ].mxPropertySet.is() )
                {
                    Reference< rendering::XBitmap > xFillBitmap;
                    if ( rGraphic.maUser[ 0 ].mxPropertySet->getPropertyValue( u"FillBitmap"_ustr ) >>= xFillBitmap )
                        xGraphic.set( xFillBitmap, UNO_QUERY_THROW );
                }
                else if ( rGraphic.maUser[ 0 ].mxShape.is() )
                {
                    Reference< XPropertySet > xShapePropertySet( rGraphic.maUser[ 0 ].mxShape, UNO_QUERY_THROW );
                    xShapePropertySet->getPropertyValue( u"Graphic"_ustr ) >>= xGraphic;
                }
                if ( xGraphic.is() )
                {
                    Reference< XPropertySet > xNewGraphicPropertySet( xGraphic, UNO_QUERY_THROW );
                    awt::Size aSize100thMM( GraphicCollector::GetOriginalSize( rxContext, xGraphic ) );
                    Reference< XGraphic > xNewGraphic( ImpCompressGraphic( rxContext, xGraphic, rGraphic.maLogicalSize, rGraphic.maGraphicCropLogic, aGraphicSettings ) );
                    if ( xNewGraphic.is() )
                    {
                        // applying graphic to each user
                        forauto& rGraphicUser : rGraphic.maUser )
                        {
                            if ( rGraphicUser.mxShape.is() )
                            {
                                Reference< XPropertySet > xShapePropertySet( rGraphicUser.mxShape, UNO_QUERY_THROW );
                                xShapePropertySet->setPropertyValue( u"Graphic"_ustr, Any( xNewGraphic ) );

                                if ( rGraphicUser.maGraphicCropLogic.Left || rGraphicUser.maGraphicCropLogic.Top
                                || rGraphicUser.maGraphicCropLogic.Right || rGraphicUser.maGraphicCropLogic.Bottom )
                                {   // removing crop area was not possible or shouldn't been applied
                                    text::GraphicCrop aGraphicCropLogic( 0, 0, 0, 0 );
                                    if ( !aGraphicSettings.mbRemoveCropArea )
                                    {
                                        awt::Size aNewSize( GraphicCollector::GetOriginalSize( rxContext, xNewGraphic ) );
                                        aGraphicCropLogic.Left = static_cast<sal_Int32>(static_cast<double>(rGraphicUser.maGraphicCropLogic.Left) * (static_cast<double>(aNewSize.Width) / static_cast<double>(aSize100thMM.Width)));
                                        aGraphicCropLogic.Top = static_cast<sal_Int32>(static_cast<double>(rGraphicUser.maGraphicCropLogic.Top) * (static_cast<double>(aNewSize.Height) / static_cast<double>(aSize100thMM.Height)));
                                        aGraphicCropLogic.Right = static_cast<sal_Int32>(static_cast<double>(rGraphicUser.maGraphicCropLogic.Right) * (static_cast<double>(aNewSize.Width) / static_cast<double>(aSize100thMM.Width)));
                                        aGraphicCropLogic.Bottom = static_cast<sal_Int32>(static_cast<double>(rGraphicUser.maGraphicCropLogic.Bottom) * (static_cast<double>(aNewSize.Height) / static_cast<double>(aSize100thMM.Height)));
                                    }
                                    xShapePropertySet->setPropertyValue( u"GraphicCrop"_ustr, Any( aGraphicCropLogic ) );
                                }
                            }
                            else if ( rGraphicUser.mxPropertySet.is() )
                            {
                                Reference< rendering::XBitmap > xFillBitmap( xNewGraphic, UNO_QUERY );
                                if ( xFillBitmap.is() )
                                {
                                    awt::Size aSize;
                                    bool bLogicalSize;

                                    Reference< XPropertySet >& rxPropertySet( rGraphicUser.mxPropertySet );
                                    rxPropertySet->setPropertyValue( u"FillBitmap"_ustr, Any( xFillBitmap ) );
                                    if ( ( rxPropertySet->getPropertyValue( u"FillBitmapLogicalSize"_ustr ) >>= bLogicalSize )
                                        && ( rxPropertySet->getPropertyValue( u"FillBitmapSizeX"_ustr ) >>= aSize.Width )
                                        && ( rxPropertySet->getPropertyValue( u"FillBitmapSizeY"_ustr ) >>= aSize.Height ) )
                                    {
                                        if ( !aSize.Width || !aSize.Height )
                                        {
                                            rxPropertySet->setPropertyValue( u"FillBitmapLogicalSize"_ustr, Any( true ) );
                                            rxPropertySet->setPropertyValue( u"FillBitmapSizeX"_ustr, Any( rGraphicUser.maLogicalSize.Width ) );
                                            rxPropertySet->setPropertyValue( u"FillBitmapSizeY"_ustr, Any( rGraphicUser.maLogicalSize.Height ) );
                                        }
                                    }
                                    if ( rGraphicUser.mxPagePropertySet.is() )
                                        rGraphicUser.mxPagePropertySet->setPropertyValue( u"Background"_ustr, Any( rxPropertySet ) );
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    catch ( Exception& )
    {
    }
}


ImpOptimizer::ImpOptimizer( const Reference< XComponentContext >& rxContext, const Reference< XModel >& rxModel ) :
    mxContext                   ( rxContext ),
    mxModel                     ( rxModel ),
    mbJPEGCompression           ( false ),
    mnJPEGQuality               ( 90 ),
    mbRemoveCropArea            ( false ),
    mnImageResolution           ( 0 ),
    mbEmbedLinkedGraphics       ( true ),
    mbOLEOptimization           ( false ),
    mnOLEOptimizationType       ( 0 ),
    mbDeleteUnusedMasterPages   ( false ),
    mbDeleteHiddenSlides        ( false ),
    mbDeleteNotesPages          ( false ),
    mbOpenNewDocument           ( true )
{
}


ImpOptimizer::~ImpOptimizer()
{
}


void ImpOptimizer::DispatchStatus()
{
    if ( mxStatusDispatcher.is() )
    {
        URL aURL;
        aURL.Protocol = "vnd.com.sun.star.comp.PresentationMinimizer:";
        aURL.Path = "statusupdate";
        mxStatusDispatcher->dispatch( aURL, GetStatusSequence() );
    }
}


void ImpOptimizer::Optimize()
{

    if ( !maCustomShowName.isEmpty() )
        ImpExtractCustomShow( mxModel, maCustomShowName );

    if ( mbDeleteHiddenSlides )
    {
        SetStatusValue( TK_Progress, Any( static_cast< sal_Int32 >( 40 ) ) );
        SetStatusValue( TK_Status, Any( u"STR_DELETING_SLIDES"_ustr ) );
        DispatchStatus();
        ImpDeleteHiddenSlides( mxModel );
    }

    if ( mbDeleteNotesPages )
    {
        SetStatusValue( TK_Status, Any( u"STR_DELETING_SLIDES"_ustr ) );
        DispatchStatus();
        ImpDeleteNotesPages( mxModel );
    }

    if ( mbDeleteUnusedMasterPages )
    {
        SetStatusValue( TK_Progress, Any( static_cast< sal_Int32 >( 40 ) ) );
        SetStatusValue( TK_Status, Any( u"STR_DELETING_SLIDES"_ustr ) );
        DispatchStatus();
        ImpDeleteUnusedMasterPages( mxModel );
    }

    if ( mbOLEOptimization )
    {
        SetStatusValue( TK_Progress, Any( static_cast< sal_Int32 >( 45 ) ) );
        SetStatusValue( TK_Status, Any( u"STR_CREATING_OLE_REPLACEMENTS"_ustr ) );
        DispatchStatus();
        ImpConvertOLE( mxModel, mnOLEOptimizationType );
    }

    if ( mbJPEGCompression || mbRemoveCropArea || mnImageResolution )
    {
        SetStatusValue( TK_Progress, Any( static_cast< sal_Int32 >( 50 ) ) );
        SetStatusValue( TK_Status, Any( u"STR_OPTIMIZING_GRAPHICS"_ustr ) );
        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();
}

static void DispatchURL( const Reference< XComponentContext >& xContext, const OUString&&nbsp;sURL, const Reference< XFrame >& xFrame )
{
    try
    {
        Reference< XURLTransformer > xURLTransformer( URLTransformer::create(xContext) );
        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& )
    {
    }
}


void ImpOptimizer::Optimize( const Sequence< PropertyValue >& rArguments )
{
    if ( !mxModel.is() )
        return;

    sal_Int64 nEstimatedFileSize = 0;
    SetStatusValue( TK_Progress, Any( static_cast< sal_Int32 >( 0 ) ) );
    DispatchStatus();

    for ( const auto& rArgument : rArguments )
    {
        switch( TKGet( rArgument.Name ) )
        {
            case TK_StatusDispatcher : rArgument.Value >>= mxStatusDispatcher; break;
            case TK_DocumentFrame: rArgument.Value >>= mxDocumentFrame; break;
            case TK_DialogParentWindow: rArgument.Value >>= mxDialogParentWindow; break;
            case TK_Settings :
            {
                css::uno::Sequence< css::beans::PropertyValue > aSettings;
                rArgument.Value >>= aSettings;
                for (const auto& rSetting : aSettings)
                {
                    switch( TKGet( rSetting.Name ) )
                    {
                        case TK_JPEGCompression         : rSetting.Value >>= mbJPEGCompression; break;
                        case TK_JPEGQuality             : rSetting.Value >>= mnJPEGQuality; break;
                        case TK_RemoveCropArea          : rSetting.Value >>= mbRemoveCropArea; break;
                        case TK_ImageResolution         : rSetting.Value >>= mnImageResolution; break;
                        case TK_EmbedLinkedGraphics     : rSetting.Value >>= mbEmbedLinkedGraphics; break;
                        case TK_OLEOptimization         : rSetting.Value >>= mbOLEOptimization; break;
                        case TK_OLEOptimizationType     : rSetting.Value >>= mnOLEOptimizationType; break;
                        case TK_CustomShowName          : rSetting.Value >>= maCustomShowName; break;
                        case TK_DeleteUnusedMasterPages : rSetting.Value >>= mbDeleteUnusedMasterPages; break;
                        case TK_DeleteHiddenSlides      : rSetting.Value >>= mbDeleteHiddenSlides; break;
                        case TK_DeleteNotesPages        : rSetting.Value >>= mbDeleteNotesPages; break;
                        case TK_SaveAsURL               : rSetting.Value >>= maSaveAsURL; break;
                        case TK_FilterName              : rSetting.Value >>= maFilterName; break;
                        case TK_OpenNewDocument         : rSetting.Value >>= mbOpenNewDocument; break;
                        case TK_EstimatedFileSize       : rSetting.Value >>= nEstimatedFileSize; break;
                        defaultbreak;
                    }
                }
            }
            break;
            defaultbreak;
        }
    }

    sal_Int64 nSourceSize = 0;
    sal_Int64 nDestSize = 0;

    Reference< XFrame > xSelf;
    if ( !maSaveAsURL.isEmpty() )
    {

        SetStatusValue( TK_Progress, Any( static_cast< sal_Int32 >( 10 ) ) );
        SetStatusValue( TK_Status, Any( u"STR_DUPLICATING_PRESENTATION"_ustr ) );
        DispatchStatus();

        Reference< XStorable >xStorable( mxModel, UNO_QUERY );
        if ( xStorable.is() )
        {
            if ( xStorable->hasLocation() )
                nSourceSize = PPPOptimizer::GetFileSize( xStorable->getLocation() );

            Sequence< PropertyValue > aArguments;
            if ( !maFilterName.isEmpty() )
            {
                int nLength = aArguments.getLength();
                aArguments.realloc( nLength + 1 );
                auto pArguments = aArguments.getArray();
                pArguments[ nLength ].Name = "FilterName";
                pArguments[ 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( u"STR_DUPLICATING_PRESENTATION"_ustr ) );
            DispatchStatus();

            Reference< XDesktop2 > xDesktop = Desktop::create( mxContext );
            xSelf = xDesktop->findFrame( u"_blank"_ustr, FrameSearchFlag::CREATE );
            Reference< XComponentLoader > xComponentLoader( xSelf, UNO_QUERY );

            Sequence< PropertyValue > aLoadProps{ comphelper::makePropertyValue(u"Hidden"_ustr, true) };
            mxModel.set( xComponentLoader->loadComponentFromURL(
                maSaveAsURL, u"_self"_ustr, 0, aLoadProps ), UNO_QUERY );
        }
    }

    // check if the document is ReadOnly -> error
    Reference< XStorable > xStorable( mxModel, UNO_QUERY );
    if ( xStorable.is() && !xStorable->isReadonly() )
    {
        mxModel->lockControllers();
        Optimize();
        mxModel->unlockControllers();

        // clearing undo stack:
        Reference< XFrame > xFrame( xSelf.is() ? xSelf : mxDocumentFrame );
        if ( xFrame.is() )
        {
            DispatchURL(mxContext, u".uno:ClearUndoStack"_ustr, xFrame);
        }
    }

    if ( !maSaveAsURL.isEmpty() )
    {
        if ( xStorable.is() )
        {
            xStorable->store();
            nDestSize = PPPOptimizer::GetFileSize( maSaveAsURL );
        }
    }

    if ( mxDocumentFrame.is() )
    {
        InformationDialog aInformationDialog( mxContext, mxDialogParentWindow, maSaveAsURL, mbOpenNewDocument, nSourceSize, nDestSize, nEstimatedFileSize );
        aInformationDialog.execute();
        SetStatusValue( TK_OpenNewDocument, Any( mbOpenNewDocument ) );
        DispatchStatus();
    }

    if ( !maSaveAsURL.isEmpty() )
    {
        if ( mbOpenNewDocument && xSelf.is() )
        {
            Reference< awt::XWindow > xContainerWindow( xSelf->getContainerWindow() );
            xContainerWindow->setVisible( true );
        }
        else
        {
            mxModel->dispose();
        }
    }
    if ( nSourceSize && nDestSize )
    {
        SetStatusValue( TK_FileSizeSource, Any( nSourceSize ) );
        SetStatusValue( TK_FileSizeDestination, Any( nDestSize ) );
        DispatchStatus();
    }
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=95 H=95 G=94

¤ Dauer der Verarbeitung: 0.15 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.