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_framework.hxx" 26 #include "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_UI_XUICONFIGURATIONMANAGER_HPP_ 36 #include <com/sun/star/ui/XUIConfigurationManager.hpp> 37 #endif 38 39 #ifndef __COM_SUN_STAR_UI_XMODULEUICONFIGURATIONMANAGERSUPPLIER_HPP_ 40 #include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp> 41 #endif 42 43 #ifndef __COM_SUN_STAR_UI_XUICONFIGURATIONMANAGERSUPPLIER_HPP_ 44 #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp> 45 #endif 46 47 #ifndef __COM_SUN_STAR_AWT_KEYMODIFIER_HPP_ 48 #include <com/sun/star/awt/KeyModifier.hpp> 49 #endif 50 51 #ifndef __COM_SUN_STAR_UNO_SEQUENCE_HXX_ 52 #include <com/sun/star/uno/Sequence.hxx> 53 #endif 54 55 #ifndef __COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_ 56 #include <com/sun/star/beans/PropertyValue.hpp> 57 #endif 58 59 //=============================================== 60 // namespace 61 62 namespace svt 63 { 64 65 namespace css = ::com::sun::star; 66 67 //=============================================== 68 // definitions 69 70 //----------------------------------------------- 71 AcceleratorExecute::AcceleratorExecute() 72 : TMutexInit ( ) 73 , m_aAsyncCallback(LINK(this, AcceleratorExecute, impl_ts_asyncCallback)) 74 { 75 } 76 77 //----------------------------------------------- 78 AcceleratorExecute::AcceleratorExecute(const AcceleratorExecute& rCopy) 79 : TMutexInit ( ) 80 , m_aAsyncCallback(LINK(this, AcceleratorExecute, impl_ts_asyncCallback)) 81 { 82 // copy construction sint supported in real ... 83 // but we need this ctor to init our async callback ... 84 } 85 86 //----------------------------------------------- 87 AcceleratorExecute::~AcceleratorExecute() 88 { 89 // does nothing real 90 } 91 92 //----------------------------------------------- 93 AcceleratorExecute* AcceleratorExecute::createAcceleratorHelper() 94 { 95 AcceleratorExecute* pNew = new AcceleratorExecute(); 96 return pNew; 97 } 98 99 //----------------------------------------------- 100 void AcceleratorExecute::init(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR, 101 const css::uno::Reference< css::frame::XFrame >& xEnv ) 102 { 103 // SAFE -> ---------------------------------- 104 ::osl::ResettableMutexGuard aLock(m_aLock); 105 106 // take over the uno service manager 107 m_xSMGR = xSMGR; 108 109 // specify our internal dispatch provider 110 // frame or desktop?! => document or global config. 111 sal_Bool bDesktopIsUsed = sal_False; 112 m_xDispatcher = css::uno::Reference< css::frame::XDispatchProvider >(xEnv, css::uno::UNO_QUERY); 113 if (!m_xDispatcher.is()) 114 { 115 aLock.clear(); 116 // <- SAFE ------------------------------ 117 118 css::uno::Reference< css::frame::XDispatchProvider > xDispatcher( 119 xSMGR->createInstance(SERVICENAME_DESKTOP), 120 css::uno::UNO_QUERY_THROW); 121 122 // SAFE -> ------------------------------ 123 aLock.reset(); 124 125 m_xDispatcher = xDispatcher; 126 bDesktopIsUsed = sal_True; 127 } 128 129 aLock.clear(); 130 // <- SAFE ---------------------------------- 131 132 // open all needed configuration objects 133 css::uno::Reference< css::ui::XAcceleratorConfiguration > xGlobalCfg; 134 css::uno::Reference< css::ui::XAcceleratorConfiguration > xModuleCfg; 135 css::uno::Reference< css::ui::XAcceleratorConfiguration > xDocCfg ; 136 137 // global cfg 138 xGlobalCfg = AcceleratorExecute::impl_st_openGlobalConfig(xSMGR); 139 if (!bDesktopIsUsed) 140 { 141 // module cfg 142 xModuleCfg = AcceleratorExecute::impl_st_openModuleConfig(xSMGR, xEnv); 143 144 // doc cfg 145 css::uno::Reference< css::frame::XController > xController; 146 css::uno::Reference< css::frame::XModel > xModel; 147 xController = xEnv->getController(); 148 if (xController.is()) 149 xModel = xController->getModel(); 150 if (xModel.is()) 151 xDocCfg = AcceleratorExecute::impl_st_openDocConfig(xModel); 152 } 153 154 // SAFE -> ------------------------------ 155 aLock.reset(); 156 157 m_xGlobalCfg = xGlobalCfg; 158 m_xModuleCfg = xModuleCfg; 159 m_xDocCfg = xDocCfg ; 160 161 aLock.clear(); 162 // <- SAFE ---------------------------------- 163 } 164 165 //----------------------------------------------- 166 void AcceleratorExecute::execute(const KeyCode& aVCLKey) 167 { 168 css::awt::KeyEvent aAWTKey = AcceleratorExecute::st_VCLKey2AWTKey(aVCLKey); 169 execute(aAWTKey); 170 } 171 172 //----------------------------------------------- 173 void AcceleratorExecute::execute(const css::awt::KeyEvent& aAWTKey) 174 { 175 ::rtl::OUString sCommand = impl_ts_findCommand(aAWTKey); 176 177 // No Command found? Do nothing! User isnt interested on any error handling .-) 178 if (!sCommand.getLength()) 179 return; 180 181 // SAFE -> ---------------------------------- 182 ::osl::ResettableMutexGuard aLock(m_aLock); 183 184 m_lCommandQueue.push_back(sCommand); 185 m_aAsyncCallback.Post(0); 186 187 aLock.clear(); 188 // <- SAFE ---------------------------------- 189 } 190 191 //----------------------------------------------- 192 css::awt::KeyEvent AcceleratorExecute::st_VCLKey2AWTKey(const KeyCode& aVCLKey) 193 { 194 css::awt::KeyEvent aAWTKey; 195 aAWTKey.Modifiers = 0; 196 aAWTKey.KeyCode = (sal_Int16)aVCLKey.GetCode(); 197 198 if (aVCLKey.IsShift()) 199 aAWTKey.Modifiers |= css::awt::KeyModifier::SHIFT; 200 if (aVCLKey.IsMod1()) 201 aAWTKey.Modifiers |= css::awt::KeyModifier::MOD1; 202 if (aVCLKey.IsMod2()) 203 aAWTKey.Modifiers |= css::awt::KeyModifier::MOD2; 204 if (aVCLKey.IsMod3()) 205 aAWTKey.Modifiers |= css::awt::KeyModifier::MOD3; 206 207 return aAWTKey; 208 } 209 210 /* 211 ViewFrame->GetObjectShell 212 ObjectShell->GetStyleSheetPool 213 */ 214 215 //----------------------------------------------- 216 KeyCode AcceleratorExecute::st_AWTKey2VCLKey(const css::awt::KeyEvent& aAWTKey) 217 { 218 sal_Bool bShift = ((aAWTKey.Modifiers & css::awt::KeyModifier::SHIFT) == css::awt::KeyModifier::SHIFT ); 219 sal_Bool bMod1 = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD1 ) == css::awt::KeyModifier::MOD1 ); 220 sal_Bool bMod2 = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD2 ) == css::awt::KeyModifier::MOD2 ); 221 sal_Bool bMod3 = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD3 ) == css::awt::KeyModifier::MOD3 ); 222 sal_uInt16 nKey = (sal_uInt16)aAWTKey.KeyCode; 223 224 return KeyCode(nKey, bShift, bMod1, bMod2, bMod3); 225 } 226 227 //----------------------------------------------- 228 ::rtl::OUString AcceleratorExecute::impl_ts_findCommand(const css::awt::KeyEvent& aKey) 229 { 230 // SAFE -> ---------------------------------- 231 ::osl::ResettableMutexGuard aLock(m_aLock); 232 233 css::uno::Reference< css::ui::XAcceleratorConfiguration > xGlobalCfg = m_xGlobalCfg; 234 css::uno::Reference< css::ui::XAcceleratorConfiguration > xModuleCfg = m_xModuleCfg; 235 css::uno::Reference< css::ui::XAcceleratorConfiguration > xDocCfg = m_xDocCfg ; 236 237 aLock.clear(); 238 // <- SAFE ---------------------------------- 239 240 ::rtl::OUString sCommand; 241 try 242 { 243 if (xDocCfg.is()) 244 sCommand = xDocCfg->getCommandByKeyEvent(aKey); 245 } 246 catch(const css::container::NoSuchElementException&) 247 { 248 try 249 { 250 if (xModuleCfg.is()) 251 sCommand = xModuleCfg->getCommandByKeyEvent(aKey); 252 } 253 catch(const css::container::NoSuchElementException&) 254 { 255 try 256 { 257 if (xGlobalCfg.is()) 258 sCommand = xGlobalCfg->getCommandByKeyEvent(aKey); 259 } 260 catch(const css::container::NoSuchElementException&) 261 {} 262 } 263 } 264 265 return sCommand; 266 } 267 268 //----------------------------------------------- 269 css::uno::Reference< css::ui::XAcceleratorConfiguration > AcceleratorExecute::impl_st_openGlobalConfig(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR) 270 { 271 css::uno::Reference< css::ui::XAcceleratorConfiguration > xAccCfg( 272 xSMGR->createInstance(SERVICENAME_GLOBALACCELERATORCONFIGURATION), 273 css::uno::UNO_QUERY_THROW); 274 return xAccCfg; 275 } 276 277 //----------------------------------------------- 278 css::uno::Reference< css::ui::XAcceleratorConfiguration > AcceleratorExecute::impl_st_openModuleConfig(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR , 279 const css::uno::Reference< css::frame::XFrame >& xFrame) 280 { 281 css::uno::Reference< css::frame::XModuleManager > xModuleDetection( 282 xSMGR->createInstance(SERVICENAME_MODULEMANAGER), 283 css::uno::UNO_QUERY_THROW); 284 285 ::rtl::OUString sModule; 286 try 287 { 288 sModule = xModuleDetection->identify(xFrame); 289 } 290 catch(const css::uno::RuntimeException& exRuntime) 291 { throw exRuntime; } 292 catch(const css::uno::Exception&) 293 { return css::uno::Reference< css::ui::XAcceleratorConfiguration >(); } 294 295 css::uno::Reference< css::ui::XModuleUIConfigurationManagerSupplier > xUISupplier( 296 xSMGR->createInstance(SERVICENAME_MODULEUICONFIGURATIONMANAGERSUPPLIER), 297 css::uno::UNO_QUERY_THROW); 298 299 css::uno::Reference< css::ui::XUIConfigurationManager > xUIManager = xUISupplier->getUIConfigurationManager(sModule); 300 css::uno::Reference< css::ui::XAcceleratorConfiguration > xAccCfg (xUIManager->getShortCutManager(), css::uno::UNO_QUERY_THROW); 301 return xAccCfg; 302 } 303 304 //----------------------------------------------- 305 css::uno::Reference< css::ui::XAcceleratorConfiguration > AcceleratorExecute::impl_st_openDocConfig(const css::uno::Reference< css::frame::XModel >& xModel) 306 { 307 css::uno::Reference< css::ui::XUIConfigurationManagerSupplier > xUISupplier(xModel, css::uno::UNO_QUERY_THROW); 308 css::uno::Reference< css::ui::XUIConfigurationManager > xUIManager = xUISupplier->getUIConfigurationManager(); 309 css::uno::Reference< css::ui::XAcceleratorConfiguration > xAccCfg (xUIManager->getShortCutManager(), css::uno::UNO_QUERY_THROW); 310 return xAccCfg; 311 } 312 313 //----------------------------------------------- 314 css::uno::Reference< css::util::XURLTransformer > AcceleratorExecute::impl_ts_getURLParser() 315 { 316 // SAFE -> ---------------------------------- 317 ::osl::ResettableMutexGuard aLock(m_aLock); 318 319 if (m_xURLParser.is()) 320 return m_xURLParser; 321 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR; 322 323 aLock.clear(); 324 // <- SAFE ---------------------------------- 325 326 css::uno::Reference< css::util::XURLTransformer > xParser( 327 xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), 328 css::uno::UNO_QUERY_THROW); 329 330 // SAFE -> ---------------------------------- 331 aLock.reset(); 332 m_xURLParser = xParser; 333 aLock.clear(); 334 // <- SAFE ---------------------------------- 335 336 return xParser; 337 } 338 339 //----------------------------------------------- 340 IMPL_LINK(AcceleratorExecute, impl_ts_asyncCallback, void*, pVoid) 341 { 342 // SAFE -> ---------------------------------- 343 ::osl::ResettableMutexGuard aLock(m_aLock); 344 345 TCommandQueue::iterator pIt = m_lCommandQueue.begin(); 346 if (pIt == m_lCommandQueue.end()) 347 return 0; 348 ::rtl::OUString sCommand = *pIt; 349 m_lCommandQueue.erase(pIt); 350 351 css::uno::Reference< css::frame::XDispatchProvider > xProvider = m_xDispatcher; 352 353 aLock.clear(); 354 // <- SAFE ---------------------------------- 355 356 // convert command in URL structure 357 css::uno::Reference< css::util::XURLTransformer > xParser = impl_ts_getURLParser(); 358 css::util::URL aURL; 359 aURL.Complete = sCommand; 360 xParser->parseStrict(aURL); 361 362 // ask for dispatch object 363 css::uno::Reference< css::frame::XDispatch > xDispatch = xProvider->queryDispatch(aURL, ::rtl::OUString(), 0); 364 css::uno::Sequence< css::beans::PropertyValue> aArgs; 365 if (xDispatch.is()) 366 { 367 if(::comphelper::UiEventsLogger::isEnabled()) //#i88653# 368 { 369 Sequence<css::beans::PropertyValue> source; 370 ::comphelper::UiEventsLogger::appendDispatchOrigin(OUString::createFromAscii("AcceleratorExecute")); 371 ::comphelper::UiEventsLogger::logDispatch(aURL, source); 372 } 373 xDispatch->dispatch(aURL, css::uno::Sequence< css::beans::PropertyValue >()); 374 } 375 return 0; 376 } 377 378 } // namespace svt 379