1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_framework.hxx" 30 #include "acceleratorexecute.hxx" 31 32 //=============================================== 33 // includes 34 35 #ifndef __COM_SUN_STAR_FRAME_XMODULEMANAGER_HPP_ 36 #include <com/sun/star/frame/XModuleManager.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_KEYMODIFIER_HPP_ 52 #include <com/sun/star/awt/KeyModifier.hpp> 53 #endif 54 55 #ifndef __COM_SUN_STAR_UNO_SEQUENCE_HXX_ 56 #include <com/sun/star/uno/Sequence.hxx> 57 #endif 58 59 #ifndef __COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_ 60 #include <com/sun/star/beans/PropertyValue.hpp> 61 #endif 62 63 //=============================================== 64 // namespace 65 66 namespace svt 67 { 68 69 namespace css = ::com::sun::star; 70 71 //=============================================== 72 // definitions 73 74 //----------------------------------------------- 75 AcceleratorExecute::AcceleratorExecute() 76 : TMutexInit ( ) 77 , m_aAsyncCallback(LINK(this, AcceleratorExecute, impl_ts_asyncCallback)) 78 { 79 } 80 81 //----------------------------------------------- 82 AcceleratorExecute::AcceleratorExecute(const AcceleratorExecute& rCopy) 83 : TMutexInit ( ) 84 , m_aAsyncCallback(LINK(this, AcceleratorExecute, impl_ts_asyncCallback)) 85 { 86 // copy construction sint supported in real ... 87 // but we need this ctor to init our async callback ... 88 } 89 90 //----------------------------------------------- 91 AcceleratorExecute::~AcceleratorExecute() 92 { 93 // does nothing real 94 } 95 96 //----------------------------------------------- 97 AcceleratorExecute* AcceleratorExecute::createAcceleratorHelper() 98 { 99 AcceleratorExecute* pNew = new AcceleratorExecute(); 100 return pNew; 101 } 102 103 //----------------------------------------------- 104 void AcceleratorExecute::init(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR, 105 const css::uno::Reference< css::frame::XFrame >& xEnv ) 106 { 107 // SAFE -> ---------------------------------- 108 ::osl::ResettableMutexGuard aLock(m_aLock); 109 110 // take over the uno service manager 111 m_xSMGR = xSMGR; 112 113 // specify our internal dispatch provider 114 // frame or desktop?! => document or global config. 115 sal_Bool bDesktopIsUsed = sal_False; 116 m_xDispatcher = css::uno::Reference< css::frame::XDispatchProvider >(xEnv, css::uno::UNO_QUERY); 117 if (!m_xDispatcher.is()) 118 { 119 aLock.clear(); 120 // <- SAFE ------------------------------ 121 122 css::uno::Reference< css::frame::XDispatchProvider > xDispatcher( 123 xSMGR->createInstance(SERVICENAME_DESKTOP), 124 css::uno::UNO_QUERY_THROW); 125 126 // SAFE -> ------------------------------ 127 aLock.reset(); 128 129 m_xDispatcher = xDispatcher; 130 bDesktopIsUsed = sal_True; 131 } 132 133 aLock.clear(); 134 // <- SAFE ---------------------------------- 135 136 // open all needed configuration objects 137 css::uno::Reference< css::ui::XAcceleratorConfiguration > xGlobalCfg; 138 css::uno::Reference< css::ui::XAcceleratorConfiguration > xModuleCfg; 139 css::uno::Reference< css::ui::XAcceleratorConfiguration > xDocCfg ; 140 141 // global cfg 142 xGlobalCfg = AcceleratorExecute::impl_st_openGlobalConfig(xSMGR); 143 if (!bDesktopIsUsed) 144 { 145 // module cfg 146 xModuleCfg = AcceleratorExecute::impl_st_openModuleConfig(xSMGR, xEnv); 147 148 // doc cfg 149 css::uno::Reference< css::frame::XController > xController; 150 css::uno::Reference< css::frame::XModel > xModel; 151 xController = xEnv->getController(); 152 if (xController.is()) 153 xModel = xController->getModel(); 154 if (xModel.is()) 155 xDocCfg = AcceleratorExecute::impl_st_openDocConfig(xModel); 156 } 157 158 // SAFE -> ------------------------------ 159 aLock.reset(); 160 161 m_xGlobalCfg = xGlobalCfg; 162 m_xModuleCfg = xModuleCfg; 163 m_xDocCfg = xDocCfg ; 164 165 aLock.clear(); 166 // <- SAFE ---------------------------------- 167 } 168 169 //----------------------------------------------- 170 void AcceleratorExecute::execute(const KeyCode& aVCLKey) 171 { 172 css::awt::KeyEvent aAWTKey = AcceleratorExecute::st_VCLKey2AWTKey(aVCLKey); 173 execute(aAWTKey); 174 } 175 176 //----------------------------------------------- 177 void AcceleratorExecute::execute(const css::awt::KeyEvent& aAWTKey) 178 { 179 ::rtl::OUString sCommand = impl_ts_findCommand(aAWTKey); 180 181 // No Command found? Do nothing! User isnt interested on any error handling .-) 182 if (!sCommand.getLength()) 183 return; 184 185 // SAFE -> ---------------------------------- 186 ::osl::ResettableMutexGuard aLock(m_aLock); 187 188 m_lCommandQueue.push_back(sCommand); 189 m_aAsyncCallback.Post(0); 190 191 aLock.clear(); 192 // <- SAFE ---------------------------------- 193 } 194 195 //----------------------------------------------- 196 css::awt::KeyEvent AcceleratorExecute::st_VCLKey2AWTKey(const KeyCode& aVCLKey) 197 { 198 css::awt::KeyEvent aAWTKey; 199 aAWTKey.Modifiers = 0; 200 aAWTKey.KeyCode = (sal_Int16)aVCLKey.GetCode(); 201 202 if (aVCLKey.IsShift()) 203 aAWTKey.Modifiers |= css::awt::KeyModifier::SHIFT; 204 if (aVCLKey.IsMod1()) 205 aAWTKey.Modifiers |= css::awt::KeyModifier::MOD1; 206 if (aVCLKey.IsMod2()) 207 aAWTKey.Modifiers |= css::awt::KeyModifier::MOD2; 208 if (aVCLKey.IsMod3()) 209 aAWTKey.Modifiers |= css::awt::KeyModifier::MOD3; 210 211 return aAWTKey; 212 } 213 214 /* 215 ViewFrame->GetObjectShell 216 ObjectShell->GetStyleSheetPool 217 */ 218 219 //----------------------------------------------- 220 KeyCode AcceleratorExecute::st_AWTKey2VCLKey(const css::awt::KeyEvent& aAWTKey) 221 { 222 sal_Bool bShift = ((aAWTKey.Modifiers & css::awt::KeyModifier::SHIFT) == css::awt::KeyModifier::SHIFT ); 223 sal_Bool bMod1 = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD1 ) == css::awt::KeyModifier::MOD1 ); 224 sal_Bool bMod2 = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD2 ) == css::awt::KeyModifier::MOD2 ); 225 sal_Bool bMod3 = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD3 ) == css::awt::KeyModifier::MOD3 ); 226 sal_uInt16 nKey = (sal_uInt16)aAWTKey.KeyCode; 227 228 return KeyCode(nKey, bShift, bMod1, bMod2, bMod3); 229 } 230 231 //----------------------------------------------- 232 ::rtl::OUString AcceleratorExecute::impl_ts_findCommand(const css::awt::KeyEvent& aKey) 233 { 234 // SAFE -> ---------------------------------- 235 ::osl::ResettableMutexGuard aLock(m_aLock); 236 237 css::uno::Reference< css::ui::XAcceleratorConfiguration > xGlobalCfg = m_xGlobalCfg; 238 css::uno::Reference< css::ui::XAcceleratorConfiguration > xModuleCfg = m_xModuleCfg; 239 css::uno::Reference< css::ui::XAcceleratorConfiguration > xDocCfg = m_xDocCfg ; 240 241 aLock.clear(); 242 // <- SAFE ---------------------------------- 243 244 ::rtl::OUString sCommand; 245 try 246 { 247 if (xDocCfg.is()) 248 sCommand = xDocCfg->getCommandByKeyEvent(aKey); 249 } 250 catch(const css::container::NoSuchElementException&) 251 { 252 try 253 { 254 if (xModuleCfg.is()) 255 sCommand = xModuleCfg->getCommandByKeyEvent(aKey); 256 } 257 catch(const css::container::NoSuchElementException&) 258 { 259 try 260 { 261 if (xGlobalCfg.is()) 262 sCommand = xGlobalCfg->getCommandByKeyEvent(aKey); 263 } 264 catch(const css::container::NoSuchElementException&) 265 {} 266 } 267 } 268 269 return sCommand; 270 } 271 272 //----------------------------------------------- 273 css::uno::Reference< css::ui::XAcceleratorConfiguration > AcceleratorExecute::impl_st_openGlobalConfig(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR) 274 { 275 css::uno::Reference< css::ui::XAcceleratorConfiguration > xAccCfg( 276 xSMGR->createInstance(SERVICENAME_GLOBALACCELERATORCONFIGURATION), 277 css::uno::UNO_QUERY_THROW); 278 return xAccCfg; 279 } 280 281 //----------------------------------------------- 282 css::uno::Reference< css::ui::XAcceleratorConfiguration > AcceleratorExecute::impl_st_openModuleConfig(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR , 283 const css::uno::Reference< css::frame::XFrame >& xFrame) 284 { 285 css::uno::Reference< css::frame::XModuleManager > xModuleDetection( 286 xSMGR->createInstance(SERVICENAME_MODULEMANAGER), 287 css::uno::UNO_QUERY_THROW); 288 289 ::rtl::OUString sModule; 290 try 291 { 292 sModule = xModuleDetection->identify(xFrame); 293 } 294 catch(const css::uno::RuntimeException& exRuntime) 295 { throw exRuntime; } 296 catch(const css::uno::Exception&) 297 { return css::uno::Reference< css::ui::XAcceleratorConfiguration >(); } 298 299 css::uno::Reference< css::ui::XModuleUIConfigurationManagerSupplier > xUISupplier( 300 xSMGR->createInstance(SERVICENAME_MODULEUICONFIGURATIONMANAGERSUPPLIER), 301 css::uno::UNO_QUERY_THROW); 302 303 css::uno::Reference< css::ui::XUIConfigurationManager > xUIManager = xUISupplier->getUIConfigurationManager(sModule); 304 css::uno::Reference< css::ui::XAcceleratorConfiguration > xAccCfg (xUIManager->getShortCutManager(), css::uno::UNO_QUERY_THROW); 305 return xAccCfg; 306 } 307 308 //----------------------------------------------- 309 css::uno::Reference< css::ui::XAcceleratorConfiguration > AcceleratorExecute::impl_st_openDocConfig(const css::uno::Reference< css::frame::XModel >& xModel) 310 { 311 css::uno::Reference< css::ui::XUIConfigurationManagerSupplier > xUISupplier(xModel, css::uno::UNO_QUERY_THROW); 312 css::uno::Reference< css::ui::XUIConfigurationManager > xUIManager = xUISupplier->getUIConfigurationManager(); 313 css::uno::Reference< css::ui::XAcceleratorConfiguration > xAccCfg (xUIManager->getShortCutManager(), css::uno::UNO_QUERY_THROW); 314 return xAccCfg; 315 } 316 317 //----------------------------------------------- 318 css::uno::Reference< css::util::XURLTransformer > AcceleratorExecute::impl_ts_getURLParser() 319 { 320 // SAFE -> ---------------------------------- 321 ::osl::ResettableMutexGuard aLock(m_aLock); 322 323 if (m_xURLParser.is()) 324 return m_xURLParser; 325 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR; 326 327 aLock.clear(); 328 // <- SAFE ---------------------------------- 329 330 css::uno::Reference< css::util::XURLTransformer > xParser( 331 xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), 332 css::uno::UNO_QUERY_THROW); 333 334 // SAFE -> ---------------------------------- 335 aLock.reset(); 336 m_xURLParser = xParser; 337 aLock.clear(); 338 // <- SAFE ---------------------------------- 339 340 return xParser; 341 } 342 343 //----------------------------------------------- 344 IMPL_LINK(AcceleratorExecute, impl_ts_asyncCallback, void*, pVoid) 345 { 346 // SAFE -> ---------------------------------- 347 ::osl::ResettableMutexGuard aLock(m_aLock); 348 349 TCommandQueue::iterator pIt = m_lCommandQueue.begin(); 350 if (pIt == m_lCommandQueue.end()) 351 return 0; 352 ::rtl::OUString sCommand = *pIt; 353 m_lCommandQueue.erase(pIt); 354 355 css::uno::Reference< css::frame::XDispatchProvider > xProvider = m_xDispatcher; 356 357 aLock.clear(); 358 // <- SAFE ---------------------------------- 359 360 // convert command in URL structure 361 css::uno::Reference< css::util::XURLTransformer > xParser = impl_ts_getURLParser(); 362 css::util::URL aURL; 363 aURL.Complete = sCommand; 364 xParser->parseStrict(aURL); 365 366 // ask for dispatch object 367 css::uno::Reference< css::frame::XDispatch > xDispatch = xProvider->queryDispatch(aURL, ::rtl::OUString(), 0); 368 css::uno::Sequence< css::beans::PropertyValue> aArgs; 369 if (xDispatch.is()) 370 { 371 if(::comphelper::UiEventsLogger::isEnabled()) //#i88653# 372 { 373 Sequence<css::beans::PropertyValue> source; 374 ::comphelper::UiEventsLogger::appendDispatchOrigin(OUString::createFromAscii("AcceleratorExecute")); 375 ::comphelper::UiEventsLogger::logDispatch(aURL, source); 376 } 377 xDispatch->dispatch(aURL, css::uno::Sequence< css::beans::PropertyValue >()); 378 } 379 return 0; 380 } 381 382 } // namespace svt 383