1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sdext.hxx"
26
27 #include "PresenterViewFactory.hxx"
28 #include "PresenterPaneContainer.hxx"
29 #include "PresenterHelper.hxx"
30 #include "PresenterHelpView.hxx"
31 #include "PresenterNotesView.hxx"
32 #include "PresenterSlideShowView.hxx"
33 #include "PresenterSlidePreview.hxx"
34 #include "PresenterSlideSorter.hxx"
35 #include "PresenterToolBar.hxx"
36 #include <com/sun/star/beans/XPropertySet.hpp>
37 #include <com/sun/star/drawing/framework/ResourceId.hpp>
38 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
39 #include <com/sun/star/drawing/framework/XConfigurationController.hpp>
40 #include <com/sun/star/drawing/XDrawPages.hpp>
41 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
42 #include <com/sun/star/drawing/XSlideSorterBase.hpp>
43 #include <com/sun/star/presentation/XSlideShow.hpp>
44 #include <com/sun/star/presentation/XSlideShowView.hpp>
45 #include <cppuhelper/compbase1.hxx>
46 #include <boost/bind.hpp>
47
48 using namespace ::com::sun::star;
49 using namespace ::com::sun::star::uno;
50 using namespace ::com::sun::star::drawing::framework;
51 using ::rtl::OUString;
52
53 #define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
54
55 namespace sdext { namespace presenter {
56
57 const ::rtl::OUString PresenterViewFactory::msCurrentSlidePreviewViewURL(
58 A2S("private:resource/view/Presenter/CurrentSlidePreview"));
59 const ::rtl::OUString PresenterViewFactory::msNextSlidePreviewViewURL(
60 A2S("private:resource/view/Presenter/NextSlidePreview"));
61 const ::rtl::OUString PresenterViewFactory::msNotesViewURL(
62 A2S("private:resource/view/Presenter/Notes"));
63 const ::rtl::OUString PresenterViewFactory::msToolBarViewURL(
64 A2S("private:resource/view/Presenter/ToolBar"));
65 const ::rtl::OUString PresenterViewFactory::msSlideSorterURL(
66 A2S("private:resource/view/Presenter/SlideSorter"));
67 const ::rtl::OUString PresenterViewFactory::msHelpViewURL(
68 A2S("private:resource/view/Presenter/Help"));
69
70
71
72 //===== SimpleView ============================================================
73
74 namespace {
75
76 typedef ::cppu::WeakComponentImplHelper1 <XView> SimpleViewInterfaceBase;
77
78 class SimpleView
79 : private ::cppu::BaseMutex,
80 public SimpleViewInterfaceBase
81 {
82 public:
SimpleView(const Reference<XResourceId> & rxViewId)83 SimpleView (const Reference<XResourceId>& rxViewId)
84 : SimpleViewInterfaceBase(m_aMutex),mxResourceId(rxViewId) {};
~SimpleView(void)85 virtual ~SimpleView (void) {};
86
87 // XView
88
getResourceId(void)89 virtual Reference<XResourceId> SAL_CALL getResourceId (void) throw (RuntimeException)
90 { return mxResourceId; };
91
92 private:
93 Reference<XResourceId> mxResourceId;
94 };
95
96
97
98 /** By default the PresenterSlidePreview shows the preview of the current
99 slide. This adapter class makes it display the preview of the next
100 slide.
101 */
102 class NextSlidePreview : public PresenterSlidePreview
103 {
104 public:
NextSlidePreview(const css::uno::Reference<css::uno::XComponentContext> & rxContext,const css::uno::Reference<css::drawing::framework::XResourceId> & rxViewId,const css::uno::Reference<css::drawing::framework::XPane> & rxAnchorPane,const::rtl::Reference<PresenterController> & rpPresenterController)105 NextSlidePreview (
106 const css::uno::Reference<css::uno::XComponentContext>& rxContext,
107 const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId,
108 const css::uno::Reference<css::drawing::framework::XPane>& rxAnchorPane,
109 const ::rtl::Reference<PresenterController>& rpPresenterController)
110 : PresenterSlidePreview(rxContext, rxViewId, rxAnchorPane, rpPresenterController)
111 {
112 }
~NextSlidePreview(void)113 virtual ~NextSlidePreview (void) {}
setCurrentPage(const css::uno::Reference<css::drawing::XDrawPage> & rxSlide)114 virtual void SAL_CALL setCurrentPage (
115 const css::uno::Reference<css::drawing::XDrawPage>& rxSlide)
116 throw (css::uno::RuntimeException)
117 {
118 Reference<presentation::XSlideShowController> xSlideShowController (
119 mpPresenterController->GetSlideShowController());
120 Reference<drawing::XDrawPage> xSlide;
121 if (xSlideShowController.is())
122 {
123 const sal_Int32 nCount (xSlideShowController->getSlideCount());
124 sal_Int32 nNextSlideIndex (-1);
125 if (xSlideShowController->getCurrentSlide() == rxSlide)
126 {
127 nNextSlideIndex = xSlideShowController->getNextSlideIndex();
128 }
129 else
130 {
131 for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
132 {
133 if (rxSlide == Reference<drawing::XDrawPage>(
134 xSlideShowController->getSlideByIndex(nIndex), UNO_QUERY))
135 {
136 nNextSlideIndex = nIndex + 1;
137 }
138 }
139 }
140 if (nNextSlideIndex >= 0)
141 {
142 if (nNextSlideIndex < nCount)
143 {
144 xSlide = Reference<drawing::XDrawPage>(
145 xSlideShowController->getSlideByIndex(nNextSlideIndex),
146 UNO_QUERY);
147 }
148 }
149 }
150 PresenterSlidePreview::setCurrentPage(xSlide);
151 }
152 };
153
154 } // end of anonymous namespace
155
156
157
158
159 //===== PresenterViewFactory ==============================================
160
PresenterViewFactory(const Reference<uno::XComponentContext> & rxContext,const Reference<frame::XController> & rxController,const::rtl::Reference<PresenterController> & rpPresenterController)161 PresenterViewFactory::PresenterViewFactory (
162 const Reference<uno::XComponentContext>& rxContext,
163 const Reference<frame::XController>& rxController,
164 const ::rtl::Reference<PresenterController>& rpPresenterController)
165 : PresenterViewFactoryInterfaceBase(m_aMutex),
166 mxComponentContext(rxContext),
167 mxConfigurationController(),
168 mxControllerWeak(rxController),
169 mpPresenterController(rpPresenterController),
170 mpResourceCache()
171 {
172 }
173
174
175
176
Create(const Reference<uno::XComponentContext> & rxContext,const Reference<frame::XController> & rxController,const::rtl::Reference<PresenterController> & rpPresenterController)177 Reference<drawing::framework::XResourceFactory> PresenterViewFactory::Create (
178 const Reference<uno::XComponentContext>& rxContext,
179 const Reference<frame::XController>& rxController,
180 const ::rtl::Reference<PresenterController>& rpPresenterController)
181 {
182 rtl::Reference<PresenterViewFactory> pFactory (
183 new PresenterViewFactory(rxContext,rxController,rpPresenterController));
184 pFactory->Register(rxController);
185 return Reference<drawing::framework::XResourceFactory>(
186 static_cast<XWeak*>(pFactory.get()), UNO_QUERY);
187 }
188
189
190
191
Register(const Reference<frame::XController> & rxController)192 void PresenterViewFactory::Register (const Reference<frame::XController>& rxController)
193 {
194 try
195 {
196 // Get the configuration controller.
197 Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW);
198 mxConfigurationController = xCM->getConfigurationController();
199 if ( ! mxConfigurationController.is())
200 {
201 throw RuntimeException();
202 }
203 else
204 {
205 mxConfigurationController->addResourceFactory(msCurrentSlidePreviewViewURL, this);
206 mxConfigurationController->addResourceFactory(msNextSlidePreviewViewURL, this);
207 mxConfigurationController->addResourceFactory(msNotesViewURL, this);
208 mxConfigurationController->addResourceFactory(msToolBarViewURL, this);
209 mxConfigurationController->addResourceFactory(msSlideSorterURL, this);
210 mxConfigurationController->addResourceFactory(msHelpViewURL, this);
211 }
212 }
213 catch (RuntimeException&)
214 {
215 OSL_ASSERT(false);
216 if (mxConfigurationController.is())
217 mxConfigurationController->removeResourceFactoryForReference(this);
218 mxConfigurationController = NULL;
219
220 throw;
221 }
222 }
223
224
225
226
~PresenterViewFactory(void)227 PresenterViewFactory::~PresenterViewFactory (void)
228 {
229 }
230
231
232
233
disposing(void)234 void SAL_CALL PresenterViewFactory::disposing (void)
235 throw (RuntimeException)
236 {
237 if (mxConfigurationController.is())
238 mxConfigurationController->removeResourceFactoryForReference(this);
239 mxConfigurationController = NULL;
240
241 if (mpResourceCache.get() != NULL)
242 {
243 // Dispose all views in the cache.
244 ResourceContainer::const_iterator iView (mpResourceCache->begin());
245 ResourceContainer::const_iterator iEnd (mpResourceCache->end());
246 for ( ; iView!=iEnd; ++iView)
247 {
248 try
249 {
250 Reference<lang::XComponent> xComponent (iView->second.first, UNO_QUERY);
251 if (xComponent.is())
252 xComponent->dispose();
253 }
254 catch (lang::DisposedException&)
255 {
256 }
257 }
258 mpResourceCache.reset();
259 }
260 }
261
262
263
264
265 //----- XViewFactory ----------------------------------------------------------
266
createResource(const Reference<XResourceId> & rxViewId)267 Reference<XResource> SAL_CALL PresenterViewFactory::createResource (
268 const Reference<XResourceId>& rxViewId)
269 throw (RuntimeException)
270 {
271 ThrowIfDisposed();
272
273 Reference<XResource> xView;
274
275 if (rxViewId.is())
276 {
277 Reference<XPane> xAnchorPane (
278 mxConfigurationController->getResource(rxViewId->getAnchor()),
279 UNO_QUERY_THROW);
280 xView = GetViewFromCache(rxViewId, xAnchorPane);
281 if (xView == NULL)
282 xView = CreateView(rxViewId, xAnchorPane);
283
284 // Activate the view.
285 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
286 mpPresenterController->GetPaneContainer()->FindPaneId(rxViewId->getAnchor()));
287 if (pDescriptor.get() != NULL)
288 pDescriptor->SetActivationState(true);
289 }
290
291 return xView;
292 }
293
294
295
296
releaseResource(const Reference<XResource> & rxView)297 void SAL_CALL PresenterViewFactory::releaseResource (const Reference<XResource>& rxView)
298 throw (RuntimeException)
299 {
300 ThrowIfDisposed();
301
302 if ( ! rxView.is())
303 return;
304
305 // Deactivate the view.
306 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
307 mpPresenterController->GetPaneContainer()->FindPaneId(
308 rxView->getResourceId()->getAnchor()));
309 if (pDescriptor.get() != NULL)
310 pDescriptor->SetActivationState(false);
311
312 // Dispose only views that we can not put into the cache.
313 CachablePresenterView* pView = dynamic_cast<CachablePresenterView*>(rxView.get());
314 if (pView == NULL || mpResourceCache.get()==NULL)
315 {
316 try
317 {
318 if (pView != NULL)
319 pView->ReleaseView();
320 Reference<lang::XComponent> xComponent (rxView, UNO_QUERY);
321 if (xComponent.is())
322 xComponent->dispose();
323 }
324 catch (lang::DisposedException&)
325 {
326 // Do not let disposed exceptions get out. It might be interpreted
327 // as coming from the factory, which would then be removed from the
328 // drawing framework.
329 }
330 }
331 else
332 {
333 // Put cachable views in the cache.
334 Reference<XResourceId> xViewId (rxView->getResourceId());
335 if (xViewId.is())
336 {
337 Reference<XPane> xAnchorPane (
338 mxConfigurationController->getResource(xViewId->getAnchor()),
339 UNO_QUERY_THROW);
340 (*mpResourceCache)[xViewId->getResourceURL()]
341 = ViewResourceDescriptor(Reference<XView>(rxView, UNO_QUERY), xAnchorPane);
342 pView->DeactivatePresenterView();
343 }
344 }
345 }
346
347
348
349
350 //-----------------------------------------------------------------------------
351
GetViewFromCache(const Reference<XResourceId> & rxViewId,const Reference<XPane> & rxAnchorPane) const352 Reference<XResource> PresenterViewFactory::GetViewFromCache(
353 const Reference<XResourceId>& rxViewId,
354 const Reference<XPane>& rxAnchorPane) const
355 {
356 if (mpResourceCache.get() == NULL)
357 return NULL;
358
359 try
360 {
361 const OUString sResourceURL (rxViewId->getResourceURL());
362
363 // Can we use a view from the cache?
364 ResourceContainer::const_iterator iView (mpResourceCache->find(sResourceURL));
365 if (iView != mpResourceCache->end())
366 {
367 // The view is in the container but it can only be used if
368 // the anchor pane is the same now as it was at creation of
369 // the view.
370 if (iView->second.second == rxAnchorPane)
371 {
372 CachablePresenterView* pView
373 = dynamic_cast<CachablePresenterView*>(iView->second.first.get());
374 if (pView != NULL)
375 pView->ActivatePresenterView();
376 return Reference<XResource>(iView->second.first, UNO_QUERY);
377 }
378
379 // Right view, wrong pane. Create a new view.
380 }
381 }
382 catch (RuntimeException&)
383 {
384 }
385 return NULL;
386 }
387
388
389
390
CreateView(const Reference<XResourceId> & rxViewId,const Reference<XPane> & rxAnchorPane)391 Reference<XResource> PresenterViewFactory::CreateView(
392 const Reference<XResourceId>& rxViewId,
393 const Reference<XPane>& rxAnchorPane)
394 {
395 Reference<XView> xView;
396
397 try
398 {
399 const OUString sResourceURL (rxViewId->getResourceURL());
400
401 if (sResourceURL.equals(msCurrentSlidePreviewViewURL))
402 {
403 xView = CreateSlideShowView(rxViewId);
404 }
405 else if (sResourceURL.equals(msNotesViewURL))
406 {
407 xView = CreateNotesView(rxViewId, rxAnchorPane);
408 }
409 else if (sResourceURL.equals(msNextSlidePreviewViewURL))
410 {
411 xView = CreateSlidePreviewView(rxViewId, rxAnchorPane);
412 }
413 else if (sResourceURL.equals(msToolBarViewURL))
414 {
415 xView = CreateToolBarView(rxViewId);
416 }
417 else if (sResourceURL.equals(msSlideSorterURL))
418 {
419 xView = CreateSlideSorterView(rxViewId);
420 }
421 else if (sResourceURL.equals(msHelpViewURL))
422 {
423 xView = CreateHelpView(rxViewId);
424 }
425
426 // Activate it.
427 CachablePresenterView* pView = dynamic_cast<CachablePresenterView*>(xView.get());
428 if (pView != NULL)
429 pView->ActivatePresenterView();
430 }
431 catch (RuntimeException&)
432 {
433 xView = NULL;
434 }
435
436 return Reference<XResource>(xView, UNO_QUERY);
437 }
438
439
440
441
CreateSlideShowView(const Reference<XResourceId> & rxViewId) const442 Reference<XView> PresenterViewFactory::CreateSlideShowView(
443 const Reference<XResourceId>& rxViewId) const
444 {
445 Reference<XView> xView;
446
447 if ( ! mxConfigurationController.is())
448 return xView;
449 if ( ! mxComponentContext.is())
450 return xView;
451
452 try
453 {
454 rtl::Reference<PresenterSlideShowView> pShowView (
455 new PresenterSlideShowView(
456 mxComponentContext,
457 rxViewId,
458 Reference<frame::XController>(mxControllerWeak),
459 mpPresenterController));
460 pShowView->LateInit();
461 xView = Reference<XView>(pShowView.get());
462 }
463 catch (RuntimeException&)
464 {
465 xView = NULL;
466 }
467
468 return xView;
469 }
470
471
472
473
CreateSlidePreviewView(const Reference<XResourceId> & rxViewId,const Reference<XPane> & rxAnchorPane) const474 Reference<XView> PresenterViewFactory::CreateSlidePreviewView(
475 const Reference<XResourceId>& rxViewId,
476 const Reference<XPane>& rxAnchorPane) const
477 {
478 Reference<XView> xView;
479
480 if ( ! mxConfigurationController.is())
481 return xView;
482 if ( ! mxComponentContext.is())
483 return xView;
484
485 try
486 {
487 xView = Reference<XView>(
488 static_cast<XWeak*>(new NextSlidePreview(
489 mxComponentContext,
490 rxViewId,
491 rxAnchorPane,
492 mpPresenterController)),
493 UNO_QUERY_THROW);
494 }
495 catch (RuntimeException&)
496 {
497 xView = NULL;
498 }
499
500 return xView;
501 }
502
503
504
505
CreateToolBarView(const Reference<XResourceId> & rxViewId) const506 Reference<XView> PresenterViewFactory::CreateToolBarView(
507 const Reference<XResourceId>& rxViewId) const
508 {
509 return new PresenterToolBarView(
510 mxComponentContext,
511 rxViewId,
512 Reference<frame::XController>(mxControllerWeak),
513 mpPresenterController);
514 }
515
516
517
518
CreateNotesView(const Reference<XResourceId> & rxViewId,const Reference<XPane> & rxAnchorPane) const519 Reference<XView> PresenterViewFactory::CreateNotesView(
520 const Reference<XResourceId>& rxViewId,
521 const Reference<XPane>& rxAnchorPane) const
522 {
523 (void)rxAnchorPane;
524 Reference<XView> xView;
525
526 if ( ! mxConfigurationController.is())
527 return xView;
528 if ( ! mxComponentContext.is())
529 return xView;
530
531 try
532 {
533 xView = Reference<XView>(static_cast<XWeak*>(
534 new PresenterNotesView(
535 mxComponentContext,
536 rxViewId,
537 Reference<frame::XController>(mxControllerWeak),
538 mpPresenterController)),
539 UNO_QUERY_THROW);
540 }
541 catch (RuntimeException&)
542 {
543 xView = NULL;
544 }
545
546 return xView;
547 }
548
549
550
551
CreateSlideSorterView(const Reference<XResourceId> & rxViewId) const552 Reference<XView> PresenterViewFactory::CreateSlideSorterView(
553 const Reference<XResourceId>& rxViewId) const
554 {
555 Reference<XView> xView;
556
557 if ( ! mxConfigurationController.is())
558 return xView;
559 if ( ! mxComponentContext.is())
560 return xView;
561
562 try
563 {
564 rtl::Reference<PresenterSlideSorter> pView (
565 new PresenterSlideSorter(
566 mxComponentContext,
567 rxViewId,
568 Reference<frame::XController>(mxControllerWeak),
569 mpPresenterController));
570 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
571 mpPresenterController->GetPaneContainer()->FindPaneId(rxViewId->getAnchor()));
572 if (pDescriptor.get() != NULL)
573 pDescriptor->maActivator = ::boost::bind(
574 &PresenterSlideSorter::SetActiveState, pView.get(), _1);
575 xView = pView.get();
576 }
577 catch (RuntimeException&)
578 {
579 xView = NULL;
580 }
581
582 return xView;
583 }
584
585
586
587
CreateHelpView(const Reference<XResourceId> & rxViewId) const588 Reference<XView> PresenterViewFactory::CreateHelpView(
589 const Reference<XResourceId>& rxViewId) const
590 {
591 return Reference<XView>(new PresenterHelpView(
592 mxComponentContext,
593 rxViewId,
594 Reference<frame::XController>(mxControllerWeak),
595 mpPresenterController));
596 }
597
598
599
600
601
ThrowIfDisposed(void) const602 void PresenterViewFactory::ThrowIfDisposed (void) const
603 throw (::com::sun::star::lang::DisposedException)
604 {
605 if (rBHelper.bDisposed || rBHelper.bInDispose)
606 {
607 throw lang::DisposedException (
608 OUString(RTL_CONSTASCII_USTRINGPARAM(
609 "PresenterViewFactory object has already been disposed")),
610 const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
611 }
612 }
613
614
615
616
617 //===== CachablePresenterView =================================================
618
CachablePresenterView(void)619 CachablePresenterView::CachablePresenterView (void)
620 : mbIsPresenterViewActive(true)
621 {
622 }
623
624
625
626
ActivatePresenterView(void)627 void CachablePresenterView::ActivatePresenterView (void)
628 {
629 mbIsPresenterViewActive = true;
630 }
631
632
633
634
DeactivatePresenterView(void)635 void CachablePresenterView::DeactivatePresenterView (void)
636 {
637 mbIsPresenterViewActive = false;
638 }
639
640
641
642
ReleaseView(void)643 void CachablePresenterView::ReleaseView (void)
644 {
645 }
646
647
648
649 } }
650