bump product version to 5.0.4.1
[LibreOffice.git] / sd / source / ui / slideshow / slideshowviewimpl.cxx
blob7ae836be6975d45e83ac18f4e1b4e1adabc15d45
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>
34 using ::com::sun::star::uno::UNO_QUERY;
35 using ::com::sun::star::uno::XInterface;
36 using ::com::sun::star::uno::Reference;
37 using ::com::sun::star::uno::WeakReference;
38 using ::com::sun::star::uno::RuntimeException;
39 using ::com::sun::star::lang::XComponent;
40 using ::com::sun::star::uno::Exception;
41 using ::com::sun::star::presentation::XSlideShow;
42 using ::com::sun::star::presentation::XSlideShowView;
43 using ::com::sun::star::presentation::XShapeEventListener;
44 using ::com::sun::star::presentation::XSlideShowListener;
46 using namespace ::com::sun::star;
48 namespace sd
51 // SlideShowViewListeners
52 SlideShowViewListeners::SlideShowViewListeners( ::osl::Mutex& rMutex )
53 : mrMutex( rMutex )
57 void SlideShowViewListeners::addListener( const Reference< util::XModifyListener >& _rxListener )
59 ::osl::MutexGuard aGuard( mrMutex );
61 WeakReference< util::XModifyListener > xWeak( _rxListener );
62 if( std::find( maListeners.begin(), maListeners.end(), xWeak ) == maListeners.end() )
63 maListeners.push_back( xWeak );
66 void SlideShowViewListeners::removeListener( const Reference< util::XModifyListener >& _rxListener )
68 ::osl::MutexGuard aGuard( mrMutex );
70 WeakReference< util::XModifyListener > xWeak( _rxListener );
71 ViewListenerVector::iterator aIter( std::find( maListeners.begin(), maListeners.end(), xWeak ) );
72 if( aIter != maListeners.end() )
73 maListeners.erase( aIter );
76 bool SlideShowViewListeners::notify( const lang::EventObject& _rEvent ) throw( com::sun::star::uno::Exception )
78 ::osl::MutexGuard aGuard( mrMutex );
80 ViewListenerVector::iterator aIter( maListeners.begin() );
81 while( aIter != maListeners.end() )
83 Reference< util::XModifyListener > xListener( (*aIter) );
84 if( xListener.is() )
86 xListener->modified( _rEvent );
87 ++aIter;
89 else
91 aIter = maListeners.erase( aIter );
94 return true;
97 void SlideShowViewListeners::disposing( const lang::EventObject& _rEventSource )
99 ::osl::MutexGuard aGuard( mrMutex );
101 ViewListenerVector::iterator aIter( maListeners.begin() );
102 while( aIter != maListeners.end() )
104 Reference< util::XModifyListener > xListener( (*aIter++) );
105 if( xListener.is() )
106 xListener->disposing( _rEventSource );
109 maListeners.clear();
112 // SlideShowViewPaintListeners
113 SlideShowViewPaintListeners::SlideShowViewPaintListeners( ::osl::Mutex& rMutex )
114 : SlideShowViewPaintListeners_Base( rMutex )
118 bool SlideShowViewPaintListeners::implTypedNotify( const Reference< awt::XPaintListener >& rListener,
119 const awt::PaintEvent& rEvent ) throw( uno::Exception )
121 rListener->windowPaint( rEvent );
122 return true; // continue calling listeners
125 // SlideShowViewMouseListeners
126 SlideShowViewMouseListeners::SlideShowViewMouseListeners( ::osl::Mutex& rMutex ) :
127 SlideShowViewMouseListeners_Base( rMutex )
131 bool SlideShowViewMouseListeners::implTypedNotify( const Reference< awt::XMouseListener >& rListener,
132 const WrappedMouseEvent& rEvent ) throw( uno::Exception )
134 switch( rEvent.meType )
136 case WrappedMouseEvent::PRESSED:
137 rListener->mousePressed( rEvent.maEvent );
138 break;
140 case WrappedMouseEvent::RELEASED:
141 rListener->mouseReleased( rEvent.maEvent );
142 break;
144 case WrappedMouseEvent::ENTERED:
145 rListener->mouseEntered( rEvent.maEvent );
146 break;
148 case WrappedMouseEvent::EXITED:
149 rListener->mouseExited( rEvent.maEvent );
150 break;
153 return true; // continue calling listeners
156 // SlideShowViewMouseMotionListeners
157 SlideShowViewMouseMotionListeners::SlideShowViewMouseMotionListeners( ::osl::Mutex& rMutex ) :
158 SlideShowViewMouseMotionListeners_Base( rMutex )
162 bool SlideShowViewMouseMotionListeners::implTypedNotify( const Reference< awt::XMouseMotionListener >& rListener,
163 const WrappedMouseMotionEvent& rEvent ) throw( uno::Exception )
165 switch( rEvent.meType )
167 case WrappedMouseMotionEvent::DRAGGED:
168 rListener->mouseDragged( rEvent.maEvent );
169 break;
171 case WrappedMouseMotionEvent::MOVED:
172 rListener->mouseMoved( rEvent.maEvent );
173 break;
176 return true; // continue calling listeners
179 // SlideShowView
180 SlideShowView::SlideShowView( ShowWindow& rOutputWindow,
181 SdDrawDocument* pDoc,
182 AnimationMode eAnimationMode,
183 SlideshowImpl* pSlideShow,
184 bool bFullScreen )
185 : SlideShowView_Base( m_aMutex ),
186 mpCanvas( ::cppcanvas::VCLFactory::createSpriteCanvas( rOutputWindow ) ),
187 mxWindow( VCLUnoHelper::GetInterface( &rOutputWindow ), uno::UNO_QUERY_THROW ),
188 mxWindowPeer( mxWindow, uno::UNO_QUERY_THROW ),
189 mxPointer(),
190 mpSlideShow( pSlideShow ),
191 mrOutputWindow( rOutputWindow ),
192 mpViewListeners( new SlideShowViewListeners( m_aMutex ) ),
193 mpPaintListeners( new SlideShowViewPaintListeners( m_aMutex ) ),
194 mpMouseListeners( new SlideShowViewMouseListeners( m_aMutex ) ),
195 mpMouseMotionListeners( new SlideShowViewMouseMotionListeners( m_aMutex ) ),
196 mpDoc( pDoc ),
197 mbIsMouseMotionListener( false ),
198 meAnimationMode( eAnimationMode ),
199 mbFirstPaint( true ),
200 mbFullScreen( bFullScreen ),
201 mbMousePressedEaten( false )
203 init();
205 mTranslationOffset.Width = 0;
206 mTranslationOffset.Height = 0;
209 // Dispose all internal references
210 void SAL_CALL SlideShowView::dispose() throw (RuntimeException, std::exception)
212 ::osl::MutexGuard aGuard( m_aMutex );
214 mpSlideShow = 0;
216 // deregister listeners
217 if( mxWindow.is() )
219 mxWindow->removeWindowListener( this );
220 mxWindow->removeMouseListener( this );
222 if( mbIsMouseMotionListener )
223 mxWindow->removeMouseMotionListener( this );
226 mpCanvas.reset();
227 mxWindow.clear();
229 // clear all listener containers
230 disposing( lang::EventObject() );
232 // call base
233 WeakComponentImplHelperBase::dispose();
236 // Disposing our broadcaster
237 void SAL_CALL SlideShowView::disposing( const lang::EventObject& ) throw(RuntimeException, std::exception)
239 ::osl::MutexGuard aGuard( m_aMutex );
241 // notify all listeners that _we_ are going down (send a disposing()),
242 // then delete listener containers:
243 lang::EventObject const evt( static_cast<OWeakObject *>(this) );
244 if (mpViewListeners.get() != 0) {
245 mpViewListeners->disposing( evt );
246 mpViewListeners.reset();
248 if (mpPaintListeners.get() != 0) {
249 mpPaintListeners->disposing( evt );
250 mpPaintListeners.reset();
252 if (mpMouseListeners.get() != 0) {
253 mpMouseListeners->disposing( evt );
254 mpMouseListeners.reset();
256 if (mpMouseMotionListeners.get() != 0) {
257 mpMouseMotionListeners->disposing( evt );
258 mpMouseMotionListeners.reset();
262 void SAL_CALL SlideShowView::paint( const awt::PaintEvent& e ) throw (RuntimeException)
264 ::osl::ClearableMutexGuard aGuard( m_aMutex );
266 if( mbFirstPaint )
268 mbFirstPaint = false;
269 SlideshowImpl* pSlideShow = mpSlideShow;
270 aGuard.clear();
271 if( pSlideShow )
272 pSlideShow->onFirstPaint();
274 else
276 // Change event source, to enable listeners to match event
277 // with view
278 awt::PaintEvent aEvent( e );
279 aEvent.Source = static_cast< ::cppu::OWeakObject* >( this );
280 mpPaintListeners->notify( aEvent );
281 updateimpl( aGuard, mpSlideShow ); // warning: clears guard!
285 // XSlideShowView methods
286 Reference< rendering::XSpriteCanvas > SAL_CALL SlideShowView::getCanvas( ) throw (RuntimeException, std::exception)
288 ::osl::MutexGuard aGuard( m_aMutex );
290 return mpCanvas.get() ? mpCanvas->getUNOSpriteCanvas() : Reference< rendering::XSpriteCanvas >();
293 void SAL_CALL SlideShowView::clear() throw (::com::sun::star::uno::RuntimeException, std::exception)
295 // paint background in black
296 ::osl::MutexGuard aGuard( m_aMutex );
297 SolarMutexGuard aSolarGuard;
299 // fill the bounds rectangle in black
301 const Size aWindowSize( mrOutputWindow.GetSizePixel() );
303 ::basegfx::B2DPolygon aPoly( ::basegfx::tools::createPolygonFromRect(
304 ::basegfx::B2DRectangle(0.0,0.0,
305 aWindowSize.Width(),
306 aWindowSize.Height() ) ) );
307 ::cppcanvas::PolyPolygonSharedPtr pPolyPoly(
308 ::cppcanvas::BaseGfxFactory::createPolyPolygon( mpCanvas, aPoly ) );
310 if( pPolyPoly.get() )
312 pPolyPoly->setRGBAFillColor( 0x000000FFU );
313 pPolyPoly->draw();
317 geometry::IntegerSize2D SAL_CALL SlideShowView::getTranslationOffset( ) throw (RuntimeException, std::exception)
319 return mTranslationOffset;
322 geometry::AffineMatrix2D SAL_CALL SlideShowView::getTransformation( ) throw (RuntimeException, std::exception)
324 ::osl::MutexGuard aGuard( m_aMutex );
325 SolarMutexGuard aSolarGuard;
327 const Size& rTmpSize( mrOutputWindow.GetSizePixel() );
329 if (rTmpSize.Width()<=0 || rTmpSize.Height()<=0)
331 return geometry::AffineMatrix2D (1,0,0,0,1,0);
334 const Size aWindowSize( mrOutputWindow.GetSizePixel() );
335 Size aOutputSize( aWindowSize );
337 if( meAnimationMode != ANIMATIONMODE_SHOW )
339 aOutputSize.Width() = (long)( aOutputSize.Width() / 1.03 );
340 aOutputSize.Height() = (long)( aOutputSize.Height() / 1.03 );
343 SdPage* pP = mpDoc->GetSdPage( 0, PK_STANDARD );
344 Size aPageSize( pP->GetSize() );
346 const double page_ratio = (double)aPageSize.Width() / (double)aPageSize.Height();
347 const double output_ratio = (double)aOutputSize.Width() / (double)aOutputSize.Height();
349 if( page_ratio > output_ratio )
351 aOutputSize.Height() = ( aOutputSize.Width() * aPageSize.Height() ) / aPageSize.Width();
353 else if( page_ratio < output_ratio )
355 aOutputSize.Width() = ( aOutputSize.Height() * aPageSize.Width() ) / aPageSize.Height();
358 Point aOutputOffset( ( aWindowSize.Width() - aOutputSize.Width() ) >> 1,
359 ( aWindowSize.Height() - aOutputSize.Height() ) >> 1 );
361 // Reduce available width by one, as the slides might actually
362 // render one pixel wider and higher as aPageSize below specifies
363 // (when shapes of page size have visible border lines)
364 aOutputSize.Width() --;
365 aOutputSize.Height() --;
367 // Record mTranslationOffset
368 mTranslationOffset.Height = aOutputOffset.Y();
369 mTranslationOffset.Width = aOutputOffset.X();
371 maPresentationArea = Rectangle( aOutputOffset, aOutputSize );
372 mrOutputWindow.SetPresentationArea( maPresentationArea );
374 // scale presentation into available window rect (minus 10%); center in the window
375 const basegfx::B2DHomMatrix aMatrix(basegfx::tools::createScaleTranslateB2DHomMatrix(
376 aOutputSize.Width(), aOutputSize.Height(), aOutputOffset.X(), aOutputOffset.Y()));
378 geometry::AffineMatrix2D aRes;
380 return ::basegfx::unotools::affineMatrixFromHomMatrix( aRes, aMatrix );
383 void SAL_CALL SlideShowView::addTransformationChangedListener( const Reference< util::XModifyListener >& xListener ) throw (RuntimeException, std::exception)
385 ::osl::MutexGuard aGuard( m_aMutex );
387 if( mpViewListeners.get() )
388 mpViewListeners->addListener( xListener );
391 void SAL_CALL SlideShowView::removeTransformationChangedListener( const Reference< util::XModifyListener >& xListener ) throw (RuntimeException, std::exception)
393 ::osl::MutexGuard aGuard( m_aMutex );
395 if( mpViewListeners.get() )
396 mpViewListeners->removeListener( xListener );
399 void SAL_CALL SlideShowView::addPaintListener( const Reference< awt::XPaintListener >& xListener ) throw (RuntimeException, std::exception)
401 ::osl::MutexGuard aGuard( m_aMutex );
403 if( mpPaintListeners.get() )
404 mpPaintListeners->addTypedListener( xListener );
407 void SAL_CALL SlideShowView::removePaintListener( const Reference< awt::XPaintListener >& xListener ) throw (RuntimeException, std::exception)
409 ::osl::MutexGuard aGuard( m_aMutex );
411 if( mpPaintListeners.get() )
412 mpPaintListeners->removeTypedListener( xListener );
415 void SAL_CALL SlideShowView::addMouseListener( const Reference< awt::XMouseListener >& xListener ) throw (RuntimeException, std::exception)
417 ::osl::MutexGuard aGuard( m_aMutex );
419 if( mpMouseListeners.get() )
420 mpMouseListeners->addTypedListener( xListener );
423 void SAL_CALL SlideShowView::removeMouseListener( const Reference< awt::XMouseListener >& xListener ) throw (RuntimeException, std::exception)
425 ::osl::MutexGuard aGuard( m_aMutex );
427 if( mpMouseListeners.get() )
428 mpMouseListeners->removeTypedListener( xListener );
431 void SAL_CALL SlideShowView::addMouseMotionListener( const Reference< awt::XMouseMotionListener >& xListener ) throw (RuntimeException, std::exception)
433 ::osl::MutexGuard aGuard( m_aMutex );
435 if( !mbIsMouseMotionListener && mxWindow.is() )
437 // delay motion event registration, until we really
438 // need it
439 mbIsMouseMotionListener = true;
440 mxWindow->addMouseMotionListener( this );
443 if( mpMouseMotionListeners.get() )
444 mpMouseMotionListeners->addTypedListener( xListener );
447 void SAL_CALL SlideShowView::removeMouseMotionListener( const Reference< awt::XMouseMotionListener >& xListener ) throw (RuntimeException, std::exception)
449 ::osl::MutexGuard aGuard( m_aMutex );
451 if( mpMouseMotionListeners.get() )
452 mpMouseMotionListeners->removeTypedListener( xListener );
454 // TODO(P1): Might be nice to deregister for mouse motion
455 // events, when the last listener is gone.
458 void SAL_CALL SlideShowView::setMouseCursor( sal_Int16 nPointerShape ) throw (RuntimeException, std::exception)
460 ::osl::MutexGuard aGuard( m_aMutex );
462 // forward to window
463 if( mxPointer.is() )
464 mxPointer->setType( nPointerShape );
466 if( mxWindowPeer.is() )
467 mxWindowPeer->setPointer( mxPointer );
470 awt::Rectangle SAL_CALL SlideShowView::getCanvasArea( ) throw (RuntimeException, std::exception)
472 awt::Rectangle aRectangle;
474 if( mxWindow.is() )
475 return mxWindow->getPosSize();
477 aRectangle.X = aRectangle.Y = aRectangle.Width = aRectangle.Height = 0;
479 return aRectangle;
482 void SlideShowView::updateimpl( ::osl::ClearableMutexGuard& rGuard, SlideshowImpl* pSlideShow )
484 if( pSlideShow )
486 ::rtl::Reference< SlideshowImpl > aSLGuard( pSlideShow );
488 if( mbFirstPaint )
490 mbFirstPaint = false;
491 SlideshowImpl* pTmpSlideShow = mpSlideShow;
492 rGuard.clear();
493 if( pTmpSlideShow )
494 pTmpSlideShow->onFirstPaint();
495 } else
496 rGuard.clear();
498 pSlideShow->startUpdateTimer();
502 // XWindowListener methods
503 void SAL_CALL SlideShowView::windowResized( const awt::WindowEvent& e ) throw (RuntimeException, std::exception)
505 ::osl::ClearableMutexGuard aGuard( m_aMutex );
507 if( mpViewListeners.get() )
509 // Change event source, to enable listeners to match event
510 // with view
511 awt::WindowEvent aEvent( e );
512 aEvent.Source = static_cast< ::cppu::OWeakObject* >( this );
514 mpViewListeners->notify( aEvent );
515 updateimpl( aGuard, mpSlideShow ); // warning: clears guard!
519 void SAL_CALL SlideShowView::windowMoved( const awt::WindowEvent& ) throw (RuntimeException, std::exception)
521 // ignored
524 void SAL_CALL SlideShowView::windowShown( const lang::EventObject& ) throw (RuntimeException, std::exception)
526 // ignored
529 void SAL_CALL SlideShowView::windowHidden( const lang::EventObject& ) throw (RuntimeException, std::exception)
531 // ignored
534 // XMouseListener implementation
535 void SAL_CALL SlideShowView::mousePressed( const awt::MouseEvent& e ) throw (uno::RuntimeException, std::exception)
537 ::osl::ClearableMutexGuard aGuard( m_aMutex );
538 if( mpSlideShow && mpSlideShow->isInputFreezed() )
540 mbMousePressedEaten = true;
542 else
544 mbMousePressedEaten = false;
546 // Change event source, to enable listeners to match event
547 // with view
548 WrappedMouseEvent aEvent;
549 aEvent.meType = WrappedMouseEvent::PRESSED;
550 aEvent.maEvent = e;
551 aEvent.maEvent.Source = static_cast< ::cppu::OWeakObject* >( this );
553 if( mpMouseListeners.get() )
554 mpMouseListeners->notify( aEvent );
555 updateimpl( aGuard, mpSlideShow ); // warning: clears guard!
559 void SAL_CALL SlideShowView::mouseReleased( const awt::MouseEvent& e ) throw (uno::RuntimeException, std::exception)
561 ::osl::ClearableMutexGuard aGuard( m_aMutex );
562 if( mbMousePressedEaten )
564 // if mouse button down was ignored, also ignore mouse button up
565 mbMousePressedEaten = false;
567 else if( mpSlideShow && !mpSlideShow->isInputFreezed() )
569 // Change event source, to enable listeners to match event
570 // with view
571 WrappedMouseEvent aEvent;
572 aEvent.meType = WrappedMouseEvent::RELEASED;
573 aEvent.maEvent = e;
574 aEvent.maEvent.Source = static_cast< ::cppu::OWeakObject* >( this );
576 if( mpMouseListeners.get() )
577 mpMouseListeners->notify( aEvent );
578 updateimpl( aGuard, mpSlideShow ); // warning: clears guard!
582 void SAL_CALL SlideShowView::mouseEntered( const awt::MouseEvent& e ) throw (uno::RuntimeException, std::exception)
584 ::osl::ClearableMutexGuard aGuard( m_aMutex );
586 // Change event source, to enable listeners to match event
587 // with view
588 WrappedMouseEvent aEvent;
589 aEvent.meType = WrappedMouseEvent::ENTERED;
590 aEvent.maEvent = e;
591 aEvent.maEvent.Source = static_cast< ::cppu::OWeakObject* >( this );
593 if( mpMouseListeners.get() )
594 mpMouseListeners->notify( aEvent );
595 updateimpl( aGuard, mpSlideShow ); // warning: clears guard!
598 void SAL_CALL SlideShowView::mouseExited( const awt::MouseEvent& e ) throw (uno::RuntimeException, std::exception)
600 ::osl::ClearableMutexGuard aGuard( m_aMutex );
602 // Change event source, to enable listeners to match event
603 // with view
604 WrappedMouseEvent aEvent;
605 aEvent.meType = WrappedMouseEvent::EXITED;
606 aEvent.maEvent = e;
607 aEvent.maEvent.Source = static_cast< ::cppu::OWeakObject* >( this );
609 if( mpMouseListeners.get() )
610 mpMouseListeners->notify( aEvent );
611 updateimpl( aGuard, mpSlideShow ); // warning: clears guard!
614 // XMouseMotionListener implementation
615 void SAL_CALL SlideShowView::mouseDragged( const awt::MouseEvent& e ) throw (uno::RuntimeException, std::exception)
617 ::osl::ClearableMutexGuard aGuard( m_aMutex );
619 // Change event source, to enable listeners to match event
620 // with view
621 WrappedMouseMotionEvent aEvent;
622 aEvent.meType = WrappedMouseMotionEvent::DRAGGED;
623 aEvent.maEvent = e;
624 aEvent.maEvent.Source = static_cast< ::cppu::OWeakObject* >( this );
626 if( mpMouseMotionListeners.get() )
627 mpMouseMotionListeners->notify( aEvent );
628 updateimpl( aGuard, mpSlideShow ); // warning: clears guard!
631 void SAL_CALL SlideShowView::mouseMoved( const awt::MouseEvent& e ) throw (uno::RuntimeException, std::exception)
633 ::osl::ClearableMutexGuard aGuard( m_aMutex );
635 // Change event source, to enable listeners to match event
636 // with view
637 WrappedMouseMotionEvent aEvent;
638 aEvent.meType = WrappedMouseMotionEvent::MOVED;
639 aEvent.maEvent = e;
640 aEvent.maEvent.Source = static_cast< ::cppu::OWeakObject* >( this );
642 if( mpMouseMotionListeners.get() )
643 mpMouseMotionListeners->notify( aEvent );
644 updateimpl( aGuard, mpSlideShow ); // warning: clears guard!
647 void SlideShowView::init()
649 mxWindow->addWindowListener( this );
650 mxWindow->addMouseListener( this );
652 mxPointer = awt::Pointer::create( ::comphelper::getProcessComponentContext() );
654 getTransformation();
656 // #i48939# only switch on kind of hacky scroll optimization, when
657 // running fullscreen. this minimizes the probability that other
658 // windows partially cover the show.
659 if( mbFullScreen )
663 Reference< beans::XPropertySet > xCanvasProps( getCanvas(),
664 uno::UNO_QUERY_THROW );
665 xCanvasProps->setPropertyValue("UnsafeScrolling",
666 uno::makeAny( true ) );
668 catch( uno::Exception& )
674 } // namespace ::sd
676 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */