Update ooo320-m1
[ooovba.git] / sw / source / core / doc / doctxm.cxx
blob57ce88fec8c79a0f51b60b1be2ac870da8579def
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: doctxm.cxx,v $
10 * $Revision: 1.53 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #include <limits.h>
36 #include <hintids.hxx>
38 #define _SVSTDARR_STRINGSSORT
39 #include <svtools/svstdarr.hxx>
40 #include <svx/langitem.hxx>
41 #include <svx/brkitem.hxx>
42 #include <svx/tstpitem.hxx>
43 #include <svx/lrspitem.hxx>
44 #include <sot/clsids.hxx>
45 #include <docsh.hxx>
46 #include <ndole.hxx>
47 #include <txttxmrk.hxx>
48 #include <fmtinfmt.hxx>
49 #include <fmtpdsc.hxx>
50 #include <frmfmt.hxx>
51 #include <fmtfsize.hxx>
52 #include <frmatr.hxx>
53 #include <pagedesc.hxx>
54 #include <doc.hxx>
55 #include <pagefrm.hxx>
56 #include <ndtxt.hxx>
57 #include <swtable.hxx>
58 #include <doctxm.hxx>
59 #include <txmsrt.hxx>
60 #include <rolbck.hxx>
61 #include <poolfmt.hxx>
62 #include <txtfrm.hxx>
63 #include <rootfrm.hxx>
64 #include <undobj.hxx>
65 #include <swundo.hxx>
66 #include <mdiexp.hxx>
67 #include <docary.hxx>
68 #include <charfmt.hxx>
69 #include <fchrfmt.hxx>
70 #include <fldbas.hxx>
71 #include <fmtfld.hxx>
72 #include <txtfld.hxx>
73 #include <expfld.hxx>
74 #include <chpfld.hxx>
75 #include <mvsave.hxx>
76 #include <node2lay.hxx>
77 #include <SwStyleNameMapper.hxx>
78 #include <breakit.hxx>
79 #include <editsh.hxx>
80 #include <scriptinfo.hxx>
82 using namespace ::com::sun::star;
84 const sal_Unicode cNumRepl = '@';
85 const sal_Unicode cEndPageNum = '~';
86 const sal_Char __FAR_DATA sPageDeli[] = ", ";
88 SV_IMPL_PTRARR(SwTOXSortTabBases, SwTOXSortTabBasePtr)
90 TYPEINIT2( SwTOXBaseSection, SwTOXBase, SwSection ); // fuers RTTI
92 struct LinkStruct
94 SwFmtINetFmt aINetFmt;
95 xub_StrLen nStartTextPos, nEndTextPos;
97 LinkStruct( const String& rURL, xub_StrLen nStart, xub_StrLen nEnd )
98 : aINetFmt( rURL, aEmptyStr),
99 nStartTextPos( nStart),
100 nEndTextPos(nEnd) {}
103 typedef LinkStruct* LinkStructPtr;
104 SV_DECL_PTRARR(LinkStructArr, LinkStructPtr, 0, 5 )
105 SV_IMPL_PTRARR(LinkStructArr, LinkStructPtr)
107 USHORT SwDoc::GetTOIKeys( SwTOIKeyType eTyp, SvStringsSort& rArr ) const
109 if( rArr.Count() )
110 rArr.Remove( USHORT(0), rArr.Count() );
112 // dann mal ueber den Pool und alle Primary oder Secondary heraussuchen
113 const SwTxtTOXMark* pMark;
114 const SfxPoolItem* pItem;
115 const SwTOXType* pTOXType;
116 USHORT i, nMaxItems = GetAttrPool().GetItemCount( RES_TXTATR_TOXMARK );
117 for( i = 0; i < nMaxItems; ++i )
118 if( 0 != (pItem = GetAttrPool().GetItem( RES_TXTATR_TOXMARK, i ) ) &&
119 0!= ( pTOXType = ((SwTOXMark*)pItem)->GetTOXType()) &&
120 TOX_INDEX == pTOXType->GetType() &&
121 0 != ( pMark = ((SwTOXMark*)pItem)->GetTxtTOXMark() ) &&
122 pMark->GetpTxtNd() &&
123 pMark->GetpTxtNd()->GetNodes().IsDocNodes() )
125 const String* pStr;
126 if( TOI_PRIMARY == eTyp )
127 pStr = &((SwTOXMark*)pItem)->GetPrimaryKey();
128 else
129 pStr = &((SwTOXMark*)pItem)->GetSecondaryKey();
131 if( pStr->Len() )
132 rArr.Insert( (StringPtr)pStr );
135 return rArr.Count();
138 /*--------------------------------------------------------------------
139 Beschreibung: aktuelle Verzeichnismarkierungen ermitteln
140 --------------------------------------------------------------------*/
143 USHORT SwDoc::GetCurTOXMark( const SwPosition& rPos,
144 SwTOXMarks& rArr ) const
146 // suche an der Position rPos nach allen SwTOXMark's
147 SwTxtNode* pTxtNd = GetNodes()[ rPos.nNode ]->GetTxtNode();
148 // kein TextNode oder kein HintsArray vorhanden ??
149 if( !pTxtNd || !pTxtNd->GetpSwpHints() )
150 return 0;
152 const SwpHints & rHts = *pTxtNd->GetpSwpHints();
153 const SwTxtAttr* pHt;
154 xub_StrLen nSttIdx;
155 const xub_StrLen *pEndIdx;
157 xub_StrLen nAktPos = rPos.nContent.GetIndex();
159 for( USHORT n = 0; n < rHts.Count(); ++n )
161 if( RES_TXTATR_TOXMARK != (pHt = rHts[n])->Which() )
162 continue;
163 if( ( nSttIdx = *pHt->GetStart() ) < nAktPos )
165 // pruefe Ende mit ab
166 if( 0 == ( pEndIdx = pHt->GetEnd() ) ||
167 *pEndIdx <= nAktPos )
168 continue; // weiter suchen
170 else if( nSttIdx > nAktPos )
171 // ist Start vom Hint groesser als rPos, dann abbrechen. Denn
172 // die Attribute sind nach Start sortiert !
173 break;
175 const SwTOXMark* pTMark = &pHt->GetTOXMark();
176 rArr.Insert( pTMark, rArr.Count() );
178 return rArr.Count();
181 /*--------------------------------------------------------------------
182 Beschreibung: Marke loeschen
183 --------------------------------------------------------------------*/
185 void SwDoc::DeleteTOXMark( const SwTOXMark* pTOXMark )
187 // hole den TextNode und
188 const SwTxtTOXMark* pTxtTOXMark = pTOXMark->GetTxtTOXMark();
189 ASSERT( pTxtTOXMark, "Kein TxtTOXMark, kann nicht geloescht werden" );
191 SwTxtNode& rTxtNd = const_cast<SwTxtNode&>(pTxtTOXMark->GetTxtNode());
192 ASSERT( rTxtNd.GetpSwpHints(), "kann nicht geloescht werden" );
194 if( DoesUndo() )
196 // fuers Undo die Attribute sichern
197 ClearRedo();
198 SwUndoResetAttr* pUndo = new SwUndoResetAttr(
199 SwPosition( rTxtNd, SwIndex( &rTxtNd, *pTxtTOXMark->GetStart() ) ),
200 RES_TXTATR_TOXMARK );
201 AppendUndo( pUndo );
203 SwRegHistory aRHst( rTxtNd, &pUndo->GetHistory() );
204 rTxtNd.GetpSwpHints()->Register( &aRHst );
207 rTxtNd.DeleteAttribute( const_cast<SwTxtTOXMark*>(pTxtTOXMark) );
209 if ( DoesUndo() )
211 if( rTxtNd.GetpSwpHints() )
212 rTxtNd.GetpSwpHints()->DeRegister();
214 SetModified();
217 /*--------------------------------------------------------------------
218 Beschreibung: Traveln zwischen TOXMarks
219 --------------------------------------------------------------------*/
221 class CompareNodeCntnt
223 ULONG nNode;
224 xub_StrLen nCntnt;
225 public:
226 CompareNodeCntnt( ULONG nNd, xub_StrLen nCnt )
227 : nNode( nNd ), nCntnt( nCnt ) {}
229 int operator==( const CompareNodeCntnt& rCmp )
230 { return nNode == rCmp.nNode && nCntnt == rCmp.nCntnt; }
231 int operator!=( const CompareNodeCntnt& rCmp )
232 { return 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 int operator>=( const CompareNodeCntnt& rCmp )
243 { return nNode > rCmp.nNode ||
244 ( nNode == rCmp.nNode && nCntnt >= rCmp.nCntnt); }
247 const SwTOXMark& SwDoc::GotoTOXMark( const SwTOXMark& rCurTOXMark,
248 SwTOXSearch eDir, BOOL bInReadOnly )
250 const SwTxtTOXMark* pMark = rCurTOXMark.GetTxtTOXMark();
251 ASSERT(pMark, "pMark==0 Ungueltige TxtTOXMark");
253 const SwTxtNode *pTOXSrc = pMark->GetpTxtNd();
255 CompareNodeCntnt aAbsIdx( pTOXSrc->GetIndex(), *pMark->GetStart() );
256 CompareNodeCntnt aPrevPos( 0, 0 );
257 CompareNodeCntnt aNextPos( ULONG_MAX, STRING_NOTFOUND );
258 CompareNodeCntnt aMax( 0, 0 );
259 CompareNodeCntnt aMin( ULONG_MAX, STRING_NOTFOUND );
261 const SwTOXMark* pNew = 0;
262 const SwTOXMark* pMax = &rCurTOXMark;
263 const SwTOXMark* pMin = &rCurTOXMark;
265 const SwModify* pType = rCurTOXMark.GetRegisteredIn();
266 SwClientIter aIter( *(SwModify*)pType );
268 const SwTOXMark* pTOXMark;
269 const SwCntntFrm* pCFrm;
270 Point aPt;
271 for( pTOXMark = (SwTOXMark*)aIter.First( TYPE( SwTOXMark )); pTOXMark;
272 pTOXMark = (SwTOXMark*)aIter.Next() )
274 if( pTOXMark != &rCurTOXMark &&
275 0 != ( pMark = pTOXMark->GetTxtTOXMark()) &&
276 0 != ( pTOXSrc = pMark->GetpTxtNd() ) &&
277 0 != ( pCFrm = pTOXSrc->GetFrm( &aPt, 0, FALSE )) &&
278 ( bInReadOnly || !pCFrm->IsProtected() ))
280 CompareNodeCntnt aAbsNew( pTOXSrc->GetIndex(), *pMark->GetStart() );
281 switch( eDir )
283 //Die untenstehenden etwas komplizierter ausgefallen Ausdruecke
284 //dienen dazu auch ueber Eintraege auf der selben (!) Position
285 //traveln zu koennen. Wenn einer Zeit hat mag er sie mal
286 //optimieren.
288 case TOX_SAME_PRV:
289 if( pTOXMark->GetText() != rCurTOXMark.GetText() )
290 break;
291 /* no break here */
292 case TOX_PRV:
293 if ( (aAbsNew < aAbsIdx && aAbsNew > aPrevPos &&
294 aPrevPos != aAbsIdx && aAbsNew != aAbsIdx ) ||
295 (aAbsIdx == aAbsNew &&
296 (ULONG(&rCurTOXMark) > ULONG(pTOXMark) &&
297 (!pNew ||
298 (pNew && (aPrevPos < aAbsIdx ||
299 ULONG(pNew) < ULONG(pTOXMark)))))) ||
300 (aPrevPos == aAbsNew && aAbsIdx != aAbsNew &&
301 ULONG(pTOXMark) > ULONG(pNew)) )
303 pNew = pTOXMark;
304 aPrevPos = aAbsNew;
305 if ( aAbsNew >= aMax )
307 aMax = aAbsNew;
308 pMax = pTOXMark;
311 break;
313 case TOX_SAME_NXT:
314 if( pTOXMark->GetText() != rCurTOXMark.GetText() )
315 break;
316 /* no break here */
317 case TOX_NXT:
318 if ( (aAbsNew > aAbsIdx && aAbsNew < aNextPos &&
319 aNextPos != aAbsIdx && aAbsNew != aAbsIdx ) ||
320 (aAbsIdx == aAbsNew &&
321 (ULONG(&rCurTOXMark) < ULONG(pTOXMark) &&
322 (!pNew ||
323 (pNew && (aNextPos > aAbsIdx ||
324 ULONG(pNew) > ULONG(pTOXMark)))))) ||
325 (aNextPos == aAbsNew && aAbsIdx != aAbsNew &&
326 ULONG(pTOXMark) < ULONG(pNew)) )
328 pNew = pTOXMark;
329 aNextPos = aAbsNew;
330 if ( aAbsNew <= aMin )
332 aMin = aAbsNew;
333 pMin = pTOXMark;
336 break;
342 // kein Nachfolger wurde gefunden
343 // Min oder Max benutzen
344 if(!pNew)
346 switch(eDir)
348 case TOX_PRV:
349 case TOX_SAME_PRV:
350 pNew = pMax;
351 break;
352 case TOX_NXT:
353 case TOX_SAME_NXT:
354 pNew = pMin;
355 break;
356 default:
357 pNew = &rCurTOXMark;
360 return *pNew;
363 /* \f */
365 const SwTOXBaseSection* SwDoc::InsertTableOf( const SwPosition& rPos,
366 const SwTOXBase& rTOX,
367 const SfxItemSet* pSet,
368 BOOL bExpand )
370 StartUndo( UNDO_INSTOX, NULL );
372 SwTOXBaseSection* pNew = new SwTOXBaseSection( rTOX );
373 String sSectNm( rTOX.GetTOXName() );
374 sSectNm = GetUniqueTOXBaseName( *rTOX.GetTOXType(), &sSectNm );
375 pNew->SetTOXName(sSectNm);
376 pNew->SwSection::SetName(sSectNm);
377 SwPaM aPam( rPos );
378 SwSection* pSect = InsertSwSection( aPam, *pNew, pSet, false );
379 if( pSect )
381 SwSectionNode* pSectNd = pSect->GetFmt()->GetSectionNode();
382 SwSection* pCl = pNew;
383 pSect->GetFmt()->Add( pCl );
384 pSectNd->SetNewSection( pNew );
386 if( bExpand )
388 // OD 19.03.2003 #106329# - add value for 2nd parameter = true to
389 // indicate, that a creation of a new table of content has to be performed.
390 // Value of 1st parameter = default value.
391 pNew->Update( 0, true );
393 else if( 1 == rTOX.GetTitle().Len() && IsInReading() )
394 // insert title of TOX
396 // then insert the headline section
397 SwNodeIndex aIdx( *pSectNd, +1 );
399 SwTxtNode* pHeadNd = GetNodes().MakeTxtNode( aIdx,
400 GetTxtCollFromPool( RES_POOLCOLL_STANDARD ) );
402 String sNm( pNew->GetTOXName() );
403 // ??Resource
404 sNm.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "_Head" ));
406 SwSection aSect( TOX_HEADER_SECTION, sNm );
408 SwNodeIndex aStt( *pHeadNd ); aIdx--;
409 SwSectionFmt* pSectFmt = MakeSectionFmt( 0 );
410 GetNodes().InsertSection( aStt, *pSectFmt, aSect, &aIdx,
411 TRUE, FALSE );
414 else
415 delete pNew, pNew = 0;
417 EndUndo( UNDO_INSTOX, NULL );
419 return pNew;
424 const SwTOXBaseSection* SwDoc::InsertTableOf( ULONG nSttNd, ULONG nEndNd,
425 const SwTOXBase& rTOX,
426 const SfxItemSet* pSet )
428 // check for recursiv TOX
429 SwNode* pNd = GetNodes()[ nSttNd ];
430 SwSectionNode* pSectNd = pNd->FindSectionNode();
431 while( pSectNd )
433 SectionType eT = pSectNd->GetSection().GetType();
434 if( TOX_HEADER_SECTION == eT || TOX_CONTENT_SECTION == eT )
435 return 0;
436 pSectNd = pSectNd->StartOfSectionNode()->FindSectionNode();
439 // create SectionNode around the Nodes
440 SwTOXBaseSection* pNew = new SwTOXBaseSection( rTOX );
442 String sSectNm( rTOX.GetTOXName() );
443 sSectNm = GetUniqueTOXBaseName(*rTOX.GetTOXType(), &sSectNm);
444 pNew->SetTOXName(sSectNm);
445 pNew->SwSection::SetName(sSectNm);
447 SwNodeIndex aStt( GetNodes(), nSttNd ), aEnd( GetNodes(), nEndNd );
448 SwSectionFmt* pFmt = MakeSectionFmt( 0 );
449 if(pSet)
450 pFmt->SetFmtAttr(*pSet);
452 // --aEnd; // im InsertSection ist Ende inclusive
454 pSectNd = GetNodes().InsertSection( aStt, *pFmt, *pNew, &aEnd );
455 if( pSectNd )
457 SwSection* pCl = pNew;
458 pFmt->Add( pCl );
459 pSectNd->SetNewSection( pNew );
461 else
463 delete pNew, pNew = 0;
464 DelSectionFmt( pFmt );
467 return pNew;
470 /*--------------------------------------------------------------------
471 Beschreibung: Aktuelles Verzeichnis ermitteln
472 --------------------------------------------------------------------*/
474 const SwTOXBase* SwDoc::GetCurTOX( const SwPosition& rPos ) const
476 const SwNode& rNd = rPos.nNode.GetNode();
477 const SwSectionNode* pSectNd = rNd.FindSectionNode();
478 while( pSectNd )
480 SectionType eT = pSectNd->GetSection().GetType();
481 if( TOX_CONTENT_SECTION == eT )
483 ASSERT( pSectNd->GetSection().ISA( SwTOXBaseSection ),
484 "keine TOXBaseSection!" );
485 SwTOXBaseSection& rTOXSect = (SwTOXBaseSection&)
486 pSectNd->GetSection();
487 return &rTOXSect;
489 pSectNd = pSectNd->StartOfSectionNode()->FindSectionNode();
491 return 0;
493 /* -----------------01.09.99 16:01-------------------
495 --------------------------------------------------*/
496 const SwAttrSet& SwDoc::GetTOXBaseAttrSet(const SwTOXBase& rTOXBase) const
498 ASSERT( rTOXBase.ISA( SwTOXBaseSection ), "no TOXBaseSection!" );
499 const SwTOXBaseSection& rTOXSect = (const SwTOXBaseSection&)rTOXBase;
500 SwSectionFmt* pFmt = rTOXSect.GetFmt();
501 ASSERT( pFmt, "invalid TOXBaseSection!" );
502 return pFmt->GetAttrSet();
504 /* -----------------02.09.99 07:48-------------------
506 --------------------------------------------------*/
507 const SwTOXBase* SwDoc::GetDefaultTOXBase( TOXTypes eTyp, BOOL bCreate )
509 SwTOXBase** prBase = 0;
510 switch(eTyp)
512 case TOX_CONTENT: prBase = &pDefTOXBases->pContBase; break;
513 case TOX_INDEX: prBase = &pDefTOXBases->pIdxBase; break;
514 case TOX_USER: prBase = &pDefTOXBases->pUserBase; break;
515 case TOX_TABLES: prBase = &pDefTOXBases->pTblBase; break;
516 case TOX_OBJECTS: prBase = &pDefTOXBases->pObjBase; break;
517 case TOX_ILLUSTRATIONS: prBase = &pDefTOXBases->pIllBase; break;
518 case TOX_AUTHORITIES: prBase = &pDefTOXBases->pAuthBase; break;
520 if(!(*prBase) && bCreate)
522 SwForm aForm(eTyp);
523 const SwTOXType* pType = GetTOXType(eTyp, 0);
524 (*prBase) = new SwTOXBase(pType, aForm, 0, pType->GetTypeName());
526 return (*prBase);
528 /* -----------------02.09.99 08:06-------------------
530 --------------------------------------------------*/
531 void SwDoc::SetDefaultTOXBase(const SwTOXBase& rBase)
533 SwTOXBase** prBase = 0;
534 switch(rBase.GetType())
536 case TOX_CONTENT: prBase = &pDefTOXBases->pContBase; break;
537 case TOX_INDEX: prBase = &pDefTOXBases->pIdxBase; break;
538 case TOX_USER: prBase = &pDefTOXBases->pUserBase; break;
539 case TOX_TABLES: prBase = &pDefTOXBases->pTblBase; break;
540 case TOX_OBJECTS: prBase = &pDefTOXBases->pObjBase; break;
541 case TOX_ILLUSTRATIONS: prBase = &pDefTOXBases->pIllBase; break;
542 case TOX_AUTHORITIES: prBase = &pDefTOXBases->pAuthBase; break;
544 if(*prBase)
545 delete (*prBase);
546 (*prBase) = new SwTOXBase(rBase);
549 /*--------------------------------------------------------------------
550 Beschreibung: Verzeichnis loeschen
551 --------------------------------------------------------------------*/
554 BOOL SwDoc::DeleteTOX( const SwTOXBase& rTOXBase, BOOL bDelNodes )
556 // its only delete the TOX, not the nodes
557 BOOL bRet = FALSE;
558 ASSERT( rTOXBase.ISA( SwTOXBaseSection ), "keine TOXBaseSection!" );
560 const SwTOXBaseSection& rTOXSect = (const SwTOXBaseSection&)rTOXBase;
561 SwSectionFmt* pFmt = rTOXSect.GetFmt();
562 if( pFmt )
564 StartUndo( UNDO_CLEARTOXRANGE, NULL );
566 /* Save the start node of the TOX' section. */
567 SwSectionNode * pMyNode = pFmt->GetSectionNode();
568 /* Save start node of section's surrounding. */
569 SwNode * pStartNd = pMyNode->StartOfSectionNode();
571 /* Look for point where to move the cursors in the area to
572 delete to. This is done by first searching forward from the
573 end of the TOX' section. If no content node is found behind
574 the TOX one is searched before it. If this is not
575 successfull, too, insert new text node behind the end of
576 the TOX' section. The cursors from the TOX' section will be
577 moved to the content node found or the new text node. */
579 /* Set PaM to end of TOX' section and search following content node.
581 aSearchPam will contain the point where to move the cursors
582 to. */
583 SwPaM aSearchPam(*pMyNode->EndOfSectionNode());
584 SwPosition aEndPos(*pStartNd->EndOfSectionNode(), 0);
585 if (! aSearchPam.Move() /* no content node found */
586 || *aSearchPam.GetPoint() >= aEndPos /* content node found
587 outside surrounding */
590 /* Set PaM to beginning of TOX' section and search previous
591 content node */
592 SwPaM aTmpPam(*pMyNode);
593 aSearchPam = aTmpPam;
594 SwPosition aStartPos(*pStartNd, 0);
596 if ( ! aSearchPam.Move(fnMoveBackward) /* no content node found */
597 || *aSearchPam.GetPoint() <= aStartPos /* content node
598 found outside
599 surrounding */
602 /* There is no content node in the surrounding of
603 TOX'. Append text node behind TOX' section. */
605 SwPosition aInsPos(*pMyNode->EndOfSectionNode(), 0);
606 AppendTxtNode(aInsPos);
608 SwPaM aTmpPam1(aInsPos);
609 aSearchPam = aTmpPam1;
614 /* PaM containing the TOX. */
615 SwPaM aPam(*pMyNode->EndOfSectionNode(), *pMyNode);
617 /* Move cursors contained in TOX to point determined above. */
618 PaMCorrAbs(aPam, *aSearchPam.GetPoint());
620 if( !bDelNodes )
622 SwSections aArr( 0, 4 );
623 USHORT nCnt = pFmt->GetChildSections( aArr, SORTSECT_NOT, FALSE );
624 for( USHORT n = 0; n < nCnt; ++n )
626 SwSection* pSect = aArr[ n ];
627 if( TOX_HEADER_SECTION == pSect->GetType() )
629 DelSectionFmt( pSect->GetFmt(), bDelNodes );
634 DelSectionFmt( pFmt, bDelNodes );
636 EndUndo( UNDO_CLEARTOXRANGE, NULL );
637 bRet = TRUE;
640 return bRet;
643 /*--------------------------------------------------------------------
644 Beschreibung: Verzeichnistypen verwalten
645 --------------------------------------------------------------------*/
647 USHORT SwDoc::GetTOXTypeCount(TOXTypes eTyp) const
649 const SwTOXTypePtr * ppTTypes = pTOXTypes->GetData();
650 USHORT nCnt = 0;
651 for( USHORT n = 0; n < pTOXTypes->Count(); ++n, ++ppTTypes )
652 if( eTyp == (*ppTTypes)->GetType() )
653 ++nCnt;
654 return nCnt;
656 /*--------------------------------------------------------------------
658 --------------------------------------------------------------------*/
659 const SwTOXType* SwDoc::GetTOXType( TOXTypes eTyp, USHORT nId ) const
661 const SwTOXTypePtr * ppTTypes = pTOXTypes->GetData();
662 USHORT nCnt = 0;
663 for( USHORT n = 0; n < pTOXTypes->Count(); ++n, ++ppTTypes )
664 if( eTyp == (*ppTTypes)->GetType() && nCnt++ == nId )
665 return (*ppTTypes);
666 return 0;
669 /*--------------------------------------------------------------------
671 --------------------------------------------------------------------*/
672 const SwTOXType* SwDoc::InsertTOXType( const SwTOXType& rTyp )
674 SwTOXType * pNew = new SwTOXType( rTyp );
675 pTOXTypes->Insert( pNew, pTOXTypes->Count() );
676 return pNew;
678 /*--------------------------------------------------------------------
680 --------------------------------------------------------------------*/
681 String SwDoc::GetUniqueTOXBaseName( const SwTOXType& rType,
682 const String* pChkStr ) const
684 USHORT n;
685 const SwSectionNode* pSectNd;
686 const SwSection* pSect;
688 if(pChkStr && !pChkStr->Len())
689 pChkStr = 0;
690 String aName( rType.GetTypeName() );
691 xub_StrLen nNmLen = aName.Len();
693 USHORT nNum = 0;
694 USHORT nTmp = 0;
695 USHORT nFlagSize = ( pSectionFmtTbl->Count() / 8 ) +2;
696 BYTE* pSetFlags = new BYTE[ nFlagSize ];
697 memset( pSetFlags, 0, nFlagSize );
699 for( n = 0; n < pSectionFmtTbl->Count(); ++n )
700 if( 0 != ( pSectNd = (*pSectionFmtTbl)[ n ]->GetSectionNode( FALSE ) )&&
701 TOX_CONTENT_SECTION == (pSect = &pSectNd->GetSection())->GetType())
703 const String& rNm = pSect->GetName();
704 if( rNm.Match( aName ) == nNmLen )
706 // Nummer bestimmen und das Flag setzen
707 nNum = (USHORT)rNm.Copy( nNmLen ).ToInt32();
708 if( nNum-- && nNum < pSectionFmtTbl->Count() )
709 pSetFlags[ nNum / 8 ] |= (0x01 << ( nNum & 0x07 ));
711 if( pChkStr && pChkStr->Equals( rNm ) )
712 pChkStr = 0;
715 if( !pChkStr )
717 // alle Nummern entsprechend geflag, also bestimme die richtige Nummer
718 nNum = pSectionFmtTbl->Count();
719 for( n = 0; n < nFlagSize; ++n )
720 if( 0xff != ( nTmp = pSetFlags[ n ] ))
722 // also die Nummer bestimmen
723 nNum = n * 8;
724 while( nTmp & 1 )
725 ++nNum, nTmp >>= 1;
726 break;
729 delete [] pSetFlags;
730 if( pChkStr )
731 return *pChkStr;
732 return aName += String::CreateFromInt32( ++nNum );
735 /*--------------------------------------------------------------------
737 --------------------------------------------------------------------*/
738 BOOL SwDoc::SetTOXBaseName(const SwTOXBase& rTOXBase, const String& rName)
740 ASSERT( rTOXBase.ISA( SwTOXBaseSection ),
741 "keine TOXBaseSection!" );
742 SwTOXBaseSection* pTOX = (SwTOXBaseSection*)&rTOXBase;
744 String sTmp = GetUniqueTOXBaseName(*rTOXBase.GetTOXType(), &rName);
745 BOOL bRet = sTmp == rName;
746 if(bRet)
748 pTOX->SetTOXName(rName);
749 pTOX->SwTOXBaseSection::SetName(rName);
750 SetModified();
752 return bRet;
755 /* \f */
757 const SwTxtNode* lcl_FindChapterNode( const SwNode& rNd, BYTE nLvl = 0 )
759 const SwNode* pNd = &rNd;
760 if( pNd->GetNodes().GetEndOfExtras().GetIndex() > pNd->GetIndex() )
762 // then find the "Anchor" (Body) position
763 Point aPt;
764 SwNode2Layout aNode2Layout( *pNd, pNd->GetIndex() );
765 const SwFrm* pFrm = aNode2Layout.GetFrm( &aPt, 0, FALSE );
767 if( pFrm )
769 SwPosition aPos( *pNd );
770 pNd = GetBodyTxtNode( *pNd->GetDoc(), aPos, *pFrm );
771 ASSERT( pNd, "wo steht der Absatz" );
774 return pNd ? pNd->FindOutlineNodeOfLevel( nLvl ) : 0;
778 /*--------------------------------------------------------------------
779 Beschreibung: Verzeichnis-Klasse
780 --------------------------------------------------------------------*/
782 SwTOXBaseSection::SwTOXBaseSection( const SwTOXBase& rBase )
783 : SwTOXBase( rBase ), SwSection( TOX_CONTENT_SECTION, aEmptyStr )
785 SetProtect( rBase.IsProtected() );
786 SwSection::SetName( GetTOXName() );
790 SwTOXBaseSection::~SwTOXBaseSection()
795 BOOL SwTOXBaseSection::SetPosAtStartEnd( SwPosition& rPos, BOOL bAtStart ) const
797 BOOL bRet = FALSE;
798 const SwSectionNode* pSectNd = GetFmt()->GetSectionNode();
799 if( pSectNd )
801 SwCntntNode* pCNd;
802 xub_StrLen nC = 0;
803 if( bAtStart )
805 rPos.nNode = *pSectNd;
806 pCNd = pSectNd->GetDoc()->GetNodes().GoNext( &rPos.nNode );
808 else
810 rPos.nNode = *pSectNd->EndOfSectionNode();
811 pCNd = pSectNd->GetDoc()->GetNodes().GoPrevious( &rPos.nNode );
812 if( pCNd ) nC = pCNd->Len();
814 rPos.nContent.Assign( pCNd, nC );
815 bRet = TRUE;
817 return bRet;
820 /*--------------------------------------------------------------------
821 Beschreibung: Verzeichnisinhalt zusammensammeln
822 --------------------------------------------------------------------*/
824 void SwTOXBaseSection::Update(const SfxItemSet* pAttr,
825 const bool _bNewTOX )
827 const SwSectionNode* pSectNd;
828 if( !SwTOXBase::GetRegisteredIn()->GetDepends() ||
829 !GetFmt() || 0 == (pSectNd = GetFmt()->GetSectionNode() ) ||
830 !pSectNd->GetNodes().IsDocNodes() ||
831 IsHiddenFlag() )
832 return;
834 SwDoc* pDoc = (SwDoc*)pSectNd->GetDoc();
836 DBG_ASSERT(pDoc != NULL, "Where is the document?");
838 if(pAttr && pDoc && GetFmt())
839 pDoc->ChgFmt(*GetFmt(), *pAttr);
841 // OD 18.03.2003 #106329# - determine default page description, which
842 // will be used by the content nodes, if no approriate one is found.
843 const SwPageDesc* pDefaultPageDesc;
845 pDefaultPageDesc =
846 pSectNd->GetSection().GetFmt()->GetPageDesc().GetPageDesc();
847 if ( !_bNewTOX && !pDefaultPageDesc )
849 // determine page description of table-of-content
850 sal_uInt32 nPgDescNdIdx = pSectNd->GetIndex() + 1;
851 sal_uInt32* pPgDescNdIdx = &nPgDescNdIdx;
852 pDefaultPageDesc = pSectNd->FindPageDesc( FALSE, pPgDescNdIdx );
853 if ( nPgDescNdIdx < pSectNd->GetIndex() )
855 pDefaultPageDesc = 0;
858 // OD 28.04.2003 #109166# - consider end node of content section in the
859 // node array.
860 if ( !pDefaultPageDesc &&
861 ( pSectNd->EndOfSectionNode()->GetIndex() <
862 (pSectNd->GetNodes().GetEndOfContent().GetIndex() - 1) )
865 // determine page description of content after table-of-content
866 SwNodeIndex aIdx( *(pSectNd->EndOfSectionNode()) );
867 const SwCntntNode* pNdAfterTOX = pSectNd->GetNodes().GoNext( &aIdx );
868 const SwAttrSet& aNdAttrSet = pNdAfterTOX->GetSwAttrSet();
869 const SvxBreak eBreak = aNdAttrSet.GetBreak().GetBreak();
870 if ( !( eBreak == SVX_BREAK_PAGE_BEFORE ||
871 eBreak == SVX_BREAK_PAGE_BOTH )
874 pDefaultPageDesc = pNdAfterTOX->FindPageDesc( FALSE );
877 // OD 28.04.2003 #109166# - consider start node of content section in
878 // the node array.
879 if ( !pDefaultPageDesc &&
880 ( pSectNd->GetIndex() >
881 (pSectNd->GetNodes().GetEndOfContent().StartOfSectionIndex() + 1) )
884 // determine page description of content before table-of-content
885 SwNodeIndex aIdx( *pSectNd );
886 pDefaultPageDesc =
887 pSectNd->GetNodes().GoPrevious( &aIdx )->FindPageDesc( FALSE );
890 if ( !pDefaultPageDesc )
892 // determine default page description
893 pDefaultPageDesc =
894 &const_cast<const SwDoc *>(pDoc)->GetPageDesc( 0 );
898 pDoc->SetModified();
900 // get current Language
901 SwTOXInternational aIntl( GetLanguage(),
902 TOX_INDEX == GetTOXType()->GetType() ?
903 GetOptions() : 0,
904 GetSortAlgorithm() );
906 aSortArr.DeleteAndDestroy( 0, aSortArr.Count() );
908 // find the first layout node for this TOX, if it only find the content
909 // in his own chapter
910 const SwTxtNode* pOwnChapterNode = IsFromChapter()
911 ? ::lcl_FindChapterNode( *pSectNd, 0 )
912 : 0;
914 SwNode2Layout aN2L( *pSectNd );
915 ((SwSectionNode*)pSectNd)->DelFrms();
917 // remove old content an insert one empty textnode (to hold the layout!)
918 SwTxtNode* pFirstEmptyNd;
920 pDoc->DeleteRedline( *pSectNd, true, USHRT_MAX );
922 SwNodeIndex aSttIdx( *pSectNd, +1 );
923 SwNodeIndex aEndIdx( *pSectNd->EndOfSectionNode() );
924 pFirstEmptyNd = pDoc->GetNodes().MakeTxtNode( aEndIdx,
925 pDoc->GetTxtCollFromPool( RES_POOLCOLL_TEXT ) );
928 // Task 70995 - save and restore PageDesc and Break Attributes
929 SwNodeIndex aNxtIdx( aSttIdx );
930 const SwCntntNode* pCNd = aNxtIdx.GetNode().GetCntntNode();
931 if( !pCNd )
932 pCNd = pDoc->GetNodes().GoNext( &aNxtIdx );
933 if( pCNd->HasSwAttrSet() )
935 SfxItemSet aBrkSet( pDoc->GetAttrPool(), aBreakSetRange );
936 aBrkSet.Put( *pCNd->GetpSwAttrSet() );
937 if( aBrkSet.Count() )
938 pFirstEmptyNd->SetAttr( aBrkSet );
941 aEndIdx--;
942 SwPosition aPos( aEndIdx, SwIndex( pFirstEmptyNd, 0 ));
943 pDoc->CorrAbs( aSttIdx, aEndIdx, aPos, TRUE );
945 // delete all before
946 DelFlyInRange( aSttIdx, aEndIdx );
947 _DelBookmarks( aSttIdx, aEndIdx );
949 pDoc->GetNodes().Delete( aSttIdx, aEndIdx.GetIndex() - aSttIdx.GetIndex() );
954 // insert title of TOX
955 if( GetTitle().Len() )
957 // then insert the headline section
958 SwNodeIndex aIdx( *pSectNd, +1 );
960 SwTxtNode* pHeadNd = pDoc->GetNodes().MakeTxtNode( aIdx,
961 GetTxtFmtColl( FORM_TITLE ) );
962 pHeadNd->InsertText( GetTitle(), SwIndex( pHeadNd ) );
964 String sNm( GetTOXName() );
965 // ??Resource
966 sNm.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "_Head" ));
968 SwSection aSect( TOX_HEADER_SECTION, sNm );
970 SwNodeIndex aStt( *pHeadNd ); aIdx--;
971 SwSectionFmt* pSectFmt = pDoc->MakeSectionFmt( 0 );
972 pDoc->GetNodes().InsertSection( aStt, *pSectFmt, aSect, &aIdx,
973 TRUE, FALSE );
976 // jetzt waere ein prima Zeitpunkt, um die Numerierung zu updaten
977 pDoc->UpdateNumRule();
979 if( GetCreateType() & nsSwTOXElement::TOX_MARK )
980 UpdateMarks( aIntl, pOwnChapterNode );
982 if( GetCreateType() & nsSwTOXElement::TOX_OUTLINELEVEL )
983 UpdateOutline( pOwnChapterNode );
985 if( GetCreateType() & nsSwTOXElement::TOX_TEMPLATE )
986 UpdateTemplate( pOwnChapterNode );
988 if( GetCreateType() & nsSwTOXElement::TOX_OLE ||
989 TOX_OBJECTS == SwTOXBase::GetType())
990 UpdateCntnt( nsSwTOXElement::TOX_OLE, pOwnChapterNode );
992 if( GetCreateType() & nsSwTOXElement::TOX_TABLE ||
993 (TOX_TABLES == SwTOXBase::GetType() && IsFromObjectNames()) )
994 UpdateTable( pOwnChapterNode );
996 if( GetCreateType() & nsSwTOXElement::TOX_GRAPHIC ||
997 (TOX_ILLUSTRATIONS == SwTOXBase::GetType() && IsFromObjectNames()))
998 UpdateCntnt( nsSwTOXElement::TOX_GRAPHIC, pOwnChapterNode );
1000 if( GetSequenceName().Len() && !IsFromObjectNames() &&
1001 (TOX_TABLES == SwTOXBase::GetType() ||
1002 TOX_ILLUSTRATIONS == SwTOXBase::GetType() ) )
1003 UpdateSequence( pOwnChapterNode );
1005 if( GetCreateType() & nsSwTOXElement::TOX_FRAME )
1006 UpdateCntnt( nsSwTOXElement::TOX_FRAME, pOwnChapterNode );
1008 if(TOX_AUTHORITIES == SwTOXBase::GetType())
1009 UpdateAuthorities( aIntl );
1011 // Bei Bedarf Alphadelimitter einfuegen (nur bei Stichwoertern)
1013 if( TOX_INDEX == SwTOXBase::GetType() &&
1014 ( GetOptions() & nsSwTOIOptions::TOI_ALPHA_DELIMITTER ) )
1015 InsertAlphaDelimitter( aIntl );
1017 // sortierte Liste aller Verzeichnismarken und Verzeichnisbereiche
1018 void* p = 0;
1019 String* pStr = 0;
1020 USHORT nCnt = 0, nFormMax = GetTOXForm().GetFormMax();
1021 SvStringsDtor aStrArr( (BYTE)nFormMax );
1022 SvPtrarr aCollArr( (BYTE)nFormMax );
1023 for( ; nCnt < nFormMax; ++nCnt )
1025 aCollArr.Insert( p, nCnt );
1026 aStrArr.Insert( pStr, nCnt );
1029 SwNodeIndex aInsPos( *pFirstEmptyNd, 1 );
1030 for( nCnt = 0; nCnt < aSortArr.Count(); ++nCnt )
1032 ::SetProgressState( 0, pDoc->GetDocShell() );
1034 // setze den Text in das Verzeichniss
1035 USHORT nLvl = aSortArr[ nCnt ]->GetLevel();
1036 SwTxtFmtColl* pColl = (SwTxtFmtColl*)aCollArr[ nLvl ];
1037 if( !pColl )
1039 pColl = GetTxtFmtColl( nLvl );
1040 aCollArr.Remove( nLvl );
1041 p = pColl;
1042 aCollArr.Insert( p , nLvl );
1045 // Generierung: dynamische TabStops setzen
1046 SwTxtNode* pTOXNd = pDoc->GetNodes().MakeTxtNode( aInsPos , pColl );
1047 aSortArr[ nCnt ]->pTOXNd = pTOXNd;
1049 // Generierung: Form auswerten und Platzhalter
1050 // fuer die Seitennummer eintragen
1051 //if it is a TOX_INDEX and the SwForm IsCommaSeparated()
1052 // then a range of entries must be generated into one paragraph
1053 USHORT nRange = 1;
1054 if(TOX_INDEX == SwTOXBase::GetType() &&
1055 GetTOXForm().IsCommaSeparated() &&
1056 aSortArr[nCnt]->GetType() == TOX_SORT_INDEX)
1058 const SwTOXMark& rMark = aSortArr[nCnt]->pTxtMark->GetTOXMark();
1059 const String sPrimKey = rMark.GetPrimaryKey();
1060 const String sSecKey = rMark.GetSecondaryKey();
1061 const SwTOXMark* pNextMark = 0;
1062 while(aSortArr.Count() > (nCnt + nRange)&&
1063 aSortArr[nCnt + nRange]->GetType() == TOX_SORT_INDEX &&
1064 0 != (pNextMark = &(aSortArr[nCnt + nRange]->pTxtMark->GetTOXMark())) &&
1065 pNextMark->GetPrimaryKey() == sPrimKey &&
1066 pNextMark->GetSecondaryKey() == sSecKey)
1067 nRange++;
1069 // OD 18.03.2003 #106329# - pass node index of table-of-content section
1070 // and default page description to method <GenerateText(..)>.
1071 GenerateText( nCnt, nRange, aStrArr, pSectNd->GetIndex(), pDefaultPageDesc );
1072 nCnt += nRange - 1;
1075 // delete the first dummy node and remove all Cursor into the prev node
1076 aInsPos = *pFirstEmptyNd;
1078 SwPaM aCorPam( *pFirstEmptyNd );
1079 aCorPam.GetPoint()->nContent.Assign( pFirstEmptyNd, 0 );
1080 if( !aCorPam.Move( fnMoveForward ) )
1081 aCorPam.Move( fnMoveBackward );
1082 SwNodeIndex aEndIdx( aInsPos, 1 );
1083 pDoc->CorrAbs( aInsPos, aEndIdx, *aCorPam.GetPoint(), TRUE );
1085 // Task 70995 - save and restore PageDesc and Break Attributes
1086 if( pFirstEmptyNd->HasSwAttrSet() )
1088 if( GetTitle().Len() )
1089 aEndIdx = *pSectNd;
1090 else
1091 aEndIdx = *pFirstEmptyNd;
1092 SwCntntNode* pCNd = pDoc->GetNodes().GoNext( &aEndIdx );
1093 if( pCNd ) // Robust against defect documents, e.g. i60336
1094 pCNd->SetAttr( *pFirstEmptyNd->GetpSwAttrSet() );
1098 // now create the new Frames
1099 ULONG nIdx = pSectNd->GetIndex();
1100 // don't delete if index is empty
1101 if(nIdx + 2 < pSectNd->EndOfSectionIndex())
1102 pDoc->GetNodes().Delete( aInsPos, 1 );
1104 aN2L.RestoreUpperFrms( pDoc->GetNodes(), nIdx, nIdx + 1 );
1105 if(pDoc->GetRootFrm())
1106 SwFrm::CheckPageDescs( (SwPageFrm*)pDoc->GetRootFrm()->Lower() );
1108 SetProtect( SwTOXBase::IsProtected() );
1111 /*--------------------------------------------------------------------
1112 Beschreibung: AlphaDelimitter einfuegen
1113 --------------------------------------------------------------------*/
1116 void SwTOXBaseSection::InsertAlphaDelimitter( const SwTOXInternational& rIntl )
1118 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
1119 String sDeli, sLastDeli;
1120 USHORT i = 0;
1121 while( i < aSortArr.Count() )
1123 ::SetProgressState( 0, pDoc->GetDocShell() );
1125 USHORT nLevel = aSortArr[i]->GetLevel();
1127 // Alpha-Delimitter ueberlesen
1128 if( nLevel == FORM_ALPHA_DELIMITTER )
1129 continue;
1131 String sMyString, sMyStringReading;
1132 aSortArr[i]->GetTxt( sMyString, sMyStringReading );
1134 sDeli = rIntl.GetIndexKey( sMyString, sMyStringReading,
1135 aSortArr[i]->GetLocale() );
1137 // Delimitter schon vorhanden ??
1138 if( sDeli.Len() && sLastDeli != sDeli )
1140 // alle kleiner Blank wollen wir nicht haben -> sind Sonderzeichen
1141 if( ' ' <= sDeli.GetChar( 0 ) )
1143 SwTOXCustom* pCst = new SwTOXCustom( sDeli, aEmptyStr, FORM_ALPHA_DELIMITTER,
1144 rIntl, aSortArr[i]->GetLocale() );
1145 aSortArr.Insert( pCst, i++ );
1147 sLastDeli = sDeli;
1150 // Skippen bis gleibhes oder kleineres Level erreicht ist
1151 do {
1152 i++;
1153 } while (i < aSortArr.Count() && aSortArr[i]->GetLevel() > nLevel);
1157 /*--------------------------------------------------------------------
1158 Beschreibung: Template auswerten
1159 --------------------------------------------------------------------*/
1161 SwTxtFmtColl* SwTOXBaseSection::GetTxtFmtColl( USHORT nLevel )
1163 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
1164 const String& rName = GetTOXForm().GetTemplate( nLevel );
1165 SwTxtFmtColl* pColl = rName.Len() ? pDoc->FindTxtFmtCollByName(rName) :0;
1166 if( !pColl )
1168 USHORT nPoolFmt = 0;
1169 const TOXTypes eMyType = SwTOXBase::GetType();
1170 switch( eMyType )
1172 case TOX_INDEX: nPoolFmt = RES_POOLCOLL_TOX_IDXH; break;
1173 case TOX_USER:
1174 if( nLevel < 6 )
1175 nPoolFmt = RES_POOLCOLL_TOX_USERH;
1176 else
1177 nPoolFmt = RES_POOLCOLL_TOX_USER6 - 6;
1178 break;
1179 case TOX_ILLUSTRATIONS: nPoolFmt = RES_POOLCOLL_TOX_ILLUSH; break;
1180 case TOX_OBJECTS: nPoolFmt = RES_POOLCOLL_TOX_OBJECTH; break;
1181 case TOX_TABLES: nPoolFmt = RES_POOLCOLL_TOX_TABLESH; break;
1182 case TOX_AUTHORITIES: nPoolFmt = RES_POOLCOLL_TOX_AUTHORITIESH; break;
1184 case TOX_CONTENT:
1185 // im Content Bereich gibt es einen Sprung!
1186 if( nLevel < 6 )
1187 nPoolFmt = RES_POOLCOLL_TOX_CNTNTH;
1188 else
1189 nPoolFmt = RES_POOLCOLL_TOX_CNTNT6 - 6;
1190 break;
1193 if(eMyType == TOX_AUTHORITIES && nLevel)
1194 nPoolFmt = nPoolFmt + 1;
1195 else if(eMyType == TOX_INDEX && nLevel)
1197 //pool: Level 1,2,3, Delimiter
1198 //SwForm: Delimiter, Level 1,2,3
1199 nPoolFmt += 1 == nLevel ? nLevel + 3 : nLevel - 1;
1201 else
1202 nPoolFmt = nPoolFmt + nLevel;
1203 pColl = pDoc->GetTxtCollFromPool( nPoolFmt );
1205 return pColl;
1209 /*--------------------------------------------------------------------
1210 Beschreibung: Aus Markierungen erzeugen
1211 --------------------------------------------------------------------*/
1213 void SwTOXBaseSection::UpdateMarks( const SwTOXInternational& rIntl,
1214 const SwTxtNode* pOwnChapterNode )
1216 const SwModify* pType = SwTOXBase::GetRegisteredIn();
1217 if( !pType->GetDepends() )
1218 return;
1220 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
1221 TOXTypes eTOXTyp = GetTOXType()->GetType();
1222 SwClientIter aIter( *(SwModify*)pType );
1224 SwTxtTOXMark* pTxtMark;
1225 SwTOXMark* pMark;
1226 for( pMark = (SwTOXMark*)aIter.First( TYPE( SwTOXMark )); pMark;
1227 pMark = (SwTOXMark*)aIter.Next() )
1229 ::SetProgressState( 0, pDoc->GetDocShell() );
1231 if( pMark->GetTOXType()->GetType() == eTOXTyp &&
1232 0 != ( pTxtMark = pMark->GetTxtTOXMark() ) )
1234 const SwTxtNode* pTOXSrc = pTxtMark->GetpTxtNd();
1235 // nur TOXMarks einfuegen die im Doc stehen
1236 // nicht die, die im UNDO stehen
1238 // if selected use marks from the same chapter only
1239 if( pTOXSrc->GetNodes().IsDocNodes() &&
1240 pTOXSrc->GetTxt().Len() && pTOXSrc->GetDepends() &&
1241 pTOXSrc->GetFrm() &&
1242 (!IsFromChapter() || ::lcl_FindChapterNode( *pTOXSrc, 0 ) == pOwnChapterNode ) &&
1243 !pTOXSrc->HasHiddenParaField() &&
1244 !SwScriptInfo::IsInHiddenRange( *pTOXSrc, *pTxtMark->GetStart() ) )
1246 SwTOXSortTabBase* pBase = 0;
1247 if(TOX_INDEX == eTOXTyp)
1249 // Stichwortverzeichnismarkierung
1250 lang::Locale aLocale;
1251 if ( pBreakIt->GetBreakIter().is() )
1253 aLocale = pBreakIt->GetLocale(
1254 pTOXSrc->GetLang( *pTxtMark->GetStart() ) );
1257 pBase = new SwTOXIndex( *pTOXSrc, pTxtMark,
1258 GetOptions(), FORM_ENTRY, rIntl, aLocale );
1259 InsertSorted(pBase);
1260 if(GetOptions() & nsSwTOIOptions::TOI_KEY_AS_ENTRY &&
1261 pTxtMark->GetTOXMark().GetPrimaryKey().Len())
1263 pBase = new SwTOXIndex( *pTOXSrc, pTxtMark,
1264 GetOptions(), FORM_PRIMARY_KEY, rIntl, aLocale );
1265 InsertSorted(pBase);
1266 if(pTxtMark->GetTOXMark().GetSecondaryKey().Len())
1268 pBase = new SwTOXIndex( *pTOXSrc, pTxtMark,
1269 GetOptions(), FORM_SECONDARY_KEY, rIntl, aLocale );
1270 InsertSorted(pBase);
1274 else if( TOX_USER == eTOXTyp ||
1275 pMark->GetLevel() <= GetLevel())
1276 { // Inhaltsberzeichnismarkierung
1277 // also used for user marks
1278 pBase = new SwTOXContent( *pTOXSrc, pTxtMark, rIntl );
1279 InsertSorted(pBase);
1287 /*--------------------------------------------------------------------
1288 Beschreibung: Verzeichnisinhalt aus Gliederungsebene generieren
1289 --------------------------------------------------------------------*/
1292 void SwTOXBaseSection::UpdateOutline( const SwTxtNode* pOwnChapterNode )
1294 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
1295 SwNodes& rNds = pDoc->GetNodes();
1297 const SwOutlineNodes& rOutlNds = rNds.GetOutLineNds();
1298 for( USHORT n = 0; n < rOutlNds.Count(); ++n )
1300 ::SetProgressState( 0, pDoc->GetDocShell() );
1301 SwTxtNode* pTxtNd = rOutlNds[ n ]->GetTxtNode();
1302 if( pTxtNd && pTxtNd->Len() && pTxtNd->GetDepends() &&
1303 //USHORT(pTxtNd->GetTxtColl()->GetOutlineLevel()+1) <= GetLevel() && //#outline level,zhaojianwei
1304 USHORT( pTxtNd->GetAttrOutlineLevel()) <= GetLevel() && //<-end,zhaojianwei
1305 pTxtNd->GetFrm() &&
1306 !pTxtNd->HasHiddenParaField() &&
1307 !pTxtNd->HasHiddenCharAttribute( true ) &&
1308 ( !IsFromChapter() ||
1309 ::lcl_FindChapterNode( *pTxtNd, 0 ) == pOwnChapterNode ))
1311 SwTOXPara * pNew = new SwTOXPara( *pTxtNd, nsSwTOXElement::TOX_OUTLINELEVEL );
1312 InsertSorted( pNew );
1317 /*--------------------------------------------------------------------
1318 Beschreibung: Verzeichnisinhalt aus Vorlagenbereichen generieren
1319 --------------------------------------------------------------------*/
1321 void SwTOXBaseSection::UpdateTemplate( const SwTxtNode* pOwnChapterNode )
1323 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
1324 for(USHORT i = 0; i < MAXLEVEL; i++)
1326 String sTmpStyleNames = GetStyleNames(i);
1327 USHORT nTokenCount = sTmpStyleNames.GetTokenCount(TOX_STYLE_DELIMITER);
1328 for( USHORT nStyle = 0; nStyle < nTokenCount; ++nStyle )
1330 SwTxtFmtColl* pColl = pDoc->FindTxtFmtCollByName(
1331 sTmpStyleNames.GetToken( nStyle,
1332 TOX_STYLE_DELIMITER ));
1333 //TODO: no outline Collections in content indexes if OutlineLevels are already included
1334 if( !pColl ||
1335 ( TOX_CONTENT == SwTOXBase::GetType() &&
1336 GetCreateType() & nsSwTOXElement::TOX_OUTLINELEVEL &&
1337 //NO_NUMBERING != pColl->GetOutlineLevel() ) )//#outline level,zhaojianwei
1338 pColl->IsAssignedToListLevelOfOutlineStyle()) )//<-end,zhaojianwei
1339 continue;
1341 SwClientIter aIter( *pColl );
1342 SwTxtNode* pTxtNd = (SwTxtNode*)aIter.First( TYPE( SwTxtNode ));
1343 for( ; pTxtNd; pTxtNd = (SwTxtNode*)aIter.Next() )
1345 ::SetProgressState( 0, pDoc->GetDocShell() );
1347 if( pTxtNd->GetTxt().Len() && pTxtNd->GetFrm() &&
1348 pTxtNd->GetNodes().IsDocNodes() &&
1349 ( !IsFromChapter() || pOwnChapterNode ==
1350 ::lcl_FindChapterNode( *pTxtNd, 0 ) ) )
1352 SwTOXPara * pNew = new SwTOXPara( *pTxtNd, nsSwTOXElement::TOX_TEMPLATE, i + 1 );
1353 InsertSorted(pNew);
1360 /* -----------------14.07.99 09:59-------------------
1361 Description: generate content from sequence fields
1362 --------------------------------------------------*/
1363 void SwTOXBaseSection::UpdateSequence( const SwTxtNode* pOwnChapterNode )
1365 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
1366 SwFieldType* pSeqFld = pDoc->GetFldType(RES_SETEXPFLD, GetSequenceName(), false);
1367 if(!pSeqFld)
1368 return;
1370 SwClientIter aIter( *pSeqFld );
1371 SwFmtFld* pFmtFld = (SwFmtFld*)aIter.First( TYPE( SwFmtFld ));
1372 for( ; pFmtFld; pFmtFld = (SwFmtFld*)aIter.Next() )
1374 const SwTxtFld* pTxtFld = pFmtFld->GetTxtFld();
1375 if(!pTxtFld)
1376 continue;
1377 const SwTxtNode& rTxtNode = pTxtFld->GetTxtNode();
1378 ::SetProgressState( 0, pDoc->GetDocShell() );
1380 if( rTxtNode.GetTxt().Len() && rTxtNode.GetFrm() &&
1381 rTxtNode.GetNodes().IsDocNodes() &&
1382 ( !IsFromChapter() ||
1383 ::lcl_FindChapterNode( rTxtNode, 0 ) == pOwnChapterNode ) )
1385 SwTOXPara * pNew = new SwTOXPara( rTxtNode, nsSwTOXElement::TOX_SEQUENCE, 1 );
1386 //set indexes if the number or the reference text are to be displayed
1387 if( GetCaptionDisplay() == CAPTION_TEXT )
1389 pNew->SetStartIndex(
1390 SwGetExpField::GetReferenceTextPos( *pFmtFld, *pDoc ));
1392 else if(GetCaptionDisplay() == CAPTION_NUMBER)
1394 pNew->SetEndIndex(*pTxtFld->GetStart() + 1);
1396 InsertSorted(pNew);
1400 /* -----------------15.09.99 14:18-------------------
1402 --------------------------------------------------*/
1403 void SwTOXBaseSection::UpdateAuthorities( const SwTOXInternational& rIntl )
1405 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
1406 SwFieldType* pAuthFld = pDoc->GetFldType(RES_AUTHORITY, aEmptyStr, false);
1407 if(!pAuthFld)
1408 return;
1410 SwClientIter aIter( *pAuthFld );
1411 SwFmtFld* pFmtFld = (SwFmtFld*)aIter.First( TYPE( SwFmtFld ));
1412 for( ; pFmtFld; pFmtFld = (SwFmtFld*)aIter.Next() )
1414 const SwTxtFld* pTxtFld = pFmtFld->GetTxtFld();
1415 //undo
1416 if(!pTxtFld)
1417 continue;
1418 const SwTxtNode& rTxtNode = pTxtFld->GetTxtNode();
1419 ::SetProgressState( 0, pDoc->GetDocShell() );
1421 // const SwTxtNode* pChapterCompareNode = 0;
1423 if( rTxtNode.GetTxt().Len() && rTxtNode.GetFrm() &&
1424 rTxtNode.GetNodes().IsDocNodes() /*&&
1425 (!IsFromChapter() || pChapterCompareNode == pOwnChapterNode) */)
1427 //#106485# the body node has to be used!
1428 SwCntntFrm *pFrm = rTxtNode.GetFrm();
1429 SwPosition aFldPos(rTxtNode);
1430 const SwTxtNode* pTxtNode = 0;
1431 if(pFrm && !pFrm->IsInDocBody())
1432 pTxtNode = GetBodyTxtNode( *pDoc, aFldPos, *pFrm );
1433 if(!pTxtNode)
1434 pTxtNode = &rTxtNode;
1435 SwTOXAuthority* pNew = new SwTOXAuthority( *pTxtNode, *pFmtFld, rIntl );
1437 InsertSorted(pNew);
1442 long lcl_IsSOObject( const SvGlobalName& rFactoryNm )
1444 static struct _SoObjType {
1445 long nFlag;
1446 // GlobalNameId
1447 struct _GlobalNameIds {
1448 UINT32 n1;
1449 USHORT n2, n3;
1450 BYTE b8, b9, b10, b11, b12, b13, b14, b15;
1451 } aGlNmIds[4];
1452 } aArr[] = {
1453 { nsSwTOOElements::TOO_MATH,
1454 { {SO3_SM_CLASSID_60},{SO3_SM_CLASSID_50},
1455 {SO3_SM_CLASSID_40},{SO3_SM_CLASSID_30} } },
1456 { nsSwTOOElements::TOO_CHART,
1457 { {SO3_SCH_CLASSID_60},{SO3_SCH_CLASSID_50},
1458 {SO3_SCH_CLASSID_40},{SO3_SCH_CLASSID_30} } },
1459 { nsSwTOOElements::TOO_CALC,
1460 { {SO3_SC_CLASSID_60},{SO3_SC_CLASSID_50},
1461 {SO3_SC_CLASSID_40},{SO3_SC_CLASSID_30} } },
1462 { nsSwTOOElements::TOO_DRAW_IMPRESS,
1463 { {SO3_SIMPRESS_CLASSID_60},{SO3_SIMPRESS_CLASSID_50},
1464 {SO3_SIMPRESS_CLASSID_40},{SO3_SIMPRESS_CLASSID_30} } },
1465 { nsSwTOOElements::TOO_DRAW_IMPRESS,
1466 { {SO3_SDRAW_CLASSID_60},{SO3_SDRAW_CLASSID_50}}},
1467 { 0,{{0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0},
1468 {0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0} } }
1471 long nRet = 0;
1472 for( const _SoObjType* pArr = aArr; !nRet && pArr->nFlag; ++pArr )
1473 for ( int n = 0; n < 4; ++n )
1475 const _SoObjType::_GlobalNameIds& rId = pArr->aGlNmIds[ n ];
1476 if( !rId.n1 )
1477 break;
1478 SvGlobalName aGlbNm( rId.n1, rId.n2, rId.n3,
1479 rId.b8, rId.b9, rId.b10, rId.b11,
1480 rId.b12, rId.b13, rId.b14, rId.b15 );
1481 if( rFactoryNm == aGlbNm )
1483 nRet = pArr->nFlag;
1484 break;
1488 return nRet;
1491 void SwTOXBaseSection::UpdateCntnt( SwTOXElement eMyType,
1492 const SwTxtNode* pOwnChapterNode )
1494 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
1495 SwNodes& rNds = pDoc->GetNodes();
1496 // auf den 1. Node der 1. Section
1497 ULONG nIdx = rNds.GetEndOfAutotext().StartOfSectionIndex() + 2,
1498 nEndIdx = rNds.GetEndOfAutotext().GetIndex();
1500 while( nIdx < nEndIdx )
1502 ::SetProgressState( 0, pDoc->GetDocShell() );
1504 SwNode* pNd = rNds[ nIdx ];
1505 SwCntntNode* pCNd = 0;
1506 switch( eMyType )
1508 case nsSwTOXElement::TOX_FRAME:
1509 if( !pNd->IsNoTxtNode() )
1511 pCNd = pNd->GetCntntNode();
1512 if( !pCNd )
1514 SwNodeIndex aTmp( *pNd );
1515 pCNd = rNds.GoNext( &aTmp );
1518 break;
1519 case nsSwTOXElement::TOX_GRAPHIC:
1520 if( pNd->IsGrfNode() )
1521 pCNd = (SwCntntNode*)pNd;
1522 break;
1523 case nsSwTOXElement::TOX_OLE:
1524 if( pNd->IsOLENode() )
1526 BOOL bInclude = TRUE;
1527 if(TOX_OBJECTS == SwTOXBase::GetType())
1529 SwOLENode* pOLENode = pNd->GetOLENode();
1530 long nMyOLEOptions = GetOLEOptions();
1531 SwOLEObj& rOLEObj = pOLENode->GetOLEObj();
1533 if( rOLEObj.IsOleRef() ) //Noch nicht geladen
1535 SvGlobalName aTmpName = SvGlobalName( rOLEObj.GetOleRef()->getClassID() );
1536 long nObj = ::lcl_IsSOObject( aTmpName );
1537 bInclude = ( (nMyOLEOptions & nsSwTOOElements::TOO_OTHER) && 0 == nObj)
1538 || (0 != (nMyOLEOptions & nObj));
1540 else
1542 DBG_ERROR("OLE-object nicht geladen?");
1543 bInclude = FALSE;
1547 if(bInclude)
1548 pCNd = (SwCntntNode*)pNd;
1550 break;
1551 default: break;
1554 if( pCNd )
1556 //find node in body text
1557 int nSetLevel = USHRT_MAX;
1559 //#111105# tables of tables|illustrations|objects don't support hierarchies
1560 if( IsLevelFromChapter() &&
1561 TOX_TABLES != SwTOXBase::GetType() &&
1562 TOX_ILLUSTRATIONS != SwTOXBase::GetType() &&
1563 TOX_OBJECTS != SwTOXBase::GetType() )
1565 const SwTxtNode* pOutlNd = ::lcl_FindChapterNode( *pCNd,
1566 MAXLEVEL - 1 );
1567 if( pOutlNd )
1569 //USHORT nTmp = pOutlNd->GetTxtColl()->GetOutlineLevel();//#outline level,zhaojianwei
1570 //if( nTmp < NO_NUMBERING )
1571 // nSetLevel = nTmp + 1;
1572 if( pOutlNd->GetTxtColl()->IsAssignedToListLevelOfOutlineStyle())
1573 nSetLevel = pOutlNd->GetTxtColl()->GetAttrOutlineLevel() ;//<-end,zhaojianwei
1577 if( pCNd->GetFrm() && ( !IsFromChapter() ||
1578 ::lcl_FindChapterNode( *pCNd, 0 ) == pOwnChapterNode ))
1580 SwTOXPara * pNew = new SwTOXPara( *pCNd, eMyType,
1581 ( USHRT_MAX != nSetLevel )
1582 ? static_cast<USHORT>(nSetLevel)
1583 : FORM_ALPHA_DELIMITTER );
1584 InsertSorted( pNew );
1588 nIdx = pNd->StartOfSectionNode()->EndOfSectionIndex() + 2; // 2 == End-/StartNode
1592 /*--------------------------------------------------------------------
1593 Beschreibung: Tabelleneintraege zusammensuchen
1594 --------------------------------------------------------------------*/
1596 void SwTOXBaseSection::UpdateTable( const SwTxtNode* pOwnChapterNode )
1598 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
1599 SwNodes& rNds = pDoc->GetNodes();
1600 const SwFrmFmts& rArr = *pDoc->GetTblFrmFmts();
1602 for( USHORT n = 0; n < rArr.Count(); ++n )
1604 ::SetProgressState( 0, pDoc->GetDocShell() );
1606 SwTable* pTmpTbl = SwTable::FindTable( rArr[ n ] );
1607 SwTableBox* pFBox;
1608 if( pTmpTbl && 0 != (pFBox = pTmpTbl->GetTabSortBoxes()[0] ) &&
1609 pFBox->GetSttNd() && pFBox->GetSttNd()->GetNodes().IsDocNodes() )
1611 const SwTableNode* pTblNd = pFBox->GetSttNd()->FindTableNode();
1612 SwNodeIndex aCntntIdx( *pTblNd, 1 );
1614 SwCntntNode* pCNd;
1615 while( 0 != ( pCNd = rNds.GoNext( &aCntntIdx ) ) &&
1616 aCntntIdx.GetIndex() < pTblNd->EndOfSectionIndex() )
1618 if( pCNd->GetFrm() && (!IsFromChapter() ||
1619 ::lcl_FindChapterNode( *pCNd, 0 ) == pOwnChapterNode ))
1621 SwTOXTable * pNew = new SwTOXTable( *pCNd );
1622 if( IsLevelFromChapter() && TOX_TABLES != SwTOXBase::GetType())
1624 const SwTxtNode* pOutlNd =
1625 ::lcl_FindChapterNode( *pCNd, MAXLEVEL - 1 );
1626 if( pOutlNd )
1628 //USHORT nTmp = pOutlNd->GetTxtColl()->GetOutlineLevel();//#outline level,zhaojianwei
1629 //if( nTmp < NO_NUMBERING )
1630 // pNew->SetLevel( nTmp + 1 );
1631 if( pOutlNd->GetTxtColl()->IsAssignedToListLevelOfOutlineStyle())
1633 const int nTmp = pOutlNd->GetTxtColl()->GetAttrOutlineLevel();
1634 pNew->SetLevel( static_cast<USHORT>(nTmp) );//<-end ,zhaojianwei
1638 InsertSorted(pNew);
1639 break;
1646 /*--------------------------------------------------------------------
1647 Beschreibung: String generieren anhand der Form
1648 SonderZeichen 0-31 und 255 entfernen
1649 --------------------------------------------------------------------*/
1651 String lcl_GetNumString( const SwTOXSortTabBase& rBase, sal_Bool bUsePrefix, BYTE nLevel )
1653 String sRet;
1655 if( !rBase.pTxtMark && rBase.aTOXSources.Count() > 0 )
1656 { // nur wenn es keine Marke ist
1657 const SwTxtNode* pNd = rBase.aTOXSources[0].pNd->GetTxtNode();
1658 if( pNd )
1660 const SwNumRule* pRule = pNd->GetNumRule();
1662 if( pRule && pNd->GetActualListLevel() < MAXLEVEL )
1663 sRet = pNd->GetNumString(bUsePrefix, nLevel);
1666 return sRet;
1669 // OD 18.03.2003 #106329# - add parameter <_TOXSectNdIdx> and <_pDefaultPageDesc>
1670 // in order to control, which page description is used, no appropriate one is found.
1671 void SwTOXBaseSection::GenerateText( USHORT nArrayIdx,
1672 USHORT nCount,
1673 SvStringsDtor& ,
1674 const sal_uInt32 _nTOXSectNdIdx,
1675 const SwPageDesc* _pDefaultPageDesc )
1677 LinkStructArr aLinkArr;
1678 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
1679 ::SetProgressState( 0, pDoc->GetDocShell() );
1681 //pTOXNd is only set at the first mark
1682 SwTxtNode* pTOXNd = (SwTxtNode*)aSortArr[nArrayIdx]->pTOXNd;
1683 String& rTxt = (String&)pTOXNd->GetTxt();
1684 rTxt.Erase();
1685 for(USHORT nIndex = nArrayIdx; nIndex < nArrayIdx + nCount; nIndex++)
1687 if(nIndex > nArrayIdx)
1688 rTxt.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ", " )); // comma separation
1689 // String mit dem Pattern aus der Form initialisieren
1690 const SwTOXSortTabBase& rBase = *aSortArr[nIndex];
1691 USHORT nLvl = rBase.GetLevel();
1692 ASSERT( nLvl < GetTOXForm().GetFormMax(), "ungueltiges FORM_LEVEL");
1694 SvxTabStopItem aTStops( 0, 0, SVX_TAB_ADJUST_DEFAULT, RES_PARATR_TABSTOP );
1695 xub_StrLen nLinkStartPosition = STRING_NOTFOUND;
1696 String sLinkCharacterStyle; //default to "Default" character style - which is none
1697 String sURL;
1698 // create an enumerator
1699 // #i21237#
1700 SwFormTokens aPattern = GetTOXForm().GetPattern(nLvl);
1701 SwFormTokens::iterator aIt = aPattern.begin();
1702 // remove text from node
1703 while(aIt != aPattern.end()) // #i21237#
1705 SwFormToken aToken = *aIt; // #i21237#
1706 xub_StrLen nStartCharStyle = rTxt.Len();
1707 switch( aToken.eTokenType )
1709 case TOKEN_ENTRY_NO:
1710 // fuer Inhaltsverzeichnis Numerierung
1711 rTxt.Insert( lcl_GetNumString( rBase, aToken.nChapterFormat == CF_NUMBER, static_cast<BYTE>(aToken.nOutlineLevel - 1)) );
1712 break;
1714 case TOKEN_ENTRY_TEXT:
1716 SwIndex aIdx( pTOXNd, rTxt.Len() );
1717 rBase.FillText( *pTOXNd, aIdx );
1719 break;
1721 case TOKEN_ENTRY:
1723 // fuer Inhaltsverzeichnis Numerierung
1724 rTxt.Insert( lcl_GetNumString( rBase, sal_True, MAXLEVEL ));
1726 SwIndex aIdx( pTOXNd, rTxt.Len() );
1727 rBase.FillText( *pTOXNd, aIdx );
1729 break;
1731 case TOKEN_TAB_STOP:
1732 if (aToken.bWithTab) // #i21237#
1733 rTxt.Append('\t');
1736 if(SVX_TAB_ADJUST_END > aToken.eTabAlign)
1738 const SvxLRSpaceItem& rLR =
1739 (SvxLRSpaceItem&)pTOXNd->
1740 SwCntntNode::GetAttr( RES_LR_SPACE, TRUE );
1742 long nTabPosition = aToken.nTabStopPosition;
1743 if( !GetTOXForm().IsRelTabPos() && rLR.GetTxtLeft() )
1744 nTabPosition -= rLR.GetTxtLeft();
1745 aTStops.Insert( SvxTabStop( nTabPosition,
1746 aToken.eTabAlign,
1747 cDfltDecimalChar,
1748 aToken.cTabFillChar ));
1750 else
1752 const SwPageDesc* pPageDesc = ((SwFmtPageDesc&)pTOXNd->
1753 SwCntntNode::GetAttr( RES_PAGEDESC )).GetPageDesc();
1755 BOOL bCallFindRect = TRUE;
1756 long nRightMargin;
1757 if( pPageDesc )
1759 const SwFrm* pFrm = pTOXNd->GetFrm( 0, 0, TRUE );
1760 if( !pFrm || 0 == ( pFrm = pFrm->FindPageFrm() ) ||
1761 pPageDesc != ((SwPageFrm*)pFrm)->GetPageDesc() )
1762 // dann muss man ueber den PageDesc gehen
1763 bCallFindRect = FALSE;
1766 SwRect aNdRect;
1767 if( bCallFindRect )
1768 aNdRect = pTOXNd->FindLayoutRect( TRUE );
1770 if( aNdRect.IsEmpty() )
1772 // dann hilft alles nichts, wir muessen ueber die Seiten-
1773 // vorlage gehen.
1774 // OD 18.03.2003 #106329# - call
1775 sal_uInt32 nPgDescNdIdx = pTOXNd->GetIndex() + 1;
1776 sal_uInt32* pPgDescNdIdx = &nPgDescNdIdx;
1777 pPageDesc = pTOXNd->FindPageDesc( FALSE, pPgDescNdIdx );
1778 if ( !pPageDesc ||
1779 *pPgDescNdIdx < _nTOXSectNdIdx )
1781 // use default page description, if none is found
1782 // or the found one is given by a node before the
1783 // table-of-content section.
1784 pPageDesc = _pDefaultPageDesc;
1787 const SwFrmFmt& rPgDscFmt = pPageDesc->GetMaster();
1788 nRightMargin = rPgDscFmt.GetFrmSize().GetWidth() -
1789 rPgDscFmt.GetLRSpace().GetLeft() -
1790 rPgDscFmt.GetLRSpace().GetRight();
1792 else
1793 nRightMargin = aNdRect.Width();
1794 //#i24363# tab stops relative to indent
1795 if( pDoc->get(IDocumentSettingAccess::TABS_RELATIVE_TO_INDENT) )
1797 //left margin of paragraph style
1798 const SvxLRSpaceItem& rLRSpace = pTOXNd->GetTxtColl()->GetLRSpace();
1799 nRightMargin -= rLRSpace.GetLeft();
1800 nRightMargin -= rLRSpace.GetTxtFirstLineOfst();
1803 aTStops.Insert( SvxTabStop( nRightMargin, SVX_TAB_ADJUST_RIGHT,
1804 cDfltDecimalChar,
1805 aToken.cTabFillChar ));
1807 break;
1809 case TOKEN_TEXT:
1810 rTxt.Append( aToken.sText );
1811 break;
1813 case TOKEN_PAGE_NUMS:
1814 // Platzhalter fuer Seitennummer(n) es wird nur der erste beachtet
1817 // Die Anzahl der gleichen Eintrage bestimmt die Seitennummern-Pattern
1819 USHORT nSize = rBase.aTOXSources.Count();
1820 if( nSize > 0 )
1822 String aInsStr( cNumRepl );
1823 for(USHORT i=1; i < nSize; ++i)
1825 aInsStr.AppendAscii( sPageDeli );
1826 aInsStr += cNumRepl;
1828 aInsStr += cEndPageNum;
1829 rTxt.Append( aInsStr );
1831 // // Tab entfernen, wenn keine Seitennummer
1832 // else if( rTxt.Len() && '\t' == rTxt.GetChar( rTxt.Len() - 1 ))
1833 // rTxt.Erase( rTxt.Len()-1, 1 );
1835 break;
1837 case TOKEN_CHAPTER_INFO:
1839 // ein bischen trickreich: suche irgend einen Frame
1840 const SwTOXSource* pTOXSource = 0;
1841 if(rBase.aTOXSources.Count())
1842 pTOXSource = &rBase.aTOXSources[0];
1844 // --> OD 2008-02-14 #i53420#
1845 // if( pTOXSource && pTOXSource->pNd
1846 // pTOXSource->pNd->IsTxtNode() )
1847 if ( pTOXSource && pTOXSource->pNd &&
1848 pTOXSource->pNd->IsCntntNode() )
1849 // <--
1851 const SwCntntFrm* pFrm = pTOXSource->pNd->GetFrm();
1852 if( pFrm )
1854 SwChapterFieldType aFldTyp;
1855 SwChapterField aFld( &aFldTyp, aToken.nChapterFormat );
1856 aFld.SetLevel( static_cast<BYTE>(aToken.nOutlineLevel - 1) );
1857 // --> OD 2008-02-14 #i53420#
1858 // aFld.ChangeExpansion( pFrm, (SwTxtNode*)pTOXSource->pNd, TRUE );
1859 aFld.ChangeExpansion( pFrm,
1860 dynamic_cast<const SwCntntNode*>(pTOXSource->pNd),
1861 TRUE );
1862 // <--
1863 //---> i89791
1864 // OD 2008-06-26 - continue to support CF_NUMBER
1865 // and CF_NUM_TITLE in order to handle ODF 1.0/1.1
1866 // written by OOo 3.x in the same way as OOo 2.x
1867 // would handle them.
1868 if ( CF_NUM_NOPREPST_TITLE == aToken.nChapterFormat ||
1869 CF_NUMBER == aToken.nChapterFormat )
1870 rTxt.Insert(aFld.GetNumber()); //get the string number without pre/postfix
1871 else if ( CF_NUMBER_NOPREPST == aToken.nChapterFormat ||
1872 CF_NUM_TITLE == aToken.nChapterFormat )
1873 //<---
1875 rTxt += aFld.GetNumber();
1876 rTxt += ' ';
1877 rTxt += aFld.GetTitle();
1879 else if(CF_TITLE == aToken.nChapterFormat)
1880 rTxt += aFld.GetTitle();
1884 break;
1886 case TOKEN_LINK_START:
1887 nLinkStartPosition = rTxt.Len();
1888 sLinkCharacterStyle = aToken.sCharStyleName;
1889 break;
1891 case TOKEN_LINK_END:
1892 //TODO: only paired start/end tokens are valid
1893 if( STRING_NOTFOUND != nLinkStartPosition)
1895 SwIndex aIdx( pTOXNd, nLinkStartPosition );
1896 //pTOXNd->Erase( aIdx, SwForm::nFormLinkSttLen );
1897 xub_StrLen nEnd = rTxt.Len();
1899 if( !sURL.Len() )
1901 sURL = rBase.GetURL();
1902 if( !sURL.Len() )
1903 break;
1905 LinkStruct* pNewLink = new LinkStruct(sURL, nLinkStartPosition,
1906 nEnd);
1907 pNewLink->aINetFmt.SetVisitedFmt(sLinkCharacterStyle);
1908 pNewLink->aINetFmt.SetINetFmt(sLinkCharacterStyle);
1909 if(sLinkCharacterStyle.Len())
1911 USHORT nPoolId =
1912 SwStyleNameMapper::GetPoolIdFromUIName( sLinkCharacterStyle, nsSwGetPoolIdFromName::GET_POOLID_CHRFMT );
1913 pNewLink->aINetFmt.SetVisitedFmtId(nPoolId);
1914 pNewLink->aINetFmt.SetINetFmtId(nPoolId);
1916 else
1918 pNewLink->aINetFmt.SetVisitedFmtId(USHRT_MAX);
1919 pNewLink->aINetFmt.SetINetFmtId(USHRT_MAX);
1921 aLinkArr.Insert( pNewLink, aLinkArr.Count() );
1922 nLinkStartPosition = STRING_NOTFOUND;
1923 sLinkCharacterStyle.Erase();
1925 break;
1927 case TOKEN_AUTHORITY:
1929 ToxAuthorityField eField = (ToxAuthorityField)aToken.nAuthorityField;
1930 SwIndex aIdx( pTOXNd, rTxt.Len() );
1931 rBase.FillText( *pTOXNd, aIdx, static_cast<USHORT>(eField) );
1933 break;
1934 case TOKEN_END: break;
1937 if( aToken.sCharStyleName.Len() )
1939 SwCharFmt* pCharFmt;
1940 if( USHRT_MAX != aToken.nPoolId )
1941 pCharFmt = pDoc->GetCharFmtFromPool( aToken.nPoolId );
1942 else
1943 pCharFmt = pDoc->FindCharFmtByName( aToken.sCharStyleName);
1945 if (pCharFmt)
1947 SwFmtCharFmt aFmt( pCharFmt );
1948 pTOXNd->InsertItem( aFmt, nStartCharStyle,
1949 rTxt.Len(), nsSetAttrMode::SETATTR_DONTEXPAND );
1953 aIt++; // #i21237#
1956 pTOXNd->SetAttr( aTStops );
1959 if(aLinkArr.Count())
1960 for(USHORT i = 0; i < aLinkArr.Count(); ++i )
1962 LinkStruct* pTmp = aLinkArr.GetObject(i);
1963 pTOXNd->InsertItem( pTmp->aINetFmt, pTmp->nStartTextPos,
1964 pTmp->nEndTextPos);
1968 /*--------------------------------------------------------------------
1969 Beschreibung: Seitennummer errechnen und nach dem Formatieren
1970 eintragen
1971 --------------------------------------------------------------------*/
1973 void SwTOXBaseSection::UpdatePageNum()
1975 if( !aSortArr.Count() )
1976 return ;
1978 // die aktuellen Seitennummern ins Verzeichnis eintragen
1979 SwPageFrm* pAktPage = 0;
1980 USHORT nPage = 0;
1981 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
1983 SwTOXInternational aIntl( GetLanguage(),
1984 TOX_INDEX == GetTOXType()->GetType() ?
1985 GetOptions() : 0,
1986 GetSortAlgorithm() );
1988 for( USHORT nCnt = 0; nCnt < aSortArr.Count(); ++nCnt )
1990 // Schleife ueber alle SourceNodes
1991 SvUShorts aNums; //Die Seitennummern
1992 SvPtrarr aDescs; //Die PageDescriptoren passend zu den Seitennummern.
1993 SvUShorts* pMainNums = 0; // contains page numbers of main entries
1995 // process run in lines
1996 USHORT nRange = 0;
1997 if(GetTOXForm().IsCommaSeparated() &&
1998 aSortArr[nCnt]->GetType() == TOX_SORT_INDEX)
2000 const SwTOXMark& rMark = aSortArr[nCnt]->pTxtMark->GetTOXMark();
2001 const String sPrimKey = rMark.GetPrimaryKey();
2002 const String sSecKey = rMark.GetSecondaryKey();
2003 const SwTOXMark* pNextMark = 0;
2004 while(aSortArr.Count() > (nCnt + nRange)&&
2005 aSortArr[nCnt + nRange]->GetType() == TOX_SORT_INDEX &&
2006 0 != (pNextMark = &(aSortArr[nCnt + nRange]->pTxtMark->GetTOXMark())) &&
2007 pNextMark->GetPrimaryKey() == sPrimKey &&
2008 pNextMark->GetSecondaryKey() == sSecKey)
2009 nRange++;
2011 else
2012 nRange = 1;
2014 for(USHORT nRunInEntry = nCnt; nRunInEntry < nCnt + nRange; nRunInEntry++)
2016 SwTOXSortTabBase* pSortBase = aSortArr[nRunInEntry];
2017 USHORT nSize = pSortBase->aTOXSources.Count();
2018 USHORT i;
2019 for( USHORT j = 0; j < nSize; ++j )
2021 ::SetProgressState( 0, pDoc->GetDocShell() );
2023 SwTOXSource& rTOXSource = pSortBase->aTOXSources[j];
2024 if( rTOXSource.pNd )
2026 SwCntntFrm* pFrm = rTOXSource.pNd->GetFrm();
2027 ASSERT( pFrm || pDoc->IsUpdateTOX(), "TOX, no Frame found");
2028 if( !pFrm )
2029 continue;
2030 if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->HasFollow() )
2032 // dann suche den richtigen heraus
2033 SwTxtFrm* pNext = (SwTxtFrm*)pFrm;
2034 while( 0 != ( pNext = (SwTxtFrm*)pFrm->GetFollow() )
2035 && rTOXSource.nPos >= pNext->GetOfst() )
2036 pFrm = pNext;
2039 SwPageFrm* pTmpPage = pFrm->FindPageFrm();
2040 if( pTmpPage != pAktPage )
2042 nPage = pTmpPage->GetVirtPageNum();
2043 pAktPage = pTmpPage;
2046 // sortiert einfuegen
2047 for( i = 0; i < aNums.Count() && aNums[i] < nPage; ++i )
2050 if( i >= aNums.Count() || aNums[ i ] != nPage )
2052 aNums.Insert( nPage, i );
2053 aDescs.Insert( (void*)pAktPage->GetPageDesc(), i );
2055 // is it a main entry?
2056 if(TOX_SORT_INDEX == pSortBase->GetType() &&
2057 rTOXSource.bMainEntry)
2059 if(!pMainNums)
2060 pMainNums = new SvUShorts;
2061 pMainNums->Insert(nPage, pMainNums->Count());
2065 // einfuegen der Seitennummer in den Verzeichnis-Text-Node
2066 const SwTOXSortTabBase* pBase = aSortArr[ nCnt ];
2067 if(pBase->pTOXNd)
2069 const SwTxtNode* pTxtNd = pBase->pTOXNd->GetTxtNode();
2070 ASSERT( pTxtNd, "kein TextNode, falsches Verzeichnis" );
2072 _UpdatePageNum( (SwTxtNode*)pTxtNd, aNums, aDescs, pMainNums,
2073 aIntl );
2075 DELETEZ(pMainNums);
2076 aNums.Remove(0, aNums.Count());
2079 // nach dem Setzen der richtigen Seitennummer, das Mapping-Array
2080 // wieder loeschen !!
2081 aSortArr.DeleteAndDestroy( 0, aSortArr.Count() );
2085 /*--------------------------------------------------------------------
2086 Beschreibung: Austausch der Seitennummer-Platzhalter
2087 --------------------------------------------------------------------*/
2089 // search for the page no in the array of main entry page numbers
2090 BOOL lcl_HasMainEntry( const SvUShorts* pMainEntryNums, USHORT nToFind )
2092 for(USHORT i = 0; pMainEntryNums && i < pMainEntryNums->Count(); ++i)
2093 if(nToFind == (*pMainEntryNums)[i])
2094 return TRUE;
2095 return FALSE;
2098 void SwTOXBaseSection::_UpdatePageNum( SwTxtNode* pNd,
2099 const SvUShorts& rNums,
2100 const SvPtrarr & rDescs,
2101 const SvUShorts* pMainEntryNums,
2102 const SwTOXInternational& rIntl )
2104 //collect starts end ends of main entry character style
2105 SvUShorts* pCharStyleIdx = pMainEntryNums ? new SvUShorts : 0;
2107 String sSrchStr( cNumRepl );
2108 sSrchStr.AppendAscii( sPageDeli ) += cNumRepl;
2109 xub_StrLen nStartPos = pNd->GetTxt().Search( sSrchStr );
2110 ( sSrchStr = cNumRepl ) += cEndPageNum;
2111 xub_StrLen nEndPos = pNd->GetTxt().Search( sSrchStr );
2112 USHORT i;
2114 if( STRING_NOTFOUND == nEndPos || !rNums.Count() )
2115 return;
2117 if( STRING_NOTFOUND == nStartPos || nStartPos > nEndPos)
2118 nStartPos = nEndPos;
2120 USHORT nOld = rNums[0],
2121 nBeg = nOld,
2122 nCount = 0;
2123 String aNumStr( SvxNumberType( ((SwPageDesc*)rDescs[0])->GetNumType() ).
2124 GetNumStr( nBeg ) );
2125 if( pCharStyleIdx && lcl_HasMainEntry( pMainEntryNums, nBeg ))
2127 USHORT nTemp = 0;
2128 pCharStyleIdx->Insert( nTemp, pCharStyleIdx->Count());
2131 // Platzhalter loeschen
2132 SwIndex aPos(pNd, nStartPos);
2133 SwCharFmt* pPageNoCharFmt = 0;
2134 SwpHints* pHints = pNd->GetpSwpHints();
2135 if(pHints)
2136 for(USHORT nHintIdx = 0; nHintIdx < pHints->GetStartCount(); nHintIdx++)
2138 SwTxtAttr* pAttr = pHints->GetStart(nHintIdx);
2139 xub_StrLen nTmpEnd = pAttr->GetEnd() ? *pAttr->GetEnd() : 0;
2140 if( nStartPos >= *pAttr->GetStart() &&
2141 (nStartPos + 2) <= nTmpEnd &&
2142 pAttr->Which() == RES_TXTATR_CHARFMT)
2144 pPageNoCharFmt = pAttr->GetCharFmt().GetCharFmt();
2145 break;
2148 pNd->EraseText(aPos, nEndPos - nStartPos + 2);
2150 for( i = 1; i < rNums.Count(); ++i)
2152 SvxNumberType aType( ((SwPageDesc*)rDescs[i])->GetNumType() );
2153 if( TOX_INDEX == SwTOXBase::GetType() )
2154 { // Zusammenfassen f. ff.
2155 // Alle folgenden aufaddieren
2156 // break up if main entry starts or ends and
2157 // insert a char style index
2158 BOOL bMainEntryChanges = lcl_HasMainEntry(pMainEntryNums, nOld)
2159 != lcl_HasMainEntry(pMainEntryNums, rNums[i]);
2161 if(nOld == rNums[i]-1 && !bMainEntryChanges &&
2162 0 != (GetOptions() & (nsSwTOIOptions::TOI_FF|nsSwTOIOptions::TOI_DASH)))
2163 nCount++;
2164 else
2166 // ff. f. alten Wert flushen
2167 if(GetOptions() & nsSwTOIOptions::TOI_FF)
2169 if ( nCount >= 1 )
2170 aNumStr += rIntl.GetFollowingText( nCount > 1 );
2172 else
2174 if(nCount >= 2 )
2175 aNumStr += '-';
2176 else if(nCount == 1 )
2177 aNumStr.AppendAscii( sPageDeli );
2178 //#58127# Wenn nCount == 0, dann steht die einzige Seitenzahl schon im aNumStr!
2179 if(nCount)
2180 aNumStr += aType.GetNumStr( nBeg + nCount );
2183 // neuen String anlegen
2184 nBeg = rNums[i];
2185 aNumStr.AppendAscii( sPageDeli );
2186 //the change of the character style must apply after sPageDeli is appended
2187 if(pCharStyleIdx && bMainEntryChanges)
2188 pCharStyleIdx->Insert(aNumStr.Len(),
2189 pCharStyleIdx->Count());
2190 aNumStr += aType.GetNumStr( nBeg );
2191 nCount = 0;
2193 nOld = rNums[i];
2195 else
2196 { // Alle Nummern eintragen
2197 aNumStr += aType.GetNumStr( USHORT(rNums[i]) );
2198 if(i != (rNums.Count()-1))
2199 aNumStr.AppendAscii( sPageDeli );
2202 // Bei Ende und ff. alten Wert flushen
2203 if( TOX_INDEX == SwTOXBase::GetType() )
2205 if(GetOptions() & nsSwTOIOptions::TOI_FF)
2207 if( nCount >= 1 )
2208 aNumStr += rIntl.GetFollowingText( nCount > 1 );
2210 else
2212 if(nCount >= 2)
2213 aNumStr +='-';
2214 else if(nCount == 1)
2215 aNumStr.AppendAscii( sPageDeli );
2216 //#58127# Wenn nCount == 0, dann steht die einzige Seitenzahl schon im aNumStr!
2217 if(nCount)
2218 aNumStr += SvxNumberType( ((SwPageDesc*)rDescs[i-1])->
2219 GetNumType() ).GetNumStr( nBeg+nCount );
2222 pNd->InsertText( aNumStr, aPos,
2223 IDocumentContentOperations::INS_EMPTYEXPAND );
2224 if(pPageNoCharFmt)
2226 SwFmtCharFmt aCharFmt( pPageNoCharFmt );
2227 pNd->InsertItem(aCharFmt, nStartPos, nStartPos + aNumStr.Len(), nsSetAttrMode::SETATTR_DONTEXPAND);
2230 //now the main entries should get there character style
2231 if(pCharStyleIdx && pCharStyleIdx->Count() && GetMainEntryCharStyle().Len())
2233 // eventually the last index must me appended
2234 if(pCharStyleIdx->Count()&0x01)
2235 pCharStyleIdx->Insert(aNumStr.Len(), pCharStyleIdx->Count());
2237 //search by name
2238 SwDoc* pDoc = pNd->GetDoc();
2239 USHORT nPoolId = SwStyleNameMapper::GetPoolIdFromUIName( GetMainEntryCharStyle(), nsSwGetPoolIdFromName::GET_POOLID_CHRFMT );
2240 SwCharFmt* pCharFmt = 0;
2241 if(USHRT_MAX != nPoolId)
2242 pCharFmt = pDoc->GetCharFmtFromPool(nPoolId);
2243 else
2244 pCharFmt = pDoc->FindCharFmtByName( GetMainEntryCharStyle() );
2245 if(!pCharFmt)
2246 pCharFmt = pDoc->MakeCharFmt(GetMainEntryCharStyle(), 0);
2248 //find the page numbers in aNumStr and set the character style
2249 xub_StrLen nOffset = pNd->GetTxt().Len() - aNumStr.Len();
2250 SwFmtCharFmt aCharFmt(pCharFmt);
2251 for(USHORT j = 0; j < pCharStyleIdx->Count(); j += 2)
2253 xub_StrLen nStartIdx = (*pCharStyleIdx)[j] + nOffset;
2254 xub_StrLen nEndIdx = (*pCharStyleIdx)[j + 1] + nOffset;
2255 pNd->InsertItem(aCharFmt, nStartIdx, nEndIdx, nsSetAttrMode::SETATTR_DONTEXPAND);
2259 delete pCharStyleIdx;
2263 /*--------------------------------------------------------------------
2264 Beschreibung: Sortiert einfuegen in das SortArr
2265 --------------------------------------------------------------------*/
2267 void SwTOXBaseSection::InsertSorted(SwTOXSortTabBase* pNew)
2269 Range aRange(0, aSortArr.Count());
2270 if( TOX_INDEX == SwTOXBase::GetType() && pNew->pTxtMark )
2272 const SwTOXMark& rMark = pNew->pTxtMark->GetTOXMark();
2273 // Schluessel auswerten
2274 // Den Bereich ermitteln, in dem einzufuegen ist
2275 if( 0 == (GetOptions() & nsSwTOIOptions::TOI_KEY_AS_ENTRY) &&
2276 rMark.GetPrimaryKey().Len() )
2278 aRange = GetKeyRange( rMark.GetPrimaryKey(),
2279 rMark.GetPrimaryKeyReading(),
2280 *pNew, FORM_PRIMARY_KEY, aRange );
2282 if( rMark.GetSecondaryKey().Len() )
2283 aRange = GetKeyRange( rMark.GetSecondaryKey(),
2284 rMark.GetSecondaryKeyReading(),
2285 *pNew, FORM_SECONDARY_KEY, aRange );
2288 //search for identical entries and remove the trailing one
2289 if(TOX_AUTHORITIES == SwTOXBase::GetType())
2291 for(short i = (short)aRange.Min(); i < (short)aRange.Max(); ++i)
2293 SwTOXSortTabBase* pOld = aSortArr[i];
2294 if(*pOld == *pNew)
2296 if(*pOld < *pNew)
2298 delete pNew;
2299 return;
2301 else
2303 // remove the old content
2304 aSortArr.DeleteAndDestroy( i, 1 );
2305 aRange.Max()--;
2306 break;
2312 // find position and insert
2314 short i;
2316 for( i = (short)aRange.Min(); i < (short)aRange.Max(); ++i)
2317 { // nur auf gleicher Ebene pruefen
2319 SwTOXSortTabBase* pOld = aSortArr[i];
2320 if(*pOld == *pNew)
2322 if(TOX_AUTHORITIES != SwTOXBase::GetType())
2324 // Eigener Eintrag fuer Doppelte oder Keywords
2326 if( pOld->GetType() == TOX_SORT_CUSTOM &&
2327 pNew->GetOptions() & nsSwTOIOptions::TOI_KEY_AS_ENTRY)
2328 continue;
2330 if(!(pNew->GetOptions() & nsSwTOIOptions::TOI_SAME_ENTRY))
2331 { // Eigener Eintrag
2332 aSortArr.Insert(pNew, i );
2333 return;
2335 // Eintrag schon vorhanden in Referenzliste aufnehmen
2336 pOld->aTOXSources.Insert( pNew->aTOXSources[0],
2337 pOld->aTOXSources.Count() );
2339 delete pNew;
2340 return;
2342 #ifdef DBG_UTIL
2343 else
2344 DBG_ERROR("Bibliography entries cannot be found here");
2345 #endif
2347 if(*pNew < *pOld)
2348 break;
2350 // SubLevel Skippen
2351 while( TOX_INDEX == SwTOXBase::GetType() && i < aRange.Max() &&
2352 aSortArr[i]->GetLevel() > pNew->GetLevel() )
2353 i++;
2355 // An Position i wird eingefuegt
2356 aSortArr.Insert(pNew, i );
2359 /*--------------------------------------------------------------------
2360 Beschreibung: Schluessel-Bereich suchen und evtl einfuegen
2361 --------------------------------------------------------------------*/
2363 Range SwTOXBaseSection::GetKeyRange(const String& rStr, const String& rStrReading,
2364 const SwTOXSortTabBase& rNew,
2365 USHORT nLevel, const Range& rRange )
2367 const SwTOXInternational& rIntl = *rNew.pTOXIntl;
2368 String sToCompare(rStr);
2369 String sToCompareReading(rStrReading);
2371 if( 0 != (nsSwTOIOptions::TOI_INITIAL_CAPS & GetOptions()) )
2373 String sUpper( rIntl.ToUpper( sToCompare, 0 ));
2374 sToCompare.Erase( 0, 1 ).Insert( sUpper, 0 );
2377 ASSERT(rRange.Min() >= 0 && rRange.Max() >= 0, "Min Max < 0");
2379 const USHORT nMin = (USHORT)rRange.Min();
2380 const USHORT nMax = (USHORT)rRange.Max();
2382 USHORT i;
2384 for( i = nMin; i < nMax; ++i)
2386 SwTOXSortTabBase* pBase = aSortArr[i];
2388 String sMyString, sMyStringReading;
2389 pBase->GetTxt( sMyString, sMyStringReading );
2391 if( rIntl.IsEqual( sMyString, sMyStringReading, pBase->GetLocale(),
2392 sToCompare, sToCompareReading, rNew.GetLocale() ) &&
2393 pBase->GetLevel() == nLevel &&
2394 pBase->GetType() == TOX_SORT_CUSTOM )
2395 break;
2397 if(i == nMax)
2398 { // Falls nicht vorhanden erzeugen und einfuegen
2400 SwTOXCustom* pKey = new SwTOXCustom( sToCompare, sToCompareReading, nLevel, rIntl,
2401 rNew.GetLocale() );
2402 for(i = nMin; i < nMax; ++i)
2404 if(nLevel == aSortArr[i]->GetLevel() && *pKey < *(aSortArr[i]))
2405 break;
2407 aSortArr.Insert(pKey, i );
2409 USHORT nStart = i+1;
2410 USHORT nEnd = aSortArr.Count();
2412 // Ende des Bereiches suchen
2413 for(i = nStart; i < aSortArr.Count(); ++i)
2415 if(aSortArr[i]->GetLevel() <= nLevel)
2416 { nEnd = i;
2417 break;
2420 return Range(nStart, nEnd);
2424 BOOL SwTOXBase::IsTOXBaseInReadonly() const
2426 const SwTOXBaseSection *pSect = PTR_CAST(SwTOXBaseSection, this);
2427 BOOL bRet = FALSE;
2428 const SwSectionNode* pSectNode;
2429 if(pSect && pSect->GetFmt() &&
2430 0 != (pSectNode = pSect->GetFmt()->GetSectionNode()))
2432 const SwDocShell* pDocSh;
2433 bRet = (0 != (pDocSh = pSectNode->GetDoc()->GetDocShell()) &&
2434 pDocSh->IsReadOnly()) ||
2435 (0 != (pSectNode = pSectNode->StartOfSectionNode()->FindSectionNode())&&
2436 pSectNode->GetSection().IsProtectFlag());
2439 return bRet;
2441 /* -----------------17.08.99 13:29-------------------
2443 --------------------------------------------------*/
2444 const SfxItemSet* SwTOXBase::GetAttrSet() const
2446 const SwTOXBaseSection *pSect = PTR_CAST(SwTOXBaseSection, this);
2447 if(pSect && pSect->GetFmt())
2448 return &pSect->GetFmt()->GetAttrSet();
2449 return 0;
2452 void SwTOXBase::SetAttrSet( const SfxItemSet& rSet )
2454 SwTOXBaseSection *pSect = PTR_CAST(SwTOXBaseSection, this);
2455 if( pSect && pSect->GetFmt() )
2456 pSect->GetFmt()->SetFmtAttr( rSet );
2459 BOOL SwTOXBase::GetInfo( SfxPoolItem& rInfo ) const
2461 switch( rInfo.Which() )
2463 case RES_CONTENT_VISIBLE:
2465 SwTOXBaseSection *pSect = PTR_CAST(SwTOXBaseSection, this);
2466 if( pSect && pSect->GetFmt() )
2467 pSect->GetFmt()->GetInfo( rInfo );
2469 return FALSE;
2471 return TRUE;
2474 /* \f */