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