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