Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <txtftn.hxx>
30 : : #include <fmtftn.hxx>
31 : : #include <ftninfo.hxx>
32 : : #include <doc.hxx>
33 : : #include <ftnidx.hxx>
34 : : #include <ndtxt.hxx>
35 : : #include <ndindex.hxx>
36 : : #include <section.hxx>
37 : : #include <fmtftntx.hxx>
38 : : #include <rootfrm.hxx>
39 : :
40 : :
41 : :
42 : 409 : bool CompareSwFtnIdxs::operator()(SwTxtFtn* const& lhs, SwTxtFtn* const& rhs) const
43 : : {
44 : 409 : sal_uLong nIdxLHS = _SwTxtFtn_GetIndex( lhs );
45 : 409 : sal_uLong nIdxRHS = _SwTxtFtn_GetIndex( rhs );
46 [ + + ][ - + ]: 409 : return ( nIdxLHS == nIdxRHS && *lhs->GetStart() < *rhs->GetStart() ) || nIdxLHS < nIdxRHS;
[ + - ]
47 : : }
48 : :
49 : 627 : void SwFtnIdxs::UpdateFtn( const SwNodeIndex& rStt )
50 : : {
51 [ + + ]: 627 : if( empty() )
52 : : return;
53 : :
54 : : // Get the NodesArray using the first foot note's StartIndex
55 : 93 : SwDoc* pDoc = rStt.GetNode().GetDoc();
56 [ + + ]: 93 : if( pDoc->IsInReading() )
57 : : return ;
58 : : SwTxtFtn* pTxtFtn;
59 : :
60 : 84 : const SwEndNoteInfo& rEndInfo = pDoc->GetEndNoteInfo();
61 : 84 : const SwFtnInfo& rFtnInfo = pDoc->GetFtnInfo();
62 : :
63 : : // For normal foot notes we treat per-chapter and per-document numbering
64 : : // seperately. For Endnotes we only have per-document numbering.
65 [ - + ]: 84 : if( FTNNUM_CHAPTER == rFtnInfo.eNum )
66 : : {
67 [ # # ][ # # ]: 0 : const SwOutlineNodes& rOutlNds = pDoc->GetNodes().GetOutLineNds();
68 [ # # ]: 0 : const SwNode* pCapStt = &pDoc->GetNodes().GetEndOfExtras();
69 [ # # ]: 0 : sal_uLong nCapEnd = pDoc->GetNodes().GetEndOfContent().GetIndex();
70 [ # # ]: 0 : if( !rOutlNds.empty() )
71 : : {
72 : : // Find the Chapter's start, which contains rStt
73 : : sal_uInt16 n;
74 : :
75 [ # # ]: 0 : for( n = 0; n < rOutlNds.size(); ++n )
76 [ # # ][ # # ]: 0 : if( rOutlNds[ n ]->GetIndex() > rStt.GetIndex() )
77 : 0 : break; // found it!
78 : : //else if( !rOutlNds[ n ]->GetTxtNode()->GetTxtColl()->GetOutlineLevel() ) //#outline level,zhaojianwei
79 [ # # ][ # # ]: 0 : else if ( rOutlNds[ n ]->GetTxtNode()->GetAttrOutlineLevel() == 1 ) //<-end,zhaojianwei
[ # # ]
80 [ # # ]: 0 : pCapStt = rOutlNds[ n ]; // Beginning of a new Chapter
81 : : // now find the end of the range
82 [ # # ]: 0 : for( ; n < rOutlNds.size(); ++n )
83 : : //if( !rOutlNds[ n ]->GetTxtNode()->GetTxtColl()->GetOutlineLevel() )//#outline level,zhaojianwei
84 [ # # ][ # # ]: 0 : if ( rOutlNds[ n ]->GetTxtNode()->GetAttrOutlineLevel() == 1 )//<-end,zhaojianwei
[ # # ]
85 : : {
86 [ # # ]: 0 : nCapEnd = rOutlNds[ n ]->GetIndex(); // End of the found Chapter
87 : 0 : break;
88 : : }
89 : : }
90 : :
91 : 0 : sal_uInt16 nPos, nFtnNo = 1;
92 [ # # ][ # # ]: 0 : if( SeekEntry( *pCapStt, &nPos ) && nPos )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
93 : : {
94 : : // Step forward until the Index is not the same anymore
95 : 0 : const SwNode* pCmpNd = &rStt.GetNode();
96 [ # # ][ # # ]: 0 : while( nPos && pCmpNd == &((*this)[ --nPos ]->GetTxtNode()) )
[ # # ][ # # ]
[ # # ]
97 : : ;
98 : 0 : ++nPos;
99 : : }
100 : :
101 [ # # ]: 0 : if( nPos == size() ) // nothing found
102 : : return;
103 : :
104 [ # # ]: 0 : if( rOutlNds.empty() )
105 : 0 : nFtnNo = nPos+1;
106 : :
107 [ # # ]: 0 : for( ; nPos < size(); ++nPos )
108 : : {
109 [ # # ]: 0 : pTxtFtn = (*this)[ nPos ];
110 [ # # ]: 0 : if( pTxtFtn->GetTxtNode().GetIndex() >= nCapEnd )
111 : 0 : break;
112 : :
113 : 0 : const SwFmtFtn &rFtn = pTxtFtn->GetFtn();
114 [ # # ][ # # ]: 0 : if( !rFtn.GetNumStr().Len() && !rFtn.IsEndNote() &&
[ # # ][ # # ]
115 [ # # ]: 0 : !SwUpdFtnEndNtAtEnd::FindSectNdWithEndAttr( *pTxtFtn ))
116 : : pTxtFtn->SetNumber( rFtnInfo.nFtnOffset + nFtnNo++,
117 [ # # ]: 0 : &rFtn.GetNumStr() );
118 : : }
119 : : }
120 : :
121 [ + - ]: 84 : SwUpdFtnEndNtAtEnd aNumArr;
122 : :
123 : : // unless we have per-document numbering, only look at endnotes here
124 : 84 : const sal_Bool bEndNoteOnly = FTNNUM_DOC != rFtnInfo.eNum;
125 : :
126 : 84 : sal_uInt16 nPos, nFtnNo = 1, nEndNo = 1;
127 : 84 : sal_uLong nUpdNdIdx = rStt.GetIndex();
128 [ + - ]: 84 : for( nPos = 0; nPos < size(); ++nPos )
129 : : {
130 [ + - ]: 84 : pTxtFtn = (*this)[ nPos ];
131 [ + - ]: 84 : if( nUpdNdIdx <= pTxtFtn->GetTxtNode().GetIndex() )
132 : 84 : break;
133 : :
134 : 0 : const SwFmtFtn &rFtn = pTxtFtn->GetFtn();
135 [ # # ]: 0 : if( !rFtn.GetNumStr().Len() )
136 : : {
137 [ # # ][ # # ]: 0 : if( !aNumArr.ChkNumber( *pTxtFtn ) )
138 : : {
139 [ # # ]: 0 : if( pTxtFtn->GetFtn().IsEndNote() )
140 : 0 : nEndNo++;
141 : : else
142 : 0 : nFtnNo++;
143 : : }
144 : : }
145 : : }
146 : :
147 : : // Set the array number for all footnotes starting from nPos
148 [ + + ]: 191 : for( ; nPos < size(); ++nPos )
149 : : {
150 [ + - ]: 107 : pTxtFtn = (*this)[ nPos ];
151 : 107 : const SwFmtFtn &rFtn = pTxtFtn->GetFtn();
152 [ + + ]: 107 : if( !rFtn.GetNumStr().Len() )
153 : : {
154 [ + - ]: 29 : sal_uInt16 nSectNo = aNumArr.ChkNumber( *pTxtFtn );
155 [ + - ][ + + ]: 29 : if( !nSectNo && ( rFtn.IsEndNote() || !bEndNoteOnly ))
[ + - ][ + - ]
156 : 29 : nSectNo = rFtn.IsEndNote()
157 : : ? rEndInfo.nFtnOffset + nEndNo++
158 [ + + ]: 29 : : rFtnInfo.nFtnOffset + nFtnNo++;
159 : :
160 [ + - ]: 29 : if( nSectNo )
161 : : {
162 [ + - ]: 29 : pTxtFtn->SetNumber( nSectNo, &rFtn.GetNumStr() );
163 : : }
164 : : }
165 : 627 : }
166 : : }
167 : :
168 : :
169 : 49 : void SwFtnIdxs::UpdateAllFtn()
170 : : {
171 [ + + ]: 49 : if( empty() )
172 : 49 : return;
173 : :
174 : : // Get the NodesArray via the StartIndex of the first Footnote
175 [ + - ]: 28 : SwDoc* pDoc = (SwDoc*) (*this)[ 0 ]->GetTxtNode().GetDoc();
176 : : SwTxtFtn* pTxtFtn;
177 : 28 : const SwEndNoteInfo& rEndInfo = pDoc->GetEndNoteInfo();
178 : 28 : const SwFtnInfo& rFtnInfo = pDoc->GetFtnInfo();
179 : :
180 [ + - ]: 28 : SwUpdFtnEndNtAtEnd aNumArr;
181 : :
182 [ + - ]: 28 : SwRootFrm* pTmpRoot = pDoc->GetCurrentLayout();//swmod 080305
183 [ + - ]: 28 : std::set<SwRootFrm*> aAllLayouts = pDoc->GetAllLayouts();
184 : : // For normal Footnotes per-chapter and per-document numbering are treated separately.
185 : : // For Endnotes we only have document-wise numbering.
186 [ + + ]: 28 : if( FTNNUM_CHAPTER == rFtnInfo.eNum )
187 : : {
188 [ + - ][ + - ]: 4 : const SwOutlineNodes& rOutlNds = pDoc->GetNodes().GetOutLineNds();
189 : 4 : sal_uInt16 nNo = 1, // Number for the Footnotes
190 : 4 : nFtnIdx = 0; // Index into theFtnIdx array
191 [ - + ]: 4 : for( sal_uInt16 n = 0; n < rOutlNds.size(); ++n )
192 : : {
193 [ # # ][ # # ]: 0 : if ( rOutlNds[ n ]->GetTxtNode()->GetAttrOutlineLevel() == 1 )//<-end,zhaojianwei
[ # # ]
194 : : {
195 [ # # ]: 0 : sal_uLong nCapStt = rOutlNds[ n ]->GetIndex(); // Start of a new chapter
196 [ # # ]: 0 : for( ; nFtnIdx < size(); ++nFtnIdx )
197 : : {
198 [ # # ]: 0 : pTxtFtn = (*this)[ nFtnIdx ];
199 [ # # ]: 0 : if( pTxtFtn->GetTxtNode().GetIndex() >= nCapStt )
200 : 0 : break;
201 : :
202 : : // Endnotes are per-document only
203 : 0 : const SwFmtFtn &rFtn = pTxtFtn->GetFtn();
204 [ # # ][ # # ]: 0 : if( !rFtn.IsEndNote() && !rFtn.GetNumStr().Len() &&
[ # # ][ # # ]
205 [ # # ]: 0 : !SwUpdFtnEndNtAtEnd::FindSectNdWithEndAttr( *pTxtFtn ))
206 : : pTxtFtn->SetNumber( rFtnInfo.nFtnOffset + nNo++,
207 [ # # ]: 0 : &rFtn.GetNumStr() );
208 : : }
209 [ # # ]: 0 : if( nFtnIdx >= size() )
210 : 0 : break; // ok, everything is updated
211 : 0 : nNo = 1;
212 : : }
213 : : }
214 : :
215 [ + + ]: 8 : for( nNo = 1; nFtnIdx < size(); ++nFtnIdx )
216 : : {
217 : : // Endnotes are per-document
218 [ + - ]: 4 : pTxtFtn = (*this)[ nFtnIdx ];
219 : 4 : const SwFmtFtn &rFtn = pTxtFtn->GetFtn();
220 [ + - ][ + - ]: 8 : if( !rFtn.IsEndNote() && !rFtn.GetNumStr().Len() &&
[ + - ][ + - ]
221 [ + - ]: 4 : !SwUpdFtnEndNtAtEnd::FindSectNdWithEndAttr( *pTxtFtn ))
222 : : pTxtFtn->SetNumber( rFtnInfo.nFtnOffset + nNo++,
223 [ + - ]: 4 : &rFtn.GetNumStr() );
224 : : }
225 : :
226 : : }
227 : :
228 : : // We use sal_Bool here, so that we also iterate through the Endnotes with a chapter setting.
229 : 28 : const sal_Bool bEndNoteOnly = FTNNUM_DOC != rFtnInfo.eNum;
230 : 28 : sal_uInt16 nFtnNo = 0, nEndNo = 0;
231 [ + + ]: 56 : for( sal_uInt16 nPos = 0; nPos < size(); ++nPos )
232 : : {
233 [ + - ]: 28 : pTxtFtn = (*this)[ nPos ];
234 : 28 : const SwFmtFtn &rFtn = pTxtFtn->GetFtn();
235 [ + + ]: 28 : if( !rFtn.GetNumStr().Len() )
236 : : {
237 [ + - ]: 26 : sal_uInt16 nSectNo = aNumArr.ChkNumber( *pTxtFtn );
238 [ + - ][ + + ]: 26 : if( !nSectNo && ( rFtn.IsEndNote() || !bEndNoteOnly ))
[ + + ][ + + ]
239 : 22 : nSectNo = rFtn.IsEndNote()
240 : : ? rEndInfo.nFtnOffset + (++nEndNo)
241 [ + + ]: 22 : : rFtnInfo.nFtnOffset + (++nFtnNo);
242 : :
243 [ + + ]: 26 : if( nSectNo )
244 : : {
245 [ + - ]: 22 : pTxtFtn->SetNumber( nSectNo, &rFtn.GetNumStr() );
246 : : }
247 : : }
248 : : }
249 : :
250 [ + - ][ - + ]: 28 : if( pTmpRoot && FTNNUM_PAGE == rFtnInfo.eNum )
251 [ # # ][ # # ]: 49 : std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::mem_fun(&SwRootFrm::UpdateFtnNums));//swmod 0
252 : : }
253 : :
254 : 194 : SwTxtFtn* SwFtnIdxs::SeekEntry( const SwNodeIndex& rPos, sal_uInt16* pFndPos ) const
255 : : {
256 : 194 : sal_uLong nIdx = rPos.GetIndex();
257 : :
258 : 194 : sal_uInt16 nO = size(), nM, nU = 0;
259 [ + - ]: 194 : if( nO > 0 )
260 : : {
261 : 194 : nO--;
262 [ + + ]: 238 : while( nU <= nO )
263 : : {
264 : 194 : nM = nU + ( nO - nU ) / 2;
265 : 194 : sal_uLong nNdIdx = _SwTxtFtn_GetIndex( (*this)[ nM ] );
266 [ + + ]: 194 : if( nNdIdx == nIdx )
267 : : {
268 [ + - ]: 54 : if( pFndPos )
269 : 54 : *pFndPos = nM;
270 : 54 : return (*this)[ nM ];
271 : : }
272 [ + + ]: 140 : else if( nNdIdx < nIdx )
273 : 44 : nU = nM + 1;
274 [ + - ]: 96 : else if( nM == 0 )
275 : : {
276 [ + - ]: 96 : if( pFndPos )
277 : 96 : *pFndPos = nU;
278 : 96 : return 0;
279 : : }
280 : : else
281 : 0 : nO = nM - 1;
282 : : }
283 : : }
284 [ + - ]: 44 : if( pFndPos )
285 : 44 : *pFndPos = nU;
286 : 194 : return 0;
287 : : }
288 : :
289 : :
290 : 273 : const SwSectionNode* SwUpdFtnEndNtAtEnd::FindSectNdWithEndAttr(
291 : : const SwTxtFtn& rTxtFtn )
292 : : {
293 : 273 : sal_uInt16 nWh = static_cast<sal_uInt16>( rTxtFtn.GetFtn().IsEndNote() ?
294 [ + + ]: 273 : RES_END_AT_TXTEND : RES_FTN_AT_TXTEND );
295 : : sal_uInt16 nVal;
296 : 273 : const SwSectionNode* pNd = rTxtFtn.GetTxtNode().FindSectionNode();
297 [ - + # # ]: 273 : while( pNd && FTNEND_ATTXTEND_OWNNUMSEQ != ( nVal =
[ # # ][ - + ]
298 : 0 : ((const SwFmtFtnAtTxtEnd&)pNd->GetSection().GetFmt()->
299 : 0 : GetFmtAttr( nWh, sal_True )).GetValue() ) &&
300 : : FTNEND_ATTXTEND_OWNNUMANDFMT != nVal )
301 : 0 : pNd = pNd->StartOfSectionNode()->FindSectionNode();
302 : :
303 : 273 : return pNd;
304 : : }
305 : :
306 : 0 : sal_uInt16 SwUpdFtnEndNtAtEnd::GetNumber( const SwTxtFtn& rTxtFtn,
307 : : const SwSectionNode& rNd )
308 : : {
309 : 0 : sal_uInt16 nRet = 0, nWh;
310 : : std::vector<const SwSectionNode*>* pArr;
311 : : std::vector<sal_uInt16> *pNum;
312 [ # # ]: 0 : if( rTxtFtn.GetFtn().IsEndNote() )
313 : : {
314 : 0 : pArr = &aEndSects;
315 : 0 : pNum = &aEndNums;
316 : 0 : nWh = RES_END_AT_TXTEND;
317 : : }
318 : : else
319 : : {
320 : 0 : pArr = &aFtnSects;
321 : 0 : pNum = &aFtnNums;
322 : 0 : nWh = RES_FTN_AT_TXTEND;
323 : : }
324 : :
325 [ # # ]: 0 : for( sal_uInt16 n = pArr->size(); n; )
326 [ # # ]: 0 : if( (*pArr)[ --n ] == &rNd )
327 : : {
328 [ # # ]: 0 : nRet = ++((*pNum)[ n ]);
329 : 0 : break;
330 : : }
331 : :
332 [ # # ]: 0 : if( !nRet )
333 : : {
334 [ # # ]: 0 : pArr->push_back( &rNd );
335 : 0 : nRet = ((SwFmtFtnEndAtTxtEnd&)rNd.GetSection().GetFmt()->
336 [ # # ]: 0 : GetFmtAttr( nWh )).GetOffset();
337 : 0 : ++nRet;
338 [ # # ]: 0 : pNum->push_back( nRet );
339 : : }
340 : 0 : return nRet;
341 : : }
342 : :
343 : 55 : sal_uInt16 SwUpdFtnEndNtAtEnd::ChkNumber( const SwTxtFtn& rTxtFtn )
344 : : {
345 : 55 : const SwSectionNode* pSectNd = FindSectNdWithEndAttr( rTxtFtn );
346 [ - + ]: 55 : return pSectNd ? GetNumber( rTxtFtn, *pSectNd ) : 0;
347 : : }
348 : :
349 : :
350 : :
351 : :
352 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|