1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 5 * This Source Code Form is subject to the terms of the Mozilla Public 6 * License, v. 2.0. If a copy of the MPL was not distributed with this 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 */ 9 10 #include "CommandImageResolver.hxx" 11 #include <vcl/settings.hxx> 12 #include <vcl/svapp.hxx> 13 #include <rtl/ustrbuf.hxx> 14 #include <tools/urlobj.hxx> 15 16 using css::uno::Sequence; 17 18 namespace vcl 19 { 20 21 namespace 22 { 23 24 constexpr o3tl::enumarray<ImageType, OUString> ImageType_Prefixes 25 { 26 u"cmd/sc_"_ustr, 27 u"cmd/lc_"_ustr, 28 u"cmd/32/"_ustr 29 }; 30 lclConvertToCanonicalName(const OUString & rFileName)31OUString lclConvertToCanonicalName(const OUString& rFileName) 32 { 33 bool bRemoveSlash(true); 34 sal_Int32 nLength = rFileName.getLength(); 35 const sal_Unicode* pString = rFileName.getStr(); 36 37 OUStringBuffer aBuffer(nLength*2); 38 39 for (sal_Int32 i = 0; i < nLength; i++) 40 { 41 const sal_Unicode cCurrentChar = pString[i]; 42 switch (cCurrentChar) 43 { 44 // map forbidden characters to escape 45 case '/': 46 if (!bRemoveSlash) 47 aBuffer.append("%2f"); 48 break; 49 case '\\': aBuffer.append("%5c"); bRemoveSlash = false; break; 50 case ':': aBuffer.append("%3a"); bRemoveSlash = false; break; 51 case '*': aBuffer.append("%2a"); bRemoveSlash = false; break; 52 case '?': aBuffer.append("%3f"); bRemoveSlash = false; break; 53 case '<': aBuffer.append("%3c"); bRemoveSlash = false; break; 54 case '>': aBuffer.append("%3e"); bRemoveSlash = false; break; 55 case '|': aBuffer.append("%7c"); bRemoveSlash = false; break; 56 default: 57 aBuffer.append(cCurrentChar); bRemoveSlash = false; break; 58 } 59 } 60 return aBuffer.makeStringAndClear(); 61 } 62 63 } // end anonymous namespace 64 CommandImageResolver()65CommandImageResolver::CommandImageResolver() 66 { 67 } 68 ~CommandImageResolver()69CommandImageResolver::~CommandImageResolver() 70 { 71 } 72 registerCommands(const Sequence<OUString> & aCommandSequence)73void CommandImageResolver::registerCommands(const Sequence<OUString>& aCommandSequence) 74 { 75 sal_Int32 nSequenceSize = aCommandSequence.getLength(); 76 77 m_aImageCommandNameVector.resize(nSequenceSize); 78 m_aImageNameVector.resize(nSequenceSize); 79 80 for (sal_Int32 i = 0; i < nSequenceSize; ++i) 81 { 82 OUString aCommandName(aCommandSequence[i]); 83 OUString aImageName; 84 85 m_aImageCommandNameVector[i] = aCommandName; 86 87 if (aCommandName.indexOf(".uno:") != 0) 88 { 89 INetURLObject aUrlObject(aCommandName, INetURLObject::EncodeMechanism::All); 90 aImageName = aUrlObject.GetURLPath(); 91 aImageName = lclConvertToCanonicalName(aImageName); 92 } 93 else 94 { 95 // just remove the schema 96 if (aCommandName.getLength() > 5) 97 aImageName = aCommandName.copy(5); 98 99 // Search for query part. 100 if (aImageName.indexOf('?') != -1) 101 aImageName = lclConvertToCanonicalName(aImageName); 102 } 103 104 // Image names are not case-dependent. Always use lower case characters to 105 // reflect this. 106 aImageName = aImageName.toAsciiLowerCase() + ".png"; 107 108 m_aImageNameVector[i] = aImageName; 109 m_aCommandToImageNameMap[aCommandName] = aImageName; 110 } 111 } 112 hasImage(const OUString & rCommandURL)113bool CommandImageResolver::hasImage(const OUString& rCommandURL) 114 { 115 CommandToImageNameMap::const_iterator pIterator = m_aCommandToImageNameMap.find(rCommandURL); 116 return pIterator != m_aCommandToImageNameMap.end(); 117 } 118 getImageList(ImageType nImageType)119ImageList* CommandImageResolver::getImageList(ImageType nImageType) 120 { 121 const OUString sIconTheme = Application::GetSettings().GetStyleSettings().DetermineIconTheme(); 122 123 if (sIconTheme != m_sIconTheme) 124 { 125 m_sIconTheme = sIconTheme; 126 for (auto& rp : m_pImageList) 127 rp.reset(); 128 } 129 130 if (!m_pImageList[nImageType]) 131 { 132 OUString sIconPath = ImageType_Prefixes[nImageType]; 133 m_pImageList[nImageType].reset( new ImageList(m_aImageNameVector, sIconPath) ); 134 } 135 136 return m_pImageList[nImageType].get(); 137 } 138 getImageFromCommandURL(ImageType nImageType,const OUString & rCommandURL)139Image CommandImageResolver::getImageFromCommandURL(ImageType nImageType, const OUString& rCommandURL) 140 { 141 CommandToImageNameMap::const_iterator pIterator = m_aCommandToImageNameMap.find(rCommandURL); 142 if (pIterator != m_aCommandToImageNameMap.end()) 143 { 144 ImageList* pImageList = getImageList(nImageType); 145 return pImageList->GetImage(pIterator->second); 146 } 147 return Image(); 148 } 149 150 } // end namespace vcl 151 152 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 153
