1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_framework.hxx" 26 #include <accelerators/acceleratorcache.hxx> 27 28 //_______________________________________________ 29 // own includes 30 31 #ifndef __FRAMEWORK_XML_ACCELERATORCONFIGURATIONREADER_HXX_ 32 #include <xml/acceleratorconfigurationreader.hxx> 33 #endif 34 #include <threadhelp/readguard.hxx> 35 #include <threadhelp/writeguard.hxx> 36 37 //_______________________________________________ 38 // interface includes 39 40 #ifndef __COM_SUN_STAR_CONTAINER_ELEMENTEXISTEXCEPTION_HPP_ 41 #include <com/sun/star/container/ElementExistException.hpp> 42 #endif 43 44 #ifndef __COM_SUN_STAR_CONTAINER_NOSUCHELEMENTEXCEPTION_HPP_ 45 #include <com/sun/star/container/NoSuchElementException.hpp> 46 #endif 47 48 //_______________________________________________ 49 // other includes 50 #include <vcl/svapp.hxx> 51 52 namespace framework 53 { 54 55 //----------------------------------------------- 56 AcceleratorCache::AcceleratorCache() 57 : ThreadHelpBase(&Application::GetSolarMutex()) 58 { 59 } 60 61 //----------------------------------------------- 62 AcceleratorCache::AcceleratorCache(const AcceleratorCache& rCopy) 63 : ThreadHelpBase(&Application::GetSolarMutex()) 64 { 65 m_lCommand2Keys = rCopy.m_lCommand2Keys; 66 m_lKey2Commands = rCopy.m_lKey2Commands; 67 } 68 69 //----------------------------------------------- 70 AcceleratorCache::~AcceleratorCache() 71 { 72 // Dont save anything automaticly here. 73 // The user has to do that explicitly! 74 } 75 76 //----------------------------------------------- 77 void AcceleratorCache::takeOver(const AcceleratorCache& rCopy) 78 { 79 // SAFE -> ---------------------------------- 80 WriteGuard aWriteLock(m_aLock); 81 82 m_lCommand2Keys = rCopy.m_lCommand2Keys; 83 m_lKey2Commands = rCopy.m_lKey2Commands; 84 85 aWriteLock.unlock(); 86 // <- SAFE ---------------------------------- 87 } 88 89 //----------------------------------------------- 90 AcceleratorCache& AcceleratorCache::operator=(const AcceleratorCache& rCopy) 91 { 92 takeOver(rCopy); 93 return *this; 94 } 95 96 //----------------------------------------------- 97 sal_Bool AcceleratorCache::hasKey(const css::awt::KeyEvent& aKey) const 98 { 99 // SAFE -> ---------------------------------- 100 ReadGuard aReadLock(m_aLock); 101 102 return (m_lKey2Commands.find(aKey) != m_lKey2Commands.end()); 103 // <- SAFE ---------------------------------- 104 } 105 106 //----------------------------------------------- 107 sal_Bool AcceleratorCache::hasCommand(const ::rtl::OUString& sCommand) const 108 { 109 // SAFE -> ---------------------------------- 110 ReadGuard aReadLock(m_aLock); 111 112 return (m_lCommand2Keys.find(sCommand) != m_lCommand2Keys.end()); 113 // <- SAFE ---------------------------------- 114 } 115 116 //----------------------------------------------- 117 AcceleratorCache::TKeyList AcceleratorCache::getAllKeys() const 118 { 119 TKeyList lKeys; 120 121 // SAFE -> ---------------------------------- 122 ReadGuard aReadLock(m_aLock); 123 lKeys.reserve(m_lKey2Commands.size()); 124 125 TKey2Commands::const_iterator pIt; 126 TKey2Commands::const_iterator pEnd = m_lKey2Commands.end(); 127 for ( pIt = m_lKey2Commands.begin(); 128 pIt != pEnd ; 129 ++pIt ) 130 { 131 lKeys.push_back(pIt->first); 132 } 133 134 aReadLock.unlock(); 135 // <- SAFE ---------------------------------- 136 137 return lKeys; 138 } 139 140 //----------------------------------------------- 141 void AcceleratorCache::setKeyCommandPair(const css::awt::KeyEvent& aKey , 142 const ::rtl::OUString& sCommand) 143 { 144 // SAFE -> ---------------------------------- 145 WriteGuard aWriteLock(m_aLock); 146 147 // register command for the specified key 148 m_lKey2Commands[aKey] = sCommand; 149 150 // update optimized structure to bind multiple keys to one command 151 TKeyList& rKeyList = m_lCommand2Keys[sCommand]; 152 rKeyList.push_back(aKey); 153 154 aWriteLock.unlock(); 155 // <- SAFE ---------------------------------- 156 } 157 158 //----------------------------------------------- 159 AcceleratorCache::TKeyList AcceleratorCache::getKeysByCommand(const ::rtl::OUString& sCommand) const 160 { 161 TKeyList lKeys; 162 163 // SAFE -> ---------------------------------- 164 ReadGuard aReadLock(m_aLock); 165 166 TCommand2Keys::const_iterator pCommand = m_lCommand2Keys.find(sCommand); 167 if (pCommand == m_lCommand2Keys.end()) 168 throw css::container::NoSuchElementException( 169 ::rtl::OUString(), css::uno::Reference< css::uno::XInterface >()); 170 lKeys = pCommand->second; 171 172 aReadLock.unlock(); 173 // <- SAFE ---------------------------------- 174 175 return lKeys; 176 } 177 178 //----------------------------------------------- 179 ::rtl::OUString AcceleratorCache::getCommandByKey(const css::awt::KeyEvent& aKey) const 180 { 181 ::rtl::OUString sCommand; 182 183 // SAFE -> ---------------------------------- 184 ReadGuard aReadLock(m_aLock); 185 186 TKey2Commands::const_iterator pKey = m_lKey2Commands.find(aKey); 187 if (pKey == m_lKey2Commands.end()) 188 throw css::container::NoSuchElementException( 189 ::rtl::OUString(), css::uno::Reference< css::uno::XInterface >()); 190 sCommand = pKey->second; 191 192 aReadLock.unlock(); 193 // <- SAFE ---------------------------------- 194 195 return sCommand; 196 } 197 198 //----------------------------------------------- 199 void AcceleratorCache::removeKey(const css::awt::KeyEvent& aKey) 200 { 201 // SAFE -> ---------------------------------- 202 WriteGuard aWriteLock(m_aLock); 203 204 // check if key exists 205 TKey2Commands::const_iterator pKey = m_lKey2Commands.find(aKey); 206 if (pKey == m_lKey2Commands.end()) 207 return; 208 209 // get its registered command 210 // Because we must know its place inside the optimized 211 // structure, which bind keys to commands, too! 212 ::rtl::OUString sCommand = pKey->second; 213 pKey = m_lKey2Commands.end(); // nobody should use an undefined value .-) 214 215 // remove key from primary list 216 m_lKey2Commands.erase(aKey); 217 218 // remove key from optimized command list 219 m_lCommand2Keys.erase(sCommand); 220 221 aWriteLock.unlock(); 222 // <- SAFE ---------------------------------- 223 } 224 225 //----------------------------------------------- 226 void AcceleratorCache::removeCommand(const ::rtl::OUString& sCommand) 227 { 228 // SAFE -> ---------------------------------- 229 WriteGuard aWriteLock(m_aLock); 230 231 const TKeyList& lKeys = getKeysByCommand(sCommand); 232 AcceleratorCache::TKeyList::const_iterator pKey ; 233 for ( pKey = lKeys.begin(); 234 pKey != lKeys.end() ; 235 ++pKey ) 236 { 237 const css::awt::KeyEvent& rKey = *pKey; 238 removeKey(rKey); 239 } 240 m_lCommand2Keys.erase(sCommand); 241 242 aWriteLock.unlock(); 243 // <- SAFE ---------------------------------- 244 } 245 246 } // namespace framework 247