summaryrefslogtreecommitdiff
path: root/sw/source/core/doc/ftnidx.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/doc/ftnidx.cxx')
-rw-r--r--sw/source/core/doc/ftnidx.cxx398
1 files changed, 398 insertions, 0 deletions
diff --git a/sw/source/core/doc/ftnidx.cxx b/sw/source/core/doc/ftnidx.cxx
new file mode 100644
index 000000000000..3def8b968a60
--- /dev/null
+++ b/sw/source/core/doc/ftnidx.cxx
@@ -0,0 +1,398 @@
+/*************************************************************************
+ *
+ * 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 <txtftn.hxx>
+#include <fmtftn.hxx>
+#include <ftninfo.hxx>
+#include <doc.hxx>
+#include <ftnidx.hxx>
+#include <ndtxt.hxx>
+#include <ndindex.hxx>
+#include <section.hxx>
+#include <fmtftntx.hxx>
+#include <rootfrm.hxx>
+
+
+_SV_IMPL_SORTAR_ALG( _SwFtnIdxs, SwTxtFtnPtr )
+BOOL _SwFtnIdxs::Seek_Entry( const SwTxtFtnPtr rSrch, USHORT* pFndPos ) const
+{
+ ULONG nIdx = _SwTxtFtn_GetIndex( rSrch );
+ xub_StrLen nCntIdx = *rSrch->GetStart();
+
+ USHORT nO = Count(), nM, nU = 0;
+ if( nO > 0 )
+ {
+ nO--;
+ while( nU <= nO )
+ {
+ nM = nU + ( nO - nU ) / 2;
+ ULONG nFndIdx = _SwTxtFtn_GetIndex( (*this)[ nM ] );
+ if( nFndIdx == nIdx && *(*this)[ nM ]->GetStart() == nCntIdx )
+ {
+ if( pFndPos )
+ *pFndPos = nM;
+ return TRUE;
+ }
+ else if( nFndIdx < nIdx ||
+ (nFndIdx == nIdx && *(*this)[ nM ]->GetStart() < nCntIdx ))
+ nU = nM + 1;
+ else if( nM == 0 )
+ {
+ if( pFndPos )
+ *pFndPos = nU;
+ return FALSE;
+ }
+ else
+ nO = nM - 1;
+ }
+ }
+ if( pFndPos )
+ *pFndPos = nU;
+ return FALSE;
+}
+
+
+void SwFtnIdxs::UpdateFtn( const SwNodeIndex& rStt )
+{
+ if( !Count() )
+ return;
+
+ // besorge erstmal das Nodes-Array ueber den StartIndex der ersten Fussnote
+ SwDoc* pDoc = rStt.GetNode().GetDoc();
+ if( pDoc->IsInReading() )
+ return ;
+ SwTxtFtn* pTxtFtn;
+
+ const SwEndNoteInfo& rEndInfo = pDoc->GetEndNoteInfo();
+ const SwFtnInfo& rFtnInfo = pDoc->GetFtnInfo();
+
+ //Fuer normale Fussnoten werden Chapter- und Dokumentweise Nummerierung
+ //getrennt behandelt. Fuer Endnoten gibt es nur die Dokumentweise
+ //Nummerierung.
+ if( FTNNUM_CHAPTER == rFtnInfo.eNum )
+ {
+ const SwOutlineNodes& rOutlNds = pDoc->GetNodes().GetOutLineNds();
+ const SwNode* pCapStt = &pDoc->GetNodes().GetEndOfExtras();
+ ULONG nCapEnd = pDoc->GetNodes().GetEndOfContent().GetIndex();
+ if( rOutlNds.Count() )
+ {
+ // suche den Start des Kapitels, in den rStt steht.
+ USHORT n;
+
+ for( n = 0; n < rOutlNds.Count(); ++n )
+ if( rOutlNds[ n ]->GetIndex() > rStt.GetIndex() )
+ break; // gefunden
+ //else if( !rOutlNds[ n ]->GetTxtNode()->GetTxtColl()->GetOutlineLevel() ) //#outline level,zhaojianwei
+ else if ( rOutlNds[ n ]->GetTxtNode()->GetAttrOutlineLevel() == 1 ) //<-end,zhaojianwei
+ pCapStt = rOutlNds[ n ]; // Start eines neuen Kapitels
+ // dann suche jetzt noch das Ende vom Bereich
+ for( ; n < rOutlNds.Count(); ++n )
+ //if( !rOutlNds[ n ]->GetTxtNode()->GetTxtColl()->GetOutlineLevel() )//#outline level,zhaojianwei
+ if ( rOutlNds[ n ]->GetTxtNode()->GetAttrOutlineLevel() == 1 )//<-end,zhaojianwei
+ {
+ nCapEnd = rOutlNds[ n ]->GetIndex(); // Ende des gefundenen Kapitels
+ break;
+ }
+ }
+
+ USHORT nPos, nFtnNo = 1;
+ if( SeekEntry( *pCapStt, &nPos ) && nPos )
+ {
+ // gehe nach vorne bis der Index nicht mehr gleich ist
+ const SwNode* pCmpNd = &rStt.GetNode();
+ while( nPos && pCmpNd == &((*this)[ --nPos ]->GetTxtNode()) )
+ ;
+ ++nPos;
+ }
+
+ if( nPos == Count() ) // nichts gefunden
+ return;
+
+ if( !rOutlNds.Count() )
+ nFtnNo = nPos+1;
+
+ for( ; nPos < Count(); ++nPos )
+ {
+ pTxtFtn = (*this)[ nPos ];
+ if( pTxtFtn->GetTxtNode().GetIndex() >= nCapEnd )
+ break;
+
+ const SwFmtFtn &rFtn = pTxtFtn->GetFtn();
+ if( !rFtn.GetNumStr().Len() && !rFtn.IsEndNote() &&
+ !SwUpdFtnEndNtAtEnd::FindSectNdWithEndAttr( *pTxtFtn ))
+ pTxtFtn->SetNumber( rFtnInfo.nFtnOffset + nFtnNo++,
+ &rFtn.GetNumStr() );
+ }
+ }
+
+ SwUpdFtnEndNtAtEnd aNumArr;
+
+ // BOOL, damit hier auch bei Chapter-Einstellung die Endnoten
+ // durchlaufen.
+ const BOOL bEndNoteOnly = FTNNUM_DOC != rFtnInfo.eNum;
+
+ USHORT nPos, nFtnNo = 1, nEndNo = 1;
+ ULONG nUpdNdIdx = rStt.GetIndex();
+ for( nPos = 0; nPos < Count(); ++nPos )
+ {
+ pTxtFtn = (*this)[ nPos ];
+ if( nUpdNdIdx <= pTxtFtn->GetTxtNode().GetIndex() )
+ break;
+
+ const SwFmtFtn &rFtn = pTxtFtn->GetFtn();
+ if( !rFtn.GetNumStr().Len() )
+ {
+ if( !aNumArr.ChkNumber( *pTxtFtn ) )
+ {
+ if( pTxtFtn->GetFtn().IsEndNote() )
+ nEndNo++;
+ else
+ nFtnNo++;
+ }
+ }
+ }
+
+ // ab nPos bei allen FootNotes die Array-Nummer setzen
+ for( ; nPos < Count(); ++nPos )
+ {
+ pTxtFtn = (*this)[ nPos ];
+ const SwFmtFtn &rFtn = pTxtFtn->GetFtn();
+ if( !rFtn.GetNumStr().Len() )
+ {
+ USHORT nSectNo = aNumArr.ChkNumber( *pTxtFtn );
+ if( !nSectNo && ( rFtn.IsEndNote() || !bEndNoteOnly ))
+ nSectNo = rFtn.IsEndNote()
+ ? rEndInfo.nFtnOffset + nEndNo++
+ : rFtnInfo.nFtnOffset + nFtnNo++;
+
+ if( nSectNo )
+ {
+ if( rFtn.IsEndNote() )
+ pTxtFtn->SetNumber( nSectNo, &rFtn.GetNumStr() );
+ else
+ pTxtFtn->SetNumber( nSectNo, &rFtn.GetNumStr() );
+ }
+ }
+ }
+ // Pageweise wird vom MA erfuellt !!
+}
+
+
+void SwFtnIdxs::UpdateAllFtn()
+{
+ if( !Count() )
+ return;
+
+ // besorge erstmal das Nodes-Array ueber den StartIndex der
+ // ersten Fussnote
+ SwDoc* pDoc = (SwDoc*) (*this)[ 0 ]->GetTxtNode().GetDoc();
+ SwTxtFtn* pTxtFtn;
+ const SwEndNoteInfo& rEndInfo = pDoc->GetEndNoteInfo();
+ const SwFtnInfo& rFtnInfo = pDoc->GetFtnInfo();
+
+ SwUpdFtnEndNtAtEnd aNumArr;
+
+ //Fuer normale Fussnoten werden Chapter- und Dokumentweise Nummerierung
+ //getrennt behandelt. Fuer Endnoten gibt es nur die Dokumentweise
+ //Nummerierung.
+ if( FTNNUM_CHAPTER == rFtnInfo.eNum )
+ {
+ const SwOutlineNodes& rOutlNds = pDoc->GetNodes().GetOutLineNds();
+ USHORT nNo = 1, // Nummer fuer die Fussnoten
+ nFtnIdx = 0; // Index in das FtnIdx-Array
+ for( USHORT n = 0; n < rOutlNds.Count(); ++n )
+ {
+ //if( !rOutlNds[ n ]->GetTxtNode()->GetTxtColl()->GetOutlineLevel() )//#outline level,zhaojianwei
+ if ( rOutlNds[ n ]->GetTxtNode()->GetAttrOutlineLevel() == 1 )//<-end,zhaojianwei
+ {
+ ULONG nCapStt = rOutlNds[ n ]->GetIndex(); // Start eines neuen Kapitels
+ for( ; nFtnIdx < Count(); ++nFtnIdx )
+ {
+ pTxtFtn = (*this)[ nFtnIdx ];
+ if( pTxtFtn->GetTxtNode().GetIndex() >= nCapStt )
+ break;
+
+ // Endnoten nur Dokumentweise
+ const SwFmtFtn &rFtn = pTxtFtn->GetFtn();
+ if( !rFtn.IsEndNote() && !rFtn.GetNumStr().Len() &&
+ !SwUpdFtnEndNtAtEnd::FindSectNdWithEndAttr( *pTxtFtn ))
+ pTxtFtn->SetNumber( rFtnInfo.nFtnOffset + nNo++,
+ &rFtn.GetNumStr() );
+ }
+ if( nFtnIdx >= Count() )
+ break; // ok alles geupdatet
+ nNo = 1;
+ }
+ }
+
+ for( nNo = 1; nFtnIdx < Count(); ++nFtnIdx )
+ {
+ //Endnoten nur Dokumentweise
+ pTxtFtn = (*this)[ nFtnIdx ];
+ const SwFmtFtn &rFtn = pTxtFtn->GetFtn();
+ if( !rFtn.IsEndNote() && !rFtn.GetNumStr().Len() &&
+ !SwUpdFtnEndNtAtEnd::FindSectNdWithEndAttr( *pTxtFtn ))
+ pTxtFtn->SetNumber( rFtnInfo.nFtnOffset + nNo++,
+ &rFtn.GetNumStr() );
+ }
+
+ }
+
+ // BOOL, damit hier auch bei Chapter-Einstellung die Endnoten
+ // durchlaufen.
+ const BOOL bEndNoteOnly = FTNNUM_DOC != rFtnInfo.eNum;
+ USHORT nFtnNo = 0, nEndNo = 0;
+ for( USHORT nPos = 0; nPos < Count(); ++nPos )
+ {
+ pTxtFtn = (*this)[ nPos ];
+ const SwFmtFtn &rFtn = pTxtFtn->GetFtn();
+ if( !rFtn.GetNumStr().Len() )
+ {
+ USHORT nSectNo = aNumArr.ChkNumber( *pTxtFtn );
+ if( !nSectNo && ( rFtn.IsEndNote() || !bEndNoteOnly ))
+ nSectNo = rFtn.IsEndNote()
+ ? rEndInfo.nFtnOffset + (++nEndNo)
+ : rFtnInfo.nFtnOffset + (++nFtnNo);
+
+ if( nSectNo )
+ {
+ if( rFtn.IsEndNote() )
+ pTxtFtn->SetNumber( nSectNo, &rFtn.GetNumStr() );
+ else
+ pTxtFtn->SetNumber( nSectNo, &rFtn.GetNumStr() );
+ }
+ }
+ }
+
+ if( pDoc->GetRootFrm() && FTNNUM_PAGE == rFtnInfo.eNum )
+ pDoc->GetRootFrm()->UpdateFtnNums();
+}
+
+SwTxtFtn* SwFtnIdxs::SeekEntry( const SwNodeIndex& rPos, USHORT* pFndPos ) const
+{
+ ULONG nIdx = rPos.GetIndex();
+
+ USHORT nO = Count(), nM, nU = 0;
+ if( nO > 0 )
+ {
+ nO--;
+ while( nU <= nO )
+ {
+ nM = nU + ( nO - nU ) / 2;
+ ULONG nNdIdx = _SwTxtFtn_GetIndex( (*this)[ nM ] );
+ if( nNdIdx == nIdx )
+ {
+ if( pFndPos )
+ *pFndPos = nM;
+ return (*this)[ nM ];
+ }
+ else if( nNdIdx < nIdx )
+ nU = nM + 1;
+ else if( nM == 0 )
+ {
+ if( pFndPos )
+ *pFndPos = nU;
+ return 0;
+ }
+ else
+ nO = nM - 1;
+ }
+ }
+ if( pFndPos )
+ *pFndPos = nU;
+ return 0;
+}
+
+/* */
+
+const SwSectionNode* SwUpdFtnEndNtAtEnd::FindSectNdWithEndAttr(
+ const SwTxtFtn& rTxtFtn )
+{
+ USHORT nWh = static_cast<USHORT>( rTxtFtn.GetFtn().IsEndNote() ?
+ RES_END_AT_TXTEND : RES_FTN_AT_TXTEND );
+ USHORT nVal;
+ const SwSectionNode* pNd = rTxtFtn.GetTxtNode().FindSectionNode();
+ while( pNd && FTNEND_ATTXTEND_OWNNUMSEQ != ( nVal =
+ ((const SwFmtFtnAtTxtEnd&)pNd->GetSection().GetFmt()->
+ GetFmtAttr( nWh, TRUE )).GetValue() ) &&
+ FTNEND_ATTXTEND_OWNNUMANDFMT != nVal )
+ pNd = pNd->StartOfSectionNode()->FindSectionNode();
+
+ return pNd;
+}
+
+USHORT SwUpdFtnEndNtAtEnd::GetNumber( const SwTxtFtn& rTxtFtn,
+ const SwSectionNode& rNd )
+{
+ USHORT nRet = 0, nWh;
+ SvPtrarr* pArr;
+ SvUShorts* pNum;
+ if( rTxtFtn.GetFtn().IsEndNote() )
+ {
+ pArr = &aEndSects;
+ pNum = &aEndNums;
+ nWh = RES_END_AT_TXTEND;
+ }
+ else
+ {
+ pArr = &aFtnSects;
+ pNum = &aFtnNums;
+ nWh = RES_FTN_AT_TXTEND;
+ }
+ void* pNd = (void*)&rNd;
+
+ for( USHORT n = pArr->Count(); n; )
+ if( pArr->GetObject( --n ) == pNd )
+ {
+ nRet = ++pNum->GetObject( n );
+ break;
+ }
+
+ if( !nRet )
+ {
+ pArr->Insert( pNd, pArr->Count() );
+ nRet = ((SwFmtFtnEndAtTxtEnd&)rNd.GetSection().GetFmt()->
+ GetFmtAttr( nWh )).GetOffset();
+ ++nRet;
+ pNum->Insert( nRet, pNum->Count() );
+ }
+ return nRet;
+}
+
+USHORT SwUpdFtnEndNtAtEnd::ChkNumber( const SwTxtFtn& rTxtFtn )
+{
+ const SwSectionNode* pSectNd = FindSectNdWithEndAttr( rTxtFtn );
+ return pSectNd ? GetNumber( rTxtFtn, *pSectNd ) : 0;
+}
+
+
+
+