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 #include "precompiled_sfx2.hxx" 23 24 #include "CommandInfoProvider.hxx" 25 26 #include <comphelper/processfactory.hxx> 27 #include <svtools/acceleratorexecute.hxx> 28 #include <cppuhelper/compbase1.hxx> 29 #include <cppuhelper/basemutex.hxx> 30 31 #include <com/sun/star/frame/XModuleManager.hpp> 32 #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp> 33 #include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp> 34 35 using namespace css; 36 using namespace cssu; 37 using ::rtl::OUString; 38 39 40 #define A2S(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s)) 41 42 43 namespace 44 { 45 typedef ::cppu::WeakComponentImplHelper1 < 46 css::lang::XEventListener 47 > FrameListenerInterfaceBase; 48 class FrameListener 49 : public ::cppu::BaseMutex, 50 public FrameListenerInterfaceBase 51 { 52 public: 53 FrameListener (sfx2::sidebar::CommandInfoProvider& rInfoProvider, const Reference<frame::XFrame>& rxFrame) 54 : FrameListenerInterfaceBase(m_aMutex), 55 mrInfoProvider(rInfoProvider), 56 mxFrame(rxFrame) 57 { 58 if (mxFrame.is()) 59 mxFrame->addEventListener(this); 60 } 61 virtual ~FrameListener (void) 62 { 63 } 64 virtual void SAL_CALL disposing (void) 65 { 66 if (mxFrame.is()) 67 mxFrame->removeEventListener(this); 68 } 69 virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent) 70 throw (cssu::RuntimeException) 71 { 72 (void)rEvent; 73 mrInfoProvider.SetFrame(NULL); 74 mxFrame = NULL; 75 } 76 77 private: 78 sfx2::sidebar::CommandInfoProvider& mrInfoProvider; 79 Reference<frame::XFrame> mxFrame; 80 }; 81 } 82 83 84 85 namespace sfx2 { namespace sidebar { 86 87 CommandInfoProvider& CommandInfoProvider::Instance (void) 88 { 89 static CommandInfoProvider aProvider; 90 return aProvider; 91 } 92 93 94 95 96 CommandInfoProvider::CommandInfoProvider (void) 97 : mxServiceFactory(comphelper::getProcessServiceFactory()), 98 mxCachedDataFrame(), 99 mxCachedDocumentAcceleratorConfiguration(), 100 mxCachedModuleAcceleratorConfiguration(), 101 mxCachedGlobalAcceleratorConfiguration(), 102 msCachedModuleIdentifier(), 103 mxFrameListener() 104 { 105 } 106 107 108 109 110 CommandInfoProvider::~CommandInfoProvider (void) 111 { 112 if (mxFrameListener.is()) 113 { 114 mxFrameListener->dispose(); 115 mxFrameListener = NULL; 116 } 117 } 118 119 120 121 122 OUString CommandInfoProvider::GetLabelForCommand ( 123 const OUString& rsCommandName, 124 const Reference<frame::XFrame>& rxFrame) 125 { 126 SetFrame(rxFrame); 127 128 const OUString sLabel (GetCommandLabel(rsCommandName)); 129 const OUString sShortCut (GetCommandShortcut(rsCommandName)); 130 if (sShortCut.getLength() > 0) 131 return sLabel + A2S(" (") + sShortCut + A2S(")"); 132 else 133 return sLabel; 134 } 135 136 137 138 139 void CommandInfoProvider::SetFrame (const Reference<frame::XFrame>& rxFrame) 140 { 141 if (rxFrame != mxCachedDataFrame) 142 { 143 // Detach from the old frame. 144 if (mxFrameListener.is()) 145 { 146 mxFrameListener->dispose(); 147 mxFrameListener = NULL; 148 } 149 150 // Release objects that are tied to the old frame. 151 mxCachedDocumentAcceleratorConfiguration = NULL; 152 mxCachedModuleAcceleratorConfiguration = NULL; 153 msCachedModuleIdentifier = OUString(); 154 mxCachedDataFrame = rxFrame; 155 156 // Connect to the new frame. 157 if (rxFrame.is()) 158 mxFrameListener = new FrameListener(*this, rxFrame); 159 } 160 } 161 162 163 164 165 Reference<ui::XAcceleratorConfiguration> CommandInfoProvider::GetDocumentAcceleratorConfiguration (void) 166 { 167 if ( ! mxCachedDocumentAcceleratorConfiguration.is()) 168 { 169 // Get the accelerator configuration for the document. 170 if (mxCachedDataFrame.is()) 171 { 172 Reference<frame::XController> xController = mxCachedDataFrame->getController(); 173 if (xController.is()) 174 { 175 Reference<frame::XModel> xModel (xController->getModel()); 176 if (xModel.is()) 177 { 178 Reference<ui::XUIConfigurationManagerSupplier> xSupplier (xModel, UNO_QUERY); 179 if (xSupplier.is()) 180 { 181 Reference<ui::XUIConfigurationManager> xConfigurationManager( 182 xSupplier->getUIConfigurationManager(), 183 UNO_QUERY); 184 if (xConfigurationManager.is()) 185 { 186 mxCachedDocumentAcceleratorConfiguration = Reference<ui::XAcceleratorConfiguration>( 187 xConfigurationManager->getShortCutManager(), 188 UNO_QUERY); 189 } 190 } 191 } 192 } 193 } 194 } 195 return mxCachedDocumentAcceleratorConfiguration; 196 } 197 198 199 200 201 Reference<ui::XAcceleratorConfiguration> CommandInfoProvider::GetModuleAcceleratorConfiguration (void) 202 { 203 if ( ! mxCachedModuleAcceleratorConfiguration.is()) 204 { 205 try 206 { 207 Reference<ui::XModuleUIConfigurationManagerSupplier> xSupplier ( 208 mxServiceFactory->createInstance(A2S("com.sun.star.ui.ModuleUIConfigurationManagerSupplier")), 209 UNO_QUERY); 210 Reference<ui::XUIConfigurationManager> xManager ( 211 xSupplier->getUIConfigurationManager(GetModuleIdentifier())); 212 if (xManager.is()) 213 { 214 mxCachedModuleAcceleratorConfiguration = Reference<ui::XAcceleratorConfiguration>( 215 xManager->getShortCutManager(), 216 UNO_QUERY); 217 } 218 } 219 catch (Exception&) 220 { 221 } 222 } 223 return mxCachedModuleAcceleratorConfiguration; 224 } 225 226 227 228 229 Reference<ui::XAcceleratorConfiguration> CommandInfoProvider::GetGlobalAcceleratorConfiguration (void) 230 { 231 // Get the global accelerator configuration. 232 if ( ! mxCachedGlobalAcceleratorConfiguration.is()) 233 { 234 mxCachedGlobalAcceleratorConfiguration = Reference<ui::XAcceleratorConfiguration>( 235 mxServiceFactory->createInstance(A2S("com.sun.star.ui.GlobalAcceleratorConfiguration")), 236 UNO_QUERY); 237 } 238 239 return mxCachedGlobalAcceleratorConfiguration; 240 } 241 242 243 244 245 OUString CommandInfoProvider::GetModuleIdentifier (void) 246 { 247 if (msCachedModuleIdentifier.getLength() == 0) 248 { 249 Reference<frame::XModuleManager> xModuleManager ( 250 mxServiceFactory->createInstance(A2S("com.sun.star.frame.ModuleManager")), 251 UNO_QUERY); 252 if (xModuleManager.is()) 253 msCachedModuleIdentifier = xModuleManager->identify(mxCachedDataFrame); 254 } 255 return msCachedModuleIdentifier; 256 } 257 258 259 260 261 OUString CommandInfoProvider::GetCommandShortcut (const OUString& rsCommandName) 262 { 263 OUString sShortcut; 264 265 sShortcut = RetrieveShortcutsFromConfiguration(GetDocumentAcceleratorConfiguration(), rsCommandName); 266 if (sShortcut.getLength() > 0) 267 return sShortcut; 268 269 sShortcut = RetrieveShortcutsFromConfiguration(GetModuleAcceleratorConfiguration(), rsCommandName); 270 if (sShortcut.getLength() > 0) 271 return sShortcut; 272 273 sShortcut = RetrieveShortcutsFromConfiguration(GetGlobalAcceleratorConfiguration(), rsCommandName); 274 if (sShortcut.getLength() > 0) 275 return sShortcut; 276 277 return OUString(); 278 } 279 280 281 282 283 OUString CommandInfoProvider::RetrieveShortcutsFromConfiguration( 284 const Reference<ui::XAcceleratorConfiguration>& rxConfiguration, 285 const OUString& rsCommandName) 286 { 287 if (rxConfiguration.is()) 288 { 289 try 290 { 291 Sequence<OUString> aCommands(1); 292 aCommands[0] = rsCommandName; 293 294 Sequence<Any> aKeyCodes (rxConfiguration->getPreferredKeyEventsForCommandList(aCommands)); 295 if (aCommands.getLength() == 1) 296 { 297 css::awt::KeyEvent aKeyEvent; 298 if (aKeyCodes[0] >>= aKeyEvent) 299 { 300 return svt::AcceleratorExecute::st_AWTKey2VCLKey(aKeyEvent).GetName(); 301 } 302 } 303 } 304 catch (lang::IllegalArgumentException&) 305 { 306 } 307 } 308 return OUString(); 309 } 310 311 312 313 314 Sequence<beans::PropertyValue> CommandInfoProvider::GetCommandProperties (const OUString& rsCommandName) 315 { 316 Sequence<beans::PropertyValue> aProperties; 317 318 try 319 { 320 const OUString sModuleIdentifier (GetModuleIdentifier()); 321 if (sModuleIdentifier.getLength() > 0) 322 { 323 Reference<container::XNameAccess> xNameAccess ( 324 mxServiceFactory->createInstance( 325 OUString::createFromAscii("com.sun.star.frame.UICommandDescription")), 326 UNO_QUERY); 327 Reference<container::XNameAccess> xUICommandLabels; 328 if (xNameAccess.is()) 329 if (xNameAccess->getByName(sModuleIdentifier) >>= xUICommandLabels) 330 xUICommandLabels->getByName(rsCommandName) >>= aProperties; 331 } 332 } 333 catch (Exception&) 334 { 335 } 336 337 return aProperties; 338 } 339 340 341 342 343 OUString CommandInfoProvider::GetCommandLabel (const OUString& rsCommandName) 344 { 345 const Sequence<beans::PropertyValue> aProperties (GetCommandProperties(rsCommandName)); 346 for (sal_Int32 nIndex=0; nIndex<aProperties.getLength(); ++nIndex) 347 { 348 if (aProperties[nIndex].Name.equalsAscii("Name")) 349 { 350 OUString sLabel; 351 aProperties[nIndex].Value >>= sLabel; 352 return sLabel; 353 } 354 } 355 return OUString(); 356 } 357 358 359 } } // end of namespace sfx2/framework 360