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_svtools.hxx"
26 #include <svtools/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_FRAME_XDESKTOP_HPP_
36 #include <com/sun/star/frame/XDesktop.hpp>
37 #endif
38 
39 #ifndef __COM_SUN_STAR_UI_XUICONFIGURATIONMANAGER_HPP_
40 #include <com/sun/star/ui/XUIConfigurationManager.hpp>
41 #endif
42 
43 #ifndef __COM_SUN_STAR_UI_XMODULEUICONFIGURATIONMANAGERSUPPLIER_HPP_
44 #include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
45 #endif
46 
47 #ifndef __COM_SUN_STAR_UI_XUICONFIGURATIONMANAGERSUPPLIER_HPP_
48 #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
49 #endif
50 
51 #ifndef __COM_SUN_STAR_AWT_XTOPWINDOW_HPP_
52 #include <com/sun/star/awt/XTopWindow.hpp>
53 #endif
54 
55 #ifndef __COM_SUN_STAR_AWT_KEYMODIFIER_HPP_
56 #include <com/sun/star/awt/KeyModifier.hpp>
57 #endif
58 
59 #ifndef __COM_SUN_STAR_UNO_SEQUENCE_HXX_
60 #include <com/sun/star/uno/Sequence.hxx>
61 #endif
62 
63 #ifndef __COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
64 #include <com/sun/star/beans/PropertyValue.hpp>
65 #endif
66 
67 #ifndef __COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_
68 #include <com/sun/star/lang/DisposedException.hpp>
69 #endif
70 #include <toolkit/helper/vclunohelper.hxx>
71 
72 #include <vcl/window.hxx>
73 #include <vcl/svapp.hxx>
74 #include <vos/mutex.hxx>
75 //IAccessibility2 Implementation 2009-----
76 #include <comphelper/uieventslogger.hxx>
77 //-----IAccessibility2 Implementation 2009
78 
79 //===============================================
80 // namespace
81 
82 namespace  css = ::com::sun::star;
83 
84 namespace svt
85 {
86 
87 //===============================================
88 // definitions
89 
90 //-----------------------------------------------
91 class SVT_DLLPRIVATE AsyncAccelExec
92 {
93     public:
94 
95         //---------------------------------------
96         /** creates a new instance of this class, which can be used
97             one times only!
98 
99             This instance can be forced to execute it's internal set request
100             asynchronous. After that it deletes itself !
101          */
102         static AsyncAccelExec* createOnShotInstance(const css::uno::Reference< css::frame::XDispatch >& xDispatch,
103                                                     const css::util::URL&                               aURL     );
104 
105         void execAsync();
106 
107     private:
108 
109         //---------------------------------------
110         /** @short  allow creation of instances of this class
111                     by using our factory only!
112          */
113         SVT_DLLPRIVATE AsyncAccelExec(const css::uno::Reference< css::frame::XDispatch >& xDispatch,
114                                       const css::util::URL&                               aURL     );
115 
116         DECL_DLLPRIVATE_LINK(impl_ts_asyncCallback, void*);
117 
118     private:
119 
120         ::vcl::EventPoster m_aAsyncCallback;
121         css::uno::Reference< css::frame::XDispatch > m_xDispatch;
122         css::util::URL m_aURL;
123 };
124 
125 //-----------------------------------------------
126 AcceleratorExecute::AcceleratorExecute()
127     : TMutexInit      (                                                     )
128     , m_aAsyncCallback(LINK(this, AcceleratorExecute, impl_ts_asyncCallback))
129 {
130 }
131 
132 //-----------------------------------------------
133 AcceleratorExecute::AcceleratorExecute(const AcceleratorExecute&)
134     : TMutexInit      (                                                     )
135     , m_aAsyncCallback(LINK(this, AcceleratorExecute, impl_ts_asyncCallback))
136 {
137     // copy construction sint supported in real ...
138     // but we need this ctor to init our async callback ...
139 }
140 
141 //-----------------------------------------------
142 AcceleratorExecute::~AcceleratorExecute()
143 {
144     // does nothing real
145 }
146 
147 //-----------------------------------------------
148 AcceleratorExecute* AcceleratorExecute::createAcceleratorHelper()
149 {
150     AcceleratorExecute* pNew = new AcceleratorExecute();
151     return pNew;
152 }
153 
154 //-----------------------------------------------
155 void AcceleratorExecute::init(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR,
156                               const css::uno::Reference< css::frame::XFrame >&              xEnv )
157 {
158     // SAFE -> ----------------------------------
159     ::osl::ResettableMutexGuard aLock(m_aLock);
160 
161     // take over the uno service manager
162     m_xSMGR = xSMGR;
163 
164     // specify our internal dispatch provider
165     // frame or desktop?! => document or global config.
166     sal_Bool bDesktopIsUsed = sal_False;
167              m_xDispatcher  = css::uno::Reference< css::frame::XDispatchProvider >(xEnv, css::uno::UNO_QUERY);
168     if (!m_xDispatcher.is())
169     {
170         aLock.clear();
171         // <- SAFE ------------------------------
172 
173         css::uno::Reference< css::frame::XDispatchProvider > xDispatcher(
174                             xSMGR->createInstance(::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop")),
175                             css::uno::UNO_QUERY_THROW);
176 
177         // SAFE -> ------------------------------
178         aLock.reset();
179 
180         m_xDispatcher  = xDispatcher;
181         bDesktopIsUsed = sal_True;
182     }
183 
184     aLock.clear();
185     // <- SAFE ----------------------------------
186 
187     // open all needed configuration objects
188     css::uno::Reference< css::ui::XAcceleratorConfiguration > xGlobalCfg;
189     css::uno::Reference< css::ui::XAcceleratorConfiguration > xModuleCfg;
190     css::uno::Reference< css::ui::XAcceleratorConfiguration > xDocCfg   ;
191 
192     // global cfg
193     xGlobalCfg = AcceleratorExecute::st_openGlobalConfig(xSMGR);
194     if (!bDesktopIsUsed)
195     {
196         // module cfg
197         xModuleCfg = AcceleratorExecute::st_openModuleConfig(xSMGR, xEnv);
198 
199         // doc cfg
200         css::uno::Reference< css::frame::XController > xController;
201         css::uno::Reference< css::frame::XModel >      xModel;
202         xController = xEnv->getController();
203         if (xController.is())
204             xModel = xController->getModel();
205         if (xModel.is())
206             xDocCfg = AcceleratorExecute::st_openDocConfig(xModel);
207     }
208 
209     // SAFE -> ------------------------------
210     aLock.reset();
211 
212     m_xGlobalCfg = xGlobalCfg;
213     m_xModuleCfg = xModuleCfg;
214     m_xDocCfg    = xDocCfg   ;
215 
216     aLock.clear();
217     // <- SAFE ----------------------------------
218 }
219 
220 //-----------------------------------------------
221 sal_Bool AcceleratorExecute::execute(const KeyCode& aVCLKey)
222 {
223     css::awt::KeyEvent aAWTKey = AcceleratorExecute::st_VCLKey2AWTKey(aVCLKey);
224     return execute(aAWTKey);
225 }
226 
227 //-----------------------------------------------
228 sal_Bool AcceleratorExecute::execute(const css::awt::KeyEvent& aAWTKey)
229 {
230     ::rtl::OUString sCommand = impl_ts_findCommand(aAWTKey);
231 
232     // No Command found? Do nothing! User isnt interested on any error handling .-)
233     if (!sCommand.getLength())
234         return sal_False;
235 
236     // SAFE -> ----------------------------------
237     ::osl::ResettableMutexGuard aLock(m_aLock);
238 
239     css::uno::Reference< css::frame::XDispatchProvider > xProvider = m_xDispatcher;
240 
241     aLock.clear();
242     // <- SAFE ----------------------------------
243 
244     // convert command in URL structure
245     css::uno::Reference< css::util::XURLTransformer > xParser = impl_ts_getURLParser();
246     css::util::URL aURL;
247     aURL.Complete = sCommand;
248     xParser->parseStrict(aURL);
249 
250     // ask for dispatch object
251     css::uno::Reference< css::frame::XDispatch > xDispatch = xProvider->queryDispatch(aURL, ::rtl::OUString(), 0);
252     sal_Bool bRet = xDispatch.is();
253     if ( bRet )
254     {
255 //IAccessibility2 Implementation 2009-----
256         if(::comphelper::UiEventsLogger::isEnabled() && m_xSMGR.is() && m_xDispatcher.is()) //#i88653#
257         {
258             try
259             {
260                 css::uno::Reference< css::frame::XModuleManager > xModuleDetection(
261                     m_xSMGR->createInstance(::rtl::OUString::createFromAscii("com.sun.star.frame.ModuleManager")),
262                     css::uno::UNO_QUERY_THROW);
263 
264                 const ::rtl::OUString sModule = xModuleDetection->identify(m_xDispatcher);
265                 css::uno::Sequence<css::beans::PropertyValue> source;
266                 ::comphelper::UiEventsLogger::appendDispatchOrigin(source, sModule, ::rtl::OUString::createFromAscii("AcceleratorExecute"));
267                 ::comphelper::UiEventsLogger::logDispatch(aURL, source);
268             }
269             catch(const css::uno::Exception&)
270                 { }
271         }
272 //-----IAccessibility2 Implementation 2009
273         // Note: Such instance can be used one times only and destroy itself afterwards .-)
274         AsyncAccelExec* pExec = AsyncAccelExec::createOnShotInstance(xDispatch, aURL);
275         pExec->execAsync();
276     }
277 
278     return bRet;
279 }
280 
281 //-----------------------------------------------
282 css::awt::KeyEvent AcceleratorExecute::st_VCLKey2AWTKey(const KeyCode& aVCLKey)
283 {
284     css::awt::KeyEvent aAWTKey;
285     aAWTKey.Modifiers = 0;
286     aAWTKey.KeyCode   = (sal_Int16)aVCLKey.GetCode();
287 
288 	if (aVCLKey.IsShift())
289         aAWTKey.Modifiers |= css::awt::KeyModifier::SHIFT;
290 	if (aVCLKey.IsMod1())
291         aAWTKey.Modifiers |= css::awt::KeyModifier::MOD1;
292 	if (aVCLKey.IsMod2())
293         aAWTKey.Modifiers |= css::awt::KeyModifier::MOD2;
294         if (aVCLKey.IsMod3())
295         aAWTKey.Modifiers |= css::awt::KeyModifier::MOD3;
296     return aAWTKey;
297 }
298 
299 //-----------------------------------------------
300 KeyCode AcceleratorExecute::st_AWTKey2VCLKey(const css::awt::KeyEvent& aAWTKey)
301 {
302     sal_Bool bShift = ((aAWTKey.Modifiers & css::awt::KeyModifier::SHIFT) == css::awt::KeyModifier::SHIFT );
303     sal_Bool bMod1  = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD1 ) == css::awt::KeyModifier::MOD1  );
304     sal_Bool bMod2  = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD2 ) == css::awt::KeyModifier::MOD2  );
305     sal_Bool bMod3  = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD3 ) == css::awt::KeyModifier::MOD3  );
306     sal_uInt16   nKey   = (sal_uInt16)aAWTKey.KeyCode;
307 
308     return KeyCode(nKey, bShift, bMod1, bMod2, bMod3);
309 }
310 //-----------------------------------------------
311 ::rtl::OUString AcceleratorExecute::findCommand(const css::awt::KeyEvent& aKey)
312 {
313     return impl_ts_findCommand(aKey);
314 }
315 //-----------------------------------------------
316 ::rtl::OUString AcceleratorExecute::impl_ts_findCommand(const css::awt::KeyEvent& aKey)
317 {
318     // SAFE -> ----------------------------------
319     ::osl::ResettableMutexGuard aLock(m_aLock);
320 
321     css::uno::Reference< css::ui::XAcceleratorConfiguration > xGlobalCfg = m_xGlobalCfg;
322     css::uno::Reference< css::ui::XAcceleratorConfiguration > xModuleCfg = m_xModuleCfg;
323     css::uno::Reference< css::ui::XAcceleratorConfiguration > xDocCfg    = m_xDocCfg   ;
324 
325     aLock.clear();
326     // <- SAFE ----------------------------------
327 
328     ::rtl::OUString sCommand;
329 
330     try
331     {
332         if (xDocCfg.is())
333             sCommand = xDocCfg->getCommandByKeyEvent(aKey);
334         if (sCommand.getLength())
335             return sCommand;
336     }
337     catch(const css::container::NoSuchElementException&)
338         {}
339 
340     try
341     {
342         if (xModuleCfg.is())
343             sCommand = xModuleCfg->getCommandByKeyEvent(aKey);
344         if (sCommand.getLength())
345             return sCommand;
346     }
347     catch(const css::container::NoSuchElementException&)
348         {}
349 
350     try
351     {
352         if (xGlobalCfg.is())
353             sCommand = xGlobalCfg->getCommandByKeyEvent(aKey);
354         if (sCommand.getLength())
355             return sCommand;
356     }
357     catch(const css::container::NoSuchElementException&)
358         {}
359 
360     // fall back to functional key codes
361     if( aKey.Modifiers == 0 )
362     {
363         switch( aKey.KeyCode )
364         {
365         case com::sun::star::awt::Key::DELETE_TO_BEGIN_OF_LINE:
366             return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:DelToStartOfLine" ) );
367 
368         case com::sun::star::awt::Key::DELETE_TO_END_OF_LINE:
369             return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:DelToEndOfLine" ) );
370 
371         case com::sun::star::awt::Key::DELETE_TO_BEGIN_OF_PARAGRAPH:
372             return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:DelToStartOfPara" ) );
373 
374         case com::sun::star::awt::Key::DELETE_TO_END_OF_PARAGRAPH:
375             return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:DelToEndOfPara" ) );
376 
377         case com::sun::star::awt::Key::DELETE_WORD_BACKWARD:
378             return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:DelToStartOfWord" ) );
379 
380         case com::sun::star::awt::Key::DELETE_WORD_FORWARD:
381             return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:DelToEndOfWord" ) );
382 
383         case com::sun::star::awt::Key::INSERT_LINEBREAK:
384             return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:InsertLinebreak" ) );
385 
386         case com::sun::star::awt::Key::INSERT_PARAGRAPH:
387             return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:InsertPara" ) );
388 
389         case com::sun::star::awt::Key::MOVE_WORD_BACKWARD:
390             return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:GoToPrevWord" ) );
391 
392         case com::sun::star::awt::Key::MOVE_WORD_FORWARD:
393             return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:GoToNextWord" ) );
394 
395         case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_LINE:
396             return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:GoToStartOfLine" ) );
397 
398         case com::sun::star::awt::Key::MOVE_TO_END_OF_LINE:
399             return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:GoToEndOfLine" ) );
400 
401         case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_PARAGRAPH:
402             return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:GoToStartOfPara" ) );
403 
404         case com::sun::star::awt::Key::MOVE_TO_END_OF_PARAGRAPH:
405             return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:GoToEndOfPara" ) );
406 
407         case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_DOCUMENT:
408             return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:GoToStartOfDoc" ) );
409 
410         case com::sun::star::awt::Key::MOVE_TO_END_OF_DOCUMENT:
411             return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:GoToEndOfDoc" ) );
412 
413         case com::sun::star::awt::Key::SELECT_BACKWARD:
414             return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:CharLeftSel" ) );
415 
416         case com::sun::star::awt::Key::SELECT_FORWARD:
417             return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:CharRightSel" ) );
418 
419         case com::sun::star::awt::Key::SELECT_WORD_BACKWARD:
420             return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:WordLeftSel" ) );
421 
422         case com::sun::star::awt::Key::SELECT_WORD_FORWARD:
423             return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:WordRightSel" ) );
424 
425         case com::sun::star::awt::Key::SELECT_WORD:
426             return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:SelectWord" ) );
427 
428         case com::sun::star::awt::Key::SELECT_LINE:
429             return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "" ) );
430 
431         case com::sun::star::awt::Key::SELECT_PARAGRAPH:
432             return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:SelectText" ) );
433 
434         case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_LINE:
435             return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:StartOfLineSel" ) );
436 
437         case com::sun::star::awt::Key::SELECT_TO_END_OF_LINE:
438             return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:EndOfLineSel" ) );
439 
440         case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_PARAGRAPH:
441             return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:StartOfParaSel" ) );
442 
443         case com::sun::star::awt::Key::SELECT_TO_END_OF_PARAGRAPH:
444             return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:EndOfParaSel" ) );
445 
446         case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_DOCUMENT:
447             return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:StartOfDocumentSel" ) );
448 
449         case com::sun::star::awt::Key::SELECT_TO_END_OF_DOCUMENT:
450             return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:EndOfDocumentSel" ) );
451 
452         case com::sun::star::awt::Key::SELECT_ALL:
453             return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:SelectAll" ) );
454         default:
455             break;
456         }
457     }
458 
459     return ::rtl::OUString();
460 }
461 
462 //-----------------------------------------------
463 css::uno::Reference< css::ui::XAcceleratorConfiguration > AcceleratorExecute::st_openGlobalConfig(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
464 {
465     css::uno::Reference< css::ui::XAcceleratorConfiguration > xAccCfg(
466         xSMGR->createInstance(::rtl::OUString::createFromAscii("com.sun.star.ui.GlobalAcceleratorConfiguration")),
467         css::uno::UNO_QUERY_THROW);
468     return xAccCfg;
469 }
470 
471 //-----------------------------------------------
472 css::uno::Reference< css::ui::XAcceleratorConfiguration > AcceleratorExecute::st_openModuleConfig(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
473                                                                                                    const css::uno::Reference< css::frame::XFrame >&              xFrame)
474 {
475     css::uno::Reference< css::frame::XModuleManager > xModuleDetection(
476         xSMGR->createInstance(::rtl::OUString::createFromAscii("com.sun.star.frame.ModuleManager")),
477         css::uno::UNO_QUERY_THROW);
478 
479     ::rtl::OUString sModule;
480     try
481     {
482         sModule = xModuleDetection->identify(xFrame);
483     }
484     catch(const css::uno::RuntimeException&rEx)
485     	{ (void) rEx; throw; }
486     catch(const css::uno::Exception&)
487         { return css::uno::Reference< css::ui::XAcceleratorConfiguration >(); }
488 
489     css::uno::Reference< css::ui::XModuleUIConfigurationManagerSupplier > xUISupplier(
490         xSMGR->createInstance(::rtl::OUString::createFromAscii("com.sun.star.ui.ModuleUIConfigurationManagerSupplier")),
491         css::uno::UNO_QUERY_THROW);
492 
493     css::uno::Reference< css::ui::XAcceleratorConfiguration > xAccCfg;
494 	try
495 	{
496     	css::uno::Reference< css::ui::XUIConfigurationManager >   xUIManager = xUISupplier->getUIConfigurationManager(sModule);
497 	    xAccCfg = css::uno::Reference< css::ui::XAcceleratorConfiguration >(xUIManager->getShortCutManager(), css::uno::UNO_QUERY_THROW);
498 	}
499     catch(const css::container::NoSuchElementException&)
500         {}
501     return xAccCfg;
502 }
503 
504 //-----------------------------------------------
505 css::uno::Reference< css::ui::XAcceleratorConfiguration > AcceleratorExecute::st_openDocConfig(const css::uno::Reference< css::frame::XModel >& xModel)
506 {
507     css::uno::Reference< css::ui::XAcceleratorConfiguration >       xAccCfg;
508     css::uno::Reference< css::ui::XUIConfigurationManagerSupplier > xUISupplier(xModel, css::uno::UNO_QUERY);
509     if (xUISupplier.is())
510     {
511         css::uno::Reference< css::ui::XUIConfigurationManager >     xUIManager = xUISupplier->getUIConfigurationManager();
512         xAccCfg.set(xUIManager->getShortCutManager(), css::uno::UNO_QUERY_THROW);
513     }
514     return xAccCfg;
515 }
516 
517 //-----------------------------------------------
518 css::uno::Reference< css::util::XURLTransformer > AcceleratorExecute::impl_ts_getURLParser()
519 {
520     // SAFE -> ----------------------------------
521     ::osl::ResettableMutexGuard aLock(m_aLock);
522 
523     if (m_xURLParser.is())
524         return m_xURLParser;
525     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
526 
527     aLock.clear();
528     // <- SAFE ----------------------------------
529 
530     css::uno::Reference< css::util::XURLTransformer > xParser(
531                 xSMGR->createInstance(::rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer")),
532                 css::uno::UNO_QUERY_THROW);
533 
534     // SAFE -> ----------------------------------
535     aLock.reset();
536     m_xURLParser = xParser;
537     aLock.clear();
538     // <- SAFE ----------------------------------
539 
540     return xParser;
541 }
542 
543 //-----------------------------------------------
544 IMPL_LINK(AcceleratorExecute, impl_ts_asyncCallback, void*, EMPTYARG)
545 {
546     // replaced by AsyncAccelExec!
547     return 0;
548 }
549 
550 //-----------------------------------------------
551 AsyncAccelExec::AsyncAccelExec(const css::uno::Reference< css::frame::XDispatch >& xDispatch,
552                                const css::util::URL&                               aURL     )
553     : m_aAsyncCallback(LINK(this, AsyncAccelExec, impl_ts_asyncCallback))
554     , m_xDispatch     (xDispatch                                        )
555     , m_aURL          (aURL                                             )
556 {
557 }
558 
559 //-----------------------------------------------
560 AsyncAccelExec* AsyncAccelExec::createOnShotInstance(const css::uno::Reference< css::frame::XDispatch >& xDispatch,
561                                                      const css::util::URL&                               aURL     )
562 {
563     AsyncAccelExec* pExec = new AsyncAccelExec(xDispatch, aURL);
564     return pExec;
565 }
566 
567 //-----------------------------------------------
568 void AsyncAccelExec::execAsync()
569 {
570     m_aAsyncCallback.Post(0);
571 }
572 
573 //-----------------------------------------------
574 IMPL_LINK(AsyncAccelExec, impl_ts_asyncCallback, void*,)
575 {
576     if (! m_xDispatch.is())
577         return 0;
578 
579     try
580     {
581         m_xDispatch->dispatch(m_aURL, css::uno::Sequence< css::beans::PropertyValue >());
582     }
583     catch(const css::lang::DisposedException&)
584         {}
585     catch(const css::uno::RuntimeException& )
586         { throw; }
587     catch(const css::uno::Exception&)
588         {}
589 
590     delete this;
591 
592     return 0;
593 }
594 
595 } // namespace svt
596