1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
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/.
10 #include "NotesPaneModule.hxx"
12 #include <DrawController.hxx>
13 #include <DrawViewShell.hxx>
14 #include <EventMultiplexer.hxx>
15 #include <ViewShellBase.hxx>
16 #include <ViewShellManager.hxx>
18 #include <framework/ConfigurationController.hxx>
19 #include <framework/FrameworkHelper.hxx>
20 #include <framework/ViewShellWrapper.hxx>
22 #include <officecfg/Office/Impress.hxx>
24 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
25 #include <com/sun/star/frame/XController.hpp>
27 using namespace ::com::sun::star
;
28 using namespace ::com::sun::star::uno
;
29 using namespace ::com::sun::star::drawing::framework
;
33 const sal_Int32 ResourceActivationRequestEvent
= 0;
34 const sal_Int32 ResourceDeactivationRequestEvent
= 1;
37 namespace sd::framework
39 NotesPaneModule::NotesPaneModule(const rtl::Reference
<::sd::DrawController
>& rxController
)
40 : mxBottomImpressPaneId(FrameworkHelper::CreateResourceId(
41 FrameworkHelper::msNotesPanelViewURL
, FrameworkHelper::msBottomImpressPaneURL
))
42 , mxMainViewAnchorId(FrameworkHelper::CreateResourceId(FrameworkHelper::msCenterPaneURL
))
44 if (!rxController
.is())
47 mpViewShellBase
= rxController
->GetViewShellBase();
49 mxConfigurationController
= rxController
->getConfigurationController();
50 if (!mxConfigurationController
.is())
53 mxConfigurationController
->addConfigurationChangeListener(
54 this, FrameworkHelper::msResourceActivationRequestEvent
,
55 Any(ResourceActivationRequestEvent
));
56 mxConfigurationController
->addConfigurationChangeListener(
57 this, FrameworkHelper::msResourceDeactivationRequestEvent
,
58 Any(ResourceDeactivationRequestEvent
));
60 if (officecfg::Office::Impress::MultiPaneGUI::NotesPane::Visible::ImpressView::get().value_or(
62 AddActiveMainView(FrameworkHelper::msImpressViewURL
);
63 if (officecfg::Office::Impress::MultiPaneGUI::NotesPane::Visible::OutlineView::get().value_or(
65 AddActiveMainView(FrameworkHelper::msOutlineViewURL
);
66 if (officecfg::Office::Impress::MultiPaneGUI::NotesPane::Visible::NotesView::get().value_or(
68 AddActiveMainView(FrameworkHelper::msNotesViewURL
);
71 NotesPaneModule::~NotesPaneModule()
73 if (mpViewShellBase
&& mbListeningEventMultiplexer
)
74 mpViewShellBase
->GetEventMultiplexer()->RemoveEventListener(
75 LINK(this, NotesPaneModule
, EventMultiplexerListener
));
78 void NotesPaneModule::AddActiveMainView(const OUString
& rsMainViewURL
)
80 maActiveMainViewContainer
.insert(rsMainViewURL
);
83 bool NotesPaneModule::IsResourceActive(const OUString
& rsMainViewURL
)
85 return maActiveMainViewContainer
.contains(rsMainViewURL
);
88 void NotesPaneModule::SaveResourceState()
90 auto xChanges
= comphelper::ConfigurationChanges::create();
91 officecfg::Office::Impress::MultiPaneGUI::NotesPane::Visible::ImpressView::set(
92 IsResourceActive(FrameworkHelper::msImpressViewURL
), xChanges
);
93 officecfg::Office::Impress::MultiPaneGUI::NotesPane::Visible::OutlineView::set(
94 IsResourceActive(FrameworkHelper::msOutlineViewURL
), xChanges
);
95 officecfg::Office::Impress::MultiPaneGUI::NotesPane::Visible::NotesView::set(
96 IsResourceActive(FrameworkHelper::msNotesViewURL
), xChanges
);
100 void NotesPaneModule::disposing(std::unique_lock
<std::mutex
>&)
102 if (mxConfigurationController
.is())
104 mxConfigurationController
->removeConfigurationChangeListener(this);
105 mxConfigurationController
= nullptr;
109 IMPL_LINK(NotesPaneModule
, EventMultiplexerListener
, sd::tools::EventMultiplexerEvent
&, rEvent
,
112 if (!mxConfigurationController
.is())
115 switch (rEvent
.meEventId
)
117 case EventMultiplexerEventId::EditModeNormal
:
118 mbInMasterEditMode
= false;
119 if (IsResourceActive(msCurrentMainViewURL
))
121 mxConfigurationController
->requestResourceActivation(
122 mxBottomImpressPaneId
->getAnchor(), ResourceActivationMode_ADD
);
123 mxConfigurationController
->requestResourceActivation(
124 mxBottomImpressPaneId
, ResourceActivationMode_REPLACE
);
128 mxConfigurationController
->requestResourceDeactivation(mxBottomImpressPaneId
);
131 case EventMultiplexerEventId::EditModeMaster
:
132 mbInMasterEditMode
= true;
133 mxConfigurationController
->requestResourceDeactivation(mxBottomImpressPaneId
);
140 void SAL_CALL
NotesPaneModule::notifyConfigurationChange(const ConfigurationChangeEvent
& rEvent
)
142 if (!mxConfigurationController
.is())
145 // the late init is hacked here since there's EventMultiplexer isn't available when the
146 // NotesPaneModule is constructed
147 if (!mbListeningEventMultiplexer
)
149 mpViewShellBase
->GetEventMultiplexer()->AddEventListener(
150 LINK(this, NotesPaneModule
, EventMultiplexerListener
));
151 mbListeningEventMultiplexer
= true;
154 sal_Int32 nEventType
= 0;
155 rEvent
.UserData
>>= nEventType
;
158 case ResourceActivationRequestEvent
:
159 if (rEvent
.ResourceId
->isBoundToURL(FrameworkHelper::msCenterPaneURL
,
160 AnchorBindingMode_DIRECT
))
162 if (rEvent
.ResourceId
->getResourceTypePrefix() == FrameworkHelper::msViewURLPrefix
)
164 onMainViewSwitch(rEvent
.ResourceId
->getResourceURL(), true);
167 else if (rEvent
.ResourceId
->compareTo(mxBottomImpressPaneId
) == 0)
169 onResourceRequest(true, rEvent
.Configuration
);
173 case ResourceDeactivationRequestEvent
:
174 if (rEvent
.ResourceId
->compareTo(mxMainViewAnchorId
) == 0)
176 onMainViewSwitch(OUString(), false);
178 else if (rEvent
.ResourceId
->compareTo(mxBottomImpressPaneId
) == 0)
180 onResourceRequest(false, rEvent
.Configuration
);
188 void SAL_CALL
NotesPaneModule::disposing(const lang::EventObject
& rEvent
)
190 if (mxConfigurationController
.is() && rEvent
.Source
== mxConfigurationController
)
193 // Without the configuration controller this class can do nothing.
194 mxConfigurationController
= nullptr;
199 void NotesPaneModule::onMainViewSwitch(const OUString
& rsViewURL
, const bool bIsActivated
)
202 msCurrentMainViewURL
= rsViewURL
;
204 msCurrentMainViewURL
.clear();
206 if (!mxConfigurationController
.is())
209 sd::framework::ConfigurationController::Lock
aLock(mxConfigurationController
);
211 if (IsResourceActive(msCurrentMainViewURL
) && !mbInMasterEditMode
)
213 mxConfigurationController
->requestResourceActivation(mxBottomImpressPaneId
->getAnchor(),
214 ResourceActivationMode_ADD
);
215 mxConfigurationController
->requestResourceActivation(mxBottomImpressPaneId
,
216 ResourceActivationMode_REPLACE
);
220 mxConfigurationController
->requestResourceDeactivation(mxBottomImpressPaneId
);
224 bool NotesPaneModule::IsMasterView(const Reference
<XView
>& xView
)
226 if (mpViewShellBase
!= nullptr)
228 auto pViewShellWrapper
= dynamic_cast<ViewShellWrapper
*>(xView
.get());
229 if (pViewShellWrapper
)
231 std::shared_ptr
<ViewShell
> pViewShell
= pViewShellWrapper
->GetViewShell();
232 auto pDrawViewShell
= std::dynamic_pointer_cast
<DrawViewShell
>(pViewShell
);
234 if (pDrawViewShell
&& pDrawViewShell
->GetEditMode() == EditMode::MasterPage
)
241 void NotesPaneModule::onResourceRequest(
243 const css::uno::Reference
<css::drawing::framework::XConfiguration
>& rxConfiguration
)
245 Sequence
<Reference
<XResourceId
>> aCenterViews
= rxConfiguration
->getResources(
246 FrameworkHelper::CreateResourceId(FrameworkHelper::msCenterPaneURL
),
247 FrameworkHelper::msViewURLPrefix
, AnchorBindingMode_DIRECT
);
249 if (aCenterViews
.getLength() != 1)
252 // do not record the state of bottom pane when in master edit modes
253 if (!IsMasterView({ mxConfigurationController
->getResource(aCenterViews
[0]), UNO_QUERY
}))
257 maActiveMainViewContainer
.insert(aCenterViews
[0]->getResourceURL());
261 maActiveMainViewContainer
.erase(aCenterViews
[0]->getResourceURL());
266 } // end of namespace sd::framework
268 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */