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 sal_uInt16 nPos = pSVMenu->GetItemPos( SID_MDIWINDOWLIST ); 345 if ( nPos != MENU_ITEM_NOTFOUND && xFrame.is() ) 346 { 347 // Retrieve addon popup menus and add them to our menu bar 348 Reference< com::sun::star::frame::XModel > xModel; 349 Reference< com::sun::star::frame::XController > xController( xFrame->getController(), UNO_QUERY ); 350 if ( xController.is() ) 351 xModel = Reference< com::sun::star::frame::XModel >( xController->getModel(), UNO_QUERY ); 352 framework::AddonMenuManager::MergeAddonPopupMenus( xFrame, xModel, nPos, (MenuBar *)pSVMenu ); 353 } 354 355 // Merge the Add-Ons help menu items into the Office help menu 356 if ( xFrame.is() ) 357 framework::AddonMenuManager::MergeAddonHelpMenu( xFrame, (MenuBar *)pSVMenu ); 358 359 // Set addon menu pointer here to avoid problems. When accessibility is enabled, the whole menu 360 // is created immediately! 361 pAddonsMenu = pSVMenu->GetPopupMenu( SID_ADDONLIST ); 362 } 363 else if ( pParent ) 364 { 365 if ( pSVMenu == pParent->pAddonsMenu && 366 framework::AddonsOptions().HasAddonsMenu() && 367 !pSVMenu->GetPopupMenu( SID_ADDONS ) ) 368 { 369 // Create menu item at the end of the tools popup menu for the addons popup menu 370 InsertAddOnsMenuItem( pSVMenu ); 371 } 372 } 373 374 // get and store the number of items 375 nCount = pSVMenu->GetItemCount(); 376 377 // Achtung: nur zu diesem Zeitpunkt ist garantiert, da\s nCount und 378 // der ItemCount des SV-Menues "ubereinstimmen; sp"ater kann das SvMenue 379 // auch mehr Eintr"age haben (Pickliste!) 380 if (nCount) 381 pItems = new SfxMenuControl[nCount]; 382 383 // remember some values 384 SFX_APP(); 385 const int bOleServer = sal_False; 386 const int bMac = sal_False; 387 SvtMenuOptions aOptions; 388 aOptions.AddListenerLink( LINK( this, SfxVirtualMenu, SettingsChanged ) ); 389 390 // iterate through the items 391 pBindings->ENTERREGISTRATIONS(); ++nLocks; 392 pImageControl = new SfxMenuImageControl_Impl( SID_IMAGE_ORIENTATION, *pBindings, this ); 393 394 // Update high contrast state 395 bWasHighContrast = IsHiContrastMode(); 396 397 sal_uInt16 nSVPos = 0; 398 for ( sal_uInt16 nPos=0; nPos<nCount; ++nPos, ++nSVPos ) 399 { 400 sal_uInt16 nSlotId = pSVMenu->GetItemId(nSVPos); 401 PopupMenu* pPopup = pSVMenu->GetPopupMenu(nSlotId); 402 if( pPopup && nSlotId >= SID_OBJECTMENU0 && nSlotId <= SID_OBJECTMENU_LAST ) 403 { 404 // artefact in XML menuconfig: every entry in root menu must have a popup! 405 pSVMenu->SetPopupMenu( nSlotId, NULL ); 406 DELETEZ( pPopup ); 407 } 408 409 const String sItemText = pSVMenu->GetItemText(nSlotId); 410 const String sHelpText = pSVMenu->GetHelpText(nSlotId); 411 412 if ( pPopup ) 413 { 414 415 SfxMenuControl *pMnuCtrl = 416 SfxMenuControl::CreateControl(nSlotId, *pPopup, *pBindings); 417 418 if ( pMnuCtrl ) 419 { 420 // Das Popup war offensichtlich kein "echtes"; solche werden 421 // niemals aus der Resource geladen und m"ussen daher explizit 422 // gel"oscht werden 423 if ( pSVMenu->GetPopupMenu( nSlotId ) == pPopup ) 424 pSVMenu->SetPopupMenu( nSlotId, NULL ); 425 delete pPopup; 426 pPopup = 0; 427 428 SfxMenuCtrlArr_Impl &rCtrlArr = GetAppCtrl_Impl(); 429 rCtrlArr.C40_INSERT( SfxMenuControl, pMnuCtrl, rCtrlArr.Count() ); 430 (pItems+nPos)->Bind( 0, nSlotId, sItemText, sHelpText, *pBindings); 431 pMnuCtrl->Bind( this, nSlotId, sItemText, sHelpText, *pBindings); 432 433 if ( Application::GetSettings().GetStyleSettings().GetUseImagesInMenus() ) 434 { 435 rtl::OUString aSlotURL( RTL_CONSTASCII_USTRINGPARAM( "slot:" )); 436 aSlotURL += rtl::OUString::valueOf( sal_Int32( nSlotId )); 437 Image aImage = GetImage( xFrame, aSlotURL, sal_False, bWasHighContrast ); 438 pSVMenu->SetItemImage( nSlotId, aImage ); 439 } 440 } 441 else 442 { 443 const SfxSlot* pSlot = pSlotPool->GetSlot( nSlotId ); 444 if ( pSlot ) 445 { 446 rtl::OString aCmd(".uno:"); 447 aCmd += pSlot->GetUnoName(); 448 pSVMenu->SetHelpId( nSlotId, pSlot->GetUnoName() ); 449 } 450 451 pMnuCtrl = pItems+nPos; 452 453 // normalerweise jetzt erst im Activate-Handler 454 if ( bOLE ) 455 { 456 pMnuCtrl->Bind( this, nSlotId, 457 *new SfxVirtualMenu(nSlotId, this, *pPopup, bHelpInitialized, *pBindings, bOLE, bResCtor), 458 sItemText, sHelpText, 459 *pBindings ); 460 } 461 } 462 463 ++nVisibleItems; 464 } 465 else 466 { 467 switch ( pSVMenu->GetItemType(nSVPos) ) 468 { 469 case MENUITEM_STRING: 470 case MENUITEM_STRINGIMAGE: 471 { 472 SfxMenuControl *pMnuCtrl=0; 473 String aCmd( pSVMenu->GetItemCommand( nSlotId ) ); 474 if ( aCmd.Len() && (( nSlotId < SID_SFX_START ) || ( nSlotId > SHRT_MAX )) ) 475 { 476 // try to create control via comand name 477 pMnuCtrl = SfxMenuControl::CreateControl( aCmd, nSlotId, *pSVMenu, sItemText, sHelpText, *pBindings, this ); 478 if ( pMnuCtrl ) 479 { 480 SfxMenuCtrlArr_Impl &rCtrlArr = GetAppCtrl_Impl(); 481 rCtrlArr.C40_INSERT( SfxMenuControl, pMnuCtrl, rCtrlArr.Count()); 482 (pItems+nPos)->Bind( 0, nSlotId, sItemText, sHelpText, *pBindings); 483 } 484 } 485 486 if ( !pMnuCtrl ) 487 { 488 // try to create control via Id 489 pMnuCtrl = SfxMenuControl::CreateControl(nSlotId, *pSVMenu, *pBindings); 490 if ( pMnuCtrl ) 491 { 492 SfxMenuCtrlArr_Impl &rCtrlArr = GetAppCtrl_Impl(); 493 rCtrlArr.C40_INSERT( SfxMenuControl, pMnuCtrl, rCtrlArr.Count()); 494 (pItems+nPos)->Bind( 0, nSlotId, sItemText, sHelpText, *pBindings); 495 } 496 else 497 // take default control 498 pMnuCtrl = (pItems+nPos); 499 500 pMnuCtrl->Bind( this, nSlotId, sItemText, sHelpText, *pBindings); 501 } 502 503 if ( Application::GetSettings().GetStyleSettings().GetUseImagesInMenus() ) 504 { 505 Image aImage; 506 if ( bIsAddonPopupMenu || framework::AddonMenuManager::IsAddonMenuId( nSlotId )) 507 { 508 rtl::OUString aImageId; 509 510 ::framework::MenuConfiguration::Attributes* pMenuAttributes = 511 (::framework::MenuConfiguration::Attributes*)pSVMenu->GetUserValue( nSlotId ); 512 513 if ( pMenuAttributes ) 514 aImageId = pMenuAttributes->aImageId; // Retrieve image id from menu attributes 515 516 aImage = RetrieveAddOnImage( xFrame, aImageId, aCmd, sal_False, bWasHighContrast ); 517 } 518 else 519 { 520 rtl::OUString aSlotURL( RTL_CONSTASCII_USTRINGPARAM( "slot:" )); 521 aSlotURL += rtl::OUString::valueOf( sal_Int32( nSlotId )); 522 aImage = GetImage( xFrame, aSlotURL, sal_False, bWasHighContrast ); 523 } 524 525 if ( !!aImage ) 526 pSVMenu->SetItemImage( nSlotId, aImage ); 527 } 528 529 if ( !IsItemHidden_Impl(nSlotId, bOleServer, bMac) ) 530 ++nVisibleItems; 531 else 532 pSVMenu->RemoveItem( nSVPos-- ); 533 break; 534 } 535 536 case MENUITEM_IMAGE: 537 //! not implemented 538 break; 539 540 case MENUITEM_SEPARATOR: 541 //! not implemented 542 break; 543 default: 544 break; // DONTKNOW and STRINGIMAGE not handled. 545 } 546 } 547 } 548 pBindings->LEAVEREGISTRATIONS(); --nLocks; 549 } 550 551 //-------------------------------------------------------------------- 552 553 // called on activation of the SV-Menu 554 555 IMPL_LINK( SfxVirtualMenu, Highlight, Menu *, pMenu ) 556 { 557 DBG_MEMTEST(); 558 DBG_CHKTHIS(SfxVirtualMenu, 0); 559 560 // eigenes StarView-Menu 561 if ( pMenu == pSVMenu ) 562 { 563 // AutoDeactivate ist jetzt nicht mehr n"otig 564 //sal_uInt16 nSlotId = pMenu->GetCurItemId(); 565 if ( pAutoDeactivate ) 566 pAutoDeactivate->Stop(); 567 } 568 569 return sal_True; 570 } 571 572 IMPL_LINK( SfxVirtualMenu, SettingsChanged, void*, EMPTYARG ) 573 { 574 sal_uInt16 nItemCount = pSVMenu->GetItemCount(); 575 SfxViewFrame *pViewFrame = pBindings->GetDispatcher()->GetFrame(); 576 sal_Bool bIcons = Application::GetSettings().GetStyleSettings().GetUseImagesInMenus(); 577 sal_Bool bIsHiContrastMode = IsHiContrastMode(); 578 Reference<com::sun::star::frame::XFrame> xFrame( pViewFrame->GetFrame().GetFrameInterface() ); 579 580 if ( !bIsAddonPopupMenu ) 581 { 582 for ( sal_uInt16 nSVPos=0; nSVPos<nItemCount; ++nSVPos ) 583 { 584 sal_uInt16 nSlotId = pSVMenu->GetItemId( nSVPos ); 585 MenuItemType nType = pSVMenu->GetItemType( nSVPos ); 586 if ( nType == MENUITEM_STRING && bIcons ) 587 { 588 if ( framework::AddonMenuManager::IsAddonMenuId( nSlotId )) 589 { 590 // Special code for Add-On menu items. They can appear inside the help menu. 591 rtl::OUString aCmd( pSVMenu->GetItemCommand( nSlotId ) ); 592 rtl::OUString aImageId; 593 594 ::framework::MenuConfiguration::Attributes* pMenuAttributes = 595 (::framework::MenuConfiguration::Attributes*)pSVMenu->GetUserValue( nSlotId ); 596 597 if ( pMenuAttributes ) 598 aImageId = pMenuAttributes->aImageId; // Retrieve image id from menu attributes 599 600 pSVMenu->SetItemImage( nSlotId, RetrieveAddOnImage( xFrame, aImageId, aCmd, sal_False, bIsHiContrastMode )); 601 } 602 else 603 { 604 rtl::OUString aSlotURL( RTL_CONSTASCII_USTRINGPARAM( "slot:" )); 605 aSlotURL += rtl::OUString::valueOf( sal_Int32( nSlotId )); 606 pSVMenu->SetItemImage( nSlotId, GetImage( xFrame, aSlotURL, sal_False, bWasHighContrast )); 607 } 608 } 609 else if( nType == MENUITEM_STRINGIMAGE && !bIcons ) 610 { 611 pSVMenu->SetItemImage( nSlotId, Image() ); 612 } 613 } 614 } 615 else 616 { 617 // Remove/update images from Add-Ons top-level popup menus when settings have changed 618 if ( !bIcons ) 619 RemoveMenuImages( pSVMenu ); 620 else 621 UpdateImages( pSVMenu ); 622 } 623 624 // Special code to remove menu images from runtime popup menus when settings have changed 625 if ( pParent && pSVMenu == pParent->pAddonsMenu ) 626 { 627 if ( !bIcons ) 628 RemoveMenuImages( pParent->pAddonsMenu->GetPopupMenu( SID_ADDONS )); 629 else 630 UpdateImages( pParent->pAddonsMenu->GetPopupMenu( SID_ADDONS )); 631 } 632 633 if ( pImageControl ) 634 pImageControl->Update(); 635 636 return 0; 637 } 638 639 //-------------------------------------------------------------------- 640 641 void SfxVirtualMenu::UpdateImages() 642 { 643 sal_Bool bIcons = Application::GetSettings().GetStyleSettings().GetUseImagesInMenus(); 644 645 if ( bIcons ) 646 { 647 sal_Bool bIsHiContrastMode = IsHiContrastMode(); 648 sal_uInt16 nItemCount = pSVMenu->GetItemCount(); 649 SfxViewFrame * pViewFrame = pBindings->GetDispatcher()->GetFrame(); 650 Reference<com::sun::star::frame::XFrame> xFrame( pViewFrame->GetFrame().GetFrameInterface() ); 651 652 for ( sal_uInt16 nSVPos=0; nSVPos < nItemCount; ++nSVPos ) 653 { 654 sal_uInt16 nSlotId = pSVMenu->GetItemId( nSVPos ); 655 if ( pSVMenu->GetItemType( nSVPos ) == MENUITEM_STRINGIMAGE ) 656 { 657 if ( framework::AddonMenuManager::IsAddonMenuId( nSlotId )) 658 { 659 // Special code for Add-On menu items. They can appear inside the help menu. 660 rtl::OUString aCmd( pSVMenu->GetItemCommand( nSlotId ) ); 661 rtl::OUString aImageId; 662 663 ::framework::MenuConfiguration::Attributes* pMenuAttributes = 664 (::framework::MenuConfiguration::Attributes*)pSVMenu->GetUserValue( nSlotId ); 665 666 if ( pMenuAttributes ) 667 aImageId = pMenuAttributes->aImageId; // Retrieve image id from menu attributes 668 669 pSVMenu->SetItemImage( nSlotId, RetrieveAddOnImage( xFrame, aImageId, aCmd, sal_False, bIsHiContrastMode )); 670 } 671 else 672 { 673 rtl::OUString aSlotURL( RTL_CONSTASCII_USTRINGPARAM( "slot:" )); 674 aSlotURL += rtl::OUString::valueOf( sal_Int32( nSlotId )); 675 pSVMenu->SetItemImage( nSlotId, GetImage( xFrame, aSlotURL, sal_False, bWasHighContrast )); 676 } 677 } 678 } 679 680 if ( pImageControl ) 681 pImageControl->Update(); 682 } 683 } 684 685 //-------------------------------------------------------------------- 686 687 void SfxVirtualMenu::UpdateImages( Menu* pMenu ) 688 { 689 if ( !pMenu ) 690 return; 691 692 framework::AddonsOptions aAddonOptions; 693 694 sal_Bool bIcons = Application::GetSettings().GetStyleSettings().GetUseImagesInMenus(); 695 if ( bIcons ) 696 { 697 sal_Bool bIsHiContrastMode = IsHiContrastMode(); 698 sal_uInt16 nItemCount = pMenu->GetItemCount(); 699 Reference<com::sun::star::frame::XFrame> aXFrame( pBindings->GetDispatcher_Impl()->GetFrame()->GetFrame().GetFrameInterface() ); 700 701 for ( sal_uInt16 nPos=0; nPos < nItemCount; ++nPos ) 702 { 703 sal_uInt16 nSlotId = pMenu->GetItemId( nPos ); 704 PopupMenu* pPopup = pMenu->GetPopupMenu( nSlotId ); 705 if ( pMenu->GetItemType( nPos ) != MENUITEM_SEPARATOR ) 706 { 707 rtl::OUString aImageId; 708 709 ::framework::MenuConfiguration::Attributes* pMenuAttributes = 710 (::framework::MenuConfiguration::Attributes*)pMenu->GetUserValue( nSlotId ); 711 712 if ( pMenuAttributes ) 713 aImageId = pMenuAttributes->aImageId; // Retrieve image id from menu attributes 714 715 pMenu->SetItemImage( nSlotId, RetrieveAddOnImage( aXFrame, aImageId, pMenu->GetItemCommand( nSlotId ), sal_False, bIsHiContrastMode )); 716 } 717 718 if ( pPopup ) 719 UpdateImages( pPopup ); 720 } 721 722 if ( pImageControl ) 723 pImageControl->Update(); 724 } 725 } 726 727 //-------------------------------------------------------------------- 728 729 void SfxVirtualMenu::RemoveMenuImages( Menu* pMenu ) 730 { 731 if ( !pMenu ) 732 return; 733 734 sal_uInt16 nItemCount = pMenu->GetItemCount(); 735 for ( sal_uInt16 nPos=0; nPos < nItemCount; ++nPos ) 736 { 737 sal_uInt16 nSlotId = pMenu->GetItemId( nPos ); 738 PopupMenu* pPopup = pMenu->GetPopupMenu( nSlotId ); 739 if ( pMenu->GetItemType( nPos ) == MENUITEM_STRINGIMAGE ) 740 pMenu->SetItemImage( nSlotId, Image() ); 741 if ( pPopup ) 742 RemoveMenuImages( pPopup ); 743 } 744 } 745 746 //-------------------------------------------------------------------- 747 748 bool SfxVirtualMenu::Bind_Impl( Menu *pMenu ) 749 { 750 // Selber suchen, da SV mit 'sal_uInt16 nSID = pSVMenu->GetCurItemId();' immer 751 // 0 liefert. Das ist so, weil die Event-Weiterleitung lt. TH nichts mit 752 // CurItem des Parent-Menus zu tun hat. 753 sal_uInt32 nAddonsPopupPrefixLen = ADDONSPOPUPMENU_URL_PREFIX.getLength(); 754 755 for ( sal_uInt16 nPos = 0; nPos < nCount; ++nPos ) 756 { 757 // angesprochenes Sub-Menu gefunden? 758 bool bFound = false; 759 sal_uInt16 nSID = pSVMenu->GetItemId(nPos); 760 SfxMenuControl &rCtrl = pItems[nPos]; 761 bFound = pSVMenu->GetPopupMenu(nSID) == pMenu; 762 SfxVirtualMenu *pSubMenu = rCtrl.GetPopupMenu(); 763 764 if ( bFound ) 765 { 766 // Nur ein gebundener Menu-Controller hat schon seine Id! 767 if ( !rCtrl.GetId() ) 768 { 769 bIsAddonPopupMenu = sal_False; 770 DBG_ASSERT( !pSubMenu, "Popup schon vorhanden!"); 771 772 // Check if the popup is an Add-On popup menu 773 // Either the popup menu has a special ID or a special command URL prefix! 774 rtl::OUString aCommand = pSVMenu->GetItemCommand( nSID ); 775 if ( ( nSID == SID_ADDONS ) || 776 ( nSID == SID_ADDONHELP ) || 777 (( (sal_uInt32)aCommand.getLength() > nAddonsPopupPrefixLen ) && 778 ( aCommand.indexOf( ADDONSPOPUPMENU_URL_PREFIX ) == 0 )) ) 779 bIsAddonPopupMenu = sal_True; 780 781 // VirtualMenu f"ur Sub-Menu erzeugen 782 sal_Bool bRes = bResCtor; 783 pSubMenu = new SfxVirtualMenu( nSID, this, 784 *pMenu, sal_False, *pBindings, bOLE, bRes, bIsAddonPopupMenu ); 785 786 DBG_OUTF( ("Neues VirtualMenu %lx erzeugt", pSubMenu) ); 787 788 rCtrl.Bind( this, nSID, *pSubMenu, 789 pSVMenu->GetItemText(nSID), pSVMenu->GetHelpText(nSID), 790 *pBindings ); 791 792 // Activate weiterleiten 793 pSubMenu->Bind_Impl( pMenu ); 794 pSubMenu->Activate( pMenu ); 795 } 796 } 797 798 // rekursiv weitersuchen (SV Activate nur am Menu selbst und Top-Menu) 799 if ( !bFound && pSubMenu ) 800 bFound = pSubMenu->Bind_Impl( pMenu ); 801 802 // gefunden, dann abbrechen 803 if ( bFound ) 804 return true; 805 } 806 807 // nicht in diesem Untermenu gefunden 808 return false; 809 } 810 811 void SfxVirtualMenu::BindControllers() 812 { 813 pBindings->ENTERREGISTRATIONS(); 814 815 sal_uInt16 nPos; 816 for ( nPos = 0; nPos < nCount; ++nPos ) 817 { 818 SfxMenuControl& rCtrl = pItems[nPos]; 819 if ( rCtrl.IsBindable_Impl() && !rCtrl.GetPopupMenu() ) 820 rCtrl.ReBind(); 821 } 822 823 SfxMenuCtrlArr_Impl& rCtrlArr = GetAppCtrl_Impl(); 824 for ( nPos=0; nPos<rCtrlArr.Count(); nPos++ ) 825 { 826 SfxMenuControl* pCtrl = rCtrlArr[nPos]; 827 sal_uInt16 nSlotId = pCtrl->GetId(); 828 if ( !pSVMenu->GetItemCommand(nSlotId).Len() ) 829 pCtrl->ReBind(); 830 } 831 832 pBindings->LEAVEREGISTRATIONS(); 833 bControllersUnBound = sal_False; 834 } 835 836 void SfxVirtualMenu::UnbindControllers() 837 { 838 pBindings->ENTERREGISTRATIONS(); 839 840 sal_uInt16 nPos; 841 for ( nPos = 0; nPos < nCount; ++nPos ) 842 { 843 SfxMenuControl &rCtrl = pItems[nPos]; 844 if ( rCtrl.IsBound() ) 845 rCtrl.UnBind(); 846 } 847 848 SfxMenuCtrlArr_Impl& rCtrlArr = GetAppCtrl_Impl(); 849 for ( nPos=0; nPos<rCtrlArr.Count(); nPos++ ) 850 { 851 SfxMenuControl* pCtrl = rCtrlArr[nPos]; 852 if ( pCtrl->IsBound() ) 853 // UnoController sind nicht gebunden! 854 pCtrl->UnBind(); 855 } 856 857 pBindings->LEAVEREGISTRATIONS(); 858 bControllersUnBound = sal_True; 859 } 860 861 862 //-------------------------------------------------------------------- 863 void SfxVirtualMenu::InsertAddOnsMenuItem( Menu* pMenu ) 864 { 865 // Create special popup menu that is filled with the 3rd party components popup menu items 866 Reference<com::sun::star::lang::XMultiServiceFactory> aXMultiServiceFactory(::comphelper::getProcessServiceFactory()); 867 ::framework::MenuConfiguration aConf( aXMultiServiceFactory ); 868 Reference<com::sun::star::frame::XFrame> xFrame( pBindings->GetDispatcher_Impl()->GetFrame()->GetFrame().GetFrameInterface() ); 869 870 PopupMenu* pAddonMenu = NULL; 871 try 872 { 873 pAddonMenu = framework::AddonMenuManager::CreateAddonMenu( xFrame ); 874 } 875 catch ( ::com::sun::star::lang::WrappedTargetException ) 876 { 877 } 878 879 // Create menu item at the end of the tools popup menu for the addons popup menu 880 if ( pAddonMenu && pAddonMenu->GetItemCount() > 0 ) 881 { 882 sal_uInt16 nItemCount = pMenu->GetItemCount(); 883 String aAddonsTitle( SfxResId( STR_MENU_ADDONS )); 884 if ( nItemCount > 0 && pMenu->GetItemType( nItemCount-1 ) != MENUITEM_SEPARATOR ) 885 pMenu->InsertSeparator(); 886 pMenu->InsertItem( SID_ADDONS, aAddonsTitle ); 887 pMenu->SetPopupMenu( SID_ADDONS, pAddonMenu ); 888 889 if ( Application::GetSettings().GetStyleSettings().GetUseImagesInMenus() ) 890 { 891 rtl::OUString aSlotURL( RTL_CONSTASCII_USTRINGPARAM( "slot:" )); 892 aSlotURL += rtl::OUString::valueOf( sal_Int32( SID_ADDONS )); 893 pMenu->SetItemImage( SID_ADDONS, GetImage( xFrame, aSlotURL, sal_False, bWasHighContrast )); 894 } 895 } 896 else 897 delete pAddonMenu; 898 } 899 900 //-------------------------------------------------------------------- 901 902 // called on activation of the SV-Menu 903 904 IMPL_LINK( SfxVirtualMenu, Activate, Menu *, pMenu ) 905 { 906 DBG_MEMTEST(); 907 DBG_CHKTHIS(SfxVirtualMenu, 0); 908 DBG_OUTF( ("SfxVirtualMenu %lx activated %lx, own %lx", this, pMenu, pSVMenu)); 909 910 // MI: wozu war der noch gut? 911 // MBA: scheint ein alter QAP-Hack gewesen zu sein ( in rev.1.41 eingecheckt ! ) 912 // if ( Application::IsInModalMode() ) 913 // return TRUE; // abw"urgen 914 915 if ( pMenu ) 916 { 917 sal_Bool bDontHide = SvtMenuOptions().IsEntryHidingEnabled(); 918 sal_uInt16 nFlag = pMenu->GetMenuFlags(); 919 if ( bDontHide ) 920 nFlag &= ~MENU_FLAG_HIDEDISABLEDENTRIES; 921 else 922 nFlag |= MENU_FLAG_HIDEDISABLEDENTRIES; 923 pMenu->SetMenuFlags( nFlag ); 924 } 925 926 // eigenes StarView-Menu 927 if ( pMenu == pSVMenu ) 928 { 929 // doppelt-Activate verhindern 930 if ( bIsActive ) 931 return sal_True; 932 933 // ggf. Pick-Menu erzeugen 934 if ( pParent && pSVMenu == pParent->pPickMenu ) 935 { 936 SfxPickList::Get()->CreateMenuEntries( pParent->pPickMenu ); 937 } 938 else 939 pPickMenu = pSVMenu->GetPopupMenu(SID_PICKLIST); 940 941 if ( pParent && pSVMenu == pParent->pWindowMenu ) 942 { 943 // update window list 944 ::std::vector< ::rtl::OUString > aNewWindowListVector; 945 Reference< XDesktop > xDesktop( ::comphelper::getProcessServiceFactory()->createInstance( 946 DEFINE_CONST_OUSTRING( "com.sun.star.frame.Desktop" ) ), UNO_QUERY ); 947 948 sal_uInt16 nActiveItemId = 0; 949 sal_uInt16 nItemId = START_ITEMID_WINDOWLIST; 950 951 if ( xDesktop.is() ) 952 { 953 Reference< XFramesSupplier > xTasksSupplier( xDesktop, UNO_QUERY ); 954 Reference< XFrame > xCurrentFrame = xDesktop->getCurrentFrame(); 955 Reference< XIndexAccess > xList ( xTasksSupplier->getFrames(), UNO_QUERY ); 956 sal_Int32 nFrameCount = xList->getCount(); 957 for( sal_Int32 i=0; i<nFrameCount; ++i ) 958 { 959 Reference< XFrame > xFrame; 960 Any aVal = xList->getByIndex(i); 961 if (!(aVal>>=xFrame) || !xFrame.is() ) 962 continue; 963 964 if ( xFrame == xCurrentFrame ) 965 nActiveItemId = nItemId; 966 967 Window* pWin = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() ); 968 if ( pWin && pWin->IsVisible() ) 969 { 970 aNewWindowListVector.push_back( pWin->GetText() ); 971 ++nItemId; 972 } 973 } 974 } 975 976 int nItemCount = pMenu->GetItemCount(); 977 978 if ( nItemCount > 0 ) 979 { 980 // remove all old window list entries from menu 981 sal_uInt16 nPos = pMenu->GetItemPos( START_ITEMID_WINDOWLIST ); 982 for ( sal_uInt16 n = nPos; n < pMenu->GetItemCount(); ) 983 pMenu->RemoveItem( n ); 984 985 if ( pMenu->GetItemType( pMenu->GetItemCount()-1 ) == MENUITEM_SEPARATOR ) 986 pMenu->RemoveItem( pMenu->GetItemCount()-1 ); 987 } 988 989 if ( aNewWindowListVector.size() > 0 ) 990 { 991 // append new window list entries to menu 992 pMenu->InsertSeparator(); 993 nItemId = START_ITEMID_WINDOWLIST; 994 for ( sal_uInt32 i = 0; i < aNewWindowListVector.size(); i++ ) 995 { 996 pMenu->InsertItem( nItemId, aNewWindowListVector.at( i ), MIB_RADIOCHECK ); 997 if ( nItemId == nActiveItemId ) 998 pMenu->CheckItem( nItemId ); 999 ++nItemId; 1000 } 1001 } 1002 } 1003 else 1004 pWindowMenu = pSVMenu->GetPopupMenu(SID_MDIWINDOWLIST); 1005 1006 if ( !pParent && pSVMenu->IsMenuBar() && !pAddonsMenu ) 1007 { 1008 // Store Add-Ons parents of our runtime menu items 1009 pAddonsMenu = pSVMenu->GetPopupMenu( SID_ADDONLIST ); 1010 } 1011 1012 // f"ur konstistenten Status sorgen 1013 if ( bControllersUnBound ) 1014 BindControllers(); 1015 1016 //InvalidateKeyCodes(); 1017 pBindings->GetDispatcher_Impl()->Flush(); 1018 for ( sal_uInt16 nPos = 0; nPos < nCount; ++nPos ) 1019 { 1020 sal_uInt16 nSlotId = (pItems+nPos)->GetId(); 1021 if ( nSlotId && nSlotId > END_ITEMID_WINDOWLIST ) 1022 pBindings->Update(nSlotId); 1023 } 1024 1025 pBindings->Update( SID_IMAGE_ORIENTATION ); 1026 1027 // HelpText on-demand 1028 if ( !bHelpInitialized ) 1029 { 1030 // TODO/CLEANUP: do we need help texts in context menus? 1031 // old way with SlotInfo doesn't work anymore 1032 } 1033 1034 // bis zum Deactivate die Statusupdates unterdr"ucken 1035 pBindings->ENTERREGISTRATIONS(); ++nLocks; bIsActive = sal_True; 1036 1037 if ( pAutoDeactivate ) // QAP-Hack 1038 pAutoDeactivate->Start(); 1039 1040 if ( IsHiContrastMode() != bWasHighContrast ) 1041 { 1042 // Refresh images as our background color changed and remember it!! 1043 bWasHighContrast = IsHiContrastMode(); 1044 if ( bIsAddonPopupMenu ) 1045 UpdateImages( pSVMenu ); 1046 else 1047 UpdateImages(); 1048 } 1049 1050 // erledigt 1051 return sal_True; 1052 } 1053 else 1054 { 1055 // VirtualMenu fuer SubMenu finden und ggf. an VirtualMenu binden 1056 bool bRet = Bind_Impl( pMenu ); 1057 #ifdef DBG_UTIL 1058 if ( !bRet) 1059 DBG_WARNING( "W1: Virtual menu konnte nicht erzeugt werden!" ); 1060 #endif 1061 return bRet; 1062 } 1063 } 1064 1065 //-------------------------------------------------------------------- 1066 1067 IMPL_LINK( SfxVirtualMenu, Deactivate, Menu *, pMenu ) 1068 { 1069 DBG_MEMTEST(); 1070 DBG_OUTF( ("SfxVirtualMenu %lx deactivated %lx, own %lx", this, pMenu, pSVMenu) ); 1071 if ( bIsActive && ( 0 == pMenu || pMenu == pSVMenu ) ) 1072 { 1073 if ( pAutoDeactivate ) 1074 pAutoDeactivate->Stop(); 1075 1076 // Bis auf die Menubar k"onnen alle Controller unbinded werden, wenn 1077 // das Menue deaktiviert ( = zugeklappt ) wird 1078 if ( pParent ) 1079 UnbindControllers(); 1080 pBindings->LEAVEREGISTRATIONS(); --nLocks; bIsActive = sal_False; 1081 } 1082 return sal_True; 1083 } 1084 //-------------------------------------------------------------------- 1085 1086 // called on activation of the SV-Menu 1087 1088 IMPL_LINK( SfxVirtualMenu, Select, Menu *, pMenu ) 1089 { 1090 sal_uInt16 nSlotId = (sal_uInt16) pMenu->GetCurItemId(); 1091 DBG_OUTF( ("SfxVirtualMenu %lx selected %u from %lx", this, nSlotId, pMenu) ); 1092 /* 1093 if ( pSVMenu->GetItemCommand( nSlotId ).Len() ) 1094 { 1095 SfxMenuCtrlArr_Impl& rCtrlArr = GetAppCtrl_Impl(); 1096 for ( sal_uInt16 nPos=0; nPos<rCtrlArr.Count(); nPos++ ) 1097 { 1098 SfxMenuControl* pCtrl = rCtrlArr[nPos]; 1099 if ( pCtrl->GetId() == nSlotId ) 1100 { 1101 SfxUnoMenuControl *pUnoCtrl = (SfxUnoMenuControl*) pCtrl; 1102 pUnoCtrl->Select(); 1103 return sal_True; 1104 } 1105 } 1106 } 1107 */ 1108 if ( nSlotId >= START_ITEMID_WINDOWLIST && nSlotId <= END_ITEMID_WINDOWLIST ) 1109 { 1110 // window list menu item selected 1111 Reference< XFramesSupplier > xDesktop( ::comphelper::getProcessServiceFactory()->createInstance( 1112 DEFINE_CONST_OUSTRING( "com.sun.star.frame.Desktop" ) ), UNO_QUERY ); 1113 if ( xDesktop.is() ) 1114 { 1115 sal_uInt16 nTaskId = START_ITEMID_WINDOWLIST; 1116 Reference< XIndexAccess > xList( xDesktop->getFrames(), UNO_QUERY ); 1117 sal_Int32 nFrameCount = xList->getCount(); 1118 for ( sal_Int32 i=0; i<nFrameCount; ++i ) 1119 { 1120 Any aItem = xList->getByIndex(i); 1121 Reference< XFrame > xFrame; 1122 if (( aItem >>= xFrame ) && xFrame.is() && nTaskId == nSlotId ) 1123 { 1124 Window* pWin = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() ); 1125 pWin->GrabFocus(); 1126 pWin->ToTop( TOTOP_RESTOREWHENMIN ); 1127 break; 1128 } 1129 1130 nTaskId++; 1131 } 1132 } 1133 1134 return sal_True; 1135 } 1136 else if ( nSlotId >= START_ITEMID_PICKLIST && nSlotId <= END_ITEMID_PICKLIST ) 1137 { 1138 SfxPickList::Get()->ExecuteMenuEntry( nSlotId ); 1139 return sal_True; 1140 } 1141 1142 if ( pMenu->GetItemCommand( nSlotId ).Len() ) 1143 pBindings->ExecuteCommand_Impl( pMenu->GetItemCommand( nSlotId ) ); 1144 else 1145 pBindings->Execute( nSlotId ); 1146 1147 return sal_True; 1148 } 1149 1150 //-------------------------------------------------------------------- 1151 1152 // returns the associated StarView-menu 1153 1154 Menu* SfxVirtualMenu::GetSVMenu() const 1155 { 1156 DBG_MEMTEST(); 1157 DBG_CHKTHIS(SfxVirtualMenu, 0); 1158 1159 return pSVMenu; 1160 } 1161 1162 //-------------------------------------------------------------------- 1163 1164 // return the position of the specified item 1165 1166 sal_uInt16 SfxVirtualMenu::GetItemPos( sal_uInt16 nItemId ) const 1167 { 1168 DBG_MEMTEST(); 1169 DBG_CHKTHIS(SfxVirtualMenu, 0); 1170 1171 for ( sal_uInt16 nPos = 0; nPos < nCount; ++nPos ) 1172 if ( (pItems+nPos)->GetId() == nItemId ) 1173 return nPos; 1174 return MENU_ITEM_NOTFOUND; 1175 } 1176 1177 //-------------------------------------------------------------------- 1178 1179 // returns the popup-menu assigned to the item or 0 if none 1180 1181 SfxVirtualMenu* SfxVirtualMenu::GetPopupMenu( sal_uInt16 nItemId ) const 1182 { 1183 DBG_MEMTEST(); 1184 DBG_CHKTHIS(SfxVirtualMenu, 0); 1185 1186 sal_uInt16 nPos = GetItemPos(nItemId); 1187 if ( nPos != MENU_ITEM_NOTFOUND ) 1188 return (pItems+nPos)->GetPopupMenu(); 1189 return 0; 1190 } 1191 //-------------------------------------------------------------------- 1192 1193 // returns the text of the item as currently shown in the menu 1194 1195 String SfxVirtualMenu::GetItemText( sal_uInt16 nSlotId ) const 1196 { 1197 DBG_MEMTEST(); 1198 DBG_CHKTHIS(SfxVirtualMenu, 0); 1199 1200 sal_uInt16 nPos = GetItemPos(nSlotId); 1201 if ( nPos != MENU_ITEM_NOTFOUND ) 1202 return (pItems+nPos)->GetTitle(); 1203 return String(); 1204 } 1205 //-------------------------------------------------------------------- 1206 1207 // returns the text of the item as currently shown in the menu 1208 1209 String SfxVirtualMenu::GetItemHelpText( sal_uInt16 nSlotId ) const 1210 { 1211 DBG_MEMTEST(); 1212 DBG_CHKTHIS(SfxVirtualMenu, 0); 1213 1214 sal_uInt16 nPos = GetItemPos(nSlotId); 1215 if ( nPos != MENU_ITEM_NOTFOUND ) 1216 return (pItems+nPos)->GetHelpText(); 1217 return String(); 1218 } 1219 1220 //-------------------------------------------------------------------- 1221 1222 // set the checkmark of the specified item 1223 1224 void SfxVirtualMenu::CheckItem( sal_uInt16 nItemId, sal_Bool bCheck ) 1225 { 1226 DBG_MEMTEST(); 1227 DBG_CHKTHIS(SfxVirtualMenu, 0); 1228 DBG_ASSERT( this != 0, ""); 1229 DBG_ASSERT( pSVMenu != 0, "" ); 1230 if (pSVMenu->GetItemPos( nItemId ) != MENU_ITEM_NOTFOUND ) 1231 pSVMenu->CheckItem( nItemId, bCheck ); 1232 } 1233 //-------------------------------------------------------------------- 1234 1235 // set the enabled-state of the specified item 1236 1237 void SfxVirtualMenu::EnableItem( sal_uInt16 nItemId, sal_Bool bEnable ) 1238 { 1239 DBG_MEMTEST(); 1240 DBG_CHKTHIS(SfxVirtualMenu, 0); 1241 DBG_ASSERT( this != 0, ""); 1242 DBG_ASSERT( pSVMenu != 0, "" ); 1243 1244 if (pSVMenu->GetItemPos( nItemId ) != MENU_ITEM_NOTFOUND ) 1245 pSVMenu->EnableItem( nItemId, bEnable ); 1246 } 1247 //-------------------------------------------------------------------- 1248 1249 // set the text of the specified item 1250 1251 void SfxVirtualMenu::SetItemText( sal_uInt16 nItemId, const String& rText ) 1252 { 1253 DBG_MEMTEST(); 1254 DBG_CHKTHIS(SfxVirtualMenu, 0); 1255 DBG_ASSERT( this != 0, ""); 1256 DBG_ASSERT( pSVMenu != 0, "" ); 1257 if (pSVMenu->GetItemPos( nItemId ) != MENU_ITEM_NOTFOUND ) 1258 pSVMenu->SetItemText( nItemId, rText ); 1259 } 1260 1261 //-------------------------------------------------------------------- 1262 1263 // 1264 1265 void SfxVirtualMenu::SetPopupMenu( sal_uInt16 nItemId, PopupMenu *pMenu ) 1266 { 1267 DBG_MEMTEST(); 1268 DBG_CHKTHIS(SfxVirtualMenu, 0); 1269 1270 if (pSVMenu->GetItemPos( nItemId ) != MENU_ITEM_NOTFOUND ) 1271 GetSVMenu()->SetPopupMenu( nItemId, pMenu ); 1272 for ( sal_uInt16 n = 0; n < nCount; ++n ) 1273 { 1274 SfxVirtualMenu *pSubMenu = (pItems+n)->GetPopupMenu(); 1275 if ( pSubMenu ) 1276 pSubMenu->SetPopupMenu( nItemId, pMenu ); 1277 } 1278 } 1279 1280 //-------------------------------------------------------------------- 1281 1282 // Erzwingt die Initialisierung, die sonst nur im Activate kommt 1283 1284 void SfxVirtualMenu::InitPopup( sal_uInt16 nPos, sal_Bool /*bOLE*/ ) 1285 { 1286 DBG_MEMTEST(); 1287 DBG_CHKTHIS(SfxVirtualMenu, 0); 1288 1289 sal_uInt16 nSID = pSVMenu->GetItemId(nPos); 1290 PopupMenu *pMenu = pSVMenu->GetPopupMenu( nSID ); 1291 1292 DBG_ASSERT( pMenu, "Hier gibt es kein Popup!"); 1293 1294 SfxMenuControl &rCtrl = pItems[nPos]; 1295 if ( !rCtrl.GetId() ) 1296 { 1297 // VirtualMenu f"ur Sub-Menu erzeugen 1298 sal_Bool bRes = bResCtor; 1299 SfxVirtualMenu *pSubMenu = 1300 new SfxVirtualMenu(nSID, this, *pMenu, sal_False, *pBindings, bOLE, bRes); 1301 1302 DBG_OUTF( ("Neues VirtualMenu %lx erzeugt", pSubMenu) ); 1303 1304 rCtrl.Bind( this, nSID, *pSubMenu, 1305 pSVMenu->GetItemText(nSID), pSVMenu->GetHelpText(nSID), 1306 *pBindings ); 1307 } 1308 } 1309 1310 void SfxVirtualMenu::InitializeHelp() 1311 { 1312 for ( sal_uInt16 nPos = 0; nPos<pSVMenu->GetItemCount(); ++nPos ) 1313 { 1314 sal_uInt16 nSlotId = pSVMenu->GetItemId(nPos); 1315 // TODO/CLEANUP: this code does nothing! 1316 // if ( !bHelpInitialized ) 1317 // pSVMenu->SetHelpText( nId, rSlotPool.GetSlotHelpText_Impl( nId ) ); 1318 SfxMenuControl &rCtrl = pItems[nPos]; 1319 if ( nSlotId && !rCtrl.GetId() ) 1320 { 1321 InitPopup( nPos, sal_True ); 1322 } 1323 1324 SfxVirtualMenu *pSubMenu = rCtrl.GetPopupMenu(); 1325 if ( pSubMenu ) 1326 pSubMenu->InitializeHelp(); 1327 } 1328 1329 bHelpInitialized = sal_True; 1330 } 1331 1332 typedef sal_uIntPtr (__LOADONCALLAPI *HelpIdFunc) ( const String& ); 1333 1334 void SfxVirtualMenu::SetHelpIds( ResMgr *pRes ) 1335 { 1336 pResMgr = pRes; 1337 } 1338 1339