1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sw.hxx" 26 27 28 #include <limits.h> 29 #include <hintids.hxx> 30 31 #define _SVSTDARR_STRINGSSORT 32 #include <svl/svstdarr.hxx> 33 #include <editeng/langitem.hxx> 34 #include <editeng/brkitem.hxx> 35 #include <editeng/tstpitem.hxx> 36 #include <editeng/lrspitem.hxx> 37 #include <sot/clsids.hxx> 38 #include <docsh.hxx> 39 #include <ndole.hxx> 40 #include <txttxmrk.hxx> 41 #include <fmtinfmt.hxx> 42 #include <fmtpdsc.hxx> 43 #include <frmfmt.hxx> 44 #include <fmtfsize.hxx> 45 #include <frmatr.hxx> 46 #include <pagedesc.hxx> 47 #include <doc.hxx> 48 #include <IDocumentUndoRedo.hxx> 49 #include <pagefrm.hxx> 50 #include <ndtxt.hxx> 51 #include <swtable.hxx> 52 #include <doctxm.hxx> 53 #include <txmsrt.hxx> 54 #include <rolbck.hxx> 55 #include <poolfmt.hxx> 56 #include <txtfrm.hxx> 57 #include <rootfrm.hxx> 58 #include <UndoAttribute.hxx> 59 #include <swundo.hxx> 60 #include <mdiexp.hxx> 61 #include <docary.hxx> 62 #include <charfmt.hxx> 63 #include <fchrfmt.hxx> 64 #include <fldbas.hxx> 65 #include <fmtfld.hxx> 66 #include <txtfld.hxx> 67 #include <expfld.hxx> 68 #include <chpfld.hxx> 69 #include <mvsave.hxx> 70 #include <node2lay.hxx> 71 #include <SwStyleNameMapper.hxx> 72 #include <breakit.hxx> 73 #include <editsh.hxx> 74 #include <scriptinfo.hxx> 75 #include <switerator.hxx> 76 77 using namespace ::com::sun::star; 78 79 const sal_Unicode cNumRepl = '@'; 80 const sal_Unicode cEndPageNum = '~'; 81 const sal_Char __FAR_DATA sPageDeli[] = ", "; 82 83 SV_IMPL_PTRARR(SwTOXSortTabBases, SwTOXSortTabBasePtr) 84 85 TYPEINIT2( SwTOXBaseSection, SwTOXBase, SwSection ); // fuers RTTI 86 87 struct LinkStruct 88 { 89 SwFmtINetFmt aINetFmt; 90 xub_StrLen nStartTextPos, nEndTextPos; 91 92 LinkStruct( const String& rURL, xub_StrLen nStart, xub_StrLen nEnd ) 93 : aINetFmt( rURL, aEmptyStr), 94 nStartTextPos( nStart), 95 nEndTextPos(nEnd) {} 96 }; 97 98 typedef LinkStruct* LinkStructPtr; 99 SV_DECL_PTRARR(LinkStructArr, LinkStructPtr, 0, 5 ) 100 SV_IMPL_PTRARR(LinkStructArr, LinkStructPtr) 101 102 sal_uInt16 SwDoc::GetTOIKeys( SwTOIKeyType eTyp, SvStringsSort& rArr ) const 103 { 104 if( rArr.Count() ) 105 rArr.Remove( sal_uInt16(0), rArr.Count() ); 106 107 // dann mal ueber den Pool und alle Primary oder Secondary heraussuchen 108 const SwTxtTOXMark* pMark; 109 const SfxPoolItem* pItem; 110 const SwTOXType* pTOXType; 111 sal_uInt32 i, nMaxItems = GetAttrPool().GetItemCount2( RES_TXTATR_TOXMARK ); 112 for( i = 0; i < nMaxItems; ++i ) 113 if( 0 != (pItem = GetAttrPool().GetItem2( RES_TXTATR_TOXMARK, i ) ) && 114 0!= ( pTOXType = ((SwTOXMark*)pItem)->GetTOXType()) && 115 TOX_INDEX == pTOXType->GetType() && 116 0 != ( pMark = ((SwTOXMark*)pItem)->GetTxtTOXMark() ) && 117 pMark->GetpTxtNd() && 118 pMark->GetpTxtNd()->GetNodes().IsDocNodes() ) 119 { 120 const String* pStr; 121 if( TOI_PRIMARY == eTyp ) 122 pStr = &((SwTOXMark*)pItem)->GetPrimaryKey(); 123 else 124 pStr = &((SwTOXMark*)pItem)->GetSecondaryKey(); 125 126 if( pStr->Len() ) 127 rArr.Insert( (StringPtr)pStr ); 128 } 129 130 return rArr.Count(); 131 } 132 133 /*-------------------------------------------------------------------- 134 Beschreibung: aktuelle Verzeichnismarkierungen ermitteln 135 --------------------------------------------------------------------*/ 136 137 138 sal_uInt16 SwDoc::GetCurTOXMark( const SwPosition& rPos, 139 SwTOXMarks& rArr ) const 140 { 141 // search on Position rPos for all SwTOXMarks 142 SwTxtNode *const pTxtNd = rPos.nNode.GetNode().GetTxtNode(); 143 if( !pTxtNd || !pTxtNd->GetpSwpHints() ) 144 return 0; 145 146 const SwpHints & rHts = *pTxtNd->GetpSwpHints(); 147 const SwTxtAttr* pHt; 148 xub_StrLen nSttIdx; 149 const xub_StrLen *pEndIdx; 150 151 xub_StrLen nAktPos = rPos.nContent.GetIndex(); 152 153 for( sal_uInt16 n = 0; n < rHts.Count(); ++n ) 154 { 155 if( RES_TXTATR_TOXMARK != (pHt = rHts[n])->Which() ) 156 continue; 157 if( ( nSttIdx = *pHt->GetStart() ) < nAktPos ) 158 { 159 // pruefe Ende mit ab 160 if( 0 == ( pEndIdx = pHt->End() ) || 161 *pEndIdx <= nAktPos ) 162 continue; // weiter suchen 163 } 164 else if( nSttIdx > nAktPos ) 165 // ist Start vom Hint groesser als rPos, dann abbrechen. Denn 166 // die Attribute sind nach Start sortiert ! 167 break; 168 169 const SwTOXMark* pTMark = &pHt->GetTOXMark(); 170 rArr.Insert( pTMark, rArr.Count() ); 171 } 172 return rArr.Count(); 173 } 174 175 /*-------------------------------------------------------------------- 176 Beschreibung: Marke loeschen 177 --------------------------------------------------------------------*/ 178 179 void SwDoc::DeleteTOXMark( const SwTOXMark* pTOXMark ) 180 { 181 // hole den TextNode und 182 const SwTxtTOXMark* pTxtTOXMark = pTOXMark->GetTxtTOXMark(); 183 ASSERT( pTxtTOXMark, "Kein TxtTOXMark, kann nicht geloescht werden" ); 184 185 SwTxtNode& rTxtNd = const_cast<SwTxtNode&>(pTxtTOXMark->GetTxtNode()); 186 ASSERT( rTxtNd.GetpSwpHints(), "kann nicht geloescht werden" ); 187 188 if (GetIDocumentUndoRedo().DoesUndo()) 189 { 190 // save attributes for Undo 191 SwUndoResetAttr* pUndo = new SwUndoResetAttr( 192 SwPosition( rTxtNd, SwIndex( &rTxtNd, *pTxtTOXMark->GetStart() ) ), 193 RES_TXTATR_TOXMARK ); 194 GetIDocumentUndoRedo().AppendUndo( pUndo ); 195 196 SwRegHistory aRHst( rTxtNd, &pUndo->GetHistory() ); 197 rTxtNd.GetpSwpHints()->Register( &aRHst ); 198 } 199 200 rTxtNd.DeleteAttribute( const_cast<SwTxtTOXMark*>(pTxtTOXMark) ); 201 202 if (GetIDocumentUndoRedo().DoesUndo()) 203 { 204 if( rTxtNd.GetpSwpHints() ) 205 rTxtNd.GetpSwpHints()->DeRegister(); 206 } 207 SetModified(); 208 } 209 210 /*-------------------------------------------------------------------- 211 Beschreibung: Traveln zwischen TOXMarks 212 --------------------------------------------------------------------*/ 213 214 class CompareNodeCntnt 215 { 216 sal_uLong nNode; 217 xub_StrLen nCntnt; 218 public: 219 CompareNodeCntnt( sal_uLong nNd, xub_StrLen nCnt ) 220 : nNode( nNd ), nCntnt( nCnt ) {} 221 222 int operator==( const CompareNodeCntnt& rCmp ) 223 { return nNode == rCmp.nNode && nCntnt == rCmp.nCntnt; } 224 int operator!=( const CompareNodeCntnt& rCmp ) 225 { return nNode != rCmp.nNode || nCntnt != rCmp.nCntnt; } 226 int operator< ( const CompareNodeCntnt& rCmp ) 227 { return nNode < rCmp.nNode || 228 ( nNode == rCmp.nNode && nCntnt < rCmp.nCntnt); } 229 int operator<=( const CompareNodeCntnt& rCmp ) 230 { return nNode < rCmp.nNode || 231 ( nNode == rCmp.nNode && nCntnt <= rCmp.nCntnt); } 232 int operator> ( const CompareNodeCntnt& rCmp ) 233 { return nNode > rCmp.nNode || 234 ( nNode == rCmp.nNode && nCntnt > rCmp.nCntnt); } 235 int operator>=( const CompareNodeCntnt& rCmp ) 236 { return nNode > rCmp.nNode || 237 ( nNode == rCmp.nNode && nCntnt >= rCmp.nCntnt); } 238 }; 239 240 const SwTOXMark& SwDoc::GotoTOXMark( const SwTOXMark& rCurTOXMark, 241 SwTOXSearch eDir, sal_Bool bInReadOnly ) 242 { 243 const SwTxtTOXMark* pMark = rCurTOXMark.GetTxtTOXMark(); 244 ASSERT(pMark, "pMark==0 Ungueltige TxtTOXMark"); 245 246 const SwTxtNode *pTOXSrc = pMark->GetpTxtNd(); 247 248 CompareNodeCntnt aAbsIdx( pTOXSrc->GetIndex(), *pMark->GetStart() ); 249 CompareNodeCntnt aPrevPos( 0, 0 ); 250 CompareNodeCntnt aNextPos( ULONG_MAX, STRING_NOTFOUND ); 251 CompareNodeCntnt aMax( 0, 0 ); 252 CompareNodeCntnt aMin( ULONG_MAX, STRING_NOTFOUND ); 253 254 const SwTOXMark* pNew = 0; 255 const SwTOXMark* pMax = &rCurTOXMark; 256 const SwTOXMark* pMin = &rCurTOXMark; 257 258 const SwTOXType* pType = rCurTOXMark.GetTOXType(); 259 SwTOXMarks aMarks; 260 SwTOXMark::InsertTOXMarks( aMarks, *pType ); 261 262 const SwTOXMark* pTOXMark; 263 const SwCntntFrm* pCFrm; 264 Point aPt; 265 for( sal_uInt16 nMark=0; nMark<aMarks.Count(); nMark++ ) 266 { 267 pTOXMark = aMarks[nMark]; 268 if( pTOXMark != &rCurTOXMark && 269 0 != ( pMark = pTOXMark->GetTxtTOXMark()) && 270 0 != ( pTOXSrc = pMark->GetpTxtNd() ) && 271 0 != ( pCFrm = pTOXSrc->getLayoutFrm( GetCurrentLayout(), &aPt, 0, sal_False )) && 272 ( bInReadOnly || !pCFrm->IsProtected() )) 273 { 274 CompareNodeCntnt aAbsNew( pTOXSrc->GetIndex(), *pMark->GetStart() ); 275 switch( eDir ) 276 { 277 //Die untenstehenden etwas komplizierter ausgefallen Ausdruecke 278 //dienen dazu auch ueber Eintraege auf der selben (!) Position 279 //traveln zu koennen. Wenn einer Zeit hat mag er sie mal 280 //optimieren. 281 282 case TOX_SAME_PRV: 283 if( pTOXMark->GetText() != rCurTOXMark.GetText() ) 284 break; 285 /* no break here */ 286 case TOX_PRV: 287 if ( (aAbsNew < aAbsIdx && aAbsNew > aPrevPos && 288 aPrevPos != aAbsIdx && aAbsNew != aAbsIdx ) || 289 (aAbsIdx == aAbsNew && 290 (sal_uLong(&rCurTOXMark) > sal_uLong(pTOXMark) && 291 (!pNew || 292 (pNew && (aPrevPos < aAbsIdx || 293 sal_uLong(pNew) < sal_uLong(pTOXMark)))))) || 294 (aPrevPos == aAbsNew && aAbsIdx != aAbsNew && 295 sal_uLong(pTOXMark) > sal_uLong(pNew)) ) 296 { 297 pNew = pTOXMark; 298 aPrevPos = aAbsNew; 299 if ( aAbsNew >= aMax ) 300 { 301 aMax = aAbsNew; 302 pMax = pTOXMark; 303 } 304 } 305 break; 306 307 case TOX_SAME_NXT: 308 if( pTOXMark->GetText() != rCurTOXMark.GetText() ) 309 break; 310 /* no break here */ 311 case TOX_NXT: 312 if ( (aAbsNew > aAbsIdx && aAbsNew < aNextPos && 313 aNextPos != aAbsIdx && aAbsNew != aAbsIdx ) || 314 (aAbsIdx == aAbsNew && 315 (sal_uLong(&rCurTOXMark) < sal_uLong(pTOXMark) && 316 (!pNew || 317 (pNew && (aNextPos > aAbsIdx || 318 sal_uLong(pNew) > sal_uLong(pTOXMark)))))) || 319 (aNextPos == aAbsNew && aAbsIdx != aAbsNew && 320 sal_uLong(pTOXMark) < sal_uLong(pNew)) ) 321 { 322 pNew = pTOXMark; 323 aNextPos = aAbsNew; 324 if ( aAbsNew <= aMin ) 325 { 326 aMin = aAbsNew; 327 pMin = pTOXMark; 328 } 329 } 330 break; 331 } 332 } 333 } 334 335 336 // kein Nachfolger wurde gefunden 337 // Min oder Max benutzen 338 if(!pNew) 339 { 340 switch(eDir) 341 { 342 case TOX_PRV: 343 case TOX_SAME_PRV: 344 pNew = pMax; 345 break; 346 case TOX_NXT: 347 case TOX_SAME_NXT: 348 pNew = pMin; 349 break; 350 default: 351 pNew = &rCurTOXMark; 352 } 353 } 354 return *pNew; 355 } 356 357 358 const SwTOXBaseSection* SwDoc::InsertTableOf( const SwPosition& rPos, 359 const SwTOXBase& rTOX, 360 const SfxItemSet* pSet, 361 sal_Bool bExpand ) 362 { 363 GetIDocumentUndoRedo().StartUndo( UNDO_INSTOX, NULL ); 364 365 String sSectNm( rTOX.GetTOXName() ); 366 sSectNm = GetUniqueTOXBaseName( *rTOX.GetTOXType(), &sSectNm ); 367 SwPaM aPam( rPos ); 368 SwSectionData aSectionData( TOX_CONTENT_SECTION, sSectNm ); 369 SwTOXBaseSection *const pNewSection = dynamic_cast<SwTOXBaseSection *>( 370 InsertSwSection( aPam, aSectionData, & rTOX, pSet, false )); 371 if (pNewSection) 372 { 373 SwSectionNode *const pSectNd = pNewSection->GetFmt()->GetSectionNode(); 374 pNewSection->SetTOXName(sSectNm); // rTOX may have had no name... 375 376 if( bExpand ) 377 { 378 // OD 19.03.2003 #106329# - add value for 2nd parameter = true to 379 // indicate, that a creation of a new table of content has to be performed. 380 // Value of 1st parameter = default value. 381 pNewSection->Update( 0, true ); 382 } 383 else if( 1 == rTOX.GetTitle().Len() && IsInReading() ) 384 // insert title of TOX 385 { 386 // then insert the headline section 387 SwNodeIndex aIdx( *pSectNd, +1 ); 388 389 SwTxtNode* pHeadNd = GetNodes().MakeTxtNode( aIdx, 390 GetTxtCollFromPool( RES_POOLCOLL_STANDARD ) ); 391 392 String sNm( pNewSection->GetTOXName() ); 393 // ??Resource 394 sNm.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "_Head" )); 395 396 SwSectionData headerData( TOX_HEADER_SECTION, sNm ); 397 398 SwNodeIndex aStt( *pHeadNd ); aIdx--; 399 SwSectionFmt* pSectFmt = MakeSectionFmt( 0 ); 400 GetNodes().InsertTextSection( 401 aStt, *pSectFmt, headerData, 0, &aIdx, true, false); 402 } 403 } 404 405 GetIDocumentUndoRedo().EndUndo( UNDO_INSTOX, NULL ); 406 407 return pNewSection; 408 } 409 410 411 412 const SwTOXBaseSection* SwDoc::InsertTableOf( sal_uLong nSttNd, sal_uLong nEndNd, 413 const SwTOXBase& rTOX, 414 const SfxItemSet* pSet ) 415 { 416 // check for recursiv TOX 417 SwNode* pNd = GetNodes()[ nSttNd ]; 418 SwSectionNode* pSectNd = pNd->FindSectionNode(); 419 while( pSectNd ) 420 { 421 SectionType eT = pSectNd->GetSection().GetType(); 422 if( TOX_HEADER_SECTION == eT || TOX_CONTENT_SECTION == eT ) 423 return 0; 424 pSectNd = pSectNd->StartOfSectionNode()->FindSectionNode(); 425 } 426 427 String sSectNm( rTOX.GetTOXName() ); 428 sSectNm = GetUniqueTOXBaseName(*rTOX.GetTOXType(), &sSectNm); 429 430 SwSectionData aSectionData( TOX_CONTENT_SECTION, sSectNm ); 431 432 SwNodeIndex aStt( GetNodes(), nSttNd ), aEnd( GetNodes(), nEndNd ); 433 SwSectionFmt* pFmt = MakeSectionFmt( 0 ); 434 if(pSet) 435 pFmt->SetFmtAttr(*pSet); 436 437 // --aEnd; // im InsertSection ist Ende inclusive 438 439 SwSectionNode *const pNewSectionNode = 440 GetNodes().InsertTextSection(aStt, *pFmt, aSectionData, &rTOX, &aEnd); 441 if (!pNewSectionNode) 442 { 443 DelSectionFmt( pFmt ); 444 return 0; 445 } 446 447 SwTOXBaseSection *const pNewSection( 448 dynamic_cast<SwTOXBaseSection*>(& pNewSectionNode->GetSection())); 449 pNewSection->SetTOXName(sSectNm); // rTOX may have had no name... 450 return pNewSection; 451 } 452 453 /*-------------------------------------------------------------------- 454 Beschreibung: Aktuelles Verzeichnis ermitteln 455 --------------------------------------------------------------------*/ 456 457 const SwTOXBase* SwDoc::GetCurTOX( const SwPosition& rPos ) const 458 { 459 const SwNode& rNd = rPos.nNode.GetNode(); 460 const SwSectionNode* pSectNd = rNd.FindSectionNode(); 461 while( pSectNd ) 462 { 463 SectionType eT = pSectNd->GetSection().GetType(); 464 if( TOX_CONTENT_SECTION == eT ) 465 { 466 ASSERT( pSectNd->GetSection().ISA( SwTOXBaseSection ), 467 "keine TOXBaseSection!" ); 468 SwTOXBaseSection& rTOXSect = (SwTOXBaseSection&) 469 pSectNd->GetSection(); 470 return &rTOXSect; 471 } 472 pSectNd = pSectNd->StartOfSectionNode()->FindSectionNode(); 473 } 474 return 0; 475 } 476 477 const SwAttrSet& SwDoc::GetTOXBaseAttrSet(const SwTOXBase& rTOXBase) const 478 { 479 ASSERT( rTOXBase.ISA( SwTOXBaseSection ), "no TOXBaseSection!" ); 480 const SwTOXBaseSection& rTOXSect = (const SwTOXBaseSection&)rTOXBase; 481 SwSectionFmt* pFmt = rTOXSect.GetFmt(); 482 ASSERT( pFmt, "invalid TOXBaseSection!" ); 483 return pFmt->GetAttrSet(); 484 } 485 486 const SwTOXBase* SwDoc::GetDefaultTOXBase( TOXTypes eTyp, sal_Bool bCreate ) 487 { 488 SwTOXBase** prBase = 0; 489 switch(eTyp) 490 { 491 case TOX_CONTENT: prBase = &pDefTOXBases->pContBase; break; 492 case TOX_INDEX: prBase = &pDefTOXBases->pIdxBase; break; 493 case TOX_USER: prBase = &pDefTOXBases->pUserBase; break; 494 case TOX_TABLES: prBase = &pDefTOXBases->pTblBase; break; 495 case TOX_OBJECTS: prBase = &pDefTOXBases->pObjBase; break; 496 case TOX_ILLUSTRATIONS: prBase = &pDefTOXBases->pIllBase; break; 497 case TOX_AUTHORITIES: prBase = &pDefTOXBases->pAuthBase; break; 498 } 499 if(!(*prBase) && bCreate) 500 { 501 SwForm aForm(eTyp); 502 const SwTOXType* pType = GetTOXType(eTyp, 0); 503 (*prBase) = new SwTOXBase(pType, aForm, 0, pType->GetTypeName()); 504 } 505 return (*prBase); 506 } 507 508 void SwDoc::SetDefaultTOXBase(const SwTOXBase& rBase) 509 { 510 SwTOXBase** prBase = 0; 511 switch(rBase.GetType()) 512 { 513 case TOX_CONTENT: prBase = &pDefTOXBases->pContBase; break; 514 case TOX_INDEX: prBase = &pDefTOXBases->pIdxBase; break; 515 case TOX_USER: prBase = &pDefTOXBases->pUserBase; break; 516 case TOX_TABLES: prBase = &pDefTOXBases->pTblBase; break; 517 case TOX_OBJECTS: prBase = &pDefTOXBases->pObjBase; break; 518 case TOX_ILLUSTRATIONS: prBase = &pDefTOXBases->pIllBase; break; 519 case TOX_AUTHORITIES: prBase = &pDefTOXBases->pAuthBase; break; 520 } 521 if(*prBase) 522 delete (*prBase); 523 (*prBase) = new SwTOXBase(rBase); 524 } 525 526 /*-------------------------------------------------------------------- 527 Beschreibung: Verzeichnis loeschen 528 --------------------------------------------------------------------*/ 529 530 531 sal_Bool SwDoc::DeleteTOX( const SwTOXBase& rTOXBase, sal_Bool bDelNodes ) 532 { 533 // its only delete the TOX, not the nodes 534 sal_Bool bRet = sal_False; 535 ASSERT( rTOXBase.ISA( SwTOXBaseSection ), "keine TOXBaseSection!" ); 536 537 const SwTOXBaseSection& rTOXSect = (const SwTOXBaseSection&)rTOXBase; 538 SwSectionFmt* pFmt = rTOXSect.GetFmt(); 539 if( pFmt ) 540 { 541 GetIDocumentUndoRedo().StartUndo( UNDO_CLEARTOXRANGE, NULL ); 542 543 /* Save the start node of the TOX' section. */ 544 SwSectionNode * pMyNode = pFmt->GetSectionNode(); 545 /* Save start node of section's surrounding. */ 546 SwNode * pStartNd = pMyNode->StartOfSectionNode(); 547 548 /* Look for point where to move the cursors in the area to 549 delete to. This is done by first searching forward from the 550 end of the TOX' section. If no content node is found behind 551 the TOX one is searched before it. If this is not 552 successfull, too, insert new text node behind the end of 553 the TOX' section. The cursors from the TOX' section will be 554 moved to the content node found or the new text node. */ 555 556 /* Set PaM to end of TOX' section and search following content node. 557 558 aSearchPam will contain the point where to move the cursors 559 to. */ 560 SwPaM aSearchPam(*pMyNode->EndOfSectionNode()); 561 SwPosition aEndPos(*pStartNd->EndOfSectionNode()); 562 if (! aSearchPam.Move() /* no content node found */ 563 || *aSearchPam.GetPoint() >= aEndPos /* content node found 564 outside surrounding */ 565 ) 566 { 567 /* Set PaM to beginning of TOX' section and search previous 568 content node */ 569 SwPaM aTmpPam(*pMyNode); 570 aSearchPam = aTmpPam; 571 SwPosition aStartPos(*pStartNd); 572 573 if ( ! aSearchPam.Move(fnMoveBackward) /* no content node found */ 574 || *aSearchPam.GetPoint() <= aStartPos /* content node 575 found outside 576 surrounding */ 577 ) 578 { 579 /* There is no content node in the surrounding of 580 TOX'. Append text node behind TOX' section. */ 581 582 SwPosition aInsPos(*pMyNode->EndOfSectionNode()); 583 AppendTxtNode(aInsPos); 584 585 SwPaM aTmpPam1(aInsPos); 586 aSearchPam = aTmpPam1; 587 } 588 } 589 590 591 /* PaM containing the TOX. */ 592 SwPaM aPam(*pMyNode->EndOfSectionNode(), *pMyNode); 593 594 /* Move cursors contained in TOX to point determined above. */ 595 PaMCorrAbs(aPam, *aSearchPam.GetPoint()); 596 597 if( !bDelNodes ) 598 { 599 SwSections aArr( 0, 4 ); 600 sal_uInt16 nCnt = pFmt->GetChildSections( aArr, SORTSECT_NOT, sal_False ); 601 for( sal_uInt16 n = 0; n < nCnt; ++n ) 602 { 603 SwSection* pSect = aArr[ n ]; 604 if( TOX_HEADER_SECTION == pSect->GetType() ) 605 { 606 DelSectionFmt( pSect->GetFmt(), bDelNodes ); 607 } 608 } 609 } 610 611 DelSectionFmt( pFmt, bDelNodes ); 612 613 GetIDocumentUndoRedo().EndUndo( UNDO_CLEARTOXRANGE, NULL ); 614 bRet = sal_True; 615 } 616 617 return bRet; 618 } 619 620 /*-------------------------------------------------------------------- 621 Beschreibung: Verzeichnistypen verwalten 622 --------------------------------------------------------------------*/ 623 624 sal_uInt16 SwDoc::GetTOXTypeCount(TOXTypes eTyp) const 625 { 626 const SwTOXTypePtr * ppTTypes = pTOXTypes->GetData(); 627 sal_uInt16 nCnt = 0; 628 for( sal_uInt16 n = 0; n < pTOXTypes->Count(); ++n, ++ppTTypes ) 629 if( eTyp == (*ppTTypes)->GetType() ) 630 ++nCnt; 631 return nCnt; 632 } 633 634 const SwTOXType* SwDoc::GetTOXType( TOXTypes eTyp, sal_uInt16 nId ) const 635 { 636 const SwTOXTypePtr * ppTTypes = pTOXTypes->GetData(); 637 sal_uInt16 nCnt = 0; 638 for( sal_uInt16 n = 0; n < pTOXTypes->Count(); ++n, ++ppTTypes ) 639 if( eTyp == (*ppTTypes)->GetType() && nCnt++ == nId ) 640 return (*ppTTypes); 641 return 0; 642 } 643 644 645 const SwTOXType* SwDoc::InsertTOXType( const SwTOXType& rTyp ) 646 { 647 SwTOXType * pNew = new SwTOXType( rTyp ); 648 pTOXTypes->Insert( pNew, pTOXTypes->Count() ); 649 return pNew; 650 } 651 652 String SwDoc::GetUniqueTOXBaseName( const SwTOXType& rType, 653 const String* pChkStr ) const 654 { 655 sal_uInt16 n; 656 const SwSectionNode* pSectNd; 657 const SwSection* pSect; 658 659 if(pChkStr && !pChkStr->Len()) 660 pChkStr = 0; 661 String aName( rType.GetTypeName() ); 662 xub_StrLen nNmLen = aName.Len(); 663 664 sal_uInt16 nNum = 0; 665 sal_uInt16 nTmp = 0; 666 sal_uInt16 nFlagSize = ( pSectionFmtTbl->Count() / 8 ) +2; 667 sal_uInt8* pSetFlags = new sal_uInt8[ nFlagSize ]; 668 memset( pSetFlags, 0, nFlagSize ); 669 670 for( n = 0; n < pSectionFmtTbl->Count(); ++n ) 671 if( 0 != ( pSectNd = (*pSectionFmtTbl)[ n ]->GetSectionNode( sal_False ) )&& 672 TOX_CONTENT_SECTION == (pSect = &pSectNd->GetSection())->GetType()) 673 { 674 const String& rNm = pSect->GetSectionName(); 675 if( rNm.Match( aName ) == nNmLen ) 676 { 677 // Nummer bestimmen und das Flag setzen 678 nNum = (sal_uInt16)rNm.Copy( nNmLen ).ToInt32(); 679 if( nNum-- && nNum < pSectionFmtTbl->Count() ) 680 pSetFlags[ nNum / 8 ] |= (0x01 << ( nNum & 0x07 )); 681 } 682 if( pChkStr && pChkStr->Equals( rNm ) ) 683 pChkStr = 0; 684 } 685 686 if( !pChkStr ) 687 { 688 // alle Nummern entsprechend geflag, also bestimme die richtige Nummer 689 nNum = pSectionFmtTbl->Count(); 690 for( n = 0; n < nFlagSize; ++n ) 691 if( 0xff != ( nTmp = pSetFlags[ n ] )) 692 { 693 // also die Nummer bestimmen 694 nNum = n * 8; 695 while( nTmp & 1 ) 696 ++nNum, nTmp >>= 1; 697 break; 698 } 699 } 700 delete [] pSetFlags; 701 if( pChkStr ) 702 return *pChkStr; 703 return aName += String::CreateFromInt32( ++nNum ); 704 } 705 706 sal_Bool SwDoc::SetTOXBaseName(const SwTOXBase& rTOXBase, const String& rName) 707 { 708 ASSERT( rTOXBase.ISA( SwTOXBaseSection ), 709 "keine TOXBaseSection!" ); 710 SwTOXBaseSection* pTOX = (SwTOXBaseSection*)&rTOXBase; 711 712 String sTmp = GetUniqueTOXBaseName(*rTOXBase.GetTOXType(), &rName); 713 sal_Bool bRet = sTmp == rName; 714 if(bRet) 715 { 716 pTOX->SetTOXName(rName); 717 pTOX->SetSectionName(rName); 718 SetModified(); 719 } 720 return bRet; 721 } 722 723 724 const SwTxtNode* lcl_FindChapterNode( const SwNode& rNd, sal_uInt8 nLvl = 0 ) 725 { 726 const SwNode* pNd = &rNd; 727 if( pNd->GetNodes().GetEndOfExtras().GetIndex() > pNd->GetIndex() ) 728 { 729 // then find the "Anchor" (Body) position 730 Point aPt; 731 SwNode2Layout aNode2Layout( *pNd, pNd->GetIndex() ); 732 const SwFrm* pFrm = aNode2Layout.GetFrm( &aPt, 0, sal_False ); 733 734 if( pFrm ) 735 { 736 SwPosition aPos( *pNd ); 737 pNd = GetBodyTxtNode( *pNd->GetDoc(), aPos, *pFrm ); 738 ASSERT( pNd, "wo steht der Absatz" ); 739 } 740 } 741 return pNd ? pNd->FindOutlineNodeOfLevel( nLvl ) : 0; 742 } 743 744 745 /*-------------------------------------------------------------------- 746 Beschreibung: Verzeichnis-Klasse 747 --------------------------------------------------------------------*/ 748 749 SwTOXBaseSection::SwTOXBaseSection(SwTOXBase const& rBase, SwSectionFmt & rFmt) 750 : SwTOXBase( rBase ) 751 , SwSection( TOX_CONTENT_SECTION, aEmptyStr, rFmt ) 752 { 753 SetProtect( rBase.IsProtected() ); 754 SetSectionName( GetTOXName() ); 755 } 756 757 758 SwTOXBaseSection::~SwTOXBaseSection() 759 { 760 aSortArr.DeleteAndDestroy( 0, aSortArr.Count() ); // i120680 761 } 762 763 764 sal_Bool SwTOXBaseSection::SetPosAtStartEnd( SwPosition& rPos, sal_Bool bAtStart ) const 765 { 766 sal_Bool bRet = sal_False; 767 const SwSectionNode* pSectNd = GetFmt()->GetSectionNode(); 768 if( pSectNd ) 769 { 770 SwCntntNode* pCNd; 771 xub_StrLen nC = 0; 772 if( bAtStart ) 773 { 774 rPos.nNode = *pSectNd; 775 pCNd = pSectNd->GetDoc()->GetNodes().GoNext( &rPos.nNode ); 776 } 777 else 778 { 779 rPos.nNode = *pSectNd->EndOfSectionNode(); 780 pCNd = pSectNd->GetDoc()->GetNodes().GoPrevious( &rPos.nNode ); 781 if( pCNd ) nC = pCNd->Len(); 782 } 783 rPos.nContent.Assign( pCNd, nC ); 784 bRet = sal_True; 785 } 786 return bRet; 787 } 788 789 /*-------------------------------------------------------------------- 790 Beschreibung: Verzeichnisinhalt zusammensammeln 791 --------------------------------------------------------------------*/ 792 793 void SwTOXBaseSection::Update(const SfxItemSet* pAttr, 794 const bool _bNewTOX )//swmodtest 080307 795 { 796 const SwSectionNode* pSectNd; 797 if( !SwTOXBase::GetRegisteredIn()->GetDepends() || 798 !GetFmt() || 0 == (pSectNd = GetFmt()->GetSectionNode() ) || 799 !pSectNd->GetNodes().IsDocNodes() || 800 IsHiddenFlag() ) 801 { 802 return; 803 } 804 805 if ( !mbKeepExpression ) 806 { 807 maMSTOCExpression = String(); 808 } 809 810 SwDoc* pDoc = (SwDoc*)pSectNd->GetDoc(); 811 812 DBG_ASSERT(pDoc != NULL, "Where is the document?"); 813 814 if(pAttr && pDoc && GetFmt()) 815 pDoc->ChgFmt(*GetFmt(), *pAttr); 816 817 // OD 18.03.2003 #106329# - determine default page description, which 818 // will be used by the content nodes, if no approriate one is found. 819 const SwPageDesc* pDefaultPageDesc; 820 { 821 pDefaultPageDesc = 822 pSectNd->GetSection().GetFmt()->GetPageDesc().GetPageDesc(); 823 if ( !_bNewTOX && !pDefaultPageDesc ) 824 { 825 // determine page description of table-of-content 826 sal_uInt32 nPgDescNdIdx = pSectNd->GetIndex() + 1; 827 sal_uInt32* pPgDescNdIdx = &nPgDescNdIdx; 828 pDefaultPageDesc = pSectNd->FindPageDesc( sal_False, pPgDescNdIdx ); 829 if ( nPgDescNdIdx < pSectNd->GetIndex() ) 830 { 831 pDefaultPageDesc = 0; 832 } 833 } 834 // OD 28.04.2003 #109166# - consider end node of content section in the 835 // node array. 836 if ( !pDefaultPageDesc && 837 ( pSectNd->EndOfSectionNode()->GetIndex() < 838 (pSectNd->GetNodes().GetEndOfContent().GetIndex() - 1) ) 839 ) 840 { 841 // determine page description of content after table-of-content 842 SwNodeIndex aIdx( *(pSectNd->EndOfSectionNode()) ); 843 const SwCntntNode* pNdAfterTOX = pSectNd->GetNodes().GoNext( &aIdx ); 844 const SwAttrSet& aNdAttrSet = pNdAfterTOX->GetSwAttrSet(); 845 const SvxBreak eBreak = aNdAttrSet.GetBreak().GetBreak(); 846 if ( !( eBreak == SVX_BREAK_PAGE_BEFORE || 847 eBreak == SVX_BREAK_PAGE_BOTH ) 848 ) 849 { 850 pDefaultPageDesc = pNdAfterTOX->FindPageDesc( sal_False ); 851 } 852 } 853 // OD 28.04.2003 #109166# - consider start node of content section in 854 // the node array. 855 if ( !pDefaultPageDesc && 856 ( pSectNd->GetIndex() > 857 (pSectNd->GetNodes().GetEndOfContent().StartOfSectionIndex() + 1) ) 858 ) 859 { 860 // determine page description of content before table-of-content 861 SwNodeIndex aIdx( *pSectNd ); 862 pDefaultPageDesc = 863 pSectNd->GetNodes().GoPrevious( &aIdx )->FindPageDesc( sal_False ); 864 865 } 866 if ( !pDefaultPageDesc ) 867 { 868 // determine default page description 869 pDefaultPageDesc = 870 &const_cast<const SwDoc *>(pDoc)->GetPageDesc( 0 ); 871 } 872 } 873 874 pDoc->SetModified(); 875 876 // get current Language 877 SwTOXInternational aIntl( GetLanguage(), 878 TOX_INDEX == GetTOXType()->GetType() ? 879 GetOptions() : 0, 880 GetSortAlgorithm() ); 881 882 aSortArr.DeleteAndDestroy( 0, aSortArr.Count() ); 883 884 // find the first layout node for this TOX, if it only find the content 885 // in his own chapter 886 const SwTxtNode* pOwnChapterNode = IsFromChapter() 887 ? ::lcl_FindChapterNode( *pSectNd, 0 ) 888 : 0; 889 890 SwNode2Layout aN2L( *pSectNd ); 891 ((SwSectionNode*)pSectNd)->DelFrms(); 892 893 // remove old content an insert one empty textnode (to hold the layout!) 894 SwTxtNode* pFirstEmptyNd; 895 { 896 pDoc->DeleteRedline( *pSectNd, true, USHRT_MAX ); 897 898 SwNodeIndex aSttIdx( *pSectNd, +1 ); 899 SwNodeIndex aEndIdx( *pSectNd->EndOfSectionNode() ); 900 pFirstEmptyNd = pDoc->GetNodes().MakeTxtNode( aEndIdx, 901 pDoc->GetTxtCollFromPool( RES_POOLCOLL_TEXT ) ); 902 903 { 904 // Task 70995 - save and restore PageDesc and Break Attributes 905 SwNodeIndex aNxtIdx( aSttIdx ); 906 const SwCntntNode* pCNd = aNxtIdx.GetNode().GetCntntNode(); 907 if( !pCNd ) 908 pCNd = pDoc->GetNodes().GoNext( &aNxtIdx ); 909 if( pCNd->HasSwAttrSet() ) 910 { 911 SfxItemSet aBrkSet( pDoc->GetAttrPool(), aBreakSetRange ); 912 aBrkSet.Put( *pCNd->GetpSwAttrSet() ); 913 if( aBrkSet.Count() ) 914 pFirstEmptyNd->SetAttr( aBrkSet ); 915 } 916 } 917 aEndIdx--; 918 SwPosition aPos( aEndIdx, SwIndex( pFirstEmptyNd, 0 )); 919 pDoc->CorrAbs( aSttIdx, aEndIdx, aPos, sal_True ); 920 921 // delete all before 922 DelFlyInRange( aSttIdx, aEndIdx ); 923 _DelBookmarks( aSttIdx, aEndIdx ); 924 925 pDoc->GetNodes().Delete( aSttIdx, aEndIdx.GetIndex() - aSttIdx.GetIndex() ); 926 927 } 928 929 // 930 // insert title of TOX 931 if( GetTitle().Len() ) 932 { 933 // then insert the headline section 934 SwNodeIndex aIdx( *pSectNd, +1 ); 935 936 SwTxtNode* pHeadNd = pDoc->GetNodes().MakeTxtNode( aIdx, 937 GetTxtFmtColl( FORM_TITLE ) ); 938 pHeadNd->InsertText( GetTitle(), SwIndex( pHeadNd ) ); 939 940 String sNm( GetTOXName() ); 941 // ??Resource 942 sNm.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "_Head" )); 943 944 SwSectionData headerData( TOX_HEADER_SECTION, sNm ); 945 946 SwNodeIndex aStt( *pHeadNd ); aIdx--; 947 SwSectionFmt* pSectFmt = pDoc->MakeSectionFmt( 0 ); 948 pDoc->GetNodes().InsertTextSection( 949 aStt, *pSectFmt, headerData, 0, &aIdx, true, false); 950 } 951 952 // jetzt waere ein prima Zeitpunkt, um die Numerierung zu updaten 953 pDoc->UpdateNumRule(); 954 955 if( GetCreateType() & nsSwTOXElement::TOX_MARK ) 956 UpdateMarks( aIntl, pOwnChapterNode ); 957 958 if( GetCreateType() & nsSwTOXElement::TOX_OUTLINELEVEL ) 959 UpdateOutline( pOwnChapterNode ); 960 961 if( GetCreateType() & nsSwTOXElement::TOX_TEMPLATE ) 962 UpdateTemplate( pOwnChapterNode ); 963 964 if( GetCreateType() & nsSwTOXElement::TOX_OLE || 965 TOX_OBJECTS == SwTOXBase::GetType()) 966 UpdateCntnt( nsSwTOXElement::TOX_OLE, pOwnChapterNode ); 967 968 if( GetCreateType() & nsSwTOXElement::TOX_TABLE || 969 (TOX_TABLES == SwTOXBase::GetType() && IsFromObjectNames()) ) 970 UpdateTable( pOwnChapterNode ); 971 972 if( GetCreateType() & nsSwTOXElement::TOX_GRAPHIC || 973 (TOX_ILLUSTRATIONS == SwTOXBase::GetType() && IsFromObjectNames())) 974 UpdateCntnt( nsSwTOXElement::TOX_GRAPHIC, pOwnChapterNode ); 975 976 if( GetSequenceName().Len() && !IsFromObjectNames() && 977 (TOX_TABLES == SwTOXBase::GetType() || 978 TOX_ILLUSTRATIONS == SwTOXBase::GetType() ) ) 979 UpdateSequence( pOwnChapterNode ); 980 981 if( GetCreateType() & nsSwTOXElement::TOX_FRAME ) 982 UpdateCntnt( nsSwTOXElement::TOX_FRAME, pOwnChapterNode ); 983 984 if(TOX_AUTHORITIES == SwTOXBase::GetType()) 985 UpdateAuthorities( aIntl ); 986 987 // Bei Bedarf Alphadelimitter einfuegen (nur bei Stichwoertern) 988 // 989 if( TOX_INDEX == SwTOXBase::GetType() && 990 ( GetOptions() & nsSwTOIOptions::TOI_ALPHA_DELIMITTER ) ) 991 InsertAlphaDelimitter( aIntl ); 992 993 // sortierte Liste aller Verzeichnismarken und Verzeichnisbereiche 994 void* p = 0; 995 String* pStr = 0; 996 sal_uInt16 nCnt = 0, nFormMax = GetTOXForm().GetFormMax(); 997 SvStringsDtor aStrArr( (sal_uInt8)nFormMax ); 998 SvPtrarr aCollArr( (sal_uInt8)nFormMax ); 999 for( ; nCnt < nFormMax; ++nCnt ) 1000 { 1001 aCollArr.Insert( p, nCnt ); 1002 aStrArr.Insert( pStr, nCnt ); 1003 } 1004 1005 SwNodeIndex aInsPos( *pFirstEmptyNd, 1 ); 1006 for( nCnt = 0; nCnt < aSortArr.Count(); ++nCnt ) 1007 { 1008 ::SetProgressState( 0, pDoc->GetDocShell() ); 1009 1010 // setze den Text in das Verzeichniss 1011 sal_uInt16 nLvl = aSortArr[ nCnt ]->GetLevel(); 1012 SwTxtFmtColl* pColl = (SwTxtFmtColl*)aCollArr[ nLvl ]; 1013 if( !pColl ) 1014 { 1015 pColl = GetTxtFmtColl( nLvl ); 1016 aCollArr.Remove( nLvl ); 1017 p = pColl; 1018 aCollArr.Insert( p , nLvl ); 1019 } 1020 1021 // Generierung: dynamische TabStops setzen 1022 SwTxtNode* pTOXNd = pDoc->GetNodes().MakeTxtNode( aInsPos , pColl ); 1023 aSortArr[ nCnt ]->pTOXNd = pTOXNd; 1024 1025 // Generierung: Form auswerten und Platzhalter 1026 // fuer die Seitennummer eintragen 1027 //if it is a TOX_INDEX and the SwForm IsCommaSeparated() 1028 // then a range of entries must be generated into one paragraph 1029 sal_uInt16 nRange = 1; 1030 if(TOX_INDEX == SwTOXBase::GetType() && 1031 GetTOXForm().IsCommaSeparated() && 1032 aSortArr[nCnt]->GetType() == TOX_SORT_INDEX) 1033 { 1034 const SwTOXMark& rMark = aSortArr[nCnt]->pTxtMark->GetTOXMark(); 1035 const String sPrimKey = rMark.GetPrimaryKey(); 1036 const String sSecKey = rMark.GetSecondaryKey(); 1037 const SwTOXMark* pNextMark = 0; 1038 while(aSortArr.Count() > (nCnt + nRange)&& 1039 aSortArr[nCnt + nRange]->GetType() == TOX_SORT_INDEX && 1040 0 != (pNextMark = &(aSortArr[nCnt + nRange]->pTxtMark->GetTOXMark())) && 1041 pNextMark->GetPrimaryKey() == sPrimKey && 1042 pNextMark->GetSecondaryKey() == sSecKey) 1043 nRange++; 1044 } 1045 // OD 18.03.2003 #106329# - pass node index of table-of-content section 1046 // and default page description to method <GenerateText(..)>. 1047 GenerateText( nCnt, nRange, aStrArr, pSectNd->GetIndex(), pDefaultPageDesc ); 1048 nCnt += nRange - 1; 1049 } 1050 1051 // delete the first dummy node and remove all Cursor into the prev node 1052 aInsPos = *pFirstEmptyNd; 1053 { 1054 SwPaM aCorPam( *pFirstEmptyNd ); 1055 aCorPam.GetPoint()->nContent.Assign( pFirstEmptyNd, 0 ); 1056 if( !aCorPam.Move( fnMoveForward ) ) 1057 aCorPam.Move( fnMoveBackward ); 1058 SwNodeIndex aEndIdx( aInsPos, 1 ); 1059 pDoc->CorrAbs( aInsPos, aEndIdx, *aCorPam.GetPoint(), sal_True ); 1060 1061 // Task 70995 - save and restore PageDesc and Break Attributes 1062 if( pFirstEmptyNd->HasSwAttrSet() ) 1063 { 1064 if( GetTitle().Len() ) 1065 aEndIdx = *pSectNd; 1066 else 1067 aEndIdx = *pFirstEmptyNd; 1068 SwCntntNode* pCNd = pDoc->GetNodes().GoNext( &aEndIdx ); 1069 if( pCNd ) // Robust against defect documents, e.g. i60336 1070 pCNd->SetAttr( *pFirstEmptyNd->GetpSwAttrSet() ); 1071 } 1072 } 1073 1074 // now create the new Frames 1075 sal_uLong nIdx = pSectNd->GetIndex(); 1076 // don't delete if index is empty 1077 if(nIdx + 2 < pSectNd->EndOfSectionIndex()) 1078 pDoc->GetNodes().Delete( aInsPos, 1 ); 1079 1080 aN2L.RestoreUpperFrms( pDoc->GetNodes(), nIdx, nIdx + 1 ); 1081 std::set<SwRootFrm*> aAllLayouts = pDoc->GetAllLayouts(); 1082 for ( std::set<SwRootFrm*>::iterator pLayoutIter = aAllLayouts.begin(); pLayoutIter != aAllLayouts.end(); pLayoutIter++) 1083 { 1084 SwFrm::CheckPageDescs( (SwPageFrm*)(*pLayoutIter)->Lower() ); 1085 }//swmod 080310 1086 1087 SetProtect( SwTOXBase::IsProtected() ); 1088 } 1089 1090 /*-------------------------------------------------------------------- 1091 Beschreibung: AlphaDelimitter einfuegen 1092 --------------------------------------------------------------------*/ 1093 1094 1095 void SwTOXBaseSection::InsertAlphaDelimitter( const SwTOXInternational& rIntl ) 1096 { 1097 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); 1098 String sDeli, sLastDeli; 1099 sal_uInt16 i = 0; 1100 while( i < aSortArr.Count() ) 1101 { 1102 ::SetProgressState( 0, pDoc->GetDocShell() ); 1103 1104 sal_uInt16 nLevel = aSortArr[i]->GetLevel(); 1105 1106 // Alpha-Delimitter ueberlesen 1107 if( nLevel == FORM_ALPHA_DELIMITTER ) 1108 continue; 1109 1110 String sMyString, sMyStringReading; 1111 aSortArr[i]->GetTxt( sMyString, sMyStringReading ); 1112 1113 sDeli = rIntl.GetIndexKey( sMyString, sMyStringReading, 1114 aSortArr[i]->GetLocale() ); 1115 1116 // Delimitter schon vorhanden ?? 1117 if( sDeli.Len() && sLastDeli != sDeli ) 1118 { 1119 // alle kleiner Blank wollen wir nicht haben -> sind Sonderzeichen 1120 if( ' ' <= sDeli.GetChar( 0 ) ) 1121 { 1122 SwTOXCustom* pCst = new SwTOXCustom( sDeli, aEmptyStr, FORM_ALPHA_DELIMITTER, 1123 rIntl, aSortArr[i]->GetLocale() ); 1124 aSortArr.Insert( pCst, i++ ); 1125 } 1126 sLastDeli = sDeli; 1127 } 1128 1129 // Skippen bis gleibhes oder kleineres Level erreicht ist 1130 do { 1131 i++; 1132 } while (i < aSortArr.Count() && aSortArr[i]->GetLevel() > nLevel); 1133 } 1134 } 1135 1136 /*-------------------------------------------------------------------- 1137 Beschreibung: Template auswerten 1138 --------------------------------------------------------------------*/ 1139 1140 SwTxtFmtColl* SwTOXBaseSection::GetTxtFmtColl( sal_uInt16 nLevel ) 1141 { 1142 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); 1143 const String& rName = GetTOXForm().GetTemplate( nLevel ); 1144 SwTxtFmtColl* pColl = rName.Len() ? pDoc->FindTxtFmtCollByName(rName) :0; 1145 if( !pColl ) 1146 { 1147 sal_uInt16 nPoolFmt = 0; 1148 const TOXTypes eMyType = SwTOXBase::GetType(); 1149 switch( eMyType ) 1150 { 1151 case TOX_INDEX: nPoolFmt = RES_POOLCOLL_TOX_IDXH; break; 1152 case TOX_USER: 1153 if( nLevel < 6 ) 1154 nPoolFmt = RES_POOLCOLL_TOX_USERH; 1155 else 1156 nPoolFmt = RES_POOLCOLL_TOX_USER6 - 6; 1157 break; 1158 case TOX_ILLUSTRATIONS: nPoolFmt = RES_POOLCOLL_TOX_ILLUSH; break; 1159 case TOX_OBJECTS: nPoolFmt = RES_POOLCOLL_TOX_OBJECTH; break; 1160 case TOX_TABLES: nPoolFmt = RES_POOLCOLL_TOX_TABLESH; break; 1161 case TOX_AUTHORITIES: nPoolFmt = RES_POOLCOLL_TOX_AUTHORITIESH; break; 1162 1163 case TOX_CONTENT: 1164 // im Content Bereich gibt es einen Sprung! 1165 if( nLevel < 6 ) 1166 nPoolFmt = RES_POOLCOLL_TOX_CNTNTH; 1167 else 1168 nPoolFmt = RES_POOLCOLL_TOX_CNTNT6 - 6; 1169 break; 1170 } 1171 1172 if(eMyType == TOX_AUTHORITIES && nLevel) 1173 nPoolFmt = nPoolFmt + 1; 1174 else if(eMyType == TOX_INDEX && nLevel) 1175 { 1176 //pool: Level 1,2,3, Delimiter 1177 //SwForm: Delimiter, Level 1,2,3 1178 nPoolFmt += 1 == nLevel ? nLevel + 3 : nLevel - 1; 1179 } 1180 else 1181 nPoolFmt = nPoolFmt + nLevel; 1182 pColl = pDoc->GetTxtCollFromPool( nPoolFmt ); 1183 } 1184 return pColl; 1185 } 1186 1187 1188 /*-------------------------------------------------------------------- 1189 Beschreibung: Aus Markierungen erzeugen 1190 --------------------------------------------------------------------*/ 1191 1192 void SwTOXBaseSection::UpdateMarks( const SwTOXInternational& rIntl, 1193 const SwTxtNode* pOwnChapterNode ) 1194 { 1195 const SwTOXType* pType = (SwTOXType*) SwTOXBase::GetRegisteredIn(); 1196 if( !pType->GetDepends() ) 1197 return; 1198 1199 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); 1200 TOXTypes eTOXTyp = GetTOXType()->GetType(); 1201 SwIterator<SwTOXMark,SwTOXType> aIter( *pType ); 1202 1203 SwTxtTOXMark* pTxtMark; 1204 SwTOXMark* pMark; 1205 for( pMark = aIter.First(); pMark; pMark = aIter.Next() ) 1206 { 1207 ::SetProgressState( 0, pDoc->GetDocShell() ); 1208 1209 if( pMark->GetTOXType()->GetType() == eTOXTyp && 1210 0 != ( pTxtMark = pMark->GetTxtTOXMark() ) ) 1211 { 1212 const SwTxtNode* pTOXSrc = pTxtMark->GetpTxtNd(); 1213 // nur TOXMarks einfuegen die im Doc stehen 1214 // nicht die, die im UNDO stehen 1215 // 1216 // if selected use marks from the same chapter only 1217 if( pTOXSrc->GetNodes().IsDocNodes() && 1218 pTOXSrc->GetTxt().Len() && pTOXSrc->GetDepends() && 1219 pTOXSrc->getLayoutFrm( pDoc->GetCurrentLayout() ) && 1220 (!IsFromChapter() || ::lcl_FindChapterNode( *pTOXSrc, 0 ) == pOwnChapterNode ) && 1221 !pTOXSrc->HasHiddenParaField() && 1222 !SwScriptInfo::IsInHiddenRange( *pTOXSrc, *pTxtMark->GetStart() ) ) 1223 { 1224 SwTOXSortTabBase* pBase = 0; 1225 if(TOX_INDEX == eTOXTyp) 1226 { 1227 // Stichwortverzeichnismarkierung 1228 lang::Locale aLocale; 1229 if ( pBreakIt->GetBreakIter().is() ) 1230 { 1231 aLocale = pBreakIt->GetLocale( 1232 pTOXSrc->GetLang( *pTxtMark->GetStart() ) ); 1233 } 1234 1235 pBase = new SwTOXIndex( *pTOXSrc, pTxtMark, 1236 GetOptions(), FORM_ENTRY, rIntl, aLocale ); 1237 InsertSorted(pBase); 1238 if(GetOptions() & nsSwTOIOptions::TOI_KEY_AS_ENTRY && 1239 pTxtMark->GetTOXMark().GetPrimaryKey().Len()) 1240 { 1241 pBase = new SwTOXIndex( *pTOXSrc, pTxtMark, 1242 GetOptions(), FORM_PRIMARY_KEY, rIntl, aLocale ); 1243 InsertSorted(pBase); 1244 if(pTxtMark->GetTOXMark().GetSecondaryKey().Len()) 1245 { 1246 pBase = new SwTOXIndex( *pTOXSrc, pTxtMark, 1247 GetOptions(), FORM_SECONDARY_KEY, rIntl, aLocale ); 1248 InsertSorted(pBase); 1249 } 1250 } 1251 } 1252 else if( TOX_USER == eTOXTyp || 1253 pMark->GetLevel() <= GetLevel()) 1254 { // Inhaltsberzeichnismarkierung 1255 // also used for user marks 1256 pBase = new SwTOXContent( *pTOXSrc, pTxtMark, rIntl ); 1257 InsertSorted(pBase); 1258 } 1259 } 1260 } 1261 } 1262 } 1263 1264 1265 /*-------------------------------------------------------------------- 1266 Beschreibung: Verzeichnisinhalt aus Gliederungsebene generieren 1267 --------------------------------------------------------------------*/ 1268 1269 1270 void SwTOXBaseSection::UpdateOutline( const SwTxtNode* pOwnChapterNode ) 1271 { 1272 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); 1273 SwNodes& rNds = pDoc->GetNodes(); 1274 1275 const SwOutlineNodes& rOutlNds = rNds.GetOutLineNds(); 1276 for( sal_uInt16 n = 0; n < rOutlNds.Count(); ++n ) 1277 { 1278 ::SetProgressState( 0, pDoc->GetDocShell() ); 1279 SwTxtNode* pTxtNd = rOutlNds[ n ]->GetTxtNode(); 1280 if( pTxtNd && pTxtNd->Len() && pTxtNd->GetDepends() && 1281 //sal_uInt16(pTxtNd->GetTxtColl()->GetOutlineLevel()+1) <= GetLevel() && //#outline level,zhaojianwei 1282 sal_uInt16( pTxtNd->GetAttrOutlineLevel()) <= GetLevel() && //<-end,zhaojianwei 1283 pTxtNd->getLayoutFrm( pDoc->GetCurrentLayout() ) && 1284 !pTxtNd->HasHiddenParaField() && 1285 !pTxtNd->HasHiddenCharAttribute( true ) && 1286 ( !IsFromChapter() || 1287 ::lcl_FindChapterNode( *pTxtNd, 0 ) == pOwnChapterNode )) 1288 { 1289 SwTOXPara * pNew = new SwTOXPara( *pTxtNd, nsSwTOXElement::TOX_OUTLINELEVEL ); 1290 InsertSorted( pNew ); 1291 } 1292 } 1293 } 1294 1295 /*-------------------------------------------------------------------- 1296 Beschreibung: Verzeichnisinhalt aus Vorlagenbereichen generieren 1297 --------------------------------------------------------------------*/ 1298 1299 void SwTOXBaseSection::UpdateTemplate( const SwTxtNode* pOwnChapterNode ) 1300 { 1301 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); 1302 for(sal_uInt16 i = 0; i < MAXLEVEL; i++) 1303 { 1304 String sTmpStyleNames = GetStyleNames(i); 1305 sal_uInt16 nTokenCount = sTmpStyleNames.GetTokenCount(TOX_STYLE_DELIMITER); 1306 for( sal_uInt16 nStyle = 0; nStyle < nTokenCount; ++nStyle ) 1307 { 1308 SwTxtFmtColl* pColl = pDoc->FindTxtFmtCollByName( 1309 sTmpStyleNames.GetToken( nStyle, 1310 TOX_STYLE_DELIMITER )); 1311 //TODO: no outline Collections in content indexes if OutlineLevels are already included 1312 if( !pColl || 1313 ( TOX_CONTENT == SwTOXBase::GetType() && 1314 GetCreateType() & nsSwTOXElement::TOX_OUTLINELEVEL && 1315 //NO_NUMBERING != pColl->GetOutlineLevel() ) )//#outline level,zhaojianwei 1316 pColl->IsAssignedToListLevelOfOutlineStyle()) )//<-end,zhaojianwei 1317 continue; 1318 1319 SwIterator<SwTxtNode,SwFmtColl> aIter( *pColl ); 1320 for( SwTxtNode* pTxtNd = aIter.First(); pTxtNd; pTxtNd = aIter.Next() ) 1321 { 1322 ::SetProgressState( 0, pDoc->GetDocShell() ); 1323 1324 if( pTxtNd->GetTxt().Len() && pTxtNd->getLayoutFrm( pDoc->GetCurrentLayout() ) && 1325 pTxtNd->GetNodes().IsDocNodes() && 1326 ( !IsFromChapter() || pOwnChapterNode == 1327 ::lcl_FindChapterNode( *pTxtNd, 0 ) ) ) 1328 { 1329 SwTOXPara * pNew = new SwTOXPara( *pTxtNd, nsSwTOXElement::TOX_TEMPLATE, i + 1 ); 1330 InsertSorted(pNew); 1331 } 1332 } 1333 } 1334 } 1335 } 1336 1337 /* -----------------14.07.99 09:59------------------- 1338 Description: generate content from sequence fields 1339 --------------------------------------------------*/ 1340 void SwTOXBaseSection::UpdateSequence( const SwTxtNode* pOwnChapterNode ) 1341 { 1342 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); 1343 SwFieldType* pSeqFld = pDoc->GetFldType(RES_SETEXPFLD, GetSequenceName(), false); 1344 if(!pSeqFld) 1345 return; 1346 1347 SwIterator<SwFmtFld,SwFieldType> aIter( *pSeqFld ); 1348 for( SwFmtFld* pFmtFld = aIter.First(); pFmtFld; pFmtFld = aIter.Next() ) 1349 { 1350 const SwTxtFld* pTxtFld = pFmtFld->GetTxtFld(); 1351 if(!pTxtFld) 1352 continue; 1353 const SwTxtNode& rTxtNode = pTxtFld->GetTxtNode(); 1354 ::SetProgressState( 0, pDoc->GetDocShell() ); 1355 1356 if( rTxtNode.GetTxt().Len() && rTxtNode.getLayoutFrm( pDoc->GetCurrentLayout() ) && 1357 rTxtNode.GetNodes().IsDocNodes() && 1358 ( !IsFromChapter() || 1359 ::lcl_FindChapterNode( rTxtNode, 0 ) == pOwnChapterNode ) ) 1360 { 1361 SwTOXPara * pNew = new SwTOXPara( rTxtNode, nsSwTOXElement::TOX_SEQUENCE, 1 ); 1362 //set indexes if the number or the reference text are to be displayed 1363 if( GetCaptionDisplay() == CAPTION_TEXT ) 1364 { 1365 pNew->SetStartIndex( 1366 SwGetExpField::GetReferenceTextPos( *pFmtFld, *pDoc )); 1367 } 1368 else if(GetCaptionDisplay() == CAPTION_NUMBER) 1369 { 1370 pNew->SetEndIndex(*pTxtFld->GetStart() + 1); 1371 } 1372 InsertSorted(pNew); 1373 } 1374 } 1375 } 1376 1377 void SwTOXBaseSection::UpdateAuthorities( const SwTOXInternational& rIntl ) 1378 { 1379 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); 1380 SwFieldType* pAuthFld = pDoc->GetFldType(RES_AUTHORITY, aEmptyStr, false); 1381 if(!pAuthFld) 1382 return; 1383 1384 SwIterator<SwFmtFld,SwFieldType> aIter( *pAuthFld ); 1385 for( SwFmtFld* pFmtFld = aIter.First(); pFmtFld; pFmtFld = aIter.Next() ) 1386 { 1387 const SwTxtFld* pTxtFld = pFmtFld->GetTxtFld(); 1388 //undo 1389 if(!pTxtFld) 1390 continue; 1391 const SwTxtNode& rTxtNode = pTxtFld->GetTxtNode(); 1392 ::SetProgressState( 0, pDoc->GetDocShell() ); 1393 1394 // const SwTxtNode* pChapterCompareNode = 0; 1395 1396 if( rTxtNode.GetTxt().Len() && rTxtNode.getLayoutFrm( pDoc->GetCurrentLayout() ) && 1397 rTxtNode.GetNodes().IsDocNodes() /*&& 1398 (!IsFromChapter() || pChapterCompareNode == pOwnChapterNode) */) 1399 { 1400 //#106485# the body node has to be used! 1401 SwCntntFrm *pFrm = rTxtNode.getLayoutFrm( pDoc->GetCurrentLayout() ); 1402 SwPosition aFldPos(rTxtNode); 1403 const SwTxtNode* pTxtNode = 0; 1404 if(pFrm && !pFrm->IsInDocBody()) 1405 pTxtNode = GetBodyTxtNode( *pDoc, aFldPos, *pFrm ); 1406 if(!pTxtNode) 1407 pTxtNode = &rTxtNode; 1408 SwTOXAuthority* pNew = new SwTOXAuthority( *pTxtNode, *pFmtFld, rIntl ); 1409 1410 InsertSorted(pNew); 1411 } 1412 } 1413 } 1414 1415 long lcl_IsSOObject( const SvGlobalName& rFactoryNm ) 1416 { 1417 static struct _SoObjType { 1418 long nFlag; 1419 // GlobalNameId 1420 struct _GlobalNameIds { 1421 sal_uInt32 n1; 1422 sal_uInt16 n2, n3; 1423 sal_uInt8 b8, b9, b10, b11, b12, b13, b14, b15; 1424 } aGlNmIds[4]; 1425 } aArr[] = { 1426 { nsSwTOOElements::TOO_MATH, 1427 { {SO3_SM_CLASSID_60},{SO3_SM_CLASSID_50}, 1428 {SO3_SM_CLASSID_40},{SO3_SM_CLASSID_30} } }, 1429 { nsSwTOOElements::TOO_CHART, 1430 { {SO3_SCH_CLASSID_60},{SO3_SCH_CLASSID_50}, 1431 {SO3_SCH_CLASSID_40},{SO3_SCH_CLASSID_30} } }, 1432 { nsSwTOOElements::TOO_CALC, 1433 { {SO3_SC_CLASSID_60},{SO3_SC_CLASSID_50}, 1434 {SO3_SC_CLASSID_40},{SO3_SC_CLASSID_30} } }, 1435 { nsSwTOOElements::TOO_DRAW_IMPRESS, 1436 { {SO3_SIMPRESS_CLASSID_60},{SO3_SIMPRESS_CLASSID_50}, 1437 {SO3_SIMPRESS_CLASSID_40},{SO3_SIMPRESS_CLASSID_30} } }, 1438 { nsSwTOOElements::TOO_DRAW_IMPRESS, 1439 { {SO3_SDRAW_CLASSID_60},{SO3_SDRAW_CLASSID_50}}}, 1440 { 0,{{0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0}, 1441 {0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0} } } 1442 }; 1443 1444 long nRet = 0; 1445 for( const _SoObjType* pArr = aArr; !nRet && pArr->nFlag; ++pArr ) 1446 for ( int n = 0; n < 4; ++n ) 1447 { 1448 const _SoObjType::_GlobalNameIds& rId = pArr->aGlNmIds[ n ]; 1449 if( !rId.n1 ) 1450 break; 1451 SvGlobalName aGlbNm( rId.n1, rId.n2, rId.n3, 1452 rId.b8, rId.b9, rId.b10, rId.b11, 1453 rId.b12, rId.b13, rId.b14, rId.b15 ); 1454 if( rFactoryNm == aGlbNm ) 1455 { 1456 nRet = pArr->nFlag; 1457 break; 1458 } 1459 } 1460 1461 return nRet; 1462 } 1463 1464 void SwTOXBaseSection::UpdateCntnt( SwTOXElement eMyType, 1465 const SwTxtNode* pOwnChapterNode ) 1466 { 1467 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); 1468 SwNodes& rNds = pDoc->GetNodes(); 1469 // auf den 1. Node der 1. Section 1470 sal_uLong nIdx = rNds.GetEndOfAutotext().StartOfSectionIndex() + 2, 1471 nEndIdx = rNds.GetEndOfAutotext().GetIndex(); 1472 1473 while( nIdx < nEndIdx ) 1474 { 1475 ::SetProgressState( 0, pDoc->GetDocShell() ); 1476 1477 SwNode* pNd = rNds[ nIdx ]; 1478 SwCntntNode* pCNd = 0; 1479 switch( eMyType ) 1480 { 1481 case nsSwTOXElement::TOX_FRAME: 1482 if( !pNd->IsNoTxtNode() ) 1483 { 1484 pCNd = pNd->GetCntntNode(); 1485 if( !pCNd ) 1486 { 1487 SwNodeIndex aTmp( *pNd ); 1488 pCNd = rNds.GoNext( &aTmp ); 1489 } 1490 } 1491 break; 1492 case nsSwTOXElement::TOX_GRAPHIC: 1493 if( pNd->IsGrfNode() ) 1494 pCNd = (SwCntntNode*)pNd; 1495 break; 1496 case nsSwTOXElement::TOX_OLE: 1497 if( pNd->IsOLENode() ) 1498 { 1499 sal_Bool bInclude = sal_True; 1500 if(TOX_OBJECTS == SwTOXBase::GetType()) 1501 { 1502 SwOLENode* pOLENode = pNd->GetOLENode(); 1503 long nMyOLEOptions = GetOLEOptions(); 1504 SwOLEObj& rOLEObj = pOLENode->GetOLEObj(); 1505 1506 if( rOLEObj.IsOleRef() ) //Noch nicht geladen 1507 { 1508 SvGlobalName aTmpName = SvGlobalName( rOLEObj.GetOleRef()->getClassID() ); 1509 long nObj = ::lcl_IsSOObject( aTmpName ); 1510 bInclude = ( (nMyOLEOptions & nsSwTOOElements::TOO_OTHER) && 0 == nObj) 1511 || (0 != (nMyOLEOptions & nObj)); 1512 } 1513 else 1514 { 1515 DBG_ERROR("OLE-object nicht geladen?"); 1516 bInclude = sal_False; 1517 } 1518 } 1519 1520 if(bInclude) 1521 pCNd = (SwCntntNode*)pNd; 1522 } 1523 break; 1524 default: break; 1525 } 1526 1527 if( pCNd ) 1528 { 1529 //find node in body text 1530 int nSetLevel = USHRT_MAX; 1531 1532 //#111105# tables of tables|illustrations|objects don't support hierarchies 1533 if( IsLevelFromChapter() && 1534 TOX_TABLES != SwTOXBase::GetType() && 1535 TOX_ILLUSTRATIONS != SwTOXBase::GetType() && 1536 TOX_OBJECTS != SwTOXBase::GetType() ) 1537 { 1538 const SwTxtNode* pOutlNd = ::lcl_FindChapterNode( *pCNd, 1539 MAXLEVEL - 1 ); 1540 if( pOutlNd ) 1541 { 1542 //sal_uInt16 nTmp = pOutlNd->GetTxtColl()->GetOutlineLevel();//#outline level,zhaojianwei 1543 //if( nTmp < NO_NUMBERING ) 1544 // nSetLevel = nTmp + 1; 1545 if( pOutlNd->GetTxtColl()->IsAssignedToListLevelOfOutlineStyle()) 1546 nSetLevel = pOutlNd->GetTxtColl()->GetAttrOutlineLevel() ;//<-end,zhaojianwei 1547 } 1548 } 1549 1550 if( pCNd->getLayoutFrm( pDoc->GetCurrentLayout() ) && ( !IsFromChapter() || 1551 ::lcl_FindChapterNode( *pCNd, 0 ) == pOwnChapterNode )) 1552 { 1553 SwTOXPara * pNew = new SwTOXPara( *pCNd, eMyType, 1554 ( USHRT_MAX != nSetLevel ) 1555 ? static_cast<sal_uInt16>(nSetLevel) 1556 : FORM_ALPHA_DELIMITTER ); 1557 InsertSorted( pNew ); 1558 } 1559 } 1560 1561 nIdx = pNd->StartOfSectionNode()->EndOfSectionIndex() + 2; // 2 == End-/StartNode 1562 } 1563 } 1564 1565 /*-------------------------------------------------------------------- 1566 Beschreibung: Tabelleneintraege zusammensuchen 1567 --------------------------------------------------------------------*/ 1568 1569 void SwTOXBaseSection::UpdateTable( const SwTxtNode* pOwnChapterNode ) 1570 { 1571 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); 1572 SwNodes& rNds = pDoc->GetNodes(); 1573 const SwFrmFmts& rArr = *pDoc->GetTblFrmFmts(); 1574 1575 for( sal_uInt16 n = 0; n < rArr.Count(); ++n ) 1576 { 1577 ::SetProgressState( 0, pDoc->GetDocShell() ); 1578 1579 SwTable* pTmpTbl = SwTable::FindTable( rArr[ n ] ); 1580 SwTableBox* pFBox; 1581 if( pTmpTbl && 0 != (pFBox = pTmpTbl->GetTabSortBoxes()[0] ) && 1582 pFBox->GetSttNd() && pFBox->GetSttNd()->GetNodes().IsDocNodes() ) 1583 { 1584 const SwTableNode* pTblNd = pFBox->GetSttNd()->FindTableNode(); 1585 SwNodeIndex aCntntIdx( *pTblNd, 1 ); 1586 1587 SwCntntNode* pCNd; 1588 while( 0 != ( pCNd = rNds.GoNext( &aCntntIdx ) ) && 1589 aCntntIdx.GetIndex() < pTblNd->EndOfSectionIndex() ) 1590 { 1591 if( pCNd->getLayoutFrm( pDoc->GetCurrentLayout() ) && (!IsFromChapter() || 1592 ::lcl_FindChapterNode( *pCNd, 0 ) == pOwnChapterNode )) 1593 { 1594 SwTOXTable * pNew = new SwTOXTable( *pCNd ); 1595 if( IsLevelFromChapter() && TOX_TABLES != SwTOXBase::GetType()) 1596 { 1597 const SwTxtNode* pOutlNd = 1598 ::lcl_FindChapterNode( *pCNd, MAXLEVEL - 1 ); 1599 if( pOutlNd ) 1600 { 1601 //sal_uInt16 nTmp = pOutlNd->GetTxtColl()->GetOutlineLevel();//#outline level,zhaojianwei 1602 //if( nTmp < NO_NUMBERING ) 1603 // pNew->SetLevel( nTmp + 1 ); 1604 if( pOutlNd->GetTxtColl()->IsAssignedToListLevelOfOutlineStyle()) 1605 { 1606 const int nTmp = pOutlNd->GetTxtColl()->GetAttrOutlineLevel(); 1607 pNew->SetLevel( static_cast<sal_uInt16>(nTmp) );//<-end ,zhaojianwei 1608 } 1609 } 1610 } 1611 InsertSorted(pNew); 1612 break; 1613 } 1614 } 1615 } 1616 } 1617 } 1618 1619 /*-------------------------------------------------------------------- 1620 Beschreibung: String generieren anhand der Form 1621 SonderZeichen 0-31 und 255 entfernen 1622 --------------------------------------------------------------------*/ 1623 1624 String lcl_GetNumString( const SwTOXSortTabBase& rBase, sal_Bool bUsePrefix, sal_uInt8 nLevel ) 1625 { 1626 String sRet; 1627 1628 if( !rBase.pTxtMark && rBase.aTOXSources.Count() > 0 ) 1629 { // nur wenn es keine Marke ist 1630 const SwTxtNode* pNd = rBase.aTOXSources[0].pNd->GetTxtNode(); 1631 if( pNd ) 1632 { 1633 const SwNumRule* pRule = pNd->GetNumRule(); 1634 1635 if( pRule && pNd->GetActualListLevel() < MAXLEVEL ) 1636 sRet = pNd->GetNumString(bUsePrefix, nLevel); 1637 } 1638 } 1639 return sRet; 1640 } 1641 1642 // OD 18.03.2003 #106329# - add parameter <_TOXSectNdIdx> and <_pDefaultPageDesc> 1643 // in order to control, which page description is used, no appropriate one is found. 1644 void SwTOXBaseSection::GenerateText( sal_uInt16 nArrayIdx, 1645 sal_uInt16 nCount, 1646 SvStringsDtor& , 1647 const sal_uInt32 _nTOXSectNdIdx, 1648 const SwPageDesc* _pDefaultPageDesc ) 1649 { 1650 LinkStructArr aLinkArr; 1651 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc(); 1652 ::SetProgressState( 0, pDoc->GetDocShell() ); 1653 1654 //pTOXNd is only set at the first mark 1655 SwTxtNode* pTOXNd = (SwTxtNode*)aSortArr[nArrayIdx]->pTOXNd; 1656 String& rTxt = (String&)pTOXNd->GetTxt(); 1657 rTxt.Erase(); 1658 for(sal_uInt16 nIndex = nArrayIdx; nIndex < nArrayIdx + nCount; nIndex++) 1659 { 1660 if(nIndex > nArrayIdx) 1661 rTxt.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ", " )); // comma separation 1662 // String mit dem Pattern aus der Form initialisieren 1663 const SwTOXSortTabBase& rBase = *aSortArr[nIndex]; 1664 sal_uInt16 nLvl = rBase.GetLevel(); 1665 ASSERT( nLvl < GetTOXForm().GetFormMax(), "ungueltiges FORM_LEVEL"); 1666 1667 SvxTabStopItem aTStops( 0, 0, SVX_TAB_ADJUST_DEFAULT, RES_PARATR_TABSTOP ); 1668 xub_StrLen nLinkStartPosition = STRING_NOTFOUND; 1669 String sLinkCharacterStyle; //default to "Default" character style - which is none 1670 String sURL; 1671 // create an enumerator 1672 // #i21237# 1673 SwFormTokens aPattern = GetTOXForm().GetPattern(nLvl); 1674 SwFormTokens::iterator aIt = aPattern.begin(); 1675 // remove text from node 1676 while(aIt != aPattern.end()) // #i21237# 1677 { 1678 SwFormToken aToken = *aIt; // #i21237# 1679 xub_StrLen nStartCharStyle = rTxt.Len(); 1680 switch( aToken.eTokenType ) 1681 { 1682 case TOKEN_ENTRY_NO: 1683 // fuer Inhaltsverzeichnis Numerierung 1684 rTxt.Insert( lcl_GetNumString( rBase, aToken.nChapterFormat == CF_NUMBER, static_cast<sal_uInt8>(aToken.nOutlineLevel - 1)) ); 1685 break; 1686 1687 case TOKEN_ENTRY_TEXT: 1688 { 1689 SwIndex aIdx( pTOXNd, rTxt.Len() ); 1690 rBase.FillText( *pTOXNd, aIdx ); 1691 } 1692 break; 1693 1694 case TOKEN_ENTRY: 1695 { 1696 // fuer Inhaltsverzeichnis Numerierung 1697 rTxt.Insert( lcl_GetNumString( rBase, sal_True, MAXLEVEL )); 1698 1699 SwIndex aIdx( pTOXNd, rTxt.Len() ); 1700 rBase.FillText( *pTOXNd, aIdx ); 1701 } 1702 break; 1703 1704 case TOKEN_TAB_STOP: 1705 if (aToken.bWithTab) // #i21237# 1706 rTxt.Append('\t'); 1707 // 1708 1709 if(SVX_TAB_ADJUST_END > aToken.eTabAlign) 1710 { 1711 const SvxLRSpaceItem& rLR = 1712 (SvxLRSpaceItem&)pTOXNd-> 1713 SwCntntNode::GetAttr( RES_LR_SPACE, sal_True ); 1714 1715 long nTabPosition = aToken.nTabStopPosition; 1716 if( !GetTOXForm().IsRelTabPos() && rLR.GetTxtLeft() ) 1717 nTabPosition -= rLR.GetTxtLeft(); 1718 aTStops.Insert( SvxTabStop( nTabPosition, 1719 aToken.eTabAlign, 1720 cDfltDecimalChar, 1721 aToken.cTabFillChar )); 1722 } 1723 else 1724 { 1725 const SwPageDesc* pPageDesc = ((SwFmtPageDesc&)pTOXNd-> 1726 SwCntntNode::GetAttr( RES_PAGEDESC )).GetPageDesc(); 1727 1728 sal_Bool bCallFindRect = sal_True; 1729 long nRightMargin; 1730 if( pPageDesc ) 1731 { 1732 const SwFrm* pFrm = pTOXNd->getLayoutFrm( pDoc->GetCurrentLayout(), 0, 0, sal_True ); 1733 if( !pFrm || 0 == ( pFrm = pFrm->FindPageFrm() ) || 1734 pPageDesc != ((SwPageFrm*)pFrm)->GetPageDesc() ) 1735 // dann muss man ueber den PageDesc gehen 1736 bCallFindRect = sal_False; 1737 } 1738 1739 SwRect aNdRect; 1740 if( bCallFindRect ) 1741 aNdRect = pTOXNd->FindLayoutRect( sal_True ); 1742 1743 if( aNdRect.IsEmpty() ) 1744 { 1745 // dann hilft alles nichts, wir muessen ueber die Seiten- 1746 // vorlage gehen. 1747 // OD 18.03.2003 #106329# - call 1748 sal_uInt32 nPgDescNdIdx = pTOXNd->GetIndex() + 1; 1749 sal_uInt32* pPgDescNdIdx = &nPgDescNdIdx; 1750 pPageDesc = pTOXNd->FindPageDesc( sal_False, pPgDescNdIdx ); 1751 if ( !pPageDesc || 1752 *pPgDescNdIdx < _nTOXSectNdIdx ) 1753 { 1754 // use default page description, if none is found 1755 // or the found one is given by a node before the 1756 // table-of-content section. 1757 pPageDesc = _pDefaultPageDesc; 1758 } 1759 1760 const SwFrmFmt& rPgDscFmt = pPageDesc->GetMaster(); 1761 nRightMargin = rPgDscFmt.GetFrmSize().GetWidth() - 1762 rPgDscFmt.GetLRSpace().GetLeft() - 1763 rPgDscFmt.GetLRSpace().GetRight(); 1764 } 1765 else 1766 nRightMargin = aNdRect.Width(); 1767 //#i24363# tab stops relative to indent 1768 if( pDoc->get(IDocumentSettingAccess::TABS_RELATIVE_TO_INDENT) ) 1769 { 1770 //left margin of paragraph style 1771 const SvxLRSpaceItem& rLRSpace = pTOXNd->GetTxtColl()->GetLRSpace(); 1772 nRightMargin -= rLRSpace.GetLeft(); 1773 nRightMargin -= rLRSpace.GetTxtFirstLineOfst(); 1774 } 1775 1776 aTStops.Insert( SvxTabStop( nRightMargin, SVX_TAB_ADJUST_RIGHT, 1777 cDfltDecimalChar, 1778 aToken.cTabFillChar )); 1779 } 1780 break; 1781 1782 case TOKEN_TEXT: 1783 rTxt.Append( aToken.sText ); 1784 break; 1785 1786 case TOKEN_PAGE_NUMS: 1787 // Platzhalter fuer Seitennummer(n) es wird nur der erste beachtet 1788 // 1789 { 1790 // Die Anzahl der gleichen Eintrage bestimmt die Seitennummern-Pattern 1791 // 1792 sal_uInt16 nSize = rBase.aTOXSources.Count(); 1793 if( nSize > 0 ) 1794 { 1795 String aInsStr( cNumRepl ); 1796 for(sal_uInt16 i=1; i < nSize; ++i) 1797 { 1798 aInsStr.AppendAscii( sPageDeli ); 1799 aInsStr += cNumRepl; 1800 } 1801 aInsStr += cEndPageNum; 1802 rTxt.Append( aInsStr ); 1803 } 1804 // // Tab entfernen, wenn keine Seitennummer 1805 // else if( rTxt.Len() && '\t' == rTxt.GetChar( rTxt.Len() - 1 )) 1806 // rTxt.Erase( rTxt.Len()-1, 1 ); 1807 } 1808 break; 1809 1810 case TOKEN_CHAPTER_INFO: 1811 { 1812 // ein bischen trickreich: suche irgend einen Frame 1813 const SwTOXSource* pTOXSource = 0; 1814 if(rBase.aTOXSources.Count()) 1815 pTOXSource = &rBase.aTOXSources[0]; 1816 1817 // --> OD 2008-02-14 #i53420# 1818 // if( pTOXSource && pTOXSource->pNd 1819 // pTOXSource->pNd->IsTxtNode() ) 1820 if ( pTOXSource && pTOXSource->pNd && 1821 pTOXSource->pNd->IsCntntNode() ) 1822 // <-- 1823 { 1824 const SwCntntFrm* pFrm = pTOXSource->pNd->getLayoutFrm( pDoc->GetCurrentLayout() ); 1825 if( pFrm ) 1826 { 1827 SwChapterFieldType aFldTyp; 1828 SwChapterField aFld( &aFldTyp, aToken.nChapterFormat ); 1829 aFld.SetLevel( static_cast<sal_uInt8>(aToken.nOutlineLevel - 1) ); 1830 // --> OD 2008-02-14 #i53420# 1831 // aFld.ChangeExpansion( pFrm, (SwTxtNode*)pTOXSource->pNd, sal_True ); 1832 aFld.ChangeExpansion( pFrm, 1833 dynamic_cast<const SwCntntNode*>(pTOXSource->pNd), 1834 sal_True ); 1835 // <-- 1836 //---> i89791 1837 // OD 2008-06-26 - continue to support CF_NUMBER 1838 // and CF_NUM_TITLE in order to handle ODF 1.0/1.1 1839 // written by OOo 3.x in the same way as OOo 2.x 1840 // would handle them. 1841 if ( CF_NUM_NOPREPST_TITLE == aToken.nChapterFormat || 1842 CF_NUMBER == aToken.nChapterFormat ) 1843 rTxt.Insert(aFld.GetNumber()); //get the string number without pre/postfix 1844 else if ( CF_NUMBER_NOPREPST == aToken.nChapterFormat || 1845 CF_NUM_TITLE == aToken.nChapterFormat ) 1846 //<--- 1847 { 1848 rTxt += aFld.GetNumber(); 1849 rTxt += ' '; 1850 rTxt += aFld.GetTitle(); 1851 } 1852 else if(CF_TITLE == aToken.nChapterFormat) 1853 rTxt += aFld.GetTitle(); 1854 } 1855 } 1856 } 1857 break; 1858 1859 case TOKEN_LINK_START: 1860 nLinkStartPosition = rTxt.Len(); 1861 sLinkCharacterStyle = aToken.sCharStyleName; 1862 break; 1863 1864 case TOKEN_LINK_END: 1865 //TODO: only paired start/end tokens are valid 1866 if( STRING_NOTFOUND != nLinkStartPosition) 1867 { 1868 SwIndex aIdx( pTOXNd, nLinkStartPosition ); 1869 //pTOXNd->Erase( aIdx, SwForm::nFormLinkSttLen ); 1870 xub_StrLen nEnd = rTxt.Len(); 1871 1872 if( !sURL.Len() ) 1873 { 1874 sURL = rBase.GetURL(); 1875 if( !sURL.Len() ) 1876 break; 1877 } 1878 LinkStruct* pNewLink = new LinkStruct(sURL, nLinkStartPosition, 1879 nEnd); 1880 const sal_uInt16 nPoolId = 1881 sLinkCharacterStyle.Len() == 0 1882 ? USHRT_MAX 1883 : SwStyleNameMapper::GetPoolIdFromUIName( sLinkCharacterStyle, nsSwGetPoolIdFromName::GET_POOLID_CHRFMT ); 1884 pNewLink->aINetFmt.SetVisitedFmtAndId( sLinkCharacterStyle, nPoolId ); 1885 pNewLink->aINetFmt.SetINetFmtAndId( sLinkCharacterStyle, nPoolId ); 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 const xub_StrLen nTmpEnd = pAttr->End() ? *pAttr->End() : 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