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 <doc.hxx>
30 : : #include <cntfrm.hxx> // OSL_ENSURE(in ~SwTxtFtn()
31 : : #include <pagefrm.hxx> // RemoveFtn()
32 : : #include <fmtftn.hxx>
33 : : #include <txtftn.hxx>
34 : : #include <ftnidx.hxx>
35 : : #include <ftninfo.hxx>
36 : : #include <swfont.hxx>
37 : : #include <ndtxt.hxx>
38 : : #include <poolfmt.hxx>
39 : : #include <ftnfrm.hxx>
40 : : #include <ndindex.hxx>
41 : : #include <fmtftntx.hxx>
42 : : #include <section.hxx>
43 : : #include <switerator.hxx>
44 : :
45 : : namespace {
46 : : /// Get a sorted list of the used footnote reference numbers.
47 : : /// @param[in] rDoc The active document.
48 : : /// @param[in] pExclude A footnote whose reference number should be excluded from the set.
49 : : /// @param[out] rInvalid A returned list of all items that had an invalid reference number.
50 : : /// @returns The set of used reference numbers.
51 : 596 : static std::set<sal_uInt16> lcl_GetUsedFtnRefNumbers(SwDoc &rDoc,
52 : : SwTxtFtn *pExclude,
53 : : std::vector<SwTxtFtn*> &rInvalid)
54 : : {
55 : 596 : std::set<sal_uInt16> aArr;
56 : 596 : SwFtnIdxs& ftnIdxs = rDoc.GetFtnIdxs();
57 : :
58 : 596 : rInvalid.clear();
59 : :
60 [ + + ]: 765 : for( sal_uInt16 n = 0; n < ftnIdxs.size(); ++n )
61 : : {
62 [ + - ]: 169 : SwTxtFtn* pTxtFtn = ftnIdxs[ n ];
63 [ + + ]: 169 : if ( pTxtFtn != pExclude )
64 : : {
65 [ - + ]: 52 : if ( USHRT_MAX == pTxtFtn->GetSeqRefNo() )
66 : : {
67 [ # # ]: 0 : rInvalid.push_back(pTxtFtn);
68 : : }
69 : : else
70 : : {
71 [ + - ]: 52 : aArr.insert( pTxtFtn->GetSeqRefNo() );
72 : : }
73 : : }
74 : : }
75 : 596 : return aArr;
76 : : }
77 : :
78 : : /// Check whether a requested reference number is available.
79 : : /// @param[in] rUsedNums Set of used reference numbers.
80 : : /// @param[in] requested The requested reference number.
81 : : /// @returns true if the number is available, false if not.
82 : 117 : static bool lcl_IsRefNumAvailable(std::set<sal_uInt16> &rUsedNums,
83 : : sal_uInt16 requested)
84 : : {
85 [ + + ]: 117 : if ( USHRT_MAX == requested )
86 : 63 : return false; // Invalid sequence number.
87 [ - + ]: 54 : if ( rUsedNums.count(requested) )
88 : 0 : return false; // Number already used.
89 : 117 : return true;
90 : : }
91 : :
92 : : /// Get the first few unused sequential reference numbers.
93 : : /// @param[in] rUsedNums The set of used sequential reference numbers.
94 : : /// @param[in] numRequired The number of reference number required.
95 : : /// @returns The lowest unused sequential reference numbers.
96 : 542 : static std::vector<sal_uInt16> lcl_GetUnusedSeqRefNums(std::set<sal_uInt16> &rUsedNums,
97 : : size_t numRequired)
98 : : {
99 [ + - ]: 542 : std::vector<sal_uInt16> unusedNums;
100 : 542 : sal_uInt16 newNum = 0;
101 [ + - ]: 542 : std::set<sal_uInt16>::iterator it;
102 : : //Start by using numbers from gaps in rUsedNums
103 [ + - ][ + - ]: 561 : for( it = rUsedNums.begin(); it != rUsedNums.end(); ++it )
[ + + ]
104 : : {
105 [ + - ][ + + ]: 32 : while ( newNum < *it )
106 : : {
107 [ + - ]: 13 : unusedNums.push_back( newNum++ );
108 [ - + ]: 13 : if ( unusedNums.size() >= numRequired )
109 : : return unusedNums;
110 : : }
111 : 19 : newNum++;
112 : : }
113 : : //Filled in all gaps. Fill the rest of the list with new numbers.
114 [ + + ]: 601 : while ( unusedNums.size() < numRequired )
115 : : {
116 [ + - ]: 59 : unusedNums.push_back( newNum++ );
117 : : }
118 : :
119 : 0 : return unusedNums;
120 : : }
121 : :
122 : : }
123 : :
124 : : /*************************************************************************
125 : : |*
126 : : |* class SwFmtFtn
127 : : |*
128 : : *************************************************************************/
129 : :
130 : :
131 : 402 : SwFmtFtn::SwFmtFtn( bool bEndNote )
132 : : : SfxPoolItem( RES_TXTATR_FTN ),
133 : : pTxtAttr( 0 ),
134 : : nNumber( 0 ),
135 [ + - ]: 402 : m_bEndNote( bEndNote )
136 : : {
137 : 402 : }
138 : :
139 : :
140 : 0 : int SwFmtFtn::operator==( const SfxPoolItem& rAttr ) const
141 : : {
142 : : OSL_ENSURE( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" );
143 : : return nNumber == ((SwFmtFtn&)rAttr).nNumber &&
144 : 0 : aNumber == ((SwFmtFtn&)rAttr).aNumber &&
145 [ # # # # ]: 0 : m_bEndNote == ((SwFmtFtn&)rAttr).m_bEndNote;
[ # # ]
146 : : }
147 : :
148 : :
149 : 260 : SfxPoolItem* SwFmtFtn::Clone( SfxItemPool* ) const
150 : : {
151 [ + - ]: 260 : SwFmtFtn* pNew = new SwFmtFtn;
152 : 260 : pNew->aNumber = aNumber;
153 : 260 : pNew->nNumber = nNumber;
154 : 260 : pNew->m_bEndNote = m_bEndNote;
155 : 260 : return pNew;
156 : : }
157 : :
158 : 0 : void SwFmtFtn::SetEndNote( bool b )
159 : : {
160 [ # # ]: 0 : if ( b != m_bEndNote )
161 : : {
162 [ # # ]: 0 : if ( GetTxtFtn() )
163 : : {
164 : 0 : GetTxtFtn()->DelFrms(0);
165 : : }
166 : 0 : m_bEndNote = b;
167 : : }
168 : 0 : }
169 : :
170 [ + - ]: 399 : SwFmtFtn::~SwFmtFtn()
171 : : {
172 [ - + ]: 729 : }
173 : :
174 : :
175 : 0 : void SwFmtFtn::GetFtnText( XubString& rStr ) const
176 : : {
177 [ # # ]: 0 : if( pTxtAttr->GetStartNode() )
178 : : {
179 [ # # ]: 0 : SwNodeIndex aIdx( *pTxtAttr->GetStartNode(), 1 );
180 : 0 : SwCntntNode* pCNd = aIdx.GetNode().GetTxtNode();
181 [ # # ]: 0 : if( !pCNd )
182 [ # # ]: 0 : pCNd = aIdx.GetNodes().GoNext( &aIdx );
183 : :
184 [ # # ]: 0 : if( pCNd->IsTxtNode() )
185 [ # # ][ # # ]: 0 : rStr = ((SwTxtNode*)pCNd)->GetExpandTxt();
[ # # ][ # # ]
186 : : }
187 : 0 : }
188 : :
189 : : // returnt den anzuzeigenden String der Fuss-/Endnote
190 : 363 : XubString SwFmtFtn::GetViewNumStr( const SwDoc& rDoc, sal_Bool bInclStrings ) const
191 : : {
192 : 363 : XubString sRet( GetNumStr() );
193 [ + + ]: 363 : if( !sRet.Len() )
194 : : {
195 : : // dann ist die Nummer von Interesse, also ueber die Info diese
196 : : // besorgen.
197 : 214 : sal_Bool bMakeNum = sal_True;
198 : : const SwSectionNode* pSectNd = pTxtAttr
199 : 214 : ? SwUpdFtnEndNtAtEnd::FindSectNdWithEndAttr( *pTxtAttr )
200 [ + - ][ + - ]: 214 : : 0;
201 : :
202 [ - + ]: 214 : if( pSectNd )
203 : : {
204 : : const SwFmtFtnEndAtTxtEnd& rFtnEnd = (SwFmtFtnEndAtTxtEnd&)
205 : 0 : pSectNd->GetSection().GetFmt()->GetFmtAttr(
206 : 0 : IsEndNote() ?
207 : : static_cast<sal_uInt16>(RES_END_AT_TXTEND) :
208 [ # # ][ # # ]: 0 : static_cast<sal_uInt16>(RES_FTN_AT_TXTEND) );
209 : :
210 [ # # ]: 0 : if( FTNEND_ATTXTEND_OWNNUMANDFMT == rFtnEnd.GetValue() )
211 : : {
212 : 0 : bMakeNum = sal_False;
213 [ # # ][ # # ]: 0 : sRet = rFtnEnd.GetSwNumType().GetNumStr( GetNumber() );
[ # # ]
214 [ # # ]: 0 : if( bInclStrings )
215 : : {
216 [ # # ][ # # ]: 0 : sRet.Insert( rFtnEnd.GetPrefix(), 0 );
[ # # ]
217 [ # # ]: 0 : sRet += rFtnEnd.GetSuffix();
218 : : }
219 : : }
220 : : }
221 : :
222 [ + - ]: 214 : if( bMakeNum )
223 : : {
224 : : const SwEndNoteInfo* pInfo;
225 [ + + ]: 214 : if( IsEndNote() )
226 : 84 : pInfo = &rDoc.GetEndNoteInfo();
227 : : else
228 : 130 : pInfo = &rDoc.GetFtnInfo();
229 [ + - ][ + - ]: 214 : sRet = pInfo->aFmt.GetNumStr( GetNumber() );
[ + - ]
230 [ + + ]: 214 : if( bInclStrings )
231 : : {
232 [ + - ][ + - ]: 92 : sRet.Insert( pInfo->GetPrefix(), 0 );
[ + - ]
233 [ + - ]: 92 : sRet += pInfo->GetSuffix();
234 : : }
235 : : }
236 : : }
237 : 363 : return sRet;
238 : : }
239 : :
240 : : /*************************************************************************
241 : : * class SwTxt/FmtFnt
242 : : *************************************************************************/
243 : :
244 : 72 : SwTxtFtn::SwTxtFtn( SwFmtFtn& rAttr, xub_StrLen nStartPos )
245 : : : SwTxtAttr( rAttr, nStartPos )
246 : : , m_pStartNode( 0 )
247 : : , m_pTxtNode( 0 )
248 : 72 : , m_nSeqNo( USHRT_MAX )
249 : : {
250 : 72 : rAttr.pTxtAttr = this;
251 : 72 : SetHasDummyChar(true);
252 : 72 : }
253 : :
254 : :
255 : 69 : SwTxtFtn::~SwTxtFtn()
256 : : {
257 [ + - ]: 69 : SetStartNode( 0 );
258 [ - + ]: 138 : }
259 : :
260 : :
261 : :
262 : 164 : void SwTxtFtn::SetStartNode( const SwNodeIndex *pNewNode, sal_Bool bDelNode )
263 : : {
264 [ - + ]: 164 : if( pNewNode )
265 : : {
266 [ # # ]: 0 : if ( !m_pStartNode )
267 : : {
268 [ # # ]: 0 : m_pStartNode = new SwNodeIndex( *pNewNode );
269 : : }
270 : : else
271 : : {
272 : 0 : *m_pStartNode = *pNewNode;
273 : : }
274 : : }
275 [ + + ]: 164 : else if ( m_pStartNode )
276 : : {
277 : : // Zwei Dinge muessen erledigt werden:
278 : : // 1) Die Fussnoten muessen bei ihren Seiten abgemeldet werden
279 : : // 2) Die Fussnoten-Sektion in den Inserts muss geloescht werden.
280 : : SwDoc* pDoc;
281 [ + - ]: 69 : if ( m_pTxtNode )
282 : : {
283 : 69 : pDoc = m_pTxtNode->GetDoc();
284 : : }
285 : : else
286 : : {
287 : : //JP 27.01.97: der sw3-Reader setzt einen StartNode aber das
288 : : // Attribut ist noch nicht im TextNode verankert.
289 : : // Wird es geloescht (z.B. bei Datei einfuegen mit
290 : : // Ftn in einen Rahmen), muss auch der Inhalt
291 : : // geloescht werden
292 : 0 : pDoc = m_pStartNode->GetNodes().GetDoc();
293 : : }
294 : :
295 : : // Wir duerfen die Fussnotennodes nicht loeschen
296 : : // und brauchen die Fussnotenframes nicht loeschen, wenn
297 : : // wir im ~SwDoc() stehen.
298 [ + + ]: 69 : if( !pDoc->IsInDtor() )
299 : : {
300 [ - + ]: 26 : if( bDelNode )
301 : : {
302 : : // 1) Die Section fuer die Fussnote wird beseitigt
303 : : // Es kann sein, dass die Inserts schon geloescht wurden.
304 : 0 : pDoc->DeleteSection( &m_pStartNode->GetNode() );
305 : : }
306 : : else
307 : : // Werden die Nodes nicht geloescht mussen sie bei den Seiten
308 : : // abmeldet (Frms loeschen) werden, denn sonst bleiben sie
309 : : // stehen (Undo loescht sie nicht!)
310 : 26 : DelFrms( 0 );
311 : : }
312 [ + - ]: 69 : DELETEZ( m_pStartNode );
313 : :
314 : : // loesche die Fussnote noch aus dem Array am Dokument
315 [ + + ]: 101 : for( sal_uInt16 n = 0; n < pDoc->GetFtnIdxs().size(); ++n )
316 [ + + ]: 32 : if( this == pDoc->GetFtnIdxs()[n] )
317 : : {
318 [ + - ][ + - ]: 26 : pDoc->GetFtnIdxs().erase( pDoc->GetFtnIdxs().begin() + n );
319 : : // gibt noch weitere Fussnoten
320 [ + - ][ + + ]: 26 : if( !pDoc->IsInDtor() && n < pDoc->GetFtnIdxs().size() )
[ + + ]
321 : : {
322 [ + - ][ + - ]: 12 : SwNodeIndex aTmp( pDoc->GetFtnIdxs()[n]->GetTxtNode() );
323 [ + - ][ + - ]: 12 : pDoc->GetFtnIdxs().UpdateFtn( aTmp );
324 : : }
325 : 26 : break;
326 : : }
327 : : }
328 : 164 : }
329 : :
330 : :
331 : 269 : void SwTxtFtn::SetNumber( const sal_uInt16 nNewNum, const XubString* pStr )
332 : : {
333 : 269 : SwFmtFtn& rFtn = (SwFmtFtn&)GetFtn();
334 [ + + ][ + + ]: 269 : if( pStr && pStr->Len() )
[ + - ]
335 : 26 : rFtn.aNumber = *pStr;
336 : : else
337 : : {
338 : 243 : rFtn.nNumber = nNewNum;
339 : 243 : rFtn.aNumber = aEmptyStr;
340 : : }
341 : :
342 : : OSL_ENSURE( m_pTxtNode, "SwTxtFtn: where is my TxtNode?" );
343 : 269 : SwNodes &rNodes = m_pTxtNode->GetDoc()->GetNodes();
344 : 269 : m_pTxtNode->ModifyNotification( 0, &rFtn );
345 [ + - ]: 269 : if ( m_pStartNode )
346 : : {
347 : : // must iterate over all TxtNodes because of footnotes on other pages
348 : : SwNode* pNd;
349 : 269 : sal_uLong nSttIdx = m_pStartNode->GetIndex() + 1;
350 : 269 : sal_uLong nEndIdx = m_pStartNode->GetNode().EndOfSectionIndex();
351 [ + + ]: 562 : for( ; nSttIdx < nEndIdx; ++nSttIdx )
352 : : {
353 : : // Es koennen ja auch Grafiken in der Fussnote stehen ...
354 [ + + ]: 293 : if( ( pNd = rNodes[ nSttIdx ] )->IsTxtNode() )
355 [ + - ]: 285 : ((SwTxtNode*)pNd)->ModifyNotification( 0, &rFtn );
356 : : }
357 : : }
358 : 269 : }
359 : :
360 : : // Die Fussnoten duplizieren
361 : 0 : void SwTxtFtn::CopyFtn(SwTxtFtn & rDest, SwTxtNode & rDestNode) const
362 : : {
363 [ # # ][ # # ]: 0 : if (m_pStartNode && !rDest.GetStartNode())
[ # # ]
364 : : {
365 : : // dest missing node section? create it here!
366 : : // (happens in SwTxtNode::CopyText if pDest == this)
367 : 0 : rDest.MakeNewTextSection( rDestNode.GetNodes() );
368 : : }
369 [ # # ][ # # ]: 0 : if (m_pStartNode && rDest.GetStartNode())
[ # # ]
370 : : {
371 : : // footnotes not necessarily in same document!
372 : 0 : SwDoc *const pDstDoc = rDestNode.GetDoc();
373 [ # # ]: 0 : SwNodes &rDstNodes = pDstDoc->GetNodes();
374 : :
375 : : // copy only the content of the section
376 : : SwNodeRange aRg( *m_pStartNode, 1,
377 [ # # ][ # # ]: 0 : *m_pStartNode->GetNode().EndOfSectionNode() );
[ # # ]
378 : :
379 : : // insert at the end of rDest, i.e., the nodes are appended.
380 : : // nDestLen contains number of CntntNodes in rDest _before_ copy.
381 [ # # ]: 0 : SwNodeIndex aStart( *(rDest.GetStartNode()) );
382 [ # # ]: 0 : SwNodeIndex aEnd( *aStart.GetNode().EndOfSectionNode() );
383 : 0 : sal_uLong nDestLen = aEnd.GetIndex() - aStart.GetIndex() - 1;
384 : :
385 [ # # ]: 0 : m_pTxtNode->GetDoc()->CopyWithFlyInFly( aRg, 0, aEnd, sal_True );
386 : :
387 : : // in case the destination section was not empty, delete the old nodes
388 : : // before: Src: SxxxE, Dst: SnE
389 : : // now: Src: SxxxE, Dst: SnxxxE
390 : : // after: Src: SxxxE, Dst: SxxxE
391 [ # # ]: 0 : aStart++;
392 [ # # ][ # # ]: 0 : rDstNodes.Delete( aStart, nDestLen );
[ # # ][ # # ]
393 : : }
394 : :
395 : : // also copy user defined number string
396 [ # # ]: 0 : if( GetFtn().aNumber.Len() )
397 : : {
398 : 0 : const_cast<SwFmtFtn &>(rDest.GetFtn()).aNumber = GetFtn().aNumber;
399 : : }
400 : 0 : }
401 : :
402 : :
403 : : // lege eine neue leere TextSection fuer diese Fussnote an
404 : 72 : void SwTxtFtn::MakeNewTextSection( SwNodes& rNodes )
405 : : {
406 [ - + ]: 72 : if ( m_pStartNode )
407 : 72 : return;
408 : :
409 : : // Nun verpassen wir dem TxtNode noch die Fussnotenvorlage.
410 : : SwTxtFmtColl *pFmtColl;
411 : : const SwEndNoteInfo* pInfo;
412 : : sal_uInt16 nPoolId;
413 : :
414 [ + + ]: 72 : if( GetFtn().IsEndNote() )
415 : : {
416 : 8 : pInfo = &rNodes.GetDoc()->GetEndNoteInfo();
417 : 8 : nPoolId = RES_POOLCOLL_ENDNOTE;
418 : : }
419 : : else
420 : : {
421 : 64 : pInfo = &rNodes.GetDoc()->GetFtnInfo();
422 : 64 : nPoolId = RES_POOLCOLL_FOOTNOTE;
423 : : }
424 : :
425 [ + + ]: 72 : if( 0 == (pFmtColl = pInfo->GetFtnTxtColl() ) )
426 : 69 : pFmtColl = rNodes.GetDoc()->GetTxtCollFromPool( nPoolId );
427 : :
428 : 72 : SwStartNode* pSttNd = rNodes.MakeTextSection( SwNodeIndex( rNodes.GetEndOfInserts() ),
429 [ + - ]: 72 : SwFootnoteStartNode, pFmtColl );
430 [ + - ]: 72 : m_pStartNode = new SwNodeIndex( *pSttNd );
431 : : }
432 : :
433 : :
434 : 60 : void SwTxtFtn::DelFrms( const SwFrm* pSib )
435 : : {
436 : : // delete the FtnFrames from the pages
437 : : OSL_ENSURE( m_pTxtNode, "SwTxtFtn: where is my TxtNode?" );
438 [ - + ]: 60 : if ( !m_pTxtNode )
439 : 60 : return;
440 : :
441 [ + + ]: 60 : const SwRootFrm* pRoot = pSib ? pSib->getRootFrm() : 0;
442 : 60 : sal_Bool bFrmFnd = sal_False;
443 : : {
444 [ + - ]: 60 : SwIterator<SwCntntFrm,SwTxtNode> aIter( *m_pTxtNode );
445 [ + - ][ + - ]: 120 : for( SwCntntFrm* pFnd = aIter.First(); pFnd; pFnd = aIter.Next() )
[ + + ]
446 : : {
447 [ + + ][ - + ]: 60 : if( pRoot != pFnd->getRootFrm() && pRoot )
[ - + ]
448 : 0 : continue;
449 [ + - ]: 60 : SwPageFrm* pPage = pFnd->FindPageFrm();
450 [ + + ]: 60 : if( pPage )
451 : : {
452 [ + - ]: 26 : pPage->RemoveFtn( pFnd, this );
453 : 26 : bFrmFnd = sal_True;
454 : : }
455 [ + - ]: 60 : }
456 : : }
457 : : //JP 13.05.97: falls das Layout vorm loeschen der Fussnoten entfernt
458 : : // wird, sollte man das ueber die Fussnote selbst tun
459 [ + + ][ + - ]: 60 : if ( !bFrmFnd && m_pStartNode )
460 : : {
461 [ + - ]: 34 : SwNodeIndex aIdx( *m_pStartNode );
462 [ + - ]: 34 : SwCntntNode* pCNd = m_pTxtNode->GetNodes().GoNext( &aIdx );
463 [ + - ]: 34 : if( pCNd )
464 : : {
465 [ + - ]: 34 : SwIterator<SwCntntFrm,SwCntntNode> aIter( *pCNd );
466 [ + - ][ # # ]: 34 : for( SwCntntFrm* pFnd = aIter.First(); pFnd; pFnd = aIter.Next() )
[ - + ]
467 : : {
468 [ # # ][ # # ]: 0 : if( pRoot != pFnd->getRootFrm() && pRoot )
[ # # ]
469 : 0 : continue;
470 [ # # ]: 0 : SwPageFrm* pPage = pFnd->FindPageFrm();
471 : :
472 : 0 : SwFrm *pFrm = pFnd->GetUpper();
473 [ # # ][ # # ]: 0 : while ( pFrm && !pFrm->IsFtnFrm() )
[ # # ]
474 : 0 : pFrm = pFrm->GetUpper();
475 : :
476 : 0 : SwFtnFrm *pFtn = (SwFtnFrm*)pFrm;
477 [ # # ][ # # ]: 0 : while ( pFtn && pFtn->GetMaster() )
[ # # ]
478 : 0 : pFtn = pFtn->GetMaster();
479 : : OSL_ENSURE( pFtn->GetAttr() == this, "Ftn mismatch error." );
480 : :
481 [ # # ]: 0 : while ( pFtn )
482 : : {
483 : 0 : SwFtnFrm *pFoll = pFtn->GetFollow();
484 [ # # ]: 0 : pFtn->Cut();
485 [ # # ][ # # ]: 0 : delete pFtn;
486 : 0 : pFtn = pFoll;
487 : : }
488 : :
489 : : // #i20556# During hiding of a section, the connection
490 : : // to the layout is already lost. pPage may be 0:
491 [ # # ]: 0 : if ( pPage )
492 [ # # ]: 0 : pPage->UpdateFtnNum();
493 [ + - ]: 34 : }
494 [ + - ]: 34 : }
495 : : }
496 : : }
497 : :
498 : : /// Set the sequence number for the current footnote.
499 : : /// @returns The new sequence number or USHRT_MAX if invalid.
500 : 126 : sal_uInt16 SwTxtFtn::SetSeqRefNo()
501 : : {
502 [ - + ]: 126 : if( !m_pTxtNode )
503 : 0 : return USHRT_MAX;
504 : :
505 : 126 : SwDoc* pDoc = m_pTxtNode->GetDoc();
506 [ + + ]: 126 : if( pDoc->IsInReading() )
507 : 9 : return USHRT_MAX;
508 : :
509 [ + - ]: 117 : std::vector<SwTxtFtn*> badRefNums;
510 [ + - ]: 117 : std::set<sal_uInt16> aUsedNums = ::lcl_GetUsedFtnRefNumbers(*pDoc, this, badRefNums);
511 [ + - ][ + + ]: 117 : if ( ::lcl_IsRefNumAvailable(aUsedNums, m_nSeqNo) )
512 : 54 : return m_nSeqNo;
513 [ + - ]: 63 : std::vector<sal_uInt16> unused = ::lcl_GetUnusedSeqRefNums(aUsedNums, 1);
514 [ + - ]: 126 : return m_nSeqNo = unused[0];
515 : : }
516 : :
517 : : /// Set a unique sequential reference number for every footnote in the document.
518 : : /// @param[in] rDoc The document to be processed.
519 : 479 : void SwTxtFtn::SetUniqueSeqRefNo( SwDoc& rDoc )
520 : : {
521 [ + - ]: 479 : std::vector<SwTxtFtn*> badRefNums;
522 [ + - ]: 479 : std::set<sal_uInt16> aUsedNums = ::lcl_GetUsedFtnRefNumbers(rDoc, NULL, badRefNums);
523 [ + - ]: 479 : std::vector<sal_uInt16> unused = ::lcl_GetUnusedSeqRefNums(aUsedNums, badRefNums.size());
524 : :
525 [ - + ]: 479 : for (size_t i = 0; i < badRefNums.size(); ++i)
526 : : {
527 [ # # ][ # # ]: 0 : badRefNums[i]->m_nSeqNo = unused[i];
528 : 479 : }
529 : 479 : }
530 : :
531 : 0 : void SwTxtFtn::CheckCondColl()
532 : : {
533 : : //FEATURE::CONDCOLL
534 [ # # ]: 0 : if( GetStartNode() )
535 : 0 : ((SwStartNode&)GetStartNode()->GetNode()).CheckSectionCondColl();
536 : : //FEATURE::CONDCOLL
537 : 0 : }
538 : :
539 : :
540 : :
541 : :
542 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|