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