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: ftnidx.cxx,v $
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"
37 #include <ftninfo.hxx>
41 #include <ndindex.hxx>
42 #include <section.hxx>
43 #include <fmtftntx.hxx>
44 #include <rootfrm.hxx>
47 _SV_IMPL_SORTAR_ALG( _SwFtnIdxs
, SwTxtFtnPtr
)
48 BOOL
_SwFtnIdxs::Seek_Entry( const SwTxtFtnPtr rSrch
, USHORT
* pFndPos
) const
50 ULONG nIdx
= _SwTxtFtn_GetIndex( rSrch
);
51 xub_StrLen nCntIdx
= *rSrch
->GetStart();
53 USHORT nO
= Count(), nM
, nU
= 0;
59 nM
= nU
+ ( nO
- nU
) / 2;
60 ULONG nFndIdx
= _SwTxtFtn_GetIndex( (*this)[ nM
] );
61 if( nFndIdx
== nIdx
&& *(*this)[ nM
]->GetStart() == nCntIdx
)
67 else if( nFndIdx
< nIdx
||
68 (nFndIdx
== nIdx
&& *(*this)[ nM
]->GetStart() < nCntIdx
))
86 void SwFtnIdxs::UpdateFtn( const SwNodeIndex
& rStt
)
91 // besorge erstmal das Nodes-Array ueber den StartIndex der ersten Fussnote
92 SwDoc
* pDoc
= rStt
.GetNode().GetDoc();
93 if( pDoc
->IsInReading() )
97 const SwEndNoteInfo
& rEndInfo
= pDoc
->GetEndNoteInfo();
98 const SwFtnInfo
& rFtnInfo
= pDoc
->GetFtnInfo();
100 //Fuer normale Fussnoten werden Chapter- und Dokumentweise Nummerierung
101 //getrennt behandelt. Fuer Endnoten gibt es nur die Dokumentweise
103 if( FTNNUM_CHAPTER
== rFtnInfo
.eNum
)
105 const SwOutlineNodes
& rOutlNds
= pDoc
->GetNodes().GetOutLineNds();
106 const SwNode
* pCapStt
= &pDoc
->GetNodes().GetEndOfExtras();
107 ULONG nCapEnd
= pDoc
->GetNodes().GetEndOfContent().GetIndex();
108 if( rOutlNds
.Count() )
110 // suche den Start des Kapitels, in den rStt steht.
113 for( n
= 0; n
< rOutlNds
.Count(); ++n
)
114 if( rOutlNds
[ n
]->GetIndex() > rStt
.GetIndex() )
116 //else if( !rOutlNds[ n ]->GetTxtNode()->GetTxtColl()->GetOutlineLevel() ) //#outline level,zhaojianwei
117 else if ( rOutlNds
[ n
]->GetTxtNode()->GetAttrOutlineLevel() == 1 ) //<-end,zhaojianwei
118 pCapStt
= rOutlNds
[ n
]; // Start eines neuen Kapitels
119 // dann suche jetzt noch das Ende vom Bereich
120 for( ; n
< rOutlNds
.Count(); ++n
)
121 //if( !rOutlNds[ n ]->GetTxtNode()->GetTxtColl()->GetOutlineLevel() )//#outline level,zhaojianwei
122 if ( rOutlNds
[ n
]->GetTxtNode()->GetAttrOutlineLevel() == 1 )//<-end,zhaojianwei
124 nCapEnd
= rOutlNds
[ n
]->GetIndex(); // Ende des gefundenen Kapitels
129 USHORT nPos
, nFtnNo
= 1;
130 if( SeekEntry( *pCapStt
, &nPos
) && nPos
)
132 // gehe nach vorne bis der Index nicht mehr gleich ist
133 const SwNode
* pCmpNd
= &rStt
.GetNode();
134 while( nPos
&& pCmpNd
== &((*this)[ --nPos
]->GetTxtNode()) )
139 if( nPos
== Count() ) // nichts gefunden
142 if( !rOutlNds
.Count() )
145 for( ; nPos
< Count(); ++nPos
)
147 pTxtFtn
= (*this)[ nPos
];
148 if( pTxtFtn
->GetTxtNode().GetIndex() >= nCapEnd
)
151 const SwFmtFtn
&rFtn
= pTxtFtn
->GetFtn();
152 if( !rFtn
.GetNumStr().Len() && !rFtn
.IsEndNote() &&
153 !SwUpdFtnEndNtAtEnd::FindSectNdWithEndAttr( *pTxtFtn
))
154 pTxtFtn
->SetNumber( rFtnInfo
.nFtnOffset
+ nFtnNo
++,
159 SwUpdFtnEndNtAtEnd aNumArr
;
161 // BOOL, damit hier auch bei Chapter-Einstellung die Endnoten
163 const BOOL bEndNoteOnly
= FTNNUM_DOC
!= rFtnInfo
.eNum
;
165 USHORT nPos
, nFtnNo
= 1, nEndNo
= 1;
166 ULONG nUpdNdIdx
= rStt
.GetIndex();
167 for( nPos
= 0; nPos
< Count(); ++nPos
)
169 pTxtFtn
= (*this)[ nPos
];
170 if( nUpdNdIdx
<= pTxtFtn
->GetTxtNode().GetIndex() )
173 const SwFmtFtn
&rFtn
= pTxtFtn
->GetFtn();
174 if( !rFtn
.GetNumStr().Len() )
176 if( !aNumArr
.ChkNumber( *pTxtFtn
) )
178 if( pTxtFtn
->GetFtn().IsEndNote() )
186 // ab nPos bei allen FootNotes die Array-Nummer setzen
187 for( ; nPos
< Count(); ++nPos
)
189 pTxtFtn
= (*this)[ nPos
];
190 const SwFmtFtn
&rFtn
= pTxtFtn
->GetFtn();
191 if( !rFtn
.GetNumStr().Len() )
193 USHORT nSectNo
= aNumArr
.ChkNumber( *pTxtFtn
);
194 if( !nSectNo
&& ( rFtn
.IsEndNote() || !bEndNoteOnly
))
195 nSectNo
= rFtn
.IsEndNote()
196 ? rEndInfo
.nFtnOffset
+ nEndNo
++
197 : rFtnInfo
.nFtnOffset
+ nFtnNo
++;
201 if( rFtn
.IsEndNote() )
202 pTxtFtn
->SetNumber( nSectNo
, &rFtn
.GetNumStr() );
204 pTxtFtn
->SetNumber( nSectNo
, &rFtn
.GetNumStr() );
208 // Pageweise wird vom MA erfuellt !!
212 void SwFtnIdxs::UpdateAllFtn()
217 // besorge erstmal das Nodes-Array ueber den StartIndex der
219 SwDoc
* pDoc
= (SwDoc
*) (*this)[ 0 ]->GetTxtNode().GetDoc();
221 const SwEndNoteInfo
& rEndInfo
= pDoc
->GetEndNoteInfo();
222 const SwFtnInfo
& rFtnInfo
= pDoc
->GetFtnInfo();
224 SwUpdFtnEndNtAtEnd aNumArr
;
226 //Fuer normale Fussnoten werden Chapter- und Dokumentweise Nummerierung
227 //getrennt behandelt. Fuer Endnoten gibt es nur die Dokumentweise
229 if( FTNNUM_CHAPTER
== rFtnInfo
.eNum
)
231 const SwOutlineNodes
& rOutlNds
= pDoc
->GetNodes().GetOutLineNds();
232 USHORT nNo
= 1, // Nummer fuer die Fussnoten
233 nFtnIdx
= 0; // Index in das FtnIdx-Array
234 for( USHORT n
= 0; n
< rOutlNds
.Count(); ++n
)
236 //if( !rOutlNds[ n ]->GetTxtNode()->GetTxtColl()->GetOutlineLevel() )//#outline level,zhaojianwei
237 if ( rOutlNds
[ n
]->GetTxtNode()->GetAttrOutlineLevel() == 1 )//<-end,zhaojianwei
239 ULONG nCapStt
= rOutlNds
[ n
]->GetIndex(); // Start eines neuen Kapitels
240 for( ; nFtnIdx
< Count(); ++nFtnIdx
)
242 pTxtFtn
= (*this)[ nFtnIdx
];
243 if( pTxtFtn
->GetTxtNode().GetIndex() >= nCapStt
)
246 // Endnoten nur Dokumentweise
247 const SwFmtFtn
&rFtn
= pTxtFtn
->GetFtn();
248 if( !rFtn
.IsEndNote() && !rFtn
.GetNumStr().Len() &&
249 !SwUpdFtnEndNtAtEnd::FindSectNdWithEndAttr( *pTxtFtn
))
250 pTxtFtn
->SetNumber( rFtnInfo
.nFtnOffset
+ nNo
++,
253 if( nFtnIdx
>= Count() )
254 break; // ok alles geupdatet
259 for( nNo
= 1; nFtnIdx
< Count(); ++nFtnIdx
)
261 //Endnoten nur Dokumentweise
262 pTxtFtn
= (*this)[ nFtnIdx
];
263 const SwFmtFtn
&rFtn
= pTxtFtn
->GetFtn();
264 if( !rFtn
.IsEndNote() && !rFtn
.GetNumStr().Len() &&
265 !SwUpdFtnEndNtAtEnd::FindSectNdWithEndAttr( *pTxtFtn
))
266 pTxtFtn
->SetNumber( rFtnInfo
.nFtnOffset
+ nNo
++,
272 // BOOL, damit hier auch bei Chapter-Einstellung die Endnoten
274 const BOOL bEndNoteOnly
= FTNNUM_DOC
!= rFtnInfo
.eNum
;
275 USHORT nFtnNo
= 0, nEndNo
= 0;
276 for( USHORT nPos
= 0; nPos
< Count(); ++nPos
)
278 pTxtFtn
= (*this)[ nPos
];
279 const SwFmtFtn
&rFtn
= pTxtFtn
->GetFtn();
280 if( !rFtn
.GetNumStr().Len() )
282 USHORT nSectNo
= aNumArr
.ChkNumber( *pTxtFtn
);
283 if( !nSectNo
&& ( rFtn
.IsEndNote() || !bEndNoteOnly
))
284 nSectNo
= rFtn
.IsEndNote()
285 ? rEndInfo
.nFtnOffset
+ (++nEndNo
)
286 : rFtnInfo
.nFtnOffset
+ (++nFtnNo
);
290 if( rFtn
.IsEndNote() )
291 pTxtFtn
->SetNumber( nSectNo
, &rFtn
.GetNumStr() );
293 pTxtFtn
->SetNumber( nSectNo
, &rFtn
.GetNumStr() );
298 if( pDoc
->GetRootFrm() && FTNNUM_PAGE
== rFtnInfo
.eNum
)
299 pDoc
->GetRootFrm()->UpdateFtnNums();
302 SwTxtFtn
* SwFtnIdxs::SeekEntry( const SwNodeIndex
& rPos
, USHORT
* pFndPos
) const
304 ULONG nIdx
= rPos
.GetIndex();
306 USHORT nO
= Count(), nM
, nU
= 0;
312 nM
= nU
+ ( nO
- nU
) / 2;
313 ULONG nNdIdx
= _SwTxtFtn_GetIndex( (*this)[ nM
] );
318 return (*this)[ nM
];
320 else if( nNdIdx
< nIdx
)
339 const SwSectionNode
* SwUpdFtnEndNtAtEnd::FindSectNdWithEndAttr(
340 const SwTxtFtn
& rTxtFtn
)
342 USHORT nWh
= static_cast<USHORT
>( rTxtFtn
.GetFtn().IsEndNote() ?
343 RES_END_AT_TXTEND
: RES_FTN_AT_TXTEND
);
345 const SwSectionNode
* pNd
= rTxtFtn
.GetTxtNode().FindSectionNode();
346 while( pNd
&& FTNEND_ATTXTEND_OWNNUMSEQ
!= ( nVal
=
347 ((const SwFmtFtnAtTxtEnd
&)pNd
->GetSection().GetFmt()->
348 GetFmtAttr( nWh
, TRUE
)).GetValue() ) &&
349 FTNEND_ATTXTEND_OWNNUMANDFMT
!= nVal
)
350 pNd
= pNd
->StartOfSectionNode()->FindSectionNode();
355 USHORT
SwUpdFtnEndNtAtEnd::GetNumber( const SwTxtFtn
& rTxtFtn
,
356 const SwSectionNode
& rNd
)
358 USHORT nRet
= 0, nWh
;
361 if( rTxtFtn
.GetFtn().IsEndNote() )
365 nWh
= RES_END_AT_TXTEND
;
371 nWh
= RES_FTN_AT_TXTEND
;
373 void* pNd
= (void*)&rNd
;
375 for( USHORT n
= pArr
->Count(); n
; )
376 if( pArr
->GetObject( --n
) == pNd
)
378 nRet
= ++pNum
->GetObject( n
);
384 pArr
->Insert( pNd
, pArr
->Count() );
385 nRet
= ((SwFmtFtnEndAtTxtEnd
&)rNd
.GetSection().GetFmt()->
386 GetFmtAttr( nWh
)).GetOffset();
388 pNum
->Insert( nRet
, pNum
->Count() );
393 USHORT
SwUpdFtnEndNtAtEnd::ChkNumber( const SwTxtFtn
& rTxtFtn
)
395 const SwSectionNode
* pSectNd
= FindSectNdWithEndAttr( rTxtFtn
);
396 return pSectNd
? GetNumber( rTxtFtn
, *pSectNd
) : 0;