Hi Frank,

sorry for the delay on this (copy and paste from the apology I'm sending
to everyone: the end of the first academic semester [it ended last
Friday here in Argentina - followed by a 2 weeks winter holidays]
kept me too busy; to this add a Patagonian trip to see the glacier
tearing apart [same as http://es.youtube.com/watch?v=TZJYN8qnirE]
and a 22 nights Krystov Kieslowski film retrospective;
all this together kept me away from hobby-things like playing with OOo
API).

I just started testing the css.sdb.application.DefaultViewController,
but as the first try reveals two important issues, I decided to report
my findings before finishing a nicer/cleaner demo.
"Important issue" means that the first two features I tested up to
know (the context menu interceptor and the css.view.XSelectionSuplier)
can not be used: the first not work and the later crashes OOo.

The demo can be found in
http://www.ArielConstenlaHaile.com.ar/ooo/tmp/dbaccess/DatabaseControllerDemo.zip

it's a NetBeans project, oxt inside the dist folder; to debug
the NBP you may need to change the settings (I can't recall what I've
done to make it work with the 3-layer OOo), or you can simply install
the extension (it is ridiculously verbose, so if you run OOo from the
command line will get info about what's going on).
The extension is copy&paste from other working code, but does nothing
useful, anyway it may help to test the features [well.. the "Edit
hyperlink" entry on Writer has been very useful for me!]. Check the
extension in a Writer document context menu and then in a Base
one to see the differences.

**********************************************************************
**********************************************************************

Context menu interceptor

In case you are too busy for this, take a look at the two pictures that
show the issue:
http://www.ArielConstenlaHaile.com.ar/ooo/tmp/dbaccess/no_seps_no_menu_item_image.png

http://www.ArielConstenlaHaile.com.ar/ooo/tmp/dbaccess/with_seps_and_menu_item_image.png


just by looking at them you'll see that on the context menu:

1. separators are converted to common menu items
2. menu item images are removed
3. although not visible [and AFAIK useless in context menus],
   the help command is not preserved
4. [and if you select an entry added by the extension] the
   menu item command is never executed

Ad 1.: in DBTreeListBox::CreateContextMenu [1], if the PopupMenu is
modified by a context menu interceptor, you also modify the menu item
IDs in lcl_adjustMenuItemIDs with a new ID generated for its command.
Inside the <code>for</code> loop in lcl_adjustMenuItemIDs you don't
check if the menu item is a seperator, so it ends up converting
separators in common menu items. Here adding the following code solves
the problem:

    void lcl_adjustMenuItemIDs( Menu& _rMenu, IController&
_rCommandController )
    {
        USHORT nCount = _rMenu.GetItemCount();
        for ( USHORT pos = 0; pos < nCount; ++pos )
        {
            // do NOT adjust SEPARATORS!
            MenuItemType nItemType = _rMenu.GetItemType( pos );
            if ( nItemType == MENUITEM_SEPARATOR )
                continue;

            //...
        }
    }

Ad 2.: commands added by context menu interceptors may have an image
[never tested setting the property "Image" in the ActionTrigger - at
least getting it has issues], lcl_adjustMenuItemIDs ignores that. The
following keeps the menu item images:

            Image aImage = _rMenu.GetItemImage( nId );
            if ( !!aImage )
                _rMenu.SetItemImage( nCommandId, aImage );


Ad 3.: the ActionTrigger has also a "HelpURL" property, that may also be
conserved by a _rMenu.GetHelpCommand and _rMenu.SetHelpCommand...
although I have no idea if the new extensible help feature will work if
the client code sets a custom help command here: F1 when a mouse is over
a context menu item does nothing, no matter if the command is built-in.
Anyway the following conserves the help command url:

            ::rtl::OUString aHelpURL = _rMenu.GetHelpCommand( nId );
            if ( aHelpURL.getLength() )
                _rMenu.SetHelpCommand(  nCommandId, aHelpURL  );



So that 1, 2 and 3 together make:

    void lcl_adjustMenuItemIDs( Menu& _rMenu, IController&
_rCommandController )
    {
        USHORT nCount = _rMenu.GetItemCount();
        for ( USHORT pos = 0; pos < nCount; ++pos )
        {
            // do NOT adjust SEPARATORS!
            MenuItemType nItemType = _rMenu.GetItemType( pos );
            if ( nItemType == MENUITEM_SEPARATOR )
                continue;

            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 );

            // first preserve IMAGES!
            Image aImage = _rMenu.GetItemImage( nId );
            if ( !!aImage )
                _rMenu.SetItemImage( nCommandId, aImage );

            // and preserve HELP command URL
            ::rtl::OUString aHelpURL = _rMenu.GetHelpCommand( nId );
            if ( aHelpURL.getLength() )
                _rMenu.SetHelpCommand(  nCommandId, aHelpURL  );

            _rMenu.RemoveItem( pos+1 );
        }
    }

This code makes the PopupMenu look like the image in
http://www.ArielConstenlaHaile.com.ar/ooo/tmp/dbaccess/with_seps_and_menu_item_image.png



Ad 4.: the issue for the command not being dispatched is a complex one:

 *  when the user chooses a context menu item,
    DBTreeListBox::ExcecuteContextMenuAction invokes
    OApplicationController::executeChecked(sal_uInt16 _nCommandId,
    const Sequence< PropertyValue >& aArgs) with the item ID of
    the selected menu item

 *  OApplicationController::executeChecked forwards the call to
    OGenericUnoController::executeChecked

 *  OGenericUnoController::executeChecked will
      * first check if the command corresponding to this ID is
        enabled [isCommandEnabled(_nCommandId)]
      * then, if enable, execute it

The first problem here is when isCommandEnabled checks the feature state:

* OApplicationController::GetState switches all the IDs it can handle
  and as <code>default</code> forwards to its base class, this will be
  the case when the ID corresponds to a command added by a context menu
  interceptor
* but in OGenericUnoController::GetState there is no code enabling so
  called "user defined features", so it returns always in this case a
  feature automatically disabled, and the command is then never executed

A very dummy hack enabling all "user defined features"


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;
            default:
                if ( ( nId >= FIRST_USER_DEFINED_FEATURE ) && ( nId <
LAST_USER_DEFINED_FEATURE ) )
                {
                    aReturn.bEnabled = sal_True;
                }
        }
    }
    catch( const Exception& )
    {
        DBG_UNHANDLED_EXCEPTION();
    }

    return aReturn;
}


