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

Generated by: LCOV version 1.10