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)
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 {
117 Reference<presentation::XSlideShowController> xSlideShowController (
118 mpPresenterController->GetSlideShowController());
119 Reference<drawing::XDrawPage> xSlide;
120 if (xSlideShowController.is())
121 {
122 const sal_Int32 nCount (xSlideShowController->getSlideCount());
123 sal_Int32 nNextSlideIndex (-1);
124 if (xSlideShowController->getCurrentSlide() == rxSlide)
125 {
126 nNextSlideIndex = xSlideShowController->getNextSlideIndex();
127 }
128 else
129 {
130 for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
131 {
132 if (rxSlide == Reference<drawing::XDrawPage>(
133 xSlideShowController->getSlideByIndex(nIndex), UNO_QUERY))
134 {
135 nNextSlideIndex = nIndex + 1;
136 }
137 }
138 }
139 if (nNextSlideIndex >= 0)
140 {
141 if (nNextSlideIndex < nCount)
142 {
143 xSlide = Reference<drawing::XDrawPage>(
144 xSlideShowController->getSlideByIndex(nNextSlideIndex),
145 UNO_QUERY);
146 }
147 }
148 }
149 PresenterSlidePreview::setCurrentPage(xSlide);
150 }
151 };
152
153 } // end of anonymous namespace
154
155
156
157
158 //===== PresenterViewFactory ==============================================
159
PresenterViewFactory(const Reference<uno::XComponentContext> & rxContext,const Reference<frame::XController> & rxController,const::rtl::Reference<PresenterController> & rpPresenterController)160 PresenterViewFactory::PresenterViewFactory (
161 const Reference<uno::XComponentContext>& rxContext,
162 const Reference<frame::XController>& rxController,
163 const ::rtl::Reference<PresenterController>& rpPresenterController)
164 : PresenterViewFactoryInterfaceBase(m_aMutex),
165 mxComponentContext(rxContext),
166 mxConfigurationController(),
167 mxControllerWeak(rxController),
168 mpPresenterController(rpPresenterController),
169 mpResourceCache()
170 {
171 }
172
173
174
175
Create(const Reference<uno::XComponentContext> & rxContext,const Reference<frame::XController> & rxController,const::rtl::Reference<PresenterController> & rpPresenterController)176 Reference<drawing::framework::XResourceFactory> PresenterViewFactory::Create (
177 const Reference<uno::XComponentContext>& rxContext,
178 const Reference<frame::XController>& rxController,
179 const ::rtl::Reference<PresenterController>& rpPresenterController)
180 {
181 rtl::Reference<PresenterViewFactory> pFactory (
182 new PresenterViewFactory(rxContext,rxController,rpPresenterController));
183 pFactory->Register(rxController);
184 return Reference<drawing::framework::XResourceFactory>(
185 static_cast<XWeak*>(pFactory.get()), UNO_QUERY);
186 }
187
188
189
190
Register(const Reference<frame::XController> & rxController)191 void PresenterViewFactory::Register (const Reference<frame::XController>& rxController)
192 {
193 try
194 {
195 // Get the configuration controller.
196 Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW);
197 mxConfigurationController = xCM->getConfigurationController();
198 if ( ! mxConfigurationController.is())
199 {
200 throw RuntimeException();
201 }
202 else
203 {
204 mxConfigurationController->addResourceFactory(msCurrentSlidePreviewViewURL, this);
205 mxConfigurationController->addResourceFactory(msNextSlidePreviewViewURL, this);
206 mxConfigurationController->addResourceFactory(msNotesViewURL, this);
207 mxConfigurationController->addResourceFactory(msToolBarViewURL, this);
208 mxConfigurationController->addResourceFactory(msSlideSorterURL, this);
209 mxConfigurationController->addResourceFactory(msHelpViewURL, this);
210 }
211 }
212 catch (RuntimeException&)
213 {
214 OSL_ASSERT(false);
215 if (mxConfigurationController.is())
216 mxConfigurationController->removeResourceFactoryForReference(this);
217 mxConfigurationController = NULL;
218
219 throw;
220 }
221 }
222
223
224
225
~PresenterViewFactory(void)226 PresenterViewFactory::~PresenterViewFactory (void)
227 {
228 }
229
230
231
232
disposing(void)233 void SAL_CALL PresenterViewFactory::disposing (void)
234 {
235 if (mxConfigurationController.is())
236 mxConfigurationController->removeResourceFactoryForReference(this);
237 mxConfigurationController = NULL;
238
239 if (mpResourceCache.get() != NULL)
240 {
241 // Dispose all views in the cache.
242 ResourceContainer::const_iterator iView (mpResourceCache->begin());
243 ResourceContainer::const_iterator iEnd (mpResourceCache->end());
244 for ( ; iView!=iEnd; ++iView)
245 {
246 try
247 {
248 Reference<lang::XComponent> xComponent (iView->second.first, UNO_QUERY);
249 if (xComponent.is())
250 xComponent->dispose();
251 }
252 catch (lang::DisposedException&)
253 {
254 }
255 }
256 mpResourceCache.reset();
257 }
258 }
259
260
261
262
263 //----- XViewFactory ----------------------------------------------------------
264
createResource(const Reference<XResourceId> & rxViewId)265 Reference<XResource> SAL_CALL PresenterViewFactory::createResource (
266 const Reference<XResourceId>& rxViewId)
267 {
268 ThrowIfDisposed();
269
270 Reference<XResource> xView;
271
272 if (rxViewId.is())
273 {
274 Reference<XPane> xAnchorPane (
275 mxConfigurationController->getResource(rxViewId->getAnchor()),
276 UNO_QUERY_THROW);
277 xView = GetViewFromCache(rxViewId, xAnchorPane);
278 if (xView == NULL)
279 xView = CreateView(rxViewId, xAnchorPane);
280
281 // Activate the view.
282 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
283 mpPresenterController->GetPaneContainer()->FindPaneId(rxViewId->getAnchor()));
284 if (pDescriptor.get() != NULL)
285 pDescriptor->SetActivationState(true);
286 }
287
288 return xView;
289 }
290
291
292
293
releaseResource(const Reference<XResource> & rxView)294 void SAL_CALL PresenterViewFactory::releaseResource (const Reference<XResource>& rxView)
295 {
296 ThrowIfDisposed();
297
298 if ( ! rxView.is())
299 return;
300
301 // Deactivate the view.
302 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
303 mpPresenterController->GetPaneContainer()->FindPaneId(
304 rxView->getResourceId()->getAnchor()));
305 if (pDescriptor.get() != NULL)
306 pDescriptor->SetActivationState(false);
307
308 // Dispose only views that we can not put into the cache.
309 CachablePresenterView* pView = dynamic_cast<CachablePresenterView*>(rxView.get());
310 if (pView == NULL || mpResourceCache.get()==NULL)
311 {
312 try
313 {
314 if (pView != NULL)
315 pView->ReleaseView();
316 Reference<lang::XComponent> xComponent (rxView, UNO_QUERY);
317 if (xComponent.is())
318 xComponent->dispose();
319 }
320 catch (lang::DisposedException&)
321 {
322 // Do not let disposed exceptions get out. It might be interpreted
323 // as coming from the factory, which would then be removed from the
324 // drawing framework.
325 }
326 }
327 else
328 {
329 // Put cachable views in the cache.
330 Reference<XResourceId> xViewId (rxView->getResourceId());
331 if (xViewId.is())
332 {
333 Reference<XPane> xAnchorPane (
334 mxConfigurationController->getResource(xViewId->getAnchor()),
335 UNO_QUERY_THROW);
336 (*mpResourceCache)[xViewId->getResourceURL()]
337 = ViewResourceDescriptor(Reference<XView>(rxView, UNO_QUERY), xAnchorPane);
338 pView->DeactivatePresenterView();
339 }
340 }
341 }
342
343
344
345
346 //-----------------------------------------------------------------------------
347
GetViewFromCache(const Reference<XResourceId> & rxViewId,const Reference<XPane> & rxAnchorPane) const348 Reference<XResource> PresenterViewFactory::GetViewFromCache(
349 const Reference<XResourceId>& rxViewId,
350 const Reference<XPane>& rxAnchorPane) const
351 {
352 if (mpResourceCache.get() == NULL)
353 return NULL;
354
355 try
356 {
357 const OUString sResourceURL (rxViewId->getResourceURL());
358
359 // Can we use a view from the cache?
360 ResourceContainer::const_iterator iView (mpResourceCache->find(sResourceURL));
361 if (iView != mpResourceCache->end())
362 {
363 // The view is in the container but it can only be used if
364 // the anchor pane is the same now as it was at creation of
365 // the view.
366 if (iView->second.second == rxAnchorPane)
367 {
368 CachablePresenterView* pView
369 = dynamic_cast<CachablePresenterView*>(iView->second.first.get());
370 if (pView != NULL)
371 pView->ActivatePresenterView();
372 return Reference<XResource>(iView->second.first, UNO_QUERY);
373 }
374
375 // Right view, wrong pane. Create a new view.
376 }
377 }
378 catch (RuntimeException&)
379 {
380 }
381 return NULL;
382 }
383
384
385
386
CreateView(const Reference<XResourceId> & rxViewId,const Reference<XPane> & rxAnchorPane)387 Reference<XResource> PresenterViewFactory::CreateView(
388 const Reference<XResourceId>& rxViewId,
389 const Reference<XPane>& rxAnchorPane)
390 {
391 Reference<XView> xView;
392
393 try
394 {
395 const OUString sResourceURL (rxViewId->getResourceURL());
396
397 if (sResourceURL.equals(msCurrentSlidePreviewViewURL))
398 {
399 xView = CreateSlideShowView(rxViewId);
400 }
401 else if (sResourceURL.equals(msNotesViewURL))
402 {
403 xView = CreateNotesView(rxViewId, rxAnchorPane);
404 }
405 else if (sResourceURL.equals(msNextSlidePreviewViewURL))
406 {
407 xView = CreateSlidePreviewView(rxViewId, rxAnchorPane);
408 }
409 else if (sResourceURL.equals(msToolBarViewURL))
410 {
411 xView = CreateToolBarView(rxViewId);
412 }
413 else if (sResourceURL.equals(msSlideSorterURL))
414 {
415 xView = CreateSlideSorterView(rxViewId);
416 }
417 else if (sResourceURL.equals(msHelpViewURL))
418 {
419 xView = CreateHelpView(rxViewId);
420 }
421
422 // Activate it.
423 CachablePresenterView* pView = dynamic_cast<CachablePresenterView*>(xView.get());
424 if (pView != NULL)
425 pView->ActivatePresenterView();
426 }
427 catch (RuntimeException&)
428 {
429 xView = NULL;
430 }
431
432 return Reference<XResource>(xView, UNO_QUERY);
433 }
434
435
436
437
CreateSlideShowView(const Reference<XResourceId> & rxViewId) const438 Reference<XView> PresenterViewFactory::CreateSlideShowView(
439 const Reference<XResourceId>& rxViewId) const
440 {
441 Reference<XView> xView;
442
443 if ( ! mxConfigurationController.is())
444 return xView;
445 if ( ! mxComponentContext.is())
446 return xView;
447
448 try
449 {
450 rtl::Reference<PresenterSlideShowView> pShowView (
451 new PresenterSlideShowView(
452 mxComponentContext,
453 rxViewId,
454 Reference<frame::XController>(mxControllerWeak),
455 mpPresenterController));
456 pShowView->LateInit();
457 xView = Reference<XView>(pShowView.get());
458 }
459 catch (RuntimeException&)
460 {
461 xView = NULL;
462 }
463
464 return xView;
465 }
466
467
468
469
CreateSlidePreviewView(const Reference<XResourceId> & rxViewId,const Reference<XPane> & rxAnchorPane) const470 Reference<XView> PresenterViewFactory::CreateSlidePreviewView(
471 const Reference<XResourceId>& rxViewId,
472 const Reference<XPane>& rxAnchorPane) const
473 {
474 Reference<XView> xView;
475
476 if ( ! mxConfigurationController.is())
477 return xView;
478 if ( ! mxComponentContext.is())
479 return xView;
480
481 try
482 {
483 xView = Reference<XView>(
484 static_cast<XWeak*>(new NextSlidePreview(
485 mxComponentContext,
486 rxViewId,
487 rxAnchorPane,
488 mpPresenterController)),
489 UNO_QUERY_THROW);
490 }
491 catch (RuntimeException&)
492 {
493 xView = NULL;
494 }
495
496 return xView;
497 }
498
499
500
501
CreateToolBarView(const Reference<XResourceId> & rxViewId) const502 Reference<XView> PresenterViewFactory::CreateToolBarView(
503 const Reference<XResourceId>& rxViewId) const
504 {
505 return new PresenterToolBarView(
506 mxComponentContext,
507 rxViewId,
508 Reference<frame::XController>(mxControllerWeak),
509 mpPresenterController);
510 }
511
512
513
514
CreateNotesView(const Reference<XResourceId> & rxViewId,const Reference<XPane> & rxAnchorPane) const515 Reference<XView> PresenterViewFactory::CreateNotesView(
516 const Reference<XResourceId>& rxViewId,
517 const Reference<XPane>& rxAnchorPane) const
518 {
519 (void)rxAnchorPane;
520 Reference<XView> xView;
521
522 if ( ! mxConfigurationController.is())
523 return xView;
524 if ( ! mxComponentContext.is())
525 return xView;
526
527 try
528 {
529 xView = Reference<XView>(static_cast<XWeak*>(
530 new PresenterNotesView(
531 mxComponentContext,
532 rxViewId,
533 Reference<frame::XController>(mxControllerWeak),
534 mpPresenterController)),
535 UNO_QUERY_THROW);
536 }
537 catch (RuntimeException&)
538 {
539 xView = NULL;
540 }
541
542 return xView;
543 }
544
545
546
547
CreateSlideSorterView(const Reference<XResourceId> & rxViewId) const548 Reference<XView> PresenterViewFactory::CreateSlideSorterView(
549 const Reference<XResourceId>& rxViewId) const
550 {
551 Reference<XView> xView;
552
553 if ( ! mxConfigurationController.is())
554 return xView;
555 if ( ! mxComponentContext.is())
556 return xView;
557
558 try
559 {
560 rtl::Reference<PresenterSlideSorter> pView (
561 new PresenterSlideSorter(
562 mxComponentContext,
563 rxViewId,
564 Reference<frame::XController>(mxControllerWeak),
565 mpPresenterController));
566 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
567 mpPresenterController->GetPaneContainer()->FindPaneId(rxViewId->getAnchor()));
568 if (pDescriptor.get() != NULL)
569 pDescriptor->maActivator = ::boost::bind(
570 &PresenterSlideSorter::SetActiveState, pView.get(), _1);
571 xView = pView.get();
572 }
573 catch (RuntimeException&)
574 {
575 xView = NULL;
576 }
577
578 return xView;
579 }
580
581
582
583
CreateHelpView(const Reference<XResourceId> & rxViewId) const584 Reference<XView> PresenterViewFactory::CreateHelpView(
585 const Reference<XResourceId>& rxViewId) const
586 {
587 return Reference<XView>(new PresenterHelpView(
588 mxComponentContext,
589 rxViewId,
590 Reference<frame::XController>(mxControllerWeak),
591 mpPresenterController));
592 }
593
594
595
596
597
ThrowIfDisposed(void) const598 void PresenterViewFactory::ThrowIfDisposed (void) const
599 {
600 if (rBHelper.bDisposed || rBHelper.bInDispose)
601 {
602 throw lang::DisposedException (
603 OUString(RTL_CONSTASCII_USTRINGPARAM(
604 "PresenterViewFactory object has already been disposed")),
605 const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
606 }
607 }
608
609
610
611
612 //===== CachablePresenterView =================================================
613
CachablePresenterView(void)614 CachablePresenterView::CachablePresenterView (void)
615 : mbIsPresenterViewActive(true)
616 {
617 }
618
619
620
621
ActivatePresenterView(void)622 void CachablePresenterView::ActivatePresenterView (void)
623 {
624 mbIsPresenterViewActive = true;
625 }
626
627
628
629
DeactivatePresenterView(void)630 void CachablePresenterView::DeactivatePresenterView (void)
631 {
632 mbIsPresenterViewActive = false;
633 }
634
635
636
637
ReleaseView(void)638 void CachablePresenterView::ReleaseView (void)
639 {
640 }
641
642
643
644 } }
645