1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sd.hxx" 30 31 #include "ToolBarManager.hxx" 32 33 #include "DrawViewShell.hxx" 34 #include "EventMultiplexer.hxx" 35 #include "ViewShellBase.hxx" 36 #include "ViewShellManager.hxx" 37 #include <com/sun/star/beans/XPropertySet.hpp> 38 #include <com/sun/star/frame/XLayoutManager.hpp> 39 #include <com/sun/star/ui/UIElementType.hpp> 40 41 #include <cppuhelper/implbase1.hxx> 42 #include <osl/mutex.hxx> 43 #include <rtl/ref.hxx> 44 #include <sfx2/app.hxx> 45 #include <sfx2/docfile.hxx> 46 #include <sfx2/objsh.hxx> 47 #include <sfx2/request.hxx> 48 #include <sfx2/viewfrm.hxx> 49 #include <svl/eitem.hxx> 50 #include <svx/dialogs.hrc> 51 #include <svx/extrusionbar.hxx> 52 #include <svx/fontworkbar.hxx> 53 #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_ 54 #include <toolkit/unohlp.hxx> 55 #endif 56 #include <tools/link.hxx> 57 58 #include <map> 59 #include <vector> 60 61 using namespace ::com::sun::star; 62 using namespace ::com::sun::star::uno; 63 64 #undef VERBOSE 65 66 #undef OUSTRING // Remove definition made in the SFX 67 #define OUSTRING(s) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))) 68 69 namespace { 70 71 using namespace sd; 72 73 class ToolBarRules; 74 75 /** Lock of the frame::XLayoutManager. 76 */ 77 class LayouterLock 78 { 79 public: 80 LayouterLock (const Reference<frame::XLayoutManager>& rxLayouter); 81 ~LayouterLock (void); 82 private: 83 Reference<frame::XLayoutManager> mxLayouter; 84 }; 85 86 87 typedef ::std::vector<rtl::OUString> NameList; 88 89 /** Store a list of tool bars for each of the tool bar groups. From 90 this the list of requested tool bars is built. 91 */ 92 class ToolBarList 93 { 94 public: 95 ToolBarList (void); 96 97 void ClearGroup (sd::ToolBarManager::ToolBarGroup eGroup); 98 void AddToolBar (sd::ToolBarManager::ToolBarGroup eGroup, const ::rtl::OUString& rsName); 99 bool RemoveToolBar (sd::ToolBarManager::ToolBarGroup eGroup, const ::rtl::OUString& rsName); 100 101 void GetToolBarsToActivate (NameList& rToolBars) const; 102 void GetToolBarsToDeactivate (NameList& rToolBars) const; 103 104 void MarkToolBarAsActive (const ::rtl::OUString& rsName); 105 void MarkToolBarAsNotActive (const ::rtl::OUString& rsName); 106 void MarkAllToolBarsAsNotActive (void); 107 108 private: 109 typedef ::std::map<sd::ToolBarManager::ToolBarGroup,NameList> Groups; 110 Groups maGroups; 111 NameList maActiveToolBars; 112 113 void MakeRequestedToolBarList (NameList& rToolBars) const; 114 }; 115 116 117 118 119 /** Manage tool bars that are implemented as sub shells of a view shell. 120 The typical procedure of updating the sub shells of a view shell is to 121 rebuild a list of sub shells that the caller would like to have active. 122 The methods ClearGroup() and AddShellId() allow the caller to do that. A 123 final call to UpdateShells() activates the requested shells that are not 124 active and deactivates the active shells that are not requested . 125 126 This is done by maintaining two lists. One (the current list) 127 reflects the current state. The other (the requested list) contains the 128 currently requested shells. UpdateShells() makes the requested 129 list the current list and clears the current list. 130 131 Each shell belongs to one group. Different groups can be modified 132 seperately. 133 */ 134 class ToolBarShellList 135 { 136 public: 137 /** Create a new object with an empty current list and an empty 138 requested list. 139 */ 140 ToolBarShellList (void); 141 142 /** Remove all shells from a group. Calling this method should normally 143 not be necessary because after the construction or after a call to 144 UpdateShells() the requested list is empty. 145 @param eGroup 146 The group to clear. Shells in other groups are not modified. 147 */ 148 void ClearGroup (sd::ToolBarManager::ToolBarGroup eGroup); 149 150 /** Add a shell. When the specified shell has alreadt been requested 151 for another group then it is moved to this group. 152 @param eGroup 153 The group to which to add the shell. 154 @param nId 155 The id of the shell to add. 156 */ 157 void AddShellId (sd::ToolBarManager::ToolBarGroup eGroup, sd::ShellId nId); 158 159 /** Releasing all shells means that the given ToolBarRules object is 160 informed that every shell mananged by the called ToolBarShellList is 161 about to be removed and that the associated framework tool bars can 162 be removed as well. The caller still has to call UpdateShells(). 163 */ 164 void ReleaseAllShells (ToolBarRules& rRules); 165 166 /** The requested list is made the current list by activating all 167 shells in the requested list and by deactivating the shells in the 168 current list that are not in the requested list. 169 @param pMainViewShell 170 The shells that are activated or deactivated are sub shells of 171 this view shell. 172 @param rManager 173 This ViewShellManager is used to activate or deactivate shells. 174 */ 175 void UpdateShells ( 176 const ::boost::shared_ptr<ViewShell>& rpMainViewShell, 177 const ::boost::shared_ptr<ViewShellManager>& rpManager); 178 179 private: 180 class ShellDescriptor 181 {public: 182 ShellDescriptor (ShellId nId,sd::ToolBarManager::ToolBarGroup eGroup); 183 ShellId mnId; 184 sd::ToolBarManager::ToolBarGroup meGroup; 185 friend bool operator<(const ShellDescriptor& r1, const ShellDescriptor& r2) 186 { return r1.mnId < r2.mnId; } 187 }; 188 189 /** The requested list of tool bar shells that will be active after the 190 next call to UpdateShells(). 191 */ 192 typedef ::std::set<ShellDescriptor> GroupedShellList; 193 GroupedShellList maNewList; 194 195 /** The list of tool bar shells that are currently on the shell stack. 196 Using a GroupedShellList is not strictly necessary but it makes 197 things easier and does not waste too much memory. 198 */ 199 GroupedShellList maCurrentList; 200 }; 201 202 203 204 205 /** This class concentrates the knowledge about when to show what tool bars 206 in one place. 207 */ 208 class ToolBarRules 209 { 210 public: 211 ToolBarRules ( 212 const ::boost::shared_ptr<ToolBarManager>& rpToolBarManager, 213 const ::boost::shared_ptr<ViewShellManager>& rpViewShellManager); 214 215 /** This method calls MainViewShellChanged() and SelectionHasChanged() 216 for the current main view shell and its view. 217 */ 218 void Update (ViewShellBase& rBase); 219 220 /** Reset all tool bars in all groups and add tool bars and tool bar 221 shells to the TBG_PERMANENT group for the specified ViewShell type. 222 */ 223 void MainViewShellChanged (ViewShell::ShellType nShellType); 224 225 /** Reset all tool bars in all groups and add tool bars and tool bar 226 shells to the TBG_PERMANENT group for the specified ViewShell. 227 */ 228 void MainViewShellChanged (const ViewShell& rMainViewShell); 229 230 /** Reset all tool bars in the TBG_FUNCTION group and add tool bars and tool bar 231 shells to this group for the current selection. 232 */ 233 void SelectionHasChanged ( 234 const ::sd::ViewShell& rViewShell, 235 const SdrView& rView); 236 237 /** Add a tool bar for the specified tool bar shell. 238 */ 239 void SubShellAdded ( 240 ::sd::ToolBarManager::ToolBarGroup eGroup, 241 sd::ShellId nShellId); 242 243 /** Remove a tool bar for the specified tool bar shell. 244 */ 245 void SubShellRemoved ( 246 ::sd::ToolBarManager::ToolBarGroup eGroup, 247 sd::ShellId nShellId); 248 249 private: 250 ::boost::shared_ptr<ToolBarManager> mpToolBarManager; 251 ::boost::shared_ptr<ViewShellManager> mpViewShellManager; 252 }; 253 254 } // end of anonymous namespace 255 256 257 258 259 namespace sd { 260 261 //===== ToolBarManager::Implementation ======================================== 262 263 class ToolBarManager::Implementation 264 { 265 public: 266 /** This constructor takes three arguments even though the 267 ToolBarManager could be taken from the ViewShellBase. This is so to 268 state explicitly which information has to be present when this 269 constructor is called. The ViewShellBase may not have been fully 270 initialized at this point and must not be asked for this values. 271 */ 272 Implementation ( 273 ViewShellBase& rBase, 274 const ::boost::shared_ptr<sd::tools::EventMultiplexer>& rpMultiplexer, 275 const ::boost::shared_ptr<ViewShellManager>& rpViewShellManager, 276 const ::boost::shared_ptr<ToolBarManager>& rpToolBarManager); 277 ~Implementation (void); 278 279 void SetValid (bool bValid); 280 281 void ResetToolBars (ToolBarGroup eGroup); 282 void ResetAllToolBars (void); 283 void AddToolBar (ToolBarGroup eGroup, const ::rtl::OUString& rsToolBarName); 284 void AddToolBarShell (ToolBarGroup eGroup, ShellId nToolBarId); 285 void RemoveToolBar (ToolBarGroup eGroup, const ::rtl::OUString& rsToolBarName); 286 287 /** Release all tool bar shells and the associated framework tool bars. 288 Typically called when the main view shell is being replaced by 289 another, all tool bar shells are released. In that process the 290 shells are destroyed anyway and whithout calling this method they 291 would still be referenced. 292 */ 293 void ReleaseAllToolBarShells (void); 294 295 void ToolBarsDestroyed(void); 296 297 void RequestUpdate (void); 298 299 void PreUpdate (void); 300 void PostUpdate (void); 301 /** Tell the XLayoutManager about the tool bars that we would like to be 302 shown. 303 @param rpLayouterLock 304 This typically is the mpSynchronousLayouterLock that is used in 305 this method and that is either released at its end or assigned 306 to mpAsynchronousLock in order to be unlocked later. 307 */ 308 void Update (::std::auto_ptr<LayouterLock> pLayouterLock); 309 310 class UpdateLockImplementation 311 { 312 public: 313 UpdateLockImplementation (Implementation& rImplementation) 314 : mrImplementation(rImplementation) { mrImplementation.LockUpdate(); } 315 ~UpdateLockImplementation (void) { mrImplementation.UnlockUpdate(); } 316 private: 317 Implementation& mrImplementation; 318 }; 319 320 void LockViewShellManager (void); 321 void LockUpdate (void); 322 void UnlockUpdate (void); 323 324 ToolBarRules& GetToolBarRules (void); 325 326 private: 327 const static ::rtl::OUString msToolBarResourcePrefix; 328 329 mutable ::osl::Mutex maMutex; 330 ViewShellBase& mrBase; 331 ::boost::shared_ptr<sd::tools::EventMultiplexer> mpEventMultiplexer; 332 bool mbIsValid; 333 ToolBarList maToolBarList; 334 ToolBarShellList maToolBarShellList; 335 Reference<frame::XLayoutManager> mxLayouter; 336 sal_Int32 mnLockCount; 337 bool mbPreUpdatePending; 338 bool mbPostUpdatePending; 339 /** The layouter locks manage the locking of the XLayoutManager. The 340 lock() and unlock() functions are not called directly because the 341 (final) unlocking is usually done asynchronously *after* the 342 list of requested toolbars is updated. 343 */ 344 ::std::auto_ptr<LayouterLock> mpSynchronousLayouterLock; 345 ::std::auto_ptr<LayouterLock> mpAsynchronousLayouterLock; 346 ::std::auto_ptr<ViewShellManager::UpdateLock> mpViewShellManagerLock; 347 sal_uLong mnPendingUpdateCall; 348 sal_uLong mnPendingSetValidCall; 349 ToolBarRules maToolBarRules; 350 351 ::rtl::OUString GetToolBarResourceName (const ::rtl::OUString& rsBaseName) const; 352 bool CheckPlugInMode (const ::rtl::OUString& rsName) const; 353 354 DECL_LINK(UpdateCallback,bool*); 355 DECL_LINK(EventMultiplexerCallback, sd::tools::EventMultiplexerEvent*); 356 DECL_LINK(SetValidCallback,void*); 357 }; 358 359 360 361 //===== ToolBarManager ======================================================== 362 363 const ::rtl::OUString ToolBarManager::msToolBar(OUSTRING("toolbar")); 364 const ::rtl::OUString ToolBarManager::msOptionsToolBar(OUSTRING("optionsbar")); 365 const ::rtl::OUString ToolBarManager::msCommonTaskToolBar(OUSTRING("commontaskbar")); 366 const ::rtl::OUString ToolBarManager::msViewerToolBar(OUSTRING("viewerbar")); 367 const ::rtl::OUString ToolBarManager::msSlideSorterToolBar(OUSTRING("slideviewtoolbar")); 368 const ::rtl::OUString ToolBarManager::msSlideSorterObjectBar(OUSTRING("slideviewobjectbar")); 369 const ::rtl::OUString ToolBarManager::msOutlineToolBar(OUSTRING("outlinetoolbar")); 370 const ::rtl::OUString ToolBarManager::msMasterViewToolBar(OUSTRING("masterviewtoolbar")); 371 const ::rtl::OUString ToolBarManager::msDrawingObjectToolBar(OUSTRING("drawingobjectbar")); 372 const ::rtl::OUString ToolBarManager::msGluePointsToolBar(OUSTRING("gluepointsobjectbar")); 373 const ::rtl::OUString ToolBarManager::msTextObjectBar(OUSTRING("textobjectbar")); 374 const ::rtl::OUString ToolBarManager::msBezierObjectBar(OUSTRING("bezierobjectbar")); 375 const ::rtl::OUString ToolBarManager::msGraphicObjectBar(OUSTRING("graphicobjectbar")); 376 const ::rtl::OUString ToolBarManager::msMediaObjectBar(OUSTRING("mediaobjectbar")); 377 const ::rtl::OUString ToolBarManager::msTableObjectBar(OUSTRING("tableobjectbar")); 378 379 380 ::boost::shared_ptr<ToolBarManager> ToolBarManager::Create ( 381 ViewShellBase& rBase, 382 const ::boost::shared_ptr<sd::tools::EventMultiplexer>& rpMultiplexer, 383 const ::boost::shared_ptr<ViewShellManager>& rpViewShellManager) 384 { 385 ::boost::shared_ptr<ToolBarManager> pManager (new ToolBarManager()); 386 pManager->mpImpl.reset( 387 new Implementation(rBase,rpMultiplexer,rpViewShellManager,pManager)); 388 return pManager; 389 } 390 391 392 393 394 ToolBarManager::ToolBarManager (void) 395 : mpImpl() 396 { 397 } 398 399 400 401 402 ToolBarManager::~ToolBarManager (void) 403 { 404 } 405 406 407 408 409 void ToolBarManager::Shutdown (void) 410 { 411 if (mpImpl.get() != NULL) 412 mpImpl.reset(); 413 } 414 415 416 417 418 void ToolBarManager::ResetToolBars (ToolBarGroup eGroup) 419 { 420 if (mpImpl.get() != NULL) 421 { 422 UpdateLock aLock (shared_from_this()); 423 mpImpl->ResetToolBars(eGroup); 424 } 425 } 426 427 428 429 430 void ToolBarManager::ResetAllToolBars (void) 431 { 432 if (mpImpl.get() != NULL) 433 { 434 UpdateLock aLock (shared_from_this()); 435 mpImpl->ResetAllToolBars(); 436 } 437 } 438 439 440 441 442 void ToolBarManager::AddToolBar ( 443 ToolBarGroup eGroup, 444 const ::rtl::OUString& rsToolBarName) 445 { 446 if (mpImpl.get() != NULL) 447 { 448 UpdateLock aLock (shared_from_this()); 449 mpImpl->AddToolBar(eGroup,rsToolBarName); 450 } 451 } 452 453 454 455 456 void ToolBarManager::AddToolBarShell ( 457 ToolBarGroup eGroup, 458 ShellId nToolBarId) 459 { 460 if (mpImpl.get() != NULL) 461 { 462 UpdateLock aLock (shared_from_this()); 463 mpImpl->AddToolBarShell(eGroup,nToolBarId); 464 } 465 } 466 467 468 469 470 void ToolBarManager::RemoveToolBar ( 471 ToolBarGroup eGroup, 472 const ::rtl::OUString& rsToolBarName) 473 { 474 if (mpImpl.get() != NULL) 475 { 476 UpdateLock aLock (shared_from_this()); 477 mpImpl->RemoveToolBar(eGroup,rsToolBarName); 478 } 479 } 480 481 482 483 484 void ToolBarManager::SetToolBar ( 485 ToolBarGroup eGroup, 486 const ::rtl::OUString& rsToolBarName) 487 { 488 if (mpImpl.get() != NULL) 489 { 490 UpdateLock aLock (shared_from_this()); 491 mpImpl->ResetToolBars(eGroup); 492 mpImpl->AddToolBar(eGroup,rsToolBarName); 493 } 494 } 495 496 497 498 499 void ToolBarManager::SetToolBarShell ( 500 ToolBarGroup eGroup, 501 ShellId nToolBarId) 502 { 503 if (mpImpl.get() != NULL) 504 { 505 UpdateLock aLock (shared_from_this()); 506 mpImpl->ResetToolBars(eGroup); 507 mpImpl->AddToolBarShell(eGroup,nToolBarId); 508 } 509 } 510 511 512 513 514 void ToolBarManager::PreUpdate (void) 515 { 516 if (mpImpl.get()!=NULL) 517 mpImpl->PreUpdate(); 518 } 519 520 521 522 523 void ToolBarManager::RequestUpdate (void) 524 { 525 if (mpImpl.get()!=NULL) 526 mpImpl->RequestUpdate(); 527 } 528 529 530 531 532 void ToolBarManager::LockViewShellManager (void) 533 { 534 if (mpImpl.get() != NULL) 535 mpImpl->LockViewShellManager(); 536 } 537 538 539 540 541 void ToolBarManager::LockUpdate (void) 542 { 543 if (mpImpl.get()!=NULL) 544 mpImpl->LockUpdate(); 545 } 546 547 548 549 550 void ToolBarManager::UnlockUpdate (void) 551 { 552 if (mpImpl.get()!=NULL) 553 mpImpl->UnlockUpdate(); 554 } 555 556 557 558 559 void ToolBarManager::MainViewShellChanged (ViewShell::ShellType nShellType) 560 { 561 if (mpImpl.get() != NULL) 562 { 563 mpImpl->ReleaseAllToolBarShells(); 564 mpImpl->GetToolBarRules().MainViewShellChanged(nShellType); 565 } 566 } 567 568 569 570 571 void ToolBarManager::MainViewShellChanged (const ViewShell& rMainViewShell) 572 { 573 if (mpImpl.get() != NULL) 574 { 575 mpImpl->ReleaseAllToolBarShells(); 576 mpImpl->GetToolBarRules().MainViewShellChanged(rMainViewShell); 577 } 578 } 579 580 581 582 583 void ToolBarManager::SelectionHasChanged ( 584 const ViewShell& rViewShell, 585 const SdrView& rView) 586 { 587 if (mpImpl.get() != NULL) 588 mpImpl->GetToolBarRules().SelectionHasChanged(rViewShell,rView); 589 } 590 591 592 void ToolBarManager::ToolBarsDestroyed(void) 593 { 594 if (mpImpl.get() != NULL) 595 mpImpl->ToolBarsDestroyed(); 596 } 597 598 599 //===== ToolBarManager::Implementation ======================================= 600 601 const ::rtl::OUString ToolBarManager::Implementation::msToolBarResourcePrefix( 602 OUSTRING("private:resource/toolbar/")); 603 604 ToolBarManager::Implementation::Implementation ( 605 ViewShellBase& rBase, 606 const ::boost::shared_ptr<sd::tools::EventMultiplexer>& rpMultiplexer, 607 const ::boost::shared_ptr<ViewShellManager>& rpViewShellManager, 608 const ::boost::shared_ptr<ToolBarManager>& rpToolBarManager) 609 : maMutex(), 610 mrBase(rBase), 611 mpEventMultiplexer(rpMultiplexer), 612 mbIsValid(false), 613 maToolBarList(), 614 maToolBarShellList(), 615 mxLayouter(NULL), 616 mnLockCount(0), 617 mbPreUpdatePending(false), 618 mbPostUpdatePending(false), 619 mpSynchronousLayouterLock(), 620 mpAsynchronousLayouterLock(), 621 mpViewShellManagerLock(), 622 mnPendingUpdateCall(0), 623 mnPendingSetValidCall(0), 624 maToolBarRules(rpToolBarManager,rpViewShellManager) 625 { 626 Link aLink (LINK(this,ToolBarManager::Implementation,EventMultiplexerCallback)); 627 mpEventMultiplexer->AddEventListener( 628 aLink, 629 tools::EventMultiplexerEvent::EID_CONTROLLER_ATTACHED 630 | tools::EventMultiplexerEvent::EID_CONTROLLER_DETACHED 631 | tools::EventMultiplexerEvent::EID_PANE_MANAGER_DYING); 632 } 633 634 635 636 /** The order of statements is important. 637 First unregister listeners, which may post user events. 638 Then remove pending user events. 639 */ 640 ToolBarManager::Implementation::~Implementation (void) 641 { 642 // Unregister at broadcasters. 643 Link aLink (LINK(this,ToolBarManager::Implementation,EventMultiplexerCallback)); 644 mpEventMultiplexer->RemoveEventListener(aLink); 645 646 // Abort pending user calls. 647 if (mnPendingUpdateCall != 0) 648 Application::RemoveUserEvent(mnPendingUpdateCall); 649 if (mnPendingSetValidCall != 0) 650 Application::RemoveUserEvent(mnPendingSetValidCall); 651 } 652 653 654 void ToolBarManager::Implementation::ToolBarsDestroyed(void) 655 { 656 maToolBarList.MarkAllToolBarsAsNotActive(); 657 } 658 659 660 void ToolBarManager::Implementation::SetValid (bool bValid) 661 { 662 ::osl::MutexGuard aGuard(maMutex); 663 664 if (mbIsValid != bValid) 665 { 666 UpdateLockImplementation aUpdateLock (*this); 667 668 mbIsValid = bValid; 669 if (mbIsValid) 670 { 671 Reference<frame::XFrame> xFrame; 672 if (mrBase.GetViewFrame() != NULL) 673 xFrame = mrBase.GetViewFrame()->GetFrame().GetFrameInterface(); 674 try 675 { 676 Reference<beans::XPropertySet> xFrameProperties (xFrame, UNO_QUERY_THROW); 677 Any aValue (xFrameProperties->getPropertyValue(OUSTRING("LayoutManager"))); 678 aValue >>= mxLayouter; 679 } 680 catch (RuntimeException aException) 681 { 682 } 683 684 GetToolBarRules().Update(mrBase); 685 } 686 else 687 { 688 ResetAllToolBars(); 689 mxLayouter = NULL; 690 } 691 } 692 } 693 694 695 696 697 void ToolBarManager::Implementation::ResetToolBars (ToolBarGroup eGroup) 698 { 699 ::osl::MutexGuard aGuard(maMutex); 700 701 maToolBarList.ClearGroup(eGroup); 702 maToolBarShellList.ClearGroup(eGroup); 703 704 mbPreUpdatePending = true; 705 } 706 707 708 709 710 void ToolBarManager::Implementation::ResetAllToolBars (void) 711 { 712 #ifdef VERBOSE 713 OSL_TRACE("resetting all tool bars\n"); 714 #endif 715 for (int i=TBG__FIRST; i<=TBG__LAST; ++i) 716 ResetToolBars((ToolBarGroup)i); 717 } 718 719 720 721 722 void ToolBarManager::Implementation::AddToolBar ( 723 ToolBarGroup eGroup, 724 const ::rtl::OUString& rsToolBarName) 725 { 726 ::osl::MutexGuard aGuard(maMutex); 727 728 if (CheckPlugInMode(rsToolBarName)) 729 { 730 maToolBarList.AddToolBar(eGroup,rsToolBarName); 731 732 mbPostUpdatePending = true; 733 if (mnLockCount == 0) 734 PostUpdate(); 735 } 736 } 737 738 739 740 741 void ToolBarManager::Implementation::RemoveToolBar ( 742 ToolBarGroup eGroup, 743 const ::rtl::OUString& rsToolBarName) 744 { 745 ::osl::MutexGuard aGuard(maMutex); 746 747 if (maToolBarList.RemoveToolBar(eGroup,rsToolBarName)) 748 { 749 mbPreUpdatePending = true; 750 if (mnLockCount == 0) 751 PreUpdate(); 752 } 753 } 754 755 756 757 758 void ToolBarManager::Implementation::AddToolBarShell ( 759 ToolBarGroup eGroup, 760 ShellId nToolBarId) 761 { 762 ViewShell* pMainViewShell = mrBase.GetMainViewShell().get(); 763 if (pMainViewShell != NULL) 764 { 765 maToolBarShellList.AddShellId(eGroup,nToolBarId); 766 GetToolBarRules().SubShellAdded(eGroup, nToolBarId); 767 } 768 } 769 770 771 772 773 void ToolBarManager::Implementation::ReleaseAllToolBarShells (void) 774 { 775 maToolBarShellList.ReleaseAllShells(GetToolBarRules()); 776 maToolBarShellList.UpdateShells(mrBase.GetMainViewShell(), mrBase.GetViewShellManager()); 777 } 778 779 780 781 782 void ToolBarManager::Implementation::RequestUpdate (void) 783 { 784 if (mnPendingUpdateCall == 0) 785 { 786 mnPendingUpdateCall = Application::PostUserEvent( 787 LINK(this,ToolBarManager::Implementation,UpdateCallback)); 788 } 789 } 790 791 792 793 794 void ToolBarManager::Implementation::PreUpdate (void) 795 { 796 ::osl::MutexGuard aGuard(maMutex); 797 798 if (mbIsValid 799 && mbPreUpdatePending 800 && mxLayouter.is()) 801 { 802 mbPreUpdatePending = false; 803 804 #ifdef VERBOSE 805 OSL_TRACE("ToolBarManager::PreUpdate ["); 806 #endif 807 808 // Get the list of tool bars that are not used anymore and are to be 809 // deactivated. 810 NameList aToolBars; 811 maToolBarList.GetToolBarsToDeactivate(aToolBars); 812 813 // Turn off the tool bars. 814 NameList::const_iterator iToolBar; 815 for (iToolBar=aToolBars.begin(); iToolBar!=aToolBars.end(); ++iToolBar) 816 { 817 ::rtl::OUString sFullName (GetToolBarResourceName(*iToolBar)); 818 #ifdef VERBOSE 819 OSL_TRACE(" turning off tool bar %s", 820 ::rtl::OUStringToOString(sFullName, RTL_TEXTENCODING_UTF8).getStr()); 821 #endif 822 mxLayouter->destroyElement(sFullName); 823 maToolBarList.MarkToolBarAsNotActive(*iToolBar); 824 } 825 826 #ifdef VERBOSE 827 OSL_TRACE("ToolBarManager::PreUpdate ]\n"); 828 #endif 829 } 830 } 831 832 833 834 835 void ToolBarManager::Implementation::PostUpdate (void) 836 { 837 ::osl::MutexGuard aGuard(maMutex); 838 839 if (mbIsValid 840 && mbPostUpdatePending 841 && mxLayouter.is()) 842 { 843 mbPostUpdatePending = false; 844 845 // Create the list of requested tool bars. 846 NameList aToolBars; 847 maToolBarList.GetToolBarsToActivate(aToolBars); 848 849 #ifdef VERBOSE 850 OSL_TRACE("ToolBarManager::PostUpdate ["); 851 #endif 852 853 // Turn on the tool bars that are visible in the new context. 854 NameList::const_iterator iToolBar; 855 for (iToolBar=aToolBars.begin(); iToolBar!=aToolBars.end(); ++iToolBar) 856 { 857 ::rtl::OUString sFullName (GetToolBarResourceName(*iToolBar)); 858 #ifdef VERBOSE 859 OSL_TRACE(" turning on tool bar %s", 860 ::rtl::OUStringToOString(sFullName, RTL_TEXTENCODING_UTF8).getStr()); 861 #endif 862 mxLayouter->requestElement(sFullName); 863 maToolBarList.MarkToolBarAsActive(*iToolBar); 864 } 865 866 #ifdef VERBOSE 867 OSL_TRACE("ToolBarManager::PostUpdate ]\n"); 868 #endif 869 } 870 } 871 872 873 874 875 void ToolBarManager::Implementation::LockViewShellManager (void) 876 { 877 if (mpViewShellManagerLock.get() == NULL) 878 mpViewShellManagerLock.reset( 879 new ViewShellManager::UpdateLock(mrBase.GetViewShellManager())); 880 } 881 882 883 884 885 void ToolBarManager::Implementation::LockUpdate (void) 886 { 887 #ifdef VERBOSE 888 OSL_TRACE("LockUpdate %d\n", mnLockCount); 889 #endif 890 ::osl::MutexGuard aGuard(maMutex); 891 892 DBG_ASSERT(mnLockCount<100, "ToolBarManager lock count unusually high"); 893 if (mnLockCount == 0) 894 { 895 OSL_ASSERT(mpSynchronousLayouterLock.get()==NULL); 896 897 mpSynchronousLayouterLock.reset(new LayouterLock(mxLayouter)); 898 } 899 ++mnLockCount; 900 } 901 902 903 904 905 void ToolBarManager::Implementation::UnlockUpdate (void) 906 { 907 #ifdef VERBOSE 908 OSL_TRACE("UnlockUpdate %d\n", mnLockCount); 909 #endif 910 ::osl::MutexGuard aGuard(maMutex); 911 912 OSL_ASSERT(mnLockCount>0); 913 --mnLockCount; 914 if (mnLockCount == 0) 915 { 916 Update(mpSynchronousLayouterLock); 917 } 918 } 919 920 921 922 923 void ToolBarManager::Implementation::Update ( 924 ::std::auto_ptr<LayouterLock> pLocalLayouterLock) 925 { 926 // When the lock is released and there are pending changes to the set of 927 // tool bars then update this set now. 928 if (mnLockCount == 0) 929 { 930 // During ceation of ViewShellBase we may have the situation that 931 // the controller has already been created and attached to the frame 932 // but that the ToolBarManager has not yet completed its 933 // initialization (by initializing the mxLayouter member.) We do 934 // this here so that we do not have to wait for the next Update() 935 // call to show the tool bars. 936 if (mnPendingSetValidCall != 0) 937 { 938 Application::RemoveUserEvent(mnPendingSetValidCall); 939 mnPendingSetValidCall = 0; 940 SetValid(true); 941 } 942 943 if (mbIsValid && mxLayouter.is() && (mbPreUpdatePending || mbPostUpdatePending)) 944 { 945 // 1) Release UNO tool bars that are not longer used. Do this 946 // now so that they are not updated when the SFX shell stack is 947 // modified. 948 if (mbPreUpdatePending) 949 PreUpdate(); 950 951 // 2) Update the requested shells that represent tool bar 952 // functionality. Those that are not used anymore are 953 // deactivated now. Those that are missing are activated in the 954 // next step together with the view shells. 955 if (mpViewShellManagerLock.get() == NULL) 956 mpViewShellManagerLock.reset( 957 new ViewShellManager::UpdateLock(mrBase.GetViewShellManager())); 958 maToolBarShellList.UpdateShells( 959 mrBase.GetMainViewShell(), 960 mrBase.GetViewShellManager()); 961 962 // 3) Unlock the ViewShellManager::UpdateLock. This updates the 963 // shell stack. We have to be carfull here. The deletion of 964 // the lock may end in a synchronous call to LockUpdate(). When 965 // at this time the lock has been deleted but the auto_ptr has 966 // not yet been reset then the lock is deleted a second time. 967 ViewShellManager::UpdateLock* pLock = mpViewShellManagerLock.release(); 968 delete pLock; 969 970 // 4) Make the UNO tool bars visible. The outstanding call to 971 // PostUpdate() is done via PostUserEvent() so that it is 972 // guaranteed to be executed when the SFX shell stack has been 973 // updated (under the assumption that our lock to the 974 // ViewShellManager was the only one open. If that is not the 975 // case then all should still be well but not as fast.) 976 // 977 // Note that the lock count may have been increased since 978 // entering this method. In that case one of the next 979 // UnlockUpdate() calls will post the UpdateCallback. 980 if (mnPendingUpdateCall==0 && mnLockCount==0) 981 { 982 mpAsynchronousLayouterLock = pLocalLayouterLock; 983 mnPendingUpdateCall = Application::PostUserEvent( 984 LINK(this,ToolBarManager::Implementation,UpdateCallback)); 985 } 986 } 987 else 988 { 989 mpViewShellManagerLock.reset(); 990 pLocalLayouterLock.reset(); 991 } 992 } 993 } 994 995 996 997 998 ToolBarRules& ToolBarManager::Implementation::GetToolBarRules (void) 999 { 1000 return maToolBarRules; 1001 } 1002 1003 1004 1005 1006 IMPL_LINK(ToolBarManager::Implementation,UpdateCallback,bool*,EMPTYARG) 1007 { 1008 mnPendingUpdateCall = 0; 1009 if (mnLockCount == 0) 1010 { 1011 if (mbPreUpdatePending) 1012 PreUpdate(); 1013 if (mbPostUpdatePending) 1014 PostUpdate(); 1015 if (mbIsValid && mxLayouter.is()) 1016 mpAsynchronousLayouterLock.reset(); 1017 } 1018 return 0; 1019 } 1020 1021 1022 1023 1024 IMPL_LINK(ToolBarManager::Implementation,EventMultiplexerCallback, 1025 sd::tools::EventMultiplexerEvent*,pEvent) 1026 { 1027 if (pEvent != NULL) 1028 { 1029 switch (pEvent->meEventId) 1030 { 1031 case tools::EventMultiplexerEvent::EID_CONTROLLER_ATTACHED: 1032 if (mnPendingSetValidCall == 0) 1033 mnPendingSetValidCall 1034 = Application::PostUserEvent(LINK(this,Implementation,SetValidCallback)); 1035 break; 1036 1037 case tools::EventMultiplexerEvent::EID_CONTROLLER_DETACHED: 1038 SetValid(false); 1039 break; 1040 1041 case tools::EventMultiplexerEvent::EID_PANE_MANAGER_DYING: 1042 SetValid(false); 1043 break; 1044 } 1045 } 1046 return 0; 1047 } 1048 1049 1050 1051 1052 IMPL_LINK(ToolBarManager::Implementation, SetValidCallback,void*,EMPTYARG) 1053 { 1054 mnPendingSetValidCall = 0; 1055 SetValid(true); 1056 return 0; 1057 } 1058 1059 1060 1061 1062 1063 ::rtl::OUString ToolBarManager::Implementation::GetToolBarResourceName ( 1064 const ::rtl::OUString& rsBaseName) const 1065 { 1066 ::rtl::OUString sToolBarName (msToolBarResourcePrefix); 1067 sToolBarName += rsBaseName; 1068 return sToolBarName; 1069 } 1070 1071 1072 1073 1074 bool ToolBarManager::Implementation::CheckPlugInMode (const ::rtl::OUString& rsName) const 1075 { 1076 bool bValid (false); 1077 1078 // Determine the plug in mode. 1079 bool bIsPlugInMode (false); 1080 do 1081 { 1082 SfxObjectShell* pObjectShell = mrBase.GetObjectShell(); 1083 if (pObjectShell == NULL) 1084 break; 1085 1086 SfxMedium* pMedium = pObjectShell->GetMedium(); 1087 if (pMedium == NULL) 1088 break; 1089 1090 SFX_ITEMSET_ARG(pMedium->GetItemSet(),pViewOnlyItem,SfxBoolItem,SID_VIEWONLY,sal_False); 1091 if (pViewOnlyItem == NULL) 1092 break; 1093 1094 bIsPlugInMode = pViewOnlyItem->GetValue(); 1095 } 1096 while (false); 1097 1098 if (rsName.equals(msViewerToolBar)) 1099 bValid = bIsPlugInMode; 1100 else 1101 bValid = ! bIsPlugInMode; 1102 1103 return bValid; 1104 } 1105 1106 1107 1108 1109 } // end of namespace sd 1110 1111 1112 1113 1114 namespace { 1115 1116 using namespace ::sd; 1117 1118 //===== LayouterLock ========================================================== 1119 1120 LayouterLock::LayouterLock (const Reference<frame::XLayoutManager>& rxLayouter) 1121 : mxLayouter(rxLayouter) 1122 { 1123 #ifdef VERBOSE 1124 OSL_TRACE("LayouterLock %d", mxLayouter.is() ? 1 :0); 1125 #endif 1126 if (mxLayouter.is()) 1127 mxLayouter->lock(); 1128 } 1129 1130 1131 1132 1133 LayouterLock::~LayouterLock (void) 1134 { 1135 #ifdef VERBOSE 1136 OSL_TRACE("~LayouterLock %d", mxLayouter.is() ? 1 :0); 1137 #endif 1138 if (mxLayouter.is()) 1139 mxLayouter->unlock(); 1140 } 1141 1142 1143 1144 1145 //===== ToolBarRules ========================================================== 1146 1147 ToolBarRules::ToolBarRules ( 1148 const ::boost::shared_ptr<sd::ToolBarManager>& rpToolBarManager, 1149 const ::boost::shared_ptr<sd::ViewShellManager>& rpViewShellManager) 1150 : mpToolBarManager(rpToolBarManager), 1151 mpViewShellManager(rpViewShellManager) 1152 { 1153 } 1154 1155 1156 1157 1158 void ToolBarRules::Update (ViewShellBase& rBase) 1159 { 1160 ViewShell* pMainViewShell = rBase.GetMainViewShell().get(); 1161 if (pMainViewShell != NULL) 1162 { 1163 MainViewShellChanged(pMainViewShell->GetShellType()); 1164 if (pMainViewShell->GetView()) 1165 SelectionHasChanged (*pMainViewShell, *pMainViewShell->GetView()); 1166 } 1167 else 1168 MainViewShellChanged(ViewShell::ST_NONE); 1169 } 1170 1171 1172 1173 1174 void ToolBarRules::MainViewShellChanged (ViewShell::ShellType nShellType) 1175 { 1176 ::sd::ToolBarManager::UpdateLock aToolBarManagerLock (mpToolBarManager); 1177 ::sd::ViewShellManager::UpdateLock aViewShellManagerLock (mpViewShellManager); 1178 1179 mpToolBarManager->ResetAllToolBars(); 1180 1181 switch(nShellType) 1182 { 1183 case ::sd::ViewShell::ST_IMPRESS: 1184 case ::sd::ViewShell::ST_NOTES: 1185 case ::sd::ViewShell::ST_HANDOUT: 1186 mpToolBarManager->AddToolBar( 1187 ToolBarManager::TBG_PERMANENT, 1188 ToolBarManager::msToolBar); 1189 mpToolBarManager->AddToolBar( 1190 ToolBarManager::TBG_PERMANENT, 1191 ToolBarManager::msOptionsToolBar); 1192 mpToolBarManager->AddToolBar( 1193 ToolBarManager::TBG_PERMANENT, 1194 ToolBarManager::msCommonTaskToolBar); 1195 mpToolBarManager->AddToolBar( 1196 ToolBarManager::TBG_PERMANENT, 1197 ToolBarManager::msViewerToolBar); 1198 break; 1199 1200 case ::sd::ViewShell::ST_DRAW: 1201 mpToolBarManager->AddToolBar( 1202 ToolBarManager::TBG_PERMANENT, 1203 ToolBarManager::msToolBar); 1204 mpToolBarManager->AddToolBar( 1205 ToolBarManager::TBG_PERMANENT, 1206 ToolBarManager::msOptionsToolBar); 1207 mpToolBarManager->AddToolBar( 1208 ToolBarManager::TBG_PERMANENT, 1209 ToolBarManager::msViewerToolBar); 1210 break; 1211 1212 case ViewShell::ST_OUTLINE: 1213 mpToolBarManager->AddToolBar( 1214 ToolBarManager::TBG_PERMANENT, 1215 ToolBarManager::msOutlineToolBar); 1216 mpToolBarManager->AddToolBar( 1217 ToolBarManager::TBG_PERMANENT, 1218 ToolBarManager::msViewerToolBar); 1219 mpToolBarManager->AddToolBarShell( 1220 ToolBarManager::TBG_PERMANENT, RID_DRAW_TEXT_TOOLBOX); 1221 break; 1222 1223 case ViewShell::ST_SLIDE_SORTER: 1224 mpToolBarManager->AddToolBar( 1225 ToolBarManager::TBG_PERMANENT, 1226 ToolBarManager::msViewerToolBar); 1227 mpToolBarManager->AddToolBar( 1228 ToolBarManager::TBG_PERMANENT, 1229 ToolBarManager::msSlideSorterToolBar); 1230 mpToolBarManager->AddToolBar( 1231 ToolBarManager::TBG_PERMANENT, 1232 ToolBarManager::msSlideSorterObjectBar); 1233 break; 1234 1235 case ViewShell::ST_NONE: 1236 case ViewShell::ST_PRESENTATION: 1237 case ViewShell::ST_TASK_PANE: 1238 default: 1239 break; 1240 } 1241 } 1242 1243 1244 1245 1246 void ToolBarRules::MainViewShellChanged (const ViewShell& rMainViewShell) 1247 { 1248 ::sd::ToolBarManager::UpdateLock aToolBarManagerLock (mpToolBarManager); 1249 ::sd::ViewShellManager::UpdateLock aViewShellManagerLock (mpViewShellManager); 1250 1251 MainViewShellChanged(rMainViewShell.GetShellType()); 1252 switch(rMainViewShell.GetShellType()) 1253 { 1254 case ::sd::ViewShell::ST_IMPRESS: 1255 case ::sd::ViewShell::ST_DRAW: 1256 case ::sd::ViewShell::ST_NOTES: 1257 { 1258 const DrawViewShell* pDrawViewShell 1259 = dynamic_cast<const DrawViewShell*>(&rMainViewShell); 1260 if (pDrawViewShell != NULL) 1261 if (pDrawViewShell->GetEditMode() == EM_MASTERPAGE) 1262 mpToolBarManager->AddToolBar( 1263 ToolBarManager::TBG_MASTER_MODE, 1264 ToolBarManager::msMasterViewToolBar); 1265 break; 1266 } 1267 1268 default: 1269 break; 1270 } 1271 } 1272 1273 1274 1275 1276 void ToolBarRules::SelectionHasChanged ( 1277 const ::sd::ViewShell& rViewShell, 1278 const SdrView& rView) 1279 { 1280 ::sd::ToolBarManager::UpdateLock aLock (mpToolBarManager); 1281 mpToolBarManager->LockViewShellManager(); 1282 bool bTextEdit = rView.IsTextEdit(); 1283 1284 mpToolBarManager->ResetToolBars(ToolBarManager::TBG_FUNCTION); 1285 1286 switch (rView.GetContext()) 1287 { 1288 case SDRCONTEXT_GRAPHIC: 1289 if( !bTextEdit ) 1290 mpToolBarManager->SetToolBarShell(ToolBarManager::TBG_FUNCTION, RID_DRAW_GRAF_TOOLBOX); 1291 break; 1292 1293 case SDRCONTEXT_MEDIA: 1294 if( !bTextEdit ) 1295 mpToolBarManager->SetToolBarShell(ToolBarManager::TBG_FUNCTION, RID_DRAW_MEDIA_TOOLBOX); 1296 break; 1297 1298 case SDRCONTEXT_TABLE: 1299 mpToolBarManager->SetToolBarShell(ToolBarManager::TBG_FUNCTION, RID_DRAW_TABLE_TOOLBOX); 1300 bTextEdit = true; 1301 break; 1302 1303 case SDRCONTEXT_STANDARD: 1304 default: 1305 if( !bTextEdit ) 1306 { 1307 switch(rViewShell.GetShellType()) 1308 { 1309 case ::sd::ViewShell::ST_IMPRESS: 1310 case ::sd::ViewShell::ST_DRAW: 1311 case ::sd::ViewShell::ST_NOTES: 1312 case ::sd::ViewShell::ST_HANDOUT: 1313 mpToolBarManager->SetToolBar( 1314 ToolBarManager::TBG_FUNCTION, 1315 ToolBarManager::msDrawingObjectToolBar); 1316 break; 1317 default: 1318 break; 1319 } 1320 break; 1321 } 1322 } 1323 1324 if( bTextEdit ) 1325 mpToolBarManager->AddToolBarShell(ToolBarManager::TBG_FUNCTION, RID_DRAW_TEXT_TOOLBOX); 1326 1327 SdrView* pView = &const_cast<SdrView&>(rView); 1328 // Check if the extrusion tool bar and the fontwork tool bar have to 1329 // be activated. 1330 if (svx::checkForSelectedCustomShapes(pView, true /* bOnlyExtruded */ )) 1331 mpToolBarManager->AddToolBarShell(ToolBarManager::TBG_FUNCTION, RID_SVX_EXTRUSION_BAR); 1332 sal_uInt32 nCheckStatus = 0; 1333 if (svx::checkForSelectedFontWork(pView, nCheckStatus)) 1334 mpToolBarManager->AddToolBarShell(ToolBarManager::TBG_FUNCTION, RID_SVX_FONTWORK_BAR); 1335 1336 // Switch on additional context-sensitive tool bars. 1337 if (rView.GetContext() == SDRCONTEXT_POINTEDIT) 1338 mpToolBarManager->AddToolBarShell(ToolBarManager::TBG_FUNCTION, RID_BEZIER_TOOLBOX); 1339 } 1340 1341 1342 1343 1344 void ToolBarRules::SubShellAdded ( 1345 ::sd::ToolBarManager::ToolBarGroup eGroup, 1346 sd::ShellId nShellId) 1347 { 1348 // For some tool bar shells (those defined in sd) we have to add the 1349 // actual tool bar here. 1350 switch (nShellId) 1351 { 1352 case RID_DRAW_GRAF_TOOLBOX: 1353 mpToolBarManager->AddToolBar(eGroup, ToolBarManager::msGraphicObjectBar); 1354 break; 1355 1356 case RID_DRAW_MEDIA_TOOLBOX: 1357 mpToolBarManager->AddToolBar(eGroup, ToolBarManager::msMediaObjectBar); 1358 break; 1359 1360 case RID_DRAW_TEXT_TOOLBOX: 1361 mpToolBarManager->AddToolBar(eGroup, ToolBarManager::msTextObjectBar); 1362 break; 1363 1364 case RID_BEZIER_TOOLBOX: 1365 mpToolBarManager->AddToolBar(eGroup, ToolBarManager::msBezierObjectBar); 1366 break; 1367 1368 case RID_DRAW_TABLE_TOOLBOX: 1369 mpToolBarManager->AddToolBar(eGroup, ToolBarManager::msTableObjectBar); 1370 break; 1371 } 1372 } 1373 1374 1375 1376 1377 void ToolBarRules::SubShellRemoved ( 1378 ::sd::ToolBarManager::ToolBarGroup eGroup, 1379 sd::ShellId nShellId) 1380 { 1381 // For some tool bar shells (those defined in sd) we have to add the 1382 // actual tool bar here. 1383 switch (nShellId) 1384 { 1385 case RID_DRAW_GRAF_TOOLBOX: 1386 mpToolBarManager->RemoveToolBar(eGroup, ToolBarManager::msGraphicObjectBar); 1387 break; 1388 1389 case RID_DRAW_MEDIA_TOOLBOX: 1390 mpToolBarManager->RemoveToolBar(eGroup, ToolBarManager::msMediaObjectBar); 1391 break; 1392 1393 case RID_DRAW_TEXT_TOOLBOX: 1394 mpToolBarManager->RemoveToolBar(eGroup, ToolBarManager::msTextObjectBar); 1395 break; 1396 1397 case RID_BEZIER_TOOLBOX: 1398 mpToolBarManager->RemoveToolBar(eGroup, ToolBarManager::msBezierObjectBar); 1399 break; 1400 1401 case RID_DRAW_TABLE_TOOLBOX: 1402 mpToolBarManager->RemoveToolBar(eGroup, ToolBarManager::msTableObjectBar); 1403 break; 1404 } 1405 } 1406 1407 1408 1409 1410 //===== ToolBarList =========================================================== 1411 1412 ToolBarList::ToolBarList (void) 1413 : maGroups(), 1414 maActiveToolBars() 1415 { 1416 } 1417 1418 1419 1420 1421 void ToolBarList::ClearGroup (sd::ToolBarManager::ToolBarGroup eGroup) 1422 { 1423 Groups::iterator iGroup (maGroups.find(eGroup)); 1424 if (iGroup != maGroups.end()) 1425 { 1426 if ( ! iGroup->second.empty()) 1427 { 1428 iGroup->second.clear(); 1429 } 1430 } 1431 } 1432 1433 1434 1435 1436 void ToolBarList::AddToolBar ( 1437 sd::ToolBarManager::ToolBarGroup eGroup, 1438 const ::rtl::OUString& rsName) 1439 { 1440 Groups::iterator iGroup (maGroups.find(eGroup)); 1441 if (iGroup == maGroups.end()) 1442 iGroup = maGroups.insert(Groups::value_type(eGroup,NameList())).first; 1443 1444 if (iGroup != maGroups.end()) 1445 { 1446 NameList::const_iterator iBar ( 1447 ::std::find(iGroup->second.begin(),iGroup->second.end(),rsName)); 1448 if (iBar == iGroup->second.end()) 1449 { 1450 iGroup->second.push_back(rsName); 1451 } 1452 } 1453 } 1454 1455 1456 1457 1458 bool ToolBarList::RemoveToolBar ( 1459 sd::ToolBarManager::ToolBarGroup eGroup, 1460 const ::rtl::OUString& rsName) 1461 { 1462 Groups::iterator iGroup (maGroups.find(eGroup)); 1463 if (iGroup != maGroups.end()) 1464 { 1465 NameList::iterator iBar ( 1466 ::std::find(iGroup->second.begin(),iGroup->second.end(),rsName)); 1467 if (iBar != iGroup->second.end()) 1468 { 1469 iGroup->second.erase(iBar); 1470 return true; 1471 } 1472 } 1473 return false; 1474 } 1475 1476 1477 1478 1479 void ToolBarList::MakeRequestedToolBarList (NameList& rRequestedToolBars) const 1480 { 1481 for (int i=sd::ToolBarManager::TBG__FIRST; i<=sd::ToolBarManager::TBG__LAST; ++i) 1482 { 1483 ::sd::ToolBarManager::ToolBarGroup eGroup = (::sd::ToolBarManager::ToolBarGroup)i; 1484 Groups::const_iterator iGroup (maGroups.find(eGroup)); 1485 if (iGroup != maGroups.end()) 1486 ::std::copy( 1487 iGroup->second.begin(), 1488 iGroup->second.end(), 1489 ::std::inserter(rRequestedToolBars,rRequestedToolBars.end())); 1490 } 1491 } 1492 1493 1494 1495 1496 void ToolBarList::GetToolBarsToActivate (NameList& rToolBars) const 1497 { 1498 NameList aRequestedToolBars; 1499 MakeRequestedToolBarList(aRequestedToolBars); 1500 1501 NameList::const_iterator iToolBar; 1502 for (iToolBar=aRequestedToolBars.begin(); iToolBar!=aRequestedToolBars.end(); ++iToolBar) 1503 { 1504 if (::std::find(maActiveToolBars.begin(),maActiveToolBars.end(),*iToolBar) 1505 == maActiveToolBars.end()) 1506 { 1507 rToolBars.push_back(*iToolBar); 1508 } 1509 } 1510 } 1511 1512 1513 1514 1515 void ToolBarList::GetToolBarsToDeactivate (NameList& rToolBars) const 1516 { 1517 NameList aRequestedToolBars; 1518 MakeRequestedToolBarList(aRequestedToolBars); 1519 1520 NameList::const_iterator iToolBar; 1521 for (iToolBar=maActiveToolBars.begin(); iToolBar!=maActiveToolBars.end(); ++iToolBar) 1522 { 1523 if (::std::find(aRequestedToolBars.begin(),aRequestedToolBars.end(),*iToolBar) 1524 == aRequestedToolBars.end()) 1525 { 1526 rToolBars.push_back(*iToolBar); 1527 } 1528 } 1529 } 1530 1531 1532 1533 1534 void ToolBarList::MarkToolBarAsActive (const ::rtl::OUString& rsName) 1535 { 1536 maActiveToolBars.push_back(rsName); 1537 } 1538 1539 1540 1541 1542 void ToolBarList::MarkToolBarAsNotActive (const ::rtl::OUString& rsName) 1543 { 1544 maActiveToolBars.erase( 1545 ::std::find(maActiveToolBars.begin(),maActiveToolBars.end(), rsName)); 1546 } 1547 1548 1549 1550 1551 void ToolBarList::MarkAllToolBarsAsNotActive (void) 1552 { 1553 maActiveToolBars.clear(); 1554 } 1555 1556 1557 1558 1559 //===== ToolBarShellList ====================================================== 1560 1561 ToolBarShellList::ShellDescriptor::ShellDescriptor ( 1562 ShellId nId, 1563 sd::ToolBarManager::ToolBarGroup eGroup) 1564 : mnId(nId), 1565 meGroup(eGroup) 1566 { 1567 } 1568 1569 1570 1571 1572 ToolBarShellList::ToolBarShellList (void) 1573 : maNewList() 1574 , maCurrentList() 1575 { 1576 } 1577 1578 1579 1580 1581 void ToolBarShellList::ClearGroup (sd::ToolBarManager::ToolBarGroup eGroup) 1582 { 1583 // In every loop we erase the first member of the specified group. 1584 // Because that invalidates the iterator another loop is started after 1585 // that. The loop is left only when no member of the group is found and 1586 // no element is erased 1587 bool bLoop; 1588 do 1589 { 1590 bLoop = false; 1591 1592 GroupedShellList::iterator iDescriptor; 1593 for (iDescriptor=maNewList.begin(); iDescriptor!=maNewList.end(); ++iDescriptor) 1594 if (iDescriptor->meGroup == eGroup) 1595 { 1596 maNewList.erase(iDescriptor); 1597 // Erasing the descriptor invalidated the iterator so we 1598 // have to exit the for loop and start anew to search for 1599 // further elements of the group. 1600 bLoop = true; 1601 break; 1602 } 1603 } 1604 while (bLoop); 1605 } 1606 1607 1608 1609 1610 void ToolBarShellList::AddShellId (sd::ToolBarManager::ToolBarGroup eGroup, sd::ShellId nId) 1611 { 1612 // Make sure that the shell is not added twice (and possibly in 1613 // different groups.) 1614 ShellDescriptor aDescriptor (nId,eGroup); 1615 GroupedShellList::iterator iDescriptor (maNewList.find(aDescriptor)); 1616 if (iDescriptor != maNewList.end()) 1617 { 1618 // The shell is already requested. 1619 if (iDescriptor->meGroup != eGroup) 1620 { 1621 // It is now being requested for another group. 1622 // (Is this an error?) 1623 // Move it to that group. 1624 maNewList.erase(iDescriptor); 1625 maNewList.insert(aDescriptor); 1626 } 1627 // else nothing to do. 1628 } 1629 else 1630 maNewList.insert(aDescriptor); 1631 } 1632 1633 1634 1635 1636 void ToolBarShellList::ReleaseAllShells (ToolBarRules& rRules) 1637 { 1638 // Release the currently active tool bars. 1639 GroupedShellList aList (maCurrentList); 1640 GroupedShellList::iterator iDescriptor; 1641 for (iDescriptor=aList.begin(); iDescriptor!=aList.end(); ++iDescriptor) 1642 { 1643 rRules.SubShellRemoved(iDescriptor->meGroup, iDescriptor->mnId); 1644 } 1645 1646 // Clear the list of requested tool bars. 1647 maNewList.clear(); 1648 } 1649 1650 1651 1652 1653 void ToolBarShellList::UpdateShells ( 1654 const ::boost::shared_ptr<ViewShell>& rpMainViewShell, 1655 const ::boost::shared_ptr<ViewShellManager>& rpManager) 1656 { 1657 if (rpMainViewShell.get() != NULL) 1658 { 1659 GroupedShellList aList; 1660 1661 // Deactivate shells that are in maCurrentList, but not in 1662 // maNewList. 1663 ::std::set_difference(maCurrentList.begin(), maCurrentList.end(), 1664 maNewList.begin(), maNewList.end(), 1665 std::insert_iterator<GroupedShellList>(aList,aList.begin())); 1666 for (GroupedShellList::iterator iShell=aList.begin(); iShell!=aList.end(); ++iShell) 1667 { 1668 #ifdef VERBOSE 1669 OSL_TRACE("deactivating tool bar shell %d\n", iShell->mnId); 1670 #endif 1671 rpManager->DeactivateSubShell(*rpMainViewShell, iShell->mnId); 1672 } 1673 1674 // Activate shells that are in maNewList, but not in 1675 // maCurrentList. 1676 aList.clear(); 1677 ::std::set_difference(maNewList.begin(), maNewList.end(), 1678 maCurrentList.begin(), maCurrentList.end(), 1679 std::insert_iterator<GroupedShellList>(aList,aList.begin())); 1680 for (GroupedShellList::iterator iShell=aList.begin(); iShell!=aList.end(); ++iShell) 1681 { 1682 #ifdef VERBOSE 1683 OSL_TRACE("activating tool bar shell %d\n", iShell->mnId); 1684 #endif 1685 rpManager->ActivateSubShell(*rpMainViewShell, iShell->mnId); 1686 } 1687 1688 // The maNewList now refelects the current state and thus is made 1689 // maCurrentList. 1690 maCurrentList = maNewList; 1691 } 1692 } 1693 1694 1695 1696 1697 } // end of anonymous namespace 1698