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/unohlp.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     seperately.
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;
operator <(const ShellDescriptor & r1,const ShellDescriptor & r2)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:
UpdateLockImplementation(Implementation & rImplementation)309         UpdateLockImplementation (Implementation& rImplementation)
310             : mrImplementation(rImplementation) { mrImplementation.LockUpdate();  }
~UpdateLockImplementation(void)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 
Create(ViewShellBase & rBase,const::boost::shared_ptr<sd::tools::EventMultiplexer> & rpMultiplexer,const::boost::shared_ptr<ViewShellManager> & rpViewShellManager)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 
ToolBarManager(void)390 ToolBarManager::ToolBarManager (void)
391         : mpImpl()
392 {
393 }
394 
395 
396 
397 
~ToolBarManager(void)398 ToolBarManager::~ToolBarManager (void)
399 {
400 }
401 
402 
403 
404 
Shutdown(void)405 void ToolBarManager::Shutdown (void)
406 {
407     if (mpImpl.get() != NULL)
408         mpImpl.reset();
409 }
410 
411 
412 
413 
ResetToolBars(ToolBarGroup eGroup)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 
ResetAllToolBars(void)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 
AddToolBar(ToolBarGroup eGroup,const::rtl::OUString & rsToolBarName)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 
AddToolBarShell(ToolBarGroup eGroup,ShellId nToolBarId)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 
RemoveToolBar(ToolBarGroup eGroup,const::rtl::OUString & rsToolBarName)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 
SetToolBar(ToolBarGroup eGroup,const::rtl::OUString & rsToolBarName)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 
SetToolBarShell(ToolBarGroup eGroup,ShellId nToolBarId)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 
PreUpdate(void)510 void ToolBarManager::PreUpdate (void)
511 {
512     if (mpImpl.get()!=NULL)
513         mpImpl->PreUpdate();
514 }
515 
516 
517 
518 
RequestUpdate(void)519 void ToolBarManager::RequestUpdate (void)
520 {
521     if (mpImpl.get()!=NULL)
522         mpImpl->RequestUpdate();
523 }
524 
525 
526 
527 
LockViewShellManager(void)528 void ToolBarManager::LockViewShellManager (void)
529 {
530     if (mpImpl.get() != NULL)
531         mpImpl->LockViewShellManager();
532 }
533 
534 
535 
536 
LockUpdate(void)537 void ToolBarManager::LockUpdate (void)
538 {
539     if (mpImpl.get()!=NULL)
540         mpImpl->LockUpdate();
541 }
542 
543 
544 
545 
UnlockUpdate(void)546 void ToolBarManager::UnlockUpdate (void)
547 {
548     if (mpImpl.get()!=NULL)
549         mpImpl->UnlockUpdate();
550 }
551 
552 
553 
554 
MainViewShellChanged(ViewShell::ShellType nShellType)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 
MainViewShellChanged(const ViewShell & rMainViewShell)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 
SelectionHasChanged(const ViewShell & rViewShell,const SdrView & rView)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 
ToolBarsDestroyed(void)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 
Implementation(ViewShellBase & rBase,const::boost::shared_ptr<sd::tools::EventMultiplexer> & rpMultiplexer,const::boost::shared_ptr<ViewShellManager> & rpViewShellManager,const::boost::shared_ptr<ToolBarManager> & rpToolBarManager)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 */
~Implementation(void)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 
ToolBarsDestroyed(void)650 void ToolBarManager::Implementation::ToolBarsDestroyed(void)
651 {
652     maToolBarList.MarkAllToolBarsAsNotActive();
653 }
654 
655 
SetValid(bool bValid)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 
ResetToolBars(ToolBarGroup eGroup)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 
ResetAllToolBars(void)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 
AddToolBar(ToolBarGroup eGroup,const::rtl::OUString & rsToolBarName)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 
RemoveToolBar(ToolBarGroup eGroup,const::rtl::OUString & rsToolBarName)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 
AddToolBarShell(ToolBarGroup eGroup,ShellId nToolBarId)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 
ReleaseAllToolBarShells(void)769 void ToolBarManager::Implementation::ReleaseAllToolBarShells (void)
770 {
771     maToolBarShellList.ReleaseAllShells(GetToolBarRules());
772     maToolBarShellList.UpdateShells(mrBase.GetMainViewShell(), mrBase.GetViewShellManager());
773 }
774 
775 
776 
777 
RequestUpdate(void)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 
PreUpdate(void)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 
PostUpdate(void)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 
LockViewShellManager(void)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 
LockUpdate(void)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 
UnlockUpdate(void)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 
Update(::std::auto_ptr<LayouterLock> pLocalLayouterLock)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 
GetToolBarRules(void)994 ToolBarRules& ToolBarManager::Implementation::GetToolBarRules (void)
995 {
996     return maToolBarRules;
997 }
998 
999 
1000 
1001 
IMPL_LINK(ToolBarManager::Implementation,UpdateCallback,bool *,EMPTYARG)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 
IMPL_LINK(ToolBarManager::Implementation,EventMultiplexerCallback,sd::tools::EventMultiplexerEvent *,pEvent)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 
IMPL_LINK(ToolBarManager::Implementation,SetValidCallback,void *,EMPTYARG)1048 IMPL_LINK(ToolBarManager::Implementation, SetValidCallback,void*,EMPTYARG)
1049 {
1050     mnPendingSetValidCall = 0;
1051     SetValid(true);
1052     return 0;
1053 }
1054 
1055 
1056 
1057 
1058 
GetToolBarResourceName(const::rtl::OUString & rsBaseName) const1059 ::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 
CheckPlugInMode(const::rtl::OUString & rsName) const1070 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 
LayouterLock(const Reference<frame::XLayoutManager> & rxLayouter)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 
~LayouterLock(void)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 
ToolBarRules(const::boost::shared_ptr<sd::ToolBarManager> & rpToolBarManager,const::boost::shared_ptr<sd::ViewShellManager> & rpViewShellManager)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 
Update(ViewShellBase & rBase)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 
MainViewShellChanged(ViewShell::ShellType nShellType)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 
MainViewShellChanged(const ViewShell & rMainViewShell)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 
SelectionHasChanged(const::sd::ViewShell & rViewShell,const SdrView & rView)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 
SubShellAdded(::sd::ToolBarManager::ToolBarGroup eGroup,sd::ShellId nShellId)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 
SubShellRemoved(::sd::ToolBarManager::ToolBarGroup eGroup,sd::ShellId nShellId)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 
ToolBarList(void)1408 ToolBarList::ToolBarList (void)
1409     : maGroups(),
1410       maActiveToolBars()
1411 {
1412 }
1413 
1414 
1415 
1416 
ClearGroup(sd::ToolBarManager::ToolBarGroup eGroup)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 
AddToolBar(sd::ToolBarManager::ToolBarGroup eGroup,const::rtl::OUString & rsName)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 
RemoveToolBar(sd::ToolBarManager::ToolBarGroup eGroup,const::rtl::OUString & rsName)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 
MakeRequestedToolBarList(NameList & rRequestedToolBars) const1475 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 
GetToolBarsToActivate(NameList & rToolBars) const1492 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 
GetToolBarsToDeactivate(NameList & rToolBars) const1511 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 
MarkToolBarAsActive(const::rtl::OUString & rsName)1530 void ToolBarList::MarkToolBarAsActive (const ::rtl::OUString& rsName)
1531 {
1532     maActiveToolBars.push_back(rsName);
1533 }
1534 
1535 
1536 
1537 
MarkToolBarAsNotActive(const::rtl::OUString & rsName)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 
MarkAllToolBarsAsNotActive(void)1547 void ToolBarList::MarkAllToolBarsAsNotActive (void)
1548 {
1549     maActiveToolBars.clear();
1550 }
1551 
1552 
1553 
1554 
1555 //===== ToolBarShellList ======================================================
1556 
ShellDescriptor(ShellId nId,sd::ToolBarManager::ToolBarGroup eGroup)1557 ToolBarShellList::ShellDescriptor::ShellDescriptor (
1558     ShellId nId,
1559     sd::ToolBarManager::ToolBarGroup eGroup)
1560     : mnId(nId),
1561       meGroup(eGroup)
1562 {
1563 }
1564 
1565 
1566 
1567 
ToolBarShellList(void)1568 ToolBarShellList::ToolBarShellList (void)
1569 : maNewList()
1570 , maCurrentList()
1571 {
1572 }
1573 
1574 
1575 
1576 
ClearGroup(sd::ToolBarManager::ToolBarGroup eGroup)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 
AddShellId(sd::ToolBarManager::ToolBarGroup eGroup,sd::ShellId nId)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 
ReleaseAllShells(ToolBarRules & rRules)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 
UpdateShells(const::boost::shared_ptr<ViewShell> & rpMainViewShell,const::boost::shared_ptr<ViewShellManager> & rpManager)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