merge the formfield patch from ooo-build
[ooovba.git] / sdext / source / presenter / PresenterSlidePreview.cxx
blob0008208178aa846a21e2ba3646374882c6456711
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: PresenterSlidePreview.cxx,v $
11 * $Revision: 1.6 $
13 * This file is part of OpenOffice.org.
15 * OpenOffice.org is free software: you can redistribute it and/or modify
16 * it under the terms of the GNU Lesser General Public License version 3
17 * only, as published by the Free Software Foundation.
19 * OpenOffice.org is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Lesser General Public License version 3 for more details
23 * (a copy is included in the LICENSE file that accompanied this code).
25 * You should have received a copy of the GNU Lesser General Public License
26 * version 3 along with OpenOffice.org. If not, see
27 * <http://www.openoffice.org/license.html>
28 * for a copy of the LGPLv3 License.
30 ************************************************************************/
32 // MARKER(update_precomp.py): autogen include statement, do not remove
33 #include "precompiled_sdext.hxx"
35 #include "PresenterSlidePreview.hxx"
36 #include "PresenterCanvasHelper.hxx"
37 #include "PresenterGeometryHelper.hxx"
38 #include "PresenterPaintManager.hxx"
39 #include <com/sun/star/awt/XWindow.hpp>
40 #include <com/sun/star/awt/XWindowPeer.hpp>
41 #include <com/sun/star/beans/XPropertySet.hpp>
42 #include <com/sun/star/drawing/framework/XConfigurationController.hpp>
43 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
44 #include <com/sun/star/drawing/framework/XPane.hpp>
45 #include <com/sun/star/rendering/CompositeOperation.hpp>
47 using namespace ::com::sun::star;
48 using namespace ::com::sun::star::uno;
49 using namespace ::com::sun::star::drawing::framework;
50 using ::rtl::OUString;
52 namespace
54 // Use a super sample factor greater than 1 to achive a poor mans
55 // antialiasing effect for slide previews.
56 const sal_Int16 gnSuperSampleFactor = 2;
59 namespace sdext { namespace presenter {
61 //===== PresenterSlidePreview =================================================
63 PresenterSlidePreview::PresenterSlidePreview (
64 const Reference<XComponentContext>& rxContext,
65 const Reference<XResourceId>& rxViewId,
66 const Reference<XPane>& rxAnchorPane,
67 const ::rtl::Reference<PresenterController>& rpPresenterController)
68 : PresenterSlidePreviewInterfaceBase(m_aMutex),
69 mpPresenterController(rpPresenterController),
70 mxPane(rxAnchorPane),
71 mxViewId(rxViewId),
72 mxPreviewRenderer(),
73 mxPreview(),
74 mxCurrentSlide(),
75 mnSlideAspectRatio(28.0 / 21.0),
76 mxWindow(),
77 mxCanvas()
79 if ( ! rxContext.is()
80 || ! rxViewId.is()
81 || ! rxAnchorPane.is()
82 || ! rpPresenterController.is())
84 throw RuntimeException(
85 OUString::createFromAscii(
86 "PresenterSlidePreview can not be constructed due to empty argument"),
87 static_cast<XWeak*>(this));
90 mxWindow = rxAnchorPane->getWindow();
91 mxCanvas = rxAnchorPane->getCanvas();
93 if (mxWindow.is())
95 mxWindow->addWindowListener(this);
96 mxWindow->addPaintListener(this);
98 Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY);
99 if (xPeer.is())
100 xPeer->setBackground(util::Color(0xff000000));
102 mxWindow->setVisible(sal_True);
105 if (mpPresenterController.get() != NULL)
106 mnSlideAspectRatio = mpPresenterController->GetSlideAspectRatio();
108 Reference<lang::XMultiComponentFactory> xFactory (rxContext->getServiceManager(), UNO_QUERY);
109 if (xFactory.is())
110 mxPreviewRenderer = Reference<drawing::XSlideRenderer>(
111 xFactory->createInstanceWithContext(
112 OUString::createFromAscii("com.sun.star.drawing.SlideRenderer"),
113 rxContext),
114 UNO_QUERY);
116 Resize();
122 PresenterSlidePreview::~PresenterSlidePreview (void)
129 void SAL_CALL PresenterSlidePreview::disposing (void)
131 if (mxWindow.is())
133 mxWindow->removeWindowListener(this);
134 mxWindow->removePaintListener(this);
135 mxWindow = NULL;
136 mxCanvas = NULL;
139 Reference<lang::XComponent> xComponent (mxPreviewRenderer, UNO_QUERY);
140 if (xComponent.is())
141 xComponent->dispose();
147 //----- XResourceId -----------------------------------------------------------
149 Reference<XResourceId> SAL_CALL PresenterSlidePreview::getResourceId (void)
150 throw (RuntimeException)
152 return mxViewId;
158 sal_Bool SAL_CALL PresenterSlidePreview::isAnchorOnly (void)
159 throw (RuntimeException)
161 return false;
167 //----- XWindowListener -------------------------------------------------------
169 void SAL_CALL PresenterSlidePreview::windowResized (const awt::WindowEvent& rEvent)
170 throw (RuntimeException)
172 (void)rEvent;
173 ThrowIfDisposed();
174 ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex());
175 Resize();
182 void SAL_CALL PresenterSlidePreview::windowMoved (const awt::WindowEvent& rEvent)
183 throw (RuntimeException)
185 (void)rEvent;
191 void SAL_CALL PresenterSlidePreview::windowShown (const lang::EventObject& rEvent)
192 throw (RuntimeException)
194 (void)rEvent;
195 ThrowIfDisposed();
196 ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex());
197 Resize();
203 void SAL_CALL PresenterSlidePreview::windowHidden (const lang::EventObject& rEvent)
204 throw (RuntimeException)
206 (void)rEvent;
212 //----- XPaintListener --------------------------------------------------------
214 void SAL_CALL PresenterSlidePreview::windowPaint (const awt::PaintEvent& rEvent)
215 throw (RuntimeException)
217 ThrowIfDisposed();
219 ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex());
220 if (mxWindow.is())
221 Paint(awt::Rectangle(
222 rEvent.UpdateRect.X,
223 rEvent.UpdateRect.Y,
224 rEvent.UpdateRect.Width,
225 rEvent.UpdateRect.Height));
231 //----- lang::XEventListener --------------------------------------------------
233 void SAL_CALL PresenterSlidePreview::disposing (const lang::EventObject& rEvent)
234 throw (RuntimeException)
236 if (rEvent.Source == mxWindow)
238 mxWindow = NULL;
239 mxCanvas = NULL;
240 mxPreview = NULL;
247 //----- XDrawView -------------------------------------------------------------
249 void SAL_CALL PresenterSlidePreview::setCurrentPage (const Reference<drawing::XDrawPage>& rxSlide)
250 throw (RuntimeException)
252 ThrowIfDisposed();
253 ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex());
254 SetSlide(rxSlide);
260 Reference<drawing::XDrawPage> SAL_CALL PresenterSlidePreview::getCurrentPage (void)
261 throw (RuntimeException)
263 ThrowIfDisposed();
264 return NULL;
270 //-----------------------------------------------------------------------------
272 void PresenterSlidePreview::SetSlide (const Reference<drawing::XDrawPage>& rxPage)
274 mxCurrentSlide = rxPage;
275 mxPreview = NULL;
277 Reference<beans::XPropertySet> xPropertySet (mxCurrentSlide, UNO_QUERY);
278 if (xPropertySet.is())
280 awt::Size aSlideSize;
283 xPropertySet->getPropertyValue(
284 OUString::createFromAscii("Width")) >>= aSlideSize.Width;
285 xPropertySet->getPropertyValue(
286 OUString::createFromAscii("Height")) >>= aSlideSize.Height;
288 catch (beans::UnknownPropertyException&)
290 OSL_ASSERT(false);
294 // The preview is not transparent, therefore only this window, not its
295 // parent, has to be invalidated.
296 mpPresenterController->GetPaintManager()->Invalidate(mxWindow);
302 void PresenterSlidePreview::Paint (const awt::Rectangle& rBoundingBox)
304 (void)rBoundingBox;
305 if ( ! mxWindow.is())
306 return;
307 if ( ! mxCanvas.is())
308 return;
309 if ( ! mxPreviewRenderer.is())
310 return;
312 // Make sure that a preview in the correct size exists.
313 awt::Rectangle aWindowBox (mxWindow->getPosSize());
315 if ( ! mxPreview.is() && mxCurrentSlide.is())
317 // Create a new preview bitmap.
318 mxPreview = mxPreviewRenderer->createPreviewForCanvas(
319 mxCurrentSlide,
320 awt::Size(aWindowBox.Width, aWindowBox.Height),
321 gnSuperSampleFactor,
322 mxCanvas);
325 // Determine the bounding box of the preview.
326 awt::Rectangle aPreviewBox;
327 if (mxPreview.is())
329 const geometry::IntegerSize2D aPreviewSize (mxPreview->getSize());
330 aPreviewBox = awt::Rectangle(
331 (aWindowBox.Width - aPreviewSize.Width)/2,
332 (aWindowBox.Height - aPreviewSize.Height)/2,
333 aPreviewSize.Width,
334 aPreviewSize.Height);
336 else
338 if (mnSlideAspectRatio > 0)
340 const awt::Size aPreviewSize (mxPreviewRenderer->calculatePreviewSize(
341 mnSlideAspectRatio,awt::Size(aWindowBox.Width, aWindowBox.Height)));
342 aPreviewBox = awt::Rectangle(
343 (aWindowBox.Width - aPreviewSize.Width)/2,
344 (aWindowBox.Height - aPreviewSize.Height)/2,
345 aPreviewSize.Width,
346 aPreviewSize.Height);
350 // Paint the background.
351 mpPresenterController->GetCanvasHelper()->Paint(
352 mpPresenterController->GetViewBackground(mxViewId->getResourceURL()),
353 mxCanvas,
354 rBoundingBox,
355 awt::Rectangle(0,0,aWindowBox.Width,aWindowBox.Height),
356 aPreviewBox);
358 // Paint the preview.
359 const rendering::ViewState aViewState(
360 geometry::AffineMatrix2D(1,0,0, 0,1,0),
361 NULL);
363 Sequence<double> aBackgroundColor(4);
364 rendering::RenderState aRenderState (
365 geometry::AffineMatrix2D(1, 0, aPreviewBox.X, 0, 1, aPreviewBox.Y),
366 NULL,
367 aBackgroundColor,
368 rendering::CompositeOperation::SOURCE);
369 PresenterCanvasHelper::SetDeviceColor(aRenderState, 0x00000000);
370 if (mxPreview.is())
372 mxCanvas->drawBitmap(mxPreview, aViewState, aRenderState);
374 else
376 if (mnSlideAspectRatio > 0)
378 Reference<rendering::XPolyPolygon2D> xPolygon (
379 PresenterGeometryHelper::CreatePolygon(aPreviewBox, mxCanvas->getDevice()));
380 if (xPolygon.is())
381 mxCanvas->fillPolyPolygon(xPolygon, aViewState, aRenderState);
385 Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
386 if (xSpriteCanvas.is())
387 xSpriteCanvas->updateScreen(sal_False);
393 void PresenterSlidePreview::Resize (void)
395 if (mxPreviewRenderer.is() && mxPreview.is())
397 const awt::Rectangle aWindowBox (mxWindow->getPosSize());
398 const awt::Size aNewPreviewSize (mxPreviewRenderer->calculatePreviewSize(
399 mnSlideAspectRatio,
400 awt::Size(aWindowBox.Width, aWindowBox.Height)));
401 const geometry::IntegerSize2D aPreviewSize (mxPreview->getSize());
402 if (aNewPreviewSize.Width==aPreviewSize.Width
403 && aNewPreviewSize.Height==aPreviewSize.Height)
405 // The size of the window may have changed but the preview would
406 // be painted in the same size (but not necessarily at the same
407 // position.)
408 return;
411 SetSlide(mxCurrentSlide);
417 void PresenterSlidePreview::ThrowIfDisposed (void)
418 throw (::com::sun::star::lang::DisposedException)
420 if (PresenterSlidePreviewInterfaceBase::rBHelper.bDisposed || PresenterSlidePreviewInterfaceBase::rBHelper.bInDispose)
422 throw lang::DisposedException (
423 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
424 "PresenterSlidePreview object has already been disposed")),
425 static_cast<uno::XWeak*>(this));
430 } } // end of namespace ::sd::presenter