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 #ifdef SOLARIS 28 // HACK: prevent conflict between STLPORT and Workshop headers on Solaris 8 29 #include <ctime> 30 #endif 31 32 #include <string> // HACK: prevent conflict between STLPORT and Workshop includes 33 #include <com/sun/star/uno/Reference.h> 34 #include <com/sun/star/frame/XDispatch.hpp> 35 #include <com/sun/star/frame/XDispatchProvider.hpp> 36 #include <com/sun/star/frame/XFrame.hpp> 37 #include <com/sun/star/util/URL.hpp> 38 #include <com/sun/star/beans/PropertyValue.hpp> 39 #ifndef _UNOTOOLS_PROCESSFACTORY_HXX 40 #include <comphelper/processfactory.hxx> 41 #endif 42 #include <com/sun/star/util/XURLTransformer.hpp> 43 #ifndef _UNOTOOLS_PROCESSFACTORY_HXX 44 #include <comphelper/processfactory.hxx> 45 #endif 46 #include <tools/urlobj.hxx> 47 #include <svl/eitem.hxx> 48 #include <svl/stritem.hxx> 49 #include <svtools/imagemgr.hxx> 50 #include <svtools/menuoptions.hxx> 51 #include <framework/menuconfiguration.hxx> 52 #ifndef GCC 53 #endif 54 55 #include <sfx2/app.hxx> 56 #include <sfx2/sfx.hrc> 57 #include <sfx2/msgpool.hxx> 58 #include <sfx2/msg.hxx> 59 #include <sfx2/bindings.hxx> 60 #include <sfx2/dispatch.hxx> 61 #include "idpool.hxx" 62 #include "sfxtypes.hxx" 63 #include "virtmenu.hxx" 64 #include <sfx2/mnuitem.hxx> 65 #include <sfx2/tbxctrl.hxx> 66 #include "arrdecl.hxx" 67 #include <sfx2/module.hxx> 68 #include <sfx2/unoctitm.hxx> 69 #include <sfx2/viewfrm.hxx> 70 #include "sfx2/imgmgr.hxx" 71 #include "sfx2/imagemgr.hxx" 72 #include "sfx2/sfxresid.hxx" 73 #include "../doc/doc.hrc" 74 75 using namespace ::com::sun::star::uno; 76 using namespace ::com::sun::star::frame; 77 using namespace ::com::sun::star::beans; 78 using namespace ::com::sun::star::util; 79 80 //==================================================================== 81 82 class SfxEnumMenu: public PopupMenu 83 { 84 sal_uInt16 nSlot; 85 SfxEnumItem *pItem; 86 SfxBindings* pBindings; 87 88 protected: 89 virtual void Select(); 90 91 public: 92 SfxEnumMenu( sal_uInt16 nSlot, SfxBindings* pBind, const SfxEnumItem &rItem ); 93 ~SfxEnumMenu(); 94 }; 95 96 //========================================================================= 97 98 SfxEnumMenu::SfxEnumMenu( sal_uInt16 nSlotId, SfxBindings* pBind, const SfxEnumItem &rItem ): 99 nSlot( nSlotId ), 100 pItem( (SfxEnumItem*) rItem.Clone() ), 101 pBindings( pBind ) 102 { 103 for ( sal_uInt16 nVal = 0; nVal < pItem->GetValueCount(); ++nVal ) 104 InsertItem( nVal+1, pItem->GetValueTextByPos(nVal) ); 105 CheckItem( pItem->GetValue() + 1, sal_True ); 106 } 107 108 //------------------------------------------------------------------------- 109 110 SfxEnumMenu::~SfxEnumMenu() 111 { 112 delete pItem; 113 } 114 115 //------------------------------------------------------------------------- 116 117 void SfxEnumMenu::Select() 118 { 119 pItem->SetValue( GetCurItemId()-1 ); 120 pBindings->GetDispatcher()->Execute( nSlot, 121 SFX_CALLMODE_ASYNCHRON|SFX_CALLMODE_RECORD, 122 pItem, 0L, 0L ); 123 } 124 125 //-------------------------------------------------------------------- 126 127 void SfxMenuControl::SetOwnMenu( SfxVirtualMenu* pMenu ) 128 { 129 pOwnMenu = pMenu; 130 if ( pSubMenu ) 131 pSubMenu->SetParentMenu( pMenu ); 132 } 133 134 135 //-------------------------------------------------------------------- 136 137 // binds the instance to the specified id and assignes the title 138 139 void SfxMenuControl::Bind( 140 SfxVirtualMenu* pOwn, 141 sal_uInt16 nSlotId, 142 const String& rTitle, 143 const String &rHelpText, 144 SfxBindings &rBindings ) 145 { 146 DBG_MEMTEST(); 147 148 aTitle = rTitle; 149 aHelpText = rHelpText; 150 pOwnMenu = pOwn; 151 pSubMenu = 0; 152 if ( pOwn ) 153 SfxControllerItem::Bind(nSlotId, &rBindings); 154 else 155 SetId( nSlotId ); 156 157 DBG( CheckConfigure_Impl(SFX_SLOT_MENUCONFIG) ); 158 } 159 160 161 //-------------------------------------------------------------------- 162 163 // binds the item to the specified menu and assignes the title 164 165 void SfxMenuControl::Bind( 166 SfxVirtualMenu* pOwn, 167 sal_uInt16 nSlotId, 168 SfxVirtualMenu& rMenu, 169 const String& rTitle, 170 const String &rHelpText, 171 SfxBindings &rBindings ) 172 { 173 DBG_MEMTEST(); 174 SetId( nSlotId ); 175 SetBindings(rBindings); 176 pOwnMenu = pOwn; 177 pSubMenu = &rMenu; 178 aTitle = rTitle; 179 aHelpText = rHelpText; 180 } 181 182 //-------------------------------------------------------------------- 183 184 // ctor for explicit registration 185 186 SfxMenuControl::SfxMenuControl( sal_Bool bShowStrings ) 187 : pOwnMenu(0), 188 pSubMenu(0), 189 b_ShowStrings(bShowStrings) 190 { 191 DBG_MEMTEST(); 192 } 193 194 //-------------------------------------------------------------------- 195 196 // ctor for array 197 198 SfxMenuControl::SfxMenuControl(): 199 pOwnMenu(0), 200 pSubMenu(0), 201 b_ShowStrings(sal_False) 202 { 203 DBG_MEMTEST(); 204 } 205 206 //-------------------------------------------------------------------- 207 208 SfxMenuControl::SfxMenuControl(sal_uInt16 nSlotId, SfxBindings& rBindings): 209 SfxControllerItem(nSlotId, rBindings), 210 pOwnMenu(0), 211 pSubMenu(0), 212 b_ShowStrings(sal_False) 213 { 214 DBG_MEMTEST(); 215 216 // Dieser Ctor soll es erm"oglichen, w"ahrend der Konstruktion schon 217 // auf die Bindings zur"uckgreifen zu k"onnen, aber gebunden wird 218 // wie immer erst sp"ater. Anwendung z.B. wenn im ctor der abgeleiteten 219 // Klasse z.B. ein StatusForwarder erzeugt werden soll. 220 UnBind(); 221 } 222 223 224 //-------------------------------------------------------------------- 225 226 // dtor 227 228 SfxMenuControl::~SfxMenuControl() 229 { 230 delete pSubMenu; 231 } 232 233 void SfxMenuControl::RemovePopup() 234 { 235 DELETEZ( pSubMenu ); 236 } 237 238 //-------------------------------------------------------------------- 239 240 // changes the state in the virtual menu 241 242 void SfxMenuControl::StateChanged 243 ( 244 sal_uInt16 nSID, 245 SfxItemState eState, 246 const SfxPoolItem* pState 247 ) 248 { 249 (void)nSID; //unused 250 DBG_MEMTEST(); 251 DBG_ASSERT( nSID == GetId(), "strange SID" ); 252 DBG_ASSERT( pOwnMenu != 0, "setting state to dangling SfxMenuControl" ); 253 254 bool bIsObjMenu = 255 GetId() >= SID_OBJECTMENU0 && GetId() < SID_OBJECTMENU_LAST; 256 257 // enabled/disabled-Flag pauschal korrigieren 258 259 #ifdef UNIX 260 if (nSID == SID_PASTE) 261 pOwnMenu->EnableItem( GetId(), sal_True ); 262 else 263 #endif 264 pOwnMenu->EnableItem( GetId(), bIsObjMenu 265 ? 0 != pOwnMenu->GetSVMenu()->GetPopupMenu( GetId() ) 266 : eState != SFX_ITEM_DISABLED ); 267 268 if ( eState != SFX_ITEM_AVAILABLE ) 269 { 270 // checken nur bei nicht-Object-Menus 271 if ( !bIsObjMenu ) 272 pOwnMenu->CheckItem( GetId(), sal_False ); 273 274 // SetItemText flackert in MenuBar insbes. unter OS/2 (Bug #20658) 275 if ( // !bIsObjMenu && nicht wegen "Format/Datenbank" 276 pOwnMenu->GetSVMenu()->GetItemText( GetId() ) != GetTitle() ) 277 { 278 DBG_WARNING("Title of menu item changed - please check if this needs correction!"); 279 // pOwnMenu->SetItemText( GetId(), GetTitle() ); 280 } 281 return; 282 } 283 284 // ggf. das alte Enum-Menu entfernen/loeschen 285 //! delete pOwnMenu->GetMenu().ChangePopupMenu( GetId(), 0 ); 286 287 bool bCheck = false; 288 if ( pState->ISA(SfxBoolItem) ) 289 { 290 // BoolItem fuer checken 291 DBG_ASSERT( GetId() < SID_OBJECTMENU0 || GetId() > SID_OBJECTMENU_LAST, 292 "SfxBoolItem not allowed for SID_OBJECTMENUx" ); 293 bCheck = ((const SfxBoolItem*)pState)->GetValue(); 294 Menu* pMenu = pOwnMenu->GetSVMenu(); 295 pMenu->SetItemBits( GetId() , pMenu->GetItemBits( GetId() ) | MIB_CHECKABLE); 296 } 297 else if ( pState->ISA(SfxEnumItemInterface) && 298 ((SfxEnumItemInterface *)pState)->HasBoolValue() ) 299 { 300 // EnumItem wie Bool behandeln 301 DBG_ASSERT( GetId() < SID_OBJECTMENU0 || GetId() > SID_OBJECTMENU_LAST, 302 "SfxEnumItem not allowed for SID_OBJECTMENUx" ); 303 bCheck = ((SfxEnumItemInterface *)pState)->GetBoolValue(); 304 Menu* pMenu = pOwnMenu->GetSVMenu(); 305 pMenu->SetItemBits( GetId() , pMenu->GetItemBits( GetId() ) | MIB_CHECKABLE); 306 } 307 else if ( ( b_ShowStrings || bIsObjMenu ) && pState->ISA(SfxStringItem) ) 308 { 309 // MenuText aus SfxStringItem holen 310 String aStr( ((const SfxStringItem*)pState)->GetValue() ); 311 if ( aStr.CompareToAscii("($1)",4) == COMPARE_EQUAL ) 312 { 313 String aEntry(SfxResId(STR_UPDATEDOC)); 314 aEntry += ' '; 315 aEntry += aStr.Copy(4); 316 aStr = aEntry; 317 } 318 else if ( aStr.CompareToAscii("($2)",4) == COMPARE_EQUAL ) 319 { 320 String aEntry(SfxResId(STR_CLOSEDOC_ANDRETURN)); 321 aEntry += aStr.Copy(4); 322 aStr = aEntry; 323 } 324 325 pOwnMenu->SetItemText( GetId(), aStr ); 326 } 327 328 #ifdef enum_item_menu_ok 329 else if ( aType == TYPE(SfxEnumItem) ) 330 { 331 DBG_ASSERT( GetId() < SID_OBJECTMENU0 || GetId() > SID_OBJECTMENU_LAST, 332 "SfxEnumItem not allowed for SID_OBJECTMENUx" ); 333 pOwnMenu->GetMenu().ChangePopupMenu( GetId(), &GetBindings(), 334 new SfxEnumMenu( GetId(), *(const SfxEnumItem*)pState ) ); 335 } 336 #endif 337 338 pOwnMenu->CheckItem( GetId(), bCheck ); 339 } 340 341 //-------------------------------------------------------------------- 342 343 SfxMenuControl* SfxMenuControl::CreateImpl( sal_uInt16 /*nId*/, Menu& /*rMenu*/, SfxBindings& /*rBindings*/ ) 344 { 345 return new SfxMenuControl( sal_True ); 346 } 347 348 //-------------------------------------------------------------------- 349 350 void SfxMenuControl::RegisterControl( sal_uInt16 nSlotId, SfxModule *pMod ) 351 { 352 RegisterMenuControl( pMod, new SfxMenuCtrlFactory( 353 SfxMenuControl::CreateImpl, TYPE(SfxStringItem), nSlotId ) ); 354 } 355 356 //-------------------------------------------------------------------- 357 void SfxMenuControl::RegisterMenuControl(SfxModule* pMod, SfxMenuCtrlFactory* pFact) 358 { 359 SFX_APP()->RegisterMenuControl_Impl( pMod, pFact ); 360 } 361 362 SfxMenuControl* SfxMenuControl::CreateControl( sal_uInt16 nId, Menu &rMenu, SfxBindings &rBindings ) 363 { 364 TypeId aSlotType = SFX_SLOTPOOL().GetSlotType(nId); 365 if ( aSlotType ) 366 { 367 SfxApplication *pApp = SFX_APP(); 368 SfxDispatcher *pDisp = rBindings.GetDispatcher_Impl(); 369 SfxModule *pMod = pDisp ? SfxModule::GetActiveModule( pDisp->GetFrame() ) :0; 370 if ( pMod ) 371 { 372 SfxMenuCtrlFactArr_Impl *pFactories = pMod->GetMenuCtrlFactories_Impl(); 373 if ( pFactories ) 374 { 375 SfxMenuCtrlFactArr_Impl &rFactories = *pFactories; 376 for ( sal_uInt16 nFactory = 0; nFactory < rFactories.Count(); ++nFactory ) 377 if ( rFactories[nFactory]->nTypeId == aSlotType && 378 ( ( rFactories[nFactory]->nSlotId == 0 ) || 379 ( rFactories[nFactory]->nSlotId == nId) ) ) 380 return rFactories[nFactory]->pCtor( nId, rMenu, rBindings ); 381 } 382 } 383 384 SfxMenuCtrlFactArr_Impl &rFactories = pApp->GetMenuCtrlFactories_Impl(); 385 386 for ( sal_uInt16 nFactory = 0; nFactory < rFactories.Count(); ++nFactory ) 387 if ( rFactories[nFactory]->nTypeId == aSlotType && 388 ( ( rFactories[nFactory]->nSlotId == 0 ) || 389 ( rFactories[nFactory]->nSlotId == nId) ) ) 390 return rFactories[nFactory]->pCtor( nId, rMenu, rBindings ); 391 } 392 return 0; 393 } 394 395 sal_Bool SfxMenuControl::IsSpecialControl( sal_uInt16 nId, SfxModule* pMod ) 396 { 397 TypeId aSlotType = SFX_SLOTPOOL().GetSlotType( nId ); 398 if ( aSlotType ) 399 { 400 if ( pMod ) 401 { 402 SfxMenuCtrlFactArr_Impl *pFactories = pMod->GetMenuCtrlFactories_Impl(); 403 if ( pFactories ) 404 { 405 SfxMenuCtrlFactArr_Impl &rFactories = *pFactories; 406 for ( sal_uInt16 nFactory = 0; nFactory < rFactories.Count(); ++nFactory ) 407 if ( rFactories[nFactory]->nTypeId == aSlotType && 408 ( ( rFactories[nFactory]->nSlotId == 0 ) || 409 ( rFactories[nFactory]->nSlotId == nId) ) ) 410 return sal_True; 411 } 412 } 413 414 SfxMenuCtrlFactArr_Impl &rFactories = SFX_APP()->GetMenuCtrlFactories_Impl(); 415 416 for ( sal_uInt16 nFactory = 0; nFactory < rFactories.Count(); ++nFactory ) 417 if ( rFactories[nFactory]->nTypeId == aSlotType && 418 ( ( rFactories[nFactory]->nSlotId == 0 ) || 419 ( rFactories[nFactory]->nSlotId == nId) ) ) 420 return sal_True; 421 } 422 return 0; 423 } 424 425 //-------------------------------------------------------------------- 426 427 PopupMenu* SfxMenuControl::GetPopup () const 428 { 429 if (GetPopupMenu()) 430 return (PopupMenu*)GetPopupMenu()->GetSVMenu(); 431 else 432 return 0; 433 } 434 435 long Select_Impl( void* pHdl, void* pVoid ); 436 437 SFX_IMPL_MENU_CONTROL( SfxAppMenuControl_Impl, SfxStringItem ); 438 439 SfxAppMenuControl_Impl::SfxAppMenuControl_Impl( 440 sal_uInt16 nPos, Menu& rMenu, SfxBindings& rBindings ) 441 : SfxMenuControl( nPos, rBindings ), pMenu(0) 442 { 443 String aText = rMenu.GetItemText( nPos ); 444 445 // Determine the current background color setting for menus 446 const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings(); 447 m_nSymbolsStyle = rSettings.GetSymbolsStyle(); 448 m_bWasHiContrastMode = rSettings.GetHighContrastMode(); 449 m_bShowMenuImages = rSettings.GetUseImagesInMenus(); 450 451 Reference<com::sun::star::lang::XMultiServiceFactory> aXMultiServiceFactory(::comphelper::getProcessServiceFactory()); 452 ::framework::MenuConfiguration aConf( aXMultiServiceFactory ); 453 Reference<com::sun::star::frame::XFrame> aXFrame( GetBindings().GetDispatcher_Impl()->GetFrame()->GetFrame().GetFrameInterface() ); 454 pMenu = aConf.CreateBookmarkMenu( aXFrame, GetId() == SID_NEWDOCDIRECT ? BOOKMARK_NEWMENU : BOOKMARK_WIZARDMENU ); 455 if( pMenu ) 456 { 457 pMenu->SetSelectHdl( Link( &(this->GetBindings()), Select_Impl ) ); 458 pMenu->SetActivateHdl( LINK(this, SfxAppMenuControl_Impl, Activate) ); 459 rMenu.SetPopupMenu( nPos, pMenu ); 460 } 461 } 462 463 SfxAppMenuControl_Impl::~SfxAppMenuControl_Impl() 464 { 465 delete pMenu; 466 } 467 468 IMPL_LINK( SfxAppMenuControl_Impl, Activate, Menu *, pActMenu ) 469 { 470 if ( pActMenu ) 471 { 472 const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings(); 473 sal_uIntPtr nSymbolsStyle = rSettings.GetSymbolsStyle(); 474 sal_Bool bIsHiContrastMode = rSettings.GetHighContrastMode(); 475 sal_Bool bShowMenuImages = rSettings.GetUseImagesInMenus(); 476 477 if (( nSymbolsStyle != m_nSymbolsStyle ) || 478 ( bIsHiContrastMode != m_bWasHiContrastMode ) || 479 ( bShowMenuImages != m_bShowMenuImages )) 480 { 481 m_nSymbolsStyle = nSymbolsStyle; 482 m_bWasHiContrastMode = bIsHiContrastMode; 483 m_bShowMenuImages = bShowMenuImages; 484 485 sal_uInt16 nCount = pActMenu->GetItemCount(); 486 for ( sal_uInt16 nSVPos = 0; nSVPos < nCount; nSVPos++ ) 487 { 488 sal_uInt16 nItemId = pActMenu->GetItemId( nSVPos ); 489 if ( pActMenu->GetItemType( nSVPos ) != MENUITEM_SEPARATOR ) 490 { 491 if ( bShowMenuImages ) 492 { 493 sal_Bool bImageSet = sal_False; 494 ::rtl::OUString aImageId; 495 ::framework::MenuConfiguration::Attributes* pMenuAttributes = 496 (::framework::MenuConfiguration::Attributes*)pMenu->GetUserValue( nItemId ); 497 498 if ( pMenuAttributes ) 499 aImageId = pMenuAttributes->aImageId; // Retrieve image id from menu attributes 500 501 if ( aImageId.getLength() > 0 ) 502 { 503 Reference< ::com::sun::star::frame::XFrame > xFrame; 504 Image aImage = GetImage( xFrame, aImageId, sal_False, bIsHiContrastMode ); 505 if ( !!aImage ) 506 { 507 bImageSet = sal_True; 508 pActMenu->SetItemImage( nItemId, aImage ); 509 } 510 } 511 512 String aCmd( pActMenu->GetItemCommand( nItemId ) ); 513 if ( !bImageSet && aCmd.Len() ) 514 { 515 Image aImage = SvFileInformationManager::GetImage( 516 INetURLObject(aCmd), sal_False, bIsHiContrastMode ); 517 if ( !!aImage ) 518 pActMenu->SetItemImage( nItemId, aImage ); 519 } 520 } 521 else 522 pActMenu->SetItemImage( nItemId, Image() ); 523 } 524 } 525 } 526 527 return sal_True; 528 } 529 530 return sal_False; 531 } 532 533 SfxUnoMenuControl* SfxMenuControl::CreateControl( const String& rCmd, 534 sal_uInt16 nId, Menu& rMenu, SfxBindings &rBindings, SfxVirtualMenu* pVirt ) 535 { 536 return new SfxUnoMenuControl( rCmd, nId, rMenu, rBindings, pVirt ); 537 } 538 539 SfxUnoMenuControl* SfxMenuControl::CreateControl( const String& rCmd, 540 sal_uInt16 nId, Menu& rMenu, const String& sItemText, const String& sHelpText, 541 SfxBindings& rBindings, SfxVirtualMenu* pVirt) 542 { 543 return new SfxUnoMenuControl( rCmd, nId, rMenu, sItemText, sHelpText, rBindings, pVirt); 544 } 545 546 SfxUnoMenuControl::SfxUnoMenuControl( const String& rCmd, sal_uInt16 nSlotId, 547 Menu& rMenu, SfxBindings& rBindings, SfxVirtualMenu* pVirt ) 548 : SfxMenuControl( nSlotId, rBindings ) 549 { 550 Bind( pVirt, nSlotId, rMenu.GetItemText(nSlotId), 551 rMenu.GetHelpText(nSlotId), rBindings); 552 UnBind(); 553 pUnoCtrl = new SfxUnoControllerItem( this, rBindings, rCmd ); 554 pUnoCtrl->acquire(); 555 pUnoCtrl->GetNewDispatch(); 556 } 557 558 SfxUnoMenuControl::SfxUnoMenuControl( 559 const String& rCmd, sal_uInt16 nSlotId, Menu& /*rMenu*/, 560 const String& rItemText, const String& rHelpText, 561 SfxBindings& rBindings, SfxVirtualMenu* pVirt) 562 : SfxMenuControl( nSlotId, rBindings ) 563 { 564 Bind( pVirt, nSlotId, rItemText, rHelpText, rBindings); 565 UnBind(); 566 pUnoCtrl = new SfxUnoControllerItem( this, rBindings, rCmd ); 567 pUnoCtrl->acquire(); 568 pUnoCtrl->GetNewDispatch(); 569 } 570 571 SfxUnoMenuControl::~SfxUnoMenuControl() 572 { 573 pUnoCtrl->UnBind(); 574 pUnoCtrl->release(); 575 } 576 577 void SfxUnoMenuControl::Select() 578 { 579 pUnoCtrl->Execute(); 580 } 581 582 long Select_Impl( void* /*pHdl*/, void* pVoid ) 583 { 584 Menu* pMenu = (Menu*)pVoid; 585 String aURL( pMenu->GetItemCommand( pMenu->GetCurItemId() ) ); 586 587 if( !aURL.Len() ) 588 return 0; 589 590 Reference < ::com::sun::star::frame::XFramesSupplier > xDesktop = 591 Reference < ::com::sun::star::frame::XFramesSupplier >( ::comphelper::getProcessServiceFactory()->createInstance( 592 DEFINE_CONST_UNICODE("com.sun.star.frame.Desktop") ), UNO_QUERY ); 593 Reference < ::com::sun::star::frame::XFrame > xFrame( xDesktop, UNO_QUERY ); 594 595 URL aTargetURL; 596 aTargetURL.Complete = aURL; 597 Reference < XURLTransformer > xTrans( ::comphelper::getProcessServiceFactory()->createInstance( 598 rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer" )), 599 UNO_QUERY ); 600 xTrans->parseStrict( aTargetURL ); 601 602 Reference < XDispatchProvider > xProv( xFrame, UNO_QUERY ); 603 Reference < XDispatch > xDisp; 604 if ( xProv.is() ) 605 { 606 if ( aTargetURL.Protocol.compareToAscii("slot:") == COMPARE_EQUAL ) 607 xDisp = xProv->queryDispatch( aTargetURL, ::rtl::OUString(), 0 ); 608 else 609 { 610 ::rtl::OUString aTargetFrame( ::rtl::OUString::createFromAscii( "_blank" ) ); 611 ::framework::MenuConfiguration::Attributes* pMenuAttributes = 612 (::framework::MenuConfiguration::Attributes*)pMenu->GetUserValue( pMenu->GetCurItemId() ); 613 614 if ( pMenuAttributes ) 615 aTargetFrame = pMenuAttributes->aTargetFrame; 616 617 xDisp = xProv->queryDispatch( aTargetURL, aTargetFrame , 0 ); 618 } 619 } 620 621 if ( xDisp.is() ) 622 { 623 SfxAppMenuControl_Impl::ExecuteInfo* pExecuteInfo = new SfxAppMenuControl_Impl::ExecuteInfo; 624 pExecuteInfo->xDispatch = xDisp; 625 pExecuteInfo->aTargetURL = aTargetURL; 626 pExecuteInfo->aArgs = Sequence< PropertyValue >(); 627 Application::PostUserEvent( STATIC_LINK( 0, SfxAppMenuControl_Impl, ExecuteHdl_Impl), pExecuteInfo ); 628 } 629 630 return sal_True; 631 } 632 633 634 IMPL_STATIC_LINK_NOINSTANCE( SfxAppMenuControl_Impl, ExecuteHdl_Impl, ExecuteInfo*, pExecuteInfo ) 635 { 636 pExecuteInfo->xDispatch->dispatch( pExecuteInfo->aTargetURL, pExecuteInfo->aArgs ); 637 delete pExecuteInfo; 638 return 0; 639 } 640