LibreOffice Module vcl (master)  1
commandinfoprovider.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
21 #include <vcl/keycod.hxx>
22 #include <vcl/mnemonic.hxx>
23 #include <comphelper/string.hxx>
24 #include <comphelper/sequence.hxx>
26 #include <cppuhelper/weakref.hxx>
27 
28 #include <com/sun/star/frame/XFrame.hpp>
29 #include <com/sun/star/frame/ModuleManager.hpp>
30 #include <com/sun/star/frame/theUICommandDescription.hpp>
31 #include <com/sun/star/ui/GlobalAcceleratorConfiguration.hpp>
32 #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
33 #include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
34 #include <com/sun/star/ui/ImageType.hpp>
35 #include <com/sun/star/ui/XImageManager.hpp>
36 #include <com/sun/star/awt/KeyModifier.hpp>
37 
38 using namespace css;
39 using namespace css::uno;
40 
41 namespace vcl { namespace CommandInfoProvider {
42 
44 {
45  static WeakReference<container::XNameAccess> xWeakRef;
46  css::uno::Reference<container::XNameAccess> xRef(xWeakRef);
47 
48  if (!xRef.is())
49  {
50  xRef = frame::theUICommandDescription::get(comphelper::getProcessComponentContext());
51  xWeakRef = xRef;
52  }
53 
54  return xRef;
55 }
56 
57 static Reference<ui::XModuleUIConfigurationManagerSupplier> GetModuleConfigurationSupplier()
58 {
59  static WeakReference<ui::XModuleUIConfigurationManagerSupplier> xWeakRef;
60  css::uno::Reference<ui::XModuleUIConfigurationManagerSupplier> xRef(xWeakRef);
61 
62  if (!xRef.is())
63  {
64  xRef = ui::theModuleUIConfigurationManagerSupplier::get(comphelper::getProcessComponentContext());
65  xWeakRef = xRef;
66  }
67 
68  return xRef;
69 }
70 
71 static Reference<ui::XAcceleratorConfiguration> GetGlobalAcceleratorConfiguration()
72 {
73  static WeakReference<ui::XAcceleratorConfiguration> xWeakRef;
74  css::uno::Reference<ui::XAcceleratorConfiguration> xRef(xWeakRef);
75 
76  if (!xRef.is())
77  {
78  xRef = ui::GlobalAcceleratorConfiguration::create(comphelper::getProcessComponentContext());
79  xWeakRef = xRef;
80  }
81 
82  return xRef;
83 }
84 
85 static Reference<ui::XAcceleratorConfiguration> GetDocumentAcceleratorConfiguration(const Reference<frame::XFrame>& rxFrame)
86 {
87  Reference<frame::XController> xController = rxFrame->getController();
88  if (xController.is())
89  {
90  Reference<ui::XUIConfigurationManagerSupplier> xSupplier(xController->getModel(), UNO_QUERY);
91  if (xSupplier.is())
92  {
93  Reference<ui::XUIConfigurationManager> xConfigurationManager(
94  xSupplier->getUIConfigurationManager());
95  if (xConfigurationManager.is())
96  {
97  return xConfigurationManager->getShortCutManager();
98  }
99  }
100  }
101  return nullptr;
102 }
103 
104 static Reference<ui::XAcceleratorConfiguration> GetModuleAcceleratorConfiguration(const Reference<frame::XFrame>& rxFrame)
105 {
106  css::uno::Reference<css::ui::XAcceleratorConfiguration> curModuleAcceleratorConfiguration;
107  try
108  {
109  Reference<ui::XModuleUIConfigurationManagerSupplier> xSupplier(GetModuleConfigurationSupplier());
110  Reference<ui::XUIConfigurationManager> xManager (
111  xSupplier->getUIConfigurationManager(GetModuleIdentifier(rxFrame)));
112  if (xManager.is())
113  {
114  curModuleAcceleratorConfiguration = xManager->getShortCutManager();
115  }
116  }
117  catch (Exception&)
118  {
119  }
120  return curModuleAcceleratorConfiguration;
121 }
122 
123 static vcl::KeyCode AWTKey2VCLKey(const awt::KeyEvent& aAWTKey)
124 {
125  bool bShift = ((aAWTKey.Modifiers & awt::KeyModifier::SHIFT) == awt::KeyModifier::SHIFT );
126  bool bMod1 = ((aAWTKey.Modifiers & awt::KeyModifier::MOD1 ) == awt::KeyModifier::MOD1 );
127  bool bMod2 = ((aAWTKey.Modifiers & awt::KeyModifier::MOD2 ) == awt::KeyModifier::MOD2 );
128  bool bMod3 = ((aAWTKey.Modifiers & awt::KeyModifier::MOD3 ) == awt::KeyModifier::MOD3 );
129  sal_uInt16 nKey = static_cast<sal_uInt16>(aAWTKey.KeyCode);
130 
131  return vcl::KeyCode(nKey, bShift, bMod1, bMod2, bMod3);
132 }
133 
135  const Reference<ui::XAcceleratorConfiguration>& rxConfiguration,
136  const OUString& rsCommandName)
137 {
138  if (rxConfiguration.is())
139  {
140  try
141  {
142  Sequence<OUString> aCommands { rsCommandName };
143 
144  Sequence<Any> aKeyCodes (rxConfiguration->getPreferredKeyEventsForCommandList(aCommands));
145  if (aCommands.getLength() == 1)
146  {
147  awt::KeyEvent aKeyEvent;
148  if (aKeyCodes[0] >>= aKeyEvent)
149  {
150  return AWTKey2VCLKey(aKeyEvent).GetName();
151  }
152  }
153  }
154  catch (css::lang::IllegalArgumentException&)
155  {
156  }
157  }
158  return OUString();
159 }
160 
161 static bool ResourceHasKey(const OUString& rsResourceName, const OUString& rsCommandName, const OUString& rsModuleName)
162 {
163  Sequence< OUString > aSequence;
164  try
165  {
166  if (!rsModuleName.isEmpty())
167  {
169  Reference<container::XNameAccess> xUICommandLabels;
170  if (xNameAccess->getByName(rsModuleName) >>= xUICommandLabels)
171  {
172  xUICommandLabels->getByName(rsResourceName) >>= aSequence;
173  if (comphelper::findValue(aSequence, rsCommandName) != -1)
174  return true;
175  }
176  }
177  }
178  catch (Exception&)
179  {
180  }
181  return false;
182 }
183 
184 static Sequence<beans::PropertyValue> GetCommandProperties(const OUString& rsCommandName, const OUString& rsModuleName)
185 {
186  Sequence<beans::PropertyValue> aProperties;
187 
188  try
189  {
190  if (!rsModuleName.isEmpty())
191  {
193  Reference<container::XNameAccess> xUICommandLabels;
194  if ((xNameAccess->getByName(rsModuleName) >>= xUICommandLabels) && xUICommandLabels->hasByName(rsCommandName))
195  xUICommandLabels->getByName(rsCommandName) >>= aProperties;
196  }
197  }
198  catch (Exception&)
199  {
200  }
201 
202  return aProperties;
203 }
204 
205 static OUString GetCommandProperty(const OUString& rsProperty, const OUString& rsCommandName, const OUString& rsModuleName)
206 {
207  const Sequence<beans::PropertyValue> aProperties (GetCommandProperties(rsCommandName, rsModuleName));
208  auto pProp = std::find_if(aProperties.begin(), aProperties.end(),
209  [&rsProperty](const beans::PropertyValue& rProp) { return rProp.Name == rsProperty; });
210  if (pProp != aProperties.end())
211  {
212  OUString sLabel;
213  pProp->Value >>= sLabel;
214  return sLabel;
215  }
216  return OUString();
217 }
218 
220  const OUString& rsCommandName,
221  const OUString& rsModuleName)
222 {
223  return GetCommandProperty("Name", rsCommandName, rsModuleName);
224 }
225 
227  const OUString& rsCommandName,
228  const OUString& rsModuleName)
229 {
230  // Here we want to use "Label", not "Name". "Name" is a stripped-down version of "Label" without accelerators
231  // and ellipsis. In the menu, we want to have those accelerators and ellipsis.
232  return GetCommandProperty("Label", rsCommandName, rsModuleName);
233 }
234 
236  const OUString& rsCommandName,
237  const OUString& rsModuleName)
238 {
239  OUString sPopupLabel(GetCommandProperty("PopupLabel", rsCommandName, rsModuleName));
240  if (!sPopupLabel.isEmpty())
241  return sPopupLabel;
242  return GetCommandProperty("Label", rsCommandName, rsModuleName);
243 }
244 
246  const OUString& rsCommandName,
247  const Reference<frame::XFrame>& rxFrame)
248 {
249  OUString sModuleName(GetModuleIdentifier(rxFrame));
250  OUString sLabel (GetCommandProperty("TooltipLabel", rsCommandName, sModuleName));
251  if (sLabel.isEmpty()) {
252  sLabel = GetPopupLabelForCommand(rsCommandName, sModuleName);
253  // Remove '...' at the end and mnemonics (we don't want those in tooltips)
254  sLabel = comphelper::string::stripEnd(sLabel, '.');
256  }
257 
258  // Command can be just an alias to another command,
259  // so need to get the shortcut of the "real" command.
260  const OUString sRealCommand(GetRealCommandForCommand(rsCommandName, sModuleName));
261  const OUString sShortCut(GetCommandShortcut(!sRealCommand.isEmpty() ? sRealCommand : rsCommandName, rxFrame));
262  if (!sShortCut.isEmpty())
263  return sLabel + " (" + sShortCut + ")";
264  return sLabel;
265 }
266 
267 OUString GetCommandShortcut (const OUString& rsCommandName,
268  const Reference<frame::XFrame>& rxFrame)
269 {
270 
271  OUString sShortcut;
272 
273  sShortcut = RetrieveShortcutsFromConfiguration(GetDocumentAcceleratorConfiguration(rxFrame), rsCommandName);
274  if (sShortcut.getLength() > 0)
275  return sShortcut;
276 
277  sShortcut = RetrieveShortcutsFromConfiguration(GetModuleAcceleratorConfiguration(rxFrame), rsCommandName);
278  if (sShortcut.getLength() > 0)
279  return sShortcut;
280 
282  if (sShortcut.getLength() > 0)
283  return sShortcut;
284 
285  return OUString();
286 }
287 
288 OUString GetRealCommandForCommand(const OUString& rCommandName,
289  const OUString& rsModuleName)
290 {
291  return GetCommandProperty("TargetURL", rCommandName, rsModuleName);
292 }
293 
294 Reference<graphic::XGraphic> GetXGraphicForCommand(const OUString& rsCommandName,
295  const Reference<frame::XFrame>& rxFrame,
296  vcl::ImageType eImageType)
297 {
298  if (rsCommandName.isEmpty())
299  return nullptr;
300 
301  sal_Int16 nImageType(ui::ImageType::COLOR_NORMAL | ui::ImageType::SIZE_DEFAULT);
302 
303  if (eImageType == vcl::ImageType::Size26)
304  nImageType |= ui::ImageType::SIZE_LARGE;
305  else if (eImageType == vcl::ImageType::Size32)
306  nImageType |= ui::ImageType::SIZE_32;
307 
308  try
309  {
310  Reference<frame::XController> xController(rxFrame->getController(), UNO_SET_THROW);
311  Reference<ui::XUIConfigurationManagerSupplier> xSupplier(xController->getModel(), UNO_QUERY);
312  if (xSupplier.is())
313  {
314  Reference<ui::XUIConfigurationManager> xDocUICfgMgr(xSupplier->getUIConfigurationManager());
315  Reference<ui::XImageManager> xDocImgMgr(xDocUICfgMgr->getImageManager(), UNO_QUERY);
316 
317  Sequence< Reference<graphic::XGraphic> > aGraphicSeq;
318  Sequence<OUString> aImageCmdSeq { rsCommandName };
319 
320  aGraphicSeq = xDocImgMgr->getImages( nImageType, aImageCmdSeq );
321  Reference<graphic::XGraphic> xGraphic = aGraphicSeq[0];
322  if (xGraphic.is())
323  return xGraphic;
324  }
325  }
326  catch (Exception&)
327  {
328  }
329 
330  try {
331  Reference<ui::XModuleUIConfigurationManagerSupplier> xModuleCfgMgrSupplier(GetModuleConfigurationSupplier());
332  Reference<ui::XUIConfigurationManager> xUICfgMgr(xModuleCfgMgrSupplier->getUIConfigurationManager(GetModuleIdentifier(rxFrame)));
333 
334  Sequence< Reference<graphic::XGraphic> > aGraphicSeq;
335  Reference<ui::XImageManager> xModuleImageManager(xUICfgMgr->getImageManager(), UNO_QUERY);
336 
337  Sequence<OUString> aImageCmdSeq { rsCommandName };
338 
339  aGraphicSeq = xModuleImageManager->getImages(nImageType, aImageCmdSeq);
340 
341  Reference<graphic::XGraphic> xGraphic(aGraphicSeq[0]);
342 
343  return xGraphic;
344  }
345  catch (Exception&)
346  {
347  }
348 
349  return nullptr;
350 }
351 
352 Image GetImageForCommand(const OUString& rsCommandName,
353  const Reference<frame::XFrame>& rxFrame,
354  vcl::ImageType eImageType)
355 {
356  return Image(GetXGraphicForCommand(rsCommandName, rxFrame, eImageType));
357 }
358 
360  const OUString& rsCommandName,
361  const OUString& rsModuleName)
362 {
363  sal_Int32 nValue = 0;
364  const Sequence<beans::PropertyValue> aProperties (GetCommandProperties(rsCommandName, rsModuleName));
365 
366  auto pProp = std::find_if(aProperties.begin(), aProperties.end(),
367  [](const beans::PropertyValue& rProp) { return rProp.Name == "Properties"; });
368  if (pProp != aProperties.end())
369  pProp->Value >>= nValue;
370 
371  return nValue;
372 }
373 
374 bool IsRotated(const OUString& rsCommandName, const OUString& rsModuleName)
375 {
376  return ResourceHasKey("private:resource/image/commandrotateimagelist", rsCommandName, rsModuleName);
377 }
378 
379 bool IsMirrored(const OUString& rsCommandName, const OUString& rsModuleName)
380 {
381  return ResourceHasKey("private:resource/image/commandmirrorimagelist", rsCommandName, rsModuleName);
382 }
383 
384 bool IsExperimental(const OUString& rsCommandName, const OUString& rModuleName)
385 {
386  Sequence<beans::PropertyValue> aProperties;
387  try
388  {
389  if( rModuleName.getLength() > 0)
390  {
392  Reference<container::XNameAccess> xUICommandLabels;
393  if (xNameAccess->getByName( rModuleName ) >>= xUICommandLabels )
394  xUICommandLabels->getByName(rsCommandName) >>= aProperties;
395 
396  auto pProp = std::find_if(aProperties.begin(), aProperties.end(),
397  [](const beans::PropertyValue& rProp) { return rProp.Name == "IsExperimental"; });
398  if (pProp != aProperties.end())
399  {
400  bool bValue;
401  return (pProp->Value >>= bValue) && bValue;
402  }
403  }
404  }
405  catch (Exception&)
406  {
407  }
408  return false;
409 }
410 
411 OUString GetModuleIdentifier(const Reference<frame::XFrame>& rxFrame)
412 {
413  static WeakReference<frame::XModuleManager2> xWeakRef;
414  css::uno::Reference<frame::XModuleManager2> xRef(xWeakRef);
415 
416  if (!xRef.is())
417  {
418  xRef = frame::ModuleManager::create(comphelper::getProcessComponentContext());
419  xWeakRef = xRef;
420  }
421 
422  try
423  {
424  return xRef->identify(rxFrame);
425  }
426  catch (const Exception&)
427  {}
428 
429  return OUString();
430 }
431 
432 } }
433 
434 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static Reference< ui::XModuleUIConfigurationManagerSupplier > GetModuleConfigurationSupplier()
OString stripEnd(const OString &rIn, sal_Char c)
static Reference< ui::XAcceleratorConfiguration > GetGlobalAcceleratorConfiguration()
OUString GetPopupLabelForCommand(const OUString &rsCommandName, const OUString &rsModuleName)
sal_Int32 findValue(const css::uno::Sequence< T1 > &_rList, const T2 &_rValue)
static vcl::KeyCode AWTKey2VCLKey(const awt::KeyEvent &aAWTKey)
static Reference< container::XNameAccess > GetCommandDescription()
bool IsMirrored(const long nPageLeftMargin, const long nPageRightMargin, const long nPageTopMargin, const long nPageBottomMargin, bool bMirrored)
Reference< XController > xController
bool IsExperimental(const OUString &rsCommandName, const OUString &rModuleName)
Returns whether the command is experimental.
static bool ResourceHasKey(const OUString &rsResourceName, const OUString &rsCommandName, const OUString &rsModuleName)
static OUString RetrieveShortcutsFromConfiguration(const Reference< ui::XAcceleratorConfiguration > &rxConfiguration, const OUString &rsCommandName)
static OUString GetCommandProperty(const OUString &rsProperty, const OUString &rsCommandName, const OUString &rsModuleName)
Image GetImageForCommand(const OUString &rsCommandName, const Reference< frame::XFrame > &rxFrame, vcl::ImageType eImageType)
OUString GetMenuLabelForCommand(const OUString &rsCommandName, const OUString &rsModuleName)
OUString GetModuleIdentifier(const Reference< frame::XFrame > &rxFrame)
ImageType
Definition: vclenum.hxx:319
Reference< graphic::XGraphic > GetXGraphicForCommand(const OUString &rsCommandName, const Reference< frame::XFrame > &rxFrame, vcl::ImageType eImageType)
static Reference< ui::XAcceleratorConfiguration > GetModuleAcceleratorConfiguration(const Reference< frame::XFrame > &rxFrame)
OUString GetName(vcl::Window *pWindow=nullptr) const
Definition: keycod.cxx:78
sal_Int32 GetPropertiesForCommand(const OUString &rsCommandName, const OUString &rsModuleName)
Definition: image.hxx:40
Reference< XComponentContext > getProcessComponentContext()
OUString GetTooltipForCommand(const OUString &rsCommandName, const Reference< frame::XFrame > &rxFrame)
OUString GetLabelForCommand(const OUString &rsCommandName, const OUString &rsModuleName)
Return a label for the given command.
OUString GetRealCommandForCommand(const OUString &rCommandName, const OUString &rsModuleName)
OUString GetCommandShortcut(const OUString &rsCommandName, const Reference< frame::XFrame > &rxFrame)
static OUString EraseAllMnemonicChars(const OUString &rStr)
Definition: mnemonic.cxx:307
bool IsRotated(const OUString &rsCommandName, const OUString &rsModuleName)
static Sequence< beans::PropertyValue > GetCommandProperties(const OUString &rsCommandName, const OUString &rsModuleName)
static Reference< ui::XAcceleratorConfiguration > GetDocumentAcceleratorConfiguration(const Reference< frame::XFrame > &rxFrame)