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->GetEnd() ) || 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_Int32 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 } 761 762 763 sal_Bool SwTOXBaseSection::SetPosAtStartEnd( SwPosition& rPos, sal_Bool bAtStart ) const 764 { 765 sal_Bool bRet = sal_False; 766 const SwSectionNode* pSectNd = GetFmt()->GetSectionNode(); 767 if( pSectNd ) 768 { 769 SwCntntNode* pCNd; 770 xub_StrLen nC = 0; 771 if( bAtStart ) 772 { 773 rPos.nNode = *pSectNd; 774 pCNd = pSectNd->GetDoc()->GetNodes().GoNext( &rPos.nNode ); 775 } 776 else 777 { 778 rPos.nNode = *pSectNd->EndOfSectionNode(); 779 pCNd = pSectNd->GetDoc()->GetNodes().GoPrevious( &rPos.nNode ); 780 if( pCNd ) nC = pCNd->Len(); 781 } 782 rPos.nContent.Assign( pCNd, nC ); 783 bRet = sal_True; 784 } 785 return bRet; 786 } 787 788 /*-------------------------------------------------------------------- 789 Beschreibung: Verzeichnisinhalt zusammensammeln 790 --------------------------------------------------------------------*/ 791 792 void SwTOXBaseSection::Update(const SfxItemSet* pAttr, 793 const bool _bNewTOX )//swmodtest 080307 794 { 795 const SwSectionNode* pSectNd; 796 if( !SwTOXBase::GetRegisteredIn()->GetDepends() || 797 !GetFmt() || 0 == (pSectNd = GetFmt()->GetSectionNode() ) || 798 !pSectNd->GetNodes().IsDocNodes() || 799 IsHiddenFlag() ) 800 return; 801 802 SwDoc* pDoc = (SwDoc*)pSectNd->GetDoc(); 803 804 DBG_ASSERT(pDoc != NULL, "Where is the document?"); 805 806 if(pAttr && pDoc && GetFmt()) 807 pDoc->ChgFmt(*GetFmt(), *pAttr); 808 809 // OD 18.03.2003 #106329# - determine default page description, which 810 // will be used by the content nodes, if no approriate one is found. 811 const SwPageDesc* pDefaultPageDesc; 812 { 813 pDefaultPageDesc = 814 pSectNd->GetSection().GetFmt()->GetPageDesc().GetPageDesc(); 815 if ( !_bNewTOX && !pDefaultPageDesc ) 816 { 817 // determine page description of table-of-content 818 sal_uInt32 nPgDescNdIdx = pSectNd->GetIndex() + 1; 819 sal_uInt32* pPgDescNdIdx = &nPgDescNdIdx; 820 pDefaultPageDesc = pSectNd->FindPageDesc( sal_False, pPgDescNdIdx ); 821 if ( nPgDescNdIdx < pSectNd->GetIndex() ) 822 { 823 pDefaultPageDesc = 0; 824 } 825 } 826 // OD 28.04.2003 #109166# - consider end node of content section in the 827 // node array. 828 if ( !pDefaultPageDesc && 829 ( pSectNd->EndOfSectionNode()->GetIndex() < 830 (pSectNd->GetNodes().GetEndOfContent().GetIndex() - 1) ) 831 ) 832 { 833 // determine page description of content after table-of-content 834 SwNodeIndex aIdx( *(pSectNd->EndOfSectionNode()) ); 835 const SwCntntNode* pNdAfterTOX = pSectNd->GetNodes().GoNext( &aIdx ); 836 const SwAttrSet& aNdAttrSet = pNdAfterTOX->GetSwAttrSet(); 837 const SvxBreak eBreak = aNdAttrSet.GetBreak().GetBreak(); 838 if ( !( eBreak == SVX_BREAK_PAGE_BEFORE || 839 eBreak == SVX_BREAK_PAGE_BOTH ) 840 ) 841 { 842 pDefaultPageDesc = pNdAfterTOX->FindPageDesc( sal_False ); 843 } 844 } 845 // OD 28.04.2003 #109166# - consider start node of content section in 846 // the node array. 847 if ( !pDefaultPageDesc && 848 ( pSectNd->GetIndex() > 849 (pSectNd->GetNodes().GetEndOfContent().StartOfSectionIndex() + 1) ) 850 ) 851 { 852 // determine page description of content before table-of-content 853 SwNodeIndex aIdx( *pSectNd ); 854 pDefaultPageDesc = 855 pSectNd->GetNodes().GoPrevious( &aIdx )->FindPageDesc( sal_False ); 856 857 } 858 if ( !pDefaultPageDesc ) 859 { 860 // determine default page description 861 pDefaultPageDesc = 862 &const_cast<const SwDoc *>(pDoc)->GetPageDesc( 0 ); 863 } 864 } 865 866 pDoc->SetModified(); 867 868 // get current Language 869 SwTOXInternational aIntl( GetLanguage(), 870 TOX_INDEX == GetTOXType()->GetType() ? 871 GetOptions() : 0, 872 GetSortAlgorithm() ); 873 874 aSortArr.DeleteAndDestroy( 0, aSortArr.Count() ); 875 876 // find the first layout node for this TOX, if it only find the content 877 // in his own chapter 878 const SwTxtNode* pOwnChapterNode = IsFromChapter() 879 ? ::lcl_FindChapterNode( *pSectNd, 0 ) 880 : 0; 881 882 SwNode2Layout aN2L( *pSectNd ); 883 ((SwSectionNode*)pSectNd)->DelFrms(); 884 885 // remove old content an insert one empty textnode (to hold the layout!) 886 SwTxtNode* pFirstEmptyNd; 887 { 888 pDoc->DeleteRedline( *pSectNd, true, USHRT_MAX ); 889 890 SwNodeIndex aSttIdx( *pSectNd, +1 ); 891 SwNodeIndex aEndIdx( *pSectNd->EndOfSectionNode() ); 892 pFirstEmptyNd = pDoc->GetNodes().MakeTxtNode( aEndIdx, 893 pDoc->GetTxtCollFromPool( RES_POOLCOLL_TEXT ) ); 894 895 { 896 // Task 70995 - save and restore PageDesc and Break Attributes 897 SwNodeIndex aNxtIdx( aSttIdx ); 898 const SwCntntNode* pCNd = aNxtIdx.GetNode().GetCntntNode(); 899 if( !pCNd ) 900 pCNd = pDoc->GetNodes().GoNext( &aNxtIdx ); 901 if( pCNd->HasSwAttrSet() ) 902 { 903 SfxItemSet aBrkSet( pDoc->GetAttrPool(), aBreakSetRange ); 904 aBrkSet.Put( *pCNd->GetpSwAttrSet() ); 905 if( aBrkSet.Count() ) 906 pFirstEmptyNd->SetAttr( aBrkSet ); 907 } 908 } 909 aEndIdx--; 910 SwPosition aPos( aEndIdx, SwIndex( pFirstEmptyNd, 0 )); 911 pDoc->CorrAbs( aSttIdx, aEndIdx, aPos, sal_True ); 912 913 // delete all before 914 DelFlyInRange( aSttIdx, aEndIdx ); 915 _DelBookmarks( aSttIdx, aEndIdx ); 916 917 pDoc->GetNodes().Delete( aSttIdx, aEndIdx.GetIndex() - aSttIdx.GetIndex() ); 918 919 } 920 921 // 922 // insert title of TOX 923 if( GetTitle().Len() ) 924 { 925 // then insert the headline section 926 SwNodeIndex aIdx( *pSectNd, +1 ); 927 928 SwTxtNode* pHeadNd = pDoc->GetNodes().MakeTxtNode( aIdx, 929 GetTxtFmtColl( FORM_TITLE ) ); 930 pHeadNd->InsertText( GetTitle(), SwIndex( pHeadNd ) ); 931 932 String sNm( GetTOXName() ); 933 // ??Resource 934 sNm.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "_Head" )); 935 936 SwSectionData headerData( TOX_HEADER_SECTION, sNm ); 937 938 SwNodeIndex aStt( *pHeadNd ); aIdx--; 939 SwSectionFmt* pSectFmt = pDoc->MakeSectionFmt( 0 ); 940 pDoc->GetNodes().InsertTextSection( 941 aStt, *pSectFmt, headerData, 0, &aIdx, true, false); 942 } 943 944 // jetzt waere ein prima Zeitpunkt, um die Numerierung zu updaten 945 pDoc->UpdateNumRule(); 946 947 if( GetCreateType() & nsSwTOXElement::TOX_MARK ) 948 UpdateMarks( aIntl, pOwnChapterNode ); 949 950 if( GetCreateType() & nsSwTOXElement::TOX_OUTLINELEVEL ) 951 UpdateOutline( pOwnChapterNode ); 952 953 if( GetCreateType() & nsSwTOXElement::TOX_TEMPLATE ) 954 UpdateTemplate( pOwnChapterNode ); 955 956 if( GetCreateType() & nsSwTOXElement::TOX_OLE || 957 TOX_OBJECTS == SwTOXBase::GetType()) 958 UpdateCntnt( nsSwTOXElement::TOX_OLE, pOwnChapterNode ); 959 960 if( GetCreateType() & nsSwTOXElement::TOX_TABLE || 961 (TOX_TABLES == SwTOXBase::GetType() && IsFromObjectNames()) ) 962 UpdateTable( pOwnChapterNode ); 963 964 if( GetCreateType() & nsSwTOXElement::TOX_GRAPHIC || 965 (TOX_ILLUSTRATIONS == SwTOXBase::GetType() && IsFromObjectNames())) 966 UpdateCntnt( nsSwTOXElement::TOX_GRAPHIC, pOwnChapterNode ); 967 968 if( GetSequenceName().Len() && !IsFromObjectNames() && 969 (TOX_TABLES == SwTOXBase::GetType() || 970 TOX_ILLUSTRATIONS == SwTOXBase::GetType() ) ) 971 UpdateSequence( pOwnChapterNode ); 972 973 if( GetCreateType() & nsSwTOXElement::TOX_FRAME ) 974 UpdateCntnt( nsSwTOXElement::TOX_FRAME, pOwnChapterNode ); 975 976 if(TOX_AUTHORITIES == SwTOXBase::GetType()) 977 UpdateAuthorities( aIntl ); 978 979 // Bei Bedarf Alphadelimitter einfuegen (nur bei Stichwoertern) 980 // 981 if( TOX_INDEX == SwTOXBase::GetType() && 982 ( GetOptions() & nsSwTOIOptions::TOI_ALPHA_DELIMITTER ) ) 983 InsertAlphaDelimitter( aIntl ); 984 985 // sortierte Liste aller Verzeichnismarken und Verzeichnisbereiche 986 void* p = 0; 987 String* pStr = 0; 988 sal_uInt16 nCnt = 0, nFormMax = GetTOXForm().GetFormMax(); 989 SvStringsDtor aStrArr( (sal_uInt8)nFormMax ); 990 SvPtrarr aCollArr( (sal_uInt8)nFormMax ); 991 for( ; nCnt < nFormMax; ++nCnt ) 992 { 993 aCollArr.Insert( p, nCnt ); 994 aStrArr.Insert( pStr, nCnt ); 995 } 996 997 SwNodeIndex aInsPos( *pFirstEmptyNd, 1 ); 998 for( nCnt = 0; nCnt < aSortArr.Count(); ++nCnt ) 999 { 1000 ::SetProgressState( 0, pDoc->GetDocShell() ); 1001 1002 // setze den Text in das Verzeichniss 1003 sal_uInt16 nLvl = aSortArr[ nCnt ]->GetLevel(); 1004 SwTxtFmtColl* pColl = (SwTxtFmtColl*)aCollArr[ nLvl ]; 1005 if( !pColl ) 1006 { 1007 pColl = GetTxtFmtColl( nLvl ); 1008 aCollArr.Remove( nLvl ); 1009 p = pColl; 1010 aCollArr.Insert( p , nLvl ); 1011 } 1012 1013 // Generierung: dynamische TabStops setzen 1014 SwTxtNode* pTOXNd = pDoc->GetNodes().MakeTxtNode( aInsPos , pColl ); 1015 aSortArr[ nCnt ]->pTOXNd = pTOXNd; 1016 1017 // Generierung: Form auswerten und Platzhalter 1018 // fuer die Seitennummer eintragen 1019 //if it is a TOX_INDEX and the SwForm IsCommaSeparated() 1020 // then a range of entries must be generated into one paragraph 1021 sal_uInt16 nRange = 1; 1022 if(TOX_INDEX == SwTOXBase::GetType() && 1023 GetTOXForm().IsCommaSeparated() && 1024 aSortArr[nCnt]->GetType() == TOX_SORT_INDEX) 1025 { 1026 const SwTOXMark& rMark = aSortArr[nCnt]->pTxtMark->GetTOXMark(); 1027 const String sPrimKey = rMark.GetPrimaryKey(); 1028 const String sSecKey = rMark.GetSecondaryKey(); 1029 const SwTOXMark* pNextMark = 0; 1030 while(aSortArr.Count() > (nCnt + nRange)&& 1031 aSortArr[nCnt + nRange]->GetType() == TOX_SORT_INDEX && 1032 0 != (pNextMark = &(aSortArr[nCnt + nRange]->pTxtMark->GetTOXMark())) && 1033 pNextMark->GetPrimaryKey() == sPrimKey && 1034 pNextMark->GetSecondaryKey() == sSecKey) 1035 nRange++; 1036 } 1037 // OD 18.03.2003 #106329# - pass node index of table-of-content section 1038 // and default page description to method <GenerateText(..)>. 1039 GenerateText( nCnt, nRange, aStrArr, pSectNd->GetIndex(), pDefaultPageDesc ); 1040 nCnt += nRange - 1; 1041 } 1042 1043 // delete the first dummy node and remove all Cursor into the prev node 1044 aInsPos = *pFirstEmptyNd; 1045 { 1046 SwPaM aCorPam( *pFirstEmptyNd ); 1047 aCorPam.GetPoint()->nContent.Assign( pFirstEmptyNd, 0 ); 1048 if( !aCorPam.Move( fnMoveForward ) ) 1049 aCorPam.Move( fnMoveBackward ); 1050 SwNodeIndex aEndIdx( aInsPos, 1 ); 1051 pDoc->CorrAbs( aInsPos, aEndIdx, *aCorPam.GetPoint(), sal_True ); 1052 1053 // Task 70995 - save and restore PageDesc and Break Attributes 1054 if( pFirstEmptyNd->HasSwAttrSet() ) 1055 { 1056 if( GetTitle().Len() ) 1057 aEndIdx = *pSectNd; 1058 else 1059 aEndIdx = *pFirstEmptyNd; 1060 SwCntntNode* pCNd = pDoc->GetNodes().GoNext( &aEndIdx ); 1061 if( pCNd ) // Robust against defect documents, e.g. i60336 1062 pCNd->SetAttr( *pFirstEmptyNd->GetpSwAttrSet() ); 1063 } 1064 } 1065 1066 // now create the new Frames 1067 sal_uLong nIdx = pSectNd->GetIndex(); 1068 // don't delete if index is empty 1069 if(nIdx + 2 < pSectNd->EndOfSectionIndex()) 1070 pDoc->GetNodes().Delete( aInsPos, 1 ); 1071 1072 aN2L.RestoreUpperFrms( pDoc->GetNodes(), nIdx, nIdx + 1 ); 1073 std::set<SwRootFrm*> aAllLayouts = pDoc->GetAllLayouts(); 1074 for ( std::set<SwRootFrm*>::iterator pLayoutIter = aAllLayouts.begin(); pLayoutIter != aAllLayouts.end(); pLayoutIter++) 1075 { 1076 SwFrm::CheckPageDescs( (SwPageFrm*)(*pLayoutIter)->Lower() ); 1077 }//swmod 080310 1078 1079 SetProtect( SwTOXBase::IsProtected() ); 1080 } 1081 1082 /*-------------------------------------------------------------------- 1083 Beschreibung: AlphaDelimitter einfuegen 1084 --------------------------------------------------------------------*/ 1085 1086 1087 void SwTOXBaseSection::InsertAlphaDelimitter( const SwTOXInternational& rIntl ) 1088 { 1089 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); 1090 String sDeli, sLastDeli; 1091 sal_uInt16 i = 0; 1092 while( i < aSortArr.Count() ) 1093 { 1094 ::SetProgressState( 0, pDoc->GetDocShell() ); 1095 1096 sal_uInt16 nLevel = aSortArr[i]->GetLevel(); 1097 1098 // Alpha-Delimitter ueberlesen 1099 if( nLevel == FORM_ALPHA_DELIMITTER ) 1100 continue; 1101 1102 String sMyString, sMyStringReading; 1103 aSortArr[i]->GetTxt( sMyString, sMyStringReading ); 1104 1105 sDeli = rIntl.GetIndexKey( sMyString, sMyStringReading, 1106 aSortArr[i]->GetLocale() ); 1107 1108 // Delimitter schon vorhanden ?? 1109 if( sDeli.Len() && sLastDeli != sDeli ) 1110 { 1111 // alle kleiner Blank wollen wir nicht haben -> sind Sonderzeichen 1112 if( ' ' <= sDeli.GetChar( 0 ) ) 1113 { 1114 SwTOXCustom* pCst = new SwTOXCustom( sDeli, aEmptyStr, FORM_ALPHA_DELIMITTER, 1115 rIntl, aSortArr[i]->GetLocale() ); 1116 aSortArr.Insert( pCst, i++ ); 1117 } 1118 sLastDeli = sDeli; 1119 } 1120 1121 // Skippen bis gleibhes oder kleineres Level erreicht ist 1122 do { 1123 i++; 1124 } while (i < aSortArr.Count() && aSortArr[i]->GetLevel() > nLevel); 1125 } 1126 } 1127 1128 /*-------------------------------------------------------------------- 1129 Beschreibung: Template auswerten 1130 --------------------------------------------------------------------*/ 1131 1132 SwTxtFmtColl* SwTOXBaseSection::GetTxtFmtColl( sal_uInt16 nLevel ) 1133 { 1134 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); 1135 const String& rName = GetTOXForm().GetTemplate( nLevel ); 1136 SwTxtFmtColl* pColl = rName.Len() ? pDoc->FindTxtFmtCollByName(rName) :0; 1137 if( !pColl ) 1138 { 1139 sal_uInt16 nPoolFmt = 0; 1140 const TOXTypes eMyType = SwTOXBase::GetType(); 1141 switch( eMyType ) 1142 { 1143 case TOX_INDEX: nPoolFmt = RES_POOLCOLL_TOX_IDXH; break; 1144 case TOX_USER: 1145 if( nLevel < 6 ) 1146 nPoolFmt = RES_POOLCOLL_TOX_USERH; 1147 else 1148 nPoolFmt = RES_POOLCOLL_TOX_USER6 - 6; 1149 break; 1150 case TOX_ILLUSTRATIONS: nPoolFmt = RES_POOLCOLL_TOX_ILLUSH; break; 1151 case TOX_OBJECTS: nPoolFmt = RES_POOLCOLL_TOX_OBJECTH; break; 1152 case TOX_TABLES: nPoolFmt = RES_POOLCOLL_TOX_TABLESH; break; 1153 case TOX_AUTHORITIES: nPoolFmt = RES_POOLCOLL_TOX_AUTHORITIESH; break; 1154 1155 case TOX_CONTENT: 1156 // im Content Bereich gibt es einen Sprung! 1157 if( nLevel < 6 ) 1158 nPoolFmt = RES_POOLCOLL_TOX_CNTNTH; 1159 else 1160 nPoolFmt = RES_POOLCOLL_TOX_CNTNT6 - 6; 1161 break; 1162 } 1163 1164 if(eMyType == TOX_AUTHORITIES && nLevel) 1165 nPoolFmt = nPoolFmt + 1; 1166 else if(eMyType == TOX_INDEX && nLevel) 1167 { 1168 //pool: Level 1,2,3, Delimiter 1169 //SwForm: Delimiter, Level 1,2,3 1170 nPoolFmt += 1 == nLevel ? nLevel + 3 : nLevel - 1; 1171 } 1172 else 1173 nPoolFmt = nPoolFmt + nLevel; 1174 pColl = pDoc->GetTxtCollFromPool( nPoolFmt ); 1175 } 1176 return pColl; 1177 } 1178 1179 1180 /*-------------------------------------------------------------------- 1181 Beschreibung: Aus Markierungen erzeugen 1182 --------------------------------------------------------------------*/ 1183 1184 void SwTOXBaseSection::UpdateMarks( const SwTOXInternational& rIntl, 1185 const SwTxtNode* pOwnChapterNode ) 1186 { 1187 const SwTOXType* pType = (SwTOXType*) SwTOXBase::GetRegisteredIn(); 1188 if( !pType->GetDepends() ) 1189 return; 1190 1191 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); 1192 TOXTypes eTOXTyp = GetTOXType()->GetType(); 1193 SwIterator<SwTOXMark,SwTOXType> aIter( *pType ); 1194 1195 SwTxtTOXMark* pTxtMark; 1196 SwTOXMark* pMark; 1197 for( pMark = aIter.First(); pMark; pMark = aIter.Next() ) 1198 { 1199 ::SetProgressState( 0, pDoc->GetDocShell() ); 1200 1201 if( pMark->GetTOXType()->GetType() == eTOXTyp && 1202 0 != ( pTxtMark = pMark->GetTxtTOXMark() ) ) 1203 { 1204 const SwTxtNode* pTOXSrc = pTxtMark->GetpTxtNd(); 1205 // nur TOXMarks einfuegen die im Doc stehen 1206 // nicht die, die im UNDO stehen 1207 // 1208 // if selected use marks from the same chapter only 1209 if( pTOXSrc->GetNodes().IsDocNodes() && 1210 pTOXSrc->GetTxt().Len() && pTOXSrc->GetDepends() && 1211 pTOXSrc->getLayoutFrm( pDoc->GetCurrentLayout() ) && 1212 (!IsFromChapter() || ::lcl_FindChapterNode( *pTOXSrc, 0 ) == pOwnChapterNode ) && 1213 !pTOXSrc->HasHiddenParaField() && 1214 !SwScriptInfo::IsInHiddenRange( *pTOXSrc, *pTxtMark->GetStart() ) ) 1215 { 1216 SwTOXSortTabBase* pBase = 0; 1217 if(TOX_INDEX == eTOXTyp) 1218 { 1219 // Stichwortverzeichnismarkierung 1220 lang::Locale aLocale; 1221 if ( pBreakIt->GetBreakIter().is() ) 1222 { 1223 aLocale = pBreakIt->GetLocale( 1224 pTOXSrc->GetLang( *pTxtMark->GetStart() ) ); 1225 } 1226 1227 pBase = new SwTOXIndex( *pTOXSrc, pTxtMark, 1228 GetOptions(), FORM_ENTRY, rIntl, aLocale ); 1229 InsertSorted(pBase); 1230 if(GetOptions() & nsSwTOIOptions::TOI_KEY_AS_ENTRY && 1231 pTxtMark->GetTOXMark().GetPrimaryKey().Len()) 1232 { 1233 pBase = new SwTOXIndex( *pTOXSrc, pTxtMark, 1234 GetOptions(), FORM_PRIMARY_KEY, rIntl, aLocale ); 1235 InsertSorted(pBase); 1236 if(pTxtMark->GetTOXMark().GetSecondaryKey().Len()) 1237 { 1238 pBase = new SwTOXIndex( *pTOXSrc, pTxtMark, 1239 GetOptions(), FORM_SECONDARY_KEY, rIntl, aLocale ); 1240 InsertSorted(pBase); 1241 } 1242 } 1243 } 1244 else if( TOX_USER == eTOXTyp || 1245 pMark->GetLevel() <= GetLevel()) 1246 { // Inhaltsberzeichnismarkierung 1247 // also used for user marks 1248 pBase = new SwTOXContent( *pTOXSrc, pTxtMark, rIntl ); 1249 InsertSorted(pBase); 1250 } 1251 } 1252 } 1253 } 1254 } 1255 1256 1257 /*-------------------------------------------------------------------- 1258 Beschreibung: Verzeichnisinhalt aus Gliederungsebene generieren 1259 --------------------------------------------------------------------*/ 1260 1261 1262 void SwTOXBaseSection::UpdateOutline( const SwTxtNode* pOwnChapterNode ) 1263 { 1264 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); 1265 SwNodes& rNds = pDoc->GetNodes(); 1266 1267 const SwOutlineNodes& rOutlNds = rNds.GetOutLineNds(); 1268 for( sal_uInt16 n = 0; n < rOutlNds.Count(); ++n ) 1269 { 1270 ::SetProgressState( 0, pDoc->GetDocShell() ); 1271 SwTxtNode* pTxtNd = rOutlNds[ n ]->GetTxtNode(); 1272 if( pTxtNd && pTxtNd->Len() && pTxtNd->GetDepends() && 1273 //sal_uInt16(pTxtNd->GetTxtColl()->GetOutlineLevel()+1) <= GetLevel() && //#outline level,zhaojianwei 1274 sal_uInt16( pTxtNd->GetAttrOutlineLevel()) <= GetLevel() && //<-end,zhaojianwei 1275 pTxtNd->getLayoutFrm( pDoc->GetCurrentLayout() ) && 1276 !pTxtNd->HasHiddenParaField() && 1277 !pTxtNd->HasHiddenCharAttribute( true ) && 1278 ( !IsFromChapter() || 1279 ::lcl_FindChapterNode( *pTxtNd, 0 ) == pOwnChapterNode )) 1280 { 1281 SwTOXPara * pNew = new SwTOXPara( *pTxtNd, nsSwTOXElement::TOX_OUTLINELEVEL ); 1282 InsertSorted( pNew ); 1283 } 1284 } 1285 } 1286 1287 /*-------------------------------------------------------------------- 1288 Beschreibung: Verzeichnisinhalt aus Vorlagenbereichen generieren 1289 --------------------------------------------------------------------*/ 1290 1291 void SwTOXBaseSection::UpdateTemplate( const SwTxtNode* pOwnChapterNode ) 1292 { 1293 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); 1294 for(sal_uInt16 i = 0; i < MAXLEVEL; i++) 1295 { 1296 String sTmpStyleNames = GetStyleNames(i); 1297 sal_uInt16 nTokenCount = sTmpStyleNames.GetTokenCount(TOX_STYLE_DELIMITER); 1298 for( sal_uInt16 nStyle = 0; nStyle < nTokenCount; ++nStyle ) 1299 { 1300 SwTxtFmtColl* pColl = pDoc->FindTxtFmtCollByName( 1301 sTmpStyleNames.GetToken( nStyle, 1302 TOX_STYLE_DELIMITER )); 1303 //TODO: no outline Collections in content indexes if OutlineLevels are already included 1304 if( !pColl || 1305 ( TOX_CONTENT == SwTOXBase::GetType() && 1306 GetCreateType() & nsSwTOXElement::TOX_OUTLINELEVEL && 1307 //NO_NUMBERING != pColl->GetOutlineLevel() ) )//#outline level,zhaojianwei 1308 pColl->IsAssignedToListLevelOfOutlineStyle()) )//<-end,zhaojianwei 1309 continue; 1310 1311 SwIterator<SwTxtNode,SwFmtColl> aIter( *pColl ); 1312 for( SwTxtNode* pTxtNd = aIter.First(); pTxtNd; pTxtNd = aIter.Next() ) 1313 { 1314 ::SetProgressState( 0, pDoc->GetDocShell() ); 1315 1316 if( pTxtNd->GetTxt().Len() && pTxtNd->getLayoutFrm( pDoc->GetCurrentLayout() ) && 1317 pTxtNd->GetNodes().IsDocNodes() && 1318 ( !IsFromChapter() || pOwnChapterNode == 1319 ::lcl_FindChapterNode( *pTxtNd, 0 ) ) ) 1320 { 1321 SwTOXPara * pNew = new SwTOXPara( *pTxtNd, nsSwTOXElement::TOX_TEMPLATE, i + 1 ); 1322 InsertSorted(pNew); 1323 } 1324 } 1325 } 1326 } 1327 } 1328 1329 /* -----------------14.07.99 09:59------------------- 1330 Description: generate content from sequence fields 1331 --------------------------------------------------*/ 1332 void SwTOXBaseSection::UpdateSequence( const SwTxtNode* pOwnChapterNode ) 1333 { 1334 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); 1335 SwFieldType* pSeqFld = pDoc->GetFldType(RES_SETEXPFLD, GetSequenceName(), false); 1336 if(!pSeqFld) 1337 return; 1338 1339 SwIterator<SwFmtFld,SwFieldType> aIter( *pSeqFld ); 1340 for( SwFmtFld* pFmtFld = aIter.First(); pFmtFld; pFmtFld = aIter.Next() ) 1341 { 1342 const SwTxtFld* pTxtFld = pFmtFld->GetTxtFld(); 1343 if(!pTxtFld) 1344 continue; 1345 const SwTxtNode& rTxtNode = pTxtFld->GetTxtNode(); 1346 ::SetProgressState( 0, pDoc->GetDocShell() ); 1347 1348 if( rTxtNode.GetTxt().Len() && rTxtNode.getLayoutFrm( pDoc->GetCurrentLayout() ) && 1349 rTxtNode.GetNodes().IsDocNodes() && 1350 ( !IsFromChapter() || 1351 ::lcl_FindChapterNode( rTxtNode, 0 ) == pOwnChapterNode ) ) 1352 { 1353 SwTOXPara * pNew = new SwTOXPara( rTxtNode, nsSwTOXElement::TOX_SEQUENCE, 1 ); 1354 //set indexes if the number or the reference text are to be displayed 1355 if( GetCaptionDisplay() == CAPTION_TEXT ) 1356 { 1357 pNew->SetStartIndex( 1358 SwGetExpField::GetReferenceTextPos( *pFmtFld, *pDoc )); 1359 } 1360 else if(GetCaptionDisplay() == CAPTION_NUMBER) 1361 { 1362 pNew->SetEndIndex(*pTxtFld->GetStart() + 1); 1363 } 1364 InsertSorted(pNew); 1365 } 1366 } 1367 } 1368 1369 void SwTOXBaseSection::UpdateAuthorities( const SwTOXInternational& rIntl ) 1370 { 1371 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); 1372 SwFieldType* pAuthFld = pDoc->GetFldType(RES_AUTHORITY, aEmptyStr, false); 1373 if(!pAuthFld) 1374 return; 1375 1376 SwIterator<SwFmtFld,SwFieldType> aIter( *pAuthFld ); 1377 for( SwFmtFld* pFmtFld = aIter.First(); pFmtFld; pFmtFld = aIter.Next() ) 1378 { 1379 const SwTxtFld* pTxtFld = pFmtFld->GetTxtFld(); 1380 //undo 1381 if(!pTxtFld) 1382 continue; 1383 const SwTxtNode& rTxtNode = pTxtFld->GetTxtNode(); 1384 ::SetProgressState( 0, pDoc->GetDocShell() ); 1385 1386 // const SwTxtNode* pChapterCompareNode = 0; 1387 1388 if( rTxtNode.GetTxt().Len() && rTxtNode.getLayoutFrm( pDoc->GetCurrentLayout() ) && 1389 rTxtNode.GetNodes().IsDocNodes() /*&& 1390 (!IsFromChapter() || pChapterCompareNode == pOwnChapterNode) */) 1391 { 1392 //#106485# the body node has to be used! 1393 SwCntntFrm *pFrm = rTxtNode.getLayoutFrm( pDoc->GetCurrentLayout() ); 1394 SwPosition aFldPos(rTxtNode); 1395 const SwTxtNode* pTxtNode = 0; 1396 if(pFrm && !pFrm->IsInDocBody()) 1397 pTxtNode = GetBodyTxtNode( *pDoc, aFldPos, *pFrm ); 1398 if(!pTxtNode) 1399 pTxtNode = &rTxtNode; 1400 SwTOXAuthority* pNew = new SwTOXAuthority( *pTxtNode, *pFmtFld, rIntl ); 1401 1402 InsertSorted(pNew); 1403 } 1404 } 1405 } 1406 1407 long lcl_IsSOObject( const SvGlobalName& rFactoryNm ) 1408 { 1409 static struct _SoObjType { 1410 long nFlag; 1411 // GlobalNameId 1412 struct _GlobalNameIds { 1413 sal_uInt32 n1; 1414 sal_uInt16 n2, n3; 1415 sal_uInt8 b8, b9, b10, b11, b12, b13, b14, b15; 1416 } aGlNmIds[4]; 1417 } aArr[] = { 1418 { nsSwTOOElements::TOO_MATH, 1419 { {SO3_SM_CLASSID_60},{SO3_SM_CLASSID_50}, 1420 {SO3_SM_CLASSID_40},{SO3_SM_CLASSID_30} } }, 1421 { nsSwTOOElements::TOO_CHART, 1422 { {SO3_SCH_CLASSID_60},{SO3_SCH_CLASSID_50}, 1423 {SO3_SCH_CLASSID_40},{SO3_SCH_CLASSID_30} } }, 1424 { nsSwTOOElements::TOO_CALC, 1425 { {SO3_SC_CLASSID_60},{SO3_SC_CLASSID_50}, 1426 {SO3_SC_CLASSID_40},{SO3_SC_CLASSID_30} } }, 1427 { nsSwTOOElements::TOO_DRAW_IMPRESS, 1428 { {SO3_SIMPRESS_CLASSID_60},{SO3_SIMPRESS_CLASSID_50}, 1429 {SO3_SIMPRESS_CLASSID_40},{SO3_SIMPRESS_CLASSID_30} } }, 1430 { nsSwTOOElements::TOO_DRAW_IMPRESS, 1431 { {SO3_SDRAW_CLASSID_60},{SO3_SDRAW_CLASSID_50}}}, 1432 { 0,{{0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0}, 1433 {0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0} } } 1434 }; 1435 1436 long nRet = 0; 1437 for( const _SoObjType* pArr = aArr; !nRet && pArr->nFlag; ++pArr ) 1438 for ( int n = 0; n < 4; ++n ) 1439 { 1440 const _SoObjType::_GlobalNameIds& rId = pArr->aGlNmIds[ n ]; 1441 if( !rId.n1 ) 1442 break; 1443 SvGlobalName aGlbNm( rId.n1, rId.n2, rId.n3, 1444 rId.b8, rId.b9, rId.b10, rId.b11, 1445 rId.b12, rId.b13, rId.b14, rId.b15 ); 1446 if( rFactoryNm == aGlbNm ) 1447 { 1448 nRet = pArr->nFlag; 1449 break; 1450 } 1451 } 1452 1453 return nRet; 1454 } 1455 1456 void SwTOXBaseSection::UpdateCntnt( SwTOXElement eMyType, 1457 const SwTxtNode* pOwnChapterNode ) 1458 { 1459 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); 1460 SwNodes& rNds = pDoc->GetNodes(); 1461 // auf den 1. Node der 1. Section 1462 sal_uLong nIdx = rNds.GetEndOfAutotext().StartOfSectionIndex() + 2, 1463 nEndIdx = rNds.GetEndOfAutotext().GetIndex(); 1464 1465 while( nIdx < nEndIdx ) 1466 { 1467 ::SetProgressState( 0, pDoc->GetDocShell() ); 1468 1469 SwNode* pNd = rNds[ nIdx ]; 1470 SwCntntNode* pCNd = 0; 1471 switch( eMyType ) 1472 { 1473 case nsSwTOXElement::TOX_FRAME: 1474 if( !pNd->IsNoTxtNode() ) 1475 { 1476 pCNd = pNd->GetCntntNode(); 1477 if( !pCNd ) 1478 { 1479 SwNodeIndex aTmp( *pNd ); 1480 pCNd = rNds.GoNext( &aTmp ); 1481 } 1482 } 1483 break; 1484 case nsSwTOXElement::TOX_GRAPHIC: 1485 if( pNd->IsGrfNode() ) 1486 pCNd = (SwCntntNode*)pNd; 1487 break; 1488 case nsSwTOXElement::TOX_OLE: 1489 if( pNd->IsOLENode() ) 1490 { 1491 sal_Bool bInclude = sal_True; 1492 if(TOX_OBJECTS == SwTOXBase::GetType()) 1493 { 1494 SwOLENode* pOLENode = pNd->GetOLENode(); 1495 long nMyOLEOptions = GetOLEOptions(); 1496 SwOLEObj& rOLEObj = pOLENode->GetOLEObj(); 1497 1498 if( rOLEObj.IsOleRef() ) //Noch nicht geladen 1499 { 1500 SvGlobalName aTmpName = SvGlobalName( rOLEObj.GetOleRef()->getClassID() ); 1501 long nObj = ::lcl_IsSOObject( aTmpName ); 1502 bInclude = ( (nMyOLEOptions & nsSwTOOElements::TOO_OTHER) && 0 == nObj) 1503 || (0 != (nMyOLEOptions & nObj)); 1504 } 1505 else 1506 { 1507 DBG_ERROR("OLE-object nicht geladen?"); 1508 bInclude = sal_False; 1509 } 1510 } 1511 1512 if(bInclude) 1513 pCNd = (SwCntntNode*)pNd; 1514 } 1515 break; 1516 default: break; 1517 } 1518 1519 if( pCNd ) 1520 { 1521 //find node in body text 1522 int nSetLevel = USHRT_MAX; 1523 1524 //#111105# tables of tables|illustrations|objects don't support hierarchies 1525 if( IsLevelFromChapter() && 1526 TOX_TABLES != SwTOXBase::GetType() && 1527 TOX_ILLUSTRATIONS != SwTOXBase::GetType() && 1528 TOX_OBJECTS != SwTOXBase::GetType() ) 1529 { 1530 const SwTxtNode* pOutlNd = ::lcl_FindChapterNode( *pCNd, 1531 MAXLEVEL - 1 ); 1532 if( pOutlNd ) 1533 { 1534 //sal_uInt16 nTmp = pOutlNd->GetTxtColl()->GetOutlineLevel();//#outline level,zhaojianwei 1535 //if( nTmp < NO_NUMBERING ) 1536 // nSetLevel = nTmp + 1; 1537 if( pOutlNd->GetTxtColl()->IsAssignedToListLevelOfOutlineStyle()) 1538 nSetLevel = pOutlNd->GetTxtColl()->GetAttrOutlineLevel() ;//<-end,zhaojianwei 1539 } 1540 } 1541 1542 if( pCNd->getLayoutFrm( pDoc->GetCurrentLayout() ) && ( !IsFromChapter() || 1543 ::lcl_FindChapterNode( *pCNd, 0 ) == pOwnChapterNode )) 1544 { 1545 SwTOXPara * pNew = new SwTOXPara( *pCNd, eMyType, 1546 ( USHRT_MAX != nSetLevel ) 1547 ? static_cast<sal_uInt16>(nSetLevel) 1548 : FORM_ALPHA_DELIMITTER ); 1549 InsertSorted( pNew ); 1550 } 1551 } 1552 1553 nIdx = pNd->StartOfSectionNode()->EndOfSectionIndex() + 2; // 2 == End-/StartNode 1554 } 1555 } 1556 1557 /*-------------------------------------------------------------------- 1558 Beschreibung: Tabelleneintraege zusammensuchen 1559 --------------------------------------------------------------------*/ 1560 1561 void SwTOXBaseSection::UpdateTable( const SwTxtNode* pOwnChapterNode ) 1562 { 1563 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); 1564 SwNodes& rNds = pDoc->GetNodes(); 1565 const SwFrmFmts& rArr = *pDoc->GetTblFrmFmts(); 1566 1567 for( sal_uInt16 n = 0; n < rArr.Count(); ++n ) 1568 { 1569 ::SetProgressState( 0, pDoc->GetDocShell() ); 1570 1571 SwTable* pTmpTbl = SwTable::FindTable( rArr[ n ] ); 1572 SwTableBox* pFBox; 1573 if( pTmpTbl && 0 != (pFBox = pTmpTbl->GetTabSortBoxes()[0] ) && 1574 pFBox->GetSttNd() && pFBox->GetSttNd()->GetNodes().IsDocNodes() ) 1575 { 1576 const SwTableNode* pTblNd = pFBox->GetSttNd()->FindTableNode(); 1577 SwNodeIndex aCntntIdx( *pTblNd, 1 ); 1578 1579 SwCntntNode* pCNd; 1580 while( 0 != ( pCNd = rNds.GoNext( &aCntntIdx ) ) && 1581 aCntntIdx.GetIndex() < pTblNd->EndOfSectionIndex() ) 1582 { 1583 if( pCNd->getLayoutFrm( pDoc->GetCurrentLayout() ) && (!IsFromChapter() || 1584 ::lcl_FindChapterNode( *pCNd, 0 ) == pOwnChapterNode )) 1585 { 1586 SwTOXTable * pNew = new SwTOXTable( *pCNd ); 1587 if( IsLevelFromChapter() && TOX_TABLES != SwTOXBase::GetType()) 1588 { 1589 const SwTxtNode* pOutlNd = 1590 ::lcl_FindChapterNode( *pCNd, MAXLEVEL - 1 ); 1591 if( pOutlNd ) 1592 { 1593 //sal_uInt16 nTmp = pOutlNd->GetTxtColl()->GetOutlineLevel();//#outline level,zhaojianwei 1594 //if( nTmp < NO_NUMBERING ) 1595 // pNew->SetLevel( nTmp + 1 ); 1596 if( pOutlNd->GetTxtColl()->IsAssignedToListLevelOfOutlineStyle()) 1597 { 1598 const int nTmp = pOutlNd->GetTxtColl()->GetAttrOutlineLevel(); 1599 pNew->SetLevel( static_cast<sal_uInt16>(nTmp) );//<-end ,zhaojianwei 1600 } 1601 } 1602 } 1603 InsertSorted(pNew); 1604 break; 1605 } 1606 } 1607 } 1608 } 1609 } 1610 1611 /*-------------------------------------------------------------------- 1612 Beschreibung: String generieren anhand der Form 1613 SonderZeichen 0-31 und 255 entfernen 1614 --------------------------------------------------------------------*/ 1615 1616 String lcl_GetNumString( const SwTOXSortTabBase& rBase, sal_Bool bUsePrefix, sal_uInt8 nLevel ) 1617 { 1618 String sRet; 1619 1620 if( !rBase.pTxtMark && rBase.aTOXSources.Count() > 0 ) 1621 { // nur wenn es keine Marke ist 1622 const SwTxtNode* pNd = rBase.aTOXSources[0].pNd->GetTxtNode(); 1623 if( pNd ) 1624 { 1625 const SwNumRule* pRule = pNd->GetNumRule(); 1626 1627 if( pRule && pNd->GetActualListLevel() < MAXLEVEL ) 1628 sRet = pNd->GetNumString(bUsePrefix, nLevel); 1629 } 1630 } 1631 return sRet; 1632 } 1633 1634 // OD 18.03.2003 #106329# - add parameter <_TOXSectNdIdx> and <_pDefaultPageDesc> 1635 // in order to control, which page description is used, no appropriate one is found. 1636 void SwTOXBaseSection::GenerateText( sal_uInt16 nArrayIdx, 1637 sal_uInt16 nCount, 1638 SvStringsDtor& , 1639 const sal_uInt32 _nTOXSectNdIdx, 1640 const SwPageDesc* _pDefaultPageDesc ) 1641 { 1642 LinkStructArr aLinkArr; 1643 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); 1644 ::SetProgressState( 0, pDoc->GetDocShell() ); 1645 1646 //pTOXNd is only set at the first mark 1647 SwTxtNode* pTOXNd = (SwTxtNode*)aSortArr[nArrayIdx]->pTOXNd; 1648 String& rTxt = (String&)pTOXNd->GetTxt(); 1649 rTxt.Erase(); 1650 for(sal_uInt16 nIndex = nArrayIdx; nIndex < nArrayIdx + nCount; nIndex++) 1651 { 1652 if(nIndex > nArrayIdx) 1653 rTxt.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ", " )); // comma separation 1654 // String mit dem Pattern aus der Form initialisieren 1655 const SwTOXSortTabBase& rBase = *aSortArr[nIndex]; 1656 sal_uInt16 nLvl = rBase.GetLevel(); 1657 ASSERT( nLvl < GetTOXForm().GetFormMax(), "ungueltiges FORM_LEVEL"); 1658 1659 SvxTabStopItem aTStops( 0, 0, SVX_TAB_ADJUST_DEFAULT, RES_PARATR_TABSTOP ); 1660 xub_StrLen nLinkStartPosition = STRING_NOTFOUND; 1661 String sLinkCharacterStyle; //default to "Default" character style - which is none 1662 String sURL; 1663 // create an enumerator 1664 // #i21237# 1665 SwFormTokens aPattern = GetTOXForm().GetPattern(nLvl); 1666 SwFormTokens::iterator aIt = aPattern.begin(); 1667 // remove text from node 1668 while(aIt != aPattern.end()) // #i21237# 1669 { 1670 SwFormToken aToken = *aIt; // #i21237# 1671 xub_StrLen nStartCharStyle = rTxt.Len(); 1672 switch( aToken.eTokenType ) 1673 { 1674 case TOKEN_ENTRY_NO: 1675 // fuer Inhaltsverzeichnis Numerierung 1676 rTxt.Insert( lcl_GetNumString( rBase, aToken.nChapterFormat == CF_NUMBER, static_cast<sal_uInt8>(aToken.nOutlineLevel - 1)) ); 1677 break; 1678 1679 case TOKEN_ENTRY_TEXT: 1680 { 1681 SwIndex aIdx( pTOXNd, rTxt.Len() ); 1682 rBase.FillText( *pTOXNd, aIdx ); 1683 } 1684 break; 1685 1686 case TOKEN_ENTRY: 1687 { 1688 // fuer Inhaltsverzeichnis Numerierung 1689 rTxt.Insert( lcl_GetNumString( rBase, sal_True, MAXLEVEL )); 1690 1691 SwIndex aIdx( pTOXNd, rTxt.Len() ); 1692 rBase.FillText( *pTOXNd, aIdx ); 1693 } 1694 break; 1695 1696 case TOKEN_TAB_STOP: 1697 if (aToken.bWithTab) // #i21237# 1698 rTxt.Append('\t'); 1699 // 1700 1701 if(SVX_TAB_ADJUST_END > aToken.eTabAlign) 1702 { 1703 const SvxLRSpaceItem& rLR = 1704 (SvxLRSpaceItem&)pTOXNd-> 1705 SwCntntNode::GetAttr( RES_LR_SPACE, sal_True ); 1706 1707 long nTabPosition = aToken.nTabStopPosition; 1708 if( !GetTOXForm().IsRelTabPos() && rLR.GetTxtLeft() ) 1709 nTabPosition -= rLR.GetTxtLeft(); 1710 aTStops.Insert( SvxTabStop( nTabPosition, 1711 aToken.eTabAlign, 1712 cDfltDecimalChar, 1713 aToken.cTabFillChar )); 1714 } 1715 else 1716 { 1717 const SwPageDesc* pPageDesc = ((SwFmtPageDesc&)pTOXNd-> 1718 SwCntntNode::GetAttr( RES_PAGEDESC )).GetPageDesc(); 1719 1720 sal_Bool bCallFindRect = sal_True; 1721 long nRightMargin; 1722 if( pPageDesc ) 1723 { 1724 const SwFrm* pFrm = pTOXNd->getLayoutFrm( pDoc->GetCurrentLayout(), 0, 0, sal_True ); 1725 if( !pFrm || 0 == ( pFrm = pFrm->FindPageFrm() ) || 1726 pPageDesc != ((SwPageFrm*)pFrm)->GetPageDesc() ) 1727 // dann muss man ueber den PageDesc gehen 1728 bCallFindRect = sal_False; 1729 } 1730 1731 SwRect aNdRect; 1732 if( bCallFindRect ) 1733 aNdRect = pTOXNd->FindLayoutRect( sal_True ); 1734 1735 if( aNdRect.IsEmpty() ) 1736 { 1737 // dann hilft alles nichts, wir muessen ueber die Seiten- 1738 // vorlage gehen. 1739 // OD 18.03.2003 #106329# - call 1740 sal_uInt32 nPgDescNdIdx = pTOXNd->GetIndex() + 1; 1741 sal_uInt32* pPgDescNdIdx = &nPgDescNdIdx; 1742 pPageDesc = pTOXNd->FindPageDesc( sal_False, pPgDescNdIdx ); 1743 if ( !pPageDesc || 1744 *pPgDescNdIdx < _nTOXSectNdIdx ) 1745 { 1746 // use default page description, if none is found 1747 // or the found one is given by a node before the 1748 // table-of-content section. 1749 pPageDesc = _pDefaultPageDesc; 1750 } 1751 1752 const SwFrmFmt& rPgDscFmt = pPageDesc->GetMaster(); 1753 nRightMargin = rPgDscFmt.GetFrmSize().GetWidth() - 1754 rPgDscFmt.GetLRSpace().GetLeft() - 1755 rPgDscFmt.GetLRSpace().GetRight(); 1756 } 1757 else 1758 nRightMargin = aNdRect.Width(); 1759 //#i24363# tab stops relative to indent 1760 if( pDoc->get(IDocumentSettingAccess::TABS_RELATIVE_TO_INDENT) ) 1761 { 1762 //left margin of paragraph style 1763 const SvxLRSpaceItem& rLRSpace = pTOXNd->GetTxtColl()->GetLRSpace(); 1764 nRightMargin -= rLRSpace.GetLeft(); 1765 nRightMargin -= rLRSpace.GetTxtFirstLineOfst(); 1766 } 1767 1768 aTStops.Insert( SvxTabStop( nRightMargin, SVX_TAB_ADJUST_RIGHT, 1769 cDfltDecimalChar, 1770 aToken.cTabFillChar )); 1771 } 1772 break; 1773 1774 case TOKEN_TEXT: 1775 rTxt.Append( aToken.sText ); 1776 break; 1777 1778 case TOKEN_PAGE_NUMS: 1779 // Platzhalter fuer Seitennummer(n) es wird nur der erste beachtet 1780 // 1781 { 1782 // Die Anzahl der gleichen Eintrage bestimmt die Seitennummern-Pattern 1783 // 1784 sal_uInt16 nSize = rBase.aTOXSources.Count(); 1785 if( nSize > 0 ) 1786 { 1787 String aInsStr( cNumRepl ); 1788 for(sal_uInt16 i=1; i < nSize; ++i) 1789 { 1790 aInsStr.AppendAscii( sPageDeli ); 1791 aInsStr += cNumRepl; 1792 } 1793 aInsStr += cEndPageNum; 1794 rTxt.Append( aInsStr ); 1795 } 1796 // // Tab entfernen, wenn keine Seitennummer 1797 // else if( rTxt.Len() && '\t' == rTxt.GetChar( rTxt.Len() - 1 )) 1798 // rTxt.Erase( rTxt.Len()-1, 1 ); 1799 } 1800 break; 1801 1802 case TOKEN_CHAPTER_INFO: 1803 { 1804 // ein bischen trickreich: suche irgend einen Frame 1805 const SwTOXSource* pTOXSource = 0; 1806 if(rBase.aTOXSources.Count()) 1807 pTOXSource = &rBase.aTOXSources[0]; 1808 1809 // --> OD 2008-02-14 #i53420# 1810 // if( pTOXSource && pTOXSource->pNd 1811 // pTOXSource->pNd->IsTxtNode() ) 1812 if ( pTOXSource && pTOXSource->pNd && 1813 pTOXSource->pNd->IsCntntNode() ) 1814 // <-- 1815 { 1816 const SwCntntFrm* pFrm = pTOXSource->pNd->getLayoutFrm( pDoc->GetCurrentLayout() ); 1817 if( pFrm ) 1818 { 1819 SwChapterFieldType aFldTyp; 1820 SwChapterField aFld( &aFldTyp, aToken.nChapterFormat ); 1821 aFld.SetLevel( static_cast<sal_uInt8>(aToken.nOutlineLevel - 1) ); 1822 // --> OD 2008-02-14 #i53420# 1823 // aFld.ChangeExpansion( pFrm, (SwTxtNode*)pTOXSource->pNd, sal_True ); 1824 aFld.ChangeExpansion( pFrm, 1825 dynamic_cast<const SwCntntNode*>(pTOXSource->pNd), 1826 sal_True ); 1827 // <-- 1828 //---> i89791 1829 // OD 2008-06-26 - continue to support CF_NUMBER 1830 // and CF_NUM_TITLE in order to handle ODF 1.0/1.1 1831 // written by OOo 3.x in the same way as OOo 2.x 1832 // would handle them. 1833 if ( CF_NUM_NOPREPST_TITLE == aToken.nChapterFormat || 1834 CF_NUMBER == aToken.nChapterFormat ) 1835 rTxt.Insert(aFld.GetNumber()); //get the string number without pre/postfix 1836 else if ( CF_NUMBER_NOPREPST == aToken.nChapterFormat || 1837 CF_NUM_TITLE == aToken.nChapterFormat ) 1838 //<--- 1839 { 1840 rTxt += aFld.GetNumber(); 1841 rTxt += ' '; 1842 rTxt += aFld.GetTitle(); 1843 } 1844 else if(CF_TITLE == aToken.nChapterFormat) 1845 rTxt += aFld.GetTitle(); 1846 } 1847 } 1848 } 1849 break; 1850 1851 case TOKEN_LINK_START: 1852 nLinkStartPosition = rTxt.Len(); 1853 sLinkCharacterStyle = aToken.sCharStyleName; 1854 break; 1855 1856 case TOKEN_LINK_END: 1857 //TODO: only paired start/end tokens are valid 1858 if( STRING_NOTFOUND != nLinkStartPosition) 1859 { 1860 SwIndex aIdx( pTOXNd, nLinkStartPosition ); 1861 //pTOXNd->Erase( aIdx, SwForm::nFormLinkSttLen ); 1862 xub_StrLen nEnd = rTxt.Len(); 1863 1864 if( !sURL.Len() ) 1865 { 1866 sURL = rBase.GetURL(); 1867 if( !sURL.Len() ) 1868 break; 1869 } 1870 LinkStruct* pNewLink = new LinkStruct(sURL, nLinkStartPosition, 1871 nEnd); 1872 pNewLink->aINetFmt.SetVisitedFmt(sLinkCharacterStyle); 1873 pNewLink->aINetFmt.SetINetFmt(sLinkCharacterStyle); 1874 if(sLinkCharacterStyle.Len()) 1875 { 1876 sal_uInt16 nPoolId = 1877 SwStyleNameMapper::GetPoolIdFromUIName( sLinkCharacterStyle, nsSwGetPoolIdFromName::GET_POOLID_CHRFMT ); 1878 pNewLink->aINetFmt.SetVisitedFmtId(nPoolId); 1879 pNewLink->aINetFmt.SetINetFmtId(nPoolId); 1880 } 1881 else 1882 { 1883 pNewLink->aINetFmt.SetVisitedFmtId(USHRT_MAX); 1884 pNewLink->aINetFmt.SetINetFmtId(USHRT_MAX); 1885 } 1886 aLinkArr.Insert( pNewLink, aLinkArr.Count() ); 1887 nLinkStartPosition = STRING_NOTFOUND; 1888 sLinkCharacterStyle.Erase(); 1889 } 1890 break; 1891 1892 case TOKEN_AUTHORITY: 1893 { 1894 ToxAuthorityField eField = (ToxAuthorityField)aToken.nAuthorityField; 1895 SwIndex aIdx( pTOXNd, rTxt.Len() ); 1896 rBase.FillText( *pTOXNd, aIdx, static_cast<sal_uInt16>(eField) ); 1897 } 1898 break; 1899 case TOKEN_END: break; 1900 } 1901 1902 if( aToken.sCharStyleName.Len() ) 1903 { 1904 SwCharFmt* pCharFmt; 1905 if( USHRT_MAX != aToken.nPoolId ) 1906 pCharFmt = pDoc->GetCharFmtFromPool( aToken.nPoolId ); 1907 else 1908 pCharFmt = pDoc->FindCharFmtByName( aToken.sCharStyleName); 1909 1910 if (pCharFmt) 1911 { 1912 SwFmtCharFmt aFmt( pCharFmt ); 1913 pTOXNd->InsertItem( aFmt, nStartCharStyle, 1914 rTxt.Len(), nsSetAttrMode::SETATTR_DONTEXPAND ); 1915 } 1916 } 1917 1918 aIt++; // #i21237# 1919 } 1920 1921 pTOXNd->SetAttr( aTStops ); 1922 } 1923 1924 if(aLinkArr.Count()) 1925 for(sal_uInt16 i = 0; i < aLinkArr.Count(); ++i ) 1926 { 1927 LinkStruct* pTmp = aLinkArr.GetObject(i); 1928 pTOXNd->InsertItem( pTmp->aINetFmt, pTmp->nStartTextPos, 1929 pTmp->nEndTextPos); 1930 } 1931 } 1932 1933 /*-------------------------------------------------------------------- 1934 Beschreibung: Seitennummer errechnen und nach dem Formatieren 1935 eintragen 1936 --------------------------------------------------------------------*/ 1937 1938 void SwTOXBaseSection::UpdatePageNum() 1939 { 1940 if( !aSortArr.Count() ) 1941 return ; 1942 1943 // die aktuellen Seitennummern ins Verzeichnis eintragen 1944 SwPageFrm* pAktPage = 0; 1945 sal_uInt16 nPage = 0; 1946 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); 1947 1948 SwTOXInternational aIntl( GetLanguage(), 1949 TOX_INDEX == GetTOXType()->GetType() ? 1950 GetOptions() : 0, 1951 GetSortAlgorithm() ); 1952 1953 for( sal_uInt16 nCnt = 0; nCnt < aSortArr.Count(); ++nCnt ) 1954 { 1955 // Schleife ueber alle SourceNodes 1956 SvUShorts aNums; //Die Seitennummern 1957 SvPtrarr aDescs; //Die PageDescriptoren passend zu den Seitennummern. 1958 SvUShorts* pMainNums = 0; // contains page numbers of main entries 1959 1960 // process run in lines 1961 sal_uInt16 nRange = 0; 1962 if(GetTOXForm().IsCommaSeparated() && 1963 aSortArr[nCnt]->GetType() == TOX_SORT_INDEX) 1964 { 1965 const SwTOXMark& rMark = aSortArr[nCnt]->pTxtMark->GetTOXMark(); 1966 const String sPrimKey = rMark.GetPrimaryKey(); 1967 const String sSecKey = rMark.GetSecondaryKey(); 1968 const SwTOXMark* pNextMark = 0; 1969 while(aSortArr.Count() > (nCnt + nRange)&& 1970 aSortArr[nCnt + nRange]->GetType() == TOX_SORT_INDEX && 1971 0 != (pNextMark = &(aSortArr[nCnt + nRange]->pTxtMark->GetTOXMark())) && 1972 pNextMark->GetPrimaryKey() == sPrimKey && 1973 pNextMark->GetSecondaryKey() == sSecKey) 1974 nRange++; 1975 } 1976 else 1977 nRange = 1; 1978 1979 for(sal_uInt16 nRunInEntry = nCnt; nRunInEntry < nCnt + nRange; nRunInEntry++) 1980 { 1981 SwTOXSortTabBase* pSortBase = aSortArr[nRunInEntry]; 1982 sal_uInt16 nSize = pSortBase->aTOXSources.Count(); 1983 sal_uInt16 i; 1984 for( sal_uInt16 j = 0; j < nSize; ++j ) 1985 { 1986 ::SetProgressState( 0, pDoc->GetDocShell() ); 1987 1988 SwTOXSource& rTOXSource = pSortBase->aTOXSources[j]; 1989 if( rTOXSource.pNd ) 1990 { 1991 SwCntntFrm* pFrm = rTOXSource.pNd->getLayoutFrm( pDoc->GetCurrentLayout() ); 1992 ASSERT( pFrm || pDoc->IsUpdateTOX(), "TOX, no Frame found"); 1993 if( !pFrm ) 1994 continue; 1995 if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->HasFollow() ) 1996 { 1997 // dann suche den richtigen heraus 1998 SwTxtFrm* pNext = (SwTxtFrm*)pFrm; 1999 while( 0 != ( pNext = (SwTxtFrm*)pFrm->GetFollow() ) 2000 && rTOXSource.nPos >= pNext->GetOfst() ) 2001 pFrm = pNext; 2002 } 2003 2004 SwPageFrm* pTmpPage = pFrm->FindPageFrm(); 2005 if( pTmpPage != pAktPage ) 2006 { 2007 nPage = pTmpPage->GetVirtPageNum(); 2008 pAktPage = pTmpPage; 2009 } 2010 2011 // sortiert einfuegen 2012 for( i = 0; i < aNums.Count() && aNums[i] < nPage; ++i ) 2013 ; 2014 2015 if( i >= aNums.Count() || aNums[ i ] != nPage ) 2016 { 2017 aNums.Insert( nPage, i ); 2018 aDescs.Insert( (void*)pAktPage->GetPageDesc(), i ); 2019 } 2020 // is it a main entry? 2021 if(TOX_SORT_INDEX == pSortBase->GetType() && 2022 rTOXSource.bMainEntry) 2023 { 2024 if(!pMainNums) 2025 pMainNums = new SvUShorts; 2026 pMainNums->Insert(nPage, pMainNums->Count()); 2027 } 2028 } 2029 } 2030 // einfuegen der Seitennummer in den Verzeichnis-Text-Node 2031 const SwTOXSortTabBase* pBase = aSortArr[ nCnt ]; 2032 if(pBase->pTOXNd) 2033 { 2034 const SwTxtNode* pTxtNd = pBase->pTOXNd->GetTxtNode(); 2035 ASSERT( pTxtNd, "kein TextNode, falsches Verzeichnis" ); 2036 2037 _UpdatePageNum( (SwTxtNode*)pTxtNd, aNums, aDescs, pMainNums, 2038 aIntl ); 2039 } 2040 DELETEZ(pMainNums); 2041 aNums.Remove(0, aNums.Count()); 2042 } 2043 } 2044 // nach dem Setzen der richtigen Seitennummer, das Mapping-Array 2045 // wieder loeschen !! 2046 aSortArr.DeleteAndDestroy( 0, aSortArr.Count() ); 2047 } 2048 2049 2050 /*-------------------------------------------------------------------- 2051 Beschreibung: Austausch der Seitennummer-Platzhalter 2052 --------------------------------------------------------------------*/ 2053 2054 // search for the page no in the array of main entry page numbers 2055 sal_Bool lcl_HasMainEntry( const SvUShorts* pMainEntryNums, sal_uInt16 nToFind ) 2056 { 2057 for(sal_uInt16 i = 0; pMainEntryNums && i < pMainEntryNums->Count(); ++i) 2058 if(nToFind == (*pMainEntryNums)[i]) 2059 return sal_True; 2060 return sal_False; 2061 } 2062 2063 void SwTOXBaseSection::_UpdatePageNum( SwTxtNode* pNd, 2064 const SvUShorts& rNums, 2065 const SvPtrarr & rDescs, 2066 const SvUShorts* pMainEntryNums, 2067 const SwTOXInternational& rIntl ) 2068 { 2069 //collect starts end ends of main entry character style 2070 SvUShorts* pCharStyleIdx = pMainEntryNums ? new SvUShorts : 0; 2071 2072 String sSrchStr( cNumRepl ); 2073 sSrchStr.AppendAscii( sPageDeli ) += cNumRepl; 2074 xub_StrLen nStartPos = pNd->GetTxt().Search( sSrchStr ); 2075 ( sSrchStr = cNumRepl ) += cEndPageNum; 2076 xub_StrLen nEndPos = pNd->GetTxt().Search( sSrchStr ); 2077 sal_uInt16 i; 2078 2079 if( STRING_NOTFOUND == nEndPos || !rNums.Count() ) 2080 return; 2081 2082 if( STRING_NOTFOUND == nStartPos || nStartPos > nEndPos) 2083 nStartPos = nEndPos; 2084 2085 sal_uInt16 nOld = rNums[0], 2086 nBeg = nOld, 2087 nCount = 0; 2088 String aNumStr( SvxNumberType( ((SwPageDesc*)rDescs[0])->GetNumType() ). 2089 GetNumStr( nBeg ) ); 2090 if( pCharStyleIdx && lcl_HasMainEntry( pMainEntryNums, nBeg )) 2091 { 2092 sal_uInt16 nTemp = 0; 2093 pCharStyleIdx->Insert( nTemp, pCharStyleIdx->Count()); 2094 } 2095 2096 // Platzhalter loeschen 2097 SwIndex aPos(pNd, nStartPos); 2098 SwCharFmt* pPageNoCharFmt = 0; 2099 SwpHints* pHints = pNd->GetpSwpHints(); 2100 if(pHints) 2101 for(sal_uInt16 nHintIdx = 0; nHintIdx < pHints->GetStartCount(); nHintIdx++) 2102 { 2103 SwTxtAttr* pAttr = pHints->GetStart(nHintIdx); 2104 xub_StrLen nTmpEnd = pAttr->GetEnd() ? *pAttr->GetEnd() : 0; 2105 if( nStartPos >= *pAttr->GetStart() && 2106 (nStartPos + 2) <= nTmpEnd && 2107 pAttr->Which() == RES_TXTATR_CHARFMT) 2108 { 2109 pPageNoCharFmt = pAttr->GetCharFmt().GetCharFmt(); 2110 break; 2111 } 2112 } 2113 pNd->EraseText(aPos, nEndPos - nStartPos + 2); 2114 2115 for( i = 1; i < rNums.Count(); ++i) 2116 { 2117 SvxNumberType aType( ((SwPageDesc*)rDescs[i])->GetNumType() ); 2118 if( TOX_INDEX == SwTOXBase::GetType() ) 2119 { // Zusammenfassen f. ff. 2120 // Alle folgenden aufaddieren 2121 // break up if main entry starts or ends and 2122 // insert a char style index 2123 sal_Bool bMainEntryChanges = lcl_HasMainEntry(pMainEntryNums, nOld) 2124 != lcl_HasMainEntry(pMainEntryNums, rNums[i]); 2125 2126 if(nOld == rNums[i]-1 && !bMainEntryChanges && 2127 0 != (GetOptions() & (nsSwTOIOptions::TOI_FF|nsSwTOIOptions::TOI_DASH))) 2128 nCount++; 2129 else 2130 { 2131 // ff. f. alten Wert flushen 2132 if(GetOptions() & nsSwTOIOptions::TOI_FF) 2133 { 2134 if ( nCount >= 1 ) 2135 aNumStr += rIntl.GetFollowingText( nCount > 1 ); 2136 } 2137 else 2138 { 2139 if(nCount >= 2 ) 2140 aNumStr += '-'; 2141 else if(nCount == 1 ) 2142 aNumStr.AppendAscii( sPageDeli ); 2143 //#58127# Wenn nCount == 0, dann steht die einzige Seitenzahl schon im aNumStr! 2144 if(nCount) 2145 aNumStr += aType.GetNumStr( nBeg + nCount ); 2146 } 2147 2148 // neuen String anlegen 2149 nBeg = rNums[i]; 2150 aNumStr.AppendAscii( sPageDeli ); 2151 //the change of the character style must apply after sPageDeli is appended 2152 if(pCharStyleIdx && bMainEntryChanges) 2153 pCharStyleIdx->Insert(aNumStr.Len(), 2154 pCharStyleIdx->Count()); 2155 aNumStr += aType.GetNumStr( nBeg ); 2156 nCount = 0; 2157 } 2158 nOld = rNums[i]; 2159 } 2160 else 2161 { // Alle Nummern eintragen 2162 aNumStr += aType.GetNumStr( sal_uInt16(rNums[i]) ); 2163 if(i != (rNums.Count()-1)) 2164 aNumStr.AppendAscii( sPageDeli ); 2165 } 2166 } 2167 // Bei Ende und ff. alten Wert flushen 2168 if( TOX_INDEX == SwTOXBase::GetType() ) 2169 { 2170 if(GetOptions() & nsSwTOIOptions::TOI_FF) 2171 { 2172 if( nCount >= 1 ) 2173 aNumStr += rIntl.GetFollowingText( nCount > 1 ); 2174 } 2175 else 2176 { 2177 if(nCount >= 2) 2178 aNumStr +='-'; 2179 else if(nCount == 1) 2180 aNumStr.AppendAscii( sPageDeli ); 2181 //#58127# Wenn nCount == 0, dann steht die einzige Seitenzahl schon im aNumStr! 2182 if(nCount) 2183 aNumStr += SvxNumberType( ((SwPageDesc*)rDescs[i-1])-> 2184 GetNumType() ).GetNumStr( nBeg+nCount ); 2185 } 2186 } 2187 pNd->InsertText( aNumStr, aPos, 2188 static_cast<IDocumentContentOperations::InsertFlags>( 2189 IDocumentContentOperations::INS_EMPTYEXPAND | 2190 IDocumentContentOperations::INS_FORCEHINTEXPAND) ); 2191 if(pPageNoCharFmt) 2192 { 2193 SwFmtCharFmt aCharFmt( pPageNoCharFmt ); 2194 pNd->InsertItem(aCharFmt, nStartPos, nStartPos + aNumStr.Len(), nsSetAttrMode::SETATTR_DONTEXPAND); 2195 } 2196 2197 //now the main entries should get there character style 2198 if(pCharStyleIdx && pCharStyleIdx->Count() && GetMainEntryCharStyle().Len()) 2199 { 2200 // eventually the last index must me appended 2201 if(pCharStyleIdx->Count()&0x01) 2202 pCharStyleIdx->Insert(aNumStr.Len(), pCharStyleIdx->Count()); 2203 2204 //search by name 2205 SwDoc* pDoc = pNd->GetDoc(); 2206 sal_uInt16 nPoolId = SwStyleNameMapper::GetPoolIdFromUIName( GetMainEntryCharStyle(), nsSwGetPoolIdFromName::GET_POOLID_CHRFMT ); 2207 SwCharFmt* pCharFmt = 0; 2208 if(USHRT_MAX != nPoolId) 2209 pCharFmt = pDoc->GetCharFmtFromPool(nPoolId); 2210 else 2211 pCharFmt = pDoc->FindCharFmtByName( GetMainEntryCharStyle() ); 2212 if(!pCharFmt) 2213 pCharFmt = pDoc->MakeCharFmt(GetMainEntryCharStyle(), 0); 2214 2215 //find the page numbers in aNumStr and set the character style 2216 xub_StrLen nOffset = pNd->GetTxt().Len() - aNumStr.Len(); 2217 SwFmtCharFmt aCharFmt(pCharFmt); 2218 for(sal_uInt16 j = 0; j < pCharStyleIdx->Count(); j += 2) 2219 { 2220 xub_StrLen nStartIdx = (*pCharStyleIdx)[j] + nOffset; 2221 xub_StrLen nEndIdx = (*pCharStyleIdx)[j + 1] + nOffset; 2222 pNd->InsertItem(aCharFmt, nStartIdx, nEndIdx, nsSetAttrMode::SETATTR_DONTEXPAND); 2223 } 2224 2225 } 2226 delete pCharStyleIdx; 2227 } 2228 2229 2230 /*-------------------------------------------------------------------- 2231 Beschreibung: Sortiert einfuegen in das SortArr 2232 --------------------------------------------------------------------*/ 2233 2234 void SwTOXBaseSection::InsertSorted(SwTOXSortTabBase* pNew) 2235 { 2236 Range aRange(0, aSortArr.Count()); 2237 if( TOX_INDEX == SwTOXBase::GetType() && pNew->pTxtMark ) 2238 { 2239 const SwTOXMark& rMark = pNew->pTxtMark->GetTOXMark(); 2240 // Schluessel auswerten 2241 // Den Bereich ermitteln, in dem einzufuegen ist 2242 if( 0 == (GetOptions() & nsSwTOIOptions::TOI_KEY_AS_ENTRY) && 2243 rMark.GetPrimaryKey().Len() ) 2244 { 2245 aRange = GetKeyRange( rMark.GetPrimaryKey(), 2246 rMark.GetPrimaryKeyReading(), 2247 *pNew, FORM_PRIMARY_KEY, aRange ); 2248 2249 if( rMark.GetSecondaryKey().Len() ) 2250 aRange = GetKeyRange( rMark.GetSecondaryKey(), 2251 rMark.GetSecondaryKeyReading(), 2252 *pNew, FORM_SECONDARY_KEY, aRange ); 2253 } 2254 } 2255 //search for identical entries and remove the trailing one 2256 if(TOX_AUTHORITIES == SwTOXBase::GetType()) 2257 { 2258 for(short i = (short)aRange.Min(); i < (short)aRange.Max(); ++i) 2259 { 2260 SwTOXSortTabBase* pOld = aSortArr[i]; 2261 if(*pOld == *pNew) 2262 { 2263 if(*pOld < *pNew) 2264 { 2265 delete pNew; 2266 return; 2267 } 2268 else 2269 { 2270 // remove the old content 2271 aSortArr.DeleteAndDestroy( i, 1 ); 2272 aRange.Max()--; 2273 break; 2274 } 2275 } 2276 } 2277 } 2278 2279 // find position and insert 2280 // 2281 short i; 2282 2283 for( i = (short)aRange.Min(); i < (short)aRange.Max(); ++i) 2284 { // nur auf gleicher Ebene pruefen 2285 // 2286 SwTOXSortTabBase* pOld = aSortArr[i]; 2287 if(*pOld == *pNew) 2288 { 2289 if(TOX_AUTHORITIES != SwTOXBase::GetType()) 2290 { 2291 // Eigener Eintrag fuer Doppelte oder Keywords 2292 // 2293 if( pOld->GetType() == TOX_SORT_CUSTOM && 2294 pNew->GetOptions() & nsSwTOIOptions::TOI_KEY_AS_ENTRY) 2295 continue; 2296 2297 if(!(pNew->GetOptions() & nsSwTOIOptions::TOI_SAME_ENTRY)) 2298 { // Eigener Eintrag 2299 aSortArr.Insert(pNew, i ); 2300 return; 2301 } 2302 // Eintrag schon vorhanden in Referenzliste aufnehmen 2303 pOld->aTOXSources.Insert( pNew->aTOXSources[0], 2304 pOld->aTOXSources.Count() ); 2305 2306 delete pNew; 2307 return; 2308 } 2309 #ifdef DBG_UTIL 2310 else 2311 DBG_ERROR("Bibliography entries cannot be found here"); 2312 #endif 2313 } 2314 if(*pNew < *pOld) 2315 break; 2316 } 2317 // SubLevel Skippen 2318 while( TOX_INDEX == SwTOXBase::GetType() && i < aRange.Max() && 2319 aSortArr[i]->GetLevel() > pNew->GetLevel() ) 2320 i++; 2321 2322 // An Position i wird eingefuegt 2323 aSortArr.Insert(pNew, i ); 2324 } 2325 2326 /*-------------------------------------------------------------------- 2327 Beschreibung: Schluessel-Bereich suchen und evtl einfuegen 2328 --------------------------------------------------------------------*/ 2329 2330 Range SwTOXBaseSection::GetKeyRange(const String& rStr, const String& rStrReading, 2331 const SwTOXSortTabBase& rNew, 2332 sal_uInt16 nLevel, const Range& rRange ) 2333 { 2334 const SwTOXInternational& rIntl = *rNew.pTOXIntl; 2335 String sToCompare(rStr); 2336 String sToCompareReading(rStrReading); 2337 2338 if( 0 != (nsSwTOIOptions::TOI_INITIAL_CAPS & GetOptions()) ) 2339 { 2340 String sUpper( rIntl.ToUpper( sToCompare, 0 )); 2341 sToCompare.Erase( 0, 1 ).Insert( sUpper, 0 ); 2342 } 2343 2344 ASSERT(rRange.Min() >= 0 && rRange.Max() >= 0, "Min Max < 0"); 2345 2346 const sal_uInt16 nMin = (sal_uInt16)rRange.Min(); 2347 const sal_uInt16 nMax = (sal_uInt16)rRange.Max(); 2348 2349 sal_uInt16 i; 2350 2351 for( i = nMin; i < nMax; ++i) 2352 { 2353 SwTOXSortTabBase* pBase = aSortArr[i]; 2354 2355 String sMyString, sMyStringReading; 2356 pBase->GetTxt( sMyString, sMyStringReading ); 2357 2358 if( rIntl.IsEqual( sMyString, sMyStringReading, pBase->GetLocale(), 2359 sToCompare, sToCompareReading, rNew.GetLocale() ) && 2360 pBase->GetLevel() == nLevel ) 2361 break; 2362 } 2363 if(i == nMax) 2364 { // Falls nicht vorhanden erzeugen und einfuegen 2365 // 2366 SwTOXCustom* pKey = new SwTOXCustom( sToCompare, sToCompareReading, nLevel, rIntl, 2367 rNew.GetLocale() ); 2368 for(i = nMin; i < nMax; ++i) 2369 { 2370 if(nLevel == aSortArr[i]->GetLevel() && *pKey < *(aSortArr[i])) 2371 break; 2372 } 2373 aSortArr.Insert(pKey, i ); 2374 } 2375 sal_uInt16 nStart = i+1; 2376 sal_uInt16 nEnd = aSortArr.Count(); 2377 2378 // Ende des Bereiches suchen 2379 for(i = nStart; i < aSortArr.Count(); ++i) 2380 { 2381 if(aSortArr[i]->GetLevel() <= nLevel) 2382 { nEnd = i; 2383 break; 2384 } 2385 } 2386 return Range(nStart, nEnd); 2387 } 2388 2389 2390 sal_Bool SwTOXBase::IsTOXBaseInReadonly() const 2391 { 2392 const SwTOXBaseSection *pSect = PTR_CAST(SwTOXBaseSection, this); 2393 sal_Bool bRet = sal_False; 2394 const SwSectionNode* pSectNode; 2395 if(pSect && pSect->GetFmt() && 2396 0 != (pSectNode = pSect->GetFmt()->GetSectionNode())) 2397 { 2398 const SwDocShell* pDocSh; 2399 bRet = (0 != (pDocSh = pSectNode->GetDoc()->GetDocShell()) && 2400 pDocSh->IsReadOnly()) || 2401 (0 != (pSectNode = pSectNode->StartOfSectionNode()->FindSectionNode())&& 2402 pSectNode->GetSection().IsProtectFlag()); 2403 2404 } 2405 return bRet; 2406 } 2407 2408 const SfxItemSet* SwTOXBase::GetAttrSet() const 2409 { 2410 const SwTOXBaseSection *pSect = PTR_CAST(SwTOXBaseSection, this); 2411 if(pSect && pSect->GetFmt()) 2412 return &pSect->GetFmt()->GetAttrSet(); 2413 return 0; 2414 } 2415 2416 void SwTOXBase::SetAttrSet( const SfxItemSet& rSet ) 2417 { 2418 SwTOXBaseSection *pSect = PTR_CAST(SwTOXBaseSection, this); 2419 if( pSect && pSect->GetFmt() ) 2420 pSect->GetFmt()->SetFmtAttr( rSet ); 2421 } 2422 2423 sal_Bool SwTOXBase::GetInfo( SfxPoolItem& rInfo ) const 2424 { 2425 switch( rInfo.Which() ) 2426 { 2427 case RES_CONTENT_VISIBLE: 2428 { 2429 SwTOXBaseSection *pSect = PTR_CAST(SwTOXBaseSection, this); 2430 if( pSect && pSect->GetFmt() ) 2431 pSect->GetFmt()->GetInfo( rInfo ); 2432 } 2433 return sal_False; 2434 } 2435 return sal_True; 2436 } 2437 2438