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 //-----------------------------------------------
AcceleratorCache()56 AcceleratorCache::AcceleratorCache()
57 : ThreadHelpBase(&Application::GetSolarMutex())
58 {
59 }
60
61 //-----------------------------------------------
AcceleratorCache(const AcceleratorCache & rCopy)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 //-----------------------------------------------
~AcceleratorCache()70 AcceleratorCache::~AcceleratorCache()
71 {
72 // Dont save anything automatically here.
73 // The user has to do that explicitly!
74 }
75
76 //-----------------------------------------------
takeOver(const AcceleratorCache & rCopy)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 //-----------------------------------------------
operator =(const AcceleratorCache & rCopy)90 AcceleratorCache& AcceleratorCache::operator=(const AcceleratorCache& rCopy)
91 {
92 takeOver(rCopy);
93 return *this;
94 }
95
96 //-----------------------------------------------
hasKey(const css::awt::KeyEvent & aKey) const97 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 //-----------------------------------------------
hasCommand(const::rtl::OUString & sCommand) const107 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 //-----------------------------------------------
getAllKeys() const117 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 //-----------------------------------------------
setKeyCommandPair(const css::awt::KeyEvent & aKey,const::rtl::OUString & sCommand)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 //-----------------------------------------------
getKeysByCommand(const::rtl::OUString & sCommand) const159 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 //-----------------------------------------------
getCommandByKey(const css::awt::KeyEvent & aKey) const179 ::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 //-----------------------------------------------
removeKey(const css::awt::KeyEvent & aKey)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 //-----------------------------------------------
removeCommand(const::rtl::OUString & sCommand)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