xref: /aoo41x/main/sfx2/source/menu/virtmenu.cxx (revision cdf0e10c)
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_sfx2.hxx"
30 
31 #include <sot/factory.hxx>
32 #include <svtools/menuoptions.hxx>
33 #include <svtools/imagemgr.hxx>
34 #include <svl/imageitm.hxx>
35 #include <com/sun/star/container/XEnumeration.hpp>
36 #include <com/sun/star/frame/XDesktop.hpp>
37 #include <com/sun/star/frame/XFramesSupplier.hpp>
38 #include <comphelper/processfactory.hxx>
39 #include <toolkit/unohlp.hxx>
40 #include <tools/urlobj.hxx>
41 
42 #include "virtmenu.hxx"
43 #include <sfx2/msgpool.hxx>
44 #include "statcach.hxx"
45 #include <sfx2/msg.hxx>
46 #include "idpool.hxx"
47 #include <sfx2/mnuitem.hxx>
48 #include <sfx2/mnumgr.hxx>
49 #include <sfx2/bindings.hxx>
50 #include <sfx2/dispatch.hxx>
51 #include <sfx2/app.hxx>
52 #include "sfxtypes.hxx"
53 #include "arrdecl.hxx"
54 #include <sfx2/sfx.hrc>
55 #include <sfx2/viewsh.hxx>
56 #include "sfxpicklist.hxx"
57 #include "sfx2/sfxresid.hxx"
58 #include "menu.hrc"
59 #include "sfx2/imagemgr.hxx"
60 #include <sfx2/viewfrm.hxx>
61 #include <sfx2/objsh.hxx>
62 #include <framework/addonsoptions.hxx>
63 
64 #ifndef __FRAMEWORK_CLASSES_ADDONMENUS_HXX_
65 #include <framework/addonmenu.hxx>
66 #endif
67 #include <framework/menuconfiguration.hxx>
68 
69 using namespace ::com::sun::star::container;
70 using namespace ::com::sun::star::frame;
71 using namespace ::com::sun::star::uno;
72 
73 //=========================================================================
74 
75 DBG_NAME(SfxVirtualMenu)
76 
77 //=========================================================================
78 
79 typedef SfxMenuControl* SfxMenuControlPtr;
80 SV_IMPL_PTRARR(SfxMenuCtrlArr_Impl, SfxMenuControlPtr);
81 
82 class SfxMenuImageControl_Impl : public SfxControllerItem
83 {
84     SfxVirtualMenu*     pMenu;
85     long                lRotation;
86     sal_Bool                bIsMirrored;
87 
88 protected:
89     virtual void        StateChanged( sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState );
90 public:
91                         SfxMenuImageControl_Impl( sal_uInt16 nSlotId, SfxBindings& rBindings, SfxVirtualMenu* pVMenu )
92                             : SfxControllerItem( nSlotId, rBindings )
93                             , pMenu( pVMenu )
94                             , lRotation( 0 )
95                             , bIsMirrored( sal_False )
96                         {}
97     void                Update();
98 };
99 
100 void SfxMenuImageControl_Impl::StateChanged( sal_uInt16 /*nSID*/, SfxItemState /*eState*/, const SfxPoolItem* pState )
101 {
102     const SfxImageItem* pItem = PTR_CAST( SfxImageItem, pState );
103     if ( pItem )
104     {
105         lRotation = pItem->GetRotation();
106         bIsMirrored = pItem->IsMirrored();
107         Update();
108     }
109 }
110 
111 void SfxMenuImageControl_Impl::Update()
112 {
113     SfxViewFrame* pViewFrame = GetBindings().GetDispatcher_Impl()->GetFrame();
114     SfxModule* pModule = pViewFrame->GetObjectShell()->GetModule();
115     SfxSlotPool* pPool = pModule->GetSlotPool();
116     Menu* pSVMenu = pMenu->GetSVMenu();
117     for (sal_uInt16 nPos = 0; nPos<pSVMenu->GetItemCount(); nPos++)
118     {
119         sal_uInt16 nslotId = pSVMenu->GetItemId( nPos );
120         const SfxSlot* pSlot = pPool->GetSlot( nslotId );
121         if ( pSlot && pSlot->IsMode( SFX_SLOT_IMAGEROTATION ) )
122         {
123             pSVMenu->SetItemImageMirrorMode( nslotId, sal_False );
124             pSVMenu->SetItemImageAngle( nslotId, lRotation );
125         }
126 
127         if ( pSlot && pSlot->IsMode( SFX_SLOT_IMAGEREFLECTION ) )
128             pSVMenu->SetItemImageMirrorMode( nslotId, bIsMirrored );
129     }
130 }
131 
132 //=========================================================================
133 
134 static Image RetrieveAddOnImage( Reference< com::sun::star::frame::XFrame >& rFrame,
135 								 const rtl::OUString& aImageId,
136 								 const rtl::OUString& aURL,
137 								 sal_Bool bBigImage,
138 								 sal_Bool bHiContrast )
139 {
140 	Image aImage;
141 
142 	if ( aImageId.getLength() > 0 )
143 	{
144 		aImage = GetImage( rFrame, aImageId, bBigImage, bHiContrast );
145 		if ( !!aImage )
146 			return aImage;
147 	}
148 
149 	aImage = GetImage( rFrame, aURL, bBigImage, bHiContrast );
150 	if ( !aImage )
151 		aImage = framework::AddonsOptions().GetImageFromURL( aURL, bBigImage, bHiContrast );
152 
153 	return aImage;
154 }
155 
156 //=========================================================================
157 
158 /*	Diese Hilfsfunktion pr"uft, ob eine Slot-Id im aktuellen Applikations-
159 	Status sichtbar ist oder nicht. Dabei bezieht sich der Applikations-Status
160 	darauf, ob die Applikation OLE-Server ist oder nicht.
161 */
162 
163 sal_Bool IsItemHidden_Impl( sal_uInt16 nItemId, int bOleServer, int bMac )
164 {
165 	return ( bMac &&
166              ( nItemId == SID_MINIMIZED ) ) ||
167 		   (  bOleServer &&
168 			 ( nItemId == SID_QUITAPP || nItemId == SID_SAVEDOC ||
169 			   nItemId == SID_OPENDOC || nItemId == SID_SAVEASDOC ||
170 			   nItemId == SID_NEWDOC ) ) ||
171 		   ( !bOleServer &&
172 			 ( nItemId == SID_EXITANDRETURN || nItemId == SID_UPDATEDOC ) );
173 }
174 
175 //====================================================================
176 
177 void SfxVirtualMenu::Construct_Impl()
178 {
179 	pSVMenu->SetHighlightHdl( LINK(this, SfxVirtualMenu, Highlight) );
180 	pSVMenu->SetActivateHdl( LINK(this, SfxVirtualMenu, Activate) );
181 	pSVMenu->SetDeactivateHdl( LINK(this, SfxVirtualMenu, Deactivate) );
182 	pSVMenu->SetSelectHdl( LINK(this, SfxVirtualMenu, Select) );
183 
184 	// #107258# accelerator keys are needed for accessibility
185     //if ( bOLE )
186     //    InvalidateKeyCodes();
187 
188 	if ( !pResMgr && pParent )
189 		pResMgr = pParent->pResMgr;
190 }
191 
192 //--------------------------------------------------------------------
193 
194 SfxVirtualMenu::SfxVirtualMenu( sal_uInt16 nOwnId,
195 				SfxVirtualMenu* pOwnParent, Menu& rMenu, sal_Bool bWithHelp,
196 				SfxBindings &rBindings, sal_Bool bOLEServer, sal_Bool bRes, sal_Bool bIsAddonMenu ):
197 	pItems(0),
198        pImageControl(0),
199 	pBindings(&rBindings),
200 	pResMgr(0),
201 	pAutoDeactivate(0),
202 	nLocks(0),
203 	bHelpInitialized( bWithHelp ),
204 	bWasHighContrast( sal_False ),
205 	bIsAddonPopupMenu( bIsAddonMenu )
206 {
207 	DBG_MEMTEST();
208 	DBG_CTOR(SfxVirtualMenu, 0);
209 	pSVMenu = &rMenu;
210 
211 	bResCtor = bRes;
212 	bOLE = bOLEServer;
213 	nId = nOwnId;
214 	pParent = pOwnParent;
215 	nVisibleItems = 0;
216 	pAppCtrl = 0;
217     pWindowMenu = NULL;
218     pPickMenu = NULL;
219     pAddonsMenu = NULL;
220 	bIsActive = sal_False;
221 	bControllersUnBound = sal_False;
222 	CreateFromSVMenu();
223 	Construct_Impl();
224 	bHelpInitialized = sal_False;
225 }
226 
227 //--------------------------------------------------------------------
228 
229 // creates a virtual menu from a StarView MenuBar or PopupMenu
230 
231 SfxVirtualMenu::SfxVirtualMenu( Menu *pStarViewMenu, sal_Bool bWithHelp,
232 					SfxBindings &rBindings, sal_Bool bOLEServer, sal_Bool bRes, sal_Bool bIsAddonMenu ):
233 	pItems(0),
234        pImageControl(0),
235 	pBindings(&rBindings),
236 	pResMgr(0),
237 	pAutoDeactivate(0),
238 	nLocks(0),
239 	bHelpInitialized( bWithHelp ),
240 	bWasHighContrast( sal_False ),
241 	bIsAddonPopupMenu( bIsAddonMenu )
242 {
243 	DBG_MEMTEST();
244 	DBG_CTOR(SfxVirtualMenu, 0);
245 
246     pSVMenu = pStarViewMenu;
247 
248 	bResCtor = bRes;
249 	bOLE = bOLEServer;
250 	nId = 0;
251 	pParent = 0;
252 	pAppCtrl = 0;
253 	nVisibleItems = 0;
254     pWindowMenu = NULL;
255     pPickMenu = NULL;
256     pAddonsMenu = NULL;
257 	bIsActive = sal_False;
258 	bControllersUnBound = sal_False;
259 	CreateFromSVMenu();
260 	Construct_Impl();
261 	bHelpInitialized = sal_False;
262 }
263 
264 //--------------------------------------------------------------------
265 
266 /*  Der Destruktor der Klasse SfxVirtualMenu gib die gebundenen Items frei
267 	und klinkt das zugeh"orige StarView-PopupMenu aus seinem Parent aus.
268 	Falls es sich um das Pickmenu oder das MDI-Menu handelt, wird es
269 	dort abgemeldet.
270 */
271 
272 SfxVirtualMenu::~SfxVirtualMenu()
273 {
274 	DBG_MEMTEST();
275 	DBG_DTOR(SfxVirtualMenu, 0);
276 
277     DELETEZ( pImageControl );
278     SvtMenuOptions().RemoveListenerLink( LINK( this, SfxVirtualMenu, SettingsChanged ) );
279 
280 	if ( bIsActive )
281 	{
282 		pBindings->LEAVEREGISTRATIONS(); --nLocks; bIsActive = sal_False;
283 	}
284 
285 	// QAP-Hack
286 	if ( pAutoDeactivate )
287 	{
288 		if ( pAutoDeactivate->IsActive() )
289 			Deactivate(0);
290 		DELETEX(pAutoDeactivate);
291 	}
292 
293 	if (pItems)
294 	{
295 		delete [] pItems;
296 	}
297 
298 	delete pAppCtrl;
299 	pBindings = 0;
300 
301 	// Alle Menues, die von SV erzeugt wurden, werden auch dort wieder
302 	// gel"oscht (also die beim Laden aus der Resource erzeugten).
303 	// Das Top-Level-Menu wird nie von SV gel"oscht, da die Allocierung
304 	// im SFX erfolgt
305 	if ( !bResCtor || !pParent)
306 	{
307         if ( pParent )
308         {
309             if( pParent->pSVMenu->GetItemPos( nId ) != MENU_ITEM_NOTFOUND )
310                 pParent->pSVMenu->SetPopupMenu( nId, 0 );
311             if ( pParent->pPickMenu == pSVMenu )
312                 pParent->pPickMenu = 0;
313             if ( pParent->pWindowMenu == pSVMenu)
314                 pParent->pWindowMenu = 0;
315             if ( pParent->pAddonsMenu == pSVMenu )
316 				pParent->pAddonsMenu = 0;
317         }
318 
319 		delete pSVMenu;
320 	}
321 
322 	DBG_OUTF( ("SfxVirtualMenu %lx destroyed", this) );
323 	DBG_ASSERT( !nLocks, "destroying active menu" );
324 }
325 //--------------------------------------------------------------------
326 
327 sal_Bool SfxVirtualMenu::IsHiContrastMode() const
328 {
329 	const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
330     return rSettings.GetHighContrastMode();
331 }
332 
333 //--------------------------------------------------------------------
334 // internal: creates the virtual menu from the pSVMenu
335 
336 void SfxVirtualMenu::CreateFromSVMenu()
337 {
338 	DBG_MEMTEST();
339 	DBG_CHKTHIS(SfxVirtualMenu, 0);
340 
341 	// Merge Addon popup menus into the SV Menu
342     SfxViewFrame* pViewFrame = pBindings->GetDispatcher()->GetFrame();
343     SfxSlotPool* pSlotPool = pViewFrame->GetObjectShell()->GetModule()->GetSlotPool();
344 	Reference< com::sun::star::frame::XFrame > xFrame( pViewFrame->GetFrame().GetFrameInterface() );
345 
346 	if ( pSVMenu->IsMenuBar() )
347 	{
348 		sal_uInt16 nPos = pSVMenu->GetItemPos( SID_MDIWINDOWLIST );
349 		if ( nPos != MENU_ITEM_NOTFOUND && xFrame.is() )
350 		{
351 			// Retrieve addon popup menus and add them to our menu bar
352 			Reference< com::sun::star::frame::XModel >		xModel;
353 			Reference< com::sun::star::frame::XController >	xController( xFrame->getController(), UNO_QUERY );
354 			if ( xController.is() )
355 				xModel = Reference< com::sun::star::frame::XModel >( xController->getModel(), UNO_QUERY );
356 			framework::AddonMenuManager::MergeAddonPopupMenus( xFrame, xModel, nPos, (MenuBar *)pSVMenu );
357 		}
358 
359         // Merge the Add-Ons help menu items into the Office help menu
360 		if ( xFrame.is() )
361 		    framework::AddonMenuManager::MergeAddonHelpMenu( xFrame, (MenuBar *)pSVMenu );
362 
363         // Set addon menu pointer here to avoid problems. When accessibility is enabled, the whole menu
364         // is created immediately!
365 		pAddonsMenu = pSVMenu->GetPopupMenu( SID_ADDONLIST );
366 	}
367 	else if ( pParent )
368 	{
369 		if ( pSVMenu == pParent->pAddonsMenu &&
370 			 framework::AddonsOptions().HasAddonsMenu() &&
371 			 !pSVMenu->GetPopupMenu( SID_ADDONS ) )
372 		{
373 			// Create menu item at the end of the tools popup menu for the addons popup menu
374 			InsertAddOnsMenuItem( pSVMenu );
375 		}
376 	}
377 
378 	// get and store the number of items
379 	nCount = pSVMenu->GetItemCount();
380 
381 	// Achtung: nur zu diesem Zeitpunkt ist garantiert, da\s nCount und
382 	// der ItemCount des SV-Menues "ubereinstimmen; sp"ater kann das SvMenue
383 	// auch mehr Eintr"age haben (Pickliste!)
384 	if (nCount)
385 		pItems = new SfxMenuControl[nCount];
386 
387 	// remember some values
388 	SFX_APP();
389 	const int bOleServer = sal_False;
390 	const int bMac = sal_False;
391     SvtMenuOptions aOptions;
392     aOptions.AddListenerLink( LINK( this, SfxVirtualMenu, SettingsChanged ) );
393 
394 	// iterate through the items
395 	pBindings->ENTERREGISTRATIONS(); ++nLocks;
396     pImageControl = new SfxMenuImageControl_Impl( SID_IMAGE_ORIENTATION, *pBindings, this );
397 
398 	// Update high contrast state
399 	bWasHighContrast = IsHiContrastMode();
400 
401 	sal_uInt16 nSVPos = 0;
402 	for ( sal_uInt16 nPos=0; nPos<nCount; ++nPos, ++nSVPos )
403 	{
404 		sal_uInt16 nSlotId = pSVMenu->GetItemId(nSVPos);
405 		PopupMenu* pPopup = pSVMenu->GetPopupMenu(nSlotId);
406 		if( pPopup && nSlotId >= SID_OBJECTMENU0 && nSlotId <= SID_OBJECTMENU_LAST )
407 		{
408 			// artefact in XML menuconfig: every entry in root menu must have a popup!
409 			pSVMenu->SetPopupMenu( nSlotId, NULL );
410 			DELETEZ( pPopup );
411 		}
412 
413 		const String sItemText = pSVMenu->GetItemText(nSlotId);
414         const String sHelpText = pSVMenu->GetHelpText(nSlotId);
415 
416         if ( pPopup )
417 		{
418 
419             SfxMenuControl *pMnuCtrl =
420 				SfxMenuControl::CreateControl(nSlotId, *pPopup, *pBindings);
421 
422 			if ( pMnuCtrl )
423 			{
424 				// Das Popup war offensichtlich kein "echtes"; solche werden
425 				// niemals aus der Resource geladen und m"ussen daher explizit
426 				// gel"oscht werden
427 				if ( pSVMenu->GetPopupMenu( nSlotId ) == pPopup )
428 					pSVMenu->SetPopupMenu( nSlotId, NULL );
429 				delete pPopup;
430 				pPopup = 0;
431 
432 				SfxMenuCtrlArr_Impl &rCtrlArr = GetAppCtrl_Impl();
433 				rCtrlArr.C40_INSERT( SfxMenuControl, pMnuCtrl, rCtrlArr.Count() );
434 				(pItems+nPos)->Bind( 0, nSlotId, sItemText, sHelpText, *pBindings);
435 				pMnuCtrl->Bind( this, nSlotId, sItemText, sHelpText, *pBindings);
436 
437                 if (  Application::GetSettings().GetStyleSettings().GetUseImagesInMenus() )
438                 {
439                     rtl::OUString aSlotURL( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
440                     aSlotURL += rtl::OUString::valueOf( sal_Int32( nSlotId ));
441                     Image aImage = GetImage( xFrame, aSlotURL, sal_False, bWasHighContrast );
442                     pSVMenu->SetItemImage( nSlotId, aImage );
443                 }
444 			}
445 			else
446 			{
447                 const SfxSlot* pSlot = pSlotPool->GetSlot( nSlotId );
448                 if ( pSlot )
449                 {
450                     rtl::OString aCmd(".uno:");
451                     aCmd += pSlot->GetUnoName();
452     				pSVMenu->SetHelpId( nSlotId, pSlot->GetUnoName() );
453                 }
454 
455 				pMnuCtrl = pItems+nPos;
456 
457 				// normalerweise jetzt erst im Activate-Handler
458 				if ( bOLE )
459 				{
460 					pMnuCtrl->Bind( this, nSlotId,
461 						*new SfxVirtualMenu(nSlotId, this, *pPopup, bHelpInitialized, *pBindings, bOLE, bResCtor),
462 						sItemText, sHelpText,
463 						*pBindings );
464 				}
465 			}
466 
467 			++nVisibleItems;
468 		}
469 		else
470 		{
471 			switch ( pSVMenu->GetItemType(nSVPos) )
472 			{
473 				case MENUITEM_STRING:
474 				case MENUITEM_STRINGIMAGE:
475 				{
476                     SfxMenuControl *pMnuCtrl=0;
477 					String aCmd( pSVMenu->GetItemCommand( nSlotId ) );
478                     if ( aCmd.Len() && (( nSlotId < SID_SFX_START ) || ( nSlotId > SHRT_MAX )) )
479 					{
480                         // try to create control via comand name
481                         pMnuCtrl = SfxMenuControl::CreateControl( aCmd, nSlotId, *pSVMenu, sItemText, sHelpText, *pBindings, this );
482 						if ( pMnuCtrl )
483 						{
484 							SfxMenuCtrlArr_Impl &rCtrlArr = GetAppCtrl_Impl();
485                             rCtrlArr.C40_INSERT( SfxMenuControl, pMnuCtrl, rCtrlArr.Count());
486                             (pItems+nPos)->Bind( 0, nSlotId, sItemText, sHelpText, *pBindings);
487 						}
488 					}
489 
490                     if ( !pMnuCtrl )
491 					{
492                         // try to create control via Id
493                         pMnuCtrl = SfxMenuControl::CreateControl(nSlotId, *pSVMenu, *pBindings);
494 						if ( pMnuCtrl )
495 						{
496 							SfxMenuCtrlArr_Impl &rCtrlArr = GetAppCtrl_Impl();
497                             rCtrlArr.C40_INSERT( SfxMenuControl, pMnuCtrl, rCtrlArr.Count());
498                             (pItems+nPos)->Bind( 0, nSlotId, sItemText, sHelpText, *pBindings);
499 						}
500 						else
501                             // take default control
502 							pMnuCtrl = (pItems+nPos);
503 
504                         pMnuCtrl->Bind( this, nSlotId, sItemText, sHelpText, *pBindings);
505 					}
506 
507                     if ( Application::GetSettings().GetStyleSettings().GetUseImagesInMenus() )
508                     {
509 						Image aImage;
510 						if ( bIsAddonPopupMenu || framework::AddonMenuManager::IsAddonMenuId( nSlotId ))
511 						{
512 							rtl::OUString aImageId;
513 
514 							::framework::MenuConfiguration::Attributes* pMenuAttributes =
515 								(::framework::MenuConfiguration::Attributes*)pSVMenu->GetUserValue( nSlotId );
516 
517 							if ( pMenuAttributes )
518 								aImageId = pMenuAttributes->aImageId; // Retrieve image id from menu attributes
519 
520 							aImage = RetrieveAddOnImage( xFrame, aImageId, aCmd, sal_False, bWasHighContrast );
521 						}
522 						else
523                         {
524                             rtl::OUString aSlotURL( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
525                             aSlotURL += rtl::OUString::valueOf( sal_Int32( nSlotId ));
526                             aImage = GetImage( xFrame, aSlotURL, sal_False, bWasHighContrast );
527                         }
528 
529 						if ( !!aImage )
530 							pSVMenu->SetItemImage( nSlotId, aImage );
531                     }
532 
533 					if ( !IsItemHidden_Impl(nSlotId, bOleServer, bMac) )
534 						++nVisibleItems;
535 					else
536 						pSVMenu->RemoveItem( nSVPos-- );
537 					break;
538 				}
539 
540 				case MENUITEM_IMAGE:
541 					//! not implemented
542 					break;
543 
544 				case MENUITEM_SEPARATOR:
545 					//! not implemented
546 					break;
547 				default:
548 					break; // DONTKNOW and STRINGIMAGE not handled.
549 			}
550 		}
551 	}
552 	pBindings->LEAVEREGISTRATIONS(); --nLocks;
553 }
554 
555 //--------------------------------------------------------------------
556 
557 // called on activation of the SV-Menu
558 
559 IMPL_LINK( SfxVirtualMenu, Highlight, Menu *, pMenu )
560 {
561 	DBG_MEMTEST();
562 	DBG_CHKTHIS(SfxVirtualMenu, 0);
563 
564 	// eigenes StarView-Menu
565 	if ( pMenu == pSVMenu )
566 	{
567 		// AutoDeactivate ist jetzt nicht mehr n"otig
568 		//sal_uInt16 nSlotId = pMenu->GetCurItemId();
569 		if ( pAutoDeactivate )
570 			pAutoDeactivate->Stop();
571 	}
572 
573 	return sal_True;
574 }
575 
576 IMPL_LINK( SfxVirtualMenu, SettingsChanged, void*, EMPTYARG )
577 {
578     sal_uInt16 nItemCount = pSVMenu->GetItemCount();
579     SfxViewFrame *pViewFrame = pBindings->GetDispatcher()->GetFrame();
580     sal_Bool bIcons = Application::GetSettings().GetStyleSettings().GetUseImagesInMenus();
581 	sal_Bool bIsHiContrastMode = IsHiContrastMode();
582 	Reference<com::sun::star::frame::XFrame> xFrame( pViewFrame->GetFrame().GetFrameInterface() );
583 
584 	if ( !bIsAddonPopupMenu )
585 	{
586 		for ( sal_uInt16 nSVPos=0; nSVPos<nItemCount; ++nSVPos )
587 		{
588 			sal_uInt16          nSlotId = pSVMenu->GetItemId( nSVPos );
589 			MenuItemType    nType   = pSVMenu->GetItemType( nSVPos );
590 			if ( nType == MENUITEM_STRING && bIcons )
591 			{
592 				if ( framework::AddonMenuManager::IsAddonMenuId( nSlotId ))
593 				{
594                     // Special code for Add-On menu items. They can appear inside the help menu.
595 					rtl::OUString aCmd( pSVMenu->GetItemCommand( nSlotId ) );
596 					rtl::OUString aImageId;
597 
598 					::framework::MenuConfiguration::Attributes* pMenuAttributes =
599 						(::framework::MenuConfiguration::Attributes*)pSVMenu->GetUserValue( nSlotId );
600 
601 					if ( pMenuAttributes )
602 						aImageId = pMenuAttributes->aImageId; // Retrieve image id from menu attributes
603 
604 					pSVMenu->SetItemImage( nSlotId, RetrieveAddOnImage( xFrame, aImageId, aCmd, sal_False, bIsHiContrastMode ));
605 				}
606 				else
607                 {
608                     rtl::OUString aSlotURL( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
609                     aSlotURL += rtl::OUString::valueOf( sal_Int32( nSlotId ));
610 				    pSVMenu->SetItemImage( nSlotId, GetImage( xFrame, aSlotURL, sal_False, bWasHighContrast ));
611                 }
612 			}
613 			else if( nType == MENUITEM_STRINGIMAGE && !bIcons )
614 			{
615 				pSVMenu->SetItemImage( nSlotId, Image() );
616 			}
617 		}
618 	}
619 	else
620 	{
621 		// Remove/update images from Add-Ons top-level popup menus when settings have changed
622 		if ( !bIcons )
623 			RemoveMenuImages( pSVMenu );
624 		else
625 			UpdateImages( pSVMenu );
626 	}
627 
628 	// Special code to remove menu images from runtime popup menus when settings have changed
629 	if ( pParent && pSVMenu == pParent->pAddonsMenu )
630 	{
631 		if ( !bIcons )
632 			RemoveMenuImages( pParent->pAddonsMenu->GetPopupMenu( SID_ADDONS ));
633 		else
634 			UpdateImages( pParent->pAddonsMenu->GetPopupMenu( SID_ADDONS ));
635 	}
636 
637     if ( pImageControl )
638         pImageControl->Update();
639 
640     return 0;
641 }
642 
643 //--------------------------------------------------------------------
644 
645 void SfxVirtualMenu::UpdateImages()
646 {
647     sal_Bool bIcons = Application::GetSettings().GetStyleSettings().GetUseImagesInMenus();
648 
649 	if ( bIcons )
650 	{
651 		sal_Bool			bIsHiContrastMode   = IsHiContrastMode();
652 		sal_uInt16			nItemCount          = pSVMenu->GetItemCount();
653 		SfxViewFrame *	pViewFrame          = pBindings->GetDispatcher()->GetFrame();
654 		Reference<com::sun::star::frame::XFrame> xFrame( pViewFrame->GetFrame().GetFrameInterface() );
655 
656 		for ( sal_uInt16 nSVPos=0; nSVPos < nItemCount; ++nSVPos )
657 		{
658 			sal_uInt16 nSlotId = pSVMenu->GetItemId( nSVPos );
659 			if ( pSVMenu->GetItemType( nSVPos ) == MENUITEM_STRINGIMAGE )
660 			{
661                 if ( framework::AddonMenuManager::IsAddonMenuId( nSlotId ))
662                 {
663                     // Special code for Add-On menu items. They can appear inside the help menu.
664 					rtl::OUString aCmd( pSVMenu->GetItemCommand( nSlotId ) );
665 					rtl::OUString aImageId;
666 
667 					::framework::MenuConfiguration::Attributes* pMenuAttributes =
668 						(::framework::MenuConfiguration::Attributes*)pSVMenu->GetUserValue( nSlotId );
669 
670 					if ( pMenuAttributes )
671 						aImageId = pMenuAttributes->aImageId; // Retrieve image id from menu attributes
672 
673 					pSVMenu->SetItemImage( nSlotId, RetrieveAddOnImage( xFrame, aImageId, aCmd, sal_False, bIsHiContrastMode ));
674                 }
675                 else
676                 {
677                     rtl::OUString aSlotURL( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
678                     aSlotURL += rtl::OUString::valueOf( sal_Int32( nSlotId ));
679 				    pSVMenu->SetItemImage( nSlotId, GetImage( xFrame, aSlotURL, sal_False, bWasHighContrast ));
680                 }
681 			}
682 		}
683 
684         if ( pImageControl )
685             pImageControl->Update();
686 	}
687 }
688 
689 //--------------------------------------------------------------------
690 
691 void SfxVirtualMenu::UpdateImages( Menu* pMenu )
692 {
693 	if ( !pMenu )
694 		return;
695 
696 	framework::AddonsOptions	aAddonOptions;
697 
698     sal_Bool bIcons = Application::GetSettings().GetStyleSettings().GetUseImagesInMenus();
699 	if ( bIcons )
700 	{
701 		sal_Bool			bIsHiContrastMode	= IsHiContrastMode();
702 		sal_uInt16			nItemCount			= pMenu->GetItemCount();
703 		Reference<com::sun::star::frame::XFrame> aXFrame( pBindings->GetDispatcher_Impl()->GetFrame()->GetFrame().GetFrameInterface() );
704 
705 		for ( sal_uInt16 nPos=0; nPos < nItemCount; ++nPos )
706 		{
707 			sal_uInt16 nSlotId = pMenu->GetItemId( nPos );
708 			PopupMenu* pPopup = pMenu->GetPopupMenu( nSlotId );
709 			if ( pMenu->GetItemType( nPos ) != MENUITEM_SEPARATOR )
710 			{
711 				rtl::OUString aImageId;
712 
713 				::framework::MenuConfiguration::Attributes* pMenuAttributes =
714 					(::framework::MenuConfiguration::Attributes*)pMenu->GetUserValue( nSlotId );
715 
716 				if ( pMenuAttributes )
717 					aImageId = pMenuAttributes->aImageId; // Retrieve image id from menu attributes
718 
719 				pMenu->SetItemImage( nSlotId, RetrieveAddOnImage( aXFrame, aImageId, pMenu->GetItemCommand( nSlotId ), sal_False, bIsHiContrastMode ));
720 			}
721 
722 			if ( pPopup )
723 				UpdateImages( pPopup );
724 		}
725 
726         if ( pImageControl )
727             pImageControl->Update();
728 	}
729 }
730 
731 //--------------------------------------------------------------------
732 
733 void SfxVirtualMenu::RemoveMenuImages( Menu* pMenu )
734 {
735 	if ( !pMenu )
736 		return;
737 
738 	sal_uInt16 nItemCount = pMenu->GetItemCount();
739 	for ( sal_uInt16 nPos=0; nPos < nItemCount; ++nPos )
740 	{
741 		sal_uInt16 nSlotId = pMenu->GetItemId( nPos );
742 		PopupMenu* pPopup = pMenu->GetPopupMenu( nSlotId );
743 		if ( pMenu->GetItemType( nPos ) == MENUITEM_STRINGIMAGE )
744 			pMenu->SetItemImage( nSlotId, Image() );
745 		if ( pPopup )
746 			RemoveMenuImages( pPopup );
747 	}
748 }
749 
750 //--------------------------------------------------------------------
751 
752 bool SfxVirtualMenu::Bind_Impl( Menu *pMenu )
753 {
754 	// Selber suchen, da SV mit 'sal_uInt16 nSID = pSVMenu->GetCurItemId();' immer
755 	// 0 liefert. Das ist so, weil die Event-Weiterleitung lt. TH nichts mit
756 	// CurItem des Parent-Menus zu tun hat.
757 	sal_uInt32 nAddonsPopupPrefixLen = ADDONSPOPUPMENU_URL_PREFIX.getLength();
758 
759 	for ( sal_uInt16 nPos = 0; nPos < nCount; ++nPos )
760 	{
761 		// angesprochenes Sub-Menu gefunden?
762 		bool bFound = false;
763 		sal_uInt16 nSID = pSVMenu->GetItemId(nPos);
764 		SfxMenuControl &rCtrl = pItems[nPos];
765 		bFound = pSVMenu->GetPopupMenu(nSID) == pMenu;
766 		SfxVirtualMenu *pSubMenu = rCtrl.GetPopupMenu();
767 
768 		if ( bFound )
769 		{
770 			// Nur ein gebundener Menu-Controller hat schon seine Id!
771 			if ( !rCtrl.GetId() )
772 			{
773 				bIsAddonPopupMenu = sal_False;
774 				DBG_ASSERT( !pSubMenu, "Popup schon vorhanden!");
775 
776 				// Check if the popup is an Add-On popup menu
777 				// Either the popup menu has a special ID  or a special command URL prefix!
778 				rtl::OUString aCommand = pSVMenu->GetItemCommand( nSID );
779 				if ( ( nSID == SID_ADDONS ) ||
780 					 ( nSID == SID_ADDONHELP ) ||
781 					 (( (sal_uInt32)aCommand.getLength() > nAddonsPopupPrefixLen ) &&
782 					  ( aCommand.indexOf( ADDONSPOPUPMENU_URL_PREFIX ) == 0 )) )
783 					bIsAddonPopupMenu = sal_True;
784 
785 				// VirtualMenu f"ur Sub-Menu erzeugen
786 				sal_Bool bRes = bResCtor;
787 				pSubMenu = new SfxVirtualMenu( nSID, this,
788 						*pMenu, sal_False, *pBindings, bOLE, bRes, bIsAddonPopupMenu );
789 
790 				DBG_OUTF( ("Neues VirtualMenu %lx erzeugt", pSubMenu) );
791 
792 				rCtrl.Bind( this, nSID, *pSubMenu,
793 					pSVMenu->GetItemText(nSID), pSVMenu->GetHelpText(nSID),
794 					*pBindings );
795 
796 				// Activate weiterleiten
797 				pSubMenu->Bind_Impl( pMenu );
798 				pSubMenu->Activate( pMenu );
799 			}
800 		}
801 
802 		// rekursiv weitersuchen (SV Activate nur am Menu selbst und Top-Menu)
803 		if ( !bFound && pSubMenu )
804 			bFound = pSubMenu->Bind_Impl( pMenu );
805 
806 		// gefunden, dann abbrechen
807 		if ( bFound )
808 			return true;
809 	}
810 
811 	// nicht in diesem Untermenu gefunden
812 	return false;
813 }
814 
815 void SfxVirtualMenu::BindControllers()
816 {
817 	pBindings->ENTERREGISTRATIONS();
818 
819 	sal_uInt16 nPos;
820 	for ( nPos = 0; nPos < nCount; ++nPos )
821 	{
822 		SfxMenuControl& rCtrl = pItems[nPos];
823 		if ( rCtrl.IsBindable_Impl() && !rCtrl.GetPopupMenu() )
824 			rCtrl.ReBind();
825 	}
826 
827 	SfxMenuCtrlArr_Impl& rCtrlArr = GetAppCtrl_Impl();
828 	for ( nPos=0; nPos<rCtrlArr.Count(); nPos++ )
829 	{
830 		SfxMenuControl* pCtrl = rCtrlArr[nPos];
831 		sal_uInt16 nSlotId = pCtrl->GetId();
832         if ( !pSVMenu->GetItemCommand(nSlotId).Len() )
833 			pCtrl->ReBind();
834 	}
835 
836 	pBindings->LEAVEREGISTRATIONS();
837 	bControllersUnBound = sal_False;
838 }
839 
840 void SfxVirtualMenu::UnbindControllers()
841 {
842 	pBindings->ENTERREGISTRATIONS();
843 
844 	sal_uInt16 nPos;
845 	for ( nPos = 0; nPos < nCount; ++nPos )
846 	{
847 		SfxMenuControl &rCtrl = pItems[nPos];
848 		if ( rCtrl.IsBound() )
849 			rCtrl.UnBind();
850 	}
851 
852 	SfxMenuCtrlArr_Impl& rCtrlArr = GetAppCtrl_Impl();
853 	for ( nPos=0; nPos<rCtrlArr.Count(); nPos++ )
854 	{
855 		SfxMenuControl* pCtrl = rCtrlArr[nPos];
856 		if ( pCtrl->IsBound() )
857 			// UnoController sind nicht gebunden!
858 			pCtrl->UnBind();
859 	}
860 
861 	pBindings->LEAVEREGISTRATIONS();
862 	bControllersUnBound = sal_True;
863 }
864 
865 
866 //--------------------------------------------------------------------
867 void SfxVirtualMenu::InsertAddOnsMenuItem( Menu* pMenu )
868 {
869 	// Create special popup menu that is filled with the 3rd party components popup menu items
870 	Reference<com::sun::star::lang::XMultiServiceFactory> aXMultiServiceFactory(::comphelper::getProcessServiceFactory());
871 	::framework::MenuConfiguration aConf( aXMultiServiceFactory );
872 	Reference<com::sun::star::frame::XFrame> xFrame( pBindings->GetDispatcher_Impl()->GetFrame()->GetFrame().GetFrameInterface() );
873 
874 	PopupMenu* pAddonMenu = NULL;
875 	try
876 	{
877 		pAddonMenu = framework::AddonMenuManager::CreateAddonMenu( xFrame );
878 	}
879 	catch ( ::com::sun::star::lang::WrappedTargetException )
880 	{
881 	}
882 
883 	// Create menu item at the end of the tools popup menu for the addons popup menu
884 	if ( pAddonMenu && pAddonMenu->GetItemCount() > 0 )
885 	{
886 	    sal_uInt16 nItemCount = pMenu->GetItemCount();
887 	    String aAddonsTitle( SfxResId( STR_MENU_ADDONS ));
888 	    if ( nItemCount > 0 && pMenu->GetItemType( nItemCount-1 ) != MENUITEM_SEPARATOR )
889 		    pMenu->InsertSeparator();
890 	    pMenu->InsertItem( SID_ADDONS, aAddonsTitle );
891         pMenu->SetPopupMenu( SID_ADDONS, pAddonMenu );
892 
893 	    if ( Application::GetSettings().GetStyleSettings().GetUseImagesInMenus() )
894 	    {
895                rtl::OUString aSlotURL( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
896                aSlotURL += rtl::OUString::valueOf( sal_Int32( SID_ADDONS ));
897 		 pMenu->SetItemImage( SID_ADDONS, GetImage( xFrame, aSlotURL, sal_False, bWasHighContrast ));
898 	    }
899     }
900 	else
901 	    delete pAddonMenu;
902 }
903 
904 //--------------------------------------------------------------------
905 
906 // called on activation of the SV-Menu
907 
908 IMPL_LINK( SfxVirtualMenu, Activate, Menu *, pMenu )
909 {
910 	DBG_MEMTEST();
911 	DBG_CHKTHIS(SfxVirtualMenu, 0);
912 	DBG_OUTF( ("SfxVirtualMenu %lx activated %lx, own %lx", this, pMenu, pSVMenu));
913 
914 	// MI: wozu war der noch gut?
915 	// MBA: scheint ein alter QAP-Hack gewesen zu sein ( in rev.1.41 eingecheckt ! )
916 //	if ( Application::IsInModalMode() )
917 //		return TRUE; // abw"urgen
918 
919 	if ( pMenu )
920 	{
921 		sal_Bool bDontHide = SvtMenuOptions().IsEntryHidingEnabled();
922 		sal_uInt16 nFlag = pMenu->GetMenuFlags();
923 		if ( bDontHide )
924 			nFlag &= ~MENU_FLAG_HIDEDISABLEDENTRIES;
925 		else
926 			nFlag |= MENU_FLAG_HIDEDISABLEDENTRIES;
927 		pMenu->SetMenuFlags( nFlag );
928 	}
929 
930 	// eigenes StarView-Menu
931 	if ( pMenu == pSVMenu )
932 	{
933 		// doppelt-Activate verhindern
934 		if ( bIsActive )
935 			return sal_True;
936 
937 		// ggf. Pick-Menu erzeugen
938         if ( pParent && pSVMenu == pParent->pPickMenu )
939         {
940 			SfxPickList::Get()->CreateMenuEntries( pParent->pPickMenu );
941         }
942         else
943             pPickMenu = pSVMenu->GetPopupMenu(SID_PICKLIST);
944 
945         if ( pParent && pSVMenu == pParent->pWindowMenu )
946         {
947 			// update window list
948 			::std::vector< ::rtl::OUString > aNewWindowListVector;
949 			Reference< XDesktop > xDesktop( ::comphelper::getProcessServiceFactory()->createInstance(
950 											DEFINE_CONST_OUSTRING( "com.sun.star.frame.Desktop" ) ), UNO_QUERY );
951 
952 			sal_uInt16	nActiveItemId = 0;
953 			sal_uInt16	nItemId = START_ITEMID_WINDOWLIST;
954 
955 			if ( xDesktop.is() )
956 			{
957                 Reference< XFramesSupplier > xTasksSupplier( xDesktop, UNO_QUERY );
958 				Reference< XFrame > xCurrentFrame = xDesktop->getCurrentFrame();
959                 Reference< XIndexAccess > xList ( xTasksSupplier->getFrames(), UNO_QUERY );
960                 sal_Int32 nFrameCount = xList->getCount();
961                 for( sal_Int32 i=0; i<nFrameCount; ++i )
962 				{
963                     Reference< XFrame > xFrame;
964                     Any aVal = xList->getByIndex(i);
965 					if (!(aVal>>=xFrame) || !xFrame.is() )
966 						continue;
967 
968 					if ( xFrame == xCurrentFrame )
969 						nActiveItemId = nItemId;
970 
971 					Window* pWin = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() );
972 					if ( pWin && pWin->IsVisible() )
973 					{
974 						aNewWindowListVector.push_back( pWin->GetText() );
975 						++nItemId;
976 					}
977 				}
978 			}
979 
980 			int	nItemCount		 = pMenu->GetItemCount();
981 
982 			if ( nItemCount > 0 )
983 			{
984 				// remove all old window list entries from menu
985 				sal_uInt16 nPos = pMenu->GetItemPos( START_ITEMID_WINDOWLIST );
986             	for ( sal_uInt16 n = nPos; n < pMenu->GetItemCount(); )
987                 	pMenu->RemoveItem( n );
988 
989 				if ( pMenu->GetItemType( pMenu->GetItemCount()-1 ) == MENUITEM_SEPARATOR )
990                 	pMenu->RemoveItem( pMenu->GetItemCount()-1 );
991 			}
992 
993 			if ( aNewWindowListVector.size() > 0 )
994 			{
995 				// append new window list entries to menu
996 				pMenu->InsertSeparator();
997 				nItemId = START_ITEMID_WINDOWLIST;
998 				for ( sal_uInt32 i = 0; i < aNewWindowListVector.size(); i++ )
999 				{
1000 					pMenu->InsertItem( nItemId, aNewWindowListVector.at( i ), MIB_RADIOCHECK );
1001 					if ( nItemId == nActiveItemId )
1002 						pMenu->CheckItem( nItemId );
1003 					++nItemId;
1004 				}
1005 			}
1006         }
1007         else
1008             pWindowMenu = pSVMenu->GetPopupMenu(SID_MDIWINDOWLIST);
1009 
1010         if ( !pParent && pSVMenu->IsMenuBar() && !pAddonsMenu )
1011         {
1012 			// Store Add-Ons parents of our runtime menu items
1013 			pAddonsMenu	= pSVMenu->GetPopupMenu( SID_ADDONLIST );
1014 		}
1015 
1016 		// f"ur konstistenten Status sorgen
1017 		if ( bControllersUnBound )
1018 			BindControllers();
1019 
1020         //InvalidateKeyCodes();
1021 		pBindings->GetDispatcher_Impl()->Flush();
1022 		for ( sal_uInt16 nPos = 0; nPos < nCount; ++nPos )
1023 		{
1024 			sal_uInt16 nSlotId = (pItems+nPos)->GetId();
1025             if ( nSlotId && nSlotId > END_ITEMID_WINDOWLIST )
1026 				pBindings->Update(nSlotId);
1027 		}
1028 
1029         pBindings->Update( SID_IMAGE_ORIENTATION );
1030 
1031 		// HelpText on-demand
1032 		if ( !bHelpInitialized )
1033 		{
1034             // TODO/CLEANUP: do we need help texts in context menus?
1035             // old way with SlotInfo doesn't work anymore
1036 		}
1037 
1038 		// bis zum Deactivate die Statusupdates unterdr"ucken
1039 		pBindings->ENTERREGISTRATIONS(); ++nLocks; bIsActive = sal_True;
1040 
1041 		if ( pAutoDeactivate ) // QAP-Hack
1042 			pAutoDeactivate->Start();
1043 
1044 		if ( IsHiContrastMode() != bWasHighContrast )
1045 		{
1046 			// Refresh images as our background color changed and remember it!!
1047 			bWasHighContrast = IsHiContrastMode();
1048 			if ( bIsAddonPopupMenu )
1049 				UpdateImages( pSVMenu );
1050 			else
1051 				UpdateImages();
1052 		}
1053 
1054 		// erledigt
1055 		return sal_True;
1056 	}
1057 	else
1058 	{
1059 		// VirtualMenu fuer SubMenu finden und ggf. an VirtualMenu binden
1060 		bool bRet = Bind_Impl( pMenu );
1061 #ifdef DBG_UTIL
1062 		if ( !bRet)
1063 			DBG_WARNING( "W1: Virtual menu konnte nicht erzeugt werden!" );
1064 #endif
1065 		return bRet;
1066 	}
1067 }
1068 
1069 //--------------------------------------------------------------------
1070 
1071 IMPL_LINK( SfxVirtualMenu, Deactivate, Menu *, pMenu )
1072 {
1073 	DBG_MEMTEST();
1074 	DBG_OUTF( ("SfxVirtualMenu %lx deactivated %lx, own %lx", this, pMenu, pSVMenu) );
1075 	if ( bIsActive && ( 0 == pMenu || pMenu == pSVMenu ) )
1076 	{
1077 		if ( pAutoDeactivate )
1078 			pAutoDeactivate->Stop();
1079 
1080 		// Bis auf die Menubar k"onnen alle Controller unbinded werden, wenn
1081 		// das Menue deaktiviert ( = zugeklappt ) wird
1082 		if ( pParent )
1083 			UnbindControllers();
1084 		pBindings->LEAVEREGISTRATIONS(); --nLocks; bIsActive = sal_False;
1085 	}
1086 	return sal_True;
1087 }
1088 //--------------------------------------------------------------------
1089 
1090 // called on activation of the SV-Menu
1091 
1092 IMPL_LINK( SfxVirtualMenu, Select, Menu *, pMenu )
1093 {
1094 	sal_uInt16 nSlotId = (sal_uInt16) pMenu->GetCurItemId();
1095 	DBG_OUTF( ("SfxVirtualMenu %lx selected %u from %lx", this, nSlotId, pMenu) );
1096 /*
1097 	if ( pSVMenu->GetItemCommand( nSlotId ).Len() )
1098 	{
1099 		SfxMenuCtrlArr_Impl& rCtrlArr = GetAppCtrl_Impl();
1100 		for ( sal_uInt16 nPos=0; nPos<rCtrlArr.Count(); nPos++ )
1101 		{
1102 			SfxMenuControl* pCtrl = rCtrlArr[nPos];
1103 			if ( pCtrl->GetId() == nSlotId )
1104 			{
1105 				SfxUnoMenuControl *pUnoCtrl = (SfxUnoMenuControl*) pCtrl;
1106 				pUnoCtrl->Select();
1107 				return sal_True;
1108 			}
1109 		}
1110 	}
1111 */
1112     if ( nSlotId >= START_ITEMID_WINDOWLIST && nSlotId <= END_ITEMID_WINDOWLIST )
1113 	{
1114 		// window list menu item selected
1115         Reference< XFramesSupplier > xDesktop( ::comphelper::getProcessServiceFactory()->createInstance(
1116 										DEFINE_CONST_OUSTRING( "com.sun.star.frame.Desktop" ) ), UNO_QUERY );
1117 		if ( xDesktop.is() )
1118 		{
1119 			sal_uInt16 nTaskId = START_ITEMID_WINDOWLIST;
1120             Reference< XIndexAccess > xList( xDesktop->getFrames(), UNO_QUERY );
1121             sal_Int32 nFrameCount = xList->getCount();
1122             for ( sal_Int32 i=0; i<nFrameCount; ++i )
1123 			{
1124                 Any aItem = xList->getByIndex(i);
1125                 Reference< XFrame > xFrame;
1126 				if (( aItem >>= xFrame ) && xFrame.is() && nTaskId == nSlotId )
1127 				{
1128                     Window* pWin = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() );
1129 					pWin->GrabFocus();
1130                     pWin->ToTop( TOTOP_RESTOREWHENMIN );
1131 					break;
1132 				}
1133 
1134 				nTaskId++;
1135 			}
1136 		}
1137 
1138 		return sal_True;
1139 	}
1140     else if ( nSlotId >= START_ITEMID_PICKLIST && nSlotId <= END_ITEMID_PICKLIST )
1141     {
1142         SfxPickList::Get()->ExecuteMenuEntry( nSlotId );
1143         return sal_True;
1144     }
1145 
1146 	if ( pMenu->GetItemCommand( nSlotId ).Len() )
1147 		pBindings->ExecuteCommand_Impl( pMenu->GetItemCommand( nSlotId ) );
1148 	else
1149 		pBindings->Execute( nSlotId );
1150 
1151 	return sal_True;
1152 }
1153 
1154 //--------------------------------------------------------------------
1155 
1156 // returns the associated StarView-menu
1157 
1158 Menu* SfxVirtualMenu::GetSVMenu() const
1159 {
1160 	DBG_MEMTEST();
1161 	DBG_CHKTHIS(SfxVirtualMenu, 0);
1162 
1163 	return pSVMenu;
1164 }
1165 
1166 //--------------------------------------------------------------------
1167 
1168 // return the position of the specified item
1169 
1170 sal_uInt16 SfxVirtualMenu::GetItemPos( sal_uInt16 nItemId ) const
1171 {
1172 	DBG_MEMTEST();
1173 	DBG_CHKTHIS(SfxVirtualMenu, 0);
1174 
1175 	for ( sal_uInt16 nPos = 0; nPos < nCount; ++nPos )
1176 		if ( (pItems+nPos)->GetId() == nItemId )
1177 			return nPos;
1178 	return MENU_ITEM_NOTFOUND;
1179 }
1180 
1181 //--------------------------------------------------------------------
1182 
1183 // returns the popup-menu assigned to the item or 0 if none
1184 
1185 SfxVirtualMenu* SfxVirtualMenu::GetPopupMenu( sal_uInt16 nItemId ) const
1186 {
1187 	DBG_MEMTEST();
1188 	DBG_CHKTHIS(SfxVirtualMenu, 0);
1189 
1190 	sal_uInt16 nPos = GetItemPos(nItemId);
1191 	if ( nPos != MENU_ITEM_NOTFOUND )
1192 		return (pItems+nPos)->GetPopupMenu();
1193 	return 0;
1194 }
1195 //--------------------------------------------------------------------
1196 
1197 // returns the text of the item as currently shown in the menu
1198 
1199 String SfxVirtualMenu::GetItemText( sal_uInt16 nSlotId ) const
1200 {
1201 	DBG_MEMTEST();
1202 	DBG_CHKTHIS(SfxVirtualMenu, 0);
1203 
1204 	sal_uInt16 nPos = GetItemPos(nSlotId);
1205 	if ( nPos != MENU_ITEM_NOTFOUND )
1206 		return (pItems+nPos)->GetTitle();
1207 	return String();
1208 }
1209 //--------------------------------------------------------------------
1210 
1211 // returns the text of the item as currently shown in the menu
1212 
1213 String SfxVirtualMenu::GetItemHelpText( sal_uInt16 nSlotId ) const
1214 {
1215 	DBG_MEMTEST();
1216 	DBG_CHKTHIS(SfxVirtualMenu, 0);
1217 
1218 	sal_uInt16 nPos = GetItemPos(nSlotId);
1219 	if ( nPos != MENU_ITEM_NOTFOUND )
1220 		return (pItems+nPos)->GetHelpText();
1221 	return String();
1222 }
1223 
1224 //--------------------------------------------------------------------
1225 
1226 // set the checkmark of the specified item
1227 
1228 void SfxVirtualMenu::CheckItem( sal_uInt16 nItemId, sal_Bool bCheck )
1229 {
1230 	DBG_MEMTEST();
1231 	DBG_CHKTHIS(SfxVirtualMenu, 0);
1232 	DBG_ASSERT( this != 0, "");
1233 	DBG_ASSERT( pSVMenu != 0, "" );
1234 	if (pSVMenu->GetItemPos( nItemId ) != MENU_ITEM_NOTFOUND )
1235 		pSVMenu->CheckItem( nItemId, bCheck );
1236 }
1237 //--------------------------------------------------------------------
1238 
1239 // set the enabled-state of the specified item
1240 
1241 void SfxVirtualMenu::EnableItem( sal_uInt16 nItemId, sal_Bool bEnable )
1242 {
1243 	DBG_MEMTEST();
1244 	DBG_CHKTHIS(SfxVirtualMenu, 0);
1245 	DBG_ASSERT( this != 0, "");
1246 	DBG_ASSERT( pSVMenu != 0, "" );
1247 
1248 	if (pSVMenu->GetItemPos( nItemId ) != MENU_ITEM_NOTFOUND )
1249 		pSVMenu->EnableItem( nItemId, bEnable );
1250 }
1251 //--------------------------------------------------------------------
1252 
1253 // set the text of the specified item
1254 
1255 void SfxVirtualMenu::SetItemText( sal_uInt16 nItemId, const String& rText )
1256 {
1257 	DBG_MEMTEST();
1258 	DBG_CHKTHIS(SfxVirtualMenu, 0);
1259 	DBG_ASSERT( this != 0, "");
1260 	DBG_ASSERT( pSVMenu != 0, "" );
1261 	if (pSVMenu->GetItemPos( nItemId ) != MENU_ITEM_NOTFOUND )
1262 		pSVMenu->SetItemText( nItemId, rText );
1263 }
1264 
1265 //--------------------------------------------------------------------
1266 
1267 //
1268 
1269 void SfxVirtualMenu::SetPopupMenu( sal_uInt16 nItemId, PopupMenu *pMenu )
1270 {
1271 	DBG_MEMTEST();
1272 	DBG_CHKTHIS(SfxVirtualMenu, 0);
1273 
1274 	if (pSVMenu->GetItemPos( nItemId ) != MENU_ITEM_NOTFOUND )
1275 		GetSVMenu()->SetPopupMenu( nItemId, pMenu );
1276 	for ( sal_uInt16 n = 0; n < nCount; ++n )
1277 	{
1278 		SfxVirtualMenu *pSubMenu = (pItems+n)->GetPopupMenu();
1279 		if ( pSubMenu )
1280 			pSubMenu->SetPopupMenu( nItemId, pMenu );
1281 	}
1282 }
1283 
1284 //--------------------------------------------------------------------
1285 
1286 // Erzwingt die Initialisierung, die sonst nur im Activate kommt
1287 
1288 void SfxVirtualMenu::InitPopup( sal_uInt16 nPos, sal_Bool /*bOLE*/ )
1289 {
1290 	DBG_MEMTEST();
1291 	DBG_CHKTHIS(SfxVirtualMenu, 0);
1292 
1293 	sal_uInt16 nSID = pSVMenu->GetItemId(nPos);
1294 	PopupMenu *pMenu = pSVMenu->GetPopupMenu( nSID );
1295 
1296 	DBG_ASSERT( pMenu, "Hier gibt es kein Popup!");
1297 
1298 	SfxMenuControl &rCtrl = pItems[nPos];
1299 	if ( !rCtrl.GetId() )
1300 	{
1301 		// VirtualMenu f"ur Sub-Menu erzeugen
1302 		sal_Bool bRes = bResCtor;
1303 		SfxVirtualMenu *pSubMenu =
1304 			new SfxVirtualMenu(nSID, this, *pMenu, sal_False, *pBindings, bOLE, bRes);
1305 
1306 		DBG_OUTF( ("Neues VirtualMenu %lx erzeugt", pSubMenu) );
1307 
1308 		rCtrl.Bind( this, nSID, *pSubMenu,
1309 			pSVMenu->GetItemText(nSID), pSVMenu->GetHelpText(nSID),
1310 			*pBindings );
1311 	}
1312 }
1313 
1314 void SfxVirtualMenu::InitializeHelp()
1315 {
1316 	for ( sal_uInt16 nPos = 0; nPos<pSVMenu->GetItemCount(); ++nPos )
1317 	{
1318 		sal_uInt16 nSlotId = pSVMenu->GetItemId(nPos);
1319         // TODO/CLEANUP: this code does nothing!
1320 //        if ( !bHelpInitialized )
1321 //            pSVMenu->SetHelpText( nId, rSlotPool.GetSlotHelpText_Impl( nId ) );
1322 		SfxMenuControl &rCtrl = pItems[nPos];
1323 		if ( nSlotId && !rCtrl.GetId() )
1324 		{
1325 			InitPopup( nPos, sal_True );
1326 		}
1327 
1328 		SfxVirtualMenu *pSubMenu = rCtrl.GetPopupMenu();
1329 		if ( pSubMenu )
1330 			pSubMenu->InitializeHelp();
1331 	}
1332 
1333 	bHelpInitialized = sal_True;
1334 }
1335 
1336 typedef sal_uIntPtr (__LOADONCALLAPI *HelpIdFunc) ( const String& );
1337 
1338 void SfxVirtualMenu::SetHelpIds( ResMgr *pRes )
1339 {
1340 	pResMgr = pRes;
1341 }
1342 
1343