xref: /trunk/main/sdext/source/presenter/PresenterViewFactory.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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