From 940b4d1848e8c70ab7642901a68594e8016caffc Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 27 Apr 2024 18:51:28 +0200 Subject: Adding upstream version 1:7.0.4. Signed-off-by: Daniel Baumann --- vcl/source/helper/commandinfoprovider.cxx | 480 ++++++++++++++++++++++++++++++ 1 file changed, 480 insertions(+) create mode 100644 vcl/source/helper/commandinfoprovider.cxx (limited to 'vcl/source/helper/commandinfoprovider.cxx') diff --git a/vcl/source/helper/commandinfoprovider.cxx b/vcl/source/helper/commandinfoprovider.cxx new file mode 100644 index 000000000..805aa7ad6 --- /dev/null +++ b/vcl/source/helper/commandinfoprovider.cxx @@ -0,0 +1,480 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace css; +using namespace css::uno; + +namespace vcl::CommandInfoProvider { + +static Reference GetCommandDescription() +{ + static WeakReference xWeakRef; + css::uno::Reference xRef(xWeakRef); + + if (!xRef.is()) + { + xRef = frame::theUICommandDescription::get(comphelper::getProcessComponentContext()); + xWeakRef = xRef; + } + + return xRef; +} + +static Reference GetModuleConfigurationSupplier() +{ + static WeakReference xWeakRef; + css::uno::Reference xRef(xWeakRef); + + if (!xRef.is()) + { + xRef = ui::theModuleUIConfigurationManagerSupplier::get(comphelper::getProcessComponentContext()); + xWeakRef = xRef; + } + + return xRef; +} + +static Reference GetGlobalAcceleratorConfiguration() +{ + static WeakReference xWeakRef; + css::uno::Reference xRef(xWeakRef); + + if (!xRef.is()) + { + xRef = ui::GlobalAcceleratorConfiguration::create(comphelper::getProcessComponentContext()); + xWeakRef = xRef; + } + + return xRef; +} + +static Reference GetDocumentAcceleratorConfiguration(const Reference& rxFrame) +{ + Reference xController = rxFrame->getController(); + if (xController.is()) + { + Reference xSupplier(xController->getModel(), UNO_QUERY); + if (xSupplier.is()) + { + Reference xConfigurationManager( + xSupplier->getUIConfigurationManager()); + if (xConfigurationManager.is()) + { + return xConfigurationManager->getShortCutManager(); + } + } + } + return nullptr; +} + +static Reference GetModuleAcceleratorConfiguration(const Reference& rxFrame) +{ + css::uno::Reference curModuleAcceleratorConfiguration; + try + { + Reference xSupplier(GetModuleConfigurationSupplier()); + Reference xManager ( + xSupplier->getUIConfigurationManager(GetModuleIdentifier(rxFrame))); + if (xManager.is()) + { + curModuleAcceleratorConfiguration = xManager->getShortCutManager(); + } + } + catch (Exception&) + { + } + return curModuleAcceleratorConfiguration; +} + +static vcl::KeyCode AWTKey2VCLKey(const awt::KeyEvent& aAWTKey) +{ + bool bShift = ((aAWTKey.Modifiers & awt::KeyModifier::SHIFT) == awt::KeyModifier::SHIFT ); + bool bMod1 = ((aAWTKey.Modifiers & awt::KeyModifier::MOD1 ) == awt::KeyModifier::MOD1 ); + bool bMod2 = ((aAWTKey.Modifiers & awt::KeyModifier::MOD2 ) == awt::KeyModifier::MOD2 ); + bool bMod3 = ((aAWTKey.Modifiers & awt::KeyModifier::MOD3 ) == awt::KeyModifier::MOD3 ); + sal_uInt16 nKey = static_cast(aAWTKey.KeyCode); + + return vcl::KeyCode(nKey, bShift, bMod1, bMod2, bMod3); +} + +static OUString RetrieveShortcutsFromConfiguration( + const Reference& rxConfiguration, + const OUString& rsCommandName) +{ + if (rxConfiguration.is()) + { + try + { + Sequence aCommands { rsCommandName }; + + Sequence aKeyCodes (rxConfiguration->getPreferredKeyEventsForCommandList(aCommands)); + if (aCommands.getLength() == 1) + { + awt::KeyEvent aKeyEvent; + if (aKeyCodes[0] >>= aKeyEvent) + { + return AWTKey2VCLKey(aKeyEvent).GetName(); + } + } + } + catch (css::lang::IllegalArgumentException&) + { + } + } + return OUString(); +} + +static vcl::KeyCode RetrieveKeyCodeShortcutsFromConfiguration( + const Reference& rxConfiguration, + const OUString& rsCommandName) +{ + if (rxConfiguration.is()) + { + try + { + Sequence aCommands { rsCommandName }; + + Sequence aKeyCodes (rxConfiguration->getPreferredKeyEventsForCommandList(aCommands)); + if (aCommands.getLength() == 1) + { + awt::KeyEvent aKeyEvent; + if (aKeyCodes[0] >>= aKeyEvent) + { + return AWTKey2VCLKey(aKeyEvent); + } + } + } + catch (css::lang::IllegalArgumentException&) + { + } + } + return vcl::KeyCode(); +} + +static bool ResourceHasKey(const OUString& rsResourceName, const OUString& rsCommandName, const OUString& rsModuleName) +{ + Sequence< OUString > aSequence; + try + { + if (!rsModuleName.isEmpty()) + { + Reference xNameAccess(GetCommandDescription()); + Reference xUICommandLabels; + if (xNameAccess->getByName(rsModuleName) >>= xUICommandLabels) + { + xUICommandLabels->getByName(rsResourceName) >>= aSequence; + if (comphelper::findValue(aSequence, rsCommandName) != -1) + return true; + } + } + } + catch (Exception&) + { + } + return false; +} + +Sequence GetCommandProperties(const OUString& rsCommandName, const OUString& rsModuleName) +{ + Sequence aProperties; + + try + { + if (!rsModuleName.isEmpty()) + { + Reference xNameAccess(GetCommandDescription()); + Reference xUICommandLabels; + if ((xNameAccess->getByName(rsModuleName) >>= xUICommandLabels) && xUICommandLabels->hasByName(rsCommandName)) + xUICommandLabels->getByName(rsCommandName) >>= aProperties; + } + } + catch (Exception&) + { + } + + return aProperties; +} + +static OUString GetCommandProperty(const OUString& rsProperty, const Sequence &rProperties) +{ + auto pProp = std::find_if(rProperties.begin(), rProperties.end(), + [&rsProperty](const beans::PropertyValue& rProp) { return rProp.Name == rsProperty; }); + if (pProp != rProperties.end()) + { + OUString sLabel; + pProp->Value >>= sLabel; + return sLabel; + } + return OUString(); +} + +OUString GetLabelForCommand(const css::uno::Sequence& rProperties) +{ + return GetCommandProperty("Name", rProperties); +} + +OUString GetMenuLabelForCommand(const css::uno::Sequence& rProperties) +{ + // Here we want to use "Label", not "Name". "Name" is a stripped-down version of "Label" without accelerators + // and ellipsis. In the menu, we want to have those accelerators and ellipsis. + return GetCommandProperty("Label", rProperties); +} + +OUString GetPopupLabelForCommand(const css::uno::Sequence& rProperties) +{ + OUString sPopupLabel(GetCommandProperty("PopupLabel", rProperties)); + if (!sPopupLabel.isEmpty()) + return sPopupLabel; + return GetCommandProperty("Label", rProperties); +} + +OUString GetTooltipLabelForCommand(const css::uno::Sequence& rProperties) +{ + OUString sLabel(GetCommandProperty("TooltipLabel", rProperties)); + if (!sLabel.isEmpty()) + return sLabel; + return GetCommandProperty("Label", rProperties); +} + +OUString GetTooltipForCommand( + const OUString& rsCommandName, + const css::uno::Sequence& rProperties, + const Reference& rxFrame) +{ + OUString sLabel(GetCommandProperty("TooltipLabel", rProperties)); + if (sLabel.isEmpty()) { + sLabel = GetPopupLabelForCommand(rProperties); + // Remove '...' at the end and mnemonics (we don't want those in tooltips) + sLabel = comphelper::string::stripEnd(sLabel, '.'); + sLabel = MnemonicGenerator::EraseAllMnemonicChars(sLabel); + } + + // Command can be just an alias to another command, + // so need to get the shortcut of the "real" command. + const OUString sRealCommand(GetRealCommandForCommand(rProperties)); + const OUString sShortCut(GetCommandShortcut(!sRealCommand.isEmpty() ? sRealCommand : rsCommandName, rxFrame)); + if (!sShortCut.isEmpty()) + return sLabel + " (" + sShortCut + ")"; + return sLabel; +} + +OUString GetCommandShortcut (const OUString& rsCommandName, + const Reference& rxFrame) +{ + + OUString sShortcut; + + sShortcut = RetrieveShortcutsFromConfiguration(GetDocumentAcceleratorConfiguration(rxFrame), rsCommandName); + if (sShortcut.getLength() > 0) + return sShortcut; + + sShortcut = RetrieveShortcutsFromConfiguration(GetModuleAcceleratorConfiguration(rxFrame), rsCommandName); + if (sShortcut.getLength() > 0) + return sShortcut; + + sShortcut = RetrieveShortcutsFromConfiguration(GetGlobalAcceleratorConfiguration(), rsCommandName); + if (sShortcut.getLength() > 0) + return sShortcut; + + return OUString(); +} + +vcl::KeyCode GetCommandKeyCodeShortcut (const OUString& rsCommandName, const Reference& rxFrame) +{ + vcl::KeyCode aKeyCodeShortcut; + + aKeyCodeShortcut = RetrieveKeyCodeShortcutsFromConfiguration(GetDocumentAcceleratorConfiguration(rxFrame), rsCommandName); + if (aKeyCodeShortcut.GetCode()) + return aKeyCodeShortcut; + + aKeyCodeShortcut = RetrieveKeyCodeShortcutsFromConfiguration(GetModuleAcceleratorConfiguration(rxFrame), rsCommandName); + if (aKeyCodeShortcut.GetCode()) + return aKeyCodeShortcut; + + aKeyCodeShortcut = RetrieveKeyCodeShortcutsFromConfiguration(GetGlobalAcceleratorConfiguration(), rsCommandName); + if (aKeyCodeShortcut.GetCode()) + return aKeyCodeShortcut; + + return vcl::KeyCode(); +} + +OUString GetRealCommandForCommand(const css::uno::Sequence& rProperties) +{ + return GetCommandProperty("TargetURL", rProperties); +} + +Reference GetXGraphicForCommand(const OUString& rsCommandName, + const Reference& rxFrame, + vcl::ImageType eImageType) +{ + if (rsCommandName.isEmpty()) + return nullptr; + + sal_Int16 nImageType(ui::ImageType::COLOR_NORMAL | ui::ImageType::SIZE_DEFAULT); + + if (eImageType == vcl::ImageType::Size26) + nImageType |= ui::ImageType::SIZE_LARGE; + else if (eImageType == vcl::ImageType::Size32) + nImageType |= ui::ImageType::SIZE_32; + + try + { + Reference xController(rxFrame->getController(), UNO_SET_THROW); + Reference xSupplier(xController->getModel(), UNO_QUERY); + if (xSupplier.is()) + { + Reference xDocUICfgMgr(xSupplier->getUIConfigurationManager()); + Reference xDocImgMgr(xDocUICfgMgr->getImageManager(), UNO_QUERY); + + Sequence< Reference > aGraphicSeq; + Sequence aImageCmdSeq { rsCommandName }; + + aGraphicSeq = xDocImgMgr->getImages( nImageType, aImageCmdSeq ); + Reference xGraphic = aGraphicSeq[0]; + if (xGraphic.is()) + return xGraphic; + } + } + catch (Exception&) + { + } + + try { + Reference xModuleCfgMgrSupplier(GetModuleConfigurationSupplier()); + Reference xUICfgMgr(xModuleCfgMgrSupplier->getUIConfigurationManager(GetModuleIdentifier(rxFrame))); + + Sequence< Reference > aGraphicSeq; + Reference xModuleImageManager(xUICfgMgr->getImageManager(), UNO_QUERY); + + Sequence aImageCmdSeq { rsCommandName }; + + aGraphicSeq = xModuleImageManager->getImages(nImageType, aImageCmdSeq); + + Reference xGraphic(aGraphicSeq[0]); + + return xGraphic; + } + catch (Exception&) + { + } + + return nullptr; +} + +Image GetImageForCommand(const OUString& rsCommandName, + const Reference& rxFrame, + vcl::ImageType eImageType) +{ + return Image(GetXGraphicForCommand(rsCommandName, rxFrame, eImageType)); +} + +sal_Int32 GetPropertiesForCommand ( + const OUString& rsCommandName, + const OUString& rsModuleName) +{ + sal_Int32 nValue = 0; + const Sequence aProperties (GetCommandProperties(rsCommandName, rsModuleName)); + + auto pProp = std::find_if(aProperties.begin(), aProperties.end(), + [](const beans::PropertyValue& rProp) { return rProp.Name == "Properties"; }); + if (pProp != aProperties.end()) + pProp->Value >>= nValue; + + return nValue; +} + +bool IsRotated(const OUString& rsCommandName, const OUString& rsModuleName) +{ + return ResourceHasKey("private:resource/image/commandrotateimagelist", rsCommandName, rsModuleName); +} + +bool IsMirrored(const OUString& rsCommandName, const OUString& rsModuleName) +{ + return ResourceHasKey("private:resource/image/commandmirrorimagelist", rsCommandName, rsModuleName); +} + +bool IsExperimental(const OUString& rsCommandName, const OUString& rModuleName) +{ + Sequence aProperties; + try + { + if( rModuleName.getLength() > 0) + { + Reference xNameAccess(GetCommandDescription()); + Reference xUICommandLabels; + if (xNameAccess->getByName( rModuleName ) >>= xUICommandLabels ) + xUICommandLabels->getByName(rsCommandName) >>= aProperties; + + auto pProp = std::find_if(aProperties.begin(), aProperties.end(), + [](const beans::PropertyValue& rProp) { return rProp.Name == "IsExperimental"; }); + if (pProp != aProperties.end()) + { + bool bValue; + return (pProp->Value >>= bValue) && bValue; + } + } + } + catch (Exception&) + { + } + return false; +} + +OUString GetModuleIdentifier(const Reference& rxFrame) +{ + static WeakReference xWeakRef; + css::uno::Reference xRef(xWeakRef); + + if (!xRef.is()) + { + xRef = frame::ModuleManager::create(comphelper::getProcessComponentContext()); + xWeakRef = xRef; + } + + try + { + return xRef->identify(rxFrame); + } + catch (const Exception&) + {} + + return OUString(); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit v1.2.3