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  mxControllerWeak(rxController),
101  mpPresenterController(rpPresenterController)
102 {
103 }
104 
105 Reference<drawing::framework::XResourceFactory> PresenterViewFactory::Create (
106  const Reference<uno::XComponentContext>& rxContext,
107  const Reference<frame::XController>& rxController,
108  const ::rtl::Reference<PresenterController>& rpPresenterController)
109 {
111  new PresenterViewFactory(rxContext,rxController,rpPresenterController));
112  pFactory->Register(rxController);
113  return Reference<drawing::framework::XResourceFactory>(pFactory);
114 }
115 
116 void PresenterViewFactory::Register (const Reference<frame::XController>& rxController)
117 {
118  try
119  {
120  // Get the configuration controller.
121  Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW);
122  mxConfigurationController = xCM->getConfigurationController();
123  if ( ! mxConfigurationController.is())
124  {
125  throw RuntimeException();
126  }
127  mxConfigurationController->addResourceFactory(msCurrentSlidePreviewViewURL, this);
128  mxConfigurationController->addResourceFactory(msNextSlidePreviewViewURL, this);
129  mxConfigurationController->addResourceFactory(msNotesViewURL, this);
130  mxConfigurationController->addResourceFactory(msToolBarViewURL, this);
131  mxConfigurationController->addResourceFactory(msSlideSorterURL, this);
132  mxConfigurationController->addResourceFactory(msHelpViewURL, this);
133  }
134  catch (RuntimeException&)
135  {
136  OSL_ASSERT(false);
137  if (mxConfigurationController.is())
138  mxConfigurationController->removeResourceFactoryForReference(this);
139  mxConfigurationController = nullptr;
140 
141  throw;
142  }
143 }
144 
146 {
147 }
148 
150 {
151  if (mxConfigurationController.is())
152  mxConfigurationController->removeResourceFactoryForReference(this);
153  mxConfigurationController = nullptr;
154 
155  if (mpResourceCache == nullptr)
156  return;
157 
158  // Dispose all views in the cache.
159  for (const auto& rView : *mpResourceCache)
160  {
161  try
162  {
163  Reference<lang::XComponent> xComponent (rView.second.first, UNO_QUERY);
164  if (xComponent.is())
165  xComponent->dispose();
166  }
167  catch (lang::DisposedException&)
168  {
169  }
170  }
171  mpResourceCache.reset();
172 }
173 
174 //----- XViewFactory ----------------------------------------------------------
175 
176 Reference<XResource> SAL_CALL PresenterViewFactory::createResource (
177  const Reference<XResourceId>& rxViewId)
178 {
179  ThrowIfDisposed();
180 
181  Reference<XResource> xView;
182 
183  if (rxViewId.is())
184  {
185  Reference<XPane> xAnchorPane (
186  mxConfigurationController->getResource(rxViewId->getAnchor()),
187  UNO_QUERY_THROW);
188  xView = GetViewFromCache(rxViewId, xAnchorPane);
189  if (xView == nullptr)
190  xView = CreateView(rxViewId, xAnchorPane);
191 
192  // Activate the view.
194  mpPresenterController->GetPaneContainer()->FindPaneId(rxViewId->getAnchor()));
195  if (pDescriptor)
196  pDescriptor->SetActivationState(true);
197  }
198 
199  return xView;
200 }
201 
202 void SAL_CALL PresenterViewFactory::releaseResource (const Reference<XResource>& rxView)
203 {
204  ThrowIfDisposed();
205 
206  if ( ! rxView.is())
207  return;
208 
209  // Deactivate the view.
211  mpPresenterController->GetPaneContainer()->FindPaneId(
212  rxView->getResourceId()->getAnchor()));
213  if (pDescriptor)
214  pDescriptor->SetActivationState(false);
215 
216  // Dispose only views that we can not put into the cache.
217  CachablePresenterView* pView = dynamic_cast<CachablePresenterView*>(rxView.get());
218  if (pView == nullptr || mpResourceCache == nullptr)
219  {
220  try
221  {
222  if (pView != nullptr)
223  pView->ReleaseView();
224  Reference<lang::XComponent> xComponent (rxView, UNO_QUERY);
225  if (xComponent.is())
226  xComponent->dispose();
227  }
228  catch (lang::DisposedException&)
229  {
230  // Do not let disposed exceptions get out. It might be interpreted
231  // as coming from the factory, which would then be removed from the
232  // drawing framework.
233  }
234  }
235  else
236  {
237  // Put cacheable views in the cache.
238  Reference<XResourceId> xViewId (rxView->getResourceId());
239  if (xViewId.is())
240  {
241  Reference<XPane> xAnchorPane (
242  mxConfigurationController->getResource(xViewId->getAnchor()),
243  UNO_QUERY_THROW);
244  (*mpResourceCache)[xViewId->getResourceURL()]
245  = ViewResourceDescriptor(Reference<XView>(rxView, UNO_QUERY), xAnchorPane);
246  pView->DeactivatePresenterView();
247  }
248  }
249 }
250 
251 
253  const Reference<XResourceId>& rxViewId,
254  const Reference<XPane>& rxAnchorPane) const
255 {
256  if (mpResourceCache == nullptr)
257  return nullptr;
258 
259  try
260  {
261  const OUString sResourceURL (rxViewId->getResourceURL());
262 
263  // Can we use a view from the cache?
264  ResourceContainer::const_iterator iView (mpResourceCache->find(sResourceURL));
265  if (iView != mpResourceCache->end())
266  {
267  // The view is in the container but it can only be used if
268  // the anchor pane is the same now as it was at creation of
269  // the view.
270  if (iView->second.second == rxAnchorPane)
271  {
272  CachablePresenterView* pView
273  = dynamic_cast<CachablePresenterView*>(iView->second.first.get());
274  if (pView != nullptr)
275  pView->ActivatePresenterView();
276  return iView->second.first;
277  }
278 
279  // Right view, wrong pane. Create a new view.
280  }
281  }
282  catch (RuntimeException&)
283  {
284  }
285  return nullptr;
286 }
287 
288 Reference<XResource> PresenterViewFactory::CreateView(
289  const Reference<XResourceId>& rxViewId,
290  const Reference<XPane>& rxAnchorPane)
291 {
292  Reference<XView> xView;
293 
294  try
295  {
296  const OUString sResourceURL (rxViewId->getResourceURL());
297 
298  if (sResourceURL == msCurrentSlidePreviewViewURL)
299  {
300  xView = CreateSlideShowView(rxViewId);
301  }
302  else if (sResourceURL == msNotesViewURL)
303  {
304  xView = CreateNotesView(rxViewId);
305  }
306  else if (sResourceURL == msNextSlidePreviewViewURL)
307  {
308  xView = CreateSlidePreviewView(rxViewId, rxAnchorPane);
309  }
310  else if (sResourceURL == msToolBarViewURL)
311  {
312  xView = CreateToolBarView(rxViewId);
313  }
314  else if (sResourceURL == msSlideSorterURL)
315  {
316  xView = CreateSlideSorterView(rxViewId);
317  }
318  else if (sResourceURL == msHelpViewURL)
319  {
320  xView = CreateHelpView(rxViewId);
321  }
322 
323  // Activate it.
324  CachablePresenterView* pView = dynamic_cast<CachablePresenterView*>(xView.get());
325  if (pView != nullptr)
326  pView->ActivatePresenterView();
327  }
328  catch (RuntimeException&)
329  {
330  xView = nullptr;
331  }
332 
333  return xView;
334 }
335 
337  const Reference<XResourceId>& rxViewId) const
338 {
339  Reference<XView> xView;
340 
341  if ( ! mxConfigurationController.is())
342  return xView;
343  if ( ! mxComponentContext.is())
344  return xView;
345 
346  try
347  {
351  rxViewId,
352  Reference<frame::XController>(mxControllerWeak),
354  pShowView->LateInit();
355  xView = pShowView;
356  }
357  catch (RuntimeException&)
358  {
359  xView = nullptr;
360  }
361 
362  return xView;
363 }
364 
366  const Reference<XResourceId>& rxViewId,
367  const Reference<XPane>& rxAnchorPane) const
368 {
369  Reference<XView> xView;
370 
371  if ( ! mxConfigurationController.is())
372  return xView;
373  if ( ! mxComponentContext.is())
374  return xView;
375 
376  try
377  {
378  xView.set(
379  static_cast<XWeak*>(new NextSlidePreview(
381  rxViewId,
382  rxAnchorPane,
384  UNO_QUERY_THROW);
385  }
386  catch (RuntimeException&)
387  {
388  xView = nullptr;
389  }
390 
391  return xView;
392 }
393 
395  const Reference<XResourceId>& rxViewId) const
396 {
397  return new PresenterToolBarView(
399  rxViewId,
400  Reference<frame::XController>(mxControllerWeak),
402 }
403 
405  const Reference<XResourceId>& rxViewId) const
406 {
407  Reference<XView> xView;
408 
409  if ( ! mxConfigurationController.is())
410  return xView;
411  if ( ! mxComponentContext.is())
412  return xView;
413 
414  try
415  {
416  xView.set(static_cast<XWeak*>(
417  new PresenterNotesView(
419  rxViewId,
420  Reference<frame::XController>(mxControllerWeak),
422  UNO_QUERY_THROW);
423  }
424  catch (RuntimeException&)
425  {
426  xView = nullptr;
427  }
428 
429  return xView;
430 }
431 
433  const Reference<XResourceId>& rxViewId) const
434 {
435  Reference<XView> xView;
436 
437  if ( ! mxConfigurationController.is())
438  return xView;
439  if ( ! mxComponentContext.is())
440  return xView;
441 
442  try
443  {
447  rxViewId,
448  Reference<frame::XController>(mxControllerWeak),
450  xView = pView.get();
451  }
452  catch (RuntimeException&)
453  {
454  xView = nullptr;
455  }
456 
457  return xView;
458 }
459 
461  const Reference<XResourceId>& rxViewId) const
462 {
463  return Reference<XView>(new PresenterHelpView(
465  rxViewId,
466  Reference<frame::XController>(mxControllerWeak),
468 }
469 
471 {
472  if (rBHelper.bDisposed || rBHelper.bInDispose)
473  {
474  throw lang::DisposedException (
475  "PresenterViewFactory object has already been disposed",
476  const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
477  }
478 }
479 
480 //===== CachablePresenterView =================================================
481 
483  : mbIsPresenterViewActive(true)
484 {
485 }
486 
488 {
490 }
491 
493 {
494  mbIsPresenterViewActive = false;
495 }
496 
498 {
499 }
500 
501 }
502 
503 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_Int32 nIndex
static constexpr OUStringLiteral msCurrentSlidePreviewViewURL
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
std::mutex m_aMutex
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