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