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# 42 SwNodeNum::SwNodeNum( SwTxtNode* pTxtNode ) 43 : SwNumberTreeNode(), 44 mpTxtNode( pTxtNode ), 45 mpNumRule( 0 ) 46 { 47 } 48 49 SwNodeNum::SwNodeNum( SwNumRule* pNumRule ) 50 : SwNumberTreeNode(), 51 mpTxtNode( 0 ), 52 mpNumRule( pNumRule ) 53 { 54 } 55 // <-- 56 57 SwNodeNum::~SwNodeNum() 58 { 59 } 60 61 SwTxtNode * SwNodeNum::GetTxtNode() const 62 { 63 return mpTxtNode; 64 } 65 66 SwNumRule * SwNodeNum::GetNumRule() const 67 { 68 return mpNumRule; 69 } 70 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 88 SwPosition SwNodeNum::GetPosition() const 89 { 90 ASSERT( GetTxtNode(), 91 "<SwNodeNum::GetPosition()> - no text node set at <SwNodeNum> instance" ); 92 return SwPosition(*mpTxtNode); 93 } 94 95 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# 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 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 155 bool SwNodeNum::IsNotifiable() const 156 { 157 bool aResult = true; 158 159 if ( GetTxtNode() ) 160 aResult = GetTxtNode()->IsNotifiable(); 161 162 return aResult; 163 } 164 165 bool SwNodeNum::IsNotificationEnabled() const 166 { 167 bool aResult = true; 168 169 if ( GetTxtNode() ) 170 aResult = GetTxtNode()->IsNotificationEnabled(); 171 172 return aResult; 173 } 174 175 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 197 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# 222 bool SwNodeNum::HasCountedChildren() const 223 { 224 bool bResult = false; 225 226 tSwNumberTreeChildren::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# 247 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 258 void SwNodeNum::NotifyNode() 259 { 260 ValidateMe(); 261 262 if (mpTxtNode) 263 { 264 mpTxtNode->NumRuleChgd(); 265 } 266 } 267 268 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# 307 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 336 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# 356 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# 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 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# 513 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