update dev300-m58
[ooovba.git] / sw / source / core / doc / doctxm.cxx
blobb2c581e5f3c7f197bb88471ecc88492ac073d8e2
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::Delete( 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 );
205 rTxtNd.Delete( const_cast<SwTxtTOXMark*>( pTxtTOXMark ), TRUE );
206 if( rTxtNd.GetpSwpHints() )
207 rTxtNd.GetpSwpHints()->DeRegister();
209 else
210 rTxtNd.Delete( const_cast<SwTxtTOXMark*>( pTxtTOXMark ), TRUE );
211 SetModified();
214 /*--------------------------------------------------------------------
215 Beschreibung: Traveln zwischen TOXMarks
216 --------------------------------------------------------------------*/
218 class CompareNodeCntnt
220 ULONG nNode;
221 xub_StrLen nCntnt;
222 public:
223 CompareNodeCntnt( ULONG nNd, xub_StrLen nCnt )
224 : nNode( nNd ), nCntnt( nCnt ) {}
226 int operator==( const CompareNodeCntnt& rCmp )
227 { return nNode == rCmp.nNode && nCntnt == rCmp.nCntnt; }
228 int operator!=( const CompareNodeCntnt& rCmp )
229 { return nNode != rCmp.nNode || nCntnt != rCmp.nCntnt; }
230 int operator< ( const CompareNodeCntnt& rCmp )
231 { return nNode < rCmp.nNode ||
232 ( nNode == rCmp.nNode && nCntnt < rCmp.nCntnt); }
233 int operator<=( const CompareNodeCntnt& rCmp )
234 { return nNode < rCmp.nNode ||
235 ( nNode == rCmp.nNode && nCntnt <= rCmp.nCntnt); }
236 int operator> ( const CompareNodeCntnt& rCmp )
237 { return nNode > rCmp.nNode ||
238 ( nNode == rCmp.nNode && nCntnt > rCmp.nCntnt); }
239 int operator>=( const CompareNodeCntnt& rCmp )
240 { return nNode > rCmp.nNode ||
241 ( nNode == rCmp.nNode && nCntnt >= rCmp.nCntnt); }
244 const SwTOXMark& SwDoc::GotoTOXMark( const SwTOXMark& rCurTOXMark,
245 SwTOXSearch eDir, BOOL bInReadOnly )
247 const SwTxtTOXMark* pMark = rCurTOXMark.GetTxtTOXMark();
248 ASSERT(pMark, "pMark==0 Ungueltige TxtTOXMark");
250 const SwTxtNode *pTOXSrc = pMark->GetpTxtNd();
252 CompareNodeCntnt aAbsIdx( pTOXSrc->GetIndex(), *pMark->GetStart() );
253 CompareNodeCntnt aPrevPos( 0, 0 );
254 CompareNodeCntnt aNextPos( ULONG_MAX, STRING_NOTFOUND );
255 CompareNodeCntnt aMax( 0, 0 );
256 CompareNodeCntnt aMin( ULONG_MAX, STRING_NOTFOUND );
258 const SwTOXMark* pNew = 0;
259 const SwTOXMark* pMax = &rCurTOXMark;
260 const SwTOXMark* pMin = &rCurTOXMark;
262 const SwModify* pType = rCurTOXMark.GetRegisteredIn();
263 SwClientIter aIter( *(SwModify*)pType );
265 const SwTOXMark* pTOXMark;
266 const SwCntntFrm* pCFrm;
267 Point aPt;
268 for( pTOXMark = (SwTOXMark*)aIter.First( TYPE( SwTOXMark )); pTOXMark;
269 pTOXMark = (SwTOXMark*)aIter.Next() )
271 if( pTOXMark != &rCurTOXMark &&
272 0 != ( pMark = pTOXMark->GetTxtTOXMark()) &&
273 0 != ( pTOXSrc = pMark->GetpTxtNd() ) &&
274 0 != ( pCFrm = pTOXSrc->GetFrm( &aPt, 0, FALSE )) &&
275 ( bInReadOnly || !pCFrm->IsProtected() ))
277 CompareNodeCntnt aAbsNew( pTOXSrc->GetIndex(), *pMark->GetStart() );
278 switch( eDir )
280 //Die untenstehenden etwas komplizierter ausgefallen Ausdruecke
281 //dienen dazu auch ueber Eintraege auf der selben (!) Position
282 //traveln zu koennen. Wenn einer Zeit hat mag er sie mal
283 //optimieren.
285 case TOX_SAME_PRV:
286 if( pTOXMark->GetText() != rCurTOXMark.GetText() )
287 break;
288 /* no break here */
289 case TOX_PRV:
290 if ( (aAbsNew < aAbsIdx && aAbsNew > aPrevPos &&
291 aPrevPos != aAbsIdx && aAbsNew != aAbsIdx ) ||
292 (aAbsIdx == aAbsNew &&
293 (ULONG(&rCurTOXMark) > ULONG(pTOXMark) &&
294 (!pNew ||
295 (pNew && (aPrevPos < aAbsIdx ||
296 ULONG(pNew) < ULONG(pTOXMark)))))) ||
297 (aPrevPos == aAbsNew && aAbsIdx != aAbsNew &&
298 ULONG(pTOXMark) > ULONG(pNew)) )
300 pNew = pTOXMark;
301 aPrevPos = aAbsNew;
302 if ( aAbsNew >= aMax )
304 aMax = aAbsNew;
305 pMax = pTOXMark;
308 break;
310 case TOX_SAME_NXT:
311 if( pTOXMark->GetText() != rCurTOXMark.GetText() )
312 break;
313 /* no break here */
314 case TOX_NXT:
315 if ( (aAbsNew > aAbsIdx && aAbsNew < aNextPos &&
316 aNextPos != aAbsIdx && aAbsNew != aAbsIdx ) ||
317 (aAbsIdx == aAbsNew &&
318 (ULONG(&rCurTOXMark) < ULONG(pTOXMark) &&
319 (!pNew ||
320 (pNew && (aNextPos > aAbsIdx ||
321 ULONG(pNew) > ULONG(pTOXMark)))))) ||
322 (aNextPos == aAbsNew && aAbsIdx != aAbsNew &&
323 ULONG(pTOXMark) < ULONG(pNew)) )
325 pNew = pTOXMark;
326 aNextPos = aAbsNew;
327 if ( aAbsNew <= aMin )
329 aMin = aAbsNew;
330 pMin = pTOXMark;
333 break;
339 // kein Nachfolger wurde gefunden
340 // Min oder Max benutzen
341 if(!pNew)
343 switch(eDir)
345 case TOX_PRV:
346 case TOX_SAME_PRV:
347 pNew = pMax;
348 break;
349 case TOX_NXT:
350 case TOX_SAME_NXT:
351 pNew = pMin;
352 break;
353 default:
354 pNew = &rCurTOXMark;
357 return *pNew;
360 /* \f */
362 const SwTOXBaseSection* SwDoc::InsertTableOf( const SwPosition& rPos,
363 const SwTOXBase& rTOX,
364 const SfxItemSet* pSet,
365 BOOL bExpand )
367 StartUndo( UNDO_INSTOX, NULL );
369 SwTOXBaseSection* pNew = new SwTOXBaseSection( rTOX );
370 String sSectNm( rTOX.GetTOXName() );
371 sSectNm = GetUniqueTOXBaseName( *rTOX.GetTOXType(), &sSectNm );
372 pNew->SetTOXName(sSectNm);
373 pNew->SwSection::SetName(sSectNm);
374 SwPaM aPam( rPos );
375 SwSection* pSect = Insert( aPam, *pNew, pSet, FALSE );
376 if( pSect )
378 SwSectionNode* pSectNd = pSect->GetFmt()->GetSectionNode();
379 SwSection* pCl = pNew;
380 pSect->GetFmt()->Add( pCl );
381 pSectNd->SetNewSection( pNew );
383 if( bExpand )
385 // OD 19.03.2003 #106329# - add value for 2nd parameter = true to
386 // indicate, that a creation of a new table of content has to be performed.
387 // Value of 1st parameter = default value.
388 pNew->Update( 0, true );
390 else if( 1 == rTOX.GetTitle().Len() && IsInReading() )
391 // insert title of TOX
393 // then insert the headline section
394 SwNodeIndex aIdx( *pSectNd, +1 );
396 SwTxtNode* pHeadNd = GetNodes().MakeTxtNode( aIdx,
397 GetTxtCollFromPool( RES_POOLCOLL_STANDARD ) );
399 String sNm( pNew->GetTOXName() );
400 // ??Resource
401 sNm.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "_Head" ));
403 SwSection aSect( TOX_HEADER_SECTION, sNm );
405 SwNodeIndex aStt( *pHeadNd ); aIdx--;
406 SwSectionFmt* pSectFmt = MakeSectionFmt( 0 );
407 GetNodes().InsertSection( aStt, *pSectFmt, aSect, &aIdx,
408 TRUE, FALSE );
411 else
412 delete pNew, pNew = 0;
414 EndUndo( UNDO_INSTOX, NULL );
416 return pNew;
421 const SwTOXBaseSection* SwDoc::InsertTableOf( ULONG nSttNd, ULONG nEndNd,
422 const SwTOXBase& rTOX,
423 const SfxItemSet* pSet )
425 // check for recursiv TOX
426 SwNode* pNd = GetNodes()[ nSttNd ];
427 SwSectionNode* pSectNd = pNd->FindSectionNode();
428 while( pSectNd )
430 SectionType eT = pSectNd->GetSection().GetType();
431 if( TOX_HEADER_SECTION == eT || TOX_CONTENT_SECTION == eT )
432 return 0;
433 pSectNd = pSectNd->StartOfSectionNode()->FindSectionNode();
436 // create SectionNode around the Nodes
437 SwTOXBaseSection* pNew = new SwTOXBaseSection( rTOX );
439 String sSectNm( rTOX.GetTOXName() );
440 sSectNm = GetUniqueTOXBaseName(*rTOX.GetTOXType(), &sSectNm);
441 pNew->SetTOXName(sSectNm);
442 pNew->SwSection::SetName(sSectNm);
444 SwNodeIndex aStt( GetNodes(), nSttNd ), aEnd( GetNodes(), nEndNd );
445 SwSectionFmt* pFmt = MakeSectionFmt( 0 );
446 if(pSet)
447 pFmt->SetFmtAttr(*pSet);
449 // --aEnd; // im InsertSection ist Ende inclusive
451 pSectNd = GetNodes().InsertSection( aStt, *pFmt, *pNew, &aEnd );
452 if( pSectNd )
454 SwSection* pCl = pNew;
455 pFmt->Add( pCl );
456 pSectNd->SetNewSection( pNew );
458 else
460 delete pNew, pNew = 0;
461 DelSectionFmt( pFmt );
464 return pNew;
467 /*--------------------------------------------------------------------
468 Beschreibung: Aktuelles Verzeichnis ermitteln
469 --------------------------------------------------------------------*/
471 const SwTOXBase* SwDoc::GetCurTOX( const SwPosition& rPos ) const
473 const SwNode& rNd = rPos.nNode.GetNode();
474 const SwSectionNode* pSectNd = rNd.FindSectionNode();
475 while( pSectNd )
477 SectionType eT = pSectNd->GetSection().GetType();
478 if( TOX_CONTENT_SECTION == eT )
480 ASSERT( pSectNd->GetSection().ISA( SwTOXBaseSection ),
481 "keine TOXBaseSection!" );
482 SwTOXBaseSection& rTOXSect = (SwTOXBaseSection&)
483 pSectNd->GetSection();
484 return &rTOXSect;
486 pSectNd = pSectNd->StartOfSectionNode()->FindSectionNode();
488 return 0;
490 /* -----------------01.09.99 16:01-------------------
492 --------------------------------------------------*/
493 const SwAttrSet& SwDoc::GetTOXBaseAttrSet(const SwTOXBase& rTOXBase) const
495 ASSERT( rTOXBase.ISA( SwTOXBaseSection ), "no TOXBaseSection!" );
496 const SwTOXBaseSection& rTOXSect = (const SwTOXBaseSection&)rTOXBase;
497 SwSectionFmt* pFmt = rTOXSect.GetFmt();
498 ASSERT( pFmt, "invalid TOXBaseSection!" );
499 return pFmt->GetAttrSet();
501 /* -----------------02.09.99 07:48-------------------
503 --------------------------------------------------*/
504 const SwTOXBase* SwDoc::GetDefaultTOXBase( TOXTypes eTyp, BOOL bCreate )
506 SwTOXBase** prBase = 0;
507 switch(eTyp)
509 case TOX_CONTENT: prBase = &pDefTOXBases->pContBase; break;
510 case TOX_INDEX: prBase = &pDefTOXBases->pIdxBase; break;
511 case TOX_USER: prBase = &pDefTOXBases->pUserBase; break;
512 case TOX_TABLES: prBase = &pDefTOXBases->pTblBase; break;
513 case TOX_OBJECTS: prBase = &pDefTOXBases->pObjBase; break;
514 case TOX_ILLUSTRATIONS: prBase = &pDefTOXBases->pIllBase; break;
515 case TOX_AUTHORITIES: prBase = &pDefTOXBases->pAuthBase; break;
517 if(!(*prBase) && bCreate)
519 SwForm aForm(eTyp);
520 const SwTOXType* pType = GetTOXType(eTyp, 0);
521 (*prBase) = new SwTOXBase(pType, aForm, 0, pType->GetTypeName());
523 return (*prBase);
525 /* -----------------02.09.99 08:06-------------------
527 --------------------------------------------------*/
528 void SwDoc::SetDefaultTOXBase(const SwTOXBase& rBase)
530 SwTOXBase** prBase = 0;
531 switch(rBase.GetType())
533 case TOX_CONTENT: prBase = &pDefTOXBases->pContBase; break;
534 case TOX_INDEX: prBase = &pDefTOXBases->pIdxBase; break;
535 case TOX_USER: prBase = &pDefTOXBases->pUserBase; break;
536 case TOX_TABLES: prBase = &pDefTOXBases->pTblBase; break;
537 case TOX_OBJECTS: prBase = &pDefTOXBases->pObjBase; break;
538 case TOX_ILLUSTRATIONS: prBase = &pDefTOXBases->pIllBase; break;
539 case TOX_AUTHORITIES: prBase = &pDefTOXBases->pAuthBase; break;
541 if(*prBase)
542 delete (*prBase);
543 (*prBase) = new SwTOXBase(rBase);
546 /*--------------------------------------------------------------------
547 Beschreibung: Verzeichnis loeschen
548 --------------------------------------------------------------------*/
551 BOOL SwDoc::DeleteTOX( const SwTOXBase& rTOXBase, BOOL bDelNodes )
553 // its only delete the TOX, not the nodes
554 BOOL bRet = FALSE;
555 ASSERT( rTOXBase.ISA( SwTOXBaseSection ), "keine TOXBaseSection!" );
557 const SwTOXBaseSection& rTOXSect = (const SwTOXBaseSection&)rTOXBase;
558 SwSectionFmt* pFmt = rTOXSect.GetFmt();
559 if( pFmt )
561 StartUndo( UNDO_CLEARTOXRANGE, NULL );
563 /* Save the start node of the TOX' section. */
564 SwSectionNode * pMyNode = pFmt->GetSectionNode();
565 /* Save start node of section's surrounding. */
566 SwNode * pStartNd = pMyNode->StartOfSectionNode();
568 /* Look for point where to move the cursors in the area to
569 delete to. This is done by first searching forward from the
570 end of the TOX' section. If no content node is found behind
571 the TOX one is searched before it. If this is not
572 successfull, too, insert new text node behind the end of
573 the TOX' section. The cursors from the TOX' section will be
574 moved to the content node found or the new text node. */
576 /* Set PaM to end of TOX' section and search following content node.
578 aSearchPam will contain the point where to move the cursors
579 to. */
580 SwPaM aSearchPam(*pMyNode->EndOfSectionNode());
581 SwPosition aEndPos(*pStartNd->EndOfSectionNode(), 0);
582 if (! aSearchPam.Move() /* no content node found */
583 || *aSearchPam.GetPoint() >= aEndPos /* content node found
584 outside surrounding */
587 /* Set PaM to beginning of TOX' section and search previous
588 content node */
589 SwPaM aTmpPam(*pMyNode);
590 aSearchPam = aTmpPam;
591 SwPosition aStartPos(*pStartNd, 0);
593 if ( ! aSearchPam.Move(fnMoveBackward) /* no content node found */
594 || *aSearchPam.GetPoint() <= aStartPos /* content node
595 found outside
596 surrounding */
599 /* There is no content node in the surrounding of
600 TOX'. Append text node behind TOX' section. */
602 SwPosition aInsPos(*pMyNode->EndOfSectionNode(), 0);
603 AppendTxtNode(aInsPos);
605 SwPaM aTmpPam1(aInsPos);
606 aSearchPam = aTmpPam1;
611 /* PaM containing the TOX. */
612 SwPaM aPam(*pMyNode->EndOfSectionNode(), *pMyNode);
614 /* Move cursors contained in TOX to point determined above. */
615 PaMCorrAbs(aPam, *aSearchPam.GetPoint());
617 if( !bDelNodes )
619 SwSections aArr( 0, 4 );
620 USHORT nCnt = pFmt->GetChildSections( aArr, SORTSECT_NOT, FALSE );
621 for( USHORT n = 0; n < nCnt; ++n )
623 SwSection* pSect = aArr[ n ];
624 if( TOX_HEADER_SECTION == pSect->GetType() )
626 DelSectionFmt( pSect->GetFmt(), bDelNodes );
631 DelSectionFmt( pFmt, bDelNodes );
633 EndUndo( UNDO_CLEARTOXRANGE, NULL );
634 bRet = TRUE;
637 return bRet;
640 /*--------------------------------------------------------------------
641 Beschreibung: Verzeichnistypen verwalten
642 --------------------------------------------------------------------*/
644 USHORT SwDoc::GetTOXTypeCount(TOXTypes eTyp) const
646 const SwTOXTypePtr * ppTTypes = pTOXTypes->GetData();
647 USHORT nCnt = 0;
648 for( USHORT n = 0; n < pTOXTypes->Count(); ++n, ++ppTTypes )
649 if( eTyp == (*ppTTypes)->GetType() )
650 ++nCnt;
651 return nCnt;
653 /*--------------------------------------------------------------------
655 --------------------------------------------------------------------*/
656 const SwTOXType* SwDoc::GetTOXType( TOXTypes eTyp, USHORT nId ) const
658 const SwTOXTypePtr * ppTTypes = pTOXTypes->GetData();
659 USHORT nCnt = 0;
660 for( USHORT n = 0; n < pTOXTypes->Count(); ++n, ++ppTTypes )
661 if( eTyp == (*ppTTypes)->GetType() && nCnt++ == nId )
662 return (*ppTTypes);
663 return 0;
666 /*--------------------------------------------------------------------
668 --------------------------------------------------------------------*/
669 const SwTOXType* SwDoc::InsertTOXType( const SwTOXType& rTyp )
671 SwTOXType * pNew = new SwTOXType( rTyp );
672 pTOXTypes->Insert( pNew, pTOXTypes->Count() );
673 return pNew;
675 /*--------------------------------------------------------------------
677 --------------------------------------------------------------------*/
678 String SwDoc::GetUniqueTOXBaseName( const SwTOXType& rType,
679 const String* pChkStr ) const
681 USHORT n;
682 const SwSectionNode* pSectNd;
683 const SwSection* pSect;
685 if(pChkStr && !pChkStr->Len())
686 pChkStr = 0;
687 String aName( rType.GetTypeName() );
688 xub_StrLen nNmLen = aName.Len();
690 USHORT nNum = 0;
691 USHORT nTmp = 0;
692 USHORT nFlagSize = ( pSectionFmtTbl->Count() / 8 ) +2;
693 BYTE* pSetFlags = new BYTE[ nFlagSize ];
694 memset( pSetFlags, 0, nFlagSize );
696 for( n = 0; n < pSectionFmtTbl->Count(); ++n )
697 if( 0 != ( pSectNd = (*pSectionFmtTbl)[ n ]->GetSectionNode( FALSE ) )&&
698 TOX_CONTENT_SECTION == (pSect = &pSectNd->GetSection())->GetType())
700 const String& rNm = pSect->GetName();
701 if( rNm.Match( aName ) == nNmLen )
703 // Nummer bestimmen und das Flag setzen
704 nNum = (USHORT)rNm.Copy( nNmLen ).ToInt32();
705 if( nNum-- && nNum < pSectionFmtTbl->Count() )
706 pSetFlags[ nNum / 8 ] |= (0x01 << ( nNum & 0x07 ));
708 if( pChkStr && pChkStr->Equals( rNm ) )
709 pChkStr = 0;
712 if( !pChkStr )
714 // alle Nummern entsprechend geflag, also bestimme die richtige Nummer
715 nNum = pSectionFmtTbl->Count();
716 for( n = 0; n < nFlagSize; ++n )
717 if( 0xff != ( nTmp = pSetFlags[ n ] ))
719 // also die Nummer bestimmen
720 nNum = n * 8;
721 while( nTmp & 1 )
722 ++nNum, nTmp >>= 1;
723 break;
726 delete [] pSetFlags;
727 if( pChkStr )
728 return *pChkStr;
729 return aName += String::CreateFromInt32( ++nNum );
732 /*--------------------------------------------------------------------
734 --------------------------------------------------------------------*/
735 BOOL SwDoc::SetTOXBaseName(const SwTOXBase& rTOXBase, const String& rName)
737 ASSERT( rTOXBase.ISA( SwTOXBaseSection ),
738 "keine TOXBaseSection!" );
739 SwTOXBaseSection* pTOX = (SwTOXBaseSection*)&rTOXBase;
741 String sTmp = GetUniqueTOXBaseName(*rTOXBase.GetTOXType(), &rName);
742 BOOL bRet = sTmp == rName;
743 if(bRet)
745 pTOX->SetTOXName(rName);
746 pTOX->SwTOXBaseSection::SetName(rName);
747 SetModified();
749 return bRet;
752 /* \f */
754 const SwTxtNode* lcl_FindChapterNode( const SwNode& rNd, BYTE nLvl = 0 )
756 const SwNode* pNd = &rNd;
757 if( pNd->GetNodes().GetEndOfExtras().GetIndex() > pNd->GetIndex() )
759 // then find the "Anchor" (Body) position
760 Point aPt;
761 SwNode2Layout aNode2Layout( *pNd, pNd->GetIndex() );
762 const SwFrm* pFrm = aNode2Layout.GetFrm( &aPt, 0, FALSE );
764 if( pFrm )
766 SwPosition aPos( *pNd );
767 pNd = GetBodyTxtNode( *pNd->GetDoc(), aPos, *pFrm );
768 ASSERT( pNd, "wo steht der Absatz" );
771 return pNd ? pNd->FindOutlineNodeOfLevel( nLvl ) : 0;
775 /*--------------------------------------------------------------------
776 Beschreibung: Verzeichnis-Klasse
777 --------------------------------------------------------------------*/
779 SwTOXBaseSection::SwTOXBaseSection( const SwTOXBase& rBase )
780 : SwTOXBase( rBase ), SwSection( TOX_CONTENT_SECTION, aEmptyStr )
782 SetProtect( rBase.IsProtected() );
783 SwSection::SetName( GetTOXName() );
787 SwTOXBaseSection::~SwTOXBaseSection()
792 BOOL SwTOXBaseSection::SetPosAtStartEnd( SwPosition& rPos, BOOL bAtStart ) const
794 BOOL bRet = FALSE;
795 const SwSectionNode* pSectNd = GetFmt()->GetSectionNode();
796 if( pSectNd )
798 SwCntntNode* pCNd;
799 xub_StrLen nC = 0;
800 if( bAtStart )
802 rPos.nNode = *pSectNd;
803 pCNd = pSectNd->GetDoc()->GetNodes().GoNext( &rPos.nNode );
805 else
807 rPos.nNode = *pSectNd->EndOfSectionNode();
808 pCNd = pSectNd->GetDoc()->GetNodes().GoPrevious( &rPos.nNode );
809 if( pCNd ) nC = pCNd->Len();
811 rPos.nContent.Assign( pCNd, nC );
812 bRet = TRUE;
814 return bRet;
817 /*--------------------------------------------------------------------
818 Beschreibung: Verzeichnisinhalt zusammensammeln
819 --------------------------------------------------------------------*/
821 void SwTOXBaseSection::Update(const SfxItemSet* pAttr,
822 const bool _bNewTOX )
824 const SwSectionNode* pSectNd;
825 if( !SwTOXBase::GetRegisteredIn()->GetDepends() ||
826 !GetFmt() || 0 == (pSectNd = GetFmt()->GetSectionNode() ) ||
827 !pSectNd->GetNodes().IsDocNodes() ||
828 IsHiddenFlag() )
829 return;
831 SwDoc* pDoc = (SwDoc*)pSectNd->GetDoc();
833 DBG_ASSERT(pDoc != NULL, "Where is the document?");
835 if(pAttr && pDoc && GetFmt())
836 pDoc->ChgFmt(*GetFmt(), *pAttr);
838 // OD 18.03.2003 #106329# - determine default page description, which
839 // will be used by the content nodes, if no approriate one is found.
840 const SwPageDesc* pDefaultPageDesc;
842 pDefaultPageDesc =
843 pSectNd->GetSection().GetFmt()->GetPageDesc().GetPageDesc();
844 if ( !_bNewTOX && !pDefaultPageDesc )
846 // determine page description of table-of-content
847 sal_uInt32 nPgDescNdIdx = pSectNd->GetIndex() + 1;
848 sal_uInt32* pPgDescNdIdx = &nPgDescNdIdx;
849 pDefaultPageDesc = pSectNd->FindPageDesc( FALSE, pPgDescNdIdx );
850 if ( nPgDescNdIdx < pSectNd->GetIndex() )
852 pDefaultPageDesc = 0;
855 // OD 28.04.2003 #109166# - consider end node of content section in the
856 // node array.
857 if ( !pDefaultPageDesc &&
858 ( pSectNd->EndOfSectionNode()->GetIndex() <
859 (pSectNd->GetNodes().GetEndOfContent().GetIndex() - 1) )
862 // determine page description of content after table-of-content
863 SwNodeIndex aIdx( *(pSectNd->EndOfSectionNode()) );
864 const SwCntntNode* pNdAfterTOX = pSectNd->GetNodes().GoNext( &aIdx );
865 const SwAttrSet& aNdAttrSet = pNdAfterTOX->GetSwAttrSet();
866 const SvxBreak eBreak = aNdAttrSet.GetBreak().GetBreak();
867 if ( !( eBreak == SVX_BREAK_PAGE_BEFORE ||
868 eBreak == SVX_BREAK_PAGE_BOTH )
871 pDefaultPageDesc = pNdAfterTOX->FindPageDesc( FALSE );
874 // OD 28.04.2003 #109166# - consider start node of content section in
875 // the node array.
876 if ( !pDefaultPageDesc &&
877 ( pSectNd->GetIndex() >
878 (pSectNd->GetNodes().GetEndOfContent().StartOfSectionIndex() + 1) )
881 // determine page description of content before table-of-content
882 SwNodeIndex aIdx( *pSectNd );
883 pDefaultPageDesc =
884 pSectNd->GetNodes().GoPrevious( &aIdx )->FindPageDesc( FALSE );
887 if ( !pDefaultPageDesc )
889 // determine default page description
890 pDefaultPageDesc =
891 &const_cast<const SwDoc *>(pDoc)->GetPageDesc( 0 );
895 pDoc->SetModified();
897 // get current Language
898 SwTOXInternational aIntl( GetLanguage(),
899 TOX_INDEX == GetTOXType()->GetType() ?
900 GetOptions() : 0,
901 GetSortAlgorithm() );
903 aSortArr.DeleteAndDestroy( 0, aSortArr.Count() );
905 // find the first layout node for this TOX, if it only find the content
906 // in his own chapter
907 const SwTxtNode* pOwnChapterNode = IsFromChapter()
908 ? ::lcl_FindChapterNode( *pSectNd, 0 )
909 : 0;
911 SwNode2Layout aN2L( *pSectNd );
912 ((SwSectionNode*)pSectNd)->DelFrms();
914 // remove old content an insert one empty textnode (to hold the layout!)
915 SwTxtNode* pFirstEmptyNd;
917 pDoc->DeleteRedline( *pSectNd, true, USHRT_MAX );
919 SwNodeIndex aSttIdx( *pSectNd, +1 );
920 SwNodeIndex aEndIdx( *pSectNd->EndOfSectionNode() );
921 pFirstEmptyNd = pDoc->GetNodes().MakeTxtNode( aEndIdx,
922 pDoc->GetTxtCollFromPool( RES_POOLCOLL_TEXT ) );
925 // Task 70995 - save and restore PageDesc and Break Attributes
926 SwNodeIndex aNxtIdx( aSttIdx );
927 const SwCntntNode* pCNd = aNxtIdx.GetNode().GetCntntNode();
928 if( !pCNd )
929 pCNd = pDoc->GetNodes().GoNext( &aNxtIdx );
930 if( pCNd->HasSwAttrSet() )
932 SfxItemSet aBrkSet( pDoc->GetAttrPool(), aBreakSetRange );
933 aBrkSet.Put( *pCNd->GetpSwAttrSet() );
934 if( aBrkSet.Count() )
935 pFirstEmptyNd->SetAttr( aBrkSet );
938 aEndIdx--;
939 SwPosition aPos( aEndIdx, SwIndex( pFirstEmptyNd, 0 ));
940 pDoc->CorrAbs( aSttIdx, aEndIdx, aPos, TRUE );
942 // delete all before
943 DelFlyInRange( aSttIdx, aEndIdx );
944 _DelBookmarks( aSttIdx, aEndIdx );
946 pDoc->GetNodes().Delete( aSttIdx, aEndIdx.GetIndex() - aSttIdx.GetIndex() );
951 // insert title of TOX
952 if( GetTitle().Len() )
954 // then insert the headline section
955 SwNodeIndex aIdx( *pSectNd, +1 );
957 SwTxtNode* pHeadNd = pDoc->GetNodes().MakeTxtNode( aIdx,
958 GetTxtFmtColl( FORM_TITLE ) );
959 pHeadNd->Insert( GetTitle(), SwIndex( pHeadNd ));
961 String sNm( GetTOXName() );
962 // ??Resource
963 sNm.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "_Head" ));
965 SwSection aSect( TOX_HEADER_SECTION, sNm );
967 SwNodeIndex aStt( *pHeadNd ); aIdx--;
968 SwSectionFmt* pSectFmt = pDoc->MakeSectionFmt( 0 );
969 pDoc->GetNodes().InsertSection( aStt, *pSectFmt, aSect, &aIdx,
970 TRUE, FALSE );
973 // jetzt waere ein prima Zeitpunkt, um die Numerierung zu updaten
974 pDoc->UpdateNumRule();
976 if( GetCreateType() & nsSwTOXElement::TOX_MARK )
977 UpdateMarks( aIntl, pOwnChapterNode );
979 if( GetCreateType() & nsSwTOXElement::TOX_OUTLINELEVEL )
980 UpdateOutline( pOwnChapterNode );
982 if( GetCreateType() & nsSwTOXElement::TOX_TEMPLATE )
983 UpdateTemplate( pOwnChapterNode );
985 if( GetCreateType() & nsSwTOXElement::TOX_OLE ||
986 TOX_OBJECTS == SwTOXBase::GetType())
987 UpdateCntnt( nsSwTOXElement::TOX_OLE, pOwnChapterNode );
989 if( GetCreateType() & nsSwTOXElement::TOX_TABLE ||
990 (TOX_TABLES == SwTOXBase::GetType() && IsFromObjectNames()) )
991 UpdateTable( pOwnChapterNode );
993 if( GetCreateType() & nsSwTOXElement::TOX_GRAPHIC ||
994 (TOX_ILLUSTRATIONS == SwTOXBase::GetType() && IsFromObjectNames()))
995 UpdateCntnt( nsSwTOXElement::TOX_GRAPHIC, pOwnChapterNode );
997 if( GetSequenceName().Len() && !IsFromObjectNames() &&
998 (TOX_TABLES == SwTOXBase::GetType() ||
999 TOX_ILLUSTRATIONS == SwTOXBase::GetType() ) )
1000 UpdateSequence( pOwnChapterNode );
1002 if( GetCreateType() & nsSwTOXElement::TOX_FRAME )
1003 UpdateCntnt( nsSwTOXElement::TOX_FRAME, pOwnChapterNode );
1005 if(TOX_AUTHORITIES == SwTOXBase::GetType())
1006 UpdateAuthorities( aIntl );
1008 // Bei Bedarf Alphadelimitter einfuegen (nur bei Stichwoertern)
1010 if( TOX_INDEX == SwTOXBase::GetType() &&
1011 ( GetOptions() & nsSwTOIOptions::TOI_ALPHA_DELIMITTER ) )
1012 InsertAlphaDelimitter( aIntl );
1014 // sortierte Liste aller Verzeichnismarken und Verzeichnisbereiche
1015 void* p = 0;
1016 String* pStr = 0;
1017 USHORT nCnt = 0, nFormMax = GetTOXForm().GetFormMax();
1018 SvStringsDtor aStrArr( (BYTE)nFormMax );
1019 SvPtrarr aCollArr( (BYTE)nFormMax );
1020 for( ; nCnt < nFormMax; ++nCnt )
1022 aCollArr.Insert( p, nCnt );
1023 aStrArr.Insert( pStr, nCnt );
1026 SwNodeIndex aInsPos( *pFirstEmptyNd, 1 );
1027 for( nCnt = 0; nCnt < aSortArr.Count(); ++nCnt )
1029 ::SetProgressState( 0, pDoc->GetDocShell() );
1031 // setze den Text in das Verzeichniss
1032 USHORT nLvl = aSortArr[ nCnt ]->GetLevel();
1033 SwTxtFmtColl* pColl = (SwTxtFmtColl*)aCollArr[ nLvl ];
1034 if( !pColl )
1036 pColl = GetTxtFmtColl( nLvl );
1037 aCollArr.Remove( nLvl );
1038 p = pColl;
1039 aCollArr.Insert( p , nLvl );
1042 // Generierung: dynamische TabStops setzen
1043 SwTxtNode* pTOXNd = pDoc->GetNodes().MakeTxtNode( aInsPos , pColl );
1044 aSortArr[ nCnt ]->pTOXNd = pTOXNd;
1046 // Generierung: Form auswerten und Platzhalter
1047 // fuer die Seitennummer eintragen
1048 //if it is a TOX_INDEX and the SwForm IsCommaSeparated()
1049 // then a range of entries must be generated into one paragraph
1050 USHORT nRange = 1;
1051 if(TOX_INDEX == SwTOXBase::GetType() &&
1052 GetTOXForm().IsCommaSeparated() &&
1053 aSortArr[nCnt]->GetType() == TOX_SORT_INDEX)
1055 const SwTOXMark& rMark = aSortArr[nCnt]->pTxtMark->GetTOXMark();
1056 const String sPrimKey = rMark.GetPrimaryKey();
1057 const String sSecKey = rMark.GetSecondaryKey();
1058 const SwTOXMark* pNextMark = 0;
1059 while(aSortArr.Count() > (nCnt + nRange)&&
1060 aSortArr[nCnt + nRange]->GetType() == TOX_SORT_INDEX &&
1061 0 != (pNextMark = &(aSortArr[nCnt + nRange]->pTxtMark->GetTOXMark())) &&
1062 pNextMark->GetPrimaryKey() == sPrimKey &&
1063 pNextMark->GetSecondaryKey() == sSecKey)
1064 nRange++;
1066 // OD 18.03.2003 #106329# - pass node index of table-of-content section
1067 // and default page description to method <GenerateText(..)>.
1068 GenerateText( nCnt, nRange, aStrArr, pSectNd->GetIndex(), pDefaultPageDesc );
1069 nCnt += nRange - 1;
1072 // delete the first dummy node and remove all Cursor into the prev node
1073 aInsPos = *pFirstEmptyNd;
1075 SwPaM aCorPam( *pFirstEmptyNd );
1076 aCorPam.GetPoint()->nContent.Assign( pFirstEmptyNd, 0 );
1077 if( !aCorPam.Move( fnMoveForward ) )
1078 aCorPam.Move( fnMoveBackward );
1079 SwNodeIndex aEndIdx( aInsPos, 1 );
1080 pDoc->CorrAbs( aInsPos, aEndIdx, *aCorPam.GetPoint(), TRUE );
1082 // Task 70995 - save and restore PageDesc and Break Attributes
1083 if( pFirstEmptyNd->HasSwAttrSet() )
1085 if( GetTitle().Len() )
1086 aEndIdx = *pSectNd;
1087 else
1088 aEndIdx = *pFirstEmptyNd;
1089 SwCntntNode* pCNd = pDoc->GetNodes().GoNext( &aEndIdx );
1090 if( pCNd ) // Robust against defect documents, e.g. i60336
1091 pCNd->SetAttr( *pFirstEmptyNd->GetpSwAttrSet() );
1095 // now create the new Frames
1096 ULONG nIdx = pSectNd->GetIndex();
1097 // don't delete if index is empty
1098 if(nIdx + 2 < pSectNd->EndOfSectionIndex())
1099 pDoc->GetNodes().Delete( aInsPos, 1 );
1101 aN2L.RestoreUpperFrms( pDoc->GetNodes(), nIdx, nIdx + 1 );
1102 if(pDoc->GetRootFrm())
1103 SwFrm::CheckPageDescs( (SwPageFrm*)pDoc->GetRootFrm()->Lower() );
1105 SetProtect( SwTOXBase::IsProtected() );
1108 /*--------------------------------------------------------------------
1109 Beschreibung: AlphaDelimitter einfuegen
1110 --------------------------------------------------------------------*/
1113 void SwTOXBaseSection::InsertAlphaDelimitter( const SwTOXInternational& rIntl )
1115 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
1116 String sDeli, sLastDeli;
1117 USHORT i = 0;
1118 while( i < aSortArr.Count() )
1120 ::SetProgressState( 0, pDoc->GetDocShell() );
1122 USHORT nLevel = aSortArr[i]->GetLevel();
1124 // Alpha-Delimitter ueberlesen
1125 if( nLevel == FORM_ALPHA_DELIMITTER )
1126 continue;
1128 String sMyString, sMyStringReading;
1129 aSortArr[i]->GetTxt( sMyString, sMyStringReading );
1131 sDeli = rIntl.GetIndexKey( sMyString, sMyStringReading,
1132 aSortArr[i]->GetLocale() );
1134 // Delimitter schon vorhanden ??
1135 if( sDeli.Len() && sLastDeli != sDeli )
1137 // alle kleiner Blank wollen wir nicht haben -> sind Sonderzeichen
1138 if( ' ' <= sDeli.GetChar( 0 ) )
1140 SwTOXCustom* pCst = new SwTOXCustom( sDeli, aEmptyStr, FORM_ALPHA_DELIMITTER,
1141 rIntl, aSortArr[i]->GetLocale() );
1142 aSortArr.Insert( pCst, i++ );
1144 sLastDeli = sDeli;
1147 // Skippen bis gleibhes oder kleineres Level erreicht ist
1148 do {
1149 i++;
1150 } while (i < aSortArr.Count() && aSortArr[i]->GetLevel() > nLevel);
1154 /*--------------------------------------------------------------------
1155 Beschreibung: Template auswerten
1156 --------------------------------------------------------------------*/
1158 SwTxtFmtColl* SwTOXBaseSection::GetTxtFmtColl( USHORT nLevel )
1160 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
1161 const String& rName = GetTOXForm().GetTemplate( nLevel );
1162 SwTxtFmtColl* pColl = rName.Len() ? pDoc->FindTxtFmtCollByName(rName) :0;
1163 if( !pColl )
1165 USHORT nPoolFmt = 0;
1166 const TOXTypes eMyType = SwTOXBase::GetType();
1167 switch( eMyType )
1169 case TOX_INDEX: nPoolFmt = RES_POOLCOLL_TOX_IDXH; break;
1170 case TOX_USER:
1171 if( nLevel < 6 )
1172 nPoolFmt = RES_POOLCOLL_TOX_USERH;
1173 else
1174 nPoolFmt = RES_POOLCOLL_TOX_USER6 - 6;
1175 break;
1176 case TOX_ILLUSTRATIONS: nPoolFmt = RES_POOLCOLL_TOX_ILLUSH; break;
1177 case TOX_OBJECTS: nPoolFmt = RES_POOLCOLL_TOX_OBJECTH; break;
1178 case TOX_TABLES: nPoolFmt = RES_POOLCOLL_TOX_TABLESH; break;
1179 case TOX_AUTHORITIES: nPoolFmt = RES_POOLCOLL_TOX_AUTHORITIESH; break;
1181 case TOX_CONTENT:
1182 // im Content Bereich gibt es einen Sprung!
1183 if( nLevel < 6 )
1184 nPoolFmt = RES_POOLCOLL_TOX_CNTNTH;
1185 else
1186 nPoolFmt = RES_POOLCOLL_TOX_CNTNT6 - 6;
1187 break;
1190 if(eMyType == TOX_AUTHORITIES && nLevel)
1191 nPoolFmt = nPoolFmt + 1;
1192 else if(eMyType == TOX_INDEX && nLevel)
1194 //pool: Level 1,2,3, Delimiter
1195 //SwForm: Delimiter, Level 1,2,3
1196 nPoolFmt += 1 == nLevel ? nLevel + 3 : nLevel - 1;
1198 else
1199 nPoolFmt = nPoolFmt + nLevel;
1200 pColl = pDoc->GetTxtCollFromPool( nPoolFmt );
1202 return pColl;
1206 /*--------------------------------------------------------------------
1207 Beschreibung: Aus Markierungen erzeugen
1208 --------------------------------------------------------------------*/
1210 void SwTOXBaseSection::UpdateMarks( const SwTOXInternational& rIntl,
1211 const SwTxtNode* pOwnChapterNode )
1213 const SwModify* pType = SwTOXBase::GetRegisteredIn();
1214 if( !pType->GetDepends() )
1215 return;
1217 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
1218 TOXTypes eTOXTyp = GetTOXType()->GetType();
1219 SwClientIter aIter( *(SwModify*)pType );
1221 SwTxtTOXMark* pTxtMark;
1222 SwTOXMark* pMark;
1223 for( pMark = (SwTOXMark*)aIter.First( TYPE( SwTOXMark )); pMark;
1224 pMark = (SwTOXMark*)aIter.Next() )
1226 ::SetProgressState( 0, pDoc->GetDocShell() );
1228 if( pMark->GetTOXType()->GetType() == eTOXTyp &&
1229 0 != ( pTxtMark = pMark->GetTxtTOXMark() ) )
1231 const SwTxtNode* pTOXSrc = pTxtMark->GetpTxtNd();
1232 // nur TOXMarks einfuegen die im Doc stehen
1233 // nicht die, die im UNDO stehen
1235 // if selected use marks from the same chapter only
1236 if( pTOXSrc->GetNodes().IsDocNodes() &&
1237 pTOXSrc->GetTxt().Len() && pTOXSrc->GetDepends() &&
1238 pTOXSrc->GetFrm() &&
1239 (!IsFromChapter() || ::lcl_FindChapterNode( *pTOXSrc, 0 ) == pOwnChapterNode ) &&
1240 !pTOXSrc->HasHiddenParaField() &&
1241 !SwScriptInfo::IsInHiddenRange( *pTOXSrc, *pTxtMark->GetStart() ) )
1243 SwTOXSortTabBase* pBase = 0;
1244 if(TOX_INDEX == eTOXTyp)
1246 // Stichwortverzeichnismarkierung
1247 lang::Locale aLocale;
1248 if ( pBreakIt->GetBreakIter().is() )
1250 aLocale = pBreakIt->GetLocale(
1251 pTOXSrc->GetLang( *pTxtMark->GetStart() ) );
1254 pBase = new SwTOXIndex( *pTOXSrc, pTxtMark,
1255 GetOptions(), FORM_ENTRY, rIntl, aLocale );
1256 InsertSorted(pBase);
1257 if(GetOptions() & nsSwTOIOptions::TOI_KEY_AS_ENTRY &&
1258 pTxtMark->GetTOXMark().GetPrimaryKey().Len())
1260 pBase = new SwTOXIndex( *pTOXSrc, pTxtMark,
1261 GetOptions(), FORM_PRIMARY_KEY, rIntl, aLocale );
1262 InsertSorted(pBase);
1263 if(pTxtMark->GetTOXMark().GetSecondaryKey().Len())
1265 pBase = new SwTOXIndex( *pTOXSrc, pTxtMark,
1266 GetOptions(), FORM_SECONDARY_KEY, rIntl, aLocale );
1267 InsertSorted(pBase);
1271 else if( TOX_USER == eTOXTyp ||
1272 pMark->GetLevel() <= GetLevel())
1273 { // Inhaltsberzeichnismarkierung
1274 // also used for user marks
1275 pBase = new SwTOXContent( *pTOXSrc, pTxtMark, rIntl );
1276 InsertSorted(pBase);
1284 /*--------------------------------------------------------------------
1285 Beschreibung: Verzeichnisinhalt aus Gliederungsebene generieren
1286 --------------------------------------------------------------------*/
1289 void SwTOXBaseSection::UpdateOutline( const SwTxtNode* pOwnChapterNode )
1291 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
1292 SwNodes& rNds = pDoc->GetNodes();
1294 const SwOutlineNodes& rOutlNds = rNds.GetOutLineNds();
1295 for( USHORT n = 0; n < rOutlNds.Count(); ++n )
1297 ::SetProgressState( 0, pDoc->GetDocShell() );
1298 SwTxtNode* pTxtNd = rOutlNds[ n ]->GetTxtNode();
1299 if( pTxtNd && pTxtNd->Len() && pTxtNd->GetDepends() &&
1300 //USHORT(pTxtNd->GetTxtColl()->GetOutlineLevel()+1) <= GetLevel() && //#outline level,zhaojianwei
1301 USHORT( pTxtNd->GetAttrOutlineLevel()) <= GetLevel() && //<-end,zhaojianwei
1302 pTxtNd->GetFrm() &&
1303 !pTxtNd->HasHiddenParaField() &&
1304 !pTxtNd->HasHiddenCharAttribute( true ) &&
1305 ( !IsFromChapter() ||
1306 ::lcl_FindChapterNode( *pTxtNd, 0 ) == pOwnChapterNode ))
1308 SwTOXPara * pNew = new SwTOXPara( *pTxtNd, nsSwTOXElement::TOX_OUTLINELEVEL );
1309 InsertSorted( pNew );
1314 /*--------------------------------------------------------------------
1315 Beschreibung: Verzeichnisinhalt aus Vorlagenbereichen generieren
1316 --------------------------------------------------------------------*/
1318 void SwTOXBaseSection::UpdateTemplate( const SwTxtNode* pOwnChapterNode )
1320 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
1321 for(USHORT i = 0; i < MAXLEVEL; i++)
1323 String sTmpStyleNames = GetStyleNames(i);
1324 USHORT nTokenCount = sTmpStyleNames.GetTokenCount(TOX_STYLE_DELIMITER);
1325 for( USHORT nStyle = 0; nStyle < nTokenCount; ++nStyle )
1327 SwTxtFmtColl* pColl = pDoc->FindTxtFmtCollByName(
1328 sTmpStyleNames.GetToken( nStyle,
1329 TOX_STYLE_DELIMITER ));
1330 //TODO: no outline Collections in content indexes if OutlineLevels are already included
1331 if( !pColl ||
1332 ( TOX_CONTENT == SwTOXBase::GetType() &&
1333 GetCreateType() & nsSwTOXElement::TOX_OUTLINELEVEL &&
1334 //NO_NUMBERING != pColl->GetOutlineLevel() ) )//#outline level,zhaojianwei
1335 pColl->IsAssignedToListLevelOfOutlineStyle()) )//<-end,zhaojianwei
1336 continue;
1338 SwClientIter aIter( *pColl );
1339 SwTxtNode* pTxtNd = (SwTxtNode*)aIter.First( TYPE( SwTxtNode ));
1340 for( ; pTxtNd; pTxtNd = (SwTxtNode*)aIter.Next() )
1342 ::SetProgressState( 0, pDoc->GetDocShell() );
1344 if( pTxtNd->GetTxt().Len() && pTxtNd->GetFrm() &&
1345 pTxtNd->GetNodes().IsDocNodes() &&
1346 ( !IsFromChapter() || pOwnChapterNode ==
1347 ::lcl_FindChapterNode( *pTxtNd, 0 ) ) )
1349 SwTOXPara * pNew = new SwTOXPara( *pTxtNd, nsSwTOXElement::TOX_TEMPLATE, i + 1 );
1350 InsertSorted(pNew);
1357 /* -----------------14.07.99 09:59-------------------
1358 Description: generate content from sequence fields
1359 --------------------------------------------------*/
1360 void SwTOXBaseSection::UpdateSequence( const SwTxtNode* pOwnChapterNode )
1362 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
1363 SwFieldType* pSeqFld = pDoc->GetFldType(RES_SETEXPFLD, GetSequenceName(), false);
1364 if(!pSeqFld)
1365 return;
1367 SwClientIter aIter( *pSeqFld );
1368 SwFmtFld* pFmtFld = (SwFmtFld*)aIter.First( TYPE( SwFmtFld ));
1369 for( ; pFmtFld; pFmtFld = (SwFmtFld*)aIter.Next() )
1371 const SwTxtFld* pTxtFld = pFmtFld->GetTxtFld();
1372 if(!pTxtFld)
1373 continue;
1374 const SwTxtNode& rTxtNode = pTxtFld->GetTxtNode();
1375 ::SetProgressState( 0, pDoc->GetDocShell() );
1377 if( rTxtNode.GetTxt().Len() && rTxtNode.GetFrm() &&
1378 rTxtNode.GetNodes().IsDocNodes() &&
1379 ( !IsFromChapter() ||
1380 ::lcl_FindChapterNode( rTxtNode, 0 ) == pOwnChapterNode ) )
1382 SwTOXPara * pNew = new SwTOXPara( rTxtNode, nsSwTOXElement::TOX_SEQUENCE, 1 );
1383 //set indexes if the number or the reference text are to be displayed
1384 if( GetCaptionDisplay() == CAPTION_TEXT )
1386 pNew->SetStartIndex(
1387 SwGetExpField::GetReferenceTextPos( *pFmtFld, *pDoc ));
1389 else if(GetCaptionDisplay() == CAPTION_NUMBER)
1391 pNew->SetEndIndex(*pTxtFld->GetStart() + 1);
1393 InsertSorted(pNew);
1397 /* -----------------15.09.99 14:18-------------------
1399 --------------------------------------------------*/
1400 void SwTOXBaseSection::UpdateAuthorities( const SwTOXInternational& rIntl )
1402 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
1403 SwFieldType* pAuthFld = pDoc->GetFldType(RES_AUTHORITY, aEmptyStr, false);
1404 if(!pAuthFld)
1405 return;
1407 SwClientIter aIter( *pAuthFld );
1408 SwFmtFld* pFmtFld = (SwFmtFld*)aIter.First( TYPE( SwFmtFld ));
1409 for( ; pFmtFld; pFmtFld = (SwFmtFld*)aIter.Next() )
1411 const SwTxtFld* pTxtFld = pFmtFld->GetTxtFld();
1412 //undo
1413 if(!pTxtFld)
1414 continue;
1415 const SwTxtNode& rTxtNode = pTxtFld->GetTxtNode();
1416 ::SetProgressState( 0, pDoc->GetDocShell() );
1418 // const SwTxtNode* pChapterCompareNode = 0;
1420 if( rTxtNode.GetTxt().Len() && rTxtNode.GetFrm() &&
1421 rTxtNode.GetNodes().IsDocNodes() /*&&
1422 (!IsFromChapter() || pChapterCompareNode == pOwnChapterNode) */)
1424 //#106485# the body node has to be used!
1425 SwCntntFrm *pFrm = rTxtNode.GetFrm();
1426 SwPosition aFldPos(rTxtNode);
1427 const SwTxtNode* pTxtNode = 0;
1428 if(pFrm && !pFrm->IsInDocBody())
1429 pTxtNode = GetBodyTxtNode( *pDoc, aFldPos, *pFrm );
1430 if(!pTxtNode)
1431 pTxtNode = &rTxtNode;
1432 SwTOXAuthority* pNew = new SwTOXAuthority( *pTxtNode, *pFmtFld, rIntl );
1434 InsertSorted(pNew);
1439 long lcl_IsSOObject( const SvGlobalName& rFactoryNm )
1441 static struct _SoObjType {
1442 long nFlag;
1443 // GlobalNameId
1444 struct _GlobalNameIds {
1445 UINT32 n1;
1446 USHORT n2, n3;
1447 BYTE b8, b9, b10, b11, b12, b13, b14, b15;
1448 } aGlNmIds[4];
1449 } aArr[] = {
1450 { nsSwTOOElements::TOO_MATH,
1451 { {SO3_SM_CLASSID_60},{SO3_SM_CLASSID_50},
1452 {SO3_SM_CLASSID_40},{SO3_SM_CLASSID_30} } },
1453 { nsSwTOOElements::TOO_CHART,
1454 { {SO3_SCH_CLASSID_60},{SO3_SCH_CLASSID_50},
1455 {SO3_SCH_CLASSID_40},{SO3_SCH_CLASSID_30} } },
1456 { nsSwTOOElements::TOO_CALC,
1457 { {SO3_SC_CLASSID_60},{SO3_SC_CLASSID_50},
1458 {SO3_SC_CLASSID_40},{SO3_SC_CLASSID_30} } },
1459 { nsSwTOOElements::TOO_DRAW_IMPRESS,
1460 { {SO3_SIMPRESS_CLASSID_60},{SO3_SIMPRESS_CLASSID_50},
1461 {SO3_SIMPRESS_CLASSID_40},{SO3_SIMPRESS_CLASSID_30} } },
1462 { nsSwTOOElements::TOO_DRAW_IMPRESS,
1463 { {SO3_SDRAW_CLASSID_60},{SO3_SDRAW_CLASSID_50}}},
1464 { 0,{{0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0},
1465 {0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0} } }
1468 long nRet = 0;
1469 for( const _SoObjType* pArr = aArr; !nRet && pArr->nFlag; ++pArr )
1470 for ( int n = 0; n < 4; ++n )
1472 const _SoObjType::_GlobalNameIds& rId = pArr->aGlNmIds[ n ];
1473 if( !rId.n1 )
1474 break;
1475 SvGlobalName aGlbNm( rId.n1, rId.n2, rId.n3,
1476 rId.b8, rId.b9, rId.b10, rId.b11,
1477 rId.b12, rId.b13, rId.b14, rId.b15 );
1478 if( rFactoryNm == aGlbNm )
1480 nRet = pArr->nFlag;
1481 break;
1485 return nRet;
1488 void SwTOXBaseSection::UpdateCntnt( SwTOXElement eMyType,
1489 const SwTxtNode* pOwnChapterNode )
1491 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
1492 SwNodes& rNds = pDoc->GetNodes();
1493 // auf den 1. Node der 1. Section
1494 ULONG nIdx = rNds.GetEndOfAutotext().StartOfSectionIndex() + 2,
1495 nEndIdx = rNds.GetEndOfAutotext().GetIndex();
1497 while( nIdx < nEndIdx )
1499 ::SetProgressState( 0, pDoc->GetDocShell() );
1501 SwNode* pNd = rNds[ nIdx ];
1502 SwCntntNode* pCNd = 0;
1503 switch( eMyType )
1505 case nsSwTOXElement::TOX_FRAME:
1506 if( !pNd->IsNoTxtNode() )
1508 pCNd = pNd->GetCntntNode();
1509 if( !pCNd )
1511 SwNodeIndex aTmp( *pNd );
1512 pCNd = rNds.GoNext( &aTmp );
1515 break;
1516 case nsSwTOXElement::TOX_GRAPHIC:
1517 if( pNd->IsGrfNode() )
1518 pCNd = (SwCntntNode*)pNd;
1519 break;
1520 case nsSwTOXElement::TOX_OLE:
1521 if( pNd->IsOLENode() )
1523 BOOL bInclude = TRUE;
1524 if(TOX_OBJECTS == SwTOXBase::GetType())
1526 SwOLENode* pOLENode = pNd->GetOLENode();
1527 long nMyOLEOptions = GetOLEOptions();
1528 SwOLEObj& rOLEObj = pOLENode->GetOLEObj();
1530 if( rOLEObj.IsOleRef() ) //Noch nicht geladen
1532 SvGlobalName aTmpName = SvGlobalName( rOLEObj.GetOleRef()->getClassID() );
1533 long nObj = ::lcl_IsSOObject( aTmpName );
1534 bInclude = ( (nMyOLEOptions & nsSwTOOElements::TOO_OTHER) && 0 == nObj)
1535 || (0 != (nMyOLEOptions & nObj));
1537 else
1539 DBG_ERROR("OLE-object nicht geladen?");
1540 bInclude = FALSE;
1544 if(bInclude)
1545 pCNd = (SwCntntNode*)pNd;
1547 break;
1548 default: break;
1551 if( pCNd )
1553 //find node in body text
1554 int nSetLevel = USHRT_MAX;
1556 //#111105# tables of tables|illustrations|objects don't support hierarchies
1557 if( IsLevelFromChapter() &&
1558 TOX_TABLES != SwTOXBase::GetType() &&
1559 TOX_ILLUSTRATIONS != SwTOXBase::GetType() &&
1560 TOX_OBJECTS != SwTOXBase::GetType() )
1562 const SwTxtNode* pOutlNd = ::lcl_FindChapterNode( *pCNd,
1563 MAXLEVEL - 1 );
1564 if( pOutlNd )
1566 //USHORT nTmp = pOutlNd->GetTxtColl()->GetOutlineLevel();//#outline level,zhaojianwei
1567 //if( nTmp < NO_NUMBERING )
1568 // nSetLevel = nTmp + 1;
1569 if( pOutlNd->GetTxtColl()->IsAssignedToListLevelOfOutlineStyle())
1570 nSetLevel = pOutlNd->GetTxtColl()->GetAttrOutlineLevel() ;//<-end,zhaojianwei
1574 if( pCNd->GetFrm() && ( !IsFromChapter() ||
1575 ::lcl_FindChapterNode( *pCNd, 0 ) == pOwnChapterNode ))
1577 SwTOXPara * pNew = new SwTOXPara( *pCNd, eMyType,
1578 ( USHRT_MAX != nSetLevel )
1579 ? static_cast<USHORT>(nSetLevel)
1580 : FORM_ALPHA_DELIMITTER );
1581 InsertSorted( pNew );
1585 nIdx = pNd->StartOfSectionNode()->EndOfSectionIndex() + 2; // 2 == End-/StartNode
1589 /*--------------------------------------------------------------------
1590 Beschreibung: Tabelleneintraege zusammensuchen
1591 --------------------------------------------------------------------*/
1593 void SwTOXBaseSection::UpdateTable( const SwTxtNode* pOwnChapterNode )
1595 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
1596 SwNodes& rNds = pDoc->GetNodes();
1597 const SwFrmFmts& rArr = *pDoc->GetTblFrmFmts();
1599 for( USHORT n = 0; n < rArr.Count(); ++n )
1601 ::SetProgressState( 0, pDoc->GetDocShell() );
1603 SwTable* pTmpTbl = SwTable::FindTable( rArr[ n ] );
1604 SwTableBox* pFBox;
1605 if( pTmpTbl && 0 != (pFBox = pTmpTbl->GetTabSortBoxes()[0] ) &&
1606 pFBox->GetSttNd() && pFBox->GetSttNd()->GetNodes().IsDocNodes() )
1608 const SwTableNode* pTblNd = pFBox->GetSttNd()->FindTableNode();
1609 SwNodeIndex aCntntIdx( *pTblNd, 1 );
1611 SwCntntNode* pCNd;
1612 while( 0 != ( pCNd = rNds.GoNext( &aCntntIdx ) ) &&
1613 aCntntIdx.GetIndex() < pTblNd->EndOfSectionIndex() )
1615 if( pCNd->GetFrm() && (!IsFromChapter() ||
1616 ::lcl_FindChapterNode( *pCNd, 0 ) == pOwnChapterNode ))
1618 SwTOXTable * pNew = new SwTOXTable( *pCNd );
1619 if( IsLevelFromChapter() && TOX_TABLES != SwTOXBase::GetType())
1621 const SwTxtNode* pOutlNd =
1622 ::lcl_FindChapterNode( *pCNd, MAXLEVEL - 1 );
1623 if( pOutlNd )
1625 //USHORT nTmp = pOutlNd->GetTxtColl()->GetOutlineLevel();//#outline level,zhaojianwei
1626 //if( nTmp < NO_NUMBERING )
1627 // pNew->SetLevel( nTmp + 1 );
1628 if( pOutlNd->GetTxtColl()->IsAssignedToListLevelOfOutlineStyle())
1630 const int nTmp = pOutlNd->GetTxtColl()->GetAttrOutlineLevel();
1631 pNew->SetLevel( static_cast<USHORT>(nTmp) );//<-end ,zhaojianwei
1635 InsertSorted(pNew);
1636 break;
1643 /*--------------------------------------------------------------------
1644 Beschreibung: String generieren anhand der Form
1645 SonderZeichen 0-31 und 255 entfernen
1646 --------------------------------------------------------------------*/
1648 String lcl_GetNumString( const SwTOXSortTabBase& rBase, sal_Bool bUsePrefix, BYTE nLevel )
1650 String sRet;
1652 if( !rBase.pTxtMark && rBase.aTOXSources.Count() > 0 )
1653 { // nur wenn es keine Marke ist
1654 const SwTxtNode* pNd = rBase.aTOXSources[0].pNd->GetTxtNode();
1655 if( pNd )
1657 const SwNumRule* pRule = pNd->GetNumRule();
1659 if( pRule && pNd->GetActualListLevel() < MAXLEVEL )
1660 sRet = pNd->GetNumString(bUsePrefix, nLevel);
1663 return sRet;
1666 // OD 18.03.2003 #106329# - add parameter <_TOXSectNdIdx> and <_pDefaultPageDesc>
1667 // in order to control, which page description is used, no appropriate one is found.
1668 void SwTOXBaseSection::GenerateText( USHORT nArrayIdx,
1669 USHORT nCount,
1670 SvStringsDtor& ,
1671 const sal_uInt32 _nTOXSectNdIdx,
1672 const SwPageDesc* _pDefaultPageDesc )
1674 LinkStructArr aLinkArr;
1675 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
1676 ::SetProgressState( 0, pDoc->GetDocShell() );
1678 //pTOXNd is only set at the first mark
1679 SwTxtNode* pTOXNd = (SwTxtNode*)aSortArr[nArrayIdx]->pTOXNd;
1680 String& rTxt = (String&)pTOXNd->GetTxt();
1681 rTxt.Erase();
1682 for(USHORT nIndex = nArrayIdx; nIndex < nArrayIdx + nCount; nIndex++)
1684 if(nIndex > nArrayIdx)
1685 rTxt.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ", " )); // comma separation
1686 // String mit dem Pattern aus der Form initialisieren
1687 const SwTOXSortTabBase& rBase = *aSortArr[nIndex];
1688 USHORT nLvl = rBase.GetLevel();
1689 ASSERT( nLvl < GetTOXForm().GetFormMax(), "ungueltiges FORM_LEVEL");
1691 SvxTabStopItem aTStops( 0, 0, SVX_TAB_ADJUST_DEFAULT, RES_PARATR_TABSTOP );
1692 xub_StrLen nLinkStartPosition = STRING_NOTFOUND;
1693 String sLinkCharacterStyle; //default to "Default" character style - which is none
1694 String sURL;
1695 // create an enumerator
1696 // #i21237#
1697 SwFormTokens aPattern = GetTOXForm().GetPattern(nLvl);
1698 SwFormTokens::iterator aIt = aPattern.begin();
1699 // remove text from node
1700 while(aIt != aPattern.end()) // #i21237#
1702 SwFormToken aToken = *aIt; // #i21237#
1703 xub_StrLen nStartCharStyle = rTxt.Len();
1704 switch( aToken.eTokenType )
1706 case TOKEN_ENTRY_NO:
1707 // fuer Inhaltsverzeichnis Numerierung
1708 rTxt.Insert( lcl_GetNumString( rBase, aToken.nChapterFormat == CF_NUMBER, static_cast<BYTE>(aToken.nOutlineLevel - 1)) );
1709 break;
1711 case TOKEN_ENTRY_TEXT:
1713 SwIndex aIdx( pTOXNd, rTxt.Len() );
1714 rBase.FillText( *pTOXNd, aIdx );
1716 break;
1718 case TOKEN_ENTRY:
1720 // fuer Inhaltsverzeichnis Numerierung
1721 rTxt.Insert( lcl_GetNumString( rBase, sal_True, MAXLEVEL ));
1723 SwIndex aIdx( pTOXNd, rTxt.Len() );
1724 rBase.FillText( *pTOXNd, aIdx );
1726 break;
1728 case TOKEN_TAB_STOP:
1729 if (aToken.bWithTab) // #i21237#
1730 rTxt.Append('\t');
1733 if(SVX_TAB_ADJUST_END > aToken.eTabAlign)
1735 const SvxLRSpaceItem& rLR =
1736 (SvxLRSpaceItem&)pTOXNd->
1737 SwCntntNode::GetAttr( RES_LR_SPACE, TRUE );
1739 long nTabPosition = aToken.nTabStopPosition;
1740 if( !GetTOXForm().IsRelTabPos() && rLR.GetTxtLeft() )
1741 nTabPosition -= rLR.GetTxtLeft();
1742 aTStops.Insert( SvxTabStop( nTabPosition,
1743 aToken.eTabAlign,
1744 cDfltDecimalChar,
1745 aToken.cTabFillChar ));
1747 else
1749 const SwPageDesc* pPageDesc = ((SwFmtPageDesc&)pTOXNd->
1750 SwCntntNode::GetAttr( RES_PAGEDESC )).GetPageDesc();
1752 BOOL bCallFindRect = TRUE;
1753 long nRightMargin;
1754 if( pPageDesc )
1756 const SwFrm* pFrm = pTOXNd->GetFrm( 0, 0, TRUE );
1757 if( !pFrm || 0 == ( pFrm = pFrm->FindPageFrm() ) ||
1758 pPageDesc != ((SwPageFrm*)pFrm)->GetPageDesc() )
1759 // dann muss man ueber den PageDesc gehen
1760 bCallFindRect = FALSE;
1763 SwRect aNdRect;
1764 if( bCallFindRect )
1765 aNdRect = pTOXNd->FindLayoutRect( TRUE );
1767 if( aNdRect.IsEmpty() )
1769 // dann hilft alles nichts, wir muessen ueber die Seiten-
1770 // vorlage gehen.
1771 // OD 18.03.2003 #106329# - call
1772 sal_uInt32 nPgDescNdIdx = pTOXNd->GetIndex() + 1;
1773 sal_uInt32* pPgDescNdIdx = &nPgDescNdIdx;
1774 pPageDesc = pTOXNd->FindPageDesc( FALSE, pPgDescNdIdx );
1775 if ( !pPageDesc ||
1776 *pPgDescNdIdx < _nTOXSectNdIdx )
1778 // use default page description, if none is found
1779 // or the found one is given by a node before the
1780 // table-of-content section.
1781 pPageDesc = _pDefaultPageDesc;
1784 const SwFrmFmt& rPgDscFmt = pPageDesc->GetMaster();
1785 nRightMargin = rPgDscFmt.GetFrmSize().GetWidth() -
1786 rPgDscFmt.GetLRSpace().GetLeft() -
1787 rPgDscFmt.GetLRSpace().GetRight();
1789 else
1790 nRightMargin = aNdRect.Width();
1791 //#i24363# tab stops relative to indent
1792 if( pDoc->get(IDocumentSettingAccess::TABS_RELATIVE_TO_INDENT) )
1794 //left margin of paragraph style
1795 const SvxLRSpaceItem& rLRSpace = pTOXNd->GetTxtColl()->GetLRSpace();
1796 nRightMargin -= rLRSpace.GetLeft();
1797 nRightMargin -= rLRSpace.GetTxtFirstLineOfst();
1800 aTStops.Insert( SvxTabStop( nRightMargin, SVX_TAB_ADJUST_RIGHT,
1801 cDfltDecimalChar,
1802 aToken.cTabFillChar ));
1804 break;
1806 case TOKEN_TEXT:
1807 rTxt.Append( aToken.sText );
1808 break;
1810 case TOKEN_PAGE_NUMS:
1811 // Platzhalter fuer Seitennummer(n) es wird nur der erste beachtet
1814 // Die Anzahl der gleichen Eintrage bestimmt die Seitennummern-Pattern
1816 USHORT nSize = rBase.aTOXSources.Count();
1817 if( nSize > 0 )
1819 String aInsStr( cNumRepl );
1820 for(USHORT i=1; i < nSize; ++i)
1822 aInsStr.AppendAscii( sPageDeli );
1823 aInsStr += cNumRepl;
1825 aInsStr += cEndPageNum;
1826 rTxt.Append( aInsStr );
1828 // // Tab entfernen, wenn keine Seitennummer
1829 // else if( rTxt.Len() && '\t' == rTxt.GetChar( rTxt.Len() - 1 ))
1830 // rTxt.Erase( rTxt.Len()-1, 1 );
1832 break;
1834 case TOKEN_CHAPTER_INFO:
1836 // ein bischen trickreich: suche irgend einen Frame
1837 const SwTOXSource* pTOXSource = 0;
1838 if(rBase.aTOXSources.Count())
1839 pTOXSource = &rBase.aTOXSources[0];
1841 // --> OD 2008-02-14 #i53420#
1842 // if( pTOXSource && pTOXSource->pNd
1843 // pTOXSource->pNd->IsTxtNode() )
1844 if ( pTOXSource && pTOXSource->pNd &&
1845 pTOXSource->pNd->IsCntntNode() )
1846 // <--
1848 const SwCntntFrm* pFrm = pTOXSource->pNd->GetFrm();
1849 if( pFrm )
1851 SwChapterFieldType aFldTyp;
1852 SwChapterField aFld( &aFldTyp, aToken.nChapterFormat );
1853 aFld.SetLevel( static_cast<BYTE>(aToken.nOutlineLevel - 1) );
1854 // --> OD 2008-02-14 #i53420#
1855 // aFld.ChangeExpansion( pFrm, (SwTxtNode*)pTOXSource->pNd, TRUE );
1856 aFld.ChangeExpansion( pFrm,
1857 dynamic_cast<const SwCntntNode*>(pTOXSource->pNd),
1858 TRUE );
1859 // <--
1860 //---> i89791
1861 // OD 2008-06-26 - continue to support CF_NUMBER
1862 // and CF_NUM_TITLE in order to handle ODF 1.0/1.1
1863 // written by OOo 3.x in the same way as OOo 2.x
1864 // would handle them.
1865 if ( CF_NUM_NOPREPST_TITLE == aToken.nChapterFormat ||
1866 CF_NUMBER == aToken.nChapterFormat )
1867 rTxt.Insert(aFld.GetNumber()); //get the string number without pre/postfix
1868 else if ( CF_NUMBER_NOPREPST == aToken.nChapterFormat ||
1869 CF_NUM_TITLE == aToken.nChapterFormat )
1870 //<---
1872 rTxt += aFld.GetNumber();
1873 rTxt += ' ';
1874 rTxt += aFld.GetTitle();
1876 else if(CF_TITLE == aToken.nChapterFormat)
1877 rTxt += aFld.GetTitle();
1881 break;
1883 case TOKEN_LINK_START:
1884 nLinkStartPosition = rTxt.Len();
1885 sLinkCharacterStyle = aToken.sCharStyleName;
1886 break;
1888 case TOKEN_LINK_END:
1889 //TODO: only paired start/end tokens are valid
1890 if( STRING_NOTFOUND != nLinkStartPosition)
1892 SwIndex aIdx( pTOXNd, nLinkStartPosition );
1893 //pTOXNd->Erase( aIdx, SwForm::nFormLinkSttLen );
1894 xub_StrLen nEnd = rTxt.Len();
1896 if( !sURL.Len() )
1898 sURL = rBase.GetURL();
1899 if( !sURL.Len() )
1900 break;
1902 LinkStruct* pNewLink = new LinkStruct(sURL, nLinkStartPosition,
1903 nEnd);
1904 pNewLink->aINetFmt.SetVisitedFmt(sLinkCharacterStyle);
1905 pNewLink->aINetFmt.SetINetFmt(sLinkCharacterStyle);
1906 if(sLinkCharacterStyle.Len())
1908 USHORT nPoolId =
1909 SwStyleNameMapper::GetPoolIdFromUIName( sLinkCharacterStyle, nsSwGetPoolIdFromName::GET_POOLID_CHRFMT );
1910 pNewLink->aINetFmt.SetVisitedFmtId(nPoolId);
1911 pNewLink->aINetFmt.SetINetFmtId(nPoolId);
1913 else
1915 pNewLink->aINetFmt.SetVisitedFmtId(USHRT_MAX);
1916 pNewLink->aINetFmt.SetINetFmtId(USHRT_MAX);
1918 aLinkArr.Insert( pNewLink, aLinkArr.Count() );
1919 nLinkStartPosition = STRING_NOTFOUND;
1920 sLinkCharacterStyle.Erase();
1922 break;
1924 case TOKEN_AUTHORITY:
1926 ToxAuthorityField eField = (ToxAuthorityField)aToken.nAuthorityField;
1927 SwIndex aIdx( pTOXNd, rTxt.Len() );
1928 rBase.FillText( *pTOXNd, aIdx, static_cast<USHORT>(eField) );
1930 break;
1931 case TOKEN_END: break;
1934 if( aToken.sCharStyleName.Len() )
1936 SwCharFmt* pCharFmt;
1937 if( USHRT_MAX != aToken.nPoolId )
1938 pCharFmt = pDoc->GetCharFmtFromPool( aToken.nPoolId );
1939 else
1940 pCharFmt = pDoc->FindCharFmtByName( aToken.sCharStyleName);
1942 if(pCharFmt)
1943 pTOXNd->InsertItem( SwFmtCharFmt( pCharFmt ), nStartCharStyle,
1944 rTxt.Len(), nsSetAttrMode::SETATTR_DONTEXPAND );
1947 aIt++; // #i21237#
1950 pTOXNd->SetAttr( aTStops );
1953 if(aLinkArr.Count())
1954 for(USHORT i = 0; i < aLinkArr.Count(); ++i )
1956 LinkStruct* pTmp = aLinkArr.GetObject(i);
1957 pTOXNd->InsertItem( pTmp->aINetFmt, pTmp->nStartTextPos,
1958 pTmp->nEndTextPos);
1962 /*--------------------------------------------------------------------
1963 Beschreibung: Seitennummer errechnen und nach dem Formatieren
1964 eintragen
1965 --------------------------------------------------------------------*/
1967 void SwTOXBaseSection::UpdatePageNum()
1969 if( !aSortArr.Count() )
1970 return ;
1972 // die aktuellen Seitennummern ins Verzeichnis eintragen
1973 SwPageFrm* pAktPage = 0;
1974 USHORT nPage = 0;
1975 SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
1977 SwTOXInternational aIntl( GetLanguage(),
1978 TOX_INDEX == GetTOXType()->GetType() ?
1979 GetOptions() : 0,
1980 GetSortAlgorithm() );
1982 for( USHORT nCnt = 0; nCnt < aSortArr.Count(); ++nCnt )
1984 // Schleife ueber alle SourceNodes
1985 SvUShorts aNums; //Die Seitennummern
1986 SvPtrarr aDescs; //Die PageDescriptoren passend zu den Seitennummern.
1987 SvUShorts* pMainNums = 0; // contains page numbers of main entries
1989 // process run in lines
1990 USHORT nRange = 0;
1991 if(GetTOXForm().IsCommaSeparated() &&
1992 aSortArr[nCnt]->GetType() == TOX_SORT_INDEX)
1994 const SwTOXMark& rMark = aSortArr[nCnt]->pTxtMark->GetTOXMark();
1995 const String sPrimKey = rMark.GetPrimaryKey();
1996 const String sSecKey = rMark.GetSecondaryKey();
1997 const SwTOXMark* pNextMark = 0;
1998 while(aSortArr.Count() > (nCnt + nRange)&&
1999 aSortArr[nCnt + nRange]->GetType() == TOX_SORT_INDEX &&
2000 0 != (pNextMark = &(aSortArr[nCnt + nRange]->pTxtMark->GetTOXMark())) &&
2001 pNextMark->GetPrimaryKey() == sPrimKey &&
2002 pNextMark->GetSecondaryKey() == sSecKey)
2003 nRange++;
2005 else
2006 nRange = 1;
2008 for(USHORT nRunInEntry = nCnt; nRunInEntry < nCnt + nRange; nRunInEntry++)
2010 SwTOXSortTabBase* pSortBase = aSortArr[nRunInEntry];
2011 USHORT nSize = pSortBase->aTOXSources.Count();
2012 USHORT i;
2013 for( USHORT j = 0; j < nSize; ++j )
2015 ::SetProgressState( 0, pDoc->GetDocShell() );
2017 SwTOXSource& rTOXSource = pSortBase->aTOXSources[j];
2018 if( rTOXSource.pNd )
2020 SwCntntFrm* pFrm = rTOXSource.pNd->GetFrm();
2021 ASSERT( pFrm || pDoc->IsUpdateTOX(), "TOX, no Frame found");
2022 if( !pFrm )
2023 continue;
2024 if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->HasFollow() )
2026 // dann suche den richtigen heraus
2027 SwTxtFrm* pNext = (SwTxtFrm*)pFrm;
2028 while( 0 != ( pNext = (SwTxtFrm*)pFrm->GetFollow() )
2029 && rTOXSource.nPos >= pNext->GetOfst() )
2030 pFrm = pNext;
2033 SwPageFrm* pTmpPage = pFrm->FindPageFrm();
2034 if( pTmpPage != pAktPage )
2036 nPage = pTmpPage->GetVirtPageNum();
2037 pAktPage = pTmpPage;
2040 // sortiert einfuegen
2041 for( i = 0; i < aNums.Count() && aNums[i] < nPage; ++i )
2044 if( i >= aNums.Count() || aNums[ i ] != nPage )
2046 aNums.Insert( nPage, i );
2047 aDescs.Insert( (void*)pAktPage->GetPageDesc(), i );
2049 // is it a main entry?
2050 if(TOX_SORT_INDEX == pSortBase->GetType() &&
2051 rTOXSource.bMainEntry)
2053 if(!pMainNums)
2054 pMainNums = new SvUShorts;
2055 pMainNums->Insert(nPage, pMainNums->Count());
2059 // einfuegen der Seitennummer in den Verzeichnis-Text-Node
2060 const SwTOXSortTabBase* pBase = aSortArr[ nCnt ];
2061 if(pBase->pTOXNd)
2063 const SwTxtNode* pTxtNd = pBase->pTOXNd->GetTxtNode();
2064 ASSERT( pTxtNd, "kein TextNode, falsches Verzeichnis" );
2066 _UpdatePageNum( (SwTxtNode*)pTxtNd, aNums, aDescs, pMainNums,
2067 aIntl );
2069 DELETEZ(pMainNums);
2070 aNums.Remove(0, aNums.Count());
2073 // nach dem Setzen der richtigen Seitennummer, das Mapping-Array
2074 // wieder loeschen !!
2075 aSortArr.DeleteAndDestroy( 0, aSortArr.Count() );
2079 /*--------------------------------------------------------------------
2080 Beschreibung: Austausch der Seitennummer-Platzhalter
2081 --------------------------------------------------------------------*/
2083 // search for the page no in the array of main entry page numbers
2084 BOOL lcl_HasMainEntry( const SvUShorts* pMainEntryNums, USHORT nToFind )
2086 for(USHORT i = 0; pMainEntryNums && i < pMainEntryNums->Count(); ++i)
2087 if(nToFind == (*pMainEntryNums)[i])
2088 return TRUE;
2089 return FALSE;
2092 void SwTOXBaseSection::_UpdatePageNum( SwTxtNode* pNd,
2093 const SvUShorts& rNums,
2094 const SvPtrarr & rDescs,
2095 const SvUShorts* pMainEntryNums,
2096 const SwTOXInternational& rIntl )
2098 //collect starts end ends of main entry character style
2099 SvUShorts* pCharStyleIdx = pMainEntryNums ? new SvUShorts : 0;
2101 String sSrchStr( cNumRepl );
2102 sSrchStr.AppendAscii( sPageDeli ) += cNumRepl;
2103 xub_StrLen nStartPos = pNd->GetTxt().Search( sSrchStr );
2104 ( sSrchStr = cNumRepl ) += cEndPageNum;
2105 xub_StrLen nEndPos = pNd->GetTxt().Search( sSrchStr );
2106 USHORT i;
2108 if( STRING_NOTFOUND == nEndPos || !rNums.Count() )
2109 return;
2111 if( STRING_NOTFOUND == nStartPos || nStartPos > nEndPos)
2112 nStartPos = nEndPos;
2114 USHORT nOld = rNums[0],
2115 nBeg = nOld,
2116 nCount = 0;
2117 String aNumStr( SvxNumberType( ((SwPageDesc*)rDescs[0])->GetNumType() ).
2118 GetNumStr( nBeg ) );
2119 if( pCharStyleIdx && lcl_HasMainEntry( pMainEntryNums, nBeg ))
2121 USHORT nTemp = 0;
2122 pCharStyleIdx->Insert( nTemp, pCharStyleIdx->Count());
2125 // Platzhalter loeschen
2126 SwIndex aPos(pNd, nStartPos);
2127 SwCharFmt* pPageNoCharFmt = 0;
2128 SwpHints* pHints = pNd->GetpSwpHints();
2129 if(pHints)
2130 for(USHORT nHintIdx = 0; nHintIdx < pHints->GetStartCount(); nHintIdx++)
2132 SwTxtAttr* pAttr = pHints->GetStart(nHintIdx);
2133 xub_StrLen nTmpEnd = pAttr->GetEnd() ? *pAttr->GetEnd() : 0;
2134 if( nStartPos >= *pAttr->GetStart() &&
2135 (nStartPos + 2) <= nTmpEnd &&
2136 pAttr->Which() == RES_TXTATR_CHARFMT)
2138 pPageNoCharFmt = pAttr->GetCharFmt().GetCharFmt();
2139 break;
2142 pNd->Erase(aPos, nEndPos - nStartPos + 2);
2144 for( i = 1; i < rNums.Count(); ++i)
2146 SvxNumberType aType( ((SwPageDesc*)rDescs[i])->GetNumType() );
2147 if( TOX_INDEX == SwTOXBase::GetType() )
2148 { // Zusammenfassen f. ff.
2149 // Alle folgenden aufaddieren
2150 // break up if main entry starts or ends and
2151 // insert a char style index
2152 BOOL bMainEntryChanges = lcl_HasMainEntry(pMainEntryNums, nOld)
2153 != lcl_HasMainEntry(pMainEntryNums, rNums[i]);
2155 if(nOld == rNums[i]-1 && !bMainEntryChanges &&
2156 0 != (GetOptions() & (nsSwTOIOptions::TOI_FF|nsSwTOIOptions::TOI_DASH)))
2157 nCount++;
2158 else
2160 // ff. f. alten Wert flushen
2161 if(GetOptions() & nsSwTOIOptions::TOI_FF)
2163 if ( nCount >= 1 )
2164 aNumStr += rIntl.GetFollowingText( nCount > 1 );
2166 else
2168 if(nCount >= 2 )
2169 aNumStr += '-';
2170 else if(nCount == 1 )
2171 aNumStr.AppendAscii( sPageDeli );
2172 //#58127# Wenn nCount == 0, dann steht die einzige Seitenzahl schon im aNumStr!
2173 if(nCount)
2174 aNumStr += aType.GetNumStr( nBeg + nCount );
2177 // neuen String anlegen
2178 nBeg = rNums[i];
2179 aNumStr.AppendAscii( sPageDeli );
2180 //the change of the character style must apply after sPageDeli is appended
2181 if(pCharStyleIdx && bMainEntryChanges)
2182 pCharStyleIdx->Insert(aNumStr.Len(),
2183 pCharStyleIdx->Count());
2184 aNumStr += aType.GetNumStr( nBeg );
2185 nCount = 0;
2187 nOld = rNums[i];
2189 else
2190 { // Alle Nummern eintragen
2191 aNumStr += aType.GetNumStr( USHORT(rNums[i]) );
2192 if(i != (rNums.Count()-1))
2193 aNumStr.AppendAscii( sPageDeli );
2196 // Bei Ende und ff. alten Wert flushen
2197 if( TOX_INDEX == SwTOXBase::GetType() )
2199 if(GetOptions() & nsSwTOIOptions::TOI_FF)
2201 if( nCount >= 1 )
2202 aNumStr += rIntl.GetFollowingText( nCount > 1 );
2204 else
2206 if(nCount >= 2)
2207 aNumStr +='-';
2208 else if(nCount == 1)
2209 aNumStr.AppendAscii( sPageDeli );
2210 //#58127# Wenn nCount == 0, dann steht die einzige Seitenzahl schon im aNumStr!
2211 if(nCount)
2212 aNumStr += SvxNumberType( ((SwPageDesc*)rDescs[i-1])->
2213 GetNumType() ).GetNumStr( nBeg+nCount );
2216 pNd->Insert( aNumStr, aPos, INS_EMPTYEXPAND );
2217 if(pPageNoCharFmt)
2219 SwFmtCharFmt aCharFmt( pPageNoCharFmt );
2220 pNd->InsertItem(aCharFmt, nStartPos, nStartPos + aNumStr.Len(), nsSetAttrMode::SETATTR_DONTEXPAND);
2223 //now the main entries should get there character style
2224 if(pCharStyleIdx && pCharStyleIdx->Count() && GetMainEntryCharStyle().Len())
2226 // eventually the last index must me appended
2227 if(pCharStyleIdx->Count()&0x01)
2228 pCharStyleIdx->Insert(aNumStr.Len(), pCharStyleIdx->Count());
2230 //search by name
2231 SwDoc* pDoc = pNd->GetDoc();
2232 USHORT nPoolId = SwStyleNameMapper::GetPoolIdFromUIName( GetMainEntryCharStyle(), nsSwGetPoolIdFromName::GET_POOLID_CHRFMT );
2233 SwCharFmt* pCharFmt = 0;
2234 if(USHRT_MAX != nPoolId)
2235 pCharFmt = pDoc->GetCharFmtFromPool(nPoolId);
2236 else
2237 pCharFmt = pDoc->FindCharFmtByName( GetMainEntryCharStyle() );
2238 if(!pCharFmt)
2239 pCharFmt = pDoc->MakeCharFmt(GetMainEntryCharStyle(), 0);
2241 //find the page numbers in aNumStr and set the character style
2242 xub_StrLen nOffset = pNd->GetTxt().Len() - aNumStr.Len();
2243 SwFmtCharFmt aCharFmt(pCharFmt);
2244 for(USHORT j = 0; j < pCharStyleIdx->Count(); j += 2)
2246 xub_StrLen nStartIdx = (*pCharStyleIdx)[j] + nOffset;
2247 xub_StrLen nEndIdx = (*pCharStyleIdx)[j + 1] + nOffset;
2248 pNd->InsertItem(aCharFmt, nStartIdx, nEndIdx, nsSetAttrMode::SETATTR_DONTEXPAND);
2252 delete pCharStyleIdx;
2256 /*--------------------------------------------------------------------
2257 Beschreibung: Sortiert einfuegen in das SortArr
2258 --------------------------------------------------------------------*/
2260 void SwTOXBaseSection::InsertSorted(SwTOXSortTabBase* pNew)
2262 Range aRange(0, aSortArr.Count());
2263 if( TOX_INDEX == SwTOXBase::GetType() && pNew->pTxtMark )
2265 const SwTOXMark& rMark = pNew->pTxtMark->GetTOXMark();
2266 // Schluessel auswerten
2267 // Den Bereich ermitteln, in dem einzufuegen ist
2268 if( 0 == (GetOptions() & nsSwTOIOptions::TOI_KEY_AS_ENTRY) &&
2269 rMark.GetPrimaryKey().Len() )
2271 aRange = GetKeyRange( rMark.GetPrimaryKey(),
2272 rMark.GetPrimaryKeyReading(),
2273 *pNew, FORM_PRIMARY_KEY, aRange );
2275 if( rMark.GetSecondaryKey().Len() )
2276 aRange = GetKeyRange( rMark.GetSecondaryKey(),
2277 rMark.GetSecondaryKeyReading(),
2278 *pNew, FORM_SECONDARY_KEY, aRange );
2281 //search for identical entries and remove the trailing one
2282 if(TOX_AUTHORITIES == SwTOXBase::GetType())
2284 for(short i = (short)aRange.Min(); i < (short)aRange.Max(); ++i)
2286 SwTOXSortTabBase* pOld = aSortArr[i];
2287 if(*pOld == *pNew)
2289 if(*pOld < *pNew)
2291 delete pNew;
2292 return;
2294 else
2296 // remove the old content
2297 aSortArr.DeleteAndDestroy( i, 1 );
2298 aRange.Max()--;
2299 break;
2305 // find position and insert
2307 short i;
2309 for( i = (short)aRange.Min(); i < (short)aRange.Max(); ++i)
2310 { // nur auf gleicher Ebene pruefen
2312 SwTOXSortTabBase* pOld = aSortArr[i];
2313 if(*pOld == *pNew)
2315 if(TOX_AUTHORITIES != SwTOXBase::GetType())
2317 // Eigener Eintrag fuer Doppelte oder Keywords
2319 if( pOld->GetType() == TOX_SORT_CUSTOM &&
2320 pNew->GetOptions() & nsSwTOIOptions::TOI_KEY_AS_ENTRY)
2321 continue;
2323 if(!(pNew->GetOptions() & nsSwTOIOptions::TOI_SAME_ENTRY))
2324 { // Eigener Eintrag
2325 aSortArr.Insert(pNew, i );
2326 return;
2328 // Eintrag schon vorhanden in Referenzliste aufnehmen
2329 pOld->aTOXSources.Insert( pNew->aTOXSources[0],
2330 pOld->aTOXSources.Count() );
2332 delete pNew;
2333 return;
2335 #ifdef DBG_UTIL
2336 else
2337 DBG_ERROR("Bibliography entries cannot be found here");
2338 #endif
2340 if(*pNew < *pOld)
2341 break;
2343 // SubLevel Skippen
2344 while( TOX_INDEX == SwTOXBase::GetType() && i < aRange.Max() &&
2345 aSortArr[i]->GetLevel() > pNew->GetLevel() )
2346 i++;
2348 // An Position i wird eingefuegt
2349 aSortArr.Insert(pNew, i );
2352 /*--------------------------------------------------------------------
2353 Beschreibung: Schluessel-Bereich suchen und evtl einfuegen
2354 --------------------------------------------------------------------*/
2356 Range SwTOXBaseSection::GetKeyRange(const String& rStr, const String& rStrReading,
2357 const SwTOXSortTabBase& rNew,
2358 USHORT nLevel, const Range& rRange )
2360 const SwTOXInternational& rIntl = *rNew.pTOXIntl;
2361 String sToCompare(rStr);
2362 String sToCompareReading(rStrReading);
2364 if( 0 != (nsSwTOIOptions::TOI_INITIAL_CAPS & GetOptions()) )
2366 String sUpper( rIntl.ToUpper( sToCompare, 0 ));
2367 sToCompare.Erase( 0, 1 ).Insert( sUpper, 0 );
2370 ASSERT(rRange.Min() >= 0 && rRange.Max() >= 0, "Min Max < 0");
2372 const USHORT nMin = (USHORT)rRange.Min();
2373 const USHORT nMax = (USHORT)rRange.Max();
2375 USHORT i;
2377 for( i = nMin; i < nMax; ++i)
2379 SwTOXSortTabBase* pBase = aSortArr[i];
2381 String sMyString, sMyStringReading;
2382 pBase->GetTxt( sMyString, sMyStringReading );
2384 if( rIntl.IsEqual( sMyString, sMyStringReading, pBase->GetLocale(),
2385 sToCompare, sToCompareReading, rNew.GetLocale() ) &&
2386 pBase->GetLevel() == nLevel &&
2387 pBase->GetType() == TOX_SORT_CUSTOM )
2388 break;
2390 if(i == nMax)
2391 { // Falls nicht vorhanden erzeugen und einfuegen
2393 SwTOXCustom* pKey = new SwTOXCustom( sToCompare, sToCompareReading, nLevel, rIntl,
2394 rNew.GetLocale() );
2395 for(i = nMin; i < nMax; ++i)
2397 if(nLevel == aSortArr[i]->GetLevel() && *pKey < *(aSortArr[i]))
2398 break;
2400 aSortArr.Insert(pKey, i );
2402 USHORT nStart = i+1;
2403 USHORT nEnd = aSortArr.Count();
2405 // Ende des Bereiches suchen
2406 for(i = nStart; i < aSortArr.Count(); ++i)
2408 if(aSortArr[i]->GetLevel() <= nLevel)
2409 { nEnd = i;
2410 break;
2413 return Range(nStart, nEnd);
2417 BOOL SwTOXBase::IsTOXBaseInReadonly() const
2419 const SwTOXBaseSection *pSect = PTR_CAST(SwTOXBaseSection, this);
2420 BOOL bRet = FALSE;
2421 const SwSectionNode* pSectNode;
2422 if(pSect && pSect->GetFmt() &&
2423 0 != (pSectNode = pSect->GetFmt()->GetSectionNode()))
2425 const SwDocShell* pDocSh;
2426 bRet = (0 != (pDocSh = pSectNode->GetDoc()->GetDocShell()) &&
2427 pDocSh->IsReadOnly()) ||
2428 (0 != (pSectNode = pSectNode->StartOfSectionNode()->FindSectionNode())&&
2429 pSectNode->GetSection().IsProtectFlag());
2432 return bRet;
2434 /* -----------------17.08.99 13:29-------------------
2436 --------------------------------------------------*/
2437 const SfxItemSet* SwTOXBase::GetAttrSet() const
2439 const SwTOXBaseSection *pSect = PTR_CAST(SwTOXBaseSection, this);
2440 if(pSect && pSect->GetFmt())
2441 return &pSect->GetFmt()->GetAttrSet();
2442 return 0;
2445 void SwTOXBase::SetAttrSet( const SfxItemSet& rSet )
2447 SwTOXBaseSection *pSect = PTR_CAST(SwTOXBaseSection, this);
2448 if( pSect && pSect->GetFmt() )
2449 pSect->GetFmt()->SetFmtAttr( rSet );
2452 BOOL SwTOXBase::GetInfo( SfxPoolItem& rInfo ) const
2454 switch( rInfo.Which() )
2456 case RES_CONTENT_VISIBLE:
2458 SwTOXBaseSection *pSect = PTR_CAST(SwTOXBaseSection, this);
2459 if( pSect && pSect->GetFmt() )
2460 pSect->GetFmt()->GetInfo( rInfo );
2462 return FALSE;
2464 return TRUE;
2467 /* \f */