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