does not solve the problem, and discovers new ones:

* isCommandEnabled returns true (because we force
  GetState( _nCommandId ).bEnabled = sal_True for all
  "user defined features", so the command ID will be
  executed

* OApplicationController::Execute(sal_uInt16 _nId,
  const Sequence< PropertyValue >& aArgs) forwards
  to its base when the ID belongs to a "user defined features"

* OGenericUnoController::Execute
  *  first gets the fully parsed command URL for this command ID
  *  then queries a dispatch object
  *  and ask the dispatch to execute the URL

The problem in these last steps is that
OGenericUnoController::queryDispatch checks that the command is among
its supported features and returns itself as dispatch object, even when
it is a "user defined features". So that looking at the code


void OGenericUnoController::Execute( sal_uInt16 _nId, const Sequence<
PropertyValue>& _rArgs )
{

    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();
    }
}

it's is obvious that:

* the controller returns *itself* as dispatch for the command
* but then the reference is *cleared*
* so the dispatch *never* dispatches the URL

Not clearing the reference does not solve anything: the application
controller won't dispatch the URL anyway.

Forcing to query the slave dispatch providers when it is a user defined
feature won't either solve the problem: I'm not sure if the comment

"user defined features can be handled by dispatch interceptors *only*.
So, we need to do a queryDispatch, and dispatch the URL"

is completely wrong (I never use dispatch interceptors because it is
quite useless, as it may happen that more than one registers for the
same command and nobody can assure who wins the battle - the same
happens with the context menu interceptors, but here there is no other
way to achieve the same, while in the other case a ProtocolHandler is
more convenient), but I'm sure that:

* a context menu interceptor can add commands handled by itself, so that
  its own ProtocolHandler is the one that is queried for a dispatch
* this way also an extension binds commands to images, and the images
  are display in the context menu
* again, the extension's ProtocolHandler is queried for a dispatch, not
  the controller, nor slaves dispatches

I tried the dummy hack of querying the controller's frame for a dispatch
object, but that does not work:



