xref: /trunk/main/sd/source/ui/presenter/PresenterPreviewCache.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 // MARKER(update_precomp.py): autogen include statement, do not remove
24 #include "precompiled_sd.hxx"
25 
26 #include "precompiled_sd.hxx"
27 
28 #include "PresenterPreviewCache.hxx"
29 
30 #include "cache/SlsCacheContext.hxx"
31 #include "tools/IdleDetection.hxx"
32 #include "sdpage.hxx"
33 #include <cppcanvas/vclfactory.hxx>
34 #include <com/sun/star/drawing/XDrawPage.hpp>
35 #include <com/sun/star/rendering/XBitmapCanvas.hpp>
36 
37 using namespace ::com::sun::star;
38 using namespace ::com::sun::star::uno;
39 using namespace ::sd::slidesorter::cache;
40 using ::rtl::OUString;
41 
42 namespace sd { namespace presenter {
43 
44 
45 class PresenterPreviewCache::PresenterCacheContext : public CacheContext
46 {
47 public:
48     PresenterCacheContext (void);
49     virtual ~PresenterCacheContext (void);
50 
51     void SetDocumentSlides (
52         const Reference<container::XIndexAccess>& rxSlides,
53         const Reference<XInterface>& rxDocument);
54     void SetVisibleSlideRange (
55         const sal_Int32 nFirstVisibleSlideIndex,
56         const sal_Int32 nLastVisibleSlideIndex);
57     const SdrPage* GetPage (const sal_Int32 nSlideIndex) const;
58     void AddPreviewCreationNotifyListener (const Reference<drawing::XSlidePreviewCacheListener>& rxListener);
59     void RemovePreviewCreationNotifyListener (const Reference<drawing::XSlidePreviewCacheListener>& rxListener);
60 
61     // CacheContext
62     virtual void NotifyPreviewCreation (
63         CacheKey aKey,
64         const Bitmap& rPreview);
65     virtual bool IsIdle (void);
66     virtual bool IsVisible (CacheKey aKey);
67     virtual const SdrPage* GetPage (CacheKey aKey);
68     virtual ::boost::shared_ptr<std::vector<CacheKey> > GetEntryList (bool bVisible);
69     virtual sal_Int32 GetPriority (CacheKey aKey);
70     virtual ::com::sun::star::uno::Reference<com::sun::star::uno::XInterface> GetModel (void);
71 
72 private:
73     Reference<container::XIndexAccess> mxSlides;
74     Reference<XInterface> mxDocument;
75     sal_Int32 mnFirstVisibleSlideIndex;
76     sal_Int32 mnLastVisibleSlideIndex;
77     typedef ::std::vector<css::uno::Reference<css::drawing::XSlidePreviewCacheListener> > ListenerContainer;
78     ListenerContainer maListeners;
79 
80     void CallListeners (const sal_Int32 nSlideIndex);
81 };
82 
83 
84 
85 
86 //===== Service ===============================================================
87 
PresenterPreviewCache_createInstance(const Reference<XComponentContext> & rxContext)88 Reference<XInterface> SAL_CALL PresenterPreviewCache_createInstance (
89     const Reference<XComponentContext>& rxContext)
90 {
91     return Reference<XInterface>(static_cast<XWeak*>(new PresenterPreviewCache(rxContext)));
92 }
93 
94 
95 
96 
PresenterPreviewCache_getImplementationName(void)97 ::rtl::OUString PresenterPreviewCache_getImplementationName (void)
98 {
99     return OUString::createFromAscii("com.sun.star.comp.Draw.PresenterPreviewCache");
100 }
101 
102 
103 
104 
PresenterPreviewCache_getSupportedServiceNames(void)105 Sequence<rtl::OUString> SAL_CALL PresenterPreviewCache_getSupportedServiceNames (void)
106 {
107     static const ::rtl::OUString sServiceName(
108         ::rtl::OUString::createFromAscii("com.sun.star.drawing.PresenterPreviewCache"));
109     return Sequence<rtl::OUString>(&sServiceName, 1);
110 }
111 
112 
113 
114 
115 //===== PresenterPreviewCache =================================================
116 
PresenterPreviewCache(const Reference<XComponentContext> & rxContext)117 PresenterPreviewCache::PresenterPreviewCache (const Reference<XComponentContext>& rxContext)
118     : PresenterPreviewCacheInterfaceBase(m_aMutex),
119       maPreviewSize(Size(200,200)),
120       mpCacheContext(new PresenterCacheContext()),
121       mpCache(new PageCache(maPreviewSize, false, mpCacheContext))
122 {
123     (void)rxContext;
124 }
125 
126 
127 
128 
~PresenterPreviewCache(void)129 PresenterPreviewCache::~PresenterPreviewCache (void)
130 {
131 }
132 
133 
134 
135 
136 //----- XInitialize -----------------------------------------------------------
137 
initialize(const Sequence<Any> & rArguments)138 void SAL_CALL PresenterPreviewCache::initialize (const Sequence<Any>& rArguments)
139 {
140     if (rArguments.getLength() != 0)
141         throw RuntimeException();
142 }
143 
144 
145 
146 
147 //----- XSlidePreviewCache ----------------------------------------------------
148 
setDocumentSlides(const Reference<container::XIndexAccess> & rxSlides,const Reference<XInterface> & rxDocument)149 void SAL_CALL PresenterPreviewCache::setDocumentSlides (
150     const Reference<container::XIndexAccess>& rxSlides,
151     const Reference<XInterface>& rxDocument)
152 {
153     ThrowIfDisposed();
154     OSL_ASSERT(mpCacheContext.get()!=NULL);
155 
156     mpCacheContext->SetDocumentSlides(rxSlides, rxDocument);
157 }
158 
159 
160 
161 
setVisibleRange(sal_Int32 nFirstVisibleSlideIndex,sal_Int32 nLastVisibleSlideIndex)162 void SAL_CALL PresenterPreviewCache::setVisibleRange (
163     sal_Int32 nFirstVisibleSlideIndex,
164     sal_Int32 nLastVisibleSlideIndex)
165 {
166     ThrowIfDisposed();
167     OSL_ASSERT(mpCacheContext.get()!=NULL);
168 
169     mpCacheContext->SetVisibleSlideRange (nFirstVisibleSlideIndex, nLastVisibleSlideIndex);
170 }
171 
172 
173 
174 
setPreviewSize(const css::geometry::IntegerSize2D & rSize)175 void SAL_CALL PresenterPreviewCache::setPreviewSize (
176     const css::geometry::IntegerSize2D& rSize)
177 {
178     ThrowIfDisposed();
179     OSL_ASSERT(mpCache.get()!=NULL);
180 
181     maPreviewSize = Size(rSize.Width, rSize.Height);
182     mpCache->ChangeSize(maPreviewSize, false);
183 }
184 
185 
186 
187 
getSlidePreview(sal_Int32 nSlideIndex,const Reference<rendering::XCanvas> & rxCanvas)188 Reference<rendering::XBitmap> SAL_CALL PresenterPreviewCache::getSlidePreview (
189     sal_Int32 nSlideIndex,
190     const Reference<rendering::XCanvas>& rxCanvas)
191 {
192     ThrowIfDisposed();
193     OSL_ASSERT(mpCacheContext.get()!=NULL);
194 
195     cppcanvas::BitmapCanvasSharedPtr pCanvas (
196         cppcanvas::VCLFactory::getInstance().createCanvas(
197             Reference<rendering::XBitmapCanvas>(rxCanvas, UNO_QUERY)));
198 
199     const SdrPage* pPage = mpCacheContext->GetPage(nSlideIndex);
200     if (pPage == NULL)
201         throw RuntimeException();
202 
203     const BitmapEx aPreview (mpCache->GetPreviewBitmap(pPage,true));
204     if (aPreview.IsEmpty())
205         return NULL;
206     else
207         return cppcanvas::VCLFactory::getInstance().createBitmap(
208             pCanvas,
209             aPreview)->getUNOBitmap();
210 }
211 
212 
213 
214 
addPreviewCreationNotifyListener(const Reference<drawing::XSlidePreviewCacheListener> & rxListener)215 void SAL_CALL PresenterPreviewCache::addPreviewCreationNotifyListener (
216     const Reference<drawing::XSlidePreviewCacheListener>& rxListener)
217 {
218     if (rBHelper.bDisposed || rBHelper.bInDispose)
219         return;
220     if (rxListener.is())
221         mpCacheContext->AddPreviewCreationNotifyListener(rxListener);
222 }
223 
224 
225 
226 
removePreviewCreationNotifyListener(const css::uno::Reference<css::drawing::XSlidePreviewCacheListener> & rxListener)227 void SAL_CALL PresenterPreviewCache::removePreviewCreationNotifyListener (
228     const css::uno::Reference<css::drawing::XSlidePreviewCacheListener>& rxListener)
229 {
230     ThrowIfDisposed();
231     mpCacheContext->RemovePreviewCreationNotifyListener(rxListener);
232 }
233 
234 
235 
236 
pause(void)237 void SAL_CALL PresenterPreviewCache::pause (void)
238 {
239     ThrowIfDisposed();
240     OSL_ASSERT(mpCache.get()!=NULL);
241     mpCache->Pause();
242 }
243 
244 
245 
246 
resume(void)247 void SAL_CALL PresenterPreviewCache::resume (void)
248 {
249     ThrowIfDisposed();
250     OSL_ASSERT(mpCache.get()!=NULL);
251     mpCache->Resume();
252 }
253 
254 
255 
256 
257 //-----------------------------------------------------------------------------
258 
ThrowIfDisposed(void)259 void PresenterPreviewCache::ThrowIfDisposed (void)
260 {
261     if (rBHelper.bDisposed || rBHelper.bInDispose)
262     {
263         throw lang::DisposedException (
264             ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
265                 "PresenterPreviewCache object has already been disposed")),
266             static_cast<uno::XWeak*>(this));
267     }
268 }
269 
270 
271 
272 
273 //===== PresenterPreviewCache::PresenterCacheContext ==========================
274 
275 
PresenterCacheContext(void)276 PresenterPreviewCache::PresenterCacheContext::PresenterCacheContext (void)
277     : mxSlides(),
278       mxDocument(),
279       mnFirstVisibleSlideIndex(-1),
280       mnLastVisibleSlideIndex(-1),
281       maListeners()
282 {
283 }
284 
285 
286 
287 
~PresenterCacheContext(void)288 PresenterPreviewCache::PresenterCacheContext::~PresenterCacheContext (void)
289 {
290 }
291 
292 
293 
294 
SetDocumentSlides(const Reference<container::XIndexAccess> & rxSlides,const Reference<XInterface> & rxDocument)295 void PresenterPreviewCache::PresenterCacheContext::SetDocumentSlides (
296     const Reference<container::XIndexAccess>& rxSlides,
297     const Reference<XInterface>& rxDocument)
298 {
299     mxSlides = rxSlides;
300     mxDocument = rxDocument;
301     mnFirstVisibleSlideIndex = -1;
302     mnLastVisibleSlideIndex = -1;
303 }
304 
305 
306 
307 
SetVisibleSlideRange(const sal_Int32 nFirstVisibleSlideIndex,const sal_Int32 nLastVisibleSlideIndex)308 void PresenterPreviewCache::PresenterCacheContext::SetVisibleSlideRange (
309     const sal_Int32 nFirstVisibleSlideIndex,
310     const sal_Int32 nLastVisibleSlideIndex)
311 {
312     if (nFirstVisibleSlideIndex > nLastVisibleSlideIndex || nFirstVisibleSlideIndex<0)
313     {
314         mnFirstVisibleSlideIndex = -1;
315         mnLastVisibleSlideIndex = -1;
316     }
317     else
318     {
319         mnFirstVisibleSlideIndex = nFirstVisibleSlideIndex;
320         mnLastVisibleSlideIndex = nLastVisibleSlideIndex;
321     }
322     if (mxSlides.is() && mnLastVisibleSlideIndex >= mxSlides->getCount())
323         mnLastVisibleSlideIndex = mxSlides->getCount() - 1;
324 }
325 
326 
327 
328 
AddPreviewCreationNotifyListener(const Reference<drawing::XSlidePreviewCacheListener> & rxListener)329 void PresenterPreviewCache::PresenterCacheContext::AddPreviewCreationNotifyListener (
330     const Reference<drawing::XSlidePreviewCacheListener>& rxListener)
331 {
332     maListeners.push_back(rxListener);
333 }
334 
335 
336 
337 
RemovePreviewCreationNotifyListener(const Reference<drawing::XSlidePreviewCacheListener> & rxListener)338 void PresenterPreviewCache::PresenterCacheContext::RemovePreviewCreationNotifyListener (
339     const Reference<drawing::XSlidePreviewCacheListener>& rxListener)
340 {
341     ListenerContainer::iterator iListener;
342     for (iListener=maListeners.begin(); iListener!=maListeners.end(); ++iListener)
343         if (*iListener == rxListener)
344         {
345             maListeners.erase(iListener);
346             return;
347         }
348 }
349 
350 
351 
352 
353 //----- CacheContext ----------------------------------------------------------
354 
NotifyPreviewCreation(CacheKey aKey,const Bitmap & rPreview)355 void PresenterPreviewCache::PresenterCacheContext::NotifyPreviewCreation (
356     CacheKey aKey,
357     const Bitmap& rPreview)
358 {
359     (void)rPreview;
360 
361     if ( ! mxSlides.is())
362         return;
363     const sal_Int32 nCount(mxSlides->getCount());
364     for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
365         if (aKey == GetPage(nIndex))
366             CallListeners(nIndex);
367 }
368 
369 
370 
371 
IsIdle(void)372 bool PresenterPreviewCache::PresenterCacheContext::IsIdle (void)
373 {
374     return true;
375     /*
376     sal_Int32 nIdleState (tools::IdleDetection::GetIdleState(NULL));
377     if (nIdleState == tools::IdleDetection::IDET_IDLE)
378         return true;
379     else
380         return false;
381     */
382 }
383 
384 
385 
386 
IsVisible(CacheKey aKey)387 bool PresenterPreviewCache::PresenterCacheContext::IsVisible (CacheKey aKey)
388 {
389     if (mnFirstVisibleSlideIndex < 0)
390         return false;
391     for (sal_Int32 nIndex=mnFirstVisibleSlideIndex; nIndex<=mnLastVisibleSlideIndex; ++nIndex)
392     {
393         const SdrPage* pPage = GetPage(nIndex);
394         if (pPage == static_cast<const SdrPage*>(aKey))
395             return true;
396     }
397     return false;
398 }
399 
400 
401 
402 
GetPage(CacheKey aKey)403 const SdrPage* PresenterPreviewCache::PresenterCacheContext::GetPage (CacheKey aKey)
404 {
405     return static_cast<const SdrPage*>(aKey);
406 }
407 
408 
409 
410 
411 ::boost::shared_ptr<std::vector<CacheKey> >
GetEntryList(bool bVisible)412     PresenterPreviewCache::PresenterCacheContext::GetEntryList (bool bVisible)
413 {
414     ::boost::shared_ptr<std::vector<CacheKey> > pKeys (new std::vector<CacheKey>());
415 
416     if ( ! mxSlides.is())
417         return pKeys;
418 
419     const sal_Int32 nFirstIndex (bVisible ? mnFirstVisibleSlideIndex : 0);
420     const sal_Int32 nLastIndex (bVisible ? mnLastVisibleSlideIndex : mxSlides->getCount()-1);
421 
422     if (nFirstIndex < 0)
423         return pKeys;
424 
425     for (sal_Int32 nIndex=nFirstIndex; nIndex<=nLastIndex; ++nIndex)
426     {
427         pKeys->push_back(GetPage(nIndex));
428     }
429 
430     return pKeys;
431 }
432 
433 
434 
435 
GetPriority(CacheKey aKey)436 sal_Int32 PresenterPreviewCache::PresenterCacheContext::GetPriority (CacheKey aKey)
437 {
438     if ( ! mxSlides.is())
439         return 0;
440 
441     const sal_Int32 nCount (mxSlides->getCount());
442 
443     for (sal_Int32 nIndex=mnFirstVisibleSlideIndex; nIndex<=mnLastVisibleSlideIndex; ++nIndex)
444         if (aKey == GetPage(nIndex))
445             return -nCount-1+nIndex;
446 
447     for (sal_Int32 nIndex=0; nIndex<=nCount; ++nIndex)
448         if (aKey == GetPage(nIndex))
449             return nIndex;
450 
451     return 0;
452 }
453 
454 
455 
456 
GetModel(void)457 Reference<XInterface> PresenterPreviewCache::PresenterCacheContext::GetModel (void)
458 {
459     return mxDocument;
460 }
461 
462 
463 
464 
465 //-----------------------------------------------------------------------------
466 
GetPage(const sal_Int32 nSlideIndex) const467 const SdrPage* PresenterPreviewCache::PresenterCacheContext::GetPage (
468     const sal_Int32 nSlideIndex) const
469 {
470     if ( ! mxSlides.is())
471         return NULL;
472     if (nSlideIndex < 0 || nSlideIndex >= mxSlides->getCount())
473         return NULL;
474 
475     Reference<drawing::XDrawPage> xSlide (mxSlides->getByIndex(nSlideIndex), UNO_QUERY);
476     const SdPage* pPage = SdPage::getImplementation(xSlide);
477     return dynamic_cast<const SdrPage*>(pPage);
478 }
479 
480 
481 
482 
CallListeners(const sal_Int32 nIndex)483 void PresenterPreviewCache::PresenterCacheContext::CallListeners (
484     const sal_Int32 nIndex)
485 {
486     ListenerContainer aListeners (maListeners);
487     ListenerContainer::const_iterator iListener;
488     for (iListener=aListeners.begin(); iListener!=aListeners.end(); ++iListener)
489     {
490         try
491         {
492             (*iListener)->notifyPreviewCreation(nIndex);
493         }
494         catch (lang::DisposedException&)
495         {
496             RemovePreviewCreationNotifyListener(*iListener);
497         }
498     }
499 }
500 
501 } } // end of namespace ::sd::presenter
502