Use ResourceMenuController for toolbar-based menus too
No need for yet another controller that does similar things.
Change-Id: I4ad79d82ea34a90a43e36082d1fb834201dba3a1
diff --git a/framework/Library_fwk.mk b/framework/Library_fwk.mk
index ce85848..0c78fc4 100644
--- a/framework/Library_fwk.mk
+++ b/framework/Library_fwk.mk
@@ -156,7 +156,6 @@ $(eval $(call gb_Library_add_exception_objects,fwk,\
framework/source/uielement/subtoolbarcontroller \
framework/source/uielement/thesaurusmenucontroller \
framework/source/uielement/togglebuttontoolbarcontroller \
framework/source/uielement/toolbarasmenucontroller \
framework/source/uielement/toolbarmanager \
framework/source/uielement/toolbarmerger \
framework/source/uielement/toolbarwrapper \
diff --git a/framework/source/uielement/resourcemenucontroller.cxx b/framework/source/uielement/resourcemenucontroller.cxx
index 581c227..4477516 100644
--- a/framework/source/uielement/resourcemenucontroller.cxx
+++ b/framework/source/uielement/resourcemenucontroller.cxx
@@ -16,6 +16,7 @@
#include <com/sun/star/embed/VerbDescriptor.hpp>
#include <com/sun/star/frame/ModuleManager.hpp>
#include <com/sun/star/frame/XStorable.hpp>
#include <com/sun/star/ui/ItemType.hpp>
#include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
#include <com/sun/star/util/URL.hpp>
@@ -26,7 +27,7 @@ class ResourceMenuController : public cppu::ImplInheritanceHelper< svt::PopupMen
{
public:
ResourceMenuController( const css::uno::Reference< css::uno::XComponentContext >& rxContext,
const css::uno::Sequence< css::uno::Any >& rxArgs );
const css::uno::Sequence< css::uno::Any >& rxArgs, bool bToolbarContainer );
virtual ~ResourceMenuController();
// XPopupMenuController
@@ -55,20 +56,23 @@ private:
OUString m_aMenuURL;
bool m_bContextMenu;
bool m_bInToolbar;
bool m_bToolbarContainer;
sal_uInt16 m_nNewMenuId;
rtl::Reference< framework::MenuBarManager > m_xMenuBarManager;
css::uno::Reference< css::container::XIndexAccess > m_xMenuContainer;
css::uno::Reference< css::uno::XComponentContext > m_xContext;
css::uno::Reference< css::ui::XUIConfigurationManager > m_xConfigManager, m_xModuleConfigManager;
void addVerbs( const css::uno::Sequence< css::embed::VerbDescriptor >& rVerbs );
void fillToolbarData();
virtual void SAL_CALL disposing() override;
};
ResourceMenuController::ResourceMenuController( const css::uno::Reference< css::uno::XComponentContext >& rxContext,
const css::uno::Sequence< css::uno::Any >& rxArgs ) :
const css::uno::Sequence< css::uno::Any >& rxArgs, bool bToolbarContainer ) :
ImplInheritanceHelper( rxContext ),
m_bContextMenu( false ),
m_bInToolbar( false ),
m_bToolbarContainer( bToolbarContainer ),
m_nNewMenuId( 1 ),
m_xContext( rxContext )
{
@@ -81,7 +85,10 @@ ResourceMenuController::ResourceMenuController( const css::uno::Reference< css::
{
OUString aMenuName;
aPropValue.Value >>= aMenuName;
m_aMenuURL = "private:resource/popupmenu/" + aMenuName;
if ( m_bToolbarContainer )
m_aMenuURL = "private:resource/toolbar/" + aMenuName;
else
m_aMenuURL = "private:resource/popupmenu/" + aMenuName;
}
else if ( aPropValue.Name == "Frame" )
aPropValue.Value >>= m_xFrame;
@@ -184,9 +191,11 @@ void ResourceMenuController::updatePopupMenu()
m_nNewMenuId = 1;
// Now fill the menu with the configuration data.
VCLXMenu* pAwtMenu = VCLXMenu::GetImplementation( m_xPopupMenu );
css::uno::Reference< css::frame::XDispatchProvider > xDispatchProvider( m_xFrame, css::uno::UNO_QUERY );
framework::MenuBarManager::FillMenu( m_nNewMenuId, pAwtMenu->GetMenu(), m_aModuleName, m_xMenuContainer, xDispatchProvider );
if ( m_bToolbarContainer )
fillToolbarData();
else
framework::MenuBarManager::FillMenu( m_nNewMenuId, VCLXMenu::GetImplementation( m_xPopupMenu )->GetMenu(), m_aModuleName, m_xMenuContainer, xDispatchProvider );
// For context menus, add object verbs.
if ( m_bContextMenu )
@@ -235,6 +244,63 @@ void ResourceMenuController::addVerbs( const css::uno::Sequence< css::embed::Ver
}
}
void ResourceMenuController::fillToolbarData()
{
if ( !m_xMenuContainer.is() )
return;
VCLXMenu* pAwtMenu = VCLXMenu::GetImplementation( m_xPopupMenu );
Menu* pVCLMenu = pAwtMenu->GetMenu();
css::uno::Sequence< css::beans::PropertyValue > aPropSequence;
for ( sal_Int32 i = 0; i < m_xMenuContainer->getCount(); ++i )
{
try
{
if ( m_xMenuContainer->getByIndex( i ) >>= aPropSequence )
{
OUString aCommandURL;
OUString aLabel;
sal_uInt16 nType = css::ui::ItemType::DEFAULT;
bool bVisible = true;
for ( const auto& aProp: aPropSequence )
{
if ( aProp.Name == "CommandURL" )
aProp.Value >>= aCommandURL;
else if ( aProp.Name == "Label" )
aProp.Value >>= aLabel;
else if ( aProp.Name == "Type" )
aProp.Value >>= nType;
else if ( aProp.Name == "IsVisible" )
aProp.Value >>= bVisible;
}
switch ( nType )
{
case css::ui::ItemType::DEFAULT:
if ( bVisible )
{
pVCLMenu->InsertItem( m_nNewMenuId, aLabel );
pVCLMenu->SetItemCommand( m_nNewMenuId++, aCommandURL );
}
break;
case css::ui::ItemType::SEPARATOR_LINE:
case css::ui::ItemType::SEPARATOR_LINEBREAK:
if ( bVisible && pVCLMenu->GetItemId( pVCLMenu->GetItemCount() - 1 ) != 0 )
pVCLMenu->InsertSeparator();
break;
default: ;
}
}
}
catch ( const css::uno::Exception& )
{
break;
}
}
}
void ResourceMenuController::itemActivated( const css::awt::MenuEvent& /*rEvent*/ )
throw ( css::uno::RuntimeException, std::exception )
{
@@ -316,14 +382,16 @@ void ResourceMenuController::disposing()
OUString ResourceMenuController::getImplementationName()
throw ( css::uno::RuntimeException, std::exception )
{
if ( m_bToolbarContainer )
return OUString( "com.sun.star.comp.framework.ToolbarAsMenuController" );
return OUString( "com.sun.star.comp.framework.ResourceMenuController" );
}
css::uno::Sequence< OUString > ResourceMenuController::getSupportedServiceNames()
throw ( css::uno::RuntimeException, std::exception )
{
css::uno::Sequence< OUString > aRet { "com.sun.star.frame.PopupMenuController" };
return aRet;
return { "com.sun.star.frame.PopupMenuController" };
}
}
@@ -333,7 +401,15 @@ com_sun_star_comp_framework_ResourceMenuController_get_implementation(
css::uno::XComponentContext* context,
css::uno::Sequence< css::uno::Any > const & args )
{
return cppu::acquire( new ResourceMenuController( context, args ) );
return cppu::acquire( new ResourceMenuController( context, args, false ) );
}
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
com_sun_star_comp_framework_ToolbarAsMenuController_get_implementation(
css::uno::XComponentContext* context,
css::uno::Sequence< css::uno::Any > const & args )
{
return cppu::acquire( new ResourceMenuController( context, args, true ) );
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/toolbarasmenucontroller.cxx b/framework/source/uielement/toolbarasmenucontroller.cxx
deleted file mode 100644
index 9ea8d0b..0000000
--- a/framework/source/uielement/toolbarasmenucontroller.cxx
+++ /dev/null
@@ -1,363 +0,0 @@
/* -*- 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/.
*/
#include <cppuhelper/implbase.hxx>
#include <svtools/popupmenucontrollerbase.hxx>
#include <vcl/menu.hxx>
#include <com/sun/star/ui/ItemType.hpp>
#include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
#include <com/sun/star/util/URLTransformer.hpp>
namespace framework {
class CommandStatusHelper : public cppu::WeakImplHelper< css::frame::XStatusListener >
{
public:
CommandStatusHelper( const css::uno::Reference< css::uno::XComponentContext >& rxContext,
const css::uno::Reference< css::frame::XFrame >& rxFrame,
const OUString& rCommandURL );
virtual ~CommandStatusHelper();
// XStatusListener
virtual void SAL_CALL statusChanged( const css::frame::FeatureStateEvent& rEvent ) throw ( css::uno::RuntimeException, std::exception ) override;
// XEventListener
virtual void SAL_CALL disposing( const css::lang::EventObject& rEvent ) throw ( css::uno::RuntimeException, std::exception ) override;
void updateCommand();
bool isCommandEnabled() { return m_bEnabled; }
bool isCommandChecked() { return m_bChecked; }
private:
bool m_bEnabled;
bool m_bChecked;
OUString m_aCommandURL;
css::uno::Reference< css::frame::XFrame > m_xFrame;
css::uno::Reference< css::util::XURLTransformer > m_xURLTransformer;
};
CommandStatusHelper::CommandStatusHelper( const css::uno::Reference< css::uno::XComponentContext >& rxContext,
const css::uno::Reference< css::frame::XFrame >& rxFrame,
const OUString& rCommandURL ) :
m_bEnabled( true ),
m_bChecked( false ),
m_aCommandURL( rCommandURL ),
m_xFrame( rxFrame ),
m_xURLTransformer( css::util::URLTransformer::create( rxContext ) )
{
}
CommandStatusHelper::~CommandStatusHelper()
{
}
void CommandStatusHelper::updateCommand()
{
css::uno::Reference< css::frame::XDispatchProvider > xDispatchProvider( m_xFrame, css::uno::UNO_QUERY );
if ( xDispatchProvider.is() )
{
css::util::URL aTargetURL;
aTargetURL.Complete = m_aCommandURL;
m_xURLTransformer->parseStrict( aTargetURL );
css::uno::Reference< css::frame::XDispatch > xDispatch( xDispatchProvider->queryDispatch( aTargetURL, OUString(), 0 ) );
if ( xDispatch.is() )
{
xDispatch->addStatusListener( this, aTargetURL );
xDispatch->removeStatusListener( this, aTargetURL );
}
}
}
void CommandStatusHelper::statusChanged( const css::frame::FeatureStateEvent& rEvent )
throw ( css::uno::RuntimeException, std::exception )
{
OUString aStringStatus;
if ( rEvent.State >>= aStringStatus )
{
const OUString aEnumPart( rEvent.FeatureURL.Complete.getToken( 2, '.' ) );
if ( !aEnumPart.isEmpty() && rEvent.FeatureURL.Protocol == ".uno:" )
m_bChecked = aStringStatus == aEnumPart;
}
rEvent.State >>= m_bChecked;
m_bEnabled = rEvent.IsEnabled;
}
void CommandStatusHelper::disposing( const css::lang::EventObject& /*rEvent*/ )
throw ( css::uno::RuntimeException, std::exception )
{
// We aren't holding reference to the dispatcher, so nothing to do here.
}
class ToolbarAsMenuController : public cppu::ImplInheritanceHelper< svt::PopupMenuControllerBase, css::ui::XUIConfigurationListener >
{
public:
ToolbarAsMenuController( const css::uno::Reference< css::uno::XComponentContext >& rxContext,
const css::uno::Sequence< css::uno::Any >& rxArgs );
virtual ~ToolbarAsMenuController();
// XPopupMenuController
virtual void SAL_CALL updatePopupMenu() throw ( css::uno::RuntimeException, std::exception ) override;
// XStatusListener
virtual void SAL_CALL statusChanged( const css::frame::FeatureStateEvent& rEvent ) throw ( css::uno::RuntimeException, std::exception ) override;
// XEventListener
virtual void SAL_CALL disposing( const css::lang::EventObject& rEvent ) throw ( css::uno::RuntimeException, std::exception ) override;
// XUIConfigurationListener
virtual void SAL_CALL elementInserted( const css::ui::ConfigurationEvent& rEvent ) throw ( css::uno::RuntimeException, std::exception ) override;
virtual void SAL_CALL elementRemoved( const css::ui::ConfigurationEvent& rEvent ) throw ( css::uno::RuntimeException, std::exception ) override;
virtual void SAL_CALL elementReplaced( const css::ui::ConfigurationEvent& 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:
OUString m_aToolbarURL;
css::uno::Reference< css::container::XIndexAccess > m_xToolbarContainer;
css::uno::Reference< css::uno::XComponentContext > m_xContext;
css::uno::Reference< css::ui::XUIConfigurationManager > m_xConfigManager, m_xModuleConfigManager;
void fillPopupMenu();
virtual void SAL_CALL disposing() override;
virtual void impl_setPopupMenu() override;
};
ToolbarAsMenuController::ToolbarAsMenuController( const css::uno::Reference< css::uno::XComponentContext >& rxContext,
const css::uno::Sequence< css::uno::Any >& rxArgs ) :
ImplInheritanceHelper( rxContext ),
m_xContext( rxContext )
{
css::beans::PropertyValue aPropValue;
for ( const auto& arg: rxArgs )
{
if ( ( arg >>= aPropValue ) && aPropValue.Name == "Value" )
{
OUString aToolbarName;
aPropValue.Value >>= aToolbarName;
m_aToolbarURL = "private:resource/toolbar/" + aToolbarName;
break;
}
}
}
ToolbarAsMenuController::~ToolbarAsMenuController()
{
}
void ToolbarAsMenuController::impl_setPopupMenu()
{
if ( m_aToolbarURL.isEmpty() )
return;
if ( !m_xConfigManager.is() )
{
try
{
css::uno::Reference< css::frame::XController > xController( m_xFrame->getController() );
css::uno::Reference< css::frame::XModel > xModel( xController->getModel() );
css::uno::Reference< css::ui::XUIConfigurationManagerSupplier > xSupplier( xModel, css::uno::UNO_QUERY_THROW );
m_xConfigManager.set( xSupplier->getUIConfigurationManager() );
css::uno::Reference< css::ui::XUIConfiguration > xConfig( m_xConfigManager, css::uno::UNO_QUERY_THROW );
xConfig->addConfigurationListener( this );
}
catch( const css::uno::RuntimeException& )
{}
}
if ( !m_xModuleConfigManager.is() )
{
try
{
css::uno::Reference< css::ui::XModuleUIConfigurationManagerSupplier > xModuleCfgMgrSupplier(
css::ui::theModuleUIConfigurationManagerSupplier::get( m_xContext ) );
m_xModuleConfigManager.set( xModuleCfgMgrSupplier->getUIConfigurationManager( m_aModuleName ) );
css::uno::Reference< css::ui::XUIConfiguration > xConfig( m_xModuleConfigManager, css::uno::UNO_QUERY_THROW );
xConfig->addConfigurationListener( this );
}
catch ( const css::container::NoSuchElementException& )
{
SAL_WARN( "fwk.uielement", "Invalid module identifier: " << m_aModuleName );
}
catch( const css::uno::RuntimeException& )
{}
}
try
{
if ( m_xConfigManager.is() && m_xConfigManager->hasSettings( m_aToolbarURL ) )
m_xToolbarContainer.set( m_xConfigManager->getSettings( m_aToolbarURL, sal_False ) );
else if ( m_xModuleConfigManager.is() && m_xModuleConfigManager->hasSettings( m_aToolbarURL ) )
m_xToolbarContainer.set( m_xModuleConfigManager->getSettings( m_aToolbarURL, sal_False ) );
}
catch ( const css::container::NoSuchElementException& )
{
SAL_WARN( "fwk.uielement", "Can not find settings for " << m_aToolbarURL );
}
catch ( const css::lang::IllegalArgumentException& )
{
SAL_WARN( "fwk.uielement", "The given URL is not valid: " << m_aToolbarURL );
}
fillPopupMenu();
}
void ToolbarAsMenuController::fillPopupMenu()
{
resetPopupMenu( m_xPopupMenu );
if ( !m_xToolbarContainer.is() )
return;
VCLXMenu* pAwtMenu = VCLXMenu::GetImplementation( m_xPopupMenu );
Menu* pVCLMenu = pAwtMenu->GetMenu();
css::uno::Sequence< css::beans::PropertyValue > aPropSequence;
for ( sal_Int32 i = 0; i < m_xToolbarContainer->getCount(); ++i )
{
try
{
if ( m_xToolbarContainer->getByIndex( i ) >>= aPropSequence )
{
OUString aCommandURL;
sal_uInt16 nType = css::ui::ItemType::DEFAULT;
bool bVisible = true;
for ( const auto& aProp: aPropSequence )
{
if ( aProp.Name == "CommandURL" )
aProp.Value >>= aCommandURL;
else if ( aProp.Name == "Type" )
aProp.Value >>= nType;
else if ( aProp.Name == "IsVisible" )
aProp.Value >>= bVisible;
}
switch ( nType )
{
case css::ui::ItemType::DEFAULT:
if ( bVisible )
pVCLMenu->InsertItem( aCommandURL, m_xFrame );
break;
case css::ui::ItemType::SEPARATOR_LINE:
case css::ui::ItemType::SEPARATOR_LINEBREAK:
if ( bVisible && pVCLMenu->GetItemId( pVCLMenu->GetItemCount() - 1 ) != 0 )
pVCLMenu->InsertSeparator();
break;
default: ;
}
}
}
catch ( const css::uno::Exception& )
{
break;
}
}
}
void ToolbarAsMenuController::updatePopupMenu()
throw ( css::uno::RuntimeException, std::exception )
{
VCLXMenu* pAwtMenu = VCLXMenu::GetImplementation( m_xPopupMenu );
Menu* pVCLMenu = pAwtMenu->GetMenu();
for ( sal_uInt16 i = 0; i < pVCLMenu->GetItemCount(); ++i )
{
const sal_uInt16 nItemId( pVCLMenu->GetItemId( i ) );
const OUString aCommandURL( pVCLMenu->GetItemCommand( nItemId ) );
if ( !aCommandURL.isEmpty() )
{
rtl::Reference< CommandStatusHelper > xHelper( new CommandStatusHelper( m_xContext, m_xFrame, aCommandURL ) );
xHelper->updateCommand();
pVCLMenu->EnableItem( nItemId, xHelper->isCommandEnabled() );
pVCLMenu->CheckItem( nItemId, xHelper->isCommandChecked() );
}
}
}
void ToolbarAsMenuController::disposing()
{
svt::PopupMenuControllerBase::disposing();
css::uno::Reference< css::ui::XUIConfiguration > xConfig( m_xConfigManager, css::uno::UNO_QUERY );
if ( xConfig.is() )
xConfig->removeConfigurationListener( this );
css::uno::Reference< css::ui::XUIConfiguration > xModuleConfig( m_xModuleConfigManager, css::uno::UNO_QUERY );
if ( xModuleConfig.is() )
xModuleConfig->removeConfigurationListener( this );
m_xConfigManager.clear();
m_xModuleConfigManager.clear();
}
void ToolbarAsMenuController::statusChanged( const css::frame::FeatureStateEvent& /*rEvent*/ )
throw ( css::uno::RuntimeException, std::exception )
{
}
void ToolbarAsMenuController::disposing( const css::lang::EventObject& rEvent )
throw ( css::uno::RuntimeException, std::exception )
{
if ( rEvent.Source == m_xConfigManager )
m_xConfigManager.clear();
else if ( rEvent.Source == m_xModuleConfigManager )
m_xModuleConfigManager.clear();
else
svt::PopupMenuControllerBase::disposing( rEvent );
}
void ToolbarAsMenuController::elementInserted( const css::ui::ConfigurationEvent& rEvent )
throw ( css::uno::RuntimeException, std::exception )
{
if ( rEvent.ResourceURL == m_aToolbarURL )
impl_setPopupMenu();
}
void ToolbarAsMenuController::elementRemoved( const css::ui::ConfigurationEvent& rEvent )
throw ( css::uno::RuntimeException, std::exception )
{
if ( rEvent.ResourceURL == m_aToolbarURL )
impl_setPopupMenu();
}
void ToolbarAsMenuController::elementReplaced( const css::ui::ConfigurationEvent& rEvent )
throw ( css::uno::RuntimeException, std::exception )
{
if ( rEvent.ResourceURL == m_aToolbarURL )
impl_setPopupMenu();
}
OUString ToolbarAsMenuController::getImplementationName()
throw ( css::uno::RuntimeException, std::exception )
{
return OUString( "com.sun.star.comp.framework.ToolbarAsMenuController" );
}
css::uno::Sequence< OUString > ToolbarAsMenuController::getSupportedServiceNames()
throw ( css::uno::RuntimeException, std::exception )
{
css::uno::Sequence< OUString > aRet { "com.sun.star.frame.PopupMenuController" };
return aRet;
}
}
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
com_sun_star_comp_framework_ToolbarAsMenuController_get_implementation(
css::uno::XComponentContext* xContext,
css::uno::Sequence< css::uno::Any > const & args )
{
return cppu::acquire( new framework::ToolbarAsMenuController( xContext, args ) );
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */