bump product version to 4.1.6.2
[LibreOffice.git] / sd / source / ui / slideshow / slideshowviewimpl.cxx
blobe2678b848c69cd07ae66bfa6028e08b95d0d380a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <slideshowviewimpl.hxx>
21 #include <slideshowimpl.hxx>
22 #include <osl/mutex.hxx>
24 #include <com/sun/star/awt/Pointer.hpp>
25 #include <com/sun/star/beans/XPropertySet.hpp>
27 #include <basegfx/polygon/b2dpolygon.hxx>
28 #include <basegfx/polygon/b2dpolygontools.hxx>
29 #include <basegfx/matrix/b2dhommatrixtools.hxx>
31 #include <cppcanvas/vclfactory.hxx>
32 #include <cppcanvas/basegfxfactory.hxx>
35 using ::com::sun::star::uno::UNO_QUERY;
36 using ::com::sun::star::uno::XInterface;
37 using ::com::sun::star::uno::Reference;
38 using ::com::sun::star::uno::WeakReference;
39 using ::com::sun::star::uno::RuntimeException;
40 using ::com::sun::star::lang::XComponent;
41 using ::com::sun::star::uno::Exception;
42 using ::com::sun::star::presentation::XSlideShow;
43 using ::com::sun::star::presentation::XSlideShowView;
44 using ::com::sun::star::presentation::XShapeEventListener;
45 using ::com::sun::star::presentation::XSlideShowListener;
46 using ::comphelper::ImplementationReference;
48 using namespace ::com::sun::star;
50 namespace sd
53 ///////////////////////////////////////////////////////////////////////
54 // SlideShowViewListeners
55 ///////////////////////////////////////////////////////////////////////
57 SlideShowViewListeners::SlideShowViewListeners( ::osl::Mutex& rMutex )
58 : mrMutex( rMutex )
62 void SlideShowViewListeners::addListener( const Reference< util::XModifyListener >& _rxListener )
64 ::osl::MutexGuard aGuard( mrMutex );
66 WeakReference< util::XModifyListener > xWeak( _rxListener );
67 if( std::find( maListeners.begin(), maListeners.end(), xWeak ) == maListeners.end() )
68 maListeners.push_back( xWeak );
71 void SlideShowViewListeners::removeListener( const Reference< util::XModifyListener >& _rxListener )
73 ::osl::MutexGuard aGuard( mrMutex );
75 WeakReference< util::XModifyListener > xWeak( _rxListener );
76 ViewListenerVector::iterator aIter( std::find( maListeners.begin(), maListeners.end(), xWeak ) );
77 if( aIter != maListeners.end() )
78 maListeners.erase( aIter );
81 bool SlideShowViewListeners::notify( const lang::EventObject& _rEvent ) throw( com::sun::star::uno::Exception )
83 ::osl::MutexGuard aGuard( mrMutex );
85 ViewListenerVector::iterator aIter( maListeners.begin() );
86 while( aIter != maListeners.end() )
88 Reference< util::XModifyListener > xListener( (*aIter) );
89 if( xListener.is() )
91 xListener->modified( _rEvent );
92 ++aIter;
94 else
96 aIter = maListeners.erase( aIter );
99 return true;
102 void SlideShowViewListeners::disposing( const lang::EventObject& _rEventSource )
104 ::osl::MutexGuard aGuard( mrMutex );
106 ViewListenerVector::iterator aIter( maListeners.begin() );
107 while( aIter != maListeners.end() )
109 Reference< util::XModifyListener > xListener( (*aIter++) );
110 if( xListener.is() )
111 xListener->disposing( _rEventSource );
114 maListeners.clear();
117 ///////////////////////////////////////////////////////////////////////
118 // SlideShowViewPaintListeners
119 ///////////////////////////////////////////////////////////////////////
121 SlideShowViewPaintListeners::SlideShowViewPaintListeners( ::osl::Mutex& rMutex )
122 : SlideShowViewPaintListeners_Base( rMutex )
126 bool SlideShowViewPaintListeners::implTypedNotify( const Reference< awt::XPaintListener >& rListener,
127 const awt::PaintEvent& rEvent ) throw( uno::Exception )
129 rListener->windowPaint( rEvent );
130 return true; // continue calling listeners
133 ///////////////////////////////////////////////////////////////////////
134 // SlideShowViewMouseListeners
135 ///////////////////////////////////////////////////////////////////////
137 SlideShowViewMouseListeners::SlideShowViewMouseListeners( ::osl::Mutex& rMutex ) :
138 SlideShowViewMouseListeners_Base( rMutex )
142 bool SlideShowViewMouseListeners::implTypedNotify( const Reference< awt::XMouseListener >& rListener,
143 const WrappedMouseEvent& rEvent ) throw( uno::Exception )
145 switch( rEvent.meType )
147 case WrappedMouseEvent::PRESSED:
148 rListener->mousePressed( rEvent.maEvent );
149 break;
151 case WrappedMouseEvent::RELEASED:
152 rListener->mouseReleased( rEvent.maEvent );
153 break;
155 case WrappedMouseEvent::ENTERED:
156 rListener->mouseEntered( rEvent.maEvent );
157 break;
159 case WrappedMouseEvent::EXITED:
160 rListener->mouseExited( rEvent.maEvent );
161 break;
164 return true; // continue calling listeners
167 ///////////////////////////////////////////////////////////////////////
168 // SlideShowViewMouseMotionListeners
169 ///////////////////////////////////////////////////////////////////////
171 SlideShowViewMouseMotionListeners::SlideShowViewMouseMotionListeners( ::osl::Mutex& rMutex ) :
172 SlideShowViewMouseMotionListeners_Base( rMutex )
176 bool SlideShowViewMouseMotionListeners::implTypedNotify( const Reference< awt::XMouseMotionListener >& rListener,
177 const WrappedMouseMotionEvent& rEvent ) throw( uno::Exception )
179 switch( rEvent.meType )
181 case WrappedMouseMotionEvent::DRAGGED:
182 rListener->mouseDragged( rEvent.maEvent );
183 break;
185 case WrappedMouseMotionEvent::MOVED:
186 rListener->mouseMoved( rEvent.maEvent );
187 break;
190 return true; // continue calling listeners
193 ///////////////////////////////////////////////////////////////////////
194 // SlideShowView
195 ///////////////////////////////////////////////////////////////////////
197 SlideShowView::SlideShowView( ShowWindow& rOutputWindow,
198 SdDrawDocument* pDoc,
199 AnimationMode eAnimationMode,
200 SlideshowImpl* pSlideShow,
201 bool bFullScreen )
202 : SlideShowView_Base( m_aMutex ),
203 mpCanvas( ::cppcanvas::VCLFactory::getInstance().createSpriteCanvas( rOutputWindow ) ),
204 mxWindow( VCLUnoHelper::GetInterface( &rOutputWindow ), uno::UNO_QUERY_THROW ),
205 mxWindowPeer( mxWindow, uno::UNO_QUERY_THROW ),
206 mxPointer(),
207 mpSlideShow( pSlideShow ),
208 mrOutputWindow( rOutputWindow ),
209 mpViewListeners( new SlideShowViewListeners( m_aMutex ) ),
210 mpPaintListeners( new SlideShowViewPaintListeners( m_aMutex ) ),
211 mpMouseListeners( new SlideShowViewMouseListeners( m_aMutex ) ),
212 mpMouseMotionListeners( new SlideShowViewMouseMotionListeners( m_aMutex ) ),
213 mpDoc( pDoc ),
214 mbIsMouseMotionListener( false ),
215 meAnimationMode( eAnimationMode ),
216 mbFirstPaint( true ),
217 mbFullScreen( bFullScreen ),
218 mbMousePressedEaten( false )
220 init();
223 /// Dispose all internal references
224 void SAL_CALL SlideShowView::dispose() throw (RuntimeException)
226 ::osl::MutexGuard aGuard( m_aMutex );
228 mpSlideShow = 0;
230 // deregister listeners
231 if( mxWindow.is() )
233 mxWindow->removeWindowListener( this );
234 mxWindow->removeMouseListener( this );
236 if( mbIsMouseMotionListener )
237 mxWindow->removeMouseMotionListener( this );
240 mpCanvas.reset();
241 mxWindow.clear();
243 // clear all listener containers
244 disposing( lang::EventObject() );
246 // call base
247 WeakComponentImplHelperBase::dispose();
250 /// Disposing our broadcaster
251 void SAL_CALL SlideShowView::disposing( const lang::EventObject& ) throw(RuntimeException)
253 ::osl::MutexGuard aGuard( m_aMutex );
255 // notify all listeners that _we_ are going down (send a disposing()),
256 // then delete listener containers:
257 lang::EventObject const evt( static_cast<OWeakObject *>(this) );
258 if (mpViewListeners.get() != 0) {
259 mpViewListeners->disposing( evt );
260 mpViewListeners.reset();
262 if (mpPaintListeners.get() != 0) {
263 mpPaintListeners->disposing( evt );
264 mpPaintListeners.reset();
266 if (mpMouseListeners.get() != 0) {
267 mpMouseListeners->disposing( evt );
268 mpMouseListeners.reset();
270 if (mpMouseMotionListeners.get() != 0) {
271 mpMouseMotionListeners->disposing( evt );
272 mpMouseMotionListeners.reset();
276 void SAL_CALL SlideShowView::paint( const awt::PaintEvent& e ) throw (RuntimeException)
278 ::osl::ClearableMutexGuard aGuard( m_aMutex );
280 if( mbFirstPaint )
282 mbFirstPaint = false;
283 SlideshowImpl* pSlideShow = mpSlideShow;
284 aGuard.clear();
285 if( pSlideShow )
286 pSlideShow->onFirstPaint();
288 else
290 // Change event source, to enable listeners to match event
291 // with view
292 awt::PaintEvent aEvent( e );
293 aEvent.Source = static_cast< ::cppu::OWeakObject* >( this );
294 mpPaintListeners->notify( aEvent );
295 updateimpl( aGuard, mpSlideShow ); // warning: clears guard!
299 // XSlideShowView methods
300 Reference< rendering::XSpriteCanvas > SAL_CALL SlideShowView::getCanvas( ) throw (RuntimeException)
302 ::osl::MutexGuard aGuard( m_aMutex );
304 return mpCanvas.get() ? mpCanvas->getUNOSpriteCanvas() : Reference< rendering::XSpriteCanvas >();
307 void SAL_CALL SlideShowView::clear() throw (::com::sun::star::uno::RuntimeException)
309 // paint background in black
310 ::osl::MutexGuard aGuard( m_aMutex );
311 SolarMutexGuard aSolarGuard;
313 // fill the bounds rectangle in black
314 // ----------------------------------
316 const Size aWindowSize( mrOutputWindow.GetSizePixel() );
318 ::basegfx::B2DPolygon aPoly( ::basegfx::tools::createPolygonFromRect(
319 ::basegfx::B2DRectangle(0.0,0.0,
320 aWindowSize.Width(),
321 aWindowSize.Height() ) ) );
322 ::cppcanvas::PolyPolygonSharedPtr pPolyPoly(
323 ::cppcanvas::BaseGfxFactory::getInstance().createPolyPolygon( mpCanvas, aPoly ) );
325 if( pPolyPoly.get() )
327 pPolyPoly->setRGBAFillColor( 0x000000FFU );
328 pPolyPoly->draw();
332 geometry::AffineMatrix2D SAL_CALL SlideShowView::getTransformation( ) throw (RuntimeException)
334 ::osl::MutexGuard aGuard( m_aMutex );
335 SolarMutexGuard aSolarGuard;
337 const Size& rTmpSize( mrOutputWindow.GetSizePixel() );
339 if (rTmpSize.Width()<=0 || rTmpSize.Height()<=0)
341 return geometry::AffineMatrix2D (1,0,0,0,1,0);
344 const Size aWindowSize( mrOutputWindow.GetSizePixel() );
345 Size aOutputSize( aWindowSize );
347 if( meAnimationMode != ANIMATIONMODE_SHOW )
349 aOutputSize.Width() = (long)( aOutputSize.Width() / 1.03 );
350 aOutputSize.Height() = (long)( aOutputSize.Height() / 1.03 );
353 SdPage* pP = mpDoc->GetSdPage( 0, PK_STANDARD );
354 Size aPageSize( pP->GetSize() );
356 const double page_ratio = (double)aPageSize.Width() / (double)aPageSize.Height();
357 const double output_ratio = (double)aOutputSize.Width() / (double)aOutputSize.Height();
359 if( page_ratio > output_ratio )
361 aOutputSize.Height() = ( aOutputSize.Width() * aPageSize.Height() ) / aPageSize.Width();
363 else if( page_ratio < output_ratio )
365 aOutputSize.Width() = ( aOutputSize.Height() * aPageSize.Width() ) / aPageSize.Height();
368 Point aOutputOffset( ( aWindowSize.Width() - aOutputSize.Width() ) >> 1,
369 ( aWindowSize.Height() - aOutputSize.Height() ) >> 1 );
371 // Reduce available width by one, as the slides might actually
372 // render one pixel wider and higher as aPageSize below specifies
373 // (when shapes of page size have visible border lines)
374 aOutputSize.Width() --;
375 aOutputSize.Height() --;
377 maPresentationArea = Rectangle( aOutputOffset, aOutputSize );
378 mrOutputWindow.SetPresentationArea( maPresentationArea );
380 // scale presentation into available window rect (minus 10%); center in the window
381 const basegfx::B2DHomMatrix aMatrix(basegfx::tools::createScaleTranslateB2DHomMatrix(
382 aOutputSize.Width(), aOutputSize.Height(), aOutputOffset.X(), aOutputOffset.Y()));
384 geometry::AffineMatrix2D aRes;
386 return ::basegfx::unotools::affineMatrixFromHomMatrix( aRes, aMatrix );
389 void SAL_CALL SlideShowView::addTransformationChangedListener( const Reference< util::XModifyListener >& xListener ) throw (RuntimeException)
391 ::osl::MutexGuard aGuard( m_aMutex );
393 if( mpViewListeners.get() )
394 mpViewListeners->addListener( xListener );
397 void SAL_CALL SlideShowView::removeTransformationChangedListener( const Reference< util::XModifyListener >& xListener ) throw (RuntimeException)
399 ::osl::MutexGuard aGuard( m_aMutex );
401 if( mpViewListeners.get() )
402 mpViewListeners->removeListener( xListener );
405 void SAL_CALL SlideShowView::addPaintListener( const Reference< awt::XPaintListener >& xListener ) throw (RuntimeException)
407 ::osl::MutexGuard aGuard( m_aMutex );
409 if( mpPaintListeners.get() )
410 mpPaintListeners->addTypedListener( xListener );
413 void SAL_CALL SlideShowView::removePaintListener( const Reference< awt::XPaintListener >& xListener ) throw (RuntimeException)
415 ::osl::MutexGuard aGuard( m_aMutex );
417 if( mpPaintListeners.get() )
418 mpPaintListeners->removeTypedListener( xListener );
421 void SAL_CALL SlideShowView::addMouseListener( const Reference< awt::XMouseListener >& xListener ) throw (RuntimeException)
423 ::osl::MutexGuard aGuard( m_aMutex );
425 if( mpMouseListeners.get() )
426 mpMouseListeners->addTypedListener( xListener );
429 void SAL_CALL SlideShowView::removeMouseListener( const Reference< awt::XMouseListener >& xListener ) throw (RuntimeException)
431 ::osl::MutexGuard aGuard( m_aMutex );
433 if( mpMouseListeners.get() )
434 mpMouseListeners->removeTypedListener( xListener );
437 void SAL_CALL SlideShowView::addMouseMotionListener( const Reference< awt::XMouseMotionListener >& xListener ) throw (RuntimeException)
439 ::osl::MutexGuard aGuard( m_aMutex );
441 if( !mbIsMouseMotionListener && mxWindow.is() )
443 // delay motion event registration, until we really
444 // need it
445 mbIsMouseMotionListener = true;
446 mxWindow->addMouseMotionListener( this );
449 if( mpMouseMotionListeners.get() )
450 mpMouseMotionListeners->addTypedListener( xListener );
453 void SAL_CALL SlideShowView::removeMouseMotionListener( const Reference< awt::XMouseMotionListener >& xListener ) throw (RuntimeException)
455 ::osl::MutexGuard aGuard( m_aMutex );
457 if( mpMouseMotionListeners.get() )
458 mpMouseMotionListeners->removeTypedListener( xListener );
460 // TODO(P1): Might be nice to deregister for mouse motion
461 // events, when the last listener is gone.
464 void SAL_CALL SlideShowView::setMouseCursor( sal_Int16 nPointerShape ) throw (RuntimeException)
466 ::osl::MutexGuard aGuard( m_aMutex );
468 // forward to window
469 if( mxPointer.is() )
470 mxPointer->setType( nPointerShape );
472 if( mxWindowPeer.is() )
473 mxWindowPeer->setPointer( mxPointer );
476 awt::Rectangle SAL_CALL SlideShowView::getCanvasArea( ) throw (RuntimeException)
478 awt::Rectangle aRectangle;
480 if( mxWindow.is() )
481 return mxWindow->getPosSize();
483 aRectangle.X = aRectangle.Y = aRectangle.Width = aRectangle.Height = 0;
485 return aRectangle;
488 void SlideShowView::updateimpl( ::osl::ClearableMutexGuard& rGuard, SlideshowImpl* pSlideShow )
490 if( pSlideShow )
492 ::rtl::Reference< SlideshowImpl > aSLGuard( pSlideShow );
494 if( mbFirstPaint )
496 mbFirstPaint = false;
497 SlideshowImpl* pTmpSlideShow = mpSlideShow;
498 rGuard.clear();
499 if( pTmpSlideShow )
500 pTmpSlideShow->onFirstPaint();
501 } else
502 rGuard.clear();
504 pSlideShow->startUpdateTimer();
508 // XWindowListener methods
509 void SAL_CALL SlideShowView::windowResized( const awt::WindowEvent& e ) throw (RuntimeException)
511 ::osl::ClearableMutexGuard aGuard( m_aMutex );
513 if( mpViewListeners.get() )
515 // Change event source, to enable listeners to match event
516 // with view
517 awt::WindowEvent aEvent( e );
518 aEvent.Source = static_cast< ::cppu::OWeakObject* >( this );
520 mpViewListeners->notify( aEvent );
521 updateimpl( aGuard, mpSlideShow ); // warning: clears guard!
525 void SAL_CALL SlideShowView::windowMoved( const awt::WindowEvent& ) throw (RuntimeException)
527 // ignored
530 void SAL_CALL SlideShowView::windowShown( const lang::EventObject& ) throw (RuntimeException)
532 // ignored
535 void SAL_CALL SlideShowView::windowHidden( const lang::EventObject& ) throw (RuntimeException)
537 // ignored
540 // XMouseListener implementation
541 void SAL_CALL SlideShowView::mousePressed( const awt::MouseEvent& e ) throw (uno::RuntimeException)
543 ::osl::ClearableMutexGuard aGuard( m_aMutex );
544 if( mpSlideShow && mpSlideShow->isInputFreezed() )
546 mbMousePressedEaten = true;
548 else
550 mbMousePressedEaten = false;
552 // Change event source, to enable listeners to match event
553 // with view
554 WrappedMouseEvent aEvent;
555 aEvent.meType = WrappedMouseEvent::PRESSED;
556 aEvent.maEvent = e;
557 aEvent.maEvent.Source = static_cast< ::cppu::OWeakObject* >( this );
559 if( mpMouseListeners.get() )
560 mpMouseListeners->notify( aEvent );
561 updateimpl( aGuard, mpSlideShow ); // warning: clears guard!
565 void SAL_CALL SlideShowView::mouseReleased( const awt::MouseEvent& e ) throw (uno::RuntimeException)
567 ::osl::ClearableMutexGuard aGuard( m_aMutex );
568 if( mbMousePressedEaten )
570 // if mouse button down was ignored, also ignore mouse button up
571 mbMousePressedEaten = false;
573 else if( mpSlideShow && !mpSlideShow->isInputFreezed() )
575 // Change event source, to enable listeners to match event
576 // with view
577 WrappedMouseEvent aEvent;
578 aEvent.meType = WrappedMouseEvent::RELEASED;
579 aEvent.maEvent = e;
580 aEvent.maEvent.Source = static_cast< ::cppu::OWeakObject* >( this );
582 if( mpMouseListeners.get() )
583 mpMouseListeners->notify( aEvent );
584 updateimpl( aGuard, mpSlideShow ); // warning: clears guard!
588 void SAL_CALL SlideShowView::mouseEntered( const awt::MouseEvent& e ) throw (uno::RuntimeException)
590 ::osl::ClearableMutexGuard aGuard( m_aMutex );
592 // Change event source, to enable listeners to match event
593 // with view
594 WrappedMouseEvent aEvent;
595 aEvent.meType = WrappedMouseEvent::ENTERED;
596 aEvent.maEvent = e;
597 aEvent.maEvent.Source = static_cast< ::cppu::OWeakObject* >( this );
599 if( mpMouseListeners.get() )
600 mpMouseListeners->notify( aEvent );
601 updateimpl( aGuard, mpSlideShow ); // warning: clears guard!
604 void SAL_CALL SlideShowView::mouseExited( const awt::MouseEvent& e ) throw (uno::RuntimeException)
606 ::osl::ClearableMutexGuard aGuard( m_aMutex );
608 // Change event source, to enable listeners to match event
609 // with view
610 WrappedMouseEvent aEvent;
611 aEvent.meType = WrappedMouseEvent::EXITED;
612 aEvent.maEvent = e;
613 aEvent.maEvent.Source = static_cast< ::cppu::OWeakObject* >( this );
615 if( mpMouseListeners.get() )
616 mpMouseListeners->notify( aEvent );
617 updateimpl( aGuard, mpSlideShow ); // warning: clears guard!
620 // XMouseMotionListener implementation
621 void SAL_CALL SlideShowView::mouseDragged( const awt::MouseEvent& e ) throw (uno::RuntimeException)
623 ::osl::ClearableMutexGuard aGuard( m_aMutex );
625 // Change event source, to enable listeners to match event
626 // with view
627 WrappedMouseMotionEvent aEvent;
628 aEvent.meType = WrappedMouseMotionEvent::DRAGGED;
629 aEvent.maEvent = e;
630 aEvent.maEvent.Source = static_cast< ::cppu::OWeakObject* >( this );
632 if( mpMouseMotionListeners.get() )
633 mpMouseMotionListeners->notify( aEvent );
634 updateimpl( aGuard, mpSlideShow ); // warning: clears guard!
637 void SAL_CALL SlideShowView::mouseMoved( const awt::MouseEvent& e ) throw (uno::RuntimeException)
639 ::osl::ClearableMutexGuard aGuard( m_aMutex );
641 // Change event source, to enable listeners to match event
642 // with view
643 WrappedMouseMotionEvent aEvent;
644 aEvent.meType = WrappedMouseMotionEvent::MOVED;
645 aEvent.maEvent = e;
646 aEvent.maEvent.Source = static_cast< ::cppu::OWeakObject* >( this );
648 if( mpMouseMotionListeners.get() )
649 mpMouseMotionListeners->notify( aEvent );
650 updateimpl( aGuard, mpSlideShow ); // warning: clears guard!
653 void SlideShowView::init()
655 mxWindow->addWindowListener( this );
656 mxWindow->addMouseListener( this );
658 mxPointer = awt::Pointer::create( ::comphelper::getProcessComponentContext() );
660 getTransformation();
662 // #i48939# only switch on kind of hacky scroll optimisation, when
663 // running fullscreen. this minimizes the probability that other
664 // windows partially cover the show.
665 if( mbFullScreen )
669 Reference< beans::XPropertySet > xCanvasProps( getCanvas(),
670 uno::UNO_QUERY_THROW );
671 xCanvasProps->setPropertyValue("UnsafeScrolling",
672 uno::makeAny( true ) );
674 catch( uno::Exception& )
680 } // namespace ::sd
682 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */