Bump version to 5.0-14
[LibreOffice.git] / svtools / source / misc / acceleratorexecute.cxx
blobf8c67f3db5bbf088f0874bcf814a59e0b6754959
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <svtools/acceleratorexecute.hxx>
22 #include <com/sun/star/frame/ModuleManager.hpp>
23 #include <com/sun/star/frame/Desktop.hpp>
24 #include <com/sun/star/ui/GlobalAcceleratorConfiguration.hpp>
25 #include <com/sun/star/ui/XUIConfigurationManager.hpp>
26 #include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
27 #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
28 #include <com/sun/star/awt/XTopWindow.hpp>
29 #include <com/sun/star/awt/KeyModifier.hpp>
30 #include <com/sun/star/uno/Sequence.hxx>
31 #include <com/sun/star/beans/PropertyValue.hpp>
32 #include <com/sun/star/lang/DisposedException.hpp>
33 #include <com/sun/star/util/URLTransformer.hpp>
34 #include <toolkit/helper/vclunohelper.hxx>
35 #include <comphelper/processfactory.hxx>
37 #include <vcl/window.hxx>
38 #include <vcl/svapp.hxx>
39 #include <osl/mutex.hxx>
42 namespace svt
47 class SVT_DLLPRIVATE AsyncAccelExec
49 public:
51 /** creates a new instance of this class, which can be used
52 one times only!
54 This instance can be forced to execute it's internal set request
55 asynchronous. After that it deletes itself !
57 static AsyncAccelExec* createOnShotInstance(const css::uno::Reference< css::frame::XDispatch >& xDispatch,
58 const css::util::URL& aURL );
60 void execAsync();
62 private:
64 /** @short allow creation of instances of this class
65 by using our factory only!
67 SVT_DLLPRIVATE AsyncAccelExec(const css::uno::Reference< css::frame::XDispatch >& xDispatch,
68 const css::util::URL& aURL );
70 DECL_DLLPRIVATE_LINK(impl_ts_asyncCallback, void*);
72 private:
73 vcl::EventPoster m_aAsyncCallback;
74 css::uno::Reference< css::frame::XDispatch > m_xDispatch;
75 css::util::URL m_aURL;
79 AcceleratorExecute::AcceleratorExecute()
80 : TMutexInit ( )
81 , m_aAsyncCallback(LINK(this, AcceleratorExecute, impl_ts_asyncCallback))
85 AcceleratorExecute::~AcceleratorExecute()
87 // does nothing real
91 AcceleratorExecute* AcceleratorExecute::createAcceleratorHelper()
93 AcceleratorExecute* pNew = new AcceleratorExecute();
94 return pNew;
98 void AcceleratorExecute::init(const css::uno::Reference< css::uno::XComponentContext >& rxContext,
99 const css::uno::Reference< css::frame::XFrame >& xEnv )
101 // SAFE -> ----------------------------------
102 ::osl::ResettableMutexGuard aLock(m_aLock);
104 // take over the uno service manager
105 m_xContext = rxContext;
107 // specify our internal dispatch provider
108 // frame or desktop?! => document or global config.
109 bool bDesktopIsUsed = false;
110 m_xDispatcher = css::uno::Reference< css::frame::XDispatchProvider >(xEnv, css::uno::UNO_QUERY);
111 if (!m_xDispatcher.is())
113 aLock.clear();
114 // <- SAFE ------------------------------
116 css::uno::Reference< css::frame::XDispatchProvider > xDispatcher(css::frame::Desktop::create(rxContext), css::uno::UNO_QUERY_THROW);
118 // SAFE -> ------------------------------
119 aLock.reset();
121 m_xDispatcher = xDispatcher;
122 bDesktopIsUsed = true;
125 aLock.clear();
126 // <- SAFE ----------------------------------
128 // open all needed configuration objects
129 css::uno::Reference< css::ui::XAcceleratorConfiguration > xGlobalCfg;
130 css::uno::Reference< css::ui::XAcceleratorConfiguration > xModuleCfg;
131 css::uno::Reference< css::ui::XAcceleratorConfiguration > xDocCfg ;
133 // global cfg
134 xGlobalCfg = css::ui::GlobalAcceleratorConfiguration::create(rxContext);
135 if (!bDesktopIsUsed)
137 // module cfg
138 xModuleCfg = AcceleratorExecute::st_openModuleConfig(rxContext, xEnv);
140 // doc cfg
141 css::uno::Reference< css::frame::XController > xController;
142 css::uno::Reference< css::frame::XModel > xModel;
143 xController = xEnv->getController();
144 if (xController.is())
145 xModel = xController->getModel();
146 if (xModel.is())
147 xDocCfg = AcceleratorExecute::st_openDocConfig(xModel);
150 // SAFE -> ------------------------------
151 aLock.reset();
153 m_xGlobalCfg = xGlobalCfg;
154 m_xModuleCfg = xModuleCfg;
155 m_xDocCfg = xDocCfg ;
157 aLock.clear();
158 // <- SAFE ----------------------------------
162 bool AcceleratorExecute::execute(const vcl::KeyCode& aVCLKey)
164 css::awt::KeyEvent aAWTKey = AcceleratorExecute::st_VCLKey2AWTKey(aVCLKey);
165 return execute(aAWTKey);
169 bool AcceleratorExecute::execute(const css::awt::KeyEvent& aAWTKey)
171 OUString sCommand = impl_ts_findCommand(aAWTKey);
173 // No Command found? Do nothing! User is not interested on any error handling .-)
174 // or for some reason m_xContext is NULL (which would crash impl_ts_getURLParser()
175 if (sCommand.isEmpty() || !m_xContext.is())
177 return false;
180 // SAFE -> ----------------------------------
181 ::osl::ResettableMutexGuard aLock(m_aLock);
183 css::uno::Reference< css::frame::XDispatchProvider > xProvider = m_xDispatcher;
185 aLock.clear();
186 // <- SAFE ----------------------------------
188 // convert command in URL structure
189 css::uno::Reference< css::util::XURLTransformer > xParser = impl_ts_getURLParser();
190 css::util::URL aURL;
191 aURL.Complete = sCommand;
192 xParser->parseStrict(aURL);
194 // ask for dispatch object
195 css::uno::Reference< css::frame::XDispatch > xDispatch = xProvider->queryDispatch(aURL, OUString(), 0);
196 bool bRet = xDispatch.is();
197 if ( bRet )
199 // Note: Such instance can be used one times only and destroy itself afterwards .-)
200 AsyncAccelExec* pExec = AsyncAccelExec::createOnShotInstance(xDispatch, aURL);
201 pExec->execAsync();
204 return bRet;
208 css::awt::KeyEvent AcceleratorExecute::st_VCLKey2AWTKey(const vcl::KeyCode& aVCLKey)
210 css::awt::KeyEvent aAWTKey;
211 aAWTKey.Modifiers = 0;
212 aAWTKey.KeyCode = (sal_Int16)aVCLKey.GetCode();
214 if (aVCLKey.IsShift())
215 aAWTKey.Modifiers |= css::awt::KeyModifier::SHIFT;
216 if (aVCLKey.IsMod1())
217 aAWTKey.Modifiers |= css::awt::KeyModifier::MOD1;
218 if (aVCLKey.IsMod2())
219 aAWTKey.Modifiers |= css::awt::KeyModifier::MOD2;
220 if (aVCLKey.IsMod3())
221 aAWTKey.Modifiers |= css::awt::KeyModifier::MOD3;
222 return aAWTKey;
226 vcl::KeyCode AcceleratorExecute::st_AWTKey2VCLKey(const css::awt::KeyEvent& aAWTKey)
228 bool bShift = ((aAWTKey.Modifiers & css::awt::KeyModifier::SHIFT) == css::awt::KeyModifier::SHIFT );
229 bool bMod1 = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD1 ) == css::awt::KeyModifier::MOD1 );
230 bool bMod2 = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD2 ) == css::awt::KeyModifier::MOD2 );
231 bool bMod3 = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD3 ) == css::awt::KeyModifier::MOD3 );
232 sal_uInt16 nKey = (sal_uInt16)aAWTKey.KeyCode;
234 return vcl::KeyCode(nKey, bShift, bMod1, bMod2, bMod3);
237 OUString AcceleratorExecute::findCommand(const css::awt::KeyEvent& aKey)
239 return impl_ts_findCommand(aKey);
242 OUString AcceleratorExecute::impl_ts_findCommand(const css::awt::KeyEvent& aKey)
244 // SAFE -> ----------------------------------
245 ::osl::ResettableMutexGuard aLock(m_aLock);
247 css::uno::Reference< css::ui::XAcceleratorConfiguration > xGlobalCfg = m_xGlobalCfg;
248 css::uno::Reference< css::ui::XAcceleratorConfiguration > xModuleCfg = m_xModuleCfg;
249 css::uno::Reference< css::ui::XAcceleratorConfiguration > xDocCfg = m_xDocCfg ;
251 aLock.clear();
252 // <- SAFE ----------------------------------
254 OUString sCommand;
258 if (xDocCfg.is())
259 sCommand = xDocCfg->getCommandByKeyEvent(aKey);
260 if (!sCommand.isEmpty())
261 return sCommand;
263 catch(const css::container::NoSuchElementException&)
268 if (xModuleCfg.is())
269 sCommand = xModuleCfg->getCommandByKeyEvent(aKey);
270 if (!sCommand.isEmpty())
271 return sCommand;
273 catch(const css::container::NoSuchElementException&)
278 if (xGlobalCfg.is())
279 sCommand = xGlobalCfg->getCommandByKeyEvent(aKey);
280 if (!sCommand.isEmpty())
281 return sCommand;
283 catch(const css::container::NoSuchElementException&)
286 // fall back to functional key codes
287 if( aKey.Modifiers == 0 )
289 switch( aKey.KeyCode )
291 case com::sun::star::awt::Key::DELETE_TO_BEGIN_OF_LINE:
292 return OUString( ".uno:DelToStartOfLine" );
293 case com::sun::star::awt::Key::DELETE_TO_END_OF_LINE:
294 return OUString( ".uno:DelToEndOfLine" );
295 case com::sun::star::awt::Key::DELETE_TO_BEGIN_OF_PARAGRAPH:
296 return OUString( ".uno:DelToStartOfPara" );
297 case com::sun::star::awt::Key::DELETE_TO_END_OF_PARAGRAPH:
298 return OUString( ".uno:DelToEndOfPara" );
299 case com::sun::star::awt::Key::DELETE_WORD_BACKWARD:
300 return OUString( ".uno:DelToStartOfWord" );
301 case com::sun::star::awt::Key::DELETE_WORD_FORWARD:
302 return OUString( ".uno:DelToEndOfWord" );
303 case com::sun::star::awt::Key::INSERT_LINEBREAK:
304 return OUString( ".uno:InsertLinebreak" );
305 case com::sun::star::awt::Key::INSERT_PARAGRAPH:
306 return OUString( ".uno:InsertPara" );
307 case com::sun::star::awt::Key::MOVE_WORD_BACKWARD:
308 return OUString( ".uno:GoToPrevWord" );
309 case com::sun::star::awt::Key::MOVE_WORD_FORWARD:
310 return OUString( ".uno:GoToNextWord" );
311 case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_LINE:
312 return OUString( ".uno:GoToStartOfLine" );
313 case com::sun::star::awt::Key::MOVE_TO_END_OF_LINE:
314 return OUString( ".uno:GoToEndOfLine" );
315 case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_PARAGRAPH:
316 return OUString( ".uno:GoToStartOfPara" );
317 case com::sun::star::awt::Key::MOVE_TO_END_OF_PARAGRAPH:
318 return OUString( ".uno:GoToEndOfPara" );
319 case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_DOCUMENT:
320 return OUString( ".uno:GoToStartOfDoc" );
321 case com::sun::star::awt::Key::MOVE_TO_END_OF_DOCUMENT:
322 return OUString( ".uno:GoToEndOfDoc" );
323 case com::sun::star::awt::Key::SELECT_BACKWARD:
324 return OUString( ".uno:CharLeftSel" );
325 case com::sun::star::awt::Key::SELECT_FORWARD:
326 return OUString( ".uno:CharRightSel" );
327 case com::sun::star::awt::Key::SELECT_WORD_BACKWARD:
328 return OUString( ".uno:WordLeftSel" );
329 case com::sun::star::awt::Key::SELECT_WORD_FORWARD:
330 return OUString( ".uno:WordRightSel" );
331 case com::sun::star::awt::Key::SELECT_WORD:
332 return OUString( ".uno:SelectWord" );
333 case com::sun::star::awt::Key::SELECT_LINE:
334 return OUString();
335 case com::sun::star::awt::Key::SELECT_PARAGRAPH:
336 return OUString( ".uno:SelectText" );
337 case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_LINE:
338 return OUString( ".uno:StartOfLineSel" );
339 case com::sun::star::awt::Key::SELECT_TO_END_OF_LINE:
340 return OUString( ".uno:EndOfLineSel" );
341 case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_PARAGRAPH:
342 return OUString( ".uno:StartOfParaSel" );
343 case com::sun::star::awt::Key::SELECT_TO_END_OF_PARAGRAPH:
344 return OUString( ".uno:EndOfParaSel" );
345 case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_DOCUMENT:
346 return OUString( ".uno:StartOfDocumentSel" );
347 case com::sun::star::awt::Key::SELECT_TO_END_OF_DOCUMENT:
348 return OUString( ".uno:EndOfDocumentSel" );
349 case com::sun::star::awt::Key::SELECT_ALL:
350 return OUString( ".uno:SelectAll" );
351 default:
352 break;
356 return OUString();
360 css::uno::Reference< css::ui::XAcceleratorConfiguration > AcceleratorExecute::st_openModuleConfig(const css::uno::Reference< css::uno::XComponentContext >& rxContext,
361 const css::uno::Reference< css::frame::XFrame >& xFrame)
363 css::uno::Reference< css::frame::XModuleManager2 > xModuleDetection(
364 css::frame::ModuleManager::create(rxContext));
366 OUString sModule;
369 sModule = xModuleDetection->identify(xFrame);
371 catch(const css::uno::RuntimeException&rEx)
372 { (void) rEx; throw; }
373 catch(const css::uno::Exception&)
374 { return css::uno::Reference< css::ui::XAcceleratorConfiguration >(); }
376 css::uno::Reference< css::ui::XModuleUIConfigurationManagerSupplier > xUISupplier(
377 css::ui::theModuleUIConfigurationManagerSupplier::get(rxContext) );
379 css::uno::Reference< css::ui::XAcceleratorConfiguration > xAccCfg;
382 css::uno::Reference< css::ui::XUIConfigurationManager > xUIManager = xUISupplier->getUIConfigurationManager(sModule);
383 xAccCfg = xUIManager->getShortCutManager();
385 catch(const css::container::NoSuchElementException&)
387 return xAccCfg;
391 css::uno::Reference< css::ui::XAcceleratorConfiguration > AcceleratorExecute::st_openDocConfig(const css::uno::Reference< css::frame::XModel >& xModel)
393 css::uno::Reference< css::ui::XAcceleratorConfiguration > xAccCfg;
394 css::uno::Reference< css::ui::XUIConfigurationManagerSupplier > xUISupplier(xModel, css::uno::UNO_QUERY);
395 if (xUISupplier.is())
397 css::uno::Reference< css::ui::XUIConfigurationManager > xUIManager = xUISupplier->getUIConfigurationManager();
398 xAccCfg = xUIManager->getShortCutManager();
400 return xAccCfg;
404 css::uno::Reference< css::util::XURLTransformer > AcceleratorExecute::impl_ts_getURLParser()
406 // SAFE -> ----------------------------------
407 ::osl::ResettableMutexGuard aLock(m_aLock);
409 if (m_xURLParser.is())
410 return m_xURLParser;
411 css::uno::Reference< css::uno::XComponentContext > xContext = m_xContext;
413 aLock.clear();
414 // <- SAFE ----------------------------------
416 css::uno::Reference< css::util::XURLTransformer > xParser = css::util::URLTransformer::create( xContext );
418 // SAFE -> ----------------------------------
419 aLock.reset();
420 m_xURLParser = xParser;
421 aLock.clear();
422 // <- SAFE ----------------------------------
424 return xParser;
428 IMPL_LINK_NOARG(AcceleratorExecute, impl_ts_asyncCallback)
430 // replaced by AsyncAccelExec!
431 return 0;
435 AsyncAccelExec::AsyncAccelExec(const css::uno::Reference< css::frame::XDispatch >& xDispatch,
436 const css::util::URL& aURL )
437 : m_aAsyncCallback(LINK(this, AsyncAccelExec, impl_ts_asyncCallback))
438 , m_xDispatch (xDispatch )
439 , m_aURL (aURL )
444 AsyncAccelExec* AsyncAccelExec::createOnShotInstance(const css::uno::Reference< css::frame::XDispatch >& xDispatch,
445 const css::util::URL& aURL )
447 AsyncAccelExec* pExec = new AsyncAccelExec(xDispatch, aURL);
448 return pExec;
452 void AsyncAccelExec::execAsync()
454 m_aAsyncCallback.Post(0);
458 IMPL_LINK_NOARG(AsyncAccelExec, impl_ts_asyncCallback)
460 if (! m_xDispatch.is())
461 return 0;
465 m_xDispatch->dispatch(m_aURL, css::uno::Sequence< css::beans::PropertyValue >());
467 catch(const css::lang::DisposedException&)
469 catch(const css::uno::RuntimeException& )
470 { throw; }
471 catch(const css::uno::Exception&)
474 delete this;
476 return 0;
479 } // namespace svt
481 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */