summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxim Monastirsky <momonasmon@gmail.com>2015-12-12 23:44:47 +0200
committerMaxim Monastirsky <momonasmon@gmail.com>2015-12-13 09:12:23 +0200
commitbb2ead8b4bcf197403842cef16a61acdb3185755 (patch)
tree564215cf2d04c02e5216fc46f55ba13fb90a58ab
parentbf18145d3ff9ec731bc6caa9797e76bfb71a6c1a (diff)
tdf#93837 Adapt sfx2 to use xml based context menus
Change-Id: I71aaa98e9cf022b53cc094418bc09fb385af55ce
-rw-r--r--include/sfx2/objface.hxx2
-rw-r--r--include/sfx2/viewsh.hxx1
-rw-r--r--sfx2/source/control/dispatch.cxx39
-rw-r--r--sfx2/source/control/objface.cxx11
-rw-r--r--sfx2/source/view/viewsh.cxx59
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