LibreOffice Module sd (master) 1
PresenterPreviewCache.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
21
24#include <vcl/bitmapex.hxx>
25#include <sdpage.hxx>
28#include <com/sun/star/drawing/XDrawPage.hpp>
29#include <osl/diagnose.h>
30
31namespace com::sun::star::uno { class XComponentContext; }
32
33using namespace ::com::sun::star;
34using namespace ::com::sun::star::uno;
35using namespace ::sd::slidesorter::cache;
36
37namespace sd::presenter {
38
40{
41public:
43
45 const Reference<container::XIndexAccess>& rxSlides,
46 const Reference<XInterface>& rxDocument);
48 const sal_Int32 nFirstVisibleSlideIndex,
49 const sal_Int32 nLastVisibleSlideIndex);
50 const SdrPage* GetPage (const sal_Int32 nSlideIndex) const;
51 void AddPreviewCreationNotifyListener (const Reference<drawing::XSlidePreviewCacheListener>& rxListener);
52 void RemovePreviewCreationNotifyListener (const Reference<drawing::XSlidePreviewCacheListener>& rxListener);
53
54 // CacheContext
55 virtual void NotifyPreviewCreation (CacheKey aKey) override;
56 virtual bool IsIdle() override;
57 virtual bool IsVisible (CacheKey aKey) override;
58 virtual const SdrPage* GetPage (CacheKey aKey) override;
59 virtual std::shared_ptr<std::vector<CacheKey> > GetEntryList (bool bVisible) override;
60 virtual sal_Int32 GetPriority (CacheKey aKey) override;
61 virtual css::uno::Reference<css::uno::XInterface> GetModel() override;
62
63private:
64 Reference<container::XIndexAccess> mxSlides;
65 Reference<XInterface> mxDocument;
68 typedef ::std::vector<css::uno::Reference<css::drawing::XSlidePreviewCacheListener> > ListenerContainer;
70
71 void CallListeners (const sal_Int32 nSlideIndex);
72};
73
74//===== PresenterPreviewCache =================================================
75
77 : maPreviewSize(Size(200,200)),
78 mpCacheContext(std::make_shared<PresenterCacheContext>()),
79 mpCache(std::make_shared<PageCache>(maPreviewSize, Bitmap::HasFastScale(), mpCacheContext))
80{
81}
82
84{
85}
86
87//----- XInitialize -----------------------------------------------------------
88
89void SAL_CALL PresenterPreviewCache::initialize (const Sequence<Any>& rArguments)
90{
91 if (rArguments.hasElements())
92 throw RuntimeException();
93}
94
96 return "com.sun.star.comp.Draw.PresenterPreviewCache";
97}
98
99sal_Bool PresenterPreviewCache::supportsService(OUString const & ServiceName) {
101}
102
104 return {"com.sun.star.drawing.PresenterPreviewCache"};
105}
106
107//----- XSlidePreviewCache ----------------------------------------------------
108
110 const Reference<container::XIndexAccess>& rxSlides,
111 const Reference<XInterface>& rxDocument)
112{
114 OSL_ASSERT(mpCacheContext != nullptr);
115
116 mpCacheContext->SetDocumentSlides(rxSlides, rxDocument);
117}
118
120 sal_Int32 nFirstVisibleSlideIndex,
121 sal_Int32 nLastVisibleSlideIndex)
122{
124 OSL_ASSERT(mpCacheContext != nullptr);
125
126 mpCacheContext->SetVisibleSlideRange (nFirstVisibleSlideIndex, nLastVisibleSlideIndex);
127}
128
130 const css::geometry::IntegerSize2D& rSize)
131{
133 OSL_ASSERT(mpCache != nullptr);
134
135 maPreviewSize = Size(rSize.Width, rSize.Height);
137}
138
139Reference<rendering::XBitmap> SAL_CALL PresenterPreviewCache::getSlidePreview (
140 sal_Int32 nSlideIndex,
141 const Reference<rendering::XCanvas>& rxCanvas)
142{
144 OSL_ASSERT(mpCacheContext != nullptr);
145
148
149 const SdrPage* pPage = mpCacheContext->GetPage(nSlideIndex);
150 if (pPage == nullptr)
151 throw RuntimeException();
152
153 const BitmapEx aPreview (mpCache->GetPreviewBitmap(pPage,true));
154 if (aPreview.IsEmpty())
155 return nullptr;
156 else
158 pCanvas,
159 aPreview)->getUNOBitmap();
160}
161
163 const Reference<drawing::XSlidePreviewCacheListener>& rxListener)
164{
165 if (m_bDisposed)
166 return;
167 if (rxListener.is())
168 mpCacheContext->AddPreviewCreationNotifyListener(rxListener);
169}
170
172 const css::uno::Reference<css::drawing::XSlidePreviewCacheListener>& rxListener)
173{
175 mpCacheContext->RemovePreviewCreationNotifyListener(rxListener);
176}
177
179{
181 OSL_ASSERT(mpCache != nullptr);
182 mpCache->Pause();
183}
184
186{
188 OSL_ASSERT(mpCache != nullptr);
189 mpCache->Resume();
190}
191
193{
194 if (m_bDisposed)
195 {
196 throw lang::DisposedException ("PresenterPreviewCache object has already been disposed",
197 static_cast<uno::XWeak*>(this));
198 }
199}
200
201//===== PresenterPreviewCache::PresenterCacheContext ==========================
202
204 : mnFirstVisibleSlideIndex(-1),
205 mnLastVisibleSlideIndex(-1)
206{
207}
208
210 const Reference<container::XIndexAccess>& rxSlides,
211 const Reference<XInterface>& rxDocument)
212{
213 mxSlides = rxSlides;
214 mxDocument = rxDocument;
215 mnFirstVisibleSlideIndex = -1;
216 mnLastVisibleSlideIndex = -1;
217}
218
220 const sal_Int32 nFirstVisibleSlideIndex,
221 const sal_Int32 nLastVisibleSlideIndex)
222{
223 if (nFirstVisibleSlideIndex > nLastVisibleSlideIndex || nFirstVisibleSlideIndex<0)
224 {
225 mnFirstVisibleSlideIndex = -1;
226 mnLastVisibleSlideIndex = -1;
227 }
228 else
229 {
230 mnFirstVisibleSlideIndex = nFirstVisibleSlideIndex;
231 mnLastVisibleSlideIndex = nLastVisibleSlideIndex;
232 }
233 if (mxSlides.is() && mnLastVisibleSlideIndex >= mxSlides->getCount())
234 mnLastVisibleSlideIndex = mxSlides->getCount() - 1;
235}
236
238 const Reference<drawing::XSlidePreviewCacheListener>& rxListener)
239{
240 maListeners.push_back(rxListener);
241}
242
244 const Reference<drawing::XSlidePreviewCacheListener>& rxListener)
245{
246 auto iListener = std::find(maListeners.begin(), maListeners.end(), rxListener);
247 if (iListener != maListeners.end())
248 maListeners.erase(iListener);
249}
250
251//----- CacheContext ----------------------------------------------------------
252
254 CacheKey aKey)
255{
256 if ( ! mxSlides.is())
257 return;
258 const sal_Int32 nCount(mxSlides->getCount());
259 for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
260 if (aKey == GetPage(nIndex))
261 CallListeners(nIndex);
262}
263
265{
266 return true;
267}
268
270{
271 if (mnFirstVisibleSlideIndex < 0)
272 return false;
273 for (sal_Int32 nIndex=mnFirstVisibleSlideIndex; nIndex<=mnLastVisibleSlideIndex; ++nIndex)
274 {
275 const SdrPage* pPage = GetPage(nIndex);
276 if (pPage == aKey)
277 return true;
278 }
279 return false;
280}
281
283{
284 return aKey;
285}
286
287std::shared_ptr<std::vector<CacheKey> >
289{
290 auto pKeys = std::make_shared<std::vector<CacheKey>>();
291
292 if ( ! mxSlides.is())
293 return pKeys;
294
295 const sal_Int32 nFirstIndex (bVisible ? mnFirstVisibleSlideIndex : 0);
296 const sal_Int32 nLastIndex (bVisible ? mnLastVisibleSlideIndex : mxSlides->getCount()-1);
297
298 if (nFirstIndex < 0)
299 return pKeys;
300
301 for (sal_Int32 nIndex=nFirstIndex; nIndex<=nLastIndex; ++nIndex)
302 {
303 pKeys->push_back(GetPage(nIndex));
304 }
305
306 return pKeys;
307}
308
310{
311 if ( ! mxSlides.is())
312 return 0;
313
314 const sal_Int32 nCount (mxSlides->getCount());
315
316 for (sal_Int32 nIndex=mnFirstVisibleSlideIndex; nIndex<=mnLastVisibleSlideIndex; ++nIndex)
317 if (aKey == GetPage(nIndex))
318 return -nCount-1+nIndex;
319
320 for (sal_Int32 nIndex=0; nIndex<=nCount; ++nIndex)
321 if (aKey == GetPage(nIndex))
322 return nIndex;
323
324 return 0;
325}
326
328{
329 return mxDocument;
330}
331
333 const sal_Int32 nSlideIndex) const
334{
335 if ( ! mxSlides.is())
336 return nullptr;
337 if (nSlideIndex < 0 || nSlideIndex >= mxSlides->getCount())
338 return nullptr;
339
340 Reference<drawing::XDrawPage> xSlide (mxSlides->getByIndex(nSlideIndex), UNO_QUERY);
341 const SdPage* pPage = SdPage::getImplementation(xSlide);
342 return pPage;
343}
344
346 const sal_Int32 nIndex)
347{
348 ListenerContainer aListeners (maListeners);
349 for (const auto& rxListener : aListeners)
350 {
351 try
352 {
353 rxListener->notifyPreviewCreation(nIndex);
354 }
355 catch (lang::DisposedException&)
356 {
357 RemovePreviewCreationNotifyListener(rxListener);
358 }
359 }
360}
361
362} // end of namespace ::sd::presenter
363
364
365extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
367 css::uno::Sequence<css::uno::Any> const &)
368{
369 return cppu::acquire(new sd::presenter::PresenterPreviewCache);
370}
371
372
373/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_Draw_PresenterPreviewCache_get_implementation(css::uno::XComponentContext *, css::uno::Sequence< css::uno::Any > const &)
bool IsEmpty() const
static bool HasFastScale()
static SdPage * getImplementation(const css::uno::Reference< css::drawing::XDrawPage > &xPage)
returns the SdPage implementation for the given XDrawPage or 0 if not available
Definition: sdpage.cxx:2682
static BitmapSharedPtr createBitmap(const CanvasSharedPtr &, const ::BitmapEx &rBmpEx)
static CanvasSharedPtr createCanvas(const css::uno::Reference< css::rendering::XCanvas > &xCanvas)
const SdrPage * GetPage(const sal_Int32 nSlideIndex) const
void AddPreviewCreationNotifyListener(const Reference< drawing::XSlidePreviewCacheListener > &rxListener)
::std::vector< css::uno::Reference< css::drawing::XSlidePreviewCacheListener > > ListenerContainer
void RemovePreviewCreationNotifyListener(const Reference< drawing::XSlidePreviewCacheListener > &rxListener)
void SetDocumentSlides(const Reference< container::XIndexAccess > &rxSlides, const Reference< XInterface > &rxDocument)
virtual css::uno::Reference< css::uno::XInterface > GetModel() override
void SetVisibleSlideRange(const sal_Int32 nFirstVisibleSlideIndex, const sal_Int32 nLastVisibleSlideIndex)
virtual std::shared_ptr< std::vector< CacheKey > > GetEntryList(bool bVisible) override
Uno API wrapper around the slide preview cache.
virtual void SAL_CALL setVisibleRange(sal_Int32 nFirstVisibleSlideIndex, sal_Int32 nLastVisibleSlideIndex) override
OUString SAL_CALL getImplementationName() override
virtual void SAL_CALL initialize(const css::uno::Sequence< css::uno::Any > &rArguments) override
Accepts no arguments.
std::shared_ptr< sd::slidesorter::cache::PageCache > mpCache
virtual void SAL_CALL setDocumentSlides(const css::uno::Reference< css::container::XIndexAccess > &rxSlides, const css::uno::Reference< css::uno::XInterface > &rxDocument) override
std::shared_ptr< PresenterCacheContext > mpCacheContext
virtual void SAL_CALL setPreviewSize(const css::geometry::IntegerSize2D &rSize) override
virtual void SAL_CALL pause() override
css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
virtual css::uno::Reference< css::rendering::XBitmap > SAL_CALL getSlidePreview(sal_Int32 nSlideIndex, const css::uno::Reference< css::rendering::XCanvas > &rxCanvas) override
virtual void SAL_CALL addPreviewCreationNotifyListener(const css::uno::Reference< css::drawing::XSlidePreviewCacheListener > &rxListener) override
virtual void SAL_CALL resume() override
sal_Bool SAL_CALL supportsService(OUString const &ServiceName) override
virtual void SAL_CALL removePreviewCreationNotifyListener(const css::uno::Reference< css::drawing::XSlidePreviewCacheListener > &rxListener) override
int nCount
Listeners aListeners
sal_Int32 nIndex
std::shared_ptr< Canvas > CanvasSharedPtr
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
std::shared_ptr< T > make_shared(Args &&... args)
const SdrPage * CacheKey
bool bVisible
unsigned char sal_Bool