merge the formfield patch from ooo-build
[ooovba.git] / slideshow / source / engine / slide / slideimpl.cxx
blob4cc5b050a2c84ea4c5468e31a96da26a34c27b46
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: slideimpl.cxx,v $
10 * $Revision: 1.4 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_slideshow.hxx"
34 #include <osl/diagnose.hxx>
35 #include <canvas/debug.hxx>
36 #include <tools/diagnose_ex.h>
37 #include <canvas/canvastools.hxx>
38 #include <cppcanvas/basegfxfactory.hxx>
40 #include <basegfx/matrix/b2dhommatrix.hxx>
41 #include <basegfx/point/b2dpoint.hxx>
42 #include <basegfx/polygon/b2dpolygon.hxx>
43 #include <basegfx/polygon/b2dpolygontools.hxx>
44 #include <basegfx/numeric/ftools.hxx>
46 #include <com/sun/star/awt/SystemPointer.hpp>
47 #include <com/sun/star/container/XIndexAccess.hpp>
48 #include <com/sun/star/drawing/XMasterPageTarget.hpp>
49 #include <com/sun/star/beans/XPropertySet.hpp>
50 #include <com/sun/star/container/XEnumerationAccess.hpp>
51 #include <com/sun/star/awt/Rectangle.hpp>
52 #include <com/sun/star/presentation/ParagraphTarget.hpp>
53 #include <com/sun/star/presentation/EffectNodeType.hpp>
54 #include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
55 #include <com/sun/star/animations/XTargetPropertiesCreator.hpp>
56 #include <com/sun/star/drawing/TextAnimationKind.hpp>
58 #include <animations/animationnodehelper.hxx>
60 #include <cppuhelper/exc_hlp.hxx>
61 #include <comphelper/anytostring.hxx>
63 #include "slide.hxx"
64 #include "slideshowcontext.hxx"
65 #include "slideanimations.hxx"
66 #include "doctreenode.hxx"
67 #include "screenupdater.hxx"
68 #include "cursormanager.hxx"
69 #include "shapeimporter.hxx"
70 #include "slideshowexceptions.hxx"
71 #include "eventqueue.hxx"
72 #include "activitiesqueue.hxx"
73 #include "layermanager.hxx"
74 #include "shapemanagerimpl.hxx"
75 #include "usereventqueue.hxx"
76 #include "userpaintoverlay.hxx"
77 #include "event.hxx"
78 #include "tools.hxx"
80 #include <boost/bind.hpp>
81 #include <iterator>
82 #include <algorithm>
83 #include <functional>
86 using namespace ::com::sun::star;
88 // -----------------------------------------------------------------------------
90 namespace slideshow
92 namespace internal
94 namespace
97 class SlideImpl : public Slide,
98 public CursorManager,
99 public ViewEventHandler,
100 protected ::osl::DebugBase<SlideImpl>
102 public:
103 SlideImpl( const uno::Reference<drawing::XDrawPage>& xDrawPage,
104 const uno::Reference<animations::XAnimationNode>& xRootNode,
105 EventQueue& rEventQueue,
106 EventMultiplexer& rEventMultiplexer,
107 ScreenUpdater& rScreenUpdater,
108 ActivitiesQueue& rActivitiesQueue,
109 UserEventQueue& rUserEventQueue,
110 CursorManager& rCursorManager,
111 const UnoViewContainer& rViewContainer,
112 const uno::Reference<uno::XComponentContext>& xContext,
113 const ShapeEventListenerMap& rShapeListenerMap,
114 const ShapeCursorMap& rShapeCursorMap,
115 RGBColor const& rUserPaintColor,
116 double dUserPaintStrokeWidth,
117 bool bUserPaintEnabled,
118 bool bIntrinsicAnimationsAllowed,
119 bool bDisableAnimationZOrder );
121 ~SlideImpl();
124 // Disposable interface
125 // -------------------------------------------------------------------
127 virtual void dispose();
130 // Slide interface
131 // -------------------------------------------------------------------
133 virtual bool prefetch();
134 virtual bool show( bool );
135 virtual void hide();
137 virtual basegfx::B2ISize getSlideSize() const;
138 virtual uno::Reference<drawing::XDrawPage > getXDrawPage() const;
139 virtual uno::Reference<animations::XAnimationNode> getXAnimationNode() const;
141 // TODO(F2): Rework SlideBitmap to no longer be based on XBitmap,
142 // but on canvas-independent basegfx bitmaps
143 virtual SlideBitmapSharedPtr getCurrentSlideBitmap( const UnoViewSharedPtr& rView ) const;
146 private:
147 // ViewEventHandler
148 virtual void viewAdded( const UnoViewSharedPtr& rView );
149 virtual void viewRemoved( const UnoViewSharedPtr& rView );
150 virtual void viewChanged( const UnoViewSharedPtr& rView );
151 virtual void viewsChanged();
153 // CursorManager
154 virtual bool requestCursor( sal_Int16 nCursorShape );
155 virtual void resetCursor();
157 /** Query whether the slide has animations at all
159 If the slide doesn't have animations, show() displays
160 only static content. If an event is registered with
161 registerSlideEndEvent(), this event will be
162 immediately activated at the end of the show() method.
164 @return true, if this slide has animations, false
165 otherwise
167 bool isAnimated();
169 /** Query whether this slide is currently showing.
171 @return true, if this slide is currently showing.
173 bool isShowing() const;
175 void enablePaintOverlay();
176 void disablePaintOverlay();
178 /// Set all Shapes to their initial attributes for slideshow
179 bool applyInitialShapeAttributes( const ::com::sun::star::uno::Reference<
180 ::com::sun::star::animations::XAnimationNode >& xRootAnimationNode );
182 /// Renders current slide content to bitmap
183 SlideBitmapSharedPtr createCurrentSlideBitmap(
184 const UnoViewSharedPtr& rView,
185 ::basegfx::B2ISize const & rSlideSize ) const;
187 /// Prefetch all shapes (not the animations)
188 bool loadShapes();
190 /// Retrieve slide size from XDrawPage
191 basegfx::B2ISize getSlideSizeImpl() const;
193 /// Prefetch show, but don't call applyInitialShapeAttributes()
194 bool implPrefetchShow();
196 /// Query the rectangle covered by the slide
197 ::basegfx::B2DRectangle getSlideRect() const;
199 /// Start GIF and other intrinsic shape animations
200 void endIntrinsicAnimations();
202 /// End GIF and other intrinsic shape animations
203 void startIntrinsicAnimations();
206 // Types
207 // =====
209 enum SlideAnimationState
211 CONSTRUCTING_STATE=0,
212 INITIAL_STATE=1,
213 SHOWING_STATE=2,
214 FINAL_STATE=3,
215 SlideAnimationState_NUM_ENTRIES=4
218 typedef std::vector< SlideBitmapSharedPtr > VectorOfSlideBitmaps;
219 /** Vector of slide bitmaps.
221 Since the bitmap content is sensitive to animation
222 effects, we have an inner vector containing a distinct
223 bitmap for each of the SlideAnimationStates.
225 typedef ::std::vector< std::pair< UnoViewSharedPtr,
226 VectorOfSlideBitmaps > > VectorOfVectorOfSlideBitmaps;
229 // Member variables
230 // ================
232 /// The page model object
233 uno::Reference< drawing::XDrawPage > mxDrawPage;
234 uno::Reference< animations::XAnimationNode > mxRootNode;
236 LayerManagerSharedPtr mpLayerManager;
237 boost::shared_ptr<ShapeManagerImpl> mpShapeManager;
238 boost::shared_ptr<SubsettableShapeManager> mpSubsettableShapeManager;
240 /// Contains common objects needed throughout the slideshow
241 SlideShowContext maContext;
243 /// parent cursor manager
244 CursorManager& mrCursorManager;
246 /// Handles the animation and event generation for us
247 SlideAnimations maAnimations;
249 RGBColor maUserPaintColor;
250 double mdUserPaintStrokeWidth;
251 UserPaintOverlaySharedPtr mpPaintOverlay;
253 /// Bitmaps with slide content at various states
254 mutable VectorOfVectorOfSlideBitmaps maSlideBitmaps;
256 SlideAnimationState meAnimationState;
258 const basegfx::B2ISize maSlideSize;
260 sal_Int16 mnCurrentCursor;
262 /// True, when intrinsic shape animations are allowed
263 bool mbIntrinsicAnimationsAllowed;
265 /// True, when user paint overlay is enabled
266 bool mbUserPaintOverlayEnabled;
268 /// True, if initial load of all page shapes succeeded
269 bool mbShapesLoaded;
271 /// True, if initial load of all animation info succeeded
272 bool mbShowLoaded;
274 /** True, if this slide is not static.
276 If this slide has animated content, this variable will
277 be true, and false otherwise.
279 bool mbHaveAnimations;
281 /** True, if this slide has a main animation sequence.
283 If this slide has animation content, which in turn has
284 a main animation sequence (which must be fully run
285 before EventMultiplexer::notifySlideAnimationsEnd() is
286 called), this member is true.
288 bool mbMainSequenceFound;
290 /// When true, show() was called. Slide hidden oherwise.
291 bool mbActive;
295 //////////////////////////////////////////////////////////////////////////////////
298 class SlideRenderer
300 public:
301 explicit SlideRenderer( SlideImpl& rSlide ) :
302 mrSlide( rSlide )
306 void operator()( const UnoViewSharedPtr& rView )
308 // fully clear view content to background color
309 rView->clearAll();
311 SlideBitmapSharedPtr pBitmap( mrSlide.getCurrentSlideBitmap( rView ) );
312 ::cppcanvas::CanvasSharedPtr pCanvas( rView->getCanvas() );
314 const ::basegfx::B2DHomMatrix aViewTransform( rView->getTransformation() );
315 const ::basegfx::B2DPoint aOutPosPixel( aViewTransform * ::basegfx::B2DPoint() );
317 // setup a canvas with device coordinate space, the slide
318 // bitmap already has the correct dimension.
319 ::cppcanvas::CanvasSharedPtr pDevicePixelCanvas( pCanvas->clone() );
320 pDevicePixelCanvas->setTransformation( ::basegfx::B2DHomMatrix() );
322 // render at given output position
323 pBitmap->move( aOutPosPixel );
325 // clear clip (might have been changed, e.g. from comb
326 // transition)
327 pBitmap->clip( ::basegfx::B2DPolyPolygon() );
328 pBitmap->draw( pDevicePixelCanvas );
331 private:
332 SlideImpl& mrSlide;
336 //////////////////////////////////////////////////////////////////////////////////
339 SlideImpl::SlideImpl( const uno::Reference< drawing::XDrawPage >& xDrawPage,
340 const uno::Reference< animations::XAnimationNode >& xRootNode,
341 EventQueue& rEventQueue,
342 EventMultiplexer& rEventMultiplexer,
343 ScreenUpdater& rScreenUpdater,
344 ActivitiesQueue& rActivitiesQueue,
345 UserEventQueue& rUserEventQueue,
346 CursorManager& rCursorManager,
347 const UnoViewContainer& rViewContainer,
348 const uno::Reference< uno::XComponentContext >& xComponentContext,
349 const ShapeEventListenerMap& rShapeListenerMap,
350 const ShapeCursorMap& rShapeCursorMap,
351 RGBColor const& aUserPaintColor,
352 double dUserPaintStrokeWidth,
353 bool bUserPaintEnabled,
354 bool bIntrinsicAnimationsAllowed,
355 bool bDisableAnimationZOrder ) :
356 mxDrawPage( xDrawPage ),
357 mxRootNode( xRootNode ),
358 mpLayerManager( new LayerManager(
359 rViewContainer,
360 getSlideRect(),
361 bDisableAnimationZOrder) ),
362 mpShapeManager( new ShapeManagerImpl(
363 rEventMultiplexer,
364 mpLayerManager,
365 rCursorManager,
366 rShapeListenerMap,
367 rShapeCursorMap)),
368 mpSubsettableShapeManager( mpShapeManager ),
369 maContext( mpSubsettableShapeManager,
370 rEventQueue,
371 rEventMultiplexer,
372 rScreenUpdater,
373 rActivitiesQueue,
374 rUserEventQueue,
375 *this,
376 rViewContainer,
377 xComponentContext ),
378 mrCursorManager( rCursorManager ),
379 maAnimations( maContext,
380 getSlideSizeImpl() ),
381 maUserPaintColor(aUserPaintColor),
382 mdUserPaintStrokeWidth(dUserPaintStrokeWidth),
383 mpPaintOverlay(),
384 maSlideBitmaps(),
385 meAnimationState( CONSTRUCTING_STATE ),
386 maSlideSize(getSlideSizeImpl()),
387 mnCurrentCursor( awt::SystemPointer::ARROW ),
388 mbIntrinsicAnimationsAllowed( bIntrinsicAnimationsAllowed ),
389 mbUserPaintOverlayEnabled(bUserPaintEnabled),
390 mbShapesLoaded( false ),
391 mbShowLoaded( false ),
392 mbHaveAnimations( false ),
393 mbMainSequenceFound( false ),
394 mbActive( false )
396 // clone already existing views for slide bitmaps
397 std::for_each( rViewContainer.begin(),
398 rViewContainer.end(),
399 boost::bind( &SlideImpl::viewAdded,
400 this,
401 _1 ));
403 // register screen update (LayerManager needs to signal pending
404 // updates)
405 maContext.mrScreenUpdater.addViewUpdate(mpShapeManager);
408 SlideImpl::~SlideImpl()
410 if( mpShapeManager )
412 maContext.mrScreenUpdater.removeViewUpdate(mpShapeManager);
413 mpShapeManager->dispose();
415 // TODO(Q3): Make sure LayerManager (and thus Shapes) dies
416 // first, because SlideShowContext has SubsettableShapeManager
417 // as reference member.
418 mpLayerManager.reset();
422 void SlideImpl::dispose()
424 maSlideBitmaps.clear();
425 mpPaintOverlay.reset();
426 maAnimations.dispose();
427 maContext.dispose();
429 if( mpShapeManager )
431 maContext.mrScreenUpdater.removeViewUpdate(mpShapeManager);
432 mpShapeManager->dispose();
435 // TODO(Q3): Make sure LayerManager (and thus Shapes) dies first,
436 // because SlideShowContext has SubsettableShapeManager as
437 // reference member.
438 mpLayerManager.reset();
439 mpSubsettableShapeManager.reset();
440 mpShapeManager.reset();
441 mxRootNode.clear();
442 mxDrawPage.clear();
445 bool SlideImpl::prefetch()
447 if( !mxRootNode.is() )
448 return false;
450 return applyInitialShapeAttributes(mxRootNode);
453 bool SlideImpl::show( bool bSlideBackgoundPainted )
455 // ---------------------------------------------------------------
457 if( mbActive )
458 return true; // already active
460 if( !mpShapeManager || !mpLayerManager )
461 return false; // disposed
463 // ---------------------------------------------------------------
465 // set initial shape attributes (e.g. hide shapes that have
466 // 'appear' effect set)
467 if( !applyInitialShapeAttributes(mxRootNode) )
468 return false;
470 // ---------------------------------------------------------------
472 // activate and take over view - clears view, if necessary
473 mbActive = true;
474 requestCursor( mnCurrentCursor );
476 // enable shape management & event broadcasting for shapes of this
477 // slide. Also enables LayerManager to record updates. Currently,
478 // never let LayerManager render initial slide content, use
479 // buffered slide bitmaps instead.
480 mpShapeManager->activate( true );
482 // ---------------------------------------------------------------
484 // render slide to screen, if requested
485 if( !bSlideBackgoundPainted )
487 std::for_each(maContext.mrViewContainer.begin(),
488 maContext.mrViewContainer.end(),
489 boost::mem_fn(&View::clearAll));
491 std::for_each( maContext.mrViewContainer.begin(),
492 maContext.mrViewContainer.end(),
493 SlideRenderer(*this) );
494 maContext.mrScreenUpdater.notifyUpdate();
497 // ---------------------------------------------------------------
499 // fire up animations
500 const bool bIsAnimated( isAnimated() );
501 if( bIsAnimated )
502 maAnimations.start(); // feeds initial events into queue
504 // NOTE: this looks slightly weird, but is indeed correct:
505 // as isAnimated() might return false, _although_ there is
506 // a main sequence (because the animation nodes don't
507 // contain any executable effects), we gotta check both
508 // conditions here.
509 if( !bIsAnimated || !mbMainSequenceFound )
511 // manually trigger a slide animation end event (we don't have
512 // animations at all, or we don't have a main animation
513 // sequence, but if we had, it'd end now). Note that having
514 // animations alone does not matter here, as only main
515 // sequence animations prevents showing the next slide on
516 // nextEvent().
517 maContext.mrEventMultiplexer.notifySlideAnimationsEnd();
520 // enable shape-intrinsic animations (drawing layer animations or
521 // GIF animations)
522 if( mbIntrinsicAnimationsAllowed )
523 startIntrinsicAnimations();
525 // ---------------------------------------------------------------
527 // enable paint overlay, if maUserPaintColor is valid
528 enablePaintOverlay();
530 // ---------------------------------------------------------------
532 // from now on, animations might be showing
533 meAnimationState = SHOWING_STATE;
535 return true;
538 void SlideImpl::hide()
540 if( !mbActive || !mpShapeManager )
541 return; // already hidden/disposed
543 // ---------------------------------------------------------------
545 // from now on, all animations are stopped
546 meAnimationState = FINAL_STATE;
548 // ---------------------------------------------------------------
550 // disable user paint overlay under all circumstances,
551 // this slide now ceases to be active.
552 disablePaintOverlay();
554 // ---------------------------------------------------------------
556 // switch off all shape-intrinsic animations.
557 endIntrinsicAnimations();
559 // force-end all SMIL animations, too
560 maAnimations.end();
562 // ---------------------------------------------------------------
564 // disable shape management & event broadcasting for shapes of this
565 // slide. Also disables LayerManager.
566 mpShapeManager->deactivate();
568 // vanish from view
569 resetCursor();
570 mbActive = false;
572 // ---------------------------------------------------------------
575 basegfx::B2ISize SlideImpl::getSlideSize() const
577 return maSlideSize;
580 uno::Reference<drawing::XDrawPage > SlideImpl::getXDrawPage() const
582 return mxDrawPage;
585 uno::Reference<animations::XAnimationNode> SlideImpl::getXAnimationNode() const
587 return mxRootNode;
591 SlideBitmapSharedPtr SlideImpl::getCurrentSlideBitmap( const UnoViewSharedPtr& rView ) const
593 // search corresponding entry in maSlideBitmaps (which
594 // contains the views as the key)
595 VectorOfVectorOfSlideBitmaps::iterator aIter;
596 const VectorOfVectorOfSlideBitmaps::iterator aEnd( maSlideBitmaps.end() );
597 if( (aIter=std::find_if( maSlideBitmaps.begin(),
598 aEnd,
599 boost::bind(
600 std::equal_to<UnoViewSharedPtr>(),
601 rView,
602 // select view:
603 boost::bind(
604 std::select1st<VectorOfVectorOfSlideBitmaps::value_type>(),
605 _1 )))) == aEnd )
607 // corresponding view not found - maybe view was not
608 // added to Slide?
609 ENSURE_OR_THROW( false,
610 "SlideImpl::getInitialSlideBitmap(): view does not "
611 "match any of the added ones" );
614 // ensure that the show is loaded
615 if( !mbShowLoaded )
617 // only prefetch and init shapes when not done already
618 // (otherwise, at least applyInitialShapeAttributes() will be
619 // called twice for initial slide rendering). Furthermore,
620 // applyInitialShapeAttributes() _always_ performs
621 // initializations, which would be highly unwanted during a
622 // running show. OTOH, a slide whose mbShowLoaded is false is
623 // guaranteed not be running a show.
625 // set initial shape attributes (e.g. hide 'appear' effect
626 // shapes)
627 if( !const_cast<SlideImpl*>(this)->applyInitialShapeAttributes( mxRootNode ) )
628 ENSURE_OR_THROW(false,
629 "SlideImpl::getCurrentSlideBitmap(): Cannot "
630 "apply initial attributes");
633 SlideBitmapSharedPtr& rBitmap( aIter->second.at( meAnimationState ));
634 const ::basegfx::B2ISize& rSlideSize(
635 getSlideSizePixel( getSlideSize(),
636 rView ));
638 // is the bitmap valid (actually existent, and of correct
639 // size)?
640 if( !rBitmap || rBitmap->getSize() != rSlideSize )
642 // no bitmap there yet, or wrong size - create one
643 rBitmap = createCurrentSlideBitmap(rView, rSlideSize);
646 return rBitmap;
650 // private methods
651 //--------------------------------------------------------------------------------------------------------------
654 void SlideImpl::viewAdded( const UnoViewSharedPtr& rView )
656 maSlideBitmaps.push_back(
657 std::make_pair( rView,
658 VectorOfSlideBitmaps(SlideAnimationState_NUM_ENTRIES) ));
660 if( mpLayerManager )
661 mpLayerManager->viewAdded( rView );
664 void SlideImpl::viewRemoved( const UnoViewSharedPtr& rView )
666 if( mpLayerManager )
667 mpLayerManager->viewRemoved( rView );
669 const VectorOfVectorOfSlideBitmaps::iterator aEnd( maSlideBitmaps.end() );
670 maSlideBitmaps.erase(
671 std::remove_if( maSlideBitmaps.begin(),
672 aEnd,
673 boost::bind(
674 std::equal_to<UnoViewSharedPtr>(),
675 rView,
676 // select view:
677 boost::bind(
678 std::select1st<VectorOfVectorOfSlideBitmaps::value_type>(),
679 _1 ))),
680 aEnd );
683 void SlideImpl::viewChanged( const UnoViewSharedPtr& rView )
685 // nothing to do for the Slide - getCurrentSlideBitmap() lazily
686 // handles bitmap resizes
687 if( mbActive && mpLayerManager )
688 mpLayerManager->viewChanged(rView);
691 void SlideImpl::viewsChanged()
693 // nothing to do for the Slide - getCurrentSlideBitmap() lazily
694 // handles bitmap resizes
695 if( mbActive && mpLayerManager )
696 mpLayerManager->viewsChanged();
699 bool SlideImpl::requestCursor( sal_Int16 nCursorShape )
701 mnCurrentCursor = nCursorShape;
702 return mrCursorManager.requestCursor(mnCurrentCursor);
705 void SlideImpl::resetCursor()
707 mnCurrentCursor = awt::SystemPointer::ARROW;
708 mrCursorManager.resetCursor();
711 bool SlideImpl::isShowing() const
713 return meAnimationState == SHOWING_STATE;
716 bool SlideImpl::isAnimated()
718 // prefetch, but don't apply initial shape attributes
719 if( !implPrefetchShow() )
720 return false;
722 return mbHaveAnimations && maAnimations.isAnimated();
725 SlideBitmapSharedPtr SlideImpl::createCurrentSlideBitmap( const UnoViewSharedPtr& rView,
726 const ::basegfx::B2ISize& rBmpSize ) const
728 ENSURE_OR_THROW( rView && rView->getCanvas(),
729 "SlideImpl::createCurrentSlideBitmap(): Invalid view" );
730 ENSURE_OR_THROW( mpLayerManager,
731 "SlideImpl::createCurrentSlideBitmap(): Invalid layer manager" );
732 ENSURE_OR_THROW( mbShowLoaded,
733 "SlideImpl::createCurrentSlideBitmap(): No show loaded" );
735 ::cppcanvas::CanvasSharedPtr pCanvas( rView->getCanvas() );
737 // create a bitmap of appropriate size
738 ::cppcanvas::BitmapSharedPtr pBitmap(
739 ::cppcanvas::BaseGfxFactory::getInstance().createBitmap(
740 pCanvas,
741 rBmpSize ) );
743 ENSURE_OR_THROW( pBitmap,
744 "SlideImpl::createCurrentSlideBitmap(): Cannot create page bitmap" );
746 ::cppcanvas::BitmapCanvasSharedPtr pBitmapCanvas( pBitmap->getBitmapCanvas() );
748 ENSURE_OR_THROW( pBitmapCanvas,
749 "SlideImpl::createCurrentSlideBitmap(): Cannot create page bitmap canvas" );
751 // apply linear part of destination canvas transformation (linear means in this context:
752 // transformation without any translational components)
753 ::basegfx::B2DHomMatrix aLinearTransform( rView->getTransformation() );
754 aLinearTransform.set( 0, 2, 0.0 );
755 aLinearTransform.set( 1, 2, 0.0 );
756 pBitmapCanvas->setTransformation( aLinearTransform );
758 // output all shapes to bitmap
759 initSlideBackground( pBitmapCanvas, rBmpSize );
760 mpLayerManager->renderTo( pBitmapCanvas );
762 return SlideBitmapSharedPtr( new SlideBitmap( pBitmap ) );
765 namespace
767 class MainSequenceSearcher
769 public:
770 MainSequenceSearcher()
772 maSearchKey.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "node-type" ) );
773 maSearchKey.Value <<= presentation::EffectNodeType::MAIN_SEQUENCE;
776 void operator()( const uno::Reference< animations::XAnimationNode >& xChildNode )
778 uno::Sequence< beans::NamedValue > aUserData( xChildNode->getUserData() );
780 if( findNamedValue( aUserData, maSearchKey ) )
782 maMainSequence = xChildNode;
786 uno::Reference< animations::XAnimationNode > getMainSequence() const
788 return maMainSequence;
791 private:
792 beans::NamedValue maSearchKey;
793 uno::Reference< animations::XAnimationNode > maMainSequence;
797 bool SlideImpl::implPrefetchShow()
799 if( mbShowLoaded )
800 return true;
802 ENSURE_OR_RETURN( mxDrawPage.is(),
803 "SlideImpl::implPrefetchShow(): Invalid draw page" );
804 ENSURE_OR_RETURN( mpLayerManager,
805 "SlideImpl::implPrefetchShow(): Invalid layer manager" );
807 // fetch desired page content
808 // ==========================
810 if( !loadShapes() )
811 return false;
813 // New animations framework: import the shape effect info
814 // ======================================================
818 if( mxRootNode.is() )
820 if( !maAnimations.importAnimations( mxRootNode ) )
822 OSL_ENSURE( false,
823 "SlideImpl::implPrefetchShow(): have animation nodes, "
824 "but import animations failed." );
826 // could not import animation framework,
827 // _although_ some animation nodes are there -
828 // this is an error (not finding animations at
829 // all is okay - might be a static slide)
830 return false;
833 // now check whether we've got a main sequence (if
834 // not, we must manually call
835 // EventMultiplexer::notifySlideAnimationsEnd()
836 // above, as e.g. interactive sequences alone
837 // don't block nextEvent() from issuing the next
838 // slide)
839 MainSequenceSearcher aSearcher;
840 if( ::anim::for_each_childNode( mxRootNode, aSearcher ) )
841 mbMainSequenceFound = aSearcher.getMainSequence().is();
843 // import successfully done
844 mbHaveAnimations = true;
847 catch( uno::RuntimeException& )
849 throw;
851 catch( uno::Exception& )
853 OSL_ENSURE(
854 false,
855 rtl::OUStringToOString(
856 comphelper::anyToString(cppu::getCaughtException()),
857 RTL_TEXTENCODING_UTF8 ) );
858 // TODO(E2): Error handling. For now, bail out
861 mbShowLoaded = true;
863 return true;
866 void SlideImpl::enablePaintOverlay()
868 if( mbUserPaintOverlayEnabled )
869 mpPaintOverlay = UserPaintOverlay::create( maUserPaintColor,
870 mdUserPaintStrokeWidth,
871 maContext );
874 void SlideImpl::disablePaintOverlay()
876 mpPaintOverlay.reset();
879 ::basegfx::B2DRectangle SlideImpl::getSlideRect() const
881 const basegfx::B2ISize slideSize( getSlideSizeImpl() );
882 return ::basegfx::B2DRectangle(0.0,0.0,
883 slideSize.getX(),
884 slideSize.getY());
887 void SlideImpl::endIntrinsicAnimations()
889 mpSubsettableShapeManager->notifyIntrinsicAnimationsDisabled();
892 void SlideImpl::startIntrinsicAnimations()
894 mpSubsettableShapeManager->notifyIntrinsicAnimationsEnabled();
897 bool SlideImpl::applyInitialShapeAttributes(
898 const uno::Reference< animations::XAnimationNode >& xRootAnimationNode )
900 if( !implPrefetchShow() )
901 return false;
903 if( !xRootAnimationNode.is() )
905 meAnimationState = INITIAL_STATE;
907 return true; // no animations - no attributes to apply -
908 // succeeded
911 uno::Reference< animations::XTargetPropertiesCreator > xPropsCreator;
915 ENSURE_OR_RETURN( maContext.mxComponentContext.is(),
916 "SlideImpl::applyInitialShapeAttributes(): Invalid component context" );
918 uno::Reference<lang::XMultiComponentFactory> xFac(
919 maContext.mxComponentContext->getServiceManager() );
921 xPropsCreator.set(
922 xFac->createInstanceWithContext(
923 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
924 "com.sun.star.animations.TargetPropertiesCreator") ),
925 maContext.mxComponentContext ),
926 uno::UNO_QUERY_THROW );
928 catch( uno::RuntimeException& )
930 throw;
932 catch( uno::Exception& )
934 OSL_ENSURE(
935 false,
936 rtl::OUStringToOString(
937 comphelper::anyToString(cppu::getCaughtException()),
938 RTL_TEXTENCODING_UTF8 ) );
940 // could not determine initial shape attributes - this
941 // is an error, as some effects might then be plainly
942 // invisible
943 ENSURE_OR_RETURN( false,
944 "SlideImpl::applyInitialShapeAttributes(): "
945 "couldn't create TargetPropertiesCreator." );
948 uno::Sequence< animations::TargetProperties > aProps(
949 xPropsCreator->createInitialTargetProperties( xRootAnimationNode ) );
951 // apply extracted values to our shapes
952 const ::std::size_t nSize( aProps.getLength() );
953 for( ::std::size_t i=0; i<nSize; ++i )
955 sal_Int16 nParaIndex( -1 );
956 uno::Reference< drawing::XShape > xShape( aProps[i].Target,
957 uno::UNO_QUERY );
959 if( !xShape.is() )
961 // not a shape target. Maybe a ParagraphTarget?
962 presentation::ParagraphTarget aParaTarget;
964 if( (aProps[i].Target >>= aParaTarget) )
966 // yep, ParagraphTarget found - extract shape
967 // and index
968 xShape = aParaTarget.Shape;
969 nParaIndex = aParaTarget.Paragraph;
973 if( xShape.is() )
975 ShapeSharedPtr pShape( mpLayerManager->lookupShape( xShape ) );
977 if( !pShape )
979 OSL_ENSURE( false,
980 "SlideImpl::applyInitialShapeAttributes(): no shape found for given target" );
981 continue;
984 AttributableShapeSharedPtr pAttrShape(
985 ::boost::dynamic_pointer_cast< AttributableShape >( pShape ) );
987 if( !pAttrShape )
989 OSL_ENSURE( false,
990 "SlideImpl::applyInitialShapeAttributes(): shape found does not "
991 "implement AttributableShape interface" );
992 continue;
995 if( nParaIndex != -1 )
997 // our target is a paragraph subset, thus look
998 // this up first.
999 const DocTreeNodeSupplier& rNodeSupplier( pAttrShape->getTreeNodeSupplier() );
1001 pAttrShape = pAttrShape->getSubset(
1002 rNodeSupplier.getTreeNode(
1003 nParaIndex,
1004 DocTreeNode::NODETYPE_LOGICAL_PARAGRAPH ) );
1006 if( !pAttrShape )
1008 OSL_ENSURE( false,
1009 "SlideImpl::applyInitialShapeAttributes(): shape found does not "
1010 "provide a subset for requested paragraph index" );
1011 continue;
1015 const uno::Sequence< beans::NamedValue >& rShapeProps( aProps[i].Properties );
1016 const ::std::size_t nShapePropSize( rShapeProps.getLength() );
1017 for( ::std::size_t j=0; j<nShapePropSize; ++j )
1019 bool bVisible=false;
1020 if( rShapeProps[j].Name.equalsIgnoreAsciiCaseAscii("visibility") &&
1021 extractValue( bVisible,
1022 rShapeProps[j].Value,
1023 pShape,
1024 getSlideSize() ))
1026 pAttrShape->setVisibility( bVisible );
1028 else
1030 OSL_ENSURE( false,
1031 "SlideImpl::applyInitialShapeAttributes(): Unexpected "
1032 "(and unimplemented) property encountered" );
1038 meAnimationState = INITIAL_STATE;
1040 return true;
1043 bool SlideImpl::loadShapes()
1045 if( mbShapesLoaded )
1046 return true;
1048 ENSURE_OR_RETURN( mxDrawPage.is(),
1049 "SlideImpl::loadShapes(): Invalid draw page" );
1050 ENSURE_OR_RETURN( mpLayerManager,
1051 "SlideImpl::loadShapes(): Invalid layer manager" );
1053 // fetch desired page content
1054 // ==========================
1056 // also take master page content
1057 uno::Reference< drawing::XDrawPage > xMasterPage;
1058 uno::Reference< drawing::XShapes > xMasterPageShapes;
1059 sal_Int32 nCurrCount(0);
1061 uno::Reference< drawing::XMasterPageTarget > xMasterPageTarget( mxDrawPage,
1062 uno::UNO_QUERY );
1063 if( xMasterPageTarget.is() )
1065 xMasterPage = xMasterPageTarget->getMasterPage();
1066 xMasterPageShapes.set( xMasterPage,
1067 uno::UNO_QUERY );
1069 if( xMasterPage.is() && xMasterPageShapes.is() )
1071 // TODO(P2): maybe cache master pages here (or treat the
1072 // masterpage as a single metafile. At least currently,
1073 // masterpages do not contain animation effects)
1076 // load the masterpage shapes
1077 // -------------------------------------------------------------------------
1078 ShapeImporter aMPShapesFunctor( xMasterPage,
1079 mxDrawPage,
1080 maContext,
1081 0, /* shape num starts at 0 */
1082 true );
1084 mpLayerManager->addShape(
1085 aMPShapesFunctor.importBackgroundShape() );
1087 while( !aMPShapesFunctor.isImportDone() )
1089 ShapeSharedPtr const& rShape(
1090 aMPShapesFunctor.importShape() );
1091 if( rShape )
1092 mpLayerManager->addShape( rShape );
1095 nCurrCount = xMasterPageShapes->getCount() + 1;
1097 catch( uno::RuntimeException& )
1099 throw;
1101 catch( ShapeLoadFailedException& )
1103 // TODO(E2): Error handling. For now, bail out
1104 OSL_ENSURE( false,
1105 "SlideImpl::loadShapes(): caught ShapeLoadFailedException" );
1106 return false;
1109 catch( uno::Exception& )
1111 OSL_ENSURE( false,
1112 rtl::OUStringToOString(
1113 comphelper::anyToString( cppu::getCaughtException() ),
1114 RTL_TEXTENCODING_UTF8 ).getStr() );
1116 return false;
1123 // load the normal page shapes
1124 // -------------------------------------------------------------------------
1126 ShapeImporter aShapesFunctor( mxDrawPage,
1127 mxDrawPage,
1128 maContext,
1129 nCurrCount,
1130 false );
1132 while( !aShapesFunctor.isImportDone() )
1134 ShapeSharedPtr const& rShape(
1135 aShapesFunctor.importShape() );
1136 if( rShape )
1137 mpLayerManager->addShape( rShape );
1140 catch( uno::RuntimeException& )
1142 throw;
1144 catch( ShapeLoadFailedException& )
1146 // TODO(E2): Error handling. For now, bail out
1147 OSL_ENSURE( false,
1148 "SlideImpl::loadShapes(): caught ShapeLoadFailedException" );
1149 return false;
1151 catch( uno::Exception& )
1153 OSL_ENSURE( false,
1154 rtl::OUStringToOString(
1155 comphelper::anyToString( cppu::getCaughtException() ),
1156 RTL_TEXTENCODING_UTF8 ).getStr() );
1158 return false;
1161 mbShapesLoaded = true;
1163 return true;
1166 basegfx::B2ISize SlideImpl::getSlideSizeImpl() const
1168 uno::Reference< beans::XPropertySet > xPropSet(
1169 mxDrawPage, uno::UNO_QUERY_THROW );
1171 sal_Int32 nDocWidth = 0;
1172 sal_Int32 nDocHeight = 0;
1173 xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Width") ) ) >>= nDocWidth;
1174 xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Height") ) ) >>= nDocHeight;
1176 return basegfx::B2ISize( nDocWidth, nDocHeight );
1179 } // namespace
1182 SlideSharedPtr createSlide( const uno::Reference< drawing::XDrawPage >& xDrawPage,
1183 const uno::Reference< animations::XAnimationNode >& xRootNode,
1184 EventQueue& rEventQueue,
1185 EventMultiplexer& rEventMultiplexer,
1186 ScreenUpdater& rScreenUpdater,
1187 ActivitiesQueue& rActivitiesQueue,
1188 UserEventQueue& rUserEventQueue,
1189 CursorManager& rCursorManager,
1190 const UnoViewContainer& rViewContainer,
1191 const uno::Reference< uno::XComponentContext >& xComponentContext,
1192 const ShapeEventListenerMap& rShapeListenerMap,
1193 const ShapeCursorMap& rShapeCursorMap,
1194 RGBColor const& rUserPaintColor,
1195 double dUserPaintStrokeWidth,
1196 bool bUserPaintEnabled,
1197 bool bIntrinsicAnimationsAllowed,
1198 bool bDisableAnimationZOrder )
1200 boost::shared_ptr<SlideImpl> pRet( new SlideImpl( xDrawPage, xRootNode, rEventQueue,
1201 rEventMultiplexer, rScreenUpdater,
1202 rActivitiesQueue, rUserEventQueue,
1203 rCursorManager, rViewContainer,
1204 xComponentContext, rShapeListenerMap,
1205 rShapeCursorMap, rUserPaintColor,
1206 dUserPaintStrokeWidth, bUserPaintEnabled,
1207 bIntrinsicAnimationsAllowed,
1208 bDisableAnimationZOrder ));
1210 rEventMultiplexer.addViewHandler( pRet );
1212 return pRet;
1215 } // namespace internal
1216 } // namespace slideshow