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