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 
37  "private:resource/view/Presenter/CurrentSlidePreview");
39  "private:resource/view/Presenter/NextSlidePreview");
41  "private:resource/view/Presenter/Notes");
43  "private:resource/view/Presenter/ToolBar");
45  "private:resource/view/Presenter/SlideSorter");
47  "private:resource/view/Presenter/Help");
48 
49 namespace {
50 
55 class NextSlidePreview : public PresenterSlidePreview
56 {
57 public:
58  NextSlidePreview (
59  const css::uno::Reference<css::uno::XComponentContext>& rxContext,
60  const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId,
61  const css::uno::Reference<css::drawing::framework::XPane>& rxAnchorPane,
62  const ::rtl::Reference<PresenterController>& rpPresenterController)
63  : PresenterSlidePreview(rxContext, rxViewId, rxAnchorPane, rpPresenterController)
64  {
65  }
66 
67  virtual void SAL_CALL setCurrentPage (
68  const css::uno::Reference<css::drawing::XDrawPage>& rxSlide) override
69  {
70  Reference<presentation::XSlideShowController> xSlideShowController (
71  mpPresenterController->GetSlideShowController());
73  if (xSlideShowController.is())
74  {
75  const sal_Int32 nCount (xSlideShowController->getSlideCount());
76  sal_Int32 nNextSlideIndex (-1);
77  if (xSlideShowController->getCurrentSlide() == rxSlide)
78  {
79  nNextSlideIndex = xSlideShowController->getNextSlideIndex();
80  }
81  else
82  {
83  for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
84  {
85  if (rxSlide == xSlideShowController->getSlideByIndex(nIndex))
86  {
87  nNextSlideIndex = nIndex + 1;
88  }
89  }
90  }
91  if (nNextSlideIndex >= 0)
92  {
93  if (nNextSlideIndex < nCount)
94  {
95  xSlide = xSlideShowController->getSlideByIndex(nNextSlideIndex);
96  }
97  }
98  }
100  }
101 };
102 
103 } // end of anonymous namespace
104 
105 //===== PresenterViewFactory ==============================================
106 
108  const Reference<uno::XComponentContext>& rxContext,
109  const Reference<frame::XController>& rxController,
110  const ::rtl::Reference<PresenterController>& rpPresenterController)
112  mxComponentContext(rxContext),
113  mxConfigurationController(),
114  mxControllerWeak(rxController),
115  mpPresenterController(rpPresenterController),
116  mpResourceCache()
117 {
118 }
119 
120 Reference<drawing::framework::XResourceFactory> PresenterViewFactory::Create (
121  const Reference<uno::XComponentContext>& rxContext,
122  const Reference<frame::XController>& rxController,
123  const ::rtl::Reference<PresenterController>& rpPresenterController)
124 {
126  new PresenterViewFactory(rxContext,rxController,rpPresenterController));
127  pFactory->Register(rxController);
128  return Reference<drawing::framework::XResourceFactory>(
129  static_cast<XWeak*>(pFactory.get()), UNO_QUERY);
130 }
131 
132 void PresenterViewFactory::Register (const Reference<frame::XController>& rxController)
133 {
134  try
135  {
136  // Get the configuration controller.
137  Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW);
138  mxConfigurationController = xCM->getConfigurationController();
139  if ( ! mxConfigurationController.is())
140  {
141  throw RuntimeException();
142  }
143  mxConfigurationController->addResourceFactory(msCurrentSlidePreviewViewURL, this);
144  mxConfigurationController->addResourceFactory(msNextSlidePreviewViewURL, this);
145  mxConfigurationController->addResourceFactory(msNotesViewURL, this);
146  mxConfigurationController->addResourceFactory(msToolBarViewURL, this);
147  mxConfigurationController->addResourceFactory(msSlideSorterURL, this);
148  mxConfigurationController->addResourceFactory(msHelpViewURL, this);
149  }
150  catch (RuntimeException&)
151  {
152  OSL_ASSERT(false);
153  if (mxConfigurationController.is())
154  mxConfigurationController->removeResourceFactoryForReference(this);
155  mxConfigurationController = nullptr;
156 
157  throw;
158  }
159 }
160 
162 {
163 }
164 
166 {
167  if (mxConfigurationController.is())
168  mxConfigurationController->removeResourceFactoryForReference(this);
169  mxConfigurationController = nullptr;
170 
171  if (mpResourceCache == nullptr)
172  return;
173 
174  // Dispose all views in the cache.
175  for (const auto& rView : *mpResourceCache)
176  {
177  try
178  {
179  Reference<lang::XComponent> xComponent (rView.second.first, UNO_QUERY);
180  if (xComponent.is())
181  xComponent->dispose();
182  }
183  catch (lang::DisposedException&)
184  {
185  }
186  }
187  mpResourceCache.reset();
188 }
189 
190 //----- XViewFactory ----------------------------------------------------------
191 
192 Reference<XResource> SAL_CALL PresenterViewFactory::createResource (
193  const Reference<XResourceId>& rxViewId)
194 {
195  ThrowIfDisposed();
196 
197  Reference<XResource> xView;
198 
199  if (rxViewId.is())
200  {
201  Reference<XPane> xAnchorPane (
202  mxConfigurationController->getResource(rxViewId->getAnchor()),
203  UNO_QUERY_THROW);
204  xView = GetViewFromCache(rxViewId, xAnchorPane);
205  if (xView == nullptr)
206  xView = CreateView(rxViewId, xAnchorPane);
207 
208  // Activate the view.
210  mpPresenterController->GetPaneContainer()->FindPaneId(rxViewId->getAnchor()));
211  if (pDescriptor.get() != nullptr)
212  pDescriptor->SetActivationState(true);
213  }
214 
215  return xView;
216 }
217 
218 void SAL_CALL PresenterViewFactory::releaseResource (const Reference<XResource>& rxView)
219 {
220  ThrowIfDisposed();
221 
222  if ( ! rxView.is())
223  return;
224 
225  // Deactivate the view.
227  mpPresenterController->GetPaneContainer()->FindPaneId(
228  rxView->getResourceId()->getAnchor()));
229  if (pDescriptor.get() != nullptr)
230  pDescriptor->SetActivationState(false);
231 
232  // Dispose only views that we can not put into the cache.
233  CachablePresenterView* pView = dynamic_cast<CachablePresenterView*>(rxView.get());
234  if (pView == nullptr || mpResourceCache == nullptr)
235  {
236  try
237  {
238  if (pView != nullptr)
239  pView->ReleaseView();
240  Reference<lang::XComponent> xComponent (rxView, UNO_QUERY);
241  if (xComponent.is())
242  xComponent->dispose();
243  }
244  catch (lang::DisposedException&)
245  {
246  // Do not let disposed exceptions get out. It might be interpreted
247  // as coming from the factory, which would then be removed from the
248  // drawing framework.
249  }
250  }
251  else
252  {
253  // Put cacheable views in the cache.
254  Reference<XResourceId> xViewId (rxView->getResourceId());
255  if (xViewId.is())
256  {
257  Reference<XPane> xAnchorPane (
258  mxConfigurationController->getResource(xViewId->getAnchor()),
259  UNO_QUERY_THROW);
260  (*mpResourceCache)[xViewId->getResourceURL()]
261  = ViewResourceDescriptor(Reference<XView>(rxView, UNO_QUERY), xAnchorPane);
262  pView->DeactivatePresenterView();
263  }
264  }
265 }
266 
267 
269  const Reference<XResourceId>& rxViewId,
270  const Reference<XPane>& rxAnchorPane) const
271 {
272  if (mpResourceCache == nullptr)
273  return nullptr;
274 
275  try
276  {
277  const OUString sResourceURL (rxViewId->getResourceURL());
278 
279  // Can we use a view from the cache?
280  ResourceContainer::const_iterator iView (mpResourceCache->find(sResourceURL));
281  if (iView != mpResourceCache->end())
282  {
283  // The view is in the container but it can only be used if
284  // the anchor pane is the same now as it was at creation of
285  // the view.
286  if (iView->second.second == rxAnchorPane)
287  {
288  CachablePresenterView* pView
289  = dynamic_cast<CachablePresenterView*>(iView->second.first.get());
290  if (pView != nullptr)
291  pView->ActivatePresenterView();
292  return Reference<XResource>(iView->second.first, UNO_QUERY);
293  }
294 
295  // Right view, wrong pane. Create a new view.
296  }
297  }
298  catch (RuntimeException&)
299  {
300  }
301  return nullptr;
302 }
303 
304 Reference<XResource> PresenterViewFactory::CreateView(
305  const Reference<XResourceId>& rxViewId,
306  const Reference<XPane>& rxAnchorPane)
307 {
308  Reference<XView> xView;
309 
310  try
311  {
312  const OUString sResourceURL (rxViewId->getResourceURL());
313 
314  if (sResourceURL == msCurrentSlidePreviewViewURL)
315  {
316  xView = CreateSlideShowView(rxViewId);
317  }
318  else if (sResourceURL == msNotesViewURL)
319  {
320  xView = CreateNotesView(rxViewId);
321  }
322  else if (sResourceURL == msNextSlidePreviewViewURL)
323  {
324  xView = CreateSlidePreviewView(rxViewId, rxAnchorPane);
325  }
326  else if (sResourceURL == msToolBarViewURL)
327  {
328  xView = CreateToolBarView(rxViewId);
329  }
330  else if (sResourceURL == msSlideSorterURL)
331  {
332  xView = CreateSlideSorterView(rxViewId);
333  }
334  else if (sResourceURL == msHelpViewURL)
335  {
336  xView = CreateHelpView(rxViewId);
337  }
338 
339  // Activate it.
340  CachablePresenterView* pView = dynamic_cast<CachablePresenterView*>(xView.get());
341  if (pView != nullptr)
342  pView->ActivatePresenterView();
343  }
344  catch (RuntimeException&)
345  {
346  xView = nullptr;
347  }
348 
349  return xView;
350 }
351 
353  const Reference<XResourceId>& rxViewId) const
354 {
355  Reference<XView> xView;
356 
357  if ( ! mxConfigurationController.is())
358  return xView;
359  if ( ! mxComponentContext.is())
360  return xView;
361 
362  try
363  {
367  rxViewId,
368  Reference<frame::XController>(mxControllerWeak),
370  pShowView->LateInit();
371  xView.set(pShowView.get());
372  }
373  catch (RuntimeException&)
374  {
375  xView = nullptr;
376  }
377 
378  return xView;
379 }
380 
382  const Reference<XResourceId>& rxViewId,
383  const Reference<XPane>& rxAnchorPane) const
384 {
385  Reference<XView> xView;
386 
387  if ( ! mxConfigurationController.is())
388  return xView;
389  if ( ! mxComponentContext.is())
390  return xView;
391 
392  try
393  {
394  xView.set(
395  static_cast<XWeak*>(new NextSlidePreview(
397  rxViewId,
398  rxAnchorPane,
400  UNO_QUERY_THROW);
401  }
402  catch (RuntimeException&)
403  {
404  xView = nullptr;
405  }
406 
407  return xView;
408 }
409 
411  const Reference<XResourceId>& rxViewId) const
412 {
413  return new PresenterToolBarView(
415  rxViewId,
416  Reference<frame::XController>(mxControllerWeak),
418 }
419 
421  const Reference<XResourceId>& rxViewId) const
422 {
423  Reference<XView> xView;
424 
425  if ( ! mxConfigurationController.is())
426  return xView;
427  if ( ! mxComponentContext.is())
428  return xView;
429 
430  try
431  {
432  xView.set(static_cast<XWeak*>(
433  new PresenterNotesView(
435  rxViewId,
436  Reference<frame::XController>(mxControllerWeak),
438  UNO_QUERY_THROW);
439  }
440  catch (RuntimeException&)
441  {
442  xView = nullptr;
443  }
444 
445  return xView;
446 }
447 
449  const Reference<XResourceId>& rxViewId) const
450 {
451  Reference<XView> xView;
452 
453  if ( ! mxConfigurationController.is())
454  return xView;
455  if ( ! mxComponentContext.is())
456  return xView;
457 
458  try
459  {
463  rxViewId,
464  Reference<frame::XController>(mxControllerWeak),
466  xView = pView.get();
467  }
468  catch (RuntimeException&)
469  {
470  xView = nullptr;
471  }
472 
473  return xView;
474 }
475 
477  const Reference<XResourceId>& rxViewId) const
478 {
479  return Reference<XView>(new PresenterHelpView(
481  rxViewId,
482  Reference<frame::XController>(mxControllerWeak),
484 }
485 
487 {
488  if (rBHelper.bDisposed || rBHelper.bInDispose)
489  {
490  throw lang::DisposedException (
491  "PresenterViewFactory object has already been disposed",
492  const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
493  }
494 }
495 
496 //===== CachablePresenterView =================================================
497 
499  : mbIsPresenterViewActive(true)
500 {
501 }
502 
504 {
506 }
507 
509 {
510  mbIsPresenterViewActive = false;
511 }
512 
514 {
515 }
516 
517 }
518 
519 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_Int32 nIndex
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
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
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
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
css::uno::Reference< css::lang::XComponent > xComponent
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.
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