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