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