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