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