summaryrefslogtreecommitdiff
path: root/sw/source/core/doc/doctxm.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/doc/doctxm.cxx')
-rw-r--r--sw/source/core/doc/doctxm.cxx2466
1 files changed, 2466 insertions, 0 deletions
diff --git a/sw/source/core/doc/doctxm.cxx b/sw/source/core/doc/doctxm.cxx
new file mode 100644
index 000000000000..58b3e084cf7a
--- /dev/null
+++ b/sw/source/core/doc/doctxm.cxx
@@ -0,0 +1,2466 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sw.hxx"
+
+
+#include <limits.h>
+#include <hintids.hxx>
+
+#define _SVSTDARR_STRINGSSORT
+#include <svl/svstdarr.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/brkitem.hxx>
+#include <editeng/tstpitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <sot/clsids.hxx>
+#include <docsh.hxx>
+#include <ndole.hxx>
+#include <txttxmrk.hxx>
+#include <fmtinfmt.hxx>
+#include <fmtpdsc.hxx>
+#include <frmfmt.hxx>
+#include <fmtfsize.hxx>
+#include <frmatr.hxx>
+#include <pagedesc.hxx>
+#include <doc.hxx>
+#include <pagefrm.hxx>
+#include <ndtxt.hxx>
+#include <swtable.hxx>
+#include <doctxm.hxx>
+#include <txmsrt.hxx>
+#include <rolbck.hxx>
+#include <poolfmt.hxx>
+#include <txtfrm.hxx>
+#include <rootfrm.hxx>
+#include <undobj.hxx>
+#include <swundo.hxx>
+#include <mdiexp.hxx>
+#include <docary.hxx>
+#include <charfmt.hxx>
+#include <fchrfmt.hxx>
+#include <fldbas.hxx>
+#include <fmtfld.hxx>
+#include <txtfld.hxx>
+#include <expfld.hxx>
+#include <chpfld.hxx>
+#include <mvsave.hxx>
+#include <node2lay.hxx>
+#include <SwStyleNameMapper.hxx>
+#include <breakit.hxx>
+#include <editsh.hxx>
+#include <scriptinfo.hxx>
+
+using namespace ::com::sun::star;
+
+const sal_Unicode cNumRepl = '@';
+const sal_Unicode cEndPageNum = '~';
+const sal_Char __FAR_DATA sPageDeli[] = ", ";
+
+SV_IMPL_PTRARR(SwTOXSortTabBases, SwTOXSortTabBasePtr)
+
+TYPEINIT2( SwTOXBaseSection, SwTOXBase, SwSection ); // fuers RTTI
+
+struct LinkStruct
+{
+ SwFmtINetFmt aINetFmt;
+ xub_StrLen nStartTextPos, nEndTextPos;
+
+ LinkStruct( const String& rURL, xub_StrLen nStart, xub_StrLen nEnd )
+ : aINetFmt( rURL, aEmptyStr),
+ nStartTextPos( nStart),
+ nEndTextPos(nEnd) {}
+};
+
+typedef LinkStruct* LinkStructPtr;
+SV_DECL_PTRARR(LinkStructArr, LinkStructPtr, 0, 5 )
+SV_IMPL_PTRARR(LinkStructArr, LinkStructPtr)
+
+USHORT SwDoc::GetTOIKeys( SwTOIKeyType eTyp, SvStringsSort& rArr ) const
+{
+ if( rArr.Count() )
+ rArr.Remove( USHORT(0), rArr.Count() );
+
+ // dann mal ueber den Pool und alle Primary oder Secondary heraussuchen
+ const SwTxtTOXMark* pMark;
+ const SfxPoolItem* pItem;
+ const SwTOXType* pTOXType;
+ USHORT i, nMaxItems = GetAttrPool().GetItemCount( RES_TXTATR_TOXMARK );
+ for( i = 0; i < nMaxItems; ++i )
+ if( 0 != (pItem = GetAttrPool().GetItem( RES_TXTATR_TOXMARK, i ) ) &&
+ 0!= ( pTOXType = ((SwTOXMark*)pItem)->GetTOXType()) &&
+ TOX_INDEX == pTOXType->GetType() &&
+ 0 != ( pMark = ((SwTOXMark*)pItem)->GetTxtTOXMark() ) &&
+ pMark->GetpTxtNd() &&
+ pMark->GetpTxtNd()->GetNodes().IsDocNodes() )
+ {
+ const String* pStr;
+ if( TOI_PRIMARY == eTyp )
+ pStr = &((SwTOXMark*)pItem)->GetPrimaryKey();
+ else
+ pStr = &((SwTOXMark*)pItem)->GetSecondaryKey();
+
+ if( pStr->Len() )
+ rArr.Insert( (StringPtr)pStr );
+ }
+
+ return rArr.Count();
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: aktuelle Verzeichnismarkierungen ermitteln
+ --------------------------------------------------------------------*/
+
+
+USHORT SwDoc::GetCurTOXMark( const SwPosition& rPos,
+ SwTOXMarks& rArr ) const
+{
+ // suche an der Position rPos nach allen SwTOXMark's
+ SwTxtNode* pTxtNd = GetNodes()[ rPos.nNode ]->GetTxtNode();
+ // kein TextNode oder kein HintsArray vorhanden ??
+ if( !pTxtNd || !pTxtNd->GetpSwpHints() )
+ return 0;
+
+ const SwpHints & rHts = *pTxtNd->GetpSwpHints();
+ const SwTxtAttr* pHt;
+ xub_StrLen nSttIdx;
+ const xub_StrLen *pEndIdx;
+
+ xub_StrLen nAktPos = rPos.nContent.GetIndex();
+
+ for( USHORT n = 0; n < rHts.Count(); ++n )
+ {
+ if( RES_TXTATR_TOXMARK != (pHt = rHts[n])->Which() )
+ continue;
+ if( ( nSttIdx = *pHt->GetStart() ) < nAktPos )
+ {
+ // pruefe Ende mit ab
+ if( 0 == ( pEndIdx = pHt->GetEnd() ) ||
+ *pEndIdx <= nAktPos )
+ continue; // weiter suchen
+ }
+ else if( nSttIdx > nAktPos )
+ // ist Start vom Hint groesser als rPos, dann abbrechen. Denn
+ // die Attribute sind nach Start sortiert !
+ break;
+
+ const SwTOXMark* pTMark = &pHt->GetTOXMark();
+ rArr.Insert( pTMark, rArr.Count() );
+ }
+ return rArr.Count();
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Marke loeschen
+ --------------------------------------------------------------------*/
+
+void SwDoc::DeleteTOXMark( const SwTOXMark* pTOXMark )
+{
+ // hole den TextNode und
+ const SwTxtTOXMark* pTxtTOXMark = pTOXMark->GetTxtTOXMark();
+ ASSERT( pTxtTOXMark, "Kein TxtTOXMark, kann nicht geloescht werden" );
+
+ SwTxtNode& rTxtNd = const_cast<SwTxtNode&>(pTxtTOXMark->GetTxtNode());
+ ASSERT( rTxtNd.GetpSwpHints(), "kann nicht geloescht werden" );
+
+ if( DoesUndo() )
+ {
+ // fuers Undo die Attribute sichern
+ ClearRedo();
+ SwUndoResetAttr* pUndo = new SwUndoResetAttr(
+ SwPosition( rTxtNd, SwIndex( &rTxtNd, *pTxtTOXMark->GetStart() ) ),
+ RES_TXTATR_TOXMARK );
+ AppendUndo( pUndo );
+
+ SwRegHistory aRHst( rTxtNd, &pUndo->GetHistory() );
+ rTxtNd.GetpSwpHints()->Register( &aRHst );
+ }
+
+ rTxtNd.DeleteAttribute( const_cast<SwTxtTOXMark*>(pTxtTOXMark) );
+
+ if ( DoesUndo() )
+ {
+ if( rTxtNd.GetpSwpHints() )
+ rTxtNd.GetpSwpHints()->DeRegister();
+ }
+ SetModified();
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Traveln zwischen TOXMarks
+ --------------------------------------------------------------------*/
+
+class CompareNodeCntnt
+{
+ ULONG nNode;
+ xub_StrLen nCntnt;
+public:
+ CompareNodeCntnt( ULONG nNd, xub_StrLen nCnt )
+ : nNode( nNd ), nCntnt( nCnt ) {}
+
+ int operator==( const CompareNodeCntnt& rCmp )
+ { return nNode == rCmp.nNode && nCntnt == rCmp.nCntnt; }
+ int operator!=( const CompareNodeCntnt& rCmp )
+ { return nNode != rCmp.nNode || nCntnt != rCmp.nCntnt; }
+ int operator< ( const CompareNodeCntnt& rCmp )
+ { return nNode < rCmp.nNode ||
+ ( nNode == rCmp.nNode && nCntnt < rCmp.nCntnt); }
+ int operator<=( const CompareNodeCntnt& rCmp )
+ { return nNode < rCmp.nNode ||
+ ( nNode == rCmp.nNode && nCntnt <= rCmp.nCntnt); }
+ int operator> ( const CompareNodeCntnt& rCmp )
+ { return nNode > rCmp.nNode ||
+ ( nNode == rCmp.nNode && nCntnt > rCmp.nCntnt); }
+ int operator>=( const CompareNodeCntnt& rCmp )
+ { return nNode > rCmp.nNode ||
+ ( nNode == rCmp.nNode && nCntnt >= rCmp.nCntnt); }
+};
+
+const SwTOXMark& SwDoc::GotoTOXMark( const SwTOXMark& rCurTOXMark,
+ SwTOXSearch eDir, BOOL bInReadOnly )
+{
+ const SwTxtTOXMark* pMark = rCurTOXMark.GetTxtTOXMark();
+ ASSERT(pMark, "pMark==0 Ungueltige TxtTOXMark");
+
+ const SwTxtNode *pTOXSrc = pMark->GetpTxtNd();
+
+ CompareNodeCntnt aAbsIdx( pTOXSrc->GetIndex(), *pMark->GetStart() );
+ CompareNodeCntnt aPrevPos( 0, 0 );
+ CompareNodeCntnt aNextPos( ULONG_MAX, STRING_NOTFOUND );
+ CompareNodeCntnt aMax( 0, 0 );
+ CompareNodeCntnt aMin( ULONG_MAX, STRING_NOTFOUND );
+
+ const SwTOXMark* pNew = 0;
+ const SwTOXMark* pMax = &rCurTOXMark;
+ const SwTOXMark* pMin = &rCurTOXMark;
+
+ const SwModify* pType = rCurTOXMark.GetRegisteredIn();
+ SwClientIter aIter( *(SwModify*)pType );
+
+ const SwTOXMark* pTOXMark;
+ const SwCntntFrm* pCFrm;
+ Point aPt;
+ for( pTOXMark = (SwTOXMark*)aIter.First( TYPE( SwTOXMark )); pTOXMark;
+ pTOXMark = (SwTOXMark*)aIter.Next() )
+ {
+ if( pTOXMark != &rCurTOXMark &&
+ 0 != ( pMark = pTOXMark->GetTxtTOXMark()) &&
+ 0 != ( pTOXSrc = pMark->GetpTxtNd() ) &&
+ 0 != ( pCFrm = pTOXSrc->GetFrm( &aPt, 0, FALSE )) &&
+ ( bInReadOnly || !pCFrm->IsProtected() ))
+ {
+ CompareNodeCntnt aAbsNew( pTOXSrc->GetIndex(), *pMark->GetStart() );
+ switch( eDir )
+ {
+ //Die untenstehenden etwas komplizierter ausgefallen Ausdruecke
+ //dienen dazu auch ueber Eintraege auf der selben (!) Position
+ //traveln zu koennen. Wenn einer Zeit hat mag er sie mal
+ //optimieren.
+
+ case TOX_SAME_PRV:
+ if( pTOXMark->GetText() != rCurTOXMark.GetText() )
+ break;
+ /* no break here */
+ case TOX_PRV:
+ if ( (aAbsNew < aAbsIdx && aAbsNew > aPrevPos &&
+ aPrevPos != aAbsIdx && aAbsNew != aAbsIdx ) ||
+ (aAbsIdx == aAbsNew &&
+ (ULONG(&rCurTOXMark) > ULONG(pTOXMark) &&
+ (!pNew ||
+ (pNew && (aPrevPos < aAbsIdx ||
+ ULONG(pNew) < ULONG(pTOXMark)))))) ||
+ (aPrevPos == aAbsNew && aAbsIdx != aAbsNew &&
+ ULONG(pTOXMark) > ULONG(pNew)) )
+ {
+ pNew = pTOXMark;
+ aPrevPos = aAbsNew;
+ if ( aAbsNew >= aMax )
+ {
+ aMax = aAbsNew;
+ pMax = pTOXMark;
+ }
+ }
+ break;
+
+ case TOX_SAME_NXT:
+ if( pTOXMark->GetText() != rCurTOXMark.GetText() )
+ break;
+ /* no break here */
+ case TOX_NXT:
+ if ( (aAbsNew > aAbsIdx && aAbsNew < aNextPos &&
+ aNextPos != aAbsIdx && aAbsNew != aAbsIdx ) ||
+ (aAbsIdx == aAbsNew &&
+ (ULONG(&rCurTOXMark) < ULONG(pTOXMark) &&
+ (!pNew ||
+ (pNew && (aNextPos > aAbsIdx ||
+ ULONG(pNew) > ULONG(pTOXMark)))))) ||
+ (aNextPos == aAbsNew && aAbsIdx != aAbsNew &&
+ ULONG(pTOXMark) < ULONG(pNew)) )
+ {
+ pNew = pTOXMark;
+ aNextPos = aAbsNew;
+ if ( aAbsNew <= aMin )
+ {
+ aMin = aAbsNew;
+ pMin = pTOXMark;
+ }
+ }
+ break;
+ }
+ }
+ }
+
+
+ // kein Nachfolger wurde gefunden
+ // Min oder Max benutzen
+ if(!pNew)
+ {
+ switch(eDir)
+ {
+ case TOX_PRV:
+ case TOX_SAME_PRV:
+ pNew = pMax;
+ break;
+ case TOX_NXT:
+ case TOX_SAME_NXT:
+ pNew = pMin;
+ break;
+ default:
+ pNew = &rCurTOXMark;
+ }
+ }
+ return *pNew;
+}
+
+/* */
+
+const SwTOXBaseSection* SwDoc::InsertTableOf( const SwPosition& rPos,
+ const SwTOXBase& rTOX,
+ const SfxItemSet* pSet,
+ BOOL bExpand )
+{
+ StartUndo( UNDO_INSTOX, NULL );
+
+ String sSectNm( rTOX.GetTOXName() );
+ sSectNm = GetUniqueTOXBaseName( *rTOX.GetTOXType(), &sSectNm );
+ SwPaM aPam( rPos );
+ SwSectionData aSectionData( TOX_CONTENT_SECTION, sSectNm );
+ SwTOXBaseSection *const pNewSection = dynamic_cast<SwTOXBaseSection *>(
+ InsertSwSection( aPam, aSectionData, & rTOX, pSet, false ));
+ if (pNewSection)
+ {
+ SwSectionNode *const pSectNd = pNewSection->GetFmt()->GetSectionNode();
+ pNewSection->SetTOXName(sSectNm); // rTOX may have had no name...
+
+ if( bExpand )
+ {
+ // OD 19.03.2003 #106329# - add value for 2nd parameter = true to
+ // indicate, that a creation of a new table of content has to be performed.
+ // Value of 1st parameter = default value.
+ pNewSection->Update( 0, true );
+ }
+ else if( 1 == rTOX.GetTitle().Len() && IsInReading() )
+ // insert title of TOX
+ {
+ // then insert the headline section
+ SwNodeIndex aIdx( *pSectNd, +1 );
+
+ SwTxtNode* pHeadNd = GetNodes().MakeTxtNode( aIdx,
+ GetTxtCollFromPool( RES_POOLCOLL_STANDARD ) );
+
+ String sNm( pNewSection->GetTOXName() );
+// ??Resource
+sNm.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "_Head" ));
+
+ SwSectionData headerData( TOX_HEADER_SECTION, sNm );
+
+ SwNodeIndex aStt( *pHeadNd ); aIdx--;
+ SwSectionFmt* pSectFmt = MakeSectionFmt( 0 );
+ GetNodes().InsertTextSection(
+ aStt, *pSectFmt, headerData, 0, &aIdx, true, false);
+ }
+ }
+
+ EndUndo( UNDO_INSTOX, NULL );
+
+ return pNewSection;
+}
+
+
+
+const SwTOXBaseSection* SwDoc::InsertTableOf( ULONG nSttNd, ULONG nEndNd,
+ const SwTOXBase& rTOX,
+ const SfxItemSet* pSet )
+{
+ // check for recursiv TOX
+ SwNode* pNd = GetNodes()[ nSttNd ];
+ SwSectionNode* pSectNd = pNd->FindSectionNode();
+ while( pSectNd )
+ {
+ SectionType eT = pSectNd->GetSection().GetType();
+ if( TOX_HEADER_SECTION == eT || TOX_CONTENT_SECTION == eT )
+ return 0;
+ pSectNd = pSectNd->StartOfSectionNode()->FindSectionNode();
+ }
+
+ String sSectNm( rTOX.GetTOXName() );
+ sSectNm = GetUniqueTOXBaseName(*rTOX.GetTOXType(), &sSectNm);
+
+ SwSectionData aSectionData( TOX_CONTENT_SECTION, sSectNm );
+
+ SwNodeIndex aStt( GetNodes(), nSttNd ), aEnd( GetNodes(), nEndNd );
+ SwSectionFmt* pFmt = MakeSectionFmt( 0 );
+ if(pSet)
+ pFmt->SetFmtAttr(*pSet);
+
+// --aEnd; // im InsertSection ist Ende inclusive
+
+ SwSectionNode *const pNewSectionNode =
+ GetNodes().InsertTextSection(aStt, *pFmt, aSectionData, &rTOX, &aEnd);
+ if (!pNewSectionNode)
+ {
+ DelSectionFmt( pFmt );
+ return 0;
+ }
+
+ SwTOXBaseSection *const pNewSection(
+ dynamic_cast<SwTOXBaseSection*>(& pNewSectionNode->GetSection()));
+ pNewSection->SetTOXName(sSectNm); // rTOX may have had no name...
+ return pNewSection;
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Aktuelles Verzeichnis ermitteln
+ --------------------------------------------------------------------*/
+
+const SwTOXBase* SwDoc::GetCurTOX( const SwPosition& rPos ) const
+{
+ const SwNode& rNd = rPos.nNode.GetNode();
+ const SwSectionNode* pSectNd = rNd.FindSectionNode();
+ while( pSectNd )
+ {
+ SectionType eT = pSectNd->GetSection().GetType();
+ if( TOX_CONTENT_SECTION == eT )
+ {
+ ASSERT( pSectNd->GetSection().ISA( SwTOXBaseSection ),
+ "keine TOXBaseSection!" );
+ SwTOXBaseSection& rTOXSect = (SwTOXBaseSection&)
+ pSectNd->GetSection();
+ return &rTOXSect;
+ }
+ pSectNd = pSectNd->StartOfSectionNode()->FindSectionNode();
+ }
+ return 0;
+}
+/* -----------------01.09.99 16:01-------------------
+
+ --------------------------------------------------*/
+const SwAttrSet& SwDoc::GetTOXBaseAttrSet(const SwTOXBase& rTOXBase) const
+{
+ ASSERT( rTOXBase.ISA( SwTOXBaseSection ), "no TOXBaseSection!" );
+ const SwTOXBaseSection& rTOXSect = (const SwTOXBaseSection&)rTOXBase;
+ SwSectionFmt* pFmt = rTOXSect.GetFmt();
+ ASSERT( pFmt, "invalid TOXBaseSection!" );
+ return pFmt->GetAttrSet();
+}
+/* -----------------02.09.99 07:48-------------------
+
+ --------------------------------------------------*/
+const SwTOXBase* SwDoc::GetDefaultTOXBase( TOXTypes eTyp, BOOL bCreate )
+{
+ SwTOXBase** prBase = 0;
+ switch(eTyp)
+ {
+ case TOX_CONTENT: prBase = &pDefTOXBases->pContBase; break;
+ case TOX_INDEX: prBase = &pDefTOXBases->pIdxBase; break;
+ case TOX_USER: prBase = &pDefTOXBases->pUserBase; break;
+ case TOX_TABLES: prBase = &pDefTOXBases->pTblBase; break;
+ case TOX_OBJECTS: prBase = &pDefTOXBases->pObjBase; break;
+ case TOX_ILLUSTRATIONS: prBase = &pDefTOXBases->pIllBase; break;
+ case TOX_AUTHORITIES: prBase = &pDefTOXBases->pAuthBase; break;
+ }
+ if(!(*prBase) && bCreate)
+ {
+ SwForm aForm(eTyp);
+ const SwTOXType* pType = GetTOXType(eTyp, 0);
+ (*prBase) = new SwTOXBase(pType, aForm, 0, pType->GetTypeName());
+ }
+ return (*prBase);
+}
+/* -----------------02.09.99 08:06-------------------
+
+ --------------------------------------------------*/
+void SwDoc::SetDefaultTOXBase(const SwTOXBase& rBase)
+{
+ SwTOXBase** prBase = 0;
+ switch(rBase.GetType())
+ {
+ case TOX_CONTENT: prBase = &pDefTOXBases->pContBase; break;
+ case TOX_INDEX: prBase = &pDefTOXBases->pIdxBase; break;
+ case TOX_USER: prBase = &pDefTOXBases->pUserBase; break;
+ case TOX_TABLES: prBase = &pDefTOXBases->pTblBase; break;
+ case TOX_OBJECTS: prBase = &pDefTOXBases->pObjBase; break;
+ case TOX_ILLUSTRATIONS: prBase = &pDefTOXBases->pIllBase; break;
+ case TOX_AUTHORITIES: prBase = &pDefTOXBases->pAuthBase; break;
+ }
+ if(*prBase)
+ delete (*prBase);
+ (*prBase) = new SwTOXBase(rBase);
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Verzeichnis loeschen
+ --------------------------------------------------------------------*/
+
+
+BOOL SwDoc::DeleteTOX( const SwTOXBase& rTOXBase, BOOL bDelNodes )
+{
+ // its only delete the TOX, not the nodes
+ BOOL bRet = FALSE;
+ ASSERT( rTOXBase.ISA( SwTOXBaseSection ), "keine TOXBaseSection!" );
+
+ const SwTOXBaseSection& rTOXSect = (const SwTOXBaseSection&)rTOXBase;
+ SwSectionFmt* pFmt = rTOXSect.GetFmt();
+ if( pFmt )
+ {
+ StartUndo( UNDO_CLEARTOXRANGE, NULL );
+
+ /* Save the start node of the TOX' section. */
+ SwSectionNode * pMyNode = pFmt->GetSectionNode();
+ /* Save start node of section's surrounding. */
+ SwNode * pStartNd = pMyNode->StartOfSectionNode();
+
+ /* Look for point where to move the cursors in the area to
+ delete to. This is done by first searching forward from the
+ end of the TOX' section. If no content node is found behind
+ the TOX one is searched before it. If this is not
+ successfull, too, insert new text node behind the end of
+ the TOX' section. The cursors from the TOX' section will be
+ moved to the content node found or the new text node. */
+
+ /* Set PaM to end of TOX' section and search following content node.
+
+ aSearchPam will contain the point where to move the cursors
+ to. */
+ SwPaM aSearchPam(*pMyNode->EndOfSectionNode());
+ SwPosition aEndPos(*pStartNd->EndOfSectionNode());
+ if (! aSearchPam.Move() /* no content node found */
+ || *aSearchPam.GetPoint() >= aEndPos /* content node found
+ outside surrounding */
+ )
+ {
+ /* Set PaM to beginning of TOX' section and search previous
+ content node */
+ SwPaM aTmpPam(*pMyNode);
+ aSearchPam = aTmpPam;
+ SwPosition aStartPos(*pStartNd);
+
+ if ( ! aSearchPam.Move(fnMoveBackward) /* no content node found */
+ || *aSearchPam.GetPoint() <= aStartPos /* content node
+ found outside
+ surrounding */
+ )
+ {
+ /* There is no content node in the surrounding of
+ TOX'. Append text node behind TOX' section. */
+
+ SwPosition aInsPos(*pMyNode->EndOfSectionNode());
+ AppendTxtNode(aInsPos);
+
+ SwPaM aTmpPam1(aInsPos);
+ aSearchPam = aTmpPam1;
+ }
+ }
+
+
+ /* PaM containing the TOX. */
+ SwPaM aPam(*pMyNode->EndOfSectionNode(), *pMyNode);
+
+ /* Move cursors contained in TOX to point determined above. */
+ PaMCorrAbs(aPam, *aSearchPam.GetPoint());
+
+ if( !bDelNodes )
+ {
+ SwSections aArr( 0, 4 );
+ USHORT nCnt = pFmt->GetChildSections( aArr, SORTSECT_NOT, FALSE );
+ for( USHORT n = 0; n < nCnt; ++n )
+ {
+ SwSection* pSect = aArr[ n ];
+ if( TOX_HEADER_SECTION == pSect->GetType() )
+ {
+ DelSectionFmt( pSect->GetFmt(), bDelNodes );
+ }
+ }
+ }
+
+ DelSectionFmt( pFmt, bDelNodes );
+
+ EndUndo( UNDO_CLEARTOXRANGE, NULL );
+ bRet = TRUE;
+ }
+
+ return bRet;
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Verzeichnistypen verwalten
+ --------------------------------------------------------------------*/
+
+USHORT SwDoc::GetTOXTypeCount(TOXTypes eTyp) const
+{
+ const SwTOXTypePtr * ppTTypes = pTOXTypes->GetData();
+ USHORT nCnt = 0;
+ for( USHORT n = 0; n < pTOXTypes->Count(); ++n, ++ppTTypes )
+ if( eTyp == (*ppTTypes)->GetType() )
+ ++nCnt;
+ return nCnt;
+}
+/*--------------------------------------------------------------------
+
+ --------------------------------------------------------------------*/
+const SwTOXType* SwDoc::GetTOXType( TOXTypes eTyp, USHORT nId ) const
+{
+ const SwTOXTypePtr * ppTTypes = pTOXTypes->GetData();
+ USHORT nCnt = 0;
+ for( USHORT n = 0; n < pTOXTypes->Count(); ++n, ++ppTTypes )
+ if( eTyp == (*ppTTypes)->GetType() && nCnt++ == nId )
+ return (*ppTTypes);
+ return 0;
+}
+
+/*--------------------------------------------------------------------
+
+ --------------------------------------------------------------------*/
+const SwTOXType* SwDoc::InsertTOXType( const SwTOXType& rTyp )
+{
+ SwTOXType * pNew = new SwTOXType( rTyp );
+ pTOXTypes->Insert( pNew, pTOXTypes->Count() );
+ return pNew;
+}
+/*--------------------------------------------------------------------
+
+ --------------------------------------------------------------------*/
+String SwDoc::GetUniqueTOXBaseName( const SwTOXType& rType,
+ const String* pChkStr ) const
+{
+ USHORT n;
+ const SwSectionNode* pSectNd;
+ const SwSection* pSect;
+
+ if(pChkStr && !pChkStr->Len())
+ pChkStr = 0;
+ String aName( rType.GetTypeName() );
+ xub_StrLen nNmLen = aName.Len();
+
+ USHORT nNum = 0;
+ USHORT nTmp = 0;
+ USHORT nFlagSize = ( pSectionFmtTbl->Count() / 8 ) +2;
+ BYTE* pSetFlags = new BYTE[ nFlagSize ];
+ memset( pSetFlags, 0, nFlagSize );
+
+ for( n = 0; n < pSectionFmtTbl->Count(); ++n )
+ if( 0 != ( pSectNd = (*pSectionFmtTbl)[ n ]->GetSectionNode( FALSE ) )&&
+ TOX_CONTENT_SECTION == (pSect = &pSectNd->GetSection())->GetType())
+ {
+ const String& rNm = pSect->GetSectionName();
+ if( rNm.Match( aName ) == nNmLen )
+ {
+ // Nummer bestimmen und das Flag setzen
+ nNum = (USHORT)rNm.Copy( nNmLen ).ToInt32();
+ if( nNum-- && nNum < pSectionFmtTbl->Count() )
+ pSetFlags[ nNum / 8 ] |= (0x01 << ( nNum & 0x07 ));
+ }
+ if( pChkStr && pChkStr->Equals( rNm ) )
+ pChkStr = 0;
+ }
+
+ if( !pChkStr )
+ {
+ // alle Nummern entsprechend geflag, also bestimme die richtige Nummer
+ nNum = pSectionFmtTbl->Count();
+ for( n = 0; n < nFlagSize; ++n )
+ if( 0xff != ( nTmp = pSetFlags[ n ] ))
+ {
+ // also die Nummer bestimmen
+ nNum = n * 8;
+ while( nTmp & 1 )
+ ++nNum, nTmp >>= 1;
+ break;
+ }
+ }
+ delete [] pSetFlags;
+ if( pChkStr )
+ return *pChkStr;
+ return aName += String::CreateFromInt32( ++nNum );
+}
+
+/*--------------------------------------------------------------------
+
+ --------------------------------------------------------------------*/
+BOOL SwDoc::SetTOXBaseName(const SwTOXBase& rTOXBase, const String& rName)
+{
+ ASSERT( rTOXBase.ISA( SwTOXBaseSection ),
+ "keine TOXBaseSection!" );
+ SwTOXBaseSection* pTOX = (SwTOXBaseSection*)&rTOXBase;
+
+ String sTmp = GetUniqueTOXBaseName(*rTOXBase.GetTOXType(), &rName);
+ BOOL bRet = sTmp == rName;
+ if(bRet)
+ {
+ pTOX->SetTOXName(rName);
+ pTOX->SetSectionName(rName);
+ SetModified();
+ }
+ return bRet;
+}
+
+/* */
+
+const SwTxtNode* lcl_FindChapterNode( const SwNode& rNd, BYTE nLvl = 0 )
+{
+ const SwNode* pNd = &rNd;
+ if( pNd->GetNodes().GetEndOfExtras().GetIndex() > pNd->GetIndex() )
+ {
+ // then find the "Anchor" (Body) position
+ Point aPt;
+ SwNode2Layout aNode2Layout( *pNd, pNd->GetIndex() );
+ const SwFrm* pFrm = aNode2Layout.GetFrm( &aPt, 0, FALSE );
+
+ if( pFrm )
+ {
+ SwPosition aPos( *pNd );
+ pNd = GetBodyTxtNode( *pNd->GetDoc(), aPos, *pFrm );
+ ASSERT( pNd, "wo steht der Absatz" );
+ }
+ }
+ return pNd ? pNd->FindOutlineNodeOfLevel( nLvl ) : 0;
+}
+
+
+/*--------------------------------------------------------------------
+ Beschreibung: Verzeichnis-Klasse
+ --------------------------------------------------------------------*/
+
+SwTOXBaseSection::SwTOXBaseSection(SwTOXBase const& rBase, SwSectionFmt & rFmt)
+ : SwTOXBase( rBase )
+ , SwSection( TOX_CONTENT_SECTION, aEmptyStr, rFmt )
+{
+ SetProtect( rBase.IsProtected() );
+ SetSectionName( GetTOXName() );
+}
+
+
+SwTOXBaseSection::~SwTOXBaseSection()
+{
+}
+
+
+BOOL SwTOXBaseSection::SetPosAtStartEnd( SwPosition& rPos, BOOL bAtStart ) const
+{
+ BOOL bRet = FALSE;
+ const SwSectionNode* pSectNd = GetFmt()->GetSectionNode();
+ if( pSectNd )
+ {
+ SwCntntNode* pCNd;
+ xub_StrLen nC = 0;
+ if( bAtStart )
+ {
+ rPos.nNode = *pSectNd;
+ pCNd = pSectNd->GetDoc()->GetNodes().GoNext( &rPos.nNode );
+ }
+ else
+ {
+ rPos.nNode = *pSectNd->EndOfSectionNode();
+ pCNd = pSectNd->GetDoc()->GetNodes().GoPrevious( &rPos.nNode );
+ if( pCNd ) nC = pCNd->Len();
+ }
+ rPos.nContent.Assign( pCNd, nC );
+ bRet = TRUE;
+ }
+ return bRet;
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Verzeichnisinhalt zusammensammeln
+ --------------------------------------------------------------------*/
+
+void SwTOXBaseSection::Update(const SfxItemSet* pAttr,
+ const bool _bNewTOX )
+{
+ const SwSectionNode* pSectNd;
+ if( !SwTOXBase::GetRegisteredIn()->GetDepends() ||
+ !GetFmt() || 0 == (pSectNd = GetFmt()->GetSectionNode() ) ||
+ !pSectNd->GetNodes().IsDocNodes() ||
+ IsHiddenFlag() )
+ return;
+
+ SwDoc* pDoc = (SwDoc*)pSectNd->GetDoc();
+
+ DBG_ASSERT(pDoc != NULL, "Where is the document?");
+
+ if(pAttr && pDoc && GetFmt())
+ pDoc->ChgFmt(*GetFmt(), *pAttr);
+
+ // OD 18.03.2003 #106329# - determine default page description, which
+ // will be used by the content nodes, if no approriate one is found.
+ const SwPageDesc* pDefaultPageDesc;
+ {
+ pDefaultPageDesc =
+ pSectNd->GetSection().GetFmt()->GetPageDesc().GetPageDesc();
+ if ( !_bNewTOX && !pDefaultPageDesc )
+ {
+ // determine page description of table-of-content
+ sal_uInt32 nPgDescNdIdx = pSectNd->GetIndex() + 1;
+ sal_uInt32* pPgDescNdIdx = &nPgDescNdIdx;
+ pDefaultPageDesc = pSectNd->FindPageDesc( FALSE, pPgDescNdIdx );
+ if ( nPgDescNdIdx < pSectNd->GetIndex() )
+ {
+ pDefaultPageDesc = 0;
+ }
+ }
+ // OD 28.04.2003 #109166# - consider end node of content section in the
+ // node array.
+ if ( !pDefaultPageDesc &&
+ ( pSectNd->EndOfSectionNode()->GetIndex() <
+ (pSectNd->GetNodes().GetEndOfContent().GetIndex() - 1) )
+ )
+ {
+ // determine page description of content after table-of-content
+ SwNodeIndex aIdx( *(pSectNd->EndOfSectionNode()) );
+ const SwCntntNode* pNdAfterTOX = pSectNd->GetNodes().GoNext( &aIdx );
+ const SwAttrSet& aNdAttrSet = pNdAfterTOX->GetSwAttrSet();
+ const SvxBreak eBreak = aNdAttrSet.GetBreak().GetBreak();
+ if ( !( eBreak == SVX_BREAK_PAGE_BEFORE ||
+ eBreak == SVX_BREAK_PAGE_BOTH )
+ )
+ {
+ pDefaultPageDesc = pNdAfterTOX->FindPageDesc( FALSE );
+ }
+ }
+ // OD 28.04.2003 #109166# - consider start node of content section in
+ // the node array.
+ if ( !pDefaultPageDesc &&
+ ( pSectNd->GetIndex() >
+ (pSectNd->GetNodes().GetEndOfContent().StartOfSectionIndex() + 1) )
+ )
+ {
+ // determine page description of content before table-of-content
+ SwNodeIndex aIdx( *pSectNd );
+ pDefaultPageDesc =
+ pSectNd->GetNodes().GoPrevious( &aIdx )->FindPageDesc( FALSE );
+
+ }
+ if ( !pDefaultPageDesc )
+ {
+ // determine default page description
+ pDefaultPageDesc =
+ &const_cast<const SwDoc *>(pDoc)->GetPageDesc( 0 );
+ }
+ }
+
+ pDoc->SetModified();
+
+ // get current Language
+ SwTOXInternational aIntl( GetLanguage(),
+ TOX_INDEX == GetTOXType()->GetType() ?
+ GetOptions() : 0,
+ GetSortAlgorithm() );
+
+ aSortArr.DeleteAndDestroy( 0, aSortArr.Count() );
+
+ // find the first layout node for this TOX, if it only find the content
+ // in his own chapter
+ const SwTxtNode* pOwnChapterNode = IsFromChapter()
+ ? ::lcl_FindChapterNode( *pSectNd, 0 )
+ : 0;
+
+ SwNode2Layout aN2L( *pSectNd );
+ ((SwSectionNode*)pSectNd)->DelFrms();
+
+ // remove old content an insert one empty textnode (to hold the layout!)
+ SwTxtNode* pFirstEmptyNd;
+ {
+ pDoc->DeleteRedline( *pSectNd, true, USHRT_MAX );
+
+ SwNodeIndex aSttIdx( *pSectNd, +1 );
+ SwNodeIndex aEndIdx( *pSectNd->EndOfSectionNode() );
+ pFirstEmptyNd = pDoc->GetNodes().MakeTxtNode( aEndIdx,
+ pDoc->GetTxtCollFromPool( RES_POOLCOLL_TEXT ) );
+
+ {
+ // Task 70995 - save and restore PageDesc and Break Attributes
+ SwNodeIndex aNxtIdx( aSttIdx );
+ const SwCntntNode* pCNd = aNxtIdx.GetNode().GetCntntNode();
+ if( !pCNd )
+ pCNd = pDoc->GetNodes().GoNext( &aNxtIdx );
+ if( pCNd->HasSwAttrSet() )
+ {
+ SfxItemSet aBrkSet( pDoc->GetAttrPool(), aBreakSetRange );
+ aBrkSet.Put( *pCNd->GetpSwAttrSet() );
+ if( aBrkSet.Count() )
+ pFirstEmptyNd->SetAttr( aBrkSet );
+ }
+ }
+ aEndIdx--;
+ SwPosition aPos( aEndIdx, SwIndex( pFirstEmptyNd, 0 ));
+ pDoc->CorrAbs( aSttIdx, aEndIdx, aPos, TRUE );
+
+ // delete all before
+ DelFlyInRange( aSttIdx, aEndIdx );
+ _DelBookmarks( aSttIdx, aEndIdx );
+
+ pDoc->GetNodes().Delete( aSttIdx, aEndIdx.GetIndex() - aSttIdx.GetIndex() );
+
+ }
+
+ //
+ // insert title of TOX
+ if( GetTitle().Len() )
+ {
+ // then insert the headline section
+ SwNodeIndex aIdx( *pSectNd, +1 );
+
+ SwTxtNode* pHeadNd = pDoc->GetNodes().MakeTxtNode( aIdx,
+ GetTxtFmtColl( FORM_TITLE ) );
+ pHeadNd->InsertText( GetTitle(), SwIndex( pHeadNd ) );
+
+ String sNm( GetTOXName() );
+// ??Resource
+sNm.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "_Head" ));
+
+ SwSectionData headerData( TOX_HEADER_SECTION, sNm );
+
+ SwNodeIndex aStt( *pHeadNd ); aIdx--;
+ SwSectionFmt* pSectFmt = pDoc->MakeSectionFmt( 0 );
+ pDoc->GetNodes().InsertTextSection(
+ aStt, *pSectFmt, headerData, 0, &aIdx, true, false);
+ }
+
+ // jetzt waere ein prima Zeitpunkt, um die Numerierung zu updaten
+ pDoc->UpdateNumRule();
+
+ if( GetCreateType() & nsSwTOXElement::TOX_MARK )
+ UpdateMarks( aIntl, pOwnChapterNode );
+
+ if( GetCreateType() & nsSwTOXElement::TOX_OUTLINELEVEL )
+ UpdateOutline( pOwnChapterNode );
+
+ if( GetCreateType() & nsSwTOXElement::TOX_TEMPLATE )
+ UpdateTemplate( pOwnChapterNode );
+
+ if( GetCreateType() & nsSwTOXElement::TOX_OLE ||
+ TOX_OBJECTS == SwTOXBase::GetType())
+ UpdateCntnt( nsSwTOXElement::TOX_OLE, pOwnChapterNode );
+
+ if( GetCreateType() & nsSwTOXElement::TOX_TABLE ||
+ (TOX_TABLES == SwTOXBase::GetType() && IsFromObjectNames()) )
+ UpdateTable( pOwnChapterNode );
+
+ if( GetCreateType() & nsSwTOXElement::TOX_GRAPHIC ||
+ (TOX_ILLUSTRATIONS == SwTOXBase::GetType() && IsFromObjectNames()))
+ UpdateCntnt( nsSwTOXElement::TOX_GRAPHIC, pOwnChapterNode );
+
+ if( GetSequenceName().Len() && !IsFromObjectNames() &&
+ (TOX_TABLES == SwTOXBase::GetType() ||
+ TOX_ILLUSTRATIONS == SwTOXBase::GetType() ) )
+ UpdateSequence( pOwnChapterNode );
+
+ if( GetCreateType() & nsSwTOXElement::TOX_FRAME )
+ UpdateCntnt( nsSwTOXElement::TOX_FRAME, pOwnChapterNode );
+
+ if(TOX_AUTHORITIES == SwTOXBase::GetType())
+ UpdateAuthorities( aIntl );
+
+ // Bei Bedarf Alphadelimitter einfuegen (nur bei Stichwoertern)
+ //
+ if( TOX_INDEX == SwTOXBase::GetType() &&
+ ( GetOptions() & nsSwTOIOptions::TOI_ALPHA_DELIMITTER ) )
+ InsertAlphaDelimitter( aIntl );
+
+ // sortierte Liste aller Verzeichnismarken und Verzeichnisbereiche
+ void* p = 0;
+ String* pStr = 0;
+ USHORT nCnt = 0, nFormMax = GetTOXForm().GetFormMax();
+ SvStringsDtor aStrArr( (BYTE)nFormMax );
+ SvPtrarr aCollArr( (BYTE)nFormMax );
+ for( ; nCnt < nFormMax; ++nCnt )
+ {
+ aCollArr.Insert( p, nCnt );
+ aStrArr.Insert( pStr, nCnt );
+ }
+
+ SwNodeIndex aInsPos( *pFirstEmptyNd, 1 );
+ for( nCnt = 0; nCnt < aSortArr.Count(); ++nCnt )
+ {
+ ::SetProgressState( 0, pDoc->GetDocShell() );
+
+ // setze den Text in das Verzeichniss
+ USHORT nLvl = aSortArr[ nCnt ]->GetLevel();
+ SwTxtFmtColl* pColl = (SwTxtFmtColl*)aCollArr[ nLvl ];
+ if( !pColl )
+ {
+ pColl = GetTxtFmtColl( nLvl );
+ aCollArr.Remove( nLvl );
+ p = pColl;
+ aCollArr.Insert( p , nLvl );
+ }
+
+ // Generierung: dynamische TabStops setzen
+ SwTxtNode* pTOXNd = pDoc->GetNodes().MakeTxtNode( aInsPos , pColl );
+ aSortArr[ nCnt ]->pTOXNd = pTOXNd;
+
+ // Generierung: Form auswerten und Platzhalter
+ // fuer die Seitennummer eintragen
+ //if it is a TOX_INDEX and the SwForm IsCommaSeparated()
+ // then a range of entries must be generated into one paragraph
+ USHORT nRange = 1;
+ if(TOX_INDEX == SwTOXBase::GetType() &&
+ GetTOXForm().IsCommaSeparated() &&
+ aSortArr[nCnt]->GetType() == TOX_SORT_INDEX)
+ {
+ const SwTOXMark& rMark = aSortArr[nCnt]->pTxtMark->GetTOXMark();
+ const String sPrimKey = rMark.GetPrimaryKey();
+ const String sSecKey = rMark.GetSecondaryKey();
+ const SwTOXMark* pNextMark = 0;
+ while(aSortArr.Count() > (nCnt + nRange)&&
+ aSortArr[nCnt + nRange]->GetType() == TOX_SORT_INDEX &&
+ 0 != (pNextMark = &(aSortArr[nCnt + nRange]->pTxtMark->GetTOXMark())) &&
+ pNextMark->GetPrimaryKey() == sPrimKey &&
+ pNextMark->GetSecondaryKey() == sSecKey)
+ nRange++;
+ }
+ // OD 18.03.2003 #106329# - pass node index of table-of-content section
+ // and default page description to method <GenerateText(..)>.
+ GenerateText( nCnt, nRange, aStrArr, pSectNd->GetIndex(), pDefaultPageDesc );
+ nCnt += nRange - 1;
+ }
+
+ // delete the first dummy node and remove all Cursor into the prev node
+ aInsPos = *pFirstEmptyNd;
+ {
+ SwPaM aCorPam( *pFirstEmptyNd );
+ aCorPam.GetPoint()->nContent.Assign( pFirstEmptyNd, 0 );
+ if( !aCorPam.Move( fnMoveForward ) )
+ aCorPam.Move( fnMoveBackward );
+ SwNodeIndex aEndIdx( aInsPos, 1 );
+ pDoc->CorrAbs( aInsPos, aEndIdx, *aCorPam.GetPoint(), TRUE );
+
+ // Task 70995 - save and restore PageDesc and Break Attributes
+ if( pFirstEmptyNd->HasSwAttrSet() )
+ {
+ if( GetTitle().Len() )
+ aEndIdx = *pSectNd;
+ else
+ aEndIdx = *pFirstEmptyNd;
+ SwCntntNode* pCNd = pDoc->GetNodes().GoNext( &aEndIdx );
+ if( pCNd ) // Robust against defect documents, e.g. i60336
+ pCNd->SetAttr( *pFirstEmptyNd->GetpSwAttrSet() );
+ }
+ }
+
+ // now create the new Frames
+ ULONG nIdx = pSectNd->GetIndex();
+ // don't delete if index is empty
+ if(nIdx + 2 < pSectNd->EndOfSectionIndex())
+ pDoc->GetNodes().Delete( aInsPos, 1 );
+
+ aN2L.RestoreUpperFrms( pDoc->GetNodes(), nIdx, nIdx + 1 );
+ if(pDoc->GetRootFrm())
+ SwFrm::CheckPageDescs( (SwPageFrm*)pDoc->GetRootFrm()->Lower() );
+
+ SetProtect( SwTOXBase::IsProtected() );
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: AlphaDelimitter einfuegen
+ --------------------------------------------------------------------*/
+
+
+void SwTOXBaseSection::InsertAlphaDelimitter( const SwTOXInternational& rIntl )
+{
+ SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
+ String sDeli, sLastDeli;
+ USHORT i = 0;
+ while( i < aSortArr.Count() )
+ {
+ ::SetProgressState( 0, pDoc->GetDocShell() );
+
+ USHORT nLevel = aSortArr[i]->GetLevel();
+
+ // Alpha-Delimitter ueberlesen
+ if( nLevel == FORM_ALPHA_DELIMITTER )
+ continue;
+
+ String sMyString, sMyStringReading;
+ aSortArr[i]->GetTxt( sMyString, sMyStringReading );
+
+ sDeli = rIntl.GetIndexKey( sMyString, sMyStringReading,
+ aSortArr[i]->GetLocale() );
+
+ // Delimitter schon vorhanden ??
+ if( sDeli.Len() && sLastDeli != sDeli )
+ {
+ // alle kleiner Blank wollen wir nicht haben -> sind Sonderzeichen
+ if( ' ' <= sDeli.GetChar( 0 ) )
+ {
+ SwTOXCustom* pCst = new SwTOXCustom( sDeli, aEmptyStr, FORM_ALPHA_DELIMITTER,
+ rIntl, aSortArr[i]->GetLocale() );
+ aSortArr.Insert( pCst, i++ );
+ }
+ sLastDeli = sDeli;
+ }
+
+ // Skippen bis gleibhes oder kleineres Level erreicht ist
+ do {
+ i++;
+ } while (i < aSortArr.Count() && aSortArr[i]->GetLevel() > nLevel);
+ }
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Template auswerten
+ --------------------------------------------------------------------*/
+
+SwTxtFmtColl* SwTOXBaseSection::GetTxtFmtColl( USHORT nLevel )
+{
+ SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
+ const String& rName = GetTOXForm().GetTemplate( nLevel );
+ SwTxtFmtColl* pColl = rName.Len() ? pDoc->FindTxtFmtCollByName(rName) :0;
+ if( !pColl )
+ {
+ USHORT nPoolFmt = 0;
+ const TOXTypes eMyType = SwTOXBase::GetType();
+ switch( eMyType )
+ {
+ case TOX_INDEX: nPoolFmt = RES_POOLCOLL_TOX_IDXH; break;
+ case TOX_USER:
+ if( nLevel < 6 )
+ nPoolFmt = RES_POOLCOLL_TOX_USERH;
+ else
+ nPoolFmt = RES_POOLCOLL_TOX_USER6 - 6;
+ break;
+ case TOX_ILLUSTRATIONS: nPoolFmt = RES_POOLCOLL_TOX_ILLUSH; break;
+ case TOX_OBJECTS: nPoolFmt = RES_POOLCOLL_TOX_OBJECTH; break;
+ case TOX_TABLES: nPoolFmt = RES_POOLCOLL_TOX_TABLESH; break;
+ case TOX_AUTHORITIES: nPoolFmt = RES_POOLCOLL_TOX_AUTHORITIESH; break;
+
+ case TOX_CONTENT:
+ // im Content Bereich gibt es einen Sprung!
+ if( nLevel < 6 )
+ nPoolFmt = RES_POOLCOLL_TOX_CNTNTH;
+ else
+ nPoolFmt = RES_POOLCOLL_TOX_CNTNT6 - 6;
+ break;
+ }
+
+ if(eMyType == TOX_AUTHORITIES && nLevel)
+ nPoolFmt = nPoolFmt + 1;
+ else if(eMyType == TOX_INDEX && nLevel)
+ {
+ //pool: Level 1,2,3, Delimiter
+ //SwForm: Delimiter, Level 1,2,3
+ nPoolFmt += 1 == nLevel ? nLevel + 3 : nLevel - 1;
+ }
+ else
+ nPoolFmt = nPoolFmt + nLevel;
+ pColl = pDoc->GetTxtCollFromPool( nPoolFmt );
+ }
+ return pColl;
+}
+
+
+/*--------------------------------------------------------------------
+ Beschreibung: Aus Markierungen erzeugen
+ --------------------------------------------------------------------*/
+
+void SwTOXBaseSection::UpdateMarks( const SwTOXInternational& rIntl,
+ const SwTxtNode* pOwnChapterNode )
+{
+ const SwModify* pType = SwTOXBase::GetRegisteredIn();
+ if( !pType->GetDepends() )
+ return;
+
+ SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
+ TOXTypes eTOXTyp = GetTOXType()->GetType();
+ SwClientIter aIter( *(SwModify*)pType );
+
+ SwTxtTOXMark* pTxtMark;
+ SwTOXMark* pMark;
+ for( pMark = (SwTOXMark*)aIter.First( TYPE( SwTOXMark )); pMark;
+ pMark = (SwTOXMark*)aIter.Next() )
+ {
+ ::SetProgressState( 0, pDoc->GetDocShell() );
+
+ if( pMark->GetTOXType()->GetType() == eTOXTyp &&
+ 0 != ( pTxtMark = pMark->GetTxtTOXMark() ) )
+ {
+ const SwTxtNode* pTOXSrc = pTxtMark->GetpTxtNd();
+ // nur TOXMarks einfuegen die im Doc stehen
+ // nicht die, die im UNDO stehen
+ //
+ // if selected use marks from the same chapter only
+ if( pTOXSrc->GetNodes().IsDocNodes() &&
+ pTOXSrc->GetTxt().Len() && pTOXSrc->GetDepends() &&
+ pTOXSrc->GetFrm() &&
+ (!IsFromChapter() || ::lcl_FindChapterNode( *pTOXSrc, 0 ) == pOwnChapterNode ) &&
+ !pTOXSrc->HasHiddenParaField() &&
+ !SwScriptInfo::IsInHiddenRange( *pTOXSrc, *pTxtMark->GetStart() ) )
+ {
+ SwTOXSortTabBase* pBase = 0;
+ if(TOX_INDEX == eTOXTyp)
+ {
+ // Stichwortverzeichnismarkierung
+ lang::Locale aLocale;
+ if ( pBreakIt->GetBreakIter().is() )
+ {
+ aLocale = pBreakIt->GetLocale(
+ pTOXSrc->GetLang( *pTxtMark->GetStart() ) );
+ }
+
+ pBase = new SwTOXIndex( *pTOXSrc, pTxtMark,
+ GetOptions(), FORM_ENTRY, rIntl, aLocale );
+ InsertSorted(pBase);
+ if(GetOptions() & nsSwTOIOptions::TOI_KEY_AS_ENTRY &&
+ pTxtMark->GetTOXMark().GetPrimaryKey().Len())
+ {
+ pBase = new SwTOXIndex( *pTOXSrc, pTxtMark,
+ GetOptions(), FORM_PRIMARY_KEY, rIntl, aLocale );
+ InsertSorted(pBase);
+ if(pTxtMark->GetTOXMark().GetSecondaryKey().Len())
+ {
+ pBase = new SwTOXIndex( *pTOXSrc, pTxtMark,
+ GetOptions(), FORM_SECONDARY_KEY, rIntl, aLocale );
+ InsertSorted(pBase);
+ }
+ }
+ }
+ else if( TOX_USER == eTOXTyp ||
+ pMark->GetLevel() <= GetLevel())
+ { // Inhaltsberzeichnismarkierung
+ // also used for user marks
+ pBase = new SwTOXContent( *pTOXSrc, pTxtMark, rIntl );
+ InsertSorted(pBase);
+ }
+ }
+ }
+ }
+}
+
+
+/*--------------------------------------------------------------------
+ Beschreibung: Verzeichnisinhalt aus Gliederungsebene generieren
+ --------------------------------------------------------------------*/
+
+
+void SwTOXBaseSection::UpdateOutline( const SwTxtNode* pOwnChapterNode )
+{
+ SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
+ SwNodes& rNds = pDoc->GetNodes();
+
+ const SwOutlineNodes& rOutlNds = rNds.GetOutLineNds();
+ for( USHORT n = 0; n < rOutlNds.Count(); ++n )
+ {
+ ::SetProgressState( 0, pDoc->GetDocShell() );
+ SwTxtNode* pTxtNd = rOutlNds[ n ]->GetTxtNode();
+ if( pTxtNd && pTxtNd->Len() && pTxtNd->GetDepends() &&
+ //USHORT(pTxtNd->GetTxtColl()->GetOutlineLevel()+1) <= GetLevel() && //#outline level,zhaojianwei
+ USHORT( pTxtNd->GetAttrOutlineLevel()) <= GetLevel() && //<-end,zhaojianwei
+ pTxtNd->GetFrm() &&
+ !pTxtNd->HasHiddenParaField() &&
+ !pTxtNd->HasHiddenCharAttribute( true ) &&
+ ( !IsFromChapter() ||
+ ::lcl_FindChapterNode( *pTxtNd, 0 ) == pOwnChapterNode ))
+ {
+ SwTOXPara * pNew = new SwTOXPara( *pTxtNd, nsSwTOXElement::TOX_OUTLINELEVEL );
+ InsertSorted( pNew );
+ }
+ }
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Verzeichnisinhalt aus Vorlagenbereichen generieren
+ --------------------------------------------------------------------*/
+
+void SwTOXBaseSection::UpdateTemplate( const SwTxtNode* pOwnChapterNode )
+{
+ SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
+ for(USHORT i = 0; i < MAXLEVEL; i++)
+ {
+ String sTmpStyleNames = GetStyleNames(i);
+ USHORT nTokenCount = sTmpStyleNames.GetTokenCount(TOX_STYLE_DELIMITER);
+ for( USHORT nStyle = 0; nStyle < nTokenCount; ++nStyle )
+ {
+ SwTxtFmtColl* pColl = pDoc->FindTxtFmtCollByName(
+ sTmpStyleNames.GetToken( nStyle,
+ TOX_STYLE_DELIMITER ));
+ //TODO: no outline Collections in content indexes if OutlineLevels are already included
+ if( !pColl ||
+ ( TOX_CONTENT == SwTOXBase::GetType() &&
+ GetCreateType() & nsSwTOXElement::TOX_OUTLINELEVEL &&
+ //NO_NUMBERING != pColl->GetOutlineLevel() ) )//#outline level,zhaojianwei
+ pColl->IsAssignedToListLevelOfOutlineStyle()) )//<-end,zhaojianwei
+ continue;
+
+ SwClientIter aIter( *pColl );
+ SwTxtNode* pTxtNd = (SwTxtNode*)aIter.First( TYPE( SwTxtNode ));
+ for( ; pTxtNd; pTxtNd = (SwTxtNode*)aIter.Next() )
+ {
+ ::SetProgressState( 0, pDoc->GetDocShell() );
+
+ if( pTxtNd->GetTxt().Len() && pTxtNd->GetFrm() &&
+ pTxtNd->GetNodes().IsDocNodes() &&
+ ( !IsFromChapter() || pOwnChapterNode ==
+ ::lcl_FindChapterNode( *pTxtNd, 0 ) ) )
+ {
+ SwTOXPara * pNew = new SwTOXPara( *pTxtNd, nsSwTOXElement::TOX_TEMPLATE, i + 1 );
+ InsertSorted(pNew);
+ }
+ }
+ }
+ }
+}
+
+/* -----------------14.07.99 09:59-------------------
+ Description: generate content from sequence fields
+ --------------------------------------------------*/
+void SwTOXBaseSection::UpdateSequence( const SwTxtNode* pOwnChapterNode )
+{
+ SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
+ SwFieldType* pSeqFld = pDoc->GetFldType(RES_SETEXPFLD, GetSequenceName(), false);
+ if(!pSeqFld)
+ return;
+
+ SwClientIter aIter( *pSeqFld );
+ SwFmtFld* pFmtFld = (SwFmtFld*)aIter.First( TYPE( SwFmtFld ));
+ for( ; pFmtFld; pFmtFld = (SwFmtFld*)aIter.Next() )
+ {
+ const SwTxtFld* pTxtFld = pFmtFld->GetTxtFld();
+ if(!pTxtFld)
+ continue;
+ const SwTxtNode& rTxtNode = pTxtFld->GetTxtNode();
+ ::SetProgressState( 0, pDoc->GetDocShell() );
+
+ if( rTxtNode.GetTxt().Len() && rTxtNode.GetFrm() &&
+ rTxtNode.GetNodes().IsDocNodes() &&
+ ( !IsFromChapter() ||
+ ::lcl_FindChapterNode( rTxtNode, 0 ) == pOwnChapterNode ) )
+ {
+ SwTOXPara * pNew = new SwTOXPara( rTxtNode, nsSwTOXElement::TOX_SEQUENCE, 1 );
+ //set indexes if the number or the reference text are to be displayed
+ if( GetCaptionDisplay() == CAPTION_TEXT )
+ {
+ pNew->SetStartIndex(
+ SwGetExpField::GetReferenceTextPos( *pFmtFld, *pDoc ));
+ }
+ else if(GetCaptionDisplay() == CAPTION_NUMBER)
+ {
+ pNew->SetEndIndex(*pTxtFld->GetStart() + 1);
+ }
+ InsertSorted(pNew);
+ }
+ }
+}
+/* -----------------15.09.99 14:18-------------------
+
+ --------------------------------------------------*/
+void SwTOXBaseSection::UpdateAuthorities( const SwTOXInternational& rIntl )
+{
+ SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
+ SwFieldType* pAuthFld = pDoc->GetFldType(RES_AUTHORITY, aEmptyStr, false);
+ if(!pAuthFld)
+ return;
+
+ SwClientIter aIter( *pAuthFld );
+ SwFmtFld* pFmtFld = (SwFmtFld*)aIter.First( TYPE( SwFmtFld ));
+ for( ; pFmtFld; pFmtFld = (SwFmtFld*)aIter.Next() )
+ {
+ const SwTxtFld* pTxtFld = pFmtFld->GetTxtFld();
+ //undo
+ if(!pTxtFld)
+ continue;
+ const SwTxtNode& rTxtNode = pTxtFld->GetTxtNode();
+ ::SetProgressState( 0, pDoc->GetDocShell() );
+
+// const SwTxtNode* pChapterCompareNode = 0;
+
+ if( rTxtNode.GetTxt().Len() && rTxtNode.GetFrm() &&
+ rTxtNode.GetNodes().IsDocNodes() /*&&
+ (!IsFromChapter() || pChapterCompareNode == pOwnChapterNode) */)
+ {
+ //#106485# the body node has to be used!
+ SwCntntFrm *pFrm = rTxtNode.GetFrm();
+ SwPosition aFldPos(rTxtNode);
+ const SwTxtNode* pTxtNode = 0;
+ if(pFrm && !pFrm->IsInDocBody())
+ pTxtNode = GetBodyTxtNode( *pDoc, aFldPos, *pFrm );
+ if(!pTxtNode)
+ pTxtNode = &rTxtNode;
+ SwTOXAuthority* pNew = new SwTOXAuthority( *pTxtNode, *pFmtFld, rIntl );
+
+ InsertSorted(pNew);
+ }
+ }
+}
+
+long lcl_IsSOObject( const SvGlobalName& rFactoryNm )
+{
+ static struct _SoObjType {
+ long nFlag;
+ // GlobalNameId
+ struct _GlobalNameIds {
+ UINT32 n1;
+ USHORT n2, n3;
+ BYTE b8, b9, b10, b11, b12, b13, b14, b15;
+ } aGlNmIds[4];
+ } aArr[] = {
+ { nsSwTOOElements::TOO_MATH,
+ { {SO3_SM_CLASSID_60},{SO3_SM_CLASSID_50},
+ {SO3_SM_CLASSID_40},{SO3_SM_CLASSID_30} } },
+ { nsSwTOOElements::TOO_CHART,
+ { {SO3_SCH_CLASSID_60},{SO3_SCH_CLASSID_50},
+ {SO3_SCH_CLASSID_40},{SO3_SCH_CLASSID_30} } },
+ { nsSwTOOElements::TOO_CALC,
+ { {SO3_SC_CLASSID_60},{SO3_SC_CLASSID_50},
+ {SO3_SC_CLASSID_40},{SO3_SC_CLASSID_30} } },
+ { nsSwTOOElements::TOO_DRAW_IMPRESS,
+ { {SO3_SIMPRESS_CLASSID_60},{SO3_SIMPRESS_CLASSID_50},
+ {SO3_SIMPRESS_CLASSID_40},{SO3_SIMPRESS_CLASSID_30} } },
+ { nsSwTOOElements::TOO_DRAW_IMPRESS,
+ { {SO3_SDRAW_CLASSID_60},{SO3_SDRAW_CLASSID_50}}},
+ { 0,{{0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0} } }
+ };
+
+ long nRet = 0;
+ for( const _SoObjType* pArr = aArr; !nRet && pArr->nFlag; ++pArr )
+ for ( int n = 0; n < 4; ++n )
+ {
+ const _SoObjType::_GlobalNameIds& rId = pArr->aGlNmIds[ n ];
+ if( !rId.n1 )
+ break;
+ SvGlobalName aGlbNm( rId.n1, rId.n2, rId.n3,
+ rId.b8, rId.b9, rId.b10, rId.b11,
+ rId.b12, rId.b13, rId.b14, rId.b15 );
+ if( rFactoryNm == aGlbNm )
+ {
+ nRet = pArr->nFlag;
+ break;
+ }
+ }
+
+ return nRet;
+}
+
+void SwTOXBaseSection::UpdateCntnt( SwTOXElement eMyType,
+ const SwTxtNode* pOwnChapterNode )
+{
+ SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
+ SwNodes& rNds = pDoc->GetNodes();
+ // auf den 1. Node der 1. Section
+ ULONG nIdx = rNds.GetEndOfAutotext().StartOfSectionIndex() + 2,
+ nEndIdx = rNds.GetEndOfAutotext().GetIndex();
+
+ while( nIdx < nEndIdx )
+ {
+ ::SetProgressState( 0, pDoc->GetDocShell() );
+
+ SwNode* pNd = rNds[ nIdx ];
+ SwCntntNode* pCNd = 0;
+ switch( eMyType )
+ {
+ case nsSwTOXElement::TOX_FRAME:
+ if( !pNd->IsNoTxtNode() )
+ {
+ pCNd = pNd->GetCntntNode();
+ if( !pCNd )
+ {
+ SwNodeIndex aTmp( *pNd );
+ pCNd = rNds.GoNext( &aTmp );
+ }
+ }
+ break;
+ case nsSwTOXElement::TOX_GRAPHIC:
+ if( pNd->IsGrfNode() )
+ pCNd = (SwCntntNode*)pNd;
+ break;
+ case nsSwTOXElement::TOX_OLE:
+ if( pNd->IsOLENode() )
+ {
+ BOOL bInclude = TRUE;
+ if(TOX_OBJECTS == SwTOXBase::GetType())
+ {
+ SwOLENode* pOLENode = pNd->GetOLENode();
+ long nMyOLEOptions = GetOLEOptions();
+ SwOLEObj& rOLEObj = pOLENode->GetOLEObj();
+
+ if( rOLEObj.IsOleRef() ) //Noch nicht geladen
+ {
+ SvGlobalName aTmpName = SvGlobalName( rOLEObj.GetOleRef()->getClassID() );
+ long nObj = ::lcl_IsSOObject( aTmpName );
+ bInclude = ( (nMyOLEOptions & nsSwTOOElements::TOO_OTHER) && 0 == nObj)
+ || (0 != (nMyOLEOptions & nObj));
+ }
+ else
+ {
+ DBG_ERROR("OLE-object nicht geladen?");
+ bInclude = FALSE;
+ }
+ }
+
+ if(bInclude)
+ pCNd = (SwCntntNode*)pNd;
+ }
+ break;
+ default: break;
+ }
+
+ if( pCNd )
+ {
+ //find node in body text
+ int nSetLevel = USHRT_MAX;
+
+ //#111105# tables of tables|illustrations|objects don't support hierarchies
+ if( IsLevelFromChapter() &&
+ TOX_TABLES != SwTOXBase::GetType() &&
+ TOX_ILLUSTRATIONS != SwTOXBase::GetType() &&
+ TOX_OBJECTS != SwTOXBase::GetType() )
+ {
+ const SwTxtNode* pOutlNd = ::lcl_FindChapterNode( *pCNd,
+ MAXLEVEL - 1 );
+ if( pOutlNd )
+ {
+ //USHORT nTmp = pOutlNd->GetTxtColl()->GetOutlineLevel();//#outline level,zhaojianwei
+ //if( nTmp < NO_NUMBERING )
+ // nSetLevel = nTmp + 1;
+ if( pOutlNd->GetTxtColl()->IsAssignedToListLevelOfOutlineStyle())
+ nSetLevel = pOutlNd->GetTxtColl()->GetAttrOutlineLevel() ;//<-end,zhaojianwei
+ }
+ }
+
+ if( pCNd->GetFrm() && ( !IsFromChapter() ||
+ ::lcl_FindChapterNode( *pCNd, 0 ) == pOwnChapterNode ))
+ {
+ SwTOXPara * pNew = new SwTOXPara( *pCNd, eMyType,
+ ( USHRT_MAX != nSetLevel )
+ ? static_cast<USHORT>(nSetLevel)
+ : FORM_ALPHA_DELIMITTER );
+ InsertSorted( pNew );
+ }
+ }
+
+ nIdx = pNd->StartOfSectionNode()->EndOfSectionIndex() + 2; // 2 == End-/StartNode
+ }
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Tabelleneintraege zusammensuchen
+ --------------------------------------------------------------------*/
+
+void SwTOXBaseSection::UpdateTable( const SwTxtNode* pOwnChapterNode )
+{
+ SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
+ SwNodes& rNds = pDoc->GetNodes();
+ const SwFrmFmts& rArr = *pDoc->GetTblFrmFmts();
+
+ for( USHORT n = 0; n < rArr.Count(); ++n )
+ {
+ ::SetProgressState( 0, pDoc->GetDocShell() );
+
+ SwTable* pTmpTbl = SwTable::FindTable( rArr[ n ] );
+ SwTableBox* pFBox;
+ if( pTmpTbl && 0 != (pFBox = pTmpTbl->GetTabSortBoxes()[0] ) &&
+ pFBox->GetSttNd() && pFBox->GetSttNd()->GetNodes().IsDocNodes() )
+ {
+ const SwTableNode* pTblNd = pFBox->GetSttNd()->FindTableNode();
+ SwNodeIndex aCntntIdx( *pTblNd, 1 );
+
+ SwCntntNode* pCNd;
+ while( 0 != ( pCNd = rNds.GoNext( &aCntntIdx ) ) &&
+ aCntntIdx.GetIndex() < pTblNd->EndOfSectionIndex() )
+ {
+ if( pCNd->GetFrm() && (!IsFromChapter() ||
+ ::lcl_FindChapterNode( *pCNd, 0 ) == pOwnChapterNode ))
+ {
+ SwTOXTable * pNew = new SwTOXTable( *pCNd );
+ if( IsLevelFromChapter() && TOX_TABLES != SwTOXBase::GetType())
+ {
+ const SwTxtNode* pOutlNd =
+ ::lcl_FindChapterNode( *pCNd, MAXLEVEL - 1 );
+ if( pOutlNd )
+ {
+ //USHORT nTmp = pOutlNd->GetTxtColl()->GetOutlineLevel();//#outline level,zhaojianwei
+ //if( nTmp < NO_NUMBERING )
+ // pNew->SetLevel( nTmp + 1 );
+ if( pOutlNd->GetTxtColl()->IsAssignedToListLevelOfOutlineStyle())
+ {
+ const int nTmp = pOutlNd->GetTxtColl()->GetAttrOutlineLevel();
+ pNew->SetLevel( static_cast<USHORT>(nTmp) );//<-end ,zhaojianwei
+ }
+ }
+ }
+ InsertSorted(pNew);
+ break;
+ }
+ }
+ }
+ }
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: String generieren anhand der Form
+ SonderZeichen 0-31 und 255 entfernen
+ --------------------------------------------------------------------*/
+
+String lcl_GetNumString( const SwTOXSortTabBase& rBase, sal_Bool bUsePrefix, BYTE nLevel )
+{
+ String sRet;
+
+ if( !rBase.pTxtMark && rBase.aTOXSources.Count() > 0 )
+ { // nur wenn es keine Marke ist
+ const SwTxtNode* pNd = rBase.aTOXSources[0].pNd->GetTxtNode();
+ if( pNd )
+ {
+ const SwNumRule* pRule = pNd->GetNumRule();
+
+ if( pRule && pNd->GetActualListLevel() < MAXLEVEL )
+ sRet = pNd->GetNumString(bUsePrefix, nLevel);
+ }
+ }
+ return sRet;
+}
+
+// OD 18.03.2003 #106329# - add parameter <_TOXSectNdIdx> and <_pDefaultPageDesc>
+// in order to control, which page description is used, no appropriate one is found.
+void SwTOXBaseSection::GenerateText( USHORT nArrayIdx,
+ USHORT nCount,
+ SvStringsDtor& ,
+ const sal_uInt32 _nTOXSectNdIdx,
+ const SwPageDesc* _pDefaultPageDesc )
+{
+ LinkStructArr aLinkArr;
+ SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
+ ::SetProgressState( 0, pDoc->GetDocShell() );
+
+ //pTOXNd is only set at the first mark
+ SwTxtNode* pTOXNd = (SwTxtNode*)aSortArr[nArrayIdx]->pTOXNd;
+ String& rTxt = (String&)pTOXNd->GetTxt();
+ rTxt.Erase();
+ for(USHORT nIndex = nArrayIdx; nIndex < nArrayIdx + nCount; nIndex++)
+ {
+ if(nIndex > nArrayIdx)
+ rTxt.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ", " )); // comma separation
+ // String mit dem Pattern aus der Form initialisieren
+ const SwTOXSortTabBase& rBase = *aSortArr[nIndex];
+ USHORT nLvl = rBase.GetLevel();
+ ASSERT( nLvl < GetTOXForm().GetFormMax(), "ungueltiges FORM_LEVEL");
+
+ SvxTabStopItem aTStops( 0, 0, SVX_TAB_ADJUST_DEFAULT, RES_PARATR_TABSTOP );
+ xub_StrLen nLinkStartPosition = STRING_NOTFOUND;
+ String sLinkCharacterStyle; //default to "Default" character style - which is none
+ String sURL;
+ // create an enumerator
+ // #i21237#
+ SwFormTokens aPattern = GetTOXForm().GetPattern(nLvl);
+ SwFormTokens::iterator aIt = aPattern.begin();
+ // remove text from node
+ while(aIt != aPattern.end()) // #i21237#
+ {
+ SwFormToken aToken = *aIt; // #i21237#
+ xub_StrLen nStartCharStyle = rTxt.Len();
+ switch( aToken.eTokenType )
+ {
+ case TOKEN_ENTRY_NO:
+ // fuer Inhaltsverzeichnis Numerierung
+ rTxt.Insert( lcl_GetNumString( rBase, aToken.nChapterFormat == CF_NUMBER, static_cast<BYTE>(aToken.nOutlineLevel - 1)) );
+ break;
+
+ case TOKEN_ENTRY_TEXT:
+ {
+ SwIndex aIdx( pTOXNd, rTxt.Len() );
+ rBase.FillText( *pTOXNd, aIdx );
+ }
+ break;
+
+ case TOKEN_ENTRY:
+ {
+ // fuer Inhaltsverzeichnis Numerierung
+ rTxt.Insert( lcl_GetNumString( rBase, sal_True, MAXLEVEL ));
+
+ SwIndex aIdx( pTOXNd, rTxt.Len() );
+ rBase.FillText( *pTOXNd, aIdx );
+ }
+ break;
+
+ case TOKEN_TAB_STOP:
+ if (aToken.bWithTab) // #i21237#
+ rTxt.Append('\t');
+ //
+
+ if(SVX_TAB_ADJUST_END > aToken.eTabAlign)
+ {
+ const SvxLRSpaceItem& rLR =
+ (SvxLRSpaceItem&)pTOXNd->
+ SwCntntNode::GetAttr( RES_LR_SPACE, TRUE );
+
+ long nTabPosition = aToken.nTabStopPosition;
+ if( !GetTOXForm().IsRelTabPos() && rLR.GetTxtLeft() )
+ nTabPosition -= rLR.GetTxtLeft();
+ aTStops.Insert( SvxTabStop( nTabPosition,
+ aToken.eTabAlign,
+ cDfltDecimalChar,
+ aToken.cTabFillChar ));
+ }
+ else
+ {
+ const SwPageDesc* pPageDesc = ((SwFmtPageDesc&)pTOXNd->
+ SwCntntNode::GetAttr( RES_PAGEDESC )).GetPageDesc();
+
+ BOOL bCallFindRect = TRUE;
+ long nRightMargin;
+ if( pPageDesc )
+ {
+ const SwFrm* pFrm = pTOXNd->GetFrm( 0, 0, TRUE );
+ if( !pFrm || 0 == ( pFrm = pFrm->FindPageFrm() ) ||
+ pPageDesc != ((SwPageFrm*)pFrm)->GetPageDesc() )
+ // dann muss man ueber den PageDesc gehen
+ bCallFindRect = FALSE;
+ }
+
+ SwRect aNdRect;
+ if( bCallFindRect )
+ aNdRect = pTOXNd->FindLayoutRect( TRUE );
+
+ if( aNdRect.IsEmpty() )
+ {
+ // dann hilft alles nichts, wir muessen ueber die Seiten-
+ // vorlage gehen.
+ // OD 18.03.2003 #106329# - call
+ sal_uInt32 nPgDescNdIdx = pTOXNd->GetIndex() + 1;
+ sal_uInt32* pPgDescNdIdx = &nPgDescNdIdx;
+ pPageDesc = pTOXNd->FindPageDesc( FALSE, pPgDescNdIdx );
+ if ( !pPageDesc ||
+ *pPgDescNdIdx < _nTOXSectNdIdx )
+ {
+ // use default page description, if none is found
+ // or the found one is given by a node before the
+ // table-of-content section.
+ pPageDesc = _pDefaultPageDesc;
+ }
+
+ const SwFrmFmt& rPgDscFmt = pPageDesc->GetMaster();
+ nRightMargin = rPgDscFmt.GetFrmSize().GetWidth() -
+ rPgDscFmt.GetLRSpace().GetLeft() -
+ rPgDscFmt.GetLRSpace().GetRight();
+ }
+ else
+ nRightMargin = aNdRect.Width();
+ //#i24363# tab stops relative to indent
+ if( pDoc->get(IDocumentSettingAccess::TABS_RELATIVE_TO_INDENT) )
+ {
+ //left margin of paragraph style
+ const SvxLRSpaceItem& rLRSpace = pTOXNd->GetTxtColl()->GetLRSpace();
+ nRightMargin -= rLRSpace.GetLeft();
+ nRightMargin -= rLRSpace.GetTxtFirstLineOfst();
+ }
+
+ aTStops.Insert( SvxTabStop( nRightMargin, SVX_TAB_ADJUST_RIGHT,
+ cDfltDecimalChar,
+ aToken.cTabFillChar ));
+ }
+ break;
+
+ case TOKEN_TEXT:
+ rTxt.Append( aToken.sText );
+ break;
+
+ case TOKEN_PAGE_NUMS:
+ // Platzhalter fuer Seitennummer(n) es wird nur der erste beachtet
+ //
+ {
+ // Die Anzahl der gleichen Eintrage bestimmt die Seitennummern-Pattern
+ //
+ USHORT nSize = rBase.aTOXSources.Count();
+ if( nSize > 0 )
+ {
+ String aInsStr( cNumRepl );
+ for(USHORT i=1; i < nSize; ++i)
+ {
+ aInsStr.AppendAscii( sPageDeli );
+ aInsStr += cNumRepl;
+ }
+ aInsStr += cEndPageNum;
+ rTxt.Append( aInsStr );
+ }
+// // Tab entfernen, wenn keine Seitennummer
+// else if( rTxt.Len() && '\t' == rTxt.GetChar( rTxt.Len() - 1 ))
+// rTxt.Erase( rTxt.Len()-1, 1 );
+ }
+ break;
+
+ case TOKEN_CHAPTER_INFO:
+ {
+ // ein bischen trickreich: suche irgend einen Frame
+ const SwTOXSource* pTOXSource = 0;
+ if(rBase.aTOXSources.Count())
+ pTOXSource = &rBase.aTOXSources[0];
+
+ // --> OD 2008-02-14 #i53420#
+// if( pTOXSource && pTOXSource->pNd
+// pTOXSource->pNd->IsTxtNode() )
+ if ( pTOXSource && pTOXSource->pNd &&
+ pTOXSource->pNd->IsCntntNode() )
+ // <--
+ {
+ const SwCntntFrm* pFrm = pTOXSource->pNd->GetFrm();
+ if( pFrm )
+ {
+ SwChapterFieldType aFldTyp;
+ SwChapterField aFld( &aFldTyp, aToken.nChapterFormat );
+ aFld.SetLevel( static_cast<BYTE>(aToken.nOutlineLevel - 1) );
+ // --> OD 2008-02-14 #i53420#
+// aFld.ChangeExpansion( pFrm, (SwTxtNode*)pTOXSource->pNd, TRUE );
+ aFld.ChangeExpansion( pFrm,
+ dynamic_cast<const SwCntntNode*>(pTOXSource->pNd),
+ TRUE );
+ // <--
+ //---> i89791
+ // OD 2008-06-26 - continue to support CF_NUMBER
+ // and CF_NUM_TITLE in order to handle ODF 1.0/1.1
+ // written by OOo 3.x in the same way as OOo 2.x
+ // would handle them.
+ if ( CF_NUM_NOPREPST_TITLE == aToken.nChapterFormat ||
+ CF_NUMBER == aToken.nChapterFormat )
+ rTxt.Insert(aFld.GetNumber()); //get the string number without pre/postfix
+ else if ( CF_NUMBER_NOPREPST == aToken.nChapterFormat ||
+ CF_NUM_TITLE == aToken.nChapterFormat )
+ //<---
+ {
+ rTxt += aFld.GetNumber();
+ rTxt += ' ';
+ rTxt += aFld.GetTitle();
+ }
+ else if(CF_TITLE == aToken.nChapterFormat)
+ rTxt += aFld.GetTitle();
+ }
+ }
+ }
+ break;
+
+ case TOKEN_LINK_START:
+ nLinkStartPosition = rTxt.Len();
+ sLinkCharacterStyle = aToken.sCharStyleName;
+ break;
+
+ case TOKEN_LINK_END:
+ //TODO: only paired start/end tokens are valid
+ if( STRING_NOTFOUND != nLinkStartPosition)
+ {
+ SwIndex aIdx( pTOXNd, nLinkStartPosition );
+ //pTOXNd->Erase( aIdx, SwForm::nFormLinkSttLen );
+ xub_StrLen nEnd = rTxt.Len();
+
+ if( !sURL.Len() )
+ {
+ sURL = rBase.GetURL();
+ if( !sURL.Len() )
+ break;
+ }
+ LinkStruct* pNewLink = new LinkStruct(sURL, nLinkStartPosition,
+ nEnd);
+ pNewLink->aINetFmt.SetVisitedFmt(sLinkCharacterStyle);
+ pNewLink->aINetFmt.SetINetFmt(sLinkCharacterStyle);
+ if(sLinkCharacterStyle.Len())
+ {
+ USHORT nPoolId =
+ SwStyleNameMapper::GetPoolIdFromUIName( sLinkCharacterStyle, nsSwGetPoolIdFromName::GET_POOLID_CHRFMT );
+ pNewLink->aINetFmt.SetVisitedFmtId(nPoolId);
+ pNewLink->aINetFmt.SetINetFmtId(nPoolId);
+ }
+ else
+ {
+ pNewLink->aINetFmt.SetVisitedFmtId(USHRT_MAX);
+ pNewLink->aINetFmt.SetINetFmtId(USHRT_MAX);
+ }
+ aLinkArr.Insert( pNewLink, aLinkArr.Count() );
+ nLinkStartPosition = STRING_NOTFOUND;
+ sLinkCharacterStyle.Erase();
+ }
+ break;
+
+ case TOKEN_AUTHORITY:
+ {
+ ToxAuthorityField eField = (ToxAuthorityField)aToken.nAuthorityField;
+ SwIndex aIdx( pTOXNd, rTxt.Len() );
+ rBase.FillText( *pTOXNd, aIdx, static_cast<USHORT>(eField) );
+ }
+ break;
+ case TOKEN_END: break;
+ }
+
+ if( aToken.sCharStyleName.Len() )
+ {
+ SwCharFmt* pCharFmt;
+ if( USHRT_MAX != aToken.nPoolId )
+ pCharFmt = pDoc->GetCharFmtFromPool( aToken.nPoolId );
+ else
+ pCharFmt = pDoc->FindCharFmtByName( aToken.sCharStyleName);
+
+ if (pCharFmt)
+ {
+ SwFmtCharFmt aFmt( pCharFmt );
+ pTOXNd->InsertItem( aFmt, nStartCharStyle,
+ rTxt.Len(), nsSetAttrMode::SETATTR_DONTEXPAND );
+ }
+ }
+
+ aIt++; // #i21237#
+ }
+
+ pTOXNd->SetAttr( aTStops );
+ }
+
+ if(aLinkArr.Count())
+ for(USHORT i = 0; i < aLinkArr.Count(); ++i )
+ {
+ LinkStruct* pTmp = aLinkArr.GetObject(i);
+ pTOXNd->InsertItem( pTmp->aINetFmt, pTmp->nStartTextPos,
+ pTmp->nEndTextPos);
+ }
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Seitennummer errechnen und nach dem Formatieren
+ eintragen
+ --------------------------------------------------------------------*/
+
+void SwTOXBaseSection::UpdatePageNum()
+{
+ if( !aSortArr.Count() )
+ return ;
+
+ // die aktuellen Seitennummern ins Verzeichnis eintragen
+ SwPageFrm* pAktPage = 0;
+ USHORT nPage = 0;
+ SwDoc* pDoc = (SwDoc*)GetFmt()->GetDoc();
+
+ SwTOXInternational aIntl( GetLanguage(),
+ TOX_INDEX == GetTOXType()->GetType() ?
+ GetOptions() : 0,
+ GetSortAlgorithm() );
+
+ for( USHORT nCnt = 0; nCnt < aSortArr.Count(); ++nCnt )
+ {
+ // Schleife ueber alle SourceNodes
+ SvUShorts aNums; //Die Seitennummern
+ SvPtrarr aDescs; //Die PageDescriptoren passend zu den Seitennummern.
+ SvUShorts* pMainNums = 0; // contains page numbers of main entries
+
+ // process run in lines
+ USHORT nRange = 0;
+ if(GetTOXForm().IsCommaSeparated() &&
+ aSortArr[nCnt]->GetType() == TOX_SORT_INDEX)
+ {
+ const SwTOXMark& rMark = aSortArr[nCnt]->pTxtMark->GetTOXMark();
+ const String sPrimKey = rMark.GetPrimaryKey();
+ const String sSecKey = rMark.GetSecondaryKey();
+ const SwTOXMark* pNextMark = 0;
+ while(aSortArr.Count() > (nCnt + nRange)&&
+ aSortArr[nCnt + nRange]->GetType() == TOX_SORT_INDEX &&
+ 0 != (pNextMark = &(aSortArr[nCnt + nRange]->pTxtMark->GetTOXMark())) &&
+ pNextMark->GetPrimaryKey() == sPrimKey &&
+ pNextMark->GetSecondaryKey() == sSecKey)
+ nRange++;
+ }
+ else
+ nRange = 1;
+
+ for(USHORT nRunInEntry = nCnt; nRunInEntry < nCnt + nRange; nRunInEntry++)
+ {
+ SwTOXSortTabBase* pSortBase = aSortArr[nRunInEntry];
+ USHORT nSize = pSortBase->aTOXSources.Count();
+ USHORT i;
+ for( USHORT j = 0; j < nSize; ++j )
+ {
+ ::SetProgressState( 0, pDoc->GetDocShell() );
+
+ SwTOXSource& rTOXSource = pSortBase->aTOXSources[j];
+ if( rTOXSource.pNd )
+ {
+ SwCntntFrm* pFrm = rTOXSource.pNd->GetFrm();
+ ASSERT( pFrm || pDoc->IsUpdateTOX(), "TOX, no Frame found");
+ if( !pFrm )
+ continue;
+ if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->HasFollow() )
+ {
+ // dann suche den richtigen heraus
+ SwTxtFrm* pNext = (SwTxtFrm*)pFrm;
+ while( 0 != ( pNext = (SwTxtFrm*)pFrm->GetFollow() )
+ && rTOXSource.nPos >= pNext->GetOfst() )
+ pFrm = pNext;
+ }
+
+ SwPageFrm* pTmpPage = pFrm->FindPageFrm();
+ if( pTmpPage != pAktPage )
+ {
+ nPage = pTmpPage->GetVirtPageNum();
+ pAktPage = pTmpPage;
+ }
+
+ // sortiert einfuegen
+ for( i = 0; i < aNums.Count() && aNums[i] < nPage; ++i )
+ ;
+
+ if( i >= aNums.Count() || aNums[ i ] != nPage )
+ {
+ aNums.Insert( nPage, i );
+ aDescs.Insert( (void*)pAktPage->GetPageDesc(), i );
+ }
+ // is it a main entry?
+ if(TOX_SORT_INDEX == pSortBase->GetType() &&
+ rTOXSource.bMainEntry)
+ {
+ if(!pMainNums)
+ pMainNums = new SvUShorts;
+ pMainNums->Insert(nPage, pMainNums->Count());
+ }
+ }
+ }
+ // einfuegen der Seitennummer in den Verzeichnis-Text-Node
+ const SwTOXSortTabBase* pBase = aSortArr[ nCnt ];
+ if(pBase->pTOXNd)
+ {
+ const SwTxtNode* pTxtNd = pBase->pTOXNd->GetTxtNode();
+ ASSERT( pTxtNd, "kein TextNode, falsches Verzeichnis" );
+
+ _UpdatePageNum( (SwTxtNode*)pTxtNd, aNums, aDescs, pMainNums,
+ aIntl );
+ }
+ DELETEZ(pMainNums);
+ aNums.Remove(0, aNums.Count());
+ }
+ }
+ // nach dem Setzen der richtigen Seitennummer, das Mapping-Array
+ // wieder loeschen !!
+ aSortArr.DeleteAndDestroy( 0, aSortArr.Count() );
+}
+
+
+/*--------------------------------------------------------------------
+ Beschreibung: Austausch der Seitennummer-Platzhalter
+ --------------------------------------------------------------------*/
+
+// search for the page no in the array of main entry page numbers
+BOOL lcl_HasMainEntry( const SvUShorts* pMainEntryNums, USHORT nToFind )
+{
+ for(USHORT i = 0; pMainEntryNums && i < pMainEntryNums->Count(); ++i)
+ if(nToFind == (*pMainEntryNums)[i])
+ return TRUE;
+ return FALSE;
+}
+
+void SwTOXBaseSection::_UpdatePageNum( SwTxtNode* pNd,
+ const SvUShorts& rNums,
+ const SvPtrarr & rDescs,
+ const SvUShorts* pMainEntryNums,
+ const SwTOXInternational& rIntl )
+{
+ //collect starts end ends of main entry character style
+ SvUShorts* pCharStyleIdx = pMainEntryNums ? new SvUShorts : 0;
+
+ String sSrchStr( cNumRepl );
+ sSrchStr.AppendAscii( sPageDeli ) += cNumRepl;
+ xub_StrLen nStartPos = pNd->GetTxt().Search( sSrchStr );
+ ( sSrchStr = cNumRepl ) += cEndPageNum;
+ xub_StrLen nEndPos = pNd->GetTxt().Search( sSrchStr );
+ USHORT i;
+
+ if( STRING_NOTFOUND == nEndPos || !rNums.Count() )
+ return;
+
+ if( STRING_NOTFOUND == nStartPos || nStartPos > nEndPos)
+ nStartPos = nEndPos;
+
+ USHORT nOld = rNums[0],
+ nBeg = nOld,
+ nCount = 0;
+ String aNumStr( SvxNumberType( ((SwPageDesc*)rDescs[0])->GetNumType() ).
+ GetNumStr( nBeg ) );
+ if( pCharStyleIdx && lcl_HasMainEntry( pMainEntryNums, nBeg ))
+ {
+ USHORT nTemp = 0;
+ pCharStyleIdx->Insert( nTemp, pCharStyleIdx->Count());
+ }
+
+ // Platzhalter loeschen
+ SwIndex aPos(pNd, nStartPos);
+ SwCharFmt* pPageNoCharFmt = 0;
+ SwpHints* pHints = pNd->GetpSwpHints();
+ if(pHints)
+ for(USHORT nHintIdx = 0; nHintIdx < pHints->GetStartCount(); nHintIdx++)
+ {
+ SwTxtAttr* pAttr = pHints->GetStart(nHintIdx);
+ xub_StrLen nTmpEnd = pAttr->GetEnd() ? *pAttr->GetEnd() : 0;
+ if( nStartPos >= *pAttr->GetStart() &&
+ (nStartPos + 2) <= nTmpEnd &&
+ pAttr->Which() == RES_TXTATR_CHARFMT)
+ {
+ pPageNoCharFmt = pAttr->GetCharFmt().GetCharFmt();
+ break;
+ }
+ }
+ pNd->EraseText(aPos, nEndPos - nStartPos + 2);
+
+ for( i = 1; i < rNums.Count(); ++i)
+ {
+ SvxNumberType aType( ((SwPageDesc*)rDescs[i])->GetNumType() );
+ if( TOX_INDEX == SwTOXBase::GetType() )
+ { // Zusammenfassen f. ff.
+ // Alle folgenden aufaddieren
+ // break up if main entry starts or ends and
+ // insert a char style index
+ BOOL bMainEntryChanges = lcl_HasMainEntry(pMainEntryNums, nOld)
+ != lcl_HasMainEntry(pMainEntryNums, rNums[i]);
+
+ if(nOld == rNums[i]-1 && !bMainEntryChanges &&
+ 0 != (GetOptions() & (nsSwTOIOptions::TOI_FF|nsSwTOIOptions::TOI_DASH)))
+ nCount++;
+ else
+ {
+ // ff. f. alten Wert flushen
+ if(GetOptions() & nsSwTOIOptions::TOI_FF)
+ {
+ if ( nCount >= 1 )
+ aNumStr += rIntl.GetFollowingText( nCount > 1 );
+ }
+ else
+ {
+ if(nCount >= 2 )
+ aNumStr += '-';
+ else if(nCount == 1 )
+ aNumStr.AppendAscii( sPageDeli );
+//#58127# Wenn nCount == 0, dann steht die einzige Seitenzahl schon im aNumStr!
+ if(nCount)
+ aNumStr += aType.GetNumStr( nBeg + nCount );
+ }
+
+ // neuen String anlegen
+ nBeg = rNums[i];
+ aNumStr.AppendAscii( sPageDeli );
+ //the change of the character style must apply after sPageDeli is appended
+ if(pCharStyleIdx && bMainEntryChanges)
+ pCharStyleIdx->Insert(aNumStr.Len(),
+ pCharStyleIdx->Count());
+ aNumStr += aType.GetNumStr( nBeg );
+ nCount = 0;
+ }
+ nOld = rNums[i];
+ }
+ else
+ { // Alle Nummern eintragen
+ aNumStr += aType.GetNumStr( USHORT(rNums[i]) );
+ if(i != (rNums.Count()-1))
+ aNumStr.AppendAscii( sPageDeli );
+ }
+ }
+ // Bei Ende und ff. alten Wert flushen
+ if( TOX_INDEX == SwTOXBase::GetType() )
+ {
+ if(GetOptions() & nsSwTOIOptions::TOI_FF)
+ {
+ if( nCount >= 1 )
+ aNumStr += rIntl.GetFollowingText( nCount > 1 );
+ }
+ else
+ {
+ if(nCount >= 2)
+ aNumStr +='-';
+ else if(nCount == 1)
+ aNumStr.AppendAscii( sPageDeli );
+//#58127# Wenn nCount == 0, dann steht die einzige Seitenzahl schon im aNumStr!
+ if(nCount)
+ aNumStr += SvxNumberType( ((SwPageDesc*)rDescs[i-1])->
+ GetNumType() ).GetNumStr( nBeg+nCount );
+ }
+ }
+ pNd->InsertText( aNumStr, aPos,
+ static_cast<IDocumentContentOperations::InsertFlags>(
+ IDocumentContentOperations::INS_EMPTYEXPAND |
+ IDocumentContentOperations::INS_FORCEHINTEXPAND) );
+ if(pPageNoCharFmt)
+ {
+ SwFmtCharFmt aCharFmt( pPageNoCharFmt );
+ pNd->InsertItem(aCharFmt, nStartPos, nStartPos + aNumStr.Len(), nsSetAttrMode::SETATTR_DONTEXPAND);
+ }
+
+ //now the main entries should get there character style
+ if(pCharStyleIdx && pCharStyleIdx->Count() && GetMainEntryCharStyle().Len())
+ {
+ // eventually the last index must me appended
+ if(pCharStyleIdx->Count()&0x01)
+ pCharStyleIdx->Insert(aNumStr.Len(), pCharStyleIdx->Count());
+
+ //search by name
+ SwDoc* pDoc = pNd->GetDoc();
+ USHORT nPoolId = SwStyleNameMapper::GetPoolIdFromUIName( GetMainEntryCharStyle(), nsSwGetPoolIdFromName::GET_POOLID_CHRFMT );
+ SwCharFmt* pCharFmt = 0;
+ if(USHRT_MAX != nPoolId)
+ pCharFmt = pDoc->GetCharFmtFromPool(nPoolId);
+ else
+ pCharFmt = pDoc->FindCharFmtByName( GetMainEntryCharStyle() );
+ if(!pCharFmt)
+ pCharFmt = pDoc->MakeCharFmt(GetMainEntryCharStyle(), 0);
+
+ //find the page numbers in aNumStr and set the character style
+ xub_StrLen nOffset = pNd->GetTxt().Len() - aNumStr.Len();
+ SwFmtCharFmt aCharFmt(pCharFmt);
+ for(USHORT j = 0; j < pCharStyleIdx->Count(); j += 2)
+ {
+ xub_StrLen nStartIdx = (*pCharStyleIdx)[j] + nOffset;
+ xub_StrLen nEndIdx = (*pCharStyleIdx)[j + 1] + nOffset;
+ pNd->InsertItem(aCharFmt, nStartIdx, nEndIdx, nsSetAttrMode::SETATTR_DONTEXPAND);
+ }
+
+ }
+ delete pCharStyleIdx;
+}
+
+
+/*--------------------------------------------------------------------
+ Beschreibung: Sortiert einfuegen in das SortArr
+ --------------------------------------------------------------------*/
+
+void SwTOXBaseSection::InsertSorted(SwTOXSortTabBase* pNew)
+{
+ Range aRange(0, aSortArr.Count());
+ if( TOX_INDEX == SwTOXBase::GetType() && pNew->pTxtMark )
+ {
+ const SwTOXMark& rMark = pNew->pTxtMark->GetTOXMark();
+ // Schluessel auswerten
+ // Den Bereich ermitteln, in dem einzufuegen ist
+ if( 0 == (GetOptions() & nsSwTOIOptions::TOI_KEY_AS_ENTRY) &&
+ rMark.GetPrimaryKey().Len() )
+ {
+ aRange = GetKeyRange( rMark.GetPrimaryKey(),
+ rMark.GetPrimaryKeyReading(),
+ *pNew, FORM_PRIMARY_KEY, aRange );
+
+ if( rMark.GetSecondaryKey().Len() )
+ aRange = GetKeyRange( rMark.GetSecondaryKey(),
+ rMark.GetSecondaryKeyReading(),
+ *pNew, FORM_SECONDARY_KEY, aRange );
+ }
+ }
+ //search for identical entries and remove the trailing one
+ if(TOX_AUTHORITIES == SwTOXBase::GetType())
+ {
+ for(short i = (short)aRange.Min(); i < (short)aRange.Max(); ++i)
+ {
+ SwTOXSortTabBase* pOld = aSortArr[i];
+ if(*pOld == *pNew)
+ {
+ if(*pOld < *pNew)
+ {
+ delete pNew;
+ return;
+ }
+ else
+ {
+ // remove the old content
+ aSortArr.DeleteAndDestroy( i, 1 );
+ aRange.Max()--;
+ break;
+ }
+ }
+ }
+ }
+
+ // find position and insert
+ //
+ short i;
+
+ for( i = (short)aRange.Min(); i < (short)aRange.Max(); ++i)
+ { // nur auf gleicher Ebene pruefen
+ //
+ SwTOXSortTabBase* pOld = aSortArr[i];
+ if(*pOld == *pNew)
+ {
+ if(TOX_AUTHORITIES != SwTOXBase::GetType())
+ {
+ // Eigener Eintrag fuer Doppelte oder Keywords
+ //
+ if( pOld->GetType() == TOX_SORT_CUSTOM &&
+ pNew->GetOptions() & nsSwTOIOptions::TOI_KEY_AS_ENTRY)
+ continue;
+
+ if(!(pNew->GetOptions() & nsSwTOIOptions::TOI_SAME_ENTRY))
+ { // Eigener Eintrag
+ aSortArr.Insert(pNew, i );
+ return;
+ }
+ // Eintrag schon vorhanden in Referenzliste aufnehmen
+ pOld->aTOXSources.Insert( pNew->aTOXSources[0],
+ pOld->aTOXSources.Count() );
+
+ delete pNew;
+ return;
+ }
+#ifdef DBG_UTIL
+ else
+ DBG_ERROR("Bibliography entries cannot be found here");
+#endif
+ }
+ if(*pNew < *pOld)
+ break;
+ }
+ // SubLevel Skippen
+ while( TOX_INDEX == SwTOXBase::GetType() && i < aRange.Max() &&
+ aSortArr[i]->GetLevel() > pNew->GetLevel() )
+ i++;
+
+ // An Position i wird eingefuegt
+ aSortArr.Insert(pNew, i );
+}
+
+/*--------------------------------------------------------------------
+ Beschreibung: Schluessel-Bereich suchen und evtl einfuegen
+ --------------------------------------------------------------------*/
+
+Range SwTOXBaseSection::GetKeyRange(const String& rStr, const String& rStrReading,
+ const SwTOXSortTabBase& rNew,
+ USHORT nLevel, const Range& rRange )
+{
+ const SwTOXInternational& rIntl = *rNew.pTOXIntl;
+ String sToCompare(rStr);
+ String sToCompareReading(rStrReading);
+
+ if( 0 != (nsSwTOIOptions::TOI_INITIAL_CAPS & GetOptions()) )
+ {
+ String sUpper( rIntl.ToUpper( sToCompare, 0 ));
+ sToCompare.Erase( 0, 1 ).Insert( sUpper, 0 );
+ }
+
+ ASSERT(rRange.Min() >= 0 && rRange.Max() >= 0, "Min Max < 0");
+
+ const USHORT nMin = (USHORT)rRange.Min();
+ const USHORT nMax = (USHORT)rRange.Max();
+
+ USHORT i;
+
+ for( i = nMin; i < nMax; ++i)
+ {
+ SwTOXSortTabBase* pBase = aSortArr[i];
+
+ String sMyString, sMyStringReading;
+ pBase->GetTxt( sMyString, sMyStringReading );
+
+ if( rIntl.IsEqual( sMyString, sMyStringReading, pBase->GetLocale(),
+ sToCompare, sToCompareReading, rNew.GetLocale() ) &&
+ pBase->GetLevel() == nLevel &&
+ pBase->GetType() == TOX_SORT_CUSTOM )
+ break;
+ }
+ if(i == nMax)
+ { // Falls nicht vorhanden erzeugen und einfuegen
+ //
+ SwTOXCustom* pKey = new SwTOXCustom( sToCompare, sToCompareReading, nLevel, rIntl,
+ rNew.GetLocale() );
+ for(i = nMin; i < nMax; ++i)
+ {
+ if(nLevel == aSortArr[i]->GetLevel() && *pKey < *(aSortArr[i]))
+ break;
+ }
+ aSortArr.Insert(pKey, i );
+ }
+ USHORT nStart = i+1;
+ USHORT nEnd = aSortArr.Count();
+
+ // Ende des Bereiches suchen
+ for(i = nStart; i < aSortArr.Count(); ++i)
+ {
+ if(aSortArr[i]->GetLevel() <= nLevel)
+ { nEnd = i;
+ break;
+ }
+ }
+ return Range(nStart, nEnd);
+}
+
+
+BOOL SwTOXBase::IsTOXBaseInReadonly() const
+{
+ const SwTOXBaseSection *pSect = PTR_CAST(SwTOXBaseSection, this);
+ BOOL bRet = FALSE;
+ const SwSectionNode* pSectNode;
+ if(pSect && pSect->GetFmt() &&
+ 0 != (pSectNode = pSect->GetFmt()->GetSectionNode()))
+ {
+ const SwDocShell* pDocSh;
+ bRet = (0 != (pDocSh = pSectNode->GetDoc()->GetDocShell()) &&
+ pDocSh->IsReadOnly()) ||
+ (0 != (pSectNode = pSectNode->StartOfSectionNode()->FindSectionNode())&&
+ pSectNode->GetSection().IsProtectFlag());
+
+ }
+ return bRet;
+}
+/* -----------------17.08.99 13:29-------------------
+
+ --------------------------------------------------*/
+const SfxItemSet* SwTOXBase::GetAttrSet() const
+{
+ const SwTOXBaseSection *pSect = PTR_CAST(SwTOXBaseSection, this);
+ if(pSect && pSect->GetFmt())
+ return &pSect->GetFmt()->GetAttrSet();
+ return 0;
+}
+
+void SwTOXBase::SetAttrSet( const SfxItemSet& rSet )
+{
+ SwTOXBaseSection *pSect = PTR_CAST(SwTOXBaseSection, this);
+ if( pSect && pSect->GetFmt() )
+ pSect->GetFmt()->SetFmtAttr( rSet );
+}
+
+BOOL SwTOXBase::GetInfo( SfxPoolItem& rInfo ) const
+{
+ switch( rInfo.Which() )
+ {
+ case RES_CONTENT_VISIBLE:
+ {
+ SwTOXBaseSection *pSect = PTR_CAST(SwTOXBaseSection, this);
+ if( pSect && pSect->GetFmt() )
+ pSect->GetFmt()->GetInfo( rInfo );
+ }
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* */
+
+