Updated core
[LibreOffice.git] / sdext / source / presenter / PresenterViewFactory.cxx
blob4ebc8fe59245def4550e33e9e63b58199f3c21ad
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 //===== SimpleView ============================================================
62 namespace {
64 typedef ::cppu::WeakComponentImplHelper1 <XView> SimpleViewInterfaceBase;
66 class SimpleView
67 : private ::cppu::BaseMutex,
68 public SimpleViewInterfaceBase
70 public:
71 SimpleView (const Reference<XResourceId>& rxViewId)
72 : SimpleViewInterfaceBase(m_aMutex),mxResourceId(rxViewId) {};
73 virtual ~SimpleView (void) {};
75 // XView
77 virtual Reference<XResourceId> SAL_CALL getResourceId (void) throw (RuntimeException)
78 { return mxResourceId; };
80 private:
81 Reference<XResourceId> mxResourceId;
84 /** By default the PresenterSlidePreview shows the preview of the current
85 slide. This adapter class makes it display the preview of the next
86 slide.
88 class NextSlidePreview : public PresenterSlidePreview
90 public:
91 NextSlidePreview (
92 const css::uno::Reference<css::uno::XComponentContext>& rxContext,
93 const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId,
94 const css::uno::Reference<css::drawing::framework::XPane>& rxAnchorPane,
95 const ::rtl::Reference<PresenterController>& rpPresenterController)
96 : PresenterSlidePreview(rxContext, rxViewId, rxAnchorPane, rpPresenterController)
99 virtual ~NextSlidePreview (void) {}
100 virtual void SAL_CALL setCurrentPage (
101 const css::uno::Reference<css::drawing::XDrawPage>& rxSlide)
102 throw (css::uno::RuntimeException)
104 Reference<presentation::XSlideShowController> xSlideShowController (
105 mpPresenterController->GetSlideShowController());
106 Reference<drawing::XDrawPage> xSlide;
107 if (xSlideShowController.is())
109 const sal_Int32 nCount (xSlideShowController->getSlideCount());
110 sal_Int32 nNextSlideIndex (-1);
111 if (xSlideShowController->getCurrentSlide() == rxSlide)
113 nNextSlideIndex = xSlideShowController->getNextSlideIndex();
115 else
117 for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
119 if (rxSlide == Reference<drawing::XDrawPage>(
120 xSlideShowController->getSlideByIndex(nIndex), UNO_QUERY))
122 nNextSlideIndex = nIndex + 1;
126 if (nNextSlideIndex >= 0)
128 if (nNextSlideIndex < nCount)
130 xSlide = Reference<drawing::XDrawPage>(
131 xSlideShowController->getSlideByIndex(nNextSlideIndex),
132 UNO_QUERY);
136 PresenterSlidePreview::setCurrentPage(xSlide);
140 } // end of anonymous namespace
142 //===== PresenterViewFactory ==============================================
144 PresenterViewFactory::PresenterViewFactory (
145 const Reference<uno::XComponentContext>& rxContext,
146 const Reference<frame::XController>& rxController,
147 const ::rtl::Reference<PresenterController>& rpPresenterController)
148 : PresenterViewFactoryInterfaceBase(m_aMutex),
149 mxComponentContext(rxContext),
150 mxConfigurationController(),
151 mxControllerWeak(rxController),
152 mpPresenterController(rpPresenterController),
153 mpResourceCache()
157 Reference<drawing::framework::XResourceFactory> PresenterViewFactory::Create (
158 const Reference<uno::XComponentContext>& rxContext,
159 const Reference<frame::XController>& rxController,
160 const ::rtl::Reference<PresenterController>& rpPresenterController)
162 rtl::Reference<PresenterViewFactory> pFactory (
163 new PresenterViewFactory(rxContext,rxController,rpPresenterController));
164 pFactory->Register(rxController);
165 return Reference<drawing::framework::XResourceFactory>(
166 static_cast<XWeak*>(pFactory.get()), UNO_QUERY);
169 void PresenterViewFactory::Register (const Reference<frame::XController>& rxController)
173 // Get the configuration controller.
174 Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW);
175 mxConfigurationController = xCM->getConfigurationController();
176 if ( ! mxConfigurationController.is())
178 throw RuntimeException();
180 else
182 mxConfigurationController->addResourceFactory(msCurrentSlidePreviewViewURL, this);
183 mxConfigurationController->addResourceFactory(msNextSlidePreviewViewURL, this);
184 mxConfigurationController->addResourceFactory(msNotesViewURL, this);
185 mxConfigurationController->addResourceFactory(msToolBarViewURL, this);
186 mxConfigurationController->addResourceFactory(msSlideSorterURL, this);
187 mxConfigurationController->addResourceFactory(msHelpViewURL, this);
190 catch (RuntimeException&)
192 OSL_ASSERT(false);
193 if (mxConfigurationController.is())
194 mxConfigurationController->removeResourceFactoryForReference(this);
195 mxConfigurationController = NULL;
197 throw;
201 PresenterViewFactory::~PresenterViewFactory (void)
205 void SAL_CALL PresenterViewFactory::disposing (void)
206 throw (RuntimeException)
208 if (mxConfigurationController.is())
209 mxConfigurationController->removeResourceFactoryForReference(this);
210 mxConfigurationController = NULL;
212 if (mpResourceCache.get() != NULL)
214 // Dispose all views in the cache.
215 ResourceContainer::const_iterator iView (mpResourceCache->begin());
216 ResourceContainer::const_iterator iEnd (mpResourceCache->end());
217 for ( ; iView!=iEnd; ++iView)
221 Reference<lang::XComponent> xComponent (iView->second.first, UNO_QUERY);
222 if (xComponent.is())
223 xComponent->dispose();
225 catch (lang::DisposedException&)
229 mpResourceCache.reset();
233 //----- XViewFactory ----------------------------------------------------------
235 Reference<XResource> SAL_CALL PresenterViewFactory::createResource (
236 const Reference<XResourceId>& rxViewId)
237 throw (RuntimeException)
239 ThrowIfDisposed();
241 Reference<XResource> xView;
243 if (rxViewId.is())
245 Reference<XPane> xAnchorPane (
246 mxConfigurationController->getResource(rxViewId->getAnchor()),
247 UNO_QUERY_THROW);
248 xView = GetViewFromCache(rxViewId, xAnchorPane);
249 if (xView == NULL)
250 xView = CreateView(rxViewId, xAnchorPane);
252 // Activate the view.
253 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
254 mpPresenterController->GetPaneContainer()->FindPaneId(rxViewId->getAnchor()));
255 if (pDescriptor.get() != NULL)
256 pDescriptor->SetActivationState(true);
259 return xView;
262 void SAL_CALL PresenterViewFactory::releaseResource (const Reference<XResource>& rxView)
263 throw (RuntimeException)
265 ThrowIfDisposed();
267 if ( ! rxView.is())
268 return;
270 // Deactivate the view.
271 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
272 mpPresenterController->GetPaneContainer()->FindPaneId(
273 rxView->getResourceId()->getAnchor()));
274 if (pDescriptor.get() != NULL)
275 pDescriptor->SetActivationState(false);
277 // Dispose only views that we can not put into the cache.
278 CachablePresenterView* pView = dynamic_cast<CachablePresenterView*>(rxView.get());
279 if (pView == NULL || mpResourceCache.get()==NULL)
283 if (pView != NULL)
284 pView->ReleaseView();
285 Reference<lang::XComponent> xComponent (rxView, UNO_QUERY);
286 if (xComponent.is())
287 xComponent->dispose();
289 catch (lang::DisposedException&)
291 // Do not let disposed exceptions get out. It might be interpreted
292 // as coming from the factory, which would then be removed from the
293 // drawing framework.
296 else
298 // Put cachable views in the cache.
299 Reference<XResourceId> xViewId (rxView->getResourceId());
300 if (xViewId.is())
302 Reference<XPane> xAnchorPane (
303 mxConfigurationController->getResource(xViewId->getAnchor()),
304 UNO_QUERY_THROW);
305 (*mpResourceCache)[xViewId->getResourceURL()]
306 = ViewResourceDescriptor(Reference<XView>(rxView, UNO_QUERY), xAnchorPane);
307 pView->DeactivatePresenterView();
312 //-----------------------------------------------------------------------------
314 Reference<XResource> PresenterViewFactory::GetViewFromCache(
315 const Reference<XResourceId>& rxViewId,
316 const Reference<XPane>& rxAnchorPane) const
318 if (mpResourceCache.get() == NULL)
319 return NULL;
323 const OUString sResourceURL (rxViewId->getResourceURL());
325 // Can we use a view from the cache?
326 ResourceContainer::const_iterator iView (mpResourceCache->find(sResourceURL));
327 if (iView != mpResourceCache->end())
329 // The view is in the container but it can only be used if
330 // the anchor pane is the same now as it was at creation of
331 // the view.
332 if (iView->second.second == rxAnchorPane)
334 CachablePresenterView* pView
335 = dynamic_cast<CachablePresenterView*>(iView->second.first.get());
336 if (pView != NULL)
337 pView->ActivatePresenterView();
338 return Reference<XResource>(iView->second.first, UNO_QUERY);
341 // Right view, wrong pane. Create a new view.
344 catch (RuntimeException&)
347 return NULL;
350 Reference<XResource> PresenterViewFactory::CreateView(
351 const Reference<XResourceId>& rxViewId,
352 const Reference<XPane>& rxAnchorPane)
354 Reference<XView> xView;
358 const OUString sResourceURL (rxViewId->getResourceURL());
360 if (sResourceURL.equals(msCurrentSlidePreviewViewURL))
362 xView = CreateSlideShowView(rxViewId);
364 else if (sResourceURL.equals(msNotesViewURL))
366 xView = CreateNotesView(rxViewId, rxAnchorPane);
368 else if (sResourceURL.equals(msNextSlidePreviewViewURL))
370 xView = CreateSlidePreviewView(rxViewId, rxAnchorPane);
372 else if (sResourceURL.equals(msToolBarViewURL))
374 xView = CreateToolBarView(rxViewId);
376 else if (sResourceURL.equals(msSlideSorterURL))
378 xView = CreateSlideSorterView(rxViewId);
380 else if (sResourceURL.equals(msHelpViewURL))
382 xView = CreateHelpView(rxViewId);
385 // Activate it.
386 CachablePresenterView* pView = dynamic_cast<CachablePresenterView*>(xView.get());
387 if (pView != NULL)
388 pView->ActivatePresenterView();
390 catch (RuntimeException&)
392 xView = NULL;
395 return Reference<XResource>(xView, UNO_QUERY);
398 Reference<XView> PresenterViewFactory::CreateSlideShowView(
399 const Reference<XResourceId>& rxViewId) const
401 Reference<XView> xView;
403 if ( ! mxConfigurationController.is())
404 return xView;
405 if ( ! mxComponentContext.is())
406 return xView;
410 rtl::Reference<PresenterSlideShowView> pShowView (
411 new PresenterSlideShowView(
412 mxComponentContext,
413 rxViewId,
414 Reference<frame::XController>(mxControllerWeak),
415 mpPresenterController));
416 pShowView->LateInit();
417 xView = Reference<XView>(pShowView.get());
419 catch (RuntimeException&)
421 xView = NULL;
424 return xView;
427 Reference<XView> PresenterViewFactory::CreateSlidePreviewView(
428 const Reference<XResourceId>& rxViewId,
429 const Reference<XPane>& rxAnchorPane) const
431 Reference<XView> xView;
433 if ( ! mxConfigurationController.is())
434 return xView;
435 if ( ! mxComponentContext.is())
436 return xView;
440 xView = Reference<XView>(
441 static_cast<XWeak*>(new NextSlidePreview(
442 mxComponentContext,
443 rxViewId,
444 rxAnchorPane,
445 mpPresenterController)),
446 UNO_QUERY_THROW);
448 catch (RuntimeException&)
450 xView = NULL;
453 return xView;
456 Reference<XView> PresenterViewFactory::CreateToolBarView(
457 const Reference<XResourceId>& rxViewId) const
459 return new PresenterToolBarView(
460 mxComponentContext,
461 rxViewId,
462 Reference<frame::XController>(mxControllerWeak),
463 mpPresenterController);
466 Reference<XView> PresenterViewFactory::CreateNotesView(
467 const Reference<XResourceId>& rxViewId,
468 const Reference<XPane>& rxAnchorPane) const
470 (void)rxAnchorPane;
471 Reference<XView> xView;
473 if ( ! mxConfigurationController.is())
474 return xView;
475 if ( ! mxComponentContext.is())
476 return xView;
480 xView = Reference<XView>(static_cast<XWeak*>(
481 new PresenterNotesView(
482 mxComponentContext,
483 rxViewId,
484 Reference<frame::XController>(mxControllerWeak),
485 mpPresenterController)),
486 UNO_QUERY_THROW);
488 catch (RuntimeException&)
490 xView = NULL;
493 return xView;
496 Reference<XView> PresenterViewFactory::CreateSlideSorterView(
497 const Reference<XResourceId>& rxViewId) const
499 Reference<XView> xView;
501 if ( ! mxConfigurationController.is())
502 return xView;
503 if ( ! mxComponentContext.is())
504 return xView;
508 rtl::Reference<PresenterSlideSorter> pView (
509 new PresenterSlideSorter(
510 mxComponentContext,
511 rxViewId,
512 Reference<frame::XController>(mxControllerWeak),
513 mpPresenterController));
514 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
515 mpPresenterController->GetPaneContainer()->FindPaneId(rxViewId->getAnchor()));
516 if (pDescriptor.get() != NULL)
517 pDescriptor->maActivator = ::boost::bind(
518 &PresenterSlideSorter::SetActiveState, pView.get(), _1);
519 xView = pView.get();
521 catch (RuntimeException&)
523 xView = NULL;
526 return xView;
529 Reference<XView> PresenterViewFactory::CreateHelpView(
530 const Reference<XResourceId>& rxViewId) const
532 return Reference<XView>(new PresenterHelpView(
533 mxComponentContext,
534 rxViewId,
535 Reference<frame::XController>(mxControllerWeak),
536 mpPresenterController));
539 void PresenterViewFactory::ThrowIfDisposed (void) const
540 throw (::com::sun::star::lang::DisposedException)
542 if (rBHelper.bDisposed || rBHelper.bInDispose)
544 throw lang::DisposedException (
545 OUString(
546 "PresenterViewFactory object has already been disposed"),
547 const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
551 //===== CachablePresenterView =================================================
553 CachablePresenterView::CachablePresenterView (void)
554 : mbIsPresenterViewActive(true)
558 void CachablePresenterView::ActivatePresenterView (void)
560 mbIsPresenterViewActive = true;
563 void CachablePresenterView::DeactivatePresenterView (void)
565 mbIsPresenterViewActive = false;
568 void CachablePresenterView::ReleaseView (void)
574 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */