1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <ToolBarManager.hxx>
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>
29 #include <sal/log.hxx>
30 #include <osl/mutex.hxx>
31 #include <o3tl/deleter.hxx>
32 #include <o3tl/enumrange.hxx>
33 #include <sfx2/docfile.hxx>
34 #include <sfx2/objsh.hxx>
35 #include <sfx2/toolbarids.hxx>
36 #include <sfx2/viewfrm.hxx>
37 #include <svl/eitem.hxx>
38 #include <svx/svxids.hrc>
39 #include <svx/extrusionbar.hxx>
40 #include <svx/fontworkbar.hxx>
41 #include <tools/debug.hxx>
42 #include <tools/link.hxx>
43 #include <vcl/svapp.hxx>
50 using namespace ::com::sun::star
;
51 using namespace ::com::sun::star::uno
;
59 /** Lock of the frame::XLayoutManager.
63 Reference
<frame::XLayoutManager
> mxLayouter
;
65 explicit LayouterLock (const Reference
<frame::XLayoutManager
>& rxLayouter
);
67 bool is() const { return mxLayouter
.is(); }
70 /** Store a list of tool bars for each of the tool bar groups. From
71 this the list of requested tool bars is built.
78 void ClearGroup (sd::ToolBarManager::ToolBarGroup eGroup
);
79 void AddToolBar (sd::ToolBarManager::ToolBarGroup eGroup
, const OUString
& rsName
);
80 bool RemoveToolBar (sd::ToolBarManager::ToolBarGroup eGroup
, const OUString
& rsName
);
82 void GetToolBarsToActivate (std::vector
<OUString
>& rToolBars
) const;
83 void GetToolBarsToDeactivate (std::vector
<OUString
>& rToolBars
) const;
85 void MarkToolBarAsActive (const OUString
& rsName
);
86 void MarkToolBarAsNotActive (const OUString
& rsName
);
87 void MarkAllToolBarsAsNotActive();
90 typedef ::std::map
<sd::ToolBarManager::ToolBarGroup
, std::vector
<OUString
> > Groups
;
92 std::vector
<OUString
> maActiveToolBars
;
94 void MakeRequestedToolBarList (std::vector
<OUString
>& rToolBars
) const;
97 /** Manage tool bars that are implemented as sub shells of a view shell.
98 The typical procedure of updating the sub shells of a view shell is to
99 rebuild a list of sub shells that the caller would like to have active.
100 The methods ClearGroup() and AddShellId() allow the caller to do that. A
101 final call to UpdateShells() activates the requested shells that are not
102 active and deactivates the active shells that are not requested .
104 This is done by maintaining two lists. One (the current list)
105 reflects the current state. The other (the requested list) contains the
106 currently requested shells. UpdateShells() makes the requested
107 list the current list and clears the current list.
109 Each shell belongs to one group. Different groups can be modified
112 class ToolBarShellList
115 /** Create a new object with an empty current list and an empty
120 /** Remove all shells from a group. Calling this method should normally
121 not be necessary because after the construction or after a call to
122 UpdateShells() the requested list is empty.
124 The group to clear. Shells in other groups are not modified.
126 void ClearGroup (sd::ToolBarManager::ToolBarGroup eGroup
);
128 /** Add a shell. When the specified shell has already been requested
129 for another group then it is moved to this group.
131 The group to which to add the shell.
133 The id of the shell to add.
135 void AddShellId (sd::ToolBarManager::ToolBarGroup eGroup
, sd::ShellId nId
);
137 /** Releasing all shells means that the given ToolBarRules object is
138 informed that every shell managed by the called ToolBarShellList is
139 about to be removed and that the associated framework tool bars can
140 be removed as well. The caller still has to call UpdateShells().
142 void ReleaseAllShells (ToolBarRules
& rRules
);
144 /** The requested list is made the current list by activating all
145 shells in the requested list and by deactivating the shells in the
146 current list that are not in the requested list.
147 @param pMainViewShell
148 The shells that are activated or deactivated are sub shells of
151 This ViewShellManager is used to activate or deactivate shells.
154 const std::shared_ptr
<ViewShell
>& rpMainViewShell
,
155 const std::shared_ptr
<ViewShellManager
>& rpManager
);
158 class ShellDescriptor
160 ShellDescriptor (ShellId nId
,sd::ToolBarManager::ToolBarGroup eGroup
);
162 sd::ToolBarManager::ToolBarGroup meGroup
;
163 friend bool operator<(const ShellDescriptor
& r1
, const ShellDescriptor
& r2
)
164 { return r1
.mnId
< r2
.mnId
; }
167 /** The requested list of tool bar shells that will be active after the
168 next call to UpdateShells().
170 typedef ::std::set
<ShellDescriptor
> GroupedShellList
;
171 GroupedShellList maNewList
;
173 /** The list of tool bar shells that are currently on the shell stack.
174 Using a GroupedShellList is not strictly necessary but it makes
175 things easier and does not waste too much memory.
177 GroupedShellList maCurrentList
;
180 /** This class concentrates the knowledge about when to show what tool bars
187 const std::shared_ptr
<ToolBarManager
>& rpToolBarManager
,
188 const std::shared_ptr
<ViewShellManager
>& rpViewShellManager
);
190 /** This method calls MainViewShellChanged() and SelectionHasChanged()
191 for the current main view shell and its view.
193 void Update (ViewShellBase
const & rBase
);
195 /** Reset all tool bars in all groups and add tool bars and tool bar
196 shells to the ToolBarGroup::Permanent group for the specified ViewShell type.
198 void MainViewShellChanged (ViewShell::ShellType nShellType
);
200 /** Reset all tool bars in all groups and add tool bars and tool bar
201 shells to the ToolBarGroup::Permanent group for the specified ViewShell.
203 void MainViewShellChanged (const ViewShell
& rMainViewShell
);
205 /** Reset all tool bars in the ToolBarGroup::Function group and add tool bars and tool bar
206 shells to this group for the current selection.
208 void SelectionHasChanged (
209 const ::sd::ViewShell
& rViewShell
,
210 const SdrView
& rView
);
212 /** Add a tool bar for the specified tool bar shell.
215 ::sd::ToolBarManager::ToolBarGroup eGroup
,
216 sd::ShellId nShellId
);
218 /** Remove a tool bar for the specified tool bar shell.
220 void SubShellRemoved (
221 ::sd::ToolBarManager::ToolBarGroup eGroup
,
222 sd::ShellId nShellId
);
225 std::shared_ptr
<ToolBarManager
> mpToolBarManager
;
226 std::shared_ptr
<ViewShellManager
> mpViewShellManager
;
229 } // end of anonymous namespace
233 //===== ToolBarManager::Implementation ========================================
235 class ToolBarManager::Implementation
238 /** This constructor takes three arguments even though the
239 ToolBarManager could be taken from the ViewShellBase. This is so to
240 state explicitly which information has to be present when this
241 constructor is called. The ViewShellBase may not have been fully
242 initialized at this point and must not be asked for this values.
245 ViewShellBase
& rBase
,
246 const std::shared_ptr
<sd::tools::EventMultiplexer
>& rpMultiplexer
,
247 const std::shared_ptr
<ViewShellManager
>& rpViewShellManager
,
248 const std::shared_ptr
<ToolBarManager
>& rpToolBarManager
);
251 void SetValid (bool bValid
);
253 void ResetToolBars (ToolBarGroup eGroup
);
254 void ResetAllToolBars();
255 void AddToolBar (ToolBarGroup eGroup
, const OUString
& rsToolBarName
);
256 void AddToolBarShell (ToolBarGroup eGroup
, ShellId nToolBarId
);
257 void RemoveToolBar (ToolBarGroup eGroup
, const OUString
& rsToolBarName
);
259 /** Release all tool bar shells and the associated framework tool bars.
260 Typically called when the main view shell is being replaced by
261 another, all tool bar shells are released. In that process the
262 shells are destroyed anyway and without calling this method they
263 would still be referenced.
265 void ReleaseAllToolBarShells();
267 void ToolBarsDestroyed();
269 void RequestUpdate();
273 /** Tell the XLayoutManager about the tool bars that we would like to be
275 @param rpLayouterLock
276 This typically is the mpSynchronousLayouterLock that is used in
277 this method and that is either released at its end or assigned
278 to mpAsynchronousLock in order to be unlocked later.
280 void Update (::std::unique_ptr
<LayouterLock
> pLayouterLock
);
282 class UpdateLockImplementation
285 explicit UpdateLockImplementation (Implementation
& rImplementation
)
286 : mrImplementation(rImplementation
) { mrImplementation
.LockUpdate(); }
287 ~UpdateLockImplementation() { mrImplementation
.UnlockUpdate(); }
289 Implementation
& mrImplementation
;
292 void LockViewShellManager();
296 ToolBarRules
& GetToolBarRules() { return maToolBarRules
;}
299 mutable ::osl::Mutex maMutex
;
300 ViewShellBase
& mrBase
;
301 std::shared_ptr
<sd::tools::EventMultiplexer
> mpEventMultiplexer
;
303 ToolBarList maToolBarList
;
304 ToolBarShellList maToolBarShellList
;
305 Reference
<frame::XLayoutManager
> mxLayouter
;
306 sal_Int32 mnLockCount
;
307 bool mbPreUpdatePending
;
308 bool mbPostUpdatePending
;
309 /** The layouter locks manage the locking of the XLayoutManager. The
310 lock() and unlock() functions are not called directly because the
311 (final) unlocking is usually done asynchronously *after* the
312 list of requested toolbars is updated.
314 ::std::unique_ptr
<LayouterLock
> mpSynchronousLayouterLock
;
315 ::std::unique_ptr
<LayouterLock
> mpAsynchronousLayouterLock
;
316 ::std::unique_ptr
<ViewShellManager::UpdateLock
, o3tl::default_delete
<ViewShellManager::UpdateLock
>> mpViewShellManagerLock
;
317 ImplSVEvent
* mnPendingUpdateCall
;
318 ImplSVEvent
* mnPendingSetValidCall
;
319 ToolBarRules maToolBarRules
;
321 static OUString
GetToolBarResourceName (const OUString
& rsBaseName
);
322 bool CheckPlugInMode (const OUString
& rsName
) const;
324 DECL_LINK(UpdateCallback
, void *, void);
325 DECL_LINK(EventMultiplexerCallback
, sd::tools::EventMultiplexerEvent
&, void);
326 DECL_LINK(SetValidCallback
, void*, void);
329 //===== ToolBarManager ========================================================
331 std::shared_ptr
<ToolBarManager
> ToolBarManager::Create (
332 ViewShellBase
& rBase
,
333 const std::shared_ptr
<sd::tools::EventMultiplexer
>& rpMultiplexer
,
334 const std::shared_ptr
<ViewShellManager
>& rpViewShellManager
)
336 std::shared_ptr
<ToolBarManager
> pManager (new ToolBarManager());
337 pManager
->mpImpl
.reset(
338 new Implementation(rBase
,rpMultiplexer
,rpViewShellManager
,pManager
));
342 ToolBarManager::ToolBarManager()
347 ToolBarManager::~ToolBarManager()
351 void ToolBarManager::Shutdown()
353 if (mpImpl
!= nullptr)
357 void ToolBarManager::ResetToolBars (ToolBarGroup eGroup
)
359 if (mpImpl
!= nullptr)
361 UpdateLock
aLock (shared_from_this());
362 mpImpl
->ResetToolBars(eGroup
);
366 void ToolBarManager::ResetAllToolBars()
368 if (mpImpl
!= nullptr)
370 UpdateLock
aLock (shared_from_this());
371 mpImpl
->ResetAllToolBars();
375 void ToolBarManager::AddToolBar (
377 const OUString
& rsToolBarName
)
379 if (mpImpl
!= nullptr)
381 UpdateLock
aLock (shared_from_this());
382 mpImpl
->AddToolBar(eGroup
,rsToolBarName
);
386 void ToolBarManager::AddToolBarShell (
390 if (mpImpl
!= nullptr)
392 UpdateLock
aLock (shared_from_this());
393 mpImpl
->AddToolBarShell(eGroup
,nToolBarId
);
397 void ToolBarManager::RemoveToolBar (
399 const OUString
& rsToolBarName
)
401 if (mpImpl
!= nullptr)
403 UpdateLock
aLock (shared_from_this());
404 mpImpl
->RemoveToolBar(eGroup
,rsToolBarName
);
408 void ToolBarManager::SetToolBar (
410 const OUString
& rsToolBarName
)
412 if (mpImpl
!= nullptr)
414 UpdateLock
aLock (shared_from_this());
415 mpImpl
->ResetToolBars(eGroup
);
416 mpImpl
->AddToolBar(eGroup
,rsToolBarName
);
420 void ToolBarManager::SetToolBarShell (
424 if (mpImpl
!= nullptr)
426 UpdateLock
aLock (shared_from_this());
427 mpImpl
->ResetToolBars(eGroup
);
428 mpImpl
->AddToolBarShell(eGroup
,nToolBarId
);
432 void ToolBarManager::PreUpdate()
434 if (mpImpl
!= nullptr)
438 void ToolBarManager::RequestUpdate()
440 if (mpImpl
!= nullptr)
441 mpImpl
->RequestUpdate();
444 void ToolBarManager::LockViewShellManager()
446 if (mpImpl
!= nullptr)
447 mpImpl
->LockViewShellManager();
450 void ToolBarManager::LockUpdate()
452 if (mpImpl
!= nullptr)
453 mpImpl
->LockUpdate();
456 void ToolBarManager::UnlockUpdate()
458 if (mpImpl
!= nullptr)
459 mpImpl
->UnlockUpdate();
462 void ToolBarManager::MainViewShellChanged ()
464 if (mpImpl
!= nullptr)
466 mpImpl
->ReleaseAllToolBarShells();
467 mpImpl
->GetToolBarRules().MainViewShellChanged(ViewShell::ST_NONE
);
471 void ToolBarManager::MainViewShellChanged (const ViewShell
& rMainViewShell
)
473 if (mpImpl
!= nullptr)
475 mpImpl
->ReleaseAllToolBarShells();
476 mpImpl
->GetToolBarRules().MainViewShellChanged(rMainViewShell
);
480 void ToolBarManager::SelectionHasChanged (
481 const ViewShell
& rViewShell
,
482 const SdrView
& rView
)
484 if (mpImpl
!= nullptr)
485 mpImpl
->GetToolBarRules().SelectionHasChanged(rViewShell
,rView
);
488 void ToolBarManager::ToolBarsDestroyed()
490 if (mpImpl
!= nullptr)
491 mpImpl
->ToolBarsDestroyed();
494 //===== ToolBarManager::Implementation =======================================
496 ToolBarManager::Implementation::Implementation (
497 ViewShellBase
& rBase
,
498 const std::shared_ptr
<sd::tools::EventMultiplexer
>& rpMultiplexer
,
499 const std::shared_ptr
<ViewShellManager
>& rpViewShellManager
,
500 const std::shared_ptr
<ToolBarManager
>& rpToolBarManager
)
503 mpEventMultiplexer(rpMultiplexer
),
506 maToolBarShellList(),
508 mbPreUpdatePending(false),
509 mbPostUpdatePending(false),
510 mpSynchronousLayouterLock(),
511 mpAsynchronousLayouterLock(),
512 mpViewShellManagerLock(),
513 mnPendingUpdateCall(nullptr),
514 mnPendingSetValidCall(nullptr),
515 maToolBarRules(rpToolBarManager
,rpViewShellManager
)
517 Link
<tools::EventMultiplexerEvent
&,void> aLink (LINK(this,ToolBarManager::Implementation
,EventMultiplexerCallback
));
518 mpEventMultiplexer
->AddEventListener( aLink
);
521 /** The order of statements is important.
522 First unregister listeners, which may post user events.
523 Then remove pending user events.
525 ToolBarManager::Implementation::~Implementation()
527 // Unregister at broadcasters.
528 Link
<tools::EventMultiplexerEvent
&,void> aLink (LINK(this,ToolBarManager::Implementation
,EventMultiplexerCallback
));
529 mpEventMultiplexer
->RemoveEventListener(aLink
);
531 // Abort pending user calls.
532 if (mnPendingUpdateCall
!= nullptr)
533 Application::RemoveUserEvent(mnPendingUpdateCall
);
534 if (mnPendingSetValidCall
!= nullptr)
535 Application::RemoveUserEvent(mnPendingSetValidCall
);
538 void ToolBarManager::Implementation::ToolBarsDestroyed()
540 maToolBarList
.MarkAllToolBarsAsNotActive();
543 void ToolBarManager::Implementation::SetValid (bool bValid
)
545 ::osl::MutexGuard
aGuard(maMutex
);
547 if (mbIsValid
== bValid
)
550 UpdateLockImplementation
aUpdateLock (*this);
555 Reference
<frame::XFrame
> xFrame
;
556 if (mrBase
.GetViewFrame() != nullptr)
557 xFrame
= mrBase
.GetViewFrame()->GetFrame().GetFrameInterface();
560 Reference
<beans::XPropertySet
> xFrameProperties (xFrame
, UNO_QUERY_THROW
);
561 Any
aValue (xFrameProperties
->getPropertyValue("LayoutManager"));
562 aValue
>>= mxLayouter
;
563 // tdf#119997 if mpSynchronousLayouterLock was created before mxLayouter was
564 // set then update it now that its available
565 if (mpSynchronousLayouterLock
&& !mpSynchronousLayouterLock
->is())
566 mpSynchronousLayouterLock
.reset(new LayouterLock(mxLayouter
));
568 catch (const RuntimeException
&)
572 GetToolBarRules().Update(mrBase
);
577 mxLayouter
= nullptr;
581 void ToolBarManager::Implementation::ResetToolBars (ToolBarGroup eGroup
)
583 ::osl::MutexGuard
aGuard(maMutex
);
585 maToolBarList
.ClearGroup(eGroup
);
586 maToolBarShellList
.ClearGroup(eGroup
);
588 mbPreUpdatePending
= true;
591 void ToolBarManager::Implementation::ResetAllToolBars()
593 SAL_INFO("sd.view", __func__
<< ": resetting all tool bars");
594 for (auto i
: o3tl::enumrange
<ToolBarGroup
>())
598 void ToolBarManager::Implementation::AddToolBar (
600 const OUString
& rsToolBarName
)
602 ::osl::MutexGuard
aGuard(maMutex
);
604 if (CheckPlugInMode(rsToolBarName
))
606 maToolBarList
.AddToolBar(eGroup
,rsToolBarName
);
608 mbPostUpdatePending
= true;
609 if (mnLockCount
== 0)
614 void ToolBarManager::Implementation::RemoveToolBar (
616 const OUString
& rsToolBarName
)
618 ::osl::MutexGuard
aGuard(maMutex
);
620 if (maToolBarList
.RemoveToolBar(eGroup
,rsToolBarName
))
622 mbPreUpdatePending
= true;
623 if (mnLockCount
== 0)
628 void ToolBarManager::Implementation::AddToolBarShell (
632 ViewShell
* pMainViewShell
= mrBase
.GetMainViewShell().get();
633 if (pMainViewShell
!= nullptr)
635 maToolBarShellList
.AddShellId(eGroup
,nToolBarId
);
636 GetToolBarRules().SubShellAdded(eGroup
, nToolBarId
);
640 void ToolBarManager::Implementation::ReleaseAllToolBarShells()
642 maToolBarShellList
.ReleaseAllShells(GetToolBarRules());
643 maToolBarShellList
.UpdateShells(mrBase
.GetMainViewShell(), mrBase
.GetViewShellManager());
646 void ToolBarManager::Implementation::RequestUpdate()
648 if (mnPendingUpdateCall
== nullptr)
650 mnPendingUpdateCall
= Application::PostUserEvent(
651 LINK(this,ToolBarManager::Implementation
,UpdateCallback
));
655 void ToolBarManager::Implementation::PreUpdate()
657 ::osl::MutexGuard
aGuard(maMutex
);
660 && mbPreUpdatePending
664 mbPreUpdatePending
= false;
666 SAL_INFO("sd.view", __func__
<< ": ToolBarManager::PreUpdate [");
668 // Get the list of tool bars that are not used anymore and are to be
670 std::vector
<OUString
> aToolBars
;
671 maToolBarList
.GetToolBarsToDeactivate(aToolBars
);
673 // Turn off the tool bars.
674 for (const auto& aToolBar
: aToolBars
)
676 OUString
sFullName (GetToolBarResourceName(aToolBar
));
677 SAL_INFO("sd.view", __func__
<< ": turning off tool bar " << sFullName
);
678 mxLayouter
->destroyElement(sFullName
);
679 maToolBarList
.MarkToolBarAsNotActive(aToolBar
);
682 SAL_INFO("sd.view", __func__
<< ": ToolBarManager::PreUpdate ]");
685 void ToolBarManager::Implementation::PostUpdate()
687 ::osl::MutexGuard
aGuard(maMutex
);
690 && mbPostUpdatePending
694 mbPostUpdatePending
= false;
696 // Create the list of requested tool bars.
697 std::vector
<OUString
> aToolBars
;
698 maToolBarList
.GetToolBarsToActivate(aToolBars
);
700 SAL_INFO("sd.view", __func__
<< ": ToolBarManager::PostUpdate [");
702 // Turn on the tool bars that are visible in the new context.
703 for (const auto& aToolBar
: aToolBars
)
705 OUString
sFullName (GetToolBarResourceName(aToolBar
));
706 SAL_INFO("sd.view", __func__
<< ": turning on tool bar " << sFullName
);
707 mxLayouter
->requestElement(sFullName
);
708 maToolBarList
.MarkToolBarAsActive(aToolBar
);
711 SAL_INFO("sd.view", __func__
<< ": ToolBarManager::PostUpdate ]");
714 void ToolBarManager::Implementation::LockViewShellManager()
716 if (mpViewShellManagerLock
== nullptr)
717 mpViewShellManagerLock
.reset(
718 new ViewShellManager::UpdateLock(mrBase
.GetViewShellManager()));
721 void ToolBarManager::Implementation::LockUpdate()
723 SAL_INFO("sd.view", __func__
<< ": LockUpdate " << mnLockCount
);
724 ::osl::MutexGuard
aGuard(maMutex
);
726 DBG_ASSERT(mnLockCount
<100, "ToolBarManager lock count unusually high");
727 if (mnLockCount
== 0)
729 OSL_ASSERT(mpSynchronousLayouterLock
== nullptr);
731 mpSynchronousLayouterLock
.reset(new LayouterLock(mxLayouter
));
736 void ToolBarManager::Implementation::UnlockUpdate()
738 SAL_INFO("sd.view", __func__
<< ": UnlockUpdate " << mnLockCount
);
739 ::osl::MutexGuard
aGuard(maMutex
);
741 OSL_ASSERT(mnLockCount
>0);
743 if (mnLockCount
== 0)
745 Update(std::move(mpSynchronousLayouterLock
));
749 void ToolBarManager::Implementation::Update (
750 ::std::unique_ptr
<LayouterLock
> pLocalLayouterLock
)
752 // When the lock is released and there are pending changes to the set of
753 // tool bars then update this set now.
754 if (mnLockCount
!= 0)
757 // During creation of ViewShellBase we may have the situation that
758 // the controller has already been created and attached to the frame
759 // but that the ToolBarManager has not yet completed its
760 // initialization (by initializing the mxLayouter member.) We do
761 // this here so that we do not have to wait for the next Update()
762 // call to show the tool bars.
763 if (mnPendingSetValidCall
!= nullptr)
765 Application::RemoveUserEvent(mnPendingSetValidCall
);
766 mnPendingSetValidCall
= nullptr;
770 if (mbIsValid
&& mxLayouter
.is() && (mbPreUpdatePending
|| mbPostUpdatePending
))
772 // 1) Release UNO tool bars that are no longer used. Do this
773 // now so that they are not updated when the SFX shell stack is
775 if (mbPreUpdatePending
)
778 // 2) Update the requested shells that represent tool bar
779 // functionality. Those that are not used anymore are
780 // deactivated now. Those that are missing are activated in the
781 // next step together with the view shells.
782 if (mpViewShellManagerLock
== nullptr)
783 mpViewShellManagerLock
.reset(
784 new ViewShellManager::UpdateLock(mrBase
.GetViewShellManager()));
785 maToolBarShellList
.UpdateShells(
786 mrBase
.GetMainViewShell(),
787 mrBase
.GetViewShellManager());
789 // 3) Unlock the ViewShellManager::UpdateLock. This updates the
791 mpViewShellManagerLock
.reset();
793 // 4) Make the UNO tool bars visible. The outstanding call to
794 // PostUpdate() is done via PostUserEvent() so that it is
795 // guaranteed to be executed when the SFX shell stack has been
796 // updated (under the assumption that our lock to the
797 // ViewShellManager was the only one open. If that is not the
798 // case then all should still be well but not as fast.)
800 // Note that the lock count may have been increased since
801 // entering this method. In that case one of the next
802 // UnlockUpdate() calls will post the UpdateCallback.
805 mpAsynchronousLayouterLock
= std::move(pLocalLayouterLock
);
806 if (mnPendingUpdateCall
==nullptr)
808 mnPendingUpdateCall
= Application::PostUserEvent(
809 LINK(this,ToolBarManager::Implementation
,UpdateCallback
));
815 mpViewShellManagerLock
.reset();
816 pLocalLayouterLock
.reset();
820 IMPL_LINK_NOARG(ToolBarManager::Implementation
, UpdateCallback
, void*, void)
822 mnPendingUpdateCall
= nullptr;
823 if (mnLockCount
== 0)
825 if (mbPreUpdatePending
)
827 if (mbPostUpdatePending
)
829 if (mbIsValid
&& mxLayouter
.is())
830 mpAsynchronousLayouterLock
.reset();
834 IMPL_LINK(ToolBarManager::Implementation
,EventMultiplexerCallback
,
835 sd::tools::EventMultiplexerEvent
&, rEvent
, void)
838 switch (rEvent
.meEventId
)
840 case EventMultiplexerEventId::ControllerAttached
:
841 if (mnPendingSetValidCall
== nullptr)
842 mnPendingSetValidCall
843 = Application::PostUserEvent(LINK(this,Implementation
,SetValidCallback
));
846 case EventMultiplexerEventId::ControllerDetached
:
854 IMPL_LINK_NOARG(ToolBarManager::Implementation
, SetValidCallback
, void*, void)
856 mnPendingSetValidCall
= nullptr;
860 OUString
ToolBarManager::Implementation::GetToolBarResourceName (
861 const OUString
& rsBaseName
)
863 return "private:resource/toolbar/" + rsBaseName
;
866 bool ToolBarManager::Implementation::CheckPlugInMode (const OUString
& rsName
) const
870 // Determine the plug in mode.
871 bool bIsPlugInMode (false);
874 SfxObjectShell
* pObjectShell
= mrBase
.GetObjectShell();
875 if (pObjectShell
== nullptr)
878 SfxMedium
* pMedium
= pObjectShell
->GetMedium();
879 if (pMedium
== nullptr)
882 const SfxBoolItem
* pViewOnlyItem
= SfxItemSet::GetItem
<SfxBoolItem
>(pMedium
->GetItemSet(), SID_VIEWONLY
, false);
883 if (pViewOnlyItem
== nullptr)
886 bIsPlugInMode
= pViewOnlyItem
->GetValue();
890 if (rsName
== msViewerToolBar
)
891 bValid
= bIsPlugInMode
;
893 bValid
= ! bIsPlugInMode
;
898 } // end of namespace sd
902 using namespace ::sd
;
904 //===== LayouterLock ==========================================================
906 LayouterLock::LayouterLock (const Reference
<frame::XLayoutManager
>& rxLayouter
)
907 : mxLayouter(rxLayouter
)
909 SAL_INFO("sd.view", __func__
<< ": LayouterLock " << (mxLayouter
.is() ? 1 :0));
914 LayouterLock::~LayouterLock()
916 SAL_INFO("sd.view", __func__
<< ": ~LayouterLock " << (mxLayouter
.is() ? 1 :0));
918 mxLayouter
->unlock();
921 //===== ToolBarRules ==========================================================
923 ToolBarRules::ToolBarRules (
924 const std::shared_ptr
<sd::ToolBarManager
>& rpToolBarManager
,
925 const std::shared_ptr
<sd::ViewShellManager
>& rpViewShellManager
)
926 : mpToolBarManager(rpToolBarManager
),
927 mpViewShellManager(rpViewShellManager
)
931 void ToolBarRules::Update (ViewShellBase
const & rBase
)
933 ViewShell
* pMainViewShell
= rBase
.GetMainViewShell().get();
934 if (pMainViewShell
!= nullptr)
936 MainViewShellChanged(pMainViewShell
->GetShellType());
937 if (pMainViewShell
->GetView())
938 SelectionHasChanged (*pMainViewShell
, *pMainViewShell
->GetView());
941 MainViewShellChanged(ViewShell::ST_NONE
);
944 void ToolBarRules::MainViewShellChanged (ViewShell::ShellType nShellType
)
946 ::sd::ToolBarManager::UpdateLock
aToolBarManagerLock (mpToolBarManager
);
947 ::sd::ViewShellManager::UpdateLock
aViewShellManagerLock (mpViewShellManager
);
949 mpToolBarManager
->ResetAllToolBars();
953 case ::sd::ViewShell::ST_IMPRESS
:
954 case ::sd::ViewShell::ST_NOTES
:
955 case ::sd::ViewShell::ST_HANDOUT
:
956 mpToolBarManager
->AddToolBar(
957 ToolBarManager::ToolBarGroup::Permanent
,
958 ToolBarManager::msToolBar
);
959 mpToolBarManager
->AddToolBar(
960 ToolBarManager::ToolBarGroup::Permanent
,
961 ToolBarManager::msOptionsToolBar
);
962 mpToolBarManager
->AddToolBar(
963 ToolBarManager::ToolBarGroup::Permanent
,
964 ToolBarManager::msViewerToolBar
);
967 case ::sd::ViewShell::ST_DRAW
:
968 mpToolBarManager
->AddToolBar(
969 ToolBarManager::ToolBarGroup::Permanent
,
970 ToolBarManager::msToolBar
);
971 mpToolBarManager
->AddToolBar(
972 ToolBarManager::ToolBarGroup::Permanent
,
973 ToolBarManager::msOptionsToolBar
);
974 mpToolBarManager
->AddToolBar(
975 ToolBarManager::ToolBarGroup::Permanent
,
976 ToolBarManager::msViewerToolBar
);
979 case ViewShell::ST_OUTLINE
:
980 mpToolBarManager
->AddToolBar(
981 ToolBarManager::ToolBarGroup::Permanent
,
982 ToolBarManager::msOutlineToolBar
);
983 mpToolBarManager
->AddToolBar(
984 ToolBarManager::ToolBarGroup::Permanent
,
985 ToolBarManager::msViewerToolBar
);
986 mpToolBarManager
->AddToolBarShell(
987 ToolBarManager::ToolBarGroup::Permanent
, ToolbarId::Draw_Text_Toolbox_Sd
);
990 case ViewShell::ST_SLIDE_SORTER
:
991 mpToolBarManager
->AddToolBar(
992 ToolBarManager::ToolBarGroup::Permanent
,
993 ToolBarManager::msViewerToolBar
);
994 mpToolBarManager
->AddToolBar(
995 ToolBarManager::ToolBarGroup::Permanent
,
996 ToolBarManager::msSlideSorterToolBar
);
997 mpToolBarManager
->AddToolBar(
998 ToolBarManager::ToolBarGroup::Permanent
,
999 ToolBarManager::msSlideSorterObjectBar
);
1002 case ViewShell::ST_NONE
:
1003 case ViewShell::ST_PRESENTATION
:
1004 case ViewShell::ST_SIDEBAR
:
1010 void ToolBarRules::MainViewShellChanged (const ViewShell
& rMainViewShell
)
1012 ::sd::ToolBarManager::UpdateLock
aToolBarManagerLock (mpToolBarManager
);
1013 ::sd::ViewShellManager::UpdateLock
aViewShellManagerLock (mpViewShellManager
);
1015 MainViewShellChanged(rMainViewShell
.GetShellType());
1016 switch(rMainViewShell
.GetShellType())
1018 case ::sd::ViewShell::ST_IMPRESS
:
1019 case ::sd::ViewShell::ST_DRAW
:
1020 case ::sd::ViewShell::ST_NOTES
:
1022 const DrawViewShell
* pDrawViewShell
1023 = dynamic_cast<const DrawViewShell
*>(&rMainViewShell
);
1024 if (pDrawViewShell
!= nullptr)
1026 if (pDrawViewShell
->GetEditMode() == EditMode::MasterPage
)
1027 mpToolBarManager
->AddToolBar(
1028 ToolBarManager::ToolBarGroup::MasterMode
,
1029 ToolBarManager::msMasterViewToolBar
);
1030 else if ( rMainViewShell
.GetShellType() != ::sd::ViewShell::ST_DRAW
)
1031 mpToolBarManager
->AddToolBar(
1032 ToolBarManager::ToolBarGroup::CommonTask
,
1033 ToolBarManager::msCommonTaskToolBar
);
1043 void ToolBarRules::SelectionHasChanged (
1044 const ::sd::ViewShell
& rViewShell
,
1045 const SdrView
& rView
)
1047 ::sd::ToolBarManager::UpdateLock
aLock (mpToolBarManager
);
1048 mpToolBarManager
->LockViewShellManager();
1049 bool bTextEdit
= rView
.IsTextEdit();
1051 mpToolBarManager
->ResetToolBars(ToolBarManager::ToolBarGroup::Function
);
1053 switch (rView
.GetContext())
1055 case SdrViewContext::Graphic
:
1057 mpToolBarManager
->SetToolBarShell(ToolBarManager::ToolBarGroup::Function
, ToolbarId::Draw_Graf_Toolbox
);
1060 case SdrViewContext::Media
:
1062 mpToolBarManager
->SetToolBarShell(ToolBarManager::ToolBarGroup::Function
, ToolbarId::Draw_Media_Toolbox
);
1065 case SdrViewContext::Table
:
1066 mpToolBarManager
->SetToolBarShell(ToolBarManager::ToolBarGroup::Function
, ToolbarId::Draw_Table_Toolbox
);
1070 case SdrViewContext::Standard
:
1074 switch(rViewShell
.GetShellType())
1076 case ::sd::ViewShell::ST_IMPRESS
:
1077 case ::sd::ViewShell::ST_DRAW
:
1078 case ::sd::ViewShell::ST_NOTES
:
1079 case ::sd::ViewShell::ST_HANDOUT
:
1080 mpToolBarManager
->SetToolBar(
1081 ToolBarManager::ToolBarGroup::Function
,
1082 ToolBarManager::msDrawingObjectToolBar
);
1092 mpToolBarManager
->AddToolBarShell(ToolBarManager::ToolBarGroup::Function
, ToolbarId::Draw_Text_Toolbox_Sd
);
1094 SdrView
* pView
= &const_cast<SdrView
&>(rView
);
1095 // Check if the extrusion tool bar and the fontwork tool bar have to
1097 if (svx::checkForSelectedCustomShapes(pView
, true /* bOnlyExtruded */ ))
1098 mpToolBarManager
->AddToolBarShell(ToolBarManager::ToolBarGroup::Function
, ToolbarId::Svx_Extrusion_Bar
);
1099 sal_uInt32 nCheckStatus
= 0;
1100 if (svx::checkForSelectedFontWork(pView
, nCheckStatus
))
1101 mpToolBarManager
->AddToolBarShell(ToolBarManager::ToolBarGroup::Function
, ToolbarId::Svx_Fontwork_Bar
);
1103 // Switch on additional context-sensitive tool bars.
1104 if (rView
.GetContext() == SdrViewContext::PointEdit
)
1105 mpToolBarManager
->AddToolBarShell(ToolBarManager::ToolBarGroup::Function
, ToolbarId::Bezier_Toolbox_Sd
);
1108 void ToolBarRules::SubShellAdded (
1109 ::sd::ToolBarManager::ToolBarGroup eGroup
,
1110 sd::ShellId nShellId
)
1112 // For some tool bar shells (those defined in sd) we have to add the
1113 // actual tool bar here.
1116 case ToolbarId::Draw_Graf_Toolbox
:
1117 mpToolBarManager
->AddToolBar(eGroup
, ToolBarManager::msGraphicObjectBar
);
1120 case ToolbarId::Draw_Media_Toolbox
:
1121 mpToolBarManager
->AddToolBar(eGroup
, ToolBarManager::msMediaObjectBar
);
1124 case ToolbarId::Draw_Text_Toolbox_Sd
:
1125 mpToolBarManager
->AddToolBar(eGroup
, ToolBarManager::msTextObjectBar
);
1128 case ToolbarId::Bezier_Toolbox_Sd
:
1129 mpToolBarManager
->AddToolBar(eGroup
, ToolBarManager::msBezierObjectBar
);
1132 case ToolbarId::Draw_Table_Toolbox
:
1133 mpToolBarManager
->AddToolBar(eGroup
, ToolBarManager::msTableObjectBar
);
1141 void ToolBarRules::SubShellRemoved (
1142 ::sd::ToolBarManager::ToolBarGroup eGroup
,
1143 sd::ShellId nShellId
)
1145 // For some tool bar shells (those defined in sd) we have to add the
1146 // actual tool bar here.
1149 case ToolbarId::Draw_Graf_Toolbox
:
1150 mpToolBarManager
->RemoveToolBar(eGroup
, ToolBarManager::msGraphicObjectBar
);
1153 case ToolbarId::Draw_Media_Toolbox
:
1154 mpToolBarManager
->RemoveToolBar(eGroup
, ToolBarManager::msMediaObjectBar
);
1157 case ToolbarId::Draw_Text_Toolbox_Sd
:
1158 mpToolBarManager
->RemoveToolBar(eGroup
, ToolBarManager::msTextObjectBar
);
1161 case ToolbarId::Bezier_Toolbox_Sd
:
1162 mpToolBarManager
->RemoveToolBar(eGroup
, ToolBarManager::msBezierObjectBar
);
1165 case ToolbarId::Draw_Table_Toolbox
:
1166 mpToolBarManager
->RemoveToolBar(eGroup
, ToolBarManager::msTableObjectBar
);
1174 //===== ToolBarList ===========================================================
1176 ToolBarList::ToolBarList()
1182 void ToolBarList::ClearGroup (sd::ToolBarManager::ToolBarGroup eGroup
)
1184 Groups::iterator
iGroup (maGroups
.find(eGroup
));
1185 if (iGroup
!= maGroups
.end())
1187 iGroup
->second
.clear();
1191 void ToolBarList::AddToolBar (
1192 sd::ToolBarManager::ToolBarGroup eGroup
,
1193 const OUString
& rsName
)
1195 Groups::iterator
iGroup (maGroups
.find(eGroup
));
1196 if (iGroup
== maGroups
.end())
1197 iGroup
= maGroups
.emplace(eGroup
,std::vector
<OUString
>()).first
;
1199 if (iGroup
!= maGroups
.end())
1201 auto iBar (std::find(iGroup
->second
.cbegin(),iGroup
->second
.cend(),rsName
));
1202 if (iBar
== iGroup
->second
.cend())
1204 iGroup
->second
.push_back(rsName
);
1209 bool ToolBarList::RemoveToolBar (
1210 sd::ToolBarManager::ToolBarGroup eGroup
,
1211 const OUString
& rsName
)
1213 Groups::iterator
iGroup (maGroups
.find(eGroup
));
1214 if (iGroup
!= maGroups
.end())
1216 auto iBar (std::find(iGroup
->second
.begin(),iGroup
->second
.end(),rsName
));
1217 if (iBar
!= iGroup
->second
.end())
1219 iGroup
->second
.erase(iBar
);
1226 void ToolBarList::MakeRequestedToolBarList (std::vector
<OUString
>& rRequestedToolBars
) const
1228 for (auto eGroup
: o3tl::enumrange
<sd::ToolBarManager::ToolBarGroup
>())
1230 Groups::const_iterator
iGroup (maGroups
.find(eGroup
));
1231 if (iGroup
!= maGroups
.end())
1232 rRequestedToolBars
.insert( rRequestedToolBars
.end(),
1233 iGroup
->second
.begin(),
1234 iGroup
->second
.end() );
1238 void ToolBarList::GetToolBarsToActivate (std::vector
<OUString
>& rToolBars
) const
1240 std::vector
<OUString
> aRequestedToolBars
;
1241 MakeRequestedToolBarList(aRequestedToolBars
);
1243 for (const auto& aToolBar
: aRequestedToolBars
)
1245 if (::std::find(maActiveToolBars
.begin(),maActiveToolBars
.end(),aToolBar
)
1246 == maActiveToolBars
.end())
1248 rToolBars
.push_back(aToolBar
);
1253 void ToolBarList::GetToolBarsToDeactivate (std::vector
<OUString
>& rToolBars
) const
1255 std::vector
<OUString
> aRequestedToolBars
;
1256 MakeRequestedToolBarList(aRequestedToolBars
);
1258 for (auto& aToolBar
: maActiveToolBars
)
1260 if (::std::find(aRequestedToolBars
.begin(),aRequestedToolBars
.end(),aToolBar
)
1261 == aRequestedToolBars
.end())
1263 rToolBars
.push_back(aToolBar
);
1268 void ToolBarList::MarkToolBarAsActive (const OUString
& rsName
)
1270 maActiveToolBars
.push_back(rsName
);
1273 void ToolBarList::MarkToolBarAsNotActive (const OUString
& rsName
)
1275 maActiveToolBars
.erase(
1276 ::std::find(maActiveToolBars
.begin(),maActiveToolBars
.end(), rsName
));
1279 void ToolBarList::MarkAllToolBarsAsNotActive()
1281 maActiveToolBars
.clear();
1284 //===== ToolBarShellList ======================================================
1286 ToolBarShellList::ShellDescriptor::ShellDescriptor (
1288 sd::ToolBarManager::ToolBarGroup eGroup
)
1294 ToolBarShellList::ToolBarShellList()
1300 void ToolBarShellList::ClearGroup (sd::ToolBarManager::ToolBarGroup eGroup
)
1302 for (GroupedShellList::iterator iDescriptor
= maNewList
.begin(); iDescriptor
!= maNewList
.end(); )
1303 if (iDescriptor
->meGroup
== eGroup
)
1304 iDescriptor
= maNewList
.erase(iDescriptor
);
1309 void ToolBarShellList::AddShellId (sd::ToolBarManager::ToolBarGroup eGroup
, sd::ShellId nId
)
1311 // Make sure that the shell is not added twice (and possibly in
1312 // different groups.)
1313 ShellDescriptor
aDescriptor (nId
,eGroup
);
1314 GroupedShellList::iterator
iDescriptor (maNewList
.find(aDescriptor
));
1315 if (iDescriptor
!= maNewList
.end())
1317 // The shell is already requested.
1318 if (iDescriptor
->meGroup
!= eGroup
)
1320 // It is now being requested for another group.
1321 // (Is this an error?)
1322 // Move it to that group.
1323 maNewList
.erase(iDescriptor
);
1324 maNewList
.insert(aDescriptor
);
1326 // else nothing to do.
1329 maNewList
.insert(aDescriptor
);
1332 void ToolBarShellList::ReleaseAllShells (ToolBarRules
& rRules
)
1334 // Release the currently active tool bars.
1335 GroupedShellList
aList (maCurrentList
);
1336 for (const auto& rDescriptor
: aList
)
1338 rRules
.SubShellRemoved(rDescriptor
.meGroup
, rDescriptor
.mnId
);
1341 // Clear the list of requested tool bars.
1345 void ToolBarShellList::UpdateShells (
1346 const std::shared_ptr
<ViewShell
>& rpMainViewShell
,
1347 const std::shared_ptr
<ViewShellManager
>& rpManager
)
1349 if (rpMainViewShell
== nullptr)
1352 GroupedShellList aList
;
1354 // Deactivate shells that are in maCurrentList, but not in
1356 ::std::set_difference(maCurrentList
.begin(), maCurrentList
.end(),
1357 maNewList
.begin(), maNewList
.end(),
1358 std::insert_iterator
<GroupedShellList
>(aList
,aList
.begin()));
1359 for (const auto& rShell
: aList
)
1361 SAL_INFO("sd.view", __func__
<< ": deactivating tool bar shell " << static_cast<sal_uInt32
>(rShell
.mnId
));
1362 rpManager
->DeactivateSubShell(*rpMainViewShell
, rShell
.mnId
);
1365 // Activate shells that are in maNewList, but not in
1368 ::std::set_difference(maNewList
.begin(), maNewList
.end(),
1369 maCurrentList
.begin(), maCurrentList
.end(),
1370 std::insert_iterator
<GroupedShellList
>(aList
,aList
.begin()));
1371 for (const auto& rShell
: aList
)
1373 SAL_INFO("sd.view", __func__
<< ": activating tool bar shell " << static_cast<sal_uInt32
>(rShell
.mnId
));
1374 rpManager
->ActivateSubShell(*rpMainViewShell
, rShell
.mnId
);
1377 // The maNewList now reflects the current state and thus is made
1379 maCurrentList
= maNewList
;
1382 } // end of anonymous namespace
1384 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */