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_framework.hxx" 26 #include <uielement/toolbarsmenucontroller.hxx> 27 28 #include <algorithm> 29 30 //_________________________________________________________________________________________________________________ 31 // my own includes 32 //_________________________________________________________________________________________________________________ 33 #include <threadhelp/resetableguard.hxx> 34 #include "services.h" 35 #ifndef __FRAMEWORK_CLASSES_RESOURCE_HRC_ 36 #include <classes/resource.hrc> 37 #endif 38 #include <classes/fwkresid.hxx> 39 #include <uiconfiguration/windowstateconfiguration.hxx> 40 #include <framework/imageproducer.hxx> 41 #include <framework/sfxhelperfunctions.hxx> 42 43 //_________________________________________________________________________________________________________________ 44 // interface includes 45 //_________________________________________________________________________________________________________________ 46 #include <com/sun/star/awt/XDevice.hpp> 47 #include <com/sun/star/beans/PropertyValue.hpp> 48 #include <com/sun/star/awt/MenuItemStyle.hpp> 49 #include <com/sun/star/frame/XDispatchProvider.hpp> 50 #include <com/sun/star/container/XNameContainer.hpp> 51 #include <com/sun/star/beans/XPropertySet.hpp> 52 #include <com/sun/star/frame/XLayoutManager.hpp> 53 #include <com/sun/star/ui/XUIElementSettings.hpp> 54 #include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp> 55 #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp> 56 #include <com/sun/star/ui/UIElementType.hpp> 57 58 //_________________________________________________________________________________________________________________ 59 // includes of other projects 60 //_________________________________________________________________________________________________________________ 61 62 #ifndef _VCL_MENU_HXX_ 63 #include <vcl/menu.hxx> 64 #endif 65 #include <vcl/svapp.hxx> 66 #include <vcl/i18nhelp.hxx> 67 #include <vcl/image.hxx> 68 #include <tools/urlobj.hxx> 69 #include <rtl/ustrbuf.hxx> 70 #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_ 71 #include <toolkit/unohlp.hxx> 72 #endif 73 #include <vcl/window.hxx> 74 #include <svtools/menuoptions.hxx> 75 #include <unotools/cmdoptions.hxx> 76 #include <dispatch/uieventloghelper.hxx> 77 #include <rtl/logfile.hxx> 78 79 //_________________________________________________________________________________________________________________ 80 // Defines 81 //_________________________________________________________________________________________________________________ 82 // 83 84 using namespace ::com::sun::star; 85 using namespace ::com::sun::star::uno; 86 using namespace ::com::sun::star::lang; 87 using namespace ::com::sun::star::frame; 88 using namespace ::com::sun::star::beans; 89 using namespace ::com::sun::star::util; 90 using namespace ::com::sun::star::container; 91 using namespace ::com::sun::star::frame; 92 using namespace ::com::sun::star::ui; 93 94 static const char CONFIGURE_TOOLBARS_CMD[] = "ConfigureDialog"; 95 static const char CONFIGURE_TOOLBARS[] = ".uno:ConfigureDialog"; 96 static const char CMD_COLORBAR[] = ".uno:ColorControl"; 97 static const char CMD_HYPERLINKBAR[] = ".uno:InsertHyperlink"; 98 static const char CMD_FORMULABAR[] = ".uno:InsertFormula"; 99 static const char CMD_INPUTLINEBAR[] = ".uno:InputLineVisible"; 100 static const char CMD_RESTOREVISIBILITY[] = ".cmd:RestoreVisibility"; 101 static const char ITEM_DESCRIPTOR_RESOURCEURL[] = "ResourceURL"; 102 static const char ITEM_DESCRIPTOR_UINAME[] = "UIName"; 103 static const char STATIC_PRIVATE_TB_RESOURCE[] = "private:resource/toolbar/"; 104 105 static const char STATIC_CMD_PART[] = ".uno:AvailableToolbars?Toolbar:string="; 106 static const char STATIC_INTERNAL_CMD_PART[] = ".cmd:"; 107 108 namespace framework 109 { 110 111 typedef std::hash_map< rtl::OUString, rtl::OUString, OUStringHashCode, ::std::equal_to< ::rtl::OUString > > ToolbarHashMap; 112 113 struct ToolBarEntry 114 { 115 rtl::OUString aUIName; 116 rtl::OUString aCommand; 117 sal_Bool bVisible; 118 sal_Bool bContextSensitive; 119 const CollatorWrapper* pCollatorWrapper; 120 }; 121 122 sal_Bool CompareToolBarEntry( const ToolBarEntry& aOne, const ToolBarEntry& aTwo ) 123 { 124 sal_Int32 nComp = aOne.pCollatorWrapper->compareString( aOne.aUIName, aTwo.aUIName ); 125 126 if ( nComp < 0 ) 127 return sal_True; 128 else if ( nComp > 0 ) 129 return sal_False; 130 else 131 return sal_False; 132 } 133 134 Reference< XLayoutManager > getLayoutManagerFromFrame( const Reference< XFrame >& rFrame ) 135 { 136 Reference< XPropertySet > xPropSet( rFrame, UNO_QUERY ); 137 Reference< XLayoutManager > xLayoutManager; 138 139 try 140 { 141 xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ))) >>= xLayoutManager; 142 } 143 catch ( UnknownPropertyException& ) 144 { 145 } 146 147 return xLayoutManager; 148 } 149 150 struct ToolBarInfo 151 { 152 rtl::OUString aToolBarResName; 153 rtl::OUString aToolBarUIName; 154 }; 155 156 DEFINE_XSERVICEINFO_MULTISERVICE ( ToolbarsMenuController , 157 OWeakObject , 158 SERVICENAME_POPUPMENUCONTROLLER , 159 IMPLEMENTATIONNAME_TOOLBARSMENUCONTROLLER 160 ) 161 162 DEFINE_INIT_SERVICE ( ToolbarsMenuController, {} ) 163 164 ToolbarsMenuController::ToolbarsMenuController( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager ) : 165 svt::PopupMenuControllerBase( xServiceManager ), 166 m_aPropUIName( RTL_CONSTASCII_USTRINGPARAM( "UIName" )), 167 m_aPropResourceURL( RTL_CONSTASCII_USTRINGPARAM( "ResourceURL" )), 168 m_bModuleIdentified( sal_False ), 169 m_bResetActive( sal_False ), 170 m_aIntlWrapper( xServiceManager, Application::GetSettings().GetLocale() ) 171 { 172 } 173 174 ToolbarsMenuController::~ToolbarsMenuController() 175 { 176 } 177 178 void ToolbarsMenuController::addCommand( 179 Reference< css::awt::XPopupMenu >& rPopupMenu, const rtl::OUString& rCommandURL, const rtl::OUString& rLabel ) 180 { 181 sal_uInt16 nItemId = m_xPopupMenu->getItemCount()+1; 182 183 rtl::OUString aLabel; 184 if ( rLabel.getLength() == 0 ) 185 aLabel = getUINameFromCommand( rCommandURL ); 186 else 187 aLabel = rLabel; 188 189 rPopupMenu->insertItem( nItemId, aLabel, 0, nItemId ); 190 Reference< awt::XMenuExtended > xMenuExtended( m_xPopupMenu, UNO_QUERY ); 191 xMenuExtended->setCommand( nItemId, rCommandURL ); 192 193 bool bInternal = ( rCommandURL.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STATIC_INTERNAL_CMD_PART ))) == 0); 194 if ( !bInternal ) 195 { 196 if ( !getDispatchFromCommandURL( rCommandURL ).is() ) 197 m_xPopupMenu->enableItem( nItemId, sal_False ); 198 } 199 200 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); 201 202 Image aImage; 203 const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings(); 204 205 if ( rSettings.GetUseImagesInMenus() ) 206 aImage = GetImageFromURL( m_xFrame, rCommandURL, sal_False, rSettings.GetHighContrastMode() ); 207 208 VCLXPopupMenu* pPopupMenu = (VCLXPopupMenu *)VCLXPopupMenu::GetImplementation( rPopupMenu ); 209 if ( pPopupMenu ) 210 { 211 PopupMenu* pVCLPopupMenu = (PopupMenu *)pPopupMenu->GetMenu(); 212 if ( !!aImage ) 213 pVCLPopupMenu->SetItemImage( nItemId, aImage ); 214 } 215 216 m_aCommandVector.push_back( rCommandURL ); 217 } 218 219 Reference< XDispatch > ToolbarsMenuController::getDispatchFromCommandURL( const rtl::OUString& rCommandURL ) 220 { 221 URL aTargetURL; 222 Sequence<PropertyValue> aArgs; 223 Reference< XURLTransformer > xURLTransformer; 224 Reference< XFrame > xFrame; 225 226 { 227 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); 228 xURLTransformer = m_xURLTransformer; 229 xFrame = m_xFrame; 230 } 231 232 aTargetURL.Complete = rCommandURL; 233 xURLTransformer->parseStrict( aTargetURL ); 234 Reference< XDispatchProvider > xDispatchProvider( xFrame, UNO_QUERY ); 235 if ( xDispatchProvider.is() ) 236 return xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 ); 237 else 238 return Reference< XDispatch >(); 239 } 240 241 // private function 242 rtl::OUString ToolbarsMenuController::getUINameFromCommand( const rtl::OUString& rCommandURL ) 243 { 244 rtl::OUString aLabel; 245 246 if ( !m_bModuleIdentified ) 247 { 248 try 249 { 250 Reference< XModuleManager > xModuleManager( m_xServiceManager->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY_THROW ); 251 m_aModuleIdentifier = xModuleManager->identify( m_xFrame ); 252 Reference< XNameAccess > xNameAccess( m_xServiceManager->createInstance( 253 SERVICENAME_UICOMMANDDESCRIPTION ), 254 UNO_QUERY ); 255 xNameAccess->getByName( m_aModuleIdentifier ) >>= m_xUICommandDescription; 256 } 257 catch ( Exception& ) 258 { 259 } 260 } 261 262 if ( m_xUICommandDescription.is() ) 263 { 264 try 265 { 266 Sequence< PropertyValue > aPropSeq; 267 rtl::OUString aStr; 268 if ( m_xUICommandDescription->getByName( rCommandURL ) >>= aPropSeq ) 269 { 270 for ( sal_Int32 i = 0; i < aPropSeq.getLength(); i++ ) 271 { 272 if ( aPropSeq[i].Name.equalsAscii( "Label" )) 273 { 274 aPropSeq[i].Value >>= aStr; 275 break; 276 } 277 } 278 } 279 aLabel = aStr; 280 } 281 catch ( Exception& ) 282 { 283 } 284 } 285 286 return aLabel; 287 } 288 289 static void fillHashMap( const Sequence< Sequence< ::com::sun::star::beans::PropertyValue > >& rSeqToolBars, 290 ToolbarHashMap& rHashMap ) 291 { 292 for ( sal_Int32 i = 0; i < rSeqToolBars.getLength(); i++ ) 293 { 294 rtl::OUString aResourceURL; 295 rtl::OUString aUIName; 296 const PropertyValue* pProperties = rSeqToolBars[i].getConstArray(); 297 for ( sal_Int32 j = 0; j < rSeqToolBars[i].getLength(); j++ ) 298 { 299 if ( pProperties[j].Name.equalsAscii( ITEM_DESCRIPTOR_RESOURCEURL) ) 300 pProperties[j].Value >>= aResourceURL; 301 else if ( pProperties[j].Name.equalsAscii( ITEM_DESCRIPTOR_UINAME) ) 302 pProperties[j].Value >>= aUIName; 303 } 304 305 if ( aResourceURL.getLength() > 0 && 306 rHashMap.find( aResourceURL ) == rHashMap.end() ) 307 rHashMap.insert( ToolbarHashMap::value_type( aResourceURL, aUIName )); 308 } 309 } 310 311 // private function 312 Sequence< Sequence< com::sun::star::beans::PropertyValue > > ToolbarsMenuController::getLayoutManagerToolbars( const Reference< ::com::sun::star::frame::XLayoutManager >& rLayoutManager ) 313 { 314 std::vector< ToolBarInfo > aToolBarArray; 315 Sequence< Reference< XUIElement > > aUIElements = rLayoutManager->getElements(); 316 for ( sal_Int32 i = 0; i < aUIElements.getLength(); i++ ) 317 { 318 Reference< XUIElement > xUIElement( aUIElements[i] ); 319 Reference< XPropertySet > xPropSet( aUIElements[i], UNO_QUERY ); 320 if ( xPropSet.is() && xUIElement.is() ) 321 { 322 try 323 { 324 rtl::OUString aResName; 325 sal_Int16 nType( -1 ); 326 xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Type" ))) >>= nType; 327 xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ResourceURL" ))) >>= aResName; 328 329 if (( nType == ::com::sun::star::ui::UIElementType::TOOLBAR ) && 330 ( aResName.getLength() > 0 )) 331 { 332 ToolBarInfo aToolBarInfo; 333 334 aToolBarInfo.aToolBarResName = aResName; 335 336 vos::OGuard aGuard( Application::GetSolarMutex() ); 337 Reference< css::awt::XWindow > xWindow( xUIElement->getRealInterface(), UNO_QUERY ); 338 Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); 339 if ( pWindow ) 340 aToolBarInfo.aToolBarUIName = pWindow->GetText(); 341 342 aToolBarArray.push_back( aToolBarInfo ); 343 } 344 } 345 catch ( Exception& ) 346 { 347 } 348 } 349 } 350 351 Sequence< com::sun::star::beans::PropertyValue > aTbSeq( 2 ); 352 aTbSeq[0].Name = m_aPropUIName; 353 aTbSeq[1].Name = m_aPropResourceURL; 354 355 Sequence< Sequence< com::sun::star::beans::PropertyValue > > aSeq( aToolBarArray.size() ); 356 const sal_uInt32 nCount = aToolBarArray.size(); 357 for ( sal_uInt32 i = 0; i < nCount; i++ ) 358 { 359 aTbSeq[0].Value <<= aToolBarArray[i].aToolBarUIName; 360 aTbSeq[1].Value <<= aToolBarArray[i].aToolBarResName; 361 aSeq[i] = aTbSeq; 362 } 363 364 return aSeq; 365 } 366 367 sal_Bool ToolbarsMenuController::isContextSensitiveToolbarNonVisible() 368 { 369 return m_bResetActive; 370 } 371 372 void ToolbarsMenuController::fillPopupMenu( Reference< css::awt::XPopupMenu >& rPopupMenu ) 373 { 374 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); 375 resetPopupMenu( rPopupMenu ); 376 377 m_aCommandVector.clear(); 378 379 // Retrieve layout manager for additional information 380 rtl::OUString aEmptyString; 381 Reference< awt::XMenuExtended > xMenuExtended( rPopupMenu, UNO_QUERY ); 382 Reference< XLayoutManager > xLayoutManager( getLayoutManagerFromFrame( m_xFrame )); 383 384 m_bResetActive = sal_False; 385 if ( xLayoutManager.is() ) 386 { 387 ToolbarHashMap aToolbarHashMap; 388 389 if ( m_xDocCfgMgr.is() ) 390 { 391 Sequence< Sequence< com::sun::star::beans::PropertyValue > > aSeqDocToolBars = 392 m_xDocCfgMgr->getUIElementsInfo( UIElementType::TOOLBAR ); 393 fillHashMap( aSeqDocToolBars, aToolbarHashMap ); 394 } 395 396 if ( m_xModuleCfgMgr.is() ) 397 { 398 Sequence< Sequence< com::sun::star::beans::PropertyValue > > aSeqToolBars = 399 m_xModuleCfgMgr->getUIElementsInfo( UIElementType::TOOLBAR ); 400 fillHashMap( aSeqToolBars, aToolbarHashMap ); 401 } 402 403 std::vector< ToolBarEntry > aSortedTbs; 404 rtl::OUString aStaticCmdPart( RTL_CONSTASCII_USTRINGPARAM( STATIC_CMD_PART )); 405 406 Sequence< Sequence< com::sun::star::beans::PropertyValue > > aSeqFrameToolBars = getLayoutManagerToolbars( xLayoutManager ); 407 fillHashMap( aSeqFrameToolBars, aToolbarHashMap ); 408 409 ToolbarHashMap::const_iterator pIter = aToolbarHashMap.begin(); 410 while ( pIter != aToolbarHashMap.end() ) 411 { 412 rtl::OUString aUIName = pIter->second; 413 sal_Bool bHideFromMenu( sal_False ); 414 sal_Bool bContextSensitive( sal_False ); 415 sal_Bool bVisible( sal_False ); 416 if ( aUIName.getLength() == 0 && 417 m_xPersistentWindowState.is() ) 418 { 419 try 420 { 421 Sequence< PropertyValue > aWindowState; 422 Any a( m_xPersistentWindowState->getByName( pIter->first )); 423 424 if ( a >>= aWindowState ) 425 { 426 for ( sal_Int32 i = 0; i < aWindowState.getLength(); i++ ) 427 { 428 if ( aWindowState[i].Name.equalsAscii( WINDOWSTATE_PROPERTY_UINAME )) 429 aWindowState[i].Value >>= aUIName; 430 else if ( aWindowState[i].Name.equalsAscii( WINDOWSTATE_PROPERTY_HIDEFROMENU )) 431 aWindowState[i].Value >>= bHideFromMenu; 432 else if ( aWindowState[i].Name.equalsAscii( WINDOWSTATE_PROPERTY_CONTEXT )) 433 aWindowState[i].Value >>= bContextSensitive; 434 else if ( aWindowState[i].Name.equalsAscii( WINDOWSTATE_PROPERTY_VISIBLE )) 435 aWindowState[i].Value >>= bVisible; 436 } 437 } 438 } 439 catch ( Exception& ) 440 { 441 } 442 443 // Check if we have to enable/disable "Reset" menu item 444 if ( bContextSensitive && !bVisible ) 445 m_bResetActive = sal_True; 446 447 } 448 449 if (( aUIName.getLength() > 0 ) && ( !bHideFromMenu )) 450 { 451 ToolBarEntry aTbEntry; 452 aTbEntry.aUIName = aUIName; 453 aTbEntry.aCommand = pIter->first; 454 aTbEntry.bVisible = xLayoutManager->isElementVisible( pIter->first ); 455 aTbEntry.bContextSensitive = bContextSensitive; 456 aTbEntry.pCollatorWrapper = m_aIntlWrapper.getCaseCollator(); 457 aSortedTbs.push_back( aTbEntry ); 458 } 459 pIter++; 460 } 461 462 // sort toolbars 463 std::sort( aSortedTbs.begin(), aSortedTbs.end(), CompareToolBarEntry ); 464 465 sal_Int16 nIndex( 1 ); 466 const sal_uInt32 nCount = aSortedTbs.size(); 467 for ( sal_uInt32 i = 0; i < nCount; i++ ) 468 { 469 sal_uInt16 nItemCount = m_xPopupMenu->getItemCount(); 470 m_xPopupMenu->insertItem( nIndex, aSortedTbs[i].aUIName, css::awt::MenuItemStyle::CHECKABLE, nItemCount ); 471 if ( aSortedTbs[i].bVisible ) 472 m_xPopupMenu->checkItem( nIndex, sal_True ); 473 474 { 475 vos::OGuard aGuard( Application::GetSolarMutex() ); 476 VCLXPopupMenu* pXPopupMenu = (VCLXPopupMenu *)VCLXMenu::GetImplementation( m_xPopupMenu ); 477 PopupMenu* pVCLPopupMenu = (PopupMenu *)pXPopupMenu->GetMenu(); 478 479 pVCLPopupMenu->SetUserValue( nIndex, sal_uIntPtr( aSortedTbs[i].bContextSensitive ? 1L : 0L )); 480 } 481 482 // use VCL popup menu pointer to set vital information that are not part of the awt implementation 483 rtl::OUStringBuffer aStrBuf( aStaticCmdPart ); 484 485 sal_Int32 n = aSortedTbs[i].aCommand.lastIndexOf( '/' ); 486 if (( n > 0 ) && (( n+1 ) < aSortedTbs[i].aCommand.getLength() )) 487 aStrBuf.append( aSortedTbs[i].aCommand.copy( n+1 )); 488 489 rtl::OUString aCmd( aStrBuf.makeStringAndClear() ); 490 491 // Store complete uno-command so it can also be dispatched. This is necessary to support 492 // the test tool! 493 xMenuExtended->setCommand( nIndex, aCmd ); 494 ++nIndex; 495 } 496 497 // Create commands for non-toolbars 498 if ( m_aModuleIdentifier.equalsAscii( "com.sun.star.text.TextDocument" ) || 499 m_aModuleIdentifier.equalsAscii( "com.sun.star.text.WebDocument" ) || 500 m_aModuleIdentifier.equalsAscii( "com.sun.star.text.GlobalDocument" ) || 501 m_aModuleIdentifier.equalsAscii( "com.sun.star.drawing.DrawingDocument" ) || 502 m_aModuleIdentifier.equalsAscii( "com.sun.star.presentation.PresentationDocument" ) || 503 m_aModuleIdentifier.equalsAscii( "com.sun.star.sheet.SpreadsheetDocument" )) 504 { 505 addCommand( m_xPopupMenu, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CMD_HYPERLINKBAR )), aEmptyString ); 506 if ( m_aModuleIdentifier.equalsAscii( "com.sun.star.drawing.DrawingDocument" ) || 507 m_aModuleIdentifier.equalsAscii( "com.sun.star.presentation.PresentationDocument" )) 508 addCommand( m_xPopupMenu, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CMD_COLORBAR )), aEmptyString ); 509 else if ( m_aModuleIdentifier.equalsAscii( "com.sun.star.sheet.SpreadsheetDocument" )) 510 addCommand( m_xPopupMenu, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CMD_INPUTLINEBAR )), aEmptyString ); 511 else 512 addCommand( m_xPopupMenu, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CMD_FORMULABAR )), aEmptyString ); 513 } 514 515 sal_Bool bAddCommand( sal_True ); 516 SvtCommandOptions aCmdOptions; 517 rtl::OUString aConfigureToolbar( RTL_CONSTASCII_USTRINGPARAM( CONFIGURE_TOOLBARS )); 518 519 if ( aCmdOptions.HasEntries( SvtCommandOptions::CMDOPTION_DISABLED )) 520 { 521 if ( aCmdOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED, 522 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CONFIGURE_TOOLBARS_CMD )))) 523 bAddCommand = sal_False; 524 } 525 526 if ( bAddCommand ) 527 { 528 // Create command for configure 529 if ( m_xPopupMenu->getItemCount() > 0 ) 530 { 531 sal_uInt16 nItemCount = m_xPopupMenu->getItemCount(); 532 m_xPopupMenu->insertSeparator( nItemCount+1 ); 533 } 534 535 addCommand( m_xPopupMenu, aConfigureToolbar, aEmptyString ); 536 } 537 538 // Add separator if no configure has been added 539 if ( !bAddCommand ) 540 { 541 // Create command for configure 542 if ( m_xPopupMenu->getItemCount() > 0 ) 543 { 544 sal_uInt16 nItemCount = m_xPopupMenu->getItemCount(); 545 m_xPopupMenu->insertSeparator( nItemCount+1 ); 546 } 547 } 548 549 String aLabelStr = String( FwkResId( STR_RESTORE_TOOLBARS )); 550 rtl::OUString aRestoreCmd( RTL_CONSTASCII_USTRINGPARAM( CMD_RESTOREVISIBILITY )); 551 addCommand( m_xPopupMenu, aRestoreCmd, aLabelStr ); 552 } 553 } 554 555 // XEventListener 556 void SAL_CALL ToolbarsMenuController::disposing( const EventObject& ) throw ( RuntimeException ) 557 { 558 Reference< css::awt::XMenuListener > xHolder(( OWeakObject *)this, UNO_QUERY ); 559 560 osl::MutexGuard aLock( m_aMutex ); 561 m_xFrame.clear(); 562 m_xDispatch.clear(); 563 m_xDocCfgMgr.clear(); 564 m_xModuleCfgMgr.clear(); 565 m_xServiceManager.clear(); 566 567 if ( m_xPopupMenu.is() ) 568 m_xPopupMenu->removeMenuListener( Reference< css::awt::XMenuListener >(( OWeakObject *)this, UNO_QUERY )); 569 m_xPopupMenu.clear(); 570 } 571 572 // XStatusListener 573 void SAL_CALL ToolbarsMenuController::statusChanged( const FeatureStateEvent& Event ) throw ( RuntimeException ) 574 { 575 rtl::OUString aFeatureURL( Event.FeatureURL.Complete ); 576 577 // All other status events will be processed here 578 sal_Bool bSetCheckmark = sal_False; 579 sal_Bool bCheckmark = sal_False; 580 581 osl::ClearableMutexGuard aLock( m_aMutex ); 582 Reference< css::awt::XPopupMenu > xPopupMenu( m_xPopupMenu ); 583 aLock.clear(); 584 585 if ( xPopupMenu.is() ) 586 { 587 vos::OGuard aGuard( Application::GetSolarMutex() ); 588 VCLXPopupMenu* pXPopupMenu = (VCLXPopupMenu *)VCLXMenu::GetImplementation( xPopupMenu ); 589 PopupMenu* pVCLPopupMenu = (PopupMenu *)pXPopupMenu->GetMenu(); 590 591 for ( sal_uInt16 i = 0; i < pVCLPopupMenu->GetItemCount(); i++ ) 592 { 593 sal_uInt16 nId = pVCLPopupMenu->GetItemId( i ); 594 if ( nId == 0 ) 595 continue; 596 597 rtl::OUString aCmd = pVCLPopupMenu->GetItemCommand( nId ); 598 if ( aCmd == aFeatureURL ) 599 { 600 // Enable/disable item 601 pVCLPopupMenu->EnableItem( nId, Event.IsEnabled ); 602 603 // Checkmark 604 if ( Event.State >>= bCheckmark ) 605 bSetCheckmark = sal_True; 606 607 if ( bSetCheckmark ) 608 pVCLPopupMenu->CheckItem( nId, bCheckmark ); 609 else 610 { 611 rtl::OUString aItemText; 612 613 if ( Event.State >>= aItemText ) 614 pVCLPopupMenu->SetItemText( nId, aItemText ); 615 } 616 } 617 } 618 } 619 } 620 621 // XMenuListener 622 void SAL_CALL ToolbarsMenuController::select( const css::awt::MenuEvent& rEvent ) throw (RuntimeException) 623 { 624 Reference< css::awt::XPopupMenu > xPopupMenu; 625 Reference< XMultiServiceFactory > xServiceManager; 626 Reference< XURLTransformer > xURLTransformer; 627 Reference< XFrame > xFrame; 628 Reference< XNameAccess > xPersistentWindowState; 629 630 osl::ClearableMutexGuard aLock( m_aMutex ); 631 xPopupMenu = m_xPopupMenu; 632 xServiceManager = m_xServiceManager; 633 xURLTransformer = m_xURLTransformer; 634 xFrame = m_xFrame; 635 xPersistentWindowState = m_xPersistentWindowState; 636 aLock.clear(); 637 638 if ( xPopupMenu.is() ) 639 { 640 VCLXPopupMenu* pPopupMenu = (VCLXPopupMenu *)VCLXPopupMenu::GetImplementation( xPopupMenu ); 641 if ( pPopupMenu ) 642 { 643 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); 644 PopupMenu* pVCLPopupMenu = (PopupMenu *)pPopupMenu->GetMenu(); 645 646 rtl::OUString aCmd( pVCLPopupMenu->GetItemCommand( rEvent.MenuId )); 647 if ( aCmd.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STATIC_INTERNAL_CMD_PART ))) == 0 ) 648 { 649 // Command to restore the visibility of all context sensitive toolbars 650 Reference< XNameReplace > xNameReplace( xPersistentWindowState, UNO_QUERY ); 651 if ( xPersistentWindowState.is() && xNameReplace.is() ) 652 { 653 try 654 { 655 Sequence< rtl::OUString > aElementNames = xPersistentWindowState->getElementNames(); 656 sal_Int32 nCount = aElementNames.getLength(); 657 bool bRefreshToolbars( false ); 658 659 for ( sal_Int32 i = 0; i < nCount; i++ ) 660 { 661 try 662 { 663 rtl::OUString aElementName = aElementNames[i]; 664 Sequence< PropertyValue > aWindowState; 665 666 if ( xPersistentWindowState->getByName( aElementName ) >>= aWindowState ) 667 { 668 sal_Bool bVisible( sal_False ); 669 sal_Bool bContextSensitive( sal_False ); 670 sal_Int32 nVisibleIndex( -1 ); 671 for ( sal_Int32 j = 0; j < aWindowState.getLength(); j++ ) 672 { 673 if ( aWindowState[j].Name.equalsAscii( WINDOWSTATE_PROPERTY_VISIBLE )) 674 { 675 aWindowState[j].Value >>= bVisible; 676 nVisibleIndex = j; 677 } 678 else if ( aWindowState[j].Name.equalsAscii( WINDOWSTATE_PROPERTY_CONTEXT )) 679 aWindowState[j].Value >>= bContextSensitive; 680 } 681 682 if ( !bVisible && bContextSensitive && nVisibleIndex >= 0 ) 683 { 684 // Default is: Every context sensitive toolbar is visible 685 aWindowState[nVisibleIndex].Value <<= sal_True; 686 xNameReplace->replaceByName( aElementName, makeAny( aWindowState )); 687 bRefreshToolbars = true; 688 } 689 } 690 } 691 catch ( NoSuchElementException& ) 692 { 693 } 694 } 695 696 if ( bRefreshToolbars ) 697 { 698 Reference< XLayoutManager > xLayoutManager( getLayoutManagerFromFrame( xFrame )); 699 if ( xLayoutManager.is() ) 700 { 701 Reference< XPropertySet > xPropSet( xLayoutManager, UNO_QUERY ); 702 if ( xPropSet.is() ) 703 { 704 try 705 { 706 xPropSet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RefreshContextToolbarVisibility" )), makeAny( sal_True )); 707 } 708 catch ( RuntimeException& ) 709 { 710 } 711 catch ( Exception& ) 712 { 713 } 714 } 715 } 716 RefreshToolbars( xFrame ); 717 } 718 } 719 catch ( RuntimeException& ) 720 { 721 throw; 722 } 723 catch ( Exception& ) 724 { 725 } 726 } 727 } 728 else if ( aCmd.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STATIC_CMD_PART ))) < 0 ) 729 { 730 URL aTargetURL; 731 Sequence<PropertyValue> aArgs; 732 733 aTargetURL.Complete = aCmd; 734 xURLTransformer->parseStrict( aTargetURL ); 735 Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY ); 736 if ( xDispatchProvider.is() ) 737 { 738 Reference< XDispatch > xDispatch = xDispatchProvider->queryDispatch( 739 aTargetURL, ::rtl::OUString(), 0 ); 740 741 ExecuteInfo* pExecuteInfo = new ExecuteInfo; 742 pExecuteInfo->xDispatch = xDispatch; 743 pExecuteInfo->aTargetURL = aTargetURL; 744 pExecuteInfo->aArgs = aArgs; 745 if(::comphelper::UiEventsLogger::isEnabled()) //#i88653# 746 UiEventLogHelper(::rtl::OUString::createFromAscii("ToolbarsMenuController")).log(m_xServiceManager, m_xFrame, aTargetURL, aArgs); 747 Application::PostUserEvent( STATIC_LINK(0, ToolbarsMenuController, ExecuteHdl_Impl), pExecuteInfo ); 748 } 749 } 750 else 751 { 752 Reference< XLayoutManager > xLayoutManager( getLayoutManagerFromFrame( xFrame )); 753 if ( xLayoutManager.is() ) 754 { 755 // Extract toolbar name from the combined uno-command. 756 sal_Int32 nIndex = aCmd.indexOf( '=' ); 757 if (( nIndex > 0 ) && (( nIndex+1 ) < aCmd.getLength() )) 758 { 759 rtl::OUStringBuffer aBuf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STATIC_PRIVATE_TB_RESOURCE ))); 760 aBuf.append( aCmd.copy( nIndex+1 )); 761 762 sal_Bool bShow( !pVCLPopupMenu->IsItemChecked( rEvent.MenuId )); 763 rtl::OUString aToolBarResName( aBuf.makeStringAndClear() ); 764 if ( bShow ) 765 { 766 xLayoutManager->createElement( aToolBarResName ); 767 xLayoutManager->showElement( aToolBarResName ); 768 } 769 else 770 { 771 // closing means: 772 // hide and destroy element 773 xLayoutManager->hideElement( aToolBarResName ); 774 xLayoutManager->destroyElement( aToolBarResName ); 775 } 776 } 777 } 778 } 779 } 780 } 781 } 782 783 void SAL_CALL ToolbarsMenuController::activate( const css::awt::MenuEvent& ) throw (RuntimeException) 784 { 785 std::vector< rtl::OUString > aCmdVector; 786 Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY ); 787 Reference< XURLTransformer > xURLTransformer( m_xURLTransformer ); 788 { 789 osl::MutexGuard aLock( m_aMutex ); 790 fillPopupMenu( m_xPopupMenu ); 791 aCmdVector = m_aCommandVector; 792 } 793 794 // Update status for all commands inside our toolbars popup menu 795 const sal_uInt32 nCount = aCmdVector.size(); 796 for ( sal_uInt32 i = 0; i < nCount; i++ ) 797 { 798 bool bInternal = ( aCmdVector[i].indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STATIC_INTERNAL_CMD_PART ))) == 0); 799 800 if ( !bInternal ) 801 { 802 URL aTargetURL; 803 aTargetURL.Complete = aCmdVector[i]; 804 xURLTransformer->parseStrict( aTargetURL ); 805 Reference< XDispatch > xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 ); 806 if ( xDispatch.is() ) 807 { 808 xDispatch->addStatusListener( SAL_STATIC_CAST( XStatusListener*, this ), aTargetURL ); 809 xDispatch->removeStatusListener( SAL_STATIC_CAST( XStatusListener*, this ), aTargetURL ); 810 } 811 } 812 else if ( aCmdVector[i].equalsAscii( CMD_RESTOREVISIBILITY )) 813 { 814 // Special code to determine the enable/disable state of this command 815 FeatureStateEvent aFeatureStateEvent; 816 aFeatureStateEvent.FeatureURL.Complete = aCmdVector[i]; 817 aFeatureStateEvent.IsEnabled = isContextSensitiveToolbarNonVisible(); 818 statusChanged( aFeatureStateEvent ); 819 } 820 } 821 } 822 823 // XPopupMenuController 824 void SAL_CALL ToolbarsMenuController::setPopupMenu( const Reference< css::awt::XPopupMenu >& xPopupMenu ) throw ( RuntimeException ) 825 { 826 osl::MutexGuard aLock( m_aMutex ); 827 828 throwIfDisposed(); 829 830 if ( m_xFrame.is() && !m_xPopupMenu.is() ) 831 { 832 // Create popup menu on demand 833 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); 834 835 m_xPopupMenu = xPopupMenu; 836 m_xPopupMenu->addMenuListener( Reference< css::awt::XMenuListener >( (OWeakObject*)this, UNO_QUERY )); 837 fillPopupMenu( m_xPopupMenu ); 838 } 839 } 840 841 // XInitialization 842 void SAL_CALL ToolbarsMenuController::initialize( const Sequence< Any >& aArguments ) throw ( Exception, RuntimeException ) 843 { 844 osl::MutexGuard aLock( m_aMutex ); 845 sal_Bool bInitalized( m_bInitialized ); 846 if ( !bInitalized ) 847 { 848 svt::PopupMenuControllerBase::initialize(aArguments); 849 850 if ( m_bInitialized ) 851 { 852 Reference< XModuleManager > xModuleManager( m_xServiceManager->createInstance( 853 SERVICENAME_MODULEMANAGER ), 854 UNO_QUERY ); 855 Reference< XNameAccess > xPersistentWindowStateSupplier( m_xServiceManager->createInstance( 856 SERVICENAME_WINDOWSTATECONFIGURATION ), 857 UNO_QUERY ); 858 859 // Retrieve persistent window state reference for our module 860 if ( xPersistentWindowStateSupplier.is() && xModuleManager.is() ) 861 { 862 rtl::OUString aModuleIdentifier; 863 try 864 { 865 aModuleIdentifier = xModuleManager->identify( m_xFrame ); 866 xPersistentWindowStateSupplier->getByName( aModuleIdentifier ) >>= m_xPersistentWindowState; 867 868 Reference< XModuleUIConfigurationManagerSupplier > xModuleCfgSupplier; 869 if ( m_xServiceManager.is() ) 870 xModuleCfgSupplier = Reference< XModuleUIConfigurationManagerSupplier >( 871 m_xServiceManager->createInstance( SERVICENAME_MODULEUICONFIGURATIONMANAGERSUPPLIER ), UNO_QUERY ); 872 m_xModuleCfgMgr = xModuleCfgSupplier->getUIConfigurationManager( aModuleIdentifier ); 873 874 Reference< XController > xController = m_xFrame->getController(); 875 Reference< XModel > xModel; 876 if ( xController.is() ) 877 xModel = xController->getModel(); 878 if ( xModel.is() ) 879 { 880 Reference< XUIConfigurationManagerSupplier > xUIConfigurationManagerSupplier( xModel, UNO_QUERY ); 881 if ( xUIConfigurationManagerSupplier.is() ) 882 m_xDocCfgMgr = xUIConfigurationManagerSupplier->getUIConfigurationManager(); 883 } 884 m_aModuleIdentifier = aModuleIdentifier; 885 } 886 catch ( Exception& ) 887 { 888 } 889 } 890 } 891 } 892 } 893 894 IMPL_STATIC_LINK_NOINSTANCE( ToolbarsMenuController, ExecuteHdl_Impl, ExecuteInfo*, pExecuteInfo ) 895 { 896 try 897 { 898 // Asynchronous execution as this can lead to our own destruction! 899 // Framework can recycle our current frame and the layout manager disposes all user interface 900 // elements if a component gets detached from its frame! 901 if ( pExecuteInfo->xDispatch.is() ) 902 { 903 pExecuteInfo->xDispatch->dispatch( pExecuteInfo->aTargetURL, pExecuteInfo->aArgs ); 904 } 905 } 906 catch ( Exception& ) 907 { 908 } 909 910 delete pExecuteInfo; 911 return 0; 912 } 913 914 } 915