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