LCOV - code coverage report
Current view: top level - sw/source/core/crsr - pam.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 424 550 77.1 %
Date: 2015-06-13 12:38:46 Functions: 55 66 83.3 %
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 <tools/gen.hxx>
      21             : #include <hintids.hxx>
      22             : #include <editeng/protitem.hxx>
      23             : #include <cntfrm.hxx>
      24             : #include <pagefrm.hxx>
      25             : #include <doc.hxx>
      26             : #include <IDocumentLayoutAccess.hxx>
      27             : #include <docary.hxx>
      28             : #include <pam.hxx>
      29             : #include <pamtyp.hxx>
      30             : #include <txtfrm.hxx>
      31             : #include <fmtcntnt.hxx>
      32             : #include <frmatr.hxx>
      33             : #include <swtable.hxx>
      34             : #include <crsskip.hxx>
      35             : #include <flyfrm.hxx>
      36             : #include <fmteiro.hxx>
      37             : #include <section.hxx>
      38             : #include <sectfrm.hxx>
      39             : #include <ndtxt.hxx>
      40             : 
      41             : #include <IMark.hxx>
      42             : #include <DocumentSettingManager.hxx>
      43             : #include <hints.hxx>
      44             : #include <xmloff/odffields.hxx>
      45             : 
      46             : // for the dump "MSC-" compiler
      47      183717 : inline sal_Int32 GetSttOrEnd( bool bCondition, const SwContentNode& rNd )
      48             : {
      49      183717 :     return bCondition ? 0 : rNd.Len();
      50             : }
      51             : 
      52       29638 : SwPosition::SwPosition( const SwNodeIndex & rNodeIndex, const SwIndex & rContent )
      53       29638 :     : nNode( rNodeIndex ), nContent( rContent )
      54             : {
      55       29638 : }
      56             : 
      57     1152882 : SwPosition::SwPosition( const SwNodeIndex & rNodeIndex )
      58     1152882 :     : nNode( rNodeIndex ), nContent( nNode.GetNode().GetContentNode() )
      59             : {
      60     1152882 : }
      61             : 
      62    35073734 : SwPosition::SwPosition( const SwNode& rNode )
      63    35073734 :     : nNode( rNode ), nContent( nNode.GetNode().GetContentNode() )
      64             : {
      65    35073734 : }
      66             : 
      67       48903 : SwPosition::SwPosition( SwContentNode & rNode, const sal_Int32 nOffset )
      68       48903 :     : nNode( rNode ), nContent( &rNode, nOffset )
      69             : {
      70       48903 : }
      71             : 
      72    24752536 : SwPosition::SwPosition( const SwPosition & rPos )
      73    24752536 :     : nNode( rPos.nNode ), nContent( rPos.nContent )
      74             : {
      75    24752536 : }
      76             : 
      77      599613 : SwPosition &SwPosition::operator=(const SwPosition &rPos)
      78             : {
      79      599613 :     nNode = rPos.nNode;
      80      599613 :     nContent = rPos.nContent;
      81      599613 :     return *this;
      82             : }
      83             : 
      84     2107598 : bool SwPosition::operator<(const SwPosition &rPos) const
      85             : {
      86     2107598 :     if( nNode < rPos.nNode )
      87      405886 :         return true;
      88     1701712 :     if( nNode == rPos.nNode )
      89             :     {
      90             :         // note that positions with text node but no SwIndex registered are
      91             :         // created for text frames anchored at para (see SwXFrame::getAnchor())
      92     1514710 :         SwIndexReg const*const pThisReg(nContent.GetIdxReg());
      93     1514710 :         SwIndexReg const*const pOtherReg(rPos.nContent.GetIdxReg());
      94     1514710 :         if (pThisReg && pOtherReg)
      95             :         {
      96     1511984 :             return (nContent < rPos.nContent);
      97             :         }
      98             :         else // by convention position with no index is smaller
      99             :         {
     100        2726 :             return pOtherReg != nullptr;
     101             :         }
     102             :     }
     103      187002 :     return false;
     104             : }
     105             : 
     106    11340458 : bool SwPosition::operator>(const SwPosition &rPos) const
     107             : {
     108    11340458 :     if(nNode > rPos.nNode )
     109    10571772 :         return true;
     110      768686 :     if( nNode == rPos.nNode )
     111             :     {
     112             :         // note that positions with text node but no SwIndex registered are
     113             :         // created for text frames anchored at para (see SwXFrame::getAnchor())
     114      659960 :         SwIndexReg const*const pThisReg(nContent.GetIdxReg());
     115      659960 :         SwIndexReg const*const pOtherReg(rPos.nContent.GetIdxReg());
     116      659960 :         if (pThisReg && pOtherReg)
     117             :         {
     118      657994 :             return (nContent > rPos.nContent);
     119             :         }
     120             :         else // by convention position with no index is smaller
     121             :         {
     122        1966 :             return pThisReg != nullptr;
     123             :         }
     124             :     }
     125      108726 :     return false;
     126             : }
     127             : 
     128    39730504 : bool SwPosition::operator<=(const SwPosition &rPos) const
     129             : {
     130    39730504 :     if(nNode < rPos.nNode )
     131    11478355 :         return true;
     132    28252149 :     if( nNode == rPos.nNode )
     133             :     {
     134             :         // note that positions with text node but no SwIndex registered are
     135             :         // created for text frames anchored at para (see SwXFrame::getAnchor())
     136     1693417 :         SwIndexReg const*const pThisReg(nContent.GetIdxReg());
     137     1693417 :         SwIndexReg const*const pOtherReg(rPos.nContent.GetIdxReg());
     138     1693417 :         if (pThisReg && pOtherReg)
     139             :         {
     140     1691524 :             return (nContent <= rPos.nContent);
     141             :         }
     142             :         else // by convention position with no index is smaller
     143             :         {
     144        1893 :             return pThisReg == nullptr;
     145             :         }
     146             :     }
     147    26558732 :     return false;
     148             : }
     149             : 
     150      644617 : bool SwPosition::operator>=(const SwPosition &rPos) const
     151             : {
     152      644617 :     if(nNode > rPos.nNode )
     153       11522 :         return true;
     154      633095 :     if( nNode == rPos.nNode )
     155             :     {
     156             :         // note that positions with text node but no SwIndex registered are
     157             :         // created for text frames anchored at para (see SwXFrame::getAnchor())
     158      623744 :         SwIndexReg const*const pThisReg(nContent.GetIdxReg());
     159      623744 :         SwIndexReg const*const pOtherReg(rPos.nContent.GetIdxReg());
     160      623744 :         if (pThisReg && pOtherReg)
     161             :         {
     162      622726 :             return (nContent >= rPos.nContent);
     163             :         }
     164             :         else // by convention position with no index is smaller
     165             :         {
     166        1018 :             return pOtherReg == nullptr;
     167             :         }
     168             :     }
     169        9351 :     return false;
     170             : }
     171             : 
     172      216790 : bool SwPosition::operator==(const SwPosition &rPos) const
     173             : {
     174      216790 :     return (nNode == rPos.nNode)
     175             :         // GetIndexReg may be null for FLY_AT_PARA frame anchor position
     176      124403 :         && (nContent.GetIdxReg() == rPos.nContent.GetIdxReg())
     177      339433 :         && (nContent == rPos.nContent);
     178             : }
     179             : 
     180      377645 : bool SwPosition::operator!=(const SwPosition &rPos) const
     181             : {
     182      377645 :     return (nNode != rPos.nNode)
     183             :         // GetIndexReg may be null for FLY_AT_PARA frame anchor position
     184      354879 :         || (nContent.GetIdxReg() != rPos.nContent.GetIdxReg())
     185      732524 :         || (nContent != rPos.nContent);
     186             : }
     187             : 
     188        1542 : SwDoc * SwPosition::GetDoc() const
     189             : {
     190        1542 :     return nNode.GetNode().GetDoc();
     191             : }
     192             : 
     193          52 : void SwPosition::dumpAsXml(xmlTextWriterPtr pWriter) const
     194             : {
     195          52 :     xmlTextWriterStartElement(pWriter, BAD_CAST("swPosition"));
     196          52 :     xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nNode"), BAD_CAST(OString::number(nNode.GetIndex()).getStr()));
     197          52 :     xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nContent"), BAD_CAST(OString::number(nContent.GetIndex()).getStr()));
     198          52 :     xmlTextWriterEndElement(pWriter);
     199          52 : }
     200             : 
     201           0 : std::ostream &operator <<(std::ostream& s, const SwPosition& position)
     202             : {
     203           0 :     return s << "SwPosition (node " << position.nNode.GetIndex() << ", offset " << position.nContent.GetIndex() << ")";
     204             : }
     205             : 
     206             : enum CHKSECTION { Chk_Both, Chk_One, Chk_None };
     207             : 
     208       69926 : static CHKSECTION lcl_TstIdx( sal_uLong nSttIdx, sal_uLong nEndIdx, const SwNode& rEndNd )
     209             : {
     210       69926 :     sal_uLong nStt = rEndNd.StartOfSectionIndex(), nEnd = rEndNd.GetIndex();
     211       69926 :     CHKSECTION eSec = nStt < nSttIdx && nEnd >= nSttIdx ? Chk_One : Chk_None;
     212       69926 :     if( nStt < nEndIdx && nEnd >= nEndIdx )
     213       63409 :         return( eSec == Chk_One ? Chk_Both : Chk_One );
     214        6517 :     return eSec;
     215             : }
     216             : 
     217        6331 : static bool lcl_ChkOneRange( CHKSECTION eSec, bool bChkSections,
     218             :                     const SwNode& rBaseEnd, sal_uLong nStt, sal_uLong nEnd )
     219             : {
     220        6331 :     if( eSec != Chk_Both )
     221          49 :         return false;
     222             : 
     223        6282 :     if( !bChkSections )
     224           0 :         return true;
     225             : 
     226             :     // search the surrounding section
     227        6282 :     const SwNodes& rNds = rBaseEnd.GetNodes();
     228        6282 :     const SwNode *pTmp, *pNd = rNds[ nStt ];
     229        6282 :     if( !pNd->IsStartNode() )
     230        6127 :         pNd = pNd->StartOfSectionNode();
     231             : 
     232        6282 :     if( pNd == rNds[ nEnd ]->StartOfSectionNode() )
     233        4370 :         return true; // same StartNode, same section
     234             : 
     235             :     // already on a base node => error
     236        1912 :     if( !pNd->StartOfSectionIndex() )
     237           0 :         return false;
     238             : 
     239        4748 :     while( ( pTmp = pNd->StartOfSectionNode())->EndOfSectionNode() !=
     240             :             &rBaseEnd )
     241         924 :         pNd = pTmp;
     242             : 
     243        1912 :     sal_uLong nSttIdx = pNd->GetIndex(), nEndIdx = pNd->EndOfSectionIndex();
     244        1912 :     return nSttIdx <= nStt && nStt <= nEndIdx &&
     245        3650 :            nSttIdx <= nEnd && nEnd <= nEndIdx;
     246             : }
     247             : 
     248       63436 : bool CheckNodesRange( const SwNodeIndex& rStt,
     249             :                       const SwNodeIndex& rEnd, bool bChkSection )
     250             : {
     251       63436 :     const SwNodes& rNds = rStt.GetNodes();
     252       63436 :     sal_uLong nStt = rStt.GetIndex(), nEnd = rEnd.GetIndex();
     253       63436 :     CHKSECTION eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfContent() );
     254       63436 :     if( Chk_None != eSec )
     255       57105 :         return eSec == Chk_Both;
     256             : 
     257        6331 :     eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfAutotext() );
     258        6331 :     if( Chk_None != eSec )
     259             :         return lcl_ChkOneRange( eSec, bChkSection,
     260        6253 :                             rNds.GetEndOfAutotext(), nStt, nEnd );
     261             : 
     262          78 :     eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfPostIts() );
     263          78 :     if( Chk_None != eSec )
     264             :         return lcl_ChkOneRange( eSec, bChkSection,
     265           0 :                             rNds.GetEndOfPostIts(), nStt, nEnd );
     266             : 
     267          78 :     eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfInserts() );
     268          78 :     if( Chk_None != eSec )
     269             :         return lcl_ChkOneRange( eSec, bChkSection,
     270          75 :                             rNds.GetEndOfInserts(), nStt, nEnd );
     271             : 
     272           3 :     eSec = lcl_TstIdx( nStt, nEnd, rNds.GetEndOfRedlines() );
     273           3 :     if( Chk_None != eSec )
     274             :         return lcl_ChkOneRange( eSec, bChkSection,
     275           3 :                             rNds.GetEndOfRedlines(), nStt, nEnd );
     276             : 
     277           0 :     return false; // somewhere in between => error
     278             : }
     279             : 
     280       51895 : bool GoNext(SwNode* pNd, SwIndex * pIdx, sal_uInt16 nMode )
     281             : {
     282       51895 :     if( pNd->IsContentNode() )
     283       51867 :         return static_cast<SwContentNode*>(pNd)->GoNext( pIdx, nMode );
     284          28 :     return false;
     285             : }
     286             : 
     287       68132 : bool GoPrevious( SwNode* pNd, SwIndex * pIdx, sal_uInt16 nMode )
     288             : {
     289       68132 :     if( pNd->IsContentNode() )
     290       68029 :         return static_cast<SwContentNode*>(pNd)->GoPrevious( pIdx, nMode );
     291         103 :     return false;
     292             : }
     293             : 
     294       65195 : SwContentNode* GoNextNds( SwNodeIndex* pIdx, bool bChk )
     295             : {
     296       65195 :     SwNodeIndex aIdx( *pIdx );
     297       65195 :     SwContentNode* pNd = aIdx.GetNodes().GoNext( &aIdx );
     298       65195 :     if( pNd )
     299             :     {
     300       73384 :         if( bChk && 1 != aIdx.GetIndex() - pIdx->GetIndex() &&
     301       12925 :             !CheckNodesRange( *pIdx, aIdx, true ) )
     302        5489 :                 pNd = 0;
     303             :         else
     304       54970 :             *pIdx = aIdx;
     305             :     }
     306       65195 :     return pNd;
     307             : }
     308             : 
     309      193383 : SwContentNode* GoPreviousNds( SwNodeIndex * pIdx, bool bChk )
     310             : {
     311      193383 :     SwNodeIndex aIdx( *pIdx );
     312      193383 :     SwContentNode* pNd = SwNodes::GoPrevious( &aIdx );
     313      193383 :     if( pNd )
     314             :     {
     315      188648 :         if( bChk && 1 != pIdx->GetIndex() - aIdx.GetIndex() &&
     316        1991 :             !CheckNodesRange( *pIdx, aIdx, true ) )
     317         190 :                 pNd = 0;
     318             :         else
     319      186467 :             *pIdx = aIdx;
     320             :     }
     321      193383 :     return pNd;
     322             : }
     323             : 
     324      596052 : SwPaM::SwPaM( const SwPosition& rPos, SwPaM* pRing )
     325             :     : Ring( pRing )
     326             :     , m_Bound1( rPos )
     327      596052 :     , m_Bound2( rPos.nNode.GetNode().GetNodes() ) // default initialize
     328             :     , m_pPoint( &m_Bound1 )
     329             :     , m_pMark( m_pPoint )
     330     1192104 :     , m_bIsInFrontOfLabel( false )
     331             : {
     332      596052 : }
     333             : 
     334    11608628 : SwPaM::SwPaM( const SwPosition& rMark, const SwPosition& rPoint, SwPaM* pRing )
     335             :     : Ring( pRing )
     336             :     , m_Bound1( rMark )
     337             :     , m_Bound2( rPoint )
     338             :     , m_pPoint( &m_Bound2 )
     339             :     , m_pMark( &m_Bound1 )
     340    11608628 :     , m_bIsInFrontOfLabel( false )
     341             : {
     342    11608628 : }
     343             : 
     344        1487 : SwPaM::SwPaM( const SwNodeIndex& rMark, const SwNodeIndex& rPoint,
     345             :               long nMarkOffset, long nPointOffset, SwPaM* pRing )
     346             :     : Ring( pRing )
     347             :     , m_Bound1( rMark )
     348             :     , m_Bound2( rPoint )
     349             :     , m_pPoint( &m_Bound2 )
     350             :     , m_pMark( &m_Bound1 )
     351        1487 :     , m_bIsInFrontOfLabel( false )
     352             : {
     353        1487 :     if ( nMarkOffset )
     354             :     {
     355           1 :         m_pMark->nNode += nMarkOffset;
     356             :     }
     357        1487 :     if ( nPointOffset )
     358             :     {
     359           1 :         m_pPoint->nNode += nPointOffset;
     360             :     }
     361        1487 :     m_Bound1.nContent.Assign( m_Bound1.nNode.GetNode().GetContentNode(), 0 );
     362        1487 :     m_Bound2.nContent.Assign( m_Bound2.nNode.GetNode().GetContentNode(), 0 );
     363        1487 : }
     364             : 
     365      117866 : SwPaM::SwPaM( const SwNode& rMark, const SwNode& rPoint,
     366             :               long nMarkOffset, long nPointOffset, SwPaM* pRing )
     367             :     : Ring( pRing )
     368             :     , m_Bound1( rMark )
     369             :     , m_Bound2( rPoint )
     370             :     , m_pPoint( &m_Bound2 )
     371             :     , m_pMark( &m_Bound1 )
     372      117866 :     , m_bIsInFrontOfLabel( false )
     373             : {
     374      117866 :     if ( nMarkOffset )
     375             :     {
     376          64 :         m_pMark->nNode += nMarkOffset;
     377             :     }
     378      117866 :     if ( nPointOffset )
     379             :     {
     380          20 :         m_pPoint->nNode += nPointOffset;
     381             :     }
     382      117866 :     m_Bound1.nContent.Assign( m_Bound1.nNode.GetNode().GetContentNode(), 0 );
     383      117866 :     m_Bound2.nContent.Assign( m_Bound2.nNode.GetNode().GetContentNode(), 0 );
     384      117866 : }
     385             : 
     386       19957 : SwPaM::SwPaM( const SwNodeIndex& rMark, sal_Int32 nMarkContent,
     387             :               const SwNodeIndex& rPoint, sal_Int32 nPointContent, SwPaM* pRing )
     388             :     : Ring( pRing )
     389             :     , m_Bound1( rMark )
     390             :     , m_Bound2( rPoint )
     391             :     , m_pPoint( &m_Bound2 )
     392             :     , m_pMark( &m_Bound1 )
     393       19957 :     , m_bIsInFrontOfLabel( false )
     394             : {
     395       19957 :     m_pPoint->nContent.Assign( rPoint.GetNode().GetContentNode(), nPointContent);
     396       19957 :     m_pMark ->nContent.Assign( rMark .GetNode().GetContentNode(), nMarkContent );
     397       19957 : }
     398             : 
     399        9756 : SwPaM::SwPaM( const SwNode& rMark, sal_Int32 nMarkContent,
     400             :               const SwNode& rPoint, sal_Int32 nPointContent, SwPaM* pRing )
     401             :     : Ring( pRing )
     402             :     , m_Bound1( rMark )
     403             :     , m_Bound2( rPoint )
     404             :     , m_pPoint( &m_Bound2 )
     405             :     , m_pMark( &m_Bound1 )
     406        9756 :     , m_bIsInFrontOfLabel( false )
     407             : {
     408        9756 :     m_pPoint->nContent.Assign( m_pPoint->nNode.GetNode().GetContentNode(),
     409        9756 :         nPointContent);
     410        9756 :     m_pMark ->nContent.Assign( m_pMark ->nNode.GetNode().GetContentNode(),
     411        9756 :         nMarkContent );
     412        9756 : }
     413             : 
     414       60146 : SwPaM::SwPaM( const SwNode& rNode, sal_Int32 nContent, SwPaM* pRing )
     415             :     : Ring( pRing )
     416             :     , m_Bound1( rNode )
     417       60146 :     , m_Bound2( m_Bound1.nNode.GetNode().GetNodes() ) // default initialize
     418             :     , m_pPoint( &m_Bound1 )
     419             :     , m_pMark( &m_Bound1 )
     420      120292 :     , m_bIsInFrontOfLabel( false )
     421             : {
     422       60146 :     m_pPoint->nContent.Assign( m_pPoint->nNode.GetNode().GetContentNode(),
     423       60146 :         nContent );
     424       60146 : }
     425             : 
     426      190197 : SwPaM::SwPaM( const SwNodeIndex& rNodeIdx, sal_Int32 nContent, SwPaM* pRing )
     427             :     : Ring( pRing )
     428             :     , m_Bound1( rNodeIdx )
     429      190197 :     , m_Bound2( rNodeIdx.GetNode().GetNodes() ) // default initialize
     430             :     , m_pPoint( &m_Bound1 )
     431             :     , m_pMark( &m_Bound1 )
     432      380394 :     , m_bIsInFrontOfLabel( false )
     433             : {
     434      190197 :     m_pPoint->nContent.Assign( rNodeIdx.GetNode().GetContentNode(), nContent );
     435      190197 : }
     436             : 
     437    12757270 : SwPaM::~SwPaM() {}
     438             : 
     439          30 : SwPaM::SwPaM(SwPaM const& rPam, SwPaM *const pRing)
     440             :     : Ring(pRing)
     441             :     , m_Bound1( *(rPam.m_pPoint) )
     442             :     , m_Bound2( *(rPam.m_pMark)  )
     443          30 :     , m_pPoint( &m_Bound1 ), m_pMark( rPam.HasMark() ? &m_Bound2 : m_pPoint )
     444          60 :     , m_bIsInFrontOfLabel( false )
     445             : {
     446          30 : }
     447             : 
     448             : // @@@ semantic: no copy assignment for super class Ring.
     449         759 : SwPaM &SwPaM::operator=( const SwPaM &rPam )
     450             : {
     451         759 :     *m_pPoint = *( rPam.m_pPoint );
     452         759 :     if ( rPam.HasMark() )
     453             :     {
     454         741 :         SetMark();
     455         741 :         *m_pMark = *( rPam.m_pMark );
     456             :     }
     457             :     else
     458             :     {
     459          18 :         DeleteMark();
     460             :     }
     461         759 :     return *this;
     462             : }
     463             : 
     464      273894 : void SwPaM::SetMark()
     465             : {
     466      273894 :     if (m_pPoint == &m_Bound1)
     467             :     {
     468      273832 :         m_pMark = &m_Bound2;
     469             :     }
     470             :     else
     471             :     {
     472          62 :         m_pMark = &m_Bound1;
     473             :     }
     474      273894 :     (*m_pMark) = (*m_pPoint);
     475      273894 : }
     476             : 
     477             : #ifdef DBG_UTIL
     478             : void SwPaM::Exchange()
     479             : {
     480             :     if (m_pPoint != m_pMark)
     481             :     {
     482             :         SwPosition *pTmp = m_pPoint;
     483             :         m_pPoint = m_pMark;
     484             :         m_pMark = pTmp;
     485             :     }
     486             : }
     487             : #endif
     488             : 
     489             : /// movement of cursor
     490      454966 : bool SwPaM::Move( SwMoveFn fnMove, SwGoInDoc fnGo )
     491             : {
     492      454966 :     const bool bRet = (*fnGo)( *this, fnMove );
     493             : 
     494      454966 :     m_bIsInFrontOfLabel = false;
     495      454966 :     return bRet;
     496             : }
     497             : 
     498             : /** make a new region
     499             : 
     500             :     Sets the first SwPaM onto the given SwPaM, or to the beginning or end of a
     501             :     document. SPoint stays at its position, GetMark will be changed respectively.
     502             : 
     503             :     @param fnMove  Contains information if beginning or end of document.
     504             :     @param pOrigRg The given region.
     505             : 
     506             :     @return Newly created range, in Ring with parameter pOrigRg.
     507             : */
     508          17 : SwPaM* SwPaM::MakeRegion( SwMoveFn fnMove, const SwPaM * pOrigRg )
     509             : {
     510             :     SwPaM* pPam;
     511          17 :     if( pOrigRg == 0 )
     512             :     {
     513           0 :         pPam = new SwPaM( *m_pPoint );
     514           0 :         pPam->SetMark(); // set beginning
     515           0 :         pPam->Move( fnMove, fnGoSection); // to beginning or end of a node
     516             : 
     517             :         // set SPoint onto its old position; set GetMark to the "end"
     518           0 :         pPam->Exchange();
     519             :     }
     520             :     else
     521             :     {
     522          17 :         pPam = new SwPaM(*pOrigRg, const_cast<SwPaM*>(pOrigRg)); // given search range
     523             :         // make sure that SPoint is on the "real" start position
     524             :         // FORWARD: SPoint always smaller than GetMark
     525             :         // BACKWARD: SPoint always bigger than GetMark
     526          17 :         if( (pPam->GetMark()->*fnMove->fnCmpOp)( *pPam->GetPoint() ) )
     527          17 :             pPam->Exchange();
     528             :     }
     529          17 :     return pPam;
     530             : }
     531             : 
     532       11819 : SwPaM & SwPaM::Normalize(bool bPointFirst)
     533             : {
     534       11819 :     if (HasMark())
     535       18537 :         if ( ( bPointFirst && *m_pPoint > *m_pMark) ||
     536       17921 :              (!bPointFirst && *m_pPoint < *m_pMark) )
     537             :         {
     538         395 :             Exchange();
     539             :         }
     540       11819 :     return *this;
     541             : }
     542             : 
     543             : /// return page number at cursor (for reader and page bound frames)
     544          52 : sal_uInt16 SwPaM::GetPageNum( bool bAtPoint, const Point* pLayPos )
     545             : {
     546             :     const SwContentFrm* pCFrm;
     547             :     const SwPageFrm *pPg;
     548             :     const SwContentNode *pNd ;
     549          52 :     const SwPosition* pPos = bAtPoint ? m_pPoint : m_pMark;
     550             : 
     551         156 :     if( 0 != ( pNd = pPos->nNode.GetNode().GetContentNode() ) &&
     552         104 :         0 != ( pCFrm = pNd->getLayoutFrm( pNd->GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout(), pLayPos, pPos, false )) &&
     553          52 :         0 != ( pPg = pCFrm->FindPageFrm() ))
     554          52 :         return pPg->GetPhyPageNum();
     555           0 :     return 0;
     556             : }
     557             : 
     558             : // Formular view - See also SwCrsrShell::IsCrsrReadonly()
     559           0 : static const SwFrm* lcl_FindEditInReadonlyFrm( const SwFrm& rFrm )
     560             : {
     561           0 :     const SwFrm* pRet = 0;
     562             : 
     563             :     const SwFlyFrm* pFly;
     564             :     const SwSectionFrm* pSectionFrm;
     565             : 
     566           0 :     if( rFrm.IsInFly() &&
     567           0 :        (pFly = rFrm.FindFlyFrm())->GetFormat()->GetEditInReadonly().GetValue() &&
     568           0 :         pFly->Lower() &&
     569           0 :        !pFly->Lower()->IsNoTextFrm() )
     570             :     {
     571           0 :        pRet = pFly;
     572             :     }
     573           0 :     else if ( rFrm.IsInSct() &&
     574           0 :               0 != ( pSectionFrm = rFrm.FindSctFrm() )->GetSection() &&
     575           0 :               pSectionFrm->GetSection()->IsEditInReadonlyFlag() )
     576             :     {
     577           0 :         pRet = pSectionFrm;
     578             :     }
     579             : 
     580           0 :     return pRet;
     581             : }
     582             : 
     583             : /// is in protected section or selection surrounds something protected
     584       18063 : bool SwPaM::HasReadonlySel( bool bFormView, bool bAnnotationMode ) const
     585             : {
     586       18063 :     bool bRet = false;
     587             : 
     588       18063 :     const SwContentNode* pNd = GetPoint()->nNode.GetNode().GetContentNode();
     589       18063 :     const SwContentFrm *pFrm = NULL;
     590       18063 :     if ( pNd != NULL )
     591             :     {
     592       18063 :         Point aTmpPt;
     593       18063 :         pFrm = pNd->getLayoutFrm( pNd->GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout(), &aTmpPt, GetPoint(), false );
     594             :     }
     595             : 
     596             :     // Will be set if point are inside edit-in-readonly environment
     597       18063 :     const SwFrm* pPointEditInReadonlyFrm = NULL;
     598       18063 :     if ( pFrm != NULL
     599       18075 :          && ( pFrm->IsProtected()
     600       18051 :               || ( bFormView
     601           0 :                    && 0 == ( pPointEditInReadonlyFrm = lcl_FindEditInReadonlyFrm( *pFrm ) ) ) ) )
     602             :     {
     603          12 :         bRet = true;
     604             :     }
     605       18051 :     else if( pNd != NULL )
     606             :     {
     607       18051 :         const SwSectionNode* pSNd = pNd->GetSectionNode();
     608       18051 :         if ( pSNd != NULL
     609       18051 :              && ( pSNd->GetSection().IsProtectFlag()
     610           0 :                   || ( bFormView
     611           0 :                        && !pSNd->GetSection().IsEditInReadonlyFlag()) ) )
     612             :         {
     613           0 :             bRet = true;
     614             :         }
     615             :     }
     616             : 
     617       36126 :     if ( !bRet
     618       18051 :          && HasMark()
     619       18276 :          && GetPoint()->nNode != GetMark()->nNode )
     620             :     {
     621          37 :         pNd = GetMark()->nNode.GetNode().GetContentNode();
     622          37 :         pFrm = NULL;
     623          37 :         if ( pNd != NULL )
     624             :         {
     625          37 :             Point aTmpPt;
     626          37 :             pFrm = pNd->getLayoutFrm( pNd->GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout(), &aTmpPt, GetMark(), false );
     627             :         }
     628             : 
     629          37 :         const SwFrm* pMarkEditInReadonlyFrm = NULL;
     630          37 :         if ( pFrm != NULL
     631          37 :              && ( pFrm->IsProtected()
     632          37 :                   || ( bFormView
     633           0 :                        && 0 == ( pMarkEditInReadonlyFrm = lcl_FindEditInReadonlyFrm( *pFrm ) ) ) ) )
     634             :         {
     635           0 :             bRet = true;
     636             :         }
     637          37 :         else if( pNd != NULL )
     638             :         {
     639          37 :             const SwSectionNode* pSNd = pNd->GetSectionNode();
     640          37 :             if ( pSNd != NULL
     641          37 :                  && ( pSNd->GetSection().IsProtectFlag()
     642           0 :                       || ( bFormView
     643           0 :                            && !pSNd->GetSection().IsEditInReadonlyFlag()) ) )
     644             :             {
     645           0 :                 bRet = true;
     646             :             }
     647             :         }
     648             : 
     649          37 :         if ( !bRet && bFormView )
     650             :         {
     651             :            // Check if start and end frame are inside the _same_
     652             :            // edit-in-readonly-environment. Otherwise we better return 'true'
     653           0 :            if ( pPointEditInReadonlyFrm != pMarkEditInReadonlyFrm )
     654           0 :                 bRet = true;
     655             :         }
     656             : 
     657             :         // check for protected section inside the selection
     658          37 :         if( !bRet )
     659             :         {
     660          37 :             sal_uLong nSttIdx = GetMark()->nNode.GetIndex(),
     661          37 :                     nEndIdx = GetPoint()->nNode.GetIndex();
     662          37 :             if( nEndIdx <= nSttIdx )
     663             :             {
     664          10 :                 sal_uLong nTmp = nSttIdx;
     665          10 :                 nSttIdx = nEndIdx;
     666          10 :                 nEndIdx = nTmp;
     667             :             }
     668             : 
     669             :             // If a protected section should be between nodes, then the
     670             :             // selection needs to contain already x nodes.
     671             :             // (TextNd, SectNd, TextNd, EndNd, TextNd )
     672          37 :             if( nSttIdx + 3 < nEndIdx )
     673             :             {
     674          30 :                 const SwSectionFormats& rFormats = GetDoc()->GetSections();
     675          60 :                 for( SwSectionFormats::size_type n = rFormats.size(); n;  )
     676             :                 {
     677           0 :                     const SwSectionFormat* pFormat = rFormats[ --n ];
     678           0 :                     if( pFormat->GetProtect().IsContentProtected() )
     679             :                     {
     680           0 :                         const SwFormatContent& rContent = pFormat->GetContent(false);
     681             :                         OSL_ENSURE( rContent.GetContentIdx(), "where is the SectionNode?" );
     682           0 :                         sal_uLong nIdx = rContent.GetContentIdx()->GetIndex();
     683           0 :                         if( nSttIdx <= nIdx && nEndIdx >= nIdx &&
     684           0 :                             rContent.GetContentIdx()->GetNode().GetNodes().IsDocNodes() )
     685             :                         {
     686           0 :                             bRet = true;
     687           0 :                             break;
     688             :                         }
     689             :                     }
     690             :                 }
     691             :             }
     692             :         }
     693             :     }
     694             : 
     695             :     //FIXME FieldBk
     696             :     // TODO: Form Protection when Enhanced Fields are enabled
     697       18063 :     const SwDoc *pDoc = GetDoc();
     698       18063 :     const IDocumentMarkAccess* pMarksAccess = pDoc->getIDocumentMarkAccess();
     699       18063 :     sw::mark::IMark* pA = GetPoint() ? pMarksAccess->getFieldmarkFor( *GetPoint( ) ) : NULL;
     700       18063 :     sw::mark::IMark* pB = GetMark( ) ? pMarksAccess->getFieldmarkFor( *GetMark( ) ) : pA;
     701             : 
     702       18063 :     bool bUnhandledMark = false;
     703       18063 :     sw::mark::IFieldmark* pFieldmark = pMarksAccess->getFieldmarkFor( *GetPoint() );
     704       18063 :     if ( pFieldmark )
     705          13 :         bUnhandledMark = pFieldmark->GetFieldname( ) == ODF_UNHANDLED;
     706             : 
     707       18063 :     if (!bRet)
     708             :     {
     709             :         // Unhandled fieldmarks case shouldn't be edited manually to avoid breaking anything
     710       18051 :         if ( ( pA == pB ) && bUnhandledMark )
     711           0 :             bRet = true;
     712             :         else
     713             :         {
     714             :             // Form protection case
     715       18051 :             bool bAtStartA = pA != NULL && pA->GetMarkStart() == *GetPoint();
     716       18051 :             bool bAtStartB = pB != NULL && pB->GetMarkStart() == *GetMark();
     717       18051 :             bRet = ( pA != pB ) || bAtStartA || bAtStartB;
     718       18051 :             bool bProtectForm = pDoc->GetDocumentSettingManager().get( DocumentSettingId::PROTECT_FORM );
     719       18051 :             if ( bProtectForm )
     720           2 :                 bRet |= ( pA == NULL || pB == NULL );
     721             :         }
     722             :     }
     723             :     else
     724             :     {
     725          12 :         bRet = !( pA == pB && pA != NULL );
     726             :     }
     727             : 
     728             :     // Don't allow inserting characters between the 'field mark end' and
     729             :     // the 'comment anchor', unless the cursor is inside the annotation.
     730       18063 :     if (!bRet && !bAnnotationMode)
     731             :     {
     732       18040 :         if (!pA && GetPoint() && GetPoint()->nNode.GetNode().IsTextNode() && GetPoint()->nContent.GetIndex() > 0)
     733             :         {
     734             :             // getFieldmarkFor() searches for >= start and < end, so check for
     735             :             // the previous character, to also get the fieldmark, if we're
     736             :             // exactly at the end.
     737        8646 :             SwPosition aPrevChar(*GetPoint());
     738        8646 :             --aPrevChar.nContent;
     739        8646 :             pFieldmark = pMarksAccess->getFieldmarkFor(aPrevChar);
     740        8646 :             if (pFieldmark && pFieldmark->GetMarkEnd() == *GetPoint())
     741           2 :                 bRet = true;
     742             :         }
     743             :     }
     744             : 
     745       18063 :     return bRet;
     746             : }
     747             : 
     748             : /// This function returns the next node in direction of search. If there is no
     749             : /// left or the next is out of the area, then a null-pointer is returned.
     750             : /// @param rbFirst If <true> than first time request. If so than the position of
     751             : ///        the PaM must not be changed!
     752          50 : SwContentNode* GetNode( SwPaM & rPam, bool& rbFirst, SwMoveFn fnMove,
     753             :                       bool bInReadOnly )
     754             : {
     755          50 :     SwContentNode * pNd = 0;
     756             :     SwContentFrm* pFrm;
     757         100 :     if( ((*rPam.GetPoint()).*fnMove->fnCmpOp)( *rPam.GetMark() ) ||
     758           0 :         ( *rPam.GetPoint() == *rPam.GetMark() && rbFirst ) )
     759             :     {
     760          50 :         if( rbFirst )
     761             :         {
     762          17 :             rbFirst = false;
     763          17 :             pNd = rPam.GetContentNode();
     764          17 :             if( pNd )
     765             :             {
     766          17 :                 if(
     767             :                     (
     768          34 :                         0 == ( pFrm = pNd->getLayoutFrm( pNd->GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout() ) ) ||
     769          34 :                         ( !bInReadOnly && pFrm->IsProtected() ) ||
     770          34 :                         (pFrm->IsTextFrm() && static_cast<SwTextFrm*>(pFrm)->IsHiddenNow())
     771          34 :                     ) ||
     772          17 :                     ( !bInReadOnly && pNd->FindSectionNode() &&
     773           0 :                         pNd->FindSectionNode()->GetSection().IsProtect()
     774             :                     )
     775             :                   )
     776             :                     {
     777           0 :                         pNd = 0;
     778             :                     }
     779             :             }
     780             :         }
     781             : 
     782          50 :         if( !pNd ) // is the cursor not on a ContentNode?
     783             :         {
     784          33 :             SwPosition aPos( *rPam.GetPoint() );
     785          33 :             bool bSrchForward = fnMove == fnMoveForward;
     786          33 :             SwNodes& rNodes = aPos.nNode.GetNodes();
     787             : 
     788             :             // go to next/previous ContentNode
     789             :             while( true )
     790             :             {
     791             :                 pNd = bSrchForward
     792          27 :                         ? rNodes.GoNextSection( &aPos.nNode, true, !bInReadOnly )
     793          60 :                         : SwNodes::GoPrevSection( &aPos.nNode, true, !bInReadOnly );
     794          33 :                 if( pNd )
     795             :                 {
     796          30 :                     aPos.nContent.Assign( pNd, ::GetSttOrEnd( bSrchForward,*pNd ));
     797             :                     // is the position still in the area
     798          30 :                     if( (aPos.*fnMove->fnCmpOp)( *rPam.GetMark() ) )
     799             :                     {
     800             :                         // only in AutoTextSection can be nodes that are hidden
     801          90 :                         if( 0 == ( pFrm = pNd->getLayoutFrm( pNd->GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout() ) ) ||
     802          60 :                             ( !bInReadOnly && pFrm->IsProtected() ) ||
     803          60 :                             ( pFrm->IsTextFrm() &&
     804          30 :                                 static_cast<SwTextFrm*>(pFrm)->IsHiddenNow() ) )
     805             :                         {
     806           0 :                             pNd = 0;
     807           0 :                             continue;
     808             :                         }
     809          30 :                         *rPam.GetPoint() = aPos;
     810             :                     }
     811             :                     else
     812           0 :                         pNd = 0; // no valid node
     813          30 :                     break;
     814             :                 }
     815           3 :                 break;
     816          33 :             }
     817             :         }
     818             :     }
     819          50 :     return pNd;
     820             : }
     821             : 
     822      140228 : void GoStartDoc( SwPosition * pPos )
     823             : {
     824      140228 :     SwNodes& rNodes = pPos->nNode.GetNodes();
     825      140228 :     pPos->nNode = *rNodes.GetEndOfContent().StartOfSectionNode();
     826             :     // we always need to find a ContentNode!
     827      140228 :     SwContentNode* pCNd = rNodes.GoNext( &pPos->nNode );
     828      140228 :     if( pCNd )
     829      140228 :         pCNd->MakeStartIndex( &pPos->nContent );
     830      140228 : }
     831             : 
     832       83961 : void GoEndDoc( SwPosition * pPos )
     833             : {
     834       83961 :     SwNodes& rNodes = pPos->nNode.GetNodes();
     835       83961 :     pPos->nNode = rNodes.GetEndOfContent();
     836       83961 :     SwContentNode* pCNd = GoPreviousNds( &pPos->nNode, true );
     837       83961 :     if( pCNd )
     838       83961 :         pCNd->MakeEndIndex( &pPos->nContent );
     839       83961 : }
     840             : 
     841           0 : void GoStartSection( SwPosition * pPos )
     842             : {
     843             :     // jump to section's beginning
     844           0 :     SwNodes& rNodes = pPos->nNode.GetNodes();
     845           0 :     sal_uInt16 nLevel = SwNodes::GetSectionLevel( pPos->nNode );
     846           0 :     if( pPos->nNode < rNodes.GetEndOfContent().StartOfSectionIndex() )
     847           0 :         nLevel--;
     848           0 :     do { SwNodes::GoStartOfSection( &pPos->nNode ); } while( nLevel-- );
     849             : 
     850             :     // already on a ContentNode
     851           0 :     pPos->nNode.GetNode().GetContentNode()->MakeStartIndex( &pPos->nContent );
     852           0 : }
     853             : 
     854             : /// go to the end of the current base section
     855           1 : void GoEndSection( SwPosition * pPos )
     856             : {
     857             :     // jump to section's beginning/end
     858           1 :     SwNodes& rNodes = pPos->nNode.GetNodes();
     859           1 :     sal_uInt16 nLevel = SwNodes::GetSectionLevel( pPos->nNode );
     860           1 :     if( pPos->nNode < rNodes.GetEndOfContent().StartOfSectionIndex() )
     861           0 :         nLevel--;
     862           3 :     do { SwNodes::GoEndOfSection( &pPos->nNode ); } while( nLevel-- );
     863             : 
     864             :     // now on a EndNode, thus to the previous ContentNode
     865           1 :     if( GoPreviousNds( &pPos->nNode, true ) )
     866           1 :         pPos->nNode.GetNode().GetContentNode()->MakeEndIndex( &pPos->nContent );
     867           1 : }
     868             : 
     869      224189 : bool GoInDoc( SwPaM & rPam, SwMoveFn fnMove )
     870             : {
     871      224189 :     (*fnMove->fnDoc)( rPam.GetPoint() );
     872      224189 :     return true;
     873             : }
     874             : 
     875           0 : bool GoInSection( SwPaM & rPam, SwMoveFn fnMove )
     876             : {
     877           0 :     (*fnMove->fnSections)( rPam.GetPoint() );
     878           0 :     return true;
     879             : }
     880             : 
     881      148742 : bool GoInNode( SwPaM & rPam, SwMoveFn fnMove )
     882             : {
     883      148742 :     SwContentNode *pNd = (*fnMove->fnNds)( &rPam.GetPoint()->nNode, true );
     884      148742 :     if( pNd )
     885      131601 :         rPam.GetPoint()->nContent.Assign( pNd,
     886      263202 :                         ::GetSttOrEnd( fnMove == fnMoveForward, *pNd ) );
     887      148742 :     return pNd;
     888             : }
     889             : 
     890      119981 : bool GoInContent( SwPaM & rPam, SwMoveFn fnMove )
     891             : {
     892      119981 :     if( (*fnMove->fnNd)( &rPam.GetPoint()->nNode.GetNode(),
     893      119981 :                         &rPam.GetPoint()->nContent, CRSR_SKIP_CHARS ))
     894       81994 :         return true;
     895       37987 :     return GoInNode( rPam, fnMove );
     896             : }
     897             : 
     898           0 : bool GoInContentCells( SwPaM & rPam, SwMoveFn fnMove )
     899             : {
     900           0 :     if( (*fnMove->fnNd)( &rPam.GetPoint()->nNode.GetNode(),
     901           0 :                          &rPam.GetPoint()->nContent, CRSR_SKIP_CELLS ))
     902           0 :         return true;
     903           0 :     return GoInNode( rPam, fnMove );
     904             : }
     905             : 
     906          46 : bool GoInContentSkipHidden( SwPaM & rPam, SwMoveFn fnMove )
     907             : {
     908          46 :     if( (*fnMove->fnNd)( &rPam.GetPoint()->nNode.GetNode(),
     909          46 :                         &rPam.GetPoint()->nContent, CRSR_SKIP_CHARS | CRSR_SKIP_HIDDEN ) )
     910          41 :         return true;
     911           5 :     return GoInNode( rPam, fnMove );
     912             : }
     913             : 
     914           0 : bool GoInContentCellsSkipHidden( SwPaM & rPam, SwMoveFn fnMove )
     915             : {
     916           0 :     if( (*fnMove->fnNd)( &rPam.GetPoint()->nNode.GetNode(),
     917           0 :                          &rPam.GetPoint()->nContent, CRSR_SKIP_CELLS | CRSR_SKIP_HIDDEN ) )
     918           0 :         return true;
     919           0 :     return GoInNode( rPam, fnMove );
     920             : }
     921             : 
     922           0 : bool GoPrevPara( SwPaM & rPam, SwPosPara aPosPara )
     923             : {
     924           0 :     if( rPam.Move( fnMoveBackward, fnGoNode ) )
     925             :     {
     926             :         // always on a ContentNode
     927           0 :         SwPosition& rPos = *rPam.GetPoint();
     928           0 :         SwContentNode * pNd = rPos.nNode.GetNode().GetContentNode();
     929             :         rPos.nContent.Assign( pNd,
     930           0 :                             ::GetSttOrEnd( aPosPara == fnMoveForward, *pNd ) );
     931           0 :         return true;
     932             :     }
     933           0 :     return false;
     934             : }
     935             : 
     936       25074 : bool GoCurrPara( SwPaM & rPam, SwPosPara aPosPara )
     937             : {
     938       25074 :     SwPosition& rPos = *rPam.GetPoint();
     939       25074 :     SwContentNode * pNd = rPos.nNode.GetNode().GetContentNode();
     940       25074 :     if( pNd )
     941             :     {
     942       25074 :         const sal_Int32 nOld = rPos.nContent.GetIndex();
     943       25074 :         const sal_Int32 nNew = aPosPara == fnMoveForward ? 0 : pNd->Len();
     944             :         // if already at beginning/end then to the next/previous
     945       25074 :         if( nOld != nNew )
     946             :         {
     947       25074 :             rPos.nContent.Assign( pNd, nNew );
     948       25074 :             return true;
     949             :         }
     950             :     }
     951             :     // move node to next/previous ContentNode
     952           0 :     if( ( aPosPara==fnParaStart && 0 != ( pNd =
     953           0 :             GoPreviousNds( &rPos.nNode, true ))) ||
     954           0 :         ( aPosPara==fnParaEnd && 0 != ( pNd =
     955           0 :             GoNextNds( &rPos.nNode, true ))) )
     956             :     {
     957             :         rPos.nContent.Assign( pNd,
     958           0 :                         ::GetSttOrEnd( aPosPara == fnMoveForward, *pNd ));
     959           0 :         return true;
     960             :     }
     961           0 :     return false;
     962             : }
     963             : 
     964       14432 : bool GoNextPara( SwPaM & rPam, SwPosPara aPosPara )
     965             : {
     966       14432 :     if( rPam.Move( fnMoveForward, fnGoNode ) )
     967             :     {
     968             :         // always on a ContentNode
     969       10171 :         SwPosition& rPos = *rPam.GetPoint();
     970       10171 :         SwContentNode * pNd = rPos.nNode.GetNode().GetContentNode();
     971             :         rPos.nContent.Assign( pNd,
     972       10171 :                         ::GetSttOrEnd( aPosPara == fnMoveForward, *pNd ) );
     973       10171 :         return true;
     974             :     }
     975        4261 :     return false;
     976             : }
     977             : 
     978       41915 : bool GoCurrSection( SwPaM & rPam, SwMoveFn fnMove )
     979             : {
     980       41915 :     SwPosition& rPos = *rPam.GetPoint();
     981       41915 :     SwPosition aSavePos( rPos ); // position for comparison
     982       41915 :     (fnMove->fnSection)( &rPos.nNode );
     983             :     SwContentNode *pNd;
     984       67789 :     if( 0 == ( pNd = rPos.nNode.GetNode().GetContentNode()) &&
     985       25874 :         0 == ( pNd = (*fnMove->fnNds)( &rPos.nNode, true )) )
     986             :     {
     987           0 :         rPos = aSavePos; // do not change cursor
     988           0 :         return false;
     989             :     }
     990             : 
     991             :     rPos.nContent.Assign( pNd,
     992       41915 :                         ::GetSttOrEnd( fnMove == fnMoveForward, *pNd ) );
     993       41915 :     return aSavePos != rPos;
     994             : }
     995             : 
     996           0 : bool GoNextSection( SwPaM & rPam, SwMoveFn fnMove )
     997             : {
     998           0 :     SwPosition& rPos = *rPam.GetPoint();
     999           0 :     SwPosition aSavePos( rPos ); // position for comparison
    1000           0 :     SwNodes::GoEndOfSection( &rPos.nNode );
    1001             : 
    1002             :     // no other ContentNode existent?
    1003           0 :     if( !GoInContent( rPam, fnMoveForward ) )
    1004             :     {
    1005           0 :         rPos = aSavePos; // do not change cursor
    1006           0 :         return false;
    1007             :     }
    1008           0 :     (fnMove->fnSection)( &rPos.nNode );
    1009           0 :     SwContentNode *pNd = rPos.nNode.GetNode().GetContentNode();
    1010             :     rPos.nContent.Assign( pNd,
    1011           0 :                         ::GetSttOrEnd( fnMove == fnMoveForward, *pNd ) );
    1012           0 :     return true;
    1013             : }
    1014             : 
    1015           0 : bool GoPrevSection( SwPaM & rPam, SwMoveFn fnMove )
    1016             : {
    1017           0 :     SwPosition& rPos = *rPam.GetPoint();
    1018           0 :     SwPosition aSavePos( rPos ); // position for comparison
    1019           0 :     SwNodes::GoStartOfSection( &rPos.nNode );
    1020             : 
    1021             :     // no further ContentNode existent?
    1022           0 :     if( !GoInContent( rPam, fnMoveBackward ))
    1023             :     {
    1024           0 :         rPos = aSavePos; // do not change cursor
    1025           0 :         return false;
    1026             :     }
    1027           0 :     (fnMove->fnSection)( &rPos.nNode );
    1028           0 :     SwContentNode *pNd = rPos.nNode.GetNode().GetContentNode();
    1029             :     rPos.nContent.Assign( pNd,
    1030           0 :                             ::GetSttOrEnd( fnMove == fnMoveForward, *pNd ));
    1031           0 :     return true;
    1032             : }
    1033             : 
    1034          25 : OUString SwPaM::GetText() const
    1035             : {
    1036          25 :     OUString aResult;
    1037             : 
    1038          50 :     SwNodeIndex aNodeIndex = Start()->nNode;
    1039             : 
    1040             :     // The first node can be already the end node.
    1041             :     // Use a "forever" loop with an exit condition in the middle
    1042             :     // of its body, in order to correctly handle all cases.
    1043          25 :     bool bIsStartNode = true;
    1044             :     for (;;)
    1045             :     {
    1046          28 :         const bool bIsEndNode = aNodeIndex == End()->nNode;
    1047          28 :         SwTextNode * pTextNode = aNodeIndex.GetNode().GetTextNode();
    1048             : 
    1049          28 :         if (pTextNode != NULL)
    1050             :         {
    1051          28 :             const OUString aTmpStr = pTextNode->GetText();
    1052             : 
    1053          28 :             if (bIsStartNode || bIsEndNode)
    1054             :             {
    1055             :                 // Handle corner cases of start/end node(s)
    1056             :                 const sal_Int32 nStart = bIsStartNode
    1057          25 :                     ? Start()->nContent.GetIndex()
    1058          53 :                     : 0;
    1059             :                 const sal_Int32 nEnd = bIsEndNode
    1060          25 :                     ? End()->nContent.GetIndex()
    1061          53 :                     : aTmpStr.getLength();
    1062             : 
    1063          28 :                 aResult += aTmpStr.copy(nStart, nEnd-nStart);
    1064             :             }
    1065             :             else
    1066             :             {
    1067           0 :                 aResult += aTmpStr;
    1068          28 :             }
    1069             :         }
    1070             : 
    1071          28 :         if (bIsEndNode)
    1072             :         {
    1073          25 :             break;
    1074             :         }
    1075             : 
    1076           3 :         ++aNodeIndex;
    1077           3 :         bIsStartNode = false;
    1078           3 :     }
    1079             : 
    1080          50 :     return aResult;
    1081             : }
    1082             : 
    1083           0 : void SwPaM::InvalidatePaM()
    1084             : {
    1085           0 :     const SwNode &_pNd = this->GetNode();
    1086           0 :     const SwTextNode *_pTextNd = _pNd.GetTextNode();
    1087           0 :     if (_pTextNd != NULL)
    1088             :     {
    1089             :         // pretend that the PaM marks inserted text to recalc the portion...
    1090           0 :         SwInsText aHint( Start()->nContent.GetIndex(),
    1091           0 :                         End()->nContent.GetIndex() - Start()->nContent.GetIndex() + 1 );
    1092           0 :         SwModify *_pModify=const_cast<SwModify*>(static_cast<SwModify const *>(_pTextNd));
    1093           0 :         _pModify->ModifyNotification( 0, &aHint);
    1094             :     }
    1095           0 : }
    1096             : 
    1097          52 : void SwPaM::dumpAsXml(xmlTextWriterPtr pWriter) const
    1098             : {
    1099          52 :     xmlTextWriterStartElement(pWriter, BAD_CAST("swPaM"));
    1100             : 
    1101          52 :     xmlTextWriterStartElement(pWriter, BAD_CAST("point"));
    1102          52 :     GetPoint()->dumpAsXml(pWriter);
    1103          52 :     xmlTextWriterEndElement(pWriter);
    1104             : 
    1105          52 :     if (HasMark())
    1106             :     {
    1107           0 :         xmlTextWriterStartElement(pWriter, BAD_CAST("mark"));
    1108           0 :         GetMark()->dumpAsXml(pWriter);
    1109           0 :         xmlTextWriterEndElement(pWriter);
    1110             :     }
    1111             : 
    1112          52 :     xmlTextWriterEndElement(pWriter);
    1113          52 : }
    1114             : 
    1115           0 : std::ostream &operator <<(std::ostream& s, const SwPaM& pam)
    1116             : {
    1117           0 :     if( pam.HasMark())
    1118           0 :         return s << "SwPaM (point " << *pam.GetPoint() << ", mark " << *pam.GetMark() << ")";
    1119             :     else
    1120           0 :         return s << "SwPaM (point " << *pam.GetPoint() << ")";
    1121         177 : }
    1122             : 
    1123             : 
    1124             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11