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 "PresenterViewFactory.hxx"
21 #include "PresenterPaneContainer.hxx"
22 #include "PresenterHelpView.hxx"
23 #include "PresenterNotesView.hxx"
24 #include "PresenterSlideShowView.hxx"
25 #include "PresenterSlidePreview.hxx"
26 #include "PresenterSlideSorter.hxx"
27 #include "PresenterToolBar.hxx"
28 #include <DrawController.hxx>
31 using namespace ::com::sun::star
;
32 using namespace ::com::sun::star::uno
;
33 using namespace ::com::sun::star::drawing::framework
;
35 namespace sdext::presenter
{
39 /** By default the PresenterSlidePreview shows the preview of the current
40 slide. This adapter class makes it display the preview of the next
43 class NextSlidePreview
: public PresenterSlidePreview
47 const css::uno::Reference
<css::uno::XComponentContext
>& rxContext
,
48 const css::uno::Reference
<css::drawing::framework::XResourceId
>& rxViewId
,
49 const css::uno::Reference
<css::drawing::framework::XPane
>& rxAnchorPane
,
50 const ::rtl::Reference
<PresenterController
>& rpPresenterController
)
51 : PresenterSlidePreview(rxContext
, rxViewId
, rxAnchorPane
, rpPresenterController
)
55 virtual void SAL_CALL
setCurrentPage (
56 const css::uno::Reference
<css::drawing::XDrawPage
>& rxSlide
) override
58 Reference
<presentation::XSlideShowController
> xSlideShowController (
59 mpPresenterController
->GetSlideShowController());
60 Reference
<drawing::XDrawPage
> xSlide
;
61 if (xSlideShowController
.is())
63 const sal_Int32
nCount (xSlideShowController
->getSlideCount());
64 sal_Int32
nNextSlideIndex (-1);
65 if (xSlideShowController
->getCurrentSlide() == rxSlide
)
67 nNextSlideIndex
= xSlideShowController
->getNextSlideIndex();
71 for (sal_Int32 nIndex
=0; nIndex
<nCount
; ++nIndex
)
73 if (rxSlide
== xSlideShowController
->getSlideByIndex(nIndex
))
75 nNextSlideIndex
= nIndex
+ 1;
79 if (nNextSlideIndex
>= 0)
81 if (nNextSlideIndex
< nCount
)
83 xSlide
= xSlideShowController
->getSlideByIndex(nNextSlideIndex
);
87 PresenterSlidePreview::setCurrentPage(xSlide
);
91 } // end of anonymous namespace
93 //===== PresenterViewFactory ==============================================
95 PresenterViewFactory::PresenterViewFactory (
96 const Reference
<uno::XComponentContext
>& rxContext
,
97 const rtl::Reference
<::sd::DrawController
>& rxController
,
98 ::rtl::Reference
<PresenterController
> pPresenterController
)
99 : PresenterViewFactoryInterfaceBase(m_aMutex
),
100 mxComponentContext(rxContext
),
101 mxControllerWeak(rxController
),
102 mpPresenterController(std::move(pPresenterController
))
106 Reference
<drawing::framework::XResourceFactory
> PresenterViewFactory::Create (
107 const Reference
<uno::XComponentContext
>& rxContext
,
108 const rtl::Reference
<::sd::DrawController
>& rxController
,
109 const ::rtl::Reference
<PresenterController
>& rpPresenterController
)
111 rtl::Reference
<PresenterViewFactory
> pFactory (
112 new PresenterViewFactory(rxContext
,rxController
,rpPresenterController
));
113 pFactory
->Register(rxController
);
114 return Reference
<drawing::framework::XResourceFactory
>(pFactory
);
117 void PresenterViewFactory::Register (const rtl::Reference
<::sd::DrawController
>& rxController
)
121 // Get the configuration controller.
122 mxConfigurationController
= rxController
->getConfigurationController();
123 if ( ! mxConfigurationController
.is())
125 throw RuntimeException();
127 mxConfigurationController
->addResourceFactory(msCurrentSlidePreviewViewURL
, this);
128 mxConfigurationController
->addResourceFactory(msNextSlidePreviewViewURL
, this);
129 mxConfigurationController
->addResourceFactory(msNotesViewURL
, this);
130 mxConfigurationController
->addResourceFactory(msToolBarViewURL
, this);
131 mxConfigurationController
->addResourceFactory(msSlideSorterURL
, this);
132 mxConfigurationController
->addResourceFactory(msHelpViewURL
, this);
134 catch (RuntimeException
&)
137 if (mxConfigurationController
.is())
138 mxConfigurationController
->removeResourceFactoryForReference(this);
139 mxConfigurationController
= nullptr;
145 PresenterViewFactory::~PresenterViewFactory()
149 void SAL_CALL
PresenterViewFactory::disposing()
151 if (mxConfigurationController
.is())
152 mxConfigurationController
->removeResourceFactoryForReference(this);
153 mxConfigurationController
= nullptr;
155 if (mpResourceCache
== nullptr)
158 // Dispose all views in the cache.
159 for (const auto& rView
: *mpResourceCache
)
163 Reference
<lang::XComponent
> xComponent (rView
.second
.first
, UNO_QUERY
);
165 xComponent
->dispose();
167 catch (lang::DisposedException
&)
171 mpResourceCache
.reset();
174 //----- XViewFactory ----------------------------------------------------------
176 Reference
<XResource
> SAL_CALL
PresenterViewFactory::createResource (
177 const Reference
<XResourceId
>& rxViewId
)
181 Reference
<XResource
> xView
;
185 Reference
<XPane
> xAnchorPane (
186 mxConfigurationController
->getResource(rxViewId
->getAnchor()),
188 xView
= GetViewFromCache(rxViewId
, xAnchorPane
);
189 if (xView
== nullptr)
190 xView
= CreateView(rxViewId
, xAnchorPane
);
192 // Activate the view.
193 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor (
194 mpPresenterController
->GetPaneContainer()->FindPaneId(rxViewId
->getAnchor()));
196 pDescriptor
->SetActivationState(true);
202 void SAL_CALL
PresenterViewFactory::releaseResource (const Reference
<XResource
>& rxView
)
209 // Deactivate the view.
210 PresenterPaneContainer::SharedPaneDescriptor
pDescriptor (
211 mpPresenterController
->GetPaneContainer()->FindPaneId(
212 rxView
->getResourceId()->getAnchor()));
214 pDescriptor
->SetActivationState(false);
216 // Dispose only views that we can not put into the cache.
217 CachablePresenterView
* pView
= dynamic_cast<CachablePresenterView
*>(rxView
.get());
218 if (pView
== nullptr || mpResourceCache
== nullptr)
222 if (pView
!= nullptr)
223 pView
->ReleaseView();
224 Reference
<lang::XComponent
> xComponent (rxView
, UNO_QUERY
);
226 xComponent
->dispose();
228 catch (lang::DisposedException
&)
230 // Do not let disposed exceptions get out. It might be interpreted
231 // as coming from the factory, which would then be removed from the
232 // drawing framework.
237 // Put cacheable views in the cache.
238 Reference
<XResourceId
> xViewId (rxView
->getResourceId());
241 Reference
<XPane
> xAnchorPane (
242 mxConfigurationController
->getResource(xViewId
->getAnchor()),
244 (*mpResourceCache
)[xViewId
->getResourceURL()]
245 = ViewResourceDescriptor(Reference
<XView
>(rxView
, UNO_QUERY
), xAnchorPane
);
246 pView
->DeactivatePresenterView();
252 Reference
<XResource
> PresenterViewFactory::GetViewFromCache(
253 const Reference
<XResourceId
>& rxViewId
,
254 const Reference
<XPane
>& rxAnchorPane
) const
256 if (mpResourceCache
== nullptr)
261 const OUString
sResourceURL (rxViewId
->getResourceURL());
263 // Can we use a view from the cache?
264 ResourceContainer::const_iterator
iView (mpResourceCache
->find(sResourceURL
));
265 if (iView
!= mpResourceCache
->end())
267 // The view is in the container but it can only be used if
268 // the anchor pane is the same now as it was at creation of
270 if (iView
->second
.second
== rxAnchorPane
)
272 CachablePresenterView
* pView
273 = dynamic_cast<CachablePresenterView
*>(iView
->second
.first
.get());
274 if (pView
!= nullptr)
275 pView
->ActivatePresenterView();
276 return iView
->second
.first
;
279 // Right view, wrong pane. Create a new view.
282 catch (RuntimeException
&)
288 Reference
<XResource
> PresenterViewFactory::CreateView(
289 const Reference
<XResourceId
>& rxViewId
,
290 const Reference
<XPane
>& rxAnchorPane
)
292 Reference
<XView
> xView
;
296 const OUString
sResourceURL (rxViewId
->getResourceURL());
298 if (sResourceURL
== msCurrentSlidePreviewViewURL
)
300 xView
= CreateSlideShowView(rxViewId
);
302 else if (sResourceURL
== msNotesViewURL
)
304 xView
= CreateNotesView(rxViewId
);
306 else if (sResourceURL
== msNextSlidePreviewViewURL
)
308 xView
= CreateSlidePreviewView(rxViewId
, rxAnchorPane
);
310 else if (sResourceURL
== msToolBarViewURL
)
312 xView
= CreateToolBarView(rxViewId
);
314 else if (sResourceURL
== msSlideSorterURL
)
316 xView
= CreateSlideSorterView(rxViewId
);
318 else if (sResourceURL
== msHelpViewURL
)
320 xView
= CreateHelpView(rxViewId
);
324 CachablePresenterView
* pView
= dynamic_cast<CachablePresenterView
*>(xView
.get());
325 if (pView
!= nullptr)
326 pView
->ActivatePresenterView();
328 catch (RuntimeException
&)
336 Reference
<XView
> PresenterViewFactory::CreateSlideShowView(
337 const Reference
<XResourceId
>& rxViewId
) const
339 Reference
<XView
> xView
;
341 if ( ! mxConfigurationController
.is())
343 if ( ! mxComponentContext
.is())
348 rtl::Reference
<PresenterSlideShowView
> pShowView (
349 new PresenterSlideShowView(
352 mxControllerWeak
.get(),
353 mpPresenterController
));
354 pShowView
->LateInit();
357 catch (RuntimeException
&)
365 Reference
<XView
> PresenterViewFactory::CreateSlidePreviewView(
366 const Reference
<XResourceId
>& rxViewId
,
367 const Reference
<XPane
>& rxAnchorPane
) const
369 Reference
<XView
> xView
;
371 if ( ! mxConfigurationController
.is())
373 if ( ! mxComponentContext
.is())
379 static_cast<XWeak
*>(new NextSlidePreview(
383 mpPresenterController
)),
386 catch (RuntimeException
&)
394 Reference
<XView
> PresenterViewFactory::CreateToolBarView(
395 const Reference
<XResourceId
>& rxViewId
) const
397 return new PresenterToolBarView(
400 mxControllerWeak
.get(),
401 mpPresenterController
);
404 Reference
<XView
> PresenterViewFactory::CreateNotesView(
405 const Reference
<XResourceId
>& rxViewId
) const
407 Reference
<XView
> xView
;
409 if ( ! mxConfigurationController
.is())
411 if ( ! mxComponentContext
.is())
416 xView
.set(static_cast<XWeak
*>(
417 new PresenterNotesView(
420 mxControllerWeak
.get(),
421 mpPresenterController
)),
424 catch (RuntimeException
&)
432 Reference
<XView
> PresenterViewFactory::CreateSlideSorterView(
433 const Reference
<XResourceId
>& rxViewId
) const
435 Reference
<XView
> xView
;
437 if ( ! mxConfigurationController
.is())
439 if ( ! mxComponentContext
.is())
444 rtl::Reference
<PresenterSlideSorter
> pView (
445 new PresenterSlideSorter(
448 mxControllerWeak
.get(),
449 mpPresenterController
));
452 catch (RuntimeException
&)
460 Reference
<XView
> PresenterViewFactory::CreateHelpView(
461 const Reference
<XResourceId
>& rxViewId
) const
463 return Reference
<XView
>(new PresenterHelpView(
466 mxControllerWeak
.get(),
467 mpPresenterController
));
470 void PresenterViewFactory::ThrowIfDisposed() const
472 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
474 throw lang::DisposedException (
475 "PresenterViewFactory object has already been disposed",
476 const_cast<uno::XWeak
*>(static_cast<const uno::XWeak
*>(this)));
480 //===== CachablePresenterView =================================================
482 CachablePresenterView::CachablePresenterView()
483 : mbIsPresenterViewActive(true)
487 void CachablePresenterView::ActivatePresenterView()
489 mbIsPresenterViewActive
= true;
492 void CachablePresenterView::DeactivatePresenterView()
494 mbIsPresenterViewActive
= false;
497 void CachablePresenterView::ReleaseView()
503 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */