Bump version to 5.0-14
[LibreOffice.git] / sdext / source / presenter / PresenterViewFactory.cxx
blobab884974acc60f556288d1848bef8a2aa2008960
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 "PresenterHelper.hxx"
23 #include "PresenterHelpView.hxx"
24 #include "PresenterNotesView.hxx"
25 #include "PresenterSlideShowView.hxx"
26 #include "PresenterSlidePreview.hxx"
27 #include "PresenterSlideSorter.hxx"
28 #include "PresenterToolBar.hxx"
29 #include <com/sun/star/beans/XPropertySet.hpp>
30 #include <com/sun/star/drawing/framework/ResourceId.hpp>
31 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
32 #include <com/sun/star/drawing/framework/XConfigurationController.hpp>
33 #include <com/sun/star/drawing/XDrawPages.hpp>
34 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
35 #include <com/sun/star/drawing/XSlideSorterBase.hpp>
36 #include <com/sun/star/presentation/XSlideShow.hpp>
37 #include <com/sun/star/presentation/XSlideShowView.hpp>
38 #include <cppuhelper/compbase1.hxx>
39 #include <boost/bind.hpp>
41 using namespace ::com::sun::star;
42 using namespace ::com::sun::star::uno;
43 using namespace ::com::sun::star::drawing::framework;
45 namespace sdext { namespace presenter {
47 const OUString PresenterViewFactory::msCurrentSlidePreviewViewURL(
48 "private:resource/view/Presenter/CurrentSlidePreview");
49 const OUString PresenterViewFactory::msNextSlidePreviewViewURL(
50 "private:resource/view/Presenter/NextSlidePreview");
51 const OUString PresenterViewFactory::msNotesViewURL(
52 "private:resource/view/Presenter/Notes");
53 const OUString PresenterViewFactory::msToolBarViewURL(
54 "private:resource/view/Presenter/ToolBar");
55 const OUString PresenterViewFactory::msSlideSorterURL(
56 "private:resource/view/Presenter/SlideSorter");
57 const OUString PresenterViewFactory::msHelpViewURL(
58 "private:resource/view/Presenter/Help");
60 namespace {
62 /** By default the PresenterSlidePreview shows the preview of the current
63 slide. This adapter class makes it display the preview of the next
64 slide.
66 class NextSlidePreview : public PresenterSlidePreview
68 public:
69 NextSlidePreview (
70 const css::uno::Reference<css::uno::XComponentContext>& rxContext,
71 const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId,
72 const css::uno::Reference<css::drawing::framework::XPane>& rxAnchorPane,
73 const ::rtl::Reference<PresenterController>& rpPresenterController)
74 : PresenterSlidePreview(rxContext, rxViewId, rxAnchorPane, rpPresenterController)
77 virtual ~NextSlidePreview() {}
78 virtual void SAL_CALL setCurrentPage (
79 const css::uno::Reference<css::drawing::XDrawPage>& rxSlide)
80 throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
82 Reference<presentation::XSlideShowController> xSlideShowController (
83 mpPresenterController->GetSlideShowController());
84 Reference<drawing::XDrawPage> xSlide;
85 if (xSlideShowController.is())
87 const sal_Int32 nCount (xSlideShowController->getSlideCount());
88 sal_Int32 nNextSlideIndex (-1);
89 if (xSlideShowController->getCurrentSlide() == rxSlide)
91 nNextSlideIndex = xSlideShowController->getNextSlideIndex();
93 else
95 for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
97 if (rxSlide == Reference<drawing::XDrawPage>(
98 xSlideShowController->getSlideByIndex(nIndex), UNO_QUERY))
100 nNextSlideIndex = nIndex + 1;
104 if (nNextSlideIndex >= 0)
106 if (nNextSlideIndex < nCount)
108 xSlide = Reference<drawing::XDrawPage>(
109 xSlideShowController->getSlideByIndex(nNextSlideIndex),
110 UNO_QUERY);
114 PresenterSlidePreview::setCurrentPage(xSlide);
118 } // end of anonymous namespace
120 //===== PresenterViewFactory ==============================================
122 PresenterViewFactory::PresenterViewFactory (
123 const Reference<uno::XComponentContext>& rxContext,
124 const Reference<frame::XController>& rxController,
125 const ::rtl::Reference<PresenterController>& rpPresenterController)
126 : PresenterViewFactoryInterfaceBase(m_aMutex),
127 mxComponentContext(rxContext),
128 mxConfigurationController(),
129 mxControllerWeak(rxController),
130 mpPresenterController(rpPresenterController),
131 mpResourceCache()
135 Reference<drawing::framework::XResourceFactory> PresenterViewFactory::Create (
136 const Reference<uno::XComponentContext>& rxContext,
137 const Reference<frame::XController>& rxController,
138 const ::rtl::Reference<PresenterController>& rpPresenterController)
140 rtl::Reference<PresenterViewFactory> pFactory (
141 new PresenterViewFactory(rxContext,rxController,rpPresenterController));
142 pFactory->Register(rxController);
143 return Reference<drawing::framework::XResourceFactory>(
144 static_cast<XWeak*>(pFactory.get()), UNO_QUERY);
147 void PresenterViewFactory::Register (const Reference<frame::XController>& rxController)
151 // Get the configuration controller.
152 Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW);
153 mxConfigurationController = xCM->getConfigurationController();
154 if ( ! mxConfigurationController.is())
156 throw RuntimeException();
158 else
160 mxConfigurationController->addResourceFactory(msCurrentSlidePreviewViewURL, this);
161 mxConfigurationController->addResourceFactory(msNextSlidePreviewViewURL, this);
162 mxConfigurationController->addResourceFactory(msNotesViewURL, this);
163 mxConfigurationController->addResourceFactory(msToolBarViewURL, this);
164 mxConfigurationController->addResourceFactory(msSlideSorterURL, this);
165 mxConfigurationController->addResourceFactory(msHelpViewURL, this);
168 catch (RuntimeException&)
170 OSL_ASSERT(false);
171 if (mxConfigurationController.is())
172 mxConfigurationController->removeResourceFactoryForReference(this);
173 mxConfigurationController = NULL;
175 throw;
179 PresenterViewFactory::~PresenterViewFactory()
183 void SAL_CALL PresenterViewFactory::disposing()
184 throw (RuntimeException)
186 if (mxConfigurationController.is())
187 mxConfigurationController->removeResourceFactoryForReference(this);
188 mxConfigurationController = NULL;
190 if (mpResourceCache.get() != NULL)
192 // Dispose all views in the cache.
193 ResourceContainer::const_iterator iView (mpResourceCache->begin());
194 ResourceContainer::const_iterator iEnd (mpResourceCache->end());
195 for ( ; iView!=iEnd; ++iView)
199 Reference<lang::XComponent> xComponent (iView->second.first, UNO_QUERY);
200 if (xComponent.is())
201 xComponent->dispose();
203 catch (lang::DisposedException&)
207 mpResourceCache.reset();
211 //----- XViewFactory ----------------------------------------------------------
213 Reference<XResource> SAL_CALL PresenterViewFactory::createResource (
214 const Reference<XResourceId>& rxViewId)
215 throw (RuntimeException, std::exception)
217 ThrowIfDisposed();
219 Reference<XResource> xView;
221 if (rxViewId.is())
223 Reference<XPane> xAnchorPane (
224 mxConfigurationController->getResource(rxViewId->getAnchor()),
225 UNO_QUERY_THROW);
226 xView = GetViewFromCache(rxViewId, xAnchorPane);
227 if (xView == NULL)
228 xView = CreateView(rxViewId, xAnchorPane);
230 // Activate the view.
231 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
232 mpPresenterController->GetPaneContainer()->FindPaneId(rxViewId->getAnchor()));
233 if (pDescriptor.get() != NULL)
234 pDescriptor->SetActivationState(true);
237 return xView;
240 void SAL_CALL PresenterViewFactory::releaseResource (const Reference<XResource>& rxView)
241 throw (RuntimeException, std::exception)
243 ThrowIfDisposed();
245 if ( ! rxView.is())
246 return;
248 // Deactivate the view.
249 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
250 mpPresenterController->GetPaneContainer()->FindPaneId(
251 rxView->getResourceId()->getAnchor()));
252 if (pDescriptor.get() != NULL)
253 pDescriptor->SetActivationState(false);
255 // Dispose only views that we can not put into the cache.
256 CachablePresenterView* pView = dynamic_cast<CachablePresenterView*>(rxView.get());
257 if (pView == NULL || mpResourceCache.get()==NULL)
261 if (pView != NULL)
262 pView->ReleaseView();
263 Reference<lang::XComponent> xComponent (rxView, UNO_QUERY);
264 if (xComponent.is())
265 xComponent->dispose();
267 catch (lang::DisposedException&)
269 // Do not let disposed exceptions get out. It might be interpreted
270 // as coming from the factory, which would then be removed from the
271 // drawing framework.
274 else
276 // Put cachable views in the cache.
277 Reference<XResourceId> xViewId (rxView->getResourceId());
278 if (xViewId.is())
280 Reference<XPane> xAnchorPane (
281 mxConfigurationController->getResource(xViewId->getAnchor()),
282 UNO_QUERY_THROW);
283 (*mpResourceCache)[xViewId->getResourceURL()]
284 = ViewResourceDescriptor(Reference<XView>(rxView, UNO_QUERY), xAnchorPane);
285 pView->DeactivatePresenterView();
292 Reference<XResource> PresenterViewFactory::GetViewFromCache(
293 const Reference<XResourceId>& rxViewId,
294 const Reference<XPane>& rxAnchorPane) const
296 if (mpResourceCache.get() == NULL)
297 return NULL;
301 const OUString sResourceURL (rxViewId->getResourceURL());
303 // Can we use a view from the cache?
304 ResourceContainer::const_iterator iView (mpResourceCache->find(sResourceURL));
305 if (iView != mpResourceCache->end())
307 // The view is in the container but it can only be used if
308 // the anchor pane is the same now as it was at creation of
309 // the view.
310 if (iView->second.second == rxAnchorPane)
312 CachablePresenterView* pView
313 = dynamic_cast<CachablePresenterView*>(iView->second.first.get());
314 if (pView != NULL)
315 pView->ActivatePresenterView();
316 return Reference<XResource>(iView->second.first, UNO_QUERY);
319 // Right view, wrong pane. Create a new view.
322 catch (RuntimeException&)
325 return NULL;
328 Reference<XResource> PresenterViewFactory::CreateView(
329 const Reference<XResourceId>& rxViewId,
330 const Reference<XPane>& rxAnchorPane)
332 Reference<XView> xView;
336 const OUString sResourceURL (rxViewId->getResourceURL());
338 if (sResourceURL.equals(msCurrentSlidePreviewViewURL))
340 xView = CreateSlideShowView(rxViewId);
342 else if (sResourceURL.equals(msNotesViewURL))
344 xView = CreateNotesView(rxViewId, rxAnchorPane);
346 else if (sResourceURL.equals(msNextSlidePreviewViewURL))
348 xView = CreateSlidePreviewView(rxViewId, rxAnchorPane);
350 else if (sResourceURL.equals(msToolBarViewURL))
352 xView = CreateToolBarView(rxViewId);
354 else if (sResourceURL.equals(msSlideSorterURL))
356 xView = CreateSlideSorterView(rxViewId);
358 else if (sResourceURL.equals(msHelpViewURL))
360 xView = CreateHelpView(rxViewId);
363 // Activate it.
364 CachablePresenterView* pView = dynamic_cast<CachablePresenterView*>(xView.get());
365 if (pView != NULL)
366 pView->ActivatePresenterView();
368 catch (RuntimeException&)
370 xView = NULL;
373 return xView;
376 Reference<XView> PresenterViewFactory::CreateSlideShowView(
377 const Reference<XResourceId>& rxViewId) const
379 Reference<XView> xView;
381 if ( ! mxConfigurationController.is())
382 return xView;
383 if ( ! mxComponentContext.is())
384 return xView;
388 rtl::Reference<PresenterSlideShowView> pShowView (
389 new PresenterSlideShowView(
390 mxComponentContext,
391 rxViewId,
392 Reference<frame::XController>(mxControllerWeak),
393 mpPresenterController));
394 pShowView->LateInit();
395 xView = Reference<XView>(pShowView.get());
397 catch (RuntimeException&)
399 xView = NULL;
402 return xView;
405 Reference<XView> PresenterViewFactory::CreateSlidePreviewView(
406 const Reference<XResourceId>& rxViewId,
407 const Reference<XPane>& rxAnchorPane) const
409 Reference<XView> xView;
411 if ( ! mxConfigurationController.is())
412 return xView;
413 if ( ! mxComponentContext.is())
414 return xView;
418 xView = Reference<XView>(
419 static_cast<XWeak*>(new NextSlidePreview(
420 mxComponentContext,
421 rxViewId,
422 rxAnchorPane,
423 mpPresenterController)),
424 UNO_QUERY_THROW);
426 catch (RuntimeException&)
428 xView = NULL;
431 return xView;
434 Reference<XView> PresenterViewFactory::CreateToolBarView(
435 const Reference<XResourceId>& rxViewId) const
437 return new PresenterToolBarView(
438 mxComponentContext,
439 rxViewId,
440 Reference<frame::XController>(mxControllerWeak),
441 mpPresenterController);
444 Reference<XView> PresenterViewFactory::CreateNotesView(
445 const Reference<XResourceId>& rxViewId,
446 const Reference<XPane>& rxAnchorPane) const
448 (void)rxAnchorPane;
449 Reference<XView> xView;
451 if ( ! mxConfigurationController.is())
452 return xView;
453 if ( ! mxComponentContext.is())
454 return xView;
458 xView = Reference<XView>(static_cast<XWeak*>(
459 new PresenterNotesView(
460 mxComponentContext,
461 rxViewId,
462 Reference<frame::XController>(mxControllerWeak),
463 mpPresenterController)),
464 UNO_QUERY_THROW);
466 catch (RuntimeException&)
468 xView = NULL;
471 return xView;
474 Reference<XView> PresenterViewFactory::CreateSlideSorterView(
475 const Reference<XResourceId>& rxViewId) const
477 Reference<XView> xView;
479 if ( ! mxConfigurationController.is())
480 return xView;
481 if ( ! mxComponentContext.is())
482 return xView;
486 rtl::Reference<PresenterSlideSorter> pView (
487 new PresenterSlideSorter(
488 mxComponentContext,
489 rxViewId,
490 Reference<frame::XController>(mxControllerWeak),
491 mpPresenterController));
492 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
493 mpPresenterController->GetPaneContainer()->FindPaneId(rxViewId->getAnchor()));
494 if (pDescriptor.get() != NULL)
495 pDescriptor->maActivator = ::boost::bind(
496 &PresenterSlideSorter::SetActiveState, _1);
497 xView = pView.get();
499 catch (RuntimeException&)
501 xView = NULL;
504 return xView;
507 Reference<XView> PresenterViewFactory::CreateHelpView(
508 const Reference<XResourceId>& rxViewId) const
510 return Reference<XView>(new PresenterHelpView(
511 mxComponentContext,
512 rxViewId,
513 Reference<frame::XController>(mxControllerWeak),
514 mpPresenterController));
517 void PresenterViewFactory::ThrowIfDisposed() const
518 throw (::com::sun::star::lang::DisposedException)
520 if (rBHelper.bDisposed || rBHelper.bInDispose)
522 throw lang::DisposedException (
523 OUString(
524 "PresenterViewFactory object has already been disposed"),
525 const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
529 //===== CachablePresenterView =================================================
531 CachablePresenterView::CachablePresenterView()
532 : mbIsPresenterViewActive(true)
536 void CachablePresenterView::ActivatePresenterView()
538 mbIsPresenterViewActive = true;
541 void CachablePresenterView::DeactivatePresenterView()
543 mbIsPresenterViewActive = false;
546 void CachablePresenterView::ReleaseView()
552 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */