LCOV - code coverage report
Current view: top level - sw/source/core/doc - ftnidx.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 143 174 82.2 %
Date: 2015-06-13 12:38:46 Functions: 9 9 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <txtftn.hxx>
      21             : #include <fmtftn.hxx>
      22             : #include <ftninfo.hxx>
      23             : #include <doc.hxx>
      24             : #include <IDocumentLayoutAccess.hxx>
      25             : #include <ftnidx.hxx>
      26             : #include <ndtxt.hxx>
      27             : #include <ndindex.hxx>
      28             : #include <section.hxx>
      29             : #include <fmtftntx.hxx>
      30             : #include <rootfrm.hxx>
      31             : 
      32         749 : bool CompareSwFootnoteIdxs::operator()(SwTextFootnote* const& lhs, SwTextFootnote* const& rhs) const
      33             : {
      34         749 :     sal_uLong nIdxLHS = _SwTextFootnote_GetIndex( lhs );
      35         749 :     sal_uLong nIdxRHS = _SwTextFootnote_GetIndex( rhs );
      36         749 :     return ( nIdxLHS == nIdxRHS && lhs->GetStart() < rhs->GetStart() ) || nIdxLHS < nIdxRHS;
      37             : }
      38             : 
      39        2113 : void SwFootnoteIdxs::UpdateFootnote( const SwNodeIndex& rStt )
      40             : {
      41        2113 :     if( empty() )
      42        3923 :         return;
      43             : 
      44             :     // Get the NodesArray using the first foot note's StartIndex
      45         184 :     SwDoc* pDoc = rStt.GetNode().GetDoc();
      46         184 :     if( pDoc->IsInReading() )
      47          65 :         return ;
      48             :     SwTextFootnote* pTextFootnote;
      49             : 
      50         119 :     const SwEndNoteInfo& rEndInfo = pDoc->GetEndNoteInfo();
      51         119 :     const SwFootnoteInfo& rFootnoteInfo = pDoc->GetFootnoteInfo();
      52             : 
      53             :     // For normal foot notes we treat per-chapter and per-document numbering
      54             :     // separately. For Endnotes we only have per-document numbering.
      55         119 :     if( FTNNUM_CHAPTER == rFootnoteInfo.eNum )
      56             :     {
      57           3 :         const SwOutlineNodes& rOutlNds = pDoc->GetNodes().GetOutLineNds();
      58           3 :         const SwNode* pCapStt = &pDoc->GetNodes().GetEndOfExtras();
      59           3 :         sal_uLong nCapEnd = pDoc->GetNodes().GetEndOfContent().GetIndex();
      60           3 :         if( !rOutlNds.empty() )
      61             :         {
      62             :             // Find the Chapter's start, which contains rStt
      63           0 :             size_t n = 0;
      64             : 
      65           0 :             for( ; n < rOutlNds.size(); ++n )
      66           0 :                 if( rOutlNds[ n ]->GetIndex() > rStt.GetIndex() )
      67           0 :                     break;      // found it!
      68           0 :                 else if ( rOutlNds[ n ]->GetTextNode()->GetAttrOutlineLevel() == 1 )
      69           0 :                     pCapStt = rOutlNds[ n ];    // Beginning of a new Chapter
      70             :             // now find the end of the range
      71           0 :             for( ; n < rOutlNds.size(); ++n )
      72           0 :                 if ( rOutlNds[ n ]->GetTextNode()->GetAttrOutlineLevel() == 1 )
      73             :                 {
      74           0 :                     nCapEnd = rOutlNds[ n ]->GetIndex();    // End of the found Chapter
      75           0 :                     break;
      76             :                 }
      77             :         }
      78             : 
      79           3 :         size_t nPos = 0;
      80           3 :         size_t nFootnoteNo = 1;
      81           3 :         if( SeekEntry( *pCapStt, &nPos ) && nPos )
      82             :         {
      83             :             // Step forward until the Index is not the same anymore
      84           0 :             const SwNode* pCmpNd = &rStt.GetNode();
      85           0 :             while( nPos && pCmpNd == &((*this)[ --nPos ]->GetTextNode()) )
      86             :                 ;
      87           0 :             ++nPos;
      88             :         }
      89             : 
      90           3 :         if( nPos == size() )       // nothing found
      91           0 :             return;
      92             : 
      93           3 :         if( rOutlNds.empty() )
      94           3 :             nFootnoteNo = nPos+1;
      95             : 
      96           6 :         for( ; nPos < size(); ++nPos )
      97             :         {
      98           3 :             pTextFootnote = (*this)[ nPos ];
      99           3 :             if( pTextFootnote->GetTextNode().GetIndex() >= nCapEnd )
     100           0 :                 break;
     101             : 
     102           3 :             const SwFormatFootnote &rFootnote = pTextFootnote->GetFootnote();
     103           6 :             if( rFootnote.GetNumStr().isEmpty() && !rFootnote.IsEndNote() &&
     104           3 :                 !SwUpdFootnoteEndNtAtEnd::FindSectNdWithEndAttr( *pTextFootnote ))
     105             :             {
     106           3 :                 pTextFootnote->SetNumber( rFootnoteInfo.nFootnoteOffset + nFootnoteNo++, rFootnote.GetNumStr() );
     107             :             }
     108             :         }
     109             :     }
     110             : 
     111         119 :     SwUpdFootnoteEndNtAtEnd aNumArr;
     112             : 
     113             :     // unless we have per-document numbering, only look at endnotes here
     114         119 :     const bool bEndNoteOnly = FTNNUM_DOC != rFootnoteInfo.eNum;
     115             : 
     116             :     size_t nPos;
     117         119 :     size_t nFootnoteNo = 1;
     118         119 :     size_t nEndNo = 1;
     119         119 :     sal_uLong nUpdNdIdx = rStt.GetIndex();
     120         137 :     for( nPos = 0; nPos < size(); ++nPos )
     121             :     {
     122         137 :         pTextFootnote = (*this)[ nPos ];
     123         137 :         if( nUpdNdIdx <= pTextFootnote->GetTextNode().GetIndex() )
     124         119 :             break;
     125             : 
     126          18 :         const SwFormatFootnote &rFootnote = pTextFootnote->GetFootnote();
     127          18 :         if( rFootnote.GetNumStr().isEmpty() )
     128             :         {
     129          18 :             if( !aNumArr.ChkNumber( *pTextFootnote ) )
     130             :             {
     131          18 :                 if( pTextFootnote->GetFootnote().IsEndNote() )
     132           9 :                     nEndNo++;
     133             :                 else
     134           9 :                     nFootnoteNo++;
     135             :             }
     136             :         }
     137             :     }
     138             : 
     139             :     // Set the array number for all footnotes starting from nPos
     140         295 :     for( ; nPos < size(); ++nPos )
     141             :     {
     142         176 :         pTextFootnote = (*this)[ nPos ];
     143         176 :         const SwFormatFootnote &rFootnote = pTextFootnote->GetFootnote();
     144         176 :         if( rFootnote.GetNumStr().isEmpty() )
     145             :         {
     146          94 :             sal_uInt16 nSectNo = aNumArr.ChkNumber( *pTextFootnote );
     147          94 :             if( !nSectNo && ( rFootnote.IsEndNote() || !bEndNoteOnly ))
     148          87 :                 nSectNo = rFootnote.IsEndNote()
     149             :                             ? rEndInfo.nFootnoteOffset + nEndNo++
     150          87 :                             : rFootnoteInfo.nFootnoteOffset + nFootnoteNo++;
     151             : 
     152          94 :             if( nSectNo )
     153             :             {
     154          91 :                 pTextFootnote->SetNumber( nSectNo, rFootnote.GetNumStr() );
     155             :             }
     156             :         }
     157         119 :     }
     158             : }
     159             : 
     160          62 : void SwFootnoteIdxs::UpdateAllFootnote()
     161             : {
     162          62 :     if( empty() )
     163         107 :         return;
     164             : 
     165             :     // Get the NodesArray via the StartIndex of the first Footnote
     166          17 :     SwDoc* pDoc = const_cast<SwDoc*>((*this)[ 0 ]->GetTextNode().GetDoc());
     167             :     SwTextFootnote* pTextFootnote;
     168          17 :     const SwEndNoteInfo& rEndInfo = pDoc->GetEndNoteInfo();
     169          17 :     const SwFootnoteInfo& rFootnoteInfo = pDoc->GetFootnoteInfo();
     170             : 
     171          17 :     SwUpdFootnoteEndNtAtEnd aNumArr;
     172             : 
     173          17 :     SwRootFrm* pTmpRoot = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
     174          34 :     std::set<SwRootFrm*> aAllLayouts = pDoc->GetAllLayouts();
     175             :     // For normal Footnotes per-chapter and per-document numbering are treated separately.
     176             :     // For Endnotes we only have document-wise numbering.
     177          17 :     if( FTNNUM_CHAPTER == rFootnoteInfo.eNum )
     178             :     {
     179           5 :         const SwOutlineNodes& rOutlNds = pDoc->GetNodes().GetOutLineNds();
     180           5 :         sal_uInt16 nNo = 1;     // Number for the Footnotes
     181           5 :         size_t nFootnoteIdx = 0;     // Index into theFootnoteIdx array
     182           5 :         for( size_t n = 0; n < rOutlNds.size(); ++n )
     183             :         {
     184           0 :             if ( rOutlNds[ n ]->GetTextNode()->GetAttrOutlineLevel() == 1 )
     185             :             {
     186           0 :                 sal_uLong nCapStt = rOutlNds[ n ]->GetIndex();  // Start of a new chapter
     187           0 :                 for( ; nFootnoteIdx < size(); ++nFootnoteIdx )
     188             :                 {
     189           0 :                     pTextFootnote = (*this)[ nFootnoteIdx ];
     190           0 :                     if( pTextFootnote->GetTextNode().GetIndex() >= nCapStt )
     191           0 :                         break;
     192             : 
     193             :                     // Endnotes are per-document only
     194           0 :                     const SwFormatFootnote &rFootnote = pTextFootnote->GetFootnote();
     195           0 :                     if( !rFootnote.IsEndNote() && rFootnote.GetNumStr().isEmpty() &&
     196           0 :                         !SwUpdFootnoteEndNtAtEnd::FindSectNdWithEndAttr( *pTextFootnote ))
     197             :                     {
     198           0 :                         pTextFootnote->SetNumber( rFootnoteInfo.nFootnoteOffset + nNo++, rFootnote.GetNumStr() );
     199             :                     }
     200             :                 }
     201           0 :                 if( nFootnoteIdx >= size() )
     202           0 :                     break;          // ok, everything is updated
     203           0 :                 nNo = 1;
     204             :             }
     205             :         }
     206             : 
     207          10 :         for( nNo = 1; nFootnoteIdx < size(); ++nFootnoteIdx )
     208             :         {
     209             :             // Endnotes are per-document
     210           5 :             pTextFootnote = (*this)[ nFootnoteIdx ];
     211           5 :             const SwFormatFootnote &rFootnote = pTextFootnote->GetFootnote();
     212          10 :             if( !rFootnote.IsEndNote() && rFootnote.GetNumStr().isEmpty() &&
     213           5 :                 !SwUpdFootnoteEndNtAtEnd::FindSectNdWithEndAttr( *pTextFootnote ))
     214             :             {
     215           5 :                 pTextFootnote->SetNumber( rFootnoteInfo.nFootnoteOffset + nNo++, rFootnote.GetNumStr() );
     216             :             }
     217             :         }
     218             :     }
     219             : 
     220             :     // We use bool here, so that we also iterate through the Endnotes with a chapter setting.
     221          17 :     const bool bEndNoteOnly = FTNNUM_DOC != rFootnoteInfo.eNum;
     222          17 :     sal_uInt16 nFootnoteNo = 0, nEndNo = 0;
     223          34 :     for( size_t nPos = 0; nPos < size(); ++nPos )
     224             :     {
     225          17 :         pTextFootnote = (*this)[ nPos ];
     226          17 :         const SwFormatFootnote &rFootnote = pTextFootnote->GetFootnote();
     227          17 :         if( rFootnote.GetNumStr().isEmpty() )
     228             :         {
     229          16 :             sal_uInt16 nSectNo = aNumArr.ChkNumber( *pTextFootnote );
     230          16 :             if( !nSectNo && ( rFootnote.IsEndNote() || !bEndNoteOnly ))
     231          11 :                 nSectNo = rFootnote.IsEndNote()
     232             :                                 ? rEndInfo.nFootnoteOffset + (++nEndNo)
     233          11 :                                 : rFootnoteInfo.nFootnoteOffset + (++nFootnoteNo);
     234             : 
     235          16 :             if( nSectNo )
     236             :             {
     237          11 :                 pTextFootnote->SetNumber( nSectNo, rFootnote.GetNumStr() );
     238             :             }
     239             :         }
     240             :     }
     241             : 
     242          17 :     if( pTmpRoot && FTNNUM_PAGE == rFootnoteInfo.eNum )
     243          17 :         std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::mem_fun(&SwRootFrm::UpdateFootnoteNums));
     244             : }
     245             : 
     246         144 : SwTextFootnote* SwFootnoteIdxs::SeekEntry( const SwNodeIndex& rPos, size_t* pFndPos ) const
     247             : {
     248         144 :     sal_uLong nIdx = rPos.GetIndex();
     249             : 
     250         144 :     size_t nO = size();
     251         144 :     size_t nU = 0;
     252         144 :     if( nO > 0 )
     253             :     {
     254         144 :         nO--;
     255         344 :         while( nU <= nO )
     256             :         {
     257         184 :             const size_t nM = nU + ( nO - nU ) / 2;
     258         184 :             sal_uLong nNdIdx = _SwTextFootnote_GetIndex( (*this)[ nM ] );
     259         184 :             if( nNdIdx == nIdx )
     260             :             {
     261          78 :                 if( pFndPos )
     262          78 :                     *pFndPos = nM;
     263          78 :                 return (*this)[ nM ];
     264             :             }
     265         106 :             else if( nNdIdx < nIdx )
     266          39 :                 nU = nM + 1;
     267          67 :             else if( nM == 0 )
     268             :             {
     269          50 :                 if( pFndPos )
     270          50 :                     *pFndPos = nU;
     271          50 :                 return 0;
     272             :             }
     273             :             else
     274          17 :                 nO = nM - 1;
     275             :         }
     276             :     }
     277          16 :     if( pFndPos )
     278          16 :         *pFndPos = nU;
     279          16 :     return 0;
     280             : }
     281             : 
     282         391 : const SwSectionNode* SwUpdFootnoteEndNtAtEnd::FindSectNdWithEndAttr(
     283             :                 const SwTextFootnote& rTextFootnote )
     284             : {
     285         391 :     sal_uInt16 nWh = static_cast<sal_uInt16>( rTextFootnote.GetFootnote().IsEndNote() ?
     286         391 :                         RES_END_AT_TXTEND : RES_FTN_AT_TXTEND );
     287             :     sal_uInt16 nVal;
     288         391 :     const SwSectionNode* pNd = rTextFootnote.GetTextNode().FindSectionNode();
     289         965 :     while( pNd && FTNEND_ATTXTEND_OWNNUMSEQ != ( nVal =
     290         101 :             static_cast<const SwFormatFootnoteEndAtTextEnd&>(pNd->GetSection().GetFormat()->
     291         656 :             GetFormatAttr( nWh, true )).GetValue() ) &&
     292             :             FTNEND_ATTXTEND_OWNNUMANDFMT != nVal )
     293          82 :         pNd = pNd->StartOfSectionNode()->FindSectionNode();
     294             : 
     295         391 :     return pNd;
     296             : }
     297             : 
     298           4 : sal_uInt16 SwUpdFootnoteEndNtAtEnd::GetNumber( const SwTextFootnote& rTextFootnote,
     299             :                                     const SwSectionNode& rNd )
     300             : {
     301           4 :     sal_uInt16 nRet = 0, nWh;
     302             :     std::vector<const SwSectionNode*>* pArr;
     303             :     std::vector<sal_uInt16> *pNum;
     304           4 :     if( rTextFootnote.GetFootnote().IsEndNote() )
     305             :     {
     306           2 :         pArr = &aEndSects;
     307           2 :         pNum = &aEndNums;
     308           2 :         nWh = RES_END_AT_TXTEND;
     309             :     }
     310             :     else
     311             :     {
     312           2 :         pArr = &aFootnoteSects;
     313           2 :         pNum = &aFootnoteNums;
     314           2 :         nWh = RES_FTN_AT_TXTEND;
     315             :     }
     316             : 
     317           8 :     for( size_t n = pArr->size(); n; )
     318           0 :         if( (*pArr)[ --n ] == &rNd )
     319             :         {
     320           0 :             nRet = ++((*pNum)[ n ]);
     321           0 :             break;
     322             :         }
     323             : 
     324           4 :     if( !nRet )
     325             :     {
     326           4 :         pArr->push_back( &rNd );
     327           4 :         nRet = static_cast<const SwFormatFootnoteEndAtTextEnd&>(rNd.GetSection().GetFormat()->
     328           8 :                                 GetFormatAttr( nWh )).GetOffset();
     329           4 :         ++nRet;
     330           4 :         pNum->push_back( nRet );
     331             :     }
     332           4 :     return nRet;
     333             : }
     334             : 
     335         128 : sal_uInt16 SwUpdFootnoteEndNtAtEnd::ChkNumber( const SwTextFootnote& rTextFootnote )
     336             : {
     337         128 :     const SwSectionNode* pSectNd = FindSectNdWithEndAttr( rTextFootnote );
     338         128 :     return pSectNd ? GetNumber( rTextFootnote, *pSectNd ) : 0;
     339         177 : }
     340             : 
     341             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11