LCOV - code coverage report
Current view: top level - libreoffice/sw/source/core/doc - ftnidx.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 42 166 25.3 %
Date: 2012-12-27 Functions: 5 7 71.4 %
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 <ftnidx.hxx>
      25             : #include <ndtxt.hxx>
      26             : #include <ndindex.hxx>
      27             : #include <section.hxx>
      28             : #include <fmtftntx.hxx>
      29             : #include <rootfrm.hxx>
      30             : 
      31             : 
      32             : 
      33          11 : bool CompareSwFtnIdxs::operator()(SwTxtFtn* const& lhs, SwTxtFtn* const& rhs) const
      34             : {
      35          11 :     sal_uLong nIdxLHS = _SwTxtFtn_GetIndex( lhs );
      36          11 :     sal_uLong nIdxRHS = _SwTxtFtn_GetIndex( rhs );
      37          11 :     return ( nIdxLHS == nIdxRHS && *lhs->GetStart() < *rhs->GetStart() ) || nIdxLHS < nIdxRHS;
      38             : }
      39             : 
      40         222 : void SwFtnIdxs::UpdateFtn( const SwNodeIndex& rStt )
      41             : {
      42         222 :     if( empty() )
      43             :         return;
      44             : 
      45             :     // Get the NodesArray using the first foot note's StartIndex
      46          13 :     SwDoc* pDoc = rStt.GetNode().GetDoc();
      47          13 :     if( pDoc->IsInReading() )
      48             :         return ;
      49             :     SwTxtFtn* pTxtFtn;
      50             : 
      51           8 :     const SwEndNoteInfo& rEndInfo = pDoc->GetEndNoteInfo();
      52           8 :     const SwFtnInfo& rFtnInfo = pDoc->GetFtnInfo();
      53             : 
      54             :     // For normal foot notes we treat per-chapter and per-document numbering
      55             :     // seperately. For Endnotes we only have per-document numbering.
      56           8 :     if( FTNNUM_CHAPTER == rFtnInfo.eNum )
      57             :     {
      58           0 :         const SwOutlineNodes& rOutlNds = pDoc->GetNodes().GetOutLineNds();
      59           0 :         const SwNode* pCapStt = &pDoc->GetNodes().GetEndOfExtras();
      60           0 :         sal_uLong nCapEnd = pDoc->GetNodes().GetEndOfContent().GetIndex();
      61           0 :         if( !rOutlNds.empty() )
      62             :         {
      63             :             // Find the Chapter's start, which contains rStt
      64             :             sal_uInt16 n;
      65             : 
      66           0 :             for( n = 0; n < rOutlNds.size(); ++n )
      67           0 :                 if( rOutlNds[ n ]->GetIndex() > rStt.GetIndex() )
      68           0 :                     break;      // found it!
      69             :                 //else if( !rOutlNds[ n ]->GetTxtNode()->GetTxtColl()->GetOutlineLevel() )  //#outline level,zhaojianwei
      70           0 :                 else if ( rOutlNds[ n ]->GetTxtNode()->GetAttrOutlineLevel() == 1 )   //<-end,zhaojianwei
      71           0 :                     pCapStt = rOutlNds[ n ];    // Beginning of a new Chapter
      72             :             // now find the end of the range
      73           0 :             for( ; n < rOutlNds.size(); ++n )
      74             :                 //if( !rOutlNds[ n ]->GetTxtNode()->GetTxtColl()->GetOutlineLevel() )//#outline level,zhaojianwei
      75           0 :                 if ( rOutlNds[ n ]->GetTxtNode()->GetAttrOutlineLevel() == 1 )//<-end,zhaojianwei
      76             :                 {
      77           0 :                     nCapEnd = rOutlNds[ n ]->GetIndex();    // End of the found Chapter
      78           0 :                     break;
      79             :                 }
      80             :         }
      81             : 
      82           0 :         sal_uInt16 nPos, nFtnNo = 1;
      83           0 :         if( SeekEntry( *pCapStt, &nPos ) && nPos )
      84             :         {
      85             :             // Step forward until the Index is not the same anymore
      86           0 :             const SwNode* pCmpNd = &rStt.GetNode();
      87           0 :             while( nPos && pCmpNd == &((*this)[ --nPos ]->GetTxtNode()) )
      88             :                 ;
      89           0 :             ++nPos;
      90             :         }
      91             : 
      92           0 :         if( nPos == size() )       // nothing found
      93             :             return;
      94             : 
      95           0 :         if( rOutlNds.empty() )
      96           0 :             nFtnNo = nPos+1;
      97             : 
      98           0 :         for( ; nPos < size(); ++nPos )
      99             :         {
     100           0 :             pTxtFtn = (*this)[ nPos ];
     101           0 :             if( pTxtFtn->GetTxtNode().GetIndex() >= nCapEnd )
     102           0 :                 break;
     103             : 
     104           0 :             const SwFmtFtn &rFtn = pTxtFtn->GetFtn();
     105           0 :             if( !rFtn.GetNumStr().Len() && !rFtn.IsEndNote() &&
     106           0 :                 !SwUpdFtnEndNtAtEnd::FindSectNdWithEndAttr( *pTxtFtn ))
     107             :                 pTxtFtn->SetNumber( rFtnInfo.nFtnOffset + nFtnNo++,
     108           0 :                                     &rFtn.GetNumStr() );
     109             :         }
     110             :     }
     111             : 
     112           8 :     SwUpdFtnEndNtAtEnd aNumArr;
     113             : 
     114             :     // unless we have per-document numbering, only look at endnotes here
     115           8 :     const bool bEndNoteOnly = FTNNUM_DOC != rFtnInfo.eNum;
     116             : 
     117           8 :     sal_uInt16 nPos, nFtnNo = 1, nEndNo = 1;
     118           8 :     sal_uLong nUpdNdIdx = rStt.GetIndex();
     119           8 :     for( nPos = 0; nPos < size(); ++nPos )
     120             :     {
     121           8 :         pTxtFtn = (*this)[ nPos ];
     122           8 :         if( nUpdNdIdx <= pTxtFtn->GetTxtNode().GetIndex() )
     123           8 :             break;
     124             : 
     125           0 :         const SwFmtFtn &rFtn = pTxtFtn->GetFtn();
     126           0 :         if( !rFtn.GetNumStr().Len() )
     127             :         {
     128           0 :             if( !aNumArr.ChkNumber( *pTxtFtn ) )
     129             :             {
     130           0 :                 if( pTxtFtn->GetFtn().IsEndNote() )
     131           0 :                     nEndNo++;
     132             :                 else
     133           0 :                     nFtnNo++;
     134             :             }
     135             :         }
     136             :     }
     137             : 
     138             :     // Set the array number for all footnotes starting from nPos
     139          17 :     for( ; nPos < size(); ++nPos )
     140             :     {
     141           9 :         pTxtFtn = (*this)[ nPos ];
     142           9 :         const SwFmtFtn &rFtn = pTxtFtn->GetFtn();
     143           9 :         if( !rFtn.GetNumStr().Len() )
     144             :         {
     145           5 :             sal_uInt16 nSectNo = aNumArr.ChkNumber( *pTxtFtn );
     146           5 :             if( !nSectNo && ( rFtn.IsEndNote() || !bEndNoteOnly ))
     147           5 :                 nSectNo = rFtn.IsEndNote()
     148             :                             ? rEndInfo.nFtnOffset + nEndNo++
     149           5 :                             : rFtnInfo.nFtnOffset + nFtnNo++;
     150             : 
     151           5 :             if( nSectNo )
     152             :             {
     153           5 :                 pTxtFtn->SetNumber( nSectNo, &rFtn.GetNumStr() );
     154             :             }
     155             :         }
     156           8 :     }
     157             : }
     158             : 
     159             : 
     160           4 : void SwFtnIdxs::UpdateAllFtn()
     161             : {
     162           4 :     if( empty() )
     163           4 :         return;
     164             : 
     165             :     // Get the NodesArray via the StartIndex of the first Footnote
     166           0 :     SwDoc* pDoc = (SwDoc*) (*this)[ 0 ]->GetTxtNode().GetDoc();
     167             :     SwTxtFtn* pTxtFtn;
     168           0 :     const SwEndNoteInfo& rEndInfo = pDoc->GetEndNoteInfo();
     169           0 :     const SwFtnInfo& rFtnInfo = pDoc->GetFtnInfo();
     170             : 
     171           0 :     SwUpdFtnEndNtAtEnd aNumArr;
     172             : 
     173           0 :     SwRootFrm* pTmpRoot = pDoc->GetCurrentLayout();//swmod 080305
     174           0 :     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           0 :     if( FTNNUM_CHAPTER == rFtnInfo.eNum )
     178             :     {
     179           0 :         const SwOutlineNodes& rOutlNds = pDoc->GetNodes().GetOutLineNds();
     180           0 :         sal_uInt16 nNo = 1,     // Number for the Footnotes
     181           0 :                nFtnIdx = 0;     // Index into theFtnIdx array
     182           0 :         for( sal_uInt16 n = 0; n < rOutlNds.size(); ++n )
     183             :         {
     184           0 :             if ( rOutlNds[ n ]->GetTxtNode()->GetAttrOutlineLevel() == 1 )//<-end,zhaojianwei
     185             :             {
     186           0 :                 sal_uLong nCapStt = rOutlNds[ n ]->GetIndex();  // Start of a new chapter
     187           0 :                 for( ; nFtnIdx < size(); ++nFtnIdx )
     188             :                 {
     189           0 :                     pTxtFtn = (*this)[ nFtnIdx ];
     190           0 :                     if( pTxtFtn->GetTxtNode().GetIndex() >= nCapStt )
     191           0 :                         break;
     192             : 
     193             :                     // Endnotes are per-document only
     194           0 :                     const SwFmtFtn &rFtn = pTxtFtn->GetFtn();
     195           0 :                     if( !rFtn.IsEndNote() && !rFtn.GetNumStr().Len() &&
     196           0 :                         !SwUpdFtnEndNtAtEnd::FindSectNdWithEndAttr( *pTxtFtn ))
     197             :                         pTxtFtn->SetNumber( rFtnInfo.nFtnOffset + nNo++,
     198           0 :                                             &rFtn.GetNumStr() );
     199             :                 }
     200           0 :                 if( nFtnIdx >= size() )
     201           0 :                     break;          // ok, everything is updated
     202           0 :                 nNo = 1;
     203             :             }
     204             :         }
     205             : 
     206           0 :         for( nNo = 1; nFtnIdx < size(); ++nFtnIdx )
     207             :         {
     208             :             // Endnotes are per-document
     209           0 :             pTxtFtn = (*this)[ nFtnIdx ];
     210           0 :             const SwFmtFtn &rFtn = pTxtFtn->GetFtn();
     211           0 :             if( !rFtn.IsEndNote() && !rFtn.GetNumStr().Len() &&
     212           0 :                 !SwUpdFtnEndNtAtEnd::FindSectNdWithEndAttr( *pTxtFtn ))
     213             :                 pTxtFtn->SetNumber( rFtnInfo.nFtnOffset + nNo++,
     214           0 :                                     &rFtn.GetNumStr() );
     215             :         }
     216             : 
     217             :     }
     218             : 
     219             :     // We use bool here, so that we also iterate through the Endnotes with a chapter setting.
     220           0 :     const bool bEndNoteOnly = FTNNUM_DOC != rFtnInfo.eNum;
     221           0 :     sal_uInt16 nFtnNo = 0, nEndNo = 0;
     222           0 :     for( sal_uInt16 nPos = 0; nPos < size(); ++nPos )
     223             :     {
     224           0 :         pTxtFtn = (*this)[ nPos ];
     225           0 :         const SwFmtFtn &rFtn = pTxtFtn->GetFtn();
     226           0 :         if( !rFtn.GetNumStr().Len() )
     227             :         {
     228           0 :             sal_uInt16 nSectNo = aNumArr.ChkNumber( *pTxtFtn );
     229           0 :             if( !nSectNo && ( rFtn.IsEndNote() || !bEndNoteOnly ))
     230           0 :                 nSectNo = rFtn.IsEndNote()
     231             :                                 ? rEndInfo.nFtnOffset + (++nEndNo)
     232           0 :                                 : rFtnInfo.nFtnOffset + (++nFtnNo);
     233             : 
     234           0 :             if( nSectNo )
     235             :             {
     236           0 :                 pTxtFtn->SetNumber( nSectNo, &rFtn.GetNumStr() );
     237             :             }
     238             :         }
     239             :     }
     240             : 
     241           0 :     if( pTmpRoot && FTNNUM_PAGE == rFtnInfo.eNum )
     242           0 :         std::for_each( aAllLayouts.begin(), aAllLayouts.end(),std::mem_fun(&SwRootFrm::UpdateFtnNums));//swmod 0
     243             : }
     244             : 
     245           0 : SwTxtFtn* SwFtnIdxs::SeekEntry( const SwNodeIndex& rPos, sal_uInt16* pFndPos ) const
     246             : {
     247           0 :     sal_uLong nIdx = rPos.GetIndex();
     248             : 
     249           0 :     sal_uInt16 nO = size(), nM, nU = 0;
     250           0 :     if( nO > 0 )
     251             :     {
     252           0 :         nO--;
     253           0 :         while( nU <= nO )
     254             :         {
     255           0 :             nM = nU + ( nO - nU ) / 2;
     256           0 :             sal_uLong nNdIdx = _SwTxtFtn_GetIndex( (*this)[ nM ] );
     257           0 :             if( nNdIdx == nIdx )
     258             :             {
     259           0 :                 if( pFndPos )
     260           0 :                     *pFndPos = nM;
     261           0 :                 return (*this)[ nM ];
     262             :             }
     263           0 :             else if( nNdIdx < nIdx )
     264           0 :                 nU = nM + 1;
     265           0 :             else if( nM == 0 )
     266             :             {
     267           0 :                 if( pFndPos )
     268           0 :                     *pFndPos = nU;
     269           0 :                 return 0;
     270             :             }
     271             :             else
     272           0 :                 nO = nM - 1;
     273             :         }
     274             :     }
     275           0 :     if( pFndPos )
     276           0 :         *pFndPos = nU;
     277           0 :     return 0;
     278             : }
     279             : 
     280             : 
     281          17 : const SwSectionNode* SwUpdFtnEndNtAtEnd::FindSectNdWithEndAttr(
     282             :                 const SwTxtFtn& rTxtFtn )
     283             : {
     284          17 :     sal_uInt16 nWh = static_cast<sal_uInt16>( rTxtFtn.GetFtn().IsEndNote() ?
     285          17 :                         RES_END_AT_TXTEND : RES_FTN_AT_TXTEND );
     286             :     sal_uInt16 nVal;
     287          17 :     const SwSectionNode* pNd = rTxtFtn.GetTxtNode().FindSectionNode();
     288          34 :     while( pNd && FTNEND_ATTXTEND_OWNNUMSEQ != ( nVal =
     289           0 :             ((const SwFmtFtnAtTxtEnd&)pNd->GetSection().GetFmt()->
     290           0 :             GetFmtAttr( nWh, sal_True )).GetValue() ) &&
     291             :             FTNEND_ATTXTEND_OWNNUMANDFMT != nVal )
     292           0 :         pNd = pNd->StartOfSectionNode()->FindSectionNode();
     293             : 
     294          17 :     return pNd;
     295             : }
     296             : 
     297           0 : sal_uInt16 SwUpdFtnEndNtAtEnd::GetNumber( const SwTxtFtn& rTxtFtn,
     298             :                                     const SwSectionNode& rNd )
     299             : {
     300           0 :     sal_uInt16 nRet = 0, nWh;
     301             :     std::vector<const SwSectionNode*>* pArr;
     302             :     std::vector<sal_uInt16> *pNum;
     303           0 :     if( rTxtFtn.GetFtn().IsEndNote() )
     304             :     {
     305           0 :         pArr = &aEndSects;
     306           0 :         pNum = &aEndNums;
     307           0 :         nWh = RES_END_AT_TXTEND;
     308             :     }
     309             :     else
     310             :     {
     311           0 :         pArr = &aFtnSects;
     312           0 :         pNum = &aFtnNums;
     313           0 :         nWh = RES_FTN_AT_TXTEND;
     314             :     }
     315             : 
     316           0 :     for( sal_uInt16 n = pArr->size(); n; )
     317           0 :         if( (*pArr)[ --n ] == &rNd )
     318             :         {
     319           0 :             nRet = ++((*pNum)[ n ]);
     320           0 :             break;
     321             :         }
     322             : 
     323           0 :     if( !nRet )
     324             :     {
     325           0 :         pArr->push_back( &rNd );
     326           0 :         nRet = ((SwFmtFtnEndAtTxtEnd&)rNd.GetSection().GetFmt()->
     327           0 :                                 GetFmtAttr( nWh )).GetOffset();
     328           0 :         ++nRet;
     329           0 :         pNum->push_back( nRet );
     330             :     }
     331           0 :     return nRet;
     332             : }
     333             : 
     334           5 : sal_uInt16 SwUpdFtnEndNtAtEnd::ChkNumber( const SwTxtFtn& rTxtFtn )
     335             : {
     336           5 :     const SwSectionNode* pSectNd = FindSectNdWithEndAttr( rTxtFtn );
     337           5 :     return pSectNd ? GetNumber( rTxtFtn, *pSectNd ) : 0;
     338             : }
     339             : 
     340             : 
     341             : 
     342             : 
     343             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10