void OGenericUnoController::Execute( sal_uInt16 _nId, const Sequence<
PropertyValue>& _rArgs )
{
    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< XDispatchProvider > xDispatchProvider( getFrame(),
UNO_QUERY );
        Reference< XDispatch > xDispatch;

        if ( xDispatchProvider.is() )
        {
            xDispatch = xDispatchProvider->queryDispatch(
                            aFeatureURL,
                            ::rtl::OUString(
RTL_CONSTASCII_USTRINGPARAM( "_self" ) ),
                            FrameSearchFlag::AUTO );
            OSL_TRACE("trying with getFrame()");
        }
        /*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();
    }
}


I thought that getFrame() will return an css.frame.XFrame reference to
the controller's frame, and querying the frame for a dispatch for my
URL, it will query in turn my ProtocolHandler [as stated in
http://api.openoffice.org/docs/common/ref/com/sun/star/frame/ProtocolHandler.html:

"The generic dispatch mechanism on a Frame search for such registered
protocol handler and use it if it agrees with the dispatched URL."]

It seems that the other day (well...night at 2:00 AM) I was quite
asleep, although now it's 2 AM again, the distance gives me new eyes:
yes, getting the XFrame and querying it for a dispatch will end
up querying my ProtocolHandler. I was dummy not to hack enough also
OGenericUnoController::queryDispatch, I only added an OSL_TRACE, but the
controller *must* not return itself as dispatch object in the case of
"user defined commands", so now I make it this way:



Reference< XDispatch >    OGenericUnoController::queryDispatch(const URL&
aURL, const ::rtl::OUString& aTargetFrameName, sal_Int32 nSearchFlags)
throw( RuntimeException )
{
        Reference< XDispatch > xReturn;
       OSL_PRECOND( !m_aSupportedFeatures.empty(),
"OGenericUnoController::queryDispatch: shouldn't this be filled at
construction time?" );
       if ( m_aSupportedFeatures.empty() )
           fillSupportedFeatures();

       // first check our supported features
       if ( aURL.Complete.equals( getConfirmDeletionURL() )
                ||      ( m_aSupportedFeatures.find( aURL.Complete ) !=
m_aSupportedFeatures.end() )
                )
        {
           // if the feature is user defined, do *not* return ourselves!
           if ( isUserDefinedFeature( m_aSupportedFeatures[ aURL.Complete
].nFeatureId ) )
           {
               OSL_TRACE("Is user defined!");
               return xReturn;
           }
           // URL's we can handle ourself?
               xReturn = this;
        }
        // no? -> ask the slave dispatcher
        else if ( m_xSlaveDispatcher.is() )
        {
                xReturn = m_xSlaveDispatcher->queryDispatch(aURL, 
aTargetFrameName,
nSearchFlags);
        }

        // outta here
        return xReturn;
}


[mmm... seems I'm not taking care of the slave dispatchers...]

What was happening here?

I was right to use getFrame() to take the XFrame as dispatch provider in
OGenericUnoController::Execute instead of invoking queryDispatch(). But
the problem was that when the frame [in fact it's not himself but a
helper class DispatchProvider impl. in
framework/source/dispatch/dispatchprovider.cxx] searches for someone to
handle the URL, in this case he will query *first* it's controller, and
if it disagrees, *then* it searches among the registered protocol handlers.

For all this stuff, look at
framework/source/dispatch/dispatchprovider.cxx , in DEV300_m25 is v.
1.37, DispatchProvider::implts_queryFrameDispatch, spec. ll. 455 ss, the
comments there are very clear.

In conclusion, now [in my build] the the context menu interceptor has a
nice PopupMenu with images and separators, and dispatches its commands.
I send you the patch (DEV300_m25 against DEV300_m28) so you can follow
the mail. It is very simple, I only touched two files. The
OGenericUnoController fix is too hacky for my taste, sure you find
something more elegant; the PopupMenu fix I find it acceptable and nice.

Regards
Ariel.


PS: reading at the sources I found a pair of things I'd like to have at
the XDatabaseDocumentUI, may I ask them for?

--
Ariel Constenla-Haile
La Plata, Argentina

[EMAIL PROTECTED]
[EMAIL PROTECTED]

http://www.ArielConstenlaHaile.com.ar/ooo/



"Aus der Kriegsschule des Lebens
                - Was mich nicht umbringt,
        macht mich härter."
                Nietzsche Götzendämmerung, Sprüche und Pfeile, 8.


Index: app/AppController.cxx
===================================================================
RCS file: /cvs/dba/dbaccess/source/ui/app/AppController.cxx,v
retrieving revision 1.63
diff -u -r1.63 AppController.cxx
--- app/AppController.cxx       25 Jun 2008 12:35:22 -0000      1.63
+++ app/AppController.cxx       1 Aug 2008 04:22:41 -0000
@@ -1,7 +1,7 @@
 /*************************************************************************
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
+ *
  * Copyright 2008 by Sun Microsystems, Inc.
  *
  * OpenOffice.org - a multi-platform office productivity suite
@@ -628,7 +628,7 @@
                     
::std::compose1(::std::select2nd<TTypeFrame>(),::std::select2nd<TFrames::value_type>())));
                        if ( aFind2 != m_aSpecialSubFrames.end() )
                                m_aSpecialSubFrames.erase(aFind2);
-            
+
                }
                if ( xContainer.is() )
                {
@@ -1628,7 +1628,7 @@
     implDescribeSupportedFeature( ".uno:OpenUrl",            SID_OPENURL,      
         CommandGroup::APPLICATION );
 
     // this one should not appear under Tools->Customize->Keyboard
-    implDescribeSupportedFeature( ".uno:DBNewReportWithPreSelection",          
 
+    implDescribeSupportedFeature( ".uno:DBNewReportWithPreSelection",
                                                              
SID_APP_NEW_REPORT_PRE_SEL,CommandGroup::INTERNAL );
        implDescribeSupportedFeature( ".uno:DBDSImport",                
SID_DB_APP_DSIMPORT, CommandGroup::INTERNAL);
        implDescribeSupportedFeature( ".uno:DBDSExport",                
SID_DB_APP_DSEXPORT, CommandGroup::INTERNAL);
Index: browser/genericcontroller.cxx
===================================================================
RCS file: /cvs/dba/dbaccess/source/ui/browser/genericcontroller.cxx,v
retrieving revision 1.94
diff -u -r1.94 genericcontroller.cxx
--- browser/genericcontroller.cxx       26 Jun 2008 11:43:10 -0000      1.94
+++ browser/genericcontroller.cxx       1 Aug 2008 04:20:51 -0000
@@ -1,7 +1,7 @@
 /*************************************************************************
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
+ *
  * Copyright 2008 by Sun Microsystems, Inc.
  *
  * OpenOffice.org - a multi-platform office productivity suite
@@ -387,7 +387,7 @@
 //------------------------------------------------------------------------
 void OGenericUnoController::modified(const EventObject& aEvent) throw( 
RuntimeException )
 {
-       ::osl::MutexGuard aGuard(m_aMutex);     
+       ::osl::MutexGuard aGuard(m_aMutex);
        if ( !isDataSourceReadOnly() )
        {
                Reference<XModifiable> xModi(aEvent.Source,UNO_QUERY);
@@ -415,7 +415,7 @@
 void OGenericUnoController::attachFrame( const Reference< XFrame >& _rxFrame ) 
throw( RuntimeException )
 {
     vos::OGuard aSolarGuard( Application::GetSolarMutex() );
-       ::osl::MutexGuard aGuard(m_aMutex);     
+       ::osl::MutexGuard aGuard(m_aMutex);
 
     stopFrameListening( m_aCurrentFrame.getFrame() );
        Reference< XFrame > xFrame = m_aCurrentFrame.attachFrame( _rxFrame );
@@ -664,7 +664,7 @@
 {
        // ---------------------------------
        // invalidate all aupported features
-       
+
        for (   SupportedFeatures::const_iterator aIter = 
m_aSupportedFeatures.begin();
             aIter != m_aSupportedFeatures.end();
             ++aIter
@@ -684,17 +684,23 @@
 Reference< XDispatch > OGenericUnoController::queryDispatch(const URL& aURL, 
const ::rtl::OUString& aTargetFrameName, sal_Int32 nSearchFlags) throw( 
RuntimeException )
 {
        Reference< XDispatch > xReturn;
-
     OSL_PRECOND( !m_aSupportedFeatures.empty(), 
"OGenericUnoController::queryDispatch: shouldn't this be filled at construction 
time?" );
     if ( m_aSupportedFeatures.empty() )
         fillSupportedFeatures();
 
-       // URL's we can handle ourself?
-       if      (       aURL.Complete.equals( getConfirmDeletionURL() )
+    // first check our supported features
+    if ( aURL.Complete.equals( getConfirmDeletionURL() )
                ||      ( m_aSupportedFeatures.find( aURL.Complete ) != 
m_aSupportedFeatures.end() )
                )
        {
-               xReturn = this;
+        // if the feature is user defined, do not return ourselves!
+        if ( isUserDefinedFeature( m_aSupportedFeatures[ aURL.Complete 
].nFeatureId ) )
+        {
+            OSL_TRACE("Is user defined!");
+            return xReturn;
+        }
+        // URL's we can handle ourself?
+        xReturn = this;
        }
        // no? -> ask the slave dispatcher
        else if ( m_xSlaveDispatcher.is() )
@@ -843,7 +849,7 @@
                Dispatch aStatusListener = m_arrStatusListener;
                Dispatch::iterator aEnd = aStatusListener.end();
                for (Dispatch::iterator aIter = aStatusListener.begin(); aIter 
!= aEnd; ++aIter)
-               {               
+               {
                        aIter->xListener->disposing(aDisposeEvent);
                }
                m_arrStatusListener.clear();
@@ -945,6 +951,12 @@
                        case ID_BROWSER_SAVEDOC:
                                aReturn.bEnabled = sal_True;
                                break;
+            default:
+                // do something to enable user defined features, or they will 
never be executed!
+                if ( ( nId >= FIRST_USER_DEFINED_FEATURE ) && ( nId < 
LAST_USER_DEFINED_FEATURE ) )
+                {
+                    aReturn.bEnabled = sal_True;
+                }
                }
        }
        catch( const Exception& )
@@ -960,17 +972,28 @@
 {
     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(
+        Reference< XDispatchProvider > xDispatchProvider( getFrame(), 
UNO_QUERY );
+        Reference< XDispatch > xDispatch;
+
+        if ( xDispatchProvider.is() )
+        {
+            xDispatch = xDispatchProvider->queryDispatch(
+                            aFeatureURL,
+                            ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 
"_self" ) ),
+                            FrameSearchFlag::AUTO );
+            OSL_TRACE("trying with getFrame()");
+        }
+        /*Reference< XDispatch > xDispatch( queryDispatch(
             aFeatureURL,
             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_self" ) ),
             FrameSearchFlag::AUTO
-        ) );
+        ) );*/
+
         if ( xDispatch == *this )
             xDispatch.clear();
 
@@ -1197,6 +1220,7 @@
        if ( aIter != m_aSupportedFeatures.end() )
        {
                sal_uInt16 nFeatureId = aIter->second.nFeatureId;
+
                if ( GetState( nFeatureId ).bEnabled )
                        Execute( nFeatureId, aArgs );
        }
@@ -1325,7 +1349,7 @@
     }
     URL aURL;
     aURL.Complete = suURL;
