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