1 /************************************************************************* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * Copyright 2000, 2010 Oracle and/or its affiliates. 5 * 6 * OpenOffice.org - a multi-platform office productivity suite 7 * 8 * This file is part of OpenOffice.org. 9 * 10 * OpenOffice.org is free software: you can redistribute it and/or modify 11 * it under the terms of the GNU Lesser General Public License version 3 12 * only, as published by the Free Software Foundation. 13 * 14 * OpenOffice.org is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU Lesser General Public License version 3 for more details 18 * (a copy is included in the LICENSE file that accompanied this code). 19 * 20 * You should have received a copy of the GNU Lesser General Public License 21 * version 3 along with OpenOffice.org. If not, see 22 * <http://www.openoffice.org/license.html> 23 * for a copy of the LGPLv3 License. 24 * 25 ************************************************************************/ 26 27 #include "precompiled_sfx2.hxx" 28 29 #include "sfx2/taskpane.hxx" 30 #include "imagemgr.hxx" 31 #include "sfx2/sfxsids.hrc" 32 #include "sfx2/bindings.hxx" 33 #include "sfx2/dispatch.hxx" 34 #include "sfxresid.hxx" 35 #include "sfxlocal.hrc" 36 #include "helpid.hrc" 37 38 /** === begin UNO includes === **/ 39 #include <com/sun/star/frame/XModuleManager.hpp> 40 #include <com/sun/star/container/XNameAccess.hpp> 41 #include <com/sun/star/ui/XToolPanel.hpp> 42 #include <com/sun/star/ui/XUIElementFactory.hpp> 43 #include <com/sun/star/awt/XWindowPeer.hpp> 44 #include <com/sun/star/awt/PosSize.hpp> 45 #include <com/sun/star/frame/XModuleManager.hpp> 46 #include <com/sun/star/graphic/XGraphicProvider.hpp> 47 #include <com/sun/star/accessibility/XAccessible.hpp> 48 #include <com/sun/star/awt/XControl.hpp> 49 /** === end UNO includes === **/ 50 51 #include <comphelper/componentcontext.hxx> 52 #include <comphelper/namedvaluecollection.hxx> 53 #include <comphelper/types.hxx> 54 #include <comphelper/processfactory.hxx> 55 #include <tools/diagnose_ex.h> 56 #include <svtools/toolpanel/toolpaneldeck.hxx> 57 #include <svtools/toolpanel/tablayouter.hxx> 58 #include <svtools/toolpanel/drawerlayouter.hxx> 59 #include <unotools/confignode.hxx> 60 #include <vcl/menu.hxx> 61 #include <vcl/svapp.hxx> 62 #include <toolkit/helper/vclunohelper.hxx> 63 #include <tools/urlobj.hxx> 64 #include <boost/noncopyable.hpp> 65 66 //...................................................................................................................... 67 namespace sfx2 68 { 69 //...................................................................................................................... 70 71 /** === begin UNO using === **/ 72 using ::com::sun::star::uno::Reference; 73 using ::com::sun::star::uno::XInterface; 74 using ::com::sun::star::uno::UNO_QUERY; 75 using ::com::sun::star::uno::UNO_QUERY_THROW; 76 using ::com::sun::star::uno::UNO_SET_THROW; 77 using ::com::sun::star::uno::Exception; 78 using ::com::sun::star::uno::RuntimeException; 79 using ::com::sun::star::uno::Any; 80 using ::com::sun::star::uno::makeAny; 81 using ::com::sun::star::uno::Sequence; 82 using ::com::sun::star::uno::Type; 83 using ::com::sun::star::frame::XModuleManager; 84 using ::com::sun::star::container::XNameAccess; 85 using ::com::sun::star::ui::XToolPanel; 86 using ::com::sun::star::ui::XUIElementFactory; 87 using ::com::sun::star::ui::XUIElement; 88 using ::com::sun::star::awt::XWindow; 89 using ::com::sun::star::frame::XModuleManager; 90 using ::com::sun::star::frame::XFrame; 91 using ::com::sun::star::lang::XComponent; 92 using ::com::sun::star::graphic::XGraphicProvider; 93 using ::com::sun::star::graphic::XGraphic; 94 using ::com::sun::star::accessibility::XAccessible; 95 using ::com::sun::star::awt::XControl; 96 /** === end UNO using === **/ 97 namespace PosSize = ::com::sun::star::awt::PosSize; 98 99 //================================================================================================================== 100 //= helpers 101 //================================================================================================================== 102 namespace 103 { 104 //-------------------------------------------------------------------------------------------------------------- 105 ::utl::OConfigurationTreeRoot lcl_getModuleUIElementStatesConfig( const ::rtl::OUString& i_rModuleIdentifier, 106 const ::rtl::OUString& i_rResourceURL = ::rtl::OUString() ) 107 { 108 const ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() ); 109 ::rtl::OUStringBuffer aPathComposer; 110 try 111 { 112 const Reference< XNameAccess > xModuleAccess( aContext.createComponent( "com.sun.star.frame.ModuleManager" ), UNO_QUERY_THROW ); 113 const ::comphelper::NamedValueCollection aModuleProps( xModuleAccess->getByName( i_rModuleIdentifier ) ); 114 115 const ::rtl::OUString sWindowStateRef( aModuleProps.getOrDefault( "ooSetupFactoryWindowStateConfigRef", ::rtl::OUString() ) ); 116 117 aPathComposer.appendAscii( "org.openoffice.Office.UI." ); 118 aPathComposer.append( sWindowStateRef ); 119 aPathComposer.appendAscii( "/UIElements/States" ); 120 if ( i_rResourceURL.getLength() ) 121 { 122 aPathComposer.appendAscii( "/" ); 123 aPathComposer.append( i_rResourceURL ); 124 } 125 } 126 catch( const Exception& ) 127 { 128 DBG_UNHANDLED_EXCEPTION(); 129 } 130 return ::utl::OConfigurationTreeRoot( aContext, aPathComposer.makeStringAndClear(), false ); 131 } 132 133 //-------------------------------------------------------------------------------------------------------------- 134 ::rtl::OUString lcl_identifyModule( const Reference< XFrame >& i_rDocumentFrame ) 135 { 136 ::rtl::OUString sModuleName; 137 try 138 { 139 const ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() ); 140 const Reference< XModuleManager > xModuleManager( aContext.createComponent( "com.sun.star.frame.ModuleManager" ), UNO_QUERY_THROW ); 141 sModuleName = xModuleManager->identify( i_rDocumentFrame ); 142 } 143 catch( const Exception& ) 144 { 145 DBG_UNHANDLED_EXCEPTION(); 146 } 147 return sModuleName; 148 } 149 150 //-------------------------------------------------------------------------------------------------------------- 151 Reference< XFrame > lcl_getFrame( const SfxBindings* i_pBindings ) 152 { 153 const SfxViewFrame* pViewFrame = i_pBindings->GetDispatcher()->GetFrame(); 154 const SfxFrame& rFrame = pViewFrame->GetFrame(); 155 const Reference< XFrame > xFrame( rFrame.GetFrameInterface() ); 156 return xFrame; 157 } 158 159 //-------------------------------------------------------------------------------------------------------------- 160 ::rtl::OUString lcl_getPanelHelpURL( const ::utl::OConfigurationNode& i_rPanelConfigNode ) 161 { 162 const ::rtl::OUString sHelpURL( ::comphelper::getString( i_rPanelConfigNode.getNodeValue( "HelpURL" ) ) ); 163 return sHelpURL; 164 } 165 166 //-------------------------------------------------------------------------------------------------------------- 167 Image lcl_getPanelImage( const Reference< XFrame >& i_rDocFrame, const ::utl::OConfigurationNode& i_rPanelConfigNode ) 168 { 169 const ::rtl::OUString sImageURL( ::comphelper::getString( i_rPanelConfigNode.getNodeValue( "ImageURL" ) ) ); 170 if ( sImageURL.getLength() ) 171 { 172 try 173 { 174 ::comphelper::NamedValueCollection aMediaProperties; 175 aMediaProperties.put( "URL", sImageURL ); 176 177 // special handling: if the ImageURL denotes a CommandName, then retrieve the image for that command 178 const sal_Char* pCommandImagePrefix = "private:commandimage/"; 179 const sal_Int32 nCommandImagePrefixLen = strlen( pCommandImagePrefix ); 180 if ( sImageURL.compareToAscii( pCommandImagePrefix, nCommandImagePrefixLen ) == 0 ) 181 { 182 ::rtl::OUStringBuffer aCommandName; 183 aCommandName.appendAscii( ".uno:" ); 184 aCommandName.append( sImageURL.copy( nCommandImagePrefixLen ) ); 185 const ::rtl::OUString sCommandName( aCommandName.makeStringAndClear() ); 186 187 const sal_Bool bHiContrast( Application::GetSettings().GetStyleSettings().GetHighContrastMode() ); 188 const Image aPanelImage( GetImage( i_rDocFrame, sCommandName, sal_False, bHiContrast ) ); 189 return aPanelImage.GetXGraphic(); 190 } 191 192 // otherwise, delegate to the GraphicProvider 193 const ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() ); 194 const Reference< XGraphicProvider > xGraphicProvider( aContext.createComponent( "com.sun.star.graphic.GraphicProvider" ), UNO_QUERY_THROW ); 195 196 const Reference< XGraphic > xGraphic( xGraphicProvider->queryGraphic( aMediaProperties.getPropertyValues() ), UNO_SET_THROW ); 197 return Image( xGraphic ); 198 } 199 catch( const Exception& ) 200 { 201 DBG_UNHANDLED_EXCEPTION(); 202 } 203 } 204 return Image(); 205 } 206 } 207 208 //================================================================================================================== 209 //= TaskPaneDockingWindow 210 //================================================================================================================== 211 //------------------------------------------------------------------------------------------------------------------ 212 TaskPaneDockingWindow::TaskPaneDockingWindow( SfxBindings* i_pBindings, TaskPaneWrapper& i_rWrapper, Window* i_pParent, WinBits i_nBits ) 213 :TitledDockingWindow( i_pBindings, &i_rWrapper, i_pParent, i_nBits ) 214 ,m_aTaskPane( GetContentWindow(), lcl_getFrame( i_pBindings ) ) 215 ,m_aPaneController( m_aTaskPane, *this ) 216 { 217 m_aTaskPane.Show(); 218 SetText( String( SfxResId( SID_TASKPANE ) ) ); 219 } 220 221 //------------------------------------------------------------------------------------------------------------------ 222 void TaskPaneDockingWindow::ActivateToolPanel( const ::rtl::OUString& i_rPanelURL ) 223 { 224 m_aPaneController.ActivateToolPanel( i_rPanelURL ); 225 } 226 227 //------------------------------------------------------------------------------------------------------------------ 228 void TaskPaneDockingWindow::GetFocus() 229 { 230 TitledDockingWindow::GetFocus(); 231 m_aTaskPane.GrabFocus(); 232 } 233 234 //------------------------------------------------------------------------------------------------------------------ 235 void TaskPaneDockingWindow::onLayoutDone() 236 { 237 m_aTaskPane.SetPosSizePixel( Point(), GetContentWindow().GetOutputSizePixel() ); 238 } 239 240 //================================================================================================================== 241 //= TaskPaneWrapper 242 //================================================================================================================== 243 //------------------------------------------------------------------------------------------------------------------ 244 SFX_IMPL_DOCKINGWINDOW( TaskPaneWrapper, SID_TASKPANE ); 245 246 //------------------------------------------------------------------------------------------------------------------ 247 TaskPaneWrapper::TaskPaneWrapper( Window* i_pParent, sal_uInt16 i_nId, SfxBindings* i_pBindings, SfxChildWinInfo* i_pInfo ) 248 :SfxChildWindow( i_pParent, i_nId ) 249 { 250 pWindow = new TaskPaneDockingWindow( i_pBindings, *this, i_pParent, 251 WB_STDDOCKWIN | WB_CLIPCHILDREN | WB_SIZEABLE | WB_3DLOOK | WB_ROLLABLE); 252 eChildAlignment = SFX_ALIGN_RIGHT; 253 254 pWindow->SetHelpId( HID_TASKPANE_WINDOW ); 255 pWindow->SetOutputSizePixel( Size( 300, 450 ) ); 256 257 dynamic_cast< SfxDockingWindow* >( pWindow )->Initialize( i_pInfo ); 258 SetHideNotDelete( sal_True ); 259 260 pWindow->Show(); 261 } 262 263 //------------------------------------------------------------------------------------------------------------------ 264 void TaskPaneWrapper::ActivateToolPanel( const ::rtl::OUString& i_rPanelURL ) 265 { 266 TaskPaneDockingWindow* pDockingWindow = dynamic_cast< TaskPaneDockingWindow* >( GetWindow() ); 267 ENSURE_OR_RETURN_VOID( pDockingWindow, "TaskPaneWrapper::ActivateToolPanel: invalid docking window implementation!" ); 268 pDockingWindow->ActivateToolPanel( i_rPanelURL ); 269 } 270 271 //================================================================================================================== 272 //= CustomPanelUIElement 273 //================================================================================================================== 274 class CustomPanelUIElement 275 { 276 public: 277 CustomPanelUIElement() 278 :m_xUIElement() 279 ,m_xToolPanel() 280 ,m_xPanelWindow() 281 { 282 } 283 284 CustomPanelUIElement( const Reference< XUIElement >& i_rUIElement ) 285 :m_xUIElement( i_rUIElement, UNO_SET_THROW ) 286 ,m_xToolPanel( i_rUIElement->getRealInterface(), UNO_QUERY_THROW ) 287 ,m_xPanelWindow( m_xToolPanel->getWindow(), UNO_SET_THROW ) 288 { 289 } 290 291 bool is() const { return m_xPanelWindow.is(); } 292 293 const Reference< XUIElement >& getUIElement() const { return m_xUIElement; } 294 const Reference< XToolPanel >& getToolPanel() const { return m_xToolPanel; } 295 const Reference< XWindow >& getPanelWindow() const { return m_xPanelWindow; } 296 297 private: 298 Reference< XUIElement > m_xUIElement; 299 Reference< XToolPanel > m_xToolPanel; 300 Reference< XWindow > m_xPanelWindow; 301 }; 302 303 //================================================================================================================== 304 //= CustomToolPanel 305 //================================================================================================================== 306 class CustomToolPanel : public ::svt::ToolPanelBase 307 { 308 public: 309 CustomToolPanel( const ::utl::OConfigurationNode& i_rPanelWindowState, const Reference< XFrame >& i_rFrame ); 310 311 virtual ::rtl::OUString GetDisplayName() const; 312 virtual Image GetImage() const; 313 virtual rtl::OString GetHelpID() const; 314 virtual void Activate( Window& i_rParentWindow ); 315 virtual void Deactivate(); 316 virtual void SetSizePixel( const Size& i_rPanelWindowSize ); 317 virtual void GrabFocus(); 318 virtual void Dispose(); 319 virtual Reference< XAccessible > 320 CreatePanelAccessible( const Reference< XAccessible >& i_rParentAccessible ); 321 322 const ::rtl::OUString& 323 GetResourceURL() const { return m_sResourceURL; } 324 325 protected: 326 ~CustomToolPanel(); 327 328 private: 329 bool impl_ensureToolPanelWindow( Window& i_rPanelParentWindow ); 330 void impl_updatePanelConfig( const bool i_bVisible ) const; 331 332 private: 333 const ::rtl::OUString m_sUIName; 334 const Image m_aPanelImage; 335 const ::rtl::OUString m_aPanelHelpURL; 336 const ::rtl::OUString m_sResourceURL; 337 const ::rtl::OUString m_sPanelConfigPath; 338 Reference< XFrame > m_xFrame; 339 CustomPanelUIElement m_aCustomPanel; 340 bool m_bAttemptedCreation; 341 }; 342 343 //------------------------------------------------------------------------------------------------------------------ 344 CustomToolPanel::CustomToolPanel( const ::utl::OConfigurationNode& i_rPanelWindowState, const Reference< XFrame >& i_rFrame ) 345 :m_sUIName( ::comphelper::getString( i_rPanelWindowState.getNodeValue( "UIName" ) ) ) 346 ,m_aPanelImage( lcl_getPanelImage( i_rFrame, i_rPanelWindowState ) ) 347 ,m_aPanelHelpURL( lcl_getPanelHelpURL( i_rPanelWindowState ) ) 348 ,m_sResourceURL( i_rPanelWindowState.getLocalName() ) 349 ,m_sPanelConfigPath( i_rPanelWindowState.getNodePath() ) 350 ,m_xFrame( i_rFrame ) 351 ,m_aCustomPanel() 352 ,m_bAttemptedCreation( false ) 353 { 354 } 355 356 //------------------------------------------------------------------------------------------------------------------ 357 CustomToolPanel::~CustomToolPanel() 358 { 359 } 360 361 //------------------------------------------------------------------------------------------------------------------ 362 bool CustomToolPanel::impl_ensureToolPanelWindow( Window& i_rPanelParentWindow ) 363 { 364 if ( m_bAttemptedCreation ) 365 return m_aCustomPanel.is(); 366 367 m_bAttemptedCreation = true; 368 try 369 { 370 const ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() ); 371 const Reference< XUIElementFactory > xFactory( aContext.createComponent( "com.sun.star.ui.UIElementFactoryManager" ), UNO_QUERY_THROW ); 372 373 ::comphelper::NamedValueCollection aCreationArgs; 374 aCreationArgs.put( "Frame", makeAny( m_xFrame ) ); 375 aCreationArgs.put( "ParentWindow", makeAny( i_rPanelParentWindow.GetComponentInterface() ) ); 376 377 const Reference< XUIElement > xElement( 378 xFactory->createUIElement( m_sResourceURL, aCreationArgs.getPropertyValues() ), 379 UNO_SET_THROW ); 380 381 m_aCustomPanel = CustomPanelUIElement( xElement ); 382 } 383 catch( const Exception& ) 384 { 385 DBG_UNHANDLED_EXCEPTION(); 386 } 387 return m_aCustomPanel.is(); 388 } 389 390 //------------------------------------------------------------------------------------------------------------------ 391 void CustomToolPanel::impl_updatePanelConfig( const bool i_bVisible ) const 392 { 393 ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() ); 394 ::utl::OConfigurationTreeRoot aConfig( aContext, m_sPanelConfigPath, true ); 395 396 aConfig.setNodeValue( "Visible", makeAny( i_bVisible ) ); 397 aConfig.commit(); 398 } 399 400 //------------------------------------------------------------------------------------------------------------------ 401 ::rtl::OUString CustomToolPanel::GetDisplayName() const 402 { 403 return m_sUIName; 404 } 405 406 //------------------------------------------------------------------------------------------------------------------ 407 Image CustomToolPanel::GetImage() const 408 { 409 return m_aPanelImage; 410 } 411 412 static rtl::OString lcl_getHelpId( const ::rtl::OUString& _rHelpURL ) 413 { 414 INetURLObject aHID( _rHelpURL ); 415 if ( aHID.GetProtocol() == INET_PROT_HID ) 416 return rtl::OUStringToOString( aHID.GetURLPath(), RTL_TEXTENCODING_UTF8 ); 417 else 418 return rtl::OUStringToOString( _rHelpURL, RTL_TEXTENCODING_UTF8 ); 419 } 420 421 //------------------------------------------------------------------------------------------------------------------ 422 rtl::OString CustomToolPanel::GetHelpID() const 423 { 424 return lcl_getHelpId( m_aPanelHelpURL ); 425 } 426 427 //------------------------------------------------------------------------------------------------------------------ 428 void CustomToolPanel::Activate( Window& i_rParentWindow ) 429 { 430 ENSURE_OR_RETURN_VOID( impl_ensureToolPanelWindow( i_rParentWindow ), "no panel to activate!" ); 431 432 // TODO: we might need a mechanism to decide whether the panel should be destroyed/re-created, or (as it is 433 // done now) hidden/shown 434 m_aCustomPanel.getPanelWindow()->setVisible( sal_True ); 435 436 // update the panel's configuration 437 impl_updatePanelConfig( true ); 438 } 439 440 //------------------------------------------------------------------------------------------------------------------ 441 void CustomToolPanel::Deactivate() 442 { 443 ENSURE_OR_RETURN_VOID( m_aCustomPanel.is(), "no panel to deactivate!" ); 444 445 m_aCustomPanel.getPanelWindow()->setVisible( sal_False ); 446 447 // update the panel's configuration 448 impl_updatePanelConfig( false ); 449 } 450 451 //------------------------------------------------------------------------------------------------------------------ 452 void CustomToolPanel::SetSizePixel( const Size& i_rPanelWindowSize ) 453 { 454 ENSURE_OR_RETURN_VOID( m_aCustomPanel.is(), "no panel/window to position!" ); 455 456 try 457 { 458 m_aCustomPanel.getPanelWindow()->setPosSize( 0, 0, i_rPanelWindowSize.Width(), i_rPanelWindowSize.Height(), 459 PosSize::POSSIZE ); 460 } 461 catch( const Exception& ) 462 { 463 DBG_UNHANDLED_EXCEPTION(); 464 } 465 } 466 467 //------------------------------------------------------------------------------------------------------------------ 468 void CustomToolPanel::GrabFocus() 469 { 470 ENSURE_OR_RETURN_VOID( m_aCustomPanel.is(), "no panel/window to focus!" ); 471 472 m_aCustomPanel.getPanelWindow()->setFocus(); 473 } 474 475 //------------------------------------------------------------------------------------------------------------------ 476 void CustomToolPanel::Dispose() 477 { 478 if ( !m_bAttemptedCreation ) 479 // nothing to dispose 480 return; 481 482 ENSURE_OR_RETURN_VOID( m_aCustomPanel.is(), "no panel to destroy!" ); 483 try 484 { 485 Reference< XComponent > xUIElementComponent( m_aCustomPanel.getUIElement(), UNO_QUERY_THROW ); 486 xUIElementComponent->dispose(); 487 } 488 catch( const Exception& ) 489 { 490 DBG_UNHANDLED_EXCEPTION(); 491 } 492 } 493 494 //------------------------------------------------------------------------------------------------------------------ 495 Reference< XAccessible > CustomToolPanel::CreatePanelAccessible( const Reference< XAccessible >& i_rParentAccessible ) 496 { 497 ENSURE_OR_RETURN( m_aCustomPanel.is(), "no panel to ask!", NULL ); 498 499 Reference< XAccessible > xPanelAccessible; 500 try 501 { 502 xPanelAccessible.set( m_aCustomPanel.getToolPanel()->createAccessible( i_rParentAccessible ), UNO_SET_THROW ); 503 } 504 catch( const Exception& ) 505 { 506 DBG_UNHANDLED_EXCEPTION(); 507 } 508 return xPanelAccessible; 509 } 510 511 //================================================================================================================== 512 //= ModuleTaskPane_Impl 513 //================================================================================================================== 514 class ModuleTaskPane_Impl : public ::boost::noncopyable 515 { 516 public: 517 ModuleTaskPane_Impl( ModuleTaskPane& i_rAntiImpl, const Reference< XFrame >& i_rDocumentFrame, 518 const IToolPanelCompare* i_pPanelCompare ) 519 :m_rAntiImpl( i_rAntiImpl ) 520 ,m_sModuleIdentifier( lcl_identifyModule( i_rDocumentFrame ) ) 521 ,m_xFrame( i_rDocumentFrame ) 522 ,m_aPanelDeck( i_rAntiImpl ) 523 { 524 m_aPanelDeck.Show(); 525 OnResize(); 526 impl_initFromConfiguration( i_pPanelCompare ); 527 } 528 529 ~ModuleTaskPane_Impl() 530 { 531 } 532 533 void OnResize(); 534 void OnGetFocus(); 535 536 static bool ModuleHasToolPanels( const ::rtl::OUString& i_rModuleIdentifier ); 537 538 ::svt::ToolPanelDeck& GetPanelDeck() { return m_aPanelDeck; } 539 const ::svt::ToolPanelDeck& GetPanelDeck() const { return m_aPanelDeck; } 540 541 ::boost::optional< size_t > 542 GetPanelPos( const ::rtl::OUString& i_rResourceURL ); 543 ::rtl::OUString 544 GetPanelResourceURL( const size_t i_nPanelPos ) const; 545 546 void SetDrawersLayout(); 547 void SetTabsLayout( const ::svt::TabAlignment i_eTabAlignment, const ::svt::TabItemContent i_eTabContent ); 548 549 private: 550 void impl_initFromConfiguration( const IToolPanelCompare* i_pPanelCompare ); 551 552 static bool 553 impl_isToolPanelResource( const ::rtl::OUString& i_rResourceURL ); 554 555 DECL_LINK( OnActivatePanel, void* ); 556 557 private: 558 ModuleTaskPane& m_rAntiImpl; 559 const ::rtl::OUString m_sModuleIdentifier; 560 const Reference< XFrame > m_xFrame; 561 ::svt::ToolPanelDeck m_aPanelDeck; 562 }; 563 564 //------------------------------------------------------------------------------------------------------------------ 565 void ModuleTaskPane_Impl::OnResize() 566 { 567 m_aPanelDeck.SetPosSizePixel( Point(), m_rAntiImpl.GetOutputSizePixel() ); 568 } 569 570 //------------------------------------------------------------------------------------------------------------------ 571 void ModuleTaskPane_Impl::OnGetFocus() 572 { 573 m_aPanelDeck.GrabFocus(); 574 } 575 576 //------------------------------------------------------------------------------------------------------------------ 577 IMPL_LINK( ModuleTaskPane_Impl, OnActivatePanel, void*, i_pArg ) 578 { 579 m_aPanelDeck.ActivatePanel( reinterpret_cast< size_t >( i_pArg ) ); 580 return 1L; 581 } 582 583 //------------------------------------------------------------------------------------------------------------------ 584 bool ModuleTaskPane_Impl::impl_isToolPanelResource( const ::rtl::OUString& i_rResourceURL ) 585 { 586 return i_rResourceURL.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "private:resource/toolpanel/" ) ); 587 } 588 589 //------------------------------------------------------------------------------------------------------------------ 590 void ModuleTaskPane_Impl::impl_initFromConfiguration( const IToolPanelCompare* i_pPanelCompare ) 591 { 592 const ::utl::OConfigurationTreeRoot aWindowStateConfig( lcl_getModuleUIElementStatesConfig( m_sModuleIdentifier ) ); 593 if ( !aWindowStateConfig.isValid() ) 594 return; 595 596 ::rtl::OUString sFirstVisiblePanelResource; 597 ::rtl::OUString sFirstPanelResource; 598 599 const Sequence< ::rtl::OUString > aUIElements( aWindowStateConfig.getNodeNames() ); 600 for ( const ::rtl::OUString* resource = aUIElements.getConstArray(); 601 resource != aUIElements.getConstArray() + aUIElements.getLength(); 602 ++resource 603 ) 604 { 605 if ( !impl_isToolPanelResource( *resource ) ) 606 continue; 607 608 sFirstPanelResource = *resource; 609 610 ::utl::OConfigurationNode aResourceNode( aWindowStateConfig.openNode( *resource ) ); 611 ::svt::PToolPanel pCustomPanel( new CustomToolPanel( aResourceNode, m_xFrame ) ); 612 613 size_t nPanelPos = m_aPanelDeck.GetPanelCount(); 614 if ( i_pPanelCompare ) 615 { 616 // assuming that nobody will insert hundreths of panels, a simple O(n) search should suffice here ... 617 while ( nPanelPos > 0 ) 618 { 619 const short nCompare = i_pPanelCompare->compareToolPanelsURLs( 620 *resource, 621 GetPanelResourceURL( --nPanelPos ) 622 ); 623 if ( nCompare >= 0 ) 624 { 625 ++nPanelPos; 626 break; 627 } 628 } 629 } 630 nPanelPos = m_aPanelDeck.InsertPanel( pCustomPanel, nPanelPos ); 631 632 if ( ::comphelper::getBOOL( aResourceNode.getNodeValue( "Visible" ) ) ) 633 sFirstVisiblePanelResource = *resource; 634 } 635 636 if ( sFirstVisiblePanelResource.getLength() == 0 ) 637 sFirstVisiblePanelResource = sFirstPanelResource; 638 639 if ( sFirstVisiblePanelResource.getLength() ) 640 { 641 ::boost::optional< size_t > aPanelPos( GetPanelPos( sFirstVisiblePanelResource ) ); 642 OSL_ENSURE( !!aPanelPos, "ModuleTaskPane_Impl::impl_isToolPanelResource: just inserted it, and it's not there?!" ); 643 if ( !!aPanelPos ) 644 m_rAntiImpl.PostUserEvent( LINK( this, ModuleTaskPane_Impl, OnActivatePanel ), reinterpret_cast< void* >( *aPanelPos ) ); 645 } 646 } 647 648 //------------------------------------------------------------------------------------------------------------------ 649 bool ModuleTaskPane_Impl::ModuleHasToolPanels( const ::rtl::OUString& i_rModuleIdentifier ) 650 { 651 const ::utl::OConfigurationTreeRoot aWindowStateConfig( lcl_getModuleUIElementStatesConfig( i_rModuleIdentifier ) ); 652 if ( !aWindowStateConfig.isValid() ) 653 return false; 654 655 const Sequence< ::rtl::OUString > aUIElements( aWindowStateConfig.getNodeNames() ); 656 for ( const ::rtl::OUString* resource = aUIElements.getConstArray(); 657 resource != aUIElements.getConstArray() + aUIElements.getLength(); 658 ++resource 659 ) 660 { 661 if ( impl_isToolPanelResource( *resource ) ) 662 return true; 663 } 664 return false; 665 } 666 667 //------------------------------------------------------------------------------------------------------------------ 668 ::boost::optional< size_t > ModuleTaskPane_Impl::GetPanelPos( const ::rtl::OUString& i_rResourceURL ) 669 { 670 ::boost::optional< size_t > aPanelPos; 671 for ( size_t i = 0; i < m_aPanelDeck.GetPanelCount(); ++i ) 672 { 673 const ::svt::PToolPanel pPanel( m_aPanelDeck.GetPanel( i ) ); 674 const CustomToolPanel* pCustomPanel = dynamic_cast< const CustomToolPanel* >( pPanel.get() ); 675 ENSURE_OR_CONTINUE( pCustomPanel != NULL, "ModuleTaskPane_Impl::GetPanelPos: illegal panel implementation!" ); 676 if ( pCustomPanel->GetResourceURL() == i_rResourceURL ) 677 { 678 aPanelPos = i; 679 break; 680 } 681 } 682 return aPanelPos; 683 } 684 685 //------------------------------------------------------------------------------------------------------------------ 686 ::rtl::OUString ModuleTaskPane_Impl::GetPanelResourceURL( const size_t i_nPanelPos ) const 687 { 688 ENSURE_OR_RETURN( i_nPanelPos < m_aPanelDeck.GetPanelCount(), "ModuleTaskPane_Impl::GetPanelResourceURL: illegal panel position!", ::rtl::OUString() ); 689 const ::svt::PToolPanel pPanel( m_aPanelDeck.GetPanel( i_nPanelPos ) ); 690 const CustomToolPanel* pCustomPanel = dynamic_cast< const CustomToolPanel* >( pPanel.get() ); 691 ENSURE_OR_RETURN( pCustomPanel != NULL, "ModuleTaskPane_Impl::GetPanelPos: illegal panel implementation!", ::rtl::OUString() ); 692 return pCustomPanel->GetResourceURL(); 693 } 694 695 //------------------------------------------------------------------------------------------------------------------ 696 void ModuleTaskPane_Impl::SetDrawersLayout() 697 { 698 const ::svt::PDeckLayouter pLayouter( m_aPanelDeck.GetLayouter() ); 699 const ::svt::DrawerDeckLayouter* pDrawerLayouter = dynamic_cast< const ::svt::DrawerDeckLayouter* >( pLayouter.get() ); 700 if ( pDrawerLayouter != NULL ) 701 // already have the proper layout 702 return; 703 m_aPanelDeck.SetLayouter( new ::svt::DrawerDeckLayouter( m_aPanelDeck, m_aPanelDeck ) ); 704 } 705 706 //------------------------------------------------------------------------------------------------------------------ 707 void ModuleTaskPane_Impl::SetTabsLayout( const ::svt::TabAlignment i_eTabAlignment, const ::svt::TabItemContent i_eTabContent ) 708 { 709 ::svt::PDeckLayouter pLayouter( m_aPanelDeck.GetLayouter() ); 710 ::svt::TabDeckLayouter* pTabLayouter = dynamic_cast< ::svt::TabDeckLayouter* >( pLayouter.get() ); 711 if ( ( pTabLayouter != NULL ) 712 && ( pTabLayouter->GetTabAlignment() == i_eTabAlignment ) 713 && ( pTabLayouter->GetTabItemContent() == i_eTabContent ) 714 ) 715 // already have the requested layout 716 return; 717 718 if ( pTabLayouter && ( pTabLayouter->GetTabAlignment() == i_eTabAlignment ) ) 719 { 720 // changing only the item content does not require a new layouter instance 721 pTabLayouter->SetTabItemContent( i_eTabContent ); 722 return; 723 } 724 725 m_aPanelDeck.SetLayouter( new ::svt::TabDeckLayouter( m_aPanelDeck, m_aPanelDeck, i_eTabAlignment, i_eTabContent ) ); 726 } 727 728 //================================================================================================================== 729 //= ModuleTaskPane 730 //================================================================================================================== 731 //------------------------------------------------------------------------------------------------------------------ 732 ModuleTaskPane::ModuleTaskPane( Window& i_rParentWindow, const Reference< XFrame >& i_rDocumentFrame ) 733 :Window( &i_rParentWindow, WB_DIALOGCONTROL ) 734 ,m_pImpl( new ModuleTaskPane_Impl( *this, i_rDocumentFrame, NULL ) ) 735 { 736 } 737 738 //------------------------------------------------------------------------------------------------------------------ 739 ModuleTaskPane::ModuleTaskPane( Window& i_rParentWindow, const Reference< XFrame >& i_rDocumentFrame, 740 const IToolPanelCompare& i_rCompare ) 741 :Window( &i_rParentWindow, WB_DIALOGCONTROL ) 742 ,m_pImpl( new ModuleTaskPane_Impl( *this, i_rDocumentFrame, &i_rCompare ) ) 743 { 744 } 745 746 //------------------------------------------------------------------------------------------------------------------ 747 ModuleTaskPane::~ModuleTaskPane() 748 { 749 } 750 751 //------------------------------------------------------------------------------------------------------------------ 752 bool ModuleTaskPane::ModuleHasToolPanels( const ::rtl::OUString& i_rModuleIdentifier ) 753 { 754 return ModuleTaskPane_Impl::ModuleHasToolPanels( i_rModuleIdentifier ); 755 } 756 757 //------------------------------------------------------------------------------------------------------------------ 758 bool ModuleTaskPane::ModuleHasToolPanels( const Reference< XFrame >& i_rDocumentFrame ) 759 { 760 return ModuleTaskPane_Impl::ModuleHasToolPanels( lcl_identifyModule( i_rDocumentFrame ) ); 761 } 762 763 //------------------------------------------------------------------------------------------------------------------ 764 void ModuleTaskPane::Resize() 765 { 766 Window::Resize(); 767 m_pImpl->OnResize(); 768 } 769 770 //------------------------------------------------------------------------------------------------------------------ 771 void ModuleTaskPane::GetFocus() 772 { 773 Window::GetFocus(); 774 m_pImpl->OnGetFocus(); 775 } 776 777 //------------------------------------------------------------------------------------------------------------------ 778 ::svt::ToolPanelDeck& ModuleTaskPane::GetPanelDeck() 779 { 780 return m_pImpl->GetPanelDeck(); 781 } 782 783 //------------------------------------------------------------------------------------------------------------------ 784 const ::svt::ToolPanelDeck& ModuleTaskPane::GetPanelDeck() const 785 { 786 return m_pImpl->GetPanelDeck(); 787 } 788 789 //------------------------------------------------------------------------------------------------------------------ 790 ::boost::optional< size_t > ModuleTaskPane::GetPanelPos( const ::rtl::OUString& i_rResourceURL ) 791 { 792 return m_pImpl->GetPanelPos( i_rResourceURL ); 793 } 794 795 //------------------------------------------------------------------------------------------------------------------ 796 ::rtl::OUString ModuleTaskPane::GetPanelResourceURL( const size_t i_nPanelPos ) const 797 { 798 return m_pImpl->GetPanelResourceURL( i_nPanelPos ); 799 } 800 801 //------------------------------------------------------------------------------------------------------------------ 802 void ModuleTaskPane::SetDrawersLayout() 803 { 804 m_pImpl->SetDrawersLayout(); 805 } 806 807 //------------------------------------------------------------------------------------------------------------------ 808 void ModuleTaskPane::SetTabsLayout( const ::svt::TabAlignment i_eTabAlignment, const ::svt::TabItemContent i_eTabContent ) 809 { 810 m_pImpl->SetTabsLayout( i_eTabAlignment, i_eTabContent ); 811 } 812 813 // ===================================================================================================================== 814 // = PanelSelectorLayout 815 // ===================================================================================================================== 816 enum PanelSelectorLayout 817 { 818 LAYOUT_DRAWERS, 819 LAYOUT_TABS_RIGHT, 820 LAYOUT_TABS_LEFT, 821 LAYOUT_TABS_TOP, 822 LAYOUT_TABS_BOTTOM 823 }; 824 825 //================================================================================================================== 826 //= helper 827 //================================================================================================================== 828 namespace 829 { 830 PanelSelectorLayout lcl_getTabLayoutFromAlignment( const SfxChildAlignment i_eAlignment ) 831 { 832 switch ( i_eAlignment ) 833 { 834 case SFX_ALIGN_LEFT: 835 return LAYOUT_TABS_LEFT; 836 case SFX_ALIGN_TOP: 837 return LAYOUT_TABS_TOP; 838 case SFX_ALIGN_BOTTOM: 839 return LAYOUT_TABS_BOTTOM; 840 default: 841 return LAYOUT_TABS_RIGHT; 842 } 843 } 844 } 845 846 // ===================================================================================================================== 847 // = PanelDescriptor 848 // ===================================================================================================================== 849 /** is a helper class for TaskPaneController_Impl, holding the details about a single panel which is not 850 contained in the IToolPanel implementation itself. 851 */ 852 struct PanelDescriptor 853 { 854 ::svt::PToolPanel pPanel; 855 bool bHidden; 856 857 PanelDescriptor() 858 :pPanel() 859 ,bHidden( false ) 860 { 861 } 862 863 PanelDescriptor( const ::svt::PToolPanel& i_rPanel ) 864 :pPanel( i_rPanel ) 865 ,bHidden( false ) 866 { 867 } 868 }; 869 870 //================================================================================================================== 871 //= TaskPaneController_Impl 872 //================================================================================================================== 873 class TaskPaneController_Impl :public ::boost::noncopyable 874 ,public ::svt::IToolPanelDeckListener 875 { 876 public: 877 TaskPaneController_Impl( 878 ModuleTaskPane& i_rTaskPane, 879 TitledDockingWindow& i_rDockingWindow 880 ); 881 ~TaskPaneController_Impl(); 882 883 void SetDefaultTitle( const String& i_rTitle ); 884 void ActivateToolPanel( const ::rtl::OUString& i_rPanelURL ); 885 886 protected: 887 // IToolPanelDeckListener overridables 888 virtual void PanelInserted( const ::svt::PToolPanel& i_pPanel, const size_t i_nPosition ); 889 virtual void PanelRemoved( const size_t i_nPosition ); 890 virtual void ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive ); 891 virtual void LayouterChanged( const ::svt::PDeckLayouter& i_rNewLayouter ); 892 virtual void Dying(); 893 894 private: 895 DECL_LINK( OnToolboxClicked, ToolBox* ); 896 DECL_LINK( OnMenuItemSelected, Menu* ); 897 DECL_LINK( DockingChanged, TitledDockingWindow* ); 898 ::std::auto_ptr< PopupMenu > impl_createPopupMenu() const; 899 900 /// sets the given layout for the panel selector 901 void impl_setLayout( const PanelSelectorLayout i_eLayout, const bool i_bForce = false ); 902 903 /// returns the current layout of the panel selector 904 PanelSelectorLayout 905 impl_getLayout() const { return m_eCurrentLayout; } 906 907 void impl_updateDockingWindowTitle(); 908 void impl_togglePanelVisibility( const size_t i_nLogicalPanelIndex ); 909 size_t impl_getLogicalPanelIndex( const size_t i_nVisibleIndex ); 910 911 private: 912 enum MenuId 913 { 914 MID_UNLOCK_TASK_PANEL = 1, 915 MID_LOCK_TASK_PANEL = 2, 916 MID_LAYOUT_TABS = 3, 917 MID_LAYOUT_DRAWERS = 4, 918 MID_FIRST_PANEL = 5 919 }; 920 921 private: 922 typedef ::std::vector< PanelDescriptor > PanelDescriptors; 923 924 ModuleTaskPane& m_rTaskPane; 925 TitledDockingWindow& m_rDockingWindow; 926 sal_uInt16 m_nViewMenuID; 927 PanelSelectorLayout m_eCurrentLayout; 928 PanelDescriptors m_aPanelRepository; 929 bool m_bTogglingPanelVisibility; 930 ::rtl::OUString m_sDefaultTitle; 931 }; 932 933 //------------------------------------------------------------------------------------------------------------------ 934 TaskPaneController_Impl::TaskPaneController_Impl( ModuleTaskPane& i_rTaskPane, TitledDockingWindow& i_rDockingWindow ) 935 :m_rTaskPane( i_rTaskPane ) 936 ,m_rDockingWindow( i_rDockingWindow ) 937 ,m_nViewMenuID( 0 ) 938 ,m_eCurrentLayout( LAYOUT_DRAWERS ) 939 ,m_aPanelRepository() 940 ,m_bTogglingPanelVisibility( false ) 941 ,m_sDefaultTitle() 942 { 943 m_rDockingWindow.ResetToolBox(); 944 m_nViewMenuID = m_rDockingWindow.AddDropDownToolBoxItem( 945 String( SfxResId( STR_SFX_TASK_PANE_VIEW ) ), 946 HID_TASKPANE_VIEW_MENU, 947 LINK( this, TaskPaneController_Impl, OnToolboxClicked ) 948 ); 949 m_rDockingWindow.SetEndDockingHdl( LINK( this, TaskPaneController_Impl, DockingChanged ) ); 950 impl_setLayout( LAYOUT_DRAWERS, true ); 951 952 m_rTaskPane.GetPanelDeck().AddListener( *this ); 953 954 // initialize the panel repository 955 for ( size_t i = 0; i < m_rTaskPane.GetPanelDeck().GetPanelCount(); ++i ) 956 { 957 ::svt::PToolPanel pPanel( m_rTaskPane.GetPanelDeck().GetPanel( i ) ); 958 m_aPanelRepository.push_back( PanelDescriptor( pPanel ) ); 959 } 960 961 SetDefaultTitle( String( SfxResId( STR_SFX_TASKS ) ) ); 962 } 963 964 //------------------------------------------------------------------------------------------------------------------ 965 TaskPaneController_Impl::~TaskPaneController_Impl() 966 { 967 m_rTaskPane.GetPanelDeck().RemoveListener( *this ); 968 969 // remove the panels which are not under the control of the panel deck currently 970 for ( PanelDescriptors::iterator panelPos = m_aPanelRepository.begin(); 971 panelPos != m_aPanelRepository.end(); 972 ++panelPos 973 ) 974 { 975 if ( panelPos->bHidden ) 976 panelPos->pPanel->Dispose(); 977 } 978 m_aPanelRepository.clear(); 979 } 980 981 // ----------------------------------------------------------------------------------------------------------------- 982 void TaskPaneController_Impl::SetDefaultTitle( const String& i_rTitle ) 983 { 984 m_sDefaultTitle = i_rTitle; 985 impl_updateDockingWindowTitle(); 986 } 987 988 //------------------------------------------------------------------------------------------------------------------ 989 void TaskPaneController_Impl::ActivateToolPanel( const ::rtl::OUString& i_rPanelURL ) 990 { 991 ::boost::optional< size_t > aPanelPos( m_rTaskPane.GetPanelPos( i_rPanelURL ) ); 992 ENSURE_OR_RETURN_VOID( !!aPanelPos, "TaskPaneController_Impl::ActivateToolPanel: no such panel!" ); 993 994 if ( aPanelPos == m_rTaskPane.GetPanelDeck().GetActivePanel() ) 995 { 996 ::svt::PToolPanel pPanel( m_rTaskPane.GetPanelDeck().GetPanel( *aPanelPos ) ); 997 pPanel->GrabFocus(); 998 } 999 else 1000 { 1001 m_rTaskPane.GetPanelDeck().ActivatePanel( aPanelPos ); 1002 } 1003 } 1004 1005 // ----------------------------------------------------------------------------------------------------------------- 1006 IMPL_LINK( TaskPaneController_Impl, DockingChanged, TitledDockingWindow*, i_pDockingWindow ) 1007 { 1008 ENSURE_OR_RETURN( i_pDockingWindow && &m_rDockingWindow, "TaskPaneController_Impl::DockingChanged: where does this come from?", 0L ); 1009 1010 if ( impl_getLayout() == LAYOUT_DRAWERS ) 1011 return 0L; 1012 1013 impl_setLayout( lcl_getTabLayoutFromAlignment( i_pDockingWindow->GetAlignment() ) ); 1014 return 1L; 1015 } 1016 1017 // ----------------------------------------------------------------------------------------------------------------- 1018 IMPL_LINK( TaskPaneController_Impl, OnToolboxClicked, ToolBox*, i_pToolBox ) 1019 { 1020 if ( i_pToolBox->GetCurItemId() == m_nViewMenuID ) 1021 { 1022 i_pToolBox->EndSelection(); 1023 1024 ::std::auto_ptr< PopupMenu > pMenu = impl_createPopupMenu(); 1025 pMenu->SetSelectHdl( LINK( this, TaskPaneController_Impl, OnMenuItemSelected ) ); 1026 1027 // pass toolbox button rect so the menu can stay open on button up 1028 Rectangle aMenuRect( i_pToolBox->GetItemRect( m_nViewMenuID ) ); 1029 aMenuRect.SetPos( i_pToolBox->GetPosPixel() ); 1030 pMenu->Execute( &m_rDockingWindow, aMenuRect, POPUPMENU_EXECUTE_DOWN ); 1031 } 1032 1033 return 0; 1034 } 1035 1036 // --------------------------------------------------------------------------------------------------------------------- 1037 IMPL_LINK( TaskPaneController_Impl, OnMenuItemSelected, Menu*, i_pMenu ) 1038 { 1039 ENSURE_OR_RETURN( i_pMenu, "TaskPaneController_Impl::OnMenuItemSelected: illegal menu!", 0L ); 1040 1041 i_pMenu->Deactivate(); 1042 switch ( i_pMenu->GetCurItemId() ) 1043 { 1044 case MID_UNLOCK_TASK_PANEL: 1045 m_rDockingWindow.SetFloatingMode( sal_True ); 1046 break; 1047 1048 case MID_LOCK_TASK_PANEL: 1049 m_rDockingWindow.SetFloatingMode( sal_False ); 1050 break; 1051 1052 case MID_LAYOUT_DRAWERS: 1053 impl_setLayout( LAYOUT_DRAWERS ); 1054 break; 1055 1056 case MID_LAYOUT_TABS: 1057 impl_setLayout( lcl_getTabLayoutFromAlignment( m_rDockingWindow.GetAlignment() ) ); 1058 break; 1059 1060 default: 1061 { 1062 size_t nPanelIndex = size_t( i_pMenu->GetCurItemId() - MID_FIRST_PANEL ); 1063 impl_togglePanelVisibility( nPanelIndex ); 1064 } 1065 break; 1066 } 1067 1068 return 1L; 1069 } 1070 1071 // --------------------------------------------------------------------------------------------------------------------- 1072 size_t TaskPaneController_Impl::impl_getLogicalPanelIndex( const size_t i_nVisibleIndex ) 1073 { 1074 size_t nLogicalIndex = 0; 1075 size_t nVisibleIndex( i_nVisibleIndex ); 1076 for ( size_t i=0; i < m_aPanelRepository.size(); ++i ) 1077 { 1078 if ( !m_aPanelRepository[i].bHidden ) 1079 { 1080 if ( !nVisibleIndex ) 1081 break; 1082 --nVisibleIndex; 1083 } 1084 ++nLogicalIndex; 1085 } 1086 return nLogicalIndex; 1087 } 1088 1089 // --------------------------------------------------------------------------------------------------------------------- 1090 void TaskPaneController_Impl::PanelInserted( const ::svt::PToolPanel& i_pPanel, const size_t i_nPosition ) 1091 { 1092 if ( m_bTogglingPanelVisibility ) 1093 return; 1094 1095 const size_t nLogicalIndex( impl_getLogicalPanelIndex( i_nPosition ) ); 1096 m_aPanelRepository.insert( m_aPanelRepository.begin() + nLogicalIndex, PanelDescriptor( i_pPanel ) ); 1097 } 1098 1099 // --------------------------------------------------------------------------------------------------------------------- 1100 void TaskPaneController_Impl::PanelRemoved( const size_t i_nPosition ) 1101 { 1102 if ( m_bTogglingPanelVisibility ) 1103 return; 1104 1105 const size_t nLogicalIndex( impl_getLogicalPanelIndex( i_nPosition ) ); 1106 m_aPanelRepository.erase( m_aPanelRepository.begin() + nLogicalIndex ); 1107 } 1108 1109 // --------------------------------------------------------------------------------------------------------------------- 1110 void TaskPaneController_Impl::ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive ) 1111 { 1112 if ( impl_getLayout() == LAYOUT_DRAWERS ) 1113 // no adjustment of the title when we use the classical "drawers" layout 1114 return; 1115 1116 impl_updateDockingWindowTitle( ); 1117 (void)i_rOldActive; 1118 (void)i_rNewActive; 1119 } 1120 1121 // --------------------------------------------------------------------------------------------------------------------- 1122 void TaskPaneController_Impl::LayouterChanged( const ::svt::PDeckLayouter& i_rNewLayouter ) 1123 { 1124 // not interested in 1125 (void)i_rNewLayouter; 1126 } 1127 1128 // --------------------------------------------------------------------------------------------------------------------- 1129 void TaskPaneController_Impl::Dying() 1130 { 1131 OSL_ENSURE( false, "TaskPaneController_Impl::Dying: unexpected call!" ); 1132 // We are expected to live longer than the ToolPanelDeck we work with. Since we remove ourself, in our dtor, 1133 // as listener from the panel deck, this method here should never be called. 1134 } 1135 1136 // --------------------------------------------------------------------------------------------------------------------- 1137 void TaskPaneController_Impl::impl_togglePanelVisibility( const size_t i_nLogicalPanelIndex ) 1138 { 1139 ENSURE_OR_RETURN_VOID( i_nLogicalPanelIndex < m_aPanelRepository.size(), "illegal index" ); 1140 1141 // get the actual panel index, within the deck 1142 size_t nActualPanelIndex(0); 1143 for ( size_t i=0; i < i_nLogicalPanelIndex; ++i ) 1144 { 1145 if ( !m_aPanelRepository[i].bHidden ) 1146 ++nActualPanelIndex; 1147 } 1148 1149 ::boost::optional< size_t > aActivatePanel; 1150 1151 m_bTogglingPanelVisibility = true; 1152 if ( m_aPanelRepository[ i_nLogicalPanelIndex ].bHidden ) 1153 { 1154 OSL_VERIFY( m_rTaskPane.GetPanelDeck().InsertPanel( m_aPanelRepository[ i_nLogicalPanelIndex ].pPanel, nActualPanelIndex ) == nActualPanelIndex ); 1155 // if there has not been an active panel before, activate the newly inserted one 1156 ::boost::optional< size_t > aActivePanel( m_rTaskPane.GetPanelDeck().GetActivePanel() ); 1157 if ( !aActivePanel ) 1158 aActivatePanel = nActualPanelIndex; 1159 } 1160 else 1161 { 1162 OSL_VERIFY( m_rTaskPane.GetPanelDeck().RemovePanel( nActualPanelIndex ).get() == m_aPanelRepository[ i_nLogicalPanelIndex ].pPanel.get() ); 1163 } 1164 m_bTogglingPanelVisibility = false; 1165 m_aPanelRepository[ i_nLogicalPanelIndex ].bHidden = !m_aPanelRepository[ i_nLogicalPanelIndex ].bHidden; 1166 1167 if ( !!aActivatePanel ) 1168 m_rTaskPane.GetPanelDeck().ActivatePanel( *aActivatePanel ); 1169 } 1170 1171 // --------------------------------------------------------------------------------------------------------------------- 1172 void TaskPaneController_Impl::impl_setLayout( const PanelSelectorLayout i_eLayout, const bool i_bForce ) 1173 { 1174 if ( !i_bForce && ( m_eCurrentLayout == i_eLayout ) ) 1175 return; 1176 1177 switch ( i_eLayout ) 1178 { 1179 case LAYOUT_DRAWERS: 1180 m_rTaskPane.SetDrawersLayout(); 1181 break; 1182 case LAYOUT_TABS_TOP: 1183 m_rTaskPane.SetTabsLayout( ::svt::TABS_TOP, ::svt::TABITEM_IMAGE_ONLY ); 1184 break; 1185 case LAYOUT_TABS_BOTTOM: 1186 m_rTaskPane.SetTabsLayout( ::svt::TABS_BOTTOM, ::svt::TABITEM_IMAGE_ONLY ); 1187 break; 1188 case LAYOUT_TABS_LEFT: 1189 m_rTaskPane.SetTabsLayout( ::svt::TABS_LEFT, ::svt::TABITEM_IMAGE_ONLY ); 1190 break; 1191 case LAYOUT_TABS_RIGHT: 1192 m_rTaskPane.SetTabsLayout( ::svt::TABS_RIGHT, ::svt::TABITEM_IMAGE_ONLY ); 1193 break; 1194 } 1195 m_eCurrentLayout = i_eLayout; 1196 1197 impl_updateDockingWindowTitle(); 1198 } 1199 1200 // --------------------------------------------------------------------------------------------------------------------- 1201 void TaskPaneController_Impl::impl_updateDockingWindowTitle() 1202 { 1203 ::boost::optional< size_t > aActivePanel( m_rTaskPane.GetPanelDeck().GetActivePanel() ); 1204 if ( !aActivePanel || ( impl_getLayout() == LAYOUT_DRAWERS ) ) 1205 m_rDockingWindow.SetTitle( m_sDefaultTitle ); 1206 else 1207 { 1208 size_t nNewActive( *aActivePanel ); 1209 for ( size_t i=0; i < m_aPanelRepository.size(); ++i ) 1210 { 1211 if ( m_aPanelRepository[i].bHidden ) 1212 continue; 1213 1214 if ( !nNewActive ) 1215 { 1216 m_rDockingWindow.SetTitle( m_aPanelRepository[i].pPanel->GetDisplayName() ); 1217 break; 1218 } 1219 --nNewActive; 1220 } 1221 } 1222 } 1223 1224 // --------------------------------------------------------------------------------------------------------------------- 1225 ::std::auto_ptr< PopupMenu > TaskPaneController_Impl::impl_createPopupMenu() const 1226 { 1227 ::std::auto_ptr<PopupMenu> pMenu( new PopupMenu ); 1228 FloatingWindow* pMenuWindow = static_cast< FloatingWindow* >( pMenu->GetWindow() ); 1229 if ( pMenuWindow != NULL ) 1230 { 1231 pMenuWindow->SetPopupModeFlags ( pMenuWindow->GetPopupModeFlags() | FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE ); 1232 } 1233 1234 // Add one entry for every tool panel element to individually make 1235 // them visible or hide them. 1236 sal_uInt16 nIndex = MID_FIRST_PANEL; 1237 for ( size_t i=0; i<m_aPanelRepository.size(); ++i, ++nIndex ) 1238 { 1239 const PanelDescriptor& rPanelDesc( m_aPanelRepository[i] ); 1240 pMenu->InsertItem( nIndex, rPanelDesc.pPanel->GetDisplayName(), MIB_CHECKABLE ); 1241 pMenu->CheckItem( nIndex, !rPanelDesc.bHidden ); 1242 } 1243 pMenu->InsertSeparator(); 1244 1245 #if OSL_DEBUG_LEVEL > 0 1246 pMenu->InsertItem( MID_LAYOUT_TABS, String::CreateFromAscii( "Tab-Layout (exp.)" ), MIB_CHECKABLE ); 1247 pMenu->CheckItem( MID_LAYOUT_TABS, impl_getLayout() != LAYOUT_DRAWERS ); 1248 pMenu->InsertItem( MID_LAYOUT_DRAWERS, String::CreateFromAscii( "Drawer-Layout" ), MIB_CHECKABLE ); 1249 pMenu->CheckItem( MID_LAYOUT_DRAWERS, impl_getLayout() == LAYOUT_DRAWERS ); 1250 1251 pMenu->InsertSeparator(); 1252 #endif 1253 1254 // Add entry for docking or un-docking the tool panel. 1255 if ( m_rDockingWindow.IsFloatingMode() ) 1256 pMenu->InsertItem( 1257 MID_LOCK_TASK_PANEL, 1258 String( SfxResId( STR_SFX_DOCK ) ) 1259 ); 1260 else 1261 pMenu->InsertItem( 1262 MID_UNLOCK_TASK_PANEL, 1263 String( SfxResId( STR_SFX_UNDOCK ) ) 1264 ); 1265 1266 pMenu->RemoveDisabledEntries( sal_False, sal_False ); 1267 1268 return pMenu; 1269 } 1270 1271 //================================================================================================================== 1272 //= TaskPaneController 1273 //================================================================================================================== 1274 //------------------------------------------------------------------------------------------------------------------ 1275 TaskPaneController::TaskPaneController( ModuleTaskPane& i_rTaskPane, TitledDockingWindow& i_rDockingWindow ) 1276 :m_pImpl( new TaskPaneController_Impl( i_rTaskPane, i_rDockingWindow ) ) 1277 { 1278 } 1279 1280 //------------------------------------------------------------------------------------------------------------------ 1281 TaskPaneController::~TaskPaneController() 1282 { 1283 } 1284 1285 //------------------------------------------------------------------------------------------------------------------ 1286 void TaskPaneController::SetDefaultTitle( const String& i_rTitle ) 1287 { 1288 m_pImpl->SetDefaultTitle( i_rTitle ); 1289 } 1290 1291 //------------------------------------------------------------------------------------------------------------------ 1292 void TaskPaneController::ActivateToolPanel( const ::rtl::OUString& i_rPanelURL ) 1293 { 1294 m_pImpl->ActivateToolPanel( i_rPanelURL ); 1295 } 1296 1297 //...................................................................................................................... 1298 } // namespace sfx2 1299 //...................................................................................................................... 1300