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