Hi Ariel,

forgot one thing:

> **********************************************************************
> **********************************************************************
> 
> com.sun.star.view.XSelectionSupplier
> ...
> * an issue that was present in the previous impl. and was solved there
> but comes back now is that there is no notification for the icon choice
> ctrl. selection on the app. swap window
> (http://www.openoffice.org/issues/show_bug.cgi?id=69740)

Cannot reproduce this in DEV300m29 - creating a XSelectionChangeListener
in Basic, and adding it to a DBDoc's controller, gives me notifications
both when the tree view selection and when the "category" selection changes.

Could you please verify your findings?

Thanks & Ciao
Frank

PS: attached is the patch I committed to CWS dba31b, to fix the problems
you found - just in case you want to give it another try.

-- 
Frank Schönheit                         StarOffice/OpenOffice.org Base
[EMAIL PROTECTED]                    +49 40 23 646 663 / +66663
Sun Microsystems Germany                         Hamburg, Nagelsweg 55
----------------------------------------------------------------------
? DBAppController.patch
? wntmsci12
Index: inc/genericcontroller.hxx
===================================================================
RCS file: /cvs/dba/dbaccess/inc/genericcontroller.hxx,v
retrieving revision 1.13
retrieving revision 1.13.24.1
diff -u -u -u -r1.13 -r1.13.24.1
--- inc/genericcontroller.hxx	25 Jun 2008 14:51:16 -0000	1.13
+++ inc/genericcontroller.hxx	4 Aug 2008 07:23:26 -0000	1.13.24.1
@@ -77,7 +77,7 @@
 	// ====================================================================
 	// = optional
 	// ====================================================================
-    /** convenience wrapper around boost::optional, allowing type assignments
+    /** convenience wrapper around boost::optional, allowing typed assignments
     */
     template < typename T >
     class optional : public ::boost::optional< T >
@@ -134,21 +134,20 @@
 	// = helper
 	// ====================================================================
 
-	// --------------------------------------------------------------------
 	// ....................................................................
     struct ControllerFeature : public ::com::sun::star::frame::DispatchInformation
     {
         sal_uInt16 nFeatureId;
     };
 
+	// ....................................................................
     typedef ::std::map  <   ::rtl::OUString
                         ,   ControllerFeature
                         ,   ::std::less< ::rtl::OUString >
                         >   SupportedFeatures;
 
-	/// binary_function Functor object for class SupportedFeatures::value_type returntype is bool
 	// ....................................................................
-	struct SupportedFeaturesEqualId : ::std::binary_function< SupportedFeatures::value_type, sal_Int32, bool >
+	struct CompareFeatureById : ::std::binary_function< SupportedFeatures::value_type, sal_Int32, bool >
 	{
 		// ................................................................
 		inline bool operator()( const SupportedFeatures::value_type& _aType, const sal_Int32& _nId ) const
@@ -157,30 +156,29 @@
 		}
 	};
 
-	// --------------------------------------------------------------------
 	// ....................................................................
-	typedef struct FeatureStruct
+	struct FeatureListener
 	{
 		::com::sun::star::uno::Reference< ::com::sun::star::frame::XStatusListener >
 					xListener;
 		sal_Int32	nId;
 		sal_Bool	bForceBroadcast;
-	} FeaturePair;
+	};
 
 	// ....................................................................
-	typedef ::std::deque< FeaturePair > FeaturePairDeque;
+	typedef ::std::deque< FeatureListener > FeatureListeners;
 
-	/// binary_function Functor object for class FeaturePair returntype is bool
 	// ....................................................................
-	struct FeaturePairFunctor : ::std::binary_function< FeaturePair, ::com::sun::star::uno::Reference< ::com::sun::star::frame::XStatusListener >, bool >
+	struct FindFeatureListener : ::std::binary_function< FeatureListener, ::com::sun::star::uno::Reference< ::com::sun::star::frame::XStatusListener >, bool >
 	{
 		// ................................................................
-		inline bool operator()( const FeaturePair& lhs, const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XStatusListener >& rhs ) const
+		inline bool operator()( const FeatureListener& lhs, const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XStatusListener >& rhs ) const
 		{
 			return !!( lhs.xListener == rhs );
 		}
 	};
 
+	// ....................................................................
 	typedef ::comphelper::OBaseMutex	OGenericUnoController_MBASE;
 
     typedef ::cppu::WeakComponentImplHelper11   <   ::com::sun::star::frame::XDispatch
