sc: copy cache values when clone color conditional format
[LibreOffice.git] / sdext / source / presenter / PresenterViewFactory.cxx
blob7c7f8c98bae37bc6c12aef8796ba1904eea174e5
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <com/sun/star/drawing/framework/XControllerManager.hpp>
30 using namespace ::com::sun::star;
31 using namespace ::com::sun::star::uno;
32 using namespace ::com::sun::star::drawing::framework;
34 namespace sdext::presenter {
36 namespace {
38 /** By default the PresenterSlidePreview shows the preview of the current
39 slide. This adapter class makes it display the preview of the next
40 slide.
42 class NextSlidePreview : public PresenterSlidePreview
44 public:
45 NextSlidePreview (
46 const css::uno::Reference<css::uno::XComponentContext>& rxContext,
47 const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId,
48 const css::uno::Reference<css::drawing::framework::XPane>& rxAnchorPane,
49 const ::rtl::Reference<PresenterController>& rpPresenterController)
50 : PresenterSlidePreview(rxContext, rxViewId, rxAnchorPane, rpPresenterController)
54 virtual void SAL_CALL setCurrentPage (
55 const css::uno::Reference<css::drawing::XDrawPage>& rxSlide) override
57 Reference<presentation::XSlideShowController> xSlideShowController (
58 mpPresenterController->GetSlideShowController());
59 Reference<drawing::XDrawPage> xSlide;
60 if (xSlideShowController.is())
62 const sal_Int32 nCount (xSlideShowController->getSlideCount());
63 sal_Int32 nNextSlideIndex (-1);
64 if (xSlideShowController->getCurrentSlide() == rxSlide)
66 nNextSlideIndex = xSlideShowController->getNextSlideIndex();
68 else
70 for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
72 if (rxSlide == xSlideShowController->getSlideByIndex(nIndex))
74 nNextSlideIndex = nIndex + 1;
78 if (nNextSlideIndex >= 0)
80 if (nNextSlideIndex < nCount)
82 xSlide = xSlideShowController->getSlideByIndex(nNextSlideIndex);
86 PresenterSlidePreview::setCurrentPage(xSlide);
90 } // end of anonymous namespace
92 //===== PresenterViewFactory ==============================================
94 PresenterViewFactory::PresenterViewFactory (
95 const Reference<uno::XComponentContext>& rxContext,
96 const Reference<frame::XController>& rxController,
97 const ::rtl::Reference<PresenterController>& rpPresenterController)
98 : PresenterViewFactoryInterfaceBase(m_aMutex),
99 mxComponentContext(rxContext),
100 mxControllerWeak(rxController),
101 mpPresenterController(rpPresenterController)
105 Reference<drawing::framework::XResourceFactory> PresenterViewFactory::Create (
106 const Reference<uno::XComponentContext>& rxContext,
107 const Reference<frame::XController>& rxController,
108 const ::rtl::Reference<PresenterController>& rpPresenterController)
110 rtl::Reference<PresenterViewFactory> pFactory (
111 new PresenterViewFactory(rxContext,rxController,rpPresenterController));
112 pFactory->Register(rxController);
113 return Reference<drawing::framework::XResourceFactory>(pFactory);
116 void PresenterViewFactory::Register (const Reference<frame::XController>& rxController)
120 // Get the configuration controller.
121 Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW);
122 mxConfigurationController = xCM->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&)
136 OSL_ASSERT(false);
137 if (mxConfigurationController.is())
138 mxConfigurationController->removeResourceFactoryForReference(this);
139 mxConfigurationController = nullptr;
141 throw;
145 PresenterViewFactory::~PresenterViewFactory()
149 void SAL_CALL PresenterViewFactory::disposing()
151 if (mxConfigurationController.is())
152 mxConfigurationController->removeResourceFactoryForReference(this);
153 mxConfigurationController = nullptr;
155 if (mpResourceCache == nullptr)
156 return;
158 // Dispose all views in the cache.
159 for (const auto& rView : *mpResourceCache)
163 Reference<lang::XComponent> xComponent (rView.second.first, UNO_QUERY);
164 if (xComponent.is())
165 xComponent->dispose();
167 catch (lang::DisposedException&)
171 mpResourceCache.reset();
174 //----- XViewFactory ----------------------------------------------------------
176 Reference<XResource> SAL_CALL PresenterViewFactory::createResource (
177 const Reference<XResourceId>& rxViewId)
179 ThrowIfDisposed();
181 Reference<XResource> xView;
183 if (rxViewId.is())
185 Reference<XPane> xAnchorPane (
186 mxConfigurationController->getResource(rxViewId->getAnchor()),
187 UNO_QUERY_THROW);
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()));
195 if (pDescriptor)
196 pDescriptor->SetActivationState(true);
199 return xView;
202 void SAL_CALL PresenterViewFactory::releaseResource (const Reference<XResource>& rxView)
204 ThrowIfDisposed();
206 if ( ! rxView.is())
207 return;
209 // Deactivate the view.
210 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
211 mpPresenterController->GetPaneContainer()->FindPaneId(
212 rxView->getResourceId()->getAnchor()));
213 if (pDescriptor)
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);
225 if (xComponent.is())
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.
235 else
237 // Put cacheable views in the cache.
238 Reference<XResourceId> xViewId (rxView->getResourceId());
239 if (xViewId.is())
241 Reference<XPane> xAnchorPane (
242 mxConfigurationController->getResource(xViewId->getAnchor()),
243 UNO_QUERY_THROW);
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)
257 return 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
269 // the view.
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&)
285 return nullptr;
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);
323 // Activate it.
324 CachablePresenterView* pView = dynamic_cast<CachablePresenterView*>(xView.get());
325 if (pView != nullptr)
326 pView->ActivatePresenterView();
328 catch (RuntimeException&)
330 xView = nullptr;
333 return xView;
336 Reference<XView> PresenterViewFactory::CreateSlideShowView(
337 const Reference<XResourceId>& rxViewId) const
339 Reference<XView> xView;
341 if ( ! mxConfigurationController.is())
342 return xView;
343 if ( ! mxComponentContext.is())
344 return xView;
348 rtl::Reference<PresenterSlideShowView> pShowView (
349 new PresenterSlideShowView(
350 mxComponentContext,
351 rxViewId,
352 Reference<frame::XController>(mxControllerWeak),
353 mpPresenterController));
354 pShowView->LateInit();
355 xView = pShowView;
357 catch (RuntimeException&)
359 xView = nullptr;
362 return xView;
365 Reference<XView> PresenterViewFactory::CreateSlidePreviewView(
366 const Reference<XResourceId>& rxViewId,
367 const Reference<XPane>& rxAnchorPane) const
369 Reference<XView> xView;
371 if ( ! mxConfigurationController.is())
372 return xView;
373 if ( ! mxComponentContext.is())
374 return xView;
378 xView.set(
379 static_cast<XWeak*>(new NextSlidePreview(
380 mxComponentContext,
381 rxViewId,
382 rxAnchorPane,
383 mpPresenterController)),
384 UNO_QUERY_THROW);
386 catch (RuntimeException&)
388 xView = nullptr;
391 return xView;
394 Reference<XView> PresenterViewFactory::CreateToolBarView(
395 const Reference<XResourceId>& rxViewId) const
397 return new PresenterToolBarView(
398 mxComponentContext,
399 rxViewId,
400 Reference<frame::XController>(mxControllerWeak),
401 mpPresenterController);
404 Reference<XView> PresenterViewFactory::CreateNotesView(
405 const Reference<XResourceId>& rxViewId) const
407 Reference<XView> xView;
409 if ( ! mxConfigurationController.is())
410 return xView;
411 if ( ! mxComponentContext.is())
412 return xView;
416 xView.set(static_cast<XWeak*>(
417 new PresenterNotesView(
418 mxComponentContext,
419 rxViewId,
420 Reference<frame::XController>(mxControllerWeak),
421 mpPresenterController)),
422 UNO_QUERY_THROW);
424 catch (RuntimeException&)
426 xView = nullptr;
429 return xView;
432 Reference<XView> PresenterViewFactory::CreateSlideSorterView(
433 const Reference<XResourceId>& rxViewId) const
435 Reference<XView> xView;
437 if ( ! mxConfigurationController.is())
438 return xView;
439 if ( ! mxComponentContext.is())
440 return xView;
444 rtl::Reference<PresenterSlideSorter> pView (
445 new PresenterSlideSorter(
446 mxComponentContext,
447 rxViewId,
448 Reference<frame::XController>(mxControllerWeak),
449 mpPresenterController));
450 xView = pView.get();
452 catch (RuntimeException&)
454 xView = nullptr;
457 return xView;
460 Reference<XView> PresenterViewFactory::CreateHelpView(
461 const Reference<XResourceId>& rxViewId) const
463 return Reference<XView>(new PresenterHelpView(
464 mxComponentContext,
465 rxViewId,
466 Reference<frame::XController>(mxControllerWeak),
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: */