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