xref: /trunk/main/framework/source/classes/menumanager.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_framework.hxx"
30 
31 
32 //_________________________________________________________________________________________________________________
33 //  my own includes
34 //_________________________________________________________________________________________________________________
35 #include <classes/menumanager.hxx>
36 #include <framework/menuconfiguration.hxx>
37 #include <framework/bmkmenu.hxx>
38 #include <framework/addonmenu.hxx>
39 #include <framework/imageproducer.hxx>
40 #include <threadhelp/resetableguard.hxx>
41 #include "framework/addonsoptions.hxx"
42 #include <classes/fwkresid.hxx>
43 #include <services.h>
44 #include "classes/resource.hrc"
45 
46 //_________________________________________________________________________________________________________________
47 //  interface includes
48 //_________________________________________________________________________________________________________________
49 #include <com/sun/star/frame/XDispatchProvider.hpp>
50 #include <com/sun/star/frame/XDispatch.hpp>
51 #include <com/sun/star/util/XURLTransformer.hpp>
52 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
53 #include <com/sun/star/beans/XPropertySet.hpp>
54 #include <com/sun/star/frame/XFramesSupplier.hpp>
55 #include <com/sun/star/frame/XDesktop.hpp>
56 #include <com/sun/star/container/XEnumeration.hpp>
57 #include <com/sun/star/util/XStringWidth.hpp>
58 
59 //_________________________________________________________________________________________________________________
60 //  includes of other projects
61 //_________________________________________________________________________________________________________________
62 #include <comphelper/processfactory.hxx>
63 
64 #include <comphelper/extract.hxx>
65 #include <svtools/menuoptions.hxx>
66 #include <unotools/historyoptions.hxx>
67 #include <unotools/pathoptions.hxx>
68 #include <unotools/localfilehelper.hxx>
69 
70 #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
71 #include <toolkit/unohlp.hxx>
72 #endif
73 #include <tools/urlobj.hxx>
74 
75 #include <vcl/svapp.hxx>
76 #include <vcl/window.hxx>
77 #include <vos/mutex.hxx>
78 #include <vcl/svapp.hxx>
79 #include <osl/file.hxx>
80 #include <cppuhelper/implbase1.hxx>
81 
82 //_________________________________________________________________________________________________________________
83 //  namespace
84 //_________________________________________________________________________________________________________________
85 
86 using namespace ::cppu;
87 using namespace ::vos;
88 using namespace ::com::sun::star::uno;
89 using namespace ::com::sun::star::util;
90 using namespace ::com::sun::star::beans;
91 using namespace ::com::sun::star::frame;
92 using namespace ::com::sun::star::lang;
93 using namespace ::com::sun::star::container;
94 
95 
96 class StringLength : public ::cppu::WeakImplHelper1< ::com::sun::star::util::XStringWidth >
97 {
98     public:
99         StringLength() {}
100         virtual ~StringLength() {}
101 
102         // XStringWidth
103         sal_Int32 SAL_CALL queryStringWidth( const ::rtl::OUString& aString )
104             throw (::com::sun::star::uno::RuntimeException)
105         {
106             return aString.getLength();
107         }
108 };
109 
110 namespace framework
111 {
112 
113 // special menu ids/command ids for dynamic popup menus
114 #define SID_SFX_START           5000
115 #define SID_NEWDOCDIRECT        (SID_SFX_START + 537)
116 #define SID_AUTOPILOTMENU       (SID_SFX_START + 1381)
117 #define SID_PICKLIST            (SID_SFX_START + 510)
118 #define SID_MDIWINDOWLIST       (SID_SFX_START + 610)
119 #define SID_ADDONLIST           (SID_SFX_START + 1677)
120 #define SID_HELPMENU            (SID_SFX_START + 410)
121 
122 #define SFX_REFERER_USER        "private:user"
123 
124 const ::rtl::OUString aSlotNewDocDirect( RTL_CONSTASCII_USTRINGPARAM( "slot:5537" ));
125 const ::rtl::OUString aSlotAutoPilot( RTL_CONSTASCII_USTRINGPARAM( "slot:6381" ));
126 
127 const ::rtl::OUString aSpecialFileMenu( RTL_CONSTASCII_USTRINGPARAM( "file" ));
128 const ::rtl::OUString aSpecialWindowMenu( RTL_CONSTASCII_USTRINGPARAM( "window" ));
129 const ::rtl::OUString aSlotSpecialFileMenu( RTL_CONSTASCII_USTRINGPARAM( "slot:5510" ));
130 const ::rtl::OUString aSlotSpecialWindowMenu( RTL_CONSTASCII_USTRINGPARAM( "slot:5610" ));
131 const ::rtl::OUString aSlotSpecialToolsMenu( RTL_CONSTASCII_USTRINGPARAM( "slot:6677" ));
132 
133 // special uno commands for picklist and window list
134 const ::rtl::OUString aSpecialFileCommand( RTL_CONSTASCII_USTRINGPARAM( "PickList" ));
135 const ::rtl::OUString aSpecialWindowCommand( RTL_CONSTASCII_USTRINGPARAM( "WindowList" ));
136 
137 const ::rtl::OUString UNO_COMMAND( RTL_CONSTASCII_USTRINGPARAM( ".uno:" ));
138 
139 // #110897#
140 MenuManager::MenuManager(
141     const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory,
142     REFERENCE< XFRAME >& rFrame, Menu* pMenu, sal_Bool bDelete, sal_Bool bDeleteChildren )
143 :   // #110897#
144     ThreadHelpBase( &Application::GetSolarMutex() ),
145     mxServiceFactory(xServiceFactory)
146 {
147     m_bActive           = sal_False;
148     m_bDeleteMenu       = bDelete;
149     m_bDeleteChildren   = bDeleteChildren;
150     m_pVCLMenu          = pMenu;
151     m_xFrame            = rFrame;
152     m_bInitialized      = sal_False;
153     m_bIsBookmarkMenu   = sal_False;
154     SAL_STATIC_CAST( ::com::sun::star::uno::XInterface*, (OWeakObject*)this )->acquire();
155 
156     const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
157     m_bWasHiContrast    = rSettings.GetHighContrastMode();
158     m_bShowMenuImages   = rSettings.GetUseImagesInMenus();
159 
160     sal_Int32 nAddonsURLPrefixLength = ADDONSPOPUPMENU_URL_PREFIX.getLength();
161 #if 0
162     ::std::vector< sal_uInt16 > aQueryLabelItemIdVector;
163 #endif
164 
165     sal_uInt16 nItemCount = pMenu->GetItemCount();
166     m_aMenuItemHandlerVector.reserve(nItemCount);
167     ::rtl::OUString aItemCommand;
168     for ( sal_uInt16 i = 0; i < nItemCount; i++ )
169     {
170         sal_uInt16 nItemId = FillItemCommand(aItemCommand,pMenu, i );
171         bool bShowMenuImages( m_bShowMenuImages );
172         MenuItemBits nBits =  pMenu->GetItemBits( nItemId );
173         // overwrite the default?
174         if ( nBits )
175             bShowMenuImages = ( ( nBits & MIB_ICON ) == MIB_ICON );
176 
177 
178         PopupMenu* pPopupMenu = pMenu->GetPopupMenu( nItemId );
179         if ( pPopupMenu )
180         {
181             AddMenu(pPopupMenu,aItemCommand,nItemId,bDeleteChildren,bDeleteChildren);
182             if (! (( aItemCommand.getLength() > nAddonsURLPrefixLength ) &&
183                 ( aItemCommand.indexOf( ADDONSPOPUPMENU_URL_PREFIX ) == 0 )) )
184             {
185                 // #110897#
186                 // MenuManager* pSubMenuManager = new MenuManager( rFrame, pPopupMenu, bDeleteChildren, bDeleteChildren );
187 #if 0
188                 if ( pMenu->GetItemText( nItemId ).Len() == 0 )
189                     aQueryLabelItemIdVector.push_back( nItemId );
190 #endif
191 
192                 // Create addon popup menu if there exist elements and this is the tools popup menu
193                 if (( nItemId == SID_ADDONLIST ||
194                     aItemCommand == aSlotSpecialToolsMenu ) &&
195                     AddonMenuManager::HasAddonMenuElements() )
196                 {
197                     sal_uInt16      nCount   = 0;
198                     AddonMenu*  pSubMenu = AddonMenuManager::CreateAddonMenu( rFrame );
199                     if ( pSubMenu && ( pSubMenu->GetItemCount() > 0 ))
200                     {
201                         if ( pPopupMenu->GetItemType( nCount-1 ) != MENUITEM_SEPARATOR )
202                             pPopupMenu->InsertSeparator();
203 
204                         // Use resource to load popup menu title
205                         String aAddonsStrRes = String( FwkResId( STR_MENU_ADDONS ));
206                         pPopupMenu->InsertItem( ITEMID_ADDONLIST, aAddonsStrRes );
207                         pPopupMenu->SetPopupMenu( ITEMID_ADDONLIST, pSubMenu );
208 
209                         // Set item command for popup menu to enable it for GetImageFromURL
210                         const static ::rtl::OUString aSlotString( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
211                         aItemCommand = aSlotString;
212                         aItemCommand += ::rtl::OUString::valueOf( (sal_Int32)ITEMID_ADDONLIST );
213                         pPopupMenu->SetItemCommand( ITEMID_ADDONLIST, aItemCommand );
214 
215                         // #110897#
216                         // MenuManager* pSubMenuManager = new MenuManager( rFrame, pSubMenu, sal_True, sal_False );
217                         AddMenu(pSubMenu,::rtl::OUString(),nItemId,sal_True,sal_False);
218 #if 0
219                         if ( pMenu->GetItemText( nItemId ).Len() == 0 )
220                             aQueryLabelItemIdVector.push_back( nItemId );
221 #endif
222                         // Set image for the addon popup menu item
223                         if ( bShowMenuImages && !pPopupMenu->GetItemImage( ITEMID_ADDONLIST ))
224                         {
225                             Image aImage = GetImageFromURL( rFrame, aItemCommand, sal_False, m_bWasHiContrast );
226                             if ( !!aImage )
227                                 pPopupMenu->SetItemImage( ITEMID_ADDONLIST, aImage );
228                         }
229                     }
230                     else
231                         delete pSubMenu;
232                 }
233             }
234         }
235         else
236         {
237             if ( nItemId == SID_NEWDOCDIRECT ||
238                  aItemCommand == aSlotNewDocDirect )
239             {
240                 // #110897#
241                 // Reference< ::com::sun::star::lang::XMultiServiceFactory > aMultiServiceFactory(::comphelper::getProcessServiceFactory());
242                 // MenuConfiguration aMenuCfg( aMultiServiceFactory );
243                 MenuConfiguration aMenuCfg( getServiceFactory() );
244                 BmkMenu* pSubMenu = (BmkMenu*)aMenuCfg.CreateBookmarkMenu( rFrame, BOOKMARK_NEWMENU );
245                 pMenu->SetPopupMenu( nItemId, pSubMenu );
246 
247                 // #110897#
248                 // MenuManager* pSubMenuManager = new MenuManager( rFrame, pSubMenu, sal_True, sal_False );
249                 AddMenu(pSubMenu,::rtl::OUString(),nItemId,sal_True,sal_False);
250 #if 0
251                 if ( pMenu->GetItemText( nItemId ).Len() == 0 )
252                     aQueryLabelItemIdVector.push_back( nItemId );
253 #endif
254 
255                 if ( bShowMenuImages && !pMenu->GetItemImage( nItemId ))
256                 {
257                     Image aImage = GetImageFromURL( rFrame, aItemCommand, sal_False, m_bWasHiContrast );
258                     if ( !!aImage )
259                         pMenu->SetItemImage( nItemId, aImage );
260                 }
261             }
262             else if ( nItemId == SID_AUTOPILOTMENU ||
263                       aItemCommand == aSlotAutoPilot )
264             {
265                 // #110897#
266                 // Reference< ::com::sun::star::lang::XMultiServiceFactory > aMultiServiceFactory(::comphelper::getProcessServiceFactory());
267                 // MenuConfiguration aMenuCfg( aMultiServiceFactory );
268                 MenuConfiguration aMenuCfg( getServiceFactory() );
269                 BmkMenu* pSubMenu = (BmkMenu*)aMenuCfg.CreateBookmarkMenu( rFrame, BOOKMARK_WIZARDMENU );
270                 pMenu->SetPopupMenu( nItemId, pSubMenu );
271 
272                 // #110897#
273                 // MenuManager* pSubMenuManager = new MenuManager( rFrame, pSubMenu, sal_True, sal_False );
274                 AddMenu(pSubMenu,::rtl::OUString(),nItemId,sal_True,sal_False);
275 #if 0
276                 if ( pMenu->GetItemText( nItemId ).Len() == 0 )
277                     aQueryLabelItemIdVector.push_back( nItemId );
278 #endif
279 
280                 if ( bShowMenuImages && !pMenu->GetItemImage( nItemId ))
281                 {
282                     Image aImage = GetImageFromURL( rFrame, aItemCommand, sal_False, m_bWasHiContrast );
283                     if ( !!aImage )
284                         pMenu->SetItemImage( nItemId, aImage );
285                 }
286             }
287             else if ( pMenu->GetItemType( i ) != MENUITEM_SEPARATOR )
288             {
289                 if ( bShowMenuImages )
290                 {
291                     if ( AddonMenuManager::IsAddonMenuId( nItemId ))
292                     {
293                         // Add-Ons uses a images from different places
294                         Image           aImage;
295                         rtl::OUString   aImageId;
296 
297                         MenuConfiguration::Attributes* pMenuAttributes =
298                             (MenuConfiguration::Attributes*)pMenu->GetUserValue( nItemId );
299 
300                         if ( pMenuAttributes && pMenuAttributes->aImageId.getLength() > 0 )
301                         {
302                             // Retrieve image id from menu attributes
303                             aImage = GetImageFromURL( rFrame, aImageId, sal_False, m_bWasHiContrast );
304                         }
305 
306                         if ( !aImage )
307                         {
308                             aImage = GetImageFromURL( rFrame, aItemCommand, sal_False, m_bWasHiContrast );
309                             if ( !aImage )
310                                 aImage = AddonsOptions().GetImageFromURL( aItemCommand, sal_False, m_bWasHiContrast );
311                         }
312 
313                         if ( !!aImage )
314                             pMenu->SetItemImage( nItemId, aImage );
315                     }
316                     else if ( !pMenu->GetItemImage( nItemId ))
317                     {
318                         Image aImage = GetImageFromURL( rFrame, aItemCommand, sal_False, m_bWasHiContrast );
319                         if ( !!aImage )
320                             pMenu->SetItemImage( nItemId, aImage );
321                     }
322                 }
323 
324                 REFERENCE< XDISPATCH > aXDispatchRef;
325                 m_aMenuItemHandlerVector.push_back( new MenuItemHandler( nItemId, NULL, aXDispatchRef ));
326 #if 0
327                 if ( pMenu->GetItemText( nItemId ).Len() == 0 )
328                     aQueryLabelItemIdVector.push_back( nItemId );
329 #endif
330             }
331         }
332     }
333 
334 
335     // retrieve label information for all menu items without item text
336 #if 0
337     if ( aQueryLabelItemIdVector.size() > 0 )
338     {
339         Sequence< ::rtl::OUString > aURLSequence( aQueryLabelItemIdVector.size() );
340         Sequence< ::rtl::OUString > aLabelSequence( aQueryLabelItemIdVector.size() );
341 
342         sal_uInt32 nPos = 0;
343         ::std::vector< sal_uInt16 >::iterator p;
344         for ( p = aQueryLabelItemIdVector.begin(); p != aQueryLabelItemIdVector.end(); p++ )
345             aURLSequence[nPos++] = pMenu->GetItemCommand( *p );
346 
347         Reference< XDispatchInformationProvider > xDIP( xFrame, UNO_QUERY );
348         if ( xDIP.is() )
349         {
350             nPos = 0;
351             xDIP->queryDispatchInformations( aURLSequence, aLabelSequence );
352             for ( p = aQueryLabelItemIdVector.begin(); p != aQueryLabelItemIdVector.end(); p++ )
353                 pMenu->SetItemText( *p, aLabelSequence( nPos++ ));
354         }
355     }
356 #endif
357     SetHdl();
358 }
359 
360 #if 0
361 // #110897#
362 MenuManager::MenuManager(
363     const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory,
364     REFERENCE< XFRAME >& rFrame, AddonMenu* pAddonMenu, sal_Bool bDelete, sal_Bool bDeleteChildren )
365 :   // #110897#
366     ThreadHelpBase( &Application::GetSolarMutex() ),
367     mxServiceFactory(xServiceFactory)
368 {
369     m_bActive           = sal_False;
370     m_bDeleteMenu       = bDelete;
371     m_bDeleteChildren   = bDeleteChildren;
372     m_pVCLMenu          = pAddonMenu;
373     m_xFrame            = rFrame;
374     m_bInitialized      = sal_False;
375     m_bIsBookmarkMenu   = sal_True;
376 
377     const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
378     m_bWasHiContrast    = rSettings.GetHighContrastMode();
379 
380     SAL_STATIC_CAST( ::com::sun::star::uno::XInterface*, (OWeakObject*)this )->acquire();
381 
382     sal_uInt16 nItemCount = pAddonMenu->GetItemCount();
383     m_aMenuItemHandlerVector.reserve(nItemCount);
384     ::rtl::OUString aItemCommand;
385     for ( sal_uInt16 i = 0; i < nItemCount; i++ )
386     {
387         sal_uInt16 nItemId = FillItemCommand(aItemCommand,pAddonMenu, i );
388 
389         PopupMenu* pPopupMenu = pAddonMenu->GetPopupMenu( nItemId );
390         if ( pPopupMenu )
391         {
392             // #110897#
393             // MenuManager* pSubMenuManager = new MenuManager( rFrame, pPopupMenu, bDeleteChildren, bDeleteChildren );
394             AddMenu(pPopupMenu,aItemCommand,nItemId,bDeleteChildren,bDeleteChildren);
395         }
396         else
397         {
398             if ( pAddonMenu->GetItemType( i ) != MENUITEM_SEPARATOR )
399             {
400                 MenuConfiguration::Attributes* pAddonAttributes = (MenuConfiguration::Attributes *)(pAddonMenu->GetUserValue( nItemId ));
401                 REFERENCE< XDISPATCH > aXDispatchRef;
402                 MenuItemHandler* pMenuItemHandler = new MenuItemHandler( nItemId, NULL, aXDispatchRef );
403 
404                 if ( pAddonAttributes )
405                 {
406                     // read additional attributes from attributes struct and AddonMenu implementation will delete all attributes itself!!
407                     pMenuItemHandler->aTargetFrame = pAddonAttributes->aTargetFrame;
408                 }
409 
410                 m_aMenuItemHandlerVector.push_back( pMenuItemHandler );
411             }
412         }
413     }
414 
415     SetHdl();
416 }
417 #endif
418 
419 void MenuManager::SetHdl()
420 {
421     m_pVCLMenu->SetHighlightHdl( LINK( this, MenuManager, Highlight ));
422     m_pVCLMenu->SetActivateHdl( LINK( this, MenuManager, Activate ));
423     m_pVCLMenu->SetDeactivateHdl( LINK( this, MenuManager, Deactivate ));
424     m_pVCLMenu->SetSelectHdl( LINK( this, MenuManager, Select ));
425 
426     if ( mxServiceFactory.is() )
427         m_xURLTransformer.set( mxServiceFactory->createInstance(SERVICENAME_URLTRANSFORMER),UNO_QUERY );
428 }
429 
430 MenuManager::~MenuManager()
431 {
432     std::vector< MenuItemHandler* >::iterator p;
433     for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
434     {
435         MenuItemHandler* pItemHandler = *p;
436         pItemHandler->xMenuItemDispatch.clear();
437         if ( pItemHandler->pSubMenuManager )
438             SAL_STATIC_CAST( ::com::sun::star::uno::XInterface*, (OWeakObject*)pItemHandler->pSubMenuManager )->release();
439         delete pItemHandler;
440     }
441 
442     if ( m_bDeleteMenu )
443         delete m_pVCLMenu;
444 }
445 
446 
447 MenuManager::MenuItemHandler* MenuManager::GetMenuItemHandler( sal_uInt16 nItemId )
448 {
449     ResetableGuard aGuard( m_aLock );
450 
451     std::vector< MenuItemHandler* >::iterator p;
452     for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
453     {
454         MenuItemHandler* pItemHandler = *p;
455         if ( pItemHandler->nItemId == nItemId )
456             return pItemHandler;
457     }
458 
459     return 0;
460 }
461 
462 
463 void SAL_CALL MenuManager::statusChanged( const FEATURSTATEEVENT& Event )
464 throw ( RuntimeException )
465 {
466     ::rtl::OUString aFeatureURL = Event.FeatureURL.Complete;
467     MenuItemHandler* pStatusChangedMenu = NULL;
468 
469     {
470         ResetableGuard aGuard( m_aLock );
471 
472         std::vector< MenuItemHandler* >::iterator p;
473         for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
474         {
475             MenuItemHandler* pMenuItemHandler = *p;
476             if ( pMenuItemHandler->aMenuItemURL == aFeatureURL )
477             {
478                 pStatusChangedMenu = pMenuItemHandler;
479                 break;
480             }
481         }
482     }
483 
484     if ( pStatusChangedMenu )
485     {
486         OGuard  aSolarGuard( Application::GetSolarMutex() );
487         {
488             ResetableGuard aGuard( m_aLock );
489 
490             sal_Bool bSetCheckmark      = sal_False;
491             sal_Bool bCheckmark         = sal_False;
492             sal_Bool bMenuItemEnabled   = m_pVCLMenu->IsItemEnabled( pStatusChangedMenu->nItemId );
493 
494             if ( Event.IsEnabled != bMenuItemEnabled )
495                 m_pVCLMenu->EnableItem( pStatusChangedMenu->nItemId, Event.IsEnabled );
496 
497             if ( Event.State >>= bCheckmark )
498                  bSetCheckmark = sal_True;
499 
500             if ( bSetCheckmark )
501                 m_pVCLMenu->CheckItem( pStatusChangedMenu->nItemId, bCheckmark );
502         }
503 
504         if ( Event.Requery )
505         {
506             URL aTargetURL;
507             aTargetURL.Complete = pStatusChangedMenu->aMenuItemURL;
508 
509             // #110897#
510             m_xURLTransformer->parseStrict( aTargetURL );
511 
512             REFERENCE< XDISPATCHPROVIDER > xDispatchProvider( m_xFrame, UNO_QUERY );
513             REFERENCE< XDISPATCH > xMenuItemDispatch = xDispatchProvider->queryDispatch(
514                                                             aTargetURL, ::rtl::OUString(), 0 );
515 
516             if ( xMenuItemDispatch.is() )
517             {
518                 pStatusChangedMenu->xMenuItemDispatch   = xMenuItemDispatch;
519                 pStatusChangedMenu->aMenuItemURL        = aTargetURL.Complete;
520                 xMenuItemDispatch->addStatusListener( SAL_STATIC_CAST( XSTATUSLISTENER*, this ), aTargetURL );
521             }
522         }
523     }
524 }
525 
526 
527 void MenuManager::RemoveListener()
528 {
529     ResetableGuard aGuard( m_aLock );
530     ClearMenuDispatch();
531 }
532 
533 void MenuManager::ClearMenuDispatch(const EVENTOBJECT& Source,bool _bRemoveOnly)
534 {
535     // disposing called from parent dispatcher
536     // remove all listener to prepare shutdown
537 
538     // #110897#
539     std::vector< MenuItemHandler* >::iterator p;
540     for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
541     {
542         MenuItemHandler* pItemHandler = *p;
543         if ( pItemHandler->xMenuItemDispatch.is() )
544         {
545             URL aTargetURL;
546             aTargetURL.Complete = pItemHandler->aMenuItemURL;
547             m_xURLTransformer->parseStrict( aTargetURL );
548 
549             pItemHandler->xMenuItemDispatch->removeStatusListener(
550                 SAL_STATIC_CAST( XSTATUSLISTENER*, this ), aTargetURL );
551         }
552 
553         pItemHandler->xMenuItemDispatch.clear();
554         if ( pItemHandler->pSubMenuManager )
555         {
556             if ( _bRemoveOnly )
557                 pItemHandler->pSubMenuManager->RemoveListener();
558             else
559                 pItemHandler->pSubMenuManager->disposing( Source );
560         }
561     }
562 }
563 
564 
565 void SAL_CALL MenuManager::disposing( const EVENTOBJECT& Source ) throw ( RUNTIMEEXCEPTION )
566 {
567     if ( Source.Source == m_xFrame )
568     {
569         ResetableGuard aGuard( m_aLock );
570         ClearMenuDispatch(Source,false);
571     }
572     else
573     {
574         // disposing called from menu item dispatcher, remove listener
575         MenuItemHandler* pMenuItemDisposing = NULL;
576 
577         {
578             ResetableGuard aGuard( m_aLock );
579 
580             std::vector< MenuItemHandler* >::iterator p;
581             for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
582             {
583                 MenuItemHandler* pMenuItemHandler = *p;
584                 if ( pMenuItemHandler->xMenuItemDispatch == Source.Source )
585                 {
586                     pMenuItemDisposing = pMenuItemHandler;
587                     break;
588                 }
589             }
590 
591             if ( pMenuItemDisposing )
592             {
593                 URL aTargetURL;
594                 aTargetURL.Complete = pMenuItemDisposing->aMenuItemURL;
595 
596                 // #110897#
597                 m_xURLTransformer->parseStrict( aTargetURL );
598 
599                 pMenuItemDisposing->xMenuItemDispatch->removeStatusListener(SAL_STATIC_CAST( XSTATUSLISTENER*, this ), aTargetURL );
600                 pMenuItemDisposing->xMenuItemDispatch.clear();
601             }
602         }
603     }
604 }
605 
606 
607 void MenuManager::UpdateSpecialFileMenu( Menu* pMenu )
608 {
609     // update picklist
610     Sequence< Sequence< PropertyValue > > aHistoryList = SvtHistoryOptions().GetList( ePICKLIST );
611     ::std::vector< MenuItemHandler* > aNewPickVector;
612     Reference< XStringWidth > xStringLength( new StringLength );
613 
614     sal_uInt16  nPickItemId = START_ITEMID_PICKLIST;
615     int     nPickListMenuItems = ( aHistoryList.getLength() > 99 ) ? 99 : aHistoryList.getLength();
616 
617     aNewPickVector.reserve(nPickListMenuItems);
618     for ( int i = 0; i < nPickListMenuItems; i++ )
619     {
620         Sequence< PropertyValue > aPickListEntry = aHistoryList[i];
621 
622         REFERENCE< XDISPATCH > aXDispatchRef;
623         MenuItemHandler* pNewMenuItemHandler = new MenuItemHandler(
624                                                     nPickItemId++,
625                                                     NULL,
626                                                     aXDispatchRef );
627 
628         for ( int j = 0; j < aPickListEntry.getLength(); j++ )
629         {
630             Any a = aPickListEntry[j].Value;
631 
632             if ( aPickListEntry[j].Name == HISTORY_PROPERTYNAME_URL )
633                 a >>= pNewMenuItemHandler->aMenuItemURL;
634             else if ( aPickListEntry[j].Name == HISTORY_PROPERTYNAME_FILTER )
635                 a >>= pNewMenuItemHandler->aFilter;
636             else if ( aPickListEntry[j].Name == HISTORY_PROPERTYNAME_TITLE )
637                 a >>= pNewMenuItemHandler->aTitle;
638             else if ( aPickListEntry[j].Name == HISTORY_PROPERTYNAME_PASSWORD )
639                 a >>= pNewMenuItemHandler->aPassword;
640         }
641 
642         aNewPickVector.push_back( pNewMenuItemHandler );
643     }
644 
645     if ( !aNewPickVector.empty() )
646     {
647         URL aTargetURL;
648         REFERENCE< XDISPATCHPROVIDER > xDispatchProvider( m_xFrame, UNO_QUERY );
649 
650         // #110897#
651         REFERENCE< XDISPATCH > xMenuItemDispatch;
652 
653         static const ::rtl::OUString s_sDefault(RTL_CONSTASCII_USTRINGPARAM("_default"));
654         // query for dispatcher
655         std::vector< MenuItemHandler* >::iterator p;
656         for ( p = aNewPickVector.begin(); p != aNewPickVector.end(); p++ )
657         {
658             MenuItemHandler* pMenuItemHandler = *p;
659 
660             aTargetURL.Complete = pMenuItemHandler->aMenuItemURL;
661             m_xURLTransformer->parseStrict( aTargetURL );
662 
663             if ( !xMenuItemDispatch.is() )
664             {
665                 // attention: this code assume that "_blank" can only be consumed by desktop service
666                 xMenuItemDispatch = xDispatchProvider->queryDispatch( aTargetURL, s_sDefault, 0 );
667             }
668 
669             if ( xMenuItemDispatch.is() )
670             {
671                 pMenuItemHandler->xMenuItemDispatch = xMenuItemDispatch;
672                 pMenuItemHandler->aMenuItemURL      = aTargetURL.Complete;
673             }
674         }
675 
676         {
677             ResetableGuard aGuard( m_aLock );
678 
679             int nRemoveItemCount = 0;
680             int nItemCount       = pMenu->GetItemCount();
681 
682             if ( nItemCount > 0 )
683             {
684                 // remove all old picklist entries from menu
685                 sal_uInt16 nPos = pMenu->GetItemPos( START_ITEMID_PICKLIST );
686                 for ( sal_uInt16 n = nPos; n < pMenu->GetItemCount(); )
687                 {
688                     pMenu->RemoveItem( n );
689                     ++nRemoveItemCount;
690                 }
691 
692                 if ( pMenu->GetItemType( pMenu->GetItemCount()-1 ) == MENUITEM_SEPARATOR )
693                     pMenu->RemoveItem( pMenu->GetItemCount()-1 );
694 
695                 // remove all old picklist entries from menu handler
696                 if ( nRemoveItemCount > 0 )
697                 {
698                     for( sal_uInt32 nIndex = m_aMenuItemHandlerVector.size() - nRemoveItemCount;
699                          nIndex < m_aMenuItemHandlerVector.size();  )
700                     {
701                         delete m_aMenuItemHandlerVector.at( nIndex );
702                         m_aMenuItemHandlerVector.erase( m_aMenuItemHandlerVector.begin() + nIndex );
703                     }
704                 }
705             }
706 
707             // append new picklist menu entries
708             aNewPickVector.reserve(aNewPickVector.size());
709             pMenu->InsertSeparator();
710             const sal_uInt32 nCount = aNewPickVector.size();
711             for ( sal_uInt32 i = 0; i < nCount; i++ )
712             {
713                 char menuShortCut[5] = "~n: ";
714 
715                 ::rtl::OUString aMenuShortCut;
716                 if ( i <= 9 )
717                 {
718                     if ( i == 9 )
719                         aMenuShortCut = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "1~0: " ));
720                     else
721                     {
722                         menuShortCut[1] = (char)( '1' + i );
723                         aMenuShortCut = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( menuShortCut ));
724                     }
725                 }
726                 else
727                 {
728                     aMenuShortCut = rtl::OUString::valueOf((sal_Int32)( i + 1 ));
729                     aMenuShortCut += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ": " ));
730                 }
731 
732                 // Abbreviate URL
733                 rtl::OUString   aURLString( aNewPickVector.at( i )->aMenuItemURL );
734                 rtl::OUString   aTipHelpText;
735                 rtl::OUString   aMenuTitle;
736                 INetURLObject   aURL( aURLString );
737 
738                 if ( aURL.GetProtocol() == INET_PROT_FILE )
739                 {
740                     // Do handle file URL differently => convert it to a system
741                     // path and abbreviate it with a special function:
742                     String aFileSystemPath( aURL.getFSysPath( INetURLObject::FSYS_DETECT ) );
743 
744                     ::rtl::OUString aSystemPath( aFileSystemPath );
745                     ::rtl::OUString aCompactedSystemPath;
746 
747                     aTipHelpText = aSystemPath;
748                     oslFileError nError = osl_abbreviateSystemPath( aSystemPath.pData, &aCompactedSystemPath.pData, 46, NULL );
749                     if ( !nError )
750                         aMenuTitle = String( aCompactedSystemPath );
751                     else
752                         aMenuTitle = aSystemPath;
753                 }
754                 else
755                 {
756                     // Use INetURLObject to abbreviate all other URLs
757                     String  aShortURL;
758                     aShortURL = aURL.getAbbreviated( xStringLength, 46, INetURLObject::DECODE_UNAMBIGUOUS );
759                     aMenuTitle += aShortURL;
760                     aTipHelpText = aURLString;
761                 }
762 
763                 ::rtl::OUString aTitle( aMenuShortCut + aMenuTitle );
764 
765                 MenuItemHandler* pMenuItemHandler = aNewPickVector.at( i );
766                 pMenu->InsertItem( pMenuItemHandler->nItemId, aTitle );
767                 pMenu->SetTipHelpText( pMenuItemHandler->nItemId, aTipHelpText );
768                 m_aMenuItemHandlerVector.push_back( pMenuItemHandler );
769             }
770         }
771     }
772 }
773 
774 void MenuManager::UpdateSpecialWindowMenu( Menu* pMenu,const Reference< XMultiServiceFactory >& xServiceFactory,framework::IMutex& _rMutex )
775 {
776     // update window list
777     ::std::vector< ::rtl::OUString > aNewWindowListVector;
778 
779     // #110897#
780     Reference< XDesktop > xDesktop( xServiceFactory->createInstance( SERVICENAME_DESKTOP ), UNO_QUERY );
781 
782     sal_uInt16  nActiveItemId = 0;
783     sal_uInt16  nItemId = START_ITEMID_WINDOWLIST;
784 
785     if ( xDesktop.is() )
786     {
787         Reference< XFramesSupplier > xTasksSupplier( xDesktop, UNO_QUERY );
788         Reference< XFrame > xCurrentFrame = xDesktop->getCurrentFrame();
789         Reference< XIndexAccess > xList( xTasksSupplier->getFrames(), UNO_QUERY );
790         sal_Int32 nCount = xList->getCount();
791         aNewWindowListVector.reserve(nCount);
792         for (sal_Int32 i=0; i<nCount; ++i )
793         {
794             Reference< XFrame > xFrame;
795             xList->getByIndex(i) >>= xFrame;
796 
797             if (xFrame.is())
798             {
799                 if ( xFrame == xCurrentFrame )
800                     nActiveItemId = nItemId;
801 
802                 Window* pWin = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() );
803                 if ( pWin && pWin->IsVisible() )
804                 {
805                     aNewWindowListVector.push_back( pWin->GetText() );
806                     ++nItemId;
807                 }
808             }
809         }
810     }
811 
812     {
813         ResetableGuard aGuard( _rMutex );
814 
815         int nItemCount = pMenu->GetItemCount();
816 
817         if ( nItemCount > 0 )
818         {
819             // remove all old window list entries from menu
820             sal_uInt16 nPos = pMenu->GetItemPos( START_ITEMID_WINDOWLIST );
821             for ( sal_uInt16 n = nPos; n < pMenu->GetItemCount(); )
822                 pMenu->RemoveItem( n );
823 
824             if ( pMenu->GetItemType( pMenu->GetItemCount()-1 ) == MENUITEM_SEPARATOR )
825                 pMenu->RemoveItem( pMenu->GetItemCount()-1 );
826         }
827 
828         if ( !aNewWindowListVector.empty() )
829         {
830             // append new window list entries to menu
831             pMenu->InsertSeparator();
832             nItemId = START_ITEMID_WINDOWLIST;
833             const sal_uInt32 nCount = aNewWindowListVector.size();
834             for ( sal_uInt32 i = 0; i < nCount; i++ )
835             {
836                 pMenu->InsertItem( nItemId, aNewWindowListVector.at( i ), MIB_RADIOCHECK );
837                 if ( nItemId == nActiveItemId )
838                     pMenu->CheckItem( nItemId );
839                 ++nItemId;
840             }
841         }
842     }
843 }
844 
845 
846 void MenuManager::CreatePicklistArguments( Sequence< PropertyValue >& aArgsList, const MenuItemHandler* pMenuItemHandler )
847 {
848     int NUM_OF_PICKLIST_ARGS = 3;
849 
850     Any a;
851     aArgsList.realloc( NUM_OF_PICKLIST_ARGS );
852 
853     aArgsList[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FileName" ));
854     a <<= pMenuItemHandler->aMenuItemURL;
855     aArgsList[0].Value = a;
856 
857     aArgsList[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Referer" ));
858     a <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SFX_REFERER_USER ));
859     aArgsList[1].Value = a;
860 
861     ::rtl::OUString aFilter( pMenuItemHandler->aFilter );
862 
863     sal_Int32 nPos = aFilter.indexOf( '|' );
864     if ( nPos >= 0 )
865     {
866         ::rtl::OUString aFilterOptions;
867 
868         if ( nPos < ( aFilter.getLength() - 1 ) )
869             aFilterOptions = aFilter.copy( nPos+1 );
870 
871         aArgsList[2].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterOptions" ));
872         a <<= aFilterOptions;
873         aArgsList[2].Value = a;
874 
875         aFilter = aFilter.copy( 0, nPos-1 );
876         aArgsList.realloc( ++NUM_OF_PICKLIST_ARGS );
877     }
878 
879     aArgsList[NUM_OF_PICKLIST_ARGS-1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ));
880     a <<= aFilter;
881     aArgsList[NUM_OF_PICKLIST_ARGS-1].Value = a;
882 }
883 
884 
885 //_________________________________________________________________________________________________________________
886 // vcl handler
887 //_________________________________________________________________________________________________________________
888 
889 IMPL_LINK( MenuManager, Activate, Menu *, pMenu )
890 {
891     if ( pMenu == m_pVCLMenu )
892     {
893         // set/unset hiding disabled menu entries
894         sal_Bool bDontHide          = SvtMenuOptions().IsEntryHidingEnabled();
895         const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
896         sal_Bool bShowMenuImages    = rSettings.GetUseImagesInMenus();
897 
898         sal_uInt16 nFlag = pMenu->GetMenuFlags();
899         if ( bDontHide )
900             nFlag &= ~MENU_FLAG_HIDEDISABLEDENTRIES;
901         else
902             nFlag |= MENU_FLAG_HIDEDISABLEDENTRIES;
903         pMenu->SetMenuFlags( nFlag );
904 
905         if ( m_bActive )
906             return 0;
907 
908         m_bActive = sal_True;
909 
910         ::rtl::OUString aCommand( m_aMenuItemCommand );
911         if ( m_aMenuItemCommand.matchIgnoreAsciiCase( UNO_COMMAND, 0 ))
912         {
913             // Remove protocol part from command so we can use an easier comparision method
914             aCommand = aCommand.copy( UNO_COMMAND.getLength() );
915         }
916 
917         if ( m_aMenuItemCommand == aSpecialFileMenu ||
918              m_aMenuItemCommand == aSlotSpecialFileMenu ||
919              aCommand == aSpecialFileCommand )
920             UpdateSpecialFileMenu( pMenu );
921         else if ( m_aMenuItemCommand == aSpecialWindowMenu ||
922                   m_aMenuItemCommand == aSlotSpecialWindowMenu ||
923                   aCommand == aSpecialWindowCommand )
924                   UpdateSpecialWindowMenu( pMenu,getServiceFactory(),m_aLock );
925 
926         // Check if some modes have changed so we have to update our menu images
927         sal_Bool bIsHiContrast = rSettings.GetHighContrastMode();
928 
929         if ( m_bWasHiContrast != bIsHiContrast || bShowMenuImages != m_bShowMenuImages )
930         {
931             // The mode changed so we have to replace all images
932             m_bWasHiContrast    = bIsHiContrast;
933             m_bShowMenuImages   = bShowMenuImages;
934             FillMenuImages(m_xFrame,pMenu,bIsHiContrast,bShowMenuImages);
935         }
936 
937         if ( m_bInitialized )
938             return 0;
939         else
940         {
941             URL aTargetURL;
942 
943             // #110897#
944             ResetableGuard aGuard( m_aLock );
945 
946             REFERENCE< XDISPATCHPROVIDER > xDispatchProvider( m_xFrame, UNO_QUERY );
947             if ( xDispatchProvider.is() )
948             {
949                 std::vector< MenuItemHandler* >::iterator p;
950                 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
951                 {
952                     MenuItemHandler* pMenuItemHandler = *p;
953                     if ( pMenuItemHandler &&
954                          pMenuItemHandler->pSubMenuManager == 0 &&
955                          !pMenuItemHandler->xMenuItemDispatch.is() )
956                     {
957                         // There is no dispatch mechanism for the special window list menu items,
958                         // because they are handled directly through XFrame->activate!!!
959                         if ( pMenuItemHandler->nItemId < START_ITEMID_WINDOWLIST ||
960                              pMenuItemHandler->nItemId > END_ITEMID_WINDOWLIST )
961                         {
962                             ::rtl::OUString aItemCommand = pMenu->GetItemCommand( pMenuItemHandler->nItemId );
963                             if ( !aItemCommand.getLength() )
964                             {
965                                 const static ::rtl::OUString aSlotString( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
966                                 aItemCommand = aSlotString;
967                                 aItemCommand += ::rtl::OUString::valueOf( (sal_Int32)pMenuItemHandler->nItemId );
968                                 pMenu->SetItemCommand( pMenuItemHandler->nItemId, aItemCommand );
969                             }
970 
971                             aTargetURL.Complete = aItemCommand;
972 
973                             m_xURLTransformer->parseStrict( aTargetURL );
974 
975                             REFERENCE< XDISPATCH > xMenuItemDispatch;
976                             if ( m_bIsBookmarkMenu )
977                                 xMenuItemDispatch = xDispatchProvider->queryDispatch( aTargetURL, pMenuItemHandler->aTargetFrame, 0 );
978                             else
979                                 xMenuItemDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
980 
981                             if ( xMenuItemDispatch.is() )
982                             {
983                                 pMenuItemHandler->xMenuItemDispatch = xMenuItemDispatch;
984                                 pMenuItemHandler->aMenuItemURL      = aTargetURL.Complete;
985                                 xMenuItemDispatch->addStatusListener( SAL_STATIC_CAST( XSTATUSLISTENER*, this ), aTargetURL );
986                             }
987                             else
988                                 pMenu->EnableItem( pMenuItemHandler->nItemId, sal_False );
989                         }
990                     }
991                 }
992             }
993         }
994     }
995 
996     return 1;
997 }
998 
999 
1000 IMPL_LINK( MenuManager, Deactivate, Menu *, pMenu )
1001 {
1002     if ( pMenu == m_pVCLMenu )
1003         m_bActive = sal_False;
1004 
1005     return 1;
1006 }
1007 
1008 
1009 IMPL_LINK( MenuManager, Select, Menu *, pMenu )
1010 {
1011     URL                     aTargetURL;
1012     Sequence<PropertyValue> aArgs;
1013     REFERENCE< XDISPATCH >  xDispatch;
1014 
1015     {
1016         ResetableGuard aGuard( m_aLock );
1017 
1018         sal_uInt16 nCurItemId = pMenu->GetCurItemId();
1019         if ( pMenu == m_pVCLMenu &&
1020              pMenu->GetItemType( nCurItemId ) != MENUITEM_SEPARATOR )
1021         {
1022             if ( nCurItemId >= START_ITEMID_WINDOWLIST &&
1023                  nCurItemId <= END_ITEMID_WINDOWLIST )
1024             {
1025                 // window list menu item selected
1026 
1027                 // #110897#
1028                 // Reference< XFramesSupplier > xDesktop( ::comphelper::getProcessServiceFactory()->createInstance(
1029                 //  DESKTOP_SERVICE ), UNO_QUERY );
1030                 Reference< XFramesSupplier > xDesktop( getServiceFactory()->createInstance( SERVICENAME_DESKTOP ), UNO_QUERY );
1031 
1032                 if ( xDesktop.is() )
1033                 {
1034                     sal_uInt16 nTaskId = START_ITEMID_WINDOWLIST;
1035                     Reference< XIndexAccess > xList( xDesktop->getFrames(), UNO_QUERY );
1036                     sal_Int32 nCount = xList->getCount();
1037                     for ( sal_Int32 i=0; i<nCount; ++i )
1038                     {
1039                         Reference< XFrame > xFrame;
1040                         xList->getByIndex(i) >>= xFrame;
1041 
1042                         if ( xFrame.is() && nTaskId == nCurItemId )
1043                         {
1044                             Window* pWin = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() );
1045                             pWin->GrabFocus();
1046                             pWin->ToTop( TOTOP_RESTOREWHENMIN );
1047                             break;
1048                         }
1049 
1050                         nTaskId++;
1051                     }
1052                 }
1053             }
1054             else
1055             {
1056                 MenuItemHandler* pMenuItemHandler = GetMenuItemHandler( nCurItemId );
1057                 if ( pMenuItemHandler && pMenuItemHandler->xMenuItemDispatch.is() )
1058                 {
1059                     aTargetURL.Complete = pMenuItemHandler->aMenuItemURL;
1060                     m_xURLTransformer->parseStrict( aTargetURL );
1061 
1062                     if ( nCurItemId >= START_ITEMID_PICKLIST &&
1063                          nCurItemId <  START_ITEMID_WINDOWLIST )
1064                     {
1065                         // picklist menu item selected
1066                         CreatePicklistArguments( aArgs, pMenuItemHandler );
1067                     }
1068                     else if ( m_bIsBookmarkMenu )
1069                     {
1070                         // bookmark menu item selected
1071                         aArgs.realloc( 1 );
1072                         aArgs[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Referer" ));
1073                         aArgs[0].Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SFX_REFERER_USER ));
1074                     }
1075 
1076                     xDispatch = pMenuItemHandler->xMenuItemDispatch;
1077                 }
1078             }
1079         }
1080     }
1081 
1082     if ( xDispatch.is() )
1083         xDispatch->dispatch( aTargetURL, aArgs );
1084 
1085     return 1;
1086 }
1087 
1088 
1089 IMPL_LINK( MenuManager, Highlight, Menu *, EMPTYARG )
1090 {
1091     return 0;
1092 }
1093 
1094 // #110897#
1095 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& MenuManager::getServiceFactory()
1096 {
1097     // #110897#
1098     return mxServiceFactory;
1099 }
1100 
1101 void MenuManager::AddMenu(PopupMenu* _pPopupMenu,const ::rtl::OUString& _sItemCommand,sal_uInt16 _nItemId,sal_Bool _bDelete,sal_Bool _bDeleteChildren)
1102 {
1103     MenuManager* pSubMenuManager = new MenuManager( getServiceFactory(), m_xFrame, _pPopupMenu, _bDelete, _bDeleteChildren );
1104 
1105     // store menu item command as we later have to know which menu is active (see Activate handler)
1106     pSubMenuManager->m_aMenuItemCommand = _sItemCommand;
1107 
1108     REFERENCE< XDISPATCH > aXDispatchRef;
1109     MenuItemHandler* pMenuItemHandler = new MenuItemHandler(
1110                                                 _nItemId,
1111                                                 pSubMenuManager,
1112                                                 aXDispatchRef );
1113     m_aMenuItemHandlerVector.push_back( pMenuItemHandler );
1114 }
1115 
1116 sal_uInt16 MenuManager::FillItemCommand(::rtl::OUString& _rItemCommand,Menu* _pMenu,sal_uInt16 _nIndex) const
1117 {
1118     sal_uInt16 nItemId = _pMenu->GetItemId( _nIndex );
1119 
1120     _rItemCommand = _pMenu->GetItemCommand( nItemId );
1121     if ( !_rItemCommand.getLength() )
1122     {
1123         const static ::rtl::OUString aSlotString( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
1124         _rItemCommand = aSlotString;
1125         _rItemCommand += ::rtl::OUString::valueOf( (sal_Int32)nItemId );
1126         _pMenu->SetItemCommand( nItemId, _rItemCommand );
1127     }
1128     return nItemId;
1129 }
1130 void MenuManager::FillMenuImages(Reference< XFrame >& _xFrame,Menu* _pMenu,sal_Bool bIsHiContrast,sal_Bool bShowMenuImages)
1131 {
1132     AddonsOptions       aAddonOptions;
1133 
1134     for ( sal_uInt16 nPos = 0; nPos < _pMenu->GetItemCount(); nPos++ )
1135     {
1136         sal_uInt16 nId = _pMenu->GetItemId( nPos );
1137         if ( _pMenu->GetItemType( nPos ) != MENUITEM_SEPARATOR )
1138         {
1139             bool bTmpShowMenuImages( bShowMenuImages );
1140             MenuItemBits nBits =  _pMenu->GetItemBits( nId );
1141             // overwrite the default?
1142             if ( nBits )
1143                 bTmpShowMenuImages = ( ( nBits & MIB_ICON ) == MIB_ICON );
1144 
1145             if ( bTmpShowMenuImages )
1146             {
1147                 sal_Bool        bImageSet = sal_False;
1148                 ::rtl::OUString aImageId;
1149 
1150                 ::framework::MenuConfiguration::Attributes* pMenuAttributes =
1151                     (::framework::MenuConfiguration::Attributes*)_pMenu->GetUserValue( nId );
1152 
1153                 if ( pMenuAttributes )
1154                     aImageId = pMenuAttributes->aImageId; // Retrieve image id from menu attributes
1155 
1156                 if ( aImageId.getLength() > 0 )
1157                 {
1158                     Image aImage = GetImageFromURL( _xFrame, aImageId, sal_False, bIsHiContrast );
1159                     if ( !!aImage )
1160                     {
1161                         bImageSet = sal_True;
1162                         _pMenu->SetItemImage( nId, aImage );
1163                     }
1164                 }
1165 
1166                 if ( !bImageSet )
1167                 {
1168                     rtl::OUString aMenuItemCommand = _pMenu->GetItemCommand( nId );
1169                     Image aImage = GetImageFromURL( _xFrame, aMenuItemCommand, sal_False, bIsHiContrast );
1170                     if ( !aImage )
1171                         aImage = aAddonOptions.GetImageFromURL( aMenuItemCommand, sal_False, bIsHiContrast );
1172 
1173                     _pMenu->SetItemImage( nId, aImage );
1174                 }
1175             }
1176             else
1177                 _pMenu->SetItemImage( nId, Image() );
1178         }
1179     }
1180 }
1181 }
1182