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 28 #include <limits.h> 29 #include <hintids.hxx> 30 31 #define _SVSTDARR_STRINGSSORT 32 #include <svl/svstdarr.hxx> 33 #include <editeng/langitem.hxx> 34 #include <editeng/brkitem.hxx> 35 #include <editeng/tstpitem.hxx> 36 #include <editeng/lrspitem.hxx> 37 #include <sot/clsids.hxx> 38 #include <docsh.hxx> 39 #include <ndole.hxx> 40 #include <txttxmrk.hxx> 41 #include <fmtinfmt.hxx> 42 #include <fmtpdsc.hxx> 43 #include <frmfmt.hxx> 44 #include <fmtfsize.hxx> 45 #include <frmatr.hxx> 46 #include <pagedesc.hxx> 47 #include <doc.hxx> 48 #include <IDocumentUndoRedo.hxx> 49 #include <pagefrm.hxx> 50 #include <ndtxt.hxx> 51 #include <swtable.hxx> 52 #include <doctxm.hxx> 53 #include <txmsrt.hxx> 54 #include <rolbck.hxx> 55 #include <poolfmt.hxx> 56 #include <txtfrm.hxx> 57 #include <rootfrm.hxx> 58 #include <UndoAttribute.hxx> 59 #include <swundo.hxx> 60 #include <mdiexp.hxx> 61 #include <docary.hxx> 62 #include <charfmt.hxx> 63 #include <fchrfmt.hxx> 64 #include <fldbas.hxx> 65 #include <fmtfld.hxx> 66 #include <txtfld.hxx> 67 #include <expfld.hxx> 68 #include <chpfld.hxx> 69 #include <mvsave.hxx> 70 #include <node2lay.hxx> 71 #include <SwStyleNameMapper.hxx> 72 #include <breakit.hxx> 73 #include <editsh.hxx> 74 #include <scriptinfo.hxx> 75 #include <switerator.hxx> 76 77 using namespace ::com::sun::star; 78 79 const sal_Unicode cNumRepl = '@'; 80 const sal_Unicode cEndPageNum = '~'; 81 const sal_Char __FAR_DATA sPageDeli[] = ", "; 82 83 SV_IMPL_PTRARR(SwTOXSortTabBases, SwTOXSortTabBasePtr) 84 85 TYPEINIT2( SwTOXBaseSection, SwTOXBase, SwSection ); // fuers RTTI 86 87 struct LinkStruct 88 { 89 SwFmtINetFmt aINetFmt; 90 xub_StrLen nStartTextPos, nEndTextPos; 91 92 LinkStruct( const String& rURL, xub_StrLen nStart, xub_StrLen nEnd ) 93 : aINetFmt( rURL, aEmptyStr), 94 nStartTextPos( nStart), 95 nEndTextPos(nEnd) {} 96 }; 97 98 typedef LinkStruct* LinkStructPtr; 99 SV_DECL_PTRARR(LinkStructArr, LinkStructPtr, 0, 5 ) 100 SV_IMPL_PTRARR(LinkStructArr, LinkStructPtr) 101 102 sal_uInt16 SwDoc::GetTOIKeys( SwTOIKeyType eTyp, SvStringsSort& rArr ) const 103 { 104 if( rArr.Count() ) 105 rArr.Remove( sal_uInt16(0), rArr.Count() ); 106 107 // dann mal ueber den Pool und alle Primary oder Secondary heraussuchen 108 const SwTxtTOXMark* pMark; 109 const SfxPoolItem* pItem; 110 const SwTOXType* pTOXType; 111 sal_uInt32 i, nMaxItems = GetAttrPool().GetItemCount2( RES_TXTATR_TOXMARK ); 112 for( i = 0; i < nMaxItems; ++i ) 113 if( 0 != (pItem = GetAttrPool().GetItem2( RES_TXTATR_TOXMARK, i ) ) && 114 0!= ( pTOXType = ((SwTOXMark*)pItem)->GetTOXType()) && 115 TOX_INDEX == pTOXType->GetType() && 116 0 != ( pMark = ((SwTOXMark*)pItem)->GetTxtTOXMark() ) && 117 pMark->GetpTxtNd() && 118 pMark->GetpTxtNd()->GetNodes().IsDocNodes() ) 119 { 120 const String* pStr; 121 if( TOI_PRIMARY == eTyp ) 122 pStr = &((SwTOXMark*)pItem)->GetPrimaryKey(); 123 else 124 pStr = &((SwTOXMark*)pItem)->GetSecondaryKey(); 125 126 if( pStr->Len() ) 127 rArr.Insert( (StringPtr)pStr ); 128 } 129 130 return rArr.Count(); 131 } 132 133 /*-------------------------------------------------------------------- 134 Beschreibung: aktuelle Verzeichnismarkierungen ermitteln 135 --------------------------------------------------------------------*/ 136 137 138 sal_uInt16 SwDoc::GetCurTOXMark( const SwPosition& rPos, 139 SwTOXMarks& rArr ) const 140 { 141 // search on Position rPos for all SwTOXMarks 142 SwTxtNode *const pTxtNd = rPos.nNode.GetNode().GetTxtNode(); 143 if( !pTxtNd || !pTxtNd->GetpSwpHints() ) 144 return 0; 145 146 const SwpHints & rHts = *pTxtNd->GetpSwpHints(); 147 const SwTxtAttr* pHt; 148 xub_StrLen nSttIdx; 149 const xub_StrLen *pEndIdx; 150 151 xub_StrLen nAktPos = rPos.nContent.GetIndex(); 152 153 for( sal_uInt16 n = 0; n < rHts.Count(); ++n ) 154 { 155 if( RES_TXTATR_TOXMARK != (pHt = rHts[n])->Which() ) 156 continue; 157 if( ( nSttIdx = *pHt->GetStart() ) < nAktPos ) 158 { 159 // pruefe Ende mit ab 160 if( 0 == ( pEndIdx = pHt->End() ) || 161 *pEndIdx <= nAktPos ) 162 continue; // weiter suchen 163 } 164 else if( nSttIdx > nAktPos ) 165 // ist Start vom Hint groesser als rPos, dann abbrechen. Denn 166 // die Attribute sind nach Start sortiert ! 167 break; 168 169 const SwTOXMark* pTMark = &pHt->GetTOXMark(); 170 rArr.Insert( pTMark, rArr.Count() ); 171 } 172 return rArr.Count(); 173 } 174 175 /*-------------------------------------------------------------------- 176 Beschreibung: Marke loeschen 177 --------------------------------------------------------------------*/ 178 179 void SwDoc::DeleteTOXMark( const SwTOXMark* pTOXMark ) 180 { 181 // hole den TextNode und 182 const SwTxtTOXMark* pTxtTOXMark = pTOXMark->GetTxtTOXMark(); 183 ASSERT( pTxtTOXMark, "Kein TxtTOXMark, kann nicht geloescht werden" ); 184 185 SwTxtNode& rTxtNd = const_cast<SwTxtNode&>(pTxtTOXMark->GetTxtNode()); 186 ASSERT( rTxtNd.GetpSwpHints(), "kann nicht geloescht werden" ); 187 188 if (GetIDocumentUndoRedo().DoesUndo()) 189 { 190 // save attributes for Undo 191 SwUndoResetAttr* pUndo = new SwUndoResetAttr( 192 SwPosition( rTxtNd, SwIndex( &rTxtNd, *pTxtTOXMark->GetStart() ) ), 193 RES_TXTATR_TOXMARK ); 194 GetIDocumentUndoRedo().AppendUndo( pUndo ); 195 196 SwRegHistory aRHst( rTxtNd, &pUndo->GetHistory() ); 197 rTxtNd.GetpSwpHints()->Register( &aRHst ); 198 } 199 200 rTxtNd.DeleteAttribute( const_cast<SwTxtTOXMark*>(pTxtTOXMark) ); 201 202 if (GetIDocumentUndoRedo().DoesUndo()) 203 { 204 if( rTxtNd.GetpSwpHints() ) 205 rTxtNd.GetpSwpHints()->DeRegister(); 206 } 207 SetModified(); 208 } 209 210 /*-------------------------------------------------------------------- 211 Beschreibung: Traveln zwischen TOXMarks 212 --------------------------------------------------------------------*/ 213 214 class CompareNodeCntnt 215 { 216 sal_uLong nNode; 217 xub_StrLen nCntnt; 218 public: 219 CompareNodeCntnt( sal_uLong nNd, xub_StrLen nCnt ) 220 : nNode( nNd ), nCntnt( nCnt ) {} 221 222 int operator==( const CompareNodeCntnt& rCmp ) 223 { return nNode == rCmp.nNode && nCntnt == rCmp.nCntnt; } 224 int operator!=( const CompareNodeCntnt& rCmp ) 225 { return nNode != rCmp.nNode || nCntnt != rCmp.nCntnt; } 226 int operator< ( const CompareNodeCntnt& rCmp ) 227 { return nNode < rCmp.nNode || 228 ( nNode == rCmp.nNode && nCntnt < rCmp.nCntnt); } 229 int operator<=( const CompareNodeCntnt& rCmp ) 230 { return nNode < rCmp.nNode || 231 ( nNode == rCmp.nNode && nCntnt <= rCmp.nCntnt); } 232 int operator> ( const CompareNodeCntnt& rCmp ) 233 { return nNode > rCmp.nNode || 234 ( nNode == rCmp.nNode && nCntnt > rCmp.nCntnt); } 235 int operator>=( const CompareNodeCntnt& rCmp ) 236 { return nNode > rCmp.nNode || 237 ( nNode == rCmp.nNode && nCntnt >= rCmp.nCntnt); } 238 }; 239 240 const SwTOXMark& SwDoc::GotoTOXMark( const SwTOXMark& rCurTOXMark, 241 SwTOXSearch eDir, sal_Bool bInReadOnly ) 242 { 243 const SwTxtTOXMark* pMark = rCurTOXMark.GetTxtTOXMark(); 244 ASSERT(pMark, "pMark==0 Ungueltige TxtTOXMark"); 245 246 const SwTxtNode *pTOXSrc = pMark->GetpTxtNd(); 247 248 CompareNodeCntnt aAbsIdx( pTOXSrc->GetIndex(), *pMark->GetStart() ); 249 CompareNodeCntnt aPrevPos( 0, 0 ); 250 CompareNodeCntnt aNextPos( ULONG_MAX, STRING_NOTFOUND ); 251 CompareNodeCntnt aMax( 0, 0 ); 252 CompareNodeCntnt aMin( ULONG_MAX, STRING_NOTFOUND ); 253 254 const SwTOXMark* pNew = 0; 255 const SwTOXMark* pMax = &rCurTOXMark; 256 const SwTOXMark* pMin = &rCurTOXMark; 257 258 const SwTOXType* pType = rCurTOXMark.GetTOXType(); 259 SwTOXMarks aMarks; 260 SwTOXMark::InsertTOXMarks( aMarks, *pType ); 261 262 const SwTOXMark* pTOXMark; 263 const SwCntntFrm* pCFrm; 264 Point aPt; 265 for( sal_uInt16 nMark=0; nMark<aMarks.Count(); nMark++ ) 266 { 267 pTOXMark = aMarks[nMark]; 268 if( pTOXMark != &rCurTOXMark && 269 0 != ( pMark = pTOXMark->GetTxtTOXMark()) && 270 0 != ( pTOXSrc = pMark->GetpTxtNd() ) && 271 0 != ( pCFrm = pTOXSrc->getLayoutFrm( GetCurrentLayout(), &aPt, 0, sal_False )) && 272 ( bInReadOnly || !pCFrm->IsProtected() )) 273 { 274 CompareNodeCntnt aAbsNew( pTOXSrc->GetIndex(), *pMark->GetStart() ); 275 switch( eDir ) 276 { 277 //Die untenstehenden etwas komplizierter ausgefallen Ausdruecke 278 //dienen dazu auch ueber Eintraege auf der selben (!) Position 279 //traveln zu koennen. Wenn einer Zeit hat mag er sie mal 280 //optimieren. 281 282 case TOX_SAME_PRV: 283 if( pTOXMark->GetText() != rCurTOXMark.GetText() ) 284 break; 285 /* no break here */ 286 case TOX_PRV: 287 if ( (aAbsNew < aAbsIdx && aAbsNew > aPrevPos && 288 aPrevPos != aAbsIdx && aAbsNew != aAbsIdx ) || 289 (aAbsIdx == aAbsNew && 290 (sal_uLong(&rCurTOXMark) > sal_uLong(pTOXMark) && 291 (!pNew || 292 (pNew && (aPrevPos < aAbsIdx || 293 sal_uLong(pNew) < sal_uLong(pTOXMark)))))) || 294 (aPrevPos == aAbsNew && aAbsIdx != aAbsNew && 295 sal_uLong(pTOXMark) > sal_uLong(pNew)) ) 296 { 297 pNew = pTOXMark; 298 aPrevPos = aAbsNew; 299 if ( aAbsNew >= aMax ) 300 { 301 aMax = aAbsNew; 302 pMax = pTOXMark; 303 } 304 } 305 break; 306 307 case TOX_SAME_NXT: 308 if( pTOXMark->GetText() != rCurTOXMark.GetText() ) 309 break; 310 /* no break here */ 311 case TOX_NXT: 312 if ( (aAbsNew > aAbsIdx && aAbsNew < aNextPos && 313 aNextPos != aAbsIdx && aAbsNew != aAbsIdx ) || 314 (aAbsIdx == aAbsNew && 315 (sal_uLong(&rCurTOXMark) < sal_uLong(pTOXMark) && 316 (!pNew || 317 (pNew && (aNextPos > aAbsIdx || 318 sal_uLong(pNew) > sal_uLong(pTOXMark)))))) || 319 (aNextPos == aAbsNew && aAbsIdx != aAbsNew && 320 sal_uLong(pTOXMark) < sal_uLong(pNew)) ) 321 { 322 pNew = pTOXMark; 323 aNextPos = aAbsNew; 324 if ( aAbsNew <= aMin ) 325 { 326 aMin = aAbsNew; 327 pMin = pTOXMark; 328 } 329 } 330 break; 331 } 332 } 333 } 334 335 336 // kein Nachfolger wurde gefunden 337 // Min oder Max benutzen 338 if(!pNew) 339 { 340 switch(eDir) 341 { 342 case TOX_PRV: 343 case TOX_SAME_PRV: 344 pNew = pMax; 345 break; 346 case TOX_NXT: 347 case TOX_SAME_NXT: 348 pNew = pMin; 349 break; 350 default: 351 pNew = &rCurTOXMark; 352 } 353 } 354 return *pNew; 355 } 356 357 358 const SwTOXBaseSection* SwDoc::InsertTableOf( const SwPosition& rPos, 359 const SwTOXBase& rTOX, 360 const SfxItemSet* pSet, 361 sal_Bool bExpand ) 362 { 363 GetIDocumentUndoRedo().StartUndo( UNDO_INSTOX, NULL ); 364 365 String sSectNm( rTOX.GetTOXName() ); 366 sSectNm = GetUniqueTOXBaseName( *rTOX.GetTOXType(), &sSectNm ); 367 SwPaM aPam( rPos ); 368 SwSectionData aSectionData( TOX_CONTENT_SECTION, sSectNm ); 369 SwTOXBaseSection *const pNewSection = dynamic_cast<SwTOXBaseSection *>( 370 InsertSwSection( aPam, aSectionData, & rTOX, pSet, false )); 371 if (pNewSection) 372 { 373 SwSectionNode *const pSectNd = pNewSection->GetFmt()->GetSectionNode(); 374 pNewSection->SetTOXName(sSectNm); // rTOX may have had no name... 375 376 if( bExpand ) 377 { 378 // OD 19.03.2003 #106329# - add value for 2nd parameter = true to 379 // indicate, that a creation of a new table of content has to be performed. 380 // Value of 1st parameter = default value. 381 pNewSection->Update( 0, true ); 382 } 383 else if( 1 == rTOX.GetTitle().Len() && IsInReading() ) 384 // insert title of TOX 385 { 386 // then insert the headline section 387 SwNodeIndex aIdx( *pSectNd, +1 ); 388 389 SwTxtNode* pHeadNd = GetNodes().MakeTxtNode( aIdx, 390 GetTxtCollFromPool( RES_POOLCOLL_STANDARD ) ); 391 392 String sNm( pNewSection->GetTOXName() ); 393 // ??Resource 394 sNm.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "_Head" )); 395 396 SwSectionData headerData( TOX_HEADER_SECTION, sNm ); 397 398 SwNodeIndex aStt( *pHeadNd ); aIdx--; 399 SwSectionFmt* pSectFmt = MakeSectionFmt( 0 ); 400 GetNodes().InsertTextSection( 401 aStt, *pSectFmt, headerData, 0, &aIdx, true, false); 402 } 403 } 404 405 GetIDocumentUndoRedo().EndUndo( UNDO_INSTOX, NULL ); 406 407 return pNewSection; 408 } 409 410 411 412 const SwTOXBaseSection* SwDoc::InsertTableOf( sal_uLong nSttNd, sal_uLong nEndNd, 413 const SwTOXBase& rTOX, 414 const SfxItemSet* pSet ) 415 { 416 // check for recursiv TOX 417 SwNode* pNd = GetNodes()[ nSttNd ]; 418 SwSectionNode* pSectNd = pNd->FindSectionNode(); 419 while( pSectNd ) 420 { 421 SectionType eT = pSectNd->GetSection().GetType(); 422 if( TOX_HEADER_SECTION == eT || TOX_CONTENT_SECTION == eT ) 423 return 0; 424 pSectNd = pSectNd->StartOfSectionNode()->FindSectionNode(); 425 } 426 427 String sSectNm( rTOX.GetTOXName() ); 428 sSectNm = GetUniqueTOXBaseName(*rTOX.GetTOXType(), &sSectNm); 429 430 SwSectionData aSectionData( TOX_CONTENT_SECTION, sSectNm ); 431 432 SwNodeIndex aStt( GetNodes(), nSttNd ), aEnd( GetNodes(), nEndNd ); 433 SwSectionFmt* pFmt = MakeSectionFmt( 0 ); 434 if(pSet) 435 pFmt->SetFmtAttr(*pSet); 436 437 // --aEnd; // im InsertSection ist Ende inclusive 438 439 SwSectionNode *const pNewSectionNode = 440 GetNodes().InsertTextSection(aStt, *pFmt, aSectionData, &rTOX, &aEnd); 441 if (!pNewSectionNode) 442 { 443 DelSectionFmt( pFmt ); 444 return 0; 445 } 446 447 SwTOXBaseSection *const pNewSection( 448 dynamic_cast<SwTOXBaseSection*>(& pNewSectionNode->GetSection())); 449 pNewSection->SetTOXName(sSectNm); // rTOX may have had no name... 450 return pNewSection; 451 } 452 453 /*-------------------------------------------------------------------- 454 Beschreibung: Aktuelles Verzeichnis ermitteln 455 --------------------------------------------------------------------*/ 456 457 const SwTOXBase* SwDoc::GetCurTOX( const SwPosition& rPos ) const 458 { 459 const SwNode& rNd = rPos.nNode.GetNode(); 460 const SwSectionNode* pSectNd = rNd.FindSectionNode(); 461 while( pSectNd ) 462 { 463 SectionType eT = pSectNd->GetSection().GetType(); 464 if( TOX_CONTENT_SECTION == eT ) 465 { 466 ASSERT( pSectNd->GetSection().ISA( SwTOXBaseSection ), 467 "keine TOXBaseSection!" ); 468 SwTOXBaseSection& rTOXSect = (SwTOXBaseSection&) 469 pSectNd->GetSection(); 470 return &rTOXSect; 471 } 472 pSectNd = pSectNd->StartOfSectionNode()->FindSectionNode(); 473 } 474 return 0; 475 } 476 477 const SwAttrSet& SwDoc::GetTOXBaseAttrSet(const SwTOXBase& rTOXBase) const 478 { 479 ASSERT( rTOXBase.ISA( SwTOXBaseSection ), "no TOXBaseSection!" ); 480 const SwTOXBaseSection& rTOXSect = (const SwTOXBaseSection&)rTOXBase; 481 SwSectionFmt* pFmt = rTOXSect.GetFmt(); 482 ASSERT( pFmt, "invalid TOXBaseSection!" ); 483 return pFmt->GetAttrSet(); 484 } 485 486 const SwTOXBase* SwDoc::GetDefaultTOXBase( TOXTypes eTyp, sal_Bool bCreate ) 487 { 488 SwTOXBase** prBase = 0; 489 switch(eTyp) 490 { 491 case TOX_CONTENT: prBase = &pDefTOXBases->pContBase; break; 492 case TOX_INDEX: prBase = &pDefTOXBases->pIdxBase; break; 493 case TOX_USER: prBase = &pDefTOXBases->pUserBase; break; 494 case TOX_TABLES: prBase = &pDefTOXBases->pTblBase; break; 495 case TOX_OBJECTS: prBase = &pDefTOXBases->pObjBase; break; 496 case TOX_ILLUSTRATIONS: prBase = &pDefTOXBases->pIllBase; break; 497 case TOX_AUTHORITIES: prBase = &pDefTOXBases->pAuthBase; break; 498 } 499 if(!(*prBase) && bCreate) 500 { 501 SwForm aForm(eTyp); 502 const SwTOXType* pType = GetTOXType(eTyp, 0); 503 (*prBase) = new SwTOXBase(pType, aForm, 0, pType->GetTypeName()); 504 } 505 return (*prBase); 506 } 507 508 void SwDoc::SetDefaultTOXBase(const SwTOXBase& rBase) 509 { 510 SwTOXBase** prBase = 0; 511 switch(rBase.GetType()) 512 { 513 case TOX_CONTENT: prBase = &pDefTOXBases->pContBase; break; 514 case TOX_INDEX: prBase = &pDefTOXBases->pIdxBase; break; 515 case TOX_USER: prBase = &pDefTOXBases->pUserBase; break; 516 case TOX_TABLES: prBase = &pDefTOXBases->pTblBase; break; 517 case TOX_OBJECTS: prBase = &pDefTOXBases->pObjBase; break; 518 case TOX_ILLUSTRATIONS: prBase = &pDefTOXBases->pIllBase; break; 519 case TOX_AUTHORITIES: prBase = &pDefTOXBases->pAuthBase; break; 520 } 521 if(*prBase) 522 delete (*prBase); 523 (*prBase) = new SwTOXBase(rBase); 524 } 525 526 /*-------------------------------------------------------------------- 527 Beschreibung: Verzeichnis loeschen 528 --------------------------------------------------------------------*/ 529 530 531 sal_Bool SwDoc::DeleteTOX( const SwTOXBase& rTOXBase, sal_Bool bDelNodes ) 532 { 533 // its only delete the TOX, not the nodes 534 sal_Bool bRet = sal_False; 535 ASSERT( rTOXBase.ISA( SwTOXBaseSection ), "keine TOXBaseSection!" ); 536 537 const SwTOXBaseSection& rTOXSect = (const SwTOXBaseSection&)rTOXBase; 538 SwSectionFmt* pFmt = rTOXSect.GetFmt(); 539 if( pFmt ) 540 { 541 GetIDocumentUndoRedo().StartUndo( UNDO_CLEARTOXRANGE, NULL ); 542 543 /* Save the start node of the TOX' section. */ 544 SwSectionNode * pMyNode = pFmt->GetSectionNode(); 545 /* Save start node of section's surrounding. */ 546 SwNode * pStartNd = pMyNode->StartOfSectionNode(); 547 548 /* Look for point where to move the cursors in the area to 549 delete to. This is done by first searching forward from the 550 end of the TOX' section. If no content node is found behind 551 the TOX one is searched before it. If this is not 552 successfull, too, insert new text node behind the end of 553 the TOX' section. The cursors from the TOX' section will be 554 moved to the content node found or the new text node. */ 555 556 /* Set PaM to end of TOX' section and search following content node. 557 558 aSearchPam will contain the point where to move the cursors 559 to. */ 560 SwPaM aSearchPam(*pMyNode->EndOfSectionNode()); 561 SwPosition aEndPos(*pStartNd->EndOfSectionNode()); 562 if (! aSearchPam.Move() /* no content node found */ 563 || *aSearchPam.GetPoint() >= aEndPos /* content node found 564 outside surrounding */ 565 ) 566 { 567 /* Set PaM to beginning of TOX' section and search previous 568 content node */ 569 SwPaM aTmpPam(*pMyNode); 570 aSearchPam = aTmpPam; 571 SwPosition aStartPos(*pStartNd); 572 573 if ( ! aSearchPam.Move(fnMoveBackward) /* no content node found */ 574 || *aSearchPam.GetPoint() <= aStartPos /* content node 575 found outside 576 surrounding */ 577 ) 578 { 579 /* There is no content node in the surrounding of 580 TOX'. Append text node behind TOX' section. */ 581 582 SwPosition aInsPos(*pMyNode->EndOfSectionNode()); 583 AppendTxtNode(aInsPos); 584 585 SwPaM aTmpPam1(aInsPos); 586 aSearchPam = aTmpPam1; 587 } 588 } 589 590 591 /* PaM containing the TOX. */ 592 SwPaM aPam(*pMyNode->EndOfSectionNode(), *pMyNode); 593 594 /* Move cursors contained in TOX to point determined above. */ 595 PaMCorrAbs(aPam, *aSearchPam.GetPoint()); 596 597 if( !bDelNodes ) 598 { 599 SwSections aArr( 0, 4 ); 600 sal_uInt16 nCnt = pFmt->GetChildSections( aArr, SORTSECT_NOT, sal_False ); 601 for( sal_uInt16 n = 0; n < nCnt; ++n ) 602 { 603 SwSection* pSect = aArr[ n ]; 604 if( TOX_HEADER_SECTION == pSect->GetType() ) 605 { 606 DelSectionFmt( pSect->GetFmt(), bDelNodes ); 607 } 608 } 609 } 610 611 DelSectionFmt( pFmt, bDelNodes ); 612 613 GetIDocumentUndoRedo().EndUndo( UNDO_CLEARTOXRANGE, NULL ); 614 bRet = sal_True; 615 } 616 617 return bRet; 618 } 619 620 /*-------------------------------------------------------------------- 621 Beschreibung: Verzeichnistypen verwalten 622 --------------------------------------------------------------------*/ 623 624 sal_uInt16 SwDoc::GetTOXTypeCount(TOXTypes eTyp) const 625 { 626 const SwTOXTypePtr * ppTTypes = pTOXTypes->GetData(); 627 sal_uInt16 nCnt = 0; 628 for( sal_uInt16 n = 0; n < pTOXTypes->Count(); ++n, ++ppTTypes ) 629 if( eTyp == (*ppTTypes)->GetType() ) 630 ++nCnt; 631 return nCnt; 632 } 633 634 const SwTOXType* SwDoc::GetTOXType( TOXTypes eTyp, sal_uInt16 nId ) const 635 { 636 const SwTOXTypePtr * ppTTypes = pTOXTypes->GetData(); 637 sal_uInt16 nCnt = 0; 638 for( sal_uInt16 n = 0; n < pTOXTypes->Count(); ++n, ++ppTTypes ) 639 if( eTyp == (*ppTTypes)->GetType() && nCnt++ == nId ) 640 return (*ppTTypes); 641 return 0; 642 } 643 644 645 const SwTOXType* SwDoc::InsertTOXType( const SwTOXType& rTyp ) 646 { 647 SwTOXType * pNew = new SwTOXType( rTyp ); 648 pTOXTypes->Insert( pNew, pTOXTypes->Count() ); 649 return pNew; 650 } 651 652 String SwDoc::GetUniqueTOXBaseName( const SwTOXType& rType, 653 const String* pChkStr ) const 654 { 655 sal_uInt16 n; 656 const SwSectionNode* pSectNd; 657 const SwSection* pSect; 658 659 if(pChkStr && !pChkStr->Len()) 660 pChkStr = 0; 661 String aName( rType.GetTypeName() ); 662 xub_StrLen nNmLen = aName.Len(); 663 664 sal_uInt16 nNum = 0; 665 sal_uInt16 nTmp = 0; 666 sal_uInt16 nFlagSize = ( pSectionFmtTbl->Count() / 8 ) +2; 667 sal_uInt8* pSetFlags = new sal_uInt8[ nFlagSize ]; 668 memset( pSetFlags, 0, nFlagSize ); 669 670 for( n = 0; n < pSectionFmtTbl->Count(); ++n ) 671 if( 0 != ( pSectNd = (*pSectionFmtTbl)[ n ]->GetSectionNode( sal_False ) )&& 672 TOX_CONTENT_SECTION == (pSect = &pSectNd->GetSection())->GetType()) 673 { 674 const String& rNm = pSect->GetSectionName(); 675 if( rNm.Match( aName ) == nNmLen ) 676 { 677 // Nummer bestimmen und das Flag setzen 678 nNum = (sal_uInt16)rNm.Copy( nNmLen ).ToInt32(); 679 if( nNum-- && nNum < pSectionFmtTbl->Count() ) 680 pSetFlags[ nNum / 8 ] |= (0x01 << ( nNum & 0x07 )); 681 } 682 if( pChkStr && pChkStr->Equals( rNm ) ) 683 pChkStr = 0; 684 } 685 686 if( !pChkStr ) 687 { 688 // alle Nummern entsprechend geflag, also bestimme die richtige Nummer 689 nNum = pSectionFmtTbl->Count(); 690 for( n = 0; n < nFlagSize; ++n ) 691 if( 0xff != ( nTmp = pSetFlags[ n ] )) 692 { 693 // also die Nummer bestimmen 694 nNum = n * 8; 695 while( nTmp & 1 ) 696 ++nNum, nTmp >>= 1; 697 break; 698 } 699 } 700 delete [] pSetFlags; 701 if( pChkStr ) 702 return *pChkStr; 703 return aName += String::CreateFromInt32( ++nNum ); 704 } 705 706 sal_Bool SwDoc::SetTOXBaseName(const SwTOXBase& rTOXBase, const String& rName) 707 { 708 ASSERT( rTOXBase.ISA( SwTOXBaseSection ), 709 "keine TOXBaseSection!" ); 710 SwTOXBaseSection* pTOX = (SwTOXBaseSection*)&rTOXBase; 711 712 String sTmp = GetUniqueTOXBaseName(*rTOXBase.GetTOXType(), &rName); 713 sal_Bool bRet = sTmp == rName; 714 if(bRet) 715 { 716 pTOX->SetTOXName(rName); 717 pTOX->SetSectionName(rName); 718 SetModified(); 719 } 720 return bRet; 721 } 722 723 724 const SwTxtNode* lcl_FindChapterNode( const SwNode& rNd, sal_uInt8 nLvl = 0 ) 725 { 726 const SwNode* pNd = &rNd; 727 if( pNd->GetNodes().GetEndOfExtras().GetIndex() > pNd->GetIndex() ) 728 { 729 // then find the "Anchor" (Body) position 730 Point aPt; 731 SwNode2Layout aNode2Layout( *pNd, pNd->GetIndex() ); 732 const SwFrm* pFrm = aNode2Layout.GetFrm( &aPt, 0, sal_False ); 733 734 if( pFrm ) 735 { 736 SwPosition aPos( *pNd ); 737 pNd = GetBodyTxtNode( *pNd->GetDoc(), aPos, *pFrm ); 738 ASSERT( pNd, "wo steht der Absatz" ); 739 } 740 } 741 return pNd ? pNd->FindOutlineNodeOfLevel( nLvl ) : 0; 742 } 743 744 745 /*-------------------------------------------------------------------- 746 Beschreibung: Verzeichnis-Klasse 747 --------------------------------------------------------------------*/ 748 749 SwTOXBaseSection::SwTOXBaseSection(SwTOXBase const& rBase, SwSectionFmt & rFmt) 750 : SwTOXBase( rBase ) 751 , SwSection( TOX_CONTENT_SECTION, aEmptyStr, rFmt ) 752 { 753 SetProtect( rBase.IsProtected() ); 754 SetSectionName( GetTOXName() ); 755 } 756 757 758 SwTOXBaseSection::~SwTOXBaseSection() 759 { 760 aSortArr.DeleteAndDestroy( 0, aSortArr.Count() ); // i120680 761 } 762 763 764 sal_Bool SwTOXBaseSection::SetPosAtStartEnd( SwPosition& rPos, sal_Bool bAtStart ) const 765 { 766 sal_Bool bRet = sal_False; 767 const SwSectionNode* pSectNd = GetFmt()->GetSectionNode(); 768 if( pSectNd ) 769 { 770 SwCntntNode* pCNd; 771 xub_StrLen nC = 0; 772 if( bAtStart ) 773 { 774 rPos.nNode = *pSectNd; 775 pCNd = pSectNd->GetDoc()->GetNodes().GoNext( &rPos.nNode ); 776 } 777 else 778 { 779 rPos.nNode = *pSectNd->EndOfSectionNode(); 780 pCNd = pSectNd->GetDoc()->GetNodes().GoPrevious( &rPos.nNode ); 781 if( pCNd ) nC = pCNd->Len(); 782 } 783 rPos.nContent.Assign( pCNd, nC ); 784 bRet = sal_True; 785 } 786 return bRet; 787 } 788 789 /*-------------------------------------------------------------------- 790 Beschreibung: Verzeichnisinhalt zusammensammeln 791 --------------------------------------------------------------------*/ 792 793 void SwTOXBaseSection::Update(const SfxItemSet* pAttr, 794 const bool _bNewTOX )//swmodtest 080307 795 { 796 const SwSectionNode* pSectNd; 797 if( !SwTOXBase::GetRegisteredIn()->GetDepends() || 798 !GetFmt() || 0 == (pSectNd = GetFmt()->GetSectionNode() ) || 799 !pSectNd->GetNodes().IsDocNodes() || 800 IsHiddenFlag() ) 801 { 802 return; 803 } 804 805 if ( !mbKeepExpression ) 806 { 807 maMSTOCExpression = String(); 808 } 809 810 SwDoc* pDoc = (SwDoc*)pSectNd->GetDoc(); 811 812 DBG_ASSERT(pDoc != NULL, "Where is the document?"); 813 814 if(pAttr && pDoc && GetFmt()) 815 pDoc->ChgFmt(*GetFmt(), *pAttr); 816 817 // OD 18.03.2003 #106329# - determine default page description, which 818 // will be used by the content nodes, if no approriate one is found. 819 const SwPageDesc* pDefaultPageDesc; 820 { 821 pDefaultPageDesc = 822 pSectNd->GetSection().GetFmt()->GetPageDesc().GetPageDesc(); 823 if ( !_bNewTOX && !pDefaultPageDesc ) 824 { 825 // determine page description of table-of-content 826 sal_uInt32 nPgDescNdIdx = pSectNd->GetIndex() + 1; 827 sal_uInt32* pPgDescNdIdx = &nPgDescNdIdx; 828 pDefaultPageDesc = pSectNd->FindPageDesc( sal_False, pPgDescNdIdx ); 829 if ( nPgDescNdIdx < pSectNd->GetIndex() ) 830 { 831 pDefaultPageDesc = 0; 832 } 833 } 834 // OD 28.04.2003 #109166# - consider end node of content section in the 835 // node array. 836 if ( !pDefaultPageDesc && 837 ( pSectNd->EndOfSectionNode()->GetIndex() < 838 (pSectNd->GetNodes().GetEndOfContent().GetIndex() - 1) ) 839 ) 840 { 841 // determine page description of content after table-of-content 842 SwNodeIndex aIdx( *(pSectNd->EndOfSectionNode()) ); 843 const SwCntntNode* pNdAfterTOX = pSectNd->GetNodes().GoNext( &aIdx ); 844 const SwAttrSet& aNdAttrSet = pNdAfterTOX->GetSwAttrSet(); 845 const SvxBreak eBreak = aNdAttrSet.GetBreak().GetBreak(); 846 if ( !( eBreak == SVX_BREAK_PAGE_BEFORE || 847 eBreak == SVX_BREAK_PAGE_BOTH ) 848 ) 849 { 850 pDefaultPageDesc = pNdAfterTOX->FindPageDesc( sal_False ); 851 } 852 } 853 // OD 28.04.2003 #109166# - consider start node of content section in 854 // the node array. 855 if ( !pDefaultPageDesc && 856 ( pSectNd->GetIndex() > 857 (pSectNd->GetNodes().GetEndOfContent().StartOfSectionIndex() + 1) ) 858 ) 859 { 860 // determine page description of content before table-of-content 861 SwNodeIndex aIdx( *pSectNd ); 862 pDefaultPageDesc = 863 pSectNd->GetNodes().GoPrevious( &aIdx )->FindPageDesc( sal_False ); 864 865 } 866 if ( !pDefaultPageDesc ) 867 { 868 // determine default page description 869 pDefaultPageDesc = 870 &const_cast<const SwDoc *>(pDoc)->GetPageDesc( 0 ); 871 } 872 } 873 874 pDoc->SetModified(); 875 876 // get current Language 877 SwTOXInternational aIntl( GetLanguage(), 878 TOX_INDEX == GetTOXType()->GetType() ? 879 GetOptions() : 0, 880 GetSortAlgorithm() ); 881 882 aSortArr.DeleteAndDestroy( 0, aSortArr.Count() ); 883 884 // find the first layout node for this TOX, if it only find the content 885 // in his own chapter 886 const SwTxtNode* pOwnChapterNode = IsFromChapter() 887 ? ::lcl_FindChapterNode( *pSectNd, 0 ) 888 : 0; 889 890 SwNode2Layout aN2L( *pSectNd ); 891 ((SwSectionNode*)pSectNd)->DelFrms(); 892 893 // remove old content an insert one empty textnode (to hold the layout!) 894 SwTxtNode* pFirstEmptyNd; 895 { 896 pDoc->DeleteRedline( *pSectNd, true, USHRT_MAX ); 897 898 SwNodeIndex aSttIdx( *pSectNd, +1 ); 899 SwNodeIndex aEndIdx( *pSectNd->EndOfSectionNode() ); 900 pFirstEmptyNd = pDoc->GetNodes().MakeTxtNode( aEndIdx, 901 pDoc->GetTxtCollFromPool( RES_POOLCOLL_TEXT ) ); 902 903 { 904 // Task 70995 - save and restore PageDesc and Break Attributes 905 SwNodeIndex aNxtIdx( aSttIdx ); 906 const SwCntntNode* pCNd = aNxtIdx.GetNode().GetCntntNode(); 907 if( !pCNd ) 908 pCNd = pDoc->GetNodes().GoNext( &aNxtIdx ); 909 if( pCNd->HasSwAttrSet() ) 910 { 911 SfxItemSet aBrkSet( pDoc->GetAttrPool(), aBreakSetRange ); 912 aBrkSet.Put( *pCNd->GetpSwAttrSet() ); 913 if( aBrkSet.Count() ) 914 pFirstEmptyNd->SetAttr( aBrkSet ); 915 } 916 } 917 aEndIdx--; 918 SwPosition aPos( aEndIdx, SwIndex( pFirstEmptyNd, 0 )); 919 pDoc->CorrAbs( aSttIdx, aEndIdx, aPos, sal_True ); 920 921 // delete all before 922 DelFlyInRange( aSttIdx, aEndIdx ); 923 _DelBookmarks( aSttIdx, aEndIdx ); 924 925 pDoc->GetNodes().Delete( aSttIdx, aEndIdx.GetIndex() - aSttIdx.GetIndex() ); 926 927 } 928 929 // 930 // insert title of TOX 931 if( GetTitle().Len() ) 932 { 933 // then insert the headline section 934 SwNodeIndex aIdx( *pSectNd, +1 ); 935 936 SwTxtNode* pHeadNd = pDoc->GetNodes().MakeTxtNode( aIdx, 937 GetTxtFmtColl( FORM_TITLE ) ); 938 pHeadNd->InsertText( GetTitle(), SwIndex( pHeadNd ) ); 939 940 String sNm( GetTOXName() ); 941 // ??Resource 942 sNm.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "_Head" )); 943 944 SwSectionData headerData( TOX_HEADER_SECTION, sNm ); 945 946 SwNodeIndex aStt( *pHeadNd ); aIdx--; 947 SwSectionFmt* pSectFmt = pDoc->MakeSectionFmt( 0 ); 948 pDoc->GetNodes().InsertTextSection( 949 aStt, *pSectFmt, headerData, 0, &aIdx, true, false); 950 } 951 952 // jetzt waere ein prima Zeitpunkt, um die Numerierung zu updaten 953 pDoc->UpdateNumRule(); 954 955 if( GetCreateType() & nsSwTOXElement::TOX_MARK ) 956 UpdateMarks( aIntl, pOwnChapterNode ); 957 958 if( GetCreateType() & nsSwTOXElement::TOX_OUTLINELEVEL ) 959 UpdateOutline( pOwnChapterNode ); 960 961 if( GetCreateType() & nsSwTOXElement::TOX_TEMPLATE ) 962 UpdateTemplate( pOwnChapterNode ); 963 964 if( GetCreateType() & nsSwTOXElement::TOX_OLE || 965 TOX_OBJECTS == SwTOXBase::GetType()) 966 UpdateCntnt( nsSwTOXElement::TOX_OLE, pOwnChapterNode ); 967 968 if( GetCreateType() & nsSwTOXElement::TOX_TABLE || 969 (TOX_TABLES == SwTOXBase::GetType() && IsFromObjectNames()) ) 970 UpdateTable( pOwnChapterNode ); 971 972 if( GetCreateType() & nsSwTOXElement::TOX_GRAPHIC || 973 (TOX_ILLUSTRATIONS == SwTOXBase::GetType() && IsFromObjectNames())) 974 UpdateCntnt( nsSwTOXElement::TOX_GRAPHIC, pOwnChapterNode ); 975 976 if( GetSequenceName().Len() && !IsFromObjectNames() && 977 (TOX_TABLES == SwTOXBase::GetType() || 978 TOX_ILLUSTRATIONS == SwTOXBase::GetType() ) ) 979 UpdateSequence( pOwnChapterNode ); 980 981 if( GetCreateType() & nsSwTOXElement::TOX_FRAME ) 982 UpdateCntnt( nsSwTOXElement::TOX_FRAME, pOwnChapterNode ); 983 984 if(TOX_AUTHORITIES == SwTOXBase::GetType()) 985 UpdateAuthorities( aIntl ); 986 987 // Bei Bedarf Alphadelimitter einfuegen (nur bei Stichwoertern) 988 // 989 if( TOX_INDEX == SwTOXBase::GetType() && 990 ( GetOptions() & nsSwTOIOptions::TOI_ALPHA_DELIMITTER ) ) 991 InsertAlphaDelimitter( aIntl ); 992 993 // sortierte Liste aller Verzeichnismarken und Verzeichnisbereiche 994 void* p = 0; 995 String* pStr = 0; 996 sal_uInt16 nCnt = 0, nFormMax = GetTOXForm().GetFormMax(); 997 SvStringsDtor aStrArr( (sal_uInt8)nFormMax ); 998 SvPtrarr aCollArr( (sal_uInt8)nFormMax ); 999 for( ; nCnt < nFormMax; ++nCnt ) 1000 { 1001 aCollArr.Insert( p, nCnt ); 1002 aStrArr.Insert( pStr, nCnt ); 1003 } 1004 1005 SwNodeIndex aInsPos( *pFirstEmptyNd, 1 ); 1006 for( nCnt = 0; nCnt < aSortArr.Count(); ++nCnt ) 1007 { 1008 ::SetProgressState( 0, pDoc->GetDocShell() ); 1009 1010 // setze den Text in das Verzeichniss 1011 sal_uInt16 nLvl = aSortArr[ nCnt ]->GetLevel(); 1012 SwTxtFmtColl* pColl = (SwTxtFmtColl*)aCollArr[ nLvl ]; 1013 if( !pColl ) 1014 { 1015 pColl = GetTxtFmtColl( nLvl ); 1016 aCollArr.Remove( nLvl ); 1017 p = pColl; 1018 aCollArr.Insert( p , nLvl ); 1019 } 1020 1021 // Generierung: dynamische TabStops setzen 1022 SwTxtNode* pTOXNd = pDoc->GetNodes().MakeTxtNode( aInsPos , pColl ); 1023 aSortArr[ nCnt ]->pTOXNd = pTOXNd; 1024 1025 // Generierung: Form auswerten und Platzhalter 1026 // fuer die Seitennummer eintragen 1027 //if it is a TOX_INDEX and the SwForm IsCommaSeparated() 1028 // then a range of entries must be generated into one paragraph 1029 sal_uInt16 nRange = 1; 1030 if(TOX_INDEX == SwTOXBase::GetType() && 1031 GetTOXForm().IsCommaSeparated() && 1032 aSortArr[nCnt]->GetType() == TOX_SORT_INDEX) 1033 { 1034 const SwTOXMark& rMark = aSortArr[nCnt]->pTxtMark->GetTOXMark(); 1035 const String sPrimKey = rMark.GetPrimaryKey(); 1036 const String sSecKey = rMark.GetSecondaryKey(); 1037 const SwTOXMark* pNextMark = 0; 1038 while(aSortArr.Count() > (nCnt + nRange)&& 1039 aSortArr[nCnt + nRange]->GetType() == TOX_SORT_INDEX && 1040 0 != (pNextMark = &(aSortArr[nCnt + nRange]->pTxtMark->GetTOXMark())) && 1041 pNextMark->GetPrimaryKey() == sPrimKey && 1042 pNextMark->GetSecondaryKey() == sSecKey) 1043 nRange++; 1044 } 1045 // OD 18.03.2003 #106329# - pass node index of table-of-content section 1046 // and default page description to method <GenerateText(..)>. 1047 GenerateText( nCnt, nRange, aStrArr, pSectNd->GetIndex(), pDefaultPageDesc ); 1048 nCnt += nRange - 1; 1049 } 1050 1051 // delete the first dummy node and remove all Cursor into the prev node 1052 aInsPos = *pFirstEmptyNd; 1053 { 1054 SwPaM aCorPam( *pFirstEmptyNd ); 1055 aCorPam.GetPoint()->nContent.Assign( pFirstEmptyNd, 0 ); 1056 if( !aCorPam.Move( fnMoveForward ) ) 1057 aCorPam.Move( fnMoveBackward ); 1058 SwNodeIndex aEndIdx( aInsPos, 1 ); 1059 pDoc->CorrAbs( aInsPos, aEndIdx, *aCorPam.GetPoint(), sal_True ); 1060 1061 // Task 70995 - save and restore PageDesc and Break Attributes 1062 if( pFirstEmptyNd->HasSwAttrSet() ) 1063 { 1064 if( GetTitle().Len() ) 1065 aEndIdx = *pSectNd; 1066 else 1067 aEndIdx = *pFirstEmptyNd; 1068 SwCntntNode* pCNd = pDoc->GetNodes().GoNext( &aEndIdx ); 1069 if( pCNd ) // Robust against defect documents, e.g. i60336 1070 pCNd->SetAttr( *pFirstEmptyNd->GetpSwAttrSet() ); 1071 } 1072 } 1073 1074 // now create the new Frames 1075 sal_uLong nIdx = pSectNd->GetIndex(); 1076 // don't delete if index is empty 1077 if(nIdx + 2 < pSectNd->EndOfSectionIndex()) 1078 pDoc->GetNodes().Delete( aInsPos, 1 ); 1079 1080 aN2L.RestoreUpperFrms( pDoc->GetNodes(), nIdx, nIdx + 1 ); 1081 std::set<SwRootFrm*> aAllLayouts = pDoc->GetAllLayouts(); 1082 for ( std::set<SwRootFrm*>::iterator pLayoutIter = aAllLayouts.begin(); pLayoutIter != aAllLayouts.end(); pLayoutIter++) 1083 { 1084 SwFrm::CheckPageDescs( (SwPageFrm*)(*pLayoutIter)->Lower() ); 1085 }//swmod 080310 1086 1087 SetProtect( SwTOXBase::IsProtected() ); 1088 } 1089 1090 /*-------------------------------------------------------------------- 1091 Beschreibung: AlphaDelimitter einfuegen 1092 --------------------------------------------------------------------*/ 1093 1094 1095 void SwTOXBaseSection::InsertAlphaDelimitter( const SwTOXInternational& rIntl ) 1096 { 1097 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); 1098 String sDeli, sLastDeli; 1099 sal_uInt16 i = 0; 1100 while( i < aSortArr.Count() ) 1101 { 1102 ::SetProgressState( 0, pDoc->GetDocShell() ); 1103 1104 sal_uInt16 nLevel = aSortArr[i]->GetLevel(); 1105 1106 // Alpha-Delimitter ueberlesen 1107 if( nLevel == FORM_ALPHA_DELIMITTER ) 1108 continue; 1109 1110 String sMyString, sMyStringReading; 1111 aSortArr[i]->GetTxt( sMyString, sMyStringReading ); 1112 1113 sDeli = rIntl.GetIndexKey( sMyString, sMyStringReading, 1114 aSortArr[i]->GetLocale() ); 1115 1116 // Delimitter schon vorhanden ?? 1117 if( sDeli.Len() && sLastDeli != sDeli ) 1118 { 1119 // alle kleiner Blank wollen wir nicht haben -> sind Sonderzeichen 1120 if( ' ' <= sDeli.GetChar( 0 ) ) 1121 { 1122 SwTOXCustom* pCst = new SwTOXCustom( sDeli, aEmptyStr, FORM_ALPHA_DELIMITTER, 1123 rIntl, aSortArr[i]->GetLocale() ); 1124 aSortArr.Insert( pCst, i++ ); 1125 } 1126 sLastDeli = sDeli; 1127 } 1128 1129 // Skippen bis gleibhes oder kleineres Level erreicht ist 1130 do { 1131 i++; 1132 } while (i < aSortArr.Count() && aSortArr[i]->GetLevel() > nLevel); 1133 } 1134 } 1135 1136 /*-------------------------------------------------------------------- 1137 Beschreibung: Template auswerten 1138 --------------------------------------------------------------------*/ 1139 1140 SwTxtFmtColl* SwTOXBaseSection::GetTxtFmtColl( sal_uInt16 nLevel ) 1141 { 1142 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); 1143 const String& rName = GetTOXForm().GetTemplate( nLevel ); 1144 SwTxtFmtColl* pColl = rName.Len() ? pDoc->FindTxtFmtCollByName(rName) :0; 1145 if( !pColl ) 1146 { 1147 sal_uInt16 nPoolFmt = 0; 1148 const TOXTypes eMyType = SwTOXBase::GetType(); 1149 switch( eMyType ) 1150 { 1151 case TOX_INDEX: nPoolFmt = RES_POOLCOLL_TOX_IDXH; break; 1152 case TOX_USER: 1153 if( nLevel < 6 ) 1154 nPoolFmt = RES_POOLCOLL_TOX_USERH; 1155 else 1156 nPoolFmt = RES_POOLCOLL_TOX_USER6 - 6; 1157 break; 1158 case TOX_ILLUSTRATIONS: nPoolFmt = RES_POOLCOLL_TOX_ILLUSH; break; 1159 case TOX_OBJECTS: nPoolFmt = RES_POOLCOLL_TOX_OBJECTH; break; 1160 case TOX_TABLES: nPoolFmt = RES_POOLCOLL_TOX_TABLESH; break; 1161 case TOX_AUTHORITIES: nPoolFmt = RES_POOLCOLL_TOX_AUTHORITIESH; break; 1162 1163 case TOX_CONTENT: 1164 // im Content Bereich gibt es einen Sprung! 1165 if( nLevel < 6 ) 1166 nPoolFmt = RES_POOLCOLL_TOX_CNTNTH; 1167 else 1168 nPoolFmt = RES_POOLCOLL_TOX_CNTNT6 - 6; 1169 break; 1170 } 1171 1172 if(eMyType == TOX_AUTHORITIES && nLevel) 1173 nPoolFmt = nPoolFmt + 1; 1174 else if(eMyType == TOX_INDEX && nLevel) 1175 { 1176 //pool: Level 1,2,3, Delimiter 1177 //SwForm: Delimiter, Level 1,2,3 1178 nPoolFmt += 1 == nLevel ? nLevel + 3 : nLevel - 1; 1179 } 1180 else 1181 nPoolFmt = nPoolFmt + nLevel; 1182 pColl = pDoc->GetTxtCollFromPool( nPoolFmt ); 1183 } 1184 return pColl; 1185 } 1186 1187 1188 /*-------------------------------------------------------------------- 1189 Beschreibung: Aus Markierungen erzeugen 1190 --------------------------------------------------------------------*/ 1191 1192 void SwTOXBaseSection::UpdateMarks( const SwTOXInternational& rIntl, 1193 const SwTxtNode* pOwnChapterNode ) 1194 { 1195 const SwTOXType* pType = (SwTOXType*) SwTOXBase::GetRegisteredIn(); 1196 if( !pType->GetDepends() ) 1197 return; 1198 1199 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); 1200 TOXTypes eTOXTyp = GetTOXType()->GetType(); 1201 SwIterator<SwTOXMark,SwTOXType> aIter( *pType ); 1202 1203 SwTxtTOXMark* pTxtMark; 1204 SwTOXMark* pMark; 1205 for( pMark = aIter.First(); pMark; pMark = aIter.Next() ) 1206 { 1207 ::SetProgressState( 0, pDoc->GetDocShell() ); 1208 1209 if( pMark->GetTOXType()->GetType() == eTOXTyp && 1210 0 != ( pTxtMark = pMark->GetTxtTOXMark() ) ) 1211 { 1212 const SwTxtNode* pTOXSrc = pTxtMark->GetpTxtNd(); 1213 // nur TOXMarks einfuegen die im Doc stehen 1214 // nicht die, die im UNDO stehen 1215 // 1216 // if selected use marks from the same chapter only 1217 if( pTOXSrc->GetNodes().IsDocNodes() && 1218 pTOXSrc->GetTxt().Len() && pTOXSrc->GetDepends() && 1219 pTOXSrc->getLayoutFrm( pDoc->GetCurrentLayout() ) && 1220 (!IsFromChapter() || ::lcl_FindChapterNode( *pTOXSrc, 0 ) == pOwnChapterNode ) && 1221 !pTOXSrc->HasHiddenParaField() && 1222 !SwScriptInfo::IsInHiddenRange( *pTOXSrc, *pTxtMark->GetStart() ) ) 1223 { 1224 SwTOXSortTabBase* pBase = 0; 1225 if(TOX_INDEX == eTOXTyp) 1226 { 1227 // Stichwortverzeichnismarkierung 1228 lang::Locale aLocale; 1229 if ( pBreakIt->GetBreakIter().is() ) 1230 { 1231 aLocale = pBreakIt->GetLocale( 1232 pTOXSrc->GetLang( *pTxtMark->GetStart() ) ); 1233 } 1234 1235 pBase = new SwTOXIndex( *pTOXSrc, pTxtMark, 1236 GetOptions(), FORM_ENTRY, rIntl, aLocale ); 1237 InsertSorted(pBase); 1238 if(GetOptions() & nsSwTOIOptions::TOI_KEY_AS_ENTRY && 1239 pTxtMark->GetTOXMark().GetPrimaryKey().Len()) 1240 { 1241 pBase = new SwTOXIndex( *pTOXSrc, pTxtMark, 1242 GetOptions(), FORM_PRIMARY_KEY, rIntl, aLocale ); 1243 InsertSorted(pBase); 1244 if(pTxtMark->GetTOXMark().GetSecondaryKey().Len()) 1245 { 1246 pBase = new SwTOXIndex( *pTOXSrc, pTxtMark, 1247 GetOptions(), FORM_SECONDARY_KEY, rIntl, aLocale ); 1248 InsertSorted(pBase); 1249 } 1250 } 1251 } 1252 else if( TOX_USER == eTOXTyp || 1253 pMark->GetLevel() <= GetLevel()) 1254 { // Inhaltsberzeichnismarkierung 1255 // also used for user marks 1256 pBase = new SwTOXContent( *pTOXSrc, pTxtMark, rIntl ); 1257 InsertSorted(pBase); 1258 } 1259 } 1260 } 1261 } 1262 } 1263 1264 1265 /*-------------------------------------------------------------------- 1266 Beschreibung: Verzeichnisinhalt aus Gliederungsebene generieren 1267 --------------------------------------------------------------------*/ 1268 1269 1270 void SwTOXBaseSection::UpdateOutline( const SwTxtNode* pOwnChapterNode ) 1271 { 1272 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); 1273 SwNodes& rNds = pDoc->GetNodes(); 1274 1275 const SwOutlineNodes& rOutlNds = rNds.GetOutLineNds(); 1276 for( sal_uInt16 n = 0; n < rOutlNds.Count(); ++n ) 1277 { 1278 ::SetProgressState( 0, pDoc->GetDocShell() ); 1279 SwTxtNode* pTxtNd = rOutlNds[ n ]->GetTxtNode(); 1280 if( pTxtNd && pTxtNd->Len() && pTxtNd->GetDepends() && 1281 //sal_uInt16(pTxtNd->GetTxtColl()->GetOutlineLevel()+1) <= GetLevel() && //#outline level,zhaojianwei 1282 sal_uInt16( pTxtNd->GetAttrOutlineLevel()) <= GetLevel() && //<-end,zhaojianwei 1283 pTxtNd->getLayoutFrm( pDoc->GetCurrentLayout() ) && 1284 !pTxtNd->HasHiddenParaField() && 1285 !pTxtNd->HasHiddenCharAttribute( true ) && 1286 ( !IsFromChapter() || 1287 ::lcl_FindChapterNode( *pTxtNd, 0 ) == pOwnChapterNode )) 1288 { 1289 SwTOXPara * pNew = new SwTOXPara( *pTxtNd, nsSwTOXElement::TOX_OUTLINELEVEL ); 1290 InsertSorted( pNew ); 1291 } 1292 } 1293 } 1294 1295 /*-------------------------------------------------------------------- 1296 Beschreibung: Verzeichnisinhalt aus Vorlagenbereichen generieren 1297 --------------------------------------------------------------------*/ 1298 1299 void SwTOXBaseSection::UpdateTemplate( const SwTxtNode* pOwnChapterNode ) 1300 { 1301 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); 1302 for(sal_uInt16 i = 0; i < MAXLEVEL; i++) 1303 { 1304 String sTmpStyleNames = GetStyleNames(i); 1305 sal_uInt16 nTokenCount = sTmpStyleNames.GetTokenCount(TOX_STYLE_DELIMITER); 1306 for( sal_uInt16 nStyle = 0; nStyle < nTokenCount; ++nStyle ) 1307 { 1308 SwTxtFmtColl* pColl = pDoc->FindTxtFmtCollByName( 1309 sTmpStyleNames.GetToken( nStyle, 1310 TOX_STYLE_DELIMITER )); 1311 //TODO: no outline Collections in content indexes if OutlineLevels are already included 1312 if( !pColl || 1313 ( TOX_CONTENT == SwTOXBase::GetType() && 1314 GetCreateType() & nsSwTOXElement::TOX_OUTLINELEVEL && 1315 //NO_NUMBERING != pColl->GetOutlineLevel() ) )//#outline level,zhaojianwei 1316 pColl->IsAssignedToListLevelOfOutlineStyle()) )//<-end,zhaojianwei 1317 continue; 1318 1319 SwIterator<SwTxtNode,SwFmtColl> aIter( *pColl ); 1320 for( SwTxtNode* pTxtNd = aIter.First(); pTxtNd; pTxtNd = aIter.Next() ) 1321 { 1322 ::SetProgressState( 0, pDoc->GetDocShell() ); 1323 1324 if( pTxtNd->GetTxt().Len() && pTxtNd->getLayoutFrm( pDoc->GetCurrentLayout() ) && 1325 pTxtNd->GetNodes().IsDocNodes() && 1326 ( !IsFromChapter() || pOwnChapterNode == 1327 ::lcl_FindChapterNode( *pTxtNd, 0 ) ) ) 1328 { 1329 SwTOXPara * pNew = new SwTOXPara( *pTxtNd, nsSwTOXElement::TOX_TEMPLATE, i + 1 ); 1330 InsertSorted(pNew); 1331 } 1332 } 1333 } 1334 } 1335 } 1336 1337 /* -----------------14.07.99 09:59------------------- 1338 Description: generate content from sequence fields 1339 --------------------------------------------------*/ 1340 void SwTOXBaseSection::UpdateSequence( const SwTxtNode* pOwnChapterNode ) 1341 { 1342 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); 1343 SwFieldType* pSeqFld = pDoc->GetFldType(RES_SETEXPFLD, GetSequenceName(), false); 1344 if(!pSeqFld) 1345 return; 1346 1347 SwIterator<SwFmtFld,SwFieldType> aIter( *pSeqFld ); 1348 for( SwFmtFld* pFmtFld = aIter.First(); pFmtFld; pFmtFld = aIter.Next() ) 1349 { 1350 const SwTxtFld* pTxtFld = pFmtFld->GetTxtFld(); 1351 if(!pTxtFld) 1352 continue; 1353 const SwTxtNode& rTxtNode = pTxtFld->GetTxtNode(); 1354 ::SetProgressState( 0, pDoc->GetDocShell() ); 1355 1356 if( rTxtNode.GetTxt().Len() && rTxtNode.getLayoutFrm( pDoc->GetCurrentLayout() ) && 1357 rTxtNode.GetNodes().IsDocNodes() && 1358 ( !IsFromChapter() || 1359 ::lcl_FindChapterNode( rTxtNode, 0 ) == pOwnChapterNode ) ) 1360 { 1361 SwTOXPara * pNew = new SwTOXPara( rTxtNode, nsSwTOXElement::TOX_SEQUENCE, 1 ); 1362 //set indexes if the number or the reference text are to be displayed 1363 if( GetCaptionDisplay() == CAPTION_TEXT ) 1364 { 1365 pNew->SetStartIndex( 1366 SwGetExpField::GetReferenceTextPos( *pFmtFld, *pDoc )); 1367 } 1368 else if(GetCaptionDisplay() == CAPTION_NUMBER) 1369 { 1370 pNew->SetEndIndex(*pTxtFld->GetStart() + 1); 1371 } 1372 InsertSorted(pNew); 1373 } 1374 } 1375 } 1376 1377 void SwTOXBaseSection::UpdateAuthorities( const SwTOXInternational& rIntl ) 1378 { 1379 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); 1380 SwFieldType* pAuthFld = pDoc->GetFldType(RES_AUTHORITY, aEmptyStr, false); 1381 if(!pAuthFld) 1382 return; 1383 1384 SwIterator<SwFmtFld,SwFieldType> aIter( *pAuthFld ); 1385 for( SwFmtFld* pFmtFld = aIter.First(); pFmtFld; pFmtFld = aIter.Next() ) 1386 { 1387 const SwTxtFld* pTxtFld = pFmtFld->GetTxtFld(); 1388 //undo 1389 if(!pTxtFld) 1390 continue; 1391 const SwTxtNode& rTxtNode = pTxtFld->GetTxtNode(); 1392 ::SetProgressState( 0, pDoc->GetDocShell() ); 1393 1394 // const SwTxtNode* pChapterCompareNode = 0; 1395 1396 if( rTxtNode.GetTxt().Len() && rTxtNode.getLayoutFrm( pDoc->GetCurrentLayout() ) && 1397 rTxtNode.GetNodes().IsDocNodes() /*&& 1398 (!IsFromChapter() || pChapterCompareNode == pOwnChapterNode) */) 1399 { 1400 //#106485# the body node has to be used! 1401 SwCntntFrm *pFrm = rTxtNode.getLayoutFrm( pDoc->GetCurrentLayout() ); 1402 SwPosition aFldPos(rTxtNode); 1403 const SwTxtNode* pTxtNode = 0; 1404 if(pFrm && !pFrm->IsInDocBody()) 1405 pTxtNode = GetBodyTxtNode( *pDoc, aFldPos, *pFrm ); 1406 if(!pTxtNode) 1407 pTxtNode = &rTxtNode; 1408 SwTOXAuthority* pNew = new SwTOXAuthority( *pTxtNode, *pFmtFld, rIntl ); 1409 1410 InsertSorted(pNew); 1411 } 1412 } 1413 } 1414 1415 long lcl_IsSOObject( const SvGlobalName& rFactoryNm ) 1416 { 1417 static struct _SoObjType { 1418 long nFlag; 1419 // GlobalNameId 1420 struct _GlobalNameIds { 1421 sal_uInt32 n1; 1422 sal_uInt16 n2, n3; 1423 sal_uInt8 b8, b9, b10, b11, b12, b13, b14, b15; 1424 } aGlNmIds[4]; 1425 } aArr[] = { 1426 { nsSwTOOElements::TOO_MATH, 1427 { {SO3_SM_CLASSID_60},{SO3_SM_CLASSID_50}, 1428 {SO3_SM_CLASSID_40},{SO3_SM_CLASSID_30} } }, 1429 { nsSwTOOElements::TOO_CHART, 1430 { {SO3_SCH_CLASSID_60},{SO3_SCH_CLASSID_50}, 1431 {SO3_SCH_CLASSID_40},{SO3_SCH_CLASSID_30} } }, 1432 { nsSwTOOElements::TOO_CALC, 1433 { {SO3_SC_CLASSID_60},{SO3_SC_CLASSID_50}, 1434 {SO3_SC_CLASSID_40},{SO3_SC_CLASSID_30} } }, 1435 { nsSwTOOElements::TOO_DRAW_IMPRESS, 1436 { {SO3_SIMPRESS_CLASSID_60},{SO3_SIMPRESS_CLASSID_50}, 1437 {SO3_SIMPRESS_CLASSID_40},{SO3_SIMPRESS_CLASSID_30} } }, 1438 { nsSwTOOElements::TOO_DRAW_IMPRESS, 1439 { {SO3_SDRAW_CLASSID_60},{SO3_SDRAW_CLASSID_50}}}, 1440 { 0,{{0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0}, 1441 {0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0} } } 1442 }; 1443 1444 long nRet = 0; 1445 for( const _SoObjType* pArr = aArr; !nRet && pArr->nFlag; ++pArr ) 1446 for ( int n = 0; n < 4; ++n ) 1447 { 1448 const _SoObjType::_GlobalNameIds& rId = pArr->aGlNmIds[ n ]; 1449 if( !rId.n1 ) 1450 break; 1451 SvGlobalName aGlbNm( rId.n1, rId.n2, rId.n3, 1452 rId.b8, rId.b9, rId.b10, rId.b11, 1453 rId.b12, rId.b13, rId.b14, rId.b15 ); 1454 if( rFactoryNm == aGlbNm ) 1455 { 1456 nRet = pArr->nFlag; 1457 break; 1458 } 1459 } 1460 1461 return nRet; 1462 } 1463 1464 void SwTOXBaseSection::UpdateCntnt( SwTOXElement eMyType, 1465 const SwTxtNode* pOwnChapterNode ) 1466 { 1467 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); 1468 SwNodes& rNds = pDoc->GetNodes(); 1469 // auf den 1. Node der 1. Section 1470 sal_uLong nIdx = rNds.GetEndOfAutotext().StartOfSectionIndex() + 2, 1471 nEndIdx = rNds.GetEndOfAutotext().GetIndex(); 1472 1473 while( nIdx < nEndIdx ) 1474 { 1475 ::SetProgressState( 0, pDoc->GetDocShell() ); 1476 1477 SwNode* pNd = rNds[ nIdx ]; 1478 SwCntntNode* pCNd = 0; 1479 switch( eMyType ) 1480 { 1481 case nsSwTOXElement::TOX_FRAME: 1482 if( !pNd->IsNoTxtNode() ) 1483 { 1484 pCNd = pNd->GetCntntNode(); 1485 if( !pCNd ) 1486 { 1487 SwNodeIndex aTmp( *pNd ); 1488 pCNd = rNds.GoNext( &aTmp ); 1489 } 1490 } 1491 break; 1492 case nsSwTOXElement::TOX_GRAPHIC: 1493 if( pNd->IsGrfNode() ) 1494 pCNd = (SwCntntNode*)pNd; 1495 break; 1496 case nsSwTOXElement::TOX_OLE: 1497 if( pNd->IsOLENode() ) 1498 { 1499 sal_Bool bInclude = sal_True; 1500 if(TOX_OBJECTS == SwTOXBase::GetType()) 1501 { 1502 SwOLENode* pOLENode = pNd->GetOLENode(); 1503 long nMyOLEOptions = GetOLEOptions(); 1504 SwOLEObj& rOLEObj = pOLENode->GetOLEObj(); 1505 1506 if( rOLEObj.IsOleRef() ) //Noch nicht geladen 1507 { 1508 SvGlobalName aTmpName = SvGlobalName( rOLEObj.GetOleRef()->getClassID() ); 1509 long nObj = ::lcl_IsSOObject( aTmpName ); 1510 bInclude = ( (nMyOLEOptions & nsSwTOOElements::TOO_OTHER) && 0 == nObj) 1511 || (0 != (nMyOLEOptions & nObj)); 1512 } 1513 else 1514 { 1515 DBG_ERROR("OLE-object nicht geladen?"); 1516 bInclude = sal_False; 1517 } 1518 } 1519 1520 if(bInclude) 1521 pCNd = (SwCntntNode*)pNd; 1522 } 1523 break; 1524 default: break; 1525 } 1526 1527 if( pCNd ) 1528 { 1529 //find node in body text 1530 int nSetLevel = USHRT_MAX; 1531 1532 //#111105# tables of tables|illustrations|objects don't support hierarchies 1533 if( IsLevelFromChapter() && 1534 TOX_TABLES != SwTOXBase::GetType() && 1535 TOX_ILLUSTRATIONS != SwTOXBase::GetType() && 1536 TOX_OBJECTS != SwTOXBase::GetType() ) 1537 { 1538 const SwTxtNode* pOutlNd = ::lcl_FindChapterNode( *pCNd, 1539 MAXLEVEL - 1 ); 1540 if( pOutlNd ) 1541 { 1542 //sal_uInt16 nTmp = pOutlNd->GetTxtColl()->GetOutlineLevel();//#outline level,zhaojianwei 1543 //if( nTmp < NO_NUMBERING ) 1544 // nSetLevel = nTmp + 1; 1545 if( pOutlNd->GetTxtColl()->IsAssignedToListLevelOfOutlineStyle()) 1546 nSetLevel = pOutlNd->GetTxtColl()->GetAttrOutlineLevel() ;//<-end,zhaojianwei 1547 } 1548 } 1549 1550 if( pCNd->getLayoutFrm( pDoc->GetCurrentLayout() ) && ( !IsFromChapter() || 1551 ::lcl_FindChapterNode( *pCNd, 0 ) == pOwnChapterNode )) 1552 { 1553 SwTOXPara * pNew = new SwTOXPara( *pCNd, eMyType, 1554 ( USHRT_MAX != nSetLevel ) 1555 ? static_cast<sal_uInt16>(nSetLevel) 1556 : FORM_ALPHA_DELIMITTER ); 1557 InsertSorted( pNew ); 1558 } 1559 } 1560 1561 nIdx = pNd->StartOfSectionNode()->EndOfSectionIndex() + 2; // 2 == End-/StartNode 1562 } 1563 } 1564 1565 /*-------------------------------------------------------------------- 1566 Beschreibung: Tabelleneintraege zusammensuchen 1567 --------------------------------------------------------------------*/ 1568 1569 void SwTOXBaseSection::UpdateTable( const SwTxtNode* pOwnChapterNode ) 1570 { 1571 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); 1572 SwNodes& rNds = pDoc->GetNodes(); 1573 const SwFrmFmts& rArr = *pDoc->GetTblFrmFmts(); 1574 1575 for( sal_uInt16 n = 0; n < rArr.Count(); ++n ) 1576 { 1577 ::SetProgressState( 0, pDoc->GetDocShell() ); 1578 1579 SwTable* pTmpTbl = SwTable::FindTable( rArr[ n ] ); 1580 SwTableBox* pFBox; 1581 if( pTmpTbl && 0 != (pFBox = pTmpTbl->GetTabSortBoxes()[0] ) && 1582 pFBox->GetSttNd() && pFBox->GetSttNd()->GetNodes().IsDocNodes() ) 1583 { 1584 const SwTableNode* pTblNd = pFBox->GetSttNd()->FindTableNode(); 1585 SwNodeIndex aCntntIdx( *pTblNd, 1 ); 1586 1587 SwCntntNode* pCNd; 1588 while( 0 != ( pCNd = rNds.GoNext( &aCntntIdx ) ) && 1589 aCntntIdx.GetIndex() < pTblNd->EndOfSectionIndex() ) 1590 { 1591 if( pCNd->getLayoutFrm( pDoc->GetCurrentLayout() ) && (!IsFromChapter() || 1592 ::lcl_FindChapterNode( *pCNd, 0 ) == pOwnChapterNode )) 1593 { 1594 SwTOXTable * pNew = new SwTOXTable( *pCNd ); 1595 if( IsLevelFromChapter() && TOX_TABLES != SwTOXBase::GetType()) 1596 { 1597 const SwTxtNode* pOutlNd = 1598 ::lcl_FindChapterNode( *pCNd, MAXLEVEL - 1 ); 1599 if( pOutlNd ) 1600 { 1601 //sal_uInt16 nTmp = pOutlNd->GetTxtColl()->GetOutlineLevel();//#outline level,zhaojianwei 1602 //if( nTmp < NO_NUMBERING ) 1603 // pNew->SetLevel( nTmp + 1 ); 1604 if( pOutlNd->GetTxtColl()->IsAssignedToListLevelOfOutlineStyle()) 1605 { 1606 const int nTmp = pOutlNd->GetTxtColl()->GetAttrOutlineLevel(); 1607 pNew->SetLevel( static_cast<sal_uInt16>(nTmp) );//<-end ,zhaojianwei 1608 } 1609 } 1610 } 1611 InsertSorted(pNew); 1612 break; 1613 } 1614 } 1615 } 1616 } 1617 } 1618 1619 /*-------------------------------------------------------------------- 1620 Beschreibung: String generieren anhand der Form 1621 SonderZeichen 0-31 und 255 entfernen 1622 --------------------------------------------------------------------*/ 1623 1624 String lcl_GetNumString( const SwTOXSortTabBase& rBase, sal_Bool bUsePrefix, sal_uInt8 nLevel ) 1625 { 1626 String sRet; 1627 1628 if( !rBase.pTxtMark && rBase.aTOXSources.Count() > 0 ) 1629 { // nur wenn es keine Marke ist 1630 const SwTxtNode* pNd = rBase.aTOXSources[0].pNd->GetTxtNode(); 1631 if( pNd ) 1632 { 1633 const SwNumRule* pRule = pNd->GetNumRule(); 1634 1635 if( pRule && pNd->GetActualListLevel() < MAXLEVEL ) 1636 sRet = pNd->GetNumString(bUsePrefix, nLevel); 1637 } 1638 } 1639 return sRet; 1640 } 1641 1642 // OD 18.03.2003 #106329# - add parameter <_TOXSectNdIdx> and <_pDefaultPageDesc> 1643 // in order to control, which page description is used, no appropriate one is found. 1644 void SwTOXBaseSection::GenerateText( sal_uInt16 nArrayIdx, 1645 sal_uInt16 nCount, 1646 SvStringsDtor& , 1647 const sal_uInt32 _nTOXSectNdIdx, 1648 const SwPageDesc* _pDefaultPageDesc ) 1649 { 1650 LinkStructArr aLinkArr; 1651 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); 1652 ::SetProgressState( 0, pDoc->GetDocShell() ); 1653 1654 //pTOXNd is only set at the first mark 1655 SwTxtNode* pTOXNd = (SwTxtNode*)aSortArr[nArrayIdx]->pTOXNd; 1656 String& rTxt = (String&)pTOXNd->GetTxt(); 1657 rTxt.Erase(); 1658 for(sal_uInt16 nIndex = nArrayIdx; nIndex < nArrayIdx + nCount; nIndex++) 1659 { 1660 if(nIndex > nArrayIdx) 1661 rTxt.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ", " )); // comma separation 1662 // String mit dem Pattern aus der Form initialisieren 1663 const SwTOXSortTabBase& rBase = *aSortArr[nIndex]; 1664 sal_uInt16 nLvl = rBase.GetLevel(); 1665 ASSERT( nLvl < GetTOXForm().GetFormMax(), "ungueltiges FORM_LEVEL"); 1666 1667 SvxTabStopItem aTStops( 0, 0, SVX_TAB_ADJUST_DEFAULT, RES_PARATR_TABSTOP ); 1668 xub_StrLen nLinkStartPosition = STRING_NOTFOUND; 1669 String sLinkCharacterStyle; //default to "Default" character style - which is none 1670 String sURL; 1671 // create an enumerator 1672 // #i21237# 1673 SwFormTokens aPattern = GetTOXForm().GetPattern(nLvl); 1674 SwFormTokens::iterator aIt = aPattern.begin(); 1675 // remove text from node 1676 while(aIt != aPattern.end()) // #i21237# 1677 { 1678 SwFormToken aToken = *aIt; // #i21237# 1679 xub_StrLen nStartCharStyle = rTxt.Len(); 1680 switch( aToken.eTokenType ) 1681 { 1682 case TOKEN_ENTRY_NO: 1683 // fuer Inhaltsverzeichnis Numerierung 1684 rTxt.Insert( lcl_GetNumString( rBase, aToken.nChapterFormat == CF_NUMBER, static_cast<sal_uInt8>(aToken.nOutlineLevel - 1)) ); 1685 break; 1686 1687 case TOKEN_ENTRY_TEXT: 1688 { 1689 SwIndex aIdx( pTOXNd, rTxt.Len() ); 1690 rBase.FillText( *pTOXNd, aIdx ); 1691 } 1692 break; 1693 1694 case TOKEN_ENTRY: 1695 { 1696 // fuer Inhaltsverzeichnis Numerierung 1697 rTxt.Insert( lcl_GetNumString( rBase, sal_True, MAXLEVEL )); 1698 1699 SwIndex aIdx( pTOXNd, rTxt.Len() ); 1700 rBase.FillText( *pTOXNd, aIdx ); 1701 } 1702 break; 1703 1704 case TOKEN_TAB_STOP: 1705 if (aToken.bWithTab) // #i21237# 1706 rTxt.Append('\t'); 1707 // 1708 1709 if(SVX_TAB_ADJUST_END > aToken.eTabAlign) 1710 { 1711 const SvxLRSpaceItem& rLR = 1712 (SvxLRSpaceItem&)pTOXNd-> 1713 SwCntntNode::GetAttr( RES_LR_SPACE, sal_True ); 1714 1715 long nTabPosition = aToken.nTabStopPosition; 1716 if( !GetTOXForm().IsRelTabPos() && rLR.GetTxtLeft() ) 1717 nTabPosition -= rLR.GetTxtLeft(); 1718 aTStops.Insert( SvxTabStop( nTabPosition, 1719 aToken.eTabAlign, 1720 cDfltDecimalChar, 1721 aToken.cTabFillChar )); 1722 } 1723 else 1724 { 1725 const SwPageDesc* pPageDesc = ((SwFmtPageDesc&)pTOXNd-> 1726 SwCntntNode::GetAttr( RES_PAGEDESC )).GetPageDesc(); 1727 1728 sal_Bool bCallFindRect = sal_True; 1729 long nRightMargin; 1730 if( pPageDesc ) 1731 { 1732 const SwFrm* pFrm = pTOXNd->getLayoutFrm( pDoc->GetCurrentLayout(), 0, 0, sal_True ); 1733 if( !pFrm || 0 == ( pFrm = pFrm->FindPageFrm() ) || 1734 pPageDesc != ((SwPageFrm*)pFrm)->GetPageDesc() ) 1735 // dann muss man ueber den PageDesc gehen 1736 bCallFindRect = sal_False; 1737 } 1738 1739 SwRect aNdRect; 1740 if( bCallFindRect ) 1741 aNdRect = pTOXNd->FindLayoutRect( sal_True ); 1742 1743 if( aNdRect.IsEmpty() ) 1744 { 1745 // dann hilft alles nichts, wir muessen ueber die Seiten- 1746 // vorlage gehen. 1747 // OD 18.03.2003 #106329# - call 1748 sal_uInt32 nPgDescNdIdx = pTOXNd->GetIndex() + 1; 1749 sal_uInt32* pPgDescNdIdx = &nPgDescNdIdx; 1750 pPageDesc = pTOXNd->FindPageDesc( sal_False, pPgDescNdIdx ); 1751 if ( !pPageDesc || 1752 *pPgDescNdIdx < _nTOXSectNdIdx ) 1753 { 1754 // use default page description, if none is found 1755 // or the found one is given by a node before the 1756 // table-of-content section. 1757 pPageDesc = _pDefaultPageDesc; 1758 } 1759 1760 const SwFrmFmt& rPgDscFmt = pPageDesc->GetMaster(); 1761 nRightMargin = rPgDscFmt.GetFrmSize().GetWidth() - 1762 rPgDscFmt.GetLRSpace().GetLeft() - 1763 rPgDscFmt.GetLRSpace().GetRight(); 1764 } 1765 else 1766 nRightMargin = aNdRect.Width(); 1767 //#i24363# tab stops relative to indent 1768 if( pDoc->get(IDocumentSettingAccess::TABS_RELATIVE_TO_INDENT) ) 1769 { 1770 //left margin of paragraph style 1771 const SvxLRSpaceItem& rLRSpace = pTOXNd->GetTxtColl()->GetLRSpace(); 1772 nRightMargin -= rLRSpace.GetLeft(); 1773 nRightMargin -= rLRSpace.GetTxtFirstLineOfst(); 1774 } 1775 1776 aTStops.Insert( SvxTabStop( nRightMargin, SVX_TAB_ADJUST_RIGHT, 1777 cDfltDecimalChar, 1778 aToken.cTabFillChar )); 1779 } 1780 break; 1781 1782 case TOKEN_TEXT: 1783 rTxt.Append( aToken.sText ); 1784 break; 1785 1786 case TOKEN_PAGE_NUMS: 1787 // Platzhalter fuer Seitennummer(n) es wird nur der erste beachtet 1788 // 1789 { 1790 // Die Anzahl der gleichen Eintrage bestimmt die Seitennummern-Pattern 1791 // 1792 sal_uInt16 nSize = rBase.aTOXSources.Count(); 1793 if( nSize > 0 ) 1794 { 1795 String aInsStr( cNumRepl ); 1796 for(sal_uInt16 i=1; i < nSize; ++i) 1797 { 1798 aInsStr.AppendAscii( sPageDeli ); 1799 aInsStr += cNumRepl; 1800 } 1801 aInsStr += cEndPageNum; 1802 rTxt.Append( aInsStr ); 1803 } 1804 // // Tab entfernen, wenn keine Seitennummer 1805 // else if( rTxt.Len() && '\t' == rTxt.GetChar( rTxt.Len() - 1 )) 1806 // rTxt.Erase( rTxt.Len()-1, 1 ); 1807 } 1808 break; 1809 1810 case TOKEN_CHAPTER_INFO: 1811 { 1812 // ein bischen trickreich: suche irgend einen Frame 1813 const SwTOXSource* pTOXSource = 0; 1814 if(rBase.aTOXSources.Count()) 1815 pTOXSource = &rBase.aTOXSources[0]; 1816 1817 // --> OD 2008-02-14 #i53420# 1818 // if( pTOXSource && pTOXSource->pNd 1819 // pTOXSource->pNd->IsTxtNode() ) 1820 if ( pTOXSource && pTOXSource->pNd && 1821 pTOXSource->pNd->IsCntntNode() ) 1822 // <-- 1823 { 1824 const SwCntntFrm* pFrm = pTOXSource->pNd->getLayoutFrm( pDoc->GetCurrentLayout() ); 1825 if( pFrm ) 1826 { 1827 SwChapterFieldType aFldTyp; 1828 SwChapterField aFld( &aFldTyp, aToken.nChapterFormat ); 1829 aFld.SetLevel( static_cast<sal_uInt8>(aToken.nOutlineLevel - 1) ); 1830 // --> OD 2008-02-14 #i53420# 1831 // aFld.ChangeExpansion( pFrm, (SwTxtNode*)pTOXSource->pNd, sal_True ); 1832 aFld.ChangeExpansion( pFrm, 1833 dynamic_cast<const SwCntntNode*>(pTOXSource->pNd), 1834 sal_True ); 1835 // <-- 1836 //---> i89791 1837 // OD 2008-06-26 - continue to support CF_NUMBER 1838 // and CF_NUM_TITLE in order to handle ODF 1.0/1.1 1839 // written by OOo 3.x in the same way as OOo 2.x 1840 // would handle them. 1841 if ( CF_NUM_NOPREPST_TITLE == aToken.nChapterFormat || 1842 CF_NUMBER == aToken.nChapterFormat ) 1843 rTxt.Insert(aFld.GetNumber()); //get the string number without pre/postfix 1844 else if ( CF_NUMBER_NOPREPST == aToken.nChapterFormat || 1845 CF_NUM_TITLE == aToken.nChapterFormat ) 1846 //<--- 1847 { 1848 rTxt += aFld.GetNumber(); 1849 rTxt += ' '; 1850 rTxt += aFld.GetTitle(); 1851 } 1852 else if(CF_TITLE == aToken.nChapterFormat) 1853 rTxt += aFld.GetTitle(); 1854 } 1855 } 1856 } 1857 break; 1858 1859 case TOKEN_LINK_START: 1860 nLinkStartPosition = rTxt.Len(); 1861 sLinkCharacterStyle = aToken.sCharStyleName; 1862 break; 1863 1864 case TOKEN_LINK_END: 1865 //TODO: only paired start/end tokens are valid 1866 if( STRING_NOTFOUND != nLinkStartPosition) 1867 { 1868 SwIndex aIdx( pTOXNd, nLinkStartPosition ); 1869 //pTOXNd->Erase( aIdx, SwForm::nFormLinkSttLen ); 1870 xub_StrLen nEnd = rTxt.Len(); 1871 1872 if( !sURL.Len() ) 1873 { 1874 sURL = rBase.GetURL(); 1875 if( !sURL.Len() ) 1876 break; 1877 } 1878 LinkStruct* pNewLink = new LinkStruct(sURL, nLinkStartPosition, 1879 nEnd); 1880 pNewLink->aINetFmt.SetVisitedFmt(sLinkCharacterStyle); 1881 pNewLink->aINetFmt.SetINetFmt(sLinkCharacterStyle); 1882 if(sLinkCharacterStyle.Len()) 1883 { 1884 sal_uInt16 nPoolId = 1885 SwStyleNameMapper::GetPoolIdFromUIName( sLinkCharacterStyle, nsSwGetPoolIdFromName::GET_POOLID_CHRFMT ); 1886 pNewLink->aINetFmt.SetVisitedFmtId(nPoolId); 1887 pNewLink->aINetFmt.SetINetFmtId(nPoolId); 1888 } 1889 else 1890 { 1891 pNewLink->aINetFmt.SetVisitedFmtId(USHRT_MAX); 1892 pNewLink->aINetFmt.SetINetFmtId(USHRT_MAX); 1893 } 1894 aLinkArr.Insert( pNewLink, aLinkArr.Count() ); 1895 nLinkStartPosition = STRING_NOTFOUND; 1896 sLinkCharacterStyle.Erase(); 1897 } 1898 break; 1899 1900 case TOKEN_AUTHORITY: 1901 { 1902 ToxAuthorityField eField = (ToxAuthorityField)aToken.nAuthorityField; 1903 SwIndex aIdx( pTOXNd, rTxt.Len() ); 1904 rBase.FillText( *pTOXNd, aIdx, static_cast<sal_uInt16>(eField) ); 1905 } 1906 break; 1907 case TOKEN_END: break; 1908 } 1909 1910 if( aToken.sCharStyleName.Len() ) 1911 { 1912 SwCharFmt* pCharFmt; 1913 if( USHRT_MAX != aToken.nPoolId ) 1914 pCharFmt = pDoc->GetCharFmtFromPool( aToken.nPoolId ); 1915 else 1916 pCharFmt = pDoc->FindCharFmtByName( aToken.sCharStyleName); 1917 1918 if (pCharFmt) 1919 { 1920 SwFmtCharFmt aFmt( pCharFmt ); 1921 pTOXNd->InsertItem( aFmt, nStartCharStyle, 1922 rTxt.Len(), nsSetAttrMode::SETATTR_DONTEXPAND ); 1923 } 1924 } 1925 1926 aIt++; // #i21237# 1927 } 1928 1929 pTOXNd->SetAttr( aTStops ); 1930 } 1931 1932 if(aLinkArr.Count()) 1933 for(sal_uInt16 i = 0; i < aLinkArr.Count(); ++i ) 1934 { 1935 LinkStruct* pTmp = aLinkArr.GetObject(i); 1936 pTOXNd->InsertItem( pTmp->aINetFmt, pTmp->nStartTextPos, 1937 pTmp->nEndTextPos); 1938 } 1939 } 1940 1941 /*-------------------------------------------------------------------- 1942 Beschreibung: Seitennummer errechnen und nach dem Formatieren 1943 eintragen 1944 --------------------------------------------------------------------*/ 1945 1946 void SwTOXBaseSection::UpdatePageNum() 1947 { 1948 if( !aSortArr.Count() ) 1949 return ; 1950 1951 // die aktuellen Seitennummern ins Verzeichnis eintragen 1952 SwPageFrm* pAktPage = 0; 1953 sal_uInt16 nPage = 0; 1954 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); 1955 1956 SwTOXInternational aIntl( GetLanguage(), 1957 TOX_INDEX == GetTOXType()->GetType() ? 1958 GetOptions() : 0, 1959 GetSortAlgorithm() ); 1960 1961 for( sal_uInt16 nCnt = 0; nCnt < aSortArr.Count(); ++nCnt ) 1962 { 1963 // Schleife ueber alle SourceNodes 1964 SvUShorts aNums; //Die Seitennummern 1965 SvPtrarr aDescs; //Die PageDescriptoren passend zu den Seitennummern. 1966 SvUShorts* pMainNums = 0; // contains page numbers of main entries 1967 1968 // process run in lines 1969 sal_uInt16 nRange = 0; 1970 if(GetTOXForm().IsCommaSeparated() && 1971 aSortArr[nCnt]->GetType() == TOX_SORT_INDEX) 1972 { 1973 const SwTOXMark& rMark = aSortArr[nCnt]->pTxtMark->GetTOXMark(); 1974 const String sPrimKey = rMark.GetPrimaryKey(); 1975 const String sSecKey = rMark.GetSecondaryKey(); 1976 const SwTOXMark* pNextMark = 0; 1977 while(aSortArr.Count() > (nCnt + nRange)&& 1978 aSortArr[nCnt + nRange]->GetType() == TOX_SORT_INDEX && 1979 0 != (pNextMark = &(aSortArr[nCnt + nRange]->pTxtMark->GetTOXMark())) && 1980 pNextMark->GetPrimaryKey() == sPrimKey && 1981 pNextMark->GetSecondaryKey() == sSecKey) 1982 nRange++; 1983 } 1984 else 1985 nRange = 1; 1986 1987 for(sal_uInt16 nRunInEntry = nCnt; nRunInEntry < nCnt + nRange; nRunInEntry++) 1988 { 1989 SwTOXSortTabBase* pSortBase = aSortArr[nRunInEntry]; 1990 sal_uInt16 nSize = pSortBase->aTOXSources.Count(); 1991 sal_uInt16 i; 1992 for( sal_uInt16 j = 0; j < nSize; ++j ) 1993 { 1994 ::SetProgressState( 0, pDoc->GetDocShell() ); 1995 1996 SwTOXSource& rTOXSource = pSortBase->aTOXSources[j]; 1997 if( rTOXSource.pNd ) 1998 { 1999 SwCntntFrm* pFrm = rTOXSource.pNd->getLayoutFrm( pDoc->GetCurrentLayout() ); 2000 ASSERT( pFrm || pDoc->IsUpdateTOX(), "TOX, no Frame found"); 2001 if( !pFrm ) 2002 continue; 2003 if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->HasFollow() ) 2004 { 2005 // dann suche den richtigen heraus 2006 SwTxtFrm* pNext = (SwTxtFrm*)pFrm; 2007 while( 0 != ( pNext = (SwTxtFrm*)pFrm->GetFollow() ) 2008 && rTOXSource.nPos >= pNext->GetOfst() ) 2009 pFrm = pNext; 2010 } 2011 2012 SwPageFrm* pTmpPage = pFrm->FindPageFrm(); 2013 if( pTmpPage != pAktPage ) 2014 { 2015 nPage = pTmpPage->GetVirtPageNum(); 2016 pAktPage = pTmpPage; 2017 } 2018 2019 // sortiert einfuegen 2020 for( i = 0; i < aNums.Count() && aNums[i] < nPage; ++i ) 2021 ; 2022 2023 if( i >= aNums.Count() || aNums[ i ] != nPage ) 2024 { 2025 aNums.Insert( nPage, i ); 2026 aDescs.Insert( (void*)pAktPage->GetPageDesc(), i ); 2027 } 2028 // is it a main entry? 2029 if(TOX_SORT_INDEX == pSortBase->GetType() && 2030 rTOXSource.bMainEntry) 2031 { 2032 if(!pMainNums) 2033 pMainNums = new SvUShorts; 2034 pMainNums->Insert(nPage, pMainNums->Count()); 2035 } 2036 } 2037 } 2038 // einfuegen der Seitennummer in den Verzeichnis-Text-Node 2039 const SwTOXSortTabBase* pBase = aSortArr[ nCnt ]; 2040 if(pBase->pTOXNd) 2041 { 2042 const SwTxtNode* pTxtNd = pBase->pTOXNd->GetTxtNode(); 2043 ASSERT( pTxtNd, "kein TextNode, falsches Verzeichnis" ); 2044 2045 _UpdatePageNum( (SwTxtNode*)pTxtNd, aNums, aDescs, pMainNums, 2046 aIntl ); 2047 } 2048 DELETEZ(pMainNums); 2049 aNums.Remove(0, aNums.Count()); 2050 } 2051 } 2052 // nach dem Setzen der richtigen Seitennummer, das Mapping-Array 2053 // wieder loeschen !! 2054 aSortArr.DeleteAndDestroy( 0, aSortArr.Count() ); 2055 } 2056 2057 2058 /*-------------------------------------------------------------------- 2059 Beschreibung: Austausch der Seitennummer-Platzhalter 2060 --------------------------------------------------------------------*/ 2061 2062 // search for the page no in the array of main entry page numbers 2063 sal_Bool lcl_HasMainEntry( const SvUShorts* pMainEntryNums, sal_uInt16 nToFind ) 2064 { 2065 for(sal_uInt16 i = 0; pMainEntryNums && i < pMainEntryNums->Count(); ++i) 2066 if(nToFind == (*pMainEntryNums)[i]) 2067 return sal_True; 2068 return sal_False; 2069 } 2070 2071 void SwTOXBaseSection::_UpdatePageNum( SwTxtNode* pNd, 2072 const SvUShorts& rNums, 2073 const SvPtrarr & rDescs, 2074 const SvUShorts* pMainEntryNums, 2075 const SwTOXInternational& rIntl ) 2076 { 2077 //collect starts end ends of main entry character style 2078 SvUShorts* pCharStyleIdx = pMainEntryNums ? new SvUShorts : 0; 2079 2080 String sSrchStr( cNumRepl ); 2081 sSrchStr.AppendAscii( sPageDeli ) += cNumRepl; 2082 xub_StrLen nStartPos = pNd->GetTxt().Search( sSrchStr ); 2083 ( sSrchStr = cNumRepl ) += cEndPageNum; 2084 xub_StrLen nEndPos = pNd->GetTxt().Search( sSrchStr ); 2085 sal_uInt16 i; 2086 2087 if( STRING_NOTFOUND == nEndPos || !rNums.Count() ) 2088 return; 2089 2090 if( STRING_NOTFOUND == nStartPos || nStartPos > nEndPos) 2091 nStartPos = nEndPos; 2092 2093 sal_uInt16 nOld = rNums[0], 2094 nBeg = nOld, 2095 nCount = 0; 2096 String aNumStr( SvxNumberType( ((SwPageDesc*)rDescs[0])->GetNumType() ). 2097 GetNumStr( nBeg ) ); 2098 if( pCharStyleIdx && lcl_HasMainEntry( pMainEntryNums, nBeg )) 2099 { 2100 sal_uInt16 nTemp = 0; 2101 pCharStyleIdx->Insert( nTemp, pCharStyleIdx->Count()); 2102 } 2103 2104 // Platzhalter loeschen 2105 SwIndex aPos(pNd, nStartPos); 2106 SwCharFmt* pPageNoCharFmt = 0; 2107 SwpHints* pHints = pNd->GetpSwpHints(); 2108 if(pHints) 2109 for(sal_uInt16 nHintIdx = 0; nHintIdx < pHints->GetStartCount(); nHintIdx++) 2110 { 2111 SwTxtAttr* pAttr = pHints->GetStart(nHintIdx); 2112 const xub_StrLen nTmpEnd = pAttr->End() ? *pAttr->End() : 0; 2113 if( nStartPos >= *pAttr->GetStart() && 2114 (nStartPos + 2) <= nTmpEnd && 2115 pAttr->Which() == RES_TXTATR_CHARFMT) 2116 { 2117 pPageNoCharFmt = pAttr->GetCharFmt().GetCharFmt(); 2118 break; 2119 } 2120 } 2121 pNd->EraseText(aPos, nEndPos - nStartPos + 2); 2122 2123 for( i = 1; i < rNums.Count(); ++i) 2124 { 2125 SvxNumberType aType( ((SwPageDesc*)rDescs[i])->GetNumType() ); 2126 if( TOX_INDEX == SwTOXBase::GetType() ) 2127 { // Zusammenfassen f. ff. 2128 // Alle folgenden aufaddieren 2129 // break up if main entry starts or ends and 2130 // insert a char style index 2131 sal_Bool bMainEntryChanges = lcl_HasMainEntry(pMainEntryNums, nOld) 2132 != lcl_HasMainEntry(pMainEntryNums, rNums[i]); 2133 2134 if(nOld == rNums[i]-1 && !bMainEntryChanges && 2135 0 != (GetOptions() & (nsSwTOIOptions::TOI_FF|nsSwTOIOptions::TOI_DASH))) 2136 nCount++; 2137 else 2138 { 2139 // ff. f. alten Wert flushen 2140 if(GetOptions() & nsSwTOIOptions::TOI_FF) 2141 { 2142 if ( nCount >= 1 ) 2143 aNumStr += rIntl.GetFollowingText( nCount > 1 ); 2144 } 2145 else 2146 { 2147 if(nCount >= 2 ) 2148 aNumStr += '-'; 2149 else if(nCount == 1 ) 2150 aNumStr.AppendAscii( sPageDeli ); 2151 //#58127# Wenn nCount == 0, dann steht die einzige Seitenzahl schon im aNumStr! 2152 if(nCount) 2153 aNumStr += aType.GetNumStr( nBeg + nCount ); 2154 } 2155 2156 // neuen String anlegen 2157 nBeg = rNums[i]; 2158 aNumStr.AppendAscii( sPageDeli ); 2159 //the change of the character style must apply after sPageDeli is appended 2160 if(pCharStyleIdx && bMainEntryChanges) 2161 pCharStyleIdx->Insert(aNumStr.Len(), 2162 pCharStyleIdx->Count()); 2163 aNumStr += aType.GetNumStr( nBeg ); 2164 nCount = 0; 2165 } 2166 nOld = rNums[i]; 2167 } 2168 else 2169 { // Alle Nummern eintragen 2170 aNumStr += aType.GetNumStr( sal_uInt16(rNums[i]) ); 2171 if(i != (rNums.Count()-1)) 2172 aNumStr.AppendAscii( sPageDeli ); 2173 } 2174 } 2175 // Bei Ende und ff. alten Wert flushen 2176 if( TOX_INDEX == SwTOXBase::GetType() ) 2177 { 2178 if(GetOptions() & nsSwTOIOptions::TOI_FF) 2179 { 2180 if( nCount >= 1 ) 2181 aNumStr += rIntl.GetFollowingText( nCount > 1 ); 2182 } 2183 else 2184 { 2185 if(nCount >= 2) 2186 aNumStr +='-'; 2187 else if(nCount == 1) 2188 aNumStr.AppendAscii( sPageDeli ); 2189 //#58127# Wenn nCount == 0, dann steht die einzige Seitenzahl schon im aNumStr! 2190 if(nCount) 2191 aNumStr += SvxNumberType( ((SwPageDesc*)rDescs[i-1])-> 2192 GetNumType() ).GetNumStr( nBeg+nCount ); 2193 } 2194 } 2195 pNd->InsertText( aNumStr, aPos, 2196 static_cast<IDocumentContentOperations::InsertFlags>( 2197 IDocumentContentOperations::INS_EMPTYEXPAND | 2198 IDocumentContentOperations::INS_FORCEHINTEXPAND) ); 2199 if(pPageNoCharFmt) 2200 { 2201 SwFmtCharFmt aCharFmt( pPageNoCharFmt ); 2202 pNd->InsertItem(aCharFmt, nStartPos, nStartPos + aNumStr.Len(), nsSetAttrMode::SETATTR_DONTEXPAND); 2203 } 2204 2205 //now the main entries should get there character style 2206 if(pCharStyleIdx && pCharStyleIdx->Count() && GetMainEntryCharStyle().Len()) 2207 { 2208 // eventually the last index must me appended 2209 if(pCharStyleIdx->Count()&0x01) 2210 pCharStyleIdx->Insert(aNumStr.Len(), pCharStyleIdx->Count()); 2211 2212 //search by name 2213 SwDoc* pDoc = pNd->GetDoc(); 2214 sal_uInt16 nPoolId = SwStyleNameMapper::GetPoolIdFromUIName( GetMainEntryCharStyle(), nsSwGetPoolIdFromName::GET_POOLID_CHRFMT ); 2215 SwCharFmt* pCharFmt = 0; 2216 if(USHRT_MAX != nPoolId) 2217 pCharFmt = pDoc->GetCharFmtFromPool(nPoolId); 2218 else 2219 pCharFmt = pDoc->FindCharFmtByName( GetMainEntryCharStyle() ); 2220 if(!pCharFmt) 2221 pCharFmt = pDoc->MakeCharFmt(GetMainEntryCharStyle(), 0); 2222 2223 //find the page numbers in aNumStr and set the character style 2224 xub_StrLen nOffset = pNd->GetTxt().Len() - aNumStr.Len(); 2225 SwFmtCharFmt aCharFmt(pCharFmt); 2226 for(sal_uInt16 j = 0; j < pCharStyleIdx->Count(); j += 2) 2227 { 2228 xub_StrLen nStartIdx = (*pCharStyleIdx)[j] + nOffset; 2229 xub_StrLen nEndIdx = (*pCharStyleIdx)[j + 1] + nOffset; 2230 pNd->InsertItem(aCharFmt, nStartIdx, nEndIdx, nsSetAttrMode::SETATTR_DONTEXPAND); 2231 } 2232 2233 } 2234 delete pCharStyleIdx; 2235 } 2236 2237 2238 /*-------------------------------------------------------------------- 2239 Beschreibung: Sortiert einfuegen in das SortArr 2240 --------------------------------------------------------------------*/ 2241 2242 void SwTOXBaseSection::InsertSorted(SwTOXSortTabBase* pNew) 2243 { 2244 Range aRange(0, aSortArr.Count()); 2245 if( TOX_INDEX == SwTOXBase::GetType() && pNew->pTxtMark ) 2246 { 2247 const SwTOXMark& rMark = pNew->pTxtMark->GetTOXMark(); 2248 // Schluessel auswerten 2249 // Den Bereich ermitteln, in dem einzufuegen ist 2250 if( 0 == (GetOptions() & nsSwTOIOptions::TOI_KEY_AS_ENTRY) && 2251 rMark.GetPrimaryKey().Len() ) 2252 { 2253 aRange = GetKeyRange( rMark.GetPrimaryKey(), 2254 rMark.GetPrimaryKeyReading(), 2255 *pNew, FORM_PRIMARY_KEY, aRange ); 2256 2257 if( rMark.GetSecondaryKey().Len() ) 2258 aRange = GetKeyRange( rMark.GetSecondaryKey(), 2259 rMark.GetSecondaryKeyReading(), 2260 *pNew, FORM_SECONDARY_KEY, aRange ); 2261 } 2262 } 2263 //search for identical entries and remove the trailing one 2264 if(TOX_AUTHORITIES == SwTOXBase::GetType()) 2265 { 2266 for(short i = (short)aRange.Min(); i < (short)aRange.Max(); ++i) 2267 { 2268 SwTOXSortTabBase* pOld = aSortArr[i]; 2269 if(*pOld == *pNew) 2270 { 2271 if(*pOld < *pNew) 2272 { 2273 delete pNew; 2274 return; 2275 } 2276 else 2277 { 2278 // remove the old content 2279 aSortArr.DeleteAndDestroy( i, 1 ); 2280 aRange.Max()--; 2281 break; 2282 } 2283 } 2284 } 2285 } 2286 2287 // find position and insert 2288 // 2289 short i; 2290 2291 for( i = (short)aRange.Min(); i < (short)aRange.Max(); ++i) 2292 { // nur auf gleicher Ebene pruefen 2293 // 2294 SwTOXSortTabBase* pOld = aSortArr[i]; 2295 if(*pOld == *pNew) 2296 { 2297 if(TOX_AUTHORITIES != SwTOXBase::GetType()) 2298 { 2299 // Eigener Eintrag fuer Doppelte oder Keywords 2300 // 2301 if( pOld->GetType() == TOX_SORT_CUSTOM && 2302 pNew->GetOptions() & nsSwTOIOptions::TOI_KEY_AS_ENTRY) 2303 continue; 2304 2305 if(!(pNew->GetOptions() & nsSwTOIOptions::TOI_SAME_ENTRY)) 2306 { // Eigener Eintrag 2307 aSortArr.Insert(pNew, i ); 2308 return; 2309 } 2310 // Eintrag schon vorhanden in Referenzliste aufnehmen 2311 pOld->aTOXSources.Insert( pNew->aTOXSources[0], 2312 pOld->aTOXSources.Count() ); 2313 2314 delete pNew; 2315 return; 2316 } 2317 #ifdef DBG_UTIL 2318 else 2319 DBG_ERROR("Bibliography entries cannot be found here"); 2320 #endif 2321 } 2322 if(*pNew < *pOld) 2323 break; 2324 } 2325 // SubLevel Skippen 2326 while( TOX_INDEX == SwTOXBase::GetType() && i < aRange.Max() && 2327 aSortArr[i]->GetLevel() > pNew->GetLevel() ) 2328 i++; 2329 2330 // An Position i wird eingefuegt 2331 aSortArr.Insert(pNew, i ); 2332 } 2333 2334 /*-------------------------------------------------------------------- 2335 Beschreibung: Schluessel-Bereich suchen und evtl einfuegen 2336 --------------------------------------------------------------------*/ 2337 2338 Range SwTOXBaseSection::GetKeyRange(const String& rStr, const String& rStrReading, 2339 const SwTOXSortTabBase& rNew, 2340 sal_uInt16 nLevel, const Range& rRange ) 2341 { 2342 const SwTOXInternational& rIntl = *rNew.pTOXIntl; 2343 String sToCompare(rStr); 2344 String sToCompareReading(rStrReading); 2345 2346 if( 0 != (nsSwTOIOptions::TOI_INITIAL_CAPS & GetOptions()) ) 2347 { 2348 String sUpper( rIntl.ToUpper( sToCompare, 0 )); 2349 sToCompare.Erase( 0, 1 ).Insert( sUpper, 0 ); 2350 } 2351 2352 ASSERT(rRange.Min() >= 0 && rRange.Max() >= 0, "Min Max < 0"); 2353 2354 const sal_uInt16 nMin = (sal_uInt16)rRange.Min(); 2355 const sal_uInt16 nMax = (sal_uInt16)rRange.Max(); 2356 2357 sal_uInt16 i; 2358 2359 for( i = nMin; i < nMax; ++i) 2360 { 2361 SwTOXSortTabBase* pBase = aSortArr[i]; 2362 2363 String sMyString, sMyStringReading; 2364 pBase->GetTxt( sMyString, sMyStringReading ); 2365 2366 if( rIntl.IsEqual( sMyString, sMyStringReading, pBase->GetLocale(), 2367 sToCompare, sToCompareReading, rNew.GetLocale() ) && 2368 pBase->GetLevel() == nLevel ) 2369 break; 2370 } 2371 if(i == nMax) 2372 { // Falls nicht vorhanden erzeugen und einfuegen 2373 // 2374 SwTOXCustom* pKey = new SwTOXCustom( sToCompare, sToCompareReading, nLevel, rIntl, 2375 rNew.GetLocale() ); 2376 for(i = nMin; i < nMax; ++i) 2377 { 2378 if(nLevel == aSortArr[i]->GetLevel() && *pKey < *(aSortArr[i])) 2379 break; 2380 } 2381 aSortArr.Insert(pKey, i ); 2382 } 2383 sal_uInt16 nStart = i+1; 2384 sal_uInt16 nEnd = aSortArr.Count(); 2385 2386 // Ende des Bereiches suchen 2387 for(i = nStart; i < aSortArr.Count(); ++i) 2388 { 2389 if(aSortArr[i]->GetLevel() <= nLevel) 2390 { nEnd = i; 2391 break; 2392 } 2393 } 2394 return Range(nStart, nEnd); 2395 } 2396 2397 2398 sal_Bool SwTOXBase::IsTOXBaseInReadonly() const 2399 { 2400 const SwTOXBaseSection *pSect = PTR_CAST(SwTOXBaseSection, this); 2401 sal_Bool bRet = sal_False; 2402 const SwSectionNode* pSectNode; 2403 if(pSect && pSect->GetFmt() && 2404 0 != (pSectNode = pSect->GetFmt()->GetSectionNode())) 2405 { 2406 const SwDocShell* pDocSh; 2407 bRet = (0 != (pDocSh = pSectNode->GetDoc()->GetDocShell()) && 2408 pDocSh->IsReadOnly()) || 2409 (0 != (pSectNode = pSectNode->StartOfSectionNode()->FindSectionNode())&& 2410 pSectNode->GetSection().IsProtectFlag()); 2411 2412 } 2413 return bRet; 2414 } 2415 2416 const SfxItemSet* SwTOXBase::GetAttrSet() const 2417 { 2418 const SwTOXBaseSection *pSect = PTR_CAST(SwTOXBaseSection, this); 2419 if(pSect && pSect->GetFmt()) 2420 return &pSect->GetFmt()->GetAttrSet(); 2421 return 0; 2422 } 2423 2424 void SwTOXBase::SetAttrSet( const SfxItemSet& rSet ) 2425 { 2426 SwTOXBaseSection *pSect = PTR_CAST(SwTOXBaseSection, this); 2427 if( pSect && pSect->GetFmt() ) 2428 pSect->GetFmt()->SetFmtAttr( rSet ); 2429 } 2430 2431 sal_Bool SwTOXBase::GetInfo( SfxPoolItem& rInfo ) const 2432 { 2433 switch( rInfo.Which() ) 2434 { 2435 case RES_CONTENT_VISIBLE: 2436 { 2437 SwTOXBaseSection *pSect = PTR_CAST(SwTOXBaseSection, this); 2438 if( pSect && pSect->GetFmt() ) 2439 pSect->GetFmt()->GetInfo( rInfo ); 2440 } 2441 return sal_False; 2442 } 2443 return sal_True; 2444 } 2445 2446