diff options
author | Maxim Monastirsky <momonasmon@gmail.com> | 2015-12-12 23:44:47 +0200 |
---|---|---|
committer | Ashod Nakashian <ashod.nakashian@collabora.co.uk> | 2016-07-12 22:06:30 -0400 |
commit | 8f0f2807a3305e3ddd85b222525ebb396900d31d (patch) | |
tree | 83410b694dd2745bd48106fcc8512f3bbcc9e3a1 /sfx2 | |
parent | 2b5d40153d8b5a0e19459db47befa6e0e31e5c38 (diff) |
tdf#93837 Adapt sfx2 to use xml based context menus
Change-Id: I71aaa98e9cf022b53cc094418bc09fb385af55ce
(cherry picked from commit bb2ead8b4bcf197403842cef16a61acdb3185755)
Diffstat (limited to 'sfx2')
-rw-r--r-- | sfx2/source/control/dispatch.cxx | 39 | ||||
-rw-r--r-- | sfx2/source/control/objface.cxx | 11 | ||||
-rw-r--r-- | sfx2/source/view/viewsh.cxx | 59 |
3 files changed, 108 insertions, 1 deletions
diff --git a/sfx2/source/control/dispatch.cxx b/sfx2/source/control/dispatch.cxx index 023b4cb4542c..e50f9abc3e05 100644 --- a/sfx2/source/control/dispatch.cxx +++ b/sfx2/source/control/dispatch.cxx @@ -29,8 +29,11 @@ #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/frame/XDispatchRecorderSupplier.hpp> #include <com/sun/star/frame/XLayoutManager.hpp> +#include <com/sun/star/frame/XPopupMenuController.hpp> #include <comphelper/lok.hxx> +#include <comphelper/processfactory.hxx> +#include <comphelper/propertyvalue.hxx> #include <rtl/strbuf.hxx> #include <sfx2/app.hxx> #include <sfx2/bindings.hxx> @@ -57,6 +60,8 @@ #include <svl/undo.hxx> #include <svl/whiter.hxx> #include <svtools/helpopt.hxx> +#include <toolkit/awt/vclxmenu.hxx> +#include <toolkit/helper/vclunohelper.hxx> #include <vcl/wrkwin.hxx> #include <vcl/idle.hxx> @@ -1881,12 +1886,44 @@ void SfxDispatcher::ExecutePopup( sal_uInt16 nConfigId, vcl::Window *pWin, const } vcl::Window *pWindow = pWin ? pWin : rDisp.xImp->pFrame->GetFrame().GetWorkWindow_Impl()->GetWindow(); + Point aPos = pPos ? *pPos : pWindow->GetPointerPosPixel(); for ( pSh = rDisp.GetShell(nShLevel); pSh; ++nShLevel, pSh = rDisp.GetShell(nShLevel) ) { const ResId& rResId = pSh->GetInterface()->GetPopupMenuResId(); + const OUString& rResName = pSh->GetInterface()->GetPopupMenuName(); if ( ( nConfigId == 0 && rResId.GetId() ) || ( nConfigId != 0 && rResId.GetId() == nConfigId ) ) { - SfxPopupMenuManager::ExecutePopup( rResId, rDisp.GetFrame(), pPos ? *pPos : pWindow->GetPointerPosPixel(), pWindow ); + SfxPopupMenuManager::ExecutePopup( rResId, rDisp.GetFrame(), aPos, pWindow ); + return; + } + else if ( nConfigId == 0 && !rResName.isEmpty() ) + { + css::uno::Sequence< css::uno::Any > aArgs( 3 ); + aArgs[0] <<= comphelper::makePropertyValue( "Value", rResName ); + aArgs[1] <<= comphelper::makePropertyValue( "Frame", rDisp.GetFrame()->GetFrame().GetFrameInterface() ); + aArgs[2] <<= comphelper::makePropertyValue( "IsContextMenu", true ); + + css::uno::Reference< css::uno::XComponentContext > xContext = comphelper::getProcessComponentContext(); + css::uno::Reference< css::frame::XPopupMenuController > xPopupController( + 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 ( !xPopupController.is() || !xPopupMenu.is() ) + continue; + + css::ui::ContextMenuExecuteEvent aEvent; + aEvent.SourceWindow = VCLUnoHelper::GetInterface( pWindow ); + aEvent.ExecutePosition.X = aPos.X(); + aEvent.ExecutePosition.Y = aPos.Y(); + + xPopupController->setPopupMenu( xPopupMenu ); + VCLXMenu* pAwtMenu = VCLXMenu::GetImplementation( xPopupMenu ); + PopupMenu* pVCLMenu = static_cast< PopupMenu* >( pAwtMenu->GetMenu() ); + if ( pVCLMenu && rDisp.GetFrame()->GetViewShell()->TryContextMenuInterception( *pVCLMenu, rResName, aEvent ) ) + pVCLMenu->Execute( pWindow, aPos ); return; } } diff --git a/sfx2/source/control/objface.cxx b/sfx2/source/control/objface.cxx index 09132cfb94af..58a3b6e3d388 100644 --- a/sfx2/source/control/objface.cxx +++ b/sfx2/source/control/objface.cxx @@ -77,6 +77,7 @@ struct SfxInterface_Impl { SfxObjectUIArr_Impl aObjectBars; // registered ObjectBars SfxObjectUIArr_Impl aChildWindows; // registered ChildWindows + OUString aPopupName; // registered xml-based PopupMenu ResId aPopupRes; // registered PopupMenu ResId aStatBarRes; // registered StatusBar SfxModule* pModule; @@ -368,6 +369,11 @@ void SfxInterface::RegisterPopupMenu( const ResId& rResId ) pImpData->aPopupRes = rResId; } +void SfxInterface::RegisterPopupMenu( const OUString& rResourceName ) +{ + pImpData->aPopupName = rResourceName; +} + void SfxInterface::RegisterObjectBar(sal_uInt16 nPos, sal_uInt32 nResId) { RegisterObjectBar(nPos, nResId, 0UL); @@ -504,6 +510,11 @@ const ResId& SfxInterface::GetPopupMenuResId() const return pImpData->aPopupRes; } +const OUString& SfxInterface::GetPopupMenuName() const +{ + return pImpData->aPopupName; +} + const ResId& SfxInterface::GetStatusBarResId() const { if (pImpData->aStatBarRes.GetId() == 0 && pGenoType) diff --git a/sfx2/source/view/viewsh.cxx b/sfx2/source/view/viewsh.cxx index 6896abe02dba..ae34ef5dc12f 100644 --- a/sfx2/source/view/viewsh.cxx +++ b/sfx2/source/view/viewsh.cxx @@ -1958,6 +1958,65 @@ bool SfxViewShell::TryContextMenuInterception( Menu& rIn, const OUString& rMenuI return true; } +bool SfxViewShell::TryContextMenuInterception( Menu& rMenu, const OUString& rMenuIdentifier, css::ui::ContextMenuExecuteEvent aEvent ) +{ + bool bModified = false; + + // create container from menu + aEvent.ActionTriggerContainer = ::framework::ActionTriggerHelper::CreateActionTriggerContainerFromMenu( &rMenu, &rMenuIdentifier ); + + // get selection from controller + aEvent.Selection = css::uno::Reference< css::view::XSelectionSupplier >( GetController(), css::uno::UNO_QUERY ); + + // call interceptors + ::cppu::OInterfaceIteratorHelper aIt( pImp->aInterceptorContainer ); + while( aIt.hasMoreElements() ) + { + try + { + css::ui::ContextMenuInterceptorAction eAction; + { + SolarMutexReleaser rel; + eAction = static_cast< css::ui::XContextMenuInterceptor* >( aIt.next() )->notifyContextMenuExecute( aEvent ); + } + switch ( eAction ) + { + case css::ui::ContextMenuInterceptorAction_CANCELLED: + // interceptor does not want execution + return false; + case css::ui::ContextMenuInterceptorAction_EXECUTE_MODIFIED: + // interceptor wants his modified menu to be executed + bModified = true; + break; + case css::ui::ContextMenuInterceptorAction_CONTINUE_MODIFIED: + // interceptor has modified menu, but allows for calling other interceptors + bModified = true; + continue; + case css::ui::ContextMenuInterceptorAction_IGNORED: + // interceptor is indifferent + continue; + default: + SAL_WARN( "sfx.view", "Wrong return value of ContextMenuInterceptor!" ); + continue; + } + } + catch (...) + { + aIt.remove(); + } + + break; + } + + if ( bModified ) + { + rMenu.Clear(); + ::framework::ActionTriggerHelper::CreateMenuFromActionTriggerContainer( &rMenu, aEvent.ActionTriggerContainer ); + } + + return true; +} + void SfxViewShell::TakeOwnership_Impl() { // currently there is only one reason to take Ownership: a hidden frame is printed |