| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_framework.hxx" |
| #include "acceleratorexecute.hxx" |
| |
| //=============================================== |
| // includes |
| |
| #ifndef __COM_SUN_STAR_FRAME_XMODULEMANAGER_HPP_ |
| #include <com/sun/star/frame/XModuleManager.hpp> |
| #endif |
| |
| #ifndef __COM_SUN_STAR_UI_XUICONFIGURATIONMANAGER_HPP_ |
| #include <com/sun/star/ui/XUIConfigurationManager.hpp> |
| #endif |
| |
| #ifndef __COM_SUN_STAR_UI_XMODULEUICONFIGURATIONMANAGERSUPPLIER_HPP_ |
| #include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp> |
| #endif |
| |
| #ifndef __COM_SUN_STAR_UI_XUICONFIGURATIONMANAGERSUPPLIER_HPP_ |
| #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp> |
| #endif |
| |
| #ifndef __COM_SUN_STAR_AWT_KEYMODIFIER_HPP_ |
| #include <com/sun/star/awt/KeyModifier.hpp> |
| #endif |
| |
| #ifndef __COM_SUN_STAR_UNO_SEQUENCE_HXX_ |
| #include <com/sun/star/uno/Sequence.hxx> |
| #endif |
| |
| #ifndef __COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_ |
| #include <com/sun/star/beans/PropertyValue.hpp> |
| #endif |
| |
| //=============================================== |
| // namespace |
| |
| namespace svt |
| { |
| |
| namespace css = ::com::sun::star; |
| |
| //=============================================== |
| // definitions |
| |
| //----------------------------------------------- |
| AcceleratorExecute::AcceleratorExecute() |
| : TMutexInit ( ) |
| , m_aAsyncCallback(LINK(this, AcceleratorExecute, impl_ts_asyncCallback)) |
| { |
| } |
| |
| //----------------------------------------------- |
| AcceleratorExecute::AcceleratorExecute(const AcceleratorExecute& rCopy) |
| : TMutexInit ( ) |
| , m_aAsyncCallback(LINK(this, AcceleratorExecute, impl_ts_asyncCallback)) |
| { |
| // copy construction sint supported in real ... |
| // but we need this ctor to init our async callback ... |
| } |
| |
| //----------------------------------------------- |
| AcceleratorExecute::~AcceleratorExecute() |
| { |
| // does nothing real |
| } |
| |
| //----------------------------------------------- |
| AcceleratorExecute* AcceleratorExecute::createAcceleratorHelper() |
| { |
| AcceleratorExecute* pNew = new AcceleratorExecute(); |
| return pNew; |
| } |
| |
| //----------------------------------------------- |
| void AcceleratorExecute::init(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR, |
| const css::uno::Reference< css::frame::XFrame >& xEnv ) |
| { |
| // SAFE -> ---------------------------------- |
| ::osl::ResettableMutexGuard aLock(m_aLock); |
| |
| // take over the uno service manager |
| m_xSMGR = xSMGR; |
| |
| // specify our internal dispatch provider |
| // frame or desktop?! => document or global config. |
| sal_Bool bDesktopIsUsed = sal_False; |
| m_xDispatcher = css::uno::Reference< css::frame::XDispatchProvider >(xEnv, css::uno::UNO_QUERY); |
| if (!m_xDispatcher.is()) |
| { |
| aLock.clear(); |
| // <- SAFE ------------------------------ |
| |
| css::uno::Reference< css::frame::XDispatchProvider > xDispatcher( |
| xSMGR->createInstance(SERVICENAME_DESKTOP), |
| css::uno::UNO_QUERY_THROW); |
| |
| // SAFE -> ------------------------------ |
| aLock.reset(); |
| |
| m_xDispatcher = xDispatcher; |
| bDesktopIsUsed = sal_True; |
| } |
| |
| aLock.clear(); |
| // <- SAFE ---------------------------------- |
| |
| // open all needed configuration objects |
| css::uno::Reference< css::ui::XAcceleratorConfiguration > xGlobalCfg; |
| css::uno::Reference< css::ui::XAcceleratorConfiguration > xModuleCfg; |
| css::uno::Reference< css::ui::XAcceleratorConfiguration > xDocCfg ; |
| |
| // global cfg |
| xGlobalCfg = AcceleratorExecute::impl_st_openGlobalConfig(xSMGR); |
| if (!bDesktopIsUsed) |
| { |
| // module cfg |
| xModuleCfg = AcceleratorExecute::impl_st_openModuleConfig(xSMGR, xEnv); |
| |
| // doc cfg |
| css::uno::Reference< css::frame::XController > xController; |
| css::uno::Reference< css::frame::XModel > xModel; |
| xController = xEnv->getController(); |
| if (xController.is()) |
| xModel = xController->getModel(); |
| if (xModel.is()) |
| xDocCfg = AcceleratorExecute::impl_st_openDocConfig(xModel); |
| } |
| |
| // SAFE -> ------------------------------ |
| aLock.reset(); |
| |
| m_xGlobalCfg = xGlobalCfg; |
| m_xModuleCfg = xModuleCfg; |
| m_xDocCfg = xDocCfg ; |
| |
| aLock.clear(); |
| // <- SAFE ---------------------------------- |
| } |
| |
| //----------------------------------------------- |
| void AcceleratorExecute::execute(const KeyCode& aVCLKey) |
| { |
| css::awt::KeyEvent aAWTKey = AcceleratorExecute::st_VCLKey2AWTKey(aVCLKey); |
| execute(aAWTKey); |
| } |
| |
| //----------------------------------------------- |
| void AcceleratorExecute::execute(const css::awt::KeyEvent& aAWTKey) |
| { |
| ::rtl::OUString sCommand = impl_ts_findCommand(aAWTKey); |
| |
| // No Command found? Do nothing! User isnt interested on any error handling .-) |
| if (!sCommand.getLength()) |
| return; |
| |
| // SAFE -> ---------------------------------- |
| ::osl::ResettableMutexGuard aLock(m_aLock); |
| |
| m_lCommandQueue.push_back(sCommand); |
| m_aAsyncCallback.Post(0); |
| |
| aLock.clear(); |
| // <- SAFE ---------------------------------- |
| } |
| |
| //----------------------------------------------- |
| css::awt::KeyEvent AcceleratorExecute::st_VCLKey2AWTKey(const KeyCode& aVCLKey) |
| { |
| css::awt::KeyEvent aAWTKey; |
| aAWTKey.Modifiers = 0; |
| aAWTKey.KeyCode = (sal_Int16)aVCLKey.GetCode(); |
| |
| if (aVCLKey.IsShift()) |
| aAWTKey.Modifiers |= css::awt::KeyModifier::SHIFT; |
| if (aVCLKey.IsMod1()) |
| aAWTKey.Modifiers |= css::awt::KeyModifier::MOD1; |
| if (aVCLKey.IsMod2()) |
| aAWTKey.Modifiers |= css::awt::KeyModifier::MOD2; |
| if (aVCLKey.IsMod3()) |
| aAWTKey.Modifiers |= css::awt::KeyModifier::MOD3; |
| |
| return aAWTKey; |
| } |
| |
| /* |
| ViewFrame->GetObjectShell |
| ObjectShell->GetStyleSheetPool |
| */ |
| |
| //----------------------------------------------- |
| KeyCode AcceleratorExecute::st_AWTKey2VCLKey(const css::awt::KeyEvent& aAWTKey) |
| { |
| sal_Bool bShift = ((aAWTKey.Modifiers & css::awt::KeyModifier::SHIFT) == css::awt::KeyModifier::SHIFT ); |
| sal_Bool bMod1 = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD1 ) == css::awt::KeyModifier::MOD1 ); |
| sal_Bool bMod2 = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD2 ) == css::awt::KeyModifier::MOD2 ); |
| sal_Bool bMod3 = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD3 ) == css::awt::KeyModifier::MOD3 ); |
| sal_uInt16 nKey = (sal_uInt16)aAWTKey.KeyCode; |
| |
| return KeyCode(nKey, bShift, bMod1, bMod2, bMod3); |
| } |
| |
| //----------------------------------------------- |
| ::rtl::OUString AcceleratorExecute::impl_ts_findCommand(const css::awt::KeyEvent& aKey) |
| { |
| // SAFE -> ---------------------------------- |
| ::osl::ResettableMutexGuard aLock(m_aLock); |
| |
| css::uno::Reference< css::ui::XAcceleratorConfiguration > xGlobalCfg = m_xGlobalCfg; |
| css::uno::Reference< css::ui::XAcceleratorConfiguration > xModuleCfg = m_xModuleCfg; |
| css::uno::Reference< css::ui::XAcceleratorConfiguration > xDocCfg = m_xDocCfg ; |
| |
| aLock.clear(); |
| // <- SAFE ---------------------------------- |
| |
| ::rtl::OUString sCommand; |
| try |
| { |
| if (xDocCfg.is()) |
| sCommand = xDocCfg->getCommandByKeyEvent(aKey); |
| } |
| catch(const css::container::NoSuchElementException&) |
| { |
| try |
| { |
| if (xModuleCfg.is()) |
| sCommand = xModuleCfg->getCommandByKeyEvent(aKey); |
| } |
| catch(const css::container::NoSuchElementException&) |
| { |
| try |
| { |
| if (xGlobalCfg.is()) |
| sCommand = xGlobalCfg->getCommandByKeyEvent(aKey); |
| } |
| catch(const css::container::NoSuchElementException&) |
| {} |
| } |
| } |
| |
| return sCommand; |
| } |
| |
| //----------------------------------------------- |
| css::uno::Reference< css::ui::XAcceleratorConfiguration > AcceleratorExecute::impl_st_openGlobalConfig(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR) |
| { |
| css::uno::Reference< css::ui::XAcceleratorConfiguration > xAccCfg( |
| xSMGR->createInstance(SERVICENAME_GLOBALACCELERATORCONFIGURATION), |
| css::uno::UNO_QUERY_THROW); |
| return xAccCfg; |
| } |
| |
| //----------------------------------------------- |
| css::uno::Reference< css::ui::XAcceleratorConfiguration > AcceleratorExecute::impl_st_openModuleConfig(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR , |
| const css::uno::Reference< css::frame::XFrame >& xFrame) |
| { |
| css::uno::Reference< css::frame::XModuleManager > xModuleDetection( |
| xSMGR->createInstance(SERVICENAME_MODULEMANAGER), |
| css::uno::UNO_QUERY_THROW); |
| |
| ::rtl::OUString sModule; |
| try |
| { |
| sModule = xModuleDetection->identify(xFrame); |
| } |
| catch(const css::uno::RuntimeException& exRuntime) |
| { throw exRuntime; } |
| catch(const css::uno::Exception&) |
| { return css::uno::Reference< css::ui::XAcceleratorConfiguration >(); } |
| |
| css::uno::Reference< css::ui::XModuleUIConfigurationManagerSupplier > xUISupplier( |
| xSMGR->createInstance(SERVICENAME_MODULEUICONFIGURATIONMANAGERSUPPLIER), |
| css::uno::UNO_QUERY_THROW); |
| |
| css::uno::Reference< css::ui::XUIConfigurationManager > xUIManager = xUISupplier->getUIConfigurationManager(sModule); |
| css::uno::Reference< css::ui::XAcceleratorConfiguration > xAccCfg (xUIManager->getShortCutManager(), css::uno::UNO_QUERY_THROW); |
| return xAccCfg; |
| } |
| |
| //----------------------------------------------- |
| css::uno::Reference< css::ui::XAcceleratorConfiguration > AcceleratorExecute::impl_st_openDocConfig(const css::uno::Reference< css::frame::XModel >& xModel) |
| { |
| css::uno::Reference< css::ui::XUIConfigurationManagerSupplier > xUISupplier(xModel, css::uno::UNO_QUERY_THROW); |
| css::uno::Reference< css::ui::XUIConfigurationManager > xUIManager = xUISupplier->getUIConfigurationManager(); |
| css::uno::Reference< css::ui::XAcceleratorConfiguration > xAccCfg (xUIManager->getShortCutManager(), css::uno::UNO_QUERY_THROW); |
| return xAccCfg; |
| } |
| |
| //----------------------------------------------- |
| css::uno::Reference< css::util::XURLTransformer > AcceleratorExecute::impl_ts_getURLParser() |
| { |
| // SAFE -> ---------------------------------- |
| ::osl::ResettableMutexGuard aLock(m_aLock); |
| |
| if (m_xURLParser.is()) |
| return m_xURLParser; |
| css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR; |
| |
| aLock.clear(); |
| // <- SAFE ---------------------------------- |
| |
| css::uno::Reference< css::util::XURLTransformer > xParser( |
| xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), |
| css::uno::UNO_QUERY_THROW); |
| |
| // SAFE -> ---------------------------------- |
| aLock.reset(); |
| m_xURLParser = xParser; |
| aLock.clear(); |
| // <- SAFE ---------------------------------- |
| |
| return xParser; |
| } |
| |
| //----------------------------------------------- |
| IMPL_LINK(AcceleratorExecute, impl_ts_asyncCallback, void*, pVoid) |
| { |
| // SAFE -> ---------------------------------- |
| ::osl::ResettableMutexGuard aLock(m_aLock); |
| |
| TCommandQueue::iterator pIt = m_lCommandQueue.begin(); |
| if (pIt == m_lCommandQueue.end()) |
| return 0; |
| ::rtl::OUString sCommand = *pIt; |
| m_lCommandQueue.erase(pIt); |
| |
| css::uno::Reference< css::frame::XDispatchProvider > xProvider = m_xDispatcher; |
| |
| aLock.clear(); |
| // <- SAFE ---------------------------------- |
| |
| // convert command in URL structure |
| css::uno::Reference< css::util::XURLTransformer > xParser = impl_ts_getURLParser(); |
| css::util::URL aURL; |
| aURL.Complete = sCommand; |
| xParser->parseStrict(aURL); |
| |
| // ask for dispatch object |
| css::uno::Reference< css::frame::XDispatch > xDispatch = xProvider->queryDispatch(aURL, ::rtl::OUString(), 0); |
| css::uno::Sequence< css::beans::PropertyValue> aArgs; |
| if (xDispatch.is()) |
| { |
| if(::comphelper::UiEventsLogger::isEnabled()) //#i88653# |
| { |
| Sequence<css::beans::PropertyValue> source; |
| ::comphelper::UiEventsLogger::appendDispatchOrigin(OUString::createFromAscii("AcceleratorExecute")); |
| ::comphelper::UiEventsLogger::logDispatch(aURL, source); |
| } |
| xDispatch->dispatch(aURL, css::uno::Sequence< css::beans::PropertyValue >()); |
| } |
| return 0; |
| } |
| |
| } // namespace svt |