1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: basenode.cxx,v $
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"
35 #include <canvas/debug.hxx>
36 #include <canvas/verbosetrace.hxx>
38 #include <com/sun/star/animations/XAnimate.hpp>
39 #include <com/sun/star/presentation/ParagraphTarget.hpp>
40 #include <com/sun/star/animations/AnimationFill.hpp>
41 #include <com/sun/star/animations/AnimationRestart.hpp>
42 #include <com/sun/star/presentation/EffectNodeType.hpp>
43 #include <com/sun/star/beans/XPropertySet.hpp>
45 #include "basenode.hxx"
46 #include "eventmultiplexer.hxx"
47 #include "basecontainernode.hxx"
48 #include "eventqueue.hxx"
49 #include "delayevent.hxx"
51 #include "nodetools.hxx"
52 #include "generateevent.hxx"
54 #include <boost/bind.hpp>
59 using namespace ::com::sun::star
;
66 typedef int StateTransitionTable
[17];
68 // State transition tables
69 // =========================================================================
71 const int* getStateTransitionTable( sal_Int16 nRestartMode
,
74 // TODO(F2): restart issues in below tables
76 // transition table for restart=NEVER, fill=REMOVE
77 static const StateTransitionTable stateTransitionTable_Never_Remove
= {
78 AnimationNode::INVALID
,
79 AnimationNode::RESOLVED
|AnimationNode::ENDED
, // active successors for UNRESOLVED
80 AnimationNode::ACTIVE
|AnimationNode::ENDED
, // active successors for RESOLVED
81 AnimationNode::INVALID
,
82 AnimationNode::ENDED
, // active successors for ACTIVE: no freeze here
83 AnimationNode::INVALID
,
84 AnimationNode::INVALID
,
85 AnimationNode::INVALID
,
86 AnimationNode::INVALID
, // active successors for FROZEN: this state is unreachable here
87 AnimationNode::INVALID
,
88 AnimationNode::INVALID
,
89 AnimationNode::INVALID
,
90 AnimationNode::INVALID
,
91 AnimationNode::INVALID
,
92 AnimationNode::INVALID
,
93 AnimationNode::INVALID
,
94 AnimationNode::ENDED
// active successors for ENDED: this state is a sink here (cannot restart)
97 // transition table for restart=WHEN_NOT_ACTIVE, fill=REMOVE
98 static const StateTransitionTable stateTransitionTable_NotActive_Remove
= {
99 AnimationNode::INVALID
,
100 AnimationNode::RESOLVED
|AnimationNode::ENDED
, // active successors for UNRESOLVED
101 AnimationNode::ACTIVE
|AnimationNode::ENDED
, // active successors for RESOLVED
102 AnimationNode::INVALID
,
103 AnimationNode::ENDED
, // active successors for ACTIVE: no freeze here
104 AnimationNode::INVALID
,
105 AnimationNode::INVALID
,
106 AnimationNode::INVALID
,
107 AnimationNode::INVALID
, // active successors for FROZEN:
108 // this state is unreachable here
109 AnimationNode::INVALID
,
110 AnimationNode::INVALID
,
111 AnimationNode::INVALID
,
112 AnimationNode::INVALID
,
113 AnimationNode::INVALID
,
114 AnimationNode::INVALID
,
115 AnimationNode::INVALID
,
116 AnimationNode::ENDED
|AnimationNode::RESOLVED
|AnimationNode::ACTIVE
// active successors for ENDED:
117 // restart possible when ended
120 // transition table for restart=ALWAYS, fill=REMOVE
121 static const StateTransitionTable stateTransitionTable_Always_Remove
= {
122 AnimationNode::INVALID
,
123 AnimationNode::RESOLVED
|AnimationNode::ENDED
, // active successors for UNRESOLVED
124 AnimationNode::ACTIVE
|AnimationNode::ENDED
, // active successors for RESOLVED
125 AnimationNode::INVALID
,
126 AnimationNode::ENDED
|AnimationNode::ACTIVE
|AnimationNode::RESOLVED
, // active successors for ACTIVE: restart
127 AnimationNode::INVALID
,
128 AnimationNode::INVALID
,
129 AnimationNode::INVALID
,
130 AnimationNode::INVALID
, // active successors for FROZEN:
131 // this state is unreachable here
132 AnimationNode::INVALID
,
133 AnimationNode::INVALID
,
134 AnimationNode::INVALID
,
135 AnimationNode::INVALID
,
136 AnimationNode::INVALID
,
137 AnimationNode::INVALID
,
138 AnimationNode::INVALID
,
139 AnimationNode::ENDED
|AnimationNode::ACTIVE
|AnimationNode::RESOLVED
// active successors for ENDED: restart
142 // transition table for restart=NEVER, fill=FREEZE
143 static const StateTransitionTable stateTransitionTable_Never_Freeze
= {
144 AnimationNode::INVALID
,
145 AnimationNode::RESOLVED
|AnimationNode::ENDED
, // active successors for UNRESOLVED
146 AnimationNode::ACTIVE
|AnimationNode::ENDED
, // active successors for RESOLVED
147 AnimationNode::INVALID
,
148 AnimationNode::FROZEN
|AnimationNode::ENDED
, // active successors for ACTIVE: freeze object
149 AnimationNode::INVALID
,
150 AnimationNode::INVALID
,
151 AnimationNode::INVALID
,
152 AnimationNode::ENDED
, // active successors for FROZEN: end
153 AnimationNode::INVALID
,
154 AnimationNode::INVALID
,
155 AnimationNode::INVALID
,
156 AnimationNode::INVALID
,
157 AnimationNode::INVALID
,
158 AnimationNode::INVALID
,
159 AnimationNode::INVALID
,
160 AnimationNode::ENDED
, // active successors for ENDED: this state is a sink here (cannot restart)
163 // transition table for restart=WHEN_NOT_ACTIVE, fill=FREEZE
164 static const StateTransitionTable stateTransitionTable_NotActive_Freeze
= {
165 AnimationNode::INVALID
,
166 AnimationNode::RESOLVED
|AnimationNode::ENDED
, // active successors for UNRESOLVED
167 AnimationNode::ACTIVE
|AnimationNode::ENDED
, // active successors for RESOLVED
168 AnimationNode::INVALID
,
169 AnimationNode::FROZEN
|AnimationNode::ENDED
, // active successors for ACTIVE: freeze object
170 AnimationNode::INVALID
,
171 AnimationNode::INVALID
,
172 AnimationNode::INVALID
,
173 AnimationNode::ENDED
|AnimationNode::RESOLVED
|AnimationNode::ACTIVE
, // active successors for FROZEN:
174 // restart possible when ended
175 AnimationNode::INVALID
,
176 AnimationNode::INVALID
,
177 AnimationNode::INVALID
,
178 AnimationNode::INVALID
,
179 AnimationNode::INVALID
,
180 AnimationNode::INVALID
,
181 AnimationNode::INVALID
,
182 AnimationNode::ENDED
|AnimationNode::RESOLVED
|AnimationNode::ACTIVE
// active successors for ENDED:
183 // restart possible when ended
186 // transition table for restart=ALWAYS, fill=FREEZE
187 static const StateTransitionTable stateTransitionTable_Always_Freeze
= {
188 AnimationNode::INVALID
,
189 AnimationNode::RESOLVED
|AnimationNode::ENDED
, // active successors for UNRESOLVED
190 AnimationNode::ACTIVE
|AnimationNode::ENDED
, // active successors for RESOLVED
191 AnimationNode::INVALID
,
192 AnimationNode::FROZEN
|AnimationNode::ENDED
|AnimationNode::ACTIVE
|AnimationNode::RESOLVED
, // active successors for ACTIVE:
193 // end object, restart
194 AnimationNode::INVALID
,
195 AnimationNode::INVALID
,
196 AnimationNode::INVALID
,
197 AnimationNode::ENDED
|AnimationNode::RESOLVED
|AnimationNode::ACTIVE
, // active successors for FROZEN: restart possible
198 AnimationNode::INVALID
,
199 AnimationNode::INVALID
,
200 AnimationNode::INVALID
,
201 AnimationNode::INVALID
,
202 AnimationNode::INVALID
,
203 AnimationNode::INVALID
,
204 AnimationNode::INVALID
,
205 AnimationNode::ENDED
|AnimationNode::ACTIVE
|AnimationNode::RESOLVED
// active successors for ENDED: restart
208 static const StateTransitionTable
* tableGuide
[] = {
209 &stateTransitionTable_Never_Remove
,
210 &stateTransitionTable_NotActive_Remove
,
211 &stateTransitionTable_Always_Remove
,
212 &stateTransitionTable_Never_Freeze
,
213 &stateTransitionTable_NotActive_Freeze
,
214 &stateTransitionTable_Always_Freeze
218 switch( nRestartMode
) {
220 case animations::AnimationRestart::DEFAULT
:
221 // same value: animations::AnimationRestart::INHERIT:
223 false, "getStateTransitionTable(): unexpected case for restart" );
224 // FALLTHROUGH intended
225 case animations::AnimationRestart::NEVER
:
228 case animations::AnimationRestart::WHEN_NOT_ACTIVE
:
231 case animations::AnimationRestart::ALWAYS
:
237 switch( nFillMode
) {
239 case animations::AnimationFill::AUTO
:
240 case animations::AnimationFill::DEFAULT
:
241 // same value: animations::AnimationFill::INHERIT:
243 false, "getStateTransitionTable(): unexpected case for fill" );
244 // FALLTHROUGH intended
245 case animations::AnimationFill::REMOVE
:
248 case animations::AnimationFill::FREEZE
:
249 case animations::AnimationFill::HOLD
:
250 case animations::AnimationFill::TRANSITION
:
255 return *tableGuide
[ 3*nFillValue
+ nRestartValue
];
258 /// Little helper predicate, to detect main sequence root node
259 bool isMainSequenceRootNode_(
260 const uno::Reference
< animations::XAnimationNode
>& xNode
)
262 // detect main sequence root node (need that for
263 // end-of-mainsequence signalling below)
264 beans::NamedValue
const aSearchKey(
265 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "node-type" ) ),
266 uno::makeAny( presentation::EffectNodeType::MAIN_SEQUENCE
) );
268 uno::Sequence
<beans::NamedValue
> const userData(xNode
->getUserData());
269 return findNamedValue( userData
, aSearchKey
);
274 // BaseNode implementation
275 //=========================================================================
277 /** state transition handling
279 class BaseNode::StateTransition
: private boost::noncopyable
282 enum Options
{ NONE
, FORCE
};
284 explicit StateTransition( BaseNode
* pNode
)
285 : mpNode(pNode
), meToState(INVALID
) {}
291 bool enter( NodeState eToState
, int options
= NONE
)
293 OSL_ENSURE( meToState
== INVALID
,
294 "### commit() before enter()ing again!" );
295 if (meToState
!= INVALID
)
297 bool const bForce
= ((options
& FORCE
) != 0);
298 if (!bForce
&& !mpNode
->isTransition( mpNode
->meCurrState
, eToState
))
300 // recursion detection:
301 if ((mpNode
->meCurrentStateTransition
& eToState
) != 0)
302 return false; // already in wanted transition
304 mpNode
->meCurrentStateTransition
|= eToState
;
305 meToState
= eToState
;
306 return true; // in transition
310 OSL_ENSURE( meToState
!= INVALID
, "### nothing to commit!" );
311 if (meToState
!= INVALID
) {
312 mpNode
->meCurrState
= meToState
;
318 if (meToState
!= INVALID
) {
319 OSL_ASSERT( (mpNode
->meCurrentStateTransition
& meToState
) != 0 );
320 mpNode
->meCurrentStateTransition
&= ~meToState
;
326 BaseNode
*const mpNode
;
330 BaseNode::BaseNode( const uno::Reference
< animations::XAnimationNode
>& xNode
,
331 const BaseContainerNodeSharedPtr
& rParent
,
332 const NodeContext
& rContext
) :
333 maContext( rContext
.maContext
),
334 maDeactivatingListeners(),
335 mxAnimationNode( xNode
),
338 mpStateTransitionTable( NULL
),
339 mnStartDelay( rContext
.mnStartDelay
),
340 meCurrState( UNRESOLVED
),
341 meCurrentStateTransition( 0 ),
343 mbIsMainSequenceRootNode( isMainSequenceRootNode_( xNode
) )
345 ENSURE_OR_THROW( mxAnimationNode
.is(),
346 "BaseNode::BaseNode(): Invalid XAnimationNode" );
348 // setup state transition table
349 mpStateTransitionTable
= getStateTransitionTable( getRestartMode(),
353 void BaseNode::dispose()
355 meCurrState
= INVALID
;
357 // discharge a loaded event, if any:
358 if (mpCurrentEvent
) {
359 mpCurrentEvent
->dispose();
360 mpCurrentEvent
.reset();
362 maDeactivatingListeners
.clear();
363 mxAnimationNode
.clear();
370 sal_Int16
BaseNode::getRestartMode()
372 const sal_Int16
nTmp( mxAnimationNode
->getRestart() );
373 return (nTmp
!= animations::AnimationRestart::DEFAULT
&&
374 nTmp
!= animations::AnimationRestart::INHERIT
)
375 ? nTmp
: getRestartDefaultMode();
378 sal_Int16
BaseNode::getFillMode()
380 const sal_Int16
nTmp( mxAnimationNode
->getFill() );
381 const sal_Int16
nFill((nTmp
!= animations::AnimationFill::DEFAULT
&&
382 nTmp
!= animations::AnimationFill::INHERIT
)
383 ? nTmp
: getFillDefaultMode());
385 // For AUTO fill mode, SMIL specifies that fill mode is FREEZE,
386 // if no explicit active duration is given
387 // (no duration, end, repeatCount or repeatDuration given),
388 // and REMOVE otherwise
389 if( nFill
== animations::AnimationFill::AUTO
) {
390 return (isIndefiniteTiming( mxAnimationNode
->getDuration() ) &&
391 isIndefiniteTiming( mxAnimationNode
->getEnd() ) &&
392 !mxAnimationNode
->getRepeatCount().hasValue() &&
393 isIndefiniteTiming( mxAnimationNode
->getRepeatDuration() ))
394 ? animations::AnimationFill::FREEZE
395 : animations::AnimationFill::REMOVE
;
402 sal_Int16
BaseNode::getFillDefaultMode() const
404 sal_Int16 nFillDefault
= mxAnimationNode
->getFillDefault();
405 if (nFillDefault
== animations::AnimationFill::DEFAULT
) {
406 nFillDefault
= (mpParent
!= 0
407 ? mpParent
->getFillDefaultMode()
408 : animations::AnimationFill::AUTO
);
413 sal_Int16
BaseNode::getRestartDefaultMode() const
415 sal_Int16 nRestartDefaultMode
= mxAnimationNode
->getRestartDefault();
416 if (nRestartDefaultMode
== animations::AnimationRestart::DEFAULT
) {
417 nRestartDefaultMode
= (mpParent
!= 0
418 ? mpParent
->getRestartDefaultMode()
419 : animations::AnimationRestart::ALWAYS
);
421 return nRestartDefaultMode
;
424 uno::Reference
<animations::XAnimationNode
> BaseNode::getXAnimationNode() const
426 return mxAnimationNode
;
429 bool BaseNode::init()
431 if (! checkValidNode())
433 meCurrState
= UNRESOLVED
;
434 // discharge a loaded event, if any:
435 if (mpCurrentEvent
) {
436 mpCurrentEvent
->dispose();
437 mpCurrentEvent
.reset();
439 return init_st(); // may call derived class
442 bool BaseNode::init_st()
447 bool BaseNode::resolve()
449 if (! checkValidNode())
452 OSL_ASSERT( meCurrState
!= RESOLVED
);
453 if (inStateOrTransition( RESOLVED
))
456 StateTransition
st(this);
457 if (st
.enter( RESOLVED
) &&
458 isTransition( RESOLVED
, ACTIVE
) &&
459 resolve_st() /* may call derived class */)
461 st
.commit(); // changing state
463 // discharge a loaded event, if any:
465 mpCurrentEvent
->dispose();
467 // schedule activation event:
469 // This method takes the NodeContext::mnStartDelay value into account,
470 // to cater for iterate container time shifts. We cannot put different
471 // iterations of the iterate container's children into different
472 // subcontainer (such as a 'DelayContainer', which delays resolving its
473 // children by a fixed amount), since all iterations' nodes must be
474 // resolved at the same time (otherwise, the delayed subset creation
475 // will not work, i.e. deactivate the subsets too late in the master
477 uno::Any
const aBegin( mxAnimationNode
->getBegin() );
478 if (aBegin
.hasValue()) {
479 mpCurrentEvent
= generateEvent(
480 aBegin
, boost::bind( &AnimationNode::activate
, mpSelf
),
481 maContext
, mnStartDelay
);
484 // For some leaf nodes, PPT import yields empty begin time,
485 // although semantically, it should be 0.0
486 // TODO(F3): That should really be provided by the PPT import
488 // schedule delayed activation event. Take iterate node
489 // timeout into account
490 mpCurrentEvent
= makeDelay(
491 boost::bind( &AnimationNode::activate
, mpSelf
), mnStartDelay
);
492 maContext
.mrEventQueue
.addEvent( mpCurrentEvent
);
500 bool BaseNode::resolve_st()
506 bool BaseNode::activate()
508 if (! checkValidNode())
511 OSL_ASSERT( meCurrState
!= ACTIVE
);
512 if (inStateOrTransition( ACTIVE
))
515 StateTransition
st(this);
516 if (st
.enter( ACTIVE
)) {
518 activate_st(); // calling derived class
520 st
.commit(); // changing state
522 maContext
.mrEventMultiplexer
.notifyAnimationStart( mpSelf
);
530 void BaseNode::activate_st()
532 scheduleDeactivationEvent();
535 void BaseNode::scheduleDeactivationEvent( EventSharedPtr
const& pEvent
)
537 if (mpCurrentEvent
) {
538 mpCurrentEvent
->dispose();
539 mpCurrentEvent
.reset();
542 if (maContext
.mrEventQueue
.addEvent( pEvent
))
543 mpCurrentEvent
= pEvent
;
546 // This method need not take the
547 // NodeContext::mnStartDelay value into account,
548 // because the deactivation event is only scheduled
549 // when the effect is started: the timeout is then
550 // already respected.
553 // think about set node, anim base node!
554 // if anim base node has no activity, this is called to schedule deactivatiion,
555 // but what if it does not schedule anything?
557 // TODO(F2): Handle end time attribute, too
558 mpCurrentEvent
= generateEvent(
559 mxAnimationNode
->getDuration(),
560 boost::bind( &AnimationNode::deactivate
, mpSelf
),
565 void BaseNode::deactivate()
567 if (inStateOrTransition( ENDED
| FROZEN
) || !checkValidNode())
570 if (isTransition( meCurrState
, FROZEN
, false /* no OSL_ASSERT */ )) {
571 // do transition to FROZEN:
572 StateTransition
st(this);
573 if (st
.enter( FROZEN
, StateTransition::FORCE
)) {
575 deactivate_st( FROZEN
);
578 notifyEndListeners();
580 // discharge a loaded event, before going on:
581 if (mpCurrentEvent
) {
582 mpCurrentEvent
->dispose();
583 mpCurrentEvent
.reset();
591 // state has changed either to FROZEN or ENDED
594 void BaseNode::deactivate_st( NodeState
)
600 bool const bIsFrozenOrInTransitionToFrozen
= inStateOrTransition( FROZEN
);
601 if (inStateOrTransition( ENDED
) || !checkValidNode())
604 // END must always be reachable. If not, that's an error in the
606 OSL_ENSURE( isTransition( meCurrState
, ENDED
),
607 "end state not reachable in transition table" );
609 StateTransition
st(this);
610 if (st
.enter( ENDED
, StateTransition::FORCE
)) {
612 deactivate_st( ENDED
);
613 st
.commit(); // changing state
615 // if is FROZEN or is to be FROZEN, then
616 // will/already notified deactivating listeners
617 if (!bIsFrozenOrInTransitionToFrozen
)
618 notifyEndListeners();
620 // discharge a loaded event, before going on:
621 if (mpCurrentEvent
) {
622 mpCurrentEvent
->dispose();
623 mpCurrentEvent
.reset();
628 void BaseNode::notifyDeactivating( const AnimationNodeSharedPtr
& rNotifier
)
630 (void) rNotifier
; // avoid warning
631 OSL_ASSERT( rNotifier
->getState() == FROZEN
||
632 rNotifier
->getState() == ENDED
);
633 // TODO(F1): for end sync functionality, this might indeed be used some day
636 void BaseNode::notifyEndListeners() const
638 // notify all listeners
639 std::for_each( maDeactivatingListeners
.begin(),
640 maDeactivatingListeners
.end(),
641 boost::bind( &AnimationNode::notifyDeactivating
, _1
,
642 boost::cref(mpSelf
) ) );
644 // notify state change
645 maContext
.mrEventMultiplexer
.notifyAnimationEnd( mpSelf
);
647 // notify main sequence end (iff we're the main
648 // sequence root node). This is because the main
649 // sequence determines the active duration of the
650 // slide. All other sequences are secondary, in that
651 // they don't prevent a slide change from happening,
652 // even if they have not been completed. In other
653 // words, all sequences except the main sequence are
654 // optional for the slide lifetime.
655 if (isMainSequenceRootNode())
656 maContext
.mrEventMultiplexer
.notifySlideAnimationsEnd();
659 AnimationNode::NodeState
BaseNode::getState() const
664 bool BaseNode::registerDeactivatingListener(
665 const AnimationNodeSharedPtr
& rNotifee
)
667 if (! checkValidNode())
672 "BaseNode::registerDeactivatingListener(): invalid notifee" );
673 maDeactivatingListeners
.push_back( rNotifee
);
678 void BaseNode::setSelf( const BaseNodeSharedPtr
& rSelf
)
680 ENSURE_OR_THROW( rSelf
.get() == this,
681 "BaseNode::setSelf(): got ptr to different object" );
682 ENSURE_OR_THROW( !mpSelf
,
683 "BaseNode::setSelf(): called multiple times" );
689 //=========================================================================
691 #if defined(VERBOSE) && defined(DBG_UTIL)
692 void BaseNode::showState() const
694 const AnimationNode::NodeState
eNodeState( getState() );
696 if( eNodeState
== AnimationNode::INVALID
)
697 VERBOSE_TRACE( "Node state: n0x%X [label=\"%s\",style=filled,"
698 "fillcolor=\"0.5,0.2,0.5\"]",
699 (const char*)this+debugGetCurrentOffset(),
702 VERBOSE_TRACE( "Node state: n0x%X [label=\"%s\",style=filled,"
703 "fillcolor=\"%f,1.0,1.0\"]",
704 (const char*)this+debugGetCurrentOffset(),
706 log(double(getState()))/4.0 );
708 // determine additional node information
709 uno::Reference
<animations::XAnimate
> const xAnimate( mxAnimationNode
,
713 uno::Reference
< drawing::XShape
> xTargetShape( xAnimate
->getTarget(),
716 if( !xTargetShape
.is() )
718 ::com::sun::star::presentation::ParagraphTarget aTarget
;
720 // no shape provided. Maybe a ParagraphTarget?
721 if( (xAnimate
->getTarget() >>= aTarget
) )
722 xTargetShape
= aTarget
.Shape
;
725 if( xTargetShape
.is() )
727 uno::Reference
< beans::XPropertySet
> xPropSet( xTargetShape
,
731 ::rtl::OUString aName
;
732 if( (xPropSet
->getPropertyValue(
733 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Name") ) )
736 const ::rtl::OString
& rAsciiName(
737 ::rtl::OUStringToOString( aName
,
738 RTL_TEXTENCODING_ASCII_US
) );
740 VERBOSE_TRACE( "Node info: n0x%X, name \"%s\"",
741 (const char*)this+debugGetCurrentOffset(),
742 rAsciiName
.getStr() );
748 const char* BaseNode::getDescription() const
753 void BaseNode::showTreeFromWithin() const
756 BaseNodeSharedPtr
pCurrNode( mpSelf
);
757 while( pCurrNode
->mpParent
) pCurrNode
= pCurrNode
->mpParent
;
759 pCurrNode
->showState();
763 } // namespace internal
764 } // namespace slideshow