-    
+
     openHelpAgent( aURL );
 }
 
@@ -1388,10 +1412,10 @@
     {
         Reference< XUntitledNumbers > xUntitledProvider(getPrivateModel(), 
UNO_QUERY      );
         Reference< XController >      xThis(static_cast< XController* >(this), 
UNO_QUERY_THROW);
-    
+
         ::framework::TitleHelper* pHelper = new 
::framework::TitleHelper(m_xServiceFactory);
         m_xTitleHelper.set( static_cast< ::cppu::OWeakObject* >(pHelper), 
UNO_QUERY_THROW);
-    
+
         pHelper->setOwner                   (xThis            );
         pHelper->connectWithUntitledNumbers (xUntitledProvider);
     }
@@ -1420,7 +1444,7 @@
     m_bExternalTitle = sal_True;
     impl_getTitleHelper_throw()->setTitle (sTitle);
 }
-    
+
 //=============================================================================
 // XTitleChangeBroadcaster
 void SAL_CALL OGenericUnoController::addTitleChangeListener(const Reference< 
XTitleChangeListener >& xListener)
@@ -1538,14 +1562,14 @@
 sal_Bool OGenericUnoController::isCommandChecked(sal_uInt16 _nCommandId) const
 {
     FeatureState aState = GetState( _nCommandId );
-    
+
        return aState.bChecked && (sal_Bool)*aState.bChecked;
 }
 // 
