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 if ( pOutlNd->GetTxtColl()->IsAssignedToListLevelOfOutlineStyle() ) 1543 { 1544 nSetLevel = pOutlNd->GetTxtColl()->GetAttrOutlineLevel(); 1545 } 1546 } 1547 } 1548 1549 if ( pCNd->getLayoutFrm( pDoc->GetCurrentLayout() ) && ( !IsFromChapter() || 1550 ::lcl_FindChapterNode( *pCNd, 0 ) == pOwnChapterNode ) ) 1551 { 1552 SwTOXPara * pNew = 1553 new SwTOXPara( 1554 *pCNd, 1555 eMyType, 1556 ( USHRT_MAX != nSetLevel ) ? static_cast< sal_uInt16 >( nSetLevel ) : 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() ) 1592 && ( !IsFromChapter() 1593 || ::lcl_FindChapterNode( *pCNd, 0 ) == pOwnChapterNode ) ) 1594 { 1595 SwTOXTable * pNew = new SwTOXTable( *pCNd ); 1596 if ( IsLevelFromChapter() && TOX_TABLES != SwTOXBase::GetType() ) 1597 { 1598 const SwTxtNode* pOutlNd = ::lcl_FindChapterNode( *pCNd, MAXLEVEL - 1 ); 1599 if ( pOutlNd ) 1600 { 1601 if ( pOutlNd->GetTxtColl()->IsAssignedToListLevelOfOutlineStyle() ) 1602 { 1603 const int nTmp = pOutlNd->GetTxtColl()->GetAttrOutlineLevel(); 1604 pNew->SetLevel( static_cast< sal_uInt16 >( nTmp ) ); 1605 } 1606 } 1607 } 1608 InsertSorted( pNew ); 1609 break; 1610 } 1611 } 1612 } 1613 } 1614 } 1615 1616 /*-------------------------------------------------------------------- 1617 Beschreibung: String generieren anhand der Form 1618 SonderZeichen 0-31 und 255 entfernen 1619 --------------------------------------------------------------------*/ 1620 1621 String lcl_GetNumString( const SwTOXSortTabBase& rBase, sal_Bool bUsePrefix, sal_uInt8 nLevel ) 1622 { 1623 String sRet; 1624 1625 if( !rBase.pTxtMark && rBase.aTOXSources.Count() > 0 ) 1626 { // nur wenn es keine Marke ist 1627 const SwTxtNode* pNd = rBase.aTOXSources[0].pNd->GetTxtNode(); 1628 if( pNd ) 1629 { 1630 const SwNumRule* pRule = pNd->GetNumRule(); 1631 1632 if( pRule && pNd->GetActualListLevel() < MAXLEVEL ) 1633 sRet = pNd->GetNumString(bUsePrefix, nLevel); 1634 } 1635 } 1636 return sRet; 1637 } 1638 1639 // OD 18.03.2003 #106329# - add parameter <_TOXSectNdIdx> and <_pDefaultPageDesc> 1640 // in order to control, which page description is used, no appropriate one is found. 1641 void SwTOXBaseSection::GenerateText( sal_uInt16 nArrayIdx, 1642 sal_uInt16 nCount, 1643 SvStringsDtor& , 1644 const sal_uInt32 _nTOXSectNdIdx, 1645 const SwPageDesc* _pDefaultPageDesc ) 1646 { 1647 LinkStructArr aLinkArr; 1648 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); 1649 ::SetProgressState( 0, pDoc->GetDocShell() ); 1650 1651 //pTOXNd is only set at the first mark 1652 SwTxtNode* pTOXNd = (SwTxtNode*)aSortArr[nArrayIdx]->pTOXNd; 1653 String& rTxt = (String&)pTOXNd->GetTxt(); 1654 rTxt.Erase(); 1655 for(sal_uInt16 nIndex = nArrayIdx; nIndex < nArrayIdx + nCount; nIndex++) 1656 { 1657 if(nIndex > nArrayIdx) 1658 rTxt.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ", " )); // comma separation 1659 // String mit dem Pattern aus der Form initialisieren 1660 const SwTOXSortTabBase& rBase = *aSortArr[nIndex]; 1661 sal_uInt16 nLvl = rBase.GetLevel(); 1662 ASSERT( nLvl < GetTOXForm().GetFormMax(), "ungueltiges FORM_LEVEL"); 1663 1664 SvxTabStopItem aTStops( 0, 0, SVX_TAB_ADJUST_DEFAULT, RES_PARATR_TABSTOP ); 1665 xub_StrLen nLinkStartPosition = STRING_NOTFOUND; 1666 String sLinkCharacterStyle; //default to "Default" character style - which is none 1667 String sURL; 1668 // create an enumerator 1669 // #i21237# 1670 SwFormTokens aPattern = GetTOXForm().GetPattern(nLvl); 1671 SwFormTokens::iterator aIt = aPattern.begin(); 1672 // remove text from node 1673 while(aIt != aPattern.end()) // #i21237# 1674 { 1675 SwFormToken aToken = *aIt; // #i21237# 1676 xub_StrLen nStartCharStyle = rTxt.Len(); 1677 switch( aToken.eTokenType ) 1678 { 1679 case TOKEN_ENTRY_NO: 1680 // fuer Inhaltsverzeichnis Numerierung 1681 rTxt.Insert( lcl_GetNumString( rBase, aToken.nChapterFormat == CF_NUMBER, static_cast<sal_uInt8>(aToken.nOutlineLevel - 1)) ); 1682 break; 1683 1684 case TOKEN_ENTRY_TEXT: 1685 { 1686 SwIndex aIdx( pTOXNd, rTxt.Len() ); 1687 rBase.FillText( *pTOXNd, aIdx ); 1688 } 1689 break; 1690 1691 case TOKEN_ENTRY: 1692 { 1693 // fuer Inhaltsverzeichnis Numerierung 1694 rTxt.Insert( lcl_GetNumString( rBase, sal_True, MAXLEVEL )); 1695 1696 SwIndex aIdx( pTOXNd, rTxt.Len() ); 1697 rBase.FillText( *pTOXNd, aIdx ); 1698 } 1699 break; 1700 1701 case TOKEN_TAB_STOP: 1702 if (aToken.bWithTab) // #i21237# 1703 rTxt.Append('\t'); 1704 // 1705 1706 if(SVX_TAB_ADJUST_END > aToken.eTabAlign) 1707 { 1708 const SvxLRSpaceItem& rLR = 1709 (SvxLRSpaceItem&)pTOXNd-> 1710 SwCntntNode::GetAttr( RES_LR_SPACE, sal_True ); 1711 1712 long nTabPosition = aToken.nTabStopPosition; 1713 if( !GetTOXForm().IsRelTabPos() && rLR.GetTxtLeft() ) 1714 nTabPosition -= rLR.GetTxtLeft(); 1715 aTStops.Insert( SvxTabStop( nTabPosition, 1716 aToken.eTabAlign, 1717 cDfltDecimalChar, 1718 aToken.cTabFillChar )); 1719 } 1720 else 1721 { 1722 const SwPageDesc* pPageDesc = ((SwFmtPageDesc&)pTOXNd-> 1723 SwCntntNode::GetAttr( RES_PAGEDESC )).GetPageDesc(); 1724 1725 sal_Bool bCallFindRect = sal_True; 1726 long nRightMargin; 1727 if( pPageDesc ) 1728 { 1729 const SwFrm* pFrm = pTOXNd->getLayoutFrm( pDoc->GetCurrentLayout(), 0, 0, sal_True ); 1730 if( !pFrm || 0 == ( pFrm = pFrm->FindPageFrm() ) || 1731 pPageDesc != ((SwPageFrm*)pFrm)->GetPageDesc() ) 1732 // dann muss man ueber den PageDesc gehen 1733 bCallFindRect = sal_False; 1734 } 1735 1736 SwRect aNdRect; 1737 if( bCallFindRect ) 1738 aNdRect = pTOXNd->FindLayoutRect( sal_True ); 1739 1740 if( aNdRect.IsEmpty() ) 1741 { 1742 // dann hilft alles nichts, wir muessen ueber die Seiten- 1743 // vorlage gehen. 1744 // OD 18.03.2003 #106329# - call 1745 sal_uInt32 nPgDescNdIdx = pTOXNd->GetIndex() + 1; 1746 sal_uInt32* pPgDescNdIdx = &nPgDescNdIdx; 1747 pPageDesc = pTOXNd->FindPageDesc( sal_False, pPgDescNdIdx ); 1748 if ( !pPageDesc || 1749 *pPgDescNdIdx < _nTOXSectNdIdx ) 1750 { 1751 // use default page description, if none is found 1752 // or the found one is given by a node before the 1753 // table-of-content section. 1754 pPageDesc = _pDefaultPageDesc; 1755 } 1756 1757 const SwFrmFmt& rPgDscFmt = pPageDesc->GetMaster(); 1758 nRightMargin = rPgDscFmt.GetFrmSize().GetWidth() - 1759 rPgDscFmt.GetLRSpace().GetLeft() - 1760 rPgDscFmt.GetLRSpace().GetRight(); 1761 } 1762 else 1763 nRightMargin = aNdRect.Width(); 1764 //#i24363# tab stops relative to indent 1765 if( pDoc->get(IDocumentSettingAccess::TABS_RELATIVE_TO_INDENT) ) 1766 { 1767 //left margin of paragraph style 1768 const SvxLRSpaceItem& rLRSpace = pTOXNd->GetTxtColl()->GetLRSpace(); 1769 nRightMargin -= rLRSpace.GetLeft(); 1770 nRightMargin -= rLRSpace.GetTxtFirstLineOfst(); 1771 } 1772 1773 aTStops.Insert( SvxTabStop( nRightMargin, SVX_TAB_ADJUST_RIGHT, 1774 cDfltDecimalChar, 1775 aToken.cTabFillChar )); 1776 } 1777 break; 1778 1779 case TOKEN_TEXT: 1780 rTxt.Append( aToken.sText ); 1781 break; 1782 1783 case TOKEN_PAGE_NUMS: 1784 // Platzhalter fuer Seitennummer(n) es wird nur der erste beachtet 1785 // 1786 { 1787 // Die Anzahl der gleichen Eintrage bestimmt die Seitennummern-Pattern 1788 // 1789 sal_uInt16 nSize = rBase.aTOXSources.Count(); 1790 if( nSize > 0 ) 1791 { 1792 String aInsStr( cNumRepl ); 1793 for(sal_uInt16 i=1; i < nSize; ++i) 1794 { 1795 aInsStr.AppendAscii( sPageDeli ); 1796 aInsStr += cNumRepl; 1797 } 1798 aInsStr += cEndPageNum; 1799 rTxt.Append( aInsStr ); 1800 } 1801 // // Tab entfernen, wenn keine Seitennummer 1802 // else if( rTxt.Len() && '\t' == rTxt.GetChar( rTxt.Len() - 1 )) 1803 // rTxt.Erase( rTxt.Len()-1, 1 ); 1804 } 1805 break; 1806 1807 case TOKEN_CHAPTER_INFO: 1808 { 1809 // ein bischen trickreich: suche irgend einen Frame 1810 const SwTOXSource* pTOXSource = 0; 1811 if(rBase.aTOXSources.Count()) 1812 pTOXSource = &rBase.aTOXSources[0]; 1813 1814 // --> OD 2008-02-14 #i53420# 1815 // if( pTOXSource && pTOXSource->pNd 1816 // pTOXSource->pNd->IsTxtNode() ) 1817 if ( pTOXSource && pTOXSource->pNd && 1818 pTOXSource->pNd->IsCntntNode() ) 1819 // <-- 1820 { 1821 const SwCntntFrm* pFrm = pTOXSource->pNd->getLayoutFrm( pDoc->GetCurrentLayout() ); 1822 if( pFrm ) 1823 { 1824 SwChapterFieldType aFldTyp; 1825 SwChapterField aFld( &aFldTyp, aToken.nChapterFormat ); 1826 aFld.SetLevel( static_cast<sal_uInt8>(aToken.nOutlineLevel - 1) ); 1827 // --> OD 2008-02-14 #i53420# 1828 // aFld.ChangeExpansion( pFrm, (SwTxtNode*)pTOXSource->pNd, sal_True ); 1829 aFld.ChangeExpansion( pFrm, 1830 dynamic_cast<const SwCntntNode*>(pTOXSource->pNd), 1831 sal_True ); 1832 // <-- 1833 //---> i89791 1834 // OD 2008-06-26 - continue to support CF_NUMBER 1835 // and CF_NUM_TITLE in order to handle ODF 1.0/1.1 1836 // written by OOo 3.x in the same way as OOo 2.x 1837 // would handle them. 1838 if ( CF_NUM_NOPREPST_TITLE == aToken.nChapterFormat || 1839 CF_NUMBER == aToken.nChapterFormat ) 1840 rTxt.Insert(aFld.GetNumber()); //get the string number without pre/postfix 1841 else if ( CF_NUMBER_NOPREPST == aToken.nChapterFormat || 1842 CF_NUM_TITLE == aToken.nChapterFormat ) 1843 //<--- 1844 { 1845 rTxt += aFld.GetNumber(); 1846 rTxt += ' '; 1847 rTxt += aFld.GetTitle(); 1848 } 1849 else if(CF_TITLE == aToken.nChapterFormat) 1850 rTxt += aFld.GetTitle(); 1851 } 1852 } 1853 } 1854 break; 1855 1856 case TOKEN_LINK_START: 1857 nLinkStartPosition = rTxt.Len(); 1858 sLinkCharacterStyle = aToken.sCharStyleName; 1859 break; 1860 1861 case TOKEN_LINK_END: 1862 //TODO: only paired start/end tokens are valid 1863 if( STRING_NOTFOUND != nLinkStartPosition) 1864 { 1865 SwIndex aIdx( pTOXNd, nLinkStartPosition ); 1866 //pTOXNd->Erase( aIdx, SwForm::nFormLinkSttLen ); 1867 xub_StrLen nEnd = rTxt.Len(); 1868 1869 if( !sURL.Len() ) 1870 { 1871 sURL = rBase.GetURL(); 1872 if( !sURL.Len() ) 1873 break; 1874 } 1875 LinkStruct* pNewLink = new LinkStruct(sURL, nLinkStartPosition, 1876 nEnd); 1877 const sal_uInt16 nPoolId = 1878 sLinkCharacterStyle.Len() == 0 1879 ? USHRT_MAX 1880 : SwStyleNameMapper::GetPoolIdFromUIName( sLinkCharacterStyle, nsSwGetPoolIdFromName::GET_POOLID_CHRFMT ); 1881 pNewLink->aINetFmt.SetVisitedFmtAndId( sLinkCharacterStyle, nPoolId ); 1882 pNewLink->aINetFmt.SetINetFmtAndId( sLinkCharacterStyle, nPoolId ); 1883 aLinkArr.Insert( pNewLink, aLinkArr.Count() ); 1884 nLinkStartPosition = STRING_NOTFOUND; 1885 sLinkCharacterStyle.Erase(); 1886 } 1887 break; 1888 1889 case TOKEN_AUTHORITY: 1890 { 1891 ToxAuthorityField eField = (ToxAuthorityField)aToken.nAuthorityField; 1892 SwIndex aIdx( pTOXNd, rTxt.Len() ); 1893 rBase.FillText( *pTOXNd, aIdx, static_cast<sal_uInt16>(eField) ); 1894 } 1895 break; 1896 case TOKEN_END: break; 1897 } 1898 1899 if( aToken.sCharStyleName.Len() ) 1900 { 1901 SwCharFmt* pCharFmt; 1902 if( USHRT_MAX != aToken.nPoolId ) 1903 pCharFmt = pDoc->GetCharFmtFromPool( aToken.nPoolId ); 1904 else 1905 pCharFmt = pDoc->FindCharFmtByName( aToken.sCharStyleName); 1906 1907 if (pCharFmt) 1908 { 1909 SwFmtCharFmt aFmt( pCharFmt ); 1910 pTOXNd->InsertItem( aFmt, nStartCharStyle, 1911 rTxt.Len(), nsSetAttrMode::SETATTR_DONTEXPAND ); 1912 } 1913 } 1914 1915 aIt++; // #i21237# 1916 } 1917 1918 pTOXNd->SetAttr( aTStops ); 1919 } 1920 1921 if(aLinkArr.Count()) 1922 for(sal_uInt16 i = 0; i < aLinkArr.Count(); ++i ) 1923 { 1924 LinkStruct* pTmp = aLinkArr.GetObject(i); 1925 pTOXNd->InsertItem( pTmp->aINetFmt, pTmp->nStartTextPos, 1926 pTmp->nEndTextPos); 1927 } 1928 } 1929 1930 /*-------------------------------------------------------------------- 1931 Beschreibung: Seitennummer errechnen und nach dem Formatieren 1932 eintragen 1933 --------------------------------------------------------------------*/ 1934 1935 void SwTOXBaseSection::UpdatePageNum() 1936 { 1937 if( !aSortArr.Count() ) 1938 return ; 1939 1940 // die aktuellen Seitennummern ins Verzeichnis eintragen 1941 SwPageFrm* pAktPage = 0; 1942 sal_uInt16 nPage = 0; 1943 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); 1944 1945 SwTOXInternational aIntl( GetLanguage(), 1946 TOX_INDEX == GetTOXType()->GetType() ? 1947 GetOptions() : 0, 1948 GetSortAlgorithm() ); 1949 1950 for( sal_uInt16 nCnt = 0; nCnt < aSortArr.Count(); ++nCnt ) 1951 { 1952 // Schleife ueber alle SourceNodes 1953 SvUShorts aNums; //Die Seitennummern 1954 SvPtrarr aDescs; //Die PageDescriptoren passend zu den Seitennummern. 1955 SvUShorts* pMainNums = 0; // contains page numbers of main entries 1956 1957 // process run in lines 1958 sal_uInt16 nRange = 0; 1959 if(GetTOXForm().IsCommaSeparated() && 1960 aSortArr[nCnt]->GetType() == TOX_SORT_INDEX) 1961 { 1962 const SwTOXMark& rMark = aSortArr[nCnt]->pTxtMark->GetTOXMark(); 1963 const String sPrimKey = rMark.GetPrimaryKey(); 1964 const String sSecKey = rMark.GetSecondaryKey(); 1965 const SwTOXMark* pNextMark = 0; 1966 while(aSortArr.Count() > (nCnt + nRange)&& 1967 aSortArr[nCnt + nRange]->GetType() == TOX_SORT_INDEX && 1968 0 != (pNextMark = &(aSortArr[nCnt + nRange]->pTxtMark->GetTOXMark())) && 1969 pNextMark->GetPrimaryKey() == sPrimKey && 1970 pNextMark->GetSecondaryKey() == sSecKey) 1971 nRange++; 1972 } 1973 else 1974 nRange = 1; 1975 1976 for(sal_uInt16 nRunInEntry = nCnt; nRunInEntry < nCnt + nRange; nRunInEntry++) 1977 { 1978 SwTOXSortTabBase* pSortBase = aSortArr[nRunInEntry]; 1979 sal_uInt16 nSize = pSortBase->aTOXSources.Count(); 1980 sal_uInt16 i; 1981 for( sal_uInt16 j = 0; j < nSize; ++j ) 1982 { 1983 ::SetProgressState( 0, pDoc->GetDocShell() ); 1984 1985 SwTOXSource& rTOXSource = pSortBase->aTOXSources[j]; 1986 if( rTOXSource.pNd ) 1987 { 1988 SwCntntFrm* pFrm = rTOXSource.pNd->getLayoutFrm( pDoc->GetCurrentLayout() ); 1989 ASSERT( pFrm || pDoc->IsUpdateTOX(), "TOX, no Frame found"); 1990 if( !pFrm ) 1991 continue; 1992 if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->HasFollow() ) 1993 { 1994 // dann suche den richtigen heraus 1995 SwTxtFrm* pNext = (SwTxtFrm*)pFrm; 1996 while( 0 != ( pNext = (SwTxtFrm*)pFrm->GetFollow() ) 1997 && rTOXSource.nPos >= pNext->GetOfst() ) 1998 pFrm = pNext; 1999 } 2000 2001 SwPageFrm* pTmpPage = pFrm->FindPageFrm(); 2002 if( pTmpPage != pAktPage ) 2003 { 2004 nPage = pTmpPage->GetVirtPageNum(); 2005 pAktPage = pTmpPage; 2006 } 2007 2008 // sortiert einfuegen 2009 for( i = 0; i < aNums.Count() && aNums[i] < nPage; ++i ) 2010 ; 2011 2012 if( i >= aNums.Count() || aNums[ i ] != nPage ) 2013 { 2014 aNums.Insert( nPage, i ); 2015 aDescs.Insert( (void*)pAktPage->GetPageDesc(), i ); 2016 } 2017 // is it a main entry? 2018 if(TOX_SORT_INDEX == pSortBase->GetType() && 2019 rTOXSource.bMainEntry) 2020 { 2021 if(!pMainNums) 2022 pMainNums = new SvUShorts; 2023 pMainNums->Insert(nPage, pMainNums->Count()); 2024 } 2025 } 2026 } 2027 // einfuegen der Seitennummer in den Verzeichnis-Text-Node 2028 const SwTOXSortTabBase* pBase = aSortArr[ nCnt ]; 2029 if(pBase->pTOXNd) 2030 { 2031 const SwTxtNode* pTxtNd = pBase->pTOXNd->GetTxtNode(); 2032 ASSERT( pTxtNd, "kein TextNode, falsches Verzeichnis" ); 2033 2034 _UpdatePageNum( (SwTxtNode*)pTxtNd, aNums, aDescs, pMainNums, 2035 aIntl ); 2036 } 2037 DELETEZ(pMainNums); 2038 aNums.Remove(0, aNums.Count()); 2039 } 2040 } 2041 // nach dem Setzen der richtigen Seitennummer, das Mapping-Array 2042 // wieder loeschen !! 2043 aSortArr.DeleteAndDestroy( 0, aSortArr.Count() ); 2044 } 2045 2046 2047 /*-------------------------------------------------------------------- 2048 Beschreibung: Austausch der Seitennummer-Platzhalter 2049 --------------------------------------------------------------------*/ 2050 2051 // search for the page no in the array of main entry page numbers 2052 sal_Bool lcl_HasMainEntry( const SvUShorts* pMainEntryNums, sal_uInt16 nToFind ) 2053 { 2054 for(sal_uInt16 i = 0; pMainEntryNums && i < pMainEntryNums->Count(); ++i) 2055 if(nToFind == (*pMainEntryNums)[i]) 2056 return sal_True; 2057 return sal_False; 2058 } 2059 2060 void SwTOXBaseSection::_UpdatePageNum( SwTxtNode* pNd, 2061 const SvUShorts& rNums, 2062 const SvPtrarr & rDescs, 2063 const SvUShorts* pMainEntryNums, 2064 const SwTOXInternational& rIntl ) 2065 { 2066 //collect starts end ends of main entry character style 2067 SvUShorts* pCharStyleIdx = pMainEntryNums ? new SvUShorts : 0; 2068 2069 String sSrchStr( cNumRepl ); 2070 sSrchStr.AppendAscii( sPageDeli ) += cNumRepl; 2071 xub_StrLen nStartPos = pNd->GetTxt().Search( sSrchStr ); 2072 ( sSrchStr = cNumRepl ) += cEndPageNum; 2073 xub_StrLen nEndPos = pNd->GetTxt().Search( sSrchStr ); 2074 sal_uInt16 i; 2075 2076 if( STRING_NOTFOUND == nEndPos || !rNums.Count() ) 2077 return; 2078 2079 if( STRING_NOTFOUND == nStartPos || nStartPos > nEndPos) 2080 nStartPos = nEndPos; 2081 2082 sal_uInt16 nOld = rNums[0], 2083 nBeg = nOld, 2084 nCount = 0; 2085 String aNumStr( SvxNumberType( ((SwPageDesc*)rDescs[0])->GetNumType() ). 2086 GetNumStr( nBeg ) ); 2087 if( pCharStyleIdx && lcl_HasMainEntry( pMainEntryNums, nBeg )) 2088 { 2089 sal_uInt16 nTemp = 0; 2090 pCharStyleIdx->Insert( nTemp, pCharStyleIdx->Count()); 2091 } 2092 2093 // Platzhalter loeschen 2094 SwIndex aPos(pNd, nStartPos); 2095 SwCharFmt* pPageNoCharFmt = 0; 2096 SwpHints* pHints = pNd->GetpSwpHints(); 2097 if(pHints) 2098 for(sal_uInt16 nHintIdx = 0; nHintIdx < pHints->GetStartCount(); nHintIdx++) 2099 { 2100 SwTxtAttr* pAttr = pHints->GetStart(nHintIdx); 2101 const xub_StrLen nTmpEnd = pAttr->End() ? *pAttr->End() : 0; 2102 if( nStartPos >= *pAttr->GetStart() && 2103 (nStartPos + 2) <= nTmpEnd && 2104 pAttr->Which() == RES_TXTATR_CHARFMT) 2105 { 2106 pPageNoCharFmt = pAttr->GetCharFmt().GetCharFmt(); 2107 break; 2108 } 2109 } 2110 pNd->EraseText(aPos, nEndPos - nStartPos + 2); 2111 2112 for( i = 1; i < rNums.Count(); ++i) 2113 { 2114 SvxNumberType aType( ((SwPageDesc*)rDescs[i])->GetNumType() ); 2115 if( TOX_INDEX == SwTOXBase::GetType() ) 2116 { // Zusammenfassen f. ff. 2117 // Alle folgenden aufaddieren 2118 // break up if main entry starts or ends and 2119 // insert a char style index 2120 sal_Bool bMainEntryChanges = lcl_HasMainEntry(pMainEntryNums, nOld) 2121 != lcl_HasMainEntry(pMainEntryNums, rNums[i]); 2122 2123 if(nOld == rNums[i]-1 && !bMainEntryChanges && 2124 0 != (GetOptions() & (nsSwTOIOptions::TOI_FF|nsSwTOIOptions::TOI_DASH))) 2125 nCount++; 2126 else 2127 { 2128 // ff. f. alten Wert flushen 2129 if(GetOptions() & nsSwTOIOptions::TOI_FF) 2130 { 2131 if ( nCount >= 1 ) 2132 aNumStr += rIntl.GetFollowingText( nCount > 1 ); 2133 } 2134 else 2135 { 2136 if(nCount >= 2 ) 2137 aNumStr += '-'; 2138 else if(nCount == 1 ) 2139 aNumStr.AppendAscii( sPageDeli ); 2140 //#58127# Wenn nCount == 0, dann steht die einzige Seitenzahl schon im aNumStr! 2141 if(nCount) 2142 aNumStr += aType.GetNumStr( nBeg + nCount ); 2143 } 2144 2145 // neuen String anlegen 2146 nBeg = rNums[i]; 2147 aNumStr.AppendAscii( sPageDeli ); 2148 //the change of the character style must apply after sPageDeli is appended 2149 if(pCharStyleIdx && bMainEntryChanges) 2150 pCharStyleIdx->Insert(aNumStr.Len(), 2151 pCharStyleIdx->Count()); 2152 aNumStr += aType.GetNumStr( nBeg ); 2153 nCount = 0; 2154 } 2155 nOld = rNums[i]; 2156 } 2157 else 2158 { // Alle Nummern eintragen 2159 aNumStr += aType.GetNumStr( sal_uInt16(rNums[i]) ); 2160 if(i != (rNums.Count()-1)) 2161 aNumStr.AppendAscii( sPageDeli ); 2162 } 2163 } 2164 // Bei Ende und ff. alten Wert flushen 2165 if( TOX_INDEX == SwTOXBase::GetType() ) 2166 { 2167 if(GetOptions() & nsSwTOIOptions::TOI_FF) 2168 { 2169 if( nCount >= 1 ) 2170 aNumStr += rIntl.GetFollowingText( nCount > 1 ); 2171 } 2172 else 2173 { 2174 if(nCount >= 2) 2175 aNumStr +='-'; 2176 else if(nCount == 1) 2177 aNumStr.AppendAscii( sPageDeli ); 2178 //#58127# Wenn nCount == 0, dann steht die einzige Seitenzahl schon im aNumStr! 2179 if(nCount) 2180 aNumStr += SvxNumberType( ((SwPageDesc*)rDescs[i-1])-> 2181 GetNumType() ).GetNumStr( nBeg+nCount ); 2182 } 2183 } 2184 pNd->InsertText( aNumStr, aPos, 2185 static_cast<IDocumentContentOperations::InsertFlags>( 2186 IDocumentContentOperations::INS_EMPTYEXPAND | 2187 IDocumentContentOperations::INS_FORCEHINTEXPAND) ); 2188 if(pPageNoCharFmt) 2189 { 2190 SwFmtCharFmt aCharFmt( pPageNoCharFmt ); 2191 pNd->InsertItem(aCharFmt, nStartPos, nStartPos + aNumStr.Len(), nsSetAttrMode::SETATTR_DONTEXPAND); 2192 } 2193 2194 //now the main entries should get there character style 2195 if(pCharStyleIdx && pCharStyleIdx->Count() && GetMainEntryCharStyle().Len()) 2196 { 2197 // eventually the last index must me appended 2198 if(pCharStyleIdx->Count()&0x01) 2199 pCharStyleIdx->Insert(aNumStr.Len(), pCharStyleIdx->Count()); 2200 2201 //search by name 2202 SwDoc* pDoc = pNd->GetDoc(); 2203 sal_uInt16 nPoolId = SwStyleNameMapper::GetPoolIdFromUIName( GetMainEntryCharStyle(), nsSwGetPoolIdFromName::GET_POOLID_CHRFMT ); 2204 SwCharFmt* pCharFmt = 0; 2205 if(USHRT_MAX != nPoolId) 2206 pCharFmt = pDoc->GetCharFmtFromPool(nPoolId); 2207 else 2208 pCharFmt = pDoc->FindCharFmtByName( GetMainEntryCharStyle() ); 2209 if(!pCharFmt) 2210 pCharFmt = pDoc->MakeCharFmt(GetMainEntryCharStyle(), 0); 2211 2212 //find the page numbers in aNumStr and set the character style 2213 xub_StrLen nOffset = pNd->GetTxt().Len() - aNumStr.Len(); 2214 SwFmtCharFmt aCharFmt(pCharFmt); 2215 for(sal_uInt16 j = 0; j < pCharStyleIdx->Count(); j += 2) 2216 { 2217 xub_StrLen nStartIdx = (*pCharStyleIdx)[j] + nOffset; 2218 xub_StrLen nEndIdx = (*pCharStyleIdx)[j + 1] + nOffset; 2219 pNd->InsertItem(aCharFmt, nStartIdx, nEndIdx, nsSetAttrMode::SETATTR_DONTEXPAND); 2220 } 2221 2222 } 2223 delete pCharStyleIdx; 2224 } 2225 2226 2227 /*-------------------------------------------------------------------- 2228 Beschreibung: Sortiert einfuegen in das SortArr 2229 --------------------------------------------------------------------*/ 2230 2231 void SwTOXBaseSection::InsertSorted(SwTOXSortTabBase* pNew) 2232 { 2233 Range aRange(0, aSortArr.Count()); 2234 if( TOX_INDEX == SwTOXBase::GetType() && pNew->pTxtMark ) 2235 { 2236 const SwTOXMark& rMark = pNew->pTxtMark->GetTOXMark(); 2237 // Schluessel auswerten 2238 // Den Bereich ermitteln, in dem einzufuegen ist 2239 if( 0 == (GetOptions() & nsSwTOIOptions::TOI_KEY_AS_ENTRY) && 2240 rMark.GetPrimaryKey().Len() ) 2241 { 2242 aRange = GetKeyRange( rMark.GetPrimaryKey(), 2243 rMark.GetPrimaryKeyReading(), 2244 *pNew, FORM_PRIMARY_KEY, aRange ); 2245 2246 if( rMark.GetSecondaryKey().Len() ) 2247 aRange = GetKeyRange( rMark.GetSecondaryKey(), 2248 rMark.GetSecondaryKeyReading(), 2249 *pNew, FORM_SECONDARY_KEY, aRange ); 2250 } 2251 } 2252 //search for identical entries and remove the trailing one 2253 if(TOX_AUTHORITIES == SwTOXBase::GetType()) 2254 { 2255 for(short i = (short)aRange.Min(); i < (short)aRange.Max(); ++i) 2256 { 2257 SwTOXSortTabBase* pOld = aSortArr[i]; 2258 if(*pOld == *pNew) 2259 { 2260 if(*pOld < *pNew) 2261 { 2262 delete pNew; 2263 return; 2264 } 2265 else 2266 { 2267 // remove the old content 2268 aSortArr.DeleteAndDestroy( i, 1 ); 2269 aRange.Max()--; 2270 break; 2271 } 2272 } 2273 } 2274 } 2275 2276 // find position and insert 2277 // 2278 short i; 2279 2280 for( i = (short)aRange.Min(); i < (short)aRange.Max(); ++i) 2281 { // nur auf gleicher Ebene pruefen 2282 // 2283 SwTOXSortTabBase* pOld = aSortArr[i]; 2284 if(*pOld == *pNew) 2285 { 2286 if(TOX_AUTHORITIES != SwTOXBase::GetType()) 2287 { 2288 // Eigener Eintrag fuer Doppelte oder Keywords 2289 // 2290 if( pOld->GetType() == TOX_SORT_CUSTOM && 2291 pNew->GetOptions() & nsSwTOIOptions::TOI_KEY_AS_ENTRY) 2292 continue; 2293 2294 if(!(pNew->GetOptions() & nsSwTOIOptions::TOI_SAME_ENTRY)) 2295 { // Eigener Eintrag 2296 aSortArr.Insert(pNew, i ); 2297 return; 2298 } 2299 // Eintrag schon vorhanden in Referenzliste aufnehmen 2300 pOld->aTOXSources.Insert( pNew->aTOXSources[0], 2301 pOld->aTOXSources.Count() ); 2302 2303 delete pNew; 2304 return; 2305 } 2306 #ifdef DBG_UTIL 2307 else 2308 DBG_ERROR("Bibliography entries cannot be found here"); 2309 #endif 2310 } 2311 if(*pNew < *pOld) 2312 break; 2313 } 2314 // SubLevel Skippen 2315 while( TOX_INDEX == SwTOXBase::GetType() && i < aRange.Max() && 2316 aSortArr[i]->GetLevel() > pNew->GetLevel() ) 2317 i++; 2318 2319 // An Position i wird eingefuegt 2320 aSortArr.Insert(pNew, i ); 2321 } 2322 2323 /*-------------------------------------------------------------------- 2324 Beschreibung: Schluessel-Bereich suchen und evtl einfuegen 2325 --------------------------------------------------------------------*/ 2326 2327 Range SwTOXBaseSection::GetKeyRange(const String& rStr, const String& rStrReading, 2328 const SwTOXSortTabBase& rNew, 2329 sal_uInt16 nLevel, const Range& rRange ) 2330 { 2331 const SwTOXInternational& rIntl = *rNew.pTOXIntl; 2332 String sToCompare(rStr); 2333 String sToCompareReading(rStrReading); 2334 2335 if( 0 != (nsSwTOIOptions::TOI_INITIAL_CAPS & GetOptions()) ) 2336 { 2337 String sUpper( rIntl.ToUpper( sToCompare, 0 )); 2338 sToCompare.Erase( 0, 1 ).Insert( sUpper, 0 ); 2339 } 2340 2341 ASSERT(rRange.Min() >= 0 && rRange.Max() >= 0, "Min Max < 0"); 2342 2343 const sal_uInt16 nMin = (sal_uInt16)rRange.Min(); 2344 const sal_uInt16 nMax = (sal_uInt16)rRange.Max(); 2345 2346 sal_uInt16 i; 2347 2348 for( i = nMin; i < nMax; ++i) 2349 { 2350 SwTOXSortTabBase* pBase = aSortArr[i]; 2351 2352 String sMyString, sMyStringReading; 2353 pBase->GetTxt( sMyString, sMyStringReading ); 2354 2355 if( rIntl.IsEqual( sMyString, sMyStringReading, pBase->GetLocale(), 2356 sToCompare, sToCompareReading, rNew.GetLocale() ) && 2357 pBase->GetLevel() == nLevel ) 2358 break; 2359 } 2360 if(i == nMax) 2361 { // Falls nicht vorhanden erzeugen und einfuegen 2362 // 2363 SwTOXCustom* pKey = new SwTOXCustom( sToCompare, sToCompareReading, nLevel, rIntl, 2364 rNew.GetLocale() ); 2365 for(i = nMin; i < nMax; ++i) 2366 { 2367 if(nLevel == aSortArr[i]->GetLevel() && *pKey < *(aSortArr[i])) 2368 break; 2369 } 2370 aSortArr.Insert(pKey, i ); 2371 } 2372 sal_uInt16 nStart = i+1; 2373 sal_uInt16 nEnd = aSortArr.Count(); 2374 2375 // Ende des Bereiches suchen 2376 for(i = nStart; i < aSortArr.Count(); ++i) 2377 { 2378 if(aSortArr[i]->GetLevel() <= nLevel) 2379 { nEnd = i; 2380 break; 2381 } 2382 } 2383 return Range(nStart, nEnd); 2384 } 2385 2386 2387 sal_Bool SwTOXBase::IsTOXBaseInReadonly() const 2388 { 2389 const SwTOXBaseSection *pSect = PTR_CAST(SwTOXBaseSection, this); 2390 sal_Bool bRet = sal_False; 2391 const SwSectionNode* pSectNode; 2392 if(pSect && pSect->GetFmt() && 2393 0 != (pSectNode = pSect->GetFmt()->GetSectionNode())) 2394 { 2395 const SwDocShell* pDocSh; 2396 bRet = (0 != (pDocSh = pSectNode->GetDoc()->GetDocShell()) && 2397 pDocSh->IsReadOnly()) || 2398 (0 != (pSectNode = pSectNode->StartOfSectionNode()->FindSectionNode())&& 2399 pSectNode->GetSection().IsProtectFlag()); 2400 2401 } 2402 return bRet; 2403 } 2404 2405 const SfxItemSet* SwTOXBase::GetAttrSet() const 2406 { 2407 const SwTOXBaseSection *pSect = PTR_CAST(SwTOXBaseSection, this); 2408 if(pSect && pSect->GetFmt()) 2409 return &pSect->GetFmt()->GetAttrSet(); 2410 return 0; 2411 } 2412 2413 void SwTOXBase::SetAttrSet( const SfxItemSet& rSet ) 2414 { 2415 SwTOXBaseSection *pSect = PTR_CAST(SwTOXBaseSection, this); 2416 if( pSect && pSect->GetFmt() ) 2417 pSect->GetFmt()->SetFmtAttr( rSet ); 2418 } 2419 2420 sal_Bool SwTOXBase::GetInfo( SfxPoolItem& rInfo ) const 2421 { 2422 switch( rInfo.Which() ) 2423 { 2424 case RES_CONTENT_VISIBLE: 2425 { 2426 SwTOXBaseSection *pSect = PTR_CAST(SwTOXBaseSection, this); 2427 if( pSect && pSect->GetFmt() ) 2428 pSect->GetFmt()->GetInfo( rInfo ); 2429 } 2430 return sal_False; 2431 } 2432 return sal_True; 2433 } 2434 2435