/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2008 by Sun Microsystems, Inc. * * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: PresenterSlidePreview.cxx,v $ * * $Revision: 1.6 $ * * 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_sdext.hxx" #include "PresenterSlidePreview.hxx" #include "PresenterCanvasHelper.hxx" #include "PresenterGeometryHelper.hxx" #include "PresenterPaintManager.hxx" #include #include #include #include #include #include #include using namespace ::com::sun::star; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::drawing::framework; using ::rtl::OUString; namespace { // Use a super sample factor greater than 1 to achive a poor mans // antialiasing effect for slide previews. const sal_Int16 gnSuperSampleFactor = 2; } namespace sdext { namespace presenter { //===== PresenterSlidePreview ================================================= PresenterSlidePreview::PresenterSlidePreview ( const Reference& rxContext, const Reference& rxViewId, const Reference& rxAnchorPane, const ::rtl::Reference& rpPresenterController) : PresenterSlidePreviewInterfaceBase(m_aMutex), mpPresenterController(rpPresenterController), mxPane(rxAnchorPane), mxViewId(rxViewId), mxPreviewRenderer(), mxPreview(), mxCurrentSlide(), mnSlideAspectRatio(28.0 / 21.0), mxWindow(), mxCanvas() { if ( ! rxContext.is() || ! rxViewId.is() || ! rxAnchorPane.is() || ! rpPresenterController.is()) { throw RuntimeException( OUString::createFromAscii( "PresenterSlidePreview can not be constructed due to empty argument"), static_cast(this)); } mxWindow = rxAnchorPane->getWindow(); mxCanvas = rxAnchorPane->getCanvas(); if (mxWindow.is()) { mxWindow->addWindowListener(this); mxWindow->addPaintListener(this); Reference xPeer (mxWindow, UNO_QUERY); if (xPeer.is()) xPeer->setBackground(util::Color(0xff000000)); mxWindow->setVisible(sal_True); } if (mpPresenterController.get() != NULL) mnSlideAspectRatio = mpPresenterController->GetSlideAspectRatio(); Reference xFactory (rxContext->getServiceManager(), UNO_QUERY); if (xFactory.is()) mxPreviewRenderer = Reference( xFactory->createInstanceWithContext( OUString::createFromAscii("com.sun.star.drawing.SlideRenderer"), rxContext), UNO_QUERY); Resize(); } PresenterSlidePreview::~PresenterSlidePreview (void) { } void SAL_CALL PresenterSlidePreview::disposing (void) { if (mxWindow.is()) { mxWindow->removeWindowListener(this); mxWindow->removePaintListener(this); mxWindow = NULL; mxCanvas = NULL; } Reference xComponent (mxPreviewRenderer, UNO_QUERY); if (xComponent.is()) xComponent->dispose(); } //----- XResourceId ----------------------------------------------------------- Reference SAL_CALL PresenterSlidePreview::getResourceId (void) throw (RuntimeException) { return mxViewId; } sal_Bool SAL_CALL PresenterSlidePreview::isAnchorOnly (void) throw (RuntimeException) { return false; } //----- XWindowListener ------------------------------------------------------- void SAL_CALL PresenterSlidePreview::windowResized (const awt::WindowEvent& rEvent) throw (RuntimeException) { (void)rEvent; ThrowIfDisposed(); ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex()); Resize(); } void SAL_CALL PresenterSlidePreview::windowMoved (const awt::WindowEvent& rEvent) throw (RuntimeException) { (void)rEvent; } void SAL_CALL PresenterSlidePreview::windowShown (const lang::EventObject& rEvent) throw (RuntimeException) { (void)rEvent; ThrowIfDisposed(); ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex()); Resize(); } void SAL_CALL PresenterSlidePreview::windowHidden (const lang::EventObject& rEvent) throw (RuntimeException) { (void)rEvent; } //----- XPaintListener -------------------------------------------------------- void SAL_CALL PresenterSlidePreview::windowPaint (const awt::PaintEvent& rEvent) throw (RuntimeException) { ThrowIfDisposed(); ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex()); if (mxWindow.is()) Paint(awt::Rectangle( rEvent.UpdateRect.X, rEvent.UpdateRect.Y, rEvent.UpdateRect.Width, rEvent.UpdateRect.Height)); } //----- lang::XEventListener -------------------------------------------------- void SAL_CALL PresenterSlidePreview::disposing (const lang::EventObject& rEvent) throw (RuntimeException) { if (rEvent.Source == mxWindow) { mxWindow = NULL; mxCanvas = NULL; mxPreview = NULL; } } //----- XDrawView ------------------------------------------------------------- void SAL_CALL PresenterSlidePreview::setCurrentPage (const Reference& rxSlide) throw (RuntimeException) { ThrowIfDisposed(); ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex()); SetSlide(rxSlide); } Reference SAL_CALL PresenterSlidePreview::getCurrentPage (void) throw (RuntimeException) { ThrowIfDisposed(); return NULL; } //----------------------------------------------------------------------------- void PresenterSlidePreview::SetSlide (const Reference& rxPage) { mxCurrentSlide = rxPage; mxPreview = NULL; Reference xPropertySet (mxCurrentSlide, UNO_QUERY); if (xPropertySet.is()) { awt::Size aSlideSize; try { xPropertySet->getPropertyValue( OUString::createFromAscii("Width")) >>= aSlideSize.Width; xPropertySet->getPropertyValue( OUString::createFromAscii("Height")) >>= aSlideSize.Height; } catch (beans::UnknownPropertyException&) { OSL_ASSERT(false); } } // The preview is not transparent, therefore only this window, not its // parent, has to be invalidated. mpPresenterController->GetPaintManager()->Invalidate(mxWindow); } void PresenterSlidePreview::Paint (const awt::Rectangle& rBoundingBox) { (void)rBoundingBox; if ( ! mxWindow.is()) return; if ( ! mxCanvas.is()) return; if ( ! mxPreviewRenderer.is()) return; // Make sure that a preview in the correct size exists. awt::Rectangle aWindowBox (mxWindow->getPosSize()); if ( ! mxPreview.is() && mxCurrentSlide.is()) { // Create a new preview bitmap. mxPreview = mxPreviewRenderer->createPreviewForCanvas( mxCurrentSlide, awt::Size(aWindowBox.Width, aWindowBox.Height), gnSuperSampleFactor, mxCanvas); } // Determine the bounding box of the preview. awt::Rectangle aPreviewBox; if (mxPreview.is()) { const geometry::IntegerSize2D aPreviewSize (mxPreview->getSize()); aPreviewBox = awt::Rectangle( (aWindowBox.Width - aPreviewSize.Width)/2, (aWindowBox.Height - aPreviewSize.Height)/2, aPreviewSize.Width, aPreviewSize.Height); } else { if (mnSlideAspectRatio > 0) { const awt::Size aPreviewSize (mxPreviewRenderer->calculatePreviewSize( mnSlideAspectRatio,awt::Size(aWindowBox.Width, aWindowBox.Height))); aPreviewBox = awt::Rectangle( (aWindowBox.Width - aPreviewSize.Width)/2, (aWindowBox.Height - aPreviewSize.Height)/2, aPreviewSize.Width, aPreviewSize.Height); } } // Paint the background. mpPresenterController->GetCanvasHelper()->Paint( mpPresenterController->GetViewBackground(mxViewId->getResourceURL()), mxCanvas, rBoundingBox, awt::Rectangle(0,0,aWindowBox.Width,aWindowBox.Height), aPreviewBox); // Paint the preview. const rendering::ViewState aViewState( geometry::AffineMatrix2D(1,0,0, 0,1,0), NULL); Sequence aBackgroundColor(4); rendering::RenderState aRenderState ( geometry::AffineMatrix2D(1, 0, aPreviewBox.X, 0, 1, aPreviewBox.Y), NULL, aBackgroundColor, rendering::CompositeOperation::SOURCE); PresenterCanvasHelper::SetDeviceColor(aRenderState, 0x00000000); if (mxPreview.is()) { mxCanvas->drawBitmap(mxPreview, aViewState, aRenderState); } else { if (mnSlideAspectRatio > 0) { Reference xPolygon ( PresenterGeometryHelper::CreatePolygon(aPreviewBox, mxCanvas->getDevice())); if (xPolygon.is()) mxCanvas->fillPolyPolygon(xPolygon, aViewState, aRenderState); } } Reference xSpriteCanvas (mxCanvas, UNO_QUERY); if (xSpriteCanvas.is()) xSpriteCanvas->updateScreen(sal_False); } void PresenterSlidePreview::Resize (void) { if (mxPreviewRenderer.is() && mxPreview.is()) { const awt::Rectangle aWindowBox (mxWindow->getPosSize()); const awt::Size aNewPreviewSize (mxPreviewRenderer->calculatePreviewSize( mnSlideAspectRatio, awt::Size(aWindowBox.Width, aWindowBox.Height))); const geometry::IntegerSize2D aPreviewSize (mxPreview->getSize()); if (aNewPreviewSize.Width==aPreviewSize.Width && aNewPreviewSize.Height==aPreviewSize.Height) { // The size of the window may have changed but the preview would // be painted in the same size (but not necessarily at the same // position.) return; } } SetSlide(mxCurrentSlide); } void PresenterSlidePreview::ThrowIfDisposed (void) throw (::com::sun::star::lang::DisposedException) { if (PresenterSlidePreviewInterfaceBase::rBHelper.bDisposed || PresenterSlidePreviewInterfaceBase::rBHelper.bInDispose) { throw lang::DisposedException ( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "PresenterSlidePreview object has already been disposed")), static_cast(this)); } } } } // end of namespace ::sd::presenter