From 17b1ebbf86ceabe2e9cabf9626ca94fae3fb9216 Mon Sep 17 00:00:00 2001 From: Maxim Monastirsky Date: Sun, 30 Oct 2016 19:28:52 +0200 Subject: Allow using xml menus in DBTreeListBox Change-Id: I8dfab0ae5d64b416123ab5690b43cf2db77d92dc --- dbaccess/source/ui/control/dbtreelistbox.cxx | 69 ++++++++++++++++++++++------ dbaccess/source/ui/inc/dbtreelistbox.hxx | 6 ++- 2 files changed, 60 insertions(+), 15 deletions(-) diff --git a/dbaccess/source/ui/control/dbtreelistbox.cxx b/dbaccess/source/ui/control/dbtreelistbox.cxx index 6c0562a7cb84..2f6e2c753ed6 100644 --- a/dbaccess/source/ui/control/dbtreelistbox.cxx +++ b/dbaccess/source/ui/control/dbtreelistbox.cxx @@ -30,10 +30,13 @@ #include #include #include +#include +#include #include #include #include #include +#include #include #include #include "svtools/treelistentry.hxx" @@ -83,6 +86,7 @@ void DBTreeListBox::init() DBTreeListBox::~DBTreeListBox() { + assert(!m_xMenuController.is()); disposeOnce(); } @@ -555,12 +559,41 @@ VclPtr DBTreeListBox::CreateContextMenu() if ( !m_pContextMenuProvider ) return pContextMenu; - // the basic context menu - pContextMenu.reset( m_pContextMenuProvider->getContextMenu( *this ) ); - // disable what is not available currently - lcl_enableEntries( pContextMenu.get(), m_pContextMenuProvider->getCommandController() ); - // set images - lcl_insertMenuItemImages( *pContextMenu, m_pContextMenuProvider->getCommandController() ); + OUString aResourceName( m_pContextMenuProvider->getContextMenuResourceName( *this ) ); + OUString aMenuIdentifier; + + if ( aResourceName.isEmpty() ) + { + // the basic context menu + pContextMenu.reset( m_pContextMenuProvider->getContextMenu( *this ) ); + // disable what is not available currently + lcl_enableEntries( pContextMenu.get(), m_pContextMenuProvider->getCommandController() ); + // set images + lcl_insertMenuItemImages( *pContextMenu, m_pContextMenuProvider->getCommandController() ); + } + else + { + css::uno::Sequence< css::uno::Any > aArgs( 3 ); + aArgs[0] <<= comphelper::makePropertyValue( "Value", aResourceName ); + aArgs[1] <<= comphelper::makePropertyValue( "Frame", m_pContextMenuProvider->getCommandController().getXController()->getFrame() ); + aArgs[2] <<= comphelper::makePropertyValue( "IsContextMenu", true ); + + css::uno::Reference< css::uno::XComponentContext > xContext = comphelper::getProcessComponentContext(); + m_xMenuController.set( xContext->getServiceManager()->createInstanceWithArgumentsAndContext( + "com.sun.star.comp.framework.ResourceMenuController", aArgs, xContext ), css::uno::UNO_QUERY ); + + css::uno::Reference< css::awt::XPopupMenu > xPopupMenu( xContext->getServiceManager()->createInstanceWithContext( + "com.sun.star.awt.PopupMenu", xContext ), css::uno::UNO_QUERY ); + + if ( !m_xMenuController.is() || !xPopupMenu.is() ) + return pContextMenu; + + m_xMenuController->setPopupMenu( xPopupMenu ); + pContextMenu.reset( static_cast< PopupMenu* >( VCLXMenu::GetImplementation( xPopupMenu )->GetMenu() ) ); + pContextMenu->AddEventListener( LINK( this, DBTreeListBox, MenuEventListener ) ); + aMenuIdentifier = "private:resource/popupmenu/" + aResourceName; + } + // allow context menu interception ::comphelper::OInterfaceContainerHelper2* pInterceptors = m_pContextMenuProvider->getContextMenuInterceptors(); if ( !pInterceptors || !pInterceptors->getLength() ) @@ -571,7 +604,7 @@ VclPtr DBTreeListBox::CreateContextMenu() aEvent.ExecutePosition.X = -1; aEvent.ExecutePosition.Y = -1; aEvent.ActionTriggerContainer = ::framework::ActionTriggerHelper::CreateActionTriggerContainerFromMenu( - pContextMenu.get(), nullptr ); + pContextMenu.get(), &aMenuIdentifier ); aEvent.Selection = new SelectionSupplier( m_pContextMenuProvider->getCurrentSelection( *this ) ); ::comphelper::OInterfaceIteratorHelper2 aIter( *pInterceptors ); @@ -617,16 +650,15 @@ VclPtr DBTreeListBox::CreateContextMenu() if ( bModifiedMenu ) { - // the interceptor(s) modified the menu description => create a new PopupMenu - VclPtrInstance pModifiedMenu; + pContextMenu->Clear(); ::framework::ActionTriggerHelper::CreateMenuFromActionTriggerContainer( - pModifiedMenu, aEvent.ActionTriggerContainer ); + pContextMenu, aEvent.ActionTriggerContainer ); aEvent.ActionTriggerContainer.clear(); - pContextMenu.reset( pModifiedMenu ); // the interceptors only know command URLs, but our menus primarily work // with IDs -> we need to translate the commands to IDs - lcl_adjustMenuItemIDs( *pModifiedMenu, m_pContextMenuProvider->getCommandController() ); + if ( aResourceName.isEmpty() ) + lcl_adjustMenuItemIDs( *pContextMenu, m_pContextMenuProvider->getCommandController() ); } return pContextMenu; @@ -634,10 +666,21 @@ VclPtr DBTreeListBox::CreateContextMenu() void DBTreeListBox::ExecuteContextMenuAction( sal_uInt16 _nSelectedPopupEntry ) { - if ( m_pContextMenuProvider && _nSelectedPopupEntry ) + if ( !m_xMenuController.is() && m_pContextMenuProvider && _nSelectedPopupEntry ) m_pContextMenuProvider->getCommandController().executeChecked( _nSelectedPopupEntry, Sequence< PropertyValue >() ); } +IMPL_LINK( DBTreeListBox, MenuEventListener, VclMenuEvent&, rMenuEvent, void ) +{ + if ( rMenuEvent.GetId() == VCLEVENT_OBJECT_DYING ) + { + css::uno::Reference< css::lang::XComponent > xComponent( m_xMenuController, css::uno::UNO_QUERY ); + if ( xComponent.is() ) + xComponent->dispose(); + m_xMenuController.clear(); + } +} + IMPL_LINK_NOARG(DBTreeListBox, OnTimeOut, Timer*, void) { implStopSelectionTimer(); diff --git a/dbaccess/source/ui/inc/dbtreelistbox.hxx b/dbaccess/source/ui/inc/dbtreelistbox.hxx index 4c091dbe7b45..2c7aeb997007 100644 --- a/dbaccess/source/ui/inc/dbtreelistbox.hxx +++ b/dbaccess/source/ui/inc/dbtreelistbox.hxx @@ -22,6 +22,7 @@ #include "ScrollHelper.hxx" #include "moduledbu.hxx" +#include #include #include @@ -58,8 +59,8 @@ namespace dbaui std::set m_aSelectedEntries; SvTreeListEntry* m_pDragedEntry; IControlActionListener* m_pActionListener; - IContextMenuProvider* - m_pContextMenuProvider; + IContextMenuProvider* m_pContextMenuProvider; + css::uno::Reference m_xMenuController; Link m_aPreExpandHandler; // handler to be called before a node is expanded Link m_aSelChangeHdl; // handler to be called (asynchronously) when the selection changes in any way @@ -74,6 +75,7 @@ namespace dbaui DECL_LINK( OnResetEntry, void*, void ); DECL_LINK( ScrollUpHdl, LinkParamNone*, void ); DECL_LINK( ScrollDownHdl, LinkParamNone*, void ); + DECL_LINK( MenuEventListener, VclMenuEvent&, void ); public: DBTreeListBox( vcl::Window* pParent, WinBits nWinStyle=0); -- cgit v1.2.3