odk: don't run compiler -dumpversion for eaach include of settings.mk
[LibreOffice.git] / vcl / source / helper / commandinfoprovider.cxx
blob86ea1f0397cb07bcb226f39c2cf8784046b47f78
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <vcl/commandinfoprovider.hxx>
21 #include <vcl/keycod.hxx>
22 #include <vcl/mnemonic.hxx>
23 #include <comphelper/string.hxx>
24 #include <comphelper/sequence.hxx>
25 #include <comphelper/processfactory.hxx>
26 #include <cppuhelper/weakref.hxx>
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>
38 using namespace css;
39 using namespace css::uno;
41 namespace vcl::CommandInfoProvider {
43 static Reference<container::XNameAccess> GetCommandDescription()
45 static WeakReference<container::XNameAccess> xWeakRef;
46 css::uno::Reference<container::XNameAccess> xRef(xWeakRef);
48 if (!xRef.is())
50 xRef = frame::theUICommandDescription::get(comphelper::getProcessComponentContext());
51 xWeakRef = xRef;
54 return xRef;
57 static Reference<ui::XModuleUIConfigurationManagerSupplier> GetModuleConfigurationSupplier()
59 static WeakReference<ui::XModuleUIConfigurationManagerSupplier> xWeakRef;
60 css::uno::Reference<ui::XModuleUIConfigurationManagerSupplier> xRef(xWeakRef);
62 if (!xRef.is())
64 xRef = ui::theModuleUIConfigurationManagerSupplier::get(comphelper::getProcessComponentContext());
65 xWeakRef = xRef;
68 return xRef;
71 static Reference<ui::XAcceleratorConfiguration> GetGlobalAcceleratorConfiguration()
73 static WeakReference<ui::XAcceleratorConfiguration> xWeakRef;
74 css::uno::Reference<ui::XAcceleratorConfiguration> xRef(xWeakRef);
76 if (!xRef.is())
78 xRef = ui::GlobalAcceleratorConfiguration::create(comphelper::getProcessComponentContext());
79 xWeakRef = xRef;
82 return xRef;
85 static Reference<ui::XAcceleratorConfiguration> GetDocumentAcceleratorConfiguration(const Reference<frame::XFrame>& rxFrame)
87 Reference<frame::XController> xController = rxFrame->getController();
88 if (xController.is())
90 Reference<ui::XUIConfigurationManagerSupplier> xSupplier(xController->getModel(), UNO_QUERY);
91 if (xSupplier.is())
93 Reference<ui::XUIConfigurationManager> xConfigurationManager(
94 xSupplier->getUIConfigurationManager());
95 if (xConfigurationManager.is())
97 return xConfigurationManager->getShortCutManager();
101 return nullptr;
104 static Reference<ui::XAcceleratorConfiguration> GetModuleAcceleratorConfiguration(const Reference<frame::XFrame>& rxFrame)
106 css::uno::Reference<css::ui::XAcceleratorConfiguration> curModuleAcceleratorConfiguration;
109 Reference<ui::XModuleUIConfigurationManagerSupplier> xSupplier(GetModuleConfigurationSupplier());
110 Reference<ui::XUIConfigurationManager> xManager (
111 xSupplier->getUIConfigurationManager(GetModuleIdentifier(rxFrame)));
112 if (xManager.is())
114 curModuleAcceleratorConfiguration = xManager->getShortCutManager();
117 catch (Exception&)
120 return curModuleAcceleratorConfiguration;
123 static vcl::KeyCode AWTKey2VCLKey(const awt::KeyEvent& aAWTKey)
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);
131 return vcl::KeyCode(nKey, bShift, bMod1, bMod2, bMod3);
134 static OUString RetrieveShortcutsFromConfiguration(
135 const Reference<ui::XAcceleratorConfiguration>& rxConfiguration,
136 const OUString& rsCommandName)
138 if (rxConfiguration.is())
142 Sequence<OUString> aCommands { rsCommandName };
144 Sequence<Any> aKeyCodes (rxConfiguration->getPreferredKeyEventsForCommandList(aCommands));
145 if (aCommands.getLength() == 1)
147 awt::KeyEvent aKeyEvent;
148 if (aKeyCodes[0] >>= aKeyEvent)
150 return AWTKey2VCLKey(aKeyEvent).GetName();
154 catch (css::lang::IllegalArgumentException&)
158 return OUString();
161 static vcl::KeyCode RetrieveKeyCodeShortcutsFromConfiguration(
162 const Reference<ui::XAcceleratorConfiguration>& rxConfiguration,
163 const OUString& rsCommandName)
165 if (rxConfiguration.is())
169 Sequence<OUString> aCommands { rsCommandName };
171 Sequence<Any> aKeyCodes (rxConfiguration->getPreferredKeyEventsForCommandList(aCommands));
172 if (aCommands.getLength() == 1)
174 awt::KeyEvent aKeyEvent;
175 if (aKeyCodes[0] >>= aKeyEvent)
177 return AWTKey2VCLKey(aKeyEvent);
181 catch (css::lang::IllegalArgumentException&)
185 return vcl::KeyCode();
188 static bool ResourceHasKey(const OUString& rsResourceName, const OUString& rsCommandName, const OUString& rsModuleName)
190 Sequence< OUString > aSequence;
193 if (!rsModuleName.isEmpty())
195 Reference<container::XNameAccess> xNameAccess(GetCommandDescription());
196 Reference<container::XNameAccess> xUICommandLabels;
197 if (xNameAccess->getByName(rsModuleName) >>= xUICommandLabels)
199 xUICommandLabels->getByName(rsResourceName) >>= aSequence;
200 if (comphelper::findValue(aSequence, rsCommandName) != -1)
201 return true;
205 catch (Exception&)
208 return false;
211 Sequence<beans::PropertyValue> GetCommandProperties(const OUString& rsCommandName, const OUString& rsModuleName)
213 Sequence<beans::PropertyValue> aProperties;
217 if (!rsModuleName.isEmpty())
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;
225 catch (Exception&)
229 return aProperties;
232 static OUString GetCommandProperty(const OUString& rsProperty, const Sequence<beans::PropertyValue> &rProperties)
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())
238 OUString sLabel;
239 pProp->Value >>= sLabel;
240 return sLabel;
242 return OUString();
245 OUString GetLabelForCommand(const css::uno::Sequence<css::beans::PropertyValue>& rProperties)
247 return GetCommandProperty(u"Name"_ustr, rProperties);
250 OUString GetMenuLabelForCommand(const css::uno::Sequence<css::beans::PropertyValue>& rProperties)
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(u"Label"_ustr, rProperties);
257 OUString GetPopupLabelForCommand(const css::uno::Sequence<css::beans::PropertyValue>& rProperties)
259 OUString sPopupLabel(GetCommandProperty(u"PopupLabel"_ustr, rProperties));
260 if (!sPopupLabel.isEmpty())
261 return sPopupLabel;
262 return GetCommandProperty(u"Label"_ustr, rProperties);
265 OUString GetTooltipLabelForCommand(const css::uno::Sequence<css::beans::PropertyValue>& rProperties)
267 OUString sLabel(GetCommandProperty(u"TooltipLabel"_ustr, rProperties));
268 if (!sLabel.isEmpty())
269 return sLabel;
270 return GetCommandProperty(u"Label"_ustr, rProperties);
273 OUString GetTooltipForCommand(
274 const OUString& rsCommandName,
275 const css::uno::Sequence<css::beans::PropertyValue>& rProperties,
276 const Reference<frame::XFrame>& rxFrame)
278 OUString sLabel(GetCommandProperty(u"TooltipLabel"_ustr, 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, '.');
283 sLabel = MnemonicGenerator::EraseAllMnemonicChars(sLabel);
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;
295 OUString GetCommandShortcut (const OUString& rsCommandName,
296 const Reference<frame::XFrame>& rxFrame)
299 OUString sShortcut;
301 sShortcut = RetrieveShortcutsFromConfiguration(GetDocumentAcceleratorConfiguration(rxFrame), rsCommandName);
302 if (sShortcut.getLength() > 0)
303 return sShortcut;
305 sShortcut = RetrieveShortcutsFromConfiguration(GetModuleAcceleratorConfiguration(rxFrame), rsCommandName);
306 if (sShortcut.getLength() > 0)
307 return sShortcut;
309 sShortcut = RetrieveShortcutsFromConfiguration(GetGlobalAcceleratorConfiguration(), rsCommandName);
310 if (sShortcut.getLength() > 0)
311 return sShortcut;
313 return OUString();
316 vcl::KeyCode GetCommandKeyCodeShortcut (const OUString& rsCommandName, const Reference<frame::XFrame>& rxFrame)
318 vcl::KeyCode aKeyCodeShortcut;
320 aKeyCodeShortcut = RetrieveKeyCodeShortcutsFromConfiguration(GetDocumentAcceleratorConfiguration(rxFrame), rsCommandName);
321 if (aKeyCodeShortcut.GetCode())
322 return aKeyCodeShortcut;
324 aKeyCodeShortcut = RetrieveKeyCodeShortcutsFromConfiguration(GetModuleAcceleratorConfiguration(rxFrame), rsCommandName);
325 if (aKeyCodeShortcut.GetCode())
326 return aKeyCodeShortcut;
328 aKeyCodeShortcut = RetrieveKeyCodeShortcutsFromConfiguration(GetGlobalAcceleratorConfiguration(), rsCommandName);
329 if (aKeyCodeShortcut.GetCode())
330 return aKeyCodeShortcut;
332 return vcl::KeyCode();
335 OUString GetRealCommandForCommand(const css::uno::Sequence<css::beans::PropertyValue>& rProperties)
337 return GetCommandProperty(u"TargetURL"_ustr, rProperties);
340 Reference<graphic::XGraphic> GetXGraphicForCommand(const OUString& rsCommandName,
341 const Reference<frame::XFrame>& rxFrame,
342 vcl::ImageType eImageType)
344 if (rsCommandName.isEmpty())
345 return nullptr;
347 sal_Int16 nImageType(ui::ImageType::COLOR_NORMAL | ui::ImageType::SIZE_DEFAULT);
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;
356 Reference<frame::XController> xController(rxFrame->getController(), UNO_SET_THROW);
357 Reference<ui::XUIConfigurationManagerSupplier> xSupplier(xController->getModel(), UNO_QUERY);
358 if (xSupplier.is())
360 Reference<ui::XUIConfigurationManager> xDocUICfgMgr(xSupplier->getUIConfigurationManager());
361 Reference<ui::XImageManager> xDocImgMgr(xDocUICfgMgr->getImageManager(), UNO_QUERY);
363 Sequence<OUString> aImageCmdSeq { rsCommandName };
365 Sequence<Reference<graphic::XGraphic>> aGraphicSeq = xDocImgMgr->getImages(nImageType, aImageCmdSeq);
366 Reference<graphic::XGraphic> xGraphic = aGraphicSeq[0];
367 if (xGraphic.is())
368 return xGraphic;
371 catch (Exception&)
377 Reference<ui::XModuleUIConfigurationManagerSupplier> xModuleCfgMgrSupplier(GetModuleConfigurationSupplier());
378 Reference<ui::XUIConfigurationManager> xUICfgMgr(xModuleCfgMgrSupplier->getUIConfigurationManager(GetModuleIdentifier(rxFrame)));
379 Reference<ui::XImageManager> xModuleImageManager(xUICfgMgr->getImageManager(), UNO_QUERY);
381 Sequence<OUString> aImageCmdSeq { rsCommandName };
383 Sequence<Reference<graphic::XGraphic>> aGraphicSeq = xModuleImageManager->getImages(nImageType, aImageCmdSeq);
384 Reference<graphic::XGraphic> xGraphic(aGraphicSeq[0]);
386 return xGraphic;
388 catch (Exception&)
392 return nullptr;
395 Image GetImageForCommand(const OUString& rsCommandName,
396 const Reference<frame::XFrame>& rxFrame,
397 vcl::ImageType eImageType)
399 return Image(GetXGraphicForCommand(rsCommandName, rxFrame, eImageType));
402 sal_Int32 GetPropertiesForCommand (
403 const OUString& rsCommandName,
404 const OUString& rsModuleName)
406 sal_Int32 nValue = 0;
407 const Sequence<beans::PropertyValue> aProperties (GetCommandProperties(rsCommandName, rsModuleName));
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;
414 return nValue;
417 bool IsRotated(const OUString& rsCommandName, const OUString& rsModuleName)
419 return ResourceHasKey(u"private:resource/image/commandrotateimagelist"_ustr, rsCommandName, rsModuleName);
422 bool IsMirrored(const OUString& rsCommandName, const OUString& rsModuleName)
424 return ResourceHasKey(u"private:resource/image/commandmirrorimagelist"_ustr, rsCommandName, rsModuleName);
427 bool IsExperimental(const OUString& rsCommandName, const OUString& rModuleName)
429 Sequence<beans::PropertyValue> aProperties;
432 if( rModuleName.getLength() > 0)
434 Reference<container::XNameAccess> xNameAccess(GetCommandDescription());
435 Reference<container::XNameAccess> xUICommandLabels;
436 if (xNameAccess->getByName( rModuleName ) >>= xUICommandLabels )
437 xUICommandLabels->getByName(rsCommandName) >>= aProperties;
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))
443 bool bValue;
444 return (pProp->Value >>= bValue) && bValue;
448 catch (Exception&)
451 return false;
454 OUString GetModuleIdentifier(const Reference<frame::XFrame>& rxFrame)
456 static WeakReference<frame::XModuleManager2> xWeakRef;
457 css::uno::Reference<frame::XModuleManager2> xRef(xWeakRef);
459 if (!xRef.is())
461 xRef = frame::ModuleManager::create(comphelper::getProcessComponentContext());
462 xWeakRef = xRef;
467 return xRef->identify(rxFrame);
469 catch (const Exception&)
472 return OUString();
477 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */