diff options
author | Maxim Monastirsky <momonasmon@gmail.com> | 2015-12-12 23:44:47 +0200 |
---|---|---|
committer | Maxim Monastirsky <momonasmon@gmail.com> | 2015-12-13 09:12:23 +0200 |
commit | bb2ead8b4bcf197403842cef16a61acdb3185755 (patch) | |
tree | 564215cf2d04c02e5216fc46f55ba13fb90a58ab | |
parent | bf18145d3ff9ec731bc6caa9797e76bfb71a6c1a (diff) |
tdf#93837 Adapt sfx2 to use xml based context menus
Change-Id: I71aaa98e9cf022b53cc094418bc09fb385af55ce
-rw-r--r-- | include/sfx2/objface.hxx | 2 | ||||
-rw-r--r-- | include/sfx2/viewsh.hxx | 1 | ||||
-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 |
5 files changed, 111 insertions, 1 deletions
diff --git a/include/sfx2/objface.hxx b/include/sfx2/objface.hxx index d7c1b764d04a..22b28a37304c 100644 --- a/include/sfx2/objface.hxx +++ b/include/sfx2/objface.hxx @@ -80,7 +80,9 @@ public: sal_uInt32 GetChildWindowId( sal_uInt16 nNo ) const; sal_uInt16 GetChildWindowCount() const; void RegisterPopupMenu( const ResId& ); + void RegisterPopupMenu( const OUString& ); const ResId& GetPopupMenuResId() const; + const OUString& GetPopupMenuName() const; const ResId& GetStatusBarResId() const; void Register( SfxModule* ); diff --git a/include/sfx2/viewsh.hxx b/include/sfx2/viewsh.hxx index b3331964229d..f19d66a36420 100644 --- a/include/sfx2/viewsh.hxx +++ b/include/sfx2/viewsh.hxx @@ -284,6 +284,7 @@ public: GetController(); bool TryContextMenuInterception( Menu& rIn, const OUString& rMenuIdentifier, Menu*& rpOut, css::ui::ContextMenuExecuteEvent aEvent ); + bool TryContextMenuInterception( Menu& rMenu, const OUString& rMenuIdentifier, css::ui::ContextMenuExecuteEvent aEvent ); void ExecPrint( const css::uno::Sequence < css::beans::PropertyValue >&, bool, bool ); // Like ExecPrint(), but only sets up for printing. Use Printer::ExecutePrintJob() and Printer::FinishPrintJob() afterwards. 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 4794ff167f48..cd51b0a303b9 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; @@ -372,6 +373,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); @@ -510,6 +516,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 e4c14a24e857..392f68d347d2 100644 --- a/sfx2/source/view/viewsh.cxx +++ b/sfx2/source/view/viewsh.cxx @@ -2000,6 +2000,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 |