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 #ifndef INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERSCREEN_HXX
21 #define INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERSCREEN_HXX
22 
23 #include "PresenterConfigurationAccess.hxx"
24 #include "PresenterPaneContainer.hxx"
25 #include <cppuhelper/compbase.hxx>
26 #include <cppuhelper/basemutex.hxx>
27 #include <com/sun/star/frame/XController.hpp>
28 #include <com/sun/star/frame/XModel2.hpp>
29 #include <com/sun/star/task/XJob.hpp>
30 #include <com/sun/star/lang/XServiceInfo.hpp>
31 #include <com/sun/star/drawing/framework/XConfigurationController.hpp>
32 #include <com/sun/star/presentation/XPresentation2.hpp>
33 #include <rtl/ref.hxx>
34 
35 #include <map>
36 #include <string_view>
37 
38 namespace sdext::presenter {
39 
40 class PresenterController;
41 
42 typedef ::cppu::WeakComponentImplHelper <
43     css::task::XJob, css::lang::XServiceInfo
44     > PresenterScreenJobInterfaceBase;
45 
46 /** The PresenterScreenJob service is instantiated every time a document is
47     created or loaded.  In its execute() method it then filters out all
48     non-Impress documents and creates and registers a new PresenterScreen
49     object.
50 */
51 class PresenterScreenJob
52     : private ::cppu::BaseMutex,
53       public PresenterScreenJobInterfaceBase
54 {
55 public:
56     PresenterScreenJob(const PresenterScreenJob&) = delete;
57     PresenterScreenJob& operator=(const PresenterScreenJob&) = delete;
58 
59     virtual void SAL_CALL disposing() override;
60 
61     // XServiceInfo
62     virtual OUString SAL_CALL getImplementationName() override;
63     virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override;
64     virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames () override;
65 
66     // XJob
67     virtual css::uno::Any SAL_CALL execute(
68         const css::uno::Sequence<css::beans::NamedValue >& Arguments) override;
69 
70     explicit PresenterScreenJob (const css::uno::Reference<css::uno::XComponentContext>& rxContext);
71     virtual ~PresenterScreenJob() override;
72 
73 private:
74     css::uno::Reference<css::uno::XComponentContext> mxComponentContext;
75 };
76 
77 /** This is the bootstrap class of the presenter screen.  It is registered
78     as drawing framework startup service.  That means that every drawing
79     framework instance creates an instance of this class.
80 
81     <p>A PresenterScreen object registers itself as listener for drawing
82     framework configuration changes.  It waits for the full screen marker (a
83     top level resource) to appear in the current configuration.  When that
84     happens the actual presenter screen is initialized.  A new
85     PresenterController is created and takes over the task of controlling
86     the presenter screen.</p>
87 */
88 typedef ::cppu::WeakComponentImplHelper <
89     css::lang::XEventListener
90     > PresenterScreenInterfaceBase;
91 class PresenterScreen
92     : private ::cppu::BaseMutex,
93       public PresenterScreenInterfaceBase
94 {
95 public:
96     PresenterScreen (
97         const css::uno::Reference<css::uno::XComponentContext>& rxContext,
98         const css::uno::Reference<css::frame::XModel2>& rxModel);
99     virtual ~PresenterScreen() override;
100     PresenterScreen(const PresenterScreen&) = delete;
101     PresenterScreen& operator=(const PresenterScreen&) = delete;
102 
103     virtual void SAL_CALL disposing() override;
104 
105     static bool isPresenterScreenEnabled(
106         const css::uno::Reference<css::uno::XComponentContext>& rxContext);
107     /** Make the presenter screen visible.
108     */
109     void InitializePresenterScreen();
110 
111     /** Do not call ShutdownPresenterScreen() directly.  Call
112         RequestShutdownPresenterScreen() instead.  It will issue an
113         asynchronous call to ShutdownPresenterScreen() when that is safe.
114     */
115     void RequestShutdownPresenterScreen();
116 
117     /** Switch / converse monitors between presenter view and slide output
118      */
119     void SwitchMonitors();
120 
121     // XEventListener
122 
123     virtual void SAL_CALL disposing ( const css::lang::EventObject& rEvent) override;
124 
125 private:
126     css::uno::Reference<css::frame::XModel2 > mxModel;
127     css::uno::Reference<css::frame::XController> mxController;
128     css::uno::WeakReference<css::drawing::framework::XConfigurationController>
129         mxConfigurationControllerWeak;
130     css::uno::WeakReference<css::uno::XComponentContext> mxContextWeak;
131     ::rtl::Reference<PresenterController> mpPresenterController;
132     css::uno::Reference<css::drawing::framework::XConfiguration> mxSavedConfiguration;
133     ::rtl::Reference<PresenterPaneContainer> mpPaneContainer;
134     css::uno::Reference<css::drawing::framework::XResourceFactory> mxPaneFactory;
135     css::uno::Reference<css::drawing::framework::XResourceFactory> mxViewFactory;
136 
137     class ViewDescriptor
138     {
139     public:
140         OUString msTitle;
141         OUString msAccessibleTitle;
142         bool mbIsOpaque;
ViewDescriptor()143         ViewDescriptor()
144             : mbIsOpaque(false)
145         {
146         }
147     };
148     typedef ::std::map<OUString,ViewDescriptor> ViewDescriptorContainer;
149     ViewDescriptorContainer maViewDescriptors;
150 
151     void ShutdownPresenterScreen();
152 
153     /** Create and initialize the factory for presenter view specific panes.
154     */
155     void SetupPaneFactory (
156         const css::uno::Reference<css::uno::XComponentContext>& rxContext);
157 
158     /** Create and initialize the factory for presenter view specific views.
159     */
160     void SetupViewFactory (
161         const css::uno::Reference<css::uno::XComponentContext>& rxContext);
162 
163     /** Read the current layout from the configuration and call
164         ProcessLayout to bring it on to the screen.
165     */
166     void SetupConfiguration (
167         const css::uno::Reference<css::uno::XComponentContext>& rxContext,
168         const css::uno::Reference<css::drawing::framework::XResourceId>& rxAnchorId);
169 
170     /** Read one layout from the configuration and make resource activation
171         requests to bring it on to the screen.  When one layout references a
172         parent layout then this method calls itself recursively.
173     */
174     void ProcessLayout (
175         PresenterConfigurationAccess& rConfiguration,
176         std::u16string_view rsLayoutName,
177         const css::uno::Reference<css::uno::XComponentContext>& rxContext,
178         const css::uno::Reference<css::drawing::framework::XResourceId>& rxAnchorId);
179 
180     /** Called by ProcessLayout for a single entry of a Layouts
181         configuration list.
182     */
183     void ProcessComponent (
184         const ::std::vector<css::uno::Any>& rValues,
185         const css::uno::Reference<css::uno::XComponentContext>& rxContext,
186         const css::uno::Reference<css::drawing::framework::XResourceId>& rxAnchorId);
187 
188     /** Read the view descriptions from the configuration.
189     */
190     void ProcessViewDescriptions (
191         PresenterConfigurationAccess& rConfiguration);
192 
193     /** Called by ProcessViewDescriptions for a single entry.
194     */
195     void ProcessViewDescription (
196         const ::std::vector<css::uno::Any>& rValues);
197 
198     void SetupView (
199         const css::uno::Reference<css::uno::XComponentContext>& rxContext,
200         const css::uno::Reference<css::drawing::framework::XResourceId>& rxAnchorId,
201         const OUString& rsPaneURL,
202         const OUString& rsViewURL,
203         const PresenterPaneContainer::ViewInitializationFunction& rViewInitialization);
204 
205     /** Return the built-in screen number on the presentation will normally
206         display the presenter console.
207         @return
208             Returns -1 when the presenter screen can or shall not be
209             displayed.
210     */
211     sal_Int32 GetPresenterScreenNumber (
212                 const css::uno::Reference<css::presentation::XPresentation2>& rxPresentation) const;
213 
214     static sal_Int32 GetPresenterScreenFromScreen( sal_Int32 nPresentationScreen );
215 
216     /** Create a resource id for the full screen background pane so that it
217         is displayed on another screen than the full screen presentation.
218     */
219     css::uno::Reference<css::drawing::framework::XResourceId> GetMainPaneId (
220         const css::uno::Reference<css::presentation::XPresentation2>& rxPresentation) const;
221 };
222 
223 }
224 
225 #endif
226 
227 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
228