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