summaryrefslogtreecommitdiffstats
path: root/sdext/source/minimizer
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
commit267c6f2ac71f92999e969232431ba04678e7437e (patch)
tree358c9467650e1d0a1d7227a21dac2e3d08b622b2 /sdext/source/minimizer
parentInitial commit. (diff)
downloadlibreoffice-267c6f2ac71f92999e969232431ba04678e7437e.tar.xz
libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.zip
Adding upstream version 4:24.2.0.upstream/4%24.2.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--sdext/source/minimizer/configurationaccess.cxx456
-rw-r--r--sdext/source/minimizer/configurationaccess.hxx116
-rw-r--r--sdext/source/minimizer/fileopendialog.cxx169
-rw-r--r--sdext/source/minimizer/fileopendialog.hxx59
-rw-r--r--sdext/source/minimizer/graphiccollector.cxx423
-rw-r--r--sdext/source/minimizer/graphiccollector.hxx95
-rw-r--r--sdext/source/minimizer/impoptimizer.cxx703
-rw-r--r--sdext/source/minimizer/impoptimizer.hxx70
-rw-r--r--sdext/source/minimizer/informationdialog.cxx145
-rw-r--r--sdext/source/minimizer/informationdialog.hxx51
-rw-r--r--sdext/source/minimizer/minimizer.component16
-rw-r--r--sdext/source/minimizer/optimizationstats.cxx86
-rw-r--r--sdext/source/minimizer/optimizationstats.hxx45
-rw-r--r--sdext/source/minimizer/optimizerdialog.cxx675
-rw-r--r--sdext/source/minimizer/optimizerdialog.hxx244
-rw-r--r--sdext/source/minimizer/optimizerdialogcontrols.cxx359
-rw-r--r--sdext/source/minimizer/pagecollector.cxx136
-rw-r--r--sdext/source/minimizer/pagecollector.hxx43
-rw-r--r--sdext/source/minimizer/pppoptimizer.cxx39
-rw-r--r--sdext/source/minimizer/pppoptimizer.hxx32
-rw-r--r--sdext/source/minimizer/pppoptimizerdialog.cxx153
-rw-r--r--sdext/source/minimizer/pppoptimizerdialog.hxx81
-rw-r--r--sdext/source/minimizer/pppoptimizertoken.cxx145
-rw-r--r--sdext/source/minimizer/pppoptimizertoken.hxx95
24 files changed, 4436 insertions, 0 deletions
diff --git a/sdext/source/minimizer/configurationaccess.cxx b/sdext/source/minimizer/configurationaccess.cxx
new file mode 100644
index 0000000000..55e60c52ca
--- /dev/null
+++ b/sdext/source/minimizer/configurationaccess.cxx
@@ -0,0 +1,456 @@
+/* -*- 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 "configurationaccess.hxx"
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/configuration/theDefaultProvider.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <comphelper/propertysequence.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <sal/macros.h>
+#include <sal/log.hxx>
+#include <comphelper/diagnose_ex.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+
+static OUString GetPathToConfigurationRoot()
+{
+ return "org.openoffice.Office.PresentationMinimizer";
+}
+
+void OptimizerSettings::LoadSettingsFromConfiguration( const Reference< XNameAccess >& rSettings )
+{
+ if ( !rSettings.is() )
+ return;
+
+ const Sequence< OUString > aElements( rSettings->getElementNames() );
+ for ( const OUString& aPropertyName : aElements )
+ {
+ try
+ {
+ Any aValue( rSettings->getByName( aPropertyName ) );
+ switch( TKGet( aPropertyName ) )
+ {
+ case TK_Name : aValue >>= maName; break;
+ case TK_JPEGCompression : aValue >>= mbJPEGCompression; break;
+ case TK_JPEGQuality : aValue >>= mnJPEGQuality; break;
+ case TK_RemoveCropArea : aValue >>= mbRemoveCropArea; break;
+ case TK_ImageResolution : aValue >>= mnImageResolution; break;
+ case TK_EmbedLinkedGraphics : aValue >>= mbEmbedLinkedGraphics; break;
+ case TK_OLEOptimization : aValue >>= mbOLEOptimization; break;
+ case TK_OLEOptimizationType : aValue >>= mnOLEOptimizationType; break;
+ case TK_DeleteUnusedMasterPages : aValue >>= mbDeleteUnusedMasterPages; break;
+ case TK_DeleteHiddenSlides : aValue >>= mbDeleteHiddenSlides; break;
+ case TK_DeleteNotesPages : aValue >>= mbDeleteNotesPages ;break;
+ case TK_SaveAs : aValue >>= mbSaveAs; break;
+// case TK_SaveAsURL : aValue >>= maSaveAsURL; break; // URL is not saved to configuration
+// case TK_FilterName : aValue >>= maFilterName; break; // URL is not saved to configuration
+ case TK_OpenNewDocument : aValue >>= mbOpenNewDocument; break;
+ default: break;
+ }
+ }
+ catch (const Exception&)
+ {
+ }
+ }
+}
+
+void OptimizerSettings::SaveSettingsToConfiguration( const Reference< XNameReplace >& rSettings )
+{
+ if ( !rSettings.is() )
+ return;
+
+ OUString pNames[] = {
+ OUString("Name"),
+ OUString("JPEGCompression"),
+ OUString("JPEGQuality"),
+ OUString("RemoveCropArea"),
+ OUString("ImageResolution"),
+ OUString("EmbedLinkedGraphics"),
+ OUString("OLEOptimization"),
+ OUString("OLEOptimizationType"),
+ OUString("DeleteUnusedMasterPages"),
+ OUString("DeleteHiddenSlides"),
+ OUString("DeleteNotesPages"),
+ OUString("SaveAs"),
+// OUString("SaveAsURL"),
+// OUString("FilterName"),
+ OUString("OpenNewDocument") };
+
+ Any pValues[] = {
+ Any( maName ),
+ Any( mbJPEGCompression ),
+ Any( mnJPEGQuality ),
+ Any( mbRemoveCropArea ),
+ Any( mnImageResolution ),
+ Any( mbEmbedLinkedGraphics ),
+ Any( mbOLEOptimization ),
+ Any( mnOLEOptimizationType ),
+ Any( mbDeleteUnusedMasterPages ),
+ Any( mbDeleteHiddenSlides ),
+ Any( mbDeleteNotesPages ),
+ Any( mbSaveAs ),
+// Any( maSaveAsURL ),
+// Any( maFilterName ),
+ Any( mbOpenNewDocument ) };
+
+ for ( int i = 0; i < int(SAL_N_ELEMENTS( pNames )); i++ )
+ {
+ try
+ {
+ rSettings->replaceByName( pNames[ i ], pValues[ i ] );
+ }
+ catch (const Exception&)
+ {
+ }
+ }
+}
+
+bool OptimizerSettings::operator==( const OptimizerSettings& rOptimizerSettings ) const
+{
+ return ( rOptimizerSettings.mbJPEGCompression == mbJPEGCompression )
+ && ( rOptimizerSettings.mnJPEGQuality == mnJPEGQuality )
+ && ( rOptimizerSettings.mbRemoveCropArea == mbRemoveCropArea )
+ && ( rOptimizerSettings.mnImageResolution == mnImageResolution )
+ && ( rOptimizerSettings.mbEmbedLinkedGraphics == mbEmbedLinkedGraphics )
+ && ( rOptimizerSettings.mbOLEOptimization == mbOLEOptimization )
+ && ( rOptimizerSettings.mnOLEOptimizationType == mnOLEOptimizationType )
+ && ( rOptimizerSettings.mbDeleteUnusedMasterPages == mbDeleteUnusedMasterPages )
+ && ( rOptimizerSettings.mbDeleteHiddenSlides == mbDeleteHiddenSlides )
+ && ( rOptimizerSettings.mbDeleteNotesPages == mbDeleteNotesPages );
+}
+
+ConfigurationAccess::ConfigurationAccess( const Reference< uno::XComponentContext >& rxContext ) :
+ mxContext( rxContext )
+{
+ LoadStrings();
+ maSettings.emplace_back( );
+ maSettings.back().maName = "LastUsedSettings";
+ LoadConfiguration();
+};
+
+ConfigurationAccess::~ConfigurationAccess()
+{
+}
+
+OUString ConfigurationAccess::getString( const PPPOptimizerTokenEnum eToken ) const
+{
+ std::map< PPPOptimizerTokenEnum, OUString >::const_iterator aIter( maStrings.find( eToken ) );
+ return aIter != maStrings.end() ? ((*aIter).second) : OUString();
+}
+
+void ConfigurationAccess::LoadStrings()
+{
+ try
+ {
+ do
+ {
+ Reference< XInterface > xRoot( OpenConfiguration( true ) );
+ if ( !xRoot.is() )
+ break;
+ Reference< container::XNameAccess > xSet( GetConfigurationNode( xRoot, "Strings" ), UNO_QUERY );
+ if ( xSet.is() )
+ {
+ const Sequence< OUString > aElements( xSet->getElementNames() );
+ for ( const auto& rElement : aElements )
+ {
+ try
+ {
+ OUString aString, aPropertyName( rElement );
+ if ( xSet->getByName( aPropertyName ) >>= aString )
+ maStrings[ TKGet( aPropertyName ) ] = aString;
+ }
+ catch (const Exception&)
+ {
+ }
+ }
+ }
+ }
+ while( false );
+ }
+ catch (const Exception&)
+ {
+ }
+}
+
+void ConfigurationAccess::LoadConfiguration()
+{
+ try
+ {
+ do
+ {
+ Reference< XInterface > xRoot( OpenConfiguration( true ) );
+ if ( !xRoot.is() )
+ break;
+ Reference< container::XNameAccess > xSet( GetConfigurationNode( xRoot, "LastUsedSettings" ), UNO_QUERY );
+ if ( xSet.is() )
+ {
+ OptimizerSettings& rCurrent( maSettings.front() );
+ rCurrent.LoadSettingsFromConfiguration( xSet );
+ }
+ xSet.set( GetConfigurationNode( xRoot, "Settings/Templates" ), UNO_QUERY );
+ if ( xSet.is() )
+ {
+ const Sequence< OUString > aElements( xSet->getElementNames() );
+ for ( const auto& rElement : aElements )
+ {
+ try
+ {
+ OUString aPath( "Settings/Templates/" + rElement );
+ Reference< container::XNameAccess > xTemplates( GetConfigurationNode( xRoot, aPath ), UNO_QUERY );
+ if ( xTemplates.is() )
+ {
+ maSettings.emplace_back( );
+ maSettings.back().LoadSettingsFromConfiguration( xTemplates );
+ }
+ }
+ catch (const Exception&)
+ {
+ }
+ }
+ }
+ }
+ while( false );
+ }
+ catch (const Exception&)
+ {
+ }
+}
+
+void ConfigurationAccess::SaveConfiguration()
+{
+ try
+ {
+ do
+ {
+ Reference<util::XChangesBatch> xRoot( OpenConfiguration( false ), UNO_QUERY_THROW );
+
+ // storing the last used settings
+ Reference< container::XNameReplace > xSet( GetConfigurationNode( xRoot, "LastUsedSettings" ), UNO_QUERY_THROW );
+ OptimizerSettings& rCurrent( maSettings.front() );
+ rCurrent.SaveSettingsToConfiguration( xSet );
+
+ // updating template elements
+ xSet.set( GetConfigurationNode( xRoot, "Settings/Templates" ), UNO_QUERY_THROW );
+ Reference< container::XNameContainer > xNameContainer( xSet, UNO_QUERY_THROW );
+
+ const Sequence< OUString > aElements( xSet->getElementNames() );
+ for( const auto& rElement : aElements )
+ xNameContainer->removeByName( rElement );
+
+ for( std::vector<OptimizerSettings>::size_type k = 1; k < maSettings.size(); k++ )
+ {
+ OptimizerSettings& rSettings( maSettings[ k ] );
+ OUString aElementName( "Template" + OUString::number( k ) );
+ Reference< lang::XSingleServiceFactory > xChildFactory ( xSet, UNO_QUERY_THROW );
+ Reference< container::XNameReplace > xChild( xChildFactory->createInstance(), UNO_QUERY_THROW );
+ xNameContainer->insertByName( aElementName, Any( xChild ) );
+
+ OUString aPath( "Settings/Templates/" + aElementName );
+ Reference< container::XNameReplace > xTemplates( GetConfigurationNode( xRoot, aPath ), UNO_QUERY );
+ rSettings.SaveSettingsToConfiguration( xTemplates );
+ }
+ xRoot->commitChanges();
+ }
+ while( false );
+ }
+ catch (const Exception&)
+ {
+ }
+}
+
+Reference< XInterface > ConfigurationAccess::OpenConfiguration( bool bReadOnly )
+{
+ Reference< XInterface > xRoot;
+ try
+ {
+ Reference< lang::XMultiServiceFactory > xProvider = configuration::theDefaultProvider::get( mxContext );
+ uno::Sequence<uno::Any> aCreationArguments(comphelper::InitAnyPropertySequence(
+ {
+ {"nodepath", uno::Any(GetPathToConfigurationRoot())}
+ }));
+ OUString sAccessService;
+ if ( bReadOnly )
+ sAccessService = "com.sun.star.configuration.ConfigurationAccess";
+ else
+ sAccessService =
+ "com.sun.star.configuration.ConfigurationUpdateAccess";
+
+ xRoot = xProvider->createInstanceWithArguments(
+ sAccessService, aCreationArguments );
+ }
+ catch (const Exception&)
+ {
+ }
+ return xRoot;
+}
+
+Reference< XInterface > ConfigurationAccess::GetConfigurationNode(
+ const Reference< XInterface >& xRoot,
+ const OUString& sPathToNode )
+{
+ Reference< XInterface > xNode;
+ try
+ {
+ if ( sPathToNode.isEmpty() )
+ xNode = xRoot;
+ else
+ {
+ Reference< XHierarchicalNameAccess > xHierarchy( xRoot, UNO_QUERY );
+ if ( xHierarchy.is() )
+ {
+ xHierarchy->getByHierarchicalName( sPathToNode ) >>= xNode;
+ }
+ }
+ }
+ catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("sdext.minimizer", "caught exception while getting configuration node "
+ << sPathToNode);
+ }
+ return xNode;
+}
+
+css::uno::Any ConfigurationAccess::GetConfigProperty( const PPPOptimizerTokenEnum ePropertyToken ) const
+{
+ Any aRetValue;
+ const OptimizerSettings& rSettings( maSettings.front() );
+ try
+ {
+ switch( ePropertyToken )
+ {
+ case TK_Name : aRetValue <<= rSettings.maName; break;
+ case TK_JPEGCompression : aRetValue <<= rSettings.mbJPEGCompression; break;
+ case TK_JPEGQuality : aRetValue <<= rSettings.mnJPEGQuality; break;
+ case TK_RemoveCropArea : aRetValue <<= rSettings.mbRemoveCropArea; break;
+ case TK_ImageResolution : aRetValue <<= rSettings.mnImageResolution; break;
+ case TK_EmbedLinkedGraphics : aRetValue <<= rSettings.mbEmbedLinkedGraphics; break;
+ case TK_OLEOptimization : aRetValue <<= rSettings.mbOLEOptimization; break;
+ case TK_OLEOptimizationType : aRetValue <<= rSettings.mnOLEOptimizationType; break;
+ case TK_DeleteUnusedMasterPages : aRetValue <<= rSettings.mbDeleteUnusedMasterPages; break;
+ case TK_DeleteHiddenSlides : aRetValue <<= rSettings.mbDeleteHiddenSlides; break;
+ case TK_DeleteNotesPages : aRetValue <<= rSettings.mbDeleteNotesPages; break;
+ case TK_SaveAs : aRetValue <<= rSettings.mbSaveAs; break;
+ case TK_SaveAsURL : aRetValue <<= rSettings.maSaveAsURL; break;
+ case TK_FilterName : aRetValue <<= rSettings.maFilterName; break;
+ case TK_OpenNewDocument : aRetValue <<= rSettings.mbOpenNewDocument; break;
+ case TK_EstimatedFileSize : aRetValue <<= rSettings.mnEstimatedFileSize; break;
+ default:
+ break;
+ }
+ }
+ catch (const Exception&)
+ {
+ }
+ return aRetValue;
+}
+
+void ConfigurationAccess::SetConfigProperty( const PPPOptimizerTokenEnum ePropertyToken, const css::uno::Any& rValue )
+{
+ OptimizerSettings& rSettings( maSettings.front() );
+ try
+ {
+ switch( ePropertyToken )
+ {
+ case TK_Name : rValue >>= rSettings.maName; break;
+ case TK_JPEGCompression : rValue >>= rSettings.mbJPEGCompression; break;
+ case TK_JPEGQuality : rValue >>= rSettings.mnJPEGQuality; break;
+ case TK_RemoveCropArea : rValue >>= rSettings.mbRemoveCropArea; break;
+ case TK_ImageResolution : rValue >>= rSettings.mnImageResolution; break;
+ case TK_EmbedLinkedGraphics : rValue >>= rSettings.mbEmbedLinkedGraphics; break;
+ case TK_OLEOptimization : rValue >>= rSettings.mbOLEOptimization; break;
+ case TK_OLEOptimizationType : rValue >>= rSettings.mnOLEOptimizationType; break;
+ case TK_DeleteUnusedMasterPages : rValue >>= rSettings.mbDeleteUnusedMasterPages; break;
+ case TK_DeleteHiddenSlides : rValue >>= rSettings.mbDeleteHiddenSlides; break;
+ case TK_DeleteNotesPages : rValue >>= rSettings.mbDeleteNotesPages; break;
+ case TK_CustomShowName : rValue >>= rSettings.maCustomShowName; break;
+ case TK_SaveAs : rValue >>= rSettings.mbSaveAs; break;
+ case TK_SaveAsURL : rValue >>= rSettings.maSaveAsURL; break;
+ case TK_FilterName : rValue >>= rSettings.maFilterName; break;
+ case TK_OpenNewDocument : rValue >>= rSettings.mbOpenNewDocument; break;
+ case TK_EstimatedFileSize : rValue >>= rSettings.mnEstimatedFileSize; break;
+ default:
+ break;
+ }
+ }
+ catch (const Exception&)
+ {
+ }
+}
+
+bool ConfigurationAccess::GetConfigProperty( const PPPOptimizerTokenEnum ePropertyToken, const bool bDefault ) const
+{
+ bool bRetValue = bDefault;
+ if ( ! ( GetConfigProperty( ePropertyToken ) >>= bRetValue ) )
+ bRetValue = bDefault;
+ return bRetValue;
+}
+
+sal_Int16 ConfigurationAccess::GetConfigProperty( const PPPOptimizerTokenEnum ePropertyToken, const sal_Int16 nDefault ) const
+{
+ sal_Int16 nRetValue = nDefault;
+ if ( ! ( GetConfigProperty( ePropertyToken ) >>= nRetValue ) )
+ nRetValue = nDefault;
+ return nRetValue;
+}
+
+sal_Int32 ConfigurationAccess::GetConfigProperty( const PPPOptimizerTokenEnum ePropertyToken, const sal_Int32 nDefault ) const
+{
+ sal_Int32 nRetValue = nDefault;
+ if ( ! ( GetConfigProperty( ePropertyToken ) >>= nRetValue ) )
+ nRetValue = nDefault;
+ return nRetValue;
+}
+
+Sequence< PropertyValue > ConfigurationAccess::GetConfigurationSequence()
+{
+ OptimizerSettings& rSettings( maSettings.front() );
+ Sequence< PropertyValue > aRet{
+ comphelper::makePropertyValue("JPEGCompression", rSettings.mbJPEGCompression),
+ comphelper::makePropertyValue("JPEGQuality", rSettings.mnJPEGQuality),
+ comphelper::makePropertyValue("RemoveCropArea", rSettings.mbRemoveCropArea),
+ comphelper::makePropertyValue("ImageResolution", rSettings.mnImageResolution),
+ comphelper::makePropertyValue("EmbedLinkedGraphics", rSettings.mbEmbedLinkedGraphics),
+ comphelper::makePropertyValue("OLEOptimization", rSettings.mbOLEOptimization),
+ comphelper::makePropertyValue("OLEOptimizationType", rSettings.mnOLEOptimizationType),
+ comphelper::makePropertyValue("DeleteUnusedMasterPages", rSettings.mbDeleteUnusedMasterPages),
+ comphelper::makePropertyValue("DeleteHiddenSlides", rSettings.mbDeleteHiddenSlides),
+ comphelper::makePropertyValue("DeleteNotesPages", rSettings.mbDeleteNotesPages),
+ comphelper::makePropertyValue("CustomShowName", rSettings.maCustomShowName),
+ comphelper::makePropertyValue("SaveAsURL", rSettings.maSaveAsURL),
+ comphelper::makePropertyValue("FilterName", rSettings.maFilterName),
+ comphelper::makePropertyValue("OpenNewDocument", rSettings.mbOpenNewDocument),
+ comphelper::makePropertyValue("EstimatedFileSize", rSettings.mnEstimatedFileSize)
+ };
+ return aRet;
+}
+
+std::vector< OptimizerSettings >::iterator ConfigurationAccess::GetOptimizerSettingsByName( const OUString& rName )
+{
+ return std::find_if(maSettings.begin() + 1, maSettings.end(),
+ [&rName](const OptimizerSettings& rSettings) { return rSettings.maName == rName; });
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/minimizer/configurationaccess.hxx b/sdext/source/minimizer/configurationaccess.hxx
new file mode 100644
index 0000000000..5cf884fc13
--- /dev/null
+++ b/sdext/source/minimizer/configurationaccess.hxx
@@ -0,0 +1,116 @@
+/* -*- 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 .
+ */
+
+#ifndef INCLUDED_SDEXT_SOURCE_MINIMIZER_CONFIGURATIONACCESS_HXX
+#define INCLUDED_SDEXT_SOURCE_MINIMIZER_CONFIGURATIONACCESS_HXX
+
+#include <vector>
+#include "pppoptimizertoken.hxx"
+#include <com/sun/star/uno/Any.h>
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/uno/XInterface.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <map>
+
+struct OptimizerSettings
+{
+ OUString maName;
+ bool mbJPEGCompression;
+ sal_Int32 mnJPEGQuality;
+ bool mbRemoveCropArea;
+ sal_Int32 mnImageResolution;
+ bool mbEmbedLinkedGraphics;
+ bool mbOLEOptimization;
+ sal_Int16 mnOLEOptimizationType;
+ bool mbDeleteUnusedMasterPages;
+ bool mbDeleteHiddenSlides;
+ bool mbDeleteNotesPages;
+ OUString maCustomShowName;
+ bool mbSaveAs;
+ OUString maSaveAsURL;
+ OUString maFilterName;
+ bool mbOpenNewDocument;
+ sal_Int64 mnEstimatedFileSize;
+
+ OptimizerSettings() :
+ mbJPEGCompression( false ),
+ mnJPEGQuality( 90 ),
+ mbRemoveCropArea( false ),
+ mnImageResolution( 0 ),
+ mbEmbedLinkedGraphics( false ),
+ mbOLEOptimization( false ),
+ mnOLEOptimizationType( 0 ),
+ mbDeleteUnusedMasterPages( false ),
+ mbDeleteHiddenSlides( false ),
+ mbDeleteNotesPages( false ),
+ mbSaveAs( true ),
+ mbOpenNewDocument( true ),
+ mnEstimatedFileSize( 0 ){};
+
+ void LoadSettingsFromConfiguration( const css::uno::Reference< css::container::XNameAccess >& rSettings );
+ void SaveSettingsToConfiguration( const css::uno::Reference< css::container::XNameReplace >& rSettings );
+
+ bool operator==( const OptimizerSettings& rOptimizerSettings ) const;
+
+};
+class ConfigurationAccess
+{
+ public:
+
+ explicit ConfigurationAccess( const css::uno::Reference< css::uno::XComponentContext >& rXFactory );
+ ~ConfigurationAccess();
+ void SaveConfiguration();
+
+ OUString getString( const PPPOptimizerTokenEnum ) const;
+
+ // access to current OptimizerSettings (stored in the first entry of maSettings)
+ css::uno::Any GetConfigProperty( const PPPOptimizerTokenEnum ) const;
+ void SetConfigProperty( const PPPOptimizerTokenEnum, const css::uno::Any& aValue );
+
+ bool GetConfigProperty( const PPPOptimizerTokenEnum, const bool bDefault ) const;
+ sal_Int16 GetConfigProperty( const PPPOptimizerTokenEnum, const sal_Int16 nDefault ) const;
+ sal_Int32 GetConfigProperty( const PPPOptimizerTokenEnum, const sal_Int32 nDefault ) const;
+
+ css::uno::Sequence< css::beans::PropertyValue > GetConfigurationSequence();
+
+ // getting access to the OptimizerSettings list
+ std::vector< OptimizerSettings >& GetOptimizerSettings() { return maSettings; };
+ std::vector< OptimizerSettings >::iterator GetOptimizerSettingsByName( const OUString& rName );
+
+ protected:
+ css::uno::Reference< css::uno::XComponentContext > mxContext;
+
+ private:
+ std::map < PPPOptimizerTokenEnum, OUString > maStrings;
+
+ std::vector< OptimizerSettings > maSettings;
+
+ void LoadStrings();
+ void LoadConfiguration();
+ css::uno::Reference< css::uno::XInterface > OpenConfiguration( bool bReadOnly );
+ static css::uno::Reference< css::uno::XInterface > GetConfigurationNode(
+ const css::uno::Reference< css::uno::XInterface >& xRoot, const OUString& sPathToNode );
+};
+
+#endif // INCLUDED_SDEXT_SOURCE_MINIMIZER_CONFIGURATIONACCESS_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/minimizer/fileopendialog.cxx b/sdext/source/minimizer/fileopendialog.cxx
new file mode 100644
index 0000000000..ef0dbf4b4a
--- /dev/null
+++ b/sdext/source/minimizer/fileopendialog.cxx
@@ -0,0 +1,169 @@
+/* -*- 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 "fileopendialog.hxx"
+#include <sal/types.h>
+#include "pppoptimizertoken.hxx"
+#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
+#include <com/sun/star/ui/dialogs/FilePicker.hpp>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
+#include <com/sun/star/ui/dialogs/XFilterManager.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/container/XEnumeration.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/view/XControlAccess.hpp>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::view;
+using namespace ::com::sun::star::ui::dialogs;
+
+FileOpenDialog::FileOpenDialog( const Reference< XComponentContext >& rxContext )
+{
+ mxFilePicker = FilePicker::createWithMode( rxContext, TemplateDescription::FILESAVE_AUTOEXTENSION);
+ mxFilePicker->setMultiSelectionMode( false );
+
+ Reference< XFilePickerControlAccess > xAccess( mxFilePicker, UNO_QUERY );
+ if ( xAccess.is() )
+ {
+ try
+ {
+ xAccess->setValue( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, 0, Any( true ) );
+ }
+ catch( css::uno::Exception& )
+ {}
+ }
+
+ // collecting a list of impress filters
+ Reference< XNameAccess > xFilters( rxContext->getServiceManager()->createInstanceWithContext(
+ "com.sun.star.document.FilterFactory", rxContext ), UNO_QUERY_THROW );
+ const Sequence< OUString > aFilterList( xFilters->getElementNames() );
+ for ( const auto& rFilter : aFilterList )
+ {
+ try
+ {
+ Sequence< PropertyValue > aFilterProperties;
+ if ( xFilters->getByName( rFilter ) >>= aFilterProperties )
+ {
+ FilterEntry aFilterEntry;
+ bool bImpressFilter = false;
+ for ( const PropertyValue& rProperty : std::as_const(aFilterProperties) )
+ {
+ bool bStop = false;
+ switch( TKGet( rProperty.Name ) )
+ {
+ case TK_DocumentService :
+ {
+ OUString sDocumentService;
+ rProperty.Value >>= sDocumentService;
+ if ( sDocumentService == "com.sun.star.presentation.PresentationDocument" )
+ bImpressFilter = true;
+ else
+ bStop = true;
+ }
+ break;
+ case TK_Name : rProperty.Value >>= aFilterEntry.maFilterEntryName; break;
+ case TK_UIName : rProperty.Value >>= aFilterEntry.maUIName; break;
+ case TK_Type : rProperty.Value >>= aFilterEntry.maType; break;
+ case TK_Flags : rProperty.Value >>= aFilterEntry.maFlags; break;
+ default : break;
+ }
+
+ if (bStop)
+ break;
+ }
+ if ( bImpressFilter && ( ( aFilterEntry.maFlags & 3 ) == 3 ) )
+ {
+ aFilterEntryList.push_back( aFilterEntry );
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ }
+ }
+
+ Reference< XNameAccess > xTypes( rxContext->getServiceManager()->createInstanceWithContext(
+ "com.sun.star.document.TypeDetection", rxContext ), UNO_QUERY_THROW );
+
+ for (auto& rFilterEntry : aFilterEntryList)
+ {
+ Sequence< PropertyValue > aTypeProperties;
+ try
+ {
+ if ( xTypes->getByName( rFilterEntry.maType ) >>= aTypeProperties )
+ {
+ Sequence< OUString > aExtensions;
+ auto pProp = std::find_if(std::cbegin(aTypeProperties), std::cend(aTypeProperties),
+ [](const PropertyValue& rProp) { return rProp.Name == "Extensions"; });
+ if (pProp != std::cend(aTypeProperties))
+ pProp->Value >>= aExtensions;
+ if ( aExtensions.hasElements() )
+ {
+ // The filter title must be formed in the same way it is currently done in the
+ // internal implementation (see sfx2::appendFiltersForSave). And we will look
+ // for the same string returned from the dialog, so save it to maUIName:
+ OUString aTitle(
+ rFilterEntry.maUIName + " (." + aExtensions[0] + ")");
+ rFilterEntry.maUIName = aTitle;
+ OUString aFilter("*." + aExtensions[0]);
+ mxFilePicker->appendFilter(aTitle, aFilter);
+ if ( rFilterEntry.maFlags & 0x100 )
+ mxFilePicker->setCurrentFilter(aTitle);
+ }
+ }
+ }
+ catch ( const Exception& )
+ {
+ }
+ }
+}
+FileOpenDialog::~FileOpenDialog()
+{
+}
+sal_Int16 FileOpenDialog::execute()
+{
+ return mxFilePicker->execute();
+}
+void FileOpenDialog::setDefaultName( const OUString& rDefaultName )
+{
+ mxFilePicker->setDefaultName( rDefaultName );
+}
+OUString FileOpenDialog::getURL() const
+{
+ Sequence< OUString > aFileSeq( mxFilePicker->getSelectedFiles() );
+ return aFileSeq.hasElements() ? aFileSeq[ 0 ] : OUString();
+};
+OUString FileOpenDialog::getFilterName() const
+{
+ OUString aFilterName;
+ Reference< XFilterManager > xFilterManager( mxFilePicker, UNO_QUERY_THROW );
+ OUString aUIName( xFilterManager->getCurrentFilter() );
+ auto aIter = std::find_if(aFilterEntryList.begin(), aFilterEntryList.end(),
+ [&aUIName](const FilterEntry& rFilterEntry) { return rFilterEntry.maUIName == aUIName; });
+ if (aIter != aFilterEntryList.end())
+ aFilterName = aIter->maFilterEntryName;
+ return aFilterName;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/minimizer/fileopendialog.hxx b/sdext/source/minimizer/fileopendialog.hxx
new file mode 100644
index 0000000000..176fe155e2
--- /dev/null
+++ b/sdext/source/minimizer/fileopendialog.hxx
@@ -0,0 +1,59 @@
+/* -*- 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 .
+ */
+
+
+#ifndef INCLUDED_SDEXT_SOURCE_MINIMIZER_FILEOPENDIALOG_HXX
+#define INCLUDED_SDEXT_SOURCE_MINIMIZER_FILEOPENDIALOG_HXX
+
+#include <vector>
+#include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+
+class FileOpenDialog
+{
+ // a list of filters that are provided within the SaveDialog
+ struct FilterEntry
+ {
+ OUString maFilterEntryName;
+ OUString maType;
+ OUString maUIName;
+ sal_Int32 maFlags;
+
+ FilterEntry() : maFlags( 0 ) {}
+ };
+ css::uno::Reference < css::ui::dialogs::XFilePicker3 > mxFilePicker;
+
+ std::vector< FilterEntry > aFilterEntryList;
+
+public:
+ explicit FileOpenDialog( const css::uno::Reference< css::uno::XComponentContext >& rxContext );
+ ~FileOpenDialog();
+
+ sal_Int16 execute();
+
+ void setDefaultName( const OUString& );
+// void setDefaultDirectory( const OUString& );
+
+ OUString getURL() const;
+ OUString getFilterName() const;
+};
+
+#endif // INCLUDED_SDEXT_SOURCE_MINIMIZER_FILEOPENDIALOG_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/minimizer/graphiccollector.cxx b/sdext/source/minimizer/graphiccollector.cxx
new file mode 100644
index 0000000000..c307b04b09
--- /dev/null
+++ b/sdext/source/minimizer/graphiccollector.cxx
@@ -0,0 +1,423 @@
+/* -*- 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 "graphiccollector.hxx"
+#include <com/sun/star/awt/XDevice.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/drawing/FillStyle.hpp>
+#include <com/sun/star/drawing/BitmapMode.hpp>
+#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
+#include <com/sun/star/presentation/XPresentationPage.hpp>
+#include <com/sun/star/drawing/XMasterPagesSupplier.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::graphic;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::presentation;
+
+const DeviceInfo& GraphicCollector::GetDeviceInfo( const Reference< XComponentContext >& rxFact )
+{
+ static DeviceInfo aDeviceInfo;
+ if( !aDeviceInfo.Width )
+ {
+ try
+ {
+ Reference< XDesktop2 > xDesktop = Desktop::create( rxFact );
+ Reference< XFrame > xFrame( xDesktop->getActiveFrame() );
+ Reference< XWindow > xWindow( xFrame->getContainerWindow() );
+ Reference< XDevice > xDevice( xWindow, UNO_QUERY_THROW );
+ aDeviceInfo = xDevice->getInfo();
+ }
+ catch( Exception& )
+ {
+ }
+ }
+ return aDeviceInfo;
+}
+
+static void ImpAddEntity( std::vector< GraphicCollector::GraphicEntity >& rGraphicEntities, const GraphicSettings& rGraphicSettings, const GraphicCollector::GraphicUser& rUser )
+{
+ if ( !rGraphicSettings.mbEmbedLinkedGraphics )
+ return;
+
+ auto aIter = std::find_if(rGraphicEntities.begin(), rGraphicEntities.end(),
+ [&rUser](const GraphicCollector::GraphicEntity& rGraphicEntity) {
+ return rGraphicEntity.maUser[ 0 ].mxGraphic == rUser.mxGraphic;
+ });
+ if ( aIter == rGraphicEntities.end() )
+ {
+ GraphicCollector::GraphicEntity aEntity( rUser );
+ rGraphicEntities.push_back( aEntity );
+ }
+ else
+ {
+ if ( rUser.maLogicalSize.Width > aIter->maLogicalSize.Width )
+ aIter->maLogicalSize.Width = rUser.maLogicalSize.Width;
+ if ( rUser.maLogicalSize.Height > aIter->maLogicalSize.Height )
+ aIter->maLogicalSize.Height = rUser.maLogicalSize.Height;
+ aIter->maUser.push_back( rUser );
+ }
+}
+
+static void ImpAddGraphicEntity( const Reference< XComponentContext >& rxMSF, Reference< XShape > const & rxShape, const GraphicSettings& rGraphicSettings, std::vector< GraphicCollector::GraphicEntity >& rGraphicEntities )
+{
+ Reference< XGraphic > xGraphic;
+ Reference< XPropertySet > xShapePropertySet( rxShape, UNO_QUERY_THROW );
+ if ( !(xShapePropertySet->getPropertyValue( "Graphic" ) >>= xGraphic) )
+ return;
+
+ text::GraphicCrop aGraphicCropLogic( 0, 0, 0, 0 );
+
+ GraphicCollector::GraphicUser aUser;
+ aUser.mxShape = rxShape;
+ aUser.mbFillBitmap = false;
+ aUser.mxGraphic = xGraphic;
+ xShapePropertySet->getPropertyValue( "GraphicCrop" ) >>= aGraphicCropLogic;
+ awt::Size aLogicalSize( rxShape->getSize() );
+
+ // calculating the logical size, as if there were no cropping
+ if ( aGraphicCropLogic.Left || aGraphicCropLogic.Right || aGraphicCropLogic.Top || aGraphicCropLogic.Bottom )
+ {
+ awt::Size aSize100thMM( GraphicCollector::GetOriginalSize( rxMSF, xGraphic ) );
+ if ( aSize100thMM.Width && aSize100thMM.Height )
+ {
+ awt::Size aCropSize( aSize100thMM.Width - ( aGraphicCropLogic.Left + aGraphicCropLogic.Right ),
+ aSize100thMM.Height - ( aGraphicCropLogic.Top + aGraphicCropLogic.Bottom ));
+ if ( aCropSize.Width && aCropSize.Height )
+ {
+ awt::Size aNewLogSize( static_cast< sal_Int32 >( static_cast< double >( aSize100thMM.Width * aLogicalSize.Width ) / aCropSize.Width ),
+ static_cast< sal_Int32 >( static_cast< double >( aSize100thMM.Height * aLogicalSize.Height ) / aCropSize.Height ) );
+ aLogicalSize = aNewLogSize;
+ }
+ }
+ }
+ aUser.maGraphicCropLogic = aGraphicCropLogic;
+ aUser.maLogicalSize = aLogicalSize;
+ ImpAddEntity( rGraphicEntities, rGraphicSettings, aUser );
+}
+
+static void ImpAddFillBitmapEntity( const Reference< XComponentContext >& rxMSF, const Reference< XPropertySet >& rxPropertySet, const awt::Size& rLogicalSize,
+ std::vector< GraphicCollector::GraphicEntity >& rGraphicEntities, const GraphicSettings& rGraphicSettings, const Reference< XPropertySet >& rxPagePropertySet )
+{
+ try
+ {
+ FillStyle eFillStyle;
+ if ( rxPropertySet->getPropertyValue( "FillStyle" ) >>= eFillStyle )
+ {
+ if ( eFillStyle == FillStyle_BITMAP )
+ {
+ Reference< XBitmap > xFillBitmap;
+ if ( rxPropertySet->getPropertyValue( "FillBitmap" ) >>= xFillBitmap )
+ {
+ Reference< XGraphic > xGraphic( xFillBitmap, UNO_QUERY_THROW );
+ awt::Size aLogicalSize( rLogicalSize );
+ Reference< XPropertySetInfo > axPropSetInfo( rxPropertySet->getPropertySetInfo() );
+ if ( axPropSetInfo.is() )
+ {
+ if ( axPropSetInfo->hasPropertyByName( "FillBitmapMode" ) )
+ {
+ BitmapMode eBitmapMode;
+ if ( rxPropertySet->getPropertyValue( "FillBitmapMode" ) >>= eBitmapMode )
+ {
+ if ( ( eBitmapMode == BitmapMode_REPEAT ) || ( eBitmapMode == BitmapMode_NO_REPEAT ) )
+ {
+ bool bLogicalSize = false;
+ awt::Size aSize( 0, 0 );
+ if ( ( rxPropertySet->getPropertyValue( "FillBitmapLogicalSize" ) >>= bLogicalSize )
+ && ( rxPropertySet->getPropertyValue( "FillBitmapSizeX" ) >>= aSize.Width )
+ && ( rxPropertySet->getPropertyValue( "FillBitmapSizeY" ) >>= aSize.Height ) )
+ {
+ if ( bLogicalSize )
+ {
+ if ( !aSize.Width || !aSize.Height )
+ {
+ awt::Size aSize100thMM( GraphicCollector::GetOriginalSize( rxMSF, xGraphic ) );
+ if ( aSize100thMM.Width && aSize100thMM.Height )
+ aLogicalSize = aSize100thMM;
+ }
+ else
+ aLogicalSize = aSize;
+ }
+ else
+ {
+ aLogicalSize.Width = sal::static_int_cast< sal_Int32 >( ( static_cast< double >( aLogicalSize.Width ) * aSize.Width ) / -100.0 );
+ aLogicalSize.Height = sal::static_int_cast< sal_Int32 >( ( static_cast< double >( aLogicalSize.Height ) * aSize.Height ) / -100.0 );
+ }
+ }
+ }
+ }
+ }
+ }
+ GraphicCollector::GraphicUser aUser;
+ aUser.mxPropertySet = rxPropertySet;
+ aUser.mxGraphic = xGraphic;
+ aUser.mbFillBitmap = true;
+ aUser.maLogicalSize = aLogicalSize;
+ aUser.mxPagePropertySet = rxPagePropertySet;
+ ImpAddEntity( rGraphicEntities, rGraphicSettings, aUser );
+ }
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+static void ImpCollectBackgroundGraphic( const Reference< XComponentContext >& rxMSF, const Reference< XDrawPage >& rxDrawPage, const GraphicSettings& rGraphicSettings, std::vector< GraphicCollector::GraphicEntity >& rGraphicEntities )
+{
+ try
+ {
+ awt::Size aLogicalSize( 28000, 21000 );
+ Reference< XPropertySet > xPropertySet( rxDrawPage, UNO_QUERY_THROW );
+ xPropertySet->getPropertyValue( "Width" ) >>= aLogicalSize.Width;
+ xPropertySet->getPropertyValue( "Height" ) >>= aLogicalSize.Height;
+
+ Reference< XPropertySet > xBackgroundPropSet;
+ if ( xPropertySet->getPropertyValue( "Background" ) >>= xBackgroundPropSet )
+ ImpAddFillBitmapEntity( rxMSF, xBackgroundPropSet, aLogicalSize, rGraphicEntities, rGraphicSettings, xPropertySet );
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+static void ImpCollectGraphicObjects( const Reference< XComponentContext >& rxMSF, const Reference< XShapes >& rxShapes, const GraphicSettings& rGraphicSettings, std::vector< GraphicCollector::GraphicEntity >& rGraphicEntities )
+{
+ for ( sal_Int32 i = 0; i < rxShapes->getCount(); i++ )
+ {
+ try
+ {
+ Reference< XShape > xShape( rxShapes->getByIndex( i ), UNO_QUERY_THROW );
+ const OUString sShapeType( xShape->getShapeType() );
+ if ( sShapeType == "com.sun.star.drawing.GroupShape" )
+ {
+ Reference< XShapes > xShapes( xShape, UNO_QUERY_THROW );
+ ImpCollectGraphicObjects( rxMSF, xShapes, rGraphicSettings, rGraphicEntities );
+ continue;
+ }
+
+ if ( sShapeType == "com.sun.star.drawing.GraphicObjectShape" ||
+ sShapeType == "com.sun.star.presentation.GraphicObjectShape" )
+ ImpAddGraphicEntity( rxMSF, xShape, rGraphicSettings, rGraphicEntities );
+
+ // now check for a fillstyle
+ Reference< XPropertySet > xEmptyPagePropSet;
+ Reference< XPropertySet > xShapePropertySet( xShape, UNO_QUERY_THROW );
+ awt::Size aLogicalSize( xShape->getSize() );
+ ImpAddFillBitmapEntity( rxMSF, xShapePropertySet, aLogicalSize, rGraphicEntities, rGraphicSettings, xEmptyPagePropSet );
+ }
+ catch( Exception& )
+ {
+ }
+ }
+}
+
+awt::Size GraphicCollector::GetOriginalSize( const Reference< XComponentContext >& rxMSF, const Reference< XGraphic >& rxGraphic )
+{
+ awt::Size aSize100thMM( 0, 0 );
+ Reference< XPropertySet > xGraphicPropertySet( rxGraphic, UNO_QUERY_THROW );
+ if ( xGraphicPropertySet->getPropertyValue( "Size100thMM" ) >>= aSize100thMM )
+ {
+ if ( !aSize100thMM.Width && !aSize100thMM.Height )
+ { // MAPMODE_PIXEL USED :-(
+ awt::Size aSourceSizePixel( 0, 0 );
+ if ( xGraphicPropertySet->getPropertyValue( "SizePixel" ) >>= aSourceSizePixel )
+ {
+ const DeviceInfo& rDeviceInfo( GraphicCollector::GetDeviceInfo( rxMSF ) );
+ if ( rDeviceInfo.PixelPerMeterX && rDeviceInfo.PixelPerMeterY )
+ {
+ aSize100thMM.Width = static_cast< sal_Int32 >( ( aSourceSizePixel.Width * 100000.0 ) / rDeviceInfo.PixelPerMeterX );
+ aSize100thMM.Height = static_cast< sal_Int32 >( ( aSourceSizePixel.Height * 100000.0 ) / rDeviceInfo.PixelPerMeterY );
+ }
+ }
+ }
+ }
+ return aSize100thMM;
+}
+
+void GraphicCollector::CollectGraphics( const Reference< XComponentContext >& rxMSF, const Reference< XModel >& rxModel,
+ const GraphicSettings& rGraphicSettings, std::vector< GraphicCollector::GraphicEntity >& rGraphicList )
+{
+ try
+ {
+ sal_Int32 i;
+ Reference< XDrawPagesSupplier > xDrawPagesSupplier( rxModel, UNO_QUERY_THROW );
+ Reference< XDrawPages > xDrawPages( xDrawPagesSupplier->getDrawPages(), UNO_SET_THROW );
+ for ( i = 0; i < xDrawPages->getCount(); i++ )
+ {
+ Reference< XDrawPage > xDrawPage( xDrawPages->getByIndex( i ), UNO_QUERY_THROW );
+ ImpCollectBackgroundGraphic( rxMSF, xDrawPage, rGraphicSettings, rGraphicList );
+ ImpCollectGraphicObjects( rxMSF, xDrawPage, rGraphicSettings, rGraphicList );
+
+ Reference< XPresentationPage > xPresentationPage( xDrawPage, UNO_QUERY_THROW );
+ Reference< XDrawPage > xNotesPage( xPresentationPage->getNotesPage() );
+ ImpCollectBackgroundGraphic( rxMSF, xNotesPage, rGraphicSettings, rGraphicList );
+ ImpCollectGraphicObjects( rxMSF, xNotesPage, rGraphicSettings, rGraphicList );
+ }
+ Reference< XMasterPagesSupplier > xMasterPagesSupplier( rxModel, UNO_QUERY_THROW );
+ Reference< XDrawPages > xMasterPages( xMasterPagesSupplier->getMasterPages(), UNO_SET_THROW );
+ for ( i = 0; i < xMasterPages->getCount(); i++ )
+ {
+ Reference< XDrawPage > xMasterPage( xMasterPages->getByIndex( i ), UNO_QUERY_THROW );
+ ImpCollectBackgroundGraphic( rxMSF, xMasterPage, rGraphicSettings, rGraphicList );
+ ImpCollectGraphicObjects( rxMSF, xMasterPage, rGraphicSettings, rGraphicList );
+ }
+
+ for( auto& rGraphic : rGraphicList )
+ {
+ // check if it is possible to remove the crop area
+ rGraphic.mbRemoveCropArea = rGraphicSettings.mbRemoveCropArea;
+ if ( rGraphic.mbRemoveCropArea )
+ {
+ std::vector< GraphicCollector::GraphicUser >::iterator aGUIter( rGraphic.maUser.begin() );
+ while( rGraphic.mbRemoveCropArea && ( aGUIter != rGraphic.maUser.end() ) )
+ {
+ if ( aGUIter->maGraphicCropLogic.Left || aGUIter->maGraphicCropLogic.Top
+ || aGUIter->maGraphicCropLogic.Right || aGUIter->maGraphicCropLogic.Bottom )
+ {
+ if ( aGUIter == rGraphic.maUser.begin() )
+ rGraphic.maGraphicCropLogic = aGUIter->maGraphicCropLogic;
+ else if ( ( rGraphic.maGraphicCropLogic.Left != aGUIter->maGraphicCropLogic.Left )
+ || ( rGraphic.maGraphicCropLogic.Top != aGUIter->maGraphicCropLogic.Top )
+ || ( rGraphic.maGraphicCropLogic.Right != aGUIter->maGraphicCropLogic.Right )
+ || ( rGraphic.maGraphicCropLogic.Bottom != aGUIter->maGraphicCropLogic.Bottom ) )
+ {
+ rGraphic.mbRemoveCropArea = false;
+ }
+ }
+ else
+ rGraphic.mbRemoveCropArea = false;
+ ++aGUIter;
+ }
+ }
+ if ( !rGraphic.mbRemoveCropArea )
+ rGraphic.maGraphicCropLogic = text::GraphicCrop( 0, 0, 0, 0 );
+ }
+ }
+ catch ( Exception& )
+ {
+ }
+}
+
+static void ImpCountGraphicObjects( const Reference< XComponentContext >& rxMSF, const Reference< XShapes >& rxShapes, const GraphicSettings& rGraphicSettings, sal_Int32& rnGraphics )
+{
+ for ( sal_Int32 i = 0; i < rxShapes->getCount(); i++ )
+ {
+ try
+ {
+ Reference< XShape > xShape( rxShapes->getByIndex( i ), UNO_QUERY_THROW );
+ const OUString sShapeType( xShape->getShapeType() );
+ if ( sShapeType == "com.sun.star.drawing.GroupShape" )
+ {
+ Reference< XShapes > xShapes( xShape, UNO_QUERY_THROW );
+ ImpCountGraphicObjects( rxMSF, xShapes, rGraphicSettings, rnGraphics );
+ continue;
+ }
+
+ if ( sShapeType == "com.sun.star.drawing.GraphicObjectShape" ||
+ sShapeType == "com.sun.star.presentation.GraphicObjectShape" )
+ {
+ rnGraphics++;
+ }
+
+ // now check for a fillstyle
+ Reference< XPropertySet > xShapePropertySet( xShape, UNO_QUERY_THROW );
+ FillStyle eFillStyle;
+ if ( xShapePropertySet->getPropertyValue( "FillStyle" ) >>= eFillStyle )
+ {
+ if ( eFillStyle == FillStyle_BITMAP )
+ {
+ rnGraphics++;
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ }
+ }
+}
+
+static void ImpCountBackgroundGraphic(
+ const Reference< XDrawPage >& rxDrawPage, sal_Int32& rnGraphics )
+{
+ try
+ {
+ awt::Size aLogicalSize( 28000, 21000 );
+ Reference< XPropertySet > xPropertySet( rxDrawPage, UNO_QUERY_THROW );
+ xPropertySet->getPropertyValue( "Width" ) >>= aLogicalSize.Width;
+ xPropertySet->getPropertyValue( "Height" ) >>= aLogicalSize.Height;
+
+ Reference< XPropertySet > xBackgroundPropSet;
+ if ( xPropertySet->getPropertyValue( "Background" ) >>= xBackgroundPropSet )
+ {
+ FillStyle eFillStyle;
+ if ( xBackgroundPropSet->getPropertyValue( "FillStyle" ) >>= eFillStyle )
+ {
+ if ( eFillStyle == FillStyle_BITMAP )
+ {
+ rnGraphics++;
+ }
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+void GraphicCollector::CountGraphics( const Reference< XComponentContext >& rxMSF, const Reference< XModel >& rxModel,
+ const GraphicSettings& rGraphicSettings, sal_Int32& rnGraphics )
+{
+ try
+ {
+ sal_Int32 i;
+ Reference< XDrawPagesSupplier > xDrawPagesSupplier( rxModel, UNO_QUERY_THROW );
+ Reference< XDrawPages > xDrawPages( xDrawPagesSupplier->getDrawPages(), UNO_SET_THROW );
+ for ( i = 0; i < xDrawPages->getCount(); i++ )
+ {
+ Reference< XDrawPage > xDrawPage( xDrawPages->getByIndex( i ), UNO_QUERY_THROW );
+ ImpCountBackgroundGraphic( xDrawPage, rnGraphics );
+ ImpCountGraphicObjects( rxMSF, xDrawPage, rGraphicSettings, rnGraphics );
+
+ Reference< XPresentationPage > xPresentationPage( xDrawPage, UNO_QUERY_THROW );
+ Reference< XDrawPage > xNotesPage( xPresentationPage->getNotesPage() );
+ ImpCountBackgroundGraphic( xNotesPage, rnGraphics );
+ ImpCountGraphicObjects( rxMSF, xNotesPage, rGraphicSettings, rnGraphics );
+ }
+ Reference< XMasterPagesSupplier > xMasterPagesSupplier( rxModel, UNO_QUERY_THROW );
+ Reference< XDrawPages > xMasterPages( xMasterPagesSupplier->getMasterPages(), UNO_SET_THROW );
+ for ( i = 0; i < xMasterPages->getCount(); i++ )
+ {
+ Reference< XDrawPage > xMasterPage( xMasterPages->getByIndex( i ), UNO_QUERY_THROW );
+ ImpCountBackgroundGraphic( xMasterPage, rnGraphics );
+ ImpCountGraphicObjects( rxMSF, xMasterPage, rGraphicSettings, rnGraphics );
+ }
+ }
+ catch ( Exception& )
+ {
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/minimizer/graphiccollector.hxx b/sdext/source/minimizer/graphiccollector.hxx
new file mode 100644
index 0000000000..f989a95ad3
--- /dev/null
+++ b/sdext/source/minimizer/graphiccollector.hxx
@@ -0,0 +1,95 @@
+/* -*- 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 .
+ */
+
+#ifndef INCLUDED_SDEXT_SOURCE_MINIMIZER_GRAPHICCOLLECTOR_HXX
+#define INCLUDED_SDEXT_SOURCE_MINIMIZER_GRAPHICCOLLECTOR_HXX
+
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/awt/DeviceInfo.hpp>
+#include <com/sun/star/text/GraphicCrop.hpp>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <vector>
+
+
+struct GraphicSettings
+{
+ bool mbJPEGCompression;
+ sal_Int32 mnJPEGQuality;
+ bool mbRemoveCropArea;
+ sal_Int32 mnImageResolution;
+ bool mbEmbedLinkedGraphics;
+
+ GraphicSettings( bool bJPEGCompression, sal_Int32 nJPEGQuality, bool bRemoveCropArea,
+ sal_Int32 nImageResolution, bool bEmbedLinkedGraphics )
+ : mbJPEGCompression( bJPEGCompression )
+ , mnJPEGQuality( nJPEGQuality )
+ , mbRemoveCropArea( bRemoveCropArea )
+ , mnImageResolution( nImageResolution )
+ , mbEmbedLinkedGraphics( bEmbedLinkedGraphics ) {};
+};
+
+class GraphicCollector
+{
+ public:
+
+ struct GraphicUser
+ {
+ css::uno::Reference< css::drawing::XShape > mxShape; // if mbFillBitmap is false the xShape has
+ css::uno::Reference< css::beans::XPropertySet > mxPropertySet; // to be used otherwise the PropertySet
+ css::uno::Reference< css::beans::XPropertySet > mxPagePropertySet;
+ css::uno::Reference< css::graphic::XGraphic > mxGraphic;
+
+ css::text::GraphicCrop maGraphicCropLogic;
+ css::awt::Size maLogicalSize;
+ bool mbFillBitmap;
+
+ GraphicUser() : mxShape(), maGraphicCropLogic( 0, 0, 0, 0 ), mbFillBitmap( false ) {};
+ };
+
+ struct GraphicEntity
+ {
+ css::awt::Size maLogicalSize; // the biggest logical size the graphic will be displayed
+ bool mbRemoveCropArea;
+ css::text::GraphicCrop maGraphicCropLogic;
+ std::vector< GraphicUser > maUser;
+
+ explicit GraphicEntity( const GraphicUser& rUser )
+ : maLogicalSize( rUser.maLogicalSize ), mbRemoveCropArea( false ), maGraphicCropLogic( 0, 0, 0, 0 ) { maUser.push_back( rUser ); };
+ };
+
+ static const css::awt::DeviceInfo& GetDeviceInfo( const css::uno::Reference< css::uno::XComponentContext >& rxFact );
+ static css::awt::Size GetOriginalSize( const css::uno::Reference< css::uno::XComponentContext >& rxMSF,
+ const css::uno::Reference< css::graphic::XGraphic >& rxGraphic );
+
+ // collecting graphic instances, the downside of this method is that every graphic is swapped in
+ static void CollectGraphics( const css::uno::Reference< css::uno::XComponentContext >& rxMSF, const css::uno::Reference< css::frame::XModel >& rxModel,
+ const GraphicSettings& rGraphicSettings, std::vector< GraphicEntity >& io_rGraphicList );
+ // counting graphics without swapping in graphics
+ static void CountGraphics( const css::uno::Reference< css::uno::XComponentContext >& rxMSF, const css::uno::Reference< css::frame::XModel >& rxModel,
+ const GraphicSettings& rGraphicSettings, sal_Int32& rGraphics );
+};
+
+
+#endif // INCLUDED_SDEXT_SOURCE_MINIMIZER_GRAPHICCOLLECTOR_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/minimizer/impoptimizer.cxx b/sdext/source/minimizer/impoptimizer.cxx
new file mode 100644
index 0000000000..72be9c6660
--- /dev/null
+++ b/sdext/source/minimizer/impoptimizer.cxx
@@ -0,0 +1,703 @@
+/* -*- 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::document;
+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 );
+ for( const 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 );
+ for( const 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( "Visible" ) >>= 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( "Layout", 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( "IsInternal" ) >>= bIsInternal;
+ bConvertOLE = !bIsInternal;
+ }
+ if ( bConvertOLE )
+ {
+ Reference< XGraphic > xGraphic;
+ if ( xPropSet->getPropertyValue( "Graphic" ) >>= xGraphic )
+ {
+ Reference< XMultiServiceFactory > xFact( rxModel, UNO_QUERY_THROW );
+ Reference< XShape > xShape2( xFact->createInstance( "com.sun.star.drawing.GraphicObjectShape" ), UNO_QUERY_THROW );
+ xShapes->add( xShape2 );
+ xShape2->setPosition( xShape->getPosition() );
+ xShape2->setSize( xShape->getSize() );
+ Reference< XPropertySet > xPropSet2( xShape2, UNO_QUERY_THROW );
+ xPropSet2->setPropertyValue( "Graphic", Any( xGraphic ) );
+ xShapes->remove( xShape );
+ xPropSet2->setPropertyValue( "ZOrder", 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("ImageResolution", nImageResolution),
+ comphelper::makePropertyValue("ColorMode", sal_Int32(0)), // todo: jpeg color mode (0->true color, 1->greyscale)
+ comphelper::makePropertyValue("Quality", nJPEGQuality), // quality that is used if we export to jpeg
+ comphelper::makePropertyValue("Compression", sal_Int32(6)), // compression that is used if we export to png
+ comphelper::makePropertyValue("Interlaced", sal_Int32(0)), // interlaced is turned off if we export to png
+ comphelper::makePropertyValue("LogicalSize", rLogicalSize),
+ comphelper::makePropertyValue("RemoveCropArea", bRemoveCropping),
+ comphelper::makePropertyValue("GraphicCropLogic", rGraphicCropLogic)
+ };
+
+ Sequence< PropertyValue > aArgs{
+ comphelper::makePropertyValue("MimeType", rDestMimeType), // the GraphicProvider is using "MimeType", the GraphicExporter "MediaType"...
+ comphelper::makePropertyValue("OutputStream", rxOutputStream),
+ comphelper::makePropertyValue("FilterData", 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( "MimeType" ) >>= 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( "SizePixel" ) >>= aSourceSizePixel ) &&
+ ( xGraphicPropertySet->getPropertyValue( "Transparent" ) >>= bTransparent ) &&
+ ( xGraphicPropertySet->getPropertyValue( "Alpha" ) >>= bAlpha ) &&
+ ( xGraphicPropertySet->getPropertyValue( "Animated" ) >>= 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( "image/png" );
+ 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(
+ "InputStream", 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("InputStream",
+ 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;
+ for( auto& rGraphic : rGraphicList )
+ {
+ i++;
+ sal_Int32 nProgress = static_cast< sal_Int32 >( 40.0 * ( i / static_cast< double >( 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( "FillBitmap" ) >>= 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( "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, rGraphic.maLogicalSize, rGraphic.maGraphicCropLogic, aGraphicSettings ) );
+ if ( xNewGraphic.is() )
+ {
+ // applying graphic to each user
+ for( auto& rGraphicUser : rGraphic.maUser )
+ {
+ if ( rGraphicUser.mxShape.is() )
+ {
+ Reference< XPropertySet > xShapePropertySet( rGraphicUser.mxShape, UNO_QUERY_THROW );
+ xShapePropertySet->setPropertyValue( "Graphic", 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( "GraphicCrop", 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( "FillBitmap", Any( xFillBitmap ) );
+ if ( ( rxPropertySet->getPropertyValue( "FillBitmapLogicalSize" ) >>= bLogicalSize )
+ && ( rxPropertySet->getPropertyValue( "FillBitmapSizeX" ) >>= aSize.Width )
+ && ( rxPropertySet->getPropertyValue( "FillBitmapSizeY" ) >>= aSize.Height ) )
+ {
+ if ( !aSize.Width || !aSize.Height )
+ {
+ rxPropertySet->setPropertyValue( "FillBitmapLogicalSize", Any( true ) );
+ rxPropertySet->setPropertyValue( "FillBitmapSizeX", Any( rGraphicUser.maLogicalSize.Width ) );
+ rxPropertySet->setPropertyValue( "FillBitmapSizeY", Any( rGraphicUser.maLogicalSize.Height ) );
+ }
+ }
+ if ( rGraphicUser.mxPagePropertySet.is() )
+ rGraphicUser.mxPagePropertySet->setPropertyValue( "Background", 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( OUString("STR_DELETING_SLIDES") ) );
+ DispatchStatus();
+ ImpDeleteHiddenSlides( mxModel );
+ }
+
+ if ( mbDeleteNotesPages )
+ {
+ SetStatusValue( TK_Status, Any( OUString("STR_DELETING_SLIDES") ) );
+ DispatchStatus();
+ ImpDeleteNotesPages( mxModel );
+ }
+
+ if ( mbDeleteUnusedMasterPages )
+ {
+ SetStatusValue( TK_Progress, Any( static_cast< sal_Int32 >( 40 ) ) );
+ SetStatusValue( TK_Status, Any( OUString("STR_DELETING_SLIDES") ) );
+ DispatchStatus();
+ ImpDeleteUnusedMasterPages( mxModel );
+ }
+
+ if ( mbOLEOptimization )
+ {
+ SetStatusValue( TK_Progress, Any( static_cast< sal_Int32 >( 45 ) ) );
+ SetStatusValue( TK_Status, Any( OUString("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( OUString("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();
+}
+
+static void DispatchURL( const Reference< XComponentContext >& xContext, const OUString& 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 : std::as_const(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;
+ default: break;
+ }
+ }
+ }
+ break;
+ default: break;
+ }
+ }
+
+ 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( OUString("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.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( OUString("STR_DUPLICATING_PRESENTATION") ) );
+ DispatchStatus();
+
+ Reference< XDesktop2 > xDesktop = Desktop::create( mxContext );
+ xSelf = xDesktop->findFrame( "_blank", FrameSearchFlag::CREATE );
+ Reference< XComponentLoader > xComponentLoader( xSelf, UNO_QUERY );
+
+ Sequence< PropertyValue > aLoadProps{ comphelper::makePropertyValue("Hidden", true) };
+ mxModel.set( xComponentLoader->loadComponentFromURL(
+ maSaveAsURL, "_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();
+ Optimize();
+ mxModel->unlockControllers();
+
+ // clearing undo stack:
+ Reference< XFrame > xFrame( xSelf.is() ? xSelf : mxDocumentFrame );
+ if ( xFrame.is() )
+ {
+ DispatchURL(mxContext, ".uno:ClearUndoStack", 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: */
diff --git a/sdext/source/minimizer/impoptimizer.hxx b/sdext/source/minimizer/impoptimizer.hxx
new file mode 100644
index 0000000000..98d22e71d1
--- /dev/null
+++ b/sdext/source/minimizer/impoptimizer.hxx
@@ -0,0 +1,70 @@
+/* -*- 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 .
+ */
+
+#ifndef INCLUDED_SDEXT_SOURCE_MINIMIZER_IMPOPTIMIZER_HXX
+#define INCLUDED_SDEXT_SOURCE_MINIMIZER_IMPOPTIMIZER_HXX
+
+#include "optimizationstats.hxx"
+#include <com/sun/star/uno/Sequence.h>
+#include <com/sun/star/frame/XDispatch.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+
+
+class ImpOptimizer : public OptimizationStats
+{
+private:
+
+ css::uno::Reference< css::uno::XComponentContext > mxContext;
+ css::uno::Reference< css::frame::XModel > mxModel;
+ css::uno::Reference< css::frame::XDispatch > mxStatusDispatcher;
+ css::uno::Reference<css::frame::XFrame> mxDocumentFrame;
+ css::uno::Reference<css::awt::XWindow> mxDialogParentWindow;
+
+ bool mbJPEGCompression;
+ sal_Int32 mnJPEGQuality;
+ bool mbRemoveCropArea;
+ sal_Int32 mnImageResolution;
+ bool mbEmbedLinkedGraphics;
+ bool mbOLEOptimization;
+ sal_Int32 mnOLEOptimizationType;
+ OUString maCustomShowName;
+ bool mbDeleteUnusedMasterPages;
+ bool mbDeleteHiddenSlides;
+ bool mbDeleteNotesPages;
+ OUString maSaveAsURL;
+ OUString maFilterName;
+ bool mbOpenNewDocument;
+
+ void Optimize();
+
+public:
+
+ ImpOptimizer( const css::uno::Reference< css::uno::XComponentContext >& rXFactory,
+ const css::uno::Reference< css::frame::XModel >& rxModel );
+ ~ImpOptimizer();
+
+ void Optimize( const css::uno::Sequence< css::beans::PropertyValue >& rArguments );
+ void DispatchStatus();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/minimizer/informationdialog.cxx b/sdext/source/minimizer/informationdialog.cxx
new file mode 100644
index 0000000000..caea0fc1d7
--- /dev/null
+++ b/sdext/source/minimizer/informationdialog.cxx
@@ -0,0 +1,145 @@
+/* -*- 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 "informationdialog.hxx"
+#include <com/sun/star/awt/PushButtonType.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/util/URL.hpp>
+#include <com/sun/star/util/URLTransformer.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <rtl/ustrbuf.hxx>
+#include <sal/macros.h>
+#include <vcl/svapp.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::ui;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+
+static OUString ImpValueOfInMB( sal_Int64 rVal )
+{
+ double fVal( static_cast<double>( rVal ) );
+ fVal /= ( 1 << 20 );
+ fVal += 0.05;
+ OUStringBuffer aVal( OUString::number( fVal ) );
+ sal_Int32 nX( aVal.indexOf( '.' ) );
+ if ( nX > 0 )
+ aVal.setLength( nX + 2 );
+ return aVal.makeStringAndClear();
+}
+
+void InformationDialog::InitDialog()
+{
+ set_title(getString(STR_SUN_OPTIMIZATION_WIZARD2));
+
+ sal_Int64 nSource = mnSourceSize;
+ sal_Int64 nDest = mnDestSize;
+
+ PPPOptimizerTokenEnum eInfoString( STR_INFO_SECONDARY_1 );
+ if ( mnSourceSize )
+ {
+ if ( mnDestSize )
+ eInfoString = STR_INFO_SECONDARY_1;
+ else
+ {
+ eInfoString = STR_INFO_SECONDARY_2;
+ nDest = mnApproxSize;
+ }
+ }
+ else if ( mnDestSize )
+ eInfoString = STR_INFO_SECONDARY_3;
+ else
+ {
+ eInfoString = STR_INFO_SECONDARY_4;
+ nDest = mnApproxSize;
+ }
+
+ OUString aTitle;
+ if ( !maSaveAsURL.isEmpty() )
+ {
+ Reference< XURLTransformer > xURLTransformer( URLTransformer::create(mxContext) );
+ util::URL aURL, aPresentationURL;
+ aURL.Complete = maSaveAsURL;
+ xURLTransformer->parseSmart( aURL, OUString() );
+
+ static constexpr OUString sFileProtocol( u"file:///"_ustr );
+ aPresentationURL.Complete = sFileProtocol + aURL.Name;
+ aTitle = xURLTransformer->getPresentation( aPresentationURL, false );
+
+ if ( aTitle.match( sFileProtocol ) )
+ aTitle = aTitle.replaceAt( 0, sFileProtocol.getLength(), u"" );
+ }
+
+ OUString sPrimary( getString( STR_INFO_PRIMARY ) );
+ OUString sSecondary( getString( eInfoString ) );
+ static constexpr OUString aOldSizePlaceholder( u"%OLDFILESIZE"_ustr );
+ static constexpr OUString aNewSizePlaceholder( u"%NEWFILESIZE"_ustr );
+ const OUString aTitlePlaceholder( !aTitle.isEmpty() ? OUString("%TITLE" )
+ : OUString("'%TITLE'") );
+
+ sal_Int32 i = sSecondary.indexOf( aOldSizePlaceholder );
+ if ( i >= 0 )
+ sSecondary = sSecondary.replaceAt( i, aOldSizePlaceholder.getLength(), ImpValueOfInMB( nSource ) );
+
+ sal_Int32 j = sSecondary.indexOf( aNewSizePlaceholder );
+ if ( j >= 0 )
+ sSecondary = sSecondary.replaceAt( j, aNewSizePlaceholder.getLength(), ImpValueOfInMB( nDest ) );
+
+ sal_Int32 k = sPrimary.indexOf( aTitlePlaceholder );
+ if ( k >= 0 )
+ sPrimary = sPrimary.replaceAt( k, aTitlePlaceholder.getLength(), aTitle );
+
+ set_primary_text(sPrimary);
+ set_secondary_text(sSecondary);
+ mxCheckBox->set_visible(!maSaveAsURL.isEmpty());
+ mxCheckBox->set_active(mrbOpenNewDocument);
+}
+
+InformationDialog::InformationDialog(const Reference< XComponentContext > &rxContext, const Reference<XWindow>& rxDialogParent,
+ const OUString& rSaveAsURL, bool& rbOpenNewDocument,
+ sal_Int64 rSourceSize, sal_Int64 rDestSize, sal_Int64 rApproxSize)
+ : MessageDialogController(Application::GetFrameWeld(rxDialogParent), "modules/simpress/ui/pminfodialog.ui", "PMInfoDialog", "ask")
+ , ConfigurationAccess(rxContext)
+ , mxCheckBox(m_xBuilder->weld_check_button("ask"))
+ , mnSourceSize(rSourceSize)
+ , mnDestSize(rDestSize)
+ , mnApproxSize(rApproxSize)
+ , mrbOpenNewDocument(rbOpenNewDocument)
+ , maSaveAsURL(rSaveAsURL)
+{
+ InitDialog();
+}
+
+InformationDialog::~InformationDialog()
+{
+}
+
+void InformationDialog::execute()
+{
+ run();
+ if (!maSaveAsURL.isEmpty())
+ mrbOpenNewDocument = mxCheckBox->get_active();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/minimizer/informationdialog.hxx b/sdext/source/minimizer/informationdialog.hxx
new file mode 100644
index 0000000000..56c6994a2c
--- /dev/null
+++ b/sdext/source/minimizer/informationdialog.hxx
@@ -0,0 +1,51 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include "configurationaccess.hxx"
+#include <vcl/weld.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <cppuhelper/implbase.hxx>
+
+class InformationDialog : public weld::MessageDialogController, public ConfigurationAccess
+{
+public:
+
+ InformationDialog( const css::uno::Reference< css::uno::XComponentContext >& rxContext,
+ const css::uno::Reference<css::awt::XWindow>& rxDialogParent, const OUString& rSaveAsURL,
+ bool& bOpenNewDocument, sal_Int64 nSourceSize, sal_Int64 nDestSize, sal_Int64 nApproxDest );
+ ~InformationDialog();
+
+ void execute();
+
+private:
+
+ void InitDialog();
+
+ std::unique_ptr<weld::CheckButton> mxCheckBox;
+
+ sal_Int64 mnSourceSize;
+ sal_Int64 mnDestSize;
+ sal_Int64 mnApproxSize;
+ bool& mrbOpenNewDocument;
+ const OUString& maSaveAsURL;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/minimizer/minimizer.component b/sdext/source/minimizer/minimizer.component
new file mode 100644
index 0000000000..63f92cbbd5
--- /dev/null
+++ b/sdext/source/minimizer/minimizer.component
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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/.
+ *
+-->
+<component loader="com.sun.star.loader.SharedLibrary" environment="@CPPU_ENV@"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.comp.PresentationMinimizerImp"
+ constructor="sdext_PPPOptimizerDialog_get_implementation">
+ <service name="com.sun.star.comp.PresentationMinimizer"/>
+ </implementation>
+</component>
diff --git a/sdext/source/minimizer/optimizationstats.cxx b/sdext/source/minimizer/optimizationstats.cxx
new file mode 100644
index 0000000000..1deef26ac0
--- /dev/null
+++ b/sdext/source/minimizer/optimizationstats.cxx
@@ -0,0 +1,86 @@
+/* -*- 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 "optimizationstats.hxx"
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/drawing/XShapes.hpp>
+#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
+
+#include <comphelper/propertyvalue.hxx>
+
+#include <algorithm>
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::beans;
+
+
+OptimizationStats::OptimizationStats()
+{
+}
+
+
+void OptimizationStats::SetStatusValue( const PPPOptimizerTokenEnum eStat, const uno::Any& rStatValue )
+{
+ maStats[ eStat ] = rStatValue;
+}
+
+
+const uno::Any* OptimizationStats::GetStatusValue( const PPPOptimizerTokenEnum eStat ) const
+{
+ std::map< PPPOptimizerTokenEnum, uno::Any >::const_iterator aIter( maStats.find( eStat ) );
+ return aIter != maStats.end() ? &((*aIter).second) : nullptr;
+}
+
+
+css::beans::PropertyValues OptimizationStats::GetStatusSequence()
+{
+ uno::Sequence< PropertyValue > aStatsSequence( maStats.size() );
+ std::transform(maStats.begin(), maStats.end(), aStatsSequence.getArray(),
+ [](const auto& rEntry)
+ { return comphelper::makePropertyValue(TKGet( rEntry.first ), rEntry.second); });
+ return aStatsSequence;
+}
+
+
+void OptimizationStats::InitializeStatusValues( const uno::Sequence< PropertyValue >& rOptimizationStats )
+{
+ for( const auto& rStat : rOptimizationStats )
+ maStats[ TKGet( rStat.Name ) ] = rStat.Value;
+}
+
+
+void OptimizationStats::InitializeStatusValuesFromDocument( const Reference< XModel >& rxModel )
+{
+ try
+ {
+ Reference< XDrawPagesSupplier > xDrawPagesSupplier( rxModel, UNO_QUERY_THROW );
+ Reference< XDrawPages > xDrawPages( xDrawPagesSupplier->getDrawPages(), UNO_SET_THROW );
+ SetStatusValue( TK_Pages, Any( awt::Size( 0, xDrawPages->getCount() ) ) );
+ }
+ catch ( Exception& )
+ {
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/minimizer/optimizationstats.hxx b/sdext/source/minimizer/optimizationstats.hxx
new file mode 100644
index 0000000000..a1af8f30e7
--- /dev/null
+++ b/sdext/source/minimizer/optimizationstats.hxx
@@ -0,0 +1,45 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <com/sun/star/uno/Sequence.h>
+#include <com/sun/star/beans/PropertyValues.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include "pppoptimizertoken.hxx"
+#include <map>
+
+class OptimizationStats
+{
+ std::map < PPPOptimizerTokenEnum, css::uno::Any > maStats;
+
+ public:
+
+ OptimizationStats();
+
+ void SetStatusValue( const PPPOptimizerTokenEnum eStat, const css::uno::Any& rStatValue );
+ const css::uno::Any* GetStatusValue( const PPPOptimizerTokenEnum eStat ) const;
+
+ void InitializeStatusValuesFromDocument( const css::uno::Reference< css::frame::XModel >& rxModel );
+ void InitializeStatusValues( const css::uno::Sequence< css::beans::PropertyValue >& rOptimizationStats );
+
+ css::beans::PropertyValues GetStatusSequence();
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/minimizer/optimizerdialog.cxx b/sdext/source/minimizer/optimizerdialog.cxx
new file mode 100644
index 0000000000..773970a41b
--- /dev/null
+++ b/sdext/source/minimizer/optimizerdialog.cxx
@@ -0,0 +1,675 @@
+/* -*- 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 "optimizerdialog.hxx"
+#include "impoptimizer.hxx"
+#include "fileopendialog.hxx"
+#include <com/sun/star/awt/XItemEventBroadcaster.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/frame/XTitle.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
+#include <com/sun/star/io/IOException.hpp>
+#include <com/sun/star/util/XModifiable.hpp>
+
+#include <comphelper/propertyvalue.hxx>
+#include <sal/macros.h>
+#include <osl/time.h>
+#include <vcl/errinf.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <svtools/sfxecode.hxx>
+#include <svtools/ehdl.hxx>
+#include <tools/urlobj.hxx>
+#include <o3tl/string_view.hxx>
+#include <bitmaps.hlst>
+
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::ui;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+
+IntroPage::IntroPage(weld::Container* pPage, OptimizerDialog& rOptimizerDialog)
+ : vcl::OWizardPage(pPage, &rOptimizerDialog, "modules/simpress/ui/pmintropage.ui", "PMIntroPage")
+ , mrOptimizerDialog(rOptimizerDialog)
+ , mxComboBox(m_xBuilder->weld_combo_box("LB_SETTINGS"))
+ , mxButton(m_xBuilder->weld_button("STR_REMOVE"))
+{
+ rOptimizerDialog.SetIntroPage(this);
+ mxComboBox->connect_changed(LINK(this, IntroPage, ComboBoxActionPerformed));
+ mxButton->connect_clicked(LINK(this, IntroPage, ButtonActionPerformed));
+}
+
+void IntroPage::UpdateControlStates(const std::vector<OUString>& rItemList, int nSelectedItem, bool bRemoveButtonEnabled)
+{
+ mxComboBox->clear();
+ for (const auto& a : rItemList)
+ mxComboBox->append_text(a);
+ mxComboBox->set_active(nSelectedItem);
+ mxButton->set_sensitive(bRemoveButtonEnabled);
+}
+
+SlidesPage::SlidesPage(weld::Container* pPage, OptimizerDialog& rOptimizerDialog)
+ : vcl::OWizardPage(pPage, &rOptimizerDialog, "modules/simpress/ui/pmslidespage.ui", "PMSlidesPage")
+ , mrOptimizerDialog(rOptimizerDialog)
+ , mxMasterSlides(m_xBuilder->weld_check_button("STR_DELETE_MASTER_PAGES"))
+ , mxHiddenSlides(m_xBuilder->weld_check_button("STR_DELETE_HIDDEN_SLIDES"))
+ , mxUnusedSlides(m_xBuilder->weld_check_button("STR_CUSTOM_SHOW"))
+ , mxComboBox(m_xBuilder->weld_combo_box("LB_SLIDES"))
+ , mxClearNodes(m_xBuilder->weld_check_button("STR_DELETE_NOTES_PAGES"))
+{
+ rOptimizerDialog.SetSlidesPage(this);
+ mxMasterSlides->connect_toggled(LINK(this, SlidesPage, UnusedMasterPagesActionPerformed));
+ mxHiddenSlides->connect_toggled(LINK(this, SlidesPage, UnusedHiddenSlidesActionPerformed));
+ mxUnusedSlides->connect_toggled(LINK(this, SlidesPage, UnusedSlidesActionPerformed));
+ mxClearNodes->connect_toggled(LINK(this, SlidesPage, DeleteNotesActionPerformed));
+}
+
+void SlidesPage::Init(const css::uno::Sequence<OUString>& rCustomShowList)
+{
+ mxComboBox->clear();
+ for (const auto& a : rCustomShowList)
+ mxComboBox->append_text(a);
+ mxUnusedSlides->set_sensitive(rCustomShowList.hasElements());
+}
+
+void SlidesPage::UpdateControlStates(bool bDeleteUnusedMasterPages, bool bDeleteHiddenSlides, bool bDeleteNotesPages)
+{
+ mxMasterSlides->set_active(bDeleteUnusedMasterPages);
+ mxHiddenSlides->set_active(bDeleteHiddenSlides);
+ mxClearNodes->set_active(bDeleteNotesPages);
+ mxComboBox->set_sensitive(mxUnusedSlides->get_sensitive());
+}
+
+ImagesPage::ImagesPage(weld::Container* pPage, OptimizerDialog& rOptimizerDialog)
+ : vcl::OWizardPage(pPage, &rOptimizerDialog, "modules/simpress/ui/pmimagespage.ui", "PMImagesPage")
+ , mrOptimizerDialog(rOptimizerDialog)
+ , m_xLossLessCompression(m_xBuilder->weld_radio_button("STR_LOSSLESS_COMPRESSION"))
+ , m_xQualityLabel(m_xBuilder->weld_label("STR_QUALITY"))
+ , m_xQuality(m_xBuilder->weld_spin_button("SB_QUALITY"))
+ , m_xJpegCompression(m_xBuilder->weld_radio_button("STR_JPEG_COMPRESSION"))
+ , m_xResolution(m_xBuilder->weld_combo_box("LB_RESOLUTION"))
+ , m_xRemoveCropArea(m_xBuilder->weld_check_button("STR_REMOVE_CROP_AREA"))
+ , m_xEmbedLinkedGraphics(m_xBuilder->weld_check_button("STR_EMBED_LINKED_GRAPHICS"))
+{
+ rOptimizerDialog.SetImagesPage(this);
+ m_xRemoveCropArea->connect_toggled(LINK(this, ImagesPage, RemoveCropAreaActionPerformed));
+ m_xEmbedLinkedGraphics->connect_toggled(LINK(this, ImagesPage, EmbedLinkedGraphicsActionPerformed));
+ m_xResolution->connect_changed(LINK(this, ImagesPage, ComboBoxActionPerformed));
+ m_xQuality->connect_value_changed(LINK(this, ImagesPage, SpinButtonActionPerformed));
+
+ m_xJpegCompression->connect_toggled(LINK(this, ImagesPage, CompressionActionPerformed));
+ m_xLossLessCompression->connect_toggled(LINK(this, ImagesPage, CompressionActionPerformed));
+}
+
+void ImagesPage::UpdateControlStates(bool bJPEGCompression, int nJPEGQuality, bool bRemoveCropArea,
+ int nResolution, bool bEmbedLinkedGraphics)
+{
+ m_xLossLessCompression->set_active(!bJPEGCompression);
+ m_xJpegCompression->set_active(bJPEGCompression);
+ m_xQualityLabel->set_sensitive(bJPEGCompression);
+ m_xQuality->set_sensitive(bJPEGCompression);
+ m_xQuality->set_value(nJPEGQuality);
+ m_xResolution->set_active_id(OUString::number(nResolution));
+ m_xRemoveCropArea->set_active(bRemoveCropArea);
+ m_xEmbedLinkedGraphics->set_active(bEmbedLinkedGraphics);
+}
+
+ObjectsPage::ObjectsPage(weld::Container* pPage, OptimizerDialog& rOptimizerDialog)
+ : vcl::OWizardPage(pPage, &rOptimizerDialog, "modules/simpress/ui/pmobjectspage.ui", "PMObjectsPage")
+ , mrOptimizerDialog(rOptimizerDialog)
+ , m_xCreateStaticImage(m_xBuilder->weld_check_button("STR_OLE_REPLACE"))
+ , m_xAllOLEObjects(m_xBuilder->weld_radio_button("STR_ALL_OLE_OBJECTS"))
+ , m_xForeignOLEObjects(m_xBuilder->weld_radio_button("STR_ALIEN_OLE_OBJECTS_ONLY"))
+ , m_xLabel(m_xBuilder->weld_label("STR_OLE_OBJECTS_DESC"))
+{
+ rOptimizerDialog.SetObjectsPage(this);
+ m_xCreateStaticImage->connect_toggled(LINK(this, ObjectsPage, OLEOptimizationActionPerformed));
+ m_xAllOLEObjects->connect_toggled(LINK(this, ObjectsPage, OLEActionPerformed));
+ m_xForeignOLEObjects->connect_toggled(LINK(this, ObjectsPage, OLEActionPerformed));
+}
+
+void ObjectsPage::Init(const OUString& rDesc)
+{
+ m_xLabel->set_label(rDesc);
+}
+
+void ObjectsPage::UpdateControlStates(bool bConvertOLEObjects, int nOLEOptimizationType)
+{
+ m_xCreateStaticImage->set_active(bConvertOLEObjects);
+ m_xAllOLEObjects->set_sensitive(bConvertOLEObjects);
+ m_xForeignOLEObjects->set_sensitive(bConvertOLEObjects);
+ m_xAllOLEObjects->set_active(nOLEOptimizationType == 0);
+ m_xForeignOLEObjects->set_active(nOLEOptimizationType == 1);
+}
+
+SummaryPage::SummaryPage(weld::Container* pPage, OptimizerDialog& rOptimizerDialog)
+ : vcl::OWizardPage(pPage, &rOptimizerDialog, "modules/simpress/ui/pmsummarypage.ui", "PMSummaryPage")
+ , mrOptimizerDialog(rOptimizerDialog)
+ , m_xLabel1(m_xBuilder->weld_label("LABEL1"))
+ , m_xLabel2(m_xBuilder->weld_label("LABEL2"))
+ , m_xLabel3(m_xBuilder->weld_label("LABEL3"))
+ , m_xCurrentSize(m_xBuilder->weld_label("CURRENT_FILESIZE"))
+ , m_xEstimatedSize(m_xBuilder->weld_label("ESTIMATED_FILESIZE"))
+ , m_xStatus(m_xBuilder->weld_label("STR_STATUS"))
+ , m_xProgress(m_xBuilder->weld_progress_bar("PROGRESS"))
+ , m_xApplyToCurrent(m_xBuilder->weld_radio_button("STR_APPLY_TO_CURRENT"))
+ , m_xSaveToNew(m_xBuilder->weld_radio_button("STR_SAVE_AS"))
+ , m_xComboBox(m_xBuilder->weld_combo_box("MY_SETTINGS"))
+ , m_xSaveSettings(m_xBuilder->weld_check_button("STR_SAVE_SETTINGS"))
+{
+ rOptimizerDialog.SetSummaryPage(this);
+ m_xApplyToCurrent->connect_toggled(LINK(this, SummaryPage, SaveAsNewActionPerformed));
+ m_xSaveToNew->connect_toggled(LINK(this, SummaryPage, SaveAsNewActionPerformed));
+ m_xSaveSettings->connect_toggled(LINK(this, SummaryPage, SaveSettingsActionPerformed));
+}
+
+void SummaryPage::Init(const OUString& rSettingsName, bool bIsReadonly)
+{
+ m_xComboBox->set_entry_text(rSettingsName);
+ m_xApplyToCurrent->set_sensitive(!bIsReadonly);
+ m_xSaveToNew->set_sensitive(!bIsReadonly);
+}
+
+void SummaryPage::UpdateControlStates(bool bSaveAs, bool bSaveSettingsEnabled,
+ const std::vector<OUString>& rItemList,
+ const std::vector<OUString>& rSummaryStrings,
+ const OUString& rCurrentFileSize,
+ const OUString& rEstimatedFileSize)
+{
+ m_xApplyToCurrent->set_active(!bSaveAs);
+ m_xSaveToNew->set_active(bSaveAs);
+
+ for (const auto& a : rItemList)
+ m_xComboBox->append_text(a);
+
+ m_xSaveSettings->set_sensitive(bSaveSettingsEnabled);
+ m_xComboBox->set_sensitive(bSaveSettingsEnabled && m_xSaveSettings->get_active());
+
+ assert(rSummaryStrings.size() == 3);
+ m_xLabel1->set_label(rSummaryStrings[0]);
+ m_xLabel2->set_label(rSummaryStrings[1]);
+ m_xLabel3->set_label(rSummaryStrings[2]);
+
+ m_xCurrentSize->set_label(rCurrentFileSize);
+ m_xEstimatedSize->set_label(rEstimatedFileSize);
+}
+
+void SummaryPage::UpdateStatusLabel(const OUString& rStatus)
+{
+ m_xStatus->set_label(rStatus);
+}
+
+void SummaryPage::UpdateProgressValue(int nProgress)
+{
+ m_xProgress->set_percentage(nProgress);
+}
+
+void OptimizerDialog::InitDialog()
+{
+ set_title(getString(STR_SUN_OPTIMIZATION_WIZARD2));
+}
+
+void OptimizerDialog::InitRoadmap()
+{
+ declarePath(
+ 0,
+ {ITEM_ID_INTRODUCTION,
+ ITEM_ID_SLIDES,
+ ITEM_ID_GRAPHIC_OPTIMIZATION,
+ ITEM_ID_OLE_OPTIMIZATION,
+ ITEM_ID_SUMMARY}
+ );
+
+ m_xAssistant->set_page_side_image(BMP_PRESENTATION_MINIMIZER);
+}
+
+void OptimizerDialog::UpdateConfiguration()
+{
+ // page0
+ OUString sTKName(mpPage0->Get_TK_Name());
+ if (!sTKName.isEmpty())
+ SetConfigProperty(TK_Name, Any(sTKName));
+
+ // page1
+ OUString sTKCustomShowName(mpPage1->Get_TK_CustomShowName());
+ if (!sTKCustomShowName.isEmpty())
+ SetConfigProperty(TK_CustomShowName, Any(sTKCustomShowName));
+}
+
+OptimizerDialog::OptimizerDialog( const Reference< XComponentContext > &rxContext, Reference< XFrame > const & rxFrame, Reference< XDispatch > const & rxStatusDispatcher )
+ : vcl::RoadmapWizardMachine(Application::GetFrameWeld(rxFrame->getComponentWindow()))
+ , ConfigurationAccess(rxContext)
+ , mnEndStatus(RET_CANCEL)
+ , mxFrame(rxFrame)
+ , mxController(rxFrame->getController())
+ , mxStatusDispatcher(rxStatusDispatcher)
+{
+ Reference< XStorable > xStorable( mxController->getModel(), UNO_QUERY_THROW );
+ mbIsReadonly = xStorable->isReadonly();
+
+ InitDialog();
+ InitRoadmap();
+ InitNavigationBar();
+ InitPage0();
+ InitPage1();
+ InitPage2();
+ InitPage3();
+ InitPage4();
+
+ ActivatePage();
+ m_xAssistant->set_current_page(0);
+
+ OptimizationStats aStats;
+ aStats.InitializeStatusValuesFromDocument( mxController->getModel() );
+ Sequence< PropertyValue > aStatusSequence( aStats.GetStatusSequence() );
+ UpdateStatus( aStatusSequence );
+}
+
+OUString OptimizerDialog::getStateDisplayName(vcl::WizardTypes::WizardState nState) const
+{
+ switch (nState)
+ {
+ case ITEM_ID_INTRODUCTION:
+ return getString(STR_INTRODUCTION);
+ case ITEM_ID_SLIDES:
+ return getString(STR_SLIDES);
+ case ITEM_ID_GRAPHIC_OPTIMIZATION:
+ return getString(STR_IMAGE_OPTIMIZATION);
+ case ITEM_ID_OLE_OPTIMIZATION:
+ return getString(STR_OLE_OBJECTS);
+ case ITEM_ID_SUMMARY:
+ return getString(STR_SUMMARY);
+ }
+ return OUString();
+}
+
+std::unique_ptr<BuilderPage> OptimizerDialog::createPage(vcl::WizardTypes::WizardState nState)
+{
+ OUString sIdent(OUString::number(nState));
+ weld::Container* pPageContainer = m_xAssistant->append_page(sIdent);
+
+ std::unique_ptr<vcl::OWizardPage> xRet;
+
+ switch (nState)
+ {
+ case ITEM_ID_INTRODUCTION:
+ xRet.reset(new IntroPage(pPageContainer, *this));
+ break;
+ case ITEM_ID_SLIDES:
+ xRet.reset(new SlidesPage(pPageContainer, *this));
+ break;
+ case ITEM_ID_GRAPHIC_OPTIMIZATION:
+ xRet.reset(new ImagesPage(pPageContainer, *this));
+ break;
+ case ITEM_ID_OLE_OPTIMIZATION:
+ xRet.reset(new ObjectsPage(pPageContainer, *this));
+ break;
+ case ITEM_ID_SUMMARY:
+ xRet.reset(new SummaryPage(pPageContainer, *this));
+ break;
+ }
+
+ m_xAssistant->set_page_title(sIdent, getStateDisplayName(nState));
+
+ return xRet;
+}
+
+OptimizerDialog::~OptimizerDialog()
+{
+ // not saving configuration if the dialog has been finished via cancel or close window
+ if (mnEndStatus == RET_OK)
+ SaveConfiguration();
+}
+
+void OptimizerDialog::execute()
+{
+ mnEndStatus = run();
+ UpdateConfiguration(); // taking actual control settings for the configuration
+}
+
+void OptimizerDialog::UpdateControlStates( sal_Int16 nPage )
+{
+ switch( nPage )
+ {
+ case 0 : UpdateControlStatesPage0(); break;
+ case 1 : UpdateControlStatesPage1(); break;
+ case 2 : UpdateControlStatesPage2(); break;
+ case 3 : UpdateControlStatesPage3(); break;
+ case 4 : UpdateControlStatesPage4(); break;
+ default:
+ {
+ UpdateControlStatesPage0();
+ UpdateControlStatesPage1();
+ UpdateControlStatesPage2();
+ UpdateControlStatesPage3();
+ UpdateControlStatesPage4();
+ }
+ }
+}
+
+void OptimizerDialog::UpdateStatus( const css::uno::Sequence< css::beans::PropertyValue >& rStatus )
+{
+ maStats.InitializeStatusValues( rStatus );
+ const Any* pVal( maStats.GetStatusValue( TK_Status ) );
+ if ( pVal )
+ {
+ OUString sStatus;
+ if ( *pVal >>= sStatus )
+ {
+ mpPage4->UpdateStatusLabel(getString(TKGet(sStatus)));
+ }
+ }
+ pVal = maStats.GetStatusValue( TK_Progress );
+ if ( pVal )
+ {
+ sal_Int32 nProgress = 0;
+ if ( *pVal >>= nProgress )
+ mpPage4->UpdateProgressValue(nProgress);
+ }
+ pVal = maStats.GetStatusValue( TK_OpenNewDocument );
+ if ( pVal )
+ SetConfigProperty( TK_OpenNewDocument, *pVal );
+
+ Application::Reschedule(true);
+}
+
+IMPL_LINK(SummaryPage, SaveAsNewActionPerformed, weld::Toggleable&, rBox, void)
+{
+ if (!rBox.get_active())
+ return;
+
+ const bool bSaveToNew = &rBox == m_xSaveToNew.get();
+ mrOptimizerDialog.SetConfigProperty( TK_SaveAs, Any(bSaveToNew) );
+}
+
+IMPL_LINK(SummaryPage, SaveSettingsActionPerformed, weld::Toggleable&, rBox, void)
+{
+ m_xComboBox->set_sensitive(rBox.get_active());
+}
+
+IMPL_LINK(ObjectsPage, OLEActionPerformed, weld::Toggleable&, rBox, void)
+{
+ if (!rBox.get_active())
+ return;
+
+ const bool bALLOles = &rBox == m_xAllOLEObjects.get();
+ sal_Int16 nInt16 = bALLOles ? 0 : 1;
+ mrOptimizerDialog.SetConfigProperty( TK_OLEOptimizationType, Any( nInt16 ) );
+}
+
+IMPL_LINK(ObjectsPage, OLEOptimizationActionPerformed, weld::Toggleable&, rBox, void)
+{
+ const bool bOLEOptimization = rBox.get_active();
+ mrOptimizerDialog.SetConfigProperty( TK_OLEOptimization, Any(bOLEOptimization) );
+ m_xAllOLEObjects->set_sensitive(bOLEOptimization);
+ m_xForeignOLEObjects->set_sensitive(bOLEOptimization);
+}
+
+IMPL_LINK(ImagesPage, CompressionActionPerformed, weld::Toggleable&, rBox, void)
+{
+ if (!rBox.get_active())
+ return;
+
+ const bool bJPEGCompression = &rBox == m_xJpegCompression.get();
+ mrOptimizerDialog.SetConfigProperty(TK_JPEGCompression, Any(bJPEGCompression));
+ m_xQualityLabel->set_sensitive(bJPEGCompression);
+ m_xQuality->set_sensitive(bJPEGCompression);
+}
+
+IMPL_LINK(ImagesPage, RemoveCropAreaActionPerformed, weld::Toggleable&, rBox, void)
+{
+ mrOptimizerDialog.SetConfigProperty(TK_RemoveCropArea, Any(rBox.get_active()));
+}
+
+IMPL_LINK(ImagesPage, EmbedLinkedGraphicsActionPerformed, weld::Toggleable&, rBox, void)
+{
+ mrOptimizerDialog.SetConfigProperty(TK_EmbedLinkedGraphics, Any(rBox.get_active()));
+}
+
+IMPL_LINK(SlidesPage, UnusedHiddenSlidesActionPerformed, weld::Toggleable&, rBox, void)
+{
+ mrOptimizerDialog.SetConfigProperty(TK_DeleteHiddenSlides, Any(rBox.get_active()));
+}
+
+IMPL_LINK(SlidesPage, UnusedMasterPagesActionPerformed, weld::Toggleable&, rBox, void)
+{
+ mrOptimizerDialog.SetConfigProperty(TK_DeleteUnusedMasterPages, Any(rBox.get_active()));
+}
+
+IMPL_LINK(SlidesPage, DeleteNotesActionPerformed, weld::Toggleable&, rBox, void)
+{
+ mrOptimizerDialog.SetConfigProperty(TK_DeleteNotesPages, Any(rBox.get_active()));
+}
+
+IMPL_LINK(SlidesPage, UnusedSlidesActionPerformed, weld::Toggleable&, rBox, void)
+{
+ mxComboBox->set_sensitive(rBox.get_active());
+}
+
+bool OptimizerDialog::onFinish()
+{
+ UpdateConfiguration();
+
+ ShowPage(ITEM_ID_SUMMARY);
+ m_xPrevPage->set_sensitive(false);
+ m_xNextPage->set_sensitive(false);
+ m_xFinish->set_sensitive(false);
+ m_xCancel->set_sensitive(false);
+
+ // check if we have to open the FileDialog
+ bool bSuccessfullyExecuted = true;
+ if (mpPage4->GetSaveAsNew())
+ {
+ // Duplicate presentation before applying changes
+ OUString aSaveAsURL;
+ FileOpenDialog aFileOpenDialog(mxContext);
+
+ // generating default file name
+ OUString aName;
+ Reference< XStorable > xStorable( mxController->getModel(), UNO_QUERY );
+ if ( xStorable.is() && xStorable->hasLocation() )
+ {
+ INetURLObject aURLObj( xStorable->getLocation() );
+ if ( !aURLObj.hasFinalSlash() )
+ {
+ // tdf#105382 uri-decode file name
+ aURLObj.removeExtension(INetURLObject::LAST_SEGMENT, false);
+ aName = aURLObj.getName(INetURLObject::LAST_SEGMENT, false,
+ INetURLObject::DecodeMechanism::WithCharset);
+ }
+ }
+ else
+ {
+ // If no filename, try to use model title ("Untitled 1" or something like this)
+ Reference<XTitle> xTitle(
+ GetFrame()->getController()->getModel(), UNO_QUERY);
+ aName = xTitle->getTitle();
+ }
+
+ if (!aName.isEmpty())
+ {
+ aName += " " + getString(STR_FILENAME_SUFFIX);
+ aFileOpenDialog.setDefaultName(aName);
+ }
+
+ if (aFileOpenDialog.execute() == dialogs::ExecutableDialogResults::OK)
+ {
+ aSaveAsURL = aFileOpenDialog.getURL();
+ SetConfigProperty( TK_SaveAsURL, Any( aSaveAsURL ) );
+ SetConfigProperty( TK_FilterName, Any( aFileOpenDialog.getFilterName() ) );
+ }
+ if ( aSaveAsURL.isEmpty() )
+ {
+ // something goes wrong...
+ bSuccessfullyExecuted = false;
+ }
+
+ // waiting for 500ms
+ Application::Reschedule(true);
+ for ( sal_uInt32 i = osl_getGlobalTimer(); ( i + 500 ) > ( osl_getGlobalTimer() ); )
+ Application::Reschedule(true);
+ }
+ else
+ {
+ // Apply changes to current presentation
+ Reference<XModifiable> xModifiable(mxController->getModel(),
+ UNO_QUERY_THROW );
+ if ( xModifiable->isModified() )
+ {
+ SolarMutexGuard aSolarGuard;
+ std::unique_ptr<weld::MessageDialog> popupDlg(Application::CreateMessageDialog(
+ m_xAssistant.get(), VclMessageType::Question, VclButtonsType::YesNo,
+ getString(STR_WARN_UNSAVED_PRESENTATION)));
+ if (popupDlg->run() != RET_YES)
+ {
+ // Selected not "yes" ("no" or dialog was cancelled) so return to previous step
+ m_xPrevPage->set_sensitive(true);
+ m_xNextPage->set_sensitive(true);
+ m_xFinish->set_sensitive(true);
+ m_xCancel->set_sensitive(true);
+ return false;
+ }
+ }
+ }
+ if ( bSuccessfullyExecuted )
+ {
+ // now check if we have to store a session template
+ const bool bSaveSettings = mpPage4->GetSaveSettings();
+ OUString aSettingsName = mpPage4->GetSettingsName();
+ if (bSaveSettings && !aSettingsName.isEmpty())
+ {
+ std::vector< OptimizerSettings >::iterator aIter( GetOptimizerSettingsByName( aSettingsName ) );
+ std::vector< OptimizerSettings >& rSettings( GetOptimizerSettings() );
+ OptimizerSettings aNewSettings( rSettings[ 0 ] );
+ aNewSettings.maName = aSettingsName;
+ if ( aIter == rSettings.end() )
+ rSettings.push_back( aNewSettings );
+ else
+ *aIter = aNewSettings;
+ }
+ }
+ if ( bSuccessfullyExecuted )
+ {
+ URL aURL;
+ aURL.Protocol = "vnd.com.sun.star.comp.PPPOptimizer:";
+ aURL.Path = "optimize";
+
+ Sequence< PropertyValue > lArguments{
+ comphelper::makePropertyValue("Settings", GetConfigurationSequence()),
+ comphelper::makePropertyValue("StatusDispatcher", GetStatusDispatcher()),
+ comphelper::makePropertyValue("DocumentFrame", GetFrame()),
+ comphelper::makePropertyValue("DialogParentWindow", m_xAssistant->GetXWindow())
+ };
+
+ ErrCode errorCode;
+ try
+ {
+ ImpOptimizer aOptimizer(mxContext, GetFrame()->getController()->getModel());
+ aOptimizer.Optimize(lArguments);
+ }
+ catch (css::io::IOException&)
+ {
+ // We always receive just ERRCODE_IO_CANTWRITE in case of problems, so no need to bother
+ // about extracting error code from exception text
+ errorCode = ERRCODE_IO_CANTWRITE;
+ }
+ catch (css::uno::Exception&)
+ {
+ // Other general exception
+ errorCode = ERRCODE_IO_GENERAL;
+ }
+
+ if (errorCode != ERRCODE_NONE)
+ {
+ // Restore wizard controls
+ maStats.SetStatusValue(TK_Progress, Any(static_cast<sal_Int32>(0)));
+ m_xPrevPage->set_sensitive(true);
+ m_xNextPage->set_sensitive(false);
+ m_xFinish->set_sensitive(true);
+ m_xCancel->set_sensitive(true);
+
+ OUString aFileName;
+ GetConfigProperty(TK_SaveAsURL) >>= aFileName;
+ SfxErrorContext aEc(ERRCTX_SFX_SAVEASDOC, aFileName);
+ ErrorHandler::HandleError(errorCode);
+ return false;
+ }
+ }
+ else
+ {
+ m_xPrevPage->set_sensitive(true);
+ m_xNextPage->set_sensitive(false);
+ m_xFinish->set_sensitive(true);
+ m_xCancel->set_sensitive(true);
+ }
+
+ return vcl::RoadmapWizardMachine::onFinish();
+}
+
+IMPL_LINK_NOARG(IntroPage, ButtonActionPerformed, weld::Button&, void)
+{
+ // delete configuration
+ OUString aSelectedItem(mxComboBox->get_active_text());
+ if ( !aSelectedItem.isEmpty() )
+ {
+ std::vector< OptimizerSettings >::iterator aIter( mrOptimizerDialog.GetOptimizerSettingsByName( aSelectedItem ) );
+ std::vector< OptimizerSettings >& rList( mrOptimizerDialog.GetOptimizerSettings() );
+ if ( aIter != rList.end() )
+ {
+ rList.erase( aIter );
+ mrOptimizerDialog.UpdateControlStates();
+ }
+ }
+}
+
+IMPL_LINK(IntroPage, ComboBoxActionPerformed, weld::ComboBox&, rBox, void)
+{
+ OUString sActionCommand(rBox.get_active_text());
+ if (!sActionCommand.isEmpty())
+ {
+ std::vector< OptimizerSettings >::iterator aIter( mrOptimizerDialog.GetOptimizerSettingsByName(sActionCommand) );
+ std::vector< OptimizerSettings >& rList( mrOptimizerDialog.GetOptimizerSettings() );
+ if ( aIter != rList.end() )
+ rList[ 0 ] = *aIter;
+ }
+ mrOptimizerDialog.UpdateControlStates();
+}
+
+IMPL_LINK(ImagesPage, SpinButtonActionPerformed, weld::SpinButton&, rBox, void)
+{
+ mrOptimizerDialog.SetConfigProperty( TK_JPEGQuality, Any( static_cast<sal_Int32>(rBox.get_value()) ) );
+}
+
+IMPL_LINK_NOARG(ImagesPage, ComboBoxActionPerformed, weld::ComboBox&, void)
+{
+ mrOptimizerDialog.SetConfigProperty( TK_ImageResolution, Any( m_xResolution->get_active_id().toInt32() ) );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/minimizer/optimizerdialog.hxx b/sdext/source/minimizer/optimizerdialog.hxx
new file mode 100644
index 0000000000..88c01b5430
--- /dev/null
+++ b/sdext/source/minimizer/optimizerdialog.hxx
@@ -0,0 +1,244 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <vector>
+#include "optimizationstats.hxx"
+#include "configurationaccess.hxx"
+#include <com/sun/star/uno/Sequence.h>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/frame/XDispatch.hpp>
+#include <cppuhelper/implbase.hxx>
+#include <vcl/roadmapwizard.hxx>
+
+#define MAX_STEP 4
+#define OD_DIALOG_WIDTH 330
+#define DIALOG_HEIGHT 210
+#define BUTTON_WIDTH 50
+#define BUTTON_HEIGHT 14
+#define BUTTON_POS_Y DIALOG_HEIGHT - BUTTON_HEIGHT - 6
+
+#define PAGE_POS_X 91
+#define PAGE_POS_Y 8
+#define PAGE_WIDTH OD_DIALOG_WIDTH - PAGE_POS_X
+
+#define ITEM_ID_INTRODUCTION 0
+#define ITEM_ID_SLIDES 1
+#define ITEM_ID_GRAPHIC_OPTIMIZATION 2
+#define ITEM_ID_OLE_OPTIMIZATION 3
+#define ITEM_ID_SUMMARY 4
+
+class OptimizerDialog;
+
+class IntroPage : public vcl::OWizardPage
+{
+private:
+ OptimizerDialog& mrOptimizerDialog;
+ std::unique_ptr<weld::ComboBox> mxComboBox;
+ std::unique_ptr<weld::Button> mxButton;
+
+ DECL_LINK(ComboBoxActionPerformed, weld::ComboBox&, void);
+ DECL_LINK(ButtonActionPerformed, weld::Button&, void);
+
+public:
+ IntroPage(weld::Container* pPage, OptimizerDialog& rOptimizerDialog);
+ void UpdateControlStates(const std::vector<OUString>& rItemList, int nSelectedItem, bool bRemoveButtonEnabled);
+ OUString Get_TK_Name() const
+ {
+ return mxComboBox->get_active_text();
+ }
+};
+
+class SlidesPage : public vcl::OWizardPage
+{
+private:
+ OptimizerDialog& mrOptimizerDialog;
+ std::unique_ptr<weld::CheckButton> mxMasterSlides;
+ std::unique_ptr<weld::CheckButton> mxHiddenSlides;
+ std::unique_ptr<weld::CheckButton> mxUnusedSlides;
+ std::unique_ptr<weld::ComboBox> mxComboBox;
+ std::unique_ptr<weld::CheckButton> mxClearNodes;
+
+ DECL_LINK(UnusedMasterPagesActionPerformed, weld::Toggleable&, void);
+ DECL_LINK(UnusedHiddenSlidesActionPerformed, weld::Toggleable&, void);
+ DECL_LINK(UnusedSlidesActionPerformed, weld::Toggleable&, void);
+ DECL_LINK(DeleteNotesActionPerformed, weld::Toggleable&, void);
+
+public:
+ SlidesPage(weld::Container* pPage, OptimizerDialog& rOptimizerDialog);
+ void Init(const css::uno::Sequence<OUString>& rCustomShowList);
+ void UpdateControlStates(bool bDeleteUnusedMasterPages, bool bDeleteHiddenSlides, bool bDeleteNotesPages);
+ OUString Get_TK_CustomShowName() const
+ {
+ if (!mxUnusedSlides->get_sensitive())
+ return OUString();
+ return mxComboBox->get_active_text();
+ }
+};
+
+class ImagesPage : public vcl::OWizardPage
+{
+private:
+ OptimizerDialog& mrOptimizerDialog;
+ std::unique_ptr<weld::RadioButton> m_xLossLessCompression;
+ std::unique_ptr<weld::Label> m_xQualityLabel;
+ std::unique_ptr<weld::SpinButton> m_xQuality;
+ std::unique_ptr<weld::RadioButton> m_xJpegCompression;
+ std::unique_ptr<weld::ComboBox> m_xResolution;
+ std::unique_ptr<weld::CheckButton> m_xRemoveCropArea;
+ std::unique_ptr<weld::CheckButton> m_xEmbedLinkedGraphics;
+
+ DECL_LINK(EmbedLinkedGraphicsActionPerformed, weld::Toggleable&, void);
+ DECL_LINK(RemoveCropAreaActionPerformed, weld::Toggleable&, void);
+ DECL_LINK(ComboBoxActionPerformed, weld::ComboBox&, void);
+ DECL_LINK(CompressionActionPerformed, weld::Toggleable&, void);
+ DECL_LINK(SpinButtonActionPerformed, weld::SpinButton&, void);
+
+public:
+ ImagesPage(weld::Container* pPage, OptimizerDialog& rOptimizerDialog);
+
+ void UpdateControlStates(bool bJPEGCompression, int nJPEGQuality, bool bRemoveCropArea,
+ int nResolution, bool bEmbedLinkedGraphics);
+};
+
+class ObjectsPage : public vcl::OWizardPage
+{
+private:
+ OptimizerDialog& mrOptimizerDialog;
+ std::unique_ptr<weld::CheckButton> m_xCreateStaticImage;
+ std::unique_ptr<weld::RadioButton> m_xAllOLEObjects;
+ std::unique_ptr<weld::RadioButton> m_xForeignOLEObjects;
+ std::unique_ptr<weld::Label> m_xLabel;
+
+ DECL_LINK(OLEOptimizationActionPerformed, weld::Toggleable&, void);
+ DECL_LINK(OLEActionPerformed, weld::Toggleable&, void);
+
+public:
+ ObjectsPage(weld::Container* pPage, OptimizerDialog& rOptimizerDialog);
+
+ void Init(const OUString& rDesc);
+
+ void UpdateControlStates(bool bConvertOLEObjects, int nOLEOptimizationType);
+};
+
+class SummaryPage : public vcl::OWizardPage
+{
+private:
+ OptimizerDialog& mrOptimizerDialog;
+ std::unique_ptr<weld::Label> m_xLabel1;
+ std::unique_ptr<weld::Label> m_xLabel2;
+ std::unique_ptr<weld::Label> m_xLabel3;
+ std::unique_ptr<weld::Label> m_xCurrentSize;
+ std::unique_ptr<weld::Label> m_xEstimatedSize;
+ std::unique_ptr<weld::Label> m_xStatus;
+ std::unique_ptr<weld::ProgressBar> m_xProgress;
+ std::unique_ptr<weld::RadioButton> m_xApplyToCurrent;
+ std::unique_ptr<weld::RadioButton> m_xSaveToNew;
+ std::unique_ptr<weld::ComboBox> m_xComboBox;
+ std::unique_ptr<weld::CheckButton> m_xSaveSettings;
+
+ DECL_LINK(SaveSettingsActionPerformed, weld::Toggleable&, void);
+ DECL_LINK(SaveAsNewActionPerformed, weld::Toggleable&, void);
+
+public:
+ SummaryPage(weld::Container* pPage, OptimizerDialog& rOptimizerDialog);
+
+ void Init(const OUString& rSettingsName, bool bIsReadonly);
+
+ void UpdateControlStates(bool bSaveAs, bool bSaveSettingsEnabled,
+ const std::vector<OUString>& rItemList,
+ const std::vector<OUString>& rSummaryStrings,
+ const OUString& rCurrentFileSize,
+ const OUString& rEstimatedFileSize);
+
+ void UpdateStatusLabel(const OUString& rStatus);
+ void UpdateProgressValue(int nProgress);
+
+ bool GetSaveAsNew() const { return m_xSaveToNew->get_active(); }
+ bool GetSaveSettings() const { return m_xSaveSettings->get_active(); }
+ OUString GetSettingsName() const { return m_xComboBox->get_active_text(); }
+};
+
+class OptimizerDialog : public vcl::RoadmapWizardMachine, public ConfigurationAccess
+{
+public:
+
+ OptimizerDialog( const css::uno::Reference< css::uno::XComponentContext >& rxContext, css::uno::Reference< css::frame::XFrame > const & rxFrame,
+ css::uno::Reference< css::frame::XDispatch > const & rxStatusDispatcher );
+ std::unique_ptr<BuilderPage> createPage(vcl::WizardTypes::WizardState nState) override;
+ ~OptimizerDialog();
+
+ void execute();
+
+ short mnEndStatus;
+ bool mbIsReadonly;
+
+private:
+ css::uno::Reference< css::frame::XFrame > mxFrame;
+ css::uno::Reference< css::frame::XController > mxController;
+
+ css::uno::Reference< css::frame::XDispatch > mxStatusDispatcher;
+
+ IntroPage* mpPage0;
+ SlidesPage* mpPage1;
+ ImagesPage* mpPage2;
+ ObjectsPage* mpPage3;
+ SummaryPage* mpPage4;
+
+ void InitDialog();
+ void InitRoadmap();
+ void InitNavigationBar();
+ void InitPage0();
+ void InitPage1();
+ void InitPage2();
+ void InitPage3();
+ void InitPage4();
+ void UpdateControlStatesPage0();
+ void UpdateControlStatesPage1();
+ void UpdateControlStatesPage2();
+ void UpdateControlStatesPage3();
+ void UpdateControlStatesPage4();
+
+ virtual OUString getStateDisplayName(vcl::WizardTypes::WizardState nState) const override;
+
+ virtual bool onFinish() override;
+
+public:
+
+ OptimizationStats maStats;
+
+ void UpdateStatus( const css::uno::Sequence< css::beans::PropertyValue >& rStatus );
+
+ // the ConfigurationAccess is updated to actual control settings
+ void UpdateConfiguration();
+
+ void UpdateControlStates( sal_Int16 nStep = -1 );
+
+ void SetIntroPage(IntroPage* pPage0) { mpPage0 = pPage0; }
+ void SetSlidesPage(SlidesPage* pPage1) { mpPage1 = pPage1; }
+ void SetImagesPage(ImagesPage* pPage2) { mpPage2 = pPage2; }
+ void SetObjectsPage(ObjectsPage* pPage3) { mpPage3 = pPage3; }
+ void SetSummaryPage(SummaryPage* pPage4) { mpPage4 = pPage4; }
+
+ css::uno::Reference< css::frame::XDispatch >& GetStatusDispatcher() { return mxStatusDispatcher; };
+ css::uno::Reference< css::frame::XFrame>& GetFrame() { return mxFrame; };
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/minimizer/optimizerdialogcontrols.cxx b/sdext/source/minimizer/optimizerdialogcontrols.cxx
new file mode 100644
index 0000000000..5ed2dd942b
--- /dev/null
+++ b/sdext/source/minimizer/optimizerdialogcontrols.cxx
@@ -0,0 +1,359 @@
+/* -*- 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 "optimizerdialog.hxx"
+
+
+#include "pppoptimizer.hxx"
+#include "graphiccollector.hxx"
+#include "pagecollector.hxx"
+#include <com/sun/star/awt/PushButtonType.hpp>
+#include <com/sun/star/awt/XSpinField.hpp>
+#include <com/sun/star/awt/XTextComponent.hpp>
+#include <com/sun/star/presentation/XCustomPresentationSupplier.hpp>
+#include <com/sun/star/drawing/XMasterPagesSupplier.hpp>
+#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
+#include <com/sun/star/awt/FontDescriptor.hpp>
+#include <com/sun/star/awt/FontWeight.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <rtl/ustrbuf.hxx>
+#include <sal/macros.h>
+#include <o3tl/string_view.hxx>
+
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::presentation;
+
+void OptimizerDialog::InitNavigationBar()
+{
+ m_xHelp->hide();
+}
+
+void OptimizerDialog::UpdateControlStatesPage0()
+{
+ int nSelectedItem = -1;
+ std::vector<OUString> aItemList;
+ const std::vector< OptimizerSettings >& rList( GetOptimizerSettings() );
+ if ( rList.size() > 1 ) // the first session in the list is the actual one -> skipping first one
+ {
+ for ( std::vector<OptimizerSettings>::size_type i = 1; i < rList.size(); i++ )
+ {
+ aItemList.push_back(rList[i].maName);
+ if ( nSelectedItem < 0 )
+ {
+ if ( rList[ i ] == rList[ 0 ] )
+ nSelectedItem = static_cast< short >( i - 1 );
+ }
+ }
+ }
+ bool bRemoveButtonEnabled = false;
+ if ( nSelectedItem >= 0 )
+ {
+ if ( nSelectedItem > 2 ) // only allowing to delete custom themes, the first can|t be deleted
+ bRemoveButtonEnabled = true;
+ }
+ mpPage0->UpdateControlStates(aItemList, nSelectedItem, bRemoveButtonEnabled);
+}
+
+void OptimizerDialog::InitPage0()
+{
+ UpdateControlStatesPage0();
+}
+
+void OptimizerDialog::UpdateControlStatesPage1()
+{
+ bool bDeleteUnusedMasterPages( GetConfigProperty( TK_DeleteUnusedMasterPages, false ) );
+ bool bDeleteHiddenSlides( GetConfigProperty( TK_DeleteHiddenSlides, false ) );
+ bool bDeleteNotesPages( GetConfigProperty( TK_DeleteNotesPages, false ) );
+ mpPage1->UpdateControlStates(bDeleteUnusedMasterPages, bDeleteHiddenSlides, bDeleteNotesPages);
+}
+
+void OptimizerDialog::InitPage1()
+{
+ Sequence< OUString > aCustomShowList;
+ Reference< XModel > xModel( mxController->getModel() );
+ if ( xModel.is() )
+ {
+ Reference< XCustomPresentationSupplier > aXCPSup( xModel, UNO_QUERY_THROW );
+ Reference< XNameContainer > aXCont( aXCPSup->getCustomPresentations() );
+ if ( aXCont.is() )
+ aCustomShowList = aXCont->getElementNames();
+ }
+ mpPage1->Init(aCustomShowList);
+
+ UpdateControlStatesPage1();
+}
+
+void OptimizerDialog::UpdateControlStatesPage2()
+{
+ bool bJPEGCompression( GetConfigProperty( TK_JPEGCompression, false ) );
+ bool bRemoveCropArea( GetConfigProperty( TK_RemoveCropArea, false ) );
+ bool bEmbedLinkedGraphics( GetConfigProperty( TK_EmbedLinkedGraphics, true ) );
+ sal_Int32 nJPEGQuality( GetConfigProperty( TK_JPEGQuality, sal_Int32(90) ) );
+ sal_Int32 nImageResolution( GetConfigProperty( TK_ImageResolution, sal_Int32(0) ) );
+
+ mpPage2->UpdateControlStates(bJPEGCompression, nJPEGQuality, bRemoveCropArea, nImageResolution, bEmbedLinkedGraphics);
+}
+
+void OptimizerDialog::InitPage2()
+{
+ UpdateControlStatesPage2();
+}
+
+void OptimizerDialog::UpdateControlStatesPage3()
+{
+ bool bConvertOLEObjects( GetConfigProperty( TK_OLEOptimization, false ) );
+ sal_Int16 nOLEOptimizationType( GetConfigProperty( TK_OLEOptimizationType, sal_Int16(0) ) );
+
+ mpPage3->UpdateControlStates(bConvertOLEObjects, nOLEOptimizationType);
+}
+
+void OptimizerDialog::InitPage3()
+{
+ int nOLECount = 0;
+ Reference< XModel > xModel( mxController->getModel() );
+ Reference< XDrawPagesSupplier > xDrawPagesSupplier( xModel, 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" )
+ nOLECount++;
+ }
+ }
+
+ mpPage3->Init(nOLECount ? getString(STR_OLE_OBJECTS_DESC) : getString(STR_NO_OLE_OBJECTS_DESC));
+
+ UpdateControlStatesPage3();
+}
+
+static OUString ImpValueOfInMB( sal_Int64 rVal, sal_Unicode nSeparator )
+{
+ double fVal( static_cast<double>( rVal ) );
+ fVal /= ( 1 << 20 );
+ fVal += 0.05;
+ OUStringBuffer aVal( OUString::number( fVal ) );
+ sal_Int32 nX( aVal.indexOf( '.' ) );
+ if ( nX >= 0 )
+ {
+ aVal.setLength( nX + 2 );
+ aVal[nX] = nSeparator;
+ }
+ aVal.append( " MB" );
+ return aVal.makeStringAndClear();
+}
+
+void OptimizerDialog::UpdateControlStatesPage4()
+{
+ bool bSaveAs( GetConfigProperty( TK_SaveAs, true ) );
+ if ( mbIsReadonly )
+ bSaveAs = true;
+
+ std::vector<OUString> aItemList;
+ const std::vector< OptimizerSettings >& rList( GetOptimizerSettings() );
+ if ( rList.size() > 1 ) // the first session in the list is the actual one -> skipping first one
+ {
+ for ( std::vector<OptimizerSettings>::size_type w = 1; w < rList.size(); w++ )
+ aItemList.push_back(rList[ w ].maName);
+ }
+
+ // now check if it is sensible to enable the combo box
+ bool bSaveSettingsEnabled = true;
+ if ( rList.size() > 1 ) // the first session in the list is the actual one -> skipping first one
+ {
+ for ( std::vector<OptimizerSettings>::size_type w = 1; w < rList.size(); w++ )
+ {
+ if ( rList[ w ] == rList[ 0 ] )
+ {
+ bSaveSettingsEnabled = false;
+ break;
+ }
+ }
+ }
+
+ std::vector< OUString > aSummaryStrings;
+
+ // taking care of deleted slides
+ sal_Int32 nDeletedSlides = 0;
+ OUString sTKCustomShowName(mpPage1->Get_TK_CustomShowName());
+ if (!sTKCustomShowName.isEmpty())
+ SetConfigProperty(TK_CustomShowName, Any(sTKCustomShowName));
+ if ( GetConfigProperty( TK_DeleteHiddenSlides, false ) )
+ {
+ Reference< XDrawPagesSupplier > xDrawPagesSupplier( mxController->getModel(), 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( "Visible" ) >>= bVisible )
+ {
+ if (!bVisible )
+ nDeletedSlides++;
+ }
+ }
+ }
+ if ( GetConfigProperty( TK_DeleteUnusedMasterPages, false ) )
+ {
+ std::vector< PageCollector::MasterPageEntity > aMasterPageList;
+ PageCollector::CollectMasterPages( mxController->getModel(), aMasterPageList );
+ Reference< XMasterPagesSupplier > xMasterPagesSupplier( mxController->getModel(), UNO_QUERY_THROW );
+ Reference< XDrawPages > xMasterPages( xMasterPagesSupplier->getMasterPages(), UNO_SET_THROW );
+ nDeletedSlides += std::count_if(aMasterPageList.begin(), aMasterPageList.end(),
+ [](const PageCollector::MasterPageEntity& rEntity) { return !rEntity.bUsed; });
+ }
+ if ( nDeletedSlides > 1 )
+ {
+ OUString aStr( getString( STR_DELETE_SLIDES ) );
+ OUString aPlaceholder( "%SLIDES" );
+ sal_Int32 i = aStr.indexOf( aPlaceholder );
+ if ( i >= 0 )
+ aStr = aStr.replaceAt( i, aPlaceholder.getLength(), OUString::number( nDeletedSlides ) );
+ aSummaryStrings.push_back( aStr );
+ }
+
+// generating graphic compression info
+ sal_Int32 nGraphics = 0;
+ bool bJPEGCompression( GetConfigProperty( TK_JPEGCompression, false ) );
+ sal_Int32 nJPEGQuality( GetConfigProperty( TK_JPEGQuality, sal_Int32(90) ) );
+ sal_Int32 nImageResolution( GetConfigProperty( TK_ImageResolution, sal_Int32(0) ) );
+ GraphicSettings aGraphicSettings( bJPEGCompression, nJPEGQuality, GetConfigProperty( TK_RemoveCropArea, false ),
+ nImageResolution, GetConfigProperty( TK_EmbedLinkedGraphics, true ) );
+ GraphicCollector::CountGraphics( mxContext, mxController->getModel(), aGraphicSettings, nGraphics );
+ if ( nGraphics > 1 )
+ {
+ OUString aStr( getString( STR_OPTIMIZE_IMAGES ) );
+ OUString aImagePlaceholder( "%IMAGES" );
+ OUString aQualityPlaceholder( "%QUALITY" );
+ OUString aResolutionPlaceholder( "%RESOLUTION" );
+ sal_Int32 i = aStr.indexOf( aImagePlaceholder );
+ if ( i >= 0 )
+ aStr = aStr.replaceAt( i, aImagePlaceholder.getLength(), OUString::number( nGraphics ) );
+
+ sal_Int32 j = aStr.indexOf( aQualityPlaceholder );
+ if ( j >= 0 )
+ aStr = aStr.replaceAt( j, aQualityPlaceholder.getLength(), OUString::number( nJPEGQuality ) );
+
+ sal_Int32 k = aStr.indexOf( aResolutionPlaceholder );
+ if ( k >= 0 )
+ aStr = aStr.replaceAt( k, aResolutionPlaceholder.getLength(), OUString::number( nImageResolution ) );
+
+ aSummaryStrings.push_back( aStr );
+ }
+
+ if ( GetConfigProperty( TK_OLEOptimization, false ) )
+ {
+ sal_Int32 nOLEReplacements = 0;
+ Reference< XDrawPagesSupplier > xDrawPagesSupplier( mxController->getModel(), 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" )
+ nOLEReplacements++;
+ }
+ }
+ if ( nOLEReplacements > 1 )
+ {
+ OUString aStr( getString( STR_CREATE_REPLACEMENT ) );
+ OUString aPlaceholder( "%OLE" );
+ sal_Int32 i = aStr.indexOf( aPlaceholder );
+ if ( i >= 0 )
+ aStr = aStr.replaceAt( i, aPlaceholder.getLength(), OUString::number( nOLEReplacements ) );
+ aSummaryStrings.push_back( aStr );
+ }
+ }
+ while( aSummaryStrings.size() < 3 )
+ aSummaryStrings.emplace_back( );
+
+ sal_Int64 nCurrentFileSize = 0;
+ sal_Int64 nEstimatedFileSize = 0;
+ Reference< XStorable > xStorable( mxController->getModel(), UNO_QUERY );
+ if ( xStorable.is() && xStorable->hasLocation() )
+ nCurrentFileSize = PPPOptimizer::GetFileSize( xStorable->getLocation() );
+
+ if ( nCurrentFileSize )
+ {
+ double fE = static_cast< double >( nCurrentFileSize );
+ if ( nImageResolution )
+ {
+ double v = ( static_cast< double >( nImageResolution ) + 75.0 ) / 300.0;
+ if ( v < 1.0 )
+ fE *= v;
+ }
+ if ( bJPEGCompression )
+ {
+ double v = 0.75 - ( ( 100.0 - static_cast< double >( nJPEGQuality ) ) / 400.0 ) ;
+ fE *= v;
+ }
+ nEstimatedFileSize = static_cast< sal_Int64 >( fE );
+ }
+ sal_Unicode nSeparator = '.';
+ OUString aStr( getString( STR_FILESIZESEPARATOR ) );
+ if ( !aStr.isEmpty() )
+ nSeparator = aStr[ 0 ];
+ mpPage4->UpdateControlStates(bSaveAs, bSaveSettingsEnabled, aItemList,
+ aSummaryStrings,
+ ImpValueOfInMB(nCurrentFileSize, nSeparator),
+ ImpValueOfInMB(nEstimatedFileSize, nSeparator));
+ SetConfigProperty( TK_EstimatedFileSize, Any( nEstimatedFileSize ) );
+}
+
+void OptimizerDialog::InitPage4()
+{
+ // creating a default session name that hasn't been used yet
+ OUString aSettingsName;
+ OUString aDefault( getString( STR_MY_SETTINGS ) );
+ sal_Int32 nSession = 1;
+ std::vector<OptimizerSettings>::size_type i;
+ const std::vector< OptimizerSettings >& rList( GetOptimizerSettings() );
+ do
+ {
+ OUString aTemp = aDefault + OUString::number( nSession++ );
+ for ( i = 1; i < rList.size(); i++ )
+ {
+ if ( rList[ i ].maName == aTemp )
+ break;
+ }
+ if ( i == rList.size() )
+ aSettingsName = aTemp;
+ }
+ while( aSettingsName.isEmpty() );
+
+ mpPage4->Init(aSettingsName, mbIsReadonly);
+
+ UpdateControlStatesPage4();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/minimizer/pagecollector.cxx b/sdext/source/minimizer/pagecollector.cxx
new file mode 100644
index 0000000000..f42c7d271a
--- /dev/null
+++ b/sdext/source/minimizer/pagecollector.cxx
@@ -0,0 +1,136 @@
+/* -*- 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 "pagecollector.hxx"
+#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
+#include <com/sun/star/drawing/XMasterPagesSupplier.hpp>
+#include <com/sun/star/drawing/XMasterPageTarget.hpp>
+#include <com/sun/star/presentation/XCustomPresentationSupplier.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::presentation;
+
+void PageCollector::CollectCustomShowPages( const css::uno::Reference< css::frame::XModel >& rxModel, std::u16string_view rCustomShowName, std::vector< Reference< XDrawPage > >& rUsedPageList )
+{
+ try
+ {
+ Reference< XCustomPresentationSupplier > aXCPSup( rxModel, UNO_QUERY_THROW );
+ Reference< XNameContainer > aXCont( aXCPSup->getCustomPresentations() );
+ if ( aXCont.is() )
+ {
+ // creating a list of every page that is used within our customshow
+ const Sequence< OUString> aNameSeq( aXCont->getElementNames() );
+ for ( OUString const & i :aNameSeq )
+ {
+ if ( i == rCustomShowName )
+ {
+ Reference< container::XIndexContainer > aXIC( aXCont->getByName( i ), UNO_QUERY_THROW );
+ sal_Int32 j, nSlideCount = aXIC->getCount();
+ for ( j = 0; j < nSlideCount; j++ )
+ {
+ Reference< XDrawPage > xDrawPage( aXIC->getByIndex( j ), UNO_QUERY_THROW );
+ auto aIter = std::find(rUsedPageList.begin(), rUsedPageList.end(), xDrawPage);
+ if ( aIter == rUsedPageList.end() )
+ rUsedPageList.push_back( xDrawPage );
+ }
+ }
+ }
+ }
+ }
+ catch( Exception& )
+ {
+
+ }
+}
+
+void PageCollector::CollectNonCustomShowPages( const css::uno::Reference< css::frame::XModel >& rxModel, std::u16string_view rCustomShowName, std::vector< Reference< XDrawPage > >& rNonUsedPageList )
+{
+ try
+ {
+ std::vector< Reference< XDrawPage > > vUsedPageList;
+ PageCollector::CollectCustomShowPages( rxModel, rCustomShowName, vUsedPageList );
+ if ( !vUsedPageList.empty() )
+ {
+ Reference< XDrawPagesSupplier > xDrawPagesSupplier( rxModel, UNO_QUERY_THROW );
+ Reference< XDrawPages > xDrawPages( xDrawPagesSupplier->getDrawPages(), UNO_SET_THROW );
+ for ( sal_Int32 j = 0; j < xDrawPages->getCount(); j++ )
+ {
+ Reference< XDrawPage > xDrawPage( xDrawPages->getByIndex( j ), UNO_QUERY_THROW );
+ auto aIter = std::find(vUsedPageList.begin(), vUsedPageList.end(), xDrawPage);
+ if ( aIter == vUsedPageList.end() )
+ rNonUsedPageList.push_back( xDrawPage );
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+
+void PageCollector::CollectMasterPages( const Reference< XModel >& rxModel, std::vector< PageCollector::MasterPageEntity >& rMasterPageList )
+{
+ try
+ {
+ // generating list of all master pages
+ Reference< XMasterPagesSupplier > xMasterPagesSupplier( rxModel, UNO_QUERY_THROW );
+ Reference< XDrawPages > xMasterPages( xMasterPagesSupplier->getMasterPages(), UNO_SET_THROW );
+ for ( sal_Int32 i = 0; i < xMasterPages->getCount(); i++ )
+ {
+ Reference< XDrawPage > xMasterPage( xMasterPages->getByIndex( i ), UNO_QUERY_THROW );
+ auto aIter = std::find_if(rMasterPageList.begin(), rMasterPageList.end(),
+ [&xMasterPage](const MasterPageEntity& rEntity) { return rEntity.xMasterPage == xMasterPage; });
+ if ( aIter == rMasterPageList.end() )
+ {
+ MasterPageEntity aMasterPageEntity;
+ aMasterPageEntity.xMasterPage = xMasterPage;
+ aMasterPageEntity.bUsed = false;
+ rMasterPageList.push_back( aMasterPageEntity );
+ }
+ }
+
+ // mark masterpages which are referenced by drawpages
+ Reference< XDrawPagesSupplier > xDrawPagesSupplier( rxModel, UNO_QUERY_THROW );
+ Reference< XDrawPages > xDrawPages( xDrawPagesSupplier->getDrawPages(), UNO_SET_THROW );
+ for ( sal_Int32 j = 0; j < xDrawPages->getCount(); j++ )
+ {
+ Reference< XMasterPageTarget > xMasterPageTarget( xDrawPages->getByIndex( j ), UNO_QUERY_THROW );
+ Reference< XDrawPage > xMasterPage( xMasterPageTarget->getMasterPage(), UNO_SET_THROW );
+ auto aIter = std::find_if(rMasterPageList.begin(), rMasterPageList.end(),
+ [&xMasterPage](const MasterPageEntity& rEntity) { return rEntity.xMasterPage == xMasterPage; });
+ if ( aIter == rMasterPageList.end() )
+ throw uno::RuntimeException();
+ aIter->bUsed = true;
+ }
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/minimizer/pagecollector.hxx b/sdext/source/minimizer/pagecollector.hxx
new file mode 100644
index 0000000000..d2cc48d9ed
--- /dev/null
+++ b/sdext/source/minimizer/pagecollector.hxx
@@ -0,0 +1,43 @@
+/* -*- 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 .
+ */
+
+#ifndef INCLUDED_SDEXT_SOURCE_MINIMIZER_PAGECOLLECTOR_HXX
+#define INCLUDED_SDEXT_SOURCE_MINIMIZER_PAGECOLLECTOR_HXX
+
+#include <com/sun/star/drawing/XDrawPage.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <vector>
+
+class PageCollector
+{
+ public:
+
+ struct MasterPageEntity
+ {
+ css::uno::Reference< css::drawing::XDrawPage > xMasterPage;
+ bool bUsed;
+ };
+ static void CollectCustomShowPages( const css::uno::Reference< css::frame::XModel >&, std::u16string_view rCustomShow, std::vector< css::uno::Reference< css::drawing::XDrawPage > >& );
+ static void CollectNonCustomShowPages( const css::uno::Reference< css::frame::XModel >&, std::u16string_view rCustomShow, std::vector< css::uno::Reference< css::drawing::XDrawPage > >& );
+ static void CollectMasterPages( const css::uno::Reference< css::frame::XModel >&, std::vector< MasterPageEntity >& );
+};
+
+#endif // INCLUDED_SDEXT_SOURCE_MINIMIZER_PAGECOLLECTOR_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/minimizer/pppoptimizer.cxx b/sdext/source/minimizer/pppoptimizer.cxx
new file mode 100644
index 0000000000..c869f72187
--- /dev/null
+++ b/sdext/source/minimizer/pppoptimizer.cxx
@@ -0,0 +1,39 @@
+/* -*- 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 "pppoptimizer.hxx"
+#include <osl/file.hxx>
+
+// returning filesize, on error zero is returned
+sal_Int64 PPPOptimizer::GetFileSize(const OUString& rURL)
+{
+ sal_Int64 nFileSize = 0;
+ osl::DirectoryItem aItem;
+ if (osl::DirectoryItem::get(rURL, aItem) == osl::FileBase::E_None)
+ {
+ osl::FileStatus aStatus(osl_FileStatus_Mask_FileSize);
+ if (aItem.getFileStatus(aStatus) == osl::FileBase::E_None)
+ {
+ nFileSize = aStatus.getFileSize();
+ }
+ }
+ return nFileSize;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/minimizer/pppoptimizer.hxx b/sdext/source/minimizer/pppoptimizer.hxx
new file mode 100644
index 0000000000..60b191a7bd
--- /dev/null
+++ b/sdext/source/minimizer/pppoptimizer.hxx
@@ -0,0 +1,32 @@
+/* -*- 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 .
+ */
+
+#ifndef INCLUDED_SDEXT_SOURCE_MINIMIZER_PPPOPTIMIZER_HXX
+#define INCLUDED_SDEXT_SOURCE_MINIMIZER_PPPOPTIMIZER_HXX
+
+#include <rtl/ustring.hxx>
+
+struct PPPOptimizer
+{
+ static sal_Int64 GetFileSize(const OUString& rURL);
+};
+
+#endif // INCLUDED_SDEXT_SOURCE_MINIMIZER_PPPOPTIMIZER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/minimizer/pppoptimizerdialog.cxx b/sdext/source/minimizer/pppoptimizerdialog.cxx
new file mode 100644
index 0000000000..74a89bfbac
--- /dev/null
+++ b/sdext/source/minimizer/pppoptimizerdialog.cxx
@@ -0,0 +1,153 @@
+/* -*- 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 "pppoptimizerdialog.hxx"
+#include "optimizerdialog.hxx"
+#include <sal/log.hxx>
+#include <cppuhelper/supportsservice.hxx>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::beans;
+
+PPPOptimizerDialog::PPPOptimizerDialog( const Reference< XComponentContext > &xContext ) :
+ mxContext( xContext ),
+ mpOptimizerDialog( nullptr )
+{
+}
+
+PPPOptimizerDialog::~PPPOptimizerDialog()
+{
+}
+
+void SAL_CALL PPPOptimizerDialog::initialize( const Sequence< Any >& aArguments )
+{
+ if( aArguments.getLength() != 1 )
+ throw IllegalArgumentException();
+
+ aArguments[ 0 ] >>= mxFrame;
+ if ( mxFrame.is() )
+ mxController = mxFrame->getController();
+}
+
+OUString SAL_CALL PPPOptimizerDialog::getImplementationName()
+{
+ return "com.sun.star.comp.PresentationMinimizerImp";
+}
+
+sal_Bool SAL_CALL PPPOptimizerDialog::supportsService( const OUString& ServiceName )
+{
+ return cppu::supportsService(this, ServiceName);
+}
+
+Sequence< OUString > SAL_CALL PPPOptimizerDialog::getSupportedServiceNames()
+{
+ return { "com.sun.star.comp.PresentationMinimizer" };
+}
+
+Reference< css::frame::XDispatch > SAL_CALL PPPOptimizerDialog::queryDispatch(
+ const URL& aURL, const OUString& /* aTargetFrameName */, sal_Int32 /* nSearchFlags */ )
+{
+ Reference < XDispatch > xRet;
+ if ( aURL.Protocol.equalsIgnoreAsciiCase( "vnd.com.sun.star.comp.PresentationMinimizer:" ) )
+ xRet = this;
+
+ return xRet;
+}
+
+Sequence< Reference< css::frame::XDispatch > > SAL_CALL PPPOptimizerDialog::queryDispatches(
+ const Sequence< css::frame::DispatchDescriptor >& aDescripts )
+{
+ Sequence< Reference< css::frame::XDispatch> > aReturn( aDescripts.getLength() );
+ std::transform(aDescripts.begin(), aDescripts.end(), aReturn.getArray(),
+ [this](const css::frame::DispatchDescriptor& rDescr) -> Reference<css::frame::XDispatch> {
+ return queryDispatch(rDescr.FeatureURL, rDescr.FrameName, rDescr.SearchFlags); });
+ return aReturn;
+}
+
+void SAL_CALL PPPOptimizerDialog::dispatch( const URL& rURL,
+ const Sequence< PropertyValue >& rArguments )
+{
+
+ if ( !(mxController.is() && rURL.Protocol.equalsIgnoreAsciiCase( "vnd.com.sun.star.comp.PresentationMinimizer:" )) )
+ return;
+
+ if ( rURL.Path == "execute" )
+ {
+ try
+ {
+ sal_Int64 nFileSizeSource = 0;
+ sal_Int64 nFileSizeDest = 0;
+ mpOptimizerDialog = new OptimizerDialog( mxContext, mxFrame, this );
+ mpOptimizerDialog->execute();
+
+ const Any* pVal( mpOptimizerDialog->maStats.GetStatusValue( TK_FileSizeSource ) );
+ if ( pVal )
+ *pVal >>= nFileSizeSource;
+ pVal = mpOptimizerDialog->maStats.GetStatusValue( TK_FileSizeDestination );
+ if ( pVal )
+ *pVal >>= nFileSizeDest;
+
+ if ( nFileSizeSource && nFileSizeDest )
+ {
+ OUString sResult = "Your Presentation has been minimized from:" +
+ OUString::number( nFileSizeSource >> 10 ) +
+ "KB to " +
+ OUString::number( nFileSizeDest >> 10 ) +
+ "KB.";
+ SAL_INFO("sdext.minimizer", sResult );
+ }
+ }
+ catch( ... )
+ {
+ }
+ delete mpOptimizerDialog;
+ mpOptimizerDialog = nullptr;
+ }
+ else if ( rURL.Path == "statusupdate" )
+ {
+ if ( mpOptimizerDialog )
+ mpOptimizerDialog->UpdateStatus( rArguments );
+ }
+}
+
+void SAL_CALL PPPOptimizerDialog::addStatusListener( const Reference< XStatusListener >&, const URL& )
+{
+ // TODO
+ // OSL_FAIL( "PPPOptimizerDialog::addStatusListener()\nNot implemented yet!" );
+}
+
+void SAL_CALL PPPOptimizerDialog::removeStatusListener( const Reference< XStatusListener >&, const URL& )
+{
+ // TODO
+ // OSL_FAIL( "PPPOptimizerDialog::removeStatusListener()\nNot implemented yet!" );
+}
+
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+sdext_PPPOptimizerDialog_get_implementation(
+ css::uno::XComponentContext* context , css::uno::Sequence<css::uno::Any> const&)
+{
+ return cppu::acquire(new PPPOptimizerDialog(context));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/minimizer/pppoptimizerdialog.hxx b/sdext/source/minimizer/pppoptimizerdialog.hxx
new file mode 100644
index 0000000000..1d1042f64e
--- /dev/null
+++ b/sdext/source/minimizer/pppoptimizerdialog.hxx
@@ -0,0 +1,81 @@
+/* -*- 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 .
+ */
+
+#ifndef INCLUDED_SDEXT_SOURCE_MINIMIZER_PPPOPTIMIZERDIALOG_HXX
+#define INCLUDED_SDEXT_SOURCE_MINIMIZER_PPPOPTIMIZERDIALOG_HXX
+
+#include <com/sun/star/uno/Sequence.h>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/frame/XDispatch.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <cppuhelper/implbase.hxx>
+
+
+class OptimizerDialog;
+class PPPOptimizerDialog : public ::cppu::WeakImplHelper<
+ css::lang::XInitialization,
+ css::lang::XServiceInfo,
+ css::frame::XDispatchProvider,
+ css::frame::XDispatch >
+{
+ css::uno::Reference< css::uno::XComponentContext > mxContext;
+ css::uno::Reference< css::frame::XFrame > mxFrame;
+ css::uno::Reference< css::frame::XController > mxController;
+
+ OptimizerDialog* mpOptimizerDialog;
+
+public:
+
+ explicit PPPOptimizerDialog( const css::uno::Reference< css::uno::XComponentContext >& xContext );
+ virtual ~PPPOptimizerDialog() override;
+
+ // XInitialization
+ void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) override;
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override;
+
+ virtual sal_Bool SAL_CALL supportsService( const OUString& sServiceName ) override;
+
+ virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
+
+ // XDispatchProvider
+ virtual css::uno::Reference< css::frame::XDispatch > SAL_CALL queryDispatch(
+ const css::util::URL& aURL, const OUString& aTargetFrameName, sal_Int32 nSearchFlags ) override;
+
+ virtual css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL queryDispatches(
+ const css::uno::Sequence< css::frame::DispatchDescriptor >& aDescripts ) override;
+
+ // XDispatch
+ virtual void SAL_CALL dispatch( const css::util::URL& aURL,
+ const css::uno::Sequence< css::beans::PropertyValue >& lArguments ) override;
+
+ virtual void SAL_CALL addStatusListener( const css::uno::Reference< css::frame::XStatusListener >& xListener,
+ const css::util::URL& aURL ) override;
+ virtual void SAL_CALL removeStatusListener( const css::uno::Reference< css::frame::XStatusListener >& xListener,
+ const css::util::URL& aURL ) override;
+};
+
+#endif // INCLUDED_SDEXT_SOURCE_MINIMIZER_PPPOPTIMIZERDIALOG_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/minimizer/pppoptimizertoken.cxx b/sdext/source/minimizer/pppoptimizertoken.cxx
new file mode 100644
index 0000000000..472992551b
--- /dev/null
+++ b/sdext/source/minimizer/pppoptimizertoken.cxx
@@ -0,0 +1,145 @@
+/* -*- 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 "pppoptimizertoken.hxx"
+
+#include <sal/macros.h>
+#include <unordered_map>
+#include <memory>
+#include <mutex>
+
+typedef std::unordered_map< const char*, PPPOptimizerTokenEnum, rtl::CStringHash, rtl::CStringEqual> TypeNameHashMap;
+static TypeNameHashMap* pHashMap = nullptr;
+static std::mutex& getHashMapMutex()
+{
+ static std::mutex s_aHashMapProtection;
+ return s_aHashMapProtection;
+}
+
+namespace {
+
+struct TokenTable
+{
+ const char* pS;
+ PPPOptimizerTokenEnum pE;
+};
+
+}
+
+const TokenTable pTokenTableArray[] =
+{
+ { "btnNavFinish", TK_btnNavFinish },
+
+ { "DocumentService", TK_DocumentService },
+ { "FileSizeDestination",TK_FileSizeDestination },
+ { "FileSizeSource", TK_FileSizeSource },
+ { "FilterName", TK_FilterName },
+ { "Flags", TK_Flags },
+ { "DocumentFrame", TK_DocumentFrame },
+ { "DialogParentWindow", TK_DialogParentWindow },
+ { "Name", TK_Name },
+ { "Progress", TK_Progress },
+ { "Settings", TK_Settings },
+ { "StatusDispatcher", TK_StatusDispatcher },
+ { "Type", TK_Type },
+ { "UIName", TK_UIName },
+
+ { "JPEGCompression", TK_JPEGCompression },
+ { "JPEGQuality", TK_JPEGQuality },
+ { "RemoveCropArea", TK_RemoveCropArea },
+ { "ImageResolution", TK_ImageResolution },
+ { "EmbedLinkedGraphics",TK_EmbedLinkedGraphics },
+ { "OLEOptimization", TK_OLEOptimization },
+ { "OLEOptimizationType",TK_OLEOptimizationType },
+ { "DeleteUnusedMasterPages", TK_DeleteUnusedMasterPages },
+ { "DeleteHiddenSlides", TK_DeleteHiddenSlides },
+ { "DeleteNotesPages", TK_DeleteNotesPages },
+ { "CustomShowName", TK_CustomShowName },
+ { "SaveAs", TK_SaveAs },
+ { "SaveAsURL", TK_SaveAsURL },
+ { "OpenNewDocument", TK_OpenNewDocument },
+ { "EstimatedFileSize", TK_EstimatedFileSize },
+
+ { "Status", TK_Status },
+ { "Pages", TK_Pages },
+
+ { "STR_SUN_OPTIMIZATION_WIZARD2",STR_SUN_OPTIMIZATION_WIZARD2 },
+ { "STR_INTRODUCTION", STR_INTRODUCTION },
+ { "STR_IMAGE_OPTIMIZATION", STR_IMAGE_OPTIMIZATION },
+ { "STR_OLE_OBJECTS", STR_OLE_OBJECTS },
+ { "STR_OLE_OBJECTS_DESC", STR_OLE_OBJECTS_DESC },
+ { "STR_NO_OLE_OBJECTS_DESC", STR_NO_OLE_OBJECTS_DESC },
+ { "STR_SLIDES", STR_SLIDES },
+ { "STR_SUMMARY", STR_SUMMARY },
+ { "STR_DELETE_SLIDES", STR_DELETE_SLIDES },
+ { "STR_OPTIMIZE_IMAGES", STR_OPTIMIZE_IMAGES },
+ { "STR_CREATE_REPLACEMENT", STR_CREATE_REPLACEMENT },
+ { "MY_SETTINGS", STR_MY_SETTINGS },
+ { "STR_OK", STR_OK },
+ { "STR_INFO_PRIMARY", STR_INFO_PRIMARY },
+ { "STR_INFO_SECONDARY_1", STR_INFO_SECONDARY_1 },
+ { "STR_INFO_SECONDARY_2", STR_INFO_SECONDARY_2 },
+ { "STR_INFO_SECONDARY_3", STR_INFO_SECONDARY_3 },
+ { "STR_INFO_SECONDARY_4", STR_INFO_SECONDARY_4 },
+ { "STR_DUPLICATING_PRESENTATION",STR_DUPLICATING_PRESENTATION },
+ { "STR_DELETING_SLIDES", STR_DELETING_SLIDES },
+ { "STR_OPTIMIZING_GRAPHICS", STR_OPTIMIZING_GRAPHICS },
+ { "STR_CREATING_OLE_REPLACEMENTS",STR_CREATING_OLE_REPLACEMENTS },
+ { "STR_FileSizeSeparator", STR_FILESIZESEPARATOR },
+ { "STR_FILENAME_SUFFIX", STR_FILENAME_SUFFIX },
+ { "STR_WARN_UNSAVED_PRESENTATION", STR_WARN_UNSAVED_PRESENTATION },
+
+
+ { "NotFound", TK_NotFound }
+};
+
+PPPOptimizerTokenEnum TKGet( std::u16string_view rToken )
+{
+ if ( !pHashMap )
+ { // init hash map
+ std::scoped_lock aGuard( getHashMapMutex() );
+ if ( !pHashMap )
+ {
+ TypeNameHashMap* pH = new TypeNameHashMap;
+ const TokenTable* pPtr = pTokenTableArray;
+ const TokenTable* pEnd = pPtr + SAL_N_ELEMENTS( pTokenTableArray );
+ for ( ; pPtr < pEnd; pPtr++ )
+ (*pH)[ pPtr->pS ] = pPtr->pE;
+ pHashMap = pH;
+ }
+ }
+ PPPOptimizerTokenEnum eRetValue = TK_NotFound;
+ size_t i, nLen = rToken.size();
+ std::unique_ptr<char[]> pBuf(new char[ nLen + 1 ]);
+ for ( i = 0; i < nLen; i++ )
+ pBuf[ i ] = static_cast<char>(rToken[ i ]);
+ pBuf[ i ] = 0;
+ TypeNameHashMap::iterator aHashIter( pHashMap->find( pBuf.get() ) );
+ if ( aHashIter != pHashMap->end() )
+ eRetValue = (*aHashIter).second;
+ return eRetValue;
+}
+
+OUString TKGet( const PPPOptimizerTokenEnum eToken )
+{
+ return OUString::createFromAscii( pTokenTableArray[ eToken ].pS );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sdext/source/minimizer/pppoptimizertoken.hxx b/sdext/source/minimizer/pppoptimizertoken.hxx
new file mode 100644
index 0000000000..f665e82ece
--- /dev/null
+++ b/sdext/source/minimizer/pppoptimizertoken.hxx
@@ -0,0 +1,95 @@
+/* -*- 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 .
+ */
+
+#ifndef INCLUDED_SDEXT_SOURCE_MINIMIZER_PPPOPTIMIZERTOKEN_HXX
+#define INCLUDED_SDEXT_SOURCE_MINIMIZER_PPPOPTIMIZERTOKEN_HXX
+
+#include <rtl/ustring.hxx>
+
+enum PPPOptimizerTokenEnum
+{
+ TK_btnNavFinish,
+
+ TK_DocumentService,
+ TK_FileSizeDestination,
+ TK_FileSizeSource,
+ TK_FilterName,
+ TK_Flags,
+ TK_DocumentFrame,
+ TK_DialogParentWindow,
+ TK_Name,
+ TK_Progress,
+ TK_Settings,
+ TK_StatusDispatcher,
+ TK_Type,
+ TK_UIName,
+
+ TK_JPEGCompression,
+ TK_JPEGQuality,
+ TK_RemoveCropArea,
+ TK_ImageResolution,
+ TK_EmbedLinkedGraphics,
+ TK_OLEOptimization,
+ TK_OLEOptimizationType,
+ TK_DeleteUnusedMasterPages,
+ TK_DeleteHiddenSlides,
+ TK_DeleteNotesPages,
+ TK_CustomShowName,
+ TK_SaveAs,
+ TK_SaveAsURL,
+ TK_OpenNewDocument,
+ TK_EstimatedFileSize,
+
+ TK_Status,
+ TK_Pages,
+
+ STR_SUN_OPTIMIZATION_WIZARD2,
+ STR_INTRODUCTION,
+ STR_IMAGE_OPTIMIZATION,
+ STR_OLE_OBJECTS,
+ STR_OLE_OBJECTS_DESC,
+ STR_NO_OLE_OBJECTS_DESC,
+ STR_SLIDES,
+ STR_SUMMARY,
+ STR_DELETE_SLIDES,
+ STR_OPTIMIZE_IMAGES,
+ STR_CREATE_REPLACEMENT,
+ STR_MY_SETTINGS,
+ STR_OK,
+ STR_INFO_PRIMARY,
+ STR_INFO_SECONDARY_1,
+ STR_INFO_SECONDARY_2,
+ STR_INFO_SECONDARY_3,
+ STR_INFO_SECONDARY_4,
+ STR_DUPLICATING_PRESENTATION,
+ STR_DELETING_SLIDES,
+ STR_OPTIMIZING_GRAPHICS,
+ STR_CREATING_OLE_REPLACEMENTS,
+ STR_FILESIZESEPARATOR,
+ STR_FILENAME_SUFFIX,
+ STR_WARN_UNSAVED_PRESENTATION,
+ TK_NotFound
+};
+
+PPPOptimizerTokenEnum TKGet(std::u16string_view);
+OUString TKGet(const PPPOptimizerTokenEnum);
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */