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