Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
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>
40 :
41 : using namespace ::com::sun::star;
42 : using namespace ::com::sun::star::uno;
43 : using namespace ::com::sun::star::drawing::framework;
44 : using ::rtl::OUString;
45 :
46 : #define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
47 :
48 : namespace sdext { namespace presenter {
49 :
50 0 : const ::rtl::OUString PresenterViewFactory::msCurrentSlidePreviewViewURL(
51 : A2S("private:resource/view/Presenter/CurrentSlidePreview"));
52 0 : const ::rtl::OUString PresenterViewFactory::msNextSlidePreviewViewURL(
53 : A2S("private:resource/view/Presenter/NextSlidePreview"));
54 0 : const ::rtl::OUString PresenterViewFactory::msNotesViewURL(
55 : A2S("private:resource/view/Presenter/Notes"));
56 0 : const ::rtl::OUString PresenterViewFactory::msToolBarViewURL(
57 : A2S("private:resource/view/Presenter/ToolBar"));
58 0 : const ::rtl::OUString PresenterViewFactory::msSlideSorterURL(
59 : A2S("private:resource/view/Presenter/SlideSorter"));
60 0 : const ::rtl::OUString PresenterViewFactory::msHelpViewURL(
61 : A2S("private:resource/view/Presenter/Help"));
62 :
63 : //===== SimpleView ============================================================
64 :
65 : namespace {
66 :
67 : typedef ::cppu::WeakComponentImplHelper1 <XView> SimpleViewInterfaceBase;
68 :
69 : class SimpleView
70 : : private ::cppu::BaseMutex,
71 : public SimpleViewInterfaceBase
72 : {
73 : public:
74 : SimpleView (const Reference<XResourceId>& rxViewId)
75 : : SimpleViewInterfaceBase(m_aMutex),mxResourceId(rxViewId) {};
76 0 : virtual ~SimpleView (void) {};
77 :
78 : // XView
79 :
80 0 : virtual Reference<XResourceId> SAL_CALL getResourceId (void) throw (RuntimeException)
81 0 : { return mxResourceId; };
82 :
83 : private:
84 : Reference<XResourceId> mxResourceId;
85 : };
86 :
87 : /** By default the PresenterSlidePreview shows the preview of the current
88 : slide. This adapter class makes it display the preview of the next
89 : slide.
90 : */
91 : class NextSlidePreview : public PresenterSlidePreview
92 : {
93 : public:
94 0 : NextSlidePreview (
95 : const css::uno::Reference<css::uno::XComponentContext>& rxContext,
96 : const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId,
97 : const css::uno::Reference<css::drawing::framework::XPane>& rxAnchorPane,
98 : const ::rtl::Reference<PresenterController>& rpPresenterController)
99 0 : : PresenterSlidePreview(rxContext, rxViewId, rxAnchorPane, rpPresenterController)
100 : {
101 0 : }
102 0 : virtual ~NextSlidePreview (void) {}
103 0 : virtual void SAL_CALL setCurrentPage (
104 : const css::uno::Reference<css::drawing::XDrawPage>& rxSlide)
105 : throw (css::uno::RuntimeException)
106 : {
107 : Reference<presentation::XSlideShowController> xSlideShowController (
108 0 : mpPresenterController->GetSlideShowController());
109 0 : Reference<drawing::XDrawPage> xSlide;
110 0 : if (xSlideShowController.is())
111 : {
112 0 : const sal_Int32 nCount (xSlideShowController->getSlideCount());
113 0 : sal_Int32 nNextSlideIndex (-1);
114 0 : if (xSlideShowController->getCurrentSlide() == rxSlide)
115 : {
116 0 : nNextSlideIndex = xSlideShowController->getNextSlideIndex();
117 : }
118 : else
119 : {
120 0 : for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
121 : {
122 0 : if (rxSlide == Reference<drawing::XDrawPage>(
123 0 : xSlideShowController->getSlideByIndex(nIndex), UNO_QUERY))
124 : {
125 0 : nNextSlideIndex = nIndex + 1;
126 : }
127 : }
128 : }
129 0 : if (nNextSlideIndex >= 0)
130 : {
131 0 : if (nNextSlideIndex < nCount)
132 : {
133 : xSlide = Reference<drawing::XDrawPage>(
134 0 : xSlideShowController->getSlideByIndex(nNextSlideIndex),
135 0 : UNO_QUERY);
136 : }
137 : }
138 : }
139 0 : PresenterSlidePreview::setCurrentPage(xSlide);
140 0 : }
141 : };
142 :
143 : } // end of anonymous namespace
144 :
145 : //===== PresenterViewFactory ==============================================
146 :
147 0 : PresenterViewFactory::PresenterViewFactory (
148 : const Reference<uno::XComponentContext>& rxContext,
149 : const Reference<frame::XController>& rxController,
150 : const ::rtl::Reference<PresenterController>& rpPresenterController)
151 : : PresenterViewFactoryInterfaceBase(m_aMutex),
152 : mxComponentContext(rxContext),
153 : mxConfigurationController(),
154 : mxControllerWeak(rxController),
155 : mpPresenterController(rpPresenterController),
156 0 : mpResourceCache()
157 : {
158 0 : }
159 :
160 0 : Reference<drawing::framework::XResourceFactory> PresenterViewFactory::Create (
161 : const Reference<uno::XComponentContext>& rxContext,
162 : const Reference<frame::XController>& rxController,
163 : const ::rtl::Reference<PresenterController>& rpPresenterController)
164 : {
165 : rtl::Reference<PresenterViewFactory> pFactory (
166 0 : new PresenterViewFactory(rxContext,rxController,rpPresenterController));
167 0 : pFactory->Register(rxController);
168 : return Reference<drawing::framework::XResourceFactory>(
169 0 : static_cast<XWeak*>(pFactory.get()), UNO_QUERY);
170 : }
171 :
172 0 : void PresenterViewFactory::Register (const Reference<frame::XController>& rxController)
173 : {
174 : try
175 : {
176 : // Get the configuration controller.
177 0 : Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW);
178 0 : mxConfigurationController = xCM->getConfigurationController();
179 0 : if ( ! mxConfigurationController.is())
180 : {
181 0 : throw RuntimeException();
182 : }
183 : else
184 : {
185 0 : mxConfigurationController->addResourceFactory(msCurrentSlidePreviewViewURL, this);
186 0 : mxConfigurationController->addResourceFactory(msNextSlidePreviewViewURL, this);
187 0 : mxConfigurationController->addResourceFactory(msNotesViewURL, this);
188 0 : mxConfigurationController->addResourceFactory(msToolBarViewURL, this);
189 0 : mxConfigurationController->addResourceFactory(msSlideSorterURL, this);
190 0 : mxConfigurationController->addResourceFactory(msHelpViewURL, this);
191 0 : }
192 : }
193 0 : catch (RuntimeException&)
194 : {
195 : OSL_ASSERT(false);
196 0 : if (mxConfigurationController.is())
197 0 : mxConfigurationController->removeResourceFactoryForReference(this);
198 0 : mxConfigurationController = NULL;
199 :
200 0 : throw;
201 : }
202 0 : }
203 :
204 0 : PresenterViewFactory::~PresenterViewFactory (void)
205 : {
206 0 : }
207 :
208 0 : void SAL_CALL PresenterViewFactory::disposing (void)
209 : throw (RuntimeException)
210 : {
211 0 : if (mxConfigurationController.is())
212 0 : mxConfigurationController->removeResourceFactoryForReference(this);
213 0 : mxConfigurationController = NULL;
214 :
215 0 : if (mpResourceCache.get() != NULL)
216 : {
217 : // Dispose all views in the cache.
218 0 : ResourceContainer::const_iterator iView (mpResourceCache->begin());
219 0 : ResourceContainer::const_iterator iEnd (mpResourceCache->end());
220 0 : for ( ; iView!=iEnd; ++iView)
221 : {
222 : try
223 : {
224 0 : Reference<lang::XComponent> xComponent (iView->second.first, UNO_QUERY);
225 0 : if (xComponent.is())
226 0 : xComponent->dispose();
227 : }
228 0 : catch (lang::DisposedException&)
229 : {
230 : }
231 : }
232 0 : mpResourceCache.reset();
233 : }
234 0 : }
235 :
236 : //----- XViewFactory ----------------------------------------------------------
237 :
238 0 : Reference<XResource> SAL_CALL PresenterViewFactory::createResource (
239 : const Reference<XResourceId>& rxViewId)
240 : throw (RuntimeException)
241 : {
242 0 : ThrowIfDisposed();
243 :
244 0 : Reference<XResource> xView;
245 :
246 0 : if (rxViewId.is())
247 : {
248 : Reference<XPane> xAnchorPane (
249 0 : mxConfigurationController->getResource(rxViewId->getAnchor()),
250 0 : UNO_QUERY_THROW);
251 0 : xView = GetViewFromCache(rxViewId, xAnchorPane);
252 0 : if (xView == NULL)
253 0 : xView = CreateView(rxViewId, xAnchorPane);
254 :
255 : // Activate the view.
256 : PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
257 0 : mpPresenterController->GetPaneContainer()->FindPaneId(rxViewId->getAnchor()));
258 0 : if (pDescriptor.get() != NULL)
259 0 : pDescriptor->SetActivationState(true);
260 : }
261 :
262 0 : return xView;
263 : }
264 :
265 0 : void SAL_CALL PresenterViewFactory::releaseResource (const Reference<XResource>& rxView)
266 : throw (RuntimeException)
267 : {
268 0 : ThrowIfDisposed();
269 :
270 0 : if ( ! rxView.is())
271 0 : return;
272 :
273 : // Deactivate the view.
274 : PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
275 : mpPresenterController->GetPaneContainer()->FindPaneId(
276 0 : rxView->getResourceId()->getAnchor()));
277 0 : if (pDescriptor.get() != NULL)
278 0 : pDescriptor->SetActivationState(false);
279 :
280 : // Dispose only views that we can not put into the cache.
281 0 : CachablePresenterView* pView = dynamic_cast<CachablePresenterView*>(rxView.get());
282 0 : if (pView == NULL || mpResourceCache.get()==NULL)
283 : {
284 : try
285 : {
286 0 : if (pView != NULL)
287 0 : pView->ReleaseView();
288 0 : Reference<lang::XComponent> xComponent (rxView, UNO_QUERY);
289 0 : if (xComponent.is())
290 0 : xComponent->dispose();
291 : }
292 0 : catch (lang::DisposedException&)
293 : {
294 : // Do not let disposed exceptions get out. It might be interpreted
295 : // as coming from the factory, which would then be removed from the
296 : // drawing framework.
297 : }
298 : }
299 : else
300 : {
301 : // Put cachable views in the cache.
302 0 : Reference<XResourceId> xViewId (rxView->getResourceId());
303 0 : if (xViewId.is())
304 : {
305 : Reference<XPane> xAnchorPane (
306 0 : mxConfigurationController->getResource(xViewId->getAnchor()),
307 0 : UNO_QUERY_THROW);
308 0 : (*mpResourceCache)[xViewId->getResourceURL()]
309 0 : = ViewResourceDescriptor(Reference<XView>(rxView, UNO_QUERY), xAnchorPane);
310 0 : pView->DeactivatePresenterView();
311 0 : }
312 0 : }
313 : }
314 :
315 : //-----------------------------------------------------------------------------
316 :
317 0 : Reference<XResource> PresenterViewFactory::GetViewFromCache(
318 : const Reference<XResourceId>& rxViewId,
319 : const Reference<XPane>& rxAnchorPane) const
320 : {
321 0 : if (mpResourceCache.get() == NULL)
322 0 : return NULL;
323 :
324 : try
325 : {
326 0 : const OUString sResourceURL (rxViewId->getResourceURL());
327 :
328 : // Can we use a view from the cache?
329 0 : ResourceContainer::const_iterator iView (mpResourceCache->find(sResourceURL));
330 0 : if (iView != mpResourceCache->end())
331 : {
332 : // The view is in the container but it can only be used if
333 : // the anchor pane is the same now as it was at creation of
334 : // the view.
335 0 : if (iView->second.second == rxAnchorPane)
336 : {
337 : CachablePresenterView* pView
338 0 : = dynamic_cast<CachablePresenterView*>(iView->second.first.get());
339 0 : if (pView != NULL)
340 0 : pView->ActivatePresenterView();
341 0 : return Reference<XResource>(iView->second.first, UNO_QUERY);
342 : }
343 :
344 : // Right view, wrong pane. Create a new view.
345 0 : }
346 : }
347 0 : catch (RuntimeException&)
348 : {
349 : }
350 0 : return NULL;
351 : }
352 :
353 0 : Reference<XResource> PresenterViewFactory::CreateView(
354 : const Reference<XResourceId>& rxViewId,
355 : const Reference<XPane>& rxAnchorPane)
356 : {
357 0 : Reference<XView> xView;
358 :
359 : try
360 : {
361 0 : const OUString sResourceURL (rxViewId->getResourceURL());
362 :
363 0 : if (sResourceURL.equals(msCurrentSlidePreviewViewURL))
364 : {
365 0 : xView = CreateSlideShowView(rxViewId);
366 : }
367 0 : else if (sResourceURL.equals(msNotesViewURL))
368 : {
369 0 : xView = CreateNotesView(rxViewId, rxAnchorPane);
370 : }
371 0 : else if (sResourceURL.equals(msNextSlidePreviewViewURL))
372 : {
373 0 : xView = CreateSlidePreviewView(rxViewId, rxAnchorPane);
374 : }
375 0 : else if (sResourceURL.equals(msToolBarViewURL))
376 : {
377 0 : xView = CreateToolBarView(rxViewId);
378 : }
379 0 : else if (sResourceURL.equals(msSlideSorterURL))
380 : {
381 0 : xView = CreateSlideSorterView(rxViewId);
382 : }
383 0 : else if (sResourceURL.equals(msHelpViewURL))
384 : {
385 0 : xView = CreateHelpView(rxViewId);
386 : }
387 :
388 : // Activate it.
389 0 : CachablePresenterView* pView = dynamic_cast<CachablePresenterView*>(xView.get());
390 0 : if (pView != NULL)
391 0 : pView->ActivatePresenterView();
392 : }
393 0 : catch (RuntimeException&)
394 : {
395 0 : xView = NULL;
396 : }
397 :
398 0 : return Reference<XResource>(xView, UNO_QUERY);
399 : }
400 :
401 0 : Reference<XView> PresenterViewFactory::CreateSlideShowView(
402 : const Reference<XResourceId>& rxViewId) const
403 : {
404 0 : Reference<XView> xView;
405 :
406 0 : if ( ! mxConfigurationController.is())
407 0 : return xView;
408 0 : if ( ! mxComponentContext.is())
409 0 : return xView;
410 :
411 : try
412 : {
413 : rtl::Reference<PresenterSlideShowView> pShowView (
414 : new PresenterSlideShowView(
415 : mxComponentContext,
416 : rxViewId,
417 : Reference<frame::XController>(mxControllerWeak),
418 0 : mpPresenterController));
419 0 : pShowView->LateInit();
420 0 : xView = Reference<XView>(pShowView.get());
421 : }
422 0 : catch (RuntimeException&)
423 : {
424 0 : xView = NULL;
425 : }
426 :
427 0 : return xView;
428 : }
429 :
430 0 : Reference<XView> PresenterViewFactory::CreateSlidePreviewView(
431 : const Reference<XResourceId>& rxViewId,
432 : const Reference<XPane>& rxAnchorPane) const
433 : {
434 0 : Reference<XView> xView;
435 :
436 0 : if ( ! mxConfigurationController.is())
437 0 : return xView;
438 0 : if ( ! mxComponentContext.is())
439 0 : return xView;
440 :
441 : try
442 : {
443 : xView = Reference<XView>(
444 : static_cast<XWeak*>(new NextSlidePreview(
445 : mxComponentContext,
446 : rxViewId,
447 : rxAnchorPane,
448 0 : mpPresenterController)),
449 0 : UNO_QUERY_THROW);
450 : }
451 0 : catch (RuntimeException&)
452 : {
453 0 : xView = NULL;
454 : }
455 :
456 0 : return xView;
457 : }
458 :
459 0 : Reference<XView> PresenterViewFactory::CreateToolBarView(
460 : const Reference<XResourceId>& rxViewId) const
461 : {
462 : return new PresenterToolBarView(
463 : mxComponentContext,
464 : rxViewId,
465 : Reference<frame::XController>(mxControllerWeak),
466 0 : mpPresenterController);
467 : }
468 :
469 0 : Reference<XView> PresenterViewFactory::CreateNotesView(
470 : const Reference<XResourceId>& rxViewId,
471 : const Reference<XPane>& rxAnchorPane) const
472 : {
473 : (void)rxAnchorPane;
474 0 : Reference<XView> xView;
475 :
476 0 : if ( ! mxConfigurationController.is())
477 0 : return xView;
478 0 : if ( ! mxComponentContext.is())
479 0 : return xView;
480 :
481 : try
482 : {
483 : xView = Reference<XView>(static_cast<XWeak*>(
484 : new PresenterNotesView(
485 : mxComponentContext,
486 : rxViewId,
487 : Reference<frame::XController>(mxControllerWeak),
488 0 : mpPresenterController)),
489 0 : UNO_QUERY_THROW);
490 : }
491 0 : catch (RuntimeException&)
492 : {
493 0 : xView = NULL;
494 : }
495 :
496 0 : return xView;
497 : }
498 :
499 0 : Reference<XView> PresenterViewFactory::CreateSlideSorterView(
500 : const Reference<XResourceId>& rxViewId) const
501 : {
502 0 : Reference<XView> xView;
503 :
504 0 : if ( ! mxConfigurationController.is())
505 0 : return xView;
506 0 : if ( ! mxComponentContext.is())
507 0 : return xView;
508 :
509 : try
510 : {
511 : rtl::Reference<PresenterSlideSorter> pView (
512 : new PresenterSlideSorter(
513 : mxComponentContext,
514 : rxViewId,
515 : Reference<frame::XController>(mxControllerWeak),
516 0 : mpPresenterController));
517 : PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
518 0 : mpPresenterController->GetPaneContainer()->FindPaneId(rxViewId->getAnchor()));
519 0 : if (pDescriptor.get() != NULL)
520 0 : pDescriptor->maActivator = ::boost::bind(
521 0 : &PresenterSlideSorter::SetActiveState, pView.get(), _1);
522 0 : xView = pView.get();
523 : }
524 0 : catch (RuntimeException&)
525 : {
526 0 : xView = NULL;
527 : }
528 :
529 0 : return xView;
530 : }
531 :
532 0 : Reference<XView> PresenterViewFactory::CreateHelpView(
533 : const Reference<XResourceId>& rxViewId) const
534 : {
535 : return Reference<XView>(new PresenterHelpView(
536 : mxComponentContext,
537 : rxViewId,
538 : Reference<frame::XController>(mxControllerWeak),
539 0 : mpPresenterController));
540 : }
541 :
542 0 : void PresenterViewFactory::ThrowIfDisposed (void) const
543 : throw (::com::sun::star::lang::DisposedException)
544 : {
545 0 : if (rBHelper.bDisposed || rBHelper.bInDispose)
546 : {
547 : throw lang::DisposedException (
548 : OUString(RTL_CONSTASCII_USTRINGPARAM(
549 : "PresenterViewFactory object has already been disposed")),
550 0 : const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
551 : }
552 0 : }
553 :
554 : //===== CachablePresenterView =================================================
555 :
556 0 : CachablePresenterView::CachablePresenterView (void)
557 0 : : mbIsPresenterViewActive(true)
558 : {
559 0 : }
560 :
561 0 : void CachablePresenterView::ActivatePresenterView (void)
562 : {
563 0 : mbIsPresenterViewActive = true;
564 0 : }
565 :
566 0 : void CachablePresenterView::DeactivatePresenterView (void)
567 : {
568 0 : mbIsPresenterViewActive = false;
569 0 : }
570 :
571 0 : void CachablePresenterView::ReleaseView (void)
572 : {
573 0 : }
574 :
575 0 : } }
576 :
577 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|