summaryrefslogtreecommitdiff
path: root/sd/source/ui/presenter/PresenterPreviewCache.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sd/source/ui/presenter/PresenterPreviewCache.cxx')
-rw-r--r--sd/source/ui/presenter/PresenterPreviewCache.cxx519
1 files changed, 519 insertions, 0 deletions
diff --git a/sd/source/ui/presenter/PresenterPreviewCache.cxx b/sd/source/ui/presenter/PresenterPreviewCache.cxx
new file mode 100644
index 000000000000..1d069f40b765
--- /dev/null
+++ b/sd/source/ui/presenter/PresenterPreviewCache.cxx
@@ -0,0 +1,519 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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
+ * <http://www.openoffice.org/license.html>
+ * 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 <cppcanvas/vclfactory.hxx>
+#include <com/sun/star/drawing/XDrawPage.hpp>
+#include <com/sun/star/rendering/XBitmapCanvas.hpp>
+
+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<container::XIndexAccess>& rxSlides,
+ const Reference<XInterface>& rxDocument);
+ void SetVisibleSlideRange (
+ const sal_Int32 nFirstVisibleSlideIndex,
+ const sal_Int32 nLastVisibleSlideIndex);
+ const SdrPage* GetPage (const sal_Int32 nSlideIndex) const;
+ void AddPreviewCreationNotifyListener (const Reference<drawing::XSlidePreviewCacheListener>& rxListener);
+ void RemovePreviewCreationNotifyListener (const Reference<drawing::XSlidePreviewCacheListener>& rxListener);
+
+ // CacheContext
+ virtual void NotifyPreviewCreation (
+ CacheKey aKey,
+ const Bitmap& rPreview);
+ virtual bool IsIdle (void);
+ virtual bool IsVisible (CacheKey aKey);
+ virtual const SdrPage* GetPage (CacheKey aKey);
+ virtual ::boost::shared_ptr<std::vector<CacheKey> > GetEntryList (bool bVisible);
+ virtual sal_Int32 GetPriority (CacheKey aKey);
+ virtual ::com::sun::star::uno::Reference<com::sun::star::uno::XInterface> GetModel (void);
+
+private:
+ Reference<container::XIndexAccess> mxSlides;
+ Reference<XInterface> mxDocument;
+ sal_Int32 mnFirstVisibleSlideIndex;
+ sal_Int32 mnLastVisibleSlideIndex;
+ typedef ::std::vector<css::uno::Reference<css::drawing::XSlidePreviewCacheListener> > ListenerContainer;
+ ListenerContainer maListeners;
+
+ void CallListeners (const sal_Int32 nSlideIndex);
+};
+
+
+
+
+//===== Service ===============================================================
+
+Reference<XInterface> SAL_CALL PresenterPreviewCache_createInstance (
+ const Reference<XComponentContext>& rxContext)
+{
+ return Reference<XInterface>(static_cast<XWeak*>(new PresenterPreviewCache(rxContext)));
+}
+
+
+
+
+::rtl::OUString PresenterPreviewCache_getImplementationName (void) throw(RuntimeException)
+{
+ return OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Draw.PresenterPreviewCache"));
+}
+
+
+
+
+Sequence<rtl::OUString> SAL_CALL PresenterPreviewCache_getSupportedServiceNames (void)
+ throw (RuntimeException)
+{
+ static const ::rtl::OUString sServiceName(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.PresenterPreviewCache")));
+ return Sequence<rtl::OUString>(&sServiceName, 1);
+}
+
+
+
+
+//===== PresenterPreviewCache =================================================
+
+PresenterPreviewCache::PresenterPreviewCache (const Reference<XComponentContext>& rxContext)
+ : PresenterPreviewCacheInterfaceBase(m_aMutex),
+ maPreviewSize(Size(200,200)),
+ mpCacheContext(new PresenterCacheContext()),
+ mpCache(new PageCache(maPreviewSize, false, mpCacheContext))
+{
+ (void)rxContext;
+}
+
+
+
+
+PresenterPreviewCache::~PresenterPreviewCache (void)
+{
+}
+
+
+
+
+//----- XInitialize -----------------------------------------------------------
+
+void SAL_CALL PresenterPreviewCache::initialize (const Sequence<Any>& rArguments)
+ throw(Exception, RuntimeException)
+{
+ if (rArguments.getLength() != 0)
+ throw RuntimeException();
+}
+
+
+
+
+//----- XSlidePreviewCache ----------------------------------------------------
+
+void SAL_CALL PresenterPreviewCache::setDocumentSlides (
+ const Reference<container::XIndexAccess>& rxSlides,
+ const Reference<XInterface>& 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, false);
+}
+
+
+
+
+Reference<rendering::XBitmap> SAL_CALL PresenterPreviewCache::getSlidePreview (
+ sal_Int32 nSlideIndex,
+ const Reference<rendering::XCanvas>& rxCanvas)
+ throw (css::uno::RuntimeException)
+{
+ ThrowIfDisposed();
+ OSL_ASSERT(mpCacheContext.get()!=NULL);
+
+ cppcanvas::BitmapCanvasSharedPtr pCanvas (
+ cppcanvas::VCLFactory::getInstance().createCanvas(
+ Reference<rendering::XBitmapCanvas>(rxCanvas, UNO_QUERY)));
+
+ const SdrPage* pPage = mpCacheContext->GetPage(nSlideIndex);
+ if (pPage == NULL)
+ throw RuntimeException();
+
+ const BitmapEx aPreview (mpCache->GetPreviewBitmap(pPage,true));
+ if (aPreview.IsEmpty())
+ return NULL;
+ else
+ return cppcanvas::VCLFactory::getInstance().createBitmap(
+ pCanvas,
+ aPreview)->getUNOBitmap();
+}
+
+
+
+
+void SAL_CALL PresenterPreviewCache::addPreviewCreationNotifyListener (
+ const Reference<drawing::XSlidePreviewCacheListener>& 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<css::drawing::XSlidePreviewCacheListener>& 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<uno::XWeak*>(this));
+ }
+}
+
+
+
+
+//===== PresenterPreviewCache::PresenterCacheContext ==========================
+
+
+PresenterPreviewCache::PresenterCacheContext::PresenterCacheContext (void)
+ : mxSlides(),
+ mxDocument(),
+ mnFirstVisibleSlideIndex(-1),
+ mnLastVisibleSlideIndex(-1),
+ maListeners()
+{
+}
+
+
+
+
+PresenterPreviewCache::PresenterCacheContext::~PresenterCacheContext (void)
+{
+}
+
+
+
+
+void PresenterPreviewCache::PresenterCacheContext::SetDocumentSlides (
+ const Reference<container::XIndexAccess>& rxSlides,
+ const Reference<XInterface>& 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<drawing::XSlidePreviewCacheListener>& rxListener)
+{
+ maListeners.push_back(rxListener);
+}
+
+
+
+
+void PresenterPreviewCache::PresenterCacheContext::RemovePreviewCreationNotifyListener (
+ const Reference<drawing::XSlidePreviewCacheListener>& 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 Bitmap& rPreview)
+{
+ (void)rPreview;
+
+ if ( ! mxSlides.is())
+ return;
+ const sal_Int32 nCount(mxSlides->getCount());
+ for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
+ if (aKey == GetPage(nIndex))
+ CallListeners(nIndex);
+}
+
+
+
+
+bool PresenterPreviewCache::PresenterCacheContext::IsIdle (void)
+{
+ return true;
+ /*
+ sal_Int32 nIdleState (tools::IdleDetection::GetIdleState(NULL));
+ if (nIdleState == tools::IdleDetection::IDET_IDLE)
+ return true;
+ else
+ return false;
+ */
+}
+
+
+
+
+bool PresenterPreviewCache::PresenterCacheContext::IsVisible (CacheKey aKey)
+{
+ if (mnFirstVisibleSlideIndex < 0)
+ return false;
+ for (sal_Int32 nIndex=mnFirstVisibleSlideIndex; nIndex<=mnLastVisibleSlideIndex; ++nIndex)
+ {
+ const SdrPage* pPage = GetPage(nIndex);
+ if (pPage == static_cast<const SdrPage*>(aKey))
+ return true;
+ }
+ return false;
+}
+
+
+
+
+const SdrPage* PresenterPreviewCache::PresenterCacheContext::GetPage (CacheKey aKey)
+{
+ return static_cast<const SdrPage*>(aKey);
+}
+
+
+
+
+::boost::shared_ptr<std::vector<CacheKey> >
+ PresenterPreviewCache::PresenterCacheContext::GetEntryList (bool bVisible)
+{
+ ::boost::shared_ptr<std::vector<CacheKey> > pKeys (new std::vector<CacheKey>());
+
+ 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<XInterface> 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<drawing::XDrawPage> xSlide (mxSlides->getByIndex(nSlideIndex), UNO_QUERY);
+ const SdPage* pPage = SdPage::getImplementation(xSlide);
+ return dynamic_cast<const SdrPage*>(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
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */