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