bump product version to 5.0.4.1
[LibreOffice.git] / slideshow / source / engine / animationnodes / basenode.cxx
blob4940a8330ed7d9ffeabada58da6d4f3042ef2b9f
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 .
21 // must be first
22 #include <canvas/debug.hxx>
23 #include <canvas/verbosetrace.hxx>
25 #include <com/sun/star/animations/XAnimate.hpp>
26 #include <com/sun/star/presentation/ParagraphTarget.hpp>
27 #include <com/sun/star/animations/AnimationFill.hpp>
28 #include <com/sun/star/animations/AnimationRestart.hpp>
29 #include <com/sun/star/presentation/EffectNodeType.hpp>
30 #include <com/sun/star/beans/XPropertySet.hpp>
32 #include "basenode.hxx"
33 #include "eventmultiplexer.hxx"
34 #include "basecontainernode.hxx"
35 #include "eventqueue.hxx"
36 #include "delayevent.hxx"
37 #include "tools.hxx"
38 #include "nodetools.hxx"
39 #include "generateevent.hxx"
41 #include <boost/bind.hpp>
42 #include <vector>
43 #include <algorithm>
44 #include <iterator>
46 using namespace ::com::sun::star;
48 namespace slideshow {
49 namespace internal {
51 namespace {
53 typedef int StateTransitionTable[17];
55 // State transition tables
56 // =========================================================================
58 const int* getStateTransitionTable( sal_Int16 nRestartMode,
59 sal_Int16 nFillMode )
61 // TODO(F2): restart issues in below tables
63 // transition table for restart=NEVER, fill=REMOVE
64 static const StateTransitionTable stateTransitionTable_Never_Remove = {
65 AnimationNode::INVALID,
66 AnimationNode::RESOLVED|AnimationNode::ENDED, // active successors for UNRESOLVED
67 AnimationNode::ACTIVE|AnimationNode::ENDED, // active successors for RESOLVED
68 AnimationNode::INVALID,
69 AnimationNode::ENDED, // active successors for ACTIVE: no freeze here
70 AnimationNode::INVALID,
71 AnimationNode::INVALID,
72 AnimationNode::INVALID,
73 AnimationNode::INVALID, // active successors for FROZEN: this state is unreachable here
74 AnimationNode::INVALID,
75 AnimationNode::INVALID,
76 AnimationNode::INVALID,
77 AnimationNode::INVALID,
78 AnimationNode::INVALID,
79 AnimationNode::INVALID,
80 AnimationNode::INVALID,
81 AnimationNode::ENDED // active successors for ENDED: this state is a sink here (cannot restart)
84 // transition table for restart=WHEN_NOT_ACTIVE, fill=REMOVE
85 static const StateTransitionTable stateTransitionTable_NotActive_Remove = {
86 AnimationNode::INVALID,
87 AnimationNode::RESOLVED|AnimationNode::ENDED, // active successors for UNRESOLVED
88 AnimationNode::ACTIVE|AnimationNode::ENDED, // active successors for RESOLVED
89 AnimationNode::INVALID,
90 AnimationNode::ENDED, // active successors for ACTIVE: no freeze here
91 AnimationNode::INVALID,
92 AnimationNode::INVALID,
93 AnimationNode::INVALID,
94 AnimationNode::INVALID, // active successors for FROZEN:
95 // this state is unreachable here
96 AnimationNode::INVALID,
97 AnimationNode::INVALID,
98 AnimationNode::INVALID,
99 AnimationNode::INVALID,
100 AnimationNode::INVALID,
101 AnimationNode::INVALID,
102 AnimationNode::INVALID,
103 AnimationNode::ENDED|AnimationNode::RESOLVED|AnimationNode::ACTIVE // active successors for ENDED:
104 // restart possible when ended
107 // transition table for restart=ALWAYS, fill=REMOVE
108 static const StateTransitionTable stateTransitionTable_Always_Remove = {
109 AnimationNode::INVALID,
110 AnimationNode::RESOLVED|AnimationNode::ENDED, // active successors for UNRESOLVED
111 AnimationNode::ACTIVE|AnimationNode::ENDED, // active successors for RESOLVED
112 AnimationNode::INVALID,
113 AnimationNode::ENDED|AnimationNode::ACTIVE|AnimationNode::RESOLVED, // active successors for ACTIVE: restart
114 AnimationNode::INVALID,
115 AnimationNode::INVALID,
116 AnimationNode::INVALID,
117 AnimationNode::INVALID, // active successors for FROZEN:
118 // this state is unreachable here
119 AnimationNode::INVALID,
120 AnimationNode::INVALID,
121 AnimationNode::INVALID,
122 AnimationNode::INVALID,
123 AnimationNode::INVALID,
124 AnimationNode::INVALID,
125 AnimationNode::INVALID,
126 AnimationNode::ENDED|AnimationNode::ACTIVE|AnimationNode::RESOLVED // active successors for ENDED: restart
129 // transition table for restart=NEVER, fill=FREEZE
130 static const StateTransitionTable stateTransitionTable_Never_Freeze = {
131 AnimationNode::INVALID,
132 AnimationNode::RESOLVED|AnimationNode::ENDED, // active successors for UNRESOLVED
133 AnimationNode::ACTIVE|AnimationNode::ENDED, // active successors for RESOLVED
134 AnimationNode::INVALID,
135 AnimationNode::FROZEN|AnimationNode::ENDED, // active successors for ACTIVE: freeze object
136 AnimationNode::INVALID,
137 AnimationNode::INVALID,
138 AnimationNode::INVALID,
139 AnimationNode::ENDED, // active successors for FROZEN: end
140 AnimationNode::INVALID,
141 AnimationNode::INVALID,
142 AnimationNode::INVALID,
143 AnimationNode::INVALID,
144 AnimationNode::INVALID,
145 AnimationNode::INVALID,
146 AnimationNode::INVALID,
147 AnimationNode::ENDED, // active successors for ENDED: this state is a sink here (cannot restart)
150 // transition table for restart=WHEN_NOT_ACTIVE, fill=FREEZE
151 static const StateTransitionTable stateTransitionTable_NotActive_Freeze = {
152 AnimationNode::INVALID,
153 AnimationNode::RESOLVED|AnimationNode::ENDED, // active successors for UNRESOLVED
154 AnimationNode::ACTIVE|AnimationNode::ENDED, // active successors for RESOLVED
155 AnimationNode::INVALID,
156 AnimationNode::FROZEN|AnimationNode::ENDED, // active successors for ACTIVE: freeze object
157 AnimationNode::INVALID,
158 AnimationNode::INVALID,
159 AnimationNode::INVALID,
160 AnimationNode::ENDED|AnimationNode::RESOLVED|AnimationNode::ACTIVE, // active successors for FROZEN:
161 // restart possible when ended
162 AnimationNode::INVALID,
163 AnimationNode::INVALID,
164 AnimationNode::INVALID,
165 AnimationNode::INVALID,
166 AnimationNode::INVALID,
167 AnimationNode::INVALID,
168 AnimationNode::INVALID,
169 AnimationNode::ENDED|AnimationNode::RESOLVED|AnimationNode::ACTIVE // active successors for ENDED:
170 // restart possible when ended
173 // transition table for restart=ALWAYS, fill=FREEZE
174 static const StateTransitionTable stateTransitionTable_Always_Freeze = {
175 AnimationNode::INVALID,
176 AnimationNode::RESOLVED|AnimationNode::ENDED, // active successors for UNRESOLVED
177 AnimationNode::ACTIVE|AnimationNode::ENDED, // active successors for RESOLVED
178 AnimationNode::INVALID,
179 AnimationNode::FROZEN|AnimationNode::ENDED|AnimationNode::ACTIVE|AnimationNode::RESOLVED, // active successors for ACTIVE:
180 // end object, restart
181 AnimationNode::INVALID,
182 AnimationNode::INVALID,
183 AnimationNode::INVALID,
184 AnimationNode::ENDED|AnimationNode::RESOLVED|AnimationNode::ACTIVE, // active successors for FROZEN: restart possible
185 AnimationNode::INVALID,
186 AnimationNode::INVALID,
187 AnimationNode::INVALID,
188 AnimationNode::INVALID,
189 AnimationNode::INVALID,
190 AnimationNode::INVALID,
191 AnimationNode::INVALID,
192 AnimationNode::ENDED|AnimationNode::ACTIVE|AnimationNode::RESOLVED // active successors for ENDED: restart
195 static const StateTransitionTable* tableGuide[] = {
196 &stateTransitionTable_Never_Remove,
197 &stateTransitionTable_NotActive_Remove,
198 &stateTransitionTable_Always_Remove,
199 &stateTransitionTable_Never_Freeze,
200 &stateTransitionTable_NotActive_Freeze,
201 &stateTransitionTable_Always_Freeze
204 int nRestartValue;
205 switch( nRestartMode ) {
206 default:
207 case animations::AnimationRestart::DEFAULT:
208 // same value: animations::AnimationRestart::INHERIT:
209 OSL_FAIL(
210 "getStateTransitionTable(): unexpected case for restart" );
211 // FALLTHROUGH intended
212 case animations::AnimationRestart::NEVER:
213 nRestartValue = 0;
214 break;
215 case animations::AnimationRestart::WHEN_NOT_ACTIVE:
216 nRestartValue = 1;
217 break;
218 case animations::AnimationRestart::ALWAYS:
219 nRestartValue = 2;
220 break;
223 int nFillValue;
224 switch( nFillMode ) {
225 default:
226 case animations::AnimationFill::AUTO:
227 case animations::AnimationFill::DEFAULT:
228 // same value: animations::AnimationFill::INHERIT:
229 OSL_FAIL(
230 "getStateTransitionTable(): unexpected case for fill" );
231 // FALLTHROUGH intended
232 case animations::AnimationFill::REMOVE:
233 nFillValue = 0;
234 break;
235 case animations::AnimationFill::FREEZE:
236 case animations::AnimationFill::HOLD:
237 case animations::AnimationFill::TRANSITION:
238 nFillValue = 1;
239 break;
242 return *tableGuide[ 3*nFillValue + nRestartValue ];
245 /// Little helper predicate, to detect main sequence root node
246 bool isMainSequenceRootNode_(
247 const uno::Reference< animations::XAnimationNode >& xNode )
249 // detect main sequence root node (need that for
250 // end-of-mainsequence signalling below)
251 beans::NamedValue const aSearchKey(
252 OUString( "node-type" ),
253 uno::makeAny( presentation::EffectNodeType::MAIN_SEQUENCE ) );
255 uno::Sequence<beans::NamedValue> const userData(xNode->getUserData());
256 return findNamedValue( userData, aSearchKey );
259 } // anon namespace
261 // BaseNode implementation
262 //=========================================================================
264 /** state transition handling
266 class BaseNode::StateTransition : private boost::noncopyable
268 public:
269 enum Options { NONE, FORCE };
271 explicit StateTransition( BaseNode * pNode )
272 : mpNode(pNode), meToState(INVALID) {}
274 ~StateTransition() {
275 clear();
278 bool enter( NodeState eToState, int options = NONE )
280 OSL_ENSURE( meToState == INVALID,
281 "### commit() before enter()ing again!" );
282 if (meToState != INVALID)
283 return false;
284 bool const bForce = ((options & FORCE) != 0);
285 if (!bForce && !mpNode->isTransition( mpNode->meCurrState, eToState ))
286 return false;
287 // recursion detection:
288 if ((mpNode->meCurrentStateTransition & eToState) != 0)
289 return false; // already in wanted transition
290 // mark transition:
291 mpNode->meCurrentStateTransition |= eToState;
292 meToState = eToState;
293 return true; // in transition
296 void commit() {
297 OSL_ENSURE( meToState != INVALID, "### nothing to commit!" );
298 if (meToState != INVALID) {
299 mpNode->meCurrState = meToState;
300 clear();
304 void clear() {
305 if (meToState != INVALID) {
306 OSL_ASSERT( (mpNode->meCurrentStateTransition & meToState) != 0 );
307 mpNode->meCurrentStateTransition &= ~meToState;
308 meToState = INVALID;
312 private:
313 BaseNode *const mpNode;
314 NodeState meToState;
317 BaseNode::BaseNode( const uno::Reference< animations::XAnimationNode >& xNode,
318 const BaseContainerNodeSharedPtr& rParent,
319 const NodeContext& rContext ) :
320 maContext( rContext.maContext ),
321 maDeactivatingListeners(),
322 mxAnimationNode( xNode ),
323 mpParent( rParent ),
324 mpSelf(),
325 mpStateTransitionTable( NULL ),
326 mnStartDelay( rContext.mnStartDelay ),
327 meCurrState( UNRESOLVED ),
328 meCurrentStateTransition( 0 ),
329 mpCurrentEvent(),
330 mbIsMainSequenceRootNode( isMainSequenceRootNode_( xNode ) )
332 ENSURE_OR_THROW( mxAnimationNode.is(),
333 "BaseNode::BaseNode(): Invalid XAnimationNode" );
335 // setup state transition table
336 mpStateTransitionTable = getStateTransitionTable( getRestartMode(),
337 getFillMode() );
340 void BaseNode::dispose()
342 meCurrState = INVALID;
344 // discharge a loaded event, if any:
345 if (mpCurrentEvent) {
346 mpCurrentEvent->dispose();
347 mpCurrentEvent.reset();
349 maDeactivatingListeners.clear();
350 mxAnimationNode.clear();
351 mpParent.reset();
352 mpSelf.reset();
353 maContext.dispose();
357 sal_Int16 BaseNode::getRestartMode()
359 const sal_Int16 nTmp( mxAnimationNode->getRestart() );
360 return (nTmp != animations::AnimationRestart::DEFAULT &&
361 nTmp != animations::AnimationRestart::INHERIT)
362 ? nTmp : getRestartDefaultMode();
365 sal_Int16 BaseNode::getFillMode()
367 const sal_Int16 nTmp( mxAnimationNode->getFill() );
368 const sal_Int16 nFill((nTmp != animations::AnimationFill::DEFAULT &&
369 nTmp != animations::AnimationFill::INHERIT)
370 ? nTmp : getFillDefaultMode());
372 // For AUTO fill mode, SMIL specifies that fill mode is FREEZE,
373 // if no explicit active duration is given
374 // (no duration, end, repeatCount or repeatDuration given),
375 // and REMOVE otherwise
376 if( nFill == animations::AnimationFill::AUTO ) {
377 return (isIndefiniteTiming( mxAnimationNode->getDuration() ) &&
378 isIndefiniteTiming( mxAnimationNode->getEnd() ) &&
379 !mxAnimationNode->getRepeatCount().hasValue() &&
380 isIndefiniteTiming( mxAnimationNode->getRepeatDuration() ))
381 ? animations::AnimationFill::FREEZE
382 : animations::AnimationFill::REMOVE;
384 else {
385 return nFill;
389 sal_Int16 BaseNode::getFillDefaultMode() const
391 sal_Int16 nFillDefault = mxAnimationNode->getFillDefault();
392 if (nFillDefault == animations::AnimationFill::DEFAULT) {
393 nFillDefault = (mpParent != 0
394 ? mpParent->getFillDefaultMode()
395 : animations::AnimationFill::AUTO);
397 return nFillDefault;
400 sal_Int16 BaseNode::getRestartDefaultMode() const
402 sal_Int16 nRestartDefaultMode = mxAnimationNode->getRestartDefault();
403 if (nRestartDefaultMode == animations::AnimationRestart::DEFAULT) {
404 nRestartDefaultMode = (mpParent != 0
405 ? mpParent->getRestartDefaultMode()
406 : animations::AnimationRestart::ALWAYS);
408 return nRestartDefaultMode;
411 uno::Reference<animations::XAnimationNode> BaseNode::getXAnimationNode() const
413 return mxAnimationNode;
416 bool BaseNode::init()
418 if (! checkValidNode())
419 return false;
420 meCurrState = UNRESOLVED;
421 // discharge a loaded event, if any:
422 if (mpCurrentEvent) {
423 mpCurrentEvent->dispose();
424 mpCurrentEvent.reset();
426 return init_st(); // may call derived class
429 bool BaseNode::init_st()
431 return true;
434 bool BaseNode::resolve()
436 if (! checkValidNode())
437 return false;
439 OSL_ASSERT( meCurrState != RESOLVED );
440 if (inStateOrTransition( RESOLVED ))
441 return true;
443 StateTransition st(this);
444 if (st.enter( RESOLVED ) &&
445 isTransition( RESOLVED, ACTIVE ) &&
446 resolve_st() /* may call derived class */)
448 st.commit(); // changing state
450 // discharge a loaded event, if any:
451 if (mpCurrentEvent)
452 mpCurrentEvent->dispose();
454 // schedule activation event:
456 // This method takes the NodeContext::mnStartDelay value into account,
457 // to cater for iterate container time shifts. We cannot put different
458 // iterations of the iterate container's children into different
459 // subcontainer (such as a 'DelayContainer', which delays resolving its
460 // children by a fixed amount), since all iterations' nodes must be
461 // resolved at the same time (otherwise, the delayed subset creation
462 // will not work, i.e. deactivate the subsets too late in the master
463 // shape).
464 uno::Any const aBegin( mxAnimationNode->getBegin() );
465 if (aBegin.hasValue()) {
466 mpCurrentEvent = generateEvent(
467 aBegin, boost::bind( &AnimationNode::activate, mpSelf ),
468 maContext, mnStartDelay );
470 else {
471 // For some leaf nodes, PPT import yields empty begin time,
472 // although semantically, it should be 0.0
473 // TODO(F3): That should really be provided by the PPT import
475 // schedule delayed activation event. Take iterate node
476 // timeout into account
477 mpCurrentEvent = makeDelay(
478 boost::bind( &AnimationNode::activate, mpSelf ),
479 mnStartDelay,
480 "AnimationNode::activate with delay");
481 maContext.mrEventQueue.addEvent( mpCurrentEvent );
484 return true;
486 return false;
489 bool BaseNode::resolve_st()
491 return true;
495 bool BaseNode::activate()
497 if (! checkValidNode())
498 return false;
500 OSL_ASSERT( meCurrState != ACTIVE );
501 if (inStateOrTransition( ACTIVE ))
502 return true;
504 StateTransition st(this);
505 if (st.enter( ACTIVE )) {
507 activate_st(); // calling derived class
509 st.commit(); // changing state
511 maContext.mrEventMultiplexer.notifyAnimationStart( mpSelf );
513 return true;
516 return false;
519 void BaseNode::activate_st()
521 scheduleDeactivationEvent();
524 void BaseNode::scheduleDeactivationEvent( EventSharedPtr const& pEvent )
526 if (mpCurrentEvent) {
527 mpCurrentEvent->dispose();
528 mpCurrentEvent.reset();
530 if (pEvent) {
531 if (maContext.mrEventQueue.addEvent( pEvent ))
532 mpCurrentEvent = pEvent;
534 else {
535 // This method need not take the
536 // NodeContext::mnStartDelay value into account,
537 // because the deactivation event is only scheduled
538 // when the effect is started: the timeout is then
539 // already respected.
541 // xxx todo:
542 // think about set node, anim base node!
543 // if anim base node has no activity, this is called to schedule deactivatiion,
544 // but what if it does not schedule anything?
546 // TODO(F2): Handle end time attribute, too
547 mpCurrentEvent = generateEvent(
548 mxAnimationNode->getDuration(),
549 boost::bind( &AnimationNode::deactivate, mpSelf ),
550 maContext, 0.0 );
554 void BaseNode::deactivate()
556 if (inStateOrTransition( ENDED | FROZEN ) || !checkValidNode())
557 return;
559 if (isTransition( meCurrState, FROZEN, false /* no OSL_ASSERT */ )) {
560 // do transition to FROZEN:
561 StateTransition st(this);
562 if (st.enter( FROZEN, StateTransition::FORCE )) {
564 deactivate_st( FROZEN );
565 st.commit();
567 notifyEndListeners();
569 // discharge a loaded event, before going on:
570 if (mpCurrentEvent) {
571 mpCurrentEvent->dispose();
572 mpCurrentEvent.reset();
576 else {
577 // use end instead:
578 end();
580 // state has changed either to FROZEN or ENDED
583 void BaseNode::deactivate_st( NodeState )
587 void BaseNode::end()
589 bool const bIsFrozenOrInTransitionToFrozen = inStateOrTransition( FROZEN );
590 if (inStateOrTransition( ENDED ) || !checkValidNode())
591 return;
593 // END must always be reachable. If not, that's an error in the
594 // transition tables
595 OSL_ENSURE( isTransition( meCurrState, ENDED ),
596 "end state not reachable in transition table" );
598 StateTransition st(this);
599 if (st.enter( ENDED, StateTransition::FORCE )) {
601 deactivate_st( ENDED );
602 st.commit(); // changing state
604 // if is FROZEN or is to be FROZEN, then
605 // will/already notified deactivating listeners
606 if (!bIsFrozenOrInTransitionToFrozen)
607 notifyEndListeners();
609 // discharge a loaded event, before going on:
610 if (mpCurrentEvent) {
611 mpCurrentEvent->dispose();
612 mpCurrentEvent.reset();
617 void BaseNode::notifyDeactivating( const AnimationNodeSharedPtr& rNotifier )
619 (void) rNotifier; // avoid warning
620 OSL_ASSERT( rNotifier->getState() == FROZEN ||
621 rNotifier->getState() == ENDED );
622 // TODO(F1): for end sync functionality, this might indeed be used some day
625 void BaseNode::notifyEndListeners() const
627 // notify all listeners
628 std::for_each( maDeactivatingListeners.begin(),
629 maDeactivatingListeners.end(),
630 boost::bind( &AnimationNode::notifyDeactivating, _1,
631 boost::cref(mpSelf) ) );
633 // notify state change
634 maContext.mrEventMultiplexer.notifyAnimationEnd( mpSelf );
636 // notify main sequence end (iff we're the main
637 // sequence root node). This is because the main
638 // sequence determines the active duration of the
639 // slide. All other sequences are secondary, in that
640 // they don't prevent a slide change from happening,
641 // even if they have not been completed. In other
642 // words, all sequences except the main sequence are
643 // optional for the slide lifetime.
644 if (isMainSequenceRootNode())
645 maContext.mrEventMultiplexer.notifySlideAnimationsEnd();
648 AnimationNode::NodeState BaseNode::getState() const
650 return meCurrState;
653 bool BaseNode::registerDeactivatingListener(
654 const AnimationNodeSharedPtr& rNotifee )
656 if (! checkValidNode())
657 return false;
659 ENSURE_OR_RETURN_FALSE(
660 rNotifee,
661 "BaseNode::registerDeactivatingListener(): invalid notifee" );
662 maDeactivatingListeners.push_back( rNotifee );
664 return true;
667 void BaseNode::setSelf( const BaseNodeSharedPtr& rSelf )
669 ENSURE_OR_THROW( rSelf.get() == this,
670 "BaseNode::setSelf(): got ptr to different object" );
671 ENSURE_OR_THROW( !mpSelf,
672 "BaseNode::setSelf(): called multiple times" );
674 mpSelf = rSelf;
677 // Debug
680 #if OSL_DEBUG_LEVEL >= 2 && defined(DBG_UTIL)
681 void BaseNode::showState() const
683 const AnimationNode::NodeState eNodeState( getState() );
685 if( eNodeState == AnimationNode::INVALID )
686 VERBOSE_TRACE( "Node state: n%p [label=\"%s\",style=filled,"
687 "fillcolor=\"0.5,0.2,0.5\"]",
688 (const char*)this+debugGetCurrentOffset(),
689 getDescription() );
690 else
691 VERBOSE_TRACE( "Node state: n%p [label=\"%s\",style=filled,"
692 "fillcolor=\"%f,1.0,1.0\"]",
693 (const char*)this+debugGetCurrentOffset(),
694 getDescription(),
695 log(double(getState()))/4.0 );
697 // determine additional node information
698 uno::Reference<animations::XAnimate> const xAnimate( mxAnimationNode,
699 uno::UNO_QUERY );
700 if( xAnimate.is() )
702 uno::Reference< drawing::XShape > xTargetShape( xAnimate->getTarget(),
703 uno::UNO_QUERY );
705 if( !xTargetShape.is() )
707 ::com::sun::star::presentation::ParagraphTarget aTarget;
709 // no shape provided. Maybe a ParagraphTarget?
710 if( (xAnimate->getTarget() >>= aTarget) )
711 xTargetShape = aTarget.Shape;
714 if( xTargetShape.is() )
716 uno::Reference< beans::XPropertySet > xPropSet( xTargetShape,
717 uno::UNO_QUERY );
719 // read shape name
720 OUString aName;
721 if( (xPropSet->getPropertyValue(
722 OUString("Name") )
723 >>= aName) )
725 const OString& rAsciiName(
726 OUStringToOString( aName,
727 RTL_TEXTENCODING_ASCII_US ) );
729 VERBOSE_TRACE( "Node info: n%p, name \"%s\"",
730 (const char*)this+debugGetCurrentOffset(),
731 rAsciiName.getStr() );
737 const char* BaseNode::getDescription() const
739 return "BaseNode";
742 #endif
744 } // namespace internal
745 } // namespace slideshow
747 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */