LibreOffice Module sdext (master)  1
PresenterViewFactory.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 "PresenterViewFactory.hxx"
22 #include "PresenterHelpView.hxx"
23 #include "PresenterNotesView.hxx"
26 #include "PresenterSlideSorter.hxx"
27 #include "PresenterToolBar.hxx"
28 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
29 
30 using namespace ::com::sun::star;
31 using namespace ::com::sun::star::uno;
32 using namespace ::com::sun::star::drawing::framework;
33 
34 namespace sdext::presenter {
35 
36 namespace {
37 
42 class NextSlidePreview : public PresenterSlidePreview
43 {
44 public:
45  NextSlidePreview (
46  const css::uno::Reference<css::uno::XComponentContext>& rxContext,
47  const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId,
48  const css::uno::Reference<css::drawing::framework::XPane>& rxAnchorPane,
49  const ::rtl::Reference<PresenterController>& rpPresenterController)
50  : PresenterSlidePreview(rxContext, rxViewId, rxAnchorPane, rpPresenterController)
51  {
52  }
53 
54  virtual void SAL_CALL setCurrentPage (
55  const css::uno::Reference<css::drawing::XDrawPage>& rxSlide) override
56  {
57  Reference<presentation::XSlideShowController> xSlideShowController (
58  mpPresenterController->GetSlideShowController());
60  if (xSlideShowController.is())
61  {
62  const sal_Int32 nCount (xSlideShowController->getSlideCount());
63  sal_Int32 nNextSlideIndex (-1);
64  if (xSlideShowController->getCurrentSlide() == rxSlide)
65  {
66  nNextSlideIndex = xSlideShowController->getNextSlideIndex();
67  }
68  else
69  {
70  for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
71  {
72  if (rxSlide == xSlideShowController->getSlideByIndex(nIndex))
73  {
74  nNextSlideIndex = nIndex + 1;
75  }
76  }
77  }
78  if (nNextSlideIndex >= 0)
79  {
80  if (nNextSlideIndex < nCount)
81  {
82  xSlide = xSlideShowController->getSlideByIndex(nNextSlideIndex);
83  }
84  }
85  }
87  }
88 };
89 
90 } // end of anonymous namespace
91 
92 //===== PresenterViewFactory ==============================================
93 
95  const Reference<uno::XComponentContext>& rxContext,
96  const Reference<frame::XController>& rxController,
97  const ::rtl::Reference<PresenterController>& rpPresenterController)
99  mxComponentContext(rxContext),
100  mxConfigurationController(),
101  mxControllerWeak(rxController),
102  mpPresenterController(rpPresenterController),
103  mpResourceCache()
104 {
105 }
106 
107 Reference<drawing::framework::XResourceFactory> PresenterViewFactory::Create (
108  const Reference<uno::XComponentContext>& rxContext,
109  const Reference<frame::XController>& rxController,
110  const ::rtl::Reference<PresenterController>& rpPresenterController)
111 {
113  new PresenterViewFactory(rxContext,rxController,rpPresenterController));
114  pFactory->Register(rxController);
115  return Reference<drawing::framework::XResourceFactory>(
116  static_cast<XWeak*>(pFactory.get()), UNO_QUERY);
117 }
118 
119 void PresenterViewFactory::Register (const Reference<frame::XController>& rxController)
120 {
121  try
122  {
123  // Get the configuration controller.
124  Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW);
125  mxConfigurationController = xCM->getConfigurationController();
126  if ( ! mxConfigurationController.is())
127  {
128  throw RuntimeException();
129  }
130  mxConfigurationController->addResourceFactory(msCurrentSlidePreviewViewURL, this);
131  mxConfigurationController->addResourceFactory(msNextSlidePreviewViewURL, this);
132  mxConfigurationController->addResourceFactory(msNotesViewURL, this);
133  mxConfigurationController->addResourceFactory(msToolBarViewURL, this);
134  mxConfigurationController->addResourceFactory(msSlideSorterURL, this);
135  mxConfigurationController->addResourceFactory(msHelpViewURL, this);
136  }
137  catch (RuntimeException&)
138  {
139  OSL_ASSERT(false);
140  if (mxConfigurationController.is())
141  mxConfigurationController->removeResourceFactoryForReference(this);
142  mxConfigurationController = nullptr;
143 
144  throw;
145  }
146 }
147 
149 {
150 }
151 
153 {
154  if (mxConfigurationController.is())
155  mxConfigurationController->removeResourceFactoryForReference(this);
156  mxConfigurationController = nullptr;
157 
158  if (mpResourceCache == nullptr)
159  return;
160 
161  // Dispose all views in the cache.
162  for (const auto& rView : *mpResourceCache)
163  {
164  try
165  {
166  Reference<lang::XComponent> xComponent (rView.second.first, UNO_QUERY);
167  if (xComponent.is())
168  xComponent->dispose();
169  }
170  catch (lang::DisposedException&)
171  {
172  }
173  }
174  mpResourceCache.reset();
175 }
176 
177 //----- XViewFactory ----------------------------------------------------------
178 
179 Reference<XResource> SAL_CALL PresenterViewFactory::createResource (
180  const Reference<XResourceId>& rxViewId)
181 {
182  ThrowIfDisposed();
183 
184  Reference<XResource> xView;
185 
186  if (rxViewId.is())
187  {
188  Reference<XPane> xAnchorPane (
189  mxConfigurationController->getResource(rxViewId->getAnchor()),
190  UNO_QUERY_THROW);
191  xView = GetViewFromCache(rxViewId, xAnchorPane);
192  if (xView == nullptr)
193  xView = CreateView(rxViewId, xAnchorPane);
194 
195  // Activate the view.
197  mpPresenterController->GetPaneContainer()->FindPaneId(rxViewId->getAnchor()));
198  if (pDescriptor)
199  pDescriptor->SetActivationState(true);
200  }
201 
202  return xView;
203 }
204 
205 void SAL_CALL PresenterViewFactory::releaseResource (const Reference<XResource>& rxView)
206 {
207  ThrowIfDisposed();
208 
209  if ( ! rxView.is())
210  return;
211 
212  // Deactivate the view.
214  mpPresenterController->GetPaneContainer()->FindPaneId(
215  rxView->getResourceId()->getAnchor()));
216  if (pDescriptor)
217  pDescriptor->SetActivationState(false);
218 
219  // Dispose only views that we can not put into the cache.
220  CachablePresenterView* pView = dynamic_cast<CachablePresenterView*>(rxView.get());
221  if (pView == nullptr || mpResourceCache == nullptr)
222  {
223  try
224  {
225  if (pView != nullptr)
226  pView->ReleaseView();
227  Reference<lang::XComponent> xComponent (rxView, UNO_QUERY);
228  if (xComponent.is())
229  xComponent->dispose();
230  }
231  catch (lang::DisposedException&)
232  {
233  // Do not let disposed exceptions get out. It might be interpreted
234  // as coming from the factory, which would then be removed from the
235  // drawing framework.
236  }
237  }
238  else
239  {
240  // Put cacheable views in the cache.
241  Reference<XResourceId> xViewId (rxView->getResourceId());
242  if (xViewId.is())
243  {
244  Reference<XPane> xAnchorPane (
245  mxConfigurationController->getResource(xViewId->getAnchor()),
246  UNO_QUERY_THROW);
247  (*mpResourceCache)[xViewId->getResourceURL()]
248  = ViewResourceDescriptor(Reference<XView>(rxView, UNO_QUERY), xAnchorPane);
249  pView->DeactivatePresenterView();
250  }
251  }
252 }
253 
254 
256  const Reference<XResourceId>& rxViewId,
257  const Reference<XPane>& rxAnchorPane) const
258 {
259  if (mpResourceCache == nullptr)
260  return nullptr;
261 
262  try
263  {
264  const OUString sResourceURL (rxViewId->getResourceURL());
265 
266  // Can we use a view from the cache?
267  ResourceContainer::const_iterator iView (mpResourceCache->find(sResourceURL));
268  if (iView != mpResourceCache->end())
269  {
270  // The view is in the container but it can only be used if
271  // the anchor pane is the same now as it was at creation of
272  // the view.
273  if (iView->second.second == rxAnchorPane)
274  {
275  CachablePresenterView* pView
276  = dynamic_cast<CachablePresenterView*>(iView->second.first.get());
277  if (pView != nullptr)
278  pView->ActivatePresenterView();
279  return iView->second.first;
280  }
281 
282  // Right view, wrong pane. Create a new view.
283  }
284  }
285  catch (RuntimeException&)
286  {
287  }
288  return nullptr;
289 }
290 
291 Reference<XResource> PresenterViewFactory::CreateView(
292  const Reference<XResourceId>& rxViewId,
293  const Reference<XPane>& rxAnchorPane)
294 {
295  Reference<XView> xView;
296 
297  try
298  {
299  const OUString sResourceURL (rxViewId->getResourceURL());
300 
301  if (sResourceURL == msCurrentSlidePreviewViewURL)
302  {
303  xView = CreateSlideShowView(rxViewId);
304  }
305  else if (sResourceURL == msNotesViewURL)
306  {
307  xView = CreateNotesView(rxViewId);
308  }
309  else if (sResourceURL == msNextSlidePreviewViewURL)
310  {
311  xView = CreateSlidePreviewView(rxViewId, rxAnchorPane);
312  }
313  else if (sResourceURL == msToolBarViewURL)
314  {
315  xView = CreateToolBarView(rxViewId);
316  }
317  else if (sResourceURL == msSlideSorterURL)
318  {
319  xView = CreateSlideSorterView(rxViewId);
320  }
321  else if (sResourceURL == msHelpViewURL)
322  {
323  xView = CreateHelpView(rxViewId);
324  }
325 
326  // Activate it.
327  CachablePresenterView* pView = dynamic_cast<CachablePresenterView*>(xView.get());
328  if (pView != nullptr)
329  pView->ActivatePresenterView();
330  }
331  catch (RuntimeException&)
332  {
333  xView = nullptr;
334  }
335 
336  return xView;
337 }
338 
340  const Reference<XResourceId>& rxViewId) const
341 {
342  Reference<XView> xView;
343 
344  if ( ! mxConfigurationController.is())
345  return xView;
346  if ( ! mxComponentContext.is())
347  return xView;
348 
349  try
350  {
354  rxViewId,
355  Reference<frame::XController>(mxControllerWeak),
357  pShowView->LateInit();
358  xView.set(pShowView.get());
359  }
360  catch (RuntimeException&)
361  {
362  xView = nullptr;
363  }
364 
365  return xView;
366 }
367 
369  const Reference<XResourceId>& rxViewId,
370  const Reference<XPane>& rxAnchorPane) const
371 {
372  Reference<XView> xView;
373 
374  if ( ! mxConfigurationController.is())
375  return xView;
376  if ( ! mxComponentContext.is())
377  return xView;
378 
379  try
380  {
381  xView.set(
382  static_cast<XWeak*>(new NextSlidePreview(
384  rxViewId,
385  rxAnchorPane,
387  UNO_QUERY_THROW);
388  }
389  catch (RuntimeException&)
390  {
391  xView = nullptr;
392  }
393 
394  return xView;
395 }
396 
398  const Reference<XResourceId>& rxViewId) const
399 {
400  return new PresenterToolBarView(
402  rxViewId,
403  Reference<frame::XController>(mxControllerWeak),
405 }
406 
408  const Reference<XResourceId>& rxViewId) const
409 {
410  Reference<XView> xView;
411 
412  if ( ! mxConfigurationController.is())
413  return xView;
414  if ( ! mxComponentContext.is())
415  return xView;
416 
417  try
418  {
419  xView.set(static_cast<XWeak*>(
420  new PresenterNotesView(
422  rxViewId,
423  Reference<frame::XController>(mxControllerWeak),
425  UNO_QUERY_THROW);
426  }
427  catch (RuntimeException&)
428  {
429  xView = nullptr;
430  }
431 
432  return xView;
433 }
434 
436  const Reference<XResourceId>& rxViewId) const
437 {
438  Reference<XView> xView;
439 
440  if ( ! mxConfigurationController.is())
441  return xView;
442  if ( ! mxComponentContext.is())
443  return xView;
444 
445  try
446  {
450  rxViewId,
451  Reference<frame::XController>(mxControllerWeak),
453  xView = pView.get();
454  }
455  catch (RuntimeException&)
456  {
457  xView = nullptr;
458  }
459 
460  return xView;
461 }
462 
464  const Reference<XResourceId>& rxViewId) const
465 {
466  return Reference<XView>(new PresenterHelpView(
468  rxViewId,
469  Reference<frame::XController>(mxControllerWeak),
471 }
472 
474 {
475  if (rBHelper.bDisposed || rBHelper.bInDispose)
476  {
477  throw lang::DisposedException (
478  "PresenterViewFactory object has already been disposed",
479  const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
480  }
481 }
482 
483 //===== CachablePresenterView =================================================
484 
486  : mbIsPresenterViewActive(true)
487 {
488 }
489 
491 {
493 }
494 
496 {
497  mbIsPresenterViewActive = false;
498 }
499 
501 {
502 }
503 
504 }
505 
506 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_Int32 nIndex
static constexpr OUStringLiteral msCurrentSlidePreviewViewURL
osl::Mutex m_aMutex
css::uno::Reference< css::drawing::framework::XConfigurationController > mxConfigurationController
::std::pair< css::uno::Reference< css::drawing::framework::XView >, css::uno::Reference< css::drawing::framework::XPane > > ViewResourceDescriptor
virtual css::uno::Reference< css::drawing::framework::XResource > SAL_CALL createResource(const css::uno::Reference< css::drawing::framework::XResourceId > &rxViewId) override
static constexpr OUStringLiteral msNotesViewURL
css::uno::Reference< css::drawing::framework::XView > CreateToolBarView(const css::uno::Reference< css::drawing::framework::XResourceId > &rxViewId) const
css::uno::Reference< css::drawing::framework::XView > CreateNotesView(const css::uno::Reference< css::drawing::framework::XResourceId > &rxViewId) const
css::uno::WeakReference< css::frame::XController > mxControllerWeak
static constexpr OUStringLiteral msNextSlidePreviewViewURL
css::uno::Reference< css::drawing::framework::XResource > CreateView(const css::uno::Reference< css::drawing::framework::XResourceId > &rxViewId, const css::uno::Reference< css::drawing::framework::XPane > &rxAnchorPane)
::cppu::WeakComponentImplHelper< css::drawing::framework::XResourceFactory > PresenterViewFactoryInterfaceBase
int nCount
virtual void SAL_CALL disposing() override
static constexpr OUStringLiteral msToolBarViewURL
css::uno::Reference< css::drawing::framework::XResource > GetViewFromCache(const css::uno::Reference< css::drawing::framework::XResourceId > &rxViewId, const css::uno::Reference< css::drawing::framework::XPane > &rxAnchorPane) const
View for the PresenterToolBar.
A drawing framework view of the notes of a slide.
void Register(const css::uno::Reference< css::frame::XController > &rxController)
css::uno::Reference< css::uno::XComponentContext > mxComponentContext
css::uno::Reference< css::drawing::framework::XView > CreateHelpView(const css::uno::Reference< css::drawing::framework::XResourceId > &rxViewId) const
std::unique_ptr< ResourceContainer > mpResourceCache
Show help text that describes the defined keys.
virtual void SAL_CALL setCurrentPage(const css::uno::Reference< css::drawing::XDrawPage > &rxSlide) override
css::uno::Reference< css::drawing::framework::XView > CreateSlidePreviewView(const css::uno::Reference< css::drawing::framework::XResourceId > &rxViewId, const css::uno::Reference< css::drawing::framework::XPane > &rxPane) const
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...
rtl::Reference< PresenterController > mpPresenterController
A simple slide sorter for the presenter screen.
::rtl::Reference< PresenterController > mpPresenterController
css::uno::Reference< css::uno::XComponentContext > mxComponentContext
PresenterViewFactory(const css::uno::Reference< css::uno::XComponentContext > &rxContext, const css::uno::Reference< css::frame::XController > &rxController, const ::rtl::Reference< PresenterController > &rpPresenterController)
std::shared_ptr< PaneDescriptor > SharedPaneDescriptor
virtual void SAL_CALL releaseResource(const css::uno::Reference< css::drawing::framework::XResource > &rxPane) override
Life view in a secondary window of a full screen slide show.
virtual void ReleaseView()
Called before the view is disposed.
static constexpr OUStringLiteral msHelpViewURL
static constexpr OUStringLiteral msSlideSorterURL
css::uno::Reference< css::drawing::framework::XView > CreateSlideShowView(const css::uno::Reference< css::drawing::framework::XResourceId > &rxViewId) const
Base class for presenter views that allows the view factory to store them in a cache and reuse deacti...
virtual void DeactivatePresenterView()
Called when the view is put into a cache.
css::uno::Reference< css::drawing::framework::XView > CreateSlideSorterView(const css::uno::Reference< css::drawing::framework::XResourceId > &rxViewId) const