/* -*- 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 { namespace CommandInfoProvider { static Reference const GetCommandDescription() { static WeakReference xWeakRef; css::uno::Reference xRef(xWeakRef); if (!xRef.is()) { xRef = frame::theUICommandDescription::get(comphelper::getProcessComponentContext()); xWeakRef = xRef; } return xRef; } static Reference const GetModuleConfigurationSupplier() { static WeakReference xWeakRef; css::uno::Reference xRef(xWeakRef); if (!xRef.is()) { xRef = ui::theModuleUIConfigurationManagerSupplier::get(comphelper::getProcessComponentContext()); xWeakRef = xRef; } return xRef; } static Reference const GetGlobalAcceleratorConfiguration() { static WeakReference xWeakRef; css::uno::Reference xRef(xWeakRef); if (!xRef.is()) { xRef = ui::GlobalAcceleratorConfiguration::create(comphelper::getProcessComponentContext()); xWeakRef = xRef; } return xRef; } static Reference const 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 const 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 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; for ( sal_Int32 i = 0; i < aSequence.getLength(); i++ ) { if (aSequence[i] == rsCommandName) return true; } } } } catch (Exception&) { } return false; } static 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->getByName(rsCommandName) >>= aProperties; } } catch (Exception&) { } return aProperties; } static OUString GetCommandProperty(const OUString& rsProperty, const OUString& rsCommandName, const OUString& rsModuleName) { const Sequence aProperties (GetCommandProperties(rsCommandName, rsModuleName)); for (sal_Int32 nIndex=0; nIndex>= sLabel; return sLabel; } } return OUString(); } OUString GetLabelForCommand ( const OUString& rsCommandName, const OUString& rsModuleName) { return GetCommandProperty("Name", rsCommandName, rsModuleName); } OUString GetMenuLabelForCommand ( const OUString& rsCommandName, const OUString& rsModuleName) { // 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", rsCommandName, rsModuleName); } OUString GetPopupLabelForCommand ( const OUString& rsCommandName, const OUString& rsModuleName) { OUString sPopupLabel(GetCommandProperty("PopupLabel", rsCommandName, rsModuleName)); if (!sPopupLabel.isEmpty()) return sPopupLabel; return GetCommandProperty("Label", rsCommandName, rsModuleName); } OUString GetTooltipForCommand ( const OUString& rsCommandName, const Reference& rxFrame) { OUString sModuleName(GetModuleIdentifier(rxFrame)); OUString sLabel (GetCommandProperty("TooltipLabel", rsCommandName, sModuleName)); if (sLabel.isEmpty()) { sLabel = GetPopupLabelForCommand(rsCommandName, sModuleName); // 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(rsCommandName, sModuleName)); 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(); } OUString GetRealCommandForCommand(const OUString& rCommandName, const OUString& rsModuleName) { return GetCommandProperty("TargetURL", rCommandName, rsModuleName); } static BitmapEx GetBitmapForCommand(const OUString& rsCommandName, const Reference& rxFrame, vcl::ImageType eImageType) { if (rsCommandName.isEmpty()) return BitmapEx(); 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]; const Graphic aGraphic(xGraphic); BitmapEx aBitmap(aGraphic.GetBitmapEx()); if (!!aBitmap) return aBitmap; } } 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]); const Graphic aGraphic(xGraphic); return aGraphic.GetBitmapEx(); } catch (Exception&) { } return BitmapEx(); } Image GetImageForCommand(const OUString& rsCommandName, const Reference& rxFrame, vcl::ImageType eImageType) { return Image(GetBitmapForCommand(rsCommandName, rxFrame, eImageType)); } sal_Int32 GetPropertiesForCommand ( const OUString& rsCommandName, const OUString& rsModuleName) { sal_Int32 nValue = 0; const Sequence aProperties (GetCommandProperties(rsCommandName, rsModuleName)); for (sal_Int32 nIndex=0; nIndex>= nValue; break; } } 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; for (sal_Int32 nIndex=0; nIndex>= bValue) && bValue; } } } } catch (Exception&) { } return false; } OUString const 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: */