1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: acceleratorexecute.cxx,v $
10 * $Revision: 1.14.90.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
33 #include "acceleratorexecute.hxx"
35 //===============================================
38 #ifndef __COM_SUN_STAR_FRAME_XMODULEMANAGER_HPP_
39 #include <com/sun/star/frame/XModuleManager.hpp>
42 #ifndef __COM_SUN_STAR_FRAME_XDESKTOP_HPP_
43 #include <com/sun/star/frame/XDesktop.hpp>
46 #ifndef __COM_SUN_STAR_UI_XUICONFIGURATIONMANAGER_HPP_
47 #include <com/sun/star/ui/XUIConfigurationManager.hpp>
50 #ifndef __COM_SUN_STAR_UI_XMODULEUICONFIGURATIONMANAGERSUPPLIER_HPP_
51 #include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
54 #ifndef __COM_SUN_STAR_UI_XUICONFIGURATIONMANAGERSUPPLIER_HPP_
55 #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
58 #ifndef __COM_SUN_STAR_AWT_XTOPWINDOW_HPP_
59 #include <com/sun/star/awt/XTopWindow.hpp>
62 #ifndef __COM_SUN_STAR_AWT_KEYMODIFIER_HPP_
63 #include <com/sun/star/awt/KeyModifier.hpp>
66 #ifndef __COM_SUN_STAR_UNO_SEQUENCE_HXX_
67 #include <com/sun/star/uno/Sequence.hxx>
70 #ifndef __COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
71 #include <com/sun/star/beans/PropertyValue.hpp>
74 #ifndef __COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_
75 #include <com/sun/star/lang/DisposedException.hpp>
77 #include <toolkit/helper/vclunohelper.hxx>
79 #include <vcl/window.hxx>
80 #include <vcl/svapp.hxx>
81 #include <vos/mutex.hxx>
83 //===============================================
86 namespace css
= ::com::sun::star
;
91 //===============================================
94 //-----------------------------------------------
95 class SVT_DLLPRIVATE AsyncAccelExec
99 //---------------------------------------
100 /** creates a new instance of this class, which can be used
103 This instance can be forced to execute it's internal set request
104 asynchronous. After that it deletes itself !
106 static AsyncAccelExec
* createOnShotInstance(const css::uno::Reference
< css::frame::XDispatch
>& xDispatch
,
107 const css::util::URL
& aURL
);
113 //---------------------------------------
114 /** @short allow creation of instances of this class
115 by using our factory only!
117 SVT_DLLPRIVATE
AsyncAccelExec(const css::uno::Reference
< css::frame::XDispatch
>& xDispatch
,
118 const css::util::URL
& aURL
);
120 DECL_DLLPRIVATE_LINK(impl_ts_asyncCallback
, void*);
124 ::vcl::EventPoster m_aAsyncCallback
;
125 css::uno::Reference
< css::frame::XDispatch
> m_xDispatch
;
126 css::util::URL m_aURL
;
129 //-----------------------------------------------
130 AcceleratorExecute::AcceleratorExecute()
132 , m_aAsyncCallback(LINK(this, AcceleratorExecute
, impl_ts_asyncCallback
))
136 //-----------------------------------------------
137 AcceleratorExecute::AcceleratorExecute(const AcceleratorExecute
&)
139 , m_aAsyncCallback(LINK(this, AcceleratorExecute
, impl_ts_asyncCallback
))
141 // copy construction sint supported in real ...
142 // but we need this ctor to init our async callback ...
145 //-----------------------------------------------
146 AcceleratorExecute::~AcceleratorExecute()
151 //-----------------------------------------------
152 AcceleratorExecute
* AcceleratorExecute::createAcceleratorHelper()
154 AcceleratorExecute
* pNew
= new AcceleratorExecute();
158 //-----------------------------------------------
159 void AcceleratorExecute::init(const css::uno::Reference
< css::lang::XMultiServiceFactory
>& xSMGR
,
160 const css::uno::Reference
< css::frame::XFrame
>& xEnv
)
162 // SAFE -> ----------------------------------
163 ::osl::ResettableMutexGuard
aLock(m_aLock
);
165 // take over the uno service manager
168 // specify our internal dispatch provider
169 // frame or desktop?! => document or global config.
170 sal_Bool bDesktopIsUsed
= sal_False
;
171 m_xDispatcher
= css::uno::Reference
< css::frame::XDispatchProvider
>(xEnv
, css::uno::UNO_QUERY
);
172 if (!m_xDispatcher
.is())
175 // <- SAFE ------------------------------
177 css::uno::Reference
< css::frame::XDispatchProvider
> xDispatcher(
178 xSMGR
->createInstance(::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop")),
179 css::uno::UNO_QUERY_THROW
);
181 // SAFE -> ------------------------------
184 m_xDispatcher
= xDispatcher
;
185 bDesktopIsUsed
= sal_True
;
189 // <- SAFE ----------------------------------
191 // open all needed configuration objects
192 css::uno::Reference
< css::ui::XAcceleratorConfiguration
> xGlobalCfg
;
193 css::uno::Reference
< css::ui::XAcceleratorConfiguration
> xModuleCfg
;
194 css::uno::Reference
< css::ui::XAcceleratorConfiguration
> xDocCfg
;
197 xGlobalCfg
= AcceleratorExecute::st_openGlobalConfig(xSMGR
);
201 xModuleCfg
= AcceleratorExecute::st_openModuleConfig(xSMGR
, xEnv
);
204 css::uno::Reference
< css::frame::XController
> xController
;
205 css::uno::Reference
< css::frame::XModel
> xModel
;
206 xController
= xEnv
->getController();
207 if (xController
.is())
208 xModel
= xController
->getModel();
210 xDocCfg
= AcceleratorExecute::st_openDocConfig(xModel
);
213 // SAFE -> ------------------------------
216 m_xGlobalCfg
= xGlobalCfg
;
217 m_xModuleCfg
= xModuleCfg
;
218 m_xDocCfg
= xDocCfg
;
221 // <- SAFE ----------------------------------
224 //-----------------------------------------------
225 sal_Bool
AcceleratorExecute::execute(const KeyCode
& aVCLKey
)
227 css::awt::KeyEvent aAWTKey
= AcceleratorExecute::st_VCLKey2AWTKey(aVCLKey
);
228 return execute(aAWTKey
);
231 //-----------------------------------------------
232 sal_Bool
AcceleratorExecute::execute(const css::awt::KeyEvent
& aAWTKey
)
234 ::rtl::OUString sCommand
= impl_ts_findCommand(aAWTKey
);
236 // No Command found? Do nothing! User isnt interested on any error handling .-)
237 if (!sCommand
.getLength())
240 // SAFE -> ----------------------------------
241 ::osl::ResettableMutexGuard
aLock(m_aLock
);
243 css::uno::Reference
< css::frame::XDispatchProvider
> xProvider
= m_xDispatcher
;
246 // <- SAFE ----------------------------------
248 // convert command in URL structure
249 css::uno::Reference
< css::util::XURLTransformer
> xParser
= impl_ts_getURLParser();
251 aURL
.Complete
= sCommand
;
252 xParser
->parseStrict(aURL
);
254 // ask for dispatch object
255 css::uno::Reference
< css::frame::XDispatch
> xDispatch
= xProvider
->queryDispatch(aURL
, ::rtl::OUString(), 0);
256 sal_Bool bRet
= xDispatch
.is();
259 // Note: Such instance can be used one times only and destroy itself afterwards .-)
260 AsyncAccelExec
* pExec
= AsyncAccelExec::createOnShotInstance(xDispatch
, aURL
);
267 //-----------------------------------------------
268 css::awt::KeyEvent
AcceleratorExecute::st_VCLKey2AWTKey(const KeyCode
& aVCLKey
)
270 css::awt::KeyEvent aAWTKey
;
271 aAWTKey
.Modifiers
= 0;
272 aAWTKey
.KeyCode
= (sal_Int16
)aVCLKey
.GetCode();
274 if (aVCLKey
.IsShift())
275 aAWTKey
.Modifiers
|= css::awt::KeyModifier::SHIFT
;
276 if (aVCLKey
.IsMod1())
277 aAWTKey
.Modifiers
|= css::awt::KeyModifier::MOD1
;
278 if (aVCLKey
.IsMod2())
279 aAWTKey
.Modifiers
|= css::awt::KeyModifier::MOD2
;
280 if (aVCLKey
.IsMod3())
281 aAWTKey
.Modifiers
|= css::awt::KeyModifier::MOD3
;
285 //-----------------------------------------------
286 KeyCode
AcceleratorExecute::st_AWTKey2VCLKey(const css::awt::KeyEvent
& aAWTKey
)
288 sal_Bool bShift
= ((aAWTKey
.Modifiers
& css::awt::KeyModifier::SHIFT
) == css::awt::KeyModifier::SHIFT
);
289 sal_Bool bMod1
= ((aAWTKey
.Modifiers
& css::awt::KeyModifier::MOD1
) == css::awt::KeyModifier::MOD1
);
290 sal_Bool bMod2
= ((aAWTKey
.Modifiers
& css::awt::KeyModifier::MOD2
) == css::awt::KeyModifier::MOD2
);
291 sal_Bool bMod3
= ((aAWTKey
.Modifiers
& css::awt::KeyModifier::MOD3
) == css::awt::KeyModifier::MOD3
);
292 USHORT nKey
= (USHORT
)aAWTKey
.KeyCode
;
294 return KeyCode(nKey
, bShift
, bMod1
, bMod2
, bMod3
);
296 //-----------------------------------------------
297 ::rtl::OUString
AcceleratorExecute::findCommand(const css::awt::KeyEvent
& aKey
)
299 return impl_ts_findCommand(aKey
);
301 //-----------------------------------------------
302 ::rtl::OUString
AcceleratorExecute::impl_ts_findCommand(const css::awt::KeyEvent
& aKey
)
304 // SAFE -> ----------------------------------
305 ::osl::ResettableMutexGuard
aLock(m_aLock
);
307 css::uno::Reference
< css::ui::XAcceleratorConfiguration
> xGlobalCfg
= m_xGlobalCfg
;
308 css::uno::Reference
< css::ui::XAcceleratorConfiguration
> xModuleCfg
= m_xModuleCfg
;
309 css::uno::Reference
< css::ui::XAcceleratorConfiguration
> xDocCfg
= m_xDocCfg
;
312 // <- SAFE ----------------------------------
314 ::rtl::OUString sCommand
;
319 sCommand
= xDocCfg
->getCommandByKeyEvent(aKey
);
320 if (sCommand
.getLength())
323 catch(const css::container::NoSuchElementException
&)
329 sCommand
= xModuleCfg
->getCommandByKeyEvent(aKey
);
330 if (sCommand
.getLength())
333 catch(const css::container::NoSuchElementException
&)
339 sCommand
= xGlobalCfg
->getCommandByKeyEvent(aKey
);
340 if (sCommand
.getLength())
343 catch(const css::container::NoSuchElementException
&)
346 // fall back to functional key codes
347 if( aKey
.Modifiers
== 0 )
349 switch( aKey
.KeyCode
)
351 case com::sun::star::awt::Key::DELETE_TO_BEGIN_OF_LINE
:
352 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:DelToStartOfLine" ) );
354 case com::sun::star::awt::Key::DELETE_TO_END_OF_LINE
:
355 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:DelToEndOfLine" ) );
357 case com::sun::star::awt::Key::DELETE_TO_BEGIN_OF_PARAGRAPH
:
358 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:DelToStartOfPara" ) );
360 case com::sun::star::awt::Key::DELETE_TO_END_OF_PARAGRAPH
:
361 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:DelToEndOfPara" ) );
363 case com::sun::star::awt::Key::DELETE_WORD_BACKWARD
:
364 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:DelToStartOfWord" ) );
366 case com::sun::star::awt::Key::DELETE_WORD_FORWARD
:
367 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:DelToEndOfWord" ) );
369 case com::sun::star::awt::Key::INSERT_LINEBREAK
:
370 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:InsertLinebreak" ) );
372 case com::sun::star::awt::Key::INSERT_PARAGRAPH
:
373 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:InsertPara" ) );
375 case com::sun::star::awt::Key::MOVE_WORD_BACKWARD
:
376 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:GoToPrevWord" ) );
378 case com::sun::star::awt::Key::MOVE_WORD_FORWARD
:
379 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:GoToNextWord" ) );
381 case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_LINE
:
382 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:GoToStartOfLine" ) );
384 case com::sun::star::awt::Key::MOVE_TO_END_OF_LINE
:
385 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:GoToEndOfLine" ) );
387 case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_PARAGRAPH
:
388 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:GoToStartOfPara" ) );
390 case com::sun::star::awt::Key::MOVE_TO_END_OF_PARAGRAPH
:
391 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:GoToEndOfPara" ) );
393 case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_DOCUMENT
:
394 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:GoToStartOfDoc" ) );
396 case com::sun::star::awt::Key::MOVE_TO_END_OF_DOCUMENT
:
397 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:GoToEndOfDoc" ) );
399 case com::sun::star::awt::Key::SELECT_BACKWARD
:
400 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:CharLeftSel" ) );
402 case com::sun::star::awt::Key::SELECT_FORWARD
:
403 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:CharRightSel" ) );
405 case com::sun::star::awt::Key::SELECT_WORD_BACKWARD
:
406 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:WordLeftSel" ) );
408 case com::sun::star::awt::Key::SELECT_WORD_FORWARD
:
409 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:WordRightSel" ) );
411 case com::sun::star::awt::Key::SELECT_WORD
:
412 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:SelectWord" ) );
414 case com::sun::star::awt::Key::SELECT_LINE
:
415 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "" ) );
417 case com::sun::star::awt::Key::SELECT_PARAGRAPH
:
418 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:SelectText" ) );
420 case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_LINE
:
421 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:StartOfLineSel" ) );
423 case com::sun::star::awt::Key::SELECT_TO_END_OF_LINE
:
424 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:EndOfLineSel" ) );
426 case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_PARAGRAPH
:
427 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:StartOfParaSel" ) );
429 case com::sun::star::awt::Key::SELECT_TO_END_OF_PARAGRAPH
:
430 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:EndOfParaSel" ) );
432 case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_DOCUMENT
:
433 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:StartOfDocumentSel" ) );
435 case com::sun::star::awt::Key::SELECT_TO_END_OF_DOCUMENT
:
436 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:EndOfDocumentSel" ) );
438 case com::sun::star::awt::Key::SELECT_ALL
:
439 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:SelectAll" ) );
445 return ::rtl::OUString();
448 //-----------------------------------------------
449 css::uno::Reference
< css::ui::XAcceleratorConfiguration
> AcceleratorExecute::st_openGlobalConfig(const css::uno::Reference
< css::lang::XMultiServiceFactory
>& xSMGR
)
451 css::uno::Reference
< css::ui::XAcceleratorConfiguration
> xAccCfg(
452 xSMGR
->createInstance(::rtl::OUString::createFromAscii("com.sun.star.ui.GlobalAcceleratorConfiguration")),
453 css::uno::UNO_QUERY_THROW
);
457 //-----------------------------------------------
458 css::uno::Reference
< css::ui::XAcceleratorConfiguration
> AcceleratorExecute::st_openModuleConfig(const css::uno::Reference
< css::lang::XMultiServiceFactory
>& xSMGR
,
459 const css::uno::Reference
< css::frame::XFrame
>& xFrame
)
461 css::uno::Reference
< css::frame::XModuleManager
> xModuleDetection(
462 xSMGR
->createInstance(::rtl::OUString::createFromAscii("com.sun.star.frame.ModuleManager")),
463 css::uno::UNO_QUERY_THROW
);
465 ::rtl::OUString sModule
;
468 sModule
= xModuleDetection
->identify(xFrame
);
470 catch(const css::uno::RuntimeException
&rEx
)
471 { (void) rEx
; throw; }
472 catch(const css::uno::Exception
&)
473 { return css::uno::Reference
< css::ui::XAcceleratorConfiguration
>(); }
475 css::uno::Reference
< css::ui::XModuleUIConfigurationManagerSupplier
> xUISupplier(
476 xSMGR
->createInstance(::rtl::OUString::createFromAscii("com.sun.star.ui.ModuleUIConfigurationManagerSupplier")),
477 css::uno::UNO_QUERY_THROW
);
479 css::uno::Reference
< css::ui::XAcceleratorConfiguration
> xAccCfg
;
482 css::uno::Reference
< css::ui::XUIConfigurationManager
> xUIManager
= xUISupplier
->getUIConfigurationManager(sModule
);
483 xAccCfg
= css::uno::Reference
< css::ui::XAcceleratorConfiguration
>(xUIManager
->getShortCutManager(), css::uno::UNO_QUERY_THROW
);
485 catch(const css::container::NoSuchElementException
&)
490 //-----------------------------------------------
491 css::uno::Reference
< css::ui::XAcceleratorConfiguration
> AcceleratorExecute::st_openDocConfig(const css::uno::Reference
< css::frame::XModel
>& xModel
)
493 css::uno::Reference
< css::ui::XAcceleratorConfiguration
> xAccCfg
;
494 css::uno::Reference
< css::ui::XUIConfigurationManagerSupplier
> xUISupplier(xModel
, css::uno::UNO_QUERY
);
495 if (xUISupplier
.is())
497 css::uno::Reference
< css::ui::XUIConfigurationManager
> xUIManager
= xUISupplier
->getUIConfigurationManager();
498 xAccCfg
.set(xUIManager
->getShortCutManager(), css::uno::UNO_QUERY_THROW
);
503 //-----------------------------------------------
504 css::uno::Reference
< css::util::XURLTransformer
> AcceleratorExecute::impl_ts_getURLParser()
506 // SAFE -> ----------------------------------
507 ::osl::ResettableMutexGuard
aLock(m_aLock
);
509 if (m_xURLParser
.is())
511 css::uno::Reference
< css::lang::XMultiServiceFactory
> xSMGR
= m_xSMGR
;
514 // <- SAFE ----------------------------------
516 css::uno::Reference
< css::util::XURLTransformer
> xParser(
517 xSMGR
->createInstance(::rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer")),
518 css::uno::UNO_QUERY_THROW
);
520 // SAFE -> ----------------------------------
522 m_xURLParser
= xParser
;
524 // <- SAFE ----------------------------------
529 //-----------------------------------------------
530 IMPL_LINK(AcceleratorExecute
, impl_ts_asyncCallback
, void*, EMPTYARG
)
532 // replaced by AsyncAccelExec!
536 //-----------------------------------------------
537 AsyncAccelExec::AsyncAccelExec(const css::uno::Reference
< css::frame::XDispatch
>& xDispatch
,
538 const css::util::URL
& aURL
)
539 : m_aAsyncCallback(LINK(this, AsyncAccelExec
, impl_ts_asyncCallback
))
540 , m_xDispatch (xDispatch
)
545 //-----------------------------------------------
546 AsyncAccelExec
* AsyncAccelExec::createOnShotInstance(const css::uno::Reference
< css::frame::XDispatch
>& xDispatch
,
547 const css::util::URL
& aURL
)
549 AsyncAccelExec
* pExec
= new AsyncAccelExec(xDispatch
, aURL
);
553 //-----------------------------------------------
554 void AsyncAccelExec::execAsync()
556 m_aAsyncCallback
.Post(0);
559 //-----------------------------------------------
560 IMPL_LINK(AsyncAccelExec
, impl_ts_asyncCallback
, void*,)
562 if (! m_xDispatch
.is())
567 m_xDispatch
->dispatch(m_aURL
, css::uno::Sequence
< css::beans::PropertyValue
>());
569 catch(const css::lang::DisposedException
&)
571 catch(const css::uno::RuntimeException
& )
573 catch(const css::uno::Exception
&)