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