@@ -230,7 +228,7 @@
 		DECLARE_STL_MAP( sal_uInt16, FeatureState, ::std::less< sal_uInt16 >, StateCache );
 		DECLARE_STL_VECTOR( DispatchTarget, Dispatch);
 
-		FeaturePairDeque m_aFeaturesToInvalidate;
+		FeatureListeners        m_aFeaturesToInvalidate;
 
 		::osl::Mutex			m_aFeatureMutex;		// locked when features are append to or remove from deque
 		StateCache				m_aStateCache;			// save the current status of feature state
@@ -339,7 +337,13 @@
 
             @see IController::registerCommandURL
         */
-        bool    isUserDefinedFeature( const sal_uInt16 nFeatureId );
+        bool    isUserDefinedFeature( const sal_uInt16 nFeatureId ) const;
+
+        /** determines whether the given feature URL denotes a user-defined feature
+
+            @see IController::registerCommandURL
+        */
+        bool    isUserDefinedFeature( const ::rtl::OUString& _rFeatureURL ) const;
 
 		// connect to a datasource
 		::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > connect(
Index: source/ui/app/AppController.cxx
===================================================================
RCS file: /cvs/dba/dbaccess/source/ui/app/AppController.cxx,v
retrieving revision 1.63
retrieving revision 1.63.20.1
diff -u -u -u -r1.63 -r1.63.20.1
--- source/ui/app/AppController.cxx	25 Jun 2008 12:35:22 -0000	1.63
+++ source/ui/app/AppController.cxx	4 Aug 2008 07:24:15 -0000	1.63.20.1
@@ -3029,7 +3029,9 @@
     ::osl::MutexGuard aGuard(m_aMutex);
 
     Sequence< NamedDatabaseObject > aCurrentSelection;
-    getContainer()->describeCurrentSelectionForType( getContainer()->getElementType(), aCurrentSelection );
+    const ElementType eType( getContainer()->getElementType() );
+    if ( eType != E_NONE )
+        getContainer()->describeCurrentSelectionForType( eType, aCurrentSelection );
     return makeAny( aCurrentSelection );
 }
 // -----------------------------------------------------------------------------
