/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sd.hxx" #include "precompiled_sd.hxx" #include "PresenterPreviewCache.hxx" #include "cache/SlsCacheContext.hxx" #include "tools/IdleDetection.hxx" #include "sdpage.hxx" #include #include #include using namespace ::com::sun::star; using namespace ::com::sun::star::uno; using namespace ::sd::slidesorter::cache; using ::rtl::OUString; namespace sd { namespace presenter { class PresenterPreviewCache::PresenterCacheContext : public CacheContext { public: PresenterCacheContext (void); virtual ~PresenterCacheContext (void); void SetDocumentSlides ( const Reference& rxSlides, const Reference& rxDocument); void SetVisibleSlideRange ( const sal_Int32 nFirstVisibleSlideIndex, const sal_Int32 nLastVisibleSlideIndex); const SdrPage* GetPage (const sal_Int32 nSlideIndex) const; void AddPreviewCreationNotifyListener (const Reference& rxListener); void RemovePreviewCreationNotifyListener (const Reference& rxListener); // CacheContext virtual void NotifyPreviewCreation ( CacheKey aKey, const ::boost::shared_ptr& rPreview); virtual bool IsIdle (void); virtual bool IsVisible (CacheKey aKey); virtual const SdrPage* GetPage (CacheKey aKey); virtual ::boost::shared_ptr > GetEntryList (bool bVisible); virtual sal_Int32 GetPriority (CacheKey aKey); virtual ::com::sun::star::uno::Reference GetModel (void); private: Reference mxSlides; Reference mxDocument; sal_Int32 mnFirstVisibleSlideIndex; sal_Int32 mnLastVisibleSlideIndex; typedef ::std::vector > ListenerContainer; ListenerContainer maListeners; void CallListeners (const sal_Int32 nSlideIndex); }; //===== Service =============================================================== Reference SAL_CALL PresenterPreviewCache_createInstance ( const Reference& rxContext) { return Reference(static_cast(new PresenterPreviewCache(rxContext))); } ::rtl::OUString PresenterPreviewCache_getImplementationName (void) throw(RuntimeException) { return OUString::createFromAscii("com.sun.star.comp.Draw.PresenterPreviewCache"); } Sequence SAL_CALL PresenterPreviewCache_getSupportedServiceNames (void) throw (RuntimeException) { static const ::rtl::OUString sServiceName( ::rtl::OUString::createFromAscii("com.sun.star.drawing.PresenterPreviewCache")); return Sequence(&sServiceName, 1); } //===== PresenterPreviewCache ================================================= PresenterPreviewCache::PresenterPreviewCache (const Reference& rxContext) : PresenterPreviewCacheInterfaceBase(m_aMutex), maPreviewSize(Size(200,200)), mpCacheContext(new PresenterCacheContext()), mpCache(new PageCache(maPreviewSize, mpCacheContext)) { (void)rxContext; } PresenterPreviewCache::~PresenterPreviewCache (void) { } //----- XInitialize ----------------------------------------------------------- void SAL_CALL PresenterPreviewCache::initialize (const Sequence& rArguments) throw(Exception, RuntimeException) { if (rArguments.getLength() != 0) throw RuntimeException(); } //----- XSlidePreviewCache ---------------------------------------------------- void SAL_CALL PresenterPreviewCache::setDocumentSlides ( const Reference& rxSlides, const Reference& rxDocument) throw (RuntimeException) { ThrowIfDisposed(); OSL_ASSERT(mpCacheContext.get()!=NULL); mpCacheContext->SetDocumentSlides(rxSlides, rxDocument); } void SAL_CALL PresenterPreviewCache::setVisibleRange ( sal_Int32 nFirstVisibleSlideIndex, sal_Int32 nLastVisibleSlideIndex) throw (css::uno::RuntimeException) { ThrowIfDisposed(); OSL_ASSERT(mpCacheContext.get()!=NULL); mpCacheContext->SetVisibleSlideRange (nFirstVisibleSlideIndex, nLastVisibleSlideIndex); } void SAL_CALL PresenterPreviewCache::setPreviewSize ( const css::geometry::IntegerSize2D& rSize) throw (css::uno::RuntimeException) { ThrowIfDisposed(); OSL_ASSERT(mpCache.get()!=NULL); maPreviewSize = Size(rSize.Width, rSize.Height); mpCache->ChangeSize(maPreviewSize); } Reference SAL_CALL PresenterPreviewCache::getSlidePreview ( sal_Int32 nSlideIndex, const Reference& rxCanvas) throw (css::uno::RuntimeException) { ThrowIfDisposed(); OSL_ASSERT(mpCacheContext.get()!=NULL); cppcanvas::BitmapCanvasSharedPtr pCanvas ( cppcanvas::VCLFactory::getInstance().createCanvas( Reference(rxCanvas, UNO_QUERY))); const SdrPage* pPage = mpCacheContext->GetPage(nSlideIndex); if (pPage == NULL) throw RuntimeException(); const BitmapEx aPreview (mpCache->GetPreviewBitmap(pPage, maPreviewSize)); if (aPreview.IsEmpty()) return NULL; else return cppcanvas::VCLFactory::getInstance().createBitmap( pCanvas, aPreview)->getUNOBitmap(); } void SAL_CALL PresenterPreviewCache::addPreviewCreationNotifyListener ( const Reference& rxListener) throw (css::uno::RuntimeException) { if (rBHelper.bDisposed || rBHelper.bInDispose) return; if (rxListener.is()) mpCacheContext->AddPreviewCreationNotifyListener(rxListener); } void SAL_CALL PresenterPreviewCache::removePreviewCreationNotifyListener ( const css::uno::Reference& rxListener) throw (css::uno::RuntimeException) { ThrowIfDisposed(); mpCacheContext->RemovePreviewCreationNotifyListener(rxListener); } void SAL_CALL PresenterPreviewCache::pause (void) throw (css::uno::RuntimeException) { ThrowIfDisposed(); OSL_ASSERT(mpCache.get()!=NULL); mpCache->Pause(); } void SAL_CALL PresenterPreviewCache::resume (void) throw (css::uno::RuntimeException) { ThrowIfDisposed(); OSL_ASSERT(mpCache.get()!=NULL); mpCache->Resume(); } //----------------------------------------------------------------------------- void PresenterPreviewCache::ThrowIfDisposed (void) throw (::com::sun::star::lang::DisposedException) { if (rBHelper.bDisposed || rBHelper.bInDispose) { throw lang::DisposedException ( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "PresenterPreviewCache object has already been disposed")), static_cast(this)); } } //===== PresenterPreviewCache::PresenterCacheContext ========================== PresenterPreviewCache::PresenterCacheContext::PresenterCacheContext (void) : mxSlides(), mxDocument(), mnFirstVisibleSlideIndex(-1), mnLastVisibleSlideIndex(-1), maListeners() { } PresenterPreviewCache::PresenterCacheContext::~PresenterCacheContext (void) { } void PresenterPreviewCache::PresenterCacheContext::SetDocumentSlides ( const Reference& rxSlides, const Reference& rxDocument) { mxSlides = rxSlides; mxDocument = rxDocument; mnFirstVisibleSlideIndex = -1; mnLastVisibleSlideIndex = -1; } void PresenterPreviewCache::PresenterCacheContext::SetVisibleSlideRange ( const sal_Int32 nFirstVisibleSlideIndex, const sal_Int32 nLastVisibleSlideIndex) { if (nFirstVisibleSlideIndex > nLastVisibleSlideIndex || nFirstVisibleSlideIndex<0) { mnFirstVisibleSlideIndex = -1; mnLastVisibleSlideIndex = -1; } else { mnFirstVisibleSlideIndex = nFirstVisibleSlideIndex; mnLastVisibleSlideIndex = nLastVisibleSlideIndex; } if (mxSlides.is() && mnLastVisibleSlideIndex >= mxSlides->getCount()) mnLastVisibleSlideIndex = mxSlides->getCount() - 1; } void PresenterPreviewCache::PresenterCacheContext::AddPreviewCreationNotifyListener ( const Reference& rxListener) { maListeners.push_back(rxListener); } void PresenterPreviewCache::PresenterCacheContext::RemovePreviewCreationNotifyListener ( const Reference& rxListener) { ListenerContainer::iterator iListener; for (iListener=maListeners.begin(); iListener!=maListeners.end(); ++iListener) if (*iListener == rxListener) { maListeners.erase(iListener); return; } } //----- CacheContext ---------------------------------------------------------- void PresenterPreviewCache::PresenterCacheContext::NotifyPreviewCreation ( CacheKey aKey, const ::boost::shared_ptr& rPreview) { (void)rPreview; if ( ! mxSlides.is()) return; const sal_Int32 nCount(mxSlides->getCount()); for (sal_Int32 nIndex=0; nIndex(aKey)) return true; } return false; } const SdrPage* PresenterPreviewCache::PresenterCacheContext::GetPage (CacheKey aKey) { return static_cast(aKey); } ::boost::shared_ptr > PresenterPreviewCache::PresenterCacheContext::GetEntryList (bool bVisible) { ::boost::shared_ptr > pKeys (new std::vector()); if ( ! mxSlides.is()) return pKeys; const sal_Int32 nFirstIndex (bVisible ? mnFirstVisibleSlideIndex : 0); const sal_Int32 nLastIndex (bVisible ? mnLastVisibleSlideIndex : mxSlides->getCount()-1); if (nFirstIndex < 0) return pKeys; for (sal_Int32 nIndex=nFirstIndex; nIndex<=nLastIndex; ++nIndex) { pKeys->push_back(GetPage(nIndex)); } return pKeys; } sal_Int32 PresenterPreviewCache::PresenterCacheContext::GetPriority (CacheKey aKey) { if ( ! mxSlides.is()) return 0; const sal_Int32 nCount (mxSlides->getCount()); for (sal_Int32 nIndex=mnFirstVisibleSlideIndex; nIndex<=mnLastVisibleSlideIndex; ++nIndex) if (aKey == GetPage(nIndex)) return -nCount-1+nIndex; for (sal_Int32 nIndex=0; nIndex<=nCount; ++nIndex) if (aKey == GetPage(nIndex)) return nIndex; return 0; } Reference PresenterPreviewCache::PresenterCacheContext::GetModel (void) { return mxDocument; } //----------------------------------------------------------------------------- const SdrPage* PresenterPreviewCache::PresenterCacheContext::GetPage ( const sal_Int32 nSlideIndex) const { if ( ! mxSlides.is()) return NULL; if (nSlideIndex < 0 || nSlideIndex >= mxSlides->getCount()) return NULL; Reference xSlide (mxSlides->getByIndex(nSlideIndex), UNO_QUERY); const SdPage* pPage = SdPage::getImplementation(xSlide); return dynamic_cast(pPage); } void PresenterPreviewCache::PresenterCacheContext::CallListeners ( const sal_Int32 nIndex) { ListenerContainer aListeners (maListeners); ListenerContainer::const_iterator iListener; for (iListener=aListeners.begin(); iListener!=aListeners.end(); ++iListener) { try { (*iListener)->notifyPreviewCreation(nIndex); } catch (lang::DisposedException&) { RemovePreviewCreationNotifyListener(*iListener); } } } } } // end of namespace ::sd::presenter