xref: /trunk/main/sdext/source/presenter/PresenterScreen.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 "PresenterScreen.hxx"
28 #include "PresenterConfigurationAccess.hxx"
29 #include "PresenterController.hxx"
30 #include "PresenterFrameworkObserver.hxx"
31 #include "PresenterHelper.hxx"
32 #include "PresenterPaneContainer.hxx"
33 #include "PresenterPaneFactory.hxx"
34 #include "PresenterViewFactory.hxx"
35 #include "PresenterWindowManager.hxx"
36 #include <com/sun/star/frame/XController.hpp>
37 #include <com/sun/star/lang/XServiceInfo.hpp>
38 #include <com/sun/star/drawing/framework/Configuration.hpp>
39 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
40 #include <com/sun/star/drawing/framework/ResourceId.hpp>
41 #include <com/sun/star/drawing/framework/ResourceActivationMode.hpp>
42 #include <com/sun/star/presentation/XSlideShow.hpp>
43 #include <com/sun/star/presentation/XPresentation2.hpp>
44 #include <com/sun/star/presentation/XPresentationSupplier.hpp>
45 #include <com/sun/star/document/XEventBroadcaster.hpp>
46 #include <boost/bind.hpp>
47 #include <tools/debug.hxx>
48 
49 #include <com/sun/star/view/XSelectionSupplier.hpp>
50 
51 using namespace ::com::sun::star;
52 using namespace ::com::sun::star::uno;
53 using namespace ::com::sun::star::lang;
54 using namespace ::com::sun::star::presentation;
55 using namespace ::com::sun::star::drawing::framework;
56 using ::rtl::OUString;
57 
58 #define A2S(s) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s)))
59 
60 namespace sdext { namespace presenter {
61 
62 namespace {
63 
lcl_IsPresenterEnabled(const css::uno::Reference<css::uno::XComponentContext> & rxContext)64     static sal_Bool lcl_IsPresenterEnabled(
65         const css::uno::Reference< css::uno::XComponentContext > &rxContext )
66     {
67         sal_Bool bEnabled( sal_True );
68         PresenterConfigurationAccess aConfig(
69             rxContext,
70             A2S( "/org.openoffice.Office.Impress" ),
71             PresenterConfigurationAccess::READ_ONLY );
72         if ( aConfig.IsValid() )
73         {
74             sal_Bool bVal( sal_False );
75             if ( ( aConfig.GetConfigurationNode(
76                 A2S( "Misc/Start/PresenterScreen" )) >>= bVal ) )
77                 bEnabled = bVal;
78         }
79         return bEnabled;
80     }
81 
82     typedef ::cppu::WeakComponentImplHelper1 <
83         css::document::XEventListener
84         > PresenterScreenListenerInterfaceBase;
85 
86     /** One instance of a PresenterScreenListener is registered per Impress
87         document and waits for the full screen slide show to start and to
88         end.
89     */
90     class PresenterScreenListener
91         : private ::boost::noncopyable,
92           private ::cppu::BaseMutex,
93           public PresenterScreenListenerInterfaceBase
94     {
95     public:
96         PresenterScreenListener (
97             const css::uno::Reference<css::uno::XComponentContext>& rxContext,
98             const css::uno::Reference<css::frame::XModel2>& rxModel);
99         virtual ~PresenterScreenListener (void);
100 
101         void Initialize (void);
102         virtual void SAL_CALL disposing (void);
103 
104         // document::XEventListener
105 
106         virtual void SAL_CALL notifyEvent( const css::document::EventObject& Event );
107 
108         // XEventListener
109 
110         virtual void SAL_CALL disposing ( const css::lang::EventObject& rEvent);
111 
112     private:
113         css::uno::Reference<css::frame::XModel2 > mxModel;
114         css::uno::Reference<css::uno::XComponentContext> mxComponentContext;
115         rtl::Reference<PresenterScreen> mpPresenterScreen;
116 
117         void ThrowIfDisposed (void) const;
118     };
119 }
120 
121 
122 //----- Service ---------------------------------------------------------------
123 
getImplementationName_static(void)124 OUString PresenterScreenJob::getImplementationName_static (void)
125 {
126     return A2S("com.sun.star.comp.presentation.PresenterScreenJob");
127 }
128 
129 
130 
131 
getSupportedServiceNames_static(void)132 Sequence<OUString> PresenterScreenJob::getSupportedServiceNames_static (void)
133 {
134     static const ::rtl::OUString sServiceName(
135         A2S("com.sun.star.presentation.PresenterScreenJob"));
136     return Sequence<rtl::OUString>(&sServiceName, 1);
137 }
138 
139 
140 
141 
Create(const Reference<uno::XComponentContext> & rxContext)142 Reference<XInterface> PresenterScreenJob::Create (const Reference<uno::XComponentContext>& rxContext)
143 {
144     return Reference<XInterface>(static_cast<XWeak*>(new PresenterScreenJob(rxContext)));
145 }
146 
147 
148 
149 
150 //===== PresenterScreenJob ====================================================
151 
PresenterScreenJob(const Reference<XComponentContext> & rxContext)152 PresenterScreenJob::PresenterScreenJob (const Reference<XComponentContext>& rxContext)
153     : PresenterScreenJobInterfaceBase(m_aMutex),
154       mxComponentContext(rxContext)
155 {
156 }
157 
158 
159 
160 
~PresenterScreenJob(void)161 PresenterScreenJob::~PresenterScreenJob (void)
162 {
163 }
164 
165 
166 
167 
disposing(void)168 void SAL_CALL PresenterScreenJob::disposing (void)
169 {
170     mxComponentContext = NULL;
171 }
172 
173 
174 
175 
176 //----- XJob -----------------------------------------------------------
177 
execute(const Sequence<beans::NamedValue> & Arguments)178 Any SAL_CALL PresenterScreenJob::execute(
179     const Sequence< beans::NamedValue >& Arguments )
180 {
181     Sequence< beans::NamedValue > lEnv;
182 
183     sal_Int32               i = 0;
184     sal_Int32               c = Arguments.getLength();
185     const beans::NamedValue* p = Arguments.getConstArray();
186     for (i=0; i<c; ++i)
187     {
188         if (p[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Environment")))
189         {
190             p[i].Value >>= lEnv;
191             break;
192         }
193     }
194 
195     Reference<frame::XModel2> xModel;
196     c = lEnv.getLength();
197     p = lEnv.getConstArray();
198     for (i=0; i<c; ++i)
199     {
200         if (p[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Model")))
201         {
202             p[i].Value >>= xModel;
203             break;
204         }
205     }
206 
207     Reference< XServiceInfo > xInfo( xModel, UNO_QUERY );
208     if( !xInfo.is() || !xInfo->supportsService(
209         A2S( "com.sun.star.presentation.PresentationDocument" ) ) )
210         return Any();
211 
212     // Create a new listener that waits for the full screen presentation
213     // to start and to end.  It takes care of its own lifetime.
214     ::rtl::Reference<PresenterScreenListener> pListener (
215         new PresenterScreenListener(mxComponentContext, xModel));
216     pListener->Initialize();
217 
218     return Any();
219 }
220 
221 
222 
223 
224 //===== PresenterScreenListener ===============================================
225 
226 namespace {
227 
PresenterScreenListener(const css::uno::Reference<css::uno::XComponentContext> & rxContext,const css::uno::Reference<css::frame::XModel2> & rxModel)228 PresenterScreenListener::PresenterScreenListener (
229     const css::uno::Reference<css::uno::XComponentContext>& rxContext,
230     const css::uno::Reference<css::frame::XModel2>& rxModel)
231     : PresenterScreenListenerInterfaceBase(m_aMutex),
232       mxModel(rxModel),
233       mxComponentContext(rxContext),
234       mpPresenterScreen()
235 {
236 }
237 
238 
239 
240 
Initialize(void)241 void PresenterScreenListener::Initialize (void)
242 {
243     Reference< document::XEventListener > xDocListener(
244         static_cast< document::XEventListener* >(this), UNO_QUERY);
245     Reference< document::XEventBroadcaster > xDocBroadcaster( mxModel, UNO_QUERY );
246     if( xDocBroadcaster.is() )
247         xDocBroadcaster->addEventListener(xDocListener);
248 }
249 
250 
251 
252 
~PresenterScreenListener(void)253 PresenterScreenListener::~PresenterScreenListener (void)
254 {
255 }
256 
257 
258 
259 
disposing(void)260 void SAL_CALL PresenterScreenListener::disposing (void)
261 {
262     Reference< document::XEventBroadcaster > xDocBroadcaster( mxModel, UNO_QUERY );
263     if( xDocBroadcaster.is() )
264         xDocBroadcaster->removeEventListener(
265             Reference<document::XEventListener>(
266                 static_cast<document::XEventListener*>(this), UNO_QUERY));
267 
268     if (mpPresenterScreen.is())
269     {
270         mpPresenterScreen->RequestShutdownPresenterScreen();
271         mpPresenterScreen = NULL;
272     }
273 }
274 
275 
276 
277 
278 // document::XEventListener
279 
notifyEvent(const css::document::EventObject & Event)280 void SAL_CALL PresenterScreenListener::notifyEvent( const css::document::EventObject& Event )
281 {
282     ThrowIfDisposed();
283 
284     if( Event.EventName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "OnStartPresentation" ) ) )
285     {
286         mpPresenterScreen = new PresenterScreen(mxComponentContext, mxModel);
287         mpPresenterScreen->InitializePresenterScreen();
288     }
289     else if( Event.EventName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "OnEndPresentation" ) ) )
290     {
291         if (mpPresenterScreen.is())
292         {
293             mpPresenterScreen->RequestShutdownPresenterScreen();
294             mpPresenterScreen = NULL;
295         }
296     }
297 }
298 
299 
300 
301 
302 // XEventListener
303 
disposing(const css::lang::EventObject & rEvent)304 void SAL_CALL PresenterScreenListener::disposing (const css::lang::EventObject& rEvent)
305 {
306     (void)rEvent;
307 
308     if (mpPresenterScreen.is())
309     {
310         mpPresenterScreen->RequestShutdownPresenterScreen();
311         mpPresenterScreen = NULL;
312     }
313 }
314 
315 
316 
317 
ThrowIfDisposed(void) const318 void PresenterScreenListener::ThrowIfDisposed (void) const
319 {
320     if (rBHelper.bDisposed || rBHelper.bInDispose)
321     {
322         throw lang::DisposedException (
323             A2S("PresenterScreenListener object has already been disposed"),
324             const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
325     }
326 }
327 
328 } // end of anonymous namespace
329 
330 
331 
332 
333 //===== PresenterScreen =======================================================
334 
PresenterScreen(const Reference<XComponentContext> & rxContext,const css::uno::Reference<css::frame::XModel2> & rxModel)335 PresenterScreen::PresenterScreen (
336     const Reference<XComponentContext>& rxContext,
337     const css::uno::Reference<css::frame::XModel2>& rxModel)
338     : PresenterScreenInterfaceBase(m_aMutex),
339       mxModel(rxModel),
340       mxController(),
341       mxConfigurationControllerWeak(),
342       mxContextWeak(rxContext),
343       mxSlideShowControllerWeak(),
344       mpPresenterController(),
345       mxSlideShowViewId(),
346       mxSavedConfiguration(),
347       mpPaneContainer(),
348       mnComponentIndex(0),
349       mxPaneFactory(),
350       mxViewFactory(),
351       maViewDescriptors()
352 {
353 }
354 
355 
356 
357 
~PresenterScreen(void)358 PresenterScreen::~PresenterScreen (void)
359 {
360 }
361 
362 
363 
364 
disposing(void)365 void SAL_CALL PresenterScreen::disposing (void)
366 {
367     Reference<XConfigurationController> xCC (mxConfigurationControllerWeak);
368     if (xCC.is() && mxSavedConfiguration.is())
369     {
370         xCC->restoreConfiguration(mxSavedConfiguration);
371     }
372     mxConfigurationControllerWeak = Reference<XConfigurationController>(NULL);
373 
374     Reference<lang::XComponent> xViewFactoryComponent (mxViewFactory, UNO_QUERY);
375     if (xViewFactoryComponent.is())
376        xViewFactoryComponent->dispose();
377     Reference<lang::XComponent> xPaneFactoryComponent (mxPaneFactory, UNO_QUERY);
378     if (xPaneFactoryComponent.is())
379         xPaneFactoryComponent->dispose();
380 
381     mxModel = NULL;
382 }
383 
384 
385 
386 
387 //----- XEventListener --------------------------------------------------------
388 
disposing(const lang::EventObject &)389 void SAL_CALL PresenterScreen::disposing (const lang::EventObject& /*rEvent*/)
390 {
391     mxSlideShowControllerWeak = WeakReference<presentation::XSlideShowController>();
392     RequestShutdownPresenterScreen();
393 }
394 
395 
396 
397 
398 //-----------------------------------------------------------------------------
399 
InitializePresenterScreen(void)400 void PresenterScreen::InitializePresenterScreen (void)
401 {
402     try
403     {
404         Reference<XComponentContext> xContext (mxContextWeak);
405 
406         // Check if disabled by configuration
407         if (!lcl_IsPresenterEnabled(xContext) )
408             return;
409 
410         mpPaneContainer =
411             new PresenterPaneContainer(Reference<XComponentContext>(xContext));
412 
413         Reference<XPresentationSupplier> xPS ( mxModel, UNO_QUERY_THROW);
414         Reference<XPresentation2> xPresentation(xPS->getPresentation(), UNO_QUERY_THROW);
415         Reference<presentation::XSlideShowController> xSlideShowController( xPresentation->getController() );
416         mxSlideShowControllerWeak = xSlideShowController;
417 
418         if( !xSlideShowController.is() || !xSlideShowController->isFullScreen() )
419             return;
420 
421         // find first controller that is not the current controller (the one with the slideshow
422         mxController = mxModel->getCurrentController();
423         Reference< container::XEnumeration > xEnum( mxModel->getControllers() );
424         if( xEnum.is() )
425         {
426             while( xEnum->hasMoreElements() )
427             {
428                 Reference< frame::XController > xC( xEnum->nextElement(), UNO_QUERY );
429                 if( xC.is() && (xC != mxController) )
430                 {
431                     mxController = xC;
432                     break;
433                 }
434             }
435         }
436         // Get the XController from the first argument.
437         Reference<XControllerManager> xCM(mxController, UNO_QUERY_THROW);
438 
439         Reference<XConfigurationController> xCC( xCM->getConfigurationController());
440         mxConfigurationControllerWeak = xCC;
441 
442         Reference<drawing::framework::XResourceId> xMainPaneId(
443             GetMainPaneId(xPresentation));
444         // An empty reference means that the presenter screen can
445         // not or must not be displayed.
446         if ( ! xMainPaneId.is())
447             return;
448 
449         if (xCC.is() && xContext.is())
450         {
451             // Store the current configuration so that we can restore it when
452             // the presenter view is deactivated.
453             mxSavedConfiguration = xCC->getRequestedConfiguration();
454             xCC->lock();
455 
456             try
457             {
458                 // At the moment the presenter controller is displayed in its
459                 // own full screen window that is controlled by the same
460                 // configuration controller as the Impress document from
461                 // which the presentation was started.  Therefore the main
462                 // pane is activated additionally to the already existing
463                 // panes and does not replace them.
464                 xCC->requestResourceActivation(
465                     xMainPaneId,
466                     ResourceActivationMode_ADD);
467                 SetupConfiguration(xContext, xMainPaneId);
468 
469                 mpPresenterController = new PresenterController(
470                     xContext,
471                     mxController,
472                     xSlideShowController,
473                     mpPaneContainer,
474                     xMainPaneId);
475 
476                 // Create pane and view factories and integrate them into the
477                 // drawing framework.
478                 SetupPaneFactory(xContext);
479                 SetupViewFactory(xContext);
480 
481                 mpPresenterController->GetWindowManager()->RestoreViewMode();
482             }
483             catch (RuntimeException&)
484             {
485                 xCC->restoreConfiguration(mxSavedConfiguration);
486             }
487             xCC->unlock();
488         }
489     }
490     catch (Exception&)
491     {
492     }
493 }
494 
495 
496 
497 
GetScreenNumber(const Reference<presentation::XPresentation2> & rxPresentation) const498 sal_Int32 PresenterScreen::GetScreenNumber (
499     const Reference<presentation::XPresentation2>& rxPresentation) const
500 {
501     // Determine the screen on which the full screen presentation is being
502     // displayed.
503     sal_Int32 nScreenNumber (0);
504     sal_Int32 nScreenCount (1);
505     try
506     {
507         Reference<beans::XPropertySet> xProperties (rxPresentation, UNO_QUERY);
508         if ( ! xProperties.is())
509             return -1;
510 
511         sal_Int32 nDisplayNumber (-1);
512         if ( ! (xProperties->getPropertyValue(A2S("Display")) >>= nDisplayNumber))
513             return -1;
514         if (nDisplayNumber == -1)
515         {
516             // The special value -1 indicates that the slide show
517             // spans all available displays.  That leaves no room for
518             // the presenter screen.
519             return -1;
520         }
521 
522         Reference<XComponentContext> xContext (mxContextWeak);
523         if ( ! xContext.is())
524             return -1;
525         Reference<lang::XMultiComponentFactory> xFactory (
526             xContext->getServiceManager(), UNO_QUERY);
527         if ( ! xFactory.is())
528             return -1;
529         Reference<beans::XPropertySet> xDisplayProperties (
530             xFactory->createInstanceWithContext(A2S("com.sun.star.awt.DisplayAccess"),xContext),
531             UNO_QUERY);
532         if  ( ! xDisplayProperties.is())
533             return -1;
534 
535         if (nDisplayNumber > 0)
536         {
537             nScreenNumber = nDisplayNumber - 1;
538         }
539         else if (nDisplayNumber == 0)
540         {
541             // A display number value of 0 indicates the primary screen.
542             // Instantiate the DisplayAccess service to find out which
543             // screen number that is.
544             if (nDisplayNumber <= 0 && xDisplayProperties.is())
545                 xDisplayProperties->getPropertyValue(A2S("DefaultDisplay")) >>= nScreenNumber;
546         }
547 
548         // We still have to determine the number of screens to decide
549         // whether the presenter screen may be shown at all.
550         Reference<container::XIndexAccess> xIndexAccess (xDisplayProperties, UNO_QUERY);
551         if ( ! xIndexAccess.is())
552             return -1;
553         nScreenCount = xIndexAccess->getCount();
554 
555         if (nScreenCount < 2 || nDisplayNumber > nScreenCount)
556         {
557             // There is either only one screen or the full screen
558             // presentation spans all available screens.  The presenter
559             // screen is shown only when a special flag in the configuration
560             // is set.
561             PresenterConfigurationAccess aConfiguration (
562                 xContext,
563                 A2S("/org.openoffice.Office.PresenterScreen/"),
564                 PresenterConfigurationAccess::READ_ONLY);
565             bool bStartAlways (false);
566             if (aConfiguration.GetConfigurationNode(
567                 A2S("Presenter/StartAlways")) >>= bStartAlways)
568             {
569                 if (bStartAlways)
570                     return nScreenNumber;
571             }
572             return -1;
573         }
574     }
575     catch (beans::UnknownPropertyException&)
576     {
577         OSL_ASSERT(false);
578         // For some reason we can not access the screen number.  Use
579         // the default instead.
580     }
581 
582     return nScreenNumber;
583 }
584 
585 
586 
587 
GetMainPaneId(const Reference<presentation::XPresentation2> & rxPresentation) const588 Reference<drawing::framework::XResourceId> PresenterScreen::GetMainPaneId (
589     const Reference<presentation::XPresentation2>& rxPresentation) const
590 {
591     // A negative value means that the presentation spans all available
592     // displays.  That leaves no room for the presenter.
593     const sal_Int32 nScreenNumber(GetScreenNumber(rxPresentation));
594     if (nScreenNumber < 0)
595         return NULL;
596 
597     // Setup the resource id of the full screen background pane so that
598     // it is displayed on another screen than the presentation.
599     sal_Int32 nPresenterScreenNumber (1);
600     switch (nScreenNumber)
601     {
602         case 0:
603             nPresenterScreenNumber = 1;
604             break;
605 
606         case 1:
607             nPresenterScreenNumber = 0;
608             break;
609 
610         default:
611             // When the full screen presentation is displayed on a screen
612             // other than 0 or 1 then place the presenter on the first
613             // available screen.
614             nPresenterScreenNumber = 0;
615             break;
616     }
617 
618     return ResourceId::create(
619         Reference<XComponentContext>(mxContextWeak),
620         PresenterHelper::msFullScreenPaneURL
621             +A2S("?FullScreen=true&ScreenNumber=")
622                 + OUString::valueOf(nPresenterScreenNumber));
623 }
624 
625 
626 
627 
RequestShutdownPresenterScreen(void)628 void PresenterScreen::RequestShutdownPresenterScreen (void)
629 {
630     // Restore the configuration that was active before the presenter screen
631     // has been activated.  Now, that the presenter screen is displayed in
632     // its own top level window this probably not necessary, but one never knows.
633     Reference<XConfigurationController> xCC (mxConfigurationControllerWeak);
634     if (xCC.is() && mxSavedConfiguration.is())
635     {
636         xCC->restoreConfiguration(mxSavedConfiguration);
637         mxSavedConfiguration = NULL;
638     }
639 
640     if (xCC.is())
641     {
642         // The actual restoration of the configuration takes place
643         // asynchronously.  The view and pane factories can only by disposed
644         // after that.  Therefore, set up a listener and wait for the
645         // restoration.
646         rtl::Reference<PresenterScreen> pSelf (this);
647         PresenterFrameworkObserver::RunOnUpdateEnd(
648             xCC,
649             ::boost::bind(&PresenterScreen::ShutdownPresenterScreen, pSelf));
650         xCC->update();
651     }
652 }
653 
654 
655 
656 
ShutdownPresenterScreen(void)657 void PresenterScreen::ShutdownPresenterScreen (void)
658 {
659     Reference<lang::XComponent> xViewFactoryComponent (mxViewFactory, UNO_QUERY);
660     if (xViewFactoryComponent.is())
661         xViewFactoryComponent->dispose();
662     mxViewFactory = NULL;
663 
664     Reference<lang::XComponent> xPaneFactoryComponent (mxPaneFactory, UNO_QUERY);
665     if (xPaneFactoryComponent.is())
666         xPaneFactoryComponent->dispose();
667     mxPaneFactory = NULL;
668 
669     if (mpPresenterController.get() != NULL)
670     {
671         mpPresenterController->dispose();
672         mpPresenterController = rtl::Reference<PresenterController>();
673     }
674     mpPaneContainer = new PresenterPaneContainer(Reference<XComponentContext>(mxContextWeak));
675 }
676 
677 
678 
679 
SetupPaneFactory(const Reference<XComponentContext> & rxContext)680 void PresenterScreen::SetupPaneFactory (const Reference<XComponentContext>& rxContext)
681 {
682     try
683     {
684         if ( ! mxPaneFactory.is())
685             mxPaneFactory = PresenterPaneFactory::Create(
686                 rxContext,
687                 mxController,
688                 mpPresenterController);
689     }
690     catch (RuntimeException&)
691     {
692         OSL_ASSERT(false);
693     }
694 }
695 
696 
697 
698 
SetupViewFactory(const Reference<XComponentContext> & rxContext)699 void PresenterScreen::SetupViewFactory (const Reference<XComponentContext>& rxContext)
700 {
701     try
702     {
703         if ( ! mxViewFactory.is())
704             mxViewFactory = PresenterViewFactory::Create(
705                 rxContext,
706                 mxController,
707                 mpPresenterController);
708     }
709     catch (RuntimeException&)
710     {
711         OSL_ASSERT(false);
712     }
713 }
714 
715 
716 
717 
SetupConfiguration(const Reference<XComponentContext> & rxContext,const Reference<XResourceId> & rxAnchorId)718 void PresenterScreen::SetupConfiguration (
719     const Reference<XComponentContext>& rxContext,
720     const Reference<XResourceId>& rxAnchorId)
721 {
722     try
723     {
724         PresenterConfigurationAccess aConfiguration (
725             rxContext,
726             A2S("org.openoffice.Office.PresenterScreen"),
727             PresenterConfigurationAccess::READ_ONLY);
728         maViewDescriptors.clear();
729         ProcessViewDescriptions(aConfiguration);
730         OUString sLayoutName (RTL_CONSTASCII_USTRINGPARAM("DefaultLayout"));
731         aConfiguration.GetConfigurationNode(
732             A2S("Presenter/CurrentLayout")) >>= sLayoutName;
733         ProcessLayout(aConfiguration, sLayoutName, rxContext, rxAnchorId);
734     }
735     catch (RuntimeException&)
736     {
737     }
738 }
739 
740 
741 
742 
ProcessLayout(PresenterConfigurationAccess & rConfiguration,const OUString & rsLayoutName,const Reference<XComponentContext> & rxContext,const Reference<XResourceId> & rxAnchorId)743 void PresenterScreen::ProcessLayout (
744     PresenterConfigurationAccess& rConfiguration,
745     const OUString& rsLayoutName,
746     const Reference<XComponentContext>& rxContext,
747     const Reference<XResourceId>& rxAnchorId)
748 {
749     try
750     {
751         Reference<container::XHierarchicalNameAccess> xLayoutNode (
752             rConfiguration.GetConfigurationNode(
753                 A2S("Presenter/Layouts/") + rsLayoutName),
754             UNO_QUERY_THROW);
755 
756         // Read the parent layout first, if one is referenced.
757         OUString sParentLayout;
758         rConfiguration.GetConfigurationNode(
759             xLayoutNode,
760             A2S("ParentLayout")) >>= sParentLayout;
761         if (sParentLayout.getLength() > 0)
762         {
763             // Prevent infinite recursion.
764             if (rsLayoutName != sParentLayout)
765                 ProcessLayout(rConfiguration, sParentLayout, rxContext, rxAnchorId);
766         }
767 
768         // Process the actual layout list.
769         Reference<container::XNameAccess> xList (
770             rConfiguration.GetConfigurationNode(
771                 xLayoutNode,
772                 A2S("Layout")),
773             UNO_QUERY_THROW);
774 
775         ::std::vector<rtl::OUString> aProperties (6);
776         aProperties[0] = A2S("PaneURL");
777         aProperties[1] = A2S("ViewURL");
778         aProperties[2] = A2S("RelativeX");
779         aProperties[3] = A2S("RelativeY");
780         aProperties[4] = A2S("RelativeWidth");
781         aProperties[5] = A2S("RelativeHeight");
782         mnComponentIndex = 1;
783         PresenterConfigurationAccess::ForAll(
784             xList,
785             aProperties,
786             ::boost::bind(&PresenterScreen::ProcessComponent, this,
787                 _1,
788                 _2,
789                 rxContext,
790                 rxAnchorId));
791     }
792     catch (RuntimeException&)
793     {
794     }
795 }
796 
797 
798 
799 
ProcessViewDescriptions(PresenterConfigurationAccess & rConfiguration)800 void PresenterScreen::ProcessViewDescriptions (
801     PresenterConfigurationAccess& rConfiguration)
802 {
803     try
804     {
805         Reference<container::XNameAccess> xViewDescriptionsNode (
806             rConfiguration.GetConfigurationNode(A2S("Presenter/Views")),
807             UNO_QUERY_THROW);
808 
809         ::std::vector<rtl::OUString> aProperties (4);
810         aProperties[0] = A2S("ViewURL");
811         aProperties[1] = A2S("Title");
812         aProperties[2] = A2S("AccessibleTitle");
813         aProperties[3] = A2S("IsOpaque");
814         mnComponentIndex = 1;
815         PresenterConfigurationAccess::ForAll(
816             xViewDescriptionsNode,
817             aProperties,
818             ::boost::bind(&PresenterScreen::ProcessViewDescription, this, _1, _2));
819     }
820     catch (RuntimeException&)
821     {
822         OSL_ASSERT(false);
823     }
824 }
825 
826 
827 
828 
ProcessComponent(const OUString & rsKey,const::std::vector<Any> & rValues,const Reference<XComponentContext> & rxContext,const Reference<XResourceId> & rxAnchorId)829 void PresenterScreen::ProcessComponent (
830     const OUString& rsKey,
831     const ::std::vector<Any>& rValues,
832     const Reference<XComponentContext>& rxContext,
833     const Reference<XResourceId>& rxAnchorId)
834 {
835     (void)rsKey;
836 
837     if (rValues.size() != 6)
838         return;
839 
840     try
841     {
842         OUString sPaneURL;
843         OUString sViewURL;
844         double nX = 0;
845         double nY = 0;
846         double nWidth = 0;
847         double nHeight = 0;
848         rValues[0] >>= sPaneURL;
849         rValues[1] >>= sViewURL;
850         rValues[2] >>= nX;
851         rValues[3] >>= nY;
852         rValues[4] >>= nWidth;
853         rValues[5] >>= nHeight;
854 
855         if (nX>=0 && nY>=0 && nWidth>0 && nHeight>0)
856         {
857             SetupView(
858                 rxContext,
859                 rxAnchorId,
860                 sPaneURL,
861                 sViewURL,
862                 PresenterPaneContainer::ViewInitializationFunction(),
863                 nX,
864                 nY,
865                 nX+nWidth,
866                 nY+nHeight);
867         }
868     }
869     catch (Exception& e)
870     {
871         (void)e;
872         OSL_ASSERT(false);
873     }
874 }
875 
876 
877 
878 
ProcessViewDescription(const OUString & rsKey,const::std::vector<Any> & rValues)879 void PresenterScreen::ProcessViewDescription (
880     const OUString& rsKey,
881     const ::std::vector<Any>& rValues)
882 {
883     (void)rsKey;
884 
885     if (rValues.size() != 4)
886         return;
887 
888     try
889     {
890         ViewDescriptor aViewDescriptor;
891         OUString sViewURL;
892         rValues[0] >>= sViewURL;
893         rValues[1] >>= aViewDescriptor.msTitle;
894         rValues[2] >>= aViewDescriptor.msAccessibleTitle;
895         rValues[3] >>= aViewDescriptor.mbIsOpaque;
896         if (aViewDescriptor.msAccessibleTitle.getLength()==0)
897             aViewDescriptor.msAccessibleTitle = aViewDescriptor.msTitle;
898         maViewDescriptors[sViewURL] = aViewDescriptor;
899     }
900     catch (Exception&)
901     {
902         OSL_ASSERT(false);
903     }
904 }
905 
906 
907 
908 
SetupView(const Reference<XComponentContext> & rxContext,const Reference<XResourceId> & rxAnchorId,const OUString & rsPaneURL,const OUString & rsViewURL,const PresenterPaneContainer::ViewInitializationFunction & rViewInitialization,const double nLeft,const double nTop,const double nRight,const double nBottom)909 void PresenterScreen::SetupView(
910     const Reference<XComponentContext>& rxContext,
911     const Reference<XResourceId>& rxAnchorId,
912     const OUString& rsPaneURL,
913     const OUString& rsViewURL,
914     const PresenterPaneContainer::ViewInitializationFunction& rViewInitialization,
915     const double nLeft,
916     const double nTop,
917     const double nRight,
918     const double nBottom)
919 {
920     Reference<XConfigurationController> xCC (mxConfigurationControllerWeak);
921     if (xCC.is())
922     {
923         Reference<XResourceId> xPaneId (ResourceId::createWithAnchor(rxContext,rsPaneURL,rxAnchorId));
924         // Look up the view descriptor.
925         ViewDescriptor aViewDescriptor;
926         ViewDescriptorContainer::const_iterator iDescriptor (maViewDescriptors.find(rsViewURL));
927         if (iDescriptor != maViewDescriptors.end())
928             aViewDescriptor = iDescriptor->second;
929 
930         // Prepare the pane.
931         OSL_ASSERT(mpPaneContainer.get() != NULL);
932         mpPaneContainer->PreparePane(
933             xPaneId,
934             rsViewURL,
935             aViewDescriptor.msTitle,
936             aViewDescriptor.msAccessibleTitle,
937             aViewDescriptor.mbIsOpaque,
938             rViewInitialization,
939             nLeft,
940             nTop,
941             nRight,
942             nBottom);
943     }
944 }
945 
946 
947 
948 
949 } } // end of namespace ::sdext::presenter
950