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>
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
38using namespace css;
39using namespace css::uno;
40
42
43static Reference<container::XNameAccess> GetCommandDescription()
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
57static 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
71static 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
85static 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
104static 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
123static 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
162 const Reference<ui::XAcceleratorConfiguration>& rxConfiguration,
163 const OUString& rsCommandName)
164{
165 if (rxConfiguration.is())
166 {
167 try
168 {
169 Sequence<OUString> aCommands { rsCommandName };
170
171 Sequence<Any> aKeyCodes (rxConfiguration->getPreferredKeyEventsForCommandList(aCommands));
172 if (aCommands.getLength() == 1)
173 {
174 awt::KeyEvent aKeyEvent;
175 if (aKeyCodes[0] >>= aKeyEvent)
176 {
177 return AWTKey2VCLKey(aKeyEvent);
178 }
179 }
180 }
181 catch (css::lang::IllegalArgumentException&)
182 {
183 }
184 }
185 return vcl::KeyCode();
186}
187
188static bool ResourceHasKey(const OUString& rsResourceName, const OUString& rsCommandName, const OUString& rsModuleName)
189{
190 Sequence< OUString > aSequence;
191 try
192 {
193 if (!rsModuleName.isEmpty())
194 {
195 Reference<container::XNameAccess> xNameAccess(GetCommandDescription());
196 Reference<container::XNameAccess> xUICommandLabels;
197 if (xNameAccess->getByName(rsModuleName) >>= xUICommandLabels)
198 {
199 xUICommandLabels->getByName(rsResourceName) >>= aSequence;
200 if (comphelper::findValue(aSequence, rsCommandName) != -1)
201 return true;
202 }
203 }
204 }
205 catch (Exception&)
206 {
207 }
208 return false;
209}
210
211Sequence<beans::PropertyValue> GetCommandProperties(const OUString& rsCommandName, const OUString& rsModuleName)
212{
213 Sequence<beans::PropertyValue> aProperties;
214
215 try
216 {
217 if (!rsModuleName.isEmpty())
218 {
219 Reference<container::XNameAccess> xNameAccess(GetCommandDescription());
220 Reference<container::XNameAccess> xUICommandLabels;
221 if ((xNameAccess->getByName(rsModuleName) >>= xUICommandLabels) && xUICommandLabels->hasByName(rsCommandName))
222 xUICommandLabels->getByName(rsCommandName) >>= aProperties;
223 }
224 }
225 catch (Exception&)
226 {
227 }
228
229 return aProperties;
230}
231
232static OUString GetCommandProperty(const OUString& rsProperty, const Sequence<beans::PropertyValue> &rProperties)
233{
234 auto pProp = std::find_if(rProperties.begin(), rProperties.end(),
235 [&rsProperty](const beans::PropertyValue& rProp) { return rProp.Name == rsProperty; });
236 if (pProp != rProperties.end())
237 {
238 OUString sLabel;
239 pProp->Value >>= sLabel;
240 return sLabel;
241 }
242 return OUString();
243}
244
245OUString GetLabelForCommand(const css::uno::Sequence<css::beans::PropertyValue>& rProperties)
246{
247 return GetCommandProperty("Name", rProperties);
248}
249
250OUString GetMenuLabelForCommand(const css::uno::Sequence<css::beans::PropertyValue>& rProperties)
251{
252 // Here we want to use "Label", not "Name". "Name" is a stripped-down version of "Label" without accelerators
253 // and ellipsis. In the menu, we want to have those accelerators and ellipsis.
254 return GetCommandProperty("Label", rProperties);
255}
256
257OUString GetPopupLabelForCommand(const css::uno::Sequence<css::beans::PropertyValue>& rProperties)
258{
259 OUString sPopupLabel(GetCommandProperty("PopupLabel", rProperties));
260 if (!sPopupLabel.isEmpty())
261 return sPopupLabel;
262 return GetCommandProperty("Label", rProperties);
263}
264
265OUString GetTooltipLabelForCommand(const css::uno::Sequence<css::beans::PropertyValue>& rProperties)
266{
267 OUString sLabel(GetCommandProperty("TooltipLabel", rProperties));
268 if (!sLabel.isEmpty())
269 return sLabel;
270 return GetCommandProperty("Label", rProperties);
271}
272
274 const OUString& rsCommandName,
275 const css::uno::Sequence<css::beans::PropertyValue>& rProperties,
276 const Reference<frame::XFrame>& rxFrame)
277{
278 OUString sLabel(GetCommandProperty("TooltipLabel", rProperties));
279 if (sLabel.isEmpty()) {
280 sLabel = GetPopupLabelForCommand(rProperties);
281 // Remove '...' at the end and mnemonics (we don't want those in tooltips)
282 sLabel = comphelper::string::stripEnd(sLabel, '.');
284 }
285
286 // Command can be just an alias to another command,
287 // so need to get the shortcut of the "real" command.
288 const OUString sRealCommand(GetRealCommandForCommand(rProperties));
289 const OUString sShortCut(GetCommandShortcut(!sRealCommand.isEmpty() ? sRealCommand : rsCommandName, rxFrame));
290 if (!sShortCut.isEmpty())
291 return sLabel + " (" + sShortCut + ")";
292 return sLabel;
293}
294
295OUString GetCommandShortcut (const OUString& rsCommandName,
296 const Reference<frame::XFrame>& rxFrame)
297{
298
299 OUString sShortcut;
300
302 if (sShortcut.getLength() > 0)
303 return sShortcut;
304
306 if (sShortcut.getLength() > 0)
307 return sShortcut;
308
310 if (sShortcut.getLength() > 0)
311 return sShortcut;
312
313 return OUString();
314}
315
316vcl::KeyCode GetCommandKeyCodeShortcut (const OUString& rsCommandName, const Reference<frame::XFrame>& rxFrame)
317{
318 vcl::KeyCode aKeyCodeShortcut;
319
320 aKeyCodeShortcut = RetrieveKeyCodeShortcutsFromConfiguration(GetDocumentAcceleratorConfiguration(rxFrame), rsCommandName);
321 if (aKeyCodeShortcut.GetCode())
322 return aKeyCodeShortcut;
323
324 aKeyCodeShortcut = RetrieveKeyCodeShortcutsFromConfiguration(GetModuleAcceleratorConfiguration(rxFrame), rsCommandName);
325 if (aKeyCodeShortcut.GetCode())
326 return aKeyCodeShortcut;
327
329 if (aKeyCodeShortcut.GetCode())
330 return aKeyCodeShortcut;
331
332 return vcl::KeyCode();
333}
334
335OUString GetRealCommandForCommand(const css::uno::Sequence<css::beans::PropertyValue>& rProperties)
336{
337 return GetCommandProperty("TargetURL", rProperties);
338}
339
340Reference<graphic::XGraphic> GetXGraphicForCommand(const OUString& rsCommandName,
341 const Reference<frame::XFrame>& rxFrame,
342 vcl::ImageType eImageType)
343{
344 if (rsCommandName.isEmpty())
345 return nullptr;
346
347 sal_Int16 nImageType(ui::ImageType::COLOR_NORMAL | ui::ImageType::SIZE_DEFAULT);
348
349 if (eImageType == vcl::ImageType::Size26)
350 nImageType |= ui::ImageType::SIZE_LARGE;
351 else if (eImageType == vcl::ImageType::Size32)
352 nImageType |= ui::ImageType::SIZE_32;
353
354 try
355 {
356 Reference<frame::XController> xController(rxFrame->getController(), UNO_SET_THROW);
357 Reference<ui::XUIConfigurationManagerSupplier> xSupplier(xController->getModel(), UNO_QUERY);
358 if (xSupplier.is())
359 {
360 Reference<ui::XUIConfigurationManager> xDocUICfgMgr(xSupplier->getUIConfigurationManager());
361 Reference<ui::XImageManager> xDocImgMgr(xDocUICfgMgr->getImageManager(), UNO_QUERY);
362
363 Sequence<OUString> aImageCmdSeq { rsCommandName };
364
365 Sequence<Reference<graphic::XGraphic>> aGraphicSeq = xDocImgMgr->getImages(nImageType, aImageCmdSeq);
366 Reference<graphic::XGraphic> xGraphic = aGraphicSeq[0];
367 if (xGraphic.is())
368 return xGraphic;
369 }
370 }
371 catch (Exception&)
372 {
373 }
374
375 try
376 {
377 Reference<ui::XModuleUIConfigurationManagerSupplier> xModuleCfgMgrSupplier(GetModuleConfigurationSupplier());
378 Reference<ui::XUIConfigurationManager> xUICfgMgr(xModuleCfgMgrSupplier->getUIConfigurationManager(GetModuleIdentifier(rxFrame)));
379 Reference<ui::XImageManager> xModuleImageManager(xUICfgMgr->getImageManager(), UNO_QUERY);
380
381 Sequence<OUString> aImageCmdSeq { rsCommandName };
382
383 Sequence<Reference<graphic::XGraphic>> aGraphicSeq = xModuleImageManager->getImages(nImageType, aImageCmdSeq);
384 Reference<graphic::XGraphic> xGraphic(aGraphicSeq[0]);
385
386 return xGraphic;
387 }
388 catch (Exception&)
389 {
390 }
391
392 return nullptr;
393}
394
395Image GetImageForCommand(const OUString& rsCommandName,
396 const Reference<frame::XFrame>& rxFrame,
397 vcl::ImageType eImageType)
398{
399 return Image(GetXGraphicForCommand(rsCommandName, rxFrame, eImageType));
400}
401
403 const OUString& rsCommandName,
404 const OUString& rsModuleName)
405{
406 sal_Int32 nValue = 0;
407 const Sequence<beans::PropertyValue> aProperties (GetCommandProperties(rsCommandName, rsModuleName));
408
409 auto pProp = std::find_if(aProperties.begin(), aProperties.end(),
410 [](const beans::PropertyValue& rProp) { return rProp.Name == "Properties"; });
411 if (pProp != aProperties.end())
412 pProp->Value >>= nValue;
413
414 return nValue;
415}
416
417bool IsRotated(const OUString& rsCommandName, const OUString& rsModuleName)
418{
419 return ResourceHasKey("private:resource/image/commandrotateimagelist", rsCommandName, rsModuleName);
420}
421
422bool IsMirrored(const OUString& rsCommandName, const OUString& rsModuleName)
423{
424 return ResourceHasKey("private:resource/image/commandmirrorimagelist", rsCommandName, rsModuleName);
425}
426
427bool IsExperimental(const OUString& rsCommandName, const OUString& rModuleName)
428{
429 Sequence<beans::PropertyValue> aProperties;
430 try
431 {
432 if( rModuleName.getLength() > 0)
433 {
434 Reference<container::XNameAccess> xNameAccess(GetCommandDescription());
435 Reference<container::XNameAccess> xUICommandLabels;
436 if (xNameAccess->getByName( rModuleName ) >>= xUICommandLabels )
437 xUICommandLabels->getByName(rsCommandName) >>= aProperties;
438
439 auto pProp = std::find_if(std::cbegin(aProperties), std::cend(aProperties),
440 [](const beans::PropertyValue& rProp) { return rProp.Name == "IsExperimental"; });
441 if (pProp != std::cend(aProperties))
442 {
443 bool bValue;
444 return (pProp->Value >>= bValue) && bValue;
445 }
446 }
447 }
448 catch (Exception&)
449 {
450 }
451 return false;
452}
453
454OUString GetModuleIdentifier(const Reference<frame::XFrame>& rxFrame)
455{
456 static WeakReference<frame::XModuleManager2> xWeakRef;
457 css::uno::Reference<frame::XModuleManager2> xRef(xWeakRef);
458
459 if (!xRef.is())
460 {
461 xRef = frame::ModuleManager::create(comphelper::getProcessComponentContext());
462 xWeakRef = xRef;
463 }
464
465 try
466 {
467 return xRef->identify(rxFrame);
468 }
469 catch (const Exception&)
470 {}
471
472 return OUString();
473}
474
475}
476
477/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
PropertiesInfo aProperties
Definition: image.hxx:40
static OUString EraseAllMnemonicChars(const OUString &rStr)
OUString GetName() const
Definition: keycod.cxx:66
sal_uInt16 GetCode() const
Definition: keycod.hxx:49
sal_Int16 nValue
@ Exception
OString stripEnd(const OString &rIn, char c)
sal_Int32 findValue(const css::uno::Sequence< T1 > &_rList, const T2 &_rValue)
Reference< XComponentContext > getProcessComponentContext()
Sequence< beans::PropertyValue > GetCommandProperties(const OUString &rsCommandName, const OUString &rsModuleName)
Return a label for the given command.
static bool ResourceHasKey(const OUString &rsResourceName, const OUString &rsCommandName, const OUString &rsModuleName)
bool IsRotated(const OUString &rsCommandName, const OUString &rsModuleName)
OUString GetTooltipForCommand(const OUString &rsCommandName, const css::uno::Sequence< css::beans::PropertyValue > &rProperties, const Reference< frame::XFrame > &rxFrame)
OUString GetRealCommandForCommand(const css::uno::Sequence< css::beans::PropertyValue > &rProperties)
Reference< graphic::XGraphic > GetXGraphicForCommand(const OUString &rsCommandName, const Reference< frame::XFrame > &rxFrame, vcl::ImageType eImageType)
OUString GetCommandShortcut(const OUString &rsCommandName, const Reference< frame::XFrame > &rxFrame)
static Reference< ui::XAcceleratorConfiguration > GetGlobalAcceleratorConfiguration()
static vcl::KeyCode AWTKey2VCLKey(const awt::KeyEvent &aAWTKey)
static OUString RetrieveShortcutsFromConfiguration(const Reference< ui::XAcceleratorConfiguration > &rxConfiguration, const OUString &rsCommandName)
sal_Int32 GetPropertiesForCommand(const OUString &rsCommandName, const OUString &rsModuleName)
OUString GetModuleIdentifier(const Reference< frame::XFrame > &rxFrame)
OUString GetPopupLabelForCommand(const css::uno::Sequence< css::beans::PropertyValue > &rProperties)
static OUString GetCommandProperty(const OUString &rsProperty, const Sequence< beans::PropertyValue > &rProperties)
Image GetImageForCommand(const OUString &rsCommandName, const Reference< frame::XFrame > &rxFrame, vcl::ImageType eImageType)
OUString GetLabelForCommand(const css::uno::Sequence< css::beans::PropertyValue > &rProperties)
Return a label for the given command.
static Reference< container::XNameAccess > GetCommandDescription()
bool IsMirrored(const OUString &rsCommandName, const OUString &rsModuleName)
bool IsExperimental(const OUString &rsCommandName, const OUString &rModuleName)
Returns whether the command is experimental.
static Reference< ui::XAcceleratorConfiguration > GetModuleAcceleratorConfiguration(const Reference< frame::XFrame > &rxFrame)
vcl::KeyCode GetCommandKeyCodeShortcut(const OUString &rsCommandName, const Reference< frame::XFrame > &rxFrame)
static vcl::KeyCode RetrieveKeyCodeShortcutsFromConfiguration(const Reference< ui::XAcceleratorConfiguration > &rxConfiguration, const OUString &rsCommandName)
OUString GetTooltipLabelForCommand(const css::uno::Sequence< css::beans::PropertyValue > &rProperties)
static Reference< ui::XAcceleratorConfiguration > GetDocumentAcceleratorConfiguration(const Reference< frame::XFrame > &rxFrame)
static Reference< ui::XModuleUIConfigurationManagerSupplier > GetModuleConfigurationSupplier()
OUString GetMenuLabelForCommand(const css::uno::Sequence< css::beans::PropertyValue > &rProperties)
ImageType
Definition: vclenum.hxx:280
Reference< XController > xController