Index: source/ui/app/AppDetailPageHelper.cxx
===================================================================
RCS file: /cvs/dba/dbaccess/source/ui/app/AppDetailPageHelper.cxx,v
retrieving revision 1.33
retrieving revision 1.33.24.1
diff -u -u -u -r1.33 -r1.33.24.1
--- source/ui/app/AppDetailPageHelper.cxx	25 Jun 2008 12:36:31 -0000	1.33
+++ source/ui/app/AppDetailPageHelper.cxx	4 Aug 2008 07:24:15 -0000	1.33.24.1
@@ -473,7 +473,7 @@
 void OAppDetailPageHelper::describeCurrentSelectionForType( const ElementType _eType, Sequence< NamedDatabaseObject >& _out_rSelectedObjects )
 {
     OSL_ENSURE( _eType < E_ELEMENT_TYPE_COUNT, "OAppDetailPageHelper::describeCurrentSelectionForType: invalid type!" );
-    DBTreeListBox* pList = m_pLists[ _eType ];
+    DBTreeListBox* pList = ( _eType < E_ELEMENT_TYPE_COUNT ) ? m_pLists[ _eType ] : NULL;
     OSL_ENSURE( pList, "OAppDetailPageHelper::describeCurrentSelectionForType: "
                        "You really should ensure this type has already been viewed before!" );
     if ( !pList )
Index: source/ui/browser/genericcontroller.cxx
===================================================================
RCS file: /cvs/dba/dbaccess/source/ui/browser/genericcontroller.cxx,v
retrieving revision 1.94
retrieving revision 1.94.24.1
diff -u -u -u -r1.94 -r1.94.24.1
--- source/ui/browser/genericcontroller.cxx	26 Jun 2008 11:43:10 -0000	1.94
+++ source/ui/browser/genericcontroller.cxx	4 Aug 2008 07:25:59 -0000	1.94.24.1
@@ -170,14 +170,76 @@
 {
 
 //==========================================================================
+//= UserDefinedFeatures
+//==========================================================================
+class UserDefinedFeatures
+{
+public:
+    UserDefinedFeatures( const Reference< XController >& _rxController );
+
+    FeatureState    getState( const URL& _rFeatureURL );
+    void            execute( const URL& _rFeatureURL, const Sequence< PropertyValue>& _rArgs );
+
+private:
+    ::com::sun::star::uno::WeakReference< XController > m_aController;
+};
+
+//--------------------------------------------------------------------------
+UserDefinedFeatures::UserDefinedFeatures( const Reference< XController >& _rxController )
+    :m_aController( _rxController )
+{
+}
+
+//--------------------------------------------------------------------------
+FeatureState UserDefinedFeatures::getState( const URL& /*_rFeatureURL*/ )
+{
+    // for now, enable all the time
+    // TODO: we should ask the dispatcher. However, this is laborious, since you cannot ask a dispatcher
+    // directly, but need to add a status listener.
+    FeatureState aState;
+    aState.bEnabled = sal_True;
+    return aState;
+}
+
+//--------------------------------------------------------------------------
+void UserDefinedFeatures::execute( const URL& _rFeatureURL, const Sequence< PropertyValue>& _rArgs )
+{
+    try
+    {
+        Reference< XController > xController( (Reference< XController >)m_aController, UNO_SET_THROW );
+        Reference< XDispatchProvider > xDispatchProvider( xController->getFrame(), UNO_QUERY_THROW );
+        Reference< XDispatch > xDispatch( xDispatchProvider->queryDispatch(
+            _rFeatureURL,
+            ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_self" ) ),
+            FrameSearchFlag::AUTO
+        ) );
+
+        if ( xDispatch == xController )
+        {
+            OSL_ENSURE( false, "UserDefinedFeatures::execute: the controller shouldn't be the dispatcher here!" );
+            xDispatch.clear();
+        }
+
+        if ( xDispatch.is() )
+            xDispatch->dispatch( _rFeatureURL, _rArgs );
+    }
+    catch( const Exception& )
+    {
+    	DBG_UNHANDLED_EXCEPTION();
+    }
+}
+
+//==========================================================================
 //= OGenericUnoController_Data
 //==========================================================================
 struct OGenericUnoController_Data
 {
     ::sfx2::UserInputInterception   m_aUserInputInterception;
+    UserDefinedFeatures             m_aUserDefinedFeatures;
 
     OGenericUnoController_Data( OGenericUnoController& _rController, ::osl::Mutex& _rMutex )
         :m_aUserInputInterception( _rController, _rMutex )
+        ,m_aUserDefinedFeatures( _rController.getXController() )
     {
     }
 };
@@ -189,7 +251,6 @@
 // -------------------------------------------------------------------------
 OGenericUnoController::OGenericUnoController(const Reference< XMultiServiceFactory >& _rM)
 	:OGenericUnoController_Base(m_aMutex)
-    ,m_pData( new OGenericUnoController_Data( *this, m_aMutex ) )
 #ifdef DBG_UTIL
     ,m_bDescribingSupportedFeatures( false )
 #endif
@@ -203,6 +264,12 @@
 	,m_bCurrentlyModified(sal_False)
     ,m_bExternalTitle(sal_False)
 {
+    osl_incrementInterlockedCount( &m_refCount );
+    {
+        m_pData.reset( new OGenericUnoController_Data( *this, m_aMutex ) );
+    }
+    osl_decrementInterlockedCount( &m_refCount );
+
     DBG_CTOR(OGenericUnoController,NULL);
 
 	try
@@ -218,7 +285,6 @@
 // -----------------------------------------------------------------------------
 OGenericUnoController::OGenericUnoController()
 	:OGenericUnoController_Base(m_aMutex)
-    ,m_pData( new OGenericUnoController_Data( *this, m_aMutex ) )
 #ifdef DBG_UTIL
     ,m_bDescribingSupportedFeatures( false )
 #endif
@@ -559,7 +625,7 @@
 	SupportedFeatures::iterator aFeaturePos = ::std::find_if(
 		m_aSupportedFeatures.begin(),
 		m_aSupportedFeatures.end(),
-		::std::bind2nd( SupportedFeaturesEqualId(), _nId )
+		::std::bind2nd( CompareFeatureById(), _nId )
 	);
 
     return ( m_aSupportedFeatures.end() != aFeaturePos && aFeaturePos->first.getLength());
@@ -580,7 +646,7 @@
 #endif
 
 	sal_Bool bEmpty = sal_True;
-	FeaturePair aNextFeature;
+	FeatureListener aNextFeature;
 	{
 		::osl::MutexGuard aGuard( m_aFeatureMutex);
 		bEmpty = m_aFeaturesToInvalidate.empty();
@@ -599,7 +665,7 @@
 			SupportedFeatures::iterator aFeaturePos = ::std::find_if(
 				m_aSupportedFeatures.begin(),
 				m_aSupportedFeatures.end(),
-				::std::bind2nd( SupportedFeaturesEqualId(), aNextFeature.nId )
+				::std::bind2nd( CompareFeatureById(), aNextFeature.nId )
 			);
 
 #if OSL_DEBUG_LEVEL > 0
@@ -631,16 +697,16 @@
 // -----------------------------------------------------------------------
 void OGenericUnoController::ImplInvalidateFeature( sal_Int32 _nId, const Reference< XStatusListener >& _xListener, sal_Bool _bForceBroadcast )
 {
-	FeaturePair aPair;
-	aPair.nId				= _nId;
-	aPair.xListener 		= _xListener;
-	aPair.bForceBroadcast	= _bForceBroadcast;
+	FeatureListener aListener;
+	aListener.nId               = _nId;
+	aListener.xListener         = _xListener;
+	aListener.bForceBroadcast   = _bForceBroadcast;
 
 	sal_Bool bWasEmpty;
 	{
-		::osl::MutexGuard aGuard( m_aFeatureMutex);
+		::osl::MutexGuard aGuard( m_aFeatureMutex );
 		bWasEmpty = m_aFeaturesToInvalidate.empty();
-		m_aFeaturesToInvalidate.push_back(aPair);
+		m_aFeaturesToInvalidate.push_back( aListener );
 	}
 
 	if ( bWasEmpty )
@@ -690,9 +756,11 @@
         fillSupportedFeatures();
 
 	// URL's we can handle ourself?
-	if	(	aURL.Complete.equals( getConfirmDeletionURL() )
-		||	( m_aSupportedFeatures.find( aURL.Complete ) != m_aSupportedFeatures.end() )
-		)
+	if  (   aURL.Complete.equals( getConfirmDeletionURL() )
+        ||  (   ( m_aSupportedFeatures.find( aURL.Complete ) != m_aSupportedFeatures.end() )
+            &&  !isUserDefinedFeature( aURL.Complete )
+            )
+        )
 	{
 		xReturn = this;
 	}
@@ -825,11 +893,11 @@
 	}
 
 	// now remove the listener from the deque
-	::osl::MutexGuard aGuard( m_aFeatureMutex);
+	::osl::MutexGuard aGuard( m_aFeatureMutex );
 	m_aFeaturesToInvalidate.erase(
 		::std::remove_if(	m_aFeaturesToInvalidate.begin(),
 							m_aFeaturesToInvalidate.end(),
-							::std::bind2nd(FeaturePairFunctor(),aListener))
+							::std::bind2nd(FindFeatureListener(),aListener))
 		,m_aFeaturesToInvalidate.end());
 }
 
@@ -932,24 +1000,20 @@
 }
 
 //------------------------------------------------------------------------------
-FeatureState OGenericUnoController::GetState(sal_uInt16 nId) const
+FeatureState OGenericUnoController::GetState( sal_uInt16 _nId ) const
 {
 	FeatureState aReturn;
 		// (disabled automatically)
 
-	try
-	{
-		switch (nId)
-		{
-			case ID_BROWSER_UNDO:
-			case ID_BROWSER_SAVEDOC:
-				aReturn.bEnabled = sal_True;
-				break;
-		}
-	}
-	catch( const Exception& )
+	switch ( _nId )
 	{
-        DBG_UNHANDLED_EXCEPTION();
+		case ID_BROWSER_UNDO:
+		case ID_BROWSER_SAVEDOC:
+			aReturn.bEnabled = sal_True;
+			break;
+        default:
+            aReturn = m_pData->m_aUserDefinedFeatures.getState( getURLForId( _nId ) );
+            break;
 	}
 
 	return aReturn;
@@ -960,27 +1024,10 @@
 {
     OSL_ENSURE( isUserDefinedFeature( _nId ),
         "OGenericUnoController::Execute: responsible for user defined features only!" );
-    URL aFeatureURL( getURLForId( _nId ) );
-
-    // user defined features can be handled by dispatch interceptors only. So, we need to do
-    // a queryDispatch, and dispatch the URL
-    try
-    {
-        Reference< XDispatch > xDispatch( queryDispatch(
-            aFeatureURL,
-            ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_self" ) ),
-            FrameSearchFlag::AUTO
-        ) );
-        if ( xDispatch == *this )
-            xDispatch.clear();
 
-        if ( xDispatch.is() )
-            xDispatch->dispatch( aFeatureURL, _rArgs );
-    }
-    catch( const Exception& )
-    {
-    	DBG_UNHANDLED_EXCEPTION();
-    }
+    // user defined features can be handled by dispatch interceptors resp. protocol handlers only.
+    // So, we need to do a queryDispatch, and dispatch the URL
+    m_pData->m_aUserDefinedFeatures.execute( getURLForId( _nId ), _rArgs );
 }
 
 //------------------------------------------------------------------------------
@@ -992,7 +1039,7 @@
 		SupportedFeatures::const_iterator aIter = ::std::find_if(
 			m_aSupportedFeatures.begin(),
 			m_aSupportedFeatures.end(),
-			::std::bind2nd( SupportedFeaturesEqualId(), _nId )
+			::std::bind2nd( CompareFeatureById(), _nId )
 		);
 
 		if ( m_aSupportedFeatures.end() != aIter && aIter->first.getLength() )
@@ -1005,12 +1052,22 @@
 }
 
 //-------------------------------------------------------------------------
-bool OGenericUnoController::isUserDefinedFeature( const sal_uInt16 _nFeatureId )
+bool OGenericUnoController::isUserDefinedFeature( const sal_uInt16 _nFeatureId ) const
 {
     return ( _nFeatureId >= FIRST_USER_DEFINED_FEATURE ) && ( _nFeatureId < LAST_USER_DEFINED_FEATURE );
 }
 
 //-------------------------------------------------------------------------
+bool OGenericUnoController::isUserDefinedFeature( const ::rtl::OUString& _rFeatureURL ) const
+{
+    SupportedFeatures::const_iterator pos = m_aSupportedFeatures.find( _rFeatureURL );
+    OSL_PRECOND( pos != m_aSupportedFeatures.end(),
+        "OGenericUnoController::isUserDefinedFeature: this is no supported feature at all!" );
+
+    return ( pos != m_aSupportedFeatures.end() ) ? isUserDefinedFeature( pos->second.nFeatureId ) : false;
+}
+
+//-------------------------------------------------------------------------
 sal_Bool SAL_CALL OGenericUnoController::supportsService(const ::rtl::OUString& ServiceName) throw(RuntimeException)
 {
 	Sequence< ::rtl::OUString > aSupported(getSupportedServiceNames());
Index: source/ui/control/dbtreelistbox.cxx
===================================================================
RCS file: /cvs/dba/dbaccess/source/ui/control/dbtreelistbox.cxx,v
retrieving revision 1.20
retrieving revision 1.20.26.1
diff -u -u -u -r1.20 -r1.20.26.1
--- source/ui/control/dbtreelistbox.cxx	25 Jun 2008 12:43:33 -0000	1.20
+++ source/ui/control/dbtreelistbox.cxx	4 Aug 2008 07:25:30 -0000	1.20.26.1
@@ -562,6 +562,10 @@
 	    USHORT nCount = _rMenu.GetItemCount();
 	    for ( USHORT pos = 0; pos < nCount; ++pos )
 	    {
+            // do not adjust separators
+            if ( _rMenu.GetItemType( pos ) == MENUITEM_SEPARATOR )
+                continue;
+
 		    USHORT nId = _rMenu.GetItemId(pos);
 			String aCommand = _rMenu.GetItemCommand( nId );
 		    PopupMenu* pPopup = _rMenu.GetPopupMenu( nId );
@@ -572,8 +576,17 @@
 		    }
 
             USHORT nCommandId = _rCommandController.registerCommandURL( aCommand );
-		    _rMenu.InsertItem( nCommandId, _rMenu.GetItemText( nId ), _rMenu.GetItemBits( nId ), pos );
-		    _rMenu.RemoveItem( pos+1 );
+		    _rMenu.InsertItem( nCommandId, _rMenu.GetItemText( nId ), _rMenu.GetItemImage( nId ),
+                _rMenu.GetItemBits( nId ), pos );
+
+            // more things to preserve:
+            // - the help command
+            ::rtl::OUString sHelpURL = _rMenu.GetHelpCommand( nId );
+            if ( sHelpURL.getLength() )
+                _rMenu.SetHelpCommand(  nCommandId, sHelpURL  );
+
+            // remove the "old" item
+            _rMenu.RemoveItem( pos+1 );
 	    }
     }
     // =========================================================================

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

Reply via email to