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 <hintids.hxx> 28 #include <editeng/frmdiritem.hxx> 29 #include <editeng/protitem.hxx> 30 #include <com/sun/star/i18n/CharacterIteratorMode.hdl> 31 #include <fmtcntnt.hxx> 32 #include <fmtanchr.hxx> 33 #include <frmfmt.hxx> 34 #include <txtftn.hxx> 35 #include <ftnfrm.hxx> 36 #include <doc.hxx> 37 #include <docary.hxx> 38 #include <node.hxx> 39 #include <ndindex.hxx> 40 #include <numrule.hxx> 41 #include <swtable.hxx> 42 #include <ndtxt.hxx> 43 #include <pam.hxx> 44 #include <swcache.hxx> 45 #include <section.hxx> 46 #include <cntfrm.hxx> 47 #include <flyfrm.hxx> 48 #include <txtfrm.hxx> 49 #include <tabfrm.hxx> // SwTabFrm 50 #include <viewsh.hxx> 51 #include <paratr.hxx> 52 #include <ftnidx.hxx> 53 #include <fmtftn.hxx> 54 #include <fmthdft.hxx> 55 #include <frmatr.hxx> 56 #include <fmtautofmt.hxx> 57 #include <frmtool.hxx> 58 #include <pagefrm.hxx> 59 #include <node2lay.hxx> 60 #include <pagedesc.hxx> 61 #include <fmtpdsc.hxx> 62 #include <breakit.hxx> 63 #include <crsskip.hxx> 64 #include <SwStyleNameMapper.hxx> 65 #include <scriptinfo.hxx> 66 #include <rootfrm.hxx> 67 #include <istyleaccess.hxx> 68 #include <IDocumentListItems.hxx> 69 #include <switerator.hxx> 70 #include "ndole.hxx" 71 72 using namespace ::com::sun::star::i18n; 73 74 TYPEINIT2( SwCntntNode, SwModify, SwIndexReg ) 75 76 /* 77 * Some local helper functions for the attribute set handle of a content node. 78 * Since the attribute set of a content node may not be modified directly, 79 * we always have to create a new SwAttrSet, do the modifications, and get 80 * a new handle from the style access 81 */ 82 83 namespace AttrSetHandleHelper 84 { 85 86 void GetNewAutoStyle( boost::shared_ptr<const SfxItemSet>& mrpAttrSet, 87 const SwCntntNode& rNode, 88 SwAttrSet& rNewAttrSet ) 89 { 90 const SwAttrSet* pAttrSet = static_cast<const SwAttrSet*>(mrpAttrSet.get()); 91 if( rNode.GetModifyAtAttr() ) 92 const_cast<SwAttrSet*>(pAttrSet)->SetModifyAtAttr( 0 ); 93 IStyleAccess& rSA = pAttrSet->GetPool()->GetDoc()->GetIStyleAccess(); 94 mrpAttrSet = rSA.getAutomaticStyle( rNewAttrSet, rNode.IsTxtNode() ? 95 IStyleAccess::AUTO_STYLE_PARA : 96 IStyleAccess::AUTO_STYLE_NOTXT ); 97 const bool bSetModifyAtAttr = ((SwAttrSet*)mrpAttrSet.get())->SetModifyAtAttr( &rNode ); 98 rNode.SetModifyAtAttr( bSetModifyAtAttr ); 99 } 100 101 102 void SetParent( boost::shared_ptr<const SfxItemSet>& mrpAttrSet, 103 const SwCntntNode& rNode, 104 const SwFmt* pParentFmt, 105 const SwFmt* pConditionalFmt ) 106 { 107 const SwAttrSet* pAttrSet = static_cast<const SwAttrSet*>(mrpAttrSet.get()); 108 ASSERT( pAttrSet, "no SwAttrSet" ) 109 ASSERT( pParentFmt || !pConditionalFmt, "ConditionalFmt without ParentFmt?" ) 110 111 const SwAttrSet* pParentSet = pParentFmt ? &pParentFmt->GetAttrSet() : 0; 112 113 if ( pParentSet != pAttrSet->GetParent() ) 114 { 115 SwAttrSet aNewSet( *pAttrSet ); 116 aNewSet.SetParent( pParentSet ); 117 aNewSet.ClearItem( RES_FRMATR_STYLE_NAME ); 118 aNewSet.ClearItem( RES_FRMATR_CONDITIONAL_STYLE_NAME ); 119 String sVal; 120 121 if ( pParentFmt ) 122 { 123 SwStyleNameMapper::FillProgName( pParentFmt->GetName(), sVal, nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL, sal_True ); 124 const SfxStringItem aAnyFmtColl( RES_FRMATR_STYLE_NAME, sVal ); 125 aNewSet.Put( aAnyFmtColl ); 126 127 if ( pConditionalFmt != pParentFmt ) 128 SwStyleNameMapper::FillProgName( pConditionalFmt->GetName(), sVal, nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL, sal_True ); 129 130 const SfxStringItem aFmtColl( RES_FRMATR_CONDITIONAL_STYLE_NAME, sVal ); 131 aNewSet.Put( aFmtColl ); 132 } 133 134 GetNewAutoStyle( mrpAttrSet, rNode, aNewSet ); 135 } 136 } 137 138 const SfxPoolItem* Put( boost::shared_ptr<const SfxItemSet>& mrpAttrSet, 139 const SwCntntNode& rNode, 140 const SfxPoolItem& rAttr ) 141 { 142 SwAttrSet aNewSet( (SwAttrSet&)*mrpAttrSet ); 143 const SfxPoolItem* pRet = aNewSet.Put( rAttr ); 144 if ( pRet ) 145 GetNewAutoStyle( mrpAttrSet, rNode, aNewSet ); 146 return pRet; 147 } 148 149 int Put( boost::shared_ptr<const SfxItemSet>& mrpAttrSet, const SwCntntNode& rNode, 150 const SfxItemSet& rSet ) 151 { 152 SwAttrSet aNewSet( (SwAttrSet&)*mrpAttrSet ); 153 154 // --> FME 2007-4-12 #i76273# Robust: Save the style name items: 155 SfxItemSet* pStyleNames = 0; 156 if ( SFX_ITEM_SET == rSet.GetItemState( RES_FRMATR_STYLE_NAME, sal_False ) ) 157 { 158 pStyleNames = new SfxItemSet( *aNewSet.GetPool(), RES_FRMATR_STYLE_NAME, RES_FRMATR_CONDITIONAL_STYLE_NAME ); 159 pStyleNames->Put( aNewSet ); 160 } 161 // <-- 162 163 const int nRet = aNewSet.Put( rSet ); 164 165 // --> FME 2007-4-12 #i76273# Robust: Save the style name items: 166 if ( pStyleNames ) 167 { 168 aNewSet.Put( *pStyleNames ); 169 delete pStyleNames; 170 } 171 // <-- 172 173 if ( nRet ) 174 GetNewAutoStyle( mrpAttrSet, rNode, aNewSet ); 175 176 return nRet; 177 } 178 179 int Put_BC( boost::shared_ptr<const SfxItemSet>& mrpAttrSet, 180 const SwCntntNode& rNode, const SfxPoolItem& rAttr, 181 SwAttrSet* pOld, SwAttrSet* pNew ) 182 { 183 SwAttrSet aNewSet( (SwAttrSet&)*mrpAttrSet ); 184 185 // for a correct broadcast, we need to do a SetModifyAtAttr with the items 186 // from aNewSet. The 'regular' SetModifyAtAttr is done in GetNewAutoStyle 187 if( rNode.GetModifyAtAttr() ) 188 aNewSet.SetModifyAtAttr( &rNode ); 189 190 const int nRet = aNewSet.Put_BC( rAttr, pOld, pNew ); 191 192 if ( nRet ) 193 GetNewAutoStyle( mrpAttrSet, rNode, aNewSet ); 194 195 return nRet; 196 } 197 198 int Put_BC( boost::shared_ptr<const SfxItemSet>& mrpAttrSet, 199 const SwCntntNode& rNode, const SfxItemSet& rSet, 200 SwAttrSet* pOld, SwAttrSet* pNew ) 201 { 202 SwAttrSet aNewSet( (SwAttrSet&)*mrpAttrSet ); 203 204 // --> FME 2007-4-12 #i76273# Robust: Save the style name items: 205 SfxItemSet* pStyleNames = 0; 206 if ( SFX_ITEM_SET == rSet.GetItemState( RES_FRMATR_STYLE_NAME, sal_False ) ) 207 { 208 pStyleNames = new SfxItemSet( *aNewSet.GetPool(), RES_FRMATR_STYLE_NAME, RES_FRMATR_CONDITIONAL_STYLE_NAME ); 209 pStyleNames->Put( aNewSet ); 210 } 211 // <-- 212 213 // for a correct broadcast, we need to do a SetModifyAtAttr with the items 214 // from aNewSet. The 'regular' SetModifyAtAttr is done in GetNewAutoStyle 215 if( rNode.GetModifyAtAttr() ) 216 aNewSet.SetModifyAtAttr( &rNode ); 217 218 const int nRet = aNewSet.Put_BC( rSet, pOld, pNew ); 219 220 // --> FME 2007-4-12 #i76273# Robust: Save the style name items: 221 if ( pStyleNames ) 222 { 223 aNewSet.Put( *pStyleNames ); 224 delete pStyleNames; 225 } 226 // <-- 227 228 if ( nRet ) 229 GetNewAutoStyle( mrpAttrSet, rNode, aNewSet ); 230 231 return nRet; 232 } 233 234 sal_uInt16 ClearItem_BC( boost::shared_ptr<const SfxItemSet>& mrpAttrSet, 235 const SwCntntNode& rNode, sal_uInt16 nWhich, 236 SwAttrSet* pOld, SwAttrSet* pNew ) 237 { 238 SwAttrSet aNewSet( (SwAttrSet&)*mrpAttrSet ); 239 if( rNode.GetModifyAtAttr() ) 240 aNewSet.SetModifyAtAttr( &rNode ); 241 const sal_uInt16 nRet = aNewSet.ClearItem_BC( nWhich, pOld, pNew ); 242 if ( nRet ) 243 GetNewAutoStyle( mrpAttrSet, rNode, aNewSet ); 244 return nRet; 245 } 246 247 sal_uInt16 ClearItem_BC( boost::shared_ptr<const SfxItemSet>& mrpAttrSet, 248 const SwCntntNode& rNode, 249 sal_uInt16 nWhich1, sal_uInt16 nWhich2, 250 SwAttrSet* pOld, SwAttrSet* pNew ) 251 { 252 SwAttrSet aNewSet( (SwAttrSet&)*mrpAttrSet ); 253 if( rNode.GetModifyAtAttr() ) 254 aNewSet.SetModifyAtAttr( &rNode ); 255 const sal_uInt16 nRet = aNewSet.ClearItem_BC( nWhich1, nWhich2, pOld, pNew ); 256 if ( nRet ) 257 GetNewAutoStyle( mrpAttrSet, rNode, aNewSet ); 258 return nRet; 259 } 260 261 } 262 263 /******************************************************************* 264 |* 265 |* SwNode::GetSectionLevel 266 |* 267 |* Beschreibung 268 |* Die Funktion liefert den Sectionlevel an der durch 269 |* aIndex bezeichneten Position. 270 |* 271 |* Die Logik ist wie folgt: ( S -> Start, E -> End, C -> CntntNode) 272 |* Level 0 E 273 |* 1 S E 274 |* 2 SC 275 |* 276 |* alle EndNodes der GrundSection haben den Level 0 277 |* alle StartNodes der GrundSection haben den Level 1 278 |* 279 |* Ersterstellung 280 |* VER0100 vb 901214 281 |* 282 |* Aenderung: JP 11.08.93 283 |* keine Rekursion mehr !! 284 |* 285 *******************************************************************/ 286 287 288 sal_uInt16 SwNode::GetSectionLevel() const 289 { 290 // EndNode einer Grund-Section ?? diese sind immer 0 !! 291 if( IsEndNode() && 0 == pStartOfSection->StartOfSectionIndex() ) 292 return 0; 293 294 sal_uInt16 nLevel; 295 const SwNode* pNode = IsStartNode() ? this : pStartOfSection; 296 for( nLevel = 1; 0 != pNode->StartOfSectionIndex(); ++nLevel ) 297 pNode = pNode->pStartOfSection; 298 return IsEndNode() ? nLevel-1 : nLevel; 299 } 300 301 /******************************************************************* 302 |* 303 |* SwNode::SwNode 304 |* 305 |* Beschreibung 306 |* Konstruktor; dieser fuegt einen Node in das Array rNodes 307 |* an der Position rWhere ein. Dieser bekommt als 308 |* theEndOfSection den EndOfSection-Index des Nodes 309 |* unmittelbar vor ihm. Falls er sich an der Position 0 310 |* innerhalb des variablen Arrays befindet, wird 311 |* theEndOfSection 0 (der neue selbst). 312 |* 313 |* Parameter 314 |* IN 315 |* rNodes bezeichnet das variable Array, in das der Node 316 |* eingefuegt werden soll 317 |* IN 318 |* rWhere bezeichnet die Position innerhalb dieses Arrays, 319 |* an der der Node eingefuegt werden soll 320 |* 321 |* Ersterstellung 322 |* VER0100 vb 901214 323 |* 324 |* Stand 325 |* VER0100 vb 901214 326 |* 327 *******************************************************************/ 328 329 #ifdef DBG_UTIL 330 long SwNode::nSerial = 0; 331 #endif 332 333 SwNode::SwNode( const SwNodeIndex &rWhere, const sal_uInt8 nNdType ) 334 : nNodeType( nNdType ), pStartOfSection( 0 ) 335 { 336 bSetNumLSpace = bIgnoreDontExpand = sal_False; 337 nAFmtNumLvl = 0; 338 339 SwNodes& rNodes = (SwNodes&)rWhere.GetNodes(); 340 SwNode* pInsNd = this; // der MAC kann this nicht einfuegen !! 341 if( rWhere.GetIndex() ) 342 { 343 SwNode* pNd = rNodes[ rWhere.GetIndex() -1 ]; 344 rNodes.InsertNode( pInsNd, rWhere ); 345 if( 0 == ( pStartOfSection = pNd->GetStartNode()) ) 346 { 347 pStartOfSection = pNd->pStartOfSection; 348 if( pNd->GetEndNode() ) // EndNode ? Section ueberspringen! 349 { 350 pNd = pStartOfSection; 351 pStartOfSection = pNd->pStartOfSection; 352 } 353 } 354 } 355 else 356 { 357 rNodes.InsertNode( pInsNd, rWhere ); 358 pStartOfSection = (SwStartNode*)this; 359 } 360 361 #ifdef DBG_UTIL 362 nMySerial = nSerial; 363 nSerial++; 364 #endif 365 } 366 367 SwNode::SwNode( SwNodes& rNodes, sal_uLong nPos, const sal_uInt8 nNdType ) 368 : nNodeType( nNdType ), pStartOfSection( 0 ) 369 { 370 bSetNumLSpace = bIgnoreDontExpand = sal_False; 371 nAFmtNumLvl = 0; 372 373 SwNode* pInsNd = this; // der MAC kann this nicht einfuegen !! 374 if( nPos ) 375 { 376 SwNode* pNd = rNodes[ nPos - 1 ]; 377 rNodes.InsertNode( pInsNd, nPos ); 378 if( 0 == ( pStartOfSection = pNd->GetStartNode()) ) 379 { 380 pStartOfSection = pNd->pStartOfSection; 381 if( pNd->GetEndNode() ) // EndNode ? Section ueberspringen! 382 { 383 pNd = pStartOfSection; 384 pStartOfSection = pNd->pStartOfSection; 385 } 386 } 387 } 388 else 389 { 390 rNodes.InsertNode( pInsNd, nPos ); 391 pStartOfSection = (SwStartNode*)this; 392 } 393 394 #ifdef DBG_UTIL 395 nMySerial = nSerial; 396 nSerial++; 397 #endif 398 } 399 400 SwNode::~SwNode() 401 { 402 } 403 404 // suche den TabellenNode, in dem dieser steht. Wenn in keiner 405 // Tabelle wird 0 returnt. 406 407 408 SwTableNode* SwNode::FindTableNode() 409 { 410 if( IsTableNode() ) 411 return GetTableNode(); 412 SwStartNode* pTmp = pStartOfSection; 413 while( !pTmp->IsTableNode() && pTmp->GetIndex() ) 414 #if defined( ALPHA ) && defined( UNX ) 415 pTmp = ((SwNode*)pTmp)->pStartOfSection; 416 #else 417 pTmp = pTmp->pStartOfSection; 418 #endif 419 return pTmp->GetTableNode(); 420 } 421 422 423 // liegt der Node im Sichtbarenbereich der Shell ? 424 sal_Bool SwNode::IsInVisibleArea( ViewShell* pSh ) const 425 { 426 sal_Bool bRet = sal_False; 427 const SwCntntNode* pNd; 428 429 if( ND_STARTNODE & nNodeType ) 430 { 431 SwNodeIndex aIdx( *this ); 432 pNd = GetNodes().GoNext( &aIdx ); 433 } 434 else if( ND_ENDNODE & nNodeType ) 435 { 436 SwNodeIndex aIdx( *EndOfSectionNode() ); 437 pNd = GetNodes().GoPrevious( &aIdx ); 438 } 439 else 440 pNd = GetCntntNode(); 441 442 if( !pSh ) 443 // dann die Shell vom Doc besorgen: 444 GetDoc()->GetEditShell( &pSh ); 445 446 if( pSh ) 447 { 448 const SwFrm* pFrm; 449 if( pNd && 0 != ( pFrm = pNd->getLayoutFrm( pSh->GetLayout(), 0, 0, sal_False ) ) ) 450 { 451 452 if ( pFrm->IsInTab() ) 453 pFrm = pFrm->FindTabFrm(); 454 455 if( !pFrm->IsValid() ) 456 do 457 { pFrm = pFrm->FindPrev(); 458 } while ( pFrm && !pFrm->IsValid() ); 459 460 if( !pFrm || pSh->VisArea().IsOver( pFrm->Frm() ) ) 461 bRet = sal_True; 462 } 463 } 464 465 return bRet; 466 } 467 468 sal_Bool SwNode::IsInProtectSect() const 469 { 470 const SwNode* pNd = ND_SECTIONNODE == nNodeType ? pStartOfSection : this; 471 const SwSectionNode* pSectNd = pNd->FindSectionNode(); 472 return pSectNd && pSectNd->GetSection().IsProtectFlag(); 473 } 474 475 // befindet sich der Node in irgendetwas geschuetzten ? 476 // (Bereich/Rahmen/Tabellenzellen/... incl. des Ankers bei 477 // Rahmen/Fussnoten/..) 478 sal_Bool SwNode::IsProtect() const 479 { 480 const SwNode* pNd = ND_SECTIONNODE == nNodeType ? pStartOfSection : this; 481 const SwStartNode* pSttNd = pNd->FindSectionNode(); 482 if( pSttNd && ((SwSectionNode*)pSttNd)->GetSection().IsProtectFlag() ) 483 return sal_True; 484 485 if( 0 != ( pSttNd = FindTableBoxStartNode() ) ) 486 { 487 SwCntntFrm* pCFrm; 488 if( IsCntntNode() && 0 != (pCFrm = ((SwCntntNode*)this)->getLayoutFrm( GetDoc()->GetCurrentLayout() ) )) 489 return pCFrm->IsProtected(); 490 491 const SwTableBox* pBox = pSttNd->FindTableNode()->GetTable(). 492 GetTblBox( pSttNd->GetIndex() ); 493 //Robust #149568 494 if( pBox && pBox->GetFrmFmt()->GetProtect().IsCntntProtected() ) 495 return sal_True; 496 } 497 498 SwFrmFmt* pFlyFmt = GetFlyFmt(); 499 if( pFlyFmt ) 500 { 501 if( pFlyFmt->GetProtect().IsCntntProtected() ) 502 return sal_True; 503 const SwFmtAnchor& rAnchor = pFlyFmt->GetAnchor(); 504 return rAnchor.GetCntntAnchor() 505 ? rAnchor.GetCntntAnchor()->nNode.GetNode().IsProtect() 506 : sal_False; 507 } 508 509 if( 0 != ( pSttNd = FindFootnoteStartNode() ) ) 510 { 511 const SwTxtFtn* pTFtn = GetDoc()->GetFtnIdxs().SeekEntry( 512 SwNodeIndex( *pSttNd ) ); 513 if( pTFtn ) 514 return pTFtn->GetTxtNode().IsProtect(); 515 } 516 517 return sal_False; 518 } 519 520 // suche den PageDesc, mit dem dieser Node formatiert ist. Wenn das 521 // Layout vorhanden ist wird ueber das gesucht, ansonsten gibt es nur 522 // die harte Tour ueber die Nodes nach vorne suchen!! 523 const SwPageDesc* SwNode::FindPageDesc( sal_Bool bCalcLay, 524 sal_uInt32* pPgDescNdIdx ) const 525 { 526 // OD 18.03.2003 #106329# 527 if ( !GetNodes().IsDocNodes() ) 528 { 529 return 0; 530 } 531 532 const SwPageDesc* pPgDesc = 0; 533 534 const SwCntntNode* pNode; 535 if( ND_STARTNODE & nNodeType ) 536 { 537 SwNodeIndex aIdx( *this ); 538 pNode = GetNodes().GoNext( &aIdx ); 539 } 540 else if( ND_ENDNODE & nNodeType ) 541 { 542 SwNodeIndex aIdx( *EndOfSectionNode() ); 543 pNode = GetNodes().GoPrevious( &aIdx ); 544 } 545 else 546 { 547 pNode = GetCntntNode(); 548 if( pNode ) 549 pPgDesc = ((SwFmtPageDesc&)pNode->GetAttr( RES_PAGEDESC )).GetPageDesc(); 550 } 551 552 // geht es uebers Layout? 553 if( !pPgDesc ) 554 { 555 const SwFrm* pFrm; 556 const SwPageFrm* pPage; 557 if( pNode && 0 != ( pFrm = pNode->getLayoutFrm( pNode->GetDoc()->GetCurrentLayout(), 0, 0, bCalcLay ) ) && 558 0 != ( pPage = pFrm->FindPageFrm() ) ) 559 { 560 pPgDesc = pPage->GetPageDesc(); 561 // OD 18.03.2003 #106329# 562 if ( pPgDescNdIdx ) 563 { 564 *pPgDescNdIdx = pNode->GetIndex(); 565 } 566 } 567 } 568 569 if( !pPgDesc ) 570 { 571 // dann also uebers Nodes-Array 572 const SwDoc* pDoc = GetDoc(); 573 const SwNode* pNd = this; 574 const SwStartNode* pSttNd; 575 if( pNd->GetIndex() < GetNodes().GetEndOfExtras().GetIndex() && 576 0 != ( pSttNd = pNd->FindFlyStartNode() ) ) 577 { 578 // dann erstmal den richtigen Anker finden 579 const SwFrmFmt* pFmt = 0; 580 const SwSpzFrmFmts& rFmts = *pDoc->GetSpzFrmFmts(); 581 sal_uInt16 n; 582 583 for( n = 0; n < rFmts.Count(); ++n ) 584 { 585 SwFrmFmt* pFrmFmt = rFmts[ n ]; 586 const SwFmtCntnt& rCntnt = pFrmFmt->GetCntnt(); 587 if( rCntnt.GetCntntIdx() && 588 &rCntnt.GetCntntIdx()->GetNode() == (SwNode*)pSttNd ) 589 { 590 pFmt = pFrmFmt; 591 break; 592 } 593 } 594 595 if( pFmt ) 596 { 597 const SwFmtAnchor* pAnchor = &pFmt->GetAnchor(); 598 if ((FLY_AT_PAGE != pAnchor->GetAnchorId()) && 599 pAnchor->GetCntntAnchor() ) 600 { 601 pNd = &pAnchor->GetCntntAnchor()->nNode.GetNode(); 602 const SwNode* pFlyNd = pNd->FindFlyStartNode(); 603 while( pFlyNd ) 604 { 605 // dann ueber den Anker nach oben "hangeln" 606 for( n = 0; n < rFmts.Count(); ++n ) 607 { 608 const SwFrmFmt* pFrmFmt = rFmts[ n ]; 609 const SwNodeIndex* pIdx = pFrmFmt->GetCntnt(). 610 GetCntntIdx(); 611 if( pIdx && pFlyNd == &pIdx->GetNode() ) 612 { 613 if( pFmt == pFrmFmt ) 614 { 615 pNd = pFlyNd; 616 pFlyNd = 0; 617 break; 618 } 619 pAnchor = &pFrmFmt->GetAnchor(); 620 if ((FLY_AT_PAGE == pAnchor->GetAnchorId()) || 621 !pAnchor->GetCntntAnchor() ) 622 { 623 pFlyNd = 0; 624 break; 625 } 626 627 pFlyNd = pAnchor->GetCntntAnchor()->nNode. 628 GetNode().FindFlyStartNode(); 629 break; 630 } 631 } 632 if( n >= rFmts.Count() ) 633 { 634 ASSERT( !this, "Fly-Section but no format found" ); 635 return NULL; 636 } 637 } 638 } 639 } 640 // in pNd sollte jetzt der richtige Anker Node stehen oder 641 // immer noch der this 642 } 643 644 if( pNd->GetIndex() < GetNodes().GetEndOfExtras().GetIndex() ) 645 { 646 if( pNd->GetIndex() > GetNodes().GetEndOfAutotext().GetIndex() ) 647 { 648 pPgDesc = &pDoc->GetPageDesc( 0 ); 649 pNd = 0; 650 } 651 else 652 { 653 // suche den Body Textnode 654 if( 0 != ( pSttNd = pNd->FindHeaderStartNode() ) || 655 0 != ( pSttNd = pNd->FindFooterStartNode() )) 656 { 657 // dann in den PageDescs diesen StartNode suchen 658 sal_uInt16 nId; 659 UseOnPage eAskUse; 660 if( SwHeaderStartNode == pSttNd->GetStartNodeType()) 661 { 662 nId = RES_HEADER; 663 eAskUse = nsUseOnPage::PD_HEADERSHARE; 664 } 665 else 666 { 667 nId = RES_FOOTER; 668 eAskUse = nsUseOnPage::PD_FOOTERSHARE; 669 } 670 671 for( sal_uInt16 n = pDoc->GetPageDescCnt(); n && !pPgDesc; ) 672 { 673 const SwPageDesc& rPgDsc = pDoc->GetPageDesc( --n ); 674 const SwFrmFmt* pFmt = &rPgDsc.GetMaster(); 675 int nStt = 0, nLast = 1; 676 if( !( eAskUse & rPgDsc.ReadUseOn() )) ++nLast; 677 678 for( ; nStt < nLast; ++nStt, pFmt = &rPgDsc.GetLeft() ) 679 { 680 const SwFmtHeader& rHdFt = (SwFmtHeader&) 681 pFmt->GetFmtAttr( nId ); 682 if( rHdFt.GetHeaderFmt() ) 683 { 684 const SwFmtCntnt& rCntnt = 685 rHdFt.GetHeaderFmt()->GetCntnt(); 686 if( rCntnt.GetCntntIdx() && 687 &rCntnt.GetCntntIdx()->GetNode() == 688 (SwNode*)pSttNd ) 689 { 690 pPgDesc = &rPgDsc; 691 break; 692 } 693 } 694 } 695 } 696 697 if( !pPgDesc ) 698 pPgDesc = &pDoc->GetPageDesc( 0 ); 699 pNd = 0; 700 } 701 else if( 0 != ( pSttNd = pNd->FindFootnoteStartNode() )) 702 { 703 // der Anker kann nur im Bodytext sein 704 const SwTxtFtn* pTxtFtn; 705 const SwFtnIdxs& rFtnArr = pDoc->GetFtnIdxs(); 706 for( sal_uInt16 n = 0; n < rFtnArr.Count(); ++n ) 707 if( 0 != ( pTxtFtn = rFtnArr[ n ])->GetStartNode() && 708 (SwNode*)pSttNd == 709 &pTxtFtn->GetStartNode()->GetNode() ) 710 { 711 pNd = &pTxtFtn->GetTxtNode(); 712 break; 713 } 714 } 715 else 716 { 717 // kann jetzt nur noch ein Seitengebundener Fly sein 718 // oder irgendetwas neueres. 719 // Hier koennen wir nur noch den Standard returnen 720 ASSERT( pNd->FindFlyStartNode(), 721 "wo befindet sich dieser Node?" ); 722 723 pPgDesc = &pDoc->GetPageDesc( 0 ); 724 pNd = 0; 725 } 726 } 727 } 728 729 if( pNd ) 730 { 731 SwFindNearestNode aInfo( *pNd ); 732 // dann ueber alle Nodes aller PageDesc 733 const SfxPoolItem* pItem; 734 sal_uInt32 i, nMaxItems = pDoc->GetAttrPool().GetItemCount2( RES_PAGEDESC ); 735 for( i = 0; i < nMaxItems; ++i ) 736 if( 0 != (pItem = pDoc->GetAttrPool().GetItem2( RES_PAGEDESC, i ) ) && 737 ((SwFmtPageDesc*)pItem)->GetDefinedIn() ) 738 { 739 const SwModify* pMod = ((SwFmtPageDesc*)pItem)->GetDefinedIn(); 740 if( pMod->ISA( SwCntntNode ) ) 741 aInfo.CheckNode( *(SwCntntNode*)pMod ); 742 else if( pMod->ISA( SwFmt )) 743 ((SwFmt*)pMod)->GetInfo( aInfo ); 744 } 745 746 if( 0 != ( pNd = aInfo.GetFoundNode() )) 747 { 748 if( pNd->IsCntntNode() ) 749 pPgDesc = ((SwFmtPageDesc&)pNd->GetCntntNode()-> 750 GetAttr( RES_PAGEDESC )).GetPageDesc(); 751 else if( pNd->IsTableNode() ) 752 pPgDesc = pNd->GetTableNode()->GetTable(). 753 GetFrmFmt()->GetPageDesc().GetPageDesc(); 754 else if( pNd->IsSectionNode() ) 755 pPgDesc = pNd->GetSectionNode()->GetSection(). 756 GetFmt()->GetPageDesc().GetPageDesc(); 757 // OD 18.03.2003 #106329# 758 if ( pPgDescNdIdx ) 759 { 760 *pPgDescNdIdx = pNd->GetIndex(); 761 } 762 } 763 if( !pPgDesc ) 764 pPgDesc = &pDoc->GetPageDesc( 0 ); 765 } 766 } 767 return pPgDesc; 768 } 769 770 771 // falls der Node in einem Fly steht, dann wird das entsprechende Format 772 // returnt 773 SwFrmFmt* SwNode::GetFlyFmt() const 774 { 775 SwFrmFmt* pRet = 0; 776 const SwNode* pSttNd = FindFlyStartNode(); 777 if( pSttNd ) 778 { 779 if( IsCntntNode() ) 780 { 781 SwCntntFrm* pFrm = SwIterator<SwCntntFrm,SwCntntNode>::FirstElement( *(SwCntntNode*)this ); 782 if( pFrm ) 783 pRet = pFrm->FindFlyFrm()->GetFmt(); 784 } 785 if( !pRet ) 786 { 787 // dann gibts noch harten steinigen Weg uebers Dokument: 788 const SwSpzFrmFmts& rFrmFmtTbl = *GetDoc()->GetSpzFrmFmts(); 789 for( sal_uInt16 n = 0; n < rFrmFmtTbl.Count(); ++n ) 790 { 791 SwFrmFmt* pFmt = rFrmFmtTbl[n]; 792 const SwFmtCntnt& rCntnt = pFmt->GetCntnt(); 793 if( rCntnt.GetCntntIdx() && 794 &rCntnt.GetCntntIdx()->GetNode() == pSttNd ) 795 { 796 pRet = pFmt; 797 break; 798 } 799 } 800 } 801 } 802 return pRet; 803 } 804 805 SwTableBox* SwNode::GetTblBox() const 806 { 807 SwTableBox* pBox = 0; 808 const SwNode* pSttNd = FindTableBoxStartNode(); 809 if( pSttNd ) 810 pBox = (SwTableBox*)pSttNd->FindTableNode()->GetTable().GetTblBox( 811 pSttNd->GetIndex() ); 812 return pBox; 813 } 814 815 SwStartNode* SwNode::FindSttNodeByType( SwStartNodeType eTyp ) 816 { 817 SwStartNode* pTmp = IsStartNode() ? (SwStartNode*)this : pStartOfSection; 818 819 while( eTyp != pTmp->GetStartNodeType() && pTmp->GetIndex() ) 820 #if defined( ALPHA ) && defined( UNX ) 821 pTmp = ((SwNode*)pTmp)->pStartOfSection; 822 #else 823 pTmp = pTmp->pStartOfSection; 824 #endif 825 return eTyp == pTmp->GetStartNodeType() ? pTmp : 0; 826 } 827 828 const SwTxtNode* SwNode::FindOutlineNodeOfLevel( sal_uInt8 nLvl ) const 829 { 830 const SwTxtNode* pRet = 0; 831 const SwOutlineNodes& rONds = GetNodes().GetOutLineNds(); 832 if( MAXLEVEL > nLvl && rONds.Count() ) 833 { 834 sal_uInt16 nPos; 835 SwNode* pNd = (SwNode*)this; 836 sal_Bool bCheckFirst = sal_False; 837 if( !rONds.Seek_Entry( pNd, &nPos )) 838 { 839 if( nPos ) 840 nPos = nPos-1; 841 else 842 bCheckFirst = sal_True; 843 } 844 845 if( bCheckFirst ) 846 { 847 // der 1.GliederungsNode liegt hinter dem Fragenden. Dann 848 // teste mal, ob dieser auf der gleichen Seite steht. Wenn 849 // nicht, ist das ein ungueltiger. Bug 61865 850 pRet = rONds[0]->GetTxtNode(); 851 852 const SwCntntNode* pCNd = GetCntntNode(); 853 854 Point aPt( 0, 0 ); 855 const SwFrm* pFrm = pRet->getLayoutFrm( pRet->GetDoc()->GetCurrentLayout(), &aPt, 0, sal_False ), 856 * pMyFrm = pCNd ? pCNd->getLayoutFrm( pCNd->GetDoc()->GetCurrentLayout(), &aPt, 0, sal_False ) : 0; 857 const SwPageFrm* pPgFrm = pFrm ? pFrm->FindPageFrm() : 0; 858 if( pPgFrm && pMyFrm && 859 pPgFrm->Frm().Top() > pMyFrm->Frm().Top() ) 860 { 861 // der Fragende liegt vor der Seite, also ist er ungueltig 862 pRet = 0; 863 } 864 } 865 else 866 { 867 // oder ans Feld und von dort holen !! 868 while( nPos && 869 nLvl < ( pRet = rONds[nPos]->GetTxtNode() ) 870 //->GetTxtColl()->GetOutlineLevel() )//#outline level,zhaojianwei 871 ->GetAttrOutlineLevel() - 1 ) //<-end,zhaojianwei 872 --nPos; 873 874 if( !nPos ) // bei 0 gesondert holen !! 875 pRet = rONds[0]->GetTxtNode(); 876 } 877 } 878 return pRet; 879 } 880 881 inline sal_Bool IsValidNextPrevNd( const SwNode& rNd ) 882 { 883 return ND_TABLENODE == rNd.GetNodeType() || 884 ( ND_CONTENTNODE & rNd.GetNodeType() ) || 885 ( ND_ENDNODE == rNd.GetNodeType() && rNd.StartOfSectionNode() && 886 ND_TABLENODE == rNd.StartOfSectionNode()->GetNodeType() ); 887 } 888 889 sal_uInt8 SwNode::HasPrevNextLayNode() const 890 { 891 // assumption: <this> node is a node inside the document nodes array section. 892 893 sal_uInt8 nRet = 0; 894 if( IsValidNextPrevNd( *this )) 895 { 896 SwNodeIndex aIdx( *this, -1 ); 897 // --> OD 2007-06-04 #i77805# 898 // skip section start and end nodes 899 while ( aIdx.GetNode().IsSectionNode() || 900 ( aIdx.GetNode().IsEndNode() && 901 aIdx.GetNode().StartOfSectionNode()->IsSectionNode() ) ) 902 { 903 --aIdx; 904 } 905 // <-- 906 if( IsValidNextPrevNd( aIdx.GetNode() )) 907 nRet |= ND_HAS_PREV_LAYNODE; 908 // --> OD 2007-06-04 #i77805# 909 // skip section start and end nodes 910 // aIdx += 2; 911 aIdx = SwNodeIndex( *this, +1 ); 912 while ( aIdx.GetNode().IsSectionNode() || 913 ( aIdx.GetNode().IsEndNode() && 914 aIdx.GetNode().StartOfSectionNode()->IsSectionNode() ) ) 915 { 916 ++aIdx; 917 } 918 // <-- 919 if( IsValidNextPrevNd( aIdx.GetNode() )) 920 nRet |= ND_HAS_NEXT_LAYNODE; 921 } 922 return nRet; 923 } 924 925 /******************************************************************* 926 |* 927 |* SwNode::StartOfSection 928 |* 929 |* Beschreibung 930 |* Die Funktion liefert die StartOfSection des Nodes. 931 |* 932 |* Parameter 933 |* IN 934 |* rNodes bezeichnet das variable Array, in dem sich der Node 935 |* befindet 936 |* Ersterstellung 937 |* VER0100 vb 901214 938 |* 939 |* Stand 940 |* VER0100 vb 901214 941 |* 942 *******************************************************************/ 943 944 945 SwStartNode::SwStartNode( const SwNodeIndex &rWhere, const sal_uInt8 nNdType, 946 SwStartNodeType eSttNd ) 947 : SwNode( rWhere, nNdType ), eSttNdTyp( eSttNd ) 948 { 949 // erstmal temporaer, bis der EndNode eingefuegt wird. 950 pEndOfSection = (SwEndNode*)this; 951 } 952 953 SwStartNode::SwStartNode( SwNodes& rNodes, sal_uLong nPos ) 954 : SwNode( rNodes, nPos, ND_STARTNODE ), eSttNdTyp( SwNormalStartNode ) 955 { 956 // erstmal temporaer, bis der EndNode eingefuegt wird. 957 pEndOfSection = (SwEndNode*)this; 958 } 959 960 961 void SwStartNode::CheckSectionCondColl() const 962 { 963 //FEATURE::CONDCOLL 964 SwNodeIndex aIdx( *this ); 965 sal_uLong nEndIdx = EndOfSectionIndex(); 966 const SwNodes& rNds = GetNodes(); 967 SwCntntNode* pCNd; 968 while( 0 != ( pCNd = rNds.GoNext( &aIdx )) && pCNd->GetIndex() < nEndIdx ) 969 pCNd->ChkCondColl(); 970 //FEATURE::CONDCOLL 971 } 972 973 /******************************************************************* 974 |* 975 |* SwEndNode::SwEndNode 976 |* 977 |* Beschreibung 978 |* Konstruktor; dieser fuegt einen Node in das Array rNodes 979 |* an der Position aWhere ein. Der 980 |* theStartOfSection-Pointer wird entsprechend gesetzt, 981 |* und der EndOfSection-Pointer des zugehoerigen 982 |* Startnodes -- durch rStartOfSection bezeichnet -- 983 |* wird auf diesen Node gesetzt. 984 |* 985 |* Parameter 986 |* IN 987 |* rNodes bezeichnet das variable Array, in das der Node 988 |* eingefuegt werden soll 989 |* IN 990 |* aWhere bezeichnet die Position innerhalb dieses Arrays, 991 |* an der der Node eingefuegt werden soll 992 |* !!!!!!!!!!!! 993 |* Es wird eine Kopie uebergeben! 994 |* 995 |* Ersterstellung 996 |* VER0100 vb 901214 997 |* 998 |* Stand 999 |* VER0100 vb 901214 1000 |* 1001 *******************************************************************/ 1002 1003 1004 SwEndNode::SwEndNode( const SwNodeIndex &rWhere, SwStartNode& rSttNd ) 1005 : SwNode( rWhere, ND_ENDNODE ) 1006 { 1007 pStartOfSection = &rSttNd; 1008 pStartOfSection->pEndOfSection = this; 1009 } 1010 1011 SwEndNode::SwEndNode( SwNodes& rNds, sal_uLong nPos, SwStartNode& rSttNd ) 1012 : SwNode( rNds, nPos, ND_ENDNODE ) 1013 { 1014 pStartOfSection = &rSttNd; 1015 pStartOfSection->pEndOfSection = this; 1016 } 1017 1018 1019 1020 // -------------------- 1021 // SwCntntNode 1022 // -------------------- 1023 1024 1025 SwCntntNode::SwCntntNode( const SwNodeIndex &rWhere, const sal_uInt8 nNdType, 1026 SwFmtColl *pColl ) 1027 : SwModify( pColl ), // CrsrsShell, FrameFmt, 1028 SwNode( rWhere, nNdType ), 1029 pCondColl( 0 ), 1030 mbSetModifyAtAttr( false ) 1031 #ifdef OLD_INDEX 1032 ,SwIndexReg(2) 1033 #endif 1034 { 1035 } 1036 1037 1038 SwCntntNode::~SwCntntNode() 1039 { 1040 // Die Basisklasse SwClient vom SwFrm nimmt sich aus 1041 // der Abhaengikeitsliste raus! 1042 // Daher muessen alle Frames in der Abhaengigkeitsliste geloescht werden. 1043 if( GetDepends() ) 1044 DelFrms(); 1045 1046 if( pCondColl ) 1047 delete pCondColl; 1048 1049 if ( mpAttrSet.get() && mbSetModifyAtAttr ) 1050 ((SwAttrSet*)mpAttrSet.get())->SetModifyAtAttr( 0 ); 1051 } 1052 1053 void SwCntntNode::Modify( const SfxPoolItem* pOldValue, const SfxPoolItem* pNewValue ) 1054 { 1055 sal_uInt16 nWhich = pOldValue ? pOldValue->Which() : 1056 pNewValue ? pNewValue->Which() : 0 ; 1057 1058 switch( nWhich ) 1059 { 1060 case RES_OBJECTDYING : 1061 { 1062 SwFmt * pFmt = (SwFmt *) ((SwPtrMsgPoolItem *)pNewValue)->pObject; 1063 1064 // nicht umhaengen wenn dieses das oberste Format ist !! 1065 if( GetRegisteredIn() == pFmt ) 1066 { 1067 if( pFmt->GetRegisteredIn() ) 1068 { 1069 // wenn Parent, dann im neuen Parent wieder anmelden 1070 ((SwModify*)pFmt->GetRegisteredIn())->Add( this ); 1071 if ( GetpSwAttrSet() ) 1072 AttrSetHandleHelper::SetParent( mpAttrSet, *this, GetFmtColl(), GetFmtColl() ); 1073 } 1074 else 1075 { 1076 // sonst auf jeden Fall beim sterbenden abmelden 1077 ((SwModify*)GetRegisteredIn())->Remove( this ); 1078 if ( GetpSwAttrSet() ) 1079 AttrSetHandleHelper::SetParent( mpAttrSet, *this, 0, 0 ); 1080 } 1081 } 1082 } 1083 break; 1084 1085 1086 case RES_FMT_CHG: 1087 // falls mein Format Parent umgesetzt wird, dann melde ich 1088 // meinen Attrset beim Neuen an. 1089 1090 // sein eigenes Modify ueberspringen !! 1091 if( GetpSwAttrSet() && 1092 ((SwFmtChg*)pNewValue)->pChangedFmt == GetRegisteredIn() ) 1093 { 1094 // den Set an den neuen Parent haengen 1095 AttrSetHandleHelper::SetParent( mpAttrSet, *this, GetFmtColl(), GetFmtColl() ); 1096 } 1097 break; 1098 //FEATURE::CONDCOLL 1099 case RES_CONDCOLL_CONDCHG: 1100 if( ((SwCondCollCondChg*)pNewValue)->pChangedFmt == GetRegisteredIn() && 1101 &GetNodes() == &GetDoc()->GetNodes() ) 1102 { 1103 ChkCondColl(); 1104 } 1105 return ; // nicht an die Basisklasse / Frames weitergeben 1106 //FEATURE::CONDCOLL 1107 1108 case RES_ATTRSET_CHG: 1109 if( GetNodes().IsDocNodes() && IsTxtNode() ) 1110 { 1111 if( SFX_ITEM_SET == ((SwAttrSetChg*)pOldValue)->GetChgSet()->GetItemState( 1112 RES_CHRATR_HIDDEN, sal_False ) ) 1113 { 1114 ((SwTxtNode*)this)->SetCalcHiddenCharFlags(); 1115 } 1116 } 1117 break; 1118 1119 case RES_UPDATE_ATTR: 1120 if( GetNodes().IsDocNodes() && IsTxtNode() ) 1121 { 1122 const sal_uInt16 nTmp = ((SwUpdateAttr*)pNewValue)->nWhichAttr; 1123 if ( RES_ATTRSET_CHG == nTmp ) 1124 { 1125 // anybody wants to do some optimization here? 1126 ((SwTxtNode*)this)->SetCalcHiddenCharFlags(); 1127 } 1128 } 1129 break; 1130 } 1131 1132 NotifyClients( pOldValue, pNewValue ); 1133 } 1134 1135 sal_Bool SwCntntNode::InvalidateNumRule() 1136 { 1137 SwNumRule* pRule = 0; 1138 const SfxPoolItem* pItem; 1139 if( GetNodes().IsDocNodes() && 1140 0 != ( pItem = GetNoCondAttr( RES_PARATR_NUMRULE, sal_True )) && 1141 ((SwNumRuleItem*)pItem)->GetValue().Len() && 1142 0 != (pRule = GetDoc()->FindNumRulePtr( 1143 ((SwNumRuleItem*)pItem)->GetValue() ) ) ) 1144 { 1145 pRule->SetInvalidRule( sal_True ); 1146 } 1147 return 0 != pRule; 1148 } 1149 1150 SwCntntFrm *SwCntntNode::getLayoutFrm( const SwRootFrm* _pRoot, 1151 const Point* pPoint, const SwPosition *pPos, const sal_Bool bCalcFrm ) const 1152 { 1153 return (SwCntntFrm*) ::GetFrmOfModify( _pRoot, *(SwModify*)this, FRM_CNTNT, 1154 pPoint, pPos, bCalcFrm ); 1155 } 1156 1157 SwRect SwCntntNode::FindLayoutRect( const sal_Bool bPrtArea, const Point* pPoint, 1158 const sal_Bool bCalcFrm ) const 1159 { 1160 SwRect aRet; 1161 SwCntntFrm* pFrm = (SwCntntFrm*)::GetFrmOfModify( 0, *(SwModify*)this, 1162 FRM_CNTNT, pPoint, 0, bCalcFrm ); 1163 if( pFrm ) 1164 aRet = bPrtArea ? pFrm->Prt() : pFrm->Frm(); 1165 return aRet; 1166 } 1167 1168 SwRect SwCntntNode::FindPageFrmRect( const sal_Bool bPrtArea, const Point* pPoint, 1169 const sal_Bool bCalcFrm ) const 1170 { 1171 SwRect aRet; 1172 SwFrm* pFrm = ::GetFrmOfModify( 0, *(SwModify*)this, 1173 FRM_CNTNT, pPoint, 0, bCalcFrm ); 1174 if( pFrm && 0 != ( pFrm = pFrm->FindPageFrm() )) 1175 aRet = bPrtArea ? pFrm->Prt() : pFrm->Frm(); 1176 return aRet; 1177 } 1178 1179 xub_StrLen SwCntntNode::Len() const { return 0; } 1180 1181 1182 1183 SwFmtColl *SwCntntNode::ChgFmtColl( SwFmtColl *pNewColl ) 1184 { 1185 ASSERT( pNewColl, "Collectionpointer ist 0." ); 1186 SwFmtColl *pOldColl = GetFmtColl(); 1187 1188 if( pNewColl != pOldColl ) 1189 { 1190 pNewColl->Add( this ); 1191 1192 // setze den Parent von unseren Auto-Attributen auf die neue 1193 // Collection: 1194 if( GetpSwAttrSet() ) 1195 AttrSetHandleHelper::SetParent( mpAttrSet, *this, pNewColl, pNewColl ); 1196 1197 //FEATURE::CONDCOLL 1198 // HACK: hier muss die entsprechend der neuen Vorlage die Bedingungen 1199 // neu ueberprueft werden! 1200 if( sal_True /*pNewColl */ ) 1201 { 1202 SetCondFmtColl( 0 ); 1203 } 1204 //FEATURE::CONDCOLL 1205 1206 if( !IsModifyLocked() ) 1207 { 1208 SwFmtChg aTmp1( pOldColl ); 1209 SwFmtChg aTmp2( pNewColl ); 1210 SwCntntNode::Modify( &aTmp1, &aTmp2 ); 1211 } 1212 } 1213 if ( IsInCache() ) 1214 { 1215 SwFrm::GetCache().Delete( this ); 1216 SetInCache( sal_False ); 1217 } 1218 return pOldColl; 1219 } 1220 1221 1222 sal_Bool SwCntntNode::GoNext(SwIndex * pIdx, sal_uInt16 nMode ) const 1223 { 1224 sal_Bool bRet = sal_True; 1225 if( pIdx->GetIndex() < Len() ) 1226 { 1227 if( !IsTxtNode() ) 1228 (*pIdx)++; 1229 else 1230 { 1231 const SwTxtNode& rTNd = *GetTxtNode(); 1232 xub_StrLen nPos = pIdx->GetIndex(); 1233 if( pBreakIt->GetBreakIter().is() ) 1234 { 1235 sal_Int32 nDone = 0; 1236 sal_uInt16 nItrMode = ( CRSR_SKIP_CELLS & nMode ) ? 1237 CharacterIteratorMode::SKIPCELL : 1238 CharacterIteratorMode::SKIPCONTROLCHARACTER; 1239 nPos = (xub_StrLen)pBreakIt->GetBreakIter()->nextCharacters( rTNd.GetTxt(), nPos, 1240 pBreakIt->GetLocale( rTNd.GetLang( nPos ) ), 1241 nItrMode, 1, nDone ); 1242 1243 // Check if nPos is inside hidden text range: 1244 if ( CRSR_SKIP_HIDDEN & nMode ) 1245 { 1246 xub_StrLen nHiddenStart; 1247 xub_StrLen nHiddenEnd; 1248 SwScriptInfo::GetBoundsOfHiddenRange( rTNd, nPos, nHiddenStart, nHiddenEnd ); 1249 if ( nHiddenStart != STRING_LEN && nHiddenStart != nPos ) 1250 nPos = nHiddenEnd; 1251 } 1252 1253 if( 1 == nDone ) 1254 *pIdx = nPos; 1255 else 1256 bRet = sal_False; 1257 } 1258 else if( nPos < rTNd.GetTxt().Len() ) 1259 (*pIdx)++; 1260 else 1261 bRet = sal_False; 1262 } 1263 } 1264 else 1265 bRet = sal_False; 1266 return bRet; 1267 } 1268 1269 1270 sal_Bool SwCntntNode::GoPrevious(SwIndex * pIdx, sal_uInt16 nMode ) const 1271 { 1272 sal_Bool bRet = sal_True; 1273 if( pIdx->GetIndex() > 0 ) 1274 { 1275 if( !IsTxtNode() ) 1276 (*pIdx)--; 1277 else 1278 { 1279 const SwTxtNode& rTNd = *GetTxtNode(); 1280 xub_StrLen nPos = pIdx->GetIndex(); 1281 if( pBreakIt->GetBreakIter().is() ) 1282 { 1283 sal_Int32 nDone = 0; 1284 sal_uInt16 nItrMode = ( CRSR_SKIP_CELLS & nMode ) ? 1285 CharacterIteratorMode::SKIPCELL : 1286 CharacterIteratorMode::SKIPCONTROLCHARACTER; 1287 nPos = (xub_StrLen)pBreakIt->GetBreakIter()->previousCharacters( rTNd.GetTxt(), nPos, 1288 pBreakIt->GetLocale( rTNd.GetLang( nPos ) ), 1289 nItrMode, 1, nDone ); 1290 1291 // Check if nPos is inside hidden text range: 1292 if ( CRSR_SKIP_HIDDEN & nMode ) 1293 { 1294 xub_StrLen nHiddenStart; 1295 xub_StrLen nHiddenEnd; 1296 SwScriptInfo::GetBoundsOfHiddenRange( rTNd, nPos, nHiddenStart, nHiddenEnd ); 1297 if ( nHiddenStart != STRING_LEN ) 1298 nPos = nHiddenStart; 1299 } 1300 1301 if( 1 == nDone ) 1302 *pIdx = nPos; 1303 else 1304 bRet = sal_False; 1305 } 1306 else if( nPos ) 1307 (*pIdx)--; 1308 else 1309 bRet = sal_False; 1310 } 1311 } 1312 else 1313 bRet = sal_False; 1314 return bRet; 1315 } 1316 1317 1318 /* 1319 * Methode erzeugt fuer den vorhergehenden Node alle Ansichten vom 1320 * Dokument. Die erzeugten Contentframes werden in das entsprechende 1321 * Layout gehaengt. 1322 */ 1323 1324 1325 void SwCntntNode::MakeFrms( SwCntntNode& rNode ) 1326 { 1327 ASSERT( &rNode != this, 1328 "Kein Contentnode oder Copy-Node und neuer Node identisch." ); 1329 1330 if( !GetDepends() || &rNode == this ) // gibt es ueberhaupt Frames ?? 1331 return; 1332 1333 SwFrm *pFrm, *pNew; 1334 SwLayoutFrm *pUpper; 1335 // Frames anlegen fuer Nodes, die vor oder hinter der Tabelle stehen ?? 1336 ASSERT( FindTableNode() == rNode.FindTableNode(), "Table confusion" ) 1337 1338 SwNode2Layout aNode2Layout( *this, rNode.GetIndex() ); 1339 1340 while( 0 != (pUpper = aNode2Layout.UpperFrm( pFrm, rNode )) ) 1341 { 1342 pNew = rNode.MakeFrm( pUpper ); 1343 pNew->Paste( pUpper, pFrm ); 1344 // --> OD 2005-12-01 #i27138# 1345 // notify accessibility paragraphs objects about changed 1346 // CONTENT_FLOWS_FROM/_TO relation. 1347 // Relation CONTENT_FLOWS_FROM for next paragraph will change 1348 // and relation CONTENT_FLOWS_TO for previous paragraph will change. 1349 if ( pNew->IsTxtFrm() ) 1350 { 1351 ViewShell* pViewShell( pNew->getRootFrm()->GetCurrShell() ); 1352 if ( pViewShell && pViewShell->GetLayout() && 1353 pViewShell->GetLayout()->IsAnyShellAccessible() ) 1354 { 1355 pViewShell->InvalidateAccessibleParaFlowRelation( 1356 dynamic_cast<SwTxtFrm*>(pNew->FindNextCnt( true )), 1357 dynamic_cast<SwTxtFrm*>(pNew->FindPrevCnt( true )) ); 1358 } 1359 } 1360 // <-- 1361 } 1362 } 1363 1364 /* 1365 * Methode loescht fuer den Node alle Ansichten vom 1366 * Dokument. Die Contentframes werden aus dem entsprechenden 1367 * Layout ausgehaengt. 1368 */ 1369 1370 1371 void SwCntntNode::DelFrms() 1372 { 1373 if( !GetDepends() ) 1374 return; 1375 1376 SwCntntFrm::DelFrms(*this); 1377 if( IsTxtNode() ) 1378 { 1379 ((SwTxtNode*)this)->SetWrong( NULL ); 1380 ((SwTxtNode*)this)->SetWrongDirty( true ); 1381 1382 ((SwTxtNode*)this)->SetGrammarCheck( NULL ); 1383 ((SwTxtNode*)this)->SetGrammarCheckDirty( true ); 1384 // SMARTTAGS 1385 ((SwTxtNode*)this)->SetSmartTags( NULL ); 1386 ((SwTxtNode*)this)->SetSmartTagDirty( true ); 1387 1388 ((SwTxtNode*)this)->SetWordCountDirty( true ); 1389 ((SwTxtNode*)this)->SetAutoCompleteWordDirty( true ); 1390 } 1391 } 1392 1393 1394 SwCntntNode *SwCntntNode::JoinNext() 1395 { 1396 return this; 1397 } 1398 1399 1400 SwCntntNode *SwCntntNode::JoinPrev() 1401 { 1402 return this; 1403 } 1404 1405 1406 1407 // erfrage vom Modify Informationen 1408 sal_Bool SwCntntNode::GetInfo( SfxPoolItem& rInfo ) const 1409 { 1410 switch( rInfo.Which() ) 1411 { 1412 case RES_AUTOFMT_DOCNODE: 1413 if( &GetNodes() == ((SwAutoFmtGetDocNode&)rInfo).pNodes ) 1414 { 1415 ((SwAutoFmtGetDocNode&)rInfo).pCntntNode = this; 1416 return sal_False; 1417 } 1418 break; 1419 // --> OD 2008-02-19 #refactorlists# 1420 // case RES_GETNUMNODES: 1421 // // #111955# only numbered nodes in rInfo 1422 // if( IsTxtNode()) 1423 // { 1424 // SwTxtNode * pTxtNode = (SwTxtNode*)this; 1425 // pItem = (SwNumRuleItem*)GetNoCondAttr(RES_PARATR_NUMRULE, sal_True ); 1426 1427 // if (0 != pItem && 1428 // pItem->GetValue().Len() && 1429 // pItem->GetValue() == ((SwNumRuleInfo&)rInfo).GetName() && 1430 // GetNodes().IsDocNodes()) 1431 // { 1432 // ((SwNumRuleInfo&)rInfo).AddNode( *pTxtNode ); 1433 // } 1434 // } 1435 1436 // return sal_True; 1437 // <-- 1438 1439 case RES_FINDNEARESTNODE: 1440 if( ((SwFmtPageDesc&)GetAttr( RES_PAGEDESC )).GetPageDesc() ) 1441 ((SwFindNearestNode&)rInfo).CheckNode( *this ); 1442 return sal_True; 1443 1444 case RES_CONTENT_VISIBLE: 1445 { 1446 ((SwPtrMsgPoolItem&)rInfo).pObject = 1447 SwIterator<SwFrm,SwCntntNode>::FirstElement(*this); 1448 } 1449 return sal_False; 1450 } 1451 1452 return SwModify::GetInfo( rInfo ); 1453 } 1454 1455 1456 // setze ein Attribut 1457 sal_Bool SwCntntNode::SetAttr(const SfxPoolItem& rAttr ) 1458 { 1459 if( !GetpSwAttrSet() ) // lasse von den entsprechenden Nodes die 1460 NewAttrSet( GetDoc()->GetAttrPool() ); // AttrSets anlegen 1461 1462 ASSERT( GetpSwAttrSet(), "warum wurde kein AttrSet angelegt?" ); 1463 1464 if ( IsInCache() ) 1465 { 1466 SwFrm::GetCache().Delete( this ); 1467 SetInCache( sal_False ); 1468 } 1469 1470 sal_Bool bRet = sal_False; 1471 // wenn Modify gelockt ist, werden keine Modifies verschickt 1472 if( IsModifyLocked() || 1473 ( !GetDepends() && RES_PARATR_NUMRULE != rAttr.Which() )) 1474 { 1475 bRet = 0 != AttrSetHandleHelper::Put( mpAttrSet, *this, rAttr ); 1476 } 1477 else 1478 { 1479 SwAttrSet aOld( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ), 1480 aNew( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ); 1481 if( 0 != ( bRet = 0 != AttrSetHandleHelper::Put_BC( mpAttrSet, *this, rAttr, &aOld, &aNew ) )) 1482 { 1483 SwAttrSetChg aChgOld( *GetpSwAttrSet(), aOld ); 1484 SwAttrSetChg aChgNew( *GetpSwAttrSet(), aNew ); 1485 ModifyNotification( &aChgOld, &aChgNew ); // alle veraenderten werden verschickt 1486 } 1487 } 1488 return bRet; 1489 } 1490 #include <svl/itemiter.hxx> 1491 1492 sal_Bool SwCntntNode::SetAttr( const SfxItemSet& rSet ) 1493 { 1494 if ( IsInCache() ) 1495 { 1496 SwFrm::GetCache().Delete( this ); 1497 SetInCache( sal_False ); 1498 } 1499 1500 const SfxPoolItem* pFnd = 0; 1501 if( SFX_ITEM_SET == rSet.GetItemState( RES_AUTO_STYLE, sal_False, &pFnd ) ) 1502 { 1503 ASSERT( rSet.Count() == 1, "SetAutoStyle mixed with other attributes?!" ); 1504 const SwFmtAutoFmt* pTmp = static_cast<const SwFmtAutoFmt*>(pFnd); 1505 1506 // If there already is an attribute set (usually containing a numbering 1507 // item), we have to merge the attribute of the new set into the old set: 1508 bool bSetParent = true; 1509 if ( GetpSwAttrSet() ) 1510 { 1511 bSetParent = false; 1512 AttrSetHandleHelper::Put( mpAttrSet, *this, *pTmp->GetStyleHandle() ); 1513 } 1514 else 1515 { 1516 mpAttrSet = pTmp->GetStyleHandle(); 1517 } 1518 1519 if ( bSetParent ) 1520 { 1521 // If the content node has a conditional style, we have to set the 1522 // string item containing the correct conditional style name (the 1523 // style name property has already been set during the import!) 1524 // In case we do not have a conditional style, we make use of the 1525 // fact that nobody else uses the attribute set behind the handle. 1526 // FME 2007-07-10 #i78124# If autostyle does not have a parent, 1527 // the string is empty. 1528 const SfxPoolItem* pNameItem = 0; 1529 if ( 0 != GetCondFmtColl() || 1530 SFX_ITEM_SET != mpAttrSet->GetItemState( RES_FRMATR_STYLE_NAME, sal_False, &pNameItem ) || 1531 0 == static_cast<const SfxStringItem*>(pNameItem)->GetValue().Len() ) 1532 AttrSetHandleHelper::SetParent( mpAttrSet, *this, &GetAnyFmtColl(), GetFmtColl() ); 1533 else 1534 const_cast<SfxItemSet*>(mpAttrSet.get())->SetParent( &GetFmtColl()->GetAttrSet() ); 1535 } 1536 1537 return sal_True; 1538 } 1539 1540 if( !GetpSwAttrSet() ) // lasse von den entsprechenden Nodes die 1541 NewAttrSet( GetDoc()->GetAttrPool() ); // AttrSets anlegen 1542 1543 sal_Bool bRet = sal_False; 1544 // wenn Modify gelockt ist, werden keine Modifies verschickt 1545 if ( IsModifyLocked() || 1546 ( !GetDepends() && 1547 SFX_ITEM_SET != rSet.GetItemState( RES_PARATR_NUMRULE, sal_False ) ) ) 1548 { 1549 // einige Sonderbehandlungen fuer Attribute 1550 bRet = 0 != AttrSetHandleHelper::Put( mpAttrSet, *this, rSet ); 1551 } 1552 else 1553 { 1554 SwAttrSet aOld( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ), 1555 aNew( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ); 1556 if( 0 != (bRet = 0 != AttrSetHandleHelper::Put_BC( mpAttrSet, *this, rSet, &aOld, &aNew )) ) 1557 { 1558 // einige Sonderbehandlungen fuer Attribute 1559 SwAttrSetChg aChgOld( *GetpSwAttrSet(), aOld ); 1560 SwAttrSetChg aChgNew( *GetpSwAttrSet(), aNew ); 1561 ModifyNotification( &aChgOld, &aChgNew ); // alle veraenderten werden verschickt 1562 } 1563 } 1564 return bRet; 1565 } 1566 1567 // Nimmt den Hint mit nWhich aus dem Delta-Array 1568 1569 1570 sal_Bool SwCntntNode::ResetAttr( sal_uInt16 nWhich1, sal_uInt16 nWhich2 ) 1571 { 1572 if( !GetpSwAttrSet() ) 1573 return sal_False; 1574 1575 if ( IsInCache() ) 1576 { 1577 SwFrm::GetCache().Delete( this ); 1578 SetInCache( sal_False ); 1579 } 1580 1581 // wenn Modify gelockt ist, werden keine Modifies verschickt 1582 if( IsModifyLocked() ) 1583 { 1584 sal_uInt16 nDel = 0; 1585 if ( !nWhich2 || nWhich2 < nWhich1 ) 1586 { 1587 std::vector<sal_uInt16> aClearWhichIds; 1588 aClearWhichIds.push_back( nWhich1 ); 1589 nDel = ClearItemsFromAttrSet( aClearWhichIds ); 1590 } 1591 else 1592 nDel = AttrSetHandleHelper::ClearItem_BC( mpAttrSet, *this, nWhich1, nWhich2, 0, 0 ); 1593 1594 if( !GetpSwAttrSet()->Count() ) // leer, dann loeschen 1595 mpAttrSet.reset();//DELETEZ( mpAttrSet ); 1596 return 0 != nDel; 1597 } 1598 1599 // sollte kein gueltiger Bereich definiert sein ? 1600 if( !nWhich2 || nWhich2 < nWhich1 ) 1601 nWhich2 = nWhich1; // dann setze auf 1. Id, nur dieses Item 1602 1603 SwAttrSet aOld( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ), 1604 aNew( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ); 1605 sal_Bool bRet = 0 != AttrSetHandleHelper::ClearItem_BC( mpAttrSet, *this, nWhich1, nWhich2, &aOld, &aNew ); 1606 1607 if( bRet ) 1608 { 1609 SwAttrSetChg aChgOld( *GetpSwAttrSet(), aOld ); 1610 SwAttrSetChg aChgNew( *GetpSwAttrSet(), aNew ); 1611 ModifyNotification( &aChgOld, &aChgNew ); // alle veraenderten werden verschickt 1612 1613 if( !GetpSwAttrSet()->Count() ) // leer, dann loeschen 1614 mpAttrSet.reset();//DELETEZ( mpAttrSet ); 1615 } 1616 return bRet; 1617 } 1618 sal_Bool SwCntntNode::ResetAttr( const SvUShorts& rWhichArr ) 1619 { 1620 if( !GetpSwAttrSet() ) 1621 return sal_False; 1622 1623 if ( IsInCache() ) 1624 { 1625 SwFrm::GetCache().Delete( this ); 1626 SetInCache( sal_False ); 1627 } 1628 1629 // wenn Modify gelockt ist, werden keine Modifies verschickt 1630 sal_uInt16 nDel = 0; 1631 if( IsModifyLocked() ) 1632 { 1633 std::vector<sal_uInt16> aClearWhichIds; 1634 for( sal_uInt16 n = 0, nEnd = rWhichArr.Count(); n < nEnd; ++n ) 1635 aClearWhichIds.push_back( rWhichArr[ n ] ); 1636 1637 nDel = ClearItemsFromAttrSet( aClearWhichIds ); 1638 } 1639 else 1640 { 1641 SwAttrSet aOld( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ), 1642 aNew( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ); 1643 1644 for( sal_uInt16 n = 0, nEnd = rWhichArr.Count(); n < nEnd; ++n ) 1645 if( AttrSetHandleHelper::ClearItem_BC( mpAttrSet, *this, rWhichArr[ n ], &aOld, &aNew )) 1646 ++nDel; 1647 1648 if( nDel ) 1649 { 1650 SwAttrSetChg aChgOld( *GetpSwAttrSet(), aOld ); 1651 SwAttrSetChg aChgNew( *GetpSwAttrSet(), aNew ); 1652 ModifyNotification( &aChgOld, &aChgNew ); // alle veraenderten werden verschickt 1653 } 1654 } 1655 if( !GetpSwAttrSet()->Count() ) // leer, dann loeschen 1656 mpAttrSet.reset();//DELETEZ( mpAttrSet ); 1657 return 0 != nDel ; 1658 } 1659 1660 1661 sal_uInt16 SwCntntNode::ResetAllAttr() 1662 { 1663 if( !GetpSwAttrSet() ) 1664 return 0; 1665 1666 if ( IsInCache() ) 1667 { 1668 SwFrm::GetCache().Delete( this ); 1669 SetInCache( sal_False ); 1670 } 1671 1672 // wenn Modify gelockt ist, werden keine Modifies verschickt 1673 if( IsModifyLocked() ) 1674 { 1675 std::vector<sal_uInt16> aClearWhichIds; 1676 aClearWhichIds.push_back(0); 1677 sal_uInt16 nDel = ClearItemsFromAttrSet( aClearWhichIds ); 1678 if( !GetpSwAttrSet()->Count() ) // leer, dann loeschen 1679 mpAttrSet.reset(); // DELETEZ( mpAttrSet ); 1680 return nDel; 1681 } 1682 1683 SwAttrSet aOld( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ), 1684 aNew( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ); 1685 sal_Bool bRet = 0 != AttrSetHandleHelper::ClearItem_BC( mpAttrSet, *this, 0, &aOld, &aNew ); 1686 1687 if( bRet ) 1688 { 1689 SwAttrSetChg aChgOld( *GetpSwAttrSet(), aOld ); 1690 SwAttrSetChg aChgNew( *GetpSwAttrSet(), aNew ); 1691 ModifyNotification( &aChgOld, &aChgNew ); // alle veraenderten werden verschickt 1692 1693 if( !GetpSwAttrSet()->Count() ) // leer, dann loeschen 1694 mpAttrSet.reset();//DELETEZ( mpAttrSet ); 1695 } 1696 return aNew.Count(); 1697 } 1698 1699 1700 sal_Bool SwCntntNode::GetAttr( SfxItemSet& rSet, sal_Bool bInParent ) const 1701 { 1702 if( rSet.Count() ) 1703 rSet.ClearItem(); 1704 1705 const SwAttrSet& rAttrSet = GetSwAttrSet(); 1706 if( bInParent ) 1707 return rSet.Set( rAttrSet, sal_True ) ? sal_True : sal_False; 1708 1709 rSet.Put( rAttrSet ); 1710 return rSet.Count() ? sal_True : sal_False; 1711 } 1712 1713 sal_uInt16 SwCntntNode::ClearItemsFromAttrSet( const std::vector<sal_uInt16>& rWhichIds ) 1714 { 1715 sal_uInt16 nRet = 0; 1716 if ( 0 == rWhichIds.size() ) 1717 return nRet; 1718 1719 ASSERT( GetpSwAttrSet(), "no item set" ) 1720 SwAttrSet aNewAttrSet( *GetpSwAttrSet() ); 1721 for ( std::vector<sal_uInt16>::const_iterator aIter = rWhichIds.begin(); 1722 aIter != rWhichIds.end(); 1723 ++aIter ) 1724 { 1725 nRet = nRet + aNewAttrSet.ClearItem( *aIter ); 1726 } 1727 if ( nRet ) 1728 AttrSetHandleHelper::GetNewAutoStyle( mpAttrSet, *this, aNewAttrSet ); 1729 1730 return nRet; 1731 } 1732 1733 const SfxPoolItem* SwCntntNode::GetNoCondAttr( sal_uInt16 nWhich, 1734 sal_Bool bInParents ) const 1735 { 1736 const SfxPoolItem* pFnd = 0; 1737 if( pCondColl && pCondColl->GetRegisteredIn() ) 1738 { 1739 if( !GetpSwAttrSet() || ( SFX_ITEM_SET != GetpSwAttrSet()->GetItemState( 1740 nWhich, sal_False, &pFnd ) && bInParents )) 1741 ((SwFmt*)GetRegisteredIn())->GetItemState( nWhich, bInParents, &pFnd ); 1742 } 1743 // --> OD 2005-10-25 #126347# - undo change of issue #i51029# 1744 // Note: <GetSwAttrSet()> returns <mpAttrSet>, if set, otherwise it returns 1745 // the attribute set of the paragraph style, which is valid for the 1746 // content node - see file <node.hxx> 1747 else 1748 // <-- 1749 { 1750 GetSwAttrSet().GetItemState( nWhich, bInParents, &pFnd ); 1751 } 1752 return pFnd; 1753 } 1754 1755 // koennen 2 Nodes zusammengefasst werden ? 1756 // in pIdx kann die 2. Position returnt werden. 1757 int SwCntntNode::CanJoinNext( SwNodeIndex* pIdx ) const 1758 { 1759 const SwNodes& rNds = GetNodes(); 1760 sal_uInt8 nNdType = GetNodeType(); 1761 SwNodeIndex aIdx( *this, 1 ); 1762 1763 const SwNode* pNd = this; 1764 while( aIdx < rNds.Count()-1 && 1765 (( pNd = &aIdx.GetNode())->IsSectionNode() || 1766 ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode() ))) 1767 aIdx++; 1768 1769 if( pNd->GetNodeType() != nNdType || rNds.Count()-1 == aIdx.GetIndex() ) 1770 return sal_False; 1771 if( IsTxtNode() ) 1772 { // Do not merge strings if the result exceeds the allowed string length 1773 const SwTxtNode* pTxtNd = static_cast<const SwTxtNode*>(this); 1774 sal_uInt64 nSum = pTxtNd->GetTxt().Len(); 1775 pTxtNd = static_cast<const SwTxtNode*>(pNd); 1776 nSum += pTxtNd->GetTxt().Len(); 1777 if( nSum > STRING_LEN ) 1778 return sal_False; 1779 } 1780 if( pIdx ) 1781 *pIdx = aIdx; 1782 return sal_True; 1783 } 1784 1785 1786 // koennen 2 Nodes zusammengefasst werden ? 1787 // in pIdx kann die 2. Position returnt werden. 1788 int SwCntntNode::CanJoinPrev( SwNodeIndex* pIdx ) const 1789 { 1790 sal_uInt8 nNdType = GetNodeType(); 1791 SwNodeIndex aIdx( *this, -1 ); 1792 1793 const SwNode* pNd = this; 1794 while( aIdx.GetIndex() && 1795 (( pNd = &aIdx.GetNode())->IsSectionNode() || 1796 ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode() ))) 1797 aIdx--; 1798 1799 if( pNd->GetNodeType() != nNdType || 0 == aIdx.GetIndex() ) 1800 return sal_False; 1801 if( pIdx ) 1802 *pIdx = aIdx; 1803 return sal_True; 1804 } 1805 1806 1807 //FEATURE::CONDCOLL 1808 1809 1810 void SwCntntNode::SetCondFmtColl( SwFmtColl* pColl ) 1811 { 1812 if( (!pColl && pCondColl) || ( pColl && !pCondColl ) || 1813 ( pColl && pColl != pCondColl->GetRegisteredIn() ) ) 1814 { 1815 SwFmtColl* pOldColl = GetCondFmtColl(); 1816 delete pCondColl; 1817 if( pColl ) 1818 pCondColl = new SwDepend( this, pColl ); 1819 else 1820 pCondColl = 0; 1821 1822 if( GetpSwAttrSet() ) 1823 { 1824 AttrSetHandleHelper::SetParent( mpAttrSet, *this, &GetAnyFmtColl(), GetFmtColl() ); 1825 } 1826 1827 if( !IsModifyLocked() ) 1828 { 1829 SwFmtChg aTmp1( pOldColl ? pOldColl : GetFmtColl() ); 1830 SwFmtChg aTmp2( pColl ? pColl : GetFmtColl() ); 1831 NotifyClients( &aTmp1, &aTmp2 ); 1832 } 1833 if( IsInCache() ) 1834 { 1835 SwFrm::GetCache().Delete( this ); 1836 SetInCache( sal_False ); 1837 } 1838 } 1839 } 1840 1841 1842 sal_Bool SwCntntNode::IsAnyCondition( SwCollCondition& rTmp ) const 1843 { 1844 const SwNodes& rNds = GetNodes(); 1845 { 1846 int nCond = 0; 1847 const SwStartNode* pSttNd = StartOfSectionNode(); 1848 while( pSttNd ) 1849 { 1850 switch( pSttNd->GetNodeType() ) 1851 { 1852 case ND_TABLENODE: nCond = PARA_IN_TABLEBODY; break; 1853 case ND_SECTIONNODE: nCond = PARA_IN_SECTION; break; 1854 1855 default: 1856 switch( pSttNd->GetStartNodeType() ) 1857 { 1858 case SwTableBoxStartNode: 1859 { 1860 nCond = PARA_IN_TABLEBODY; 1861 const SwTableNode* pTblNd = pSttNd->FindTableNode(); 1862 const SwTableBox* pBox; 1863 if( pTblNd && 0 != ( pBox = pTblNd->GetTable(). 1864 GetTblBox( pSttNd->GetIndex() ) ) && pBox && 1865 pBox->IsInHeadline( &pTblNd->GetTable() ) ) 1866 nCond = PARA_IN_TABLEHEAD; 1867 } 1868 break; 1869 case SwFlyStartNode: nCond = PARA_IN_FRAME; break; 1870 case SwFootnoteStartNode: 1871 { 1872 nCond = PARA_IN_FOOTENOTE; 1873 const SwFtnIdxs& rFtnArr = rNds.GetDoc()->GetFtnIdxs(); 1874 const SwTxtFtn* pTxtFtn; 1875 const SwNode* pSrchNd = pSttNd; 1876 1877 for( sal_uInt16 n = 0; n < rFtnArr.Count(); ++n ) 1878 if( 0 != ( pTxtFtn = rFtnArr[ n ])->GetStartNode() && 1879 pSrchNd == &pTxtFtn->GetStartNode()->GetNode() ) 1880 { 1881 if( pTxtFtn->GetFtn().IsEndNote() ) 1882 nCond = PARA_IN_ENDNOTE; 1883 break; 1884 } 1885 } 1886 break; 1887 case SwHeaderStartNode: nCond = PARA_IN_HEADER; break; 1888 case SwFooterStartNode: nCond = PARA_IN_FOOTER; break; 1889 case SwNormalStartNode: break; 1890 } 1891 } 1892 1893 if( nCond ) 1894 { 1895 rTmp.SetCondition( (Master_CollConditions)nCond, 0 ); 1896 return sal_True; 1897 } 1898 pSttNd = pSttNd->GetIndex() 1899 ? pSttNd->StartOfSectionNode() 1900 : 0; 1901 } 1902 } 1903 1904 { 1905 sal_uInt16 nPos; 1906 const SwOutlineNodes& rOutlNds = rNds.GetOutLineNds(); 1907 if( rOutlNds.Count() ) 1908 { 1909 if( !rOutlNds.Seek_Entry( (SwCntntNode*)this, &nPos ) && nPos ) 1910 --nPos; 1911 if( nPos < rOutlNds.Count() && 1912 rOutlNds[ nPos ]->GetIndex() < GetIndex() ) 1913 { 1914 SwTxtNode* pOutlNd = rOutlNds[ nPos ]->GetTxtNode(); 1915 1916 if( pOutlNd->IsOutline()) 1917 { 1918 rTmp.SetCondition( PARA_IN_OUTLINE, pOutlNd->GetAttrOutlineLevel() - 1 ); 1919 return sal_True; 1920 } 1921 } 1922 } 1923 } 1924 1925 return sal_False; 1926 } 1927 1928 1929 void SwCntntNode::ChkCondColl() 1930 { 1931 // zur Sicherheit abfragen 1932 if( RES_CONDTXTFMTCOLL == GetFmtColl()->Which() ) 1933 { 1934 SwCollCondition aTmp( 0, 0, 0 ); 1935 const SwCollCondition* pCColl; 1936 1937 bool bDone = false; 1938 1939 if( IsAnyCondition( aTmp )) 1940 { 1941 pCColl = static_cast<SwConditionTxtFmtColl*>(GetFmtColl()) 1942 ->HasCondition( aTmp ); 1943 1944 if (pCColl) 1945 { 1946 SetCondFmtColl( pCColl->GetTxtFmtColl() ); 1947 bDone = true; 1948 } 1949 } 1950 1951 if (!bDone) 1952 { 1953 if( IsTxtNode() && ((SwTxtNode*)this)->GetNumRule()) 1954 { 1955 // steht in einer Numerierung 1956 // welcher Level? 1957 aTmp.SetCondition( PARA_IN_LIST, 1958 ((SwTxtNode*)this)->GetActualListLevel() ); 1959 pCColl = ((SwConditionTxtFmtColl*)GetFmtColl())-> 1960 HasCondition( aTmp ); 1961 } 1962 else 1963 pCColl = 0; 1964 1965 if( pCColl ) 1966 SetCondFmtColl( pCColl->GetTxtFmtColl() ); 1967 else if( pCondColl ) 1968 SetCondFmtColl( 0 ); 1969 } 1970 } 1971 } 1972 1973 // --> OD 2005-02-21 #i42921# 1974 short SwCntntNode::GetTextDirection( const SwPosition& rPos, 1975 const Point* pPt ) const 1976 { 1977 short nRet = -1; 1978 1979 Point aPt; 1980 if( pPt ) 1981 aPt = *pPt; 1982 1983 // --> OD 2007-01-10 #i72024# 1984 // No format of the frame, because this can cause recursive layout actions 1985 SwFrm* pFrm = getLayoutFrm( GetDoc()->GetCurrentLayout(), &aPt, &rPos, sal_False ); 1986 // <-- 1987 1988 if ( pFrm ) 1989 { 1990 if ( pFrm->IsVertical() ) 1991 { 1992 if ( pFrm->IsRightToLeft() ) 1993 nRet = FRMDIR_VERT_TOP_LEFT; 1994 else 1995 nRet = FRMDIR_VERT_TOP_RIGHT; 1996 } 1997 else 1998 { 1999 if ( pFrm->IsRightToLeft() ) 2000 nRet = FRMDIR_HORI_RIGHT_TOP; 2001 else 2002 nRet = FRMDIR_HORI_LEFT_TOP; 2003 } 2004 } 2005 2006 2007 return nRet; 2008 } 2009 // <-- 2010 2011 SwOLENodes* SwCntntNode::CreateOLENodesArray( const SwFmtColl& rColl, bool bOnlyWithInvalidSize ) 2012 { 2013 SwOLENodes *pNodes = 0; 2014 SwIterator<SwCntntNode,SwFmtColl> aIter( rColl ); 2015 for( SwCntntNode* pNd = aIter.First(); pNd; pNd = aIter.Next() ) 2016 { 2017 SwOLENode *pONd = pNd->GetOLENode(); 2018 if ( pONd && (!bOnlyWithInvalidSize || pONd->IsOLESizeInvalid()) ) 2019 { 2020 if ( !pNodes ) 2021 pNodes = new SwOLENodes; 2022 pNodes->Insert( pONd, pNodes->Count() ); 2023 } 2024 } 2025 2026 return pNodes; 2027 } 2028 2029 //FEATURE::CONDCOLL 2030 // Metoden aus Node.hxx - erst hier ist der TxtNode bekannt !! 2031 // os: nur fuer ICC, da der zum optimieren zu dumm ist 2032 #ifdef ICC 2033 SwTxtNode *SwNode::GetTxtNode() 2034 { 2035 return ND_TEXTNODE == nNodeType ? (SwTxtNode*)this : 0; 2036 } 2037 const SwTxtNode *SwNode::GetTxtNode() const 2038 { 2039 return ND_TEXTNODE == nNodeType ? (const SwTxtNode*)this : 0; 2040 } 2041 #endif 2042 2043 /* 2044 * Document Interface Access 2045 */ 2046 const IDocumentSettingAccess* SwNode::getIDocumentSettingAccess() const { return GetDoc(); } 2047 const IDocumentDeviceAccess* SwNode::getIDocumentDeviceAccess() const { return GetDoc(); } 2048 const IDocumentMarkAccess* SwNode::getIDocumentMarkAccess() const { return GetDoc()->getIDocumentMarkAccess(); } 2049 const IDocumentRedlineAccess* SwNode::getIDocumentRedlineAccess() const { return GetDoc(); } 2050 const IDocumentStylePoolAccess* SwNode::getIDocumentStylePoolAccess() const { return GetDoc(); } 2051 const IDocumentLineNumberAccess* SwNode::getIDocumentLineNumberAccess() const { return GetDoc(); } 2052 const IDocumentDrawModelAccess* SwNode::getIDocumentDrawModelAccess() const { return GetDoc(); } 2053 const IDocumentLayoutAccess* SwNode::getIDocumentLayoutAccess() const { return GetDoc(); } 2054 IDocumentLayoutAccess* SwNode::getIDocumentLayoutAccess() { return GetDoc(); } 2055 const IDocumentLinksAdministration* SwNode::getIDocumentLinksAdministration() const { return GetDoc(); } 2056 IDocumentLinksAdministration* SwNode::getIDocumentLinksAdministration() { return GetDoc(); } 2057 const IDocumentFieldsAccess* SwNode::getIDocumentFieldsAccess() const { return GetDoc(); } 2058 IDocumentFieldsAccess* SwNode::getIDocumentFieldsAccess() { return GetDoc(); } 2059 IDocumentContentOperations* SwNode::getIDocumentContentOperations() { return GetDoc(); } 2060 IStyleAccess& SwNode::getIDocumentStyleAccess() { return GetDoc()->GetIStyleAccess(); } 2061 // --> OD 2007-10-31 #i83479# 2062 IDocumentListItems& SwNode::getIDocumentListItems() 2063 { 2064 return *GetDoc(); 2065 } 2066 // <-- 2067 2068 sal_Bool SwNode::IsInRedlines() const 2069 { 2070 const SwDoc * pDoc = GetDoc(); 2071 sal_Bool bResult = sal_False; 2072 2073 if (pDoc != NULL) 2074 bResult = pDoc->IsInRedlines(*this); 2075 2076 return bResult; 2077 } 2078