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