summaryrefslogtreecommitdiff
path: root/sd
diff options
context:
space:
mode:
authorSarper Akdemir <sarper.akdemir@allotropia.de>2024-05-08 14:14:58 +0200
committerSarper Akdemir <sarper.akdemir@allotropia.de>2024-05-16 15:01:55 +0200
commit9d075157ccf3e9468b5208291e398a9d7e4728b8 (patch)
tree92ade858a5884c015519948f2e0e09f6beb47e5f /sd
parent45f9627659e882b9157782dfc5981e31567a306e (diff)
tdf#33603: sd: make state of notes pane persist across runs
Introduces new NotesPaneModule which manages the visibility of NotesPane across modes and different runs. Also introduces new three config values under Office/Impress/MuliPaneGUI/NotesPane/Visible ImpressView, OutlineView and NotesView. Similar to what was there for SlideSorterBar. Change-Id: Id540c508e81878e5a8e1aebd6544839e70b813c8 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167348 Tested-by: Jenkins Reviewed-by: Sarper Akdemir <sarper.akdemir@allotropia.de>
Diffstat (limited to 'sd')
-rw-r--r--sd/Library_sd.mk1
-rw-r--r--sd/source/ui/framework/module/ImpressModule.cxx2
-rw-r--r--sd/source/ui/framework/module/ModuleController.cxx2
-rw-r--r--sd/source/ui/framework/module/NotesPaneModule.cxx268
-rw-r--r--sd/source/ui/framework/module/NotesPaneModule.hxx91
-rw-r--r--sd/source/ui/inc/framework/factories/BasicPaneFactory.hxx1
6 files changed, 365 insertions, 0 deletions
diff --git a/sd/Library_sd.mk b/sd/Library_sd.mk
index de39df79b25b..01f3a1d59610 100644
--- a/sd/Library_sd.mk
+++ b/sd/Library_sd.mk
@@ -277,6 +277,7 @@ $(eval $(call gb_Library_add_exception_objects,sd,\
sd/source/ui/framework/module/DrawModule \
sd/source/ui/framework/module/ImpressModule \
sd/source/ui/framework/module/ModuleController \
+ sd/source/ui/framework/module/NotesPaneModule \
sd/source/ui/framework/module/PresentationModule \
sd/source/ui/framework/module/ShellStackGuard \
sd/source/ui/framework/module/SlideSorterModule \
diff --git a/sd/source/ui/framework/module/ImpressModule.cxx b/sd/source/ui/framework/module/ImpressModule.cxx
index 03c393e29ec4..6879513950a9 100644
--- a/sd/source/ui/framework/module/ImpressModule.cxx
+++ b/sd/source/ui/framework/module/ImpressModule.cxx
@@ -22,6 +22,7 @@
#include <framework/FrameworkHelper.hxx>
#include "ViewTabBarModule.hxx"
#include "CenterViewFocusModule.hxx"
+#include "NotesPaneModule.hxx"
#include "SlideSorterModule.hxx"
#include "ToolBarModule.hxx"
#include "ShellStackGuard.hxx"
@@ -42,6 +43,7 @@ void ImpressModule::Initialize (rtl::Reference<sd::DrawController> const & rxCon
new SlideSorterModule(
rxController,
FrameworkHelper::msLeftImpressPaneURL);
+ new NotesPaneModule(rxController);
new ToolBarModule(rxController);
new ShellStackGuard(rxController);
}
diff --git a/sd/source/ui/framework/module/ModuleController.cxx b/sd/source/ui/framework/module/ModuleController.cxx
index b064eefcdad7..501eb0d81af9 100644
--- a/sd/source/ui/framework/module/ModuleController.cxx
+++ b/sd/source/ui/framework/module/ModuleController.cxx
@@ -52,6 +52,7 @@ ModuleController::ModuleController(const rtl::Reference<::sd::DrawController>& r
"com.sun.star.drawing.framework.BasicPaneFactory",
{ "private:resource/pane/CenterPane",
"private:resource/pane/LeftImpressPane",
+ "private:resource/pane/BottomImpressPane",
"private:resource/pane/LeftDrawPane" });
ProcessFactory(
"com.sun.star.drawing.framework.BasicViewFactory",
@@ -59,6 +60,7 @@ ModuleController::ModuleController(const rtl::Reference<::sd::DrawController>& r
"private:resource/view/GraphicView",
"private:resource/view/OutlineView",
"private:resource/view/NotesView",
+ "private:resource/view/NotesPanelView",
"private:resource/view/HandoutView",
"private:resource/view/SlideSorter",
"private:resource/view/PresentationView" });
diff --git a/sd/source/ui/framework/module/NotesPaneModule.cxx b/sd/source/ui/framework/module/NotesPaneModule.cxx
new file mode 100644
index 000000000000..e489d8a8ff7c
--- /dev/null
+++ b/sd/source/ui/framework/module/NotesPaneModule.cxx
@@ -0,0 +1,268 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "NotesPaneModule.hxx"
+
+#include <DrawController.hxx>
+#include <DrawViewShell.hxx>
+#include <EventMultiplexer.hxx>
+#include <ViewShellBase.hxx>
+#include <ViewShellManager.hxx>
+
+#include <framework/ConfigurationController.hxx>
+#include <framework/FrameworkHelper.hxx>
+#include <framework/ViewShellWrapper.hxx>
+
+#include <officecfg/Office/Impress.hxx>
+
+#include <com/sun/star/drawing/framework/XControllerManager.hpp>
+#include <com/sun/star/frame/XController.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing::framework;
+
+namespace
+{
+const sal_Int32 ResourceActivationRequestEvent = 0;
+const sal_Int32 ResourceDeactivationRequestEvent = 1;
+}
+
+namespace sd::framework
+{
+NotesPaneModule::NotesPaneModule(const rtl::Reference<::sd::DrawController>& rxController)
+ : mxBottomImpressPaneId(FrameworkHelper::CreateResourceId(
+ FrameworkHelper::msNotesPanelViewURL, FrameworkHelper::msBottomImpressPaneURL))
+ , mxMainViewAnchorId(FrameworkHelper::CreateResourceId(FrameworkHelper::msCenterPaneURL))
+{
+ if (!rxController.is())
+ return;
+
+ mpViewShellBase = rxController->GetViewShellBase();
+
+ mxConfigurationController = rxController->getConfigurationController();
+ if (!mxConfigurationController.is())
+ return;
+
+ mxConfigurationController->addConfigurationChangeListener(
+ this, FrameworkHelper::msResourceActivationRequestEvent,
+ Any(ResourceActivationRequestEvent));
+ mxConfigurationController->addConfigurationChangeListener(
+ this, FrameworkHelper::msResourceDeactivationRequestEvent,
+ Any(ResourceDeactivationRequestEvent));
+
+ if (officecfg::Office::Impress::MultiPaneGUI::NotesPane::Visible::ImpressView::get().value_or(
+ false))
+ AddActiveMainView(FrameworkHelper::msImpressViewURL);
+ if (officecfg::Office::Impress::MultiPaneGUI::NotesPane::Visible::OutlineView::get().value_or(
+ false))
+ AddActiveMainView(FrameworkHelper::msOutlineViewURL);
+ if (officecfg::Office::Impress::MultiPaneGUI::NotesPane::Visible::NotesView::get().value_or(
+ false))
+ AddActiveMainView(FrameworkHelper::msNotesViewURL);
+}
+
+NotesPaneModule::~NotesPaneModule()
+{
+ if (mpViewShellBase && mbListeningEventMultiplexer)
+ mpViewShellBase->GetEventMultiplexer()->RemoveEventListener(
+ LINK(this, NotesPaneModule, EventMultiplexerListener));
+}
+
+void NotesPaneModule::AddActiveMainView(const OUString& rsMainViewURL)
+{
+ maActiveMainViewContainer.insert(rsMainViewURL);
+}
+
+bool NotesPaneModule::IsResourceActive(const OUString& rsMainViewURL)
+{
+ return maActiveMainViewContainer.contains(rsMainViewURL);
+}
+
+void NotesPaneModule::SaveResourceState()
+{
+ auto xChanges = comphelper::ConfigurationChanges::create();
+ officecfg::Office::Impress::MultiPaneGUI::NotesPane::Visible::ImpressView::set(
+ IsResourceActive(FrameworkHelper::msImpressViewURL), xChanges);
+ officecfg::Office::Impress::MultiPaneGUI::NotesPane::Visible::OutlineView::set(
+ IsResourceActive(FrameworkHelper::msOutlineViewURL), xChanges);
+ officecfg::Office::Impress::MultiPaneGUI::NotesPane::Visible::NotesView::set(
+ IsResourceActive(FrameworkHelper::msNotesViewURL), xChanges);
+ xChanges->commit();
+}
+
+void NotesPaneModule::disposing(std::unique_lock<std::mutex>&)
+{
+ if (mxConfigurationController.is())
+ {
+ mxConfigurationController->removeConfigurationChangeListener(this);
+ mxConfigurationController = nullptr;
+ }
+}
+
+IMPL_LINK(NotesPaneModule, EventMultiplexerListener, sd::tools::EventMultiplexerEvent&, rEvent,
+ void)
+{
+ if (!mxConfigurationController.is())
+ return;
+
+ switch (rEvent.meEventId)
+ {
+ case EventMultiplexerEventId::EditModeNormal:
+ mbInMasterEditMode = false;
+ if (IsResourceActive(msCurrentMainViewURL))
+ {
+ mxConfigurationController->requestResourceActivation(
+ mxBottomImpressPaneId->getAnchor(), ResourceActivationMode_ADD);
+ mxConfigurationController->requestResourceActivation(
+ mxBottomImpressPaneId, ResourceActivationMode_REPLACE);
+ }
+ else
+ {
+ mxConfigurationController->requestResourceDeactivation(mxBottomImpressPaneId);
+ }
+ break;
+ case EventMultiplexerEventId::EditModeMaster:
+ mbInMasterEditMode = true;
+ mxConfigurationController->requestResourceDeactivation(mxBottomImpressPaneId);
+ break;
+ default:
+ break;
+ }
+}
+
+void SAL_CALL NotesPaneModule::notifyConfigurationChange(const ConfigurationChangeEvent& rEvent)
+{
+ if (!mxConfigurationController.is())
+ return;
+
+ // the late init is hacked here since there's EventMultiplexer isn't available when the
+ // NotesPaneModule is constructed
+ if (!mbListeningEventMultiplexer)
+ {
+ mpViewShellBase->GetEventMultiplexer()->AddEventListener(
+ LINK(this, NotesPaneModule, EventMultiplexerListener));
+ mbListeningEventMultiplexer = true;
+ }
+
+ sal_Int32 nEventType = 0;
+ rEvent.UserData >>= nEventType;
+ switch (nEventType)
+ {
+ case ResourceActivationRequestEvent:
+ if (rEvent.ResourceId->isBoundToURL(FrameworkHelper::msCenterPaneURL,
+ AnchorBindingMode_DIRECT))
+ {
+ if (rEvent.ResourceId->getResourceTypePrefix() == FrameworkHelper::msViewURLPrefix)
+ {
+ onMainViewSwitch(rEvent.ResourceId->getResourceURL(), true);
+ }
+ }
+ else if (rEvent.ResourceId->compareTo(mxBottomImpressPaneId) == 0)
+ {
+ onResourceRequest(true, rEvent.Configuration);
+ }
+ break;
+
+ case ResourceDeactivationRequestEvent:
+ if (rEvent.ResourceId->compareTo(mxMainViewAnchorId) == 0)
+ {
+ onMainViewSwitch(OUString(), false);
+ }
+ else if (rEvent.ResourceId->compareTo(mxBottomImpressPaneId) == 0)
+ {
+ onResourceRequest(false, rEvent.Configuration);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void SAL_CALL NotesPaneModule::disposing(const lang::EventObject& rEvent)
+{
+ if (mxConfigurationController.is() && rEvent.Source == mxConfigurationController)
+ {
+ SaveResourceState();
+ // Without the configuration controller this class can do nothing.
+ mxConfigurationController = nullptr;
+ dispose();
+ }
+}
+
+void NotesPaneModule::onMainViewSwitch(const OUString& rsViewURL, const bool bIsActivated)
+{
+ if (bIsActivated)
+ msCurrentMainViewURL = rsViewURL;
+ else
+ msCurrentMainViewURL.clear();
+
+ if (!mxConfigurationController.is())
+ return;
+
+ sd::framework::ConfigurationController::Lock aLock(mxConfigurationController);
+
+ if (IsResourceActive(msCurrentMainViewURL) && !mbInMasterEditMode)
+ {
+ mxConfigurationController->requestResourceActivation(mxBottomImpressPaneId->getAnchor(),
+ ResourceActivationMode_ADD);
+ mxConfigurationController->requestResourceActivation(mxBottomImpressPaneId,
+ ResourceActivationMode_REPLACE);
+ }
+ else
+ {
+ mxConfigurationController->requestResourceDeactivation(mxBottomImpressPaneId);
+ }
+}
+
+bool NotesPaneModule::IsMasterView(const Reference<XView>& xView)
+{
+ if (mpViewShellBase != nullptr)
+ {
+ auto pViewShellWrapper = dynamic_cast<ViewShellWrapper*>(xView.get());
+ if (pViewShellWrapper)
+ {
+ std::shared_ptr<ViewShell> pViewShell = pViewShellWrapper->GetViewShell();
+ auto pDrawViewShell = std::dynamic_pointer_cast<DrawViewShell>(pViewShell);
+
+ if (pDrawViewShell && pDrawViewShell->GetEditMode() == EditMode::MasterPage)
+ return true;
+ }
+ }
+ return false;
+}
+
+void NotesPaneModule::onResourceRequest(
+ bool bActivation,
+ const css::uno::Reference<css::drawing::framework::XConfiguration>& rxConfiguration)
+{
+ Sequence<Reference<XResourceId>> aCenterViews = rxConfiguration->getResources(
+ FrameworkHelper::CreateResourceId(FrameworkHelper::msCenterPaneURL),
+ FrameworkHelper::msViewURLPrefix, AnchorBindingMode_DIRECT);
+
+ if (aCenterViews.getLength() != 1)
+ return;
+
+ // do not record the state of bottom pane when in master edit modes
+ if (!IsMasterView({ mxConfigurationController->getResource(aCenterViews[0]), UNO_QUERY }))
+ {
+ if (bActivation)
+ {
+ maActiveMainViewContainer.insert(aCenterViews[0]->getResourceURL());
+ }
+ else
+ {
+ maActiveMainViewContainer.erase(aCenterViews[0]->getResourceURL());
+ }
+ }
+}
+
+} // end of namespace sd::framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/sd/source/ui/framework/module/NotesPaneModule.hxx b/sd/source/ui/framework/module/NotesPaneModule.hxx
new file mode 100644
index 000000000000..69a74acbdf0c
--- /dev/null
+++ b/sd/source/ui/framework/module/NotesPaneModule.hxx
@@ -0,0 +1,91 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+#pragma once
+
+#include <com/sun/star/drawing/framework/XConfigurationChangeListener.hpp>
+#include <comphelper/compbase.hxx>
+#include <rtl/ref.hxx>
+#include <tools/link.hxx>
+#include <set>
+
+namespace com::sun::star::drawing::framework
+{
+class XConfigurationController;
+class XView;
+}
+namespace com::sun::star::frame
+{
+class XController;
+}
+namespace sd
+{
+class DrawController;
+class ViewShellBase;
+}
+namespace sd::tools
+{
+class EventMultiplexerEvent;
+}
+
+namespace sd::framework
+{
+/** This module is responsible for handling visibility of NotesPane across modes
+*/
+class NotesPaneModule : public comphelper::WeakComponentImplHelper<
+ css::drawing::framework::XConfigurationChangeListener>
+{
+public:
+ /** Create a new module that controls the view tab bar above the view
+ in the specified pane.
+ @param rxController
+ This is the access point to the drawing framework.
+ */
+ NotesPaneModule(const rtl::Reference<::sd::DrawController>& rxController);
+ virtual ~NotesPaneModule() override;
+
+ void AddActiveMainView(const OUString& rsMainViewURL);
+ bool IsResourceActive(const OUString& rsMainViewURL);
+ void SaveResourceState();
+
+ virtual void disposing(std::unique_lock<std::mutex>&) override;
+
+ // XConfigurationChangeListener
+
+ virtual void SAL_CALL notifyConfigurationChange(
+ const css::drawing::framework::ConfigurationChangeEvent& rEvent) override;
+
+ // XEventListener
+
+ virtual void SAL_CALL disposing(const css::lang::EventObject& rEvent) override;
+
+private:
+ css::uno::Reference<css::drawing::framework::XConfigurationController>
+ mxConfigurationController;
+
+ css::uno::Reference<css::drawing::framework::XResourceId> mxBottomImpressPaneId;
+ css::uno::Reference<css::drawing::framework::XResourceId> mxMainViewAnchorId;
+
+ std::set<OUString> maActiveMainViewContainer;
+ OUString msCurrentMainViewURL;
+ ViewShellBase* mpViewShellBase;
+ bool mbListeningEventMultiplexer = false;
+ bool mbInMasterEditMode = false;
+
+ void onMainViewSwitch(const OUString& rsViewURL, const bool bIsActivated);
+ void onResourceRequest(
+ bool bActivation,
+ const css::uno::Reference<css::drawing::framework::XConfiguration>& rxConfiguration);
+ bool IsMasterView(const css::uno::Reference<css::drawing::framework::XView>& xView);
+
+ DECL_LINK(EventMultiplexerListener, ::sd::tools::EventMultiplexerEvent&, void);
+};
+
+} // end of namespace sd::framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/sd/source/ui/inc/framework/factories/BasicPaneFactory.hxx b/sd/source/ui/inc/framework/factories/BasicPaneFactory.hxx
index fb1ac2cf8236..57395f196bf4 100644
--- a/sd/source/ui/inc/framework/factories/BasicPaneFactory.hxx
+++ b/sd/source/ui/inc/framework/factories/BasicPaneFactory.hxx
@@ -47,6 +47,7 @@ typedef comphelper::WeakComponentImplHelper <
private:resource/pane/CenterPane
private:resource/pane/FullScreenPane
private:resource/pane/LeftImpressPane
+ private:resource/pane/BottomImpressPane
private:resource/pane/LeftDrawPane
There are two left panes because this is (seems to be) the only way to
show different titles for the left pane in Draw and Impress.