1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26
27 #include <editeng/svxenum.hxx>
28 #include <numrule.hxx>
29 #include <SwNodeNum.hxx>
30 #include <ndtxt.hxx>
31 #include <pam.hxx>
32 #include <stdio.h>
33 // --> OD 2007-10-31 #i83479#
34 #include <IDocumentListItems.hxx>
35 // <--
36 // --> OD 2010-01-13 #b6912256#
37 //#include <svtools/svstdarr.hxx>
38 #include <doc.hxx>
39 // <--
40
41 // --> OD 2008-02-19 #refactorlists#
SwNodeNum(SwTxtNode * pTxtNode)42 SwNodeNum::SwNodeNum( SwTxtNode* pTxtNode )
43 : SwNumberTreeNode(),
44 mpTxtNode( pTxtNode ),
45 mpNumRule( 0 )
46 {
47 }
48
SwNodeNum(SwNumRule * pNumRule)49 SwNodeNum::SwNodeNum( SwNumRule* pNumRule )
50 : SwNumberTreeNode(),
51 mpTxtNode( 0 ),
52 mpNumRule( pNumRule )
53 {
54 }
55 // <--
56
~SwNodeNum()57 SwNodeNum::~SwNodeNum()
58 {
59 }
60
GetTxtNode() const61 SwTxtNode * SwNodeNum::GetTxtNode() const
62 {
63 return mpTxtNode;
64 }
65
GetNumRule() const66 SwNumRule * SwNodeNum::GetNumRule() const
67 {
68 return mpNumRule;
69 }
70
ChangeNumRule(SwNumRule & rNumRule)71 void SwNodeNum::ChangeNumRule( SwNumRule& rNumRule )
72 {
73 ASSERT( GetNumRule() && GetTxtNode(),
74 "<SwNodeNum::ChangeNumRule(..)> - missing list style and/or text node. Serious defect -> please informm OD." );
75 if ( GetNumRule() && GetTxtNode() )
76 {
77 GetNumRule()->RemoveTxtNode( *(GetTxtNode()) );
78 }
79
80 mpNumRule = &rNumRule;
81
82 if ( GetNumRule() && GetTxtNode() )
83 {
84 GetNumRule()->AddTxtNode( *(GetTxtNode()) );
85 }
86 }
87
GetPosition() const88 SwPosition SwNodeNum::GetPosition() const
89 {
90 ASSERT( GetTxtNode(),
91 "<SwNodeNum::GetPosition()> - no text node set at <SwNodeNum> instance" );
92 return SwPosition(*mpTxtNode);
93 }
94
Create() const95 SwNumberTreeNode * SwNodeNum::Create() const
96 {
97 // --> OD 2008-02-19 #refactorlists#
98 // SwNodeNum * pResult = new SwNodeNum();
99 // pResult->SetNumRule(mpNumRule);
100 SwNodeNum * pResult = new SwNodeNum( GetNumRule() );
101 // <--
102
103 return pResult;
104 }
105
106 // --> OD 2008-02-19 #refactorlists#
PreAdd()107 void SwNodeNum::PreAdd()
108 {
109 ASSERT( GetTxtNode(),
110 "<SwNodeNum::PreAdd()> - no text node set at <SwNodeNum> instance" );
111 if ( !GetNumRule() && GetTxtNode() )
112 {
113 mpNumRule = GetTxtNode()->GetNumRule();
114 }
115 ASSERT( GetNumRule(),
116 "<SwNodeNum::PreAdd()> - no list style set at <SwNodeNum> instance" );
117 if ( GetNumRule() && GetTxtNode() )
118 {
119 GetNumRule()->AddTxtNode( *(GetTxtNode()) );
120 }
121
122
123 {
124 if ( GetTxtNode() &&
125 GetTxtNode()->GetNodes().IsDocNodes() )
126 {
127 GetTxtNode()->getIDocumentListItems().addListItem( *this );
128 }
129 }
130 }
131
PostRemove()132 void SwNodeNum::PostRemove()
133 {
134 ASSERT( GetTxtNode(),
135 "<SwNodeNum::PostRemove()> - no text node set at <SwNodeNum> instance" );
136 ASSERT( GetNumRule(),
137 "<SwNodeNum::PostRemove()> - no list style set at <SwNodeNum> instance" );
138
139 if ( GetTxtNode() )
140 {
141 GetTxtNode()->getIDocumentListItems().removeListItem( *this );
142 }
143
144 if ( GetNumRule() )
145 {
146 if ( GetTxtNode() )
147 {
148 GetNumRule()->RemoveTxtNode( *(GetTxtNode()) );
149 }
150 mpNumRule = 0;
151 }
152 }
153 // <--
154
IsNotifiable() const155 bool SwNodeNum::IsNotifiable() const
156 {
157 bool aResult = true;
158
159 if ( GetTxtNode() )
160 aResult = GetTxtNode()->IsNotifiable();
161
162 return aResult;
163 }
164
IsNotificationEnabled() const165 bool SwNodeNum::IsNotificationEnabled() const
166 {
167 bool aResult = true;
168
169 if ( GetTxtNode() )
170 aResult = GetTxtNode()->IsNotificationEnabled();
171
172 return aResult;
173 }
174
IsContinuous() const175 bool SwNodeNum::IsContinuous() const
176 {
177 bool aResult = false;
178
179 // --> OD 2006-04-21 #i64311#
180 if ( GetNumRule() )
181 {
182 aResult = mpNumRule->IsContinusNum();
183 }
184 else if ( GetParent() )
185 {
186 aResult = GetParent()->IsContinuous();
187 }
188 else
189 {
190 ASSERT( false, "<SwNodeNum::IsContinuous()> - OD debug" );
191 }
192 // <--
193
194 return aResult;
195 }
196
IsCounted() const197 bool SwNodeNum::IsCounted() const
198 {
199 bool aResult = false;
200
201 if ( GetTxtNode() )
202 {
203 // --> OD 2006-01-25 #i59559#
204 // <SwTxtNode::IsCounted()> determines, if a text node is counted for numbering
205 // const SwNumFmt * pNumFmt = GetNumFmt();
206 // if (pNumFmt)
207 // {
208 // sal_Int16 nType = pNumFmt->GetNumberingType();
209 // if ( nType != SVX_NUM_NUMBER_NONE)
210 // aResult = mpTxtNode->IsCounted();
211 // }
212 aResult = GetTxtNode()->IsCountedInList();
213 // <--
214 }
215 else
216 aResult = SwNumberTreeNode::IsCounted();
217
218 return aResult;
219 }
220
221 // --> OD 2006-04-26 #i64010#
HasCountedChildren() const222 bool SwNodeNum::HasCountedChildren() const
223 {
224 bool bResult = false;
225
226 tSwNumberTreeChildren::const_iterator aIt;
227
228 for (aIt = mChildren.begin(); aIt != mChildren.end(); aIt++)
229 {
230 SwNodeNum* pChild( dynamic_cast<SwNodeNum*>(*aIt) );
231 ASSERT( pChild,
232 "<SwNodeNum::HasCountedChildren()> - unexcepted type of child -> please inform OD" );
233 if ( pChild &&
234 ( pChild->IsCountedForNumbering() ||
235 pChild->HasCountedChildren() ) )
236 {
237 bResult = true;
238
239 break;
240 }
241 }
242
243 return bResult;
244 }
245 // <--
246 // --> OD 2006-04-26 #i64010#
IsCountedForNumbering() const247 bool SwNodeNum::IsCountedForNumbering() const
248 {
249 return IsCounted() &&
250 ( IsPhantom() || // phantoms
251 !GetTxtNode() || // root node
252 GetTxtNode()->HasNumber() || // text node
253 GetTxtNode()->HasBullet() ); // text node
254 }
255 // <--
256
257
NotifyNode()258 void SwNodeNum::NotifyNode()
259 {
260 ValidateMe();
261
262 if (mpTxtNode)
263 {
264 mpTxtNode->NumRuleChgd();
265 }
266 }
267
LessThan(const SwNumberTreeNode & rNode) const268 bool SwNodeNum::LessThan(const SwNumberTreeNode & rNode) const
269 {
270 bool bResult = false;
271 const SwNodeNum & rTmpNode = static_cast<const SwNodeNum &>(rNode);
272
273 if (mpTxtNode == NULL && rTmpNode.mpTxtNode != NULL)
274 bResult = true;
275 else if (mpTxtNode != NULL && rTmpNode.mpTxtNode != NULL)
276 {
277 // --> OD 2007-10-31 #i83479# - refactoring
278 // simplify comparison by comparing the indexes of the text nodes
279 // SwPosition aMyPos(*mpTxtNode);
280 // SwPosition aHisPos(*rTmpNode.mpTxtNode);
281 // bResult = (aMyPos < aHisPos) ? true : false;
282 bResult = ( mpTxtNode->GetIndex() < rTmpNode.mpTxtNode->GetIndex() ) ? true : false;
283 // <--
284 }
285
286 return bResult;
287 }
288
289 //void SwNodeNum::SetRestart(bool bRestart)
290 //{
291 // // --> OD 2005-10-19 #126009#
292 // // - improvement: invalidation only, if <IsRestart()> state changes.
293 // const bool bInvalidate( mbRestart != bRestart );
294 // // <--
295 // mbRestart = bRestart;
296
297 // // --> OD 2005-10-19 #126009#
298 // if ( bInvalidate )
299 // {
300 // InvalidateMe();
301 // NotifyInvalidSiblings();
302 // }
303 // // <--
304 //}
305
306 // --> OD 2008-02-25 #refactorlists#
IsRestart() const307 bool SwNodeNum::IsRestart() const
308 {
309 bool bIsRestart = false;
310
311 if ( GetTxtNode() )
312 {
313 bIsRestart = GetTxtNode()->IsListRestart();
314 }
315
316 return bIsRestart;
317 }
318 // <--
319
320 //void SwNodeNum::SetStart(SwNumberTree::tSwNumTreeNumber nStart)
321 //{
322 // // --> OD 2005-10-19 #126009#
323 // // - improvement: invalidation only, if <IsRestart()> state changes.
324 // const bool bInvalidate( mnStart != nStart );
325 // // <--
326 // mnStart = nStart;
327
328 // // --> OD 2005-10-19 #126009#
329 // if ( bInvalidate )
330 // {
331 // InvalidateMe();
332 // NotifyInvalidSiblings();
333 // }
334 //}
335
IsCountPhantoms() const336 bool SwNodeNum::IsCountPhantoms() const
337 {
338 bool bResult = true;
339
340 // --> OD 2006-04-21 #i64311#
341 // phantoms aren't counted in consecutive numbering rules
342 if ( mpNumRule )
343 bResult = !mpNumRule->IsContinusNum() &&
344 mpNumRule->IsCountPhantoms();
345 else
346 {
347 ASSERT( false,
348 "<SwNodeNum::IsCountPhantoms(): missing numbering rule - please inform OD" );
349 }
350 // <--
351
352 return bResult;
353 }
354
355 // --> OD 2008-02-25 #refactorlists#
GetStartValue() const356 SwNumberTree::tSwNumTreeNumber SwNodeNum::GetStartValue() const
357 //SwNumberTree::tSwNumTreeNumber SwNodeNum::GetStart() const
358 {
359 SwNumberTree::tSwNumTreeNumber aResult = 1;
360
361 if ( IsRestart() && GetTxtNode() )
362 {
363 aResult = GetTxtNode()->GetActualListStartValue();
364 }
365 else
366 {
367 SwNumRule * pRule = GetNumRule();
368
369 if (pRule)
370 {
371 int nLevel = GetParent() ? GetLevelInListTree() : 0;
372
373 if (nLevel >= 0 && nLevel < MAXLEVEL)
374 {
375 const SwNumFmt * pFmt = pRule->GetNumFmt( static_cast<sal_uInt16>(nLevel));
376
377 if (pFmt)
378 aResult = pFmt->GetStart();
379 }
380 }
381 }
382
383 return aResult;
384 }
385
386 //String SwNodeNum::ToString() const
387 //{
388 // String aResult("[ ", RTL_TEXTENCODING_ASCII_US);
389
390 // if (GetTxtNode())
391 // {
392 // char aBuffer[256];
393
394 // sprintf(aBuffer, "%p ", GetTxtNode());
395
396 // aResult += String(aBuffer, RTL_TEXTENCODING_ASCII_US);
397 // aResult += String::CreateFromInt32(GetPosition().nNode.GetIndex());
398 // }
399 // else
400 // aResult += String("*", RTL_TEXTENCODING_ASCII_US);
401
402 // aResult += String(" ", RTL_TEXTENCODING_ASCII_US);
403
404 // unsigned int nLvl = GetLevel();
405 // aResult += String::CreateFromInt32(nLvl);
406
407 // aResult += String(": ", RTL_TEXTENCODING_ASCII_US);
408
409 // tNumberVector aNumVector;
410
411 // _GetNumberVector(aNumVector, false);
412
413 // for (unsigned int n = 0; n < aNumVector.size(); n++)
414 // {
415 // if (n > 0)
416 // aResult += String(", ", RTL_TEXTENCODING_ASCII_US);
417
418 // aResult += String::CreateFromInt32(aNumVector[n]);
419 // }
420
421 // if (IsCounted())
422 //// aResult += String(" counted", RTL_TEXTENCODING_ASCII_US);
423 // aResult += String(" C", RTL_TEXTENCODING_ASCII_US);
424
425 // if (IsRestart())
426 // {
427 //// aResult += String(" restart(", RTL_TEXTENCODING_ASCII_US);
428 // aResult += String(" R(", RTL_TEXTENCODING_ASCII_US);
429 // aResult += String::CreateFromInt32(GetStart());
430 // aResult += String(")", RTL_TEXTENCODING_ASCII_US);
431 // }
432
433 // if (! IsValid())
434 //// aResult += String(" invalid", RTL_TEXTENCODING_ASCII_US);
435 // aResult += String(" I", RTL_TEXTENCODING_ASCII_US);
436
437 // aResult += String(" ]", RTL_TEXTENCODING_ASCII_US);
438
439 // return aResult;
440 //}
441
442 // --> OD 2006-03-07 #131436#
HandleNumberTreeRootNodeDelete(SwNodeNum & rNodeNum)443 void SwNodeNum::HandleNumberTreeRootNodeDelete( SwNodeNum& rNodeNum )
444 {
445 SwNodeNum* pRootNode = rNodeNum.GetParent()
446 ? dynamic_cast<SwNodeNum*>(rNodeNum.GetRoot())
447 : &rNodeNum;
448 if ( !pRootNode )
449 {
450 // no root node -> nothing do.
451 return;
452 }
453
454 // unregister all number tree node entries, which correspond to a text node,
455 // about the deletion of the number tree root node.
456 _UnregisterMeAndChildrenDueToRootDelete( *pRootNode );
457 }
458
_UnregisterMeAndChildrenDueToRootDelete(SwNodeNum & rNodeNum)459 void SwNodeNum::_UnregisterMeAndChildrenDueToRootDelete( SwNodeNum& rNodeNum )
460 {
461 const bool bIsPhantom( rNodeNum.IsPhantom() );
462 tSwNumberTreeChildren::size_type nAllowedChildCount( 0 );
463 bool bDone( false );
464 while ( !bDone &&
465 rNodeNum.GetChildCount() > nAllowedChildCount )
466 {
467 SwNodeNum* pChildNode( dynamic_cast<SwNodeNum*>((*rNodeNum.mChildren.begin())) );
468 if ( !pChildNode )
469 {
470 ASSERT( false,
471 "<SwNodeNum::_UnregisterMeAndChildrenDueToRootDelete(..)> - unknown number tree node child" );
472 ++nAllowedChildCount;
473 continue;
474 }
475
476 // Unregistering the last child of a phantom will destroy the phantom.
477 // Thus <rNodeNum> will be destroyed and access on <rNodeNum> has to
478 // be suppressed.
479 if ( bIsPhantom && rNodeNum.GetChildCount() == 1 )
480 {
481 bDone = true;
482 }
483
484 _UnregisterMeAndChildrenDueToRootDelete( *pChildNode );
485 }
486
487 if ( !bIsPhantom )
488 {
489 SwTxtNode* pTxtNode( rNodeNum.GetTxtNode() );
490 if ( pTxtNode )
491 {
492 pTxtNode->RemoveFromList();
493 // --> OD 2010-01-13 #b6912256#
494 // clear all list attributes and the list style
495 SvUShortsSort aResetAttrsArray;
496 aResetAttrsArray.Insert( RES_PARATR_LIST_ID );
497 aResetAttrsArray.Insert( RES_PARATR_LIST_LEVEL );
498 aResetAttrsArray.Insert( RES_PARATR_LIST_ISRESTART );
499 aResetAttrsArray.Insert( RES_PARATR_LIST_RESTARTVALUE );
500 aResetAttrsArray.Insert( RES_PARATR_LIST_ISCOUNTED );
501 aResetAttrsArray.Insert( RES_PARATR_NUMRULE );
502 SwPaM aPam( *pTxtNode );
503 pTxtNode->GetDoc()->ResetAttrs( aPam, sal_False,
504 &aResetAttrsArray,
505 false );
506 // <--
507 }
508 }
509 }
510 // <--
511
512 // --> OD 2007-09-06 #i81002#
GetPrecedingNodeNumOf(const SwTxtNode & rTxtNode) const513 const SwNodeNum* SwNodeNum::GetPrecedingNodeNumOf( const SwTxtNode& rTxtNode ) const
514 {
515 const SwNodeNum* pPrecedingNodeNum( 0 );
516
517 // --> OD 2007-10-31 #i83479#
518 // SwNodeNum aNodeNumForTxtNode;
519 // aNodeNumForTxtNode.SetTxtNode( const_cast<SwTxtNode*>(&rTxtNode) );
520 SwNodeNum aNodeNumForTxtNode( const_cast<SwTxtNode*>(&rTxtNode) );
521 // <--
522
523 pPrecedingNodeNum = dynamic_cast<const SwNodeNum*>(
524 GetRoot()
525 ? GetRoot()->GetPrecedingNodeOf( aNodeNumForTxtNode )
526 : GetPrecedingNodeOf( aNodeNumForTxtNode ) );
527
528 return pPrecedingNodeNum;
529 }
530 // <--
531