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