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