-----------------------------------------------------------------------------
 sal_Bool OGenericUnoController::isCommandEnabled( const ::rtl::OUString& 
_rCompleteCommandURL ) const
 {
     OSL_ENSURE( _rCompleteCommandURL.getLength(), 
"OGenericUnoController::isCommandEnabled: Empty command url!" );
-    
+
        sal_Bool bIsEnabled = sal_False;
     SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.find( 
_rCompleteCommandURL );
        if ( aIter != m_aSupportedFeatures.end() )
Index: control/dbtreelistbox.cxx
===================================================================
RCS file: /cvs/dba/dbaccess/source/ui/control/dbtreelistbox.cxx,v
retrieving revision 1.20
diff -u -r1.20 dbtreelistbox.cxx
--- control/dbtreelistbox.cxx   25 Jun 2008 12:43:33 -0000      1.20
+++ control/dbtreelistbox.cxx   1 Aug 2008 04:24:03 -0000
@@ -1,7 +1,7 @@
 /*************************************************************************
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
+ *
  * Copyright 2008 by Sun Microsystems, Inc.
  *
  * OpenOffice.org - a multi-platform office productivity suite
@@ -50,7 +50,7 @@
 #ifndef _COM_SUN_STAR_DATATRANSFER_DND_XDRAGGESTURELISTENER_HDL_
 #include <com/sun/star/datatransfer/dnd/XDragGestureListener.hdl>
 #endif
-#ifndef _COM_SUN_STAR_DATATRANSFER_DND_XDRAGGESTURERECOGNIZER_HPP_ 
+#ifndef _COM_SUN_STAR_DATATRANSFER_DND_XDRAGGESTURERECOGNIZER_HPP_
 #include <com/sun/star/datatransfer/dnd/XDragGestureRecognizer.hpp>
 #endif
 #ifndef _COM_SUN_STAR_UI_XCONTEXTMENUINTERCEPTOR_HPP_
@@ -68,6 +68,9 @@
 #ifndef _SV_HELP_HXX
 #include <vcl/help.hxx>
 #endif
+#ifndef _SV_IMAGE_HXX
+#include <vcl/image.hxx>
+#endif
 #ifndef _DBAUI_TABLETREE_HRC_
 #include "tabletree.hrc"
 #endif
@@ -127,7 +130,7 @@
        ,m_xORB(_rxORB)
 {
        DBG_CTOR(DBTreeListBox,NULL);
-       init(); 
+       init();
 }
 // 
-----------------------------------------------------------------------------
 void DBTreeListBox::init()
@@ -150,7 +153,7 @@
 {
        DBG_DTOR(DBTreeListBox,NULL);
        if(m_aTimer.IsActive())
-               m_aTimer.Stop();        
+               m_aTimer.Stop();
 }
 //------------------------------------------------------------------------
 SvLBoxEntry* DBTreeListBox::GetEntryPosByName( const String& aName, 
SvLBoxEntry* pStart, const IEntryFilter* _pFilter ) const
@@ -464,7 +467,7 @@
                // 2002-12-02 - 105831 - [EMAIL PROTECTED]
        }
 
-       if ( !bHandled ) 
+       if ( !bHandled )
                SvTreeListBox::KeyInput(rKEvt);
 }
 // 
-----------------------------------------------------------------------------
@@ -485,7 +488,7 @@
                m_pSelectedEntry = NULL; // to force that the renamed selection 
will be reselected
        }
        SetEntryText(pEntry,aEntry.aNewText);
-       
+
        return FALSE;  // we never want that the base change our text
 }
 
@@ -559,21 +562,38 @@
 {
     void lcl_adjustMenuItemIDs( Menu& _rMenu, IController& _rCommandController 
)
     {
-           USHORT nCount = _rMenu.GetItemCount();
+        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 
);
+            // do NOT adjust SEPARATORS!
+            MenuItemType nItemType = _rMenu.GetItemType( pos );
+            if ( nItemType == MENUITEM_SEPARATOR )
                 continue;
-                   }
+
+            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 );
+
+            _rMenu.InsertItem( nCommandId, _rMenu.GetItemText( nId ), 
_rMenu.GetItemBits( nId ), pos );
+
+            // first preserve IMAGES!
+            Image aImage = _rMenu.GetItemImage( nId );
+            if ( !!aImage )
+                _rMenu.SetItemImage( nCommandId, aImage );
+
+            // and preserve HELP command URL
+            ::rtl::OUString aHelpURL = _rMenu.GetHelpCommand( nId );
+            if ( aHelpURL.getLength() )
+                _rMenu.SetHelpCommand(  nCommandId, aHelpURL  );
+
+            _rMenu.RemoveItem( pos+1 );
            }
     }
     // 
=========================================================================
@@ -609,20 +629,20 @@
         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)
     {
@@ -727,7 +747,7 @@
        if(m_aTimer.IsActive())
                m_aTimer.Stop();
        if (m_pSelectedEntry)
-               aSelectHdl.Call( m_pSelectedEntry );    
+               aSelectHdl.Call( m_pSelectedEntry );
        return 0L;
 }
 // 
-----------------------------------------------------------------------------





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

Reply via email to