xref: /trunk/main/framework/source/classes/menumanager.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956) !
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/helper/vclunohelper.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         {
101             return aString.getLength();
102         }
103 };
104 
105 namespace framework
106 {
107 
108 // special menu ids/command ids for dynamic popup menus
109 #define SID_SFX_START           5000
110 #define SID_NEWDOCDIRECT        (SID_SFX_START + 537)
111 #define SID_AUTOPILOTMENU       (SID_SFX_START + 1381)
112 #define SID_PICKLIST            (SID_SFX_START + 510)
113 #define SID_MDIWINDOWLIST       (SID_SFX_START + 610)
114 #define SID_ADDONLIST           (SID_SFX_START + 1677)
115 #define SID_HELPMENU            (SID_SFX_START + 410)
116 
117 #define SFX_REFERER_USER        "private:user"
118 
119 const ::rtl::OUString aSlotNewDocDirect( RTL_CONSTASCII_USTRINGPARAM( "slot:5537" ));
120 const ::rtl::OUString aSlotAutoPilot( RTL_CONSTASCII_USTRINGPARAM( "slot:6381" ));
121 
122 const ::rtl::OUString aSpecialFileMenu( RTL_CONSTASCII_USTRINGPARAM( "file" ));
123 const ::rtl::OUString aSpecialWindowMenu( RTL_CONSTASCII_USTRINGPARAM( "window" ));
124 const ::rtl::OUString aSlotSpecialFileMenu( RTL_CONSTASCII_USTRINGPARAM( "slot:5510" ));
125 const ::rtl::OUString aSlotSpecialWindowMenu( RTL_CONSTASCII_USTRINGPARAM( "slot:5610" ));
126 const ::rtl::OUString aSlotSpecialToolsMenu( RTL_CONSTASCII_USTRINGPARAM( "slot:6677" ));
127 
128 // special uno commands for picklist and window list
129 const ::rtl::OUString aSpecialFileCommand( RTL_CONSTASCII_USTRINGPARAM( "PickList" ));
130 const ::rtl::OUString aSpecialWindowCommand( RTL_CONSTASCII_USTRINGPARAM( "WindowList" ));
131 
132 const ::rtl::OUString UNO_COMMAND( RTL_CONSTASCII_USTRINGPARAM( ".uno:" ));
133 
134 // #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)135 MenuManager::MenuManager(
136     const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory,
137     REFERENCE< XFRAME >& rFrame, Menu* pMenu, sal_Bool bDelete, sal_Bool bDeleteChildren )
138 :   // #110897#
139     ThreadHelpBase( &Application::GetSolarMutex() ),
140     mxServiceFactory(xServiceFactory)
141 {
142     m_bActive           = sal_False;
143     m_bDeleteMenu       = bDelete;
144     m_bDeleteChildren   = bDeleteChildren;
145     m_pVCLMenu          = pMenu;
146     m_xFrame            = rFrame;
147     m_bInitialized      = sal_False;
148     m_bIsBookmarkMenu   = sal_False;
149 
150     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, xServiceFactory );
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 
SetHdl()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 
~MenuManager()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 
GetMenuItemHandler(sal_uInt16 nItemId)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 
statusChanged(const FEATURSTATEEVENT & Event)459 void SAL_CALL MenuManager::statusChanged( const FEATURSTATEEVENT& Event )
460 {
461     ::rtl::OUString aFeatureURL = Event.FeatureURL.Complete;
462     MenuItemHandler* pStatusChangedMenu = NULL;
463 
464     {
465         ResetableGuard aGuard( m_aLock );
466 
467         std::vector< MenuItemHandler* >::iterator p;
468         for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
469         {
470             MenuItemHandler* pMenuItemHandler = *p;
471             if ( pMenuItemHandler->aMenuItemURL == aFeatureURL )
472             {
473                 pStatusChangedMenu = pMenuItemHandler;
474                 break;
475             }
476         }
477     }
478 
479     if ( pStatusChangedMenu )
480     {
481         OGuard  aSolarGuard( Application::GetSolarMutex() );
482         {
483             ResetableGuard aGuard( m_aLock );
484 
485             sal_Bool bSetCheckmark      = sal_False;
486             sal_Bool bCheckmark         = sal_False;
487             sal_Bool bMenuItemEnabled   = m_pVCLMenu->IsItemEnabled( pStatusChangedMenu->nItemId );
488 
489             if ( Event.IsEnabled != bMenuItemEnabled )
490                 m_pVCLMenu->EnableItem( pStatusChangedMenu->nItemId, Event.IsEnabled );
491 
492             if ( Event.State >>= bCheckmark )
493                  bSetCheckmark = sal_True;
494 
495             if ( bSetCheckmark )
496                 m_pVCLMenu->CheckItem( pStatusChangedMenu->nItemId, bCheckmark );
497         }
498 
499         if ( Event.Requery )
500         {
501             URL aTargetURL;
502             aTargetURL.Complete = pStatusChangedMenu->aMenuItemURL;
503 
504             // #110897#
505             m_xURLTransformer->parseStrict( aTargetURL );
506 
507             REFERENCE< XDISPATCHPROVIDER > xDispatchProvider( m_xFrame, UNO_QUERY );
508             REFERENCE< XDISPATCH > xMenuItemDispatch = xDispatchProvider->queryDispatch(
509                                                             aTargetURL, ::rtl::OUString(), 0 );
510 
511             if ( xMenuItemDispatch.is() )
512             {
513                 pStatusChangedMenu->xMenuItemDispatch   = xMenuItemDispatch;
514                 pStatusChangedMenu->aMenuItemURL        = aTargetURL.Complete;
515                 xMenuItemDispatch->addStatusListener( SAL_STATIC_CAST( XSTATUSLISTENER*, this ), aTargetURL );
516             }
517         }
518     }
519 }
520 
521 
RemoveListener()522 void MenuManager::RemoveListener()
523 {
524     ResetableGuard aGuard( m_aLock );
525     ClearMenuDispatch();
526 }
527 
ClearMenuDispatch(const EVENTOBJECT & Source,bool _bRemoveOnly)528 void MenuManager::ClearMenuDispatch(const EVENTOBJECT& Source,bool _bRemoveOnly)
529 {
530     // disposing called from parent dispatcher
531     // remove all listener to prepare shutdown
532 
533     // #110897#
534     std::vector< MenuItemHandler* >::iterator p;
535     for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
536     {
537         MenuItemHandler* pItemHandler = *p;
538         if ( pItemHandler->xMenuItemDispatch.is() )
539         {
540             URL aTargetURL;
541             aTargetURL.Complete = pItemHandler->aMenuItemURL;
542             m_xURLTransformer->parseStrict( aTargetURL );
543 
544             pItemHandler->xMenuItemDispatch->removeStatusListener(
545                 SAL_STATIC_CAST( XSTATUSLISTENER*, this ), aTargetURL );
546         }
547 
548         pItemHandler->xMenuItemDispatch.clear();
549         if ( pItemHandler->pSubMenuManager )
550         {
551             if ( _bRemoveOnly )
552                 pItemHandler->pSubMenuManager->RemoveListener();
553             else
554                 pItemHandler->pSubMenuManager->disposing( Source );
555         }
556     }
557 }
558 
559 
disposing(const EVENTOBJECT & Source)560 void SAL_CALL MenuManager::disposing( const EVENTOBJECT& Source )
561 {
562     if ( Source.Source == m_xFrame )
563     {
564         ResetableGuard aGuard( m_aLock );
565         ClearMenuDispatch(Source,false);
566     }
567     else
568     {
569         // disposing called from menu item dispatcher, remove listener
570         MenuItemHandler* pMenuItemDisposing = NULL;
571 
572         {
573             ResetableGuard aGuard( m_aLock );
574 
575             std::vector< MenuItemHandler* >::iterator p;
576             for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
577             {
578                 MenuItemHandler* pMenuItemHandler = *p;
579                 if ( pMenuItemHandler->xMenuItemDispatch == Source.Source )
580                 {
581                     pMenuItemDisposing = pMenuItemHandler;
582                     break;
583                 }
584             }
585 
586             if ( pMenuItemDisposing )
587             {
588                 URL aTargetURL;
589                 aTargetURL.Complete = pMenuItemDisposing->aMenuItemURL;
590 
591                 // #110897#
592                 m_xURLTransformer->parseStrict( aTargetURL );
593 
594                 pMenuItemDisposing->xMenuItemDispatch->removeStatusListener(SAL_STATIC_CAST( XSTATUSLISTENER*, this ), aTargetURL );
595                 pMenuItemDisposing->xMenuItemDispatch.clear();
596             }
597         }
598     }
599 }
600 
601 
UpdateSpecialFileMenu(Menu * pMenu)602 void MenuManager::UpdateSpecialFileMenu( Menu* pMenu )
603 {
604     // update picklist
605     Sequence< Sequence< PropertyValue > > aHistoryList = SvtHistoryOptions().GetList( ePICKLIST );
606     ::std::vector< MenuItemHandler* > aNewPickVector;
607     Reference< XStringWidth > xStringLength( new StringLength );
608 
609     sal_uInt16  nPickItemId = START_ITEMID_PICKLIST;
610     int     nPickListMenuItems = ( aHistoryList.getLength() > 99 ) ? 99 : aHistoryList.getLength();
611 
612     aNewPickVector.reserve(nPickListMenuItems);
613     for ( int i = 0; i < nPickListMenuItems; i++ )
614     {
615         Sequence< PropertyValue > aPickListEntry = aHistoryList[i];
616 
617         REFERENCE< XDISPATCH > aXDispatchRef;
618         MenuItemHandler* pNewMenuItemHandler = new MenuItemHandler(
619                                                     nPickItemId++,
620                                                     NULL,
621                                                     aXDispatchRef );
622 
623         for ( int j = 0; j < aPickListEntry.getLength(); j++ )
624         {
625             Any a = aPickListEntry[j].Value;
626 
627             if ( aPickListEntry[j].Name == HISTORY_PROPERTYNAME_URL )
628                 a >>= pNewMenuItemHandler->aMenuItemURL;
629             else if ( aPickListEntry[j].Name == HISTORY_PROPERTYNAME_FILTER )
630                 a >>= pNewMenuItemHandler->aFilter;
631             else if ( aPickListEntry[j].Name == HISTORY_PROPERTYNAME_TITLE )
632                 a >>= pNewMenuItemHandler->aTitle;
633             else if ( aPickListEntry[j].Name == HISTORY_PROPERTYNAME_PASSWORD )
634                 a >>= pNewMenuItemHandler->aPassword;
635         }
636 
637         aNewPickVector.push_back( pNewMenuItemHandler );
638     }
639 
640     if ( !aNewPickVector.empty() )
641     {
642         URL aTargetURL;
643         REFERENCE< XDISPATCHPROVIDER > xDispatchProvider( m_xFrame, UNO_QUERY );
644 
645         // #110897#
646         REFERENCE< XDISPATCH > xMenuItemDispatch;
647 
648         static const ::rtl::OUString s_sDefault(RTL_CONSTASCII_USTRINGPARAM("_default"));
649         // query for dispatcher
650         std::vector< MenuItemHandler* >::iterator p;
651         for ( p = aNewPickVector.begin(); p != aNewPickVector.end(); p++ )
652         {
653             MenuItemHandler* pMenuItemHandler = *p;
654 
655             aTargetURL.Complete = pMenuItemHandler->aMenuItemURL;
656             m_xURLTransformer->parseStrict( aTargetURL );
657 
658             if ( !xMenuItemDispatch.is() )
659             {
660                 // attention: this code assume that "_blank" can only be consumed by desktop service
661                 xMenuItemDispatch = xDispatchProvider->queryDispatch( aTargetURL, s_sDefault, 0 );
662             }
663 
664             if ( xMenuItemDispatch.is() )
665             {
666                 pMenuItemHandler->xMenuItemDispatch = xMenuItemDispatch;
667                 pMenuItemHandler->aMenuItemURL      = aTargetURL.Complete;
668             }
669         }
670 
671         {
672             ResetableGuard aGuard( m_aLock );
673 
674             int nRemoveItemCount = 0;
675             int nItemCount       = pMenu->GetItemCount();
676 
677             if ( nItemCount > 0 )
678             {
679                 // remove all old picklist entries from menu
680                 sal_uInt16 nPos = pMenu->GetItemPos( START_ITEMID_PICKLIST );
681                 for ( sal_uInt16 n = nPos; n < pMenu->GetItemCount(); )
682                 {
683                     pMenu->RemoveItem( n );
684                     ++nRemoveItemCount;
685                 }
686 
687                 if ( pMenu->GetItemType( pMenu->GetItemCount()-1 ) == MENUITEM_SEPARATOR )
688                     pMenu->RemoveItem( pMenu->GetItemCount()-1 );
689 
690                 // remove all old picklist entries from menu handler
691                 if ( nRemoveItemCount > 0 )
692                 {
693                     for( sal_uInt32 nIndex = m_aMenuItemHandlerVector.size() - nRemoveItemCount;
694                          nIndex < m_aMenuItemHandlerVector.size();  )
695                     {
696                         delete m_aMenuItemHandlerVector.at( nIndex );
697                         m_aMenuItemHandlerVector.erase( m_aMenuItemHandlerVector.begin() + nIndex );
698                     }
699                 }
700             }
701 
702             // append new picklist menu entries
703             aNewPickVector.reserve(aNewPickVector.size());
704             pMenu->InsertSeparator();
705             const sal_uInt32 nCount = aNewPickVector.size();
706             for ( sal_uInt32 i = 0; i < nCount; i++ )
707             {
708                 char menuShortCut[5] = "~n: ";
709 
710                 ::rtl::OUString aMenuShortCut;
711                 if ( i <= 9 )
712                 {
713                     if ( i == 9 )
714                         aMenuShortCut = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "1~0: " ));
715                     else
716                     {
717                         menuShortCut[1] = (char)( '1' + i );
718                         aMenuShortCut = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( menuShortCut ));
719                     }
720                 }
721                 else
722                 {
723                     aMenuShortCut = rtl::OUString::valueOf((sal_Int32)( i + 1 ));
724                     aMenuShortCut += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ": " ));
725                 }
726 
727                 // Abbreviate URL
728                 rtl::OUString   aURLString( aNewPickVector.at( i )->aMenuItemURL );
729                 rtl::OUString   aTipHelpText;
730                 rtl::OUString   aMenuTitle;
731                 INetURLObject   aURL( aURLString );
732 
733                 if ( aURL.GetProtocol() == INET_PROT_FILE )
734                 {
735                     // Do handle file URL differently => convert it to a system
736                     // path and abbreviate it with a special function:
737                     String aFileSystemPath( aURL.getFSysPath( INetURLObject::FSYS_DETECT ) );
738 
739                     ::rtl::OUString aSystemPath( aFileSystemPath );
740                     ::rtl::OUString aCompactedSystemPath;
741 
742                     aTipHelpText = aSystemPath;
743                     oslFileError nError = osl_abbreviateSystemPath( aSystemPath.pData, &aCompactedSystemPath.pData, 46, NULL );
744                     if ( !nError )
745                         aMenuTitle = String( aCompactedSystemPath );
746                     else
747                         aMenuTitle = aSystemPath;
748                 }
749                 else
750                 {
751                     // Use INetURLObject to abbreviate all other URLs
752                     String  aShortURL;
753                     aShortURL = aURL.getAbbreviated( xStringLength, 46, INetURLObject::DECODE_UNAMBIGUOUS );
754                     aMenuTitle += aShortURL;
755                     aTipHelpText = aURLString;
756                 }
757 
758                 ::rtl::OUString aTitle( aMenuShortCut + aMenuTitle );
759 
760                 MenuItemHandler* pMenuItemHandler = aNewPickVector.at( i );
761                 pMenu->InsertItem( pMenuItemHandler->nItemId, aTitle );
762                 pMenu->SetTipHelpText( pMenuItemHandler->nItemId, aTipHelpText );
763                 m_aMenuItemHandlerVector.push_back( pMenuItemHandler );
764             }
765         }
766     }
767 }
768 
UpdateSpecialWindowMenu(Menu * pMenu,const Reference<XMultiServiceFactory> & xServiceFactory,framework::IMutex & _rMutex)769 void MenuManager::UpdateSpecialWindowMenu( Menu* pMenu,const Reference< XMultiServiceFactory >& xServiceFactory,framework::IMutex& _rMutex )
770 {
771     // update window list
772     ::std::vector< ::rtl::OUString > aNewWindowListVector;
773 
774     // #110897#
775     Reference< XDesktop > xDesktop( xServiceFactory->createInstance( SERVICENAME_DESKTOP ), UNO_QUERY );
776 
777     sal_uInt16  nActiveItemId = 0;
778     sal_uInt16  nItemId = START_ITEMID_WINDOWLIST;
779 
780     if ( xDesktop.is() )
781     {
782         Reference< XFramesSupplier > xTasksSupplier( xDesktop, UNO_QUERY );
783         Reference< XFrame > xCurrentFrame = xDesktop->getCurrentFrame();
784         Reference< XIndexAccess > xList( xTasksSupplier->getFrames(), UNO_QUERY );
785         sal_Int32 nCount = xList->getCount();
786         aNewWindowListVector.reserve(nCount);
787         for (sal_Int32 i=0; i<nCount; ++i )
788         {
789             Reference< XFrame > xFrame;
790             xList->getByIndex(i) >>= xFrame;
791 
792             if (xFrame.is())
793             {
794                 if ( xFrame == xCurrentFrame )
795                     nActiveItemId = nItemId;
796 
797                 Window* pWin = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() );
798                 if ( pWin && pWin->IsVisible() )
799                 {
800                     aNewWindowListVector.push_back( pWin->GetText() );
801                     ++nItemId;
802                 }
803             }
804         }
805     }
806 
807     {
808         ResetableGuard aGuard( _rMutex );
809 
810         int nItemCount = pMenu->GetItemCount();
811 
812         if ( nItemCount > 0 )
813         {
814             // remove all old window list entries from menu
815             sal_uInt16 nPos = pMenu->GetItemPos( START_ITEMID_WINDOWLIST );
816             for ( sal_uInt16 n = nPos; n < pMenu->GetItemCount(); )
817                 pMenu->RemoveItem( n );
818 
819             if ( pMenu->GetItemType( pMenu->GetItemCount()-1 ) == MENUITEM_SEPARATOR )
820                 pMenu->RemoveItem( pMenu->GetItemCount()-1 );
821         }
822 
823         if ( !aNewWindowListVector.empty() )
824         {
825             // append new window list entries to menu
826             pMenu->InsertSeparator();
827             nItemId = START_ITEMID_WINDOWLIST;
828             const sal_uInt32 nCount = aNewWindowListVector.size();
829             for ( sal_uInt32 i = 0; i < nCount; i++ )
830             {
831                 pMenu->InsertItem( nItemId, aNewWindowListVector.at( i ), MIB_RADIOCHECK );
832                 if ( nItemId == nActiveItemId )
833                     pMenu->CheckItem( nItemId );
834                 ++nItemId;
835             }
836         }
837     }
838 }
839 
840 
CreatePicklistArguments(Sequence<PropertyValue> & aArgsList,const MenuItemHandler * pMenuItemHandler)841 void MenuManager::CreatePicklistArguments( Sequence< PropertyValue >& aArgsList, const MenuItemHandler* pMenuItemHandler )
842 {
843     int NUM_OF_PICKLIST_ARGS = 3;
844 
845     Any a;
846     aArgsList.realloc( NUM_OF_PICKLIST_ARGS );
847 
848     aArgsList[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FileName" ));
849     a <<= pMenuItemHandler->aMenuItemURL;
850     aArgsList[0].Value = a;
851 
852     aArgsList[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Referer" ));
853     a <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SFX_REFERER_USER ));
854     aArgsList[1].Value = a;
855 
856     ::rtl::OUString aFilter( pMenuItemHandler->aFilter );
857 
858     sal_Int32 nPos = aFilter.indexOf( '|' );
859     if ( nPos >= 0 )
860     {
861         ::rtl::OUString aFilterOptions;
862 
863         if ( nPos < ( aFilter.getLength() - 1 ) )
864             aFilterOptions = aFilter.copy( nPos+1 );
865 
866         aArgsList[2].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterOptions" ));
867         a <<= aFilterOptions;
868         aArgsList[2].Value = a;
869 
870         aFilter = aFilter.copy( 0, nPos-1 );
871         aArgsList.realloc( ++NUM_OF_PICKLIST_ARGS );
872     }
873 
874     aArgsList[NUM_OF_PICKLIST_ARGS-1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ));
875     a <<= aFilter;
876     aArgsList[NUM_OF_PICKLIST_ARGS-1].Value = a;
877 }
878 
879 
880 //_________________________________________________________________________________________________________________
881 // vcl handler
882 //_________________________________________________________________________________________________________________
883 
IMPL_LINK(MenuManager,Activate,Menu *,pMenu)884 IMPL_LINK( MenuManager, Activate, Menu *, pMenu )
885 {
886     if ( pMenu == m_pVCLMenu )
887     {
888         // set/unset hiding disabled menu entries
889         sal_Bool bDontHide          = SvtMenuOptions().IsEntryHidingEnabled();
890         const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
891         sal_Bool bShowMenuImages    = rSettings.GetUseImagesInMenus();
892 
893         sal_uInt16 nFlag = pMenu->GetMenuFlags();
894         if ( bDontHide )
895             nFlag &= ~MENU_FLAG_HIDEDISABLEDENTRIES;
896         else
897             nFlag |= MENU_FLAG_HIDEDISABLEDENTRIES;
898         pMenu->SetMenuFlags( nFlag );
899 
900         if ( m_bActive )
901             return 0;
902 
903         m_bActive = sal_True;
904 
905         ::rtl::OUString aCommand( m_aMenuItemCommand );
906         if ( m_aMenuItemCommand.matchIgnoreAsciiCase( UNO_COMMAND, 0 ))
907         {
908             // Remove protocol part from command so we can use an easier comparison method
909             aCommand = aCommand.copy( UNO_COMMAND.getLength() );
910         }
911 
912         if ( m_aMenuItemCommand == aSpecialFileMenu ||
913              m_aMenuItemCommand == aSlotSpecialFileMenu ||
914              aCommand == aSpecialFileCommand )
915             UpdateSpecialFileMenu( pMenu );
916         else if ( m_aMenuItemCommand == aSpecialWindowMenu ||
917                   m_aMenuItemCommand == aSlotSpecialWindowMenu ||
918                   aCommand == aSpecialWindowCommand )
919                   UpdateSpecialWindowMenu( pMenu,getServiceFactory(),m_aLock );
920 
921         // Check if some modes have changed so we have to update our menu images
922         sal_Bool bIsHiContrast = rSettings.GetHighContrastMode();
923 
924         if ( m_bWasHiContrast != bIsHiContrast || bShowMenuImages != m_bShowMenuImages )
925         {
926             // The mode changed so we have to replace all images
927             m_bWasHiContrast    = bIsHiContrast;
928             m_bShowMenuImages   = bShowMenuImages;
929             FillMenuImages(m_xFrame,pMenu,bIsHiContrast,bShowMenuImages);
930         }
931 
932         if ( m_bInitialized )
933             return 0;
934         else
935         {
936             URL aTargetURL;
937 
938             // #110897#
939             ResetableGuard aGuard( m_aLock );
940 
941             REFERENCE< XDISPATCHPROVIDER > xDispatchProvider( m_xFrame, UNO_QUERY );
942             if ( xDispatchProvider.is() )
943             {
944                 std::vector< MenuItemHandler* >::iterator p;
945                 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
946                 {
947                     MenuItemHandler* pMenuItemHandler = *p;
948                     if ( pMenuItemHandler &&
949                          pMenuItemHandler->pSubMenuManager == 0 &&
950                          !pMenuItemHandler->xMenuItemDispatch.is() )
951                     {
952                         // There is no dispatch mechanism for the special window list menu items,
953                         // because they are handled directly through XFrame->activate!!!
954                         if ( pMenuItemHandler->nItemId < START_ITEMID_WINDOWLIST ||
955                              pMenuItemHandler->nItemId > END_ITEMID_WINDOWLIST )
956                         {
957                             ::rtl::OUString aItemCommand = pMenu->GetItemCommand( pMenuItemHandler->nItemId );
958                             if ( !aItemCommand.getLength() )
959                             {
960                                 const static ::rtl::OUString aSlotString( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
961                                 aItemCommand = aSlotString;
962                                 aItemCommand += ::rtl::OUString::valueOf( (sal_Int32)pMenuItemHandler->nItemId );
963                                 pMenu->SetItemCommand( pMenuItemHandler->nItemId, aItemCommand );
964                             }
965 
966                             aTargetURL.Complete = aItemCommand;
967 
968                             m_xURLTransformer->parseStrict( aTargetURL );
969 
970                             REFERENCE< XDISPATCH > xMenuItemDispatch;
971                             if ( m_bIsBookmarkMenu )
972                                 xMenuItemDispatch = xDispatchProvider->queryDispatch( aTargetURL, pMenuItemHandler->aTargetFrame, 0 );
973                             else
974                                 xMenuItemDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
975 
976                             if ( xMenuItemDispatch.is() )
977                             {
978                                 pMenuItemHandler->xMenuItemDispatch = xMenuItemDispatch;
979                                 pMenuItemHandler->aMenuItemURL      = aTargetURL.Complete;
980                                 xMenuItemDispatch->addStatusListener( SAL_STATIC_CAST( XSTATUSLISTENER*, this ), aTargetURL );
981                             }
982                             else
983                                 pMenu->EnableItem( pMenuItemHandler->nItemId, sal_False );
984                         }
985                     }
986                 }
987             }
988         }
989     }
990 
991     return 1;
992 }
993 
994 
IMPL_LINK(MenuManager,Deactivate,Menu *,pMenu)995 IMPL_LINK( MenuManager, Deactivate, Menu *, pMenu )
996 {
997     if ( pMenu == m_pVCLMenu )
998         m_bActive = sal_False;
999 
1000     return 1;
1001 }
1002 
1003 
IMPL_LINK(MenuManager,Select,Menu *,pMenu)1004 IMPL_LINK( MenuManager, Select, Menu *, pMenu )
1005 {
1006     URL                     aTargetURL;
1007     Sequence<PropertyValue> aArgs;
1008     REFERENCE< XDISPATCH >  xDispatch;
1009 
1010     {
1011         ResetableGuard aGuard( m_aLock );
1012 
1013         sal_uInt16 nCurItemId = pMenu->GetCurItemId();
1014         if ( pMenu == m_pVCLMenu &&
1015              pMenu->GetItemType( nCurItemId ) != MENUITEM_SEPARATOR )
1016         {
1017             if ( nCurItemId >= START_ITEMID_WINDOWLIST &&
1018                  nCurItemId <= END_ITEMID_WINDOWLIST )
1019             {
1020                 // window list menu item selected
1021 
1022                 // #110897#
1023                 // Reference< XFramesSupplier > xDesktop( ::comphelper::getProcessServiceFactory()->createInstance(
1024                 //  DESKTOP_SERVICE ), UNO_QUERY );
1025                 Reference< XFramesSupplier > xDesktop( getServiceFactory()->createInstance( SERVICENAME_DESKTOP ), UNO_QUERY );
1026 
1027                 if ( xDesktop.is() )
1028                 {
1029                     sal_uInt16 nTaskId = START_ITEMID_WINDOWLIST;
1030                     Reference< XIndexAccess > xList( xDesktop->getFrames(), UNO_QUERY );
1031                     sal_Int32 nCount = xList->getCount();
1032                     for ( sal_Int32 i=0; i<nCount; ++i )
1033                     {
1034                         Reference< XFrame > xFrame;
1035                         xList->getByIndex(i) >>= xFrame;
1036 
1037                         if ( xFrame.is() && nTaskId == nCurItemId )
1038                         {
1039                             Window* pWin = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() );
1040                             pWin->GrabFocus();
1041                             pWin->ToTop( TOTOP_RESTOREWHENMIN );
1042                             break;
1043                         }
1044 
1045                         nTaskId++;
1046                     }
1047                 }
1048             }
1049             else
1050             {
1051                 MenuItemHandler* pMenuItemHandler = GetMenuItemHandler( nCurItemId );
1052                 if ( pMenuItemHandler && pMenuItemHandler->xMenuItemDispatch.is() )
1053                 {
1054                     aTargetURL.Complete = pMenuItemHandler->aMenuItemURL;
1055                     m_xURLTransformer->parseStrict( aTargetURL );
1056 
1057                     if ( nCurItemId >= START_ITEMID_PICKLIST &&
1058                          nCurItemId <  START_ITEMID_WINDOWLIST )
1059                     {
1060                         // picklist menu item selected
1061                         CreatePicklistArguments( aArgs, pMenuItemHandler );
1062                     }
1063                     else if ( m_bIsBookmarkMenu )
1064                     {
1065                         // bookmark menu item selected
1066                         aArgs.realloc( 1 );
1067                         aArgs[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Referer" ));
1068                         aArgs[0].Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SFX_REFERER_USER ));
1069                     }
1070 
1071                     xDispatch = pMenuItemHandler->xMenuItemDispatch;
1072                 }
1073             }
1074         }
1075     }
1076 
1077     if ( xDispatch.is() )
1078         xDispatch->dispatch( aTargetURL, aArgs );
1079 
1080     return 1;
1081 }
1082 
1083 
IMPL_LINK(MenuManager,Highlight,Menu *,EMPTYARG)1084 IMPL_LINK( MenuManager, Highlight, Menu *, EMPTYARG )
1085 {
1086     return 0;
1087 }
1088 
1089 // #110897#
getServiceFactory()1090 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& MenuManager::getServiceFactory()
1091 {
1092     // #110897#
1093     return mxServiceFactory;
1094 }
1095 
AddMenu(PopupMenu * _pPopupMenu,const::rtl::OUString & _sItemCommand,sal_uInt16 _nItemId,sal_Bool _bDelete,sal_Bool _bDeleteChildren)1096 void MenuManager::AddMenu(PopupMenu* _pPopupMenu,const ::rtl::OUString& _sItemCommand,sal_uInt16 _nItemId,sal_Bool _bDelete,sal_Bool _bDeleteChildren)
1097 {
1098     MenuManager* pSubMenuManager = new MenuManager( getServiceFactory(), m_xFrame, _pPopupMenu, _bDelete, _bDeleteChildren );
1099 
1100     // store menu item command as we later have to know which menu is active (see Activate handler)
1101     pSubMenuManager->m_aMenuItemCommand = _sItemCommand;
1102 
1103     REFERENCE< XDISPATCH > aXDispatchRef;
1104     MenuItemHandler* pMenuItemHandler = new MenuItemHandler(
1105                                                 _nItemId,
1106                                                 pSubMenuManager,
1107                                                 aXDispatchRef );
1108     m_aMenuItemHandlerVector.push_back( pMenuItemHandler );
1109 }
1110 
FillItemCommand(::rtl::OUString & _rItemCommand,Menu * _pMenu,sal_uInt16 _nIndex) const1111 sal_uInt16 MenuManager::FillItemCommand(::rtl::OUString& _rItemCommand,Menu* _pMenu,sal_uInt16 _nIndex) const
1112 {
1113     sal_uInt16 nItemId = _pMenu->GetItemId( _nIndex );
1114 
1115     _rItemCommand = _pMenu->GetItemCommand( nItemId );
1116     if ( !_rItemCommand.getLength() )
1117     {
1118         const static ::rtl::OUString aSlotString( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
1119         _rItemCommand = aSlotString;
1120         _rItemCommand += ::rtl::OUString::valueOf( (sal_Int32)nItemId );
1121         _pMenu->SetItemCommand( nItemId, _rItemCommand );
1122     }
1123     return nItemId;
1124 }
FillMenuImages(Reference<XFrame> & _xFrame,Menu * _pMenu,sal_Bool bIsHiContrast,sal_Bool bShowMenuImages)1125 void MenuManager::FillMenuImages(Reference< XFrame >& _xFrame,Menu* _pMenu,sal_Bool bIsHiContrast,sal_Bool bShowMenuImages)
1126 {
1127     AddonsOptions       aAddonOptions;
1128 
1129     for ( sal_uInt16 nPos = 0; nPos < _pMenu->GetItemCount(); nPos++ )
1130     {
1131         sal_uInt16 nId = _pMenu->GetItemId( nPos );
1132         if ( _pMenu->GetItemType( nPos ) != MENUITEM_SEPARATOR )
1133         {
1134             bool bTmpShowMenuImages( bShowMenuImages );
1135             MenuItemBits nBits =  _pMenu->GetItemBits( nId );
1136             // overwrite the default?
1137             if ( nBits )
1138                 bTmpShowMenuImages = ( ( nBits & MIB_ICON ) == MIB_ICON );
1139 
1140             if ( bTmpShowMenuImages )
1141             {
1142                 sal_Bool        bImageSet = sal_False;
1143                 ::rtl::OUString aImageId;
1144 
1145                 ::framework::MenuConfiguration::Attributes* pMenuAttributes =
1146                     (::framework::MenuConfiguration::Attributes*)_pMenu->GetUserValue( nId );
1147 
1148                 if ( pMenuAttributes )
1149                     aImageId = pMenuAttributes->aImageId; // Retrieve image id from menu attributes
1150 
1151                 if ( aImageId.getLength() > 0 )
1152                 {
1153                     Image aImage = GetImageFromURL( _xFrame, aImageId, sal_False, bIsHiContrast );
1154                     if ( !!aImage )
1155                     {
1156                         bImageSet = sal_True;
1157                         _pMenu->SetItemImage( nId, aImage );
1158                     }
1159                 }
1160 
1161                 if ( !bImageSet )
1162                 {
1163                     rtl::OUString aMenuItemCommand = _pMenu->GetItemCommand( nId );
1164                     Image aImage = GetImageFromURL( _xFrame, aMenuItemCommand, sal_False, bIsHiContrast );
1165                     if ( !aImage )
1166                         aImage = aAddonOptions.GetImageFromURL( aMenuItemCommand, sal_False, bIsHiContrast );
1167 
1168                     _pMenu->SetItemImage( nId, aImage );
1169                 }
1170             }
1171             else
1172                 _pMenu->SetItemImage( nId, Image() );
1173         }
1174     }
1175 }
1176 }
1177