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 "PresenterPaneContainer.hxx"
21 #include "PresenterPaneBase.hxx"
22 
23 using namespace ::com::sun::star;
24 using namespace ::com::sun::star::uno;
25 using namespace ::com::sun::star::drawing::framework;
26 
27 namespace sdext::presenter {
28 
PresenterPaneContainer(const Reference<XComponentContext> & rxContext)29 PresenterPaneContainer::PresenterPaneContainer (
30     const Reference<XComponentContext>& rxContext)
31     : PresenterPaneContainerInterfaceBase(m_aMutex),
32       maPanes(),
33       mxPresenterHelper()
34 {
35     Reference<lang::XMultiComponentFactory> xFactory (rxContext->getServiceManager());
36     if (xFactory.is())
37     {
38         mxPresenterHelper.set(
39             xFactory->createInstanceWithContext(
40                 "com.sun.star.comp.Draw.PresenterHelper",
41                 rxContext),
42             UNO_QUERY_THROW);
43     }
44 }
45 
~PresenterPaneContainer()46 PresenterPaneContainer::~PresenterPaneContainer()
47 {
48 }
49 
PreparePane(const Reference<XResourceId> & rxPaneId,const OUString & rsViewURL,const OUString & rsTitle,const OUString & rsAccessibleTitle,const bool bIsOpaque,const ViewInitializationFunction & rViewInitialization)50 void PresenterPaneContainer::PreparePane (
51     const Reference<XResourceId>& rxPaneId,
52     const OUString& rsViewURL,
53     const OUString& rsTitle,
54     const OUString& rsAccessibleTitle,
55     const bool bIsOpaque,
56     const ViewInitializationFunction& rViewInitialization)
57 {
58     if ( ! rxPaneId.is())
59         return;
60 
61     SharedPaneDescriptor pPane (FindPaneURL(rxPaneId->getResourceURL()));
62     if (pPane)
63         return;
64 
65     // No entry found for the given pane id.  Create a new one.
66     SharedPaneDescriptor pDescriptor = std::make_shared<PaneDescriptor>();
67     pDescriptor->mxPaneId = rxPaneId;
68     pDescriptor->msViewURL = rsViewURL;
69     pDescriptor->mxPane = nullptr;
70     if (rsTitle.indexOf('%') < 0)
71     {
72         pDescriptor->msTitle = rsTitle;
73         pDescriptor->msTitleTemplate.clear();
74     }
75     else
76     {
77         pDescriptor->msTitleTemplate = rsTitle;
78         pDescriptor->msTitle.clear();
79     }
80     pDescriptor->msAccessibleTitleTemplate = rsAccessibleTitle;
81     pDescriptor->maViewInitialization = rViewInitialization;
82     pDescriptor->mbIsActive = true;
83     pDescriptor->mbIsOpaque = bIsOpaque;
84     pDescriptor->mbIsSprite = false;
85 
86     maPanes.push_back(pDescriptor);
87 }
88 
disposing()89 void SAL_CALL PresenterPaneContainer::disposing()
90 {
91     for (const auto& rxPane : maPanes)
92         if (rxPane->mxPaneId.is())
93             RemovePane(rxPane->mxPaneId);
94 }
95 
96 PresenterPaneContainer::SharedPaneDescriptor
StorePane(const rtl::Reference<PresenterPaneBase> & rxPane)97     PresenterPaneContainer::StorePane (const rtl::Reference<PresenterPaneBase>& rxPane)
98 {
99     SharedPaneDescriptor pDescriptor;
100 
101     if (rxPane.is())
102     {
103         OUString sPaneURL;
104         Reference<XResourceId> xPaneId (rxPane->getResourceId());
105         if (xPaneId.is())
106             sPaneURL = xPaneId->getResourceURL();
107 
108         pDescriptor = FindPaneURL(sPaneURL);
109         if (!pDescriptor)
110             PreparePane(xPaneId, OUString(), OUString(), OUString(),
111                 false, ViewInitializationFunction());
112         pDescriptor = FindPaneURL(sPaneURL);
113         if (pDescriptor)
114         {
115             Reference<awt::XWindow> xWindow (rxPane->getWindow());
116             pDescriptor->mxContentWindow = xWindow;
117             pDescriptor->mxPaneId = xPaneId;
118             pDescriptor->mxPane = rxPane;
119             pDescriptor->mxPane->SetTitle(pDescriptor->msTitle);
120 
121             if (xWindow.is())
122                 xWindow->addEventListener(this);
123         }
124     }
125 
126     return pDescriptor;
127 }
128 
129 PresenterPaneContainer::SharedPaneDescriptor
StoreBorderWindow(const Reference<XResourceId> & rxPaneId,const Reference<awt::XWindow> & rxBorderWindow)130     PresenterPaneContainer::StoreBorderWindow(
131         const Reference<XResourceId>& rxPaneId,
132         const Reference<awt::XWindow>& rxBorderWindow)
133 {
134     // The content window may not be present.  Use the resource URL of the
135     // pane id as key.
136     OUString sPaneURL;
137     if (rxPaneId.is())
138         sPaneURL = rxPaneId->getResourceURL();
139 
140     SharedPaneDescriptor pDescriptor (FindPaneURL(sPaneURL));
141     if (pDescriptor)
142     {
143         pDescriptor->mxBorderWindow = rxBorderWindow;
144         return pDescriptor;
145     }
146     else
147         return SharedPaneDescriptor();
148 }
149 
150 PresenterPaneContainer::SharedPaneDescriptor
StoreView(const Reference<XView> & rxView)151     PresenterPaneContainer::StoreView (
152         const Reference<XView>& rxView)
153 {
154     SharedPaneDescriptor pDescriptor;
155 
156     if (rxView.is())
157     {
158         OUString sPaneURL;
159         Reference<XResourceId> xViewId (rxView->getResourceId());
160         if (xViewId.is())
161         {
162             Reference<XResourceId> xPaneId (xViewId->getAnchor());
163             if (xPaneId.is())
164                 sPaneURL = xPaneId->getResourceURL();
165         }
166 
167         pDescriptor = FindPaneURL(sPaneURL);
168         if (pDescriptor)
169         {
170             pDescriptor->mxView = rxView;
171             try
172             {
173                 if (pDescriptor->maViewInitialization)
174                     pDescriptor->maViewInitialization(rxView);
175             }
176             catch (RuntimeException&)
177             {
178                 OSL_ASSERT(false);
179             }
180         }
181     }
182 
183     return pDescriptor;
184 }
185 
186 PresenterPaneContainer::SharedPaneDescriptor
RemovePane(const Reference<XResourceId> & rxPaneId)187     PresenterPaneContainer::RemovePane (const Reference<XResourceId>& rxPaneId)
188 {
189     SharedPaneDescriptor pDescriptor (FindPaneId(rxPaneId));
190     if (pDescriptor)
191     {
192         if (pDescriptor->mxContentWindow.is())
193             pDescriptor->mxContentWindow->removeEventListener(this);
194         pDescriptor->mxContentWindow = nullptr;
195         pDescriptor->mxBorderWindow = nullptr;
196         pDescriptor->mxPane = nullptr;
197         pDescriptor->mxView = nullptr;
198         pDescriptor->mbIsActive = false;
199     }
200     return pDescriptor;
201 }
202 
203 PresenterPaneContainer::SharedPaneDescriptor
RemoveView(const Reference<XView> & rxView)204     PresenterPaneContainer::RemoveView (const Reference<XView>& rxView)
205 {
206     SharedPaneDescriptor pDescriptor;
207 
208     if (rxView.is())
209     {
210         OUString sPaneURL;
211         Reference<XResourceId> xViewId (rxView->getResourceId());
212         if (xViewId.is())
213         {
214             Reference<XResourceId> xPaneId (xViewId->getAnchor());
215             if (xPaneId.is())
216                 sPaneURL = xPaneId->getResourceURL();
217         }
218 
219         pDescriptor = FindPaneURL(sPaneURL);
220         if (pDescriptor)
221         {
222             pDescriptor->mxView = nullptr;
223         }
224     }
225 
226     return pDescriptor;
227 }
228 
FindBorderWindow(const Reference<awt::XWindow> & rxBorderWindow)229 PresenterPaneContainer::SharedPaneDescriptor PresenterPaneContainer::FindBorderWindow (
230     const Reference<awt::XWindow>& rxBorderWindow)
231 {
232     auto iPane = std::find_if(maPanes.begin(), maPanes.end(),
233         [&rxBorderWindow](const SharedPaneDescriptor& rxPane) { return rxPane->mxBorderWindow == rxBorderWindow; });
234     if (iPane != maPanes.end())
235         return *iPane;
236     return SharedPaneDescriptor();
237 }
238 
FindContentWindow(const Reference<awt::XWindow> & rxContentWindow)239 PresenterPaneContainer::SharedPaneDescriptor PresenterPaneContainer::FindContentWindow (
240     const Reference<awt::XWindow>& rxContentWindow)
241 {
242     auto iPane = std::find_if(maPanes.begin(), maPanes.end(),
243         [&rxContentWindow](const SharedPaneDescriptor& rxPane) { return rxPane->mxContentWindow == rxContentWindow; });
244     if (iPane != maPanes.end())
245         return *iPane;
246     return SharedPaneDescriptor();
247 }
248 
FindPaneURL(const OUString & rsPaneURL)249 PresenterPaneContainer::SharedPaneDescriptor PresenterPaneContainer::FindPaneURL (
250     const OUString& rsPaneURL)
251 {
252     auto iPane = std::find_if(maPanes.begin(), maPanes.end(),
253         [&rsPaneURL](const SharedPaneDescriptor& rxPane) { return rxPane->mxPaneId->getResourceURL() == rsPaneURL; });
254     if (iPane != maPanes.end())
255         return *iPane;
256     return SharedPaneDescriptor();
257 }
258 
FindPaneId(const Reference<XResourceId> & rxPaneId)259 PresenterPaneContainer::SharedPaneDescriptor PresenterPaneContainer::FindPaneId (
260     const Reference<XResourceId>& rxPaneId)
261 {
262     if ( ! rxPaneId.is())
263         return SharedPaneDescriptor();
264 
265     auto iPane = std::find_if(maPanes.begin(), maPanes.end(),
266         [&rxPaneId](const SharedPaneDescriptor& rxPane) { return rxPaneId->compareTo(rxPane->mxPaneId) == 0; });
267     if (iPane != maPanes.end())
268         return *iPane;
269     return SharedPaneDescriptor();
270 }
271 
FindViewURL(const OUString & rsViewURL)272 PresenterPaneContainer::SharedPaneDescriptor PresenterPaneContainer::FindViewURL (
273     const OUString& rsViewURL)
274 {
275     auto iPane = std::find_if(maPanes.begin(), maPanes.end(),
276         [&rsViewURL](const SharedPaneDescriptor& rxPane) { return rsViewURL == rxPane->msViewURL; });
277     if (iPane != maPanes.end())
278         return *iPane;
279     return SharedPaneDescriptor();
280 }
281 
GetPaneURLForViewURL(const OUString & rsViewURL)282 OUString PresenterPaneContainer::GetPaneURLForViewURL (const OUString& rsViewURL)
283 {
284     SharedPaneDescriptor pDescriptor (FindViewURL(rsViewURL));
285     if (pDescriptor)
286         if (pDescriptor->mxPaneId.is())
287             return pDescriptor->mxPaneId->getResourceURL();
288     return OUString();
289 }
290 
ToTop(const SharedPaneDescriptor & rpDescriptor)291 void PresenterPaneContainer::ToTop (const SharedPaneDescriptor& rpDescriptor)
292 {
293     if (!rpDescriptor)
294         return;
295 
296     // Find iterator for pDescriptor.
297     PaneList::iterator iEnd (maPanes.end());
298     auto iPane = std::find_if(maPanes.begin(), iEnd,
299         [&rpDescriptor](SharedPaneDescriptor& rxPane) { return rxPane.get() == rpDescriptor.get(); });
300     OSL_ASSERT(iPane!=iEnd);
301     if (iPane == iEnd)
302         return;
303 
304     if (mxPresenterHelper.is())
305         mxPresenterHelper->toTop(rpDescriptor->mxBorderWindow);
306 
307     maPanes.erase(iPane);
308     maPanes.push_back(rpDescriptor);
309 }
310 
311 //----- XEventListener --------------------------------------------------------
312 
disposing(const css::lang::EventObject & rEvent)313 void SAL_CALL PresenterPaneContainer::disposing (
314     const css::lang::EventObject& rEvent)
315 {
316     SharedPaneDescriptor pDescriptor (
317         FindContentWindow(Reference<awt::XWindow>(rEvent.Source, UNO_QUERY)));
318     if (pDescriptor)
319     {
320         RemovePane(pDescriptor->mxPaneId);
321     }
322 }
323 
324 //===== PresenterPaneContainer::PaneDescriptor ================================
325 
SetActivationState(const bool bIsActive)326 void PresenterPaneContainer::PaneDescriptor::SetActivationState (const bool bIsActive)
327 {
328     mbIsActive = bIsActive;
329 }
330 
331 } // end of namespace ::sdext::presenter
332 
333 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
334