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