Update ooo320-m1
[ooovba.git] / sw / source / core / SwNumberTree / SwNodeNum.cxx
blob171c4de9208dd5964c1bf8728b3f99b78570967b
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 $
10 * $Revision: 1.16 $
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>
37 #include <ndtxt.hxx>
38 #include <pam.hxx>
39 #include <stdio.h>
40 // --> OD 2007-10-31 #i83479#
41 #include <IDocumentListItems.hxx>
42 // <--
44 // --> OD 2008-02-19 #refactorlists#
45 SwNodeNum::SwNodeNum( SwTxtNode* pTxtNode )
46 : SwNumberTreeNode(),
47 mpTxtNode( pTxtNode ),
48 mpNumRule( 0 )
52 SwNodeNum::SwNodeNum( SwNumRule* pNumRule )
53 : SwNumberTreeNode(),
54 mpTxtNode( 0 ),
55 mpNumRule( pNumRule )
58 // <--
60 SwNodeNum::~SwNodeNum()
64 SwTxtNode * SwNodeNum::GetTxtNode() const
66 return mpTxtNode;
69 SwNumRule * SwNodeNum::GetNumRule() const
71 return mpNumRule;
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
93 ASSERT( GetTxtNode(),
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() );
104 // <--
106 return pResult;
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()) );
127 if ( 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" );
142 if ( GetTxtNode() )
144 GetTxtNode()->getIDocumentListItems().removeListItem( *this );
147 if ( GetNumRule() )
149 if ( GetTxtNode() )
151 GetNumRule()->RemoveTxtNode( *(GetTxtNode()) );
153 mpNumRule = 0;
156 // <--
158 bool SwNodeNum::IsNotifiable() const
160 bool aResult = true;
162 if ( GetTxtNode() )
163 aResult = GetTxtNode()->IsNotifiable();
165 return aResult;
168 bool SwNodeNum::IsNotificationEnabled() const
170 bool aResult = true;
172 if ( GetTxtNode() )
173 aResult = GetTxtNode()->IsNotificationEnabled();
175 return aResult;
178 bool SwNodeNum::IsContinuous() const
180 bool aResult = false;
182 // --> OD 2006-04-21 #i64311#
183 if ( GetNumRule() )
185 aResult = mpNumRule->IsContinusNum();
187 else if ( GetParent() )
189 aResult = GetParent()->IsContinuous();
191 else
193 ASSERT( false, "<SwNodeNum::IsContinuous()> - OD debug" );
195 // <--
197 return aResult;
200 bool SwNodeNum::IsCounted() const
202 bool aResult = false;
204 if ( GetTxtNode() )
206 // --> OD 2006-01-25 #i59559#
207 // <SwTxtNode::IsCounted()> determines, if a text node is counted for numbering
208 // const SwNumFmt * pNumFmt = GetNumFmt();
209 // if (pNumFmt)
210 // {
211 // sal_Int16 nType = pNumFmt->GetNumberingType();
212 // if ( nType != SVX_NUM_NUMBER_NONE)
213 // aResult = mpTxtNode->IsCounted();
214 // }
215 aResult = GetTxtNode()->IsCountedInList();
216 // <--
218 else
219 aResult = SwNumberTreeNode::IsCounted();
221 return aResult;
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) );
234 ASSERT( pChild,
235 "<SwNodeNum::HasCountedChildren()> - unexcepted type of child -> please inform OD" );
236 if ( pChild &&
237 ( pChild->IsCountedForNumbering() ||
238 pChild->HasCountedChildren() ) )
240 bResult = true;
242 break;
246 return bResult;
248 // <--
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
258 // <--
261 void SwNodeNum::NotifyNode()
263 ValidateMe();
265 if (mpTxtNode)
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)
277 bResult = true;
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;
286 // <--
289 return bResult;
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 );
297 // // <--
298 // mbRestart = bRestart;
300 // // --> OD 2005-10-19 #126009#
301 // if ( bInvalidate )
302 // {
303 // InvalidateMe();
304 // NotifyInvalidSiblings();
305 // }
306 // // <--
309 // --> OD 2008-02-25 #refactorlists#
310 bool SwNodeNum::IsRestart() const
312 bool bIsRestart = false;
314 if ( GetTxtNode() )
316 bIsRestart = GetTxtNode()->IsListRestart();
319 return bIsRestart;
321 // <--
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 );
328 // // <--
329 // mnStart = nStart;
331 // // --> OD 2005-10-19 #126009#
332 // if ( bInvalidate )
333 // {
334 // InvalidateMe();
335 // NotifyInvalidSiblings();
336 // }
339 bool SwNodeNum::IsCountPhantoms() const
341 bool bResult = true;
343 // --> OD 2006-04-21 #i64311#
344 // phantoms aren't counted in consecutive numbering rules
345 if ( mpNumRule )
346 bResult = !mpNumRule->IsContinusNum() &&
347 mpNumRule->IsCountPhantoms();
348 else
350 ASSERT( false,
351 "<SwNodeNum::IsCountPhantoms(): missing numbering rule - please inform OD" );
353 // <--
355 return bResult;
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();
368 else
370 SwNumRule * pRule = GetNumRule();
372 if (pRule)
374 int nLevel = GetParent() ? GetLevelInListTree() : 0;
376 if (nLevel >= 0 && nLevel < MAXLEVEL)
378 const SwNumFmt * pFmt = pRule->GetNumFmt( static_cast<USHORT>(nLevel));
380 if (pFmt)
381 aResult = pFmt->GetStart();
386 return aResult;
389 //String SwNodeNum::ToString() const
391 // String aResult("[ ", RTL_TEXTENCODING_ASCII_US);
393 // if (GetTxtNode())
394 // {
395 // char aBuffer[256];
397 // sprintf(aBuffer, "%p ", GetTxtNode());
399 // aResult += String(aBuffer, RTL_TEXTENCODING_ASCII_US);
400 // aResult += String::CreateFromInt32(GetPosition().nNode.GetIndex());
401 // }
402 // else
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++)
417 // {
418 // if (n > 0)
419 // aResult += String(", ", RTL_TEXTENCODING_ASCII_US);
421 // aResult += String::CreateFromInt32(aNumVector[n]);
422 // }
424 // if (IsCounted())
425 //// aResult += String(" counted", RTL_TEXTENCODING_ASCII_US);
426 // aResult += String(" C", RTL_TEXTENCODING_ASCII_US);
428 // if (IsRestart())
429 // {
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);
434 // }
436 // if (! IsValid())
437 //// aResult += String(" invalid", RTL_TEXTENCODING_ASCII_US);
438 // aResult += String(" I", RTL_TEXTENCODING_ASCII_US);
440 // aResult += String(" ]", RTL_TEXTENCODING_ASCII_US);
442 // return aResult;
445 // --> OD 2006-03-07 #131436#
446 void SwNodeNum::HandleNumberTreeRootNodeDelete( SwNodeNum& rNodeNum )
448 SwNodeNum* pRootNode = rNodeNum.GetParent()
449 ? dynamic_cast<SwNodeNum*>(rNodeNum.GetRoot())
450 : &rNodeNum;
451 if ( !pRootNode )
453 // no root node -> nothing do.
454 return;
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 );
466 bool bDone( false );
467 while ( !bDone &&
468 rNodeNum.GetChildCount() > nAllowedChildCount )
470 SwNodeNum* pChildNode( dynamic_cast<SwNodeNum*>((*rNodeNum.mChildren.begin())) );
471 if ( !pChildNode )
473 ASSERT( false,
474 "<SwNodeNum::_UnregisterMeAndChildrenDueToRootDelete(..)> - unknown number tree node child" );
475 ++nAllowedChildCount;
476 continue;
479 // Unregistering the last child of a phantom will destroy the phantom.
480 // Thus <rNodeNum> will be destroyed and access on <rNodeNum> has to
481 // be suppressed.
482 if ( bIsPhantom && rNodeNum.GetChildCount() == 1 )
484 bDone = true;
487 _UnregisterMeAndChildrenDueToRootDelete( *pChildNode );
490 if ( !bIsPhantom )
492 SwTxtNode* pTxtNode( rNodeNum.GetTxtNode() );
493 if ( pTxtNode )
495 // --> OD 2008-03-13 #refactorlists#
496 pTxtNode->RemoveFromList();
500 // <--
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) );
511 // <--
513 pPrecedingNodeNum = dynamic_cast<const SwNodeNum*>(
514 GetRoot()
515 ? GetRoot()->GetPrecedingNodeOf( aNodeNumForTxtNode )
516 : GetPrecedingNodeOf( aNodeNumForTxtNode ) );
518 return pPrecedingNodeNum;
520 // <--