LibreOffice Module sdext (master)  1
PresenterPaneFactory.cxx
Go to the documentation of this file.
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"
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 
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 {
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 
51  const Reference<uno::XComponentContext>& rxContext,
52  const ::rtl::Reference<PresenterController>& rpPresenterController)
54  mxComponentContextWeak(rxContext),
55  mxConfigurationControllerWeak(),
56  mpPresenterController(rpPresenterController),
57  mpResourceCache()
58 {
59 }
60 
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());
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 
90 {
91 }
92 
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 
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.
135  mpPresenterController->GetPaneContainer());
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 
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.
164  mpPresenterController->GetPaneContainer());
165  const OUString sPaneURL (rxResource->getResourceId()->getResourceURL());
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 
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 
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 
223 Reference<XResource> PresenterPaneFactory::CreatePane (
224  const Reference<XResourceId>& rxPaneId,
225  const Reference<drawing::framework::XPane>& rxParentPane,
226  const bool bIsSpritePane)
227 {
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.
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.
260  mpPresenterController->GetPaneContainer());
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 
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: */
osl::Mutex m_aMutex
::cppu::WeakComponentImplHelper< css::drawing::framework::XResourceFactory > PresenterPaneFactoryInterfaceBase
Sequence< PropertyValue > aArguments
PresenterPaneFactory(const css::uno::Reference< css::uno::XComponentContext > &rxContext, const ::rtl::Reference< PresenterController > &rpPresenterController)
virtual void SAL_CALL disposing() override
::rtl::Reference< PresenterController > mpPresenterController
std::unique_ptr< ResourceContainer > mpResourceCache
css::uno::Reference< css::drawing::framework::XResource > CreatePane(const css::uno::Reference< css::drawing::framework::XResourceId > &rxPaneId)
rtl::Reference< PresenterController > mpPresenterController
std::shared_ptr< PaneDescriptor > SharedPaneDescriptor
css::uno::WeakReference< css::uno::XComponentContext > mxComponentContextWeak
void Register(const css::uno::Reference< css::frame::XController > &rxController)
Reference< XSingleServiceFactory > xFactory
static css::uno::Reference< css::drawing::framework::XResourceFactory > Create(const css::uno::Reference< css::uno::XComponentContext > &rxContext, const css::uno::Reference< css::frame::XController > &rxController, const ::rtl::Reference< PresenterController > &rpPresenterController)
Create a new instance of this class and register it as resource factory in the drawing framework of t...
css::uno::WeakReference< css::drawing::framework::XConfigurationController > mxConfigurationControllerWeak
virtual void SAL_CALL releaseResource(const css::uno::Reference< css::drawing::framework::XResource > &rxPane) override
virtual css::uno::Reference< css::drawing::framework::XResource > SAL_CALL createResource(const css::uno::Reference< css::drawing::framework::XResourceId > &rxPaneId) override