1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
21 #include <osl/diagnose.hxx>
22 #include <tools/diagnose_ex.h>
23 #include <canvas/canvastools.hxx>
24 #include <cppcanvas/basegfxfactory.hxx>
26 #include <basegfx/matrix/b2dhommatrix.hxx>
27 #include <basegfx/point/b2dpoint.hxx>
28 #include <basegfx/polygon/b2dpolygon.hxx>
29 #include <basegfx/polygon/b2dpolygontools.hxx>
30 #include <basegfx/numeric/ftools.hxx>
32 #include <com/sun/star/awt/SystemPointer.hpp>
33 #include <com/sun/star/container/XIndexAccess.hpp>
34 #include <com/sun/star/drawing/XMasterPageTarget.hpp>
35 #include <com/sun/star/beans/XPropertySet.hpp>
36 #include <com/sun/star/container/XEnumerationAccess.hpp>
37 #include <com/sun/star/awt/Rectangle.hpp>
38 #include <com/sun/star/presentation/ParagraphTarget.hpp>
39 #include <com/sun/star/presentation/EffectNodeType.hpp>
40 #include <com/sun/star/drawing/TextAnimationKind.hpp>
42 #include <cppuhelper/exc_hlp.hxx>
43 #include <comphelper/anytostring.hxx>
46 #include <slideshowcontext.hxx>
47 #include "slideanimations.hxx"
48 #include <doctreenode.hxx>
49 #include <screenupdater.hxx>
50 #include <cursormanager.hxx>
51 #include <shapeimporter.hxx>
52 #include <slideshowexceptions.hxx>
53 #include <eventqueue.hxx>
54 #include <activitiesqueue.hxx>
55 #include "layermanager.hxx"
56 #include "shapemanagerimpl.hxx"
57 #include <usereventqueue.hxx>
58 #include "userpaintoverlay.hxx"
60 #include "targetpropertiescreator.hxx"
67 using namespace ::com::sun::star
;
77 class SlideImpl
: public Slide
,
79 public ViewEventHandler
,
80 public ::osl::DebugBase
<SlideImpl
>
83 SlideImpl( const uno::Reference
<drawing::XDrawPage
>& xDrawPage
,
84 const uno::Reference
<drawing::XDrawPagesSupplier
>& xDrawPages
,
85 const uno::Reference
<animations::XAnimationNode
>& xRootNode
,
86 EventQueue
& rEventQueue
,
87 EventMultiplexer
& rEventMultiplexer
,
88 ScreenUpdater
& rScreenUpdater
,
89 ActivitiesQueue
& rActivitiesQueue
,
90 UserEventQueue
& rUserEventQueue
,
91 CursorManager
& rCursorManager
,
92 const UnoViewContainer
& rViewContainer
,
93 const uno::Reference
<uno::XComponentContext
>& xContext
,
94 const ShapeEventListenerMap
& rShapeListenerMap
,
95 const ShapeCursorMap
& rShapeCursorMap
,
96 const PolyPolygonVector
& rPolyPolygonVector
,
97 RGBColor
const& rUserPaintColor
,
98 double dUserPaintStrokeWidth
,
99 bool bUserPaintEnabled
,
100 bool bIntrinsicAnimationsAllowed
,
101 bool bDisableAnimationZOrder
);
103 virtual ~SlideImpl() override
;
109 virtual void prefetch() override
;
110 virtual void show( bool ) override
;
111 virtual void hide() override
;
113 virtual basegfx::B2ISize
getSlideSize() const override
;
114 virtual uno::Reference
<drawing::XDrawPage
> getXDrawPage() const override
;
115 virtual uno::Reference
<animations::XAnimationNode
> getXAnimationNode() const override
;
116 virtual PolyPolygonVector
getPolygons() override
;
117 virtual void drawPolygons() const override
;
118 virtual bool isPaintOverlayActive() const override
;
119 virtual void enablePaintOverlay() override
;
120 virtual void disablePaintOverlay() override
;
121 virtual void update_settings( bool bUserPaintEnabled
, RGBColor
const& aUserPaintColor
, double dUserPaintStrokeWidth
) override
;
124 // TODO(F2): Rework SlideBitmap to no longer be based on XBitmap,
125 // but on canvas-independent basegfx bitmaps
126 virtual SlideBitmapSharedPtr
getCurrentSlideBitmap( const UnoViewSharedPtr
& rView
) const override
;
131 virtual void viewAdded( const UnoViewSharedPtr
& rView
) override
;
132 virtual void viewRemoved( const UnoViewSharedPtr
& rView
) override
;
133 virtual void viewChanged( const UnoViewSharedPtr
& rView
) override
;
134 virtual void viewsChanged() override
;
137 virtual bool requestCursor( sal_Int16 nCursorShape
) override
;
138 virtual void resetCursor() override
;
140 void activatePaintOverlay();
141 void deactivatePaintOverlay();
143 /** Query whether the slide has animations at all
145 If the slide doesn't have animations, show() displays
146 only static content. If an event is registered with
147 registerSlideEndEvent(), this event will be
148 immediately activated at the end of the show() method.
150 @return true, if this slide has animations, false
155 /// Set all Shapes to their initial attributes for slideshow
156 bool applyInitialShapeAttributes( const css::uno::Reference
< css::animations::XAnimationNode
>& xRootAnimationNode
);
158 /// Set shapes to attributes corresponding to initial or final state of slide
159 void applyShapeAttributes(
160 const css::uno::Reference
< css::animations::XAnimationNode
>& xRootAnimationNode
,
161 bool bInitial
) const;
163 /// Renders current slide content to bitmap
164 SlideBitmapSharedPtr
createCurrentSlideBitmap(
165 const UnoViewSharedPtr
& rView
,
166 ::basegfx::B2ISize
const & rSlideSize
) const;
168 /// Prefetch all shapes (not the animations)
171 /// Retrieve slide size from XDrawPage
172 basegfx::B2ISize
getSlideSizeImpl() const;
174 /// Prefetch show, but don't call applyInitialShapeAttributes()
175 bool implPrefetchShow();
177 /// Add Polygons to the member maPolygons
178 void addPolygons(const PolyPolygonVector
& rPolygons
);
183 enum SlideAnimationState
185 CONSTRUCTING_STATE
=0,
189 SlideAnimationState_NUM_ENTRIES
=4
192 typedef std::vector
< SlideBitmapSharedPtr
> VectorOfSlideBitmaps
;
193 /** Vector of slide bitmaps.
195 Since the bitmap content is sensitive to animation
196 effects, we have an inner vector containing a distinct
197 bitmap for each of the SlideAnimationStates.
199 typedef ::std::vector
< std::pair
< UnoViewSharedPtr
,
200 VectorOfSlideBitmaps
> > VectorOfVectorOfSlideBitmaps
;
206 /// The page model object
207 uno::Reference
< drawing::XDrawPage
> mxDrawPage
;
208 uno::Reference
< drawing::XDrawPagesSupplier
> mxDrawPagesSupplier
;
209 uno::Reference
< animations::XAnimationNode
> mxRootNode
;
211 LayerManagerSharedPtr mpLayerManager
;
212 std::shared_ptr
<ShapeManagerImpl
> mpShapeManager
;
213 std::shared_ptr
<SubsettableShapeManager
> mpSubsettableShapeManager
;
215 /// Contains common objects needed throughout the slideshow
216 SlideShowContext maContext
;
218 /// parent cursor manager
219 CursorManager
& mrCursorManager
;
221 /// Handles the animation and event generation for us
222 SlideAnimations maAnimations
;
223 PolyPolygonVector maPolygons
;
225 RGBColor maUserPaintColor
;
226 double mdUserPaintStrokeWidth
;
227 UserPaintOverlaySharedPtr mpPaintOverlay
;
229 /// Bitmaps with slide content at various states
230 mutable VectorOfVectorOfSlideBitmaps maSlideBitmaps
;
232 SlideAnimationState meAnimationState
;
234 const basegfx::B2ISize maSlideSize
;
236 sal_Int16 mnCurrentCursor
;
238 /// True, when intrinsic shape animations are allowed
239 bool mbIntrinsicAnimationsAllowed
;
241 /// True, when user paint overlay is enabled
242 bool mbUserPaintOverlayEnabled
;
244 /// True, if initial load of all page shapes succeeded
247 /// True, if initial load of all animation info succeeded
250 /** True, if this slide is not static.
252 If this slide has animated content, this variable will
253 be true, and false otherwise.
255 bool mbHaveAnimations
;
257 /** True, if this slide has a main animation sequence.
259 If this slide has animation content, which in turn has
260 a main animation sequence (which must be fully run
261 before EventMultiplexer::notifySlideAnimationsEnd() is
262 called), this member is true.
264 bool mbMainSequenceFound
;
266 /// When true, show() was called. Slide hidden otherwise.
269 /// When true, enablePaintOverlay was called and mbUserPaintOverlay = true
270 bool mbPaintOverlayActive
;
272 /// When true, final state attributes are already applied to shapes
273 bool mbFinalStateApplied
;
277 void slideRenderer( SlideImpl
const * pSlide
, const UnoViewSharedPtr
& rView
)
279 // fully clear view content to background color
282 SlideBitmapSharedPtr
pBitmap( pSlide
->getCurrentSlideBitmap( rView
) );
283 ::cppcanvas::CanvasSharedPtr
pCanvas( rView
->getCanvas() );
285 const ::basegfx::B2DHomMatrix
aViewTransform( rView
->getTransformation() );
286 const ::basegfx::B2DPoint
aOutPosPixel( aViewTransform
* ::basegfx::B2DPoint() );
288 // setup a canvas with device coordinate space, the slide
289 // bitmap already has the correct dimension.
290 ::cppcanvas::CanvasSharedPtr
pDevicePixelCanvas( pCanvas
->clone() );
291 pDevicePixelCanvas
->setTransformation( ::basegfx::B2DHomMatrix() );
293 // render at given output position
294 pBitmap
->move( aOutPosPixel
);
296 // clear clip (might have been changed, e.g. from comb
298 pBitmap
->clip( ::basegfx::B2DPolyPolygon() );
299 pBitmap
->draw( pDevicePixelCanvas
);
303 SlideImpl::SlideImpl( const uno::Reference
< drawing::XDrawPage
>& xDrawPage
,
304 const uno::Reference
<drawing::XDrawPagesSupplier
>& xDrawPages
,
305 const uno::Reference
< animations::XAnimationNode
>& xRootNode
,
306 EventQueue
& rEventQueue
,
307 EventMultiplexer
& rEventMultiplexer
,
308 ScreenUpdater
& rScreenUpdater
,
309 ActivitiesQueue
& rActivitiesQueue
,
310 UserEventQueue
& rUserEventQueue
,
311 CursorManager
& rCursorManager
,
312 const UnoViewContainer
& rViewContainer
,
313 const uno::Reference
< uno::XComponentContext
>& xComponentContext
,
314 const ShapeEventListenerMap
& rShapeListenerMap
,
315 const ShapeCursorMap
& rShapeCursorMap
,
316 const PolyPolygonVector
& rPolyPolygonVector
,
317 RGBColor
const& aUserPaintColor
,
318 double dUserPaintStrokeWidth
,
319 bool bUserPaintEnabled
,
320 bool bIntrinsicAnimationsAllowed
,
321 bool bDisableAnimationZOrder
) :
322 mxDrawPage( xDrawPage
),
323 mxDrawPagesSupplier( xDrawPages
),
324 mxRootNode( xRootNode
),
325 mpLayerManager( new LayerManager(
327 bDisableAnimationZOrder
) ),
328 mpShapeManager( new ShapeManagerImpl(
334 mpSubsettableShapeManager( mpShapeManager
),
335 maContext( mpSubsettableShapeManager
,
344 mrCursorManager( rCursorManager
),
345 maAnimations( maContext
,
346 basegfx::B2DSize( getSlideSizeImpl() ) ),
347 maPolygons(rPolyPolygonVector
),
348 maUserPaintColor(aUserPaintColor
),
349 mdUserPaintStrokeWidth(dUserPaintStrokeWidth
),
352 meAnimationState( CONSTRUCTING_STATE
),
353 maSlideSize(getSlideSizeImpl()),
354 mnCurrentCursor( awt::SystemPointer::ARROW
),
355 mbIntrinsicAnimationsAllowed( bIntrinsicAnimationsAllowed
),
356 mbUserPaintOverlayEnabled(bUserPaintEnabled
),
357 mbShapesLoaded( false ),
358 mbShowLoaded( false ),
359 mbHaveAnimations( false ),
360 mbMainSequenceFound( false ),
362 mbPaintOverlayActive( false ),
363 mbFinalStateApplied( false )
365 // clone already existing views for slide bitmaps
366 for( const auto& rView
: rViewContainer
)
369 // register screen update (LayerManager needs to signal pending
371 maContext
.mrScreenUpdater
.addViewUpdate(mpShapeManager
);
374 void SlideImpl::update_settings( bool bUserPaintEnabled
, RGBColor
const& aUserPaintColor
, double dUserPaintStrokeWidth
)
376 maUserPaintColor
= aUserPaintColor
;
377 mdUserPaintStrokeWidth
= dUserPaintStrokeWidth
;
378 mbUserPaintOverlayEnabled
= bUserPaintEnabled
;
381 SlideImpl::~SlideImpl()
385 maContext
.mrScreenUpdater
.removeViewUpdate(mpShapeManager
);
386 mpShapeManager
->dispose();
388 // TODO(Q3): Make sure LayerManager (and thus Shapes) dies
389 // first, because SlideShowContext has SubsettableShapeManager
390 // as reference member.
391 mpLayerManager
.reset();
395 void SlideImpl::prefetch()
397 if( !mxRootNode
.is() )
400 applyInitialShapeAttributes(mxRootNode
);
403 void SlideImpl::show( bool bSlideBackgoundPainted
)
406 return; // already active
408 if( !mpShapeManager
|| !mpLayerManager
)
411 // set initial shape attributes (e.g. hide shapes that have
412 // 'appear' effect set)
413 if( !applyInitialShapeAttributes(mxRootNode
) )
416 // activate and take over view - clears view, if necessary
418 requestCursor( mnCurrentCursor
);
420 // enable shape management & event broadcasting for shapes of this
421 // slide. Also enables LayerManager to record updates. Currently,
422 // never let LayerManager render initial slide content, use
423 // buffered slide bitmaps instead.
424 mpShapeManager
->activate();
427 // render slide to screen, if requested
428 if( !bSlideBackgoundPainted
)
430 for( const auto& rContext
: maContext
.mrViewContainer
)
431 slideRenderer( this, rContext
);
433 maContext
.mrScreenUpdater
.notifyUpdate();
437 // fire up animations
438 const bool bIsAnimated( isAnimated() );
440 maAnimations
.start(); // feeds initial events into queue
442 // NOTE: this looks slightly weird, but is indeed correct:
443 // as isAnimated() might return false, _although_ there is
444 // a main sequence (because the animation nodes don't
445 // contain any executable effects), we gotta check both
447 if( !bIsAnimated
|| !mbMainSequenceFound
)
449 // manually trigger a slide animation end event (we don't have
450 // animations at all, or we don't have a main animation
451 // sequence, but if we had, it'd end now). Note that having
452 // animations alone does not matter here, as only main
453 // sequence animations prevents showing the next slide on
455 maContext
.mrEventMultiplexer
.notifySlideAnimationsEnd();
458 // enable shape-intrinsic animations (drawing layer animations or
460 if( mbIntrinsicAnimationsAllowed
)
461 mpSubsettableShapeManager
->notifyIntrinsicAnimationsEnabled();
463 // enable paint overlay, if maUserPaintColor is valid
464 activatePaintOverlay();
467 // from now on, animations might be showing
468 meAnimationState
= SHOWING_STATE
;
471 void SlideImpl::hide()
473 if( !mbActive
|| !mpShapeManager
)
474 return; // already hidden/disposed
477 // from now on, all animations are stopped
478 meAnimationState
= FINAL_STATE
;
481 // disable user paint overlay under all circumstances,
482 // this slide now ceases to be active.
483 deactivatePaintOverlay();
486 // switch off all shape-intrinsic animations.
487 mpSubsettableShapeManager
->notifyIntrinsicAnimationsDisabled();
489 // force-end all SMIL animations, too
493 // disable shape management & event broadcasting for shapes of this
494 // slide. Also disables LayerManager.
495 mpShapeManager
->deactivate();
502 basegfx::B2ISize
SlideImpl::getSlideSize() const
507 uno::Reference
<drawing::XDrawPage
> SlideImpl::getXDrawPage() const
512 uno::Reference
<animations::XAnimationNode
> SlideImpl::getXAnimationNode() const
517 PolyPolygonVector
SlideImpl::getPolygons()
519 if(mbPaintOverlayActive
)
520 maPolygons
= mpPaintOverlay
->getPolygons();
524 SlideBitmapSharedPtr
SlideImpl::getCurrentSlideBitmap( const UnoViewSharedPtr
& rView
) const
526 // search corresponding entry in maSlideBitmaps (which
527 // contains the views as the key)
528 VectorOfVectorOfSlideBitmaps::iterator aIter
;
529 const VectorOfVectorOfSlideBitmaps::iterator
aEnd( maSlideBitmaps
.end() );
530 if( (aIter
=std::find_if( maSlideBitmaps
.begin(),
533 ( const VectorOfVectorOfSlideBitmaps::value_type
& cp
)
534 { return rView
== cp
.first
; } ) ) == aEnd
)
536 // corresponding view not found - maybe view was not
538 ENSURE_OR_THROW( false,
539 "SlideImpl::getInitialSlideBitmap(): view does not "
540 "match any of the added ones" );
543 // ensure that the show is loaded
546 // only prefetch and init shapes when not done already
547 // (otherwise, at least applyInitialShapeAttributes() will be
548 // called twice for initial slide rendering). Furthermore,
549 // applyInitialShapeAttributes() _always_ performs
550 // initializations, which would be highly unwanted during a
551 // running show. OTOH, a slide whose mbShowLoaded is false is
552 // guaranteed not be running a show.
554 // set initial shape attributes (e.g. hide 'appear' effect
556 if( !const_cast<SlideImpl
*>(this)->applyInitialShapeAttributes( mxRootNode
) )
557 ENSURE_OR_THROW(false,
558 "SlideImpl::getCurrentSlideBitmap(): Cannot "
559 "apply initial attributes");
562 SlideBitmapSharedPtr
& rBitmap( aIter
->second
.at( meAnimationState
));
563 const ::basegfx::B2ISize
& rSlideSize(
564 getSlideSizePixel( ::basegfx::B2DSize( getSlideSize() ),
567 // is the bitmap valid (actually existent, and of correct
569 if( !rBitmap
|| rBitmap
->getSize() != rSlideSize
)
571 // no bitmap there yet, or wrong size - create one
572 rBitmap
= createCurrentSlideBitmap(rView
, rSlideSize
);
582 void SlideImpl::viewAdded( const UnoViewSharedPtr
& rView
)
584 maSlideBitmaps
.emplace_back( rView
,
585 VectorOfSlideBitmaps(SlideAnimationState_NUM_ENTRIES
) );
588 mpLayerManager
->viewAdded( rView
);
591 void SlideImpl::viewRemoved( const UnoViewSharedPtr
& rView
)
594 mpLayerManager
->viewRemoved( rView
);
596 const VectorOfVectorOfSlideBitmaps::iterator
aEnd( maSlideBitmaps
.end() );
597 maSlideBitmaps
.erase(
598 std::remove_if( maSlideBitmaps
.begin(),
601 ( const VectorOfVectorOfSlideBitmaps::value_type
& cp
)
602 { return rView
== cp
.first
; } ),
606 void SlideImpl::viewChanged( const UnoViewSharedPtr
& rView
)
608 // nothing to do for the Slide - getCurrentSlideBitmap() lazily
609 // handles bitmap resizes
610 if( mbActive
&& mpLayerManager
)
611 mpLayerManager
->viewChanged(rView
);
614 void SlideImpl::viewsChanged()
616 // nothing to do for the Slide - getCurrentSlideBitmap() lazily
617 // handles bitmap resizes
618 if( mbActive
&& mpLayerManager
)
619 mpLayerManager
->viewsChanged();
622 bool SlideImpl::requestCursor( sal_Int16 nCursorShape
)
624 mnCurrentCursor
= nCursorShape
;
625 return mrCursorManager
.requestCursor(mnCurrentCursor
);
628 void SlideImpl::resetCursor()
630 mnCurrentCursor
= awt::SystemPointer::ARROW
;
631 mrCursorManager
.resetCursor();
634 bool SlideImpl::isAnimated()
636 // prefetch, but don't apply initial shape attributes
637 if( !implPrefetchShow() )
640 return mbHaveAnimations
&& maAnimations
.isAnimated();
643 SlideBitmapSharedPtr
SlideImpl::createCurrentSlideBitmap( const UnoViewSharedPtr
& rView
,
644 const ::basegfx::B2ISize
& rBmpSize
) const
646 ENSURE_OR_THROW( rView
&& rView
->getCanvas(),
647 "SlideImpl::createCurrentSlideBitmap(): Invalid view" );
648 ENSURE_OR_THROW( mpLayerManager
,
649 "SlideImpl::createCurrentSlideBitmap(): Invalid layer manager" );
650 ENSURE_OR_THROW( mbShowLoaded
,
651 "SlideImpl::createCurrentSlideBitmap(): No show loaded" );
653 // tdf#96083 ensure end state settings are applied to shapes once when bitmap gets re-rendered
655 if(!mbFinalStateApplied
&& FINAL_STATE
== meAnimationState
&& mxRootNode
.is())
657 const_cast< SlideImpl
* >(this)->mbFinalStateApplied
= true;
658 applyShapeAttributes(mxRootNode
, false);
661 ::cppcanvas::CanvasSharedPtr
pCanvas( rView
->getCanvas() );
663 // create a bitmap of appropriate size
664 ::cppcanvas::BitmapSharedPtr
pBitmap(
665 ::cppcanvas::BaseGfxFactory::createBitmap(
669 ENSURE_OR_THROW( pBitmap
,
670 "SlideImpl::createCurrentSlideBitmap(): Cannot create page bitmap" );
672 ::cppcanvas::BitmapCanvasSharedPtr
pBitmapCanvas( pBitmap
->getBitmapCanvas() );
674 ENSURE_OR_THROW( pBitmapCanvas
,
675 "SlideImpl::createCurrentSlideBitmap(): Cannot create page bitmap canvas" );
677 // apply linear part of destination canvas transformation (linear means in this context:
678 // transformation without any translational components)
679 ::basegfx::B2DHomMatrix
aLinearTransform( rView
->getTransformation() );
680 aLinearTransform
.set( 0, 2, 0.0 );
681 aLinearTransform
.set( 1, 2, 0.0 );
682 pBitmapCanvas
->setTransformation( aLinearTransform
);
684 // output all shapes to bitmap
685 initSlideBackground( pBitmapCanvas
, rBmpSize
);
686 mpLayerManager
->renderTo( pBitmapCanvas
);
688 return std::make_shared
<SlideBitmap
>( pBitmap
);
693 class MainSequenceSearcher
696 MainSequenceSearcher()
698 maSearchKey
.Name
= "node-type";
699 maSearchKey
.Value
<<= presentation::EffectNodeType::MAIN_SEQUENCE
;
702 void operator()( const uno::Reference
< animations::XAnimationNode
>& xChildNode
)
704 uno::Sequence
< beans::NamedValue
> aUserData( xChildNode
->getUserData() );
706 if( findNamedValue( aUserData
, maSearchKey
) )
708 maMainSequence
= xChildNode
;
712 const uno::Reference
< animations::XAnimationNode
>& getMainSequence() const
714 return maMainSequence
;
718 beans::NamedValue maSearchKey
;
719 uno::Reference
< animations::XAnimationNode
> maMainSequence
;
723 bool SlideImpl::implPrefetchShow()
728 ENSURE_OR_RETURN_FALSE( mxDrawPage
.is(),
729 "SlideImpl::implPrefetchShow(): Invalid draw page" );
730 ENSURE_OR_RETURN_FALSE( mpLayerManager
,
731 "SlideImpl::implPrefetchShow(): Invalid layer manager" );
733 // fetch desired page content
734 // ==========================
739 // New animations framework: import the shape effect info
740 // ======================================================
744 if( mxRootNode
.is() )
746 if( !maAnimations
.importAnimations( mxRootNode
) )
748 OSL_FAIL( "SlideImpl::implPrefetchShow(): have animation nodes, "
749 "but import animations failed." );
751 // could not import animation framework,
752 // _although_ some animation nodes are there -
753 // this is an error (not finding animations at
754 // all is okay - might be a static slide)
758 // now check whether we've got a main sequence (if
759 // not, we must manually call
760 // EventMultiplexer::notifySlideAnimationsEnd()
761 // above, as e.g. interactive sequences alone
762 // don't block nextEvent() from issuing the next
764 MainSequenceSearcher aSearcher
;
765 if( for_each_childNode( mxRootNode
, aSearcher
) )
766 mbMainSequenceFound
= aSearcher
.getMainSequence().is();
768 // import successfully done
769 mbHaveAnimations
= true;
772 catch( uno::RuntimeException
& )
776 catch( uno::Exception
& )
778 SAL_WARN( "slideshow", comphelper::anyToString(cppu::getCaughtException()) );
779 // TODO(E2): Error handling. For now, bail out
787 void SlideImpl::enablePaintOverlay()
789 if( !mbUserPaintOverlayEnabled
|| !mbPaintOverlayActive
)
791 mbUserPaintOverlayEnabled
= true;
792 activatePaintOverlay();
796 void SlideImpl::disablePaintOverlay()
800 void SlideImpl::activatePaintOverlay()
802 if( mbUserPaintOverlayEnabled
|| !maPolygons
.empty() )
804 mpPaintOverlay
= UserPaintOverlay::create( maUserPaintColor
,
805 mdUserPaintStrokeWidth
,
808 mbUserPaintOverlayEnabled
);
809 mbPaintOverlayActive
= true;
813 void SlideImpl::drawPolygons() const
816 mpPaintOverlay
->drawPolygons();
819 void SlideImpl::addPolygons(const PolyPolygonVector
& rPolygons
)
821 if(!rPolygons
.empty())
823 for( PolyPolygonVector::const_iterator aIter
= rPolygons
.begin(),
824 aEnd
= rPolygons
.end();
828 maPolygons
.push_back(*aIter
);
833 bool SlideImpl::isPaintOverlayActive() const
835 return mbPaintOverlayActive
;
838 void SlideImpl::deactivatePaintOverlay()
840 if(mbPaintOverlayActive
)
841 maPolygons
= mpPaintOverlay
->getPolygons();
843 mpPaintOverlay
.reset();
844 mbPaintOverlayActive
= false;
847 void SlideImpl::applyShapeAttributes(
848 const css::uno::Reference
< css::animations::XAnimationNode
>& xRootAnimationNode
,
851 uno::Sequence
< animations::TargetProperties
> aProps(
852 TargetPropertiesCreator::createTargetProperties( xRootAnimationNode
, bInitial
) );
854 // apply extracted values to our shapes
855 const ::std::size_t nSize( aProps
.getLength() );
856 for( ::std::size_t i
=0; i
<nSize
; ++i
)
858 sal_Int16
nParaIndex( -1 );
859 uno::Reference
< drawing::XShape
> xShape( aProps
[i
].Target
,
864 // not a shape target. Maybe a ParagraphTarget?
865 presentation::ParagraphTarget aParaTarget
;
867 if( aProps
[i
].Target
>>= aParaTarget
)
869 // yep, ParagraphTarget found - extract shape
871 xShape
= aParaTarget
.Shape
;
872 nParaIndex
= aParaTarget
.Paragraph
;
878 ShapeSharedPtr
pShape( mpLayerManager
->lookupShape( xShape
) );
882 OSL_FAIL( "SlideImpl::applyInitialShapeAttributes(): no shape found for given target" );
886 AttributableShapeSharedPtr
pAttrShape(
887 ::std::dynamic_pointer_cast
< AttributableShape
>( pShape
) );
891 OSL_FAIL( "SlideImpl::applyInitialShapeAttributes(): shape found does not "
892 "implement AttributableShape interface" );
896 if( nParaIndex
!= -1 )
898 // our target is a paragraph subset, thus look
900 const DocTreeNodeSupplier
& rNodeSupplier( pAttrShape
->getTreeNodeSupplier() );
902 if( rNodeSupplier
.getNumberOfTreeNodes(
903 DocTreeNode::NodeType::LogicalParagraph
) <= nParaIndex
)
905 OSL_FAIL( "SlideImpl::applyInitialShapeAttributes(): shape found does not "
906 "provide a subset for requested paragraph index" );
910 pAttrShape
= pAttrShape
->getSubset(
911 rNodeSupplier
.getTreeNode(
913 DocTreeNode::NodeType::LogicalParagraph
) );
917 OSL_FAIL( "SlideImpl::applyInitialShapeAttributes(): shape found does not "
918 "provide a subset for requested paragraph index" );
923 const uno::Sequence
< beans::NamedValue
>& rShapeProps( aProps
[i
].Properties
);
924 const ::std::size_t nShapePropSize( rShapeProps
.getLength() );
925 for( ::std::size_t j
=0; j
<nShapePropSize
; ++j
)
928 if( rShapeProps
[j
].Name
.equalsIgnoreAsciiCase("visibility") &&
929 extractValue( bVisible
,
930 rShapeProps
[j
].Value
,
932 ::basegfx::B2DSize( getSlideSize() ) ))
934 pAttrShape
->setVisibility( bVisible
);
938 OSL_FAIL( "SlideImpl::applyInitialShapeAttributes(): Unexpected "
939 "(and unimplemented) property encountered" );
946 bool SlideImpl::applyInitialShapeAttributes(
947 const uno::Reference
< animations::XAnimationNode
>& xRootAnimationNode
)
949 if( !implPrefetchShow() )
952 if( !xRootAnimationNode
.is() )
954 meAnimationState
= INITIAL_STATE
;
956 return true; // no animations - no attributes to apply -
960 applyShapeAttributes(xRootAnimationNode
, true);
962 meAnimationState
= INITIAL_STATE
;
967 bool SlideImpl::loadShapes()
972 ENSURE_OR_RETURN_FALSE( mxDrawPage
.is(),
973 "SlideImpl::loadShapes(): Invalid draw page" );
974 ENSURE_OR_RETURN_FALSE( mpLayerManager
,
975 "SlideImpl::loadShapes(): Invalid layer manager" );
977 // fetch desired page content
978 // ==========================
980 // also take master page content
981 uno::Reference
< drawing::XDrawPage
> xMasterPage
;
982 uno::Reference
< drawing::XShapes
> xMasterPageShapes
;
983 sal_Int32
nCurrCount(0);
985 uno::Reference
< drawing::XMasterPageTarget
> xMasterPageTarget( mxDrawPage
,
987 if( xMasterPageTarget
.is() )
989 xMasterPage
= xMasterPageTarget
->getMasterPage();
990 xMasterPageShapes
.set( xMasterPage
,
993 if( xMasterPage
.is() && xMasterPageShapes
.is() )
995 // TODO(P2): maybe cache master pages here (or treat the
996 // masterpage as a single metafile. At least currently,
997 // masterpages do not contain animation effects)
1000 // load the masterpage shapes
1002 ShapeImporter
aMPShapesFunctor( xMasterPage
,
1004 mxDrawPagesSupplier
,
1006 0, /* shape num starts at 0 */
1009 mpLayerManager
->addShape(
1010 aMPShapesFunctor
.importBackgroundShape() );
1012 while( !aMPShapesFunctor
.isImportDone() )
1014 ShapeSharedPtr
const& rShape(
1015 aMPShapesFunctor
.importShape() );
1017 mpLayerManager
->addShape( rShape
);
1019 addPolygons(aMPShapesFunctor
.getPolygons());
1021 nCurrCount
= static_cast<sal_Int32
>(aMPShapesFunctor
.getImportedShapesCount());
1023 catch( uno::RuntimeException
& )
1027 catch( ShapeLoadFailedException
& )
1029 // TODO(E2): Error handling. For now, bail out
1030 OSL_FAIL( "SlideImpl::loadShapes(): caught ShapeLoadFailedException" );
1034 catch( uno::Exception
& )
1036 SAL_WARN( "slideshow", comphelper::anyToString( cppu::getCaughtException() ) );
1044 // load the normal page shapes
1047 ShapeImporter
aShapesFunctor( mxDrawPage
,
1049 mxDrawPagesSupplier
,
1054 while( !aShapesFunctor
.isImportDone() )
1056 ShapeSharedPtr
const& rShape(
1057 aShapesFunctor
.importShape() );
1059 mpLayerManager
->addShape( rShape
);
1061 addPolygons(aShapesFunctor
.getPolygons());
1063 catch( uno::RuntimeException
& )
1067 catch( ShapeLoadFailedException
& )
1069 // TODO(E2): Error handling. For now, bail out
1070 OSL_FAIL( "SlideImpl::loadShapes(): caught ShapeLoadFailedException" );
1073 catch( uno::Exception
& )
1075 SAL_WARN( "slideshow", comphelper::anyToString( cppu::getCaughtException() ) );
1079 mbShapesLoaded
= true;
1084 basegfx::B2ISize
SlideImpl::getSlideSizeImpl() const
1086 uno::Reference
< beans::XPropertySet
> xPropSet(
1087 mxDrawPage
, uno::UNO_QUERY_THROW
);
1089 sal_Int32 nDocWidth
= 0;
1090 sal_Int32 nDocHeight
= 0;
1091 xPropSet
->getPropertyValue("Width") >>= nDocWidth
;
1092 xPropSet
->getPropertyValue("Height") >>= nDocHeight
;
1094 return basegfx::B2ISize( nDocWidth
, nDocHeight
);
1100 SlideSharedPtr
createSlide( const uno::Reference
< drawing::XDrawPage
>& xDrawPage
,
1101 const uno::Reference
<drawing::XDrawPagesSupplier
>& xDrawPages
,
1102 const uno::Reference
< animations::XAnimationNode
>& xRootNode
,
1103 EventQueue
& rEventQueue
,
1104 EventMultiplexer
& rEventMultiplexer
,
1105 ScreenUpdater
& rScreenUpdater
,
1106 ActivitiesQueue
& rActivitiesQueue
,
1107 UserEventQueue
& rUserEventQueue
,
1108 CursorManager
& rCursorManager
,
1109 const UnoViewContainer
& rViewContainer
,
1110 const uno::Reference
< uno::XComponentContext
>& xComponentContext
,
1111 const ShapeEventListenerMap
& rShapeListenerMap
,
1112 const ShapeCursorMap
& rShapeCursorMap
,
1113 const PolyPolygonVector
& rPolyPolygonVector
,
1114 RGBColor
const& rUserPaintColor
,
1115 double dUserPaintStrokeWidth
,
1116 bool bUserPaintEnabled
,
1117 bool bIntrinsicAnimationsAllowed
,
1118 bool bDisableAnimationZOrder
)
1120 std::shared_ptr
<SlideImpl
> pRet( new SlideImpl( xDrawPage
, xDrawPages
, xRootNode
, rEventQueue
,
1121 rEventMultiplexer
, rScreenUpdater
,
1122 rActivitiesQueue
, rUserEventQueue
,
1123 rCursorManager
, rViewContainer
,
1124 xComponentContext
, rShapeListenerMap
,
1125 rShapeCursorMap
, rPolyPolygonVector
, rUserPaintColor
,
1126 dUserPaintStrokeWidth
, bUserPaintEnabled
,
1127 bIntrinsicAnimationsAllowed
,
1128 bDisableAnimationZOrder
));
1130 rEventMultiplexer
.addViewHandler( pRet
);
1135 } // namespace internal
1136 } // namespace slideshow
1138 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */