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