[Libreoffice-commits] core.git: 2 commits - framework/Library_fwk.mk framework/source framework/util officecfg/registry sfx2/sdi
Maxim Monastirsky
momonasmon at gmail.com
Wed Nov 11 05:04:46 PST 2015
framework/Library_fwk.mk | 1
framework/source/uielement/menubarmanager.cxx | 7
framework/source/uielement/thesaurusmenucontroller.cxx | 218 ++++++++++
framework/source/uielement/uicommanddescription.cxx | 12
framework/util/fwk.component | 4
officecfg/registry/data/org/openoffice/Office/UI/Controller.xcu | 11
officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu | 8
officecfg/registry/schema/org/openoffice/Office/UI/Commands.xcs | 5
sfx2/sdi/sfx.sdi | 2
9 files changed, 266 insertions(+), 2 deletions(-)
New commits:
commit a133053f94f7c5b05f4354bb4977c2250b470a8a
Author: Maxim Monastirsky <momonasmon at gmail.com>
Date: Wed Nov 11 15:01:52 2015 +0200
tdf#93837 Create Thesaurus popup menu controller
The old context menu implementation adds the thesaurus
sub-menu by manipulating the menu at runtime, which isn't a
good idea in general. Since it's a sub-menu anyway, better
to have it as a separate controller, so it can be added
to the xml, and users could decide if they want it, and
where.
Most of the code adapted from sfx2 (menu/mnumgr.cxx,
menu/thessubmenu.cxx), hence the Apache-based license
header.
Change-Id: I4f533fcdd5d6480fae8ebcf53ec7c69675025adb
diff --git a/framework/Library_fwk.mk b/framework/Library_fwk.mk
index d07f8b9..3efd330 100644
--- a/framework/Library_fwk.mk
+++ b/framework/Library_fwk.mk
@@ -153,6 +153,7 @@ $(eval $(call gb_Library_add_exception_objects,fwk,\
framework/source/uielement/statusbarwrapper \
framework/source/uielement/statusindicatorinterfacewrapper \
framework/source/uielement/subtoolbarcontroller \
+ framework/source/uielement/thesaurusmenucontroller \
framework/source/uielement/togglebuttontoolbarcontroller \
framework/source/uielement/toolbarmanager \
framework/source/uielement/toolbarmerger \
diff --git a/framework/source/uielement/thesaurusmenucontroller.cxx b/framework/source/uielement/thesaurusmenucontroller.cxx
new file mode 100644
index 0000000..b9457d7
--- /dev/null
+++ b/framework/source/uielement/thesaurusmenucontroller.cxx
@@ -0,0 +1,218 @@
+/* -*- 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 <comphelper/processfactory.hxx>
+#include <svl/lngmisc.hxx>
+#include <svtools/popupmenucontrollerbase.hxx>
+#include <unotools/lingucfg.hxx>
+#include <vcl/image.hxx>
+#include <vcl/menu.hxx>
+
+#include <com/sun/star/frame/theUICommandDescription.hpp>
+#include <com/sun/star/linguistic2/LinguServiceManager.hpp>
+
+class ThesaurusMenuController : public svt::PopupMenuControllerBase
+{
+public:
+ explicit ThesaurusMenuController( const css::uno::Reference< css::uno::XComponentContext >& rxContext );
+ virtual ~ThesaurusMenuController();
+
+ // XStatusListener
+ virtual void SAL_CALL statusChanged( const css::frame::FeatureStateEvent& rEvent ) throw ( css::uno::RuntimeException, std::exception ) override;
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() throw ( css::uno::RuntimeException, std::exception ) override;
+ virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() throw ( css::uno::RuntimeException, std::exception ) override;
+
+private:
+ virtual void impl_setPopupMenu() override;
+ void getMeanings( std::vector< OUString >& rSynonyms, const OUString& rWord, const css::lang::Locale& rLocale, size_t nMaxSynonms );
+ OUString getThesImplName( const css::lang::Locale& rLocale ) const;
+ css::uno::Reference< css::linguistic2::XLinguServiceManager2 > m_xLinguServiceManager;
+ css::uno::Reference< css::linguistic2::XThesaurus > m_xThesaurus;
+ OUString m_aLastWord;
+};
+
+namespace {
+
+OUString RetrieveLabelFromCommand( const OUString& rCmdURL, const OUString& rModuleName )
+{
+ if ( rCmdURL.isEmpty() || rModuleName.isEmpty() )
+ return OUString();
+
+ css::uno::Any a;
+ css::uno::Sequence< css::beans::PropertyValue > aPropSeq;
+ try
+ {
+ css::uno::Reference< css::container::XNameAccess > const xNameAccess(
+ css::frame::theUICommandDescription::get( comphelper::getProcessComponentContext() ), css::uno::UNO_QUERY_THROW );
+ a = xNameAccess->getByName( rModuleName );
+ css::uno::Reference< css::container::XNameAccess > xUICommandLabels;
+ a >>= xUICommandLabels;
+ a = xUICommandLabels->getByName( rCmdURL );
+ a >>= aPropSeq;
+ }
+ catch ( const css::uno::Exception& )
+ {
+ SAL_WARN( "fwk.uielement", "Failed to get label for command " << rCmdURL );
+ }
+
+ OUString aLabel;
+ for ( const auto& aProp : aPropSeq )
+ {
+ if ( aProp.Name == "Label" )
+ {
+ aProp.Value >>= aLabel;
+ }
+ else if ( aProp.Name == "PopupLabel" )
+ {
+ OUString aStr;
+ if ( ( aProp.Value >>= aStr ) && !aStr.isEmpty() )
+ return aStr;
+ }
+ }
+ return aLabel;
+}
+
+}
+
+ThesaurusMenuController::ThesaurusMenuController( const css::uno::Reference< css::uno::XComponentContext >& rxContext ) :
+ svt::PopupMenuControllerBase( rxContext ),
+ m_xLinguServiceManager( css::linguistic2::LinguServiceManager::create( rxContext ) ),
+ m_xThesaurus( m_xLinguServiceManager->getThesaurus() )
+{
+}
+
+ThesaurusMenuController::~ThesaurusMenuController()
+{
+}
+
+void ThesaurusMenuController::statusChanged( const css::frame::FeatureStateEvent& rEvent )
+ throw ( css::uno::RuntimeException, std::exception )
+{
+ rEvent.State >>= m_aLastWord;
+ m_xPopupMenu->clear();
+ if ( rEvent.IsEnabled )
+ impl_setPopupMenu();
+}
+
+void ThesaurusMenuController::impl_setPopupMenu()
+{
+ OUString aText = m_aLastWord.getToken(0, '#');
+ OUString aIsoLang = m_aLastWord.getToken(1, '#');
+ if ( aText.isEmpty() || aIsoLang.isEmpty() )
+ return;
+
+ std::vector< OUString > aSynonyms;
+ css::lang::Locale aLocale = LanguageTag::convertToLocale( aIsoLang );
+ getMeanings( aSynonyms, aText, aLocale, 7 /*max number of synonyms to retrieve*/ );
+
+ VCLXMenu* pAwtMenu = VCLXMenu::GetImplementation( m_xPopupMenu );
+ Menu* pVCLMenu = pAwtMenu->GetMenu();
+ pVCLMenu->SetMenuFlags( MenuFlags::NoAutoMnemonics );
+ if ( aSynonyms.size() > 0 )
+ {
+ SvtLinguConfig aCfg;
+ Image aImage;
+ OUString aThesImplName( getThesImplName( aLocale ) );
+ OUString aSynonymsImageUrl( aCfg.GetSynonymsContextImage( aThesImplName ) );
+ if ( !aThesImplName.isEmpty() && !aSynonymsImageUrl.isEmpty() )
+ aImage = Image( aSynonymsImageUrl );
+
+ for ( const auto& aSynonym : aSynonyms )
+ {
+ const sal_uInt16 nId = pVCLMenu->GetItemCount() + 1;
+ OUString aItemText( linguistic::GetThesaurusReplaceText( aSynonym ) );
+ pVCLMenu->InsertItem( nId, aItemText );
+ pVCLMenu->SetItemCommand( nId, ".uno:ThesaurusFromContext?WordReplace:string=" + aItemText );
+
+ if ( !aSynonymsImageUrl.isEmpty() )
+ pVCLMenu->SetItemImage( nId, aImage );
+ }
+
+ pVCLMenu->InsertSeparator();
+ OUString aThesaurusDialogCmd( ".uno:ThesaurusDialog" );
+ pVCLMenu->InsertItem( 100, RetrieveLabelFromCommand( aThesaurusDialogCmd, m_aModuleName ) );
+ pVCLMenu->SetItemCommand( 100, aThesaurusDialogCmd );
+ }
+}
+
+void ThesaurusMenuController::getMeanings( std::vector< OUString >& rSynonyms, const OUString& rWord,
+ const css::lang::Locale& rLocale, size_t nMaxSynonms )
+{
+ rSynonyms.clear();
+ if ( m_xThesaurus.is() && m_xThesaurus->hasLocale( rLocale ) && !rWord.isEmpty() && nMaxSynonms > 0 )
+ {
+ try
+ {
+ const css::uno::Sequence< css::uno::Reference< css::linguistic2::XMeaning > > aMeaningSeq(
+ m_xThesaurus->queryMeanings( rWord, rLocale, css::uno::Sequence< css::beans::PropertyValue >() ) );
+
+ for ( const auto& xMeaning : aMeaningSeq )
+ {
+ const css::uno::Sequence< OUString > aSynonymSeq( xMeaning->querySynonyms() );
+ for ( const auto& aSynonym : aSynonymSeq )
+ {
+ rSynonyms.push_back( aSynonym );
+ if ( rSynonyms.size() == nMaxSynonms )
+ return;
+ }
+ }
+ }
+ catch ( const css::uno::Exception& )
+ {
+ SAL_WARN( "fwk.uielement", "Failed to get synonyms" );
+ }
+ }
+}
+
+OUString ThesaurusMenuController::getThesImplName( const css::lang::Locale& rLocale ) const
+{
+ css::uno::Sequence< OUString > aServiceNames =
+ m_xLinguServiceManager->getConfiguredServices( "com.sun.star.linguistic2.Thesaurus", rLocale );
+ SAL_WARN_IF( aServiceNames.getLength() > 1, "fwk.uielement", "Only one thesaurus is allowed per locale, but found more!" );
+ if ( aServiceNames.getLength() == 1 )
+ return aServiceNames[0];
+
+ return OUString();
+}
+
+OUString ThesaurusMenuController::getImplementationName()
+ throw ( css::uno::RuntimeException, std::exception )
+{
+ return OUString( "com.sun.star.comp.framework.ThesaurusMenuController" );
+}
+
+css::uno::Sequence< OUString > ThesaurusMenuController::getSupportedServiceNames()
+ throw ( css::uno::RuntimeException, std::exception )
+{
+ css::uno::Sequence< OUString > aRet( 1 );
+ aRet[0] = "com.sun.star.frame.PopupMenuController";
+ return aRet;
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
+com_sun_star_comp_framework_ThesaurusMenuController_get_implementation(
+ css::uno::XComponentContext* xContext,
+ css::uno::Sequence< css::uno::Any > const & )
+{
+ return cppu::acquire( new ThesaurusMenuController( xContext ) );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/util/fwk.component b/framework/util/fwk.component
index ad16782..e1744fc 100644
--- a/framework/util/fwk.component
+++ b/framework/util/fwk.component
@@ -204,4 +204,8 @@
constructor="com_sun_star_comp_framework_SubToolBarController_get_implementation">
<service name="com.sun.star.frame.ToolbarController"/>
</implementation>
+ <implementation name="com.sun.star.comp.framework.ThesaurusMenuController"
+ constructor="com_sun_star_comp_framework_ThesaurusMenuController_get_implementation">
+ <service name="com.sun.star.frame.PopupMenuController"/>
+ </implementation>
</component>
diff --git a/officecfg/registry/data/org/openoffice/Office/UI/Controller.xcu b/officecfg/registry/data/org/openoffice/Office/UI/Controller.xcu
index 5e885fd..c4f6711 100644
--- a/officecfg/registry/data/org/openoffice/Office/UI/Controller.xcu
+++ b/officecfg/registry/data/org/openoffice/Office/UI/Controller.xcu
@@ -185,6 +185,17 @@
<value>com.sun.star.comp.framework.SaveAsMenuController</value>
</prop>
</node>
+ <node oor:name="c17" oor:op="replace">
+ <prop oor:name="Command">
+ <value>.uno:ThesaurusFromContext</value>
+ </prop>
+ <prop oor:name="Module">
+ <value/>
+ </prop>
+ <prop oor:name="Controller">
+ <value>com.sun.star.comp.framework.ThesaurusMenuController</value>
+ </prop>
+ </node>
</node>
<node oor:name="ToolBar">
<node oor:name="ZoomToolBox" oor:op="replace">
diff --git a/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu b/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu
index 161b46c..cab5cbe 100644
--- a/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu
+++ b/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu
@@ -5632,6 +5632,14 @@
<value>1</value>
</prop>
</node>
+ <node oor:name=".uno:ThesaurusFromContext" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="en-US">Synony~ms</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
</node>
<node oor:name="Popups">
<node oor:name=".uno:HelpMenu" oor:op="replace">
diff --git a/sfx2/sdi/sfx.sdi b/sfx2/sdi/sfx.sdi
index e207e8b..f151bc7 100644
--- a/sfx2/sdi/sfx.sdi
+++ b/sfx2/sdi/sfx.sdi
@@ -7802,7 +7802,7 @@ SfxInt16Item ThesaurusFromContext SID_THES
/* config: */
AccelConfig = FALSE,
- MenuConfig = FALSE,
+ MenuConfig = TRUE,
StatusBarConfig = FALSE,
ToolBoxConfig = FALSE,
GroupId = GID_TEXT;
commit 737555eb2ff5f4f90b9794784e1ac8f0451b9b97
Author: Maxim Monastirsky <momonasmon at gmail.com>
Date: Wed Oct 28 14:21:03 2015 +0200
tdf#93837 Add a new PopupLabel property
Some commands in context menus use different labels than in
the menu bar. In the old resource format those labels are
defined in the resource file itself. Note that the menu xml
has the menu:label attribute, but we can't use it because it
lacks localization support, and as such useful only for user
customization.
The order of consideration now is:
1. Label - Used if Context/PopupLabel isn't defined. (It's
also used as the base for toolbar tooltips.)
2. ContextLabel - Overrides Label when in menu or context menu.
Useful to drop the context, e.g. "Insert Image" should be only
"Image" under "Insert" menu. If exists, that's what returned
when asking for the "Label" property, instead of the full label.
3. PopupLabel - Overrides Label/ContextLabel when in context menu.
Used to give items in a context menu different labels than in
the main menu, e.g. "Paste Special" from the main menu turns to
"More Options" when in context menu. It doesn't affect the Label
property, and should be asked separately.
Change-Id: I7408fc2bfb8d384b0f1a72a78b8c5d7c50de38da
diff --git a/framework/source/uielement/menubarmanager.cxx b/framework/source/uielement/menubarmanager.cxx
index 2c0db7b..399c667 100644
--- a/framework/source/uielement/menubarmanager.cxx
+++ b/framework/source/uielement/menubarmanager.cxx
@@ -1096,6 +1096,13 @@ bool MenuBarManager::MustBeHidden( PopupMenu* pPopupMenu, const Reference< XURLT
OUString MenuBarManager::RetrieveLabelFromCommand(const OUString& rCmdURL)
{
+ if ( !m_bHasMenuBar )
+ {
+ // This is a context menu, prefer "PopupLabel" over "Label".
+ OUString aPopupLabel = framework::RetrieveLabelFromCommand(rCmdURL, m_xContext, m_xUICommandLabels,m_xFrame,m_aModuleIdentifier,m_bModuleIdentified,"PopupLabel");
+ if ( !aPopupLabel.isEmpty() )
+ return aPopupLabel;
+ }
return framework::RetrieveLabelFromCommand(rCmdURL, m_xContext, m_xUICommandLabels,m_xFrame,m_aModuleIdentifier,m_bModuleIdentified,"Label");
}
diff --git a/framework/source/uielement/uicommanddescription.cxx b/framework/source/uielement/uicommanddescription.cxx
index de99a7b..3f6bc54 100644
--- a/framework/source/uielement/uicommanddescription.cxx
+++ b/framework/source/uielement/uicommanddescription.cxx
@@ -59,11 +59,13 @@ static const char CONFIGURATION_CMD_ELEMENT_ACCESS[] = "/UserInterface/Comman
static const char CONFIGURATION_POP_ELEMENT_ACCESS[] = "/UserInterface/Popups";
static const char CONFIGURATION_PROPERTY_LABEL[] = "Label";
static const char CONFIGURATION_PROPERTY_CONTEXT_LABEL[] = "ContextLabel";
+static const char CONFIGURATION_PROPERTY_POPUP_LABEL[] = "PopupLabel";
// Property names of the resulting Property Set
static const char PROPSET_LABEL[] = "Label";
static const char PROPSET_NAME[] = "Name";
static const char PROPSET_POPUP[] = "Popup";
+static const char PROPSET_POPUPLABEL[] = "PopupLabel";
static const char PROPSET_PROPERTIES[] = "Properties";
// Special resource URLs to retrieve additional information
@@ -123,6 +125,7 @@ class ConfigurationAccess_UICommand : // Order is necessary for right initializa
OUString aLabel;
OUString aContextLabel;
OUString aCommandName;
+ OUString aPopupLabel;
bool bPopup : 1,
bCommandNameCreated : 1;
sal_Int32 nProperties;
@@ -151,9 +154,11 @@ class ConfigurationAccess_UICommand : // Order is necessary for right initializa
OUString m_aConfigPopupAccess;
OUString m_aPropUILabel;
OUString m_aPropUIContextLabel;
+ OUString m_aPropUIPopupLabel;
OUString m_aPropLabel;
OUString m_aPropName;
OUString m_aPropPopup;
+ OUString m_aPropPopupLabel;
OUString m_aPropProperties;
OUString m_aPrivateResourceURL;
Reference< XNameAccess > m_xGenericUICommands;
@@ -178,9 +183,11 @@ ConfigurationAccess_UICommand::ConfigurationAccess_UICommand( const OUString& aM
m_aConfigPopupAccess( CONFIGURATION_ROOT_ACCESS ),
m_aPropUILabel( CONFIGURATION_PROPERTY_LABEL ),
m_aPropUIContextLabel( CONFIGURATION_PROPERTY_CONTEXT_LABEL ),
+ m_aPropUIPopupLabel( CONFIGURATION_PROPERTY_POPUP_LABEL ),
m_aPropLabel( PROPSET_LABEL ),
m_aPropName( PROPSET_NAME ),
m_aPropPopup( PROPSET_POPUP ),
+ m_aPropPopupLabel( PROPSET_POPUPLABEL ),
m_aPropProperties( PROPSET_PROPERTIES ),
m_aPrivateResourceURL( PRIVATE_RESOURCE_URL ),
m_xGenericUICommands( rGenericUICommands ),
@@ -299,7 +306,7 @@ Any ConfigurationAccess_UICommand::getSequenceFromCache( const OUString& aComman
if ( !pIter->second.bCommandNameCreated )
fillInfoFromResult( pIter->second, pIter->second.aLabel );
- Sequence< PropertyValue > aPropSeq( 4 );
+ Sequence< PropertyValue > aPropSeq( 5 );
aPropSeq[0].Name = m_aPropLabel;
aPropSeq[0].Value = !pIter->second.aContextLabel.isEmpty() ?
makeAny( pIter->second.aContextLabel ): makeAny( pIter->second.aLabel );
@@ -309,6 +316,8 @@ Any ConfigurationAccess_UICommand::getSequenceFromCache( const OUString& aComman
aPropSeq[2].Value <<= pIter->second.bPopup;
aPropSeq[3].Name = m_aPropProperties;
aPropSeq[3].Value <<= pIter->second.nProperties;
+ aPropSeq[4].Name = m_aPropPopupLabel;
+ aPropSeq[4].Value <<= pIter->second.aPopupLabel;
return makeAny( aPropSeq );
}
@@ -335,6 +344,7 @@ void ConfigurationAccess_UICommand::impl_fill(const Reference< XNameAccess >& _x
aCmdToInfo.bPopup = _bPopup;
xNameAccess->getByName( m_aPropUILabel ) >>= aCmdToInfo.aLabel;
xNameAccess->getByName( m_aPropUIContextLabel ) >>= aCmdToInfo.aContextLabel;
+ xNameAccess->getByName( m_aPropUIPopupLabel ) >>= aCmdToInfo.aPopupLabel;
xNameAccess->getByName( m_aPropProperties ) >>= aCmdToInfo.nProperties;
m_aCmdInfoCache.insert( CommandToInfoCache::value_type( aNameSeq[i], aCmdToInfo ));
diff --git a/officecfg/registry/schema/org/openoffice/Office/UI/Commands.xcs b/officecfg/registry/schema/org/openoffice/Office/UI/Commands.xcs
index f5e1224..85460d2 100644
--- a/officecfg/registry/schema/org/openoffice/Office/UI/Commands.xcs
+++ b/officecfg/registry/schema/org/openoffice/Office/UI/Commands.xcs
@@ -36,6 +36,11 @@
<desc>A localized text that describes the identifier of a command in a structured menu. </desc>
</info>
</prop>
+ <prop oor:name="PopupLabel" oor:type="xs:string" oor:localized="true">
+ <info>
+ <desc>A localized text that describes the identifier of a command in a popup menu.</desc>
+ </info>
+ </prop>
<prop oor:name="Properties" oor:type="xs:int" oor:nillable="false">
<info>
<desc>
More information about the Libreoffice-commits
mailing list