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 "PresenterPaneFactory.hxx"
21 #include "PresenterController.hxx"
22 #include "PresenterPane.hxx"
23 #include "PresenterPaneBorderPainter.hxx"
24 #include "PresenterPaneContainer.hxx"
25 #include "PresenterSpritePane.hxx"
26 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
27 #include <com/sun/star/lang/XComponent.hpp>
28
29 using namespace ::com::sun::star;
30 using namespace ::com::sun::star::uno;
31 using namespace ::com::sun::star::lang;
32 using namespace ::com::sun::star::drawing::framework;
33
34 namespace sdext::presenter {
35
36 //===== PresenterPaneFactory ==================================================
37
Create(const Reference<uno::XComponentContext> & rxContext,const Reference<frame::XController> & rxController,const::rtl::Reference<PresenterController> & rpPresenterController)38 Reference<drawing::framework::XResourceFactory> PresenterPaneFactory::Create (
39 const Reference<uno::XComponentContext>& rxContext,
40 const Reference<frame::XController>& rxController,
41 const ::rtl::Reference<PresenterController>& rpPresenterController)
42 {
43 rtl::Reference<PresenterPaneFactory> pFactory (
44 new PresenterPaneFactory(rxContext,rpPresenterController));
45 pFactory->Register(rxController);
46 return Reference<drawing::framework::XResourceFactory>(
47 static_cast<XWeak*>(pFactory.get()), UNO_QUERY);
48 }
49
PresenterPaneFactory(const Reference<uno::XComponentContext> & rxContext,const::rtl::Reference<PresenterController> & rpPresenterController)50 PresenterPaneFactory::PresenterPaneFactory (
51 const Reference<uno::XComponentContext>& rxContext,
52 const ::rtl::Reference<PresenterController>& rpPresenterController)
53 : PresenterPaneFactoryInterfaceBase(m_aMutex),
54 mxComponentContextWeak(rxContext),
55 mxConfigurationControllerWeak(),
56 mpPresenterController(rpPresenterController),
57 mpResourceCache()
58 {
59 }
60
Register(const Reference<frame::XController> & rxController)61 void PresenterPaneFactory::Register (const Reference<frame::XController>& rxController)
62 {
63 Reference<XConfigurationController> xCC;
64 try
65 {
66 // Get the configuration controller.
67 Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW);
68 xCC.set(xCM->getConfigurationController());
69 mxConfigurationControllerWeak = xCC;
70 if ( ! xCC.is())
71 {
72 throw RuntimeException();
73 }
74 xCC->addResourceFactory(
75 "private:resource/pane/Presenter/*",
76 this);
77 }
78 catch (RuntimeException&)
79 {
80 OSL_ASSERT(false);
81 if (xCC.is())
82 xCC->removeResourceFactoryForReference(this);
83 mxConfigurationControllerWeak = WeakReference<XConfigurationController>();
84
85 throw;
86 }
87 }
88
~PresenterPaneFactory()89 PresenterPaneFactory::~PresenterPaneFactory()
90 {
91 }
92
disposing()93 void SAL_CALL PresenterPaneFactory::disposing()
94 {
95 Reference<XConfigurationController> xCC (mxConfigurationControllerWeak);
96 if (xCC.is())
97 xCC->removeResourceFactoryForReference(this);
98 mxConfigurationControllerWeak = WeakReference<XConfigurationController>();
99
100 // Dispose the panes in the cache.
101 if (mpResourceCache != nullptr)
102 {
103 for (const auto& rxPane : *mpResourceCache)
104 {
105 Reference<lang::XComponent> xPaneComponent (rxPane.second, UNO_QUERY);
106 if (xPaneComponent.is())
107 xPaneComponent->dispose();
108 }
109 mpResourceCache.reset();
110 }
111 }
112
113 //----- XPaneFactory ----------------------------------------------------------
114
createResource(const Reference<XResourceId> & rxPaneId)115 Reference<XResource> SAL_CALL PresenterPaneFactory::createResource (
116 const Reference<XResourceId>& rxPaneId)
117 {
118 ThrowIfDisposed();
119
120 if ( ! rxPaneId.is())
121 return nullptr;
122
123 const OUString sPaneURL (rxPaneId->getResourceURL());
124 if (sPaneURL.isEmpty())
125 return nullptr;
126
127 if (mpResourceCache != nullptr)
128 {
129 // Has the requested resource already been created?
130 ResourceContainer::const_iterator iResource (mpResourceCache->find(sPaneURL));
131 if (iResource != mpResourceCache->end())
132 {
133 // Yes. Mark it as active.
134 rtl::Reference<PresenterPaneContainer> pPaneContainer(
135 mpPresenterController->GetPaneContainer());
136 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
137 pPaneContainer->FindPaneURL(sPaneURL));
138 if (pDescriptor)
139 {
140 pDescriptor->SetActivationState(true);
141 if (pDescriptor->mxBorderWindow.is())
142 pDescriptor->mxBorderWindow->setVisible(true);
143 pPaneContainer->StorePane(pDescriptor->mxPane);
144 }
145
146 return iResource->second;
147 }
148 }
149
150 // No. Create a new one.
151 Reference<XResource> xResource = CreatePane(rxPaneId);
152 return xResource;
153 }
154
releaseResource(const Reference<XResource> & rxResource)155 void SAL_CALL PresenterPaneFactory::releaseResource (const Reference<XResource>& rxResource)
156 {
157 ThrowIfDisposed();
158
159 if ( ! rxResource.is())
160 throw lang::IllegalArgumentException();
161
162 // Mark the pane as inactive.
163 rtl::Reference<PresenterPaneContainer> pPaneContainer(
164 mpPresenterController->GetPaneContainer());
165 const OUString sPaneURL (rxResource->getResourceId()->getResourceURL());
166 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
167 pPaneContainer->FindPaneURL(sPaneURL));
168 if (!pDescriptor)
169 return;
170
171 pDescriptor->SetActivationState(false);
172 if (pDescriptor->mxBorderWindow.is())
173 pDescriptor->mxBorderWindow->setVisible(false);
174
175 if (mpResourceCache != nullptr)
176 {
177 // Store the pane in the cache.
178 (*mpResourceCache)[sPaneURL] = rxResource;
179 }
180 else
181 {
182 // Dispose the pane.
183 Reference<lang::XComponent> xPaneComponent (rxResource, UNO_QUERY);
184 if (xPaneComponent.is())
185 xPaneComponent->dispose();
186 }
187 }
188
189
CreatePane(const Reference<XResourceId> & rxPaneId)190 Reference<XResource> PresenterPaneFactory::CreatePane (
191 const Reference<XResourceId>& rxPaneId)
192 {
193 if ( ! rxPaneId.is())
194 return nullptr;
195
196 Reference<XConfigurationController> xCC (mxConfigurationControllerWeak);
197 if ( ! xCC.is())
198 return nullptr;
199
200 Reference<XComponentContext> xContext (mxComponentContextWeak);
201 if ( ! xContext.is())
202 return nullptr;
203
204 Reference<XPane> xParentPane (xCC->getResource(rxPaneId->getAnchor()), UNO_QUERY);
205 if ( ! xParentPane.is())
206 return nullptr;
207
208 try
209 {
210 return CreatePane(
211 rxPaneId,
212 xParentPane,
213 rxPaneId->getFullResourceURL().Arguments == "Sprite=1");
214 }
215 catch (Exception&)
216 {
217 OSL_ASSERT(false);
218 }
219
220 return nullptr;
221 }
222
CreatePane(const Reference<XResourceId> & rxPaneId,const Reference<drawing::framework::XPane> & rxParentPane,const bool bIsSpritePane)223 Reference<XResource> PresenterPaneFactory::CreatePane (
224 const Reference<XResourceId>& rxPaneId,
225 const Reference<drawing::framework::XPane>& rxParentPane,
226 const bool bIsSpritePane)
227 {
228 Reference<XComponentContext> xContext (mxComponentContextWeak);
229 Reference<lang::XMultiComponentFactory> xFactory (
230 xContext->getServiceManager(), UNO_SET_THROW);
231
232 // Create a border window and canvas and store it in the pane
233 // container.
234
235 // Create the pane.
236 ::rtl::Reference<PresenterPaneBase> xPane;
237 if (bIsSpritePane)
238 {
239 xPane.set( new PresenterSpritePane(xContext, mpPresenterController));
240 }
241 else
242 {
243 xPane.set( new PresenterPane(xContext, mpPresenterController));
244 }
245
246 // Supply arguments.
247 Sequence<Any> aArguments (6);
248 aArguments[0] <<= rxPaneId;
249 aArguments[1] <<= rxParentPane->getWindow();
250 aArguments[2] <<= rxParentPane->getCanvas();
251 aArguments[3] <<= OUString();
252 aArguments[4] <<= Reference<drawing::framework::XPaneBorderPainter>(
253 static_cast<XWeak*>(mpPresenterController->GetPaneBorderPainter().get()),
254 UNO_QUERY);
255 aArguments[5] <<= !bIsSpritePane;
256 xPane->initialize(aArguments);
257
258 // Store pane and canvases and windows in container.
259 ::rtl::Reference<PresenterPaneContainer> pContainer (
260 mpPresenterController->GetPaneContainer());
261 PresenterPaneContainer::SharedPaneDescriptor pDescriptor(
262 pContainer->StoreBorderWindow(rxPaneId, xPane->GetBorderWindow()));
263 pContainer->StorePane(xPane);
264 if (pDescriptor)
265 {
266 pDescriptor->mbIsSprite = bIsSpritePane;
267
268 // Get the window of the frame and make that visible.
269 Reference<awt::XWindow> xWindow (pDescriptor->mxBorderWindow, UNO_SET_THROW);
270 xWindow->setVisible(true);
271 }
272
273 return Reference<XResource>(static_cast<XWeak*>(xPane.get()), UNO_QUERY_THROW);
274 }
275
ThrowIfDisposed() const276 void PresenterPaneFactory::ThrowIfDisposed() const
277 {
278 if (rBHelper.bDisposed || rBHelper.bInDispose)
279 {
280 throw lang::DisposedException (
281 "PresenterPaneFactory object has already been disposed",
282 const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
283 }
284 }
285
286 } // end of namespace sdext::presenter
287
288 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
289