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 "acceleratorexecute.hxx"
27
28 //===============================================
29 // includes
30
31 #ifndef __COM_SUN_STAR_FRAME_XMODULEMANAGER_HPP_
32 #include <com/sun/star/frame/XModuleManager.hpp>
33 #endif
34
35 #ifndef __COM_SUN_STAR_UI_XUICONFIGURATIONMANAGER_HPP_
36 #include <com/sun/star/ui/XUIConfigurationManager.hpp>
37 #endif
38
39 #ifndef __COM_SUN_STAR_UI_XMODULEUICONFIGURATIONMANAGERSUPPLIER_HPP_
40 #include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
41 #endif
42
43 #ifndef __COM_SUN_STAR_UI_XUICONFIGURATIONMANAGERSUPPLIER_HPP_
44 #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
45 #endif
46
47 #ifndef __COM_SUN_STAR_AWT_KEYMODIFIER_HPP_
48 #include <com/sun/star/awt/KeyModifier.hpp>
49 #endif
50
51 #ifndef __COM_SUN_STAR_UNO_SEQUENCE_HXX_
52 #include <com/sun/star/uno/Sequence.hxx>
53 #endif
54
55 #ifndef __COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
56 #include <com/sun/star/beans/PropertyValue.hpp>
57 #endif
58
59 //===============================================
60 // namespace
61
62 namespace svt
63 {
64
65 namespace css = ::com::sun::star;
66
67 //===============================================
68 // definitions
69
70 //-----------------------------------------------
AcceleratorExecute()71 AcceleratorExecute::AcceleratorExecute()
72 : TMutexInit ( )
73 , m_aAsyncCallback(LINK(this, AcceleratorExecute, impl_ts_asyncCallback))
74 {
75 }
76
77 //-----------------------------------------------
AcceleratorExecute(const AcceleratorExecute & rCopy)78 AcceleratorExecute::AcceleratorExecute(const AcceleratorExecute& rCopy)
79 : TMutexInit ( )
80 , m_aAsyncCallback(LINK(this, AcceleratorExecute, impl_ts_asyncCallback))
81 {
82 // copy construction sint supported in real ...
83 // but we need this ctor to init our async callback ...
84 }
85
86 //-----------------------------------------------
~AcceleratorExecute()87 AcceleratorExecute::~AcceleratorExecute()
88 {
89 // does nothing real
90 }
91
92 //-----------------------------------------------
createAcceleratorHelper()93 AcceleratorExecute* AcceleratorExecute::createAcceleratorHelper()
94 {
95 AcceleratorExecute* pNew = new AcceleratorExecute();
96 return pNew;
97 }
98
99 //-----------------------------------------------
init(const css::uno::Reference<css::lang::XMultiServiceFactory> & xSMGR,const css::uno::Reference<css::frame::XFrame> & xEnv)100 void AcceleratorExecute::init(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR,
101 const css::uno::Reference< css::frame::XFrame >& xEnv )
102 {
103 // SAFE -> ----------------------------------
104 ::osl::ResettableMutexGuard aLock(m_aLock);
105
106 // take over the uno service manager
107 m_xSMGR = xSMGR;
108
109 // specify our internal dispatch provider
110 // frame or desktop?! => document or global config.
111 sal_Bool bDesktopIsUsed = sal_False;
112 m_xDispatcher = css::uno::Reference< css::frame::XDispatchProvider >(xEnv, css::uno::UNO_QUERY);
113 if (!m_xDispatcher.is())
114 {
115 aLock.clear();
116 // <- SAFE ------------------------------
117
118 css::uno::Reference< css::frame::XDispatchProvider > xDispatcher(
119 xSMGR->createInstance(SERVICENAME_DESKTOP),
120 css::uno::UNO_QUERY_THROW);
121
122 // SAFE -> ------------------------------
123 aLock.reset();
124
125 m_xDispatcher = xDispatcher;
126 bDesktopIsUsed = sal_True;
127 }
128
129 aLock.clear();
130 // <- SAFE ----------------------------------
131
132 // open all needed configuration objects
133 css::uno::Reference< css::ui::XAcceleratorConfiguration > xGlobalCfg;
134 css::uno::Reference< css::ui::XAcceleratorConfiguration > xModuleCfg;
135 css::uno::Reference< css::ui::XAcceleratorConfiguration > xDocCfg ;
136
137 // global cfg
138 xGlobalCfg = AcceleratorExecute::impl_st_openGlobalConfig(xSMGR);
139 if (!bDesktopIsUsed)
140 {
141 // module cfg
142 xModuleCfg = AcceleratorExecute::impl_st_openModuleConfig(xSMGR, xEnv);
143
144 // doc cfg
145 css::uno::Reference< css::frame::XController > xController;
146 css::uno::Reference< css::frame::XModel > xModel;
147 xController = xEnv->getController();
148 if (xController.is())
149 xModel = xController->getModel();
150 if (xModel.is())
151 xDocCfg = AcceleratorExecute::impl_st_openDocConfig(xModel);
152 }
153
154 // SAFE -> ------------------------------
155 aLock.reset();
156
157 m_xGlobalCfg = xGlobalCfg;
158 m_xModuleCfg = xModuleCfg;
159 m_xDocCfg = xDocCfg ;
160
161 aLock.clear();
162 // <- SAFE ----------------------------------
163 }
164
165 //-----------------------------------------------
execute(const KeyCode & aVCLKey)166 void AcceleratorExecute::execute(const KeyCode& aVCLKey)
167 {
168 css::awt::KeyEvent aAWTKey = AcceleratorExecute::st_VCLKey2AWTKey(aVCLKey);
169 execute(aAWTKey);
170 }
171
172 //-----------------------------------------------
execute(const css::awt::KeyEvent & aAWTKey)173 void AcceleratorExecute::execute(const css::awt::KeyEvent& aAWTKey)
174 {
175 ::rtl::OUString sCommand = impl_ts_findCommand(aAWTKey);
176
177 // No Command found? Do nothing! User isn't interested on any error handling .-)
178 if (!sCommand.getLength())
179 return;
180
181 // SAFE -> ----------------------------------
182 ::osl::ResettableMutexGuard aLock(m_aLock);
183
184 m_lCommandQueue.push_back(sCommand);
185 m_aAsyncCallback.Post(0);
186
187 aLock.clear();
188 // <- SAFE ----------------------------------
189 }
190
191 //-----------------------------------------------
st_VCLKey2AWTKey(const KeyCode & aVCLKey)192 css::awt::KeyEvent AcceleratorExecute::st_VCLKey2AWTKey(const KeyCode& aVCLKey)
193 {
194 css::awt::KeyEvent aAWTKey;
195 aAWTKey.Modifiers = 0;
196 aAWTKey.KeyCode = (sal_Int16)aVCLKey.GetCode();
197
198 if (aVCLKey.IsShift())
199 aAWTKey.Modifiers |= css::awt::KeyModifier::SHIFT;
200 if (aVCLKey.IsMod1())
201 aAWTKey.Modifiers |= css::awt::KeyModifier::MOD1;
202 if (aVCLKey.IsMod2())
203 aAWTKey.Modifiers |= css::awt::KeyModifier::MOD2;
204 if (aVCLKey.IsMod3())
205 aAWTKey.Modifiers |= css::awt::KeyModifier::MOD3;
206
207 return aAWTKey;
208 }
209
210 /*
211 ViewFrame->GetObjectShell
212 ObjectShell->GetStyleSheetPool
213 */
214
215 //-----------------------------------------------
st_AWTKey2VCLKey(const css::awt::KeyEvent & aAWTKey)216 KeyCode AcceleratorExecute::st_AWTKey2VCLKey(const css::awt::KeyEvent& aAWTKey)
217 {
218 sal_Bool bShift = ((aAWTKey.Modifiers & css::awt::KeyModifier::SHIFT) == css::awt::KeyModifier::SHIFT );
219 sal_Bool bMod1 = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD1 ) == css::awt::KeyModifier::MOD1 );
220 sal_Bool bMod2 = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD2 ) == css::awt::KeyModifier::MOD2 );
221 sal_Bool bMod3 = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD3 ) == css::awt::KeyModifier::MOD3 );
222 sal_uInt16 nKey = (sal_uInt16)aAWTKey.KeyCode;
223
224 return KeyCode(nKey, bShift, bMod1, bMod2, bMod3);
225 }
226
227 //-----------------------------------------------
impl_ts_findCommand(const css::awt::KeyEvent & aKey)228 ::rtl::OUString AcceleratorExecute::impl_ts_findCommand(const css::awt::KeyEvent& aKey)
229 {
230 // SAFE -> ----------------------------------
231 ::osl::ResettableMutexGuard aLock(m_aLock);
232
233 css::uno::Reference< css::ui::XAcceleratorConfiguration > xGlobalCfg = m_xGlobalCfg;
234 css::uno::Reference< css::ui::XAcceleratorConfiguration > xModuleCfg = m_xModuleCfg;
235 css::uno::Reference< css::ui::XAcceleratorConfiguration > xDocCfg = m_xDocCfg ;
236
237 aLock.clear();
238 // <- SAFE ----------------------------------
239
240 ::rtl::OUString sCommand;
241 try
242 {
243 if (xDocCfg.is())
244 sCommand = xDocCfg->getCommandByKeyEvent(aKey);
245 }
246 catch(const css::container::NoSuchElementException&)
247 {
248 try
249 {
250 if (xModuleCfg.is())
251 sCommand = xModuleCfg->getCommandByKeyEvent(aKey);
252 }
253 catch(const css::container::NoSuchElementException&)
254 {
255 try
256 {
257 if (xGlobalCfg.is())
258 sCommand = xGlobalCfg->getCommandByKeyEvent(aKey);
259 }
260 catch(const css::container::NoSuchElementException&)
261 {}
262 }
263 }
264
265 return sCommand;
266 }
267
268 //-----------------------------------------------
impl_st_openGlobalConfig(const css::uno::Reference<css::lang::XMultiServiceFactory> & xSMGR)269 css::uno::Reference< css::ui::XAcceleratorConfiguration > AcceleratorExecute::impl_st_openGlobalConfig(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
270 {
271 css::uno::Reference< css::ui::XAcceleratorConfiguration > xAccCfg(
272 xSMGR->createInstance(SERVICENAME_GLOBALACCELERATORCONFIGURATION),
273 css::uno::UNO_QUERY_THROW);
274 return xAccCfg;
275 }
276
277 //-----------------------------------------------
impl_st_openModuleConfig(const css::uno::Reference<css::lang::XMultiServiceFactory> & xSMGR,const css::uno::Reference<css::frame::XFrame> & xFrame)278 css::uno::Reference< css::ui::XAcceleratorConfiguration > AcceleratorExecute::impl_st_openModuleConfig(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
279 const css::uno::Reference< css::frame::XFrame >& xFrame)
280 {
281 css::uno::Reference< css::frame::XModuleManager > xModuleDetection(
282 xSMGR->createInstance(SERVICENAME_MODULEMANAGER),
283 css::uno::UNO_QUERY_THROW);
284
285 ::rtl::OUString sModule;
286 try
287 {
288 sModule = xModuleDetection->identify(xFrame);
289 }
290 catch(const css::uno::RuntimeException& exRuntime)
291 { throw exRuntime; }
292 catch(const css::uno::Exception&)
293 { return css::uno::Reference< css::ui::XAcceleratorConfiguration >(); }
294
295 css::uno::Reference< css::ui::XModuleUIConfigurationManagerSupplier > xUISupplier(
296 xSMGR->createInstance(SERVICENAME_MODULEUICONFIGURATIONMANAGERSUPPLIER),
297 css::uno::UNO_QUERY_THROW);
298
299 css::uno::Reference< css::ui::XUIConfigurationManager > xUIManager = xUISupplier->getUIConfigurationManager(sModule);
300 css::uno::Reference< css::ui::XAcceleratorConfiguration > xAccCfg (xUIManager->getShortCutManager(), css::uno::UNO_QUERY_THROW);
301 return xAccCfg;
302 }
303
304 //-----------------------------------------------
impl_st_openDocConfig(const css::uno::Reference<css::frame::XModel> & xModel)305 css::uno::Reference< css::ui::XAcceleratorConfiguration > AcceleratorExecute::impl_st_openDocConfig(const css::uno::Reference< css::frame::XModel >& xModel)
306 {
307 css::uno::Reference< css::ui::XUIConfigurationManagerSupplier > xUISupplier(xModel, css::uno::UNO_QUERY_THROW);
308 css::uno::Reference< css::ui::XUIConfigurationManager > xUIManager = xUISupplier->getUIConfigurationManager();
309 css::uno::Reference< css::ui::XAcceleratorConfiguration > xAccCfg (xUIManager->getShortCutManager(), css::uno::UNO_QUERY_THROW);
310 return xAccCfg;
311 }
312
313 //-----------------------------------------------
impl_ts_getURLParser()314 css::uno::Reference< css::util::XURLTransformer > AcceleratorExecute::impl_ts_getURLParser()
315 {
316 // SAFE -> ----------------------------------
317 ::osl::ResettableMutexGuard aLock(m_aLock);
318
319 if (m_xURLParser.is())
320 return m_xURLParser;
321 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
322
323 aLock.clear();
324 // <- SAFE ----------------------------------
325
326 css::uno::Reference< css::util::XURLTransformer > xParser(
327 xSMGR->createInstance(SERVICENAME_URLTRANSFORMER),
328 css::uno::UNO_QUERY_THROW);
329
330 // SAFE -> ----------------------------------
331 aLock.reset();
332 m_xURLParser = xParser;
333 aLock.clear();
334 // <- SAFE ----------------------------------
335
336 return xParser;
337 }
338
339 //-----------------------------------------------
IMPL_LINK(AcceleratorExecute,impl_ts_asyncCallback,void *,pVoid)340 IMPL_LINK(AcceleratorExecute, impl_ts_asyncCallback, void*, pVoid)
341 {
342 // SAFE -> ----------------------------------
343 ::osl::ResettableMutexGuard aLock(m_aLock);
344
345 TCommandQueue::iterator pIt = m_lCommandQueue.begin();
346 if (pIt == m_lCommandQueue.end())
347 return 0;
348 ::rtl::OUString sCommand = *pIt;
349 m_lCommandQueue.erase(pIt);
350
351 css::uno::Reference< css::frame::XDispatchProvider > xProvider = m_xDispatcher;
352
353 aLock.clear();
354 // <- SAFE ----------------------------------
355
356 // convert command in URL structure
357 css::uno::Reference< css::util::XURLTransformer > xParser = impl_ts_getURLParser();
358 css::util::URL aURL;
359 aURL.Complete = sCommand;
360 xParser->parseStrict(aURL);
361
362 // ask for dispatch object
363 css::uno::Reference< css::frame::XDispatch > xDispatch = xProvider->queryDispatch(aURL, ::rtl::OUString(), 0);
364 css::uno::Sequence< css::beans::PropertyValue> aArgs;
365 if (xDispatch.is())
366 {
367 if(::comphelper::UiEventsLogger::isEnabled()) //#i88653#
368 {
369 Sequence<css::beans::PropertyValue> source;
370 ::comphelper::UiEventsLogger::appendDispatchOrigin(OUString::createFromAscii("AcceleratorExecute"));
371 ::comphelper::UiEventsLogger::logDispatch(aURL, source);
372 }
373 xDispatch->dispatch(aURL, css::uno::Sequence< css::beans::PropertyValue >());
374 }
375 return 0;
376 }
377
378 } // namespace svt
379