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: SwNodeNum.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_sw.hxx"
34 #include <svx/svxenum.hxx>
35 #include <numrule.hxx>
36 #include <SwNodeNum.hxx>
40 // --> OD 2007-10-31 #i83479#
41 #include <IDocumentListItems.hxx>
44 // --> OD 2008-02-19 #refactorlists#
45 SwNodeNum::SwNodeNum( SwTxtNode
* pTxtNode
)
47 mpTxtNode( pTxtNode
),
52 SwNodeNum::SwNodeNum( SwNumRule
* pNumRule
)
60 SwNodeNum::~SwNodeNum()
64 SwTxtNode
* SwNodeNum::GetTxtNode() const
69 SwNumRule
* SwNodeNum::GetNumRule() const
74 void SwNodeNum::ChangeNumRule( SwNumRule
& rNumRule
)
76 ASSERT( GetNumRule() && GetTxtNode(),
77 "<SwNodeNum::ChangeNumRule(..)> - missing list style and/or text node. Serious defect -> please informm OD." );
78 if ( GetNumRule() && GetTxtNode() )
80 GetNumRule()->RemoveTxtNode( *(GetTxtNode()) );
83 mpNumRule
= &rNumRule
;
85 if ( GetNumRule() && GetTxtNode() )
87 GetNumRule()->AddTxtNode( *(GetTxtNode()) );
91 SwPosition
SwNodeNum::GetPosition() const
94 "<SwNodeNum::GetPosition()> - no text node set at <SwNodeNum> instance" );
95 return SwPosition(*mpTxtNode
);
98 SwNumberTreeNode
* SwNodeNum::Create() const
100 // --> OD 2008-02-19 #refactorlists#
101 // SwNodeNum * pResult = new SwNodeNum();
102 // pResult->SetNumRule(mpNumRule);
103 SwNodeNum
* pResult
= new SwNodeNum( GetNumRule() );
109 // --> OD 2008-02-19 #refactorlists#
110 void SwNodeNum::PreAdd()
112 ASSERT( GetTxtNode(),
113 "<SwNodeNum::PreAdd()> - no text node set at <SwNodeNum> instance" );
114 if ( !GetNumRule() && GetTxtNode() )
116 mpNumRule
= GetTxtNode()->GetNumRule();
118 ASSERT( GetNumRule(),
119 "<SwNodeNum::PreAdd()> - no list style set at <SwNodeNum> instance" );
120 if ( GetNumRule() && GetTxtNode() )
122 GetNumRule()->AddTxtNode( *(GetTxtNode()) );
128 GetTxtNode()->GetNodes().IsDocNodes() )
130 GetTxtNode()->getIDocumentListItems().addListItem( *this );
135 void SwNodeNum::PostRemove()
137 ASSERT( GetTxtNode(),
138 "<SwNodeNum::PostRemove()> - no text node set at <SwNodeNum> instance" );
139 ASSERT( GetNumRule(),
140 "<SwNodeNum::PostRemove()> - no list style set at <SwNodeNum> instance" );
144 GetTxtNode()->getIDocumentListItems().removeListItem( *this );
151 GetNumRule()->RemoveTxtNode( *(GetTxtNode()) );
158 bool SwNodeNum::IsNotifiable() const
163 aResult
= GetTxtNode()->IsNotifiable();
168 bool SwNodeNum::IsNotificationEnabled() const
173 aResult
= GetTxtNode()->IsNotificationEnabled();
178 bool SwNodeNum::IsContinuous() const
180 bool aResult
= false;
182 // --> OD 2006-04-21 #i64311#
185 aResult
= mpNumRule
->IsContinusNum();
187 else if ( GetParent() )
189 aResult
= GetParent()->IsContinuous();
193 ASSERT( false, "<SwNodeNum::IsContinuous()> - OD debug" );
200 bool SwNodeNum::IsCounted() const
202 bool aResult
= false;
206 // --> OD 2006-01-25 #i59559#
207 // <SwTxtNode::IsCounted()> determines, if a text node is counted for numbering
208 // const SwNumFmt * pNumFmt = GetNumFmt();
211 // sal_Int16 nType = pNumFmt->GetNumberingType();
212 // if ( nType != SVX_NUM_NUMBER_NONE)
213 // aResult = mpTxtNode->IsCounted();
215 aResult
= GetTxtNode()->IsCountedInList();
219 aResult
= SwNumberTreeNode::IsCounted();
224 // --> OD 2006-04-26 #i64010#
225 bool SwNodeNum::HasCountedChildren() const
227 bool bResult
= false;
229 tSwNumberTreeChildren::iterator aIt
;
231 for (aIt
= mChildren
.begin(); aIt
!= mChildren
.end(); aIt
++)
233 SwNodeNum
* pChild( dynamic_cast<SwNodeNum
*>(*aIt
) );
235 "<SwNodeNum::HasCountedChildren()> - unexcepted type of child -> please inform OD" );
237 ( pChild
->IsCountedForNumbering() ||
238 pChild
->HasCountedChildren() ) )
249 // --> OD 2006-04-26 #i64010#
250 bool SwNodeNum::IsCountedForNumbering() const
252 return IsCounted() &&
253 ( IsPhantom() || // phantoms
254 !GetTxtNode() || // root node
255 GetTxtNode()->HasNumber() || // text node
256 GetTxtNode()->HasBullet() ); // text node
261 void SwNodeNum::NotifyNode()
267 mpTxtNode
->NumRuleChgd();
271 bool SwNodeNum::LessThan(const SwNumberTreeNode
& rNode
) const
273 bool bResult
= false;
274 const SwNodeNum
& rTmpNode
= static_cast<const SwNodeNum
&>(rNode
);
276 if (mpTxtNode
== NULL
&& rTmpNode
.mpTxtNode
!= NULL
)
278 else if (mpTxtNode
!= NULL
&& rTmpNode
.mpTxtNode
!= NULL
)
280 // --> OD 2007-10-31 #i83479# - refactoring
281 // simplify comparison by comparing the indexes of the text nodes
282 // SwPosition aMyPos(*mpTxtNode);
283 // SwPosition aHisPos(*rTmpNode.mpTxtNode);
284 // bResult = (aMyPos < aHisPos) ? true : false;
285 bResult
= ( mpTxtNode
->GetIndex() < rTmpNode
.mpTxtNode
->GetIndex() ) ? true : false;
292 //void SwNodeNum::SetRestart(bool bRestart)
294 // // --> OD 2005-10-19 #126009#
295 // // - improvement: invalidation only, if <IsRestart()> state changes.
296 // const bool bInvalidate( mbRestart != bRestart );
298 // mbRestart = bRestart;
300 // // --> OD 2005-10-19 #126009#
301 // if ( bInvalidate )
304 // NotifyInvalidSiblings();
309 // --> OD 2008-02-25 #refactorlists#
310 bool SwNodeNum::IsRestart() const
312 bool bIsRestart
= false;
316 bIsRestart
= GetTxtNode()->IsListRestart();
323 //void SwNodeNum::SetStart(SwNumberTree::tSwNumTreeNumber nStart)
325 // // --> OD 2005-10-19 #126009#
326 // // - improvement: invalidation only, if <IsRestart()> state changes.
327 // const bool bInvalidate( mnStart != nStart );
331 // // --> OD 2005-10-19 #126009#
332 // if ( bInvalidate )
335 // NotifyInvalidSiblings();
339 bool SwNodeNum::IsCountPhantoms() const
343 // --> OD 2006-04-21 #i64311#
344 // phantoms aren't counted in consecutive numbering rules
346 bResult
= !mpNumRule
->IsContinusNum() &&
347 mpNumRule
->IsCountPhantoms();
351 "<SwNodeNum::IsCountPhantoms(): missing numbering rule - please inform OD" );
358 // --> OD 2008-02-25 #refactorlists#
359 SwNumberTree::tSwNumTreeNumber
SwNodeNum::GetStartValue() const
360 //SwNumberTree::tSwNumTreeNumber SwNodeNum::GetStart() const
362 SwNumberTree::tSwNumTreeNumber aResult
= 1;
364 if ( IsRestart() && GetTxtNode() )
366 aResult
= GetTxtNode()->GetActualListStartValue();
370 SwNumRule
* pRule
= GetNumRule();
374 int nLevel
= GetParent() ? GetLevelInListTree() : 0;
376 if (nLevel
>= 0 && nLevel
< MAXLEVEL
)
378 const SwNumFmt
* pFmt
= pRule
->GetNumFmt( static_cast<USHORT
>(nLevel
));
381 aResult
= pFmt
->GetStart();
389 //String SwNodeNum::ToString() const
391 // String aResult("[ ", RTL_TEXTENCODING_ASCII_US);
395 // char aBuffer[256];
397 // sprintf(aBuffer, "%p ", GetTxtNode());
399 // aResult += String(aBuffer, RTL_TEXTENCODING_ASCII_US);
400 // aResult += String::CreateFromInt32(GetPosition().nNode.GetIndex());
403 // aResult += String("*", RTL_TEXTENCODING_ASCII_US);
405 // aResult += String(" ", RTL_TEXTENCODING_ASCII_US);
407 // unsigned int nLvl = GetLevel();
408 // aResult += String::CreateFromInt32(nLvl);
410 // aResult += String(": ", RTL_TEXTENCODING_ASCII_US);
412 // tNumberVector aNumVector;
414 // _GetNumberVector(aNumVector, false);
416 // for (unsigned int n = 0; n < aNumVector.size(); n++)
419 // aResult += String(", ", RTL_TEXTENCODING_ASCII_US);
421 // aResult += String::CreateFromInt32(aNumVector[n]);
425 //// aResult += String(" counted", RTL_TEXTENCODING_ASCII_US);
426 // aResult += String(" C", RTL_TEXTENCODING_ASCII_US);
430 //// aResult += String(" restart(", RTL_TEXTENCODING_ASCII_US);
431 // aResult += String(" R(", RTL_TEXTENCODING_ASCII_US);
432 // aResult += String::CreateFromInt32(GetStart());
433 // aResult += String(")", RTL_TEXTENCODING_ASCII_US);
437 //// aResult += String(" invalid", RTL_TEXTENCODING_ASCII_US);
438 // aResult += String(" I", RTL_TEXTENCODING_ASCII_US);
440 // aResult += String(" ]", RTL_TEXTENCODING_ASCII_US);
445 // --> OD 2006-03-07 #131436#
446 void SwNodeNum::HandleNumberTreeRootNodeDelete( SwNodeNum
& rNodeNum
)
448 SwNodeNum
* pRootNode
= rNodeNum
.GetParent()
449 ? dynamic_cast<SwNodeNum
*>(rNodeNum
.GetRoot())
453 // no root node -> nothing do.
457 // unregister all number tree node entries, which correspond to a text node,
458 // about the deletion of the number tree root node.
459 _UnregisterMeAndChildrenDueToRootDelete( *pRootNode
);
462 void SwNodeNum::_UnregisterMeAndChildrenDueToRootDelete( SwNodeNum
& rNodeNum
)
464 const bool bIsPhantom( rNodeNum
.IsPhantom() );
465 tSwNumberTreeChildren::size_type
nAllowedChildCount( 0 );
468 rNodeNum
.GetChildCount() > nAllowedChildCount
)
470 SwNodeNum
* pChildNode( dynamic_cast<SwNodeNum
*>((*rNodeNum
.mChildren
.begin())) );
474 "<SwNodeNum::_UnregisterMeAndChildrenDueToRootDelete(..)> - unknown number tree node child" );
475 ++nAllowedChildCount
;
479 // Unregistering the last child of a phantom will destroy the phantom.
480 // Thus <rNodeNum> will be destroyed and access on <rNodeNum> has to
482 if ( bIsPhantom
&& rNodeNum
.GetChildCount() == 1 )
487 _UnregisterMeAndChildrenDueToRootDelete( *pChildNode
);
492 SwTxtNode
* pTxtNode( rNodeNum
.GetTxtNode() );
495 // --> OD 2008-03-13 #refactorlists#
496 pTxtNode
->RemoveFromList();
502 // --> OD 2007-09-06 #i81002#
503 const SwNodeNum
* SwNodeNum::GetPrecedingNodeNumOf( const SwTxtNode
& rTxtNode
) const
505 const SwNodeNum
* pPrecedingNodeNum( 0 );
507 // --> OD 2007-10-31 #i83479#
508 // SwNodeNum aNodeNumForTxtNode;
509 // aNodeNumForTxtNode.SetTxtNode( const_cast<SwTxtNode*>(&rTxtNode) );
510 SwNodeNum
aNodeNumForTxtNode( const_cast<SwTxtNode
*>(&rTxtNode
) );
513 pPrecedingNodeNum
= dynamic_cast<const SwNodeNum
*>(
515 ? GetRoot()->GetPrecedingNodeOf( aNodeNumForTxtNode
)
516 : GetPrecedingNodeOf( aNodeNumForTxtNode
) );
518 return pPrecedingNodeNum
;