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