LibreOffice Module sd (master) 1
ToolBarManager.cxx
Go to the documentation of this file.
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
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>
35#include <sfx2/objsh.hxx>
36#include <sfx2/toolbarids.hxx>
37#include <sfx2/viewfrm.hxx>
38#include <svl/eitem.hxx>
39#include <svx/svxids.hrc>
40#include <svx/extrusionbar.hxx>
41#include <svx/fontworkbar.hxx>
42#include <tools/debug.hxx>
43#include <tools/link.hxx>
44#include <utility>
45#include <vcl/svapp.hxx>
46#include <osl/diagnose.h>
47
48#include <map>
49#include <memory>
50#include <string_view>
51#include <vector>
52
53using namespace ::com::sun::star;
54using namespace ::com::sun::star::uno;
55
56namespace {
57
58using namespace sd;
59
60class ToolBarRules;
61
64class LayouterLock
65{
66 Reference<frame::XLayoutManager> mxLayouter;
67public:
68 explicit LayouterLock (const Reference<frame::XLayoutManager>& rxLayouter);
69 ~LayouterLock();
70 bool is() const { return mxLayouter.is(); }
71};
72
76class ToolBarList
77{
78public:
79 ToolBarList();
80
81 void ClearGroup (sd::ToolBarManager::ToolBarGroup eGroup);
82 void AddToolBar (sd::ToolBarManager::ToolBarGroup eGroup, const OUString& rsName);
83 bool RemoveToolBar (sd::ToolBarManager::ToolBarGroup eGroup, const OUString& rsName);
84
85 void GetToolBarsToActivate (std::vector<OUString>& rToolBars) const;
86 void GetToolBarsToDeactivate (std::vector<OUString>& rToolBars) const;
87
88 void MarkToolBarAsActive (const OUString& rsName);
89 void MarkToolBarAsNotActive (const OUString& rsName);
90 void MarkAllToolBarsAsNotActive();
91
92private:
93 typedef ::std::map<sd::ToolBarManager::ToolBarGroup, std::vector<OUString> > Groups;
94 Groups maGroups;
95 std::vector<OUString> maActiveToolBars;
96
97 void MakeRequestedToolBarList (std::vector<OUString>& rToolBars) const;
98};
99
115class ToolBarShellList
116{
117public:
121 ToolBarShellList();
122
129 void ClearGroup (sd::ToolBarManager::ToolBarGroup eGroup);
130
138 void AddShellId (sd::ToolBarManager::ToolBarGroup eGroup, sd::ShellId nId);
139
145 void ReleaseAllShells (ToolBarRules& rRules);
146
156 void UpdateShells (
157 const std::shared_ptr<ViewShell>& rpMainViewShell,
158 const std::shared_ptr<ViewShellManager>& rpManager);
159
160private:
161 class ShellDescriptor
162 {public:
163 ShellDescriptor (ShellId nId,sd::ToolBarManager::ToolBarGroup eGroup);
166 friend bool operator<(const ShellDescriptor& r1, const ShellDescriptor& r2)
167 { return r1.mnId < r2.mnId; }
168 };
169
173 typedef ::std::set<ShellDescriptor> GroupedShellList;
174 GroupedShellList maNewList;
175
180 GroupedShellList maCurrentList;
181};
182
186class ToolBarRules
187{
188public:
189 ToolBarRules (
190 std::shared_ptr<ToolBarManager> pToolBarManager,
191 std::shared_ptr<ViewShellManager> pViewShellManager);
192
196 void Update (ViewShellBase const & rBase);
197
201 void MainViewShellChanged (ViewShell::ShellType nShellType);
202
206 void MainViewShellChanged (const ViewShell& rMainViewShell);
207
211 void SelectionHasChanged (
212 const ::sd::ViewShell& rViewShell,
213 const SdrView& rView);
214
217 void SubShellAdded (
219 sd::ShellId nShellId);
220
223 void SubShellRemoved (
225 sd::ShellId nShellId);
226
227private:
228 std::shared_ptr<ToolBarManager> mpToolBarManager;
229 std::shared_ptr<ViewShellManager> mpViewShellManager;
230};
231
232} // end of anonymous namespace
233
234namespace sd {
235
236//===== ToolBarManager::Implementation ========================================
237
239{
240public:
248 ViewShellBase& rBase,
249 std::shared_ptr<sd::tools::EventMultiplexer> pMultiplexer,
250 const std::shared_ptr<ViewShellManager>& rpViewShellManager,
251 const std::shared_ptr<ToolBarManager>& rpToolBarManager);
253
254 void SetValid (bool bValid);
255
256 void ResetToolBars (ToolBarGroup eGroup);
257 void ResetAllToolBars();
258 void AddToolBar (ToolBarGroup eGroup, const OUString& rsToolBarName);
259 void AddToolBarShell (ToolBarGroup eGroup, ShellId nToolBarId);
260 void RemoveToolBar (ToolBarGroup eGroup, const OUString& rsToolBarName);
261
269
270 void ToolBarsDestroyed();
271
272 void RequestUpdate();
273
274 void PreUpdate();
275 void PostUpdate();
283 void Update (::std::unique_ptr<LayouterLock> pLayouterLock);
284
286 {
287 public:
288 explicit UpdateLockImplementation (Implementation& rImplementation)
289 : mrImplementation(rImplementation) { mrImplementation.LockUpdate(); }
291 private:
293 };
294
296 void LockUpdate();
297 void UnlockUpdate();
298
299 ToolBarRules& GetToolBarRules() { return maToolBarRules;}
300
301private:
302 mutable ::osl::Mutex maMutex;
304 std::shared_ptr<sd::tools::EventMultiplexer> mpEventMultiplexer;
306 ToolBarList maToolBarList;
307 ToolBarShellList maToolBarShellList;
308 Reference<frame::XLayoutManager> mxLayouter;
309 sal_Int32 mnLockCount;
317 ::std::unique_ptr<LayouterLock> mpSynchronousLayouterLock;
318 ::std::unique_ptr<LayouterLock> mpAsynchronousLayouterLock;
319 ::std::unique_ptr<ViewShellManager::UpdateLock, o3tl::default_delete<ViewShellManager::UpdateLock>> mpViewShellManagerLock;
322 ToolBarRules maToolBarRules;
323
324 static OUString GetToolBarResourceName (std::u16string_view rsBaseName);
325 bool CheckPlugInMode (std::u16string_view rsName) const;
326
327 DECL_LINK(UpdateCallback, void *, void);
328 DECL_LINK(EventMultiplexerCallback, sd::tools::EventMultiplexerEvent&, void);
329 DECL_LINK(SetValidCallback, void*, void);
330};
331
332//===== ToolBarManager ========================================================
333
334std::shared_ptr<ToolBarManager> ToolBarManager::Create (
335 ViewShellBase& rBase,
336 const std::shared_ptr<sd::tools::EventMultiplexer>& rpMultiplexer,
337 const std::shared_ptr<ViewShellManager>& rpViewShellManager)
338{
339 std::shared_ptr<ToolBarManager> pManager (new ToolBarManager());
340 pManager->mpImpl.reset(
341 new Implementation(rBase,rpMultiplexer,rpViewShellManager,pManager));
342 return pManager;
343}
344
346{
347}
348
350{
351}
352
354{
355 if (mpImpl != nullptr)
356 mpImpl.reset();
357}
358
360{
361 if (mpImpl != nullptr)
362 {
363 UpdateLock aLock (shared_from_this());
364 mpImpl->ResetToolBars(eGroup);
365 }
366}
367
369{
370 if (mpImpl != nullptr)
371 {
372 UpdateLock aLock (shared_from_this());
373 mpImpl->ResetAllToolBars();
374 }
375}
376
378 ToolBarGroup eGroup,
379 const OUString& rsToolBarName)
380{
381 if (mpImpl != nullptr)
382 {
383 UpdateLock aLock (shared_from_this());
384 mpImpl->AddToolBar(eGroup,rsToolBarName);
385 }
386}
387
389 ToolBarGroup eGroup,
390 ShellId nToolBarId)
391{
392 if (mpImpl != nullptr)
393 {
394 UpdateLock aLock (shared_from_this());
395 mpImpl->AddToolBarShell(eGroup,nToolBarId);
396 }
397}
398
400 ToolBarGroup eGroup,
401 const OUString& rsToolBarName)
402{
403 if (mpImpl != nullptr)
404 {
405 UpdateLock aLock (shared_from_this());
406 mpImpl->RemoveToolBar(eGroup,rsToolBarName);
407 }
408}
409
411 ToolBarGroup eGroup,
412 const OUString& rsToolBarName)
413{
414 if (mpImpl != nullptr)
415 {
416 UpdateLock aLock (shared_from_this());
417 mpImpl->ResetToolBars(eGroup);
418 mpImpl->AddToolBar(eGroup,rsToolBarName);
419 }
420}
421
423 ToolBarGroup eGroup,
424 ShellId nToolBarId)
425{
426 if (mpImpl != nullptr)
427 {
428 UpdateLock aLock (shared_from_this());
429 mpImpl->ResetToolBars(eGroup);
430 mpImpl->AddToolBarShell(eGroup,nToolBarId);
431 }
432}
433
435{
436 if (mpImpl != nullptr)
437 mpImpl->PreUpdate();
438}
439
441{
442 if (mpImpl != nullptr)
443 mpImpl->RequestUpdate();
444}
445
447{
448 if (mpImpl != nullptr)
449 mpImpl->LockViewShellManager();
450}
451
453{
454 if (mpImpl != nullptr)
455 mpImpl->LockUpdate();
456}
457
459{
460 if (mpImpl != nullptr)
461 mpImpl->UnlockUpdate();
462}
463
465{
466 if (mpImpl != nullptr)
467 {
468 mpImpl->ReleaseAllToolBarShells();
469 mpImpl->GetToolBarRules().MainViewShellChanged(ViewShell::ST_NONE);
470 }
471}
472
474{
475 if (mpImpl != nullptr)
476 {
477 mpImpl->ReleaseAllToolBarShells();
478 mpImpl->GetToolBarRules().MainViewShellChanged(rMainViewShell);
479 }
480}
481
483 const ViewShell& rViewShell,
484 const SdrView& rView)
485{
486 if (mpImpl != nullptr)
487 mpImpl->GetToolBarRules().SelectionHasChanged(rViewShell,rView);
488}
489
491{
492 if (mpImpl != nullptr)
493 mpImpl->ToolBarsDestroyed();
494}
495
496//===== ToolBarManager::Implementation =======================================
497
499 ViewShellBase& rBase,
500 std::shared_ptr<sd::tools::EventMultiplexer> pMultiplexer,
501 const std::shared_ptr<ViewShellManager>& rpViewShellManager,
502 const std::shared_ptr<ToolBarManager>& rpToolBarManager)
503 : mrBase(rBase),
504 mpEventMultiplexer(std::move(pMultiplexer)),
505 mbIsValid(false),
506 mnLockCount(0),
507 mbPreUpdatePending(false),
508 mbPostUpdatePending(false),
509 mnPendingUpdateCall(nullptr),
510 mnPendingSetValidCall(nullptr),
511 maToolBarRules(rpToolBarManager,rpViewShellManager)
512{
514 mpEventMultiplexer->AddEventListener( aLink );
515}
516
522{
523 // Unregister at broadcasters.
525 mpEventMultiplexer->RemoveEventListener(aLink);
526
527 // Abort pending user calls.
528 if (mnPendingUpdateCall != nullptr)
529 Application::RemoveUserEvent(mnPendingUpdateCall);
530 if (mnPendingSetValidCall != nullptr)
531 Application::RemoveUserEvent(mnPendingSetValidCall);
532}
533
535{
536 maToolBarList.MarkAllToolBarsAsNotActive();
537}
538
540{
541 ::osl::MutexGuard aGuard(maMutex);
542
543 if (mbIsValid == bValid)
544 return;
545
546 UpdateLockImplementation aUpdateLock (*this);
547
548 mbIsValid = bValid;
549 if (mbIsValid)
550 {
551 Reference<frame::XFrame> xFrame = mrBase.GetViewFrame().GetFrame().GetFrameInterface();
552 try
553 {
554 Reference<beans::XPropertySet> xFrameProperties (xFrame, UNO_QUERY_THROW);
555 Any aValue (xFrameProperties->getPropertyValue("LayoutManager"));
556 aValue >>= mxLayouter;
557 // tdf#119997 if mpSynchronousLayouterLock was created before mxLayouter was
558 // set then update it now that its available
559 if (mpSynchronousLayouterLock && !mpSynchronousLayouterLock->is())
560 mpSynchronousLayouterLock.reset(new LayouterLock(mxLayouter));
561 }
562 catch (const RuntimeException&)
563 {
564 }
565
566 GetToolBarRules().Update(mrBase);
567 }
568 else
569 {
571 mxLayouter = nullptr;
572 }
573}
574
576{
577 ::osl::MutexGuard aGuard(maMutex);
578
579 maToolBarList.ClearGroup(eGroup);
580 maToolBarShellList.ClearGroup(eGroup);
581
582 mbPreUpdatePending = true;
583}
584
586{
587 SAL_INFO("sd.view", __func__ << ": resetting all tool bars");
588 for (auto i : o3tl::enumrange<ToolBarGroup>())
590}
591
593 ToolBarGroup eGroup,
594 const OUString& rsToolBarName)
595{
596 ::osl::MutexGuard aGuard(maMutex);
597
598 if (CheckPlugInMode(rsToolBarName))
599 {
600 maToolBarList.AddToolBar(eGroup,rsToolBarName);
601
602 mbPostUpdatePending = true;
603 if (mnLockCount == 0)
604 PostUpdate();
605 }
606}
607
609 ToolBarGroup eGroup,
610 const OUString& rsToolBarName)
611{
612 ::osl::MutexGuard aGuard(maMutex);
613
614 if (maToolBarList.RemoveToolBar(eGroup,rsToolBarName))
615 {
616 mbPreUpdatePending = true;
617 if (mnLockCount == 0)
618 PreUpdate();
619 }
620}
621
623 ToolBarGroup eGroup,
624 ShellId nToolBarId)
625{
626 ViewShell* pMainViewShell = mrBase.GetMainViewShell().get();
627 if (pMainViewShell != nullptr)
628 {
629 maToolBarShellList.AddShellId(eGroup,nToolBarId);
630 GetToolBarRules().SubShellAdded(eGroup, nToolBarId);
631 }
632}
633
635{
636 maToolBarShellList.ReleaseAllShells(GetToolBarRules());
637 maToolBarShellList.UpdateShells(mrBase.GetMainViewShell(), mrBase.GetViewShellManager());
638}
639
641{
642 if (mnPendingUpdateCall == nullptr)
643 {
644 mnPendingUpdateCall = Application::PostUserEvent(
645 LINK(this,ToolBarManager::Implementation,UpdateCallback));
646 }
647}
648
650{
651 ::osl::MutexGuard aGuard(maMutex);
652
653 if (!(mbIsValid
654 && mbPreUpdatePending
655 && mxLayouter.is()))
656 return;
657
658 mbPreUpdatePending = false;
659
660 SAL_INFO("sd.view", __func__ << ": ToolBarManager::PreUpdate [");
661
662 // Get the list of tool bars that are not used anymore and are to be
663 // deactivated.
664 std::vector<OUString> aToolBars;
665 maToolBarList.GetToolBarsToDeactivate(aToolBars);
666
667 // Turn off the tool bars.
668 for (const auto& aToolBar : aToolBars)
669 {
670 OUString sFullName (GetToolBarResourceName(aToolBar));
671 SAL_INFO("sd.view", __func__ << ": turning off tool bar " << sFullName);
672 mxLayouter->destroyElement(sFullName);
673 maToolBarList.MarkToolBarAsNotActive(aToolBar);
674 }
675
676 SAL_INFO("sd.view", __func__ << ": ToolBarManager::PreUpdate ]");
677}
678
680{
681 ::osl::MutexGuard aGuard(maMutex);
682
683 if (!(mbIsValid
684 && mbPostUpdatePending
685 && mxLayouter.is()))
686 return;
687
688 mbPostUpdatePending = false;
689
690 // Create the list of requested tool bars.
691 std::vector<OUString> aToolBars;
692 maToolBarList.GetToolBarsToActivate(aToolBars);
693
694 SAL_INFO("sd.view", __func__ << ": ToolBarManager::PostUpdate [");
695
696 // Turn on the tool bars that are visible in the new context.
697 for (const auto& aToolBar : aToolBars)
698 {
699 OUString sFullName (GetToolBarResourceName(aToolBar));
700 SAL_INFO("sd.view", __func__ << ": turning on tool bar " << sFullName);
701 mxLayouter->requestElement(sFullName);
702 maToolBarList.MarkToolBarAsActive(aToolBar);
703 }
704
705 SAL_INFO("sd.view", __func__ << ": ToolBarManager::PostUpdate ]");
706}
707
709{
710 if (mpViewShellManagerLock == nullptr)
711 mpViewShellManagerLock.reset(
712 new ViewShellManager::UpdateLock(mrBase.GetViewShellManager()));
713}
714
716{
717 SAL_INFO("sd.view", __func__ << ": LockUpdate " << mnLockCount);
718 ::osl::MutexGuard aGuard(maMutex);
719
720 DBG_ASSERT(mnLockCount<100, "ToolBarManager lock count unusually high");
721 if (mnLockCount == 0)
722 {
723 OSL_ASSERT(mpSynchronousLayouterLock == nullptr);
724
725 mpSynchronousLayouterLock.reset(new LayouterLock(mxLayouter));
726 }
727 ++mnLockCount;
728}
729
731{
732 SAL_INFO("sd.view", __func__ << ": UnlockUpdate " << mnLockCount);
733 ::osl::MutexGuard aGuard(maMutex);
734
735 OSL_ASSERT(mnLockCount>0);
736 --mnLockCount;
737 if (mnLockCount == 0)
738 {
739 Update(std::move(mpSynchronousLayouterLock));
740 }
741}
742
744 ::std::unique_ptr<LayouterLock> pLocalLayouterLock)
745{
746 // When the lock is released and there are pending changes to the set of
747 // tool bars then update this set now.
748 if (mnLockCount != 0)
749 return;
750
751 // During creation of ViewShellBase we may have the situation that
752 // the controller has already been created and attached to the frame
753 // but that the ToolBarManager has not yet completed its
754 // initialization (by initializing the mxLayouter member.) We do
755 // this here so that we do not have to wait for the next Update()
756 // call to show the tool bars.
757 if (mnPendingSetValidCall != nullptr)
758 {
759 Application::RemoveUserEvent(mnPendingSetValidCall);
760 mnPendingSetValidCall = nullptr;
761 SetValid(true);
762 }
763
764 if (mbIsValid && mxLayouter.is() && (mbPreUpdatePending || mbPostUpdatePending))
765 {
766 // 1) Release UNO tool bars that are no longer used. Do this
767 // now so that they are not updated when the SFX shell stack is
768 // modified.
769 if (mbPreUpdatePending)
770 PreUpdate();
771
772 // 2) Update the requested shells that represent tool bar
773 // functionality. Those that are not used anymore are
774 // deactivated now. Those that are missing are activated in the
775 // next step together with the view shells.
776 if (mpViewShellManagerLock == nullptr)
777 mpViewShellManagerLock.reset(
778 new ViewShellManager::UpdateLock(mrBase.GetViewShellManager()));
779 maToolBarShellList.UpdateShells(
780 mrBase.GetMainViewShell(),
781 mrBase.GetViewShellManager());
782
783 // 3) Unlock the ViewShellManager::UpdateLock. This updates the
784 // shell stack.
785 mpViewShellManagerLock.reset();
786
787 // 4) Make the UNO tool bars visible. The outstanding call to
788 // PostUpdate() is done via PostUserEvent() so that it is
789 // guaranteed to be executed when the SFX shell stack has been
790 // updated (under the assumption that our lock to the
791 // ViewShellManager was the only one open. If that is not the
792 // case then all should still be well but not as fast.)
793
794 // Note that the lock count may have been increased since
795 // entering this method. In that case one of the next
796 // UnlockUpdate() calls will post the UpdateCallback.
797 if (mnLockCount==0)
798 {
799 mpAsynchronousLayouterLock = std::move(pLocalLayouterLock);
800 if (mnPendingUpdateCall==nullptr)
801 {
802 mnPendingUpdateCall = Application::PostUserEvent(
803 LINK(this,ToolBarManager::Implementation,UpdateCallback));
804 }
805 }
806 }
807 else
808 {
809 mpViewShellManagerLock.reset();
810 pLocalLayouterLock.reset();
811 }
812}
813
815{
816 mnPendingUpdateCall = nullptr;
817 if (mnLockCount == 0)
818 {
819 if (mbPreUpdatePending)
820 PreUpdate();
821 if (mbPostUpdatePending)
822 PostUpdate();
823 if (mbIsValid && mxLayouter.is())
824 mpAsynchronousLayouterLock.reset();
825 }
826}
827
830{
832 switch (rEvent.meEventId)
833 {
835 if (mnPendingSetValidCall == nullptr)
836 mnPendingSetValidCall
837 = Application::PostUserEvent(LINK(this,Implementation,SetValidCallback));
838 break;
839
841 SetValid(false);
842 break;
843
844 default: break;
845 }
846}
847
848IMPL_LINK_NOARG(ToolBarManager::Implementation, SetValidCallback, void*, void)
849{
850 mnPendingSetValidCall = nullptr;
851 SetValid(true);
852}
853
855 std::u16string_view rsBaseName)
856{
857 return OUString::Concat("private:resource/toolbar/") + rsBaseName;
858}
859
860bool ToolBarManager::Implementation::CheckPlugInMode (std::u16string_view rsName) const
861{
862 bool bValid (false);
863
864 // Determine the plug in mode.
865 bool bIsPlugInMode (false);
866 do
867 {
868 SfxObjectShell* pObjectShell = mrBase.GetObjectShell();
869 if (pObjectShell == nullptr)
870 break;
871
872 SfxMedium* pMedium = pObjectShell->GetMedium();
873 if (pMedium == nullptr)
874 break;
875
876 const SfxBoolItem* pViewOnlyItem = pMedium->GetItemSet().GetItem(SID_VIEWONLY, false);
877 if (pViewOnlyItem == nullptr)
878 break;
879
880 bIsPlugInMode = pViewOnlyItem->GetValue();
881 }
882 while (false);
883
884 if (rsName == msViewerToolBar)
885 bValid = bIsPlugInMode;
886 else
887 bValid = ! bIsPlugInMode;
888
889 return bValid;
890}
891
892} // end of namespace sd
893
894namespace {
895
896using namespace ::sd;
897
898//===== LayouterLock ==========================================================
899
900LayouterLock::LayouterLock (const Reference<frame::XLayoutManager>& rxLayouter)
901 : mxLayouter(rxLayouter)
902{
903 SAL_INFO("sd.view", __func__ << ": LayouterLock " << (mxLayouter.is() ? 1 :0));
904 if (mxLayouter.is())
905 mxLayouter->lock();
906}
907
908LayouterLock::~LayouterLock()
909{
910 SAL_INFO("sd.view", __func__ << ": ~LayouterLock " << (mxLayouter.is() ? 1 :0));
911 if (mxLayouter.is())
912 mxLayouter->unlock();
913}
914
915//===== ToolBarRules ==========================================================
916
917ToolBarRules::ToolBarRules (
918 std::shared_ptr<sd::ToolBarManager> pToolBarManager,
919 std::shared_ptr<sd::ViewShellManager> pViewShellManager)
920 : mpToolBarManager(std::move(pToolBarManager)),
921 mpViewShellManager(std::move(pViewShellManager))
922{
923}
924
925void ToolBarRules::Update (ViewShellBase const & rBase)
926{
927 ViewShell* pMainViewShell = rBase.GetMainViewShell().get();
928 if (pMainViewShell != nullptr)
929 {
930 MainViewShellChanged(pMainViewShell->GetShellType());
931 if (pMainViewShell->GetView())
932 SelectionHasChanged (*pMainViewShell, *pMainViewShell->GetView());
933 }
934 else
936}
937
938void ToolBarRules::MainViewShellChanged (ViewShell::ShellType nShellType)
939{
940 ::sd::ToolBarManager::UpdateLock aToolBarManagerLock (mpToolBarManager);
941 ::sd::ViewShellManager::UpdateLock aViewShellManagerLock (mpViewShellManager);
942
943 mpToolBarManager->ResetAllToolBars();
944
945 switch(nShellType)
946 {
947 case ::sd::ViewShell::ST_IMPRESS:
948 case ::sd::ViewShell::ST_NOTES:
949 case ::sd::ViewShell::ST_HANDOUT:
950 mpToolBarManager->AddToolBar(
953 mpToolBarManager->AddToolBar(
956 mpToolBarManager->AddToolBar(
959 break;
960
961 case ::sd::ViewShell::ST_DRAW:
962 mpToolBarManager->AddToolBar(
965 mpToolBarManager->AddToolBar(
968 mpToolBarManager->AddToolBar(
971 break;
972
974 mpToolBarManager->AddToolBar(
977 mpToolBarManager->AddToolBar(
980 mpToolBarManager->AddToolBarShell(
981 ToolBarManager::ToolBarGroup::Permanent, ToolbarId::Draw_Text_Toolbox_Sd);
982 break;
983
985 mpToolBarManager->AddToolBar(
988 mpToolBarManager->AddToolBar(
991 mpToolBarManager->AddToolBar(
994 break;
995
999 default:
1000 break;
1001 }
1002}
1003
1004void ToolBarRules::MainViewShellChanged (const ViewShell& rMainViewShell)
1005{
1006 ::sd::ToolBarManager::UpdateLock aToolBarManagerLock (mpToolBarManager);
1007 ::sd::ViewShellManager::UpdateLock aViewShellManagerLock (mpViewShellManager);
1008
1009 MainViewShellChanged(rMainViewShell.GetShellType());
1010 switch(rMainViewShell.GetShellType())
1011 {
1012 case ::sd::ViewShell::ST_IMPRESS:
1013 case ::sd::ViewShell::ST_DRAW:
1014 case ::sd::ViewShell::ST_NOTES:
1015 {
1016 const DrawViewShell* pDrawViewShell
1017 = dynamic_cast<const DrawViewShell*>(&rMainViewShell);
1018 if (pDrawViewShell != nullptr)
1019 {
1020 if (pDrawViewShell->GetEditMode() == EditMode::MasterPage)
1021 mpToolBarManager->AddToolBar(
1024 else if ( rMainViewShell.GetShellType() != ::sd::ViewShell::ST_DRAW )
1025 mpToolBarManager->AddToolBar(
1028 }
1029 break;
1030 }
1031
1032 default:
1033 break;
1034 }
1035}
1036
1037void ToolBarRules::SelectionHasChanged (
1038 const ::sd::ViewShell& rViewShell,
1039 const SdrView& rView)
1040{
1041 ::sd::ToolBarManager::UpdateLock aLock (mpToolBarManager);
1042 mpToolBarManager->LockViewShellManager();
1043 bool bTextEdit = rView.IsTextEdit();
1044
1045 mpToolBarManager->ResetToolBars(ToolBarManager::ToolBarGroup::Function);
1046
1048 {
1049 switch (rView.GetContext())
1050 {
1051 case SdrViewContext::Graphic:
1052 if (!bTextEdit)
1053 mpToolBarManager->SetToolBarShell(ToolBarManager::ToolBarGroup::Function,
1054 ToolbarId::Draw_Graf_Toolbox);
1055 break;
1056
1057 case SdrViewContext::Media:
1058 if (!bTextEdit)
1059 mpToolBarManager->SetToolBarShell(ToolBarManager::ToolBarGroup::Function,
1060 ToolbarId::Draw_Media_Toolbox);
1061 break;
1062
1063 case SdrViewContext::Table:
1064 mpToolBarManager->SetToolBarShell(ToolBarManager::ToolBarGroup::Function,
1065 ToolbarId::Draw_Table_Toolbox);
1066 bTextEdit = true;
1067 break;
1068
1069 case SdrViewContext::Standard:
1070 default:
1071 if (!bTextEdit)
1072 {
1073 switch(rViewShell.GetShellType())
1074 {
1075 case ::sd::ViewShell::ST_IMPRESS:
1076 case ::sd::ViewShell::ST_DRAW:
1077 case ::sd::ViewShell::ST_NOTES:
1078 case ::sd::ViewShell::ST_HANDOUT:
1079 mpToolBarManager->SetToolBar(ToolBarManager::ToolBarGroup::Function,
1081 break;
1082 default:
1083 break;
1084 }
1085 break;
1086 }
1087 }
1088 }
1089
1090 if( bTextEdit )
1091 mpToolBarManager->AddToolBarShell(ToolBarManager::ToolBarGroup::Function, ToolbarId::Draw_Text_Toolbox_Sd);
1092
1093 SdrView* pView = &const_cast<SdrView&>(rView);
1094 // Check if the extrusion tool bar and the fontwork tool bar have to
1095 // be activated.
1096 if (svx::checkForSelectedCustomShapes(pView, true /* bOnlyExtruded */ ))
1097 mpToolBarManager->AddToolBarShell(ToolBarManager::ToolBarGroup::Function, ToolbarId::Svx_Extrusion_Bar);
1098
1100 mpToolBarManager->AddToolBarShell(ToolBarManager::ToolBarGroup::Function, ToolbarId::Svx_Fontwork_Bar);
1101
1102 // Switch on additional context-sensitive tool bars.
1103 if (rView.GetContext() == SdrViewContext::PointEdit)
1104 mpToolBarManager->AddToolBarShell(ToolBarManager::ToolBarGroup::Function, ToolbarId::Bezier_Toolbox_Sd);
1105}
1106
1107void ToolBarRules::SubShellAdded (
1109 sd::ShellId nShellId)
1110{
1111 // For some tool bar shells (those defined in sd) we have to add the
1112 // actual tool bar here.
1113 switch (nShellId)
1114 {
1115 case ToolbarId::Draw_Graf_Toolbox:
1116 mpToolBarManager->AddToolBar(eGroup, ToolBarManager::msGraphicObjectBar);
1117 break;
1118
1119 case ToolbarId::Draw_Media_Toolbox:
1120 mpToolBarManager->AddToolBar(eGroup, ToolBarManager::msMediaObjectBar);
1121 break;
1122
1123 case ToolbarId::Draw_Text_Toolbox_Sd:
1124 mpToolBarManager->AddToolBar(eGroup, ToolBarManager::msTextObjectBar);
1125 break;
1126
1127 case ToolbarId::Bezier_Toolbox_Sd:
1128 mpToolBarManager->AddToolBar(eGroup, ToolBarManager::msBezierObjectBar);
1129 break;
1130
1131 case ToolbarId::Draw_Table_Toolbox:
1132 mpToolBarManager->AddToolBar(eGroup, ToolBarManager::msTableObjectBar);
1133 break;
1134
1135 default:
1136 break;
1137 }
1138}
1139
1140void ToolBarRules::SubShellRemoved (
1142 sd::ShellId nShellId)
1143{
1144 // For some tool bar shells (those defined in sd) we have to add the
1145 // actual tool bar here.
1146 switch (nShellId)
1147 {
1148 case ToolbarId::Draw_Graf_Toolbox:
1149 mpToolBarManager->RemoveToolBar(eGroup, ToolBarManager::msGraphicObjectBar);
1150 break;
1151
1152 case ToolbarId::Draw_Media_Toolbox:
1153 mpToolBarManager->RemoveToolBar(eGroup, ToolBarManager::msMediaObjectBar);
1154 break;
1155
1156 case ToolbarId::Draw_Text_Toolbox_Sd:
1157 mpToolBarManager->RemoveToolBar(eGroup, ToolBarManager::msTextObjectBar);
1158 break;
1159
1160 case ToolbarId::Bezier_Toolbox_Sd:
1161 mpToolBarManager->RemoveToolBar(eGroup, ToolBarManager::msBezierObjectBar);
1162 break;
1163
1164 case ToolbarId::Draw_Table_Toolbox:
1165 mpToolBarManager->RemoveToolBar(eGroup, ToolBarManager::msTableObjectBar);
1166 break;
1167
1168 default:
1169 break;
1170 }
1171}
1172
1173//===== ToolBarList ===========================================================
1174
1175ToolBarList::ToolBarList()
1176{
1177}
1178
1179void ToolBarList::ClearGroup (sd::ToolBarManager::ToolBarGroup eGroup)
1180{
1181 Groups::iterator iGroup (maGroups.find(eGroup));
1182 if (iGroup != maGroups.end())
1183 {
1184 iGroup->second.clear();
1185 }
1186}
1187
1188void ToolBarList::AddToolBar (
1190 const OUString& rsName)
1191{
1192 Groups::iterator iGroup (maGroups.find(eGroup));
1193 if (iGroup == maGroups.end())
1194 iGroup = maGroups.emplace(eGroup,std::vector<OUString>()).first;
1195
1196 if (iGroup != maGroups.end())
1197 {
1198 auto iBar (std::find(iGroup->second.cbegin(),iGroup->second.cend(),rsName));
1199 if (iBar == iGroup->second.cend())
1200 {
1201 iGroup->second.push_back(rsName);
1202 }
1203 }
1204}
1205
1206bool ToolBarList::RemoveToolBar (
1208 const OUString& rsName)
1209{
1210 Groups::iterator iGroup (maGroups.find(eGroup));
1211 if (iGroup != maGroups.end())
1212 {
1213 auto iBar (std::find(iGroup->second.begin(),iGroup->second.end(),rsName));
1214 if (iBar != iGroup->second.end())
1215 {
1216 iGroup->second.erase(iBar);
1217 return true;
1218 }
1219 }
1220 return false;
1221}
1222
1223void ToolBarList::MakeRequestedToolBarList (std::vector<OUString>& rRequestedToolBars) const
1224{
1226 {
1227 Groups::const_iterator iGroup (maGroups.find(eGroup));
1228 if (iGroup != maGroups.end())
1229 rRequestedToolBars.insert( rRequestedToolBars.end(),
1230 iGroup->second.begin(),
1231 iGroup->second.end() );
1232 }
1233}
1234
1235void ToolBarList::GetToolBarsToActivate (std::vector<OUString>& rToolBars) const
1236{
1237 std::vector<OUString> aRequestedToolBars;
1238 MakeRequestedToolBarList(aRequestedToolBars);
1239
1240 for (const auto& aToolBar : aRequestedToolBars)
1241 {
1242 if (::std::find(maActiveToolBars.begin(),maActiveToolBars.end(),aToolBar)
1243 == maActiveToolBars.end())
1244 {
1245 rToolBars.push_back(aToolBar);
1246 }
1247 }
1248}
1249
1250void ToolBarList::GetToolBarsToDeactivate (std::vector<OUString>& rToolBars) const
1251{
1252 std::vector<OUString> aRequestedToolBars;
1253 MakeRequestedToolBarList(aRequestedToolBars);
1254
1255 for (auto& aToolBar : maActiveToolBars)
1256 {
1257 if (::std::find(aRequestedToolBars.begin(),aRequestedToolBars.end(),aToolBar)
1258 == aRequestedToolBars.end())
1259 {
1260 rToolBars.push_back(aToolBar);
1261 }
1262 }
1263}
1264
1265void ToolBarList::MarkToolBarAsActive (const OUString& rsName)
1266{
1267 maActiveToolBars.push_back(rsName);
1268}
1269
1270void ToolBarList::MarkToolBarAsNotActive (const OUString& rsName)
1271{
1272 maActiveToolBars.erase(
1273 ::std::find(maActiveToolBars.begin(),maActiveToolBars.end(), rsName));
1274}
1275
1276void ToolBarList::MarkAllToolBarsAsNotActive()
1277{
1278 maActiveToolBars.clear();
1279}
1280
1281//===== ToolBarShellList ======================================================
1282
1283ToolBarShellList::ShellDescriptor::ShellDescriptor (
1284 ShellId nId,
1286 : mnId(nId),
1287 meGroup(eGroup)
1288{
1289}
1290
1291ToolBarShellList::ToolBarShellList()
1292{
1293}
1294
1295void ToolBarShellList::ClearGroup (sd::ToolBarManager::ToolBarGroup eGroup)
1296{
1297 for (GroupedShellList::iterator iDescriptor = maNewList.begin(); iDescriptor != maNewList.end(); )
1298 if (iDescriptor->meGroup == eGroup)
1299 iDescriptor = maNewList.erase(iDescriptor);
1300 else
1301 ++iDescriptor;
1302}
1303
1304void ToolBarShellList::AddShellId (sd::ToolBarManager::ToolBarGroup eGroup, sd::ShellId nId)
1305{
1306 // Make sure that the shell is not added twice (and possibly in
1307 // different groups.)
1308 ShellDescriptor aDescriptor (nId,eGroup);
1309 GroupedShellList::iterator iDescriptor (maNewList.find(aDescriptor));
1310 if (iDescriptor != maNewList.end())
1311 {
1312 // The shell is already requested.
1313 if (iDescriptor->meGroup != eGroup)
1314 {
1315 // It is now being requested for another group.
1316 // (Is this an error?)
1317 // Move it to that group.
1318 maNewList.erase(iDescriptor);
1319 maNewList.insert(aDescriptor);
1320 }
1321 // else nothing to do.
1322 }
1323 else
1324 maNewList.insert(aDescriptor);
1325}
1326
1327void ToolBarShellList::ReleaseAllShells (ToolBarRules& rRules)
1328{
1329 // Release the currently active tool bars.
1330 GroupedShellList aList (maCurrentList);
1331 for (const auto& rDescriptor : aList)
1332 {
1333 rRules.SubShellRemoved(rDescriptor.meGroup, rDescriptor.mnId);
1334 }
1335
1336 // Clear the list of requested tool bars.
1337 maNewList.clear();
1338}
1339
1340void ToolBarShellList::UpdateShells (
1341 const std::shared_ptr<ViewShell>& rpMainViewShell,
1342 const std::shared_ptr<ViewShellManager>& rpManager)
1343{
1344 if (rpMainViewShell == nullptr)
1345 return;
1346
1347 GroupedShellList aList;
1348
1349 // Deactivate shells that are in maCurrentList, but not in
1350 // maNewList.
1351 ::std::set_difference(maCurrentList.begin(), maCurrentList.end(),
1352 maNewList.begin(), maNewList.end(),
1353 std::insert_iterator<GroupedShellList>(aList,aList.begin()));
1354 for (const auto& rShell : aList)
1355 {
1356 SAL_INFO("sd.view", __func__ << ": deactivating tool bar shell " << static_cast<sal_uInt32>(rShell.mnId));
1357 rpManager->DeactivateSubShell(*rpMainViewShell, rShell.mnId);
1358 }
1359
1360 // Activate shells that are in maNewList, but not in
1361 // maCurrentList.
1362 aList.clear();
1363 ::std::set_difference(maNewList.begin(), maNewList.end(),
1364 maCurrentList.begin(), maCurrentList.end(),
1365 std::insert_iterator<GroupedShellList>(aList,aList.begin()));
1366 for (const auto& rShell : aList)
1367 {
1368 SAL_INFO("sd.view", __func__ << ": activating tool bar shell " << static_cast<sal_uInt32>(rShell.mnId));
1369 rpManager->ActivateSubShell(*rpMainViewShell, rShell.mnId);
1370 }
1371
1372 // The maNewList now reflects the current state and thus is made
1373 // maCurrentList.
1374 maCurrentList = maNewList;
1375}
1376
1377} // end of anonymous namespace
1378
1379/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@ ControllerDetached
A UNO controller has been detached to the UNO frame.
@ ControllerAttached
A UNO controller has been attached to the UNO frame.
std::mutex maMutex
static ImplSVEvent * PostUserEvent(const Link< void *, void > &rLink, void *pCaller=nullptr, bool bReferenceLink=false)
static void RemoveUserEvent(ImplSVEvent *nUserEvent)
virtual bool IsTextEdit() const final override
virtual SdrViewContext GetContext() const
bool GetValue() const
const SfxPoolItem * GetItem(sal_uInt16 nWhich, bool bSearchInParent=true) const
SfxItemSet & GetItemSet() const
SfxMedium * GetMedium() const
Base class of the stacked shells that provide graphical views to Draw and Impress documents and editi...
EditMode GetEditMode() const
bool CheckPlugInMode(std::u16string_view rsName) const
void AddToolBar(ToolBarGroup eGroup, const OUString &rsToolBarName)
::std::unique_ptr< LayouterLock > mpSynchronousLayouterLock
The layouter locks manage the locking of the XLayoutManager.
void AddToolBarShell(ToolBarGroup eGroup, ShellId nToolBarId)
void RemoveToolBar(ToolBarGroup eGroup, const OUString &rsToolBarName)
Implementation(ViewShellBase &rBase, std::shared_ptr< sd::tools::EventMultiplexer > pMultiplexer, const std::shared_ptr< ViewShellManager > &rpViewShellManager, const std::shared_ptr< ToolBarManager > &rpToolBarManager)
This constructor takes three arguments even though the ToolBarManager could be taken from the ViewShe...
DECL_LINK(UpdateCallback, void *, void)
Reference< frame::XLayoutManager > mxLayouter
DECL_LINK(SetValidCallback, void *, void)
void Update(::std::unique_ptr< LayouterLock > pLayouterLock)
Tell the XLayoutManager about the tool bars that we would like to be shown.
::std::unique_ptr< ViewShellManager::UpdateLock, o3tl::default_delete< ViewShellManager::UpdateLock > > mpViewShellManagerLock
static OUString GetToolBarResourceName(std::u16string_view rsBaseName)
void ReleaseAllToolBarShells()
Release all tool bar shells and the associated framework tool bars.
void ResetToolBars(ToolBarGroup eGroup)
::std::unique_ptr< LayouterLock > mpAsynchronousLayouterLock
std::shared_ptr< sd::tools::EventMultiplexer > mpEventMultiplexer
DECL_LINK(EventMultiplexerCallback, sd::tools::EventMultiplexerEvent &, void)
~Implementation()
The order of statements is important.
Use this class to prevent the visible tool bars from being updated (and thus causing repaints and GUI...
static constexpr OUStringLiteral msCommonTaskToolBar
static constexpr OUStringLiteral msSlideSorterToolBar
static constexpr OUStringLiteral msOutlineToolBar
void AddToolBarShell(ToolBarGroup eGroup, ShellId nToolBarId)
Add the tool bar shell to the shell stack.
ToolBarGroup
The set of tool bar groups.
static constexpr OUStringLiteral msBezierObjectBar
void RequestUpdate()
Request an update of the active tool bars.
void MainViewShellChanged()
When the view in the center pane changes then this method sets up the initial set of tool bars for th...
std::unique_ptr< Implementation > mpImpl
void LockViewShellManager()
This is a hint for the ToolBarManager to improve the performance when it updates its tool bars when i...
void AddToolBar(ToolBarGroup eGroup, const OUString &rsToolBarName)
Add the tool bar with the given name to the specified group of tool bars.
void SetToolBarShell(ToolBarGroup eGroup, ShellId nToolBarId)
This is basically a shortcut for ResetToolBars(),AddToolBar().
void RemoveToolBar(ToolBarGroup eGroup, const OUString &rsToolBarName)
Remove the tool bar with the given name from the specified group.
void SetToolBar(ToolBarGroup eGroup, const OUString &rsToolBarName)
This is basically a shortcut for ResetToolBars(),AddToolBar().
static constexpr OUStringLiteral msSlideSorterObjectBar
static constexpr OUStringLiteral msDrawingObjectToolBar
static constexpr OUStringLiteral msOptionsToolBar
static constexpr OUStringLiteral msTextObjectBar
void SelectionHasChanged(const ViewShell &rViewShell, const SdrView &rView)
Call this method when the selection has changed to update the more temporary tool bars (those in the ...
void ResetAllToolBars()
Reset all tool bars, regardless of the group they belong to.
void ResetToolBars(ToolBarGroup eGroup)
Reset the set of visible object bars in the specified group.
static constexpr OUStringLiteral msMediaObjectBar
static constexpr OUStringLiteral msMasterViewToolBar
void Shutdown()
Call this method prior to the destructor to prevent the ToolBarManager from accessing the ViewShellMa...
static constexpr OUStringLiteral msToolBar
The set of tool bars that are handled by this manager class.
static constexpr OUStringLiteral msViewerToolBar
ToolBarManager()
The ViewShellBase is used to get the XLayoutManager and to determine the plug in mode.
static constexpr OUStringLiteral msGraphicObjectBar
static constexpr OUStringLiteral msTableObjectBar
static std::shared_ptr< ToolBarManager > Create(ViewShellBase &rBase, const std::shared_ptr< tools::EventMultiplexer > &rpMultiplexer, const std::shared_ptr< ViewShellManager > &rpViewShellManager)
Use this method instead of the constructor to create new objects of this class.
SfxViewShell descendant that the stacked Draw/Impress shells are based on.
std::shared_ptr< ViewShell > GetMainViewShell() const
Return the main view shell stacked on the called ViewShellBase object.
Use this class to safely lock updates of the view shell stack.
Base class of the stacked shell hierarchy.
Definition: ViewShell.hxx:92
::sd::View * GetView() const
Definition: ViewShell.hxx:144
SD_DLLPUBLIC ShellType GetShellType() const
Return the type of the shell.
Definition: viewshel.cxx:1402
static bool IsActive(bool bConsiderSingleToolbar=false)
#define DBG_ASSERT(sCon, aError)
sal_uInt16 mnId
EventMultiplexerImpl * mpEventMultiplexer
#define SAL_INFO(area, stream)
int i
IMPL_LINK_NOARG(MainSequence, onTimerHdl, Timer *, void)
IMPL_LINK(SdCharHeightPropertyBox, implMenuSelectHdl, const OUString &, rIdent, void)
bool checkForSelectedCustomShapes(SdrView const *pSdrView, bool bOnlyExtruded)
bool checkForSelectedFontWork(SdrView const *pSdrView)
sal_Int16 nId
Reference< XFrame > xFrame
ToolbarId
bool operator<(const wwFont &r1, const wwFont &r2)