Tag: cws_dev300_dba30d
User: fs      
Date: 2008-06-01 20:58:34+0000
Modified:
   dba/dbaccess/source/ui/control/dbtreelistbox.cxx

Log:
 #i80943# use the IContextMenuProvider for context menu interception

File Changes:

Directory: /dba/dbaccess/source/ui/control/
===========================================

File [changed]: dbtreelistbox.cxx
Url: 
http://dba.openoffice.org/source/browse/dba/dbaccess/source/ui/control/dbtreelistbox.cxx?r1=1.19.30.1&r2=1.19.30.2
Delta lines:  +169 -6
---------------------
--- dbtreelistbox.cxx   2008-05-29 11:27:40+0000        1.19.30.1
+++ dbtreelistbox.cxx   2008-06-01 20:58:31+0000        1.19.30.2
@@ -7,7 +7,7 @@
  * OpenOffice.org - a multi-platform office productivity suite
  *
  * $RCSfile: dbtreelistbox.cxx,v $
- * $Revision: 1.19.30.1 $
+ * $Revision: 1.19.30.2 $
  *
  * This file is part of OpenOffice.org.
  *
@@ -53,12 +53,18 @@
 #ifndef _COM_SUN_STAR_DATATRANSFER_DND_XDRAGGESTURERECOGNIZER_HPP_ 
 #include <com/sun/star/datatransfer/dnd/XDragGestureRecognizer.hpp>
 #endif
+#ifndef _COM_SUN_STAR_UI_XCONTEXTMENUINTERCEPTOR_HPP_
+#include <com/sun/star/ui/XContextMenuInterceptor.hpp>
+#endif
 #ifndef _COM_SUN_STAR_UTIL_URL_HPP_
 #include <com/sun/star/util/URL.hpp>
 #endif
 #ifndef _CPPUHELPER_IMPLBASE1_HXX_
 #include <cppuhelper/implbase1.hxx>
 #endif
+#ifndef _CPPUHELPER_INTERFACECONTAINER_HXX_
+#include <cppuhelper/interfacecontainer.hxx>
+#endif
 #ifndef _SV_HELP_HXX
 #include <vcl/help.hxx>
 #endif
@@ -68,8 +74,14 @@
 #ifndef DBAUI_ICONTROLLER_HXX
 #include "IController.hxx"
 #endif
-#include <memory>
+#ifndef __FRAMEWORK_HELPER_ACTIONTRIGGERHELPER_HXX_
+#include <framework/actiontriggerhelper.hxx>
+#endif
+#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
+#include <toolkit/helper/vclunohelper.hxx>
+#endif
 
+#include <memory>
 
 // .........................................................................
 namespace dbaui
@@ -80,6 +92,9 @@
 using namespace ::com::sun::star::beans;
 using namespace ::com::sun::star::lang;
 using namespace ::com::sun::star::datatransfer;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::ui;
+using namespace ::com::sun::star::view;
 
 DBG_NAME(DBTreeListBox)
 #define SPACEBETWEENENTRIES            4
@@ -540,15 +555,163 @@
 }
 
 // 
-----------------------------------------------------------------------------
+namespace
+{
+    void lcl_adjustMenuItemIDs( Menu& _rMenu, IController& _rCommandController 
)
+    {
+           USHORT nCount = _rMenu.GetItemCount();
+           for ( USHORT pos = 0; pos < nCount; ++pos )
+           {
+                   USHORT nId = _rMenu.GetItemId(pos);
+                       String aCommand = _rMenu.GetItemCommand( nId );
+                   PopupMenu* pPopup = _rMenu.GetPopupMenu( nId );
+                   if ( pPopup )
+                   {
+                           lcl_adjustMenuItemIDs( *pPopup, _rCommandController 
);
+                continue;
+                   }
+
+            USHORT nCommandId = _rCommandController.registerCommandURL( 
aCommand );
+                   _rMenu.InsertItem( nCommandId, _rMenu.GetItemText( nId ), 
_rMenu.GetItemBits( nId ), pos );
+                   _rMenu.RemoveItem( pos+1 );
+           }
+    }
+    // 
=========================================================================
+    // = SelectionSupplier
+    // 
=========================================================================
+    typedef ::cppu::WeakImplHelper1 <   XSelectionSupplier
+                                    >   SelectionSupplier_Base;
+    class SelectionSupplier : public SelectionSupplier_Base
+    {
+    public:
+        SelectionSupplier( const Any& _rSelection )
+            :m_aSelection( _rSelection )
+        {
+        }
+
+        virtual ::sal_Bool SAL_CALL select( const Any& xSelection ) throw 
(IllegalArgumentException, RuntimeException);
+        virtual Any SAL_CALL getSelection(  ) throw (RuntimeException);
+        virtual void SAL_CALL addSelectionChangeListener( const Reference< 
XSelectionChangeListener >& xListener ) throw (RuntimeException);
+        virtual void SAL_CALL removeSelectionChangeListener( const Reference< 
XSelectionChangeListener >& xListener ) throw (RuntimeException);
+
+    protected:
+        virtual ~SelectionSupplier()
+        {
+        }
+
+    private:
+        Any m_aSelection;
+    };
+
+    //--------------------------------------------------------------------
+    ::sal_Bool SAL_CALL SelectionSupplier::select( const Any& /*_Selection*/ ) 
throw (IllegalArgumentException, RuntimeException)
+    {
+        throw IllegalArgumentException();
+        // API bug: this should be a NoSupportException
+    }
+    
+    //--------------------------------------------------------------------
+    Any SAL_CALL SelectionSupplier::getSelection(  ) throw (RuntimeException)
+    {
+        return m_aSelection;
+    }
+    
+    //--------------------------------------------------------------------
+    void SAL_CALL SelectionSupplier::addSelectionChangeListener( const 
Reference< XSelectionChangeListener >& /*_Listener*/ ) throw (RuntimeException)
+    {
+        OSL_ENSURE( false, "SelectionSupplier::removeSelectionChangeListener: 
no support!" );
+        // API bug: this should be a NoSupportException
+    }
+    
+    //--------------------------------------------------------------------
+    void SAL_CALL SelectionSupplier::removeSelectionChangeListener( const 
Reference< XSelectionChangeListener >& /*_Listener*/ ) throw (RuntimeException)
+    {
+        OSL_ENSURE( false, "SelectionSupplier::removeSelectionChangeListener: 
no support!" );
+        // API bug: this should be a NoSupportException
+    }
+}
+
+// 
-----------------------------------------------------------------------------
 PopupMenu* DBTreeListBox::CreateContextMenu( void )
 {
-       PopupMenu* pContextMenu = NULL;
+    ::std::auto_ptr< PopupMenu > pContextMenu;
+
        if ( m_pContextMenuProvider )
        {
-               pContextMenu = m_pContextMenuProvider->getContextMenu( *this );
-               lcl_enableEntries( pContextMenu, 
m_pContextMenuProvider->getCommandController() );
+        // the basic context menu
+               pContextMenu.reset( m_pContextMenuProvider->getContextMenu( 
*this ) );
+        // disable what is not available currently
+               lcl_enableEntries( pContextMenu.get(), 
m_pContextMenuProvider->getCommandController() );
+        // allow context menu interception
+        ::cppu::OInterfaceContainerHelper* pInterceptors = 
m_pContextMenuProvider->getContextMenuInterceptors();
+        if ( pInterceptors )
+        {
+            ContextMenuExecuteEvent aEvent;
+            aEvent.SourceWindow = VCLUnoHelper::GetInterface( this );
+            // TODO: obtain this from the base class
+            aEvent.ExecutePosition.X = -1;
+            aEvent.ExecutePosition.Y = -1;
+            aEvent.ActionTriggerContainer = 
::framework::ActionTriggerHelper::CreateActionTriggerContainerFromMenu(
+                m_xORB, pContextMenu.get() );
+            aEvent.Selection = new SelectionSupplier( 
m_pContextMenuProvider->getCurrentSelection( *this ) );
+
+            ::cppu::OInterfaceIteratorHelper aIter( *pInterceptors );
+            bool bModifiedMenu = false;
+            bool bAskInterceptors = true;
+            while ( aIter.hasMoreElements() && bAskInterceptors )
+            {
+                Reference< XContextMenuInterceptor > xInterceptor( 
aIter.next(), UNO_QUERY );
+                if ( !xInterceptor.is() )
+                    continue;
+
+                try
+                {
+                    ContextMenuInterceptorAction eAction = 
xInterceptor->notifyContextMenuExecute( aEvent );
+                    switch ( eAction )
+                    {
+                        case ContextMenuInterceptorAction_CANCELLED:
+                            return NULL;
+
+                        case ContextMenuInterceptorAction_EXECUTE_MODIFIED:
+                            bModifiedMenu = true;
+                            bAskInterceptors = false;
+                            break;
+
+                        case ContextMenuInterceptorAction_CONTINUE_MODIFIED:
+                            bModifiedMenu = true;
+                            bAskInterceptors = true;
+                            break;
+
+                        default:
+                            DBG_ERROR( "DBTreeListBox::CreateContextMenu: 
unexpected return value of the interceptor call!" );
+
+                        case ContextMenuInterceptorAction_IGNORED:
+                            break;
+                    }
+                }
+                catch( const DisposedException& e )
+                {
+                    if ( e.Context == xInterceptor )
+                        aIter.remove();
+                }
+            }
+
+            if ( bModifiedMenu )
+            {
+                // the interceptor(s) modified the menu description => create 
a new PopupMenu
+                PopupMenu* pModifiedMenu = new PopupMenu;
+                
::framework::ActionTriggerHelper::CreateMenuFromActionTriggerContainer(
+                    pModifiedMenu, 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() );
+            }
+        }
        }
-       return pContextMenu;
+       return pContextMenu.release();
 }
 
 // 
-----------------------------------------------------------------------------




---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to