xref: /trunk/main/sd/source/ui/view/ToolBarManager.cxx (revision cdf0e10c)
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