diff options
-rw-r--r-- | framework/source/uiconfiguration/imagemanagerimpl.cxx | 175 | ||||
-rw-r--r-- | framework/source/uiconfiguration/imagemanagerimpl.hxx | 29 | ||||
-rw-r--r-- | include/vcl/CommandImageResolver.hxx | 64 | ||||
-rw-r--r-- | vcl/Library_vcl.mk | 1 | ||||
-rw-r--r-- | vcl/source/bitmap/CommandImageResolver.cxx | 161 |
5 files changed, 268 insertions, 162 deletions
diff --git a/framework/source/uiconfiguration/imagemanagerimpl.cxx b/framework/source/uiconfiguration/imagemanagerimpl.cxx index e62a7a7e5603..5b5c0f59deb3 100644 --- a/framework/source/uiconfiguration/imagemanagerimpl.cxx +++ b/framework/source/uiconfiguration/imagemanagerimpl.cxx @@ -87,12 +87,8 @@ static const char* BITMAP_FILE_NAMES[] = namespace framework { - static GlobalImageList* pGlobalImageList = nullptr; - static const char* ImageType_Prefixes[ImageType_COUNT] = - { - "cmd/sc_", - "cmd/lc_" - }; + +static GlobalImageList* pGlobalImageList = nullptr; typedef GraphicNameAccess CmdToXGraphicNameAccess; @@ -117,190 +113,79 @@ static GlobalImageList* getGlobalImageList( const uno::Reference< uno::XComponen return pGlobalImageList; } -static OUString getCanonicalName( const OUString& rFileName ) -{ - bool bRemoveSlash( true ); - sal_Int32 nLength = rFileName.getLength(); - const sal_Unicode* pString = rFileName.getStr(); - - OUStringBuffer aBuf( nLength ); - for ( sal_Int32 i = 0; i < nLength; i++ ) - { - const sal_Unicode c = pString[i]; - switch ( c ) - { - // map forbidden characters to escape - case '/' : if ( !bRemoveSlash ) - aBuf.append( "%2f" ); - break; - case '\\': aBuf.append( "%5c" ); bRemoveSlash = false; break; - case ':' : aBuf.append( "%3a" ); bRemoveSlash = false; break; - case '*' : aBuf.append( "%2a" ); bRemoveSlash = false; break; - case '?' : aBuf.append( "%3f" ); bRemoveSlash = false; break; - case '<' : aBuf.append( "%3c" ); bRemoveSlash = false; break; - case '>' : aBuf.append( "%3e" ); bRemoveSlash = false; break; - case '|' : aBuf.append( "%7c" ); bRemoveSlash = false; break; - default: aBuf.append( c ); bRemoveSlash = false; - } - } - return aBuf.makeStringAndClear(); -} - CmdImageList::CmdImageList( const uno::Reference< uno::XComponentContext >& rxContext, const OUString& aModuleIdentifier ) : - m_bVectorInit( false ), + m_bInitialized(false), m_aModuleIdentifier( aModuleIdentifier ), - m_xContext( rxContext ), - m_sIconTheme( SvtMiscOptions().GetIconTheme() ) + m_xContext( rxContext ) { - for ( sal_Int32 n=0; n < ImageType_COUNT; n++ ) - m_pImageList[n] = nullptr; } CmdImageList::~CmdImageList() { - for ( sal_Int32 n=0; n < ImageType_COUNT; n++ ) - delete m_pImageList[n]; } -void CmdImageList::impl_fillCommandToImageNameMap() +void CmdImageList::initialize() { - SAL_INFO( "fwk", "framework: CmdImageList::impl_fillCommandToImageNameMap" ); - - if ( !m_bVectorInit ) + if (!m_bInitialized) { - const OUString aCommandImageList( UICOMMANDDESCRIPTION_NAMEACCESS_COMMANDIMAGELIST ); - Sequence< OUString > aCmdImageSeq; - uno::Reference< XNameAccess > xCmdDesc = frame::theUICommandDescription::get( m_xContext ); + const OUString aCommandImageList(UICOMMANDDESCRIPTION_NAMEACCESS_COMMANDIMAGELIST); + + Sequence<OUString> aCommandImageSeq; + uno::Reference<XNameAccess> xCommandDesc = frame::theUICommandDescription::get(m_xContext); - if ( !m_aModuleIdentifier.isEmpty() ) + if (!m_aModuleIdentifier.isEmpty()) { // If we have a module identifier - use to retrieve the command image name list from it. // Otherwise we will use the global command image list try { - xCmdDesc->getByName( m_aModuleIdentifier ) >>= xCmdDesc; - if ( xCmdDesc.is() ) - xCmdDesc->getByName( aCommandImageList ) >>= aCmdImageSeq; + xCommandDesc->getByName(m_aModuleIdentifier) >>= xCommandDesc; + if (xCommandDesc.is()) + xCommandDesc->getByName(aCommandImageList) >>= aCommandImageSeq; } - catch ( const NoSuchElementException& ) + catch (const NoSuchElementException&) { // Module unknown we will work with an empty command image list! return; } } - if ( xCmdDesc.is() ) + if (xCommandDesc.is()) { try { - xCmdDesc->getByName( aCommandImageList ) >>= aCmdImageSeq; + xCommandDesc->getByName(aCommandImageList) >>= aCommandImageSeq; } - catch ( const NoSuchElementException& ) + catch (const NoSuchElementException&) { } - catch ( const WrappedTargetException& ) + catch (const WrappedTargetException&) { } } - // We have to map commands which uses special characters like '/',':','?','\','<'.'>','|' - OUString aExt = ".png"; - m_aImageCommandNameVector.resize(aCmdImageSeq.getLength() ); - m_aImageNameVector.resize( aCmdImageSeq.getLength() ); - - ::std::copy( aCmdImageSeq.begin(), aCmdImageSeq.end(), - m_aImageCommandNameVector.begin() ); - - // Create a image name vector that must be provided to the vcl imagelist. We also need - // a command to image name map to speed up access time for image retrieval. - OUString aUNOString( ".uno:" ); - OUString aEmptyString; - const sal_uInt32 nCount = m_aImageCommandNameVector.size(); - for ( sal_uInt32 i = 0; i < nCount; i++ ) - { - OUString aCommandName( m_aImageCommandNameVector[i] ); - OUString aImageName; - - if ( aCommandName.indexOf( aUNOString ) != 0 ) - { - INetURLObject aUrlObject( aCommandName, INetURLObject::ENCODE_ALL ); - aImageName = aUrlObject.GetURLPath(); - aImageName = getCanonicalName( aImageName ); // convert to valid filename - } - else - { - // just remove the schema - if ( aCommandName.getLength() > 5 ) - aImageName = aCommandName.copy( 5 ); - else - aImageName = aEmptyString; + m_aResolver.registerCommands(aCommandImageSeq); - // Search for query part. - if ( aImageName.indexOf('?') != -1 ) - aImageName = getCanonicalName( aImageName ); // convert to valid filename - } - // Image names are not case-dependent. Always use lower case characters to - // reflect this. - aImageName += aExt; - aImageName = aImageName.toAsciiLowerCase(); - - m_aImageNameVector[i] = aImageName; - m_aCommandToImageNameMap.insert( CommandToImageNameMap::value_type( aCommandName, aImageName )); - } - - m_bVectorInit = true; - } -} - -ImageList* CmdImageList::impl_getImageList( sal_Int16 nImageType ) -{ - SvtMiscOptions aMiscOptions; - - const OUString& rIconTheme = aMiscOptions.GetIconTheme(); - if ( rIconTheme != m_sIconTheme ) - { - m_sIconTheme = rIconTheme; - for ( sal_Int32 n=0; n < ImageType_COUNT; n++ ) - delete m_pImageList[n], m_pImageList[n] = nullptr; - } - - if ( !m_pImageList[nImageType] ) - { - m_pImageList[nImageType] = new ImageList( m_aImageNameVector, - OUString::createFromAscii( ImageType_Prefixes[nImageType] ) ); + m_bInitialized = true; } - - return m_pImageList[nImageType]; } - -Image CmdImageList::getImageFromCommandURL( sal_Int16 nImageType, const OUString& rCommandURL ) +Image CmdImageList::getImageFromCommandURL(sal_Int16 nImageType, const OUString& rCommandURL) { - impl_fillCommandToImageNameMap(); - CommandToImageNameMap::const_iterator pIter = m_aCommandToImageNameMap.find( rCommandURL ); - if ( pIter != m_aCommandToImageNameMap.end() ) - { - ImageList* pImageList = impl_getImageList( nImageType ); - return pImageList->GetImage( pIter->second ); - } - - return Image(); + initialize(); + return m_aResolver.getImageFromCommandURL(nImageType, rCommandURL); } -bool CmdImageList::hasImage( sal_Int16 /*nImageType*/, const OUString& rCommandURL ) +bool CmdImageList::hasImage(sal_Int16 /*nImageType*/, const OUString& rCommandURL) { - impl_fillCommandToImageNameMap(); - CommandToImageNameMap::const_iterator pIter = m_aCommandToImageNameMap.find( rCommandURL ); - if ( pIter != m_aCommandToImageNameMap.end() ) - return true; - else - return false; + initialize(); + return m_aResolver.hasImage(rCommandURL); } -::std::vector< OUString >& CmdImageList::getImageCommandNames() +std::vector<OUString>& CmdImageList::getImageCommandNames() { - return impl_getImageCommandNameVector(); + return m_aResolver.getCommandNames(); } GlobalImageList::GlobalImageList( const uno::Reference< uno::XComponentContext >& rxContext ) : @@ -330,7 +215,7 @@ bool GlobalImageList::hasImage( sal_Int16 nImageType, const OUString& rCommandUR ::std::vector< OUString >& GlobalImageList::getImageCommandNames() { osl::MutexGuard guard( getGlobalImageListMutex() ); - return impl_getImageCommandNameVector(); + return CmdImageList::getImageCommandNames(); } static bool implts_checkAndScaleGraphic( uno::Reference< XGraphic >& rOutGraphic, const uno::Reference< XGraphic >& rInGraphic, sal_Int16 nImageType ) diff --git a/framework/source/uiconfiguration/imagemanagerimpl.hxx b/framework/source/uiconfiguration/imagemanagerimpl.hxx index 0ac09cc41fc6..f9c36ea3706f 100644 --- a/framework/source/uiconfiguration/imagemanagerimpl.hxx +++ b/framework/source/uiconfiguration/imagemanagerimpl.hxx @@ -41,7 +41,6 @@ #include <cppuhelper/interfacecontainer.hxx> #include <rtl/ustring.hxx> -#include <vcl/image.hxx> #include <rtl/ref.hxx> #include <salhelper/simplereferenceobject.hxx> @@ -49,33 +48,29 @@ #include <unordered_map> #include <vector> +#include <vcl/CommandImageResolver.hxx> + namespace framework { class CmdImageList { public: - CmdImageList( const css::uno::Reference< css::uno::XComponentContext >& rxContext, - const OUString& aModuleIdentifier ); + CmdImageList(const css::uno::Reference< css::uno::XComponentContext >& rxContext, const OUString& aModuleIdentifier); virtual ~CmdImageList(); - virtual Image getImageFromCommandURL( sal_Int16 nImageType, const OUString& rCommandURL ); - virtual bool hasImage( sal_Int16 nImageType, const OUString& rCommandURL ); - virtual ::std::vector< OUString >& getImageCommandNames(); + virtual Image getImageFromCommandURL(sal_Int16 nImageType, const OUString& rCommandURL); + virtual bool hasImage(sal_Int16 nImageType, const OUString& rCommandURL); + virtual std::vector<OUString>& getImageCommandNames(); protected: - void impl_fillCommandToImageNameMap(); - ImageList* impl_getImageList( sal_Int16 nImageType ); - std::vector< OUString >& impl_getImageCommandNameVector() { return m_aImageCommandNameVector;} + void initialize(); private: - bool m_bVectorInit; - OUString m_aModuleIdentifier; - ImageList* m_pImageList[ImageType_COUNT]; - CommandToImageNameMap m_aCommandToImageNameMap; - css::uno::Reference< css::uno::XComponentContext > m_xContext; - ::std::vector< OUString > m_aImageNameVector; - ::std::vector< OUString > m_aImageCommandNameVector; - OUString m_sIconTheme; + bool m_bInitialized; + vcl::CommandImageResolver m_aResolver; + + OUString m_aModuleIdentifier; + css::uno::Reference<css::uno::XComponentContext> m_xContext; }; class GlobalImageList : public CmdImageList, public salhelper::SimpleReferenceObject diff --git a/include/vcl/CommandImageResolver.hxx b/include/vcl/CommandImageResolver.hxx new file mode 100644 index 000000000000..ad09df1bcebd --- /dev/null +++ b/include/vcl/CommandImageResolver.hxx @@ -0,0 +1,64 @@ +/* -*- 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/. + */ + +#ifndef INCLUDED_VCL_COMMANDICONRESOLVER_HXX +#define INCLUDED_VCL_COMMANDICONRESOLVER_HXX + +#include <vcl/dllapi.h> +#include <vcl/image.hxx> + +#include <com/sun/star/uno/Sequence.hxx> + +#include <unordered_map> +#include <vector> + +namespace vcl +{ + +enum ImageType +{ + ImageType_Color = 0, + ImageType_Color_Large, + ImageType_COUNT +}; + +class VCL_DLLPUBLIC CommandImageResolver +{ +private: + typedef std::unordered_map<OUString, OUString, OUStringHash, std::equal_to<OUString>> CommandToImageNameMap; + + CommandToImageNameMap m_aCommandToImageNameMap; + std::vector<OUString> m_aImageCommandNameVector; + std::vector<OUString> m_aImageNameVector; + + ImageList* m_pImageList[ImageType_COUNT]; + OUString m_sIconTheme; + + ImageList* getImageList(sal_Int16 nImageType); + +public: + CommandImageResolver(); + virtual ~CommandImageResolver(); + + bool registerCommands(css::uno::Sequence<OUString>& aCommandSequence); + Image getImageFromCommandURL(sal_Int16 nImageType, const OUString& rCommandURL); + + std::vector<OUString>& getCommandNames() + { + return m_aImageCommandNameVector; + } + + bool hasImage(const OUString& rCommandURL); +}; + +} // end namespace vcl + +#endif // INCLUDED_VCL_COMMANDICONRESOLVER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk index 0da204a390d7..ef21b307b900 100644 --- a/vcl/Library_vcl.mk +++ b/vcl/Library_vcl.mk @@ -328,6 +328,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\ vcl/source/bitmap/BitmapProcessor \ vcl/source/bitmap/BitmapTools \ vcl/source/bitmap/checksum \ + vcl/source/bitmap/CommandImageResolver \ vcl/source/helper/canvasbitmap \ vcl/source/helper/canvastools \ vcl/source/helper/commandinfoprovider \ diff --git a/vcl/source/bitmap/CommandImageResolver.cxx b/vcl/source/bitmap/CommandImageResolver.cxx new file mode 100644 index 000000000000..5c636d70c9bc --- /dev/null +++ b/vcl/source/bitmap/CommandImageResolver.cxx @@ -0,0 +1,161 @@ +/* -*- 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/. + */ + +#include <vcl/CommandImageResolver.hxx> + +#include <rtl/ustrbuf.hxx> +#include <tools/urlobj.hxx> +#include <svtools/miscopt.hxx> +#include <officecfg/Office/Common.hxx> + +using css::uno::Sequence; + +namespace vcl +{ + +namespace +{ + +const char* ImageType_Prefixes[ImageType_COUNT] = +{ + "cmd/sc_", + "cmd/lc_" +}; + +OUString lclConvertToCanonicalName(const OUString& rFileName) +{ + bool bRemoveSlash(true); + sal_Int32 nLength = rFileName.getLength(); + const sal_Unicode* pString = rFileName.getStr(); + + OUStringBuffer aBuffer(nLength); + + for (sal_Int32 i = 0; i < nLength; i++) + { + const sal_Unicode cCurrentChar = pString[i]; + switch (cCurrentChar) + { + // map forbidden characters to escape + case '/': + if (!bRemoveSlash) + aBuffer.append("%2f"); + break; + case '\\': aBuffer.append("%5c"); bRemoveSlash = false; break; + case ':': aBuffer.append("%3a"); bRemoveSlash = false; break; + case '*': aBuffer.append("%2a"); bRemoveSlash = false; break; + case '?': aBuffer.append("%3f"); bRemoveSlash = false; break; + case '<': aBuffer.append("%3c"); bRemoveSlash = false; break; + case '>': aBuffer.append("%3e"); bRemoveSlash = false; break; + case '|': aBuffer.append("%7c"); bRemoveSlash = false; break; + default: + aBuffer.append(cCurrentChar); bRemoveSlash = false; break; + } + } + return aBuffer.makeStringAndClear(); +} + +} // end anonymouse namespace + +CommandImageResolver::CommandImageResolver() +{ + for (sal_Int32 n = 0; n < ImageType_COUNT; n++) + m_pImageList[n] = nullptr; +} + +CommandImageResolver::~CommandImageResolver() +{ + for (sal_Int32 n = 0; n < ImageType_COUNT; n++) + delete m_pImageList[n]; +} + +bool CommandImageResolver::registerCommands(Sequence<OUString>& aCommandSequence) +{ + sal_Int32 nSequenceSize = aCommandSequence.getLength(); + + m_aImageCommandNameVector.resize(nSequenceSize); + m_aImageNameVector.resize(nSequenceSize); + + for (sal_Int32 i = 0; i < nSequenceSize; ++i) + { + OUString aCommandName(aCommandSequence[i]); + OUString aImageName; + + m_aImageCommandNameVector[i] = aCommandName; + + if (aCommandName.indexOf(".uno:") != 0) + { + INetURLObject aUrlObject(aCommandName, INetURLObject::ENCODE_ALL); + aImageName = aUrlObject.GetURLPath(); + aImageName = lclConvertToCanonicalName(aImageName); + } + else + { + // just remove the schema + if (aCommandName.getLength() > 5) + aImageName = aCommandName.copy(5); + + // Search for query part. + if (aImageName.indexOf('?') != -1) + aImageName = lclConvertToCanonicalName(aImageName); + } + + // Image names are not case-dependent. Always use lower case characters to + // reflect this. + aImageName = aImageName.toAsciiLowerCase(); + aImageName += ".png"; + + m_aImageNameVector[i] = aImageName; + m_aCommandToImageNameMap[aCommandName] = aImageName; + } + return true; +} + +bool CommandImageResolver::hasImage(const OUString& rCommandURL) +{ + CommandToImageNameMap::const_iterator pIterator = m_aCommandToImageNameMap.find(rCommandURL); + return pIterator != m_aCommandToImageNameMap.end(); +} + +ImageList* CommandImageResolver::getImageList(sal_Int16 nImageType) +{ + const OUString& rIconTheme = officecfg::Office::Common::Misc::SymbolStyle::get(); + + if (rIconTheme != m_sIconTheme) + { + m_sIconTheme = rIconTheme; + for (sal_Int32 n = 0; n < ImageType_COUNT; ++n) + { + delete m_pImageList[n]; + m_pImageList[n] = nullptr; + } + } + + if (!m_pImageList[nImageType]) + { + OUString sIconPath = OUString::createFromAscii(ImageType_Prefixes[nImageType]); + m_pImageList[nImageType] = new ImageList(m_aImageNameVector, sIconPath); + } + + return m_pImageList[nImageType]; +} + +Image CommandImageResolver::getImageFromCommandURL(sal_Int16 nImageType, const OUString& rCommandURL) +{ + CommandToImageNameMap::const_iterator pIterator = m_aCommandToImageNameMap.find(rCommandURL); + if (pIterator != m_aCommandToImageNameMap.end()) + { + ImageList* pImageList = getImageList(nImageType); + return pImageList->GetImage(pIterator->second); + } + return Image(); +} + +} // end namespace vcl + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |