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/addonstoolbarmanager.hxx> 27 #include <uielement/toolbarmerger.hxx> 28 29 //_________________________________________________________________________________________________________________ 30 // my own includes 31 //_________________________________________________________________________________________________________________ 32 33 34 #ifndef __FRAMEWORK_UIELEMENT_TOOLBAR_HXX 35 #include <uielement/toolbar.hxx> 36 #endif 37 #ifndef __FRAMEWORK_UIELEMENT_GENERICTOOLBARCONTROLLER_HXX 38 #include <uielement/generictoolbarcontroller.hxx> 39 #endif 40 #include <threadhelp/resetableguard.hxx> 41 #include "services.h" 42 #include <framework/imageproducer.hxx> 43 #include <framework/sfxhelperfunctions.hxx> 44 #include <classes/fwkresid.hxx> 45 #ifndef __FRAMEWORK_CLASES_RESOURCE_HRC_ 46 #include <classes/resource.hrc> 47 #endif 48 #include <framework/addonsoptions.hxx> 49 #ifndef __FRAMEWORK_UIELEMENT_COMBOBOXTOOLBARCONTROLLER_HXX 50 #include <uielement/comboboxtoolbarcontroller.hxx> 51 #endif 52 #ifndef __FRAMEWORK_UIELEMENT_IMAGEBUTTONTOOLBARCONTROLLER_HXX 53 #include <uielement/imagebuttontoolbarcontroller.hxx> 54 #endif 55 #ifndef __FRAMEWORK_UIELEMENT_TOGGLEBUTTONTOOLBARCONTROLLER_HXX 56 #include <uielement/togglebuttontoolbarcontroller.hxx> 57 #endif 58 #include <uielement/buttontoolbarcontroller.hxx> 59 #include <uielement/spinfieldtoolbarcontroller.hxx> 60 #include <uielement/edittoolbarcontroller.hxx> 61 #include <uielement/dropdownboxtoolbarcontroller.hxx> 62 #include <uielement/toolbarmerger.hxx> 63 64 //_________________________________________________________________________________________________________________ 65 // interface includes 66 //_________________________________________________________________________________________________________________ 67 #include <com/sun/star/ui/ItemType.hpp> 68 #include <com/sun/star/frame/XToolbarController.hpp> 69 #include <com/sun/star/frame/XDispatchProvider.hpp> 70 #ifndef _COM_SUN_STAR_BEANS_XLAYOUTMANAGER_HPP_ 71 #include <com/sun/star/beans/XPropertySet.hpp> 72 #endif 73 #include <com/sun/star/lang/XServiceInfo.hpp> 74 #include <com/sun/star/frame/XLayoutManager.hpp> 75 #ifndef _COM_SUN_STAR_UI_XDOCKINGAREA_HPP_ 76 #include <com/sun/star/ui/DockingArea.hpp> 77 #endif 78 #include <com/sun/star/lang/XMultiComponentFactory.hpp> 79 80 //_________________________________________________________________________________________________________________ 81 // other includes 82 //_________________________________________________________________________________________________________________ 83 #include <svtools/imgdef.hxx> 84 #include <svtools/toolboxcontroller.hxx> 85 #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_ 86 #include <toolkit/unohlp.hxx> 87 #endif 88 89 #include <svtools/miscopt.hxx> 90 #include <vcl/svapp.hxx> 91 #include <vcl/menu.hxx> 92 #include <vcl/syswin.hxx> 93 #include <vcl/taskpanelist.hxx> 94 95 //_________________________________________________________________________________________________________________ 96 // namespaces 97 //_________________________________________________________________________________________________________________ 98 99 using namespace ::com::sun::star; 100 using namespace ::com::sun::star::awt; 101 using namespace ::com::sun::star::beans; 102 using namespace ::com::sun::star::uno; 103 using namespace ::com::sun::star::lang; 104 using namespace ::com::sun::star::frame; 105 using namespace ::com::sun::star::util; 106 using namespace ::com::sun::star::container; 107 using namespace ::com::sun::star::frame; 108 using namespace ::com::sun::star::ui; 109 110 namespace framework 111 { 112 113 static const char TOOLBOXITEM_SEPARATOR_STR[] = "private:separator"; 114 static const sal_uInt16 TOOLBOXITEM_SEPARATOR_STR_LEN = sizeof( TOOLBOXITEM_SEPARATOR_STR )-1; 115 116 AddonsToolBarManager::AddonsToolBarManager( const Reference< XMultiServiceFactory >& rServiceManager, 117 const Reference< XFrame >& rFrame, 118 const rtl::OUString& rResourceName, 119 ToolBar* pToolBar ) : 120 ToolBarManager( rServiceManager, rFrame, rResourceName, pToolBar ) 121 { 122 // Configuration data is retrieved from non-writable configuration layer. Therefor we 123 // must disable some menu entries. 124 m_bCanBeCustomized = sal_False; 125 126 m_pToolBar->SetMenuType( TOOLBOX_MENUTYPE_CLIPPEDITEMS ); 127 m_pToolBar->SetSelectHdl( LINK( this, AddonsToolBarManager, Select) ); 128 m_pToolBar->SetActivateHdl( LINK( this, AddonsToolBarManager, Activate) ); 129 m_pToolBar->SetDeactivateHdl( LINK( this, AddonsToolBarManager, Deactivate) ); 130 m_pToolBar->SetClickHdl( LINK( this, AddonsToolBarManager, Click ) ); 131 m_pToolBar->SetDoubleClickHdl( LINK( this, AddonsToolBarManager, DoubleClick ) ); 132 m_pToolBar->SetCommandHdl( LINK( this, AddonsToolBarManager, Command ) ); 133 m_pToolBar->SetStateChangedHdl( LINK( this, AddonsToolBarManager, StateChanged ) ); 134 m_pToolBar->SetDataChangedHdl( LINK( this, AddonsToolBarManager, DataChanged ) ); 135 } 136 137 AddonsToolBarManager::~AddonsToolBarManager() 138 { 139 } 140 141 static sal_Bool IsCorrectContext( const ::rtl::OUString& rModuleIdentifier, const ::rtl::OUString& aContextList ) 142 { 143 if ( aContextList.getLength() == 0 ) 144 return sal_True; 145 146 if ( rModuleIdentifier.getLength() > 0 ) 147 { 148 sal_Int32 nIndex = aContextList.indexOf( rModuleIdentifier ); 149 return ( nIndex >= 0 ); 150 } 151 152 return sal_False; 153 } 154 155 static Image RetrieveImage( Reference< com::sun::star::frame::XFrame >& rFrame, 156 const rtl::OUString& aImageId, 157 const rtl::OUString& aURL, 158 sal_Bool bBigImage, 159 sal_Bool bHiContrast ) 160 { 161 Image aImage; 162 163 if ( aImageId.getLength() > 0 ) 164 { 165 aImage = framework::AddonsOptions().GetImageFromURL( aImageId, bBigImage, bHiContrast ); 166 if ( !!aImage ) 167 return aImage; 168 else 169 aImage = GetImageFromURL( rFrame, aImageId, bBigImage, bHiContrast ); 170 if ( !!aImage ) 171 return aImage; 172 } 173 174 aImage = framework::AddonsOptions().GetImageFromURL( aURL, bBigImage, bHiContrast ); 175 if ( !aImage ) 176 aImage = GetImageFromURL( rFrame, aImageId, bBigImage, bHiContrast ); 177 178 return aImage; 179 } 180 181 // XComponent 182 void SAL_CALL AddonsToolBarManager::dispose() throw( RuntimeException ) 183 { 184 Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY ); 185 186 { 187 // Remove addon specific data from toolbar items. 188 ResetableGuard aGuard( m_aLock ); 189 for ( sal_uInt16 n = 0; n < m_pToolBar->GetItemCount(); n++ ) 190 { 191 sal_uInt16 nId( m_pToolBar->GetItemId( n ) ); 192 193 if ( nId > 0 ) 194 { 195 AddonsParams* pRuntimeItemData = (AddonsParams*)m_pToolBar->GetItemData( nId ); 196 if ( pRuntimeItemData ) 197 delete pRuntimeItemData; 198 m_pToolBar->SetItemData( nId, NULL ); 199 } 200 } 201 } 202 203 // Base class will destroy our m_pToolBar member 204 ToolBarManager::dispose(); 205 } 206 207 bool AddonsToolBarManager::MenuItemAllowed( sal_uInt16 nId ) const 208 { 209 if (( nId == MENUITEM_TOOLBAR_VISIBLEBUTTON ) || 210 ( nId == MENUITEM_TOOLBAR_CUSTOMIZETOOLBAR )) 211 return false; 212 else 213 return true; 214 } 215 216 void AddonsToolBarManager::RefreshImages() 217 { 218 sal_Bool bBigImages( SvtMiscOptions().AreCurrentSymbolsLarge() ); 219 for ( sal_uInt16 nPos = 0; nPos < m_pToolBar->GetItemCount(); nPos++ ) 220 { 221 sal_uInt16 nId( m_pToolBar->GetItemId( nPos ) ); 222 223 if ( nId > 0 ) 224 { 225 ::rtl::OUString aCommandURL = m_pToolBar->GetItemCommand( nId ); 226 ::rtl::OUString aImageId; 227 AddonsParams* pRuntimeItemData = (AddonsParams*)m_pToolBar->GetItemData( nId ); 228 if ( pRuntimeItemData ) 229 aImageId = pRuntimeItemData->aImageId; 230 231 m_pToolBar->SetItemImage( nId, RetrieveImage( m_xFrame, 232 aImageId, 233 aCommandURL, 234 bBigImages, 235 m_bIsHiContrast )); 236 } 237 } 238 } 239 240 void AddonsToolBarManager::FillToolbar( const Sequence< Sequence< PropertyValue > >& rAddonToolbar ) 241 { 242 ResetableGuard aGuard( m_aLock ); 243 244 if ( m_bDisposed ) 245 return; 246 247 sal_uInt16 nId( 1 ); 248 249 RemoveControllers(); 250 251 m_pToolBar->Clear(); 252 m_aControllerMap.clear(); 253 254 ::rtl::OUString aModuleIdentifier; 255 try 256 { 257 Reference< XModuleManager > xModuleManager( 258 m_xServiceManager->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY_THROW ); 259 aModuleIdentifier = xModuleManager->identify( m_xFrame ); 260 } 261 catch ( Exception& ) 262 { 263 } 264 265 Reference< XMultiComponentFactory > xToolbarControllerFactory( m_xToolbarControllerRegistration, UNO_QUERY ); 266 Reference< XComponentContext > xComponentContext; 267 Reference< XPropertySet > xProps( m_xServiceManager, UNO_QUERY ); 268 269 if ( xProps.is() ) 270 xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= xComponentContext; 271 272 sal_uInt32 nElements( 0 ); 273 sal_Bool bAppendSeparator( sal_False ); 274 Reference< XWindow > xToolbarWindow = VCLUnoHelper::GetInterface( m_pToolBar ); 275 for ( sal_uInt32 n = 0; n < (sal_uInt32)rAddonToolbar.getLength(); n++ ) 276 { 277 rtl::OUString aValueName; 278 279 rtl::OUString aURL; 280 rtl::OUString aTitle; 281 rtl::OUString aImageId; 282 rtl::OUString aContext; 283 rtl::OUString aTarget; 284 rtl::OUString aControlType; 285 sal_uInt16 nWidth( 0 ); 286 287 const Sequence< PropertyValue >& rSeq = rAddonToolbar[n]; 288 289 ToolBarMerger::ConvertSequenceToValues( rSeq, aURL, aTitle, aImageId, aTarget, aContext, aControlType, nWidth ); 290 291 if ( IsCorrectContext( aModuleIdentifier, aContext )) 292 { 293 if ( aURL.equalsAsciiL( TOOLBOXITEM_SEPARATOR_STR, TOOLBOXITEM_SEPARATOR_STR_LEN )) 294 { 295 sal_uInt16 nCount = m_pToolBar->GetItemCount(); 296 if ( nCount > 0 && ( m_pToolBar->GetItemType( nCount-1 ) != TOOLBOXITEM_SEPARATOR ) && nElements > 0 ) 297 { 298 nElements = 0; 299 m_pToolBar->InsertSeparator(); 300 } 301 } 302 else 303 { 304 sal_uInt16 nCount = m_pToolBar->GetItemCount(); 305 if ( bAppendSeparator && nCount > 0 && ( m_pToolBar->GetItemType( nCount-1 ) != TOOLBOXITEM_SEPARATOR )) 306 { 307 // We have to append a separator first if the last item is not a separator 308 m_pToolBar->InsertSeparator(); 309 } 310 bAppendSeparator = sal_False; 311 312 m_pToolBar->InsertItem( nId, aTitle ); 313 314 Image aImage = RetrieveImage( m_xFrame, aImageId, aURL, !m_bSmallSymbols, m_bIsHiContrast ); 315 if ( !!aImage ) 316 m_pToolBar->SetItemImage( nId, aImage ); 317 318 // Create TbRuntimeItemData to hold additional information we will need in the future 319 AddonsParams* pRuntimeItemData = new AddonsParams; 320 pRuntimeItemData->aImageId = aImageId; 321 pRuntimeItemData->aTarget = aTarget; 322 m_pToolBar->SetItemData( nId, pRuntimeItemData ); 323 m_pToolBar->SetItemCommand( nId, aURL ); 324 325 Reference< XStatusListener > xController; 326 327 sal_Bool bMustBeInit( sal_True ); 328 329 // Support external toolbar controller for add-ons! 330 if ( m_xToolbarControllerRegistration.is() && 331 m_xToolbarControllerRegistration->hasController( aURL, m_aModuleIdentifier )) 332 { 333 if ( xToolbarControllerFactory.is() ) 334 { 335 Sequence< Any > aArgs(5); 336 PropertyValue aPropValue; 337 338 aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ModuleName" )); 339 aPropValue.Value <<= m_aModuleIdentifier; 340 aArgs[0] <<= aPropValue; 341 aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" )); 342 aPropValue.Value <<= m_xFrame; 343 aArgs[1] <<= aPropValue; 344 aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ServiceManager" )); 345 aPropValue.Value <<= m_xServiceManager; 346 aArgs[2] <<= aPropValue; 347 aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ParentWindow" )); 348 aPropValue.Value <<= xToolbarWindow; 349 aArgs[3] <<= aPropValue; 350 aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ItemId" )); 351 aPropValue.Value = makeAny( sal_Int32( nId )); 352 aArgs[4] <<= aPropValue; 353 354 try 355 { 356 xController = Reference< XStatusListener >( xToolbarControllerFactory->createInstanceWithArgumentsAndContext( 357 aURL, aArgs, xComponentContext ), 358 UNO_QUERY ); 359 } 360 catch ( uno::Exception& ) 361 { 362 } 363 bMustBeInit = sal_False; // factory called init already! 364 } 365 } 366 else 367 { 368 ::cppu::OWeakObject* pController = 0; 369 370 pController = ToolBarMerger::CreateController( m_xServiceManager, m_xFrame, m_pToolBar, aURL, nId, nWidth, aControlType ); 371 xController = Reference< XStatusListener >( pController, UNO_QUERY ); 372 } 373 374 // insert controller to the map 375 m_aControllerMap[nId] = xController; 376 377 Reference< XInitialization > xInit( xController, UNO_QUERY ); 378 if ( xInit.is() && bMustBeInit ) 379 { 380 PropertyValue aPropValue; 381 Sequence< Any > aArgs( 3 ); 382 aPropValue.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" )); 383 aPropValue.Value <<= m_xFrame; 384 aArgs[0] <<= aPropValue; 385 aPropValue.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CommandURL" )); 386 aPropValue.Value <<= aURL; 387 aArgs[1] <<= aPropValue; 388 aPropValue.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ServiceManager" )); 389 aPropValue.Value <<= m_xServiceManager; 390 aArgs[2] <<= aPropValue; 391 try 392 { 393 xInit->initialize( aArgs ); 394 } 395 catch ( uno::Exception& ) 396 { 397 } 398 } 399 400 // Request a item window from the toolbar controller and set it at the VCL toolbar 401 Reference< XToolbarController > xTbxController( xController, UNO_QUERY ); 402 if ( xTbxController.is() && xToolbarWindow.is() ) 403 { 404 Reference< XWindow > xWindow = xTbxController->createItemWindow( xToolbarWindow ); 405 if ( xWindow.is() ) 406 { 407 Window* pItemWin = VCLUnoHelper::GetWindow( xWindow ); 408 if ( pItemWin ) 409 { 410 WindowType nType = pItemWin->GetType(); 411 if ( nType == WINDOW_LISTBOX || nType == WINDOW_MULTILISTBOX || nType == WINDOW_COMBOBOX ) 412 pItemWin->SetAccessibleName( m_pToolBar->GetItemText( nId ) ); 413 m_pToolBar->SetItemWindow( nId, pItemWin ); 414 } 415 } 416 } 417 418 // Notify controller implementation to its listeners. Controller is now useable from outside. 419 Reference< XUpdatable > xUpdatable( xController, UNO_QUERY ); 420 if ( xUpdatable.is() ) 421 { 422 try 423 { 424 xUpdatable->update(); 425 } 426 catch ( uno::Exception& ) 427 { 428 } 429 } 430 431 ++nId; 432 ++nElements; 433 } 434 } 435 } 436 437 AddFrameActionListener(); 438 } 439 440 IMPL_LINK( AddonsToolBarManager, Click, ToolBox*, EMPTYARG ) 441 { 442 if ( m_bDisposed ) 443 return 1; 444 445 sal_uInt16 nId( m_pToolBar->GetCurItemId() ); 446 ToolBarControllerMap::const_iterator pIter = m_aControllerMap.find( nId ); 447 if ( pIter != m_aControllerMap.end() ) 448 { 449 Reference< XToolbarController > xController( pIter->second, UNO_QUERY ); 450 451 if ( xController.is() ) 452 xController->click(); 453 } 454 455 return 1; 456 } 457 458 IMPL_LINK( AddonsToolBarManager, DoubleClick, ToolBox*, EMPTYARG ) 459 { 460 if ( m_bDisposed ) 461 return 1; 462 463 sal_uInt16 nId( m_pToolBar->GetCurItemId() ); 464 ToolBarControllerMap::const_iterator pIter = m_aControllerMap.find( nId ); 465 if ( pIter != m_aControllerMap.end() ) 466 { 467 Reference< XToolbarController > xController( pIter->second, UNO_QUERY ); 468 469 if ( xController.is() ) 470 xController->doubleClick(); 471 } 472 473 return 1; 474 } 475 476 IMPL_LINK( AddonsToolBarManager, Command, CommandEvent*, EMPTYARG ) 477 { 478 ResetableGuard aGuard( m_aLock ); 479 480 if ( m_bDisposed ) 481 return 1; 482 483 return 0; 484 } 485 486 IMPL_LINK( AddonsToolBarManager, Select, ToolBox*, EMPTYARG ) 487 { 488 if ( m_bDisposed ) 489 return 1; 490 491 sal_Int16 nKeyModifier( (sal_Int16)m_pToolBar->GetModifier() ); 492 sal_uInt16 nId( m_pToolBar->GetCurItemId() ); 493 ToolBarControllerMap::const_iterator pIter = m_aControllerMap.find( nId ); 494 if ( pIter != m_aControllerMap.end() ) 495 { 496 Reference< XToolbarController > xController( pIter->second, UNO_QUERY ); 497 498 if ( xController.is() ) 499 xController->execute( nKeyModifier ); 500 } 501 502 return 1; 503 } 504 505 IMPL_LINK( AddonsToolBarManager, Highlight, ToolBox*, EMPTYARG ) 506 { 507 return 1; 508 } 509 510 IMPL_LINK( AddonsToolBarManager, Activate, ToolBox*, EMPTYARG ) 511 { 512 return 1; 513 } 514 515 IMPL_LINK( AddonsToolBarManager, Deactivate, ToolBox*, EMPTYARG ) 516 { 517 return 1; 518 } 519 520 IMPL_LINK( AddonsToolBarManager, StateChanged, StateChangedType*, pStateChangedType ) 521 { 522 if ( *pStateChangedType == STATE_CHANGE_CONTROLBACKGROUND ) 523 { 524 // Check if we need to get new images for normal/high contrast mode 525 CheckAndUpdateImages(); 526 } 527 return 1; 528 } 529 530 IMPL_LINK( AddonsToolBarManager, DataChanged, DataChangedEvent*, pDataChangedEvent ) 531 { 532 if ((( pDataChangedEvent->GetType() == DATACHANGED_SETTINGS ) || 533 ( pDataChangedEvent->GetType() == DATACHANGED_DISPLAY )) && 534 ( pDataChangedEvent->GetFlags() & SETTINGS_STYLE )) 535 { 536 // Check if we need to get new images for normal/high contrast mode 537 CheckAndUpdateImages(); 538 } 539 540 for ( sal_uInt16 nPos = 0; nPos < m_pToolBar->GetItemCount(); ++nPos ) 541 { 542 const sal_uInt16 nId = m_pToolBar->GetItemId(nPos); 543 Window* pWindow = m_pToolBar->GetItemWindow( nId ); 544 if ( pWindow ) 545 { 546 const DataChangedEvent& rDCEvt( *pDataChangedEvent ); 547 pWindow->DataChanged( rDCEvt ); 548 } 549 } 550 551 return 1; 552 } 553 554 } 555 556