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