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 .
22 #include <framework/FrameworkHelper.hxx>
24 #include <framework/ConfigurationController.hxx>
25 #include <framework/ResourceId.hxx>
26 #include <framework/ViewShellWrapper.hxx>
27 #include <ViewShellBase.hxx>
28 #include <DrawViewShell.hxx>
29 #include <ViewShellHint.hxx>
30 #include <DrawController.hxx>
32 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
33 #include <com/sun/star/frame/XController.hpp>
34 #include <comphelper/servicehelper.hxx>
35 #include <comphelper/compbase.hxx>
36 #include <svl/lstner.hxx>
37 #include <rtl/ustrbuf.hxx>
39 #include <sfx2/request.hxx>
42 #include <vcl/svapp.hxx>
43 #include <comphelper/diagnose_ex.hxx>
45 #include <unordered_map>
47 using namespace ::com::sun::star
;
48 using namespace ::com::sun::star::uno
;
49 using namespace ::com::sun::star::drawing::framework
;
53 //----- CallbackCaller --------------------------------------------------------
55 typedef comphelper::WeakComponentImplHelper
<
56 css::drawing::framework::XConfigurationChangeListener
57 > CallbackCallerInterfaceBase
;
59 /** A CallbackCaller registers as listener at an XConfigurationController
60 object and waits for the notification of one type of event. When that
61 event is received, or when the CallbackCaller detects at its
62 construction that the event will not be sent in the near future, the
63 actual callback object is called and the CallbackCaller destroys itself.
66 : public CallbackCallerInterfaceBase
69 /** Create a new CallbackCaller object. This object controls its own
70 lifetime by acquiring a reference to itself in the constructor.
71 When it detects that the event will not be notified in the near
72 future (because the queue of pending configuration change operations
73 is empty and therefore no event will be sent int the near future, it
74 does not acquires a reference and thus initiates its destruction in
77 This ViewShellBase object is used to determine the
78 XConfigurationController at which to register.
80 The event type which the callback is waiting for.
82 The callback object which is to be notified. The caller will
83 typically release his reference to the caller so that when the
84 CallbackCaller dies (after having called the callback) the
85 callback is destroyed.
88 const ::sd::ViewShellBase
& rBase
,
90 ::sd::framework::FrameworkHelper::ConfigurationChangeEventFilter aFilter
,
91 ::sd::framework::FrameworkHelper::Callback aCallback
);
93 virtual void disposing(std::unique_lock
<std::mutex
>&) override
;
95 virtual void SAL_CALL
disposing (const lang::EventObject
& rEvent
) override
;
96 // XConfigurationChangeListener
97 virtual void SAL_CALL
notifyConfigurationChange (const ConfigurationChangeEvent
& rEvent
) override
;
100 OUString msEventType
;
101 Reference
<XConfigurationController
> mxConfigurationController
;
102 ::sd::framework::FrameworkHelper::ConfigurationChangeEventFilter maFilter
;
103 ::sd::framework::FrameworkHelper::Callback maCallback
;
106 //----- LifetimeController ----------------------------------------------------
108 typedef comphelper::WeakComponentImplHelper
<
109 css::lang::XEventListener
110 > LifetimeControllerInterfaceBase
;
112 /** This class helps controlling the lifetime of the
113 FrameworkHelper. Register at a ViewShellBase object and an XController
114 object and call Dispose() at the associated FrameworkHelper object when
115 one of them and Release() when both of them are destroyed.
117 class LifetimeController
118 : public LifetimeControllerInterfaceBase
,
122 explicit LifetimeController (::sd::ViewShellBase
& rBase
);
123 virtual ~LifetimeController() override
;
125 /** XEventListener. This method is called when the frame::XController
128 using WeakComponentImplHelperBase::disposing
;
129 virtual void SAL_CALL
disposing (const lang::EventObject
& rEvent
) override
;
131 /** This method is called when the ViewShellBase is being destroyed.
133 virtual void Notify (SfxBroadcaster
& rBroadcaster
, const SfxHint
& rHint
) override
;
136 ::sd::ViewShellBase
& mrBase
;
137 bool mbListeningToViewShellBase
;
138 bool mbListeningToController
;
140 /** When one or both of the mbListeningToViewShellBase and
141 mbListeningToController members were modified then call this method
142 to either dispose or release the associated FrameworkHelper.
147 } // end of anonymous namespace
149 namespace sd::framework
{
153 class FrameworkHelperAllPassFilter
156 bool operator() (const css::drawing::framework::ConfigurationChangeEvent
&) { return true; }
159 class FrameworkHelperResourceIdFilter
162 explicit FrameworkHelperResourceIdFilter (
163 const css::uno::Reference
<css::drawing::framework::XResourceId
>& rxResourceId
);
164 bool operator() (const css::drawing::framework::ConfigurationChangeEvent
& rEvent
)
165 { return mxResourceId
.is() && rEvent
.ResourceId
.is()
166 && mxResourceId
->compareTo(rEvent
.ResourceId
) == 0; }
168 css::uno::Reference
<css::drawing::framework::XResourceId
> mxResourceId
;
171 } // end of anonymous namespace
175 const OUString
FrameworkHelper::msCenterPaneURL( msPaneURLPrefix
+ "CenterPane");
176 const OUString
FrameworkHelper::msFullScreenPaneURL( msPaneURLPrefix
+ "FullScreenPane");
177 const OUString
FrameworkHelper::msLeftImpressPaneURL( msPaneURLPrefix
+ "LeftImpressPane");
178 const OUString
FrameworkHelper::msBottomImpressPaneURL( msPaneURLPrefix
+ "BottomImpressPane");
179 const OUString
FrameworkHelper::msLeftDrawPaneURL( msPaneURLPrefix
+ "LeftDrawPane");
183 const OUString
FrameworkHelper::msImpressViewURL( msViewURLPrefix
+ "ImpressView");
184 const OUString
FrameworkHelper::msDrawViewURL( msViewURLPrefix
+ "GraphicView");
185 const OUString
FrameworkHelper::msOutlineViewURL( msViewURLPrefix
+ "OutlineView");
186 const OUString
FrameworkHelper::msNotesViewURL( msViewURLPrefix
+ "NotesView");
187 const OUString
FrameworkHelper::msHandoutViewURL( msViewURLPrefix
+ "HandoutView");
188 const OUString
FrameworkHelper::msSlideSorterURL( msViewURLPrefix
+ "SlideSorter");
189 const OUString
FrameworkHelper::msPresentationViewURL( msViewURLPrefix
+ "PresentationView");
190 const OUString
FrameworkHelper::msSidebarViewURL( msViewURLPrefix
+ "SidebarView");
191 const OUString
FrameworkHelper::msNotesPanelViewURL( msViewURLPrefix
+ "NotesPanelView");
195 const OUString
FrameworkHelper::msViewTabBarURL( msToolBarURLPrefix
+ "ViewTabBar");
197 //----- helper ----------------------------------------------------------------
200 ::std::shared_ptr
< ViewShell
> lcl_getViewShell( const Reference
< XResource
>& i_rViewShellWrapper
)
202 ::std::shared_ptr
< ViewShell
> pViewShell
;
205 if (auto pWrapper
= dynamic_cast<ViewShellWrapper
*>(i_rViewShellWrapper
.get()))
206 pViewShell
= pWrapper
->GetViewShell();
208 catch( const Exception
& )
210 DBG_UNHANDLED_EXCEPTION("sd");
214 Reference
< XResource
> lcl_getFirstViewInPane( const Reference
< XConfigurationController
>& i_rConfigController
,
215 const Reference
< XResourceId
>& i_rPaneId
)
219 Reference
< XConfiguration
> xConfiguration( i_rConfigController
->getRequestedConfiguration(), UNO_SET_THROW
);
220 Sequence
< Reference
< XResourceId
> > aViewIds( xConfiguration
->getResources(
221 i_rPaneId
, FrameworkHelper::msViewURLPrefix
, AnchorBindingMode_DIRECT
) );
222 if ( aViewIds
.hasElements() )
223 return i_rConfigController
->getResource( aViewIds
[0] );
225 catch( const Exception
& )
227 DBG_UNHANDLED_EXCEPTION("sd");
233 //----- FrameworkHelper::ViewURLMap -------------------------------------------
235 /** The ViewURLMap is used to translate between the view URLs used by the
236 drawing framework and the enums defined in the ViewShell class.
238 class FrameworkHelper::ViewURLMap
239 : public std::unordered_map
<
241 ViewShell::ShellType
>
247 //----- Framework::DisposeListener ---------------------------------------------
250 typedef comphelper::WeakComponentImplHelper
<
251 css::lang::XEventListener
252 > FrameworkHelperDisposeListenerInterfaceBase
;
255 class FrameworkHelper::DisposeListener
256 : public FrameworkHelperDisposeListenerInterfaceBase
259 explicit DisposeListener (::std::shared_ptr
<FrameworkHelper
> pHelper
);
261 virtual void disposing(std::unique_lock
<std::mutex
>&) override
;
263 virtual void SAL_CALL
disposing (const lang::EventObject
& rEventObject
) override
;
266 ::std::shared_ptr
<FrameworkHelper
> mpHelper
;
269 //----- FrameworkHelper::Deleter ----------------------------------------------
271 class FrameworkHelper::Deleter
274 void operator()(FrameworkHelper
* pObject
)
280 //----- FrameworkHelper -------------------------------------------------------
282 FrameworkHelper::ViewURLMap
FrameworkHelper::maViewURLMap
;
284 FrameworkHelper::InstanceMap
FrameworkHelper::maInstanceMap
;
285 std::mutex
FrameworkHelper::maInstanceMapMutex
;
287 ::std::shared_ptr
<FrameworkHelper
> FrameworkHelper::Instance (ViewShellBase
& rBase
)
289 std::unique_lock
aGuard(maInstanceMapMutex
);
291 InstanceMap::const_iterator
iHelper (maInstanceMap
.find(&rBase
));
292 if (iHelper
!= maInstanceMap
.end())
293 return iHelper
->second
;
295 ::std::shared_ptr
<FrameworkHelper
> pHelper(
296 new FrameworkHelper(rBase
),
297 FrameworkHelper::Deleter());
298 pHelper
->Initialize();
299 maInstanceMap
[&rBase
] = pHelper
;
304 void FrameworkHelper::DisposeInstance (const ViewShellBase
& rBase
)
306 InstanceMap::iterator
iHelper (maInstanceMap
.find(&rBase
));
307 if (iHelper
!= maInstanceMap
.end())
309 iHelper
->second
->Dispose();
313 void FrameworkHelper::ReleaseInstance (const ViewShellBase
& rBase
)
315 InstanceMap::iterator
iHelper (maInstanceMap
.find(&rBase
));
316 if (iHelper
!= maInstanceMap
.end())
317 maInstanceMap
.erase(iHelper
);
320 FrameworkHelper::FrameworkHelper (ViewShellBase
& rBase
)
323 DrawController
* pDrawController
= rBase
.GetDrawController();
326 mxConfigurationController
= pDrawController
->getConfigurationController();
329 new LifetimeController(mrBase
);
332 void FrameworkHelper::Initialize()
334 mxDisposeListener
= new DisposeListener(shared_from_this());
337 FrameworkHelper::~FrameworkHelper()
341 void FrameworkHelper::Dispose()
343 if (mxDisposeListener
.is())
344 mxDisposeListener
->dispose();
345 mxConfigurationController
= nullptr;
348 bool FrameworkHelper::IsValid() const
350 return mxConfigurationController
.is();
353 ::std::shared_ptr
<ViewShell
> FrameworkHelper::GetViewShell (const OUString
& rsPaneURL
)
355 if ( !mxConfigurationController
.is() )
356 return ::std::shared_ptr
<ViewShell
>();
358 Reference
<XResourceId
> xPaneId( CreateResourceId( rsPaneURL
) );
359 return lcl_getViewShell( lcl_getFirstViewInPane( mxConfigurationController
, xPaneId
) );
362 ::std::shared_ptr
<ViewShell
> FrameworkHelper::GetViewShell (const Reference
<XView
>& rxView
)
364 return lcl_getViewShell( rxView
);
367 Reference
<XView
> FrameworkHelper::GetView (const Reference
<XResourceId
>& rxPaneOrViewId
)
369 Reference
<XView
> xView
;
371 if ( ! rxPaneOrViewId
.is() || ! mxConfigurationController
.is())
376 if (rxPaneOrViewId
->getResourceURL().match(msViewURLPrefix
))
378 xView
.set( mxConfigurationController
->getResource( rxPaneOrViewId
), UNO_QUERY
);
382 xView
.set( lcl_getFirstViewInPane( mxConfigurationController
, rxPaneOrViewId
), UNO_QUERY
);
385 catch (lang::DisposedException
&)
389 catch (RuntimeException
&)
396 Reference
<XResourceId
> FrameworkHelper::RequestView (
397 const OUString
& rsResourceURL
,
398 const OUString
& rsAnchorURL
)
400 Reference
<XResourceId
> xViewId
;
404 if (mxConfigurationController
.is())
406 mxConfigurationController
->requestResourceActivation(
407 CreateResourceId(rsAnchorURL
),
408 ResourceActivationMode_ADD
);
409 xViewId
= CreateResourceId(rsResourceURL
, rsAnchorURL
);
410 mxConfigurationController
->requestResourceActivation(
412 ResourceActivationMode_REPLACE
);
415 catch (lang::DisposedException
&)
420 catch (RuntimeException
&)
428 ViewShell::ShellType
FrameworkHelper::GetViewId (const OUString
& rsViewURL
)
430 if (maViewURLMap
.empty())
432 maViewURLMap
[msImpressViewURL
] = ViewShell::ST_IMPRESS
;
433 maViewURLMap
[msDrawViewURL
] = ViewShell::ST_DRAW
;
434 maViewURLMap
[msOutlineViewURL
] = ViewShell::ST_OUTLINE
;
435 maViewURLMap
[msNotesViewURL
] = ViewShell::ST_NOTES
;
436 maViewURLMap
[msHandoutViewURL
] = ViewShell::ST_HANDOUT
;
437 maViewURLMap
[msSlideSorterURL
] = ViewShell::ST_SLIDE_SORTER
;
438 maViewURLMap
[msPresentationViewURL
] = ViewShell::ST_PRESENTATION
;
439 maViewURLMap
[msSidebarViewURL
] = ViewShell::ST_SIDEBAR
;
440 maViewURLMap
[msNotesPanelViewURL
] = ViewShell::ST_NOTESPANEL
;
442 ViewURLMap::const_iterator
iView (maViewURLMap
.find(rsViewURL
));
443 if (iView
!= maViewURLMap
.end())
444 return iView
->second
;
446 return ViewShell::ST_NONE
;
449 const OUString
& FrameworkHelper::GetViewURL (ViewShell::ShellType eType
)
453 case ViewShell::ST_IMPRESS
: return msImpressViewURL
;
454 case ViewShell::ST_DRAW
: return msDrawViewURL
;
455 case ViewShell::ST_OUTLINE
: return msOutlineViewURL
;
456 case ViewShell::ST_NOTES
: return msNotesViewURL
;
457 case ViewShell::ST_HANDOUT
: return msHandoutViewURL
;
458 case ViewShell::ST_SLIDE_SORTER
: return msSlideSorterURL
;
459 case ViewShell::ST_PRESENTATION
: return msPresentationViewURL
;
460 case ViewShell::ST_SIDEBAR
: return msSidebarViewURL
;
461 case ViewShell::ST_NOTESPANEL
: return msNotesPanelViewURL
;
463 return EMPTY_OUSTRING
;
470 void updateEditMode(const Reference
<XView
> &xView
, const EditMode eEMode
, bool updateFrameView
)
472 // Ensure we have the expected edit mode
473 // The check is only for DrawViewShell as OutlineViewShell
474 // and SlideSorterViewShell have no master mode
475 const ::std::shared_ptr
<ViewShell
> pCenterViewShell (FrameworkHelper::GetViewShell(xView
));
476 DrawViewShell
* pDrawViewShell
477 = dynamic_cast<DrawViewShell
*>(pCenterViewShell
.get());
478 if (pDrawViewShell
!= nullptr)
480 pCenterViewShell
->Broadcast (
481 ViewShellHint(ViewShellHint::HINT_CHANGE_EDIT_MODE_START
));
483 pDrawViewShell
->ChangeEditMode(eEMode
, pDrawViewShell
->IsLayerModeActive());
485 pDrawViewShell
->WriteFrameViewData();
487 pCenterViewShell
->Broadcast (
488 ViewShellHint(ViewShellHint::HINT_CHANGE_EDIT_MODE_END
));
492 void asyncUpdateEditMode(FrameworkHelper
* const pHelper
, const EditMode eEMode
)
494 Reference
<XResourceId
> xPaneId (
495 FrameworkHelper::CreateResourceId(framework::FrameworkHelper::msCenterPaneURL
));
496 Reference
<XView
> xView (pHelper
->GetView(xPaneId
));
497 updateEditMode(xView
, eEMode
, true);
502 void FrameworkHelper::HandleModeChangeSlot (
504 SfxRequest
const & rRequest
)
506 if ( ! mxConfigurationController
.is())
509 // Parameters are allowed for NotesMasterPage and SlideMasterPage
510 // for these command, transfor xxxxMasterPage with param = false
511 // to ActivatexxxxxMode
512 if (nSlotId
== SID_NOTES_MASTER_MODE
|| nSlotId
== SID_SLIDE_MASTER_MODE
)
514 const SfxItemSet
* pRequestArguments
= rRequest
.GetArgs();
515 if (pRequestArguments
)
517 const SfxBoolItem
* pIsActive
= rRequest
.GetArg
<SfxBoolItem
>(nSlotId
);
518 if (!pIsActive
->GetValue ())
520 if (nSlotId
== SID_NOTES_MASTER_MODE
)
521 nSlotId
= SID_NOTES_MODE
;
523 nSlotId
= SID_NORMAL_MULTI_PANE_GUI
;
530 if ( ! mxConfigurationController
.is())
531 throw RuntimeException();
533 Reference
<XResourceId
> xPaneId (
534 CreateResourceId(framework::FrameworkHelper::msCenterPaneURL
));
535 Reference
<XView
> xView (GetView(xPaneId
));
537 // Compute requested view
538 OUString sRequestedView
;
542 case SID_DRAWINGMODE
:
544 case SID_NORMAL_MULTI_PANE_GUI
:
545 case SID_SLIDE_MASTER_MODE
:
546 sRequestedView
= FrameworkHelper::msImpressViewURL
;
550 case SID_NOTES_MASTER_MODE
:
551 sRequestedView
= FrameworkHelper::msNotesViewURL
;
554 case SID_HANDOUT_MASTER_MODE
:
555 sRequestedView
= FrameworkHelper::msHandoutViewURL
;
558 case SID_SLIDE_SORTER_MULTI_PANE_GUI
:
559 case SID_SLIDE_SORTER_MODE
:
560 sRequestedView
= FrameworkHelper::msSlideSorterURL
;
563 case SID_OUTLINE_MODE
:
564 sRequestedView
= FrameworkHelper::msOutlineViewURL
;
568 // Compute requested mode
569 EditMode eEMode
= EditMode::Page
;
570 if (nSlotId
== SID_SLIDE_MASTER_MODE
571 || nSlotId
== SID_NOTES_MASTER_MODE
572 || nSlotId
== SID_HANDOUT_MASTER_MODE
)
573 eEMode
= EditMode::MasterPage
;
574 // Ensure we have the expected view shell
575 if (!(xView
.is() && xView
->getResourceId()->getResourceURL() == sRequestedView
))
578 const auto xId
= CreateResourceId(sRequestedView
, msCenterPaneURL
);
579 mxConfigurationController
->requestResourceActivation(
581 ResourceActivationMode_REPLACE
);
582 RunOnResourceActivation(xId
, std::bind(&asyncUpdateEditMode
, this, eEMode
));
586 updateEditMode(xView
, eEMode
, false);
589 catch (RuntimeException
&)
591 DBG_UNHANDLED_EXCEPTION("sd");
595 void FrameworkHelper::RunOnConfigurationEvent(
596 const OUString
& rsEventType
,
597 const Callback
& rCallback
)
601 FrameworkHelperAllPassFilter(),
605 void FrameworkHelper::RunOnResourceActivation(
606 const css::uno::Reference
<css::drawing::framework::XResourceId
>& rxResourceId
,
607 const Callback
& rCallback
)
609 if (mxConfigurationController
.is()
610 && mxConfigurationController
->getResource(rxResourceId
).is())
617 msResourceActivationEvent
,
618 FrameworkHelperResourceIdFilter(rxResourceId
),
625 /** A callback that sets a flag to a specified value when the callback is
631 explicit FlagUpdater (bool& rFlag
) : mrFlag(rFlag
) {}
632 void operator() (bool) const {mrFlag
= true;}
639 void FrameworkHelper::RequestSynchronousUpdate()
641 rtl::Reference
<ConfigurationController
> pCC (
642 dynamic_cast<ConfigurationController
*>(mxConfigurationController
.get()));
644 pCC
->RequestSynchronousUpdate();
647 void FrameworkHelper::WaitForEvent (const OUString
& rsEventType
) const
649 bool bConfigurationUpdateSeen (false);
653 FrameworkHelperAllPassFilter(),
654 FlagUpdater(bConfigurationUpdateSeen
));
656 sal_uInt32 nStartTime
= osl_getGlobalTimer();
657 while ( ! bConfigurationUpdateSeen
)
659 Application::Reschedule();
661 if( (osl_getGlobalTimer() - nStartTime
) > 60000 )
663 OSL_FAIL("FrameworkHelper::WaitForEvent(), no event for a minute? giving up!");
669 void FrameworkHelper::WaitForUpdate() const
671 WaitForEvent(msConfigurationUpdateEndEvent
);
674 void FrameworkHelper::RunOnEvent(
675 const OUString
& rsEventType
,
676 const ConfigurationChangeEventFilter
& rFilter
,
677 const Callback
& rCallback
) const
679 new CallbackCaller(mrBase
,rsEventType
,rFilter
,rCallback
);
682 void FrameworkHelper::disposing (const lang::EventObject
& rEventObject
)
684 if (rEventObject
.Source
== mxConfigurationController
)
685 mxConfigurationController
= nullptr;
688 void FrameworkHelper::UpdateConfiguration()
690 if (!mxConfigurationController
.is())
695 if (mxConfigurationController
.is())
696 mxConfigurationController
->update();
698 catch (lang::DisposedException
&)
702 catch (RuntimeException
&)
704 DBG_UNHANDLED_EXCEPTION("sd");
708 OUString
FrameworkHelper::ResourceIdToString (const Reference
<XResourceId
>& rxResourceId
)
710 OUStringBuffer sString
;
711 if (rxResourceId
.is())
713 sString
.append(rxResourceId
->getResourceURL());
714 if (rxResourceId
->hasAnchor())
716 const Sequence
<OUString
> aAnchorURLs (rxResourceId
->getAnchorURLs());
717 for (const auto& rAnchorURL
: aAnchorURLs
)
719 sString
.append(" | " + rAnchorURL
);
723 return sString
.makeStringAndClear();
726 Reference
<XResourceId
> FrameworkHelper::CreateResourceId (const OUString
& rsResourceURL
)
728 return new ::sd::framework::ResourceId(rsResourceURL
);
731 Reference
<XResourceId
> FrameworkHelper::CreateResourceId (
732 const OUString
& rsResourceURL
,
733 const OUString
& rsAnchorURL
)
735 return new ::sd::framework::ResourceId(rsResourceURL
, rsAnchorURL
);
738 Reference
<XResourceId
> FrameworkHelper::CreateResourceId (
739 const OUString
& rsResourceURL
,
740 const Reference
<XResourceId
>& rxAnchorId
)
743 return new ::sd::framework::ResourceId(
745 rxAnchorId
->getResourceURL(),
746 rxAnchorId
->getAnchorURLs());
748 return new ::sd::framework::ResourceId(rsResourceURL
);
751 //----- FrameworkHelper::DisposeListener --------------------------------------
753 FrameworkHelper::DisposeListener::DisposeListener (
754 ::std::shared_ptr
<FrameworkHelper
> pHelper
)
755 : mpHelper(std::move(pHelper
))
757 Reference
<XComponent
> xComponent (mpHelper
->mxConfigurationController
, UNO_QUERY
);
759 xComponent
->addEventListener(this);
762 void FrameworkHelper::DisposeListener::disposing(std::unique_lock
<std::mutex
>&)
764 Reference
<XComponent
> xComponent (mpHelper
->mxConfigurationController
, UNO_QUERY
);
766 xComponent
->removeEventListener(this);
771 void SAL_CALL
FrameworkHelper::DisposeListener::disposing (const lang::EventObject
& rEventObject
)
773 if (mpHelper
!= nullptr)
774 mpHelper
->disposing(rEventObject
);
777 //===== FrameworkHelperResourceIdFilter =======================================
779 FrameworkHelperResourceIdFilter::FrameworkHelperResourceIdFilter (
780 const Reference
<XResourceId
>& rxResourceId
)
781 : mxResourceId(rxResourceId
)
785 } // end of namespace sd::framework
789 //===== CallbackCaller ========================================================
791 CallbackCaller::CallbackCaller (
792 const ::sd::ViewShellBase
& rBase
,
793 OUString rsEventType
,
794 ::sd::framework::FrameworkHelper::ConfigurationChangeEventFilter aFilter
,
795 ::sd::framework::FrameworkHelper::Callback aCallback
)
796 : msEventType(std::move(rsEventType
)),
797 maFilter(std::move(aFilter
)),
798 maCallback(std::move(aCallback
))
802 sd::DrawController
* pDrawController
= rBase
.GetDrawController();
803 if (!pDrawController
)
805 mxConfigurationController
= pDrawController
->getConfigurationController();
806 if (mxConfigurationController
.is())
808 if (mxConfigurationController
->hasPendingRequests())
809 mxConfigurationController
->addConfigurationChangeListener(this,msEventType
,Any());
812 // There are no requests waiting to be processed. Therefore
813 // no event, especially not the one we are waiting for, will
814 // be sent in the near future and the callback would never be
816 // Call the callback now and tell him that the event it is
817 // waiting for was not sent.
818 mxConfigurationController
= nullptr;
823 catch (RuntimeException
&)
825 DBG_UNHANDLED_EXCEPTION("sd");
829 void CallbackCaller::disposing(std::unique_lock
<std::mutex
>&)
833 if (mxConfigurationController
.is())
835 Reference
<XConfigurationController
> xCC (mxConfigurationController
);
836 mxConfigurationController
= nullptr;
837 xCC
->removeConfigurationChangeListener(this);
840 catch (RuntimeException
&)
842 DBG_UNHANDLED_EXCEPTION("sd");
846 void SAL_CALL
CallbackCaller::disposing (const lang::EventObject
& rEvent
)
848 if (rEvent
.Source
== mxConfigurationController
)
850 mxConfigurationController
= nullptr;
855 void SAL_CALL
CallbackCaller::notifyConfigurationChange (
856 const ConfigurationChangeEvent
& rEvent
)
858 if (!(rEvent
.Type
== msEventType
&& maFilter(rEvent
)))
862 if (mxConfigurationController
.is())
864 // Reset the reference to the configuration controller so that
865 // dispose() will not try to remove the listener a second time.
866 Reference
<XConfigurationController
> xCC (mxConfigurationController
);
867 mxConfigurationController
= nullptr;
869 // Removing this object from the controller may very likely lead
870 // to its destruction, so no calls after that.
871 xCC
->removeConfigurationChangeListener(this);
875 //----- LifetimeController -------------------------------------------------
877 LifetimeController::LifetimeController (::sd::ViewShellBase
& rBase
)
879 mbListeningToViewShellBase(false),
880 mbListeningToController(false)
882 // Register as listener at the ViewShellBase. Because that is not done
883 // via a reference we have to increase the reference count manually.
884 // This is necessary even though listening to the XController did
885 // increase the reference count because the controller may release its
886 // reference to us before the ViewShellBase is destroyed.
887 StartListening(mrBase
);
889 mbListeningToViewShellBase
= true;
891 Reference
<XComponent
> xComponent
= rBase
.GetController();
894 xComponent
->addEventListener(this);
895 mbListeningToController
= true;
899 LifetimeController::~LifetimeController()
901 OSL_ASSERT(!mbListeningToController
&& !mbListeningToViewShellBase
);
904 void SAL_CALL
LifetimeController::disposing (const lang::EventObject
&)
906 mbListeningToController
= false;
910 void LifetimeController::Notify (SfxBroadcaster
&, const SfxHint
& rHint
)
912 if (rHint
.GetId() == SfxHintId::Dying
)
914 mbListeningToViewShellBase
= false;
920 void LifetimeController::Update()
922 if (mbListeningToViewShellBase
&& mbListeningToController
)
924 // Both the controller and the ViewShellBase are alive. Keep
925 // waiting for their destruction.
927 else if (mbListeningToViewShellBase
)
929 // The controller has been destroyed but the ViewShellBase is still
930 // alive. Dispose the associated FrameworkHelper but keep it around
931 // so that no new instance is created for the dying framework.
932 ::sd::framework::FrameworkHelper::DisposeInstance(mrBase
);
936 // Both the controller and the ViewShellBase have been destroyed.
937 // Remove the FrameworkHelper so that the next call its Instance()
938 // method can create a new instance.
939 ::sd::framework::FrameworkHelper::ReleaseInstance(mrBase
);
943 } // end of anonymous namespace.
945 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */