diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
commit | ed5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch) | |
tree | 7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /sdext/source/minimizer | |
parent | Initial commit. (diff) | |
download | libreoffice-upstream.tar.xz libreoffice-upstream.zip |
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sdext/source/minimizer')
26 files changed, 5819 insertions, 0 deletions
diff --git a/sdext/source/minimizer/configurationaccess.cxx b/sdext/source/minimizer/configurationaccess.cxx new file mode 100644 index 000000000..3479918c2 --- /dev/null +++ b/sdext/source/minimizer/configurationaccess.cxx @@ -0,0 +1,458 @@ +/* -*- 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 <tools/diagnose_ex.h> + +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 ); +// && ( rOptimizerSettings.mbOpenNewDocument == mbOpenNewDocument ); +} + + +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 000000000..d4d4c4d3f --- /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 ); + + private: + + std::map < PPPOptimizerTokenEnum, OUString > maStrings; + + std::vector< OptimizerSettings > maSettings; + + css::uno::Reference< css::uno::XComponentContext > mxContext; + + 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 000000000..ef0dbf4b4 --- /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 000000000..176fe155e --- /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 000000000..c307b04b0 --- /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 000000000..f989a95ad --- /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 000000000..7de159177 --- /dev/null +++ b/sdext/source/minimizer/impoptimizer.cxx @@ -0,0 +1,702 @@ +/* -*- 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/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 ::std; +using namespace ::com::sun::star; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::drawing; +using namespace ::com::sun::star::graphic; +using namespace ::com::sun::star::document; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::presentation; + +static void ImpExtractCustomShow( const Reference< XModel >& rxModel, std::u16string_view rCustomShowName ) +{ + 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 ) +{ + 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< 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< 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_InformationDialog: rArgument.Value >>= mxInformationDialog; 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 : mxInformationDialog ); + if ( xFrame.is() ) + { + DispatchURL(mxContext, ".uno:ClearUndoStack", xFrame); + } + } + + if ( !maSaveAsURL.isEmpty() ) + { + if ( xStorable.is() ) + { + xStorable->store(); + nDestSize = PPPOptimizer::GetFileSize( maSaveAsURL ); + } + } + + if ( mxInformationDialog.is() ) + { + InformationDialog aInformationDialog( mxContext, mxInformationDialog, 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 000000000..6a52e9498 --- /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; + + 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; + + css::uno::Reference< css::frame::XFrame > mxInformationDialog; + + 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 000000000..0797e7856 --- /dev/null +++ b/sdext/source/minimizer/informationdialog.cxx @@ -0,0 +1,350 @@ +/* -*- 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> + +#define DIALOG_WIDTH 240 +#define DIALOG_HEIGHT 80 +#define PAGE_POS_X 35 +#define PAGE_WIDTH ( DIALOG_WIDTH - PAGE_POS_X ) - 6 + + +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::frame; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::container; + + +OUString InsertFixedText( UnoDialog& rInformationDialog, const OUString& rControlName, const OUString& rLabel, + sal_Int32 nXPos, sal_Int32 nYPos, sal_Int32 nWidth, sal_Int32 nHeight, bool bMultiLine, sal_Int16 nTabIndex ) +{ + OUString pNames[] = { + OUString("Height"), + OUString("Label"), + OUString("MultiLine"), + OUString("PositionX"), + OUString("PositionY"), + OUString("Step"), + OUString("TabIndex"), + OUString("Width") }; + + Any pValues[] = { + Any( nHeight ), + Any( rLabel ), + Any( bMultiLine ), + Any( nXPos ), + Any( nYPos ), + Any( sal_Int16(0) ), + Any( nTabIndex ), + Any( nWidth ) }; + + sal_Int32 nCount = SAL_N_ELEMENTS( pNames ); + + Sequence< OUString > aNames( pNames, nCount ); + Sequence< Any > aValues( pValues, nCount ); + + rInformationDialog.insertFixedText( rControlName, aNames, aValues ); + return rControlName; +} + +OUString InsertImage( + UnoDialog& rInformationDialog, + const OUString& rControlName, + const OUString& rURL, + sal_Int32 nPosX, + sal_Int32 nPosY, + sal_Int32 nWidth, + sal_Int32 nHeight, + bool bScale ) +{ + OUString pNames[] = { + OUString("Border"), + OUString("Height"), + OUString("ImageURL"), + OUString("PositionX"), + OUString("PositionY"), + OUString("ScaleImage"), + OUString("Width") }; + + Any pValues[] = { + Any( sal_Int16( 0 ) ), + Any( nHeight ), + Any( rURL ), + Any( nPosX ), + Any( nPosY ), + Any( bScale ), + Any( nWidth ) }; + sal_Int32 nCount = SAL_N_ELEMENTS( pNames ); + + Sequence< OUString > aNames( pNames, nCount ); + Sequence< Any > aValues( pValues, nCount ); + + rInformationDialog.insertImage( rControlName, aNames, aValues ); + return rControlName; +} + +OUString InsertCheckBox( UnoDialog& rInformationDialog, const OUString& rControlName, + const Reference< XItemListener >& rItemListener, const OUString& rLabel, + sal_Int32 nXPos, sal_Int32 nYPos, sal_Int32 nWidth, sal_Int16 nTabIndex ) +{ + sal_Int32 nHeight = 8; + OUString pNames[] = { + OUString("Enabled"), + OUString("Height"), + OUString("Label"), + OUString("PositionX"), + OUString("PositionY"), + OUString("Step"), + OUString("TabIndex"), + OUString("Width") }; + + Any pValues[] = { + Any( true ), + Any( nHeight ), + Any( rLabel ), + Any( nXPos ), + Any( nYPos ), + Any( sal_Int16(0) ), + Any( nTabIndex ), + Any( nWidth ) }; + + sal_Int32 nCount = SAL_N_ELEMENTS( pNames ); + + Sequence< OUString > aNames( pNames, nCount ); + Sequence< Any > aValues( pValues, nCount ); + + Reference< XCheckBox > xCheckBox( rInformationDialog.insertCheckBox( rControlName, aNames, aValues ) ); + if ( rItemListener.is() ) + xCheckBox->addItemListener( rItemListener ); + return rControlName; +} + +OUString InsertButton( UnoDialog& rInformationDialog, const OUString& rControlName, Reference< XActionListener > const & xActionListener, + sal_Int32 nXPos, sal_Int32 nYPos, sal_Int32 nWidth, sal_Int16 nTabIndex, const OUString& rText ) +{ + sal_Int32 nHeight = 14; + OUString pNames[] = { + OUString("Enabled"), + OUString("Height"), + OUString("Label"), + OUString("PositionX"), + OUString("PositionY"), + OUString("PushButtonType"), + OUString("Step"), + OUString("TabIndex"), + OUString("Width") }; + + Any pValues[] = { + Any( true ), + Any( nHeight ), + Any( rText ), + Any( nXPos ), + Any( nYPos ), + Any( static_cast< sal_Int16 >( PushButtonType_OK ) ), + Any( sal_Int16(0) ), + Any( nTabIndex ), + Any( nWidth ) }; + + + sal_Int32 nCount = SAL_N_ELEMENTS( pNames ); + + Sequence< OUString > aNames( pNames, nCount ); + Sequence< Any > aValues( pValues, nCount ); + + rInformationDialog.insertButton( rControlName, xActionListener, aNames, aValues ); + return rControlName; +} + + +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() +{ + sal_Int32 nDialogHeight = DIALOG_HEIGHT; + if ( maSaveAsURL.isEmpty() ) + nDialogHeight -= 22; + + // setting the dialog properties + OUString pNames[] = { + OUString("Closeable"), + OUString("Height"), + OUString("Moveable"), + OUString("PositionX"), + OUString("PositionY"), + OUString("Title"), + OUString("Width") }; + + Any pValues[] = { + Any( true ), + Any( nDialogHeight ), + Any( true ), + Any( sal_Int32( 245 ) ), + Any( sal_Int32( 115 ) ), + Any( getString( STR_SUN_OPTIMIZATION_WIZARD2 ) ), + Any( sal_Int32( DIALOG_WIDTH ) ) }; + + sal_Int32 nCount = SAL_N_ELEMENTS( pNames ); + + Sequence< OUString > aNames( pNames, nCount ); + Sequence< Any > aValues( pValues, nCount ); + + setPropertyValues(aNames, aValues); + + sal_Int64 nSource = mnSourceSize; + sal_Int64 nDest = mnDestSize; + + PPPOptimizerTokenEnum eInfoString( STR_INFO_1 ); + if ( mnSourceSize ) + { + if ( mnDestSize ) + eInfoString = STR_INFO_1; + else + { + eInfoString = STR_INFO_2; + nDest = mnApproxSize; + } + } + else if ( mnDestSize ) + eInfoString = STR_INFO_3; + else + { + eInfoString = STR_INFO_4; + nDest = mnApproxSize; + } + + OUString aTitle; + if ( !maSaveAsURL.isEmpty() ) + { + Reference< XURLTransformer > xURLTransformer( URLTransformer::create(UnoDialog::mxContext) ); + util::URL aURL, aPresentationURL; + aURL.Complete = maSaveAsURL; + xURLTransformer->parseSmart( aURL, OUString() ); + + static const OUStringLiteral sFileProtocol( u"file:///" ); + aPresentationURL.Complete = sFileProtocol + aURL.Name; + aTitle = xURLTransformer->getPresentation( aPresentationURL, false ); + + if ( aTitle.match( sFileProtocol ) ) + aTitle = aTitle.replaceAt( 0, sFileProtocol.getLength(), u"" ); + } + + OUString aInfoString( getString( eInfoString ) ); + static const OUStringLiteral aOldSizePlaceholder( u"%OLDFILESIZE" ); + static const OUStringLiteral aNewSizePlaceholder( u"%NEWFILESIZE" ); + const OUString aTitlePlaceholder( !aTitle.isEmpty() ? OUString("%TITLE" ) + : OUString("'%TITLE'") ); + + sal_Int32 i = aInfoString.indexOf( aOldSizePlaceholder ); + if ( i >= 0 ) + aInfoString = aInfoString.replaceAt( i, aOldSizePlaceholder.getLength(), ImpValueOfInMB( nSource ) ); + + sal_Int32 j = aInfoString.indexOf( aNewSizePlaceholder ); + if ( j >= 0 ) + aInfoString = aInfoString.replaceAt( j, aNewSizePlaceholder.getLength(), ImpValueOfInMB( nDest ) ); + + sal_Int32 k = aInfoString.indexOf( aTitlePlaceholder ); + if ( k >= 0 ) + aInfoString = aInfoString.replaceAt( k, aTitlePlaceholder.getLength(), aTitle ); + + css::uno::Reference< css::awt::XItemListener > xItemListener; + InsertImage( *this, + "aboutimage", + "private:standardimage/query", + 5, 5, 25, 25, false ); + InsertFixedText( *this, "fixedtext", aInfoString, PAGE_POS_X, 6, PAGE_WIDTH, 24, true, 0 ); + if ( !maSaveAsURL.isEmpty() ) + InsertCheckBox( *this, "OpenNewDocument", xItemListener, getString( STR_AUTOMATICALLY_OPEN ), PAGE_POS_X, 42, PAGE_WIDTH, 1 ); + InsertButton( *this, "button", mxActionListener, DIALOG_WIDTH / 2 - 25, nDialogHeight - 20, 50, 2, getString( STR_OK ) ); + + bool bOpenNewDocument = mrbOpenNewDocument; + setControlProperty( "OpenNewDocument", "State", Any( static_cast<sal_Int16>(bOpenNewDocument) ) ); +} + + +InformationDialog::InformationDialog( const Reference< XComponentContext > &rxContext, Reference< XFrame > const & rxFrame, const OUString& rSaveAsURL, bool& rbOpenNewDocument, sal_Int64 rSourceSize, sal_Int64 rDestSize, sal_Int64 rApproxSize ) : + UnoDialog( rxContext, rxFrame ), + ConfigurationAccess( rxContext ), + mxActionListener( new OKActionListener( *this ) ), + mnSourceSize( rSourceSize ), + mnDestSize( rDestSize ), + mnApproxSize( rApproxSize ), + mrbOpenNewDocument( rbOpenNewDocument ), + maSaveAsURL( rSaveAsURL ) +{ + InitDialog(); +} + + +InformationDialog::~InformationDialog() +{ +} + + +void InformationDialog::execute() +{ + UnoDialog::execute(); + + if ( !maSaveAsURL.isEmpty() ) + { + sal_Int16 nInt16 = 0; + Any aAny( getControlProperty( "OpenNewDocument", "State" ) ); + if ( aAny >>= nInt16 ) + { + bool bOpenNewDocument = static_cast< bool >( nInt16 ); + mrbOpenNewDocument = bOpenNewDocument; + } + } +} + + +void OKActionListener::actionPerformed( const ActionEvent& rEvent ) +{ + if ( rEvent.ActionCommand == "button" ) + { + mrDialog.endExecute( true ); + } +} +void OKActionListener::disposing( const css::lang::EventObject& /* Source */ ) +{ +} + +/* 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 000000000..761a40e01 --- /dev/null +++ b/sdext/source/minimizer/informationdialog.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_INFORMATIONDIALOG_HXX +#define INCLUDED_SDEXT_SOURCE_MINIMIZER_INFORMATIONDIALOG_HXX + +#include "unodialog.hxx" +#include "configurationaccess.hxx" +#include <com/sun/star/awt/XItemListener.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <cppuhelper/implbase.hxx> + +OUString InsertFixedText( UnoDialog& rInformationDialog, const OUString& rControlName, const OUString& rLabel, + sal_Int32 nXPos, sal_Int32 nYPos, sal_Int32 nWidth, sal_Int32 nHeight, bool bMultiLine, sal_Int16 nTabIndex ); + +OUString InsertImage( UnoDialog& rInformationDialog, const OUString& rControlName, const OUString& rURL, + sal_Int32 nPosX, sal_Int32 nPosY, sal_Int32 nWidth, sal_Int32 nHeight, bool bScale ); + +OUString InsertCheckBox( UnoDialog& rInformationDialog, const OUString& rControlName, + const css::uno::Reference< css::awt::XItemListener >& rItemListener, const OUString& rLabel, + sal_Int32 nXPos, sal_Int32 nYPos, sal_Int32 nWidth, sal_Int16 nTabIndex ); + +OUString InsertButton( UnoDialog& rInformationDialog, const OUString& rControlName, + css::uno::Reference< css::awt::XActionListener > const & xActionListener, sal_Int32 nXPos, sal_Int32 nYPos, + sal_Int32 nWidth, sal_Int16 nTabIndex, const OUString& rText ); + +class InformationDialog : public UnoDialog, public ConfigurationAccess +{ +public: + + InformationDialog( const css::uno::Reference< css::uno::XComponentContext >& rxContext, + css::uno::Reference< css::frame::XFrame > const & rxFrame, const OUString& rSaveAsURL, + bool& bOpenNewDocument, sal_Int64 nSourceSize, sal_Int64 nDestSize, sal_Int64 nApproxDest ); + ~InformationDialog(); + + void execute(); + +private: + + css::uno::Reference< css::awt::XActionListener > mxActionListener; + + void InitDialog(); + + sal_Int64 mnSourceSize; + sal_Int64 mnDestSize; + sal_Int64 mnApproxSize; + bool& mrbOpenNewDocument; + const OUString& maSaveAsURL; +}; + +class OKActionListener : public ::cppu::WeakImplHelper< css::awt::XActionListener > +{ +public: + explicit OKActionListener( UnoDialog& rDialog ) : mrDialog( rDialog ){} + + virtual void SAL_CALL actionPerformed( const css::awt::ActionEvent& Event ) override; + virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override; +private: + + UnoDialog& mrDialog; +}; + +#endif + +/* 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 000000000..63f92cbbd --- /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 000000000..1deef26ac --- /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 000000000..a1af8f30e --- /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 000000000..3112c6f22 --- /dev/null +++ b/sdext/source/minimizer/optimizerdialog.cxx @@ -0,0 +1,780 @@ +/* -*- 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; + + +void OptimizerDialog::InitDialog() +{ + // setting the dialog properties + OUString pNames[] = { + OUString("Closeable"), + OUString("Height"), + OUString("Moveable"), + OUString("PositionX"), + OUString("PositionY"), + OUString("Title"), + OUString("Width") }; + + Any pValues[] = { + Any( true ), + Any( sal_Int32( DIALOG_HEIGHT ) ), + Any( true ), + Any( sal_Int32( 200 ) ), + Any( sal_Int32( 52 ) ), + Any( getString( STR_SUN_OPTIMIZATION_WIZARD2 ) ), + Any( sal_Int32( OD_DIALOG_WIDTH ) ) }; + + sal_Int32 nCount = SAL_N_ELEMENTS( pNames ); + + Sequence< OUString > aNames( pNames, nCount ); + Sequence< Any > aValues( pValues, nCount ); + + setPropertyValues(aNames, aValues); +} + + +void OptimizerDialog::InitRoadmap() +{ + try + { + OUString pNames[] = { + OUString("Height"), + OUString("PositionX"), + OUString("PositionY"), + OUString("Step"), + OUString("TabIndex"), + OUString("Width") }; + + Any pValues[] = { + Any( sal_Int32( DIALOG_HEIGHT - 26 ) ), + Any( sal_Int32( 0 ) ), + Any( sal_Int32( 0 ) ), + Any( sal_Int32( 0 ) ), + Any( mnTabIndex++ ), + Any( sal_Int32( 85 ) ) }; + + sal_Int32 nCount = SAL_N_ELEMENTS( pNames ); + + Sequence< OUString > aNames( pNames, nCount ); + Sequence< Any > aValues( pValues, nCount ); + + mxRoadmapControlModel = insertControlModel( "com.sun.star.awt.UnoControlRoadmapModel", + "rdmNavi", aNames, aValues ); + + Reference< XPropertySet > xPropertySet( mxRoadmapControlModel, UNO_QUERY_THROW ); + xPropertySet->setPropertyValue( "Name", Any( OUString("rdmNavi") ) ); + mxRoadmapControl = getControl( "rdmNavi" ); + InsertRoadmapItem( 0, getString( STR_INTRODUCTION ), ITEM_ID_INTRODUCTION ); + InsertRoadmapItem( 1, getString( STR_SLIDES ), ITEM_ID_SLIDES ); + InsertRoadmapItem( 2, getString( STR_IMAGE_OPTIMIZATION ), ITEM_ID_GRAPHIC_OPTIMIZATION ); + InsertRoadmapItem( 3, getString( STR_OLE_OBJECTS ), ITEM_ID_OLE_OPTIMIZATION ); + InsertRoadmapItem( 4, getString( STR_SUMMARY ), ITEM_ID_SUMMARY ); + + xPropertySet->setPropertyValue( "ImageURL", Any( OUString("private:graphicrepository/" BMP_PRESENTATION_MINIMIZER) ) ); + xPropertySet->setPropertyValue( "Activated", Any( true ) ); + xPropertySet->setPropertyValue( "Complete", Any( true ) ); + xPropertySet->setPropertyValue( "CurrentItemID", Any( sal_Int16(ITEM_ID_INTRODUCTION) ) ); + xPropertySet->setPropertyValue( "Text", Any( getString( STR_STEPS ) ) ); + } + catch( Exception& ) + { + } +} + + +void OptimizerDialog::InsertRoadmapItem( const sal_Int32 nIndex, const OUString& rLabel, const sal_Int32 nItemID ) +{ + try + { + Reference< XSingleServiceFactory > xSFRoadmap( mxRoadmapControlModel, UNO_QUERY_THROW ); + Reference< XIndexContainer > aIndexContainerRoadmap( mxRoadmapControlModel, UNO_QUERY_THROW ); + Reference< XInterface > xRoadmapItem( xSFRoadmap->createInstance(), UNO_SET_THROW ); + Reference< XPropertySet > xPropertySet( xRoadmapItem, UNO_QUERY_THROW ); + xPropertySet->setPropertyValue( "Label", Any( rLabel ) ); + xPropertySet->setPropertyValue( "Enabled", Any( true ) ); + xPropertySet->setPropertyValue( "ID", Any( nItemID ) ); + aIndexContainerRoadmap->insertByIndex( nIndex, Any( xRoadmapItem ) ); + } + catch( Exception& ) + { + + } +} + + +void OptimizerDialog::UpdateConfiguration() +{ + sal_Int16 nInt16 = 0; + Any aAny; + + Sequence< sal_Int16 > aSelectedItems; + Sequence< OUString > aStringItemList; + + // page0 + aAny = getControlProperty( "ListBox0Pg0", "SelectedItems" ); + if ( aAny >>= aSelectedItems ) + { + if ( aSelectedItems.hasElements() ) + { + sal_Int16 nSelectedItem = aSelectedItems[ 0 ]; + aAny = getControlProperty( "ListBox0Pg0", "StringItemList" ); + if ( aAny >>= aStringItemList ) + { + if ( aStringItemList.getLength() > nSelectedItem ) + SetConfigProperty( TK_Name, Any( aStringItemList[ nSelectedItem ] ) ); + } + } + } + + aAny = getControlProperty( "CheckBox3Pg3", "State" ); + if ( !((aAny >>= nInt16) && nInt16) ) + return; + + aAny = getControlProperty( "ListBox0Pg3", "SelectedItems" ); + if ( !(aAny >>= aSelectedItems) ) + return; + + if ( aSelectedItems.hasElements() ) + { + sal_Int16 nSelectedItem = aSelectedItems[ 0 ]; + aAny = getControlProperty( "ListBox0Pg3", "StringItemList" ); + if ( aAny >>= aStringItemList ) + { + if ( aStringItemList.getLength() > nSelectedItem ) + SetConfigProperty( TK_CustomShowName, Any( aStringItemList[ nSelectedItem ] ) ); + } + } +} + + +OptimizerDialog::OptimizerDialog( const Reference< XComponentContext > &rxContext, Reference< XFrame > const & rxFrame, Reference< XDispatch > const & rxStatusDispatcher ) : + UnoDialog( rxContext, rxFrame ), + ConfigurationAccess( rxContext ), + mnCurrentStep( 0 ), + mnTabIndex( 0 ), + mxFrame( rxFrame ), + mxItemListener( new ItemListener( *this ) ), + mxActionListener( new ActionListener( *this ) ), + mxActionListenerListBox0Pg0( new ActionListenerListBox0Pg0( *this ) ), + mxTextListenerFormattedField0Pg1( new TextListenerFormattedField0Pg1( *this ) ), + mxTextListenerComboBox0Pg1( new TextListenerComboBox0Pg1( *this ) ), + mxSpinListenerFormattedField0Pg1( new SpinListenerFormattedField0Pg1( *this ) ), + mxStatusDispatcher( rxStatusDispatcher ) +{ + Reference< XStorable > xStorable( mxController->getModel(), UNO_QUERY_THROW ); + mbIsReadonly = xStorable->isReadonly(); + + InitDialog(); + InitRoadmap(); + InitNavigationBar(); + InitPage0(); + InitPage1(); + InitPage2(); + InitPage3(); + InitPage4(); + ActivatePage( 0 ); + + OptimizationStats aStats; + aStats.InitializeStatusValuesFromDocument( mxController->getModel() ); + Sequence< PropertyValue > aStatusSequence( aStats.GetStatusSequence() ); + UpdateStatus( aStatusSequence ); +} + + +OptimizerDialog::~OptimizerDialog() +{ + // not saving configuration if the dialog has been finished via cancel or close window + if ( endStatus() ) + SaveConfiguration(); +} + + +void OptimizerDialog::execute() +{ + Reference< XItemEventBroadcaster > xRoadmapBroadcaster( mxRoadmapControl, UNO_QUERY_THROW ); + xRoadmapBroadcaster->addItemListener( mxItemListener ); + UnoDialog::execute(); + UpdateConfiguration(); // taking actual control settings for the configuration + xRoadmapBroadcaster->removeItemListener( mxItemListener ); +} + + +void OptimizerDialog::SwitchPage( sal_Int16 nNewStep ) +{ + if ( !(( nNewStep != mnCurrentStep ) && ( nNewStep <= MAX_STEP ) && ( nNewStep >= 0 )) ) + return; + + sal_Int16 nOldStep = mnCurrentStep; + if ( nNewStep == 0 ) + disableControl( "btnNavBack" ); + else if ( nOldStep == 0 ) + enableControl( "btnNavBack" ); + + if ( nNewStep == MAX_STEP ) + disableControl( "btnNavNext" ); + else if ( nOldStep == MAX_STEP ) + enableControl( "btnNavNext" ); + + setControlProperty( "rdmNavi", "CurrentItemID", Any( nNewStep ) ); + + DeactivatePage( nOldStep ); + UpdateControlStates( nNewStep ); + + ActivatePage( nNewStep ); + mnCurrentStep = nNewStep; +} + +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(); + } + } +} + + +OUString OptimizerDialog::GetSelectedString( OUString const & token ) +{ + OUString aSelectedItem; + Sequence< sal_Int16 > sSelectedItems; + Sequence< OUString > sItemList; + + if ( ( getControlProperty( token, "SelectedItems" ) >>= sSelectedItems ) && + ( getControlProperty( token, "StringItemList" ) >>= sItemList ) ) + { + if ( sSelectedItems.getLength() == 1 ) + { + sal_Int16 nSelectedItem = sSelectedItems[ 0 ]; + if ( nSelectedItem < sItemList.getLength() ) + aSelectedItem = sItemList[ nSelectedItem ]; + } + } + return aSelectedItem; +} + + +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 ) + { + setControlProperty( "FixedText1Pg4", "Enabled", Any( true ) ); + setControlProperty( "FixedText1Pg4", "Label", Any( getString( TKGet( sStatus ) ) ) ); + } + } + pVal = maStats.GetStatusValue( TK_Progress ); + if ( pVal ) + { + sal_Int32 nProgress = 0; + if ( *pVal >>= nProgress ) + setControlProperty( "Progress", "ProgressValue", Any( nProgress ) ); + } + pVal = maStats.GetStatusValue( TK_OpenNewDocument ); + if ( pVal ) + SetConfigProperty( TK_OpenNewDocument, *pVal ); + + reschedule(); +} + + +void ItemListener::itemStateChanged( const ItemEvent& Event ) +{ + try + { + sal_Int16 nState; + Reference< XControl > xControl; + Any aSource( Event.Source ); + if ( aSource >>= xControl ) + { + Reference< XPropertySet > xPropertySet( xControl->getModel(), UNO_QUERY_THROW ); + OUString aControlName; + xPropertySet->getPropertyValue( "Name" ) >>= aControlName; + PPPOptimizerTokenEnum eControl( TKGet( aControlName ) ); + switch( eControl ) + { + case TK_rdmNavi : + { + mrOptimizerDialog.SwitchPage( static_cast< sal_Int16 >( Event.ItemId ) ); + } + break; + case TK_CheckBox1Pg1 : + { + if ( xPropertySet->getPropertyValue( "State" ) >>= nState ) + mrOptimizerDialog.SetConfigProperty( TK_RemoveCropArea, Any( nState != 0 ) ); + } + break; + case TK_CheckBox2Pg1 : + { + if ( xPropertySet->getPropertyValue( "State" ) >>= nState ) + mrOptimizerDialog.SetConfigProperty( TK_EmbedLinkedGraphics, Any( nState != 0 ) ); + } + break; + case TK_CheckBox0Pg2 : + { + if ( xPropertySet->getPropertyValue( "State" ) >>= nState ) + { + mrOptimizerDialog.SetConfigProperty( TK_OLEOptimization, Any( nState != 0 ) ); + mrOptimizerDialog.setControlProperty( "RadioButton0Pg2", "Enabled", Any( nState != 0 ) ); + mrOptimizerDialog.setControlProperty( "RadioButton1Pg2", "Enabled", Any( nState != 0 ) ); + } + } + break; + case TK_RadioButton0Pg1 : + { + sal_Int16 nInt16 = 0; + if ( xPropertySet->getPropertyValue( "State" ) >>= nInt16 ) + { + nInt16 ^= 1; + mrOptimizerDialog.SetConfigProperty( TK_JPEGCompression, Any( nInt16 != 0 ) ); + mrOptimizerDialog.setControlProperty( "FixedText1Pg1", "Enabled", Any( nInt16 != 0 ) ); + mrOptimizerDialog.setControlProperty( "FormattedField0Pg1", "Enabled", Any( nInt16 != 0 ) ); + } + } + break; + case TK_RadioButton1Pg1 : + { + if ( xPropertySet->getPropertyValue( "State" ) >>= nState ) + { + mrOptimizerDialog.SetConfigProperty( TK_JPEGCompression, Any( nState != 0 ) ); + mrOptimizerDialog.setControlProperty( "FixedText1Pg1", "Enabled", Any( nState != 0 ) ); + mrOptimizerDialog.setControlProperty( "FormattedField0Pg1", "Enabled", Any( nState != 0 ) ); + } + } + break; + case TK_RadioButton0Pg2 : + { + sal_Int16 nInt16; + if ( xPropertySet->getPropertyValue( "State" ) >>= nInt16 ) + { + nInt16 ^= 1; + mrOptimizerDialog.SetConfigProperty( TK_OLEOptimizationType, Any( nInt16 ) ); + } + } + break; + case TK_RadioButton1Pg2 : + { + if ( xPropertySet->getPropertyValue( "State" ) >>= nState ) + mrOptimizerDialog.SetConfigProperty( TK_OLEOptimizationType, Any( nState ) ); + } + break; + case TK_CheckBox0Pg3 : + { + if ( xPropertySet->getPropertyValue( "State" ) >>= nState ) + mrOptimizerDialog.SetConfigProperty( TK_DeleteUnusedMasterPages, Any( nState != 0 ) ); + } + break; + case TK_CheckBox1Pg3 : + { + if ( xPropertySet->getPropertyValue( "State" ) >>= nState ) + mrOptimizerDialog.SetConfigProperty( TK_DeleteNotesPages, Any( nState != 0 ) ); + } + break; + case TK_CheckBox2Pg3 : + { + if ( xPropertySet->getPropertyValue( "State" ) >>= nState ) + mrOptimizerDialog.SetConfigProperty( TK_DeleteHiddenSlides, Any( nState != 0 ) ); + } + break; + case TK_CheckBox3Pg3 : + { + if ( xPropertySet->getPropertyValue( "State" ) >>= nState ) + mrOptimizerDialog.setControlProperty( "ListBox0Pg3", "Enabled", Any( nState != 0 ) ); + } + break; + case TK_CheckBox1Pg4 : + { + if ( xPropertySet->getPropertyValue( "State" ) >>= nState ) + mrOptimizerDialog.setControlProperty( "ComboBox0Pg4", "Enabled", Any( nState != 0 ) ); + } + break; + case TK_RadioButton0Pg4 : + case TK_RadioButton1Pg4 : + { + if ( xPropertySet->getPropertyValue( "State" ) >>= nState ) + mrOptimizerDialog.SetConfigProperty( TK_SaveAs, Any( eControl == TK_RadioButton1Pg4 ? nState != 0 : nState == 0 ) ); + } + break; + default: + break; + } + } + } + catch ( Exception& ) + { + + } +} +void ItemListener::disposing( const css::lang::EventObject& /* Source */ ) +{ +} + +void ActionListener::actionPerformed( const ActionEvent& rEvent ) +{ + switch( TKGet( rEvent.ActionCommand ) ) + { + case TK_btnNavBack : mrOptimizerDialog.SwitchPage( mrOptimizerDialog.mnCurrentStep - 1 ); break; + case TK_btnNavNext : mrOptimizerDialog.SwitchPage( mrOptimizerDialog.mnCurrentStep + 1 ); break; + case TK_btnNavFinish : + { + mrOptimizerDialog.UpdateConfiguration(); + + mrOptimizerDialog.SwitchPage( ITEM_ID_SUMMARY ); + mrOptimizerDialog.DisablePage( ITEM_ID_SUMMARY ); + mrOptimizerDialog.setControlProperty( "btnNavBack", "Enabled", Any( false ) ); + mrOptimizerDialog.setControlProperty( "btnNavNext", "Enabled", Any( false ) ); + mrOptimizerDialog.setControlProperty( "btnNavFinish", "Enabled", Any( false ) ); + mrOptimizerDialog.setControlProperty( "btnNavCancel", "Enabled", Any( false ) ); + mrOptimizerDialog.setControlProperty( "FixedText0Pg4", "Enabled", Any( true ) ); + + // check if we have to open the FileDialog + bool bSuccessfullyExecuted = true; + sal_Int16 nInt16 = 0; + mrOptimizerDialog.getControlProperty( "RadioButton1Pg4", "State" ) >>= nInt16; + if ( nInt16 ) + { + // Duplicate presentation before applying changes + OUString aSaveAsURL; + FileOpenDialog aFileOpenDialog( mrOptimizerDialog.GetComponentContext() ); + + // generating default file name + OUString aName; + Reference< XStorable > xStorable( mrOptimizerDialog.controller()->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( + mrOptimizerDialog.GetFrame()->getController()->getModel(), UNO_QUERY); + aName = xTitle->getTitle(); + } + + if (!aName.isEmpty()) + { + aName += " " + mrOptimizerDialog.getString(STR_FILENAME_SUFFIX); + aFileOpenDialog.setDefaultName(aName); + } + + if (aFileOpenDialog.execute() == dialogs::ExecutableDialogResults::OK) + { + aSaveAsURL = aFileOpenDialog.getURL(); + mrOptimizerDialog.SetConfigProperty( TK_SaveAsURL, Any( aSaveAsURL ) ); + mrOptimizerDialog.SetConfigProperty( TK_FilterName, Any( aFileOpenDialog.getFilterName() ) ); + } + if ( aSaveAsURL.isEmpty() ) + { + // something goes wrong... + bSuccessfullyExecuted = false; + } + + // waiting for 500ms + mrOptimizerDialog.reschedule(); + for ( sal_uInt32 i = osl_getGlobalTimer(); ( i + 500 ) > ( osl_getGlobalTimer() ); ) + mrOptimizerDialog.reschedule(); + } + else + { + // Apply changes to current presentation + Reference<XModifiable> xModifiable(mrOptimizerDialog.controller()->getModel(), + UNO_QUERY_THROW ); + if ( xModifiable->isModified() ) + { + SolarMutexGuard aSolarGuard; + std::unique_ptr<weld::MessageDialog> popupDlg(Application::CreateMessageDialog( + nullptr, VclMessageType::Question, VclButtonsType::YesNo, + mrOptimizerDialog.getString(STR_WARN_UNSAVED_PRESENTATION))); + if (popupDlg->run() != RET_YES) + { + // Selected not "yes" ("no" or dialog was cancelled) so return to previous step + mrOptimizerDialog.setControlProperty("btnNavBack", "Enabled", + Any(true)); + mrOptimizerDialog.setControlProperty("btnNavNext", "Enabled", Any(false)); + mrOptimizerDialog.setControlProperty("btnNavFinish", "Enabled", Any(true)); + mrOptimizerDialog.setControlProperty("btnNavCancel", "Enabled", Any(true)); + mrOptimizerDialog.EnablePage(ITEM_ID_SUMMARY); + return; + } + } + } + if ( bSuccessfullyExecuted ) + { // now check if we have to store a session template + nInt16 = 0; + OUString aSettingsName; + mrOptimizerDialog.getControlProperty( "CheckBox1Pg4", "State" ) >>= nInt16; + mrOptimizerDialog.getControlProperty( "ComboBox0Pg4", "Text" ) >>= aSettingsName; + if ( nInt16 && !aSettingsName.isEmpty() ) + { + std::vector< OptimizerSettings >::iterator aIter( mrOptimizerDialog.GetOptimizerSettingsByName( aSettingsName ) ); + std::vector< OptimizerSettings >& rSettings( mrOptimizerDialog.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", mrOptimizerDialog.GetConfigurationSequence()), + comphelper::makePropertyValue("StatusDispatcher", mrOptimizerDialog.GetStatusDispatcher()), + comphelper::makePropertyValue("InformationDialog", mrOptimizerDialog.GetFrame()) + }; + + ErrCode errorCode; + try + { + ImpOptimizer aOptimizer( + mrOptimizerDialog.GetComponentContext(), + mrOptimizerDialog.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 + mrOptimizerDialog.maStats.SetStatusValue(TK_Progress, + Any(static_cast<sal_Int32>(0))); + mrOptimizerDialog.setControlProperty("btnNavBack", "Enabled", Any(true)); + mrOptimizerDialog.setControlProperty("btnNavNext", "Enabled", Any(false)); + mrOptimizerDialog.setControlProperty("btnNavFinish", "Enabled", Any(true)); + mrOptimizerDialog.setControlProperty("btnNavCancel", "Enabled", Any(true)); + + OUString aFileName; + mrOptimizerDialog.GetConfigProperty(TK_SaveAsURL) >>= aFileName; + SfxErrorContext aEc(ERRCTX_SFX_SAVEASDOC, aFileName); + ErrorHandler::HandleError(errorCode); + break; + } + + mrOptimizerDialog.endExecute( bSuccessfullyExecuted ); + } + else + { + mrOptimizerDialog.setControlProperty( "btnNavBack", "Enabled", Any( true ) ); + mrOptimizerDialog.setControlProperty( "btnNavNext", "Enabled", Any( false ) ); + mrOptimizerDialog.setControlProperty( "btnNavFinish", "Enabled", Any( true ) ); + mrOptimizerDialog.setControlProperty( "btnNavCancel", "Enabled", Any( true ) ); + mrOptimizerDialog.EnablePage( ITEM_ID_SUMMARY ); + } + } + break; + case TK_btnNavCancel : mrOptimizerDialog.endExecute( false ); break; + case TK_Button0Pg0 : // delete configuration + { + OUString aSelectedItem( mrOptimizerDialog.GetSelectedString( "ListBox0Pg0" ) ); + 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(); + } + } + } + break; + default: break; + } +} +void ActionListener::disposing( const css::lang::EventObject& /* Source */ ) +{ +} + + +void ActionListenerListBox0Pg0::actionPerformed( const ActionEvent& rEvent ) +{ + if ( !rEvent.ActionCommand.isEmpty() ) + { + std::vector< OptimizerSettings >::iterator aIter( mrOptimizerDialog.GetOptimizerSettingsByName( rEvent.ActionCommand ) ); + std::vector< OptimizerSettings >& rList( mrOptimizerDialog.GetOptimizerSettings() ); + if ( aIter != rList.end() ) + rList[ 0 ] = *aIter; + } + mrOptimizerDialog.UpdateControlStates(); +} +void ActionListenerListBox0Pg0::disposing( const css::lang::EventObject& /* Source */ ) +{ +} + + +void TextListenerFormattedField0Pg1::textChanged( const TextEvent& /* rEvent */ ) +{ + double fDouble = 0; + Any aAny = mrOptimizerDialog.getControlProperty( "FormattedField0Pg1", "EffectiveValue" ); + if ( aAny >>= fDouble ) + mrOptimizerDialog.SetConfigProperty( TK_JPEGQuality, Any( static_cast<sal_Int32>(fDouble) ) ); +} +void TextListenerFormattedField0Pg1::disposing( const css::lang::EventObject& /* Source */ ) +{ +} + +namespace +{ + +bool lcl_mapResolution(OUString& rResolution, std::u16string_view rImageResolution) +{ + if (o3tl::getToken(rImageResolution, 1, ';')!=rResolution) + return false; + rResolution = o3tl::getToken(rImageResolution, 0, ';'); + return true; +} + +} + +void TextListenerComboBox0Pg1::textChanged( const TextEvent& /* rEvent */ ) +{ + OUString aString; + Any aAny = mrOptimizerDialog.getControlProperty( "ComboBox0Pg1", "Text" ); + if ( !(aAny >>= aString) ) + return; + + for (int nIR{ STR_IMAGE_RESOLUTION_0 }; nIR <= STR_IMAGE_RESOLUTION_3; ++nIR) + { + if (lcl_mapResolution(aString, mrOptimizerDialog.getString(static_cast<PPPOptimizerTokenEnum>(nIR)))) + break; + } + + mrOptimizerDialog.SetConfigProperty( TK_ImageResolution, Any( aString.toInt32() ) ); +} +void TextListenerComboBox0Pg1::disposing( const css::lang::EventObject& /* Source */ ) +{ +} + + +void SpinListenerFormattedField0Pg1::up( const SpinEvent& /* rEvent */ ) +{ + double fDouble; + Any aAny = mrOptimizerDialog.getControlProperty( "FormattedField0Pg1", "EffectiveValue" ); + if ( aAny >>= fDouble ) + { + fDouble += 9; + if ( fDouble > 100 ) + fDouble = 100; + mrOptimizerDialog.setControlProperty( "FormattedField0Pg1", "EffectiveValue", Any( fDouble ) ); + mrOptimizerDialog.SetConfigProperty( TK_JPEGQuality, Any( static_cast<sal_Int32>(fDouble) ) ); + } +} +void SpinListenerFormattedField0Pg1::down( const SpinEvent& /* rEvent */ ) +{ + double fDouble; + Any aAny = mrOptimizerDialog.getControlProperty( "FormattedField0Pg1", "EffectiveValue" ); + if ( aAny >>= fDouble ) + { + fDouble -= 9; + if ( fDouble < 0 ) + fDouble = 0; + mrOptimizerDialog.setControlProperty( "FormattedField0Pg1", "EffectiveValue", Any( fDouble ) ); + mrOptimizerDialog.SetConfigProperty( TK_JPEGQuality, Any( static_cast<sal_Int32>(fDouble) ) ); + } +} +void SpinListenerFormattedField0Pg1::first( const SpinEvent& /* rEvent */ ) +{ + mrOptimizerDialog.setControlProperty( "FormattedField0Pg1", "EffectiveValue", Any( static_cast< double >( 0 ) ) ); + mrOptimizerDialog.SetConfigProperty( TK_JPEGQuality, Any( sal_Int32(0) ) ); +} +void SpinListenerFormattedField0Pg1::last( const SpinEvent& /* rEvent */ ) +{ + mrOptimizerDialog.setControlProperty( "FormattedField0Pg1", "EffectiveValue", Any( static_cast< double >( 100 ) ) ); + mrOptimizerDialog.SetConfigProperty( TK_JPEGQuality, Any( sal_Int32(100) ) ); +} +void SpinListenerFormattedField0Pg1::disposing( const css::lang::EventObject& /* Source */ ) +{ +} + +/* 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 000000000..4ea28eb75 --- /dev/null +++ b/sdext/source/minimizer/optimizerdialog.hxx @@ -0,0 +1,203 @@ +/* -*- 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_OPTIMIZERDIALOG_HXX +#define INCLUDED_SDEXT_SOURCE_MINIMIZER_OPTIMIZERDIALOG_HXX +#include <vector> +#include "unodialog.hxx" +#include "optimizationstats.hxx" +#include "configurationaccess.hxx" +#include <com/sun/star/awt/XItemListener.hpp> +#include <com/sun/star/awt/XSpinListener.hpp> +#include <com/sun/star/awt/XTextListener.hpp> +#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> + +#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 : public UnoDialog, 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 ); + ~OptimizerDialog(); + + void execute(); + + sal_Int16 mnCurrentStep; + sal_Int16 mnTabIndex; + bool mbIsReadonly; + +private: + css::uno::Reference< css::frame::XFrame > mxFrame; + + css::uno::Reference< css::uno::XInterface > mxRoadmapControl; + css::uno::Reference< css::uno::XInterface > mxRoadmapControlModel; + + css::uno::Reference< css::awt::XItemListener > mxItemListener; + css::uno::Reference< css::awt::XActionListener > mxActionListener; + css::uno::Reference< css::awt::XActionListener > mxActionListenerListBox0Pg0; + css::uno::Reference< css::awt::XTextListener > mxTextListenerFormattedField0Pg1; + css::uno::Reference< css::awt::XTextListener > mxTextListenerComboBox0Pg1; + css::uno::Reference< css::awt::XSpinListener > mxSpinListenerFormattedField0Pg1; + css::uno::Reference< css::frame::XDispatch > mxStatusDispatcher; + + std::vector< std::vector< OUString > > maControlPages; + + 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(); + + void ActivatePage( sal_Int16 nStep ); + void DeactivatePage( sal_Int16 nStep ); + void InsertRoadmapItem( const sal_Int32 nIndex, const OUString& rLabel, const sal_Int32 nItemID ); + +public: + + OptimizationStats maStats; + + void UpdateStatus( const css::uno::Sequence< css::beans::PropertyValue >& rStatus ); + + // the ConfigurationAccess is updated to actual control settings + void UpdateConfiguration(); + + void EnablePage( sal_Int16 nStep ); + void DisablePage( sal_Int16 nStep ); + + void SwitchPage( sal_Int16 nNewStep ); + void UpdateControlStates( sal_Int16 nStep = -1 ); + + OUString GetSelectedString( OUString const & token ); + css::uno::Reference< css::frame::XDispatch >& GetStatusDispatcher() { return mxStatusDispatcher; }; + css::uno::Reference< css::frame::XFrame>& GetFrame() { return mxFrame; }; + const css::uno::Reference< css::uno::XComponentContext >& GetComponentContext() const { return UnoDialog::mxContext; }; +}; + + +class ItemListener : public ::cppu::WeakImplHelper< css::awt::XItemListener > +{ +public: + explicit ItemListener( OptimizerDialog& rOptimizerDialog ) : mrOptimizerDialog( rOptimizerDialog ){} + + virtual void SAL_CALL itemStateChanged( const css::awt::ItemEvent& Event ) override; + virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override; +private: + + OptimizerDialog& mrOptimizerDialog; +}; + + +class ActionListener : public ::cppu::WeakImplHelper< css::awt::XActionListener > +{ +public: + explicit ActionListener( OptimizerDialog& rOptimizerDialog ) : mrOptimizerDialog( rOptimizerDialog ){} + + virtual void SAL_CALL actionPerformed( const css::awt::ActionEvent& Event ) override; + virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override; +private: + + OptimizerDialog& mrOptimizerDialog; +}; + + +class ActionListenerListBox0Pg0 : public ::cppu::WeakImplHelper< css::awt::XActionListener > +{ +public: + explicit ActionListenerListBox0Pg0( OptimizerDialog& rOptimizerDialog ) : mrOptimizerDialog( rOptimizerDialog ){} + + virtual void SAL_CALL actionPerformed( const css::awt::ActionEvent& Event ) override; + virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override; +private: + + OptimizerDialog& mrOptimizerDialog; +}; + + +class TextListenerFormattedField0Pg1 : public ::cppu::WeakImplHelper< css::awt::XTextListener > +{ +public: + explicit TextListenerFormattedField0Pg1( OptimizerDialog& rOptimizerDialog ) : mrOptimizerDialog( rOptimizerDialog ){} + + virtual void SAL_CALL textChanged( const css::awt::TextEvent& Event ) override; + virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override; +private: + + OptimizerDialog& mrOptimizerDialog; +}; + + +class TextListenerComboBox0Pg1 : public ::cppu::WeakImplHelper< css::awt::XTextListener > +{ +public: + explicit TextListenerComboBox0Pg1( OptimizerDialog& rOptimizerDialog ) : mrOptimizerDialog( rOptimizerDialog ){} + + virtual void SAL_CALL textChanged( const css::awt::TextEvent& Event ) override; + virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override; +private: + + OptimizerDialog& mrOptimizerDialog; +}; + + +class SpinListenerFormattedField0Pg1 : public ::cppu::WeakImplHelper< css::awt::XSpinListener > +{ +public: + explicit SpinListenerFormattedField0Pg1( OptimizerDialog& rOptimizerDialog ) : mrOptimizerDialog( rOptimizerDialog ){} + + virtual void SAL_CALL up( const css::awt::SpinEvent& Event ) override; + virtual void SAL_CALL down( const css::awt::SpinEvent& Event ) override; + virtual void SAL_CALL first( const css::awt::SpinEvent& Event ) override; + virtual void SAL_CALL last( const css::awt::SpinEvent& Event ) override; + virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override; +private: + + OptimizerDialog& mrOptimizerDialog; +}; + +#endif // INCLUDED_SDEXT_SOURCE_MINIMIZER_OPTIMIZERDIALOG_HXX + +/* 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 000000000..4ab29d969 --- /dev/null +++ b/sdext/source/minimizer/optimizerdialogcontrols.cxx @@ -0,0 +1,909 @@ +/* -*- 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; + + +static void SetBold( OptimizerDialog& rOptimizerDialog, const OUString& rControl ) +{ + FontDescriptor aFontDescriptor; + if ( rOptimizerDialog.getControlProperty( rControl, "FontDescriptor" ) >>= aFontDescriptor ) + { + aFontDescriptor.Weight = com::sun::star::awt::FontWeight::BOLD; + rOptimizerDialog.setControlProperty( rControl, "FontDescriptor", Any( aFontDescriptor ) ); + } +} + + +static OUString InsertSeparator( OptimizerDialog& rOptimizerDialog, const OUString& rControlName, sal_Int32 nOrientation, + sal_Int32 nPosX, sal_Int32 nPosY, sal_Int32 nWidth, sal_Int32 nHeight ) +{ + OUString pNames[] = { + OUString("Height"), + OUString("Orientation"), + OUString("PositionX"), + OUString("PositionY"), + OUString("Step"), + OUString("Width") }; + + Any pValues[] = { + Any( nHeight ), + Any( nOrientation ), + Any( nPosX ), + Any( nPosY ), + Any( sal_Int16( 0 ) ), + Any( nWidth ) }; + + sal_Int32 nCount = SAL_N_ELEMENTS( pNames ); + + Sequence< OUString > aNames( pNames, nCount ); + Sequence< Any > aValues( pValues, nCount ); + + rOptimizerDialog.insertControlModel( "com.sun.star.awt.UnoControlFixedLineModel", + rControlName, aNames, aValues ); + return rControlName; +} + + +static OUString InsertButton( OptimizerDialog& rOptimizerDialog, const OUString& rControlName, Reference< XActionListener > const & xActionListener, + sal_Int32 nXPos, sal_Int32 nYPos, sal_Int32 nWidth, sal_Int16 nTabIndex, bool bEnabled, PPPOptimizerTokenEnum nResID, css::awt::PushButtonType nPushButtonType ) +{ + sal_Int32 nHeight = BUTTON_HEIGHT; + OUString pNames[] = { + OUString("Enabled"), + OUString("Height"), + OUString("Label"), + OUString("PositionX"), + OUString("PositionY"), + OUString("PushButtonType"), + OUString("Step"), + OUString("TabIndex"), + OUString("Width") }; + + Any pValues[] = { + Any( bEnabled ), + Any( nHeight ), + Any( rOptimizerDialog.getString( nResID ) ), + Any( nXPos ), + Any( nYPos ), + Any( static_cast< sal_Int16 >(nPushButtonType) ), + Any( sal_Int16(0) ), + Any( nTabIndex ), + Any( nWidth ) }; + + + sal_Int32 nCount = SAL_N_ELEMENTS( pNames ); + + Sequence< OUString > aNames( pNames, nCount ); + Sequence< Any > aValues( pValues, nCount ); + + rOptimizerDialog.insertButton( rControlName, xActionListener, aNames, aValues ); + return rControlName; +} + + +static OUString InsertFixedText( OptimizerDialog& rOptimizerDialog, const OUString& rControlName, const OUString& rLabel, + sal_Int32 nXPos, sal_Int32 nYPos, sal_Int32 nWidth, sal_Int32 nHeight, bool bMultiLine, bool bBold, sal_Int16 nTabIndex ) +{ + OUString pNames[] = { + OUString("Height"), + OUString("Label"), + OUString("MultiLine"), + OUString("PositionX"), + OUString("PositionY"), + OUString("Step"), + OUString("TabIndex"), + OUString("Width") }; + + Any pValues[] = { + Any( nHeight ), + Any( rLabel ), + Any( bMultiLine ), + Any( nXPos ), + Any( nYPos ), + Any( sal_Int16(0) ), + Any( nTabIndex ), + Any( nWidth ) }; + + sal_Int32 nCount = SAL_N_ELEMENTS( pNames ); + + Sequence< OUString > aNames( pNames, nCount ); + Sequence< Any > aValues( pValues, nCount ); + + rOptimizerDialog.insertFixedText( rControlName, aNames, aValues ); + if ( bBold ) + SetBold( rOptimizerDialog, rControlName ); + return rControlName; +} + + +static OUString InsertCheckBox( OptimizerDialog& rOptimizerDialog, const OUString& rControlName, + const Reference< XItemListener >& xItemListener, const OUString& rLabel, + sal_Int32 nXPos, sal_Int32 nYPos, sal_Int32 nWidth, sal_Int16 nTabIndex ) +{ + sal_Int32 nHeight = 8; + OUString pNames[] = { + OUString("Enabled"), + OUString("Height"), + OUString("Label"), + OUString("PositionX"), + OUString("PositionY"), + OUString("Step"), + OUString("TabIndex"), + OUString("Width") }; + + Any pValues[] = { + Any( true ), + Any( nHeight ), + Any( rLabel ), + Any( nXPos ), + Any( nYPos ), + Any( sal_Int16(0) ), + Any( nTabIndex ), + Any( nWidth ) }; + + sal_Int32 nCount = SAL_N_ELEMENTS( pNames ); + + Sequence< OUString > aNames( pNames, nCount ); + Sequence< Any > aValues( pValues, nCount ); + + Reference< XCheckBox > xCheckBox( rOptimizerDialog.insertCheckBox( rControlName, aNames, aValues ) ); + if ( xItemListener.is() ) + xCheckBox->addItemListener( xItemListener ); + return rControlName; +} + + +static OUString InsertFormattedField( OptimizerDialog& rOptimizerDialog, const OUString& rControlName, + const Reference< XTextListener >& xTextListener, const Reference< XSpinListener >& xSpinListener, sal_Int32 nXPos, sal_Int32 nYPos, + double fEffectiveMin, double fEffectiveMax, sal_Int16 nTabIndex ) +{ + sal_Int32 nWidth = 50; + OUString pNames[] = { + OUString("EffectiveMax"), + OUString("EffectiveMin"), + OUString("Enabled"), + OUString("Height"), + OUString("PositionX"), + OUString("PositionY"), + OUString("Repeat"), + OUString("Spin"), + OUString("Step"), + OUString("TabIndex"), + OUString("Width") }; + + Any pValues[] = { + Any( fEffectiveMax ), + Any( fEffectiveMin ), + Any( true ), + Any( sal_Int32(12) ), + Any( nXPos ), + Any( nYPos ), + Any( true ), + Any( true ), + Any( sal_Int16(0) ), + Any( nTabIndex ), + Any( nWidth ) }; + + sal_Int32 nCount = SAL_N_ELEMENTS( pNames ); + + Sequence< OUString > aNames( pNames, nCount ); + Sequence< Any > aValues( pValues, nCount ); + + Reference< XTextComponent > xTextComponent( rOptimizerDialog.insertFormattedField( rControlName, aNames, aValues ), UNO_QUERY_THROW ); + if ( xTextListener.is() ) + xTextComponent->addTextListener( xTextListener ); + if ( xSpinListener.is() ) + { + Reference< XSpinField > xSpinField( xTextComponent, UNO_QUERY_THROW ); + xSpinField->addSpinListener( xSpinListener ); + } + return rControlName; +} + + +static OUString InsertComboBox( OptimizerDialog& rOptimizerDialog, const OUString& rControlName, + const Reference< XTextListener >& rTextListener, const bool bEnabled, const Sequence< OUString >& rItemList, + sal_Int32 nXPos, sal_Int32 nYPos, sal_Int16 nTabIndex ) +{ + sal_Int32 nHeight = 12; + sal_Int32 nWidth = 100; + OUString pNames[] = { + OUString("Dropdown"), + OUString("Enabled"), + OUString("Height"), + OUString("LineCount"), + OUString("PositionX"), + OUString("PositionY"), + OUString("Step"), + OUString("StringItemList"), + OUString("TabIndex"), + OUString("Width") }; + + Any pValues[] = { + Any( true ), + Any( bEnabled ), + Any( nHeight ), + Any( sal_Int16(8)), + Any( nXPos ), + Any( nYPos ), + Any( sal_Int16(0) ), + Any( rItemList ), + Any( nTabIndex ), + Any( nWidth ) }; + + sal_Int32 nCount = SAL_N_ELEMENTS( pNames ); + + Sequence< OUString > aNames( pNames, nCount ); + Sequence< Any > aValues( pValues, nCount ); + + Reference< XTextComponent > xTextComponent( rOptimizerDialog.insertComboBox( rControlName, aNames, aValues ), UNO_QUERY_THROW ); + if ( rTextListener.is() ) + xTextComponent->addTextListener( rTextListener ); + return rControlName; +} + + +static OUString InsertRadioButton( OptimizerDialog& rOptimizerDialog, const OUString& rControlName, const Reference< XItemListener >& rItemListener, + const OUString& rLabel, sal_Int32 nXPos, sal_Int32 nYPos, sal_Int32 nWidth, sal_Int16 nTabIndex ) +{ + sal_Int32 nHeight = 8; + OUString pNames[] = { + OUString("Height"), + OUString("Label"), + OUString("MultiLine"), + OUString("PositionX"), + OUString("PositionY"), + OUString("Step"), + OUString("TabIndex"), + OUString("Width") }; + + Any pValues[] = { + Any( nHeight ), + Any( rLabel ), + Any( false ), // bMultiLine + Any( nXPos ), + Any( nYPos ), + Any( sal_Int16(0) ), + Any( nTabIndex ), + Any( nWidth ) }; + + sal_Int32 nCount = SAL_N_ELEMENTS( pNames ); + + Sequence< OUString > aNames( pNames, nCount ); + Sequence< Any > aValues( pValues, nCount ); + + Reference< XRadioButton > xRadioButton( rOptimizerDialog.insertRadioButton( rControlName, aNames, aValues ) ); + if ( rItemListener.is() ) + xRadioButton->addItemListener( rItemListener ); + return rControlName; +} + + +static OUString InsertListBox( OptimizerDialog& rOptimizerDialog, const OUString& rControlName, + const Reference< XActionListener >& rActionListener, const bool bEnabled, const Sequence< OUString >& rItemList, + sal_Int32 nXPos, sal_Int32 nYPos, sal_Int32 nWidth, sal_Int16 nTabIndex ) +{ + sal_Int32 nHeight = 12; + OUString pNames[] = { + OUString("Dropdown"), + OUString("Enabled"), + OUString("Height"), + OUString("LineCount"), + OUString("MultiSelection"), + OUString("PositionX"), + OUString("PositionY"), + OUString("Step"), + OUString("StringItemList"), + OUString("TabIndex"), + OUString("Width") }; + + Any pValues[] = { + Any( true ), + Any( bEnabled ), + Any( nHeight ), + Any( sal_Int16(8)), + Any( false ), + Any( nXPos ), + Any( nYPos ), + Any( sal_Int16(0) ), + Any( rItemList ), + Any( nTabIndex ), + Any( nWidth ) }; + + sal_Int32 nCount = SAL_N_ELEMENTS( pNames ); + + Sequence< OUString > aNames( pNames, nCount ); + Sequence< Any > aValues( pValues, nCount ); + + Reference< XListBox > xListBox( rOptimizerDialog.insertListBox( rControlName, aNames, aValues ) ); + if ( xListBox.is() ) + xListBox->addActionListener( rActionListener ); + return rControlName; +} + + +void OptimizerDialog::InitNavigationBar() +{ + sal_Int32 nCancelPosX = OD_DIALOG_WIDTH - BUTTON_WIDTH - 6; + sal_Int32 nFinishPosX = nCancelPosX - 6 - BUTTON_WIDTH; + sal_Int32 nNextPosX = nFinishPosX - 6 - BUTTON_WIDTH; + sal_Int32 nBackPosX = nNextPosX - 3 - BUTTON_WIDTH; + + InsertSeparator( *this, "lnNavSep1", 0, 0, DIALOG_HEIGHT - 26, OD_DIALOG_WIDTH, 1 ); + InsertSeparator( *this, "lnNavSep2", 1, 85, 0, 1, BUTTON_POS_Y - 6 ); + + InsertButton( *this, "btnNavBack", mxActionListener, nBackPosX, BUTTON_POS_Y, BUTTON_WIDTH, mnTabIndex++, false, STR_BACK, PushButtonType_STANDARD ); + InsertButton( *this, "btnNavNext", mxActionListener, nNextPosX, BUTTON_POS_Y, BUTTON_WIDTH, mnTabIndex++, true, STR_NEXT, PushButtonType_STANDARD ); + InsertButton( *this, "btnNavFinish", mxActionListener, nFinishPosX, BUTTON_POS_Y, BUTTON_WIDTH, mnTabIndex++, true, STR_FINISH, PushButtonType_STANDARD ); + InsertButton( *this, "btnNavCancel", mxActionListener, nCancelPosX, BUTTON_POS_Y, BUTTON_WIDTH, mnTabIndex++, true, STR_CANCEL, PushButtonType_STANDARD ); + + setControlProperty( "btnNavNext", "DefaultButton", Any( true ) ); +} + + +void OptimizerDialog::UpdateControlStatesPage0() +{ + short nSelectedItem = -1; + Sequence< 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 + { + aItemList.realloc( rList.size() - 1 ); + auto pItemList = aItemList.getArray(); + for ( std::vector<OptimizerSettings>::size_type i = 1; i < rList.size(); i++ ) + { + pItemList[ i - 1 ] = rList[ i ].maName; + if ( nSelectedItem < 0 ) + { + if ( rList[ i ] == rList[ 0 ] ) + nSelectedItem = static_cast< short >( i - 1 ); + } + } + } + bool bRemoveButtonEnabled = false; + Sequence< short > aSelectedItems; + if ( nSelectedItem >= 0 ) + { + aSelectedItems = { nSelectedItem }; + if ( nSelectedItem > 2 ) // only allowing to delete custom themes, the first can|t be deleted + bRemoveButtonEnabled = true; + } + setControlProperty( "ListBox0Pg0", "StringItemList", Any( aItemList ) ); + setControlProperty( "ListBox0Pg0", "SelectedItems", Any( aSelectedItems ) ); + setControlProperty( "Button0Pg0", "Enabled", Any( bRemoveButtonEnabled ) ); +} +void OptimizerDialog::InitPage0() +{ + Sequence< OUString > aItemList; + std::vector< OUString > aControlList + { + InsertFixedText( *this, "FixedText0Pg0", getString( STR_INTRODUCTION ), PAGE_POS_X, PAGE_POS_Y, PAGE_WIDTH, 8, false, true, mnTabIndex++ ), + InsertFixedText( *this, "FixedText1Pg0", getString( STR_INTRODUCTION_T ), PAGE_POS_X + 6, PAGE_POS_Y + 14, PAGE_WIDTH - 12, 100, true, false, mnTabIndex++ ), + InsertSeparator( *this, "Separator1Pg0", 0, PAGE_POS_X + 6, DIALOG_HEIGHT - 66, PAGE_WIDTH - 12, 1 ), + InsertFixedText( *this, "FixedText2Pg0", getString( STR_CHOSE_SETTINGS ), PAGE_POS_X + 6, DIALOG_HEIGHT - 60, PAGE_WIDTH - 12, 8, true, false, mnTabIndex++ ), + InsertListBox( *this, "ListBox0Pg0", mxActionListenerListBox0Pg0, true, aItemList, PAGE_POS_X + 6, DIALOG_HEIGHT - 48, ( OD_DIALOG_WIDTH - 50 ) - ( PAGE_POS_X + 6 ), mnTabIndex++ ), + InsertButton( *this, "Button0Pg0", mxActionListener, OD_DIALOG_WIDTH - 46, DIALOG_HEIGHT - 49, 40, mnTabIndex++, true, STR_REMOVE, PushButtonType_STANDARD ) + }; + maControlPages.push_back( aControlList ); + DeactivatePage( 0 ); + UpdateControlStatesPage0(); +} + + +void OptimizerDialog::UpdateControlStatesPage1() +{ + bool bDeleteUnusedMasterPages( GetConfigProperty( TK_DeleteUnusedMasterPages, false ) ); + bool bDeleteHiddenSlides( GetConfigProperty( TK_DeleteHiddenSlides, false ) ); + bool bDeleteNotesPages( GetConfigProperty( TK_DeleteNotesPages, false ) ); + + setControlProperty( "CheckBox0Pg3", "State", Any( static_cast<sal_Int16>(bDeleteUnusedMasterPages) ) ); + setControlProperty( "CheckBox1Pg3", "State", Any( static_cast<sal_Int16>(bDeleteNotesPages) ) ); + setControlProperty( "CheckBox2Pg3", "State", Any( static_cast<sal_Int16>(bDeleteHiddenSlides) ) ); +} +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(); + } + std::vector< OUString > aControlList + { + InsertFixedText( *this, "FixedText0Pg3", getString( STR_CHOOSE_SLIDES ), PAGE_POS_X, PAGE_POS_Y, PAGE_WIDTH, 8, false, true, mnTabIndex++ ), + InsertCheckBox( *this, "CheckBox0Pg3", mxItemListener, getString( STR_DELETE_MASTER_PAGES ), PAGE_POS_X + 6, PAGE_POS_Y + 14, PAGE_WIDTH - 12, mnTabIndex++ ), + InsertCheckBox( *this, "CheckBox2Pg3", mxItemListener, getString( STR_DELETE_HIDDEN_SLIDES ), PAGE_POS_X + 6, PAGE_POS_Y + 28, PAGE_WIDTH - 12, mnTabIndex++ ), + InsertCheckBox( *this, "CheckBox3Pg3", mxItemListener, getString( STR_CUSTOM_SHOW ), PAGE_POS_X + 6, PAGE_POS_Y + 42, PAGE_WIDTH - 12, mnTabIndex++ ), + InsertListBox( *this, "ListBox0Pg3", mxActionListener, true, aCustomShowList, PAGE_POS_X + 14, PAGE_POS_Y + 54, 150, mnTabIndex++ ), + InsertCheckBox( *this, "CheckBox1Pg3", mxItemListener, getString( STR_DELETE_NOTES_PAGES ), PAGE_POS_X + 6, PAGE_POS_Y + 70, PAGE_WIDTH - 12, mnTabIndex++ ) + }; + maControlPages.push_back( aControlList ); + DeactivatePage( 1 ); + + setControlProperty( "CheckBox3Pg3", "State", Any( false ) ); + setControlProperty( "CheckBox3Pg3", "Enabled", Any( aCustomShowList.hasElements() ) ); + setControlProperty( "ListBox0Pg3", "Enabled", Any( false ) ); + + UpdateControlStatesPage1(); +} + +namespace +{ + +bool lcl_getResolutionText(OUString& rResolutionText, std::u16string_view rImageResolution, sal_Int32 nTargetRes) +{ + sal_Int32 nIdx{ 0 }; + if (o3tl::toInt32(o3tl::getToken(rImageResolution, 0, ';', nIdx))!=nTargetRes) + return false; + rResolutionText = o3tl::getToken(rImageResolution, 0, ';', nIdx); + return true; +} + +} + +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) ) ); + + OUString aResolutionText; + for (int nIR{ STR_IMAGE_RESOLUTION_0 }; nIR<=STR_IMAGE_RESOLUTION_3; ++nIR) + { + if (lcl_getResolutionText(aResolutionText, getString(static_cast<PPPOptimizerTokenEnum>(nIR)), nImageResolution)) + break; + } + if ( aResolutionText.isEmpty() ) + aResolutionText = OUString::number( nImageResolution ); + + setControlProperty( "RadioButton0Pg1", "State", Any( static_cast<sal_Int16>( !bJPEGCompression ) ) ); + setControlProperty( "RadioButton1Pg1", "State", Any( static_cast<sal_Int16>(bJPEGCompression) ) ); + setControlProperty( "FixedText1Pg1", "Enabled", Any( bJPEGCompression ) ); + setControlProperty( "FormattedField0Pg1", "Enabled", Any( bJPEGCompression ) ); + setControlProperty( "FormattedField0Pg1", "EffectiveValue", Any( static_cast<double>(nJPEGQuality) ) ); + setControlProperty( "CheckBox1Pg1", "State", Any( static_cast<sal_Int16>(bRemoveCropArea) ) ); + setControlProperty( "ComboBox0Pg1", "Text", Any( aResolutionText ) ); + setControlProperty( "CheckBox2Pg1", "State", Any( static_cast<sal_Int16>(bEmbedLinkedGraphics) ) ); +} +void OptimizerDialog::InitPage2() +{ + Sequence< OUString > aResolutionItemList{ + getString( STR_IMAGE_RESOLUTION_0 ).getToken( 1, ';' ), + getString( STR_IMAGE_RESOLUTION_1 ).getToken( 1, ';' ), + getString( STR_IMAGE_RESOLUTION_2 ).getToken( 1, ';' ), + getString( STR_IMAGE_RESOLUTION_3 ).getToken( 1, ';' ) + }; + + std::vector< OUString > aControlList + { + InsertFixedText( *this, "FixedText0Pg1", getString( STR_GRAPHIC_OPTIMIZATION ), PAGE_POS_X, PAGE_POS_Y, PAGE_WIDTH, 8, false, true, mnTabIndex++ ), + InsertRadioButton( *this, "RadioButton0Pg1", mxItemListener, getString( STR_LOSSLESS_COMPRESSION ), PAGE_POS_X + 6, PAGE_POS_Y + 14, PAGE_WIDTH - 12, mnTabIndex++ ), + InsertRadioButton( *this, "RadioButton1Pg1", mxItemListener, getString( STR_JPEG_COMPRESSION ), PAGE_POS_X + 6, PAGE_POS_Y + 28, PAGE_WIDTH - 12, mnTabIndex++ ), + InsertFixedText( *this, "FixedText1Pg1", getString( STR_QUALITY ), PAGE_POS_X + 20, PAGE_POS_Y + 40, 72, 8, false, false, mnTabIndex++ ), + InsertFormattedField( *this, "FormattedField0Pg1", mxTextListenerFormattedField0Pg1, mxSpinListenerFormattedField0Pg1, PAGE_POS_X + 106, PAGE_POS_Y + 38, 0, 100, mnTabIndex++ ), + InsertFixedText( *this, "FixedText2Pg1", getString( STR_IMAGE_RESOLUTION ), PAGE_POS_X + 6, PAGE_POS_Y + 54, 94, 8, false, false, mnTabIndex++ ), + InsertComboBox( *this, "ComboBox0Pg1", mxTextListenerComboBox0Pg1, true, aResolutionItemList, PAGE_POS_X + 106, PAGE_POS_Y + 52, mnTabIndex++ ), + InsertCheckBox( *this, "CheckBox1Pg1", mxItemListener, getString( STR_REMOVE_CROP_AREA ), PAGE_POS_X + 6, PAGE_POS_Y + 68, PAGE_WIDTH - 12, mnTabIndex++ ), + InsertCheckBox( *this, "CheckBox2Pg1", mxItemListener, getString( STR_EMBED_LINKED_GRAPHICS ), PAGE_POS_X + 6, PAGE_POS_Y + 82, PAGE_WIDTH - 12, mnTabIndex++ ) + }; + maControlPages.push_back( aControlList ); + DeactivatePage( 2 ); + UpdateControlStatesPage2(); +} + + +void OptimizerDialog::UpdateControlStatesPage3() +{ + bool bConvertOLEObjects( GetConfigProperty( TK_OLEOptimization, false ) ); + sal_Int16 nOLEOptimizationType( GetConfigProperty( TK_OLEOptimizationType, sal_Int16(0) ) ); + + setControlProperty( "CheckBox0Pg2", "State", Any( static_cast<sal_Int16>(bConvertOLEObjects) ) ); + setControlProperty( "RadioButton0Pg2", "Enabled", Any( bConvertOLEObjects ) ); + setControlProperty( "RadioButton0Pg2", "State", Any( static_cast<sal_Int16>( nOLEOptimizationType == 0 ) ) ); + setControlProperty( "RadioButton1Pg2", "Enabled", Any( bConvertOLEObjects ) ); + setControlProperty( "RadioButton1Pg2", "State", Any( static_cast<sal_Int16>( nOLEOptimizationType == 1 ) ) ); +} +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++; + } + } + + std::vector< OUString > aControlList + { + InsertFixedText( *this, "FixedText0Pg2", getString( STR_OLE_OPTIMIZATION ), PAGE_POS_X, PAGE_POS_Y, PAGE_WIDTH, 8, false, true, mnTabIndex++ ), + InsertCheckBox( *this, "CheckBox0Pg2", mxItemListener, getString( STR_OLE_REPLACE ), PAGE_POS_X + 6, PAGE_POS_Y + 14, PAGE_WIDTH - 12, mnTabIndex++ ), + InsertRadioButton( *this, "RadioButton0Pg2", mxItemListener, getString( STR_ALL_OLE_OBJECTS ), PAGE_POS_X + 14, PAGE_POS_Y + 28, PAGE_WIDTH - 22, mnTabIndex++ ), + InsertRadioButton( *this, "RadioButton1Pg2", mxItemListener, getString( STR_ALIEN_OLE_OBJECTS_ONLY ), PAGE_POS_X + 14, PAGE_POS_Y + 40, PAGE_WIDTH - 22, mnTabIndex++ ), + InsertFixedText( *this, "FixedText1Pg2", nOLECount ? getString( STR_OLE_OBJECTS_DESC ) : getString( STR_NO_OLE_OBJECTS_DESC ), PAGE_POS_X + 6, PAGE_POS_Y + 64, PAGE_WIDTH - 22, 50, true, false, mnTabIndex++ ) + }; + maControlPages.push_back( aControlList ); + DeactivatePage( 3 ); + 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 ) + { + setControlProperty( "RadioButton0Pg4", "State", Any( sal_Int16(false) ) ); + setControlProperty( "RadioButton1Pg4", "State", Any( sal_Int16(true) ) ); + } + else + { + setControlProperty( "RadioButton0Pg4", "State", Any( static_cast<sal_Int16>( !bSaveAs ) ) ); + setControlProperty( "RadioButton1Pg4", "State", Any( static_cast<sal_Int16>(bSaveAs) ) ); + } + setControlProperty( "ComboBox0Pg4", "Enabled", Any( false ) ); + + Sequence< 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 + { + aItemList.realloc( rList.size() - 1 ); + auto pItemList = aItemList.getArray(); + for ( std::vector<OptimizerSettings>::size_type w = 1; w < rList.size(); w++ ) + pItemList[ w - 1 ] = rList[ w ].maName; + } + setControlProperty( "ComboBox0Pg4", "StringItemList", Any( aItemList ) ); + + // 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; + } + } + } + sal_Int16 nInt16 = 0; + getControlProperty( "CheckBox1Pg4", "State" ) >>= nInt16; + setControlProperty( "CheckBox1Pg4", "Enabled", Any( bSaveSettingsEnabled ) ); + setControlProperty( "ComboBox0Pg4", "Enabled", Any( bSaveSettingsEnabled && nInt16 ) ); + + std::vector< OUString > aSummaryStrings; + + // taking care of deleted slides + sal_Int32 nDeletedSlides = 0; + if ( getControlProperty( "CheckBox3Pg3", "State" ) >>= nInt16 ) + { + if ( nInt16 ) + { + Sequence< short > aSelectedItems; + Sequence< OUString > aStringItemList; + Any aAny = getControlProperty( "ListBox0Pg3", "SelectedItems" ); + if ( aAny >>= aSelectedItems ) + { + if ( aSelectedItems.hasElements() ) + { + sal_Int16 nSelectedItem = aSelectedItems[ 0 ]; + aAny = getControlProperty( "ListBox0Pg3", "StringItemList" ); + if ( aAny >>= aStringItemList ) + { + if ( aStringItemList.getLength() > nSelectedItem ) + SetConfigProperty( TK_CustomShowName, Any( aStringItemList[ nSelectedItem ] ) ); + } + } + } + } + } + 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( UnoDialog::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( ); + setControlProperty( "FixedText4Pg4", "Label", Any( aSummaryStrings[ 0 ] ) ); + setControlProperty( "FixedText5Pg4", "Label", Any( aSummaryStrings[ 1 ] ) ); + setControlProperty( "FixedText6Pg4", "Label", Any( aSummaryStrings[ 2 ] ) ); + + 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 ]; + setControlProperty( "FixedText7Pg4", "Label", Any( ImpValueOfInMB( nCurrentFileSize, nSeparator ) ) ); + setControlProperty( "FixedText8Pg4", "Label", Any( ImpValueOfInMB( nEstimatedFileSize, nSeparator ) ) ); + SetConfigProperty( TK_EstimatedFileSize, Any( nEstimatedFileSize ) ); +} + +void OptimizerDialog::InitPage4() +{ + { // creating progress bar: + OUString pNames[] = { + OUString("Height"), + OUString("Name"), + OUString("PositionX"), + OUString("PositionY"), + OUString("ProgressValue"), + OUString("ProgressValueMax"), + OUString("ProgressValueMin"), + OUString("Width") }; + + Any pValues[] = { + Any( sal_Int32(12) ), + Any( OUString("STR_SAVE_AS") ), + Any( sal_Int32( PAGE_POS_X + 6 ) ), + Any( sal_Int32( DIALOG_HEIGHT - 75 ) ), + Any( sal_Int32(0) ), + Any( sal_Int32(100) ), + Any( sal_Int32(0) ), + Any( sal_Int32( PAGE_WIDTH - 12 ) ) }; + + sal_Int32 nCount = SAL_N_ELEMENTS( pNames ); + + Sequence< OUString > aNames( pNames, nCount ); + Sequence< Any > aValues( pValues, nCount ); + + insertControlModel( "com.sun.star.awt.UnoControlProgressBarModel", + "Progress", aNames, aValues ); + } + Reference< XTextListener > xTextListener; + Sequence< OUString > aItemList; + std::vector< OUString > aControlList + { + InsertFixedText( *this, "FixedText0Pg4", getString( STR_SUMMARY_TITLE ), PAGE_POS_X, PAGE_POS_Y, PAGE_WIDTH, 8, false, true, mnTabIndex++ ), + // InsertSeparator( *this, "Separator0Pg4", 0, PAGE_POS_X + 6, PAGE_POS_Y + 90, PAGE_WIDTH - 12, 1 ), + + InsertFixedText( *this, "FixedText4Pg4", OUString(), PAGE_POS_X + 6, PAGE_POS_Y + 14, PAGE_WIDTH - 12, 8, false, false, mnTabIndex++ ), + InsertFixedText( *this, "FixedText5Pg4", OUString(), PAGE_POS_X + 6, PAGE_POS_Y + 22, PAGE_WIDTH - 12, 8, false, false, mnTabIndex++ ), + InsertFixedText( *this, "FixedText6Pg4", OUString(), PAGE_POS_X + 6, PAGE_POS_Y + 30, PAGE_WIDTH - 12, 8, false, false, mnTabIndex++ ), + + InsertFixedText( *this, "FixedText2Pg4", getString( STR_CURRENT_FILESIZE ), PAGE_POS_X + 6, PAGE_POS_Y + 50, 88, 8, false, false, mnTabIndex++ ), + InsertFixedText( *this, "FixedText7Pg4", OUString(), PAGE_POS_X + 100, PAGE_POS_Y + 50, 30, 8, false, false, mnTabIndex++ ) + }; + setControlProperty( "FixedText7Pg4", "Align", Any( static_cast< short >( 2 ) ) ); + aControlList.push_back( InsertFixedText( *this, "FixedText3Pg4", getString( STR_ESTIMATED_FILESIZE ), PAGE_POS_X + 6, PAGE_POS_Y + 58, 88, 8, false, false, mnTabIndex++ ) ); + aControlList.push_back( InsertFixedText( *this, "FixedText8Pg4", OUString(), PAGE_POS_X + 100, PAGE_POS_Y + 58, 30, 8, false, false, mnTabIndex++ ) ); + setControlProperty( "FixedText8Pg4", "Align", Any( static_cast< short >( 2 ) ) ); + + aControlList.push_back( InsertRadioButton( *this, "RadioButton0Pg4", mxItemListener, getString( STR_APPLY_TO_CURRENT ), PAGE_POS_X + 6, PAGE_POS_Y + 78, PAGE_WIDTH - 12, mnTabIndex++ ) ); + aControlList.push_back( InsertRadioButton( *this, "RadioButton1Pg4", mxItemListener, getString( STR_SAVE_AS ), PAGE_POS_X + 6, PAGE_POS_Y + 90, PAGE_WIDTH - 12, mnTabIndex++ ) ); + aControlList.push_back( InsertFixedText( *this, "FixedText1Pg4", OUString(), PAGE_POS_X + 6, DIALOG_HEIGHT - 87, PAGE_WIDTH - 12, 8, true, false, mnTabIndex++ ) ); + aControlList.emplace_back("Progress" ); + aControlList.push_back( InsertSeparator( *this, "Separator1Pg4", 0, PAGE_POS_X + 6, DIALOG_HEIGHT - 58, PAGE_WIDTH - 12, 1 ) ); + aControlList.push_back( InsertCheckBox( *this, "CheckBox1Pg4", mxItemListener, getString( STR_SAVE_SETTINGS ), PAGE_POS_X + 6, DIALOG_HEIGHT - 47, 100, mnTabIndex++ ) ); + aControlList.push_back( InsertComboBox( *this, "ComboBox0Pg4", xTextListener, true, aItemList, PAGE_POS_X + 106, DIALOG_HEIGHT - 48, mnTabIndex++ ) ); + maControlPages.push_back( aControlList ); + DeactivatePage( 4 ); + + // 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() ); + + setControlProperty( "ComboBox0Pg4", "Text", Any( aSettingsName ) ); + setControlProperty( "RadioButton0Pg4", "Enabled", Any( !mbIsReadonly ) ); + setControlProperty( "RadioButton1Pg4", "Enabled", Any( !mbIsReadonly ) ); + + UpdateControlStatesPage4(); +} + + +void OptimizerDialog::EnablePage( sal_Int16 nStep ) +{ + for( const auto& rItem : maControlPages[ nStep ] ) + setControlProperty( rItem, "Enabled", Any( true ) ); +} +void OptimizerDialog::DisablePage( sal_Int16 nStep ) +{ + for( const auto& rItem : maControlPages[ nStep ] ) + setControlProperty( rItem, "Enabled", Any( false ) ); +} +void OptimizerDialog::ActivatePage( sal_Int16 nStep ) +{ + for( const auto& rItem : maControlPages[ nStep ] ) + setVisible( rItem, true ); +} +void OptimizerDialog::DeactivatePage( sal_Int16 nStep ) +{ + for( const auto& rItem : maControlPages[ nStep ] ) + setVisible( rItem, false ); +} + +/* 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 000000000..f42c7d271 --- /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 000000000..d2cc48d9e --- /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 000000000..c869f7218 --- /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 000000000..60b191a7b --- /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 000000000..74a89bfba --- /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 000000000..1d1042f64 --- /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 000000000..1e020bc02 --- /dev/null +++ b/sdext/source/minimizer/pppoptimizertoken.cxx @@ -0,0 +1,198 @@ +/* -*- 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[] = +{ + { "rdmNavi", TK_rdmNavi }, + { "btnNavBack", TK_btnNavBack }, + { "btnNavNext", TK_btnNavNext }, + { "btnNavFinish", TK_btnNavFinish }, + { "btnNavCancel", TK_btnNavCancel }, + + { "Button0Pg0", TK_Button0Pg0 }, + { "RadioButton0Pg1", TK_RadioButton0Pg1 }, + { "RadioButton1Pg1", TK_RadioButton1Pg1 }, + { "CheckBox1Pg1", TK_CheckBox1Pg1 }, + { "CheckBox2Pg1", TK_CheckBox2Pg1 }, + { "CheckBox0Pg2", TK_CheckBox0Pg2 }, + { "RadioButton0Pg2", TK_RadioButton0Pg2 }, + { "RadioButton1Pg2", TK_RadioButton1Pg2 }, + { "CheckBox0Pg3", TK_CheckBox0Pg3 }, + { "CheckBox1Pg3", TK_CheckBox1Pg3 }, + { "CheckBox2Pg3", TK_CheckBox2Pg3 }, + { "CheckBox3Pg3", TK_CheckBox3Pg3 }, + { "RadioButton0Pg4", TK_RadioButton0Pg4 }, + { "RadioButton1Pg4", TK_RadioButton1Pg4 }, + { "CheckBox1Pg4", TK_CheckBox1Pg4 }, + + { "DocumentService", TK_DocumentService }, + { "FileSizeDestination",TK_FileSizeDestination }, + { "FileSizeSource", TK_FileSizeSource }, + { "FilterName", TK_FilterName }, + { "Flags", TK_Flags }, + { "InformationDialog", TK_InformationDialog }, + { "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_STEPS", STR_STEPS }, + { "STR_BACK", STR_BACK }, + { "STR_NEXT", STR_NEXT }, + { "STR_FINISH", STR_FINISH }, + { "STR_CANCEL", STR_CANCEL }, + { "STR_INTRODUCTION", STR_INTRODUCTION }, + { "STR_INTRODUCTION_T", STR_INTRODUCTION_T }, + { "STR_CHOSE_SETTINGS", STR_CHOSE_SETTINGS }, + { "STR_REMOVE", STR_REMOVE }, + { "STR_GRAPHIC_OPTIMIZATION", STR_GRAPHIC_OPTIMIZATION }, + { "STR_IMAGE_OPTIMIZATION", STR_IMAGE_OPTIMIZATION }, + { "STR_LOSSLESS_COMPRESSION", STR_LOSSLESS_COMPRESSION }, + { "STR_JPEG_COMPRESSION", STR_JPEG_COMPRESSION }, + { "STR_QUALITY", STR_QUALITY }, + { "STR_REMOVE_CROP_AREA", STR_REMOVE_CROP_AREA }, + { "STR_IMAGE_RESOLUTION", STR_IMAGE_RESOLUTION }, + { "STR_IMAGE_RESOLUTION_0", STR_IMAGE_RESOLUTION_0 }, + { "STR_IMAGE_RESOLUTION_1", STR_IMAGE_RESOLUTION_1 }, + { "STR_IMAGE_RESOLUTION_2", STR_IMAGE_RESOLUTION_2 }, + { "STR_IMAGE_RESOLUTION_3", STR_IMAGE_RESOLUTION_3 }, + { "STR_EMBED_LINKED_GRAPHICS", STR_EMBED_LINKED_GRAPHICS }, + { "STR_OLE_OBJECTS", STR_OLE_OBJECTS }, + { "STR_OLE_OPTIMIZATION", STR_OLE_OPTIMIZATION }, + { "STR_OLE_REPLACE", STR_OLE_REPLACE }, + { "STR_ALL_OLE_OBJECTS", STR_ALL_OLE_OBJECTS }, + { "STR_ALIEN_OLE_OBJECTS_ONLY", STR_ALIEN_OLE_OBJECTS_ONLY }, + { "STR__OLE_OBJECTS_DESC", STR_OLE_OBJECTS_DESC }, + { "STR_NO_OLE_OBJECTS_DESC", STR_NO_OLE_OBJECTS_DESC }, + { "STR_SLIDES", STR_SLIDES }, + { "STR_CHOOSE_SLIDES", STR_CHOOSE_SLIDES }, + { "STR_DELETE_MASTER_PAGES", STR_DELETE_MASTER_PAGES }, + { "STR_DELETE_NOTES_PAGES", STR_DELETE_NOTES_PAGES }, + { "STR_DELETE_HIDDEN_SLIDES", STR_DELETE_HIDDEN_SLIDES }, + { "STR_CUSTOM_SHOW", STR_CUSTOM_SHOW }, + { "STR_SUMMARY", STR_SUMMARY }, + { "STR_SUMMARY_TITLE", STR_SUMMARY_TITLE }, + { "STR_APPLY_TO_CURRENT", STR_APPLY_TO_CURRENT }, + { "STR_AUTOMATICALLY_OPEN", STR_AUTOMATICALLY_OPEN }, + { "STR_SAVE_SETTINGS", STR_SAVE_SETTINGS }, + { "STR_SAVE_AS", STR_SAVE_AS }, + { "STR_DELETE_SLIDES", STR_DELETE_SLIDES }, + { "STR_OPTIMIZE_IMAGES", STR_OPTIMIZE_IMAGES }, + { "STR_CREATE_REPLACEMENT", STR_CREATE_REPLACEMENT }, + { "STR_CURRENT_FILESIZE", STR_CURRENT_FILESIZE }, + { "STR_ESTIMATED_FILESIZE", STR_ESTIMATED_FILESIZE }, + { "MY_SETTINGS", STR_MY_SETTINGS }, + { "STR_OK", STR_OK }, + { "STR_INFO_1", STR_INFO_1 }, + { "STR_INFO_2", STR_INFO_2 }, + { "STR_INFO_3", STR_INFO_3 }, + { "STR_INFO_4", STR_INFO_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( const OUString& 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; + int i, nLen = rToken.getLength(); + 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 000000000..d0ae65ed7 --- /dev/null +++ b/sdext/source/minimizer/pppoptimizertoken.hxx @@ -0,0 +1,148 @@ +/* -*- 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_rdmNavi, + TK_btnNavBack, + TK_btnNavNext, + TK_btnNavFinish, + TK_btnNavCancel, + + TK_Button0Pg0, + TK_RadioButton0Pg1, + TK_RadioButton1Pg1, + TK_CheckBox1Pg1, + TK_CheckBox2Pg1, + TK_CheckBox0Pg2, + TK_RadioButton0Pg2, + TK_RadioButton1Pg2, + TK_CheckBox0Pg3, + TK_CheckBox1Pg3, + TK_CheckBox2Pg3, + TK_CheckBox3Pg3, + TK_RadioButton0Pg4, + TK_RadioButton1Pg4, + TK_CheckBox1Pg4, + + TK_DocumentService, + TK_FileSizeDestination, + TK_FileSizeSource, + TK_FilterName, + TK_Flags, + TK_InformationDialog, + 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_STEPS, + STR_BACK, + STR_NEXT, + STR_FINISH, + STR_CANCEL, + STR_INTRODUCTION, + STR_INTRODUCTION_T, + STR_CHOSE_SETTINGS, + STR_REMOVE, + STR_GRAPHIC_OPTIMIZATION, + STR_IMAGE_OPTIMIZATION, + STR_LOSSLESS_COMPRESSION, + STR_JPEG_COMPRESSION, + STR_QUALITY, + STR_REMOVE_CROP_AREA, + STR_IMAGE_RESOLUTION, + STR_IMAGE_RESOLUTION_0, + STR_IMAGE_RESOLUTION_1, + STR_IMAGE_RESOLUTION_2, + STR_IMAGE_RESOLUTION_3, + STR_EMBED_LINKED_GRAPHICS, + STR_OLE_OBJECTS, + STR_OLE_OPTIMIZATION, + STR_OLE_REPLACE, + STR_ALL_OLE_OBJECTS, + STR_ALIEN_OLE_OBJECTS_ONLY, + STR_OLE_OBJECTS_DESC, + STR_NO_OLE_OBJECTS_DESC, + STR_SLIDES, + STR_CHOOSE_SLIDES, + STR_DELETE_MASTER_PAGES, + STR_DELETE_NOTES_PAGES, + STR_DELETE_HIDDEN_SLIDES, + STR_CUSTOM_SHOW, + STR_SUMMARY, + STR_SUMMARY_TITLE, + STR_APPLY_TO_CURRENT, + STR_AUTOMATICALLY_OPEN, + STR_SAVE_SETTINGS, + STR_SAVE_AS, + STR_DELETE_SLIDES, + STR_OPTIMIZE_IMAGES, + STR_CREATE_REPLACEMENT, + STR_CURRENT_FILESIZE, + STR_ESTIMATED_FILESIZE, + STR_MY_SETTINGS, + STR_OK, + STR_INFO_1, + STR_INFO_2, + STR_INFO_3, + STR_INFO_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(const OUString&); +OUString TKGet(const PPPOptimizerTokenEnum); + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/minimizer/unodialog.cxx b/sdext/source/minimizer/unodialog.cxx new file mode 100644 index 000000000..a635d102e --- /dev/null +++ b/sdext/source/minimizer/unodialog.cxx @@ -0,0 +1,309 @@ +/* -*- 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 "unodialog.hxx" + +#include <com/sun/star/awt/Toolkit.hpp> +#include <com/sun/star/awt/UnoControlDialog.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/view/XSelectionSupplier.hpp> + + +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::view; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::beans; + +UnoDialog::UnoDialog( const Reference< XComponentContext > &rxContext, Reference< XFrame > const & rxFrame ) : + mxContext( rxContext ), + mxController( rxFrame->getController() ), + mxDialogModel( mxContext->getServiceManager()->createInstanceWithContext( + "com.sun.star.awt.UnoControlDialogModel", mxContext ), UNO_SET_THROW ), + mxDialogModelMultiPropertySet( mxDialogModel, UNO_QUERY_THROW ), + mxDialogModelMSF( mxDialogModel, UNO_QUERY_THROW ), + mxDialogModelNameContainer( mxDialogModel, UNO_QUERY_THROW ), + mxDialogModelNameAccess( mxDialogModel, UNO_QUERY_THROW ), + mxControlModel( mxDialogModel, UNO_QUERY_THROW ), + mxDialog( UnoControlDialog::create(rxContext) ), + mxControl( mxDialog, UNO_QUERY_THROW ), + mbStatus( false ) +{ + mxControl->setModel( mxControlModel ); + + Reference< XFrame > xFrame( mxController->getFrame() ); + Reference< XWindow > xContainerWindow( xFrame->getContainerWindow() ); + Reference< XWindowPeer > xWindowPeer( xContainerWindow, UNO_QUERY_THROW ); + + // set the main loop handle to update GUI while busy + Reference< XToolkit > xToolkit( Toolkit::create( mxContext ), UNO_QUERY_THROW ); + mxReschedule.set( xToolkit, UNO_QUERY ); + + // allocate the real window resources + mxDialog->createPeer(xToolkit, + xWindowPeer.is() ? xWindowPeer : xToolkit->getDesktopWindow()); +} + +UnoDialog::~UnoDialog() +{ + // free the resources + Reference<XComponent> xDialogComponent(mxDialog, UNO_QUERY_THROW); + xDialogComponent->dispose(); +} + +void UnoDialog::execute() +{ + mxDialog->setEnable( true ); + mxDialog->setVisible( true ); + mxDialog->execute(); +} + +void UnoDialog::endExecute( bool bStatus ) +{ + mbStatus = bStatus; + mxDialog->endExecute(); +} + +Reference< XInterface > UnoDialog::insertControlModel( const OUString& rServiceName, const OUString& rName, + const Sequence< OUString >& rPropertyNames, const Sequence< Any >& rPropertyValues ) +{ + Reference< XInterface > xControlModel; + try + { + xControlModel = mxDialogModelMSF->createInstance( rServiceName ); + Reference< XMultiPropertySet > xMultiPropSet( xControlModel, UNO_QUERY_THROW ); + xMultiPropSet->setPropertyValues( rPropertyNames, rPropertyValues ); + mxDialogModelNameContainer->insertByName( rName, Any( xControlModel ) ); + } + catch( Exception& ) + { + } + return xControlModel; +} + + +void UnoDialog::setVisible( const OUString& rName, bool bVisible ) +{ + try + { + Reference< XInterface > xControl( mxDialog->getControl( rName ), UNO_QUERY_THROW ); + Reference< XWindow > xWindow( xControl, UNO_QUERY_THROW ); + xWindow->setVisible( bVisible ); + } + catch ( Exception& ) + { + } +} + + +Reference< XButton > UnoDialog::insertButton( const OUString& rName, const Reference< XActionListener >& xActionListener, + const Sequence< OUString >& rPropertyNames, const Sequence< Any >& rPropertyValues ) +{ + Reference< XButton > xButton; + try + { + Reference< XInterface > xButtonModel( insertControlModel( "com.sun.star.awt.UnoControlButtonModel", + rName, rPropertyNames, rPropertyValues ) ); + Reference< XPropertySet > xPropertySet( xButtonModel, UNO_QUERY_THROW ); + xPropertySet->setPropertyValue("Name", Any( rName ) ); + xButton.set( mxDialog->getControl( rName ), UNO_QUERY_THROW ); + + if ( xActionListener.is() ) + { + xButton->addActionListener( xActionListener ); + xButton->setActionCommand( rName ); + } + return xButton; + } + catch( Exception& ) + { + } + return xButton; +} + + +Reference< XFixedText > UnoDialog::insertFixedText( const OUString& rName, const Sequence< OUString >& rPropertyNames, const Sequence< Any >& rPropertyValues ) +{ + Reference< XFixedText > xFixedText; + try + { + Reference< XPropertySet > xPropertySet( insertControlModel( "com.sun.star.awt.UnoControlFixedTextModel", + rName, rPropertyNames, rPropertyValues ), UNO_QUERY_THROW ); + xPropertySet->setPropertyValue("Name", Any( rName ) ); + xFixedText.set( mxDialog->getControl( rName ), UNO_QUERY_THROW ); + } + catch ( Exception& ) + { + } + return xFixedText; +} + + +Reference< XCheckBox > UnoDialog::insertCheckBox( const OUString& rName, const Sequence< OUString >& rPropertyNames, const Sequence< Any >& rPropertyValues ) +{ + Reference< XCheckBox > xCheckBox; + try + { + Reference< XPropertySet > xPropertySet( insertControlModel( "com.sun.star.awt.UnoControlCheckBoxModel", + rName, rPropertyNames, rPropertyValues ), UNO_QUERY_THROW ); + xPropertySet->setPropertyValue("Name", Any( rName ) ); + xCheckBox.set( mxDialog->getControl( rName ), UNO_QUERY_THROW ); + } + catch ( Exception& ) + { + } + return xCheckBox; +} + + +Reference< XControl > UnoDialog::insertFormattedField( const OUString& rName, const Sequence< OUString >& rPropertyNames, const Sequence< Any >& rPropertyValues ) +{ + Reference< XControl > xControl; + try + { + Reference< XPropertySet > xPropertySet( insertControlModel( "com.sun.star.awt.UnoControlFormattedFieldModel", + rName, rPropertyNames, rPropertyValues ), UNO_QUERY_THROW ); + xPropertySet->setPropertyValue("Name", Any( rName ) ); + xControl.set( mxDialog->getControl( rName ), UNO_SET_THROW ); + } + catch ( Exception& ) + { + } + return xControl; +} + + +Reference< XComboBox > UnoDialog::insertComboBox( const OUString& rName, const Sequence< OUString >& rPropertyNames, const Sequence< Any >& rPropertyValues ) +{ + Reference< XComboBox > xControl; + try + { + Reference< XPropertySet > xPropertySet( insertControlModel( "com.sun.star.awt.UnoControlComboBoxModel", + rName, rPropertyNames, rPropertyValues ), UNO_QUERY_THROW ); + xPropertySet->setPropertyValue("Name", Any( rName ) ); + xControl.set( mxDialog->getControl( rName ), UNO_QUERY_THROW ); + } + catch ( Exception& ) + { + } + return xControl; +} + + +Reference< XRadioButton > UnoDialog::insertRadioButton( const OUString& rName, const Sequence< OUString >& rPropertyNames, const Sequence< Any >& rPropertyValues ) +{ + Reference< XRadioButton > xControl; + try + { + Reference< XPropertySet > xPropertySet( insertControlModel( "com.sun.star.awt.UnoControlRadioButtonModel", + rName, rPropertyNames, rPropertyValues ), UNO_QUERY_THROW ); + xPropertySet->setPropertyValue("Name", Any( rName ) ); + xControl.set( mxDialog->getControl( rName ), UNO_QUERY_THROW ); + } + catch ( Exception& ) + { + } + return xControl; +} + + +Reference< XListBox > UnoDialog::insertListBox( const OUString& rName, const Sequence< OUString >& rPropertyNames, const Sequence< Any >& rPropertyValues ) +{ + Reference< XListBox > xControl; + try + { + Reference< XPropertySet > xPropertySet( insertControlModel( "com.sun.star.awt.UnoControlListBoxModel", + rName, rPropertyNames, rPropertyValues ), UNO_QUERY_THROW ); + xPropertySet->setPropertyValue("Name", Any( rName ) ); + xControl.set( mxDialog->getControl( rName ), UNO_QUERY_THROW ); + } + catch ( Exception& ) + { + } + return xControl; +} + + +Reference< XControl > UnoDialog::insertImage( const OUString& rName, const Sequence< OUString >& rPropertyNames, const Sequence< Any >& rPropertyValues ) +{ + Reference< XControl > xControl; + try + { + Reference< XPropertySet > xPropertySet( insertControlModel( "com.sun.star.awt.UnoControlImageControlModel", + rName, rPropertyNames, rPropertyValues ), UNO_QUERY_THROW ); + xPropertySet->setPropertyValue("Name", Any( rName ) ); + xControl.set( mxDialog->getControl( rName ), UNO_SET_THROW ); + } + catch ( Exception& ) + { + } + return xControl; +} + + +void UnoDialog::setControlProperty( const OUString& rControlName, const OUString& rPropertyName, const Any& rPropertyValue ) +{ + try + { + if ( mxDialogModelNameAccess->hasByName( rControlName ) ) + { + Reference< XPropertySet > xPropertySet( mxDialogModelNameAccess->getByName( rControlName ), UNO_QUERY_THROW ); + xPropertySet->setPropertyValue( rPropertyName, rPropertyValue ); + } + } + catch ( Exception& ) + { + } +} + + +Any UnoDialog::getControlProperty( const OUString& rControlName, const OUString& rPropertyName ) +{ + Any aRet; + try + { + if ( mxDialogModelNameAccess->hasByName( rControlName ) ) + { + Reference< XPropertySet > xPropertySet( mxDialogModelNameAccess->getByName( rControlName ), UNO_QUERY_THROW ); + aRet = xPropertySet->getPropertyValue( rPropertyName ); + } + } + catch ( Exception& ) + { + } + return aRet; +} + + +void UnoDialog::enableControl( const OUString& rControlName ) +{ + setControlProperty( rControlName, "Enabled", Any( true ) ); +} + + +void UnoDialog::disableControl( const OUString& rControlName ) +{ + setControlProperty( rControlName, "Enabled", Any( false ) ); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/minimizer/unodialog.hxx b/sdext/source/minimizer/unodialog.hxx new file mode 100644 index 000000000..3bf908cf1 --- /dev/null +++ b/sdext/source/minimizer/unodialog.hxx @@ -0,0 +1,118 @@ +/* -*- 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_UNODIALOG_HXX +#define INCLUDED_SDEXT_SOURCE_MINIMIZER_UNODIALOG_HXX + +#include <com/sun/star/uno/Sequence.h> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/frame/XController.hpp> +#include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/beans/XMultiPropertySet.hpp> +#include <com/sun/star/awt/XControl.hpp> +#include <com/sun/star/awt/XControlModel.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/awt/XActionListener.hpp> +#include <com/sun/star/awt/XButton.hpp> +#include <com/sun/star/awt/XCheckBox.hpp> +#include <com/sun/star/awt/XComboBox.hpp> +#include <com/sun/star/awt/XRadioButton.hpp> +#include <com/sun/star/awt/XListBox.hpp> +#include <com/sun/star/awt/XFixedText.hpp> +#include <com/sun/star/awt/XUnoControlDialog.hpp> +#include <com/sun/star/awt/XReschedule.hpp> + + +class UnoDialog +{ +public: + + UnoDialog( const css::uno::Reference< css::uno::XComponentContext >& rxMSF, css::uno::Reference< css::frame::XFrame > const & rxFrame ); + ~UnoDialog(); + + void execute(); + void endExecute( bool bStatus ); + + css::uno::Reference< css::uno::XInterface > insertControlModel( const OUString& rServiceName, const OUString& rName, + const css::uno::Sequence< OUString >& rPropertyNames, const css::uno::Sequence< css::uno::Any >& rPropertyValues ); + + void setVisible( const OUString& rName, bool bVisible ); + + css::uno::Reference< css::awt::XButton > insertButton( const OUString& rName, + const css::uno::Reference< css::awt::XActionListener >& xActionListener, const css::uno::Sequence< OUString >& rPropertyNames, + const css::uno::Sequence< css::uno::Any >& rPropertyValues ); + + css::uno::Reference< css::awt::XFixedText > insertFixedText( const OUString& rName, + const css::uno::Sequence< OUString >& rPropertyNames, const css::uno::Sequence< css::uno::Any >& rPropertyValues ); + + css::uno::Reference< css::awt::XCheckBox > insertCheckBox( const OUString& rName, + const css::uno::Sequence< OUString >& rPropertyNames, const css::uno::Sequence< css::uno::Any >& rPropertyValues ); + + css::uno::Reference< css::awt::XControl > insertFormattedField( const OUString& rName, + const css::uno::Sequence< OUString >& rPropertyNames, const css::uno::Sequence< css::uno::Any >& rPropertyValues ); + + css::uno::Reference< css::awt::XComboBox > insertComboBox( const OUString& rName, + const css::uno::Sequence< OUString >& rPropertyNames, const css::uno::Sequence< css::uno::Any >& rPropertyValues ); + + css::uno::Reference< css::awt::XRadioButton > insertRadioButton( const OUString& rName, + const css::uno::Sequence< OUString >& rPropertyNames, const css::uno::Sequence< css::uno::Any >& rPropertyValues ); + + css::uno::Reference< css::awt::XListBox > insertListBox( const OUString& rName, + const css::uno::Sequence< OUString >& rPropertyNames, const css::uno::Sequence< css::uno::Any >& rPropertyValues ); + + css::uno::Reference< css::awt::XControl > insertImage( const OUString& rName, + const css::uno::Sequence< OUString >& rPropertyNames, const css::uno::Sequence< css::uno::Any >& rPropertyValues ); + + void setControlProperty( const OUString& rControlName, const OUString& rPropertyName, const css::uno::Any& rPropertyValue ); + css::uno::Any getControlProperty( const OUString& rControlName, const OUString& rPropertyName ); + + void enableControl( const OUString& rControlName ); + void disableControl( const OUString& rControlName ); + + void reschedule() const { mxReschedule->reschedule(); } + bool endStatus() const { return mbStatus; } + css::uno::Reference<css::awt::XControl> getControl(const OUString& rControlName) const { return mxDialog->getControl(rControlName); } + const css::uno::Reference<css::frame::XController>& controller() const { return mxController; } + void setPropertyValues(const css::uno::Sequence<OUString>& rNameSeq, const css::uno::Sequence<css::uno::Any>& rValueSeq) + { mxDialogModelMultiPropertySet->setPropertyValues(rNameSeq, rValueSeq); } + +protected: + css::uno::Reference< css::uno::XComponentContext > mxContext; + css::uno::Reference< css::frame::XController > mxController; + +private: + css::uno::Reference< css::awt::XReschedule > mxReschedule; + css::uno::Reference< css::uno::XInterface > mxDialogModel; + css::uno::Reference< css::beans::XMultiPropertySet > mxDialogModelMultiPropertySet; + css::uno::Reference< css::lang::XMultiServiceFactory > mxDialogModelMSF; + css::uno::Reference< css::container::XNameContainer > mxDialogModelNameContainer; + css::uno::Reference< css::container::XNameAccess > mxDialogModelNameAccess; + + css::uno::Reference< css::awt::XControlModel > mxControlModel; + + css::uno::Reference< css::awt::XUnoControlDialog > mxDialog; + css::uno::Reference< css::awt::XControl > mxControl; + bool mbStatus; +}; + +#endif // INCLUDED_SDEXT_SOURCE_MINIMIZER_UNODIALOG_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |