LCOV - code coverage report
Current view: top level - sw/source/core/crsr - swcrsr.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 679 1271 53.4 %
Date: 2014-04-11 Functions: 52 79 65.8 %
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 <hintids.hxx>
      21             : #include <editeng/protitem.hxx>
      22             : #include <com/sun/star/i18n/WordType.hpp>
      23             : #include <com/sun/star/i18n/CharType.hpp>
      24             : #include <unotools/charclass.hxx>
      25             : #include <svl/ctloptions.hxx>
      26             : #include <swmodule.hxx>
      27             : #include <fmtcntnt.hxx>
      28             : #include <swtblfmt.hxx>
      29             : #include <swcrsr.hxx>
      30             : #include <unocrsr.hxx>
      31             : #include <doc.hxx>
      32             : #include <IDocumentUndoRedo.hxx>
      33             : #include <docary.hxx>
      34             : #include <ndtxt.hxx>
      35             : #include <section.hxx>
      36             : #include <swtable.hxx>
      37             : #include <cntfrm.hxx>
      38             : #include <rootfrm.hxx>
      39             : #include <txtfrm.hxx>
      40             : #include <scriptinfo.hxx>
      41             : #include <crstate.hxx>
      42             : #include <docsh.hxx>
      43             : #include <viewsh.hxx>
      44             : #include <frmatr.hxx>
      45             : #include <breakit.hxx>
      46             : #include <crsskip.hxx>
      47             : #include <vcl/msgbox.hxx>
      48             : #include <mdiexp.hxx>
      49             : #include <statstr.hrc>
      50             : #include <redline.hxx>
      51             : #include <txatbase.hxx>
      52             : 
      53             : using namespace ::com::sun::star::i18n;
      54             : 
      55             : static const sal_uInt16 coSrchRplcThreshold = 60000;
      56             : 
      57             : struct _PercentHdl
      58             : {
      59             :     SwDocShell* pDSh;
      60             :     sal_uLong nActPos;
      61             :     bool bBack, bNodeIdx;
      62             : 
      63           0 :     _PercentHdl( sal_uLong nStt, sal_uLong nEnd, SwDocShell* pSh )
      64           0 :         : pDSh(pSh), bBack(false), bNodeIdx(false)
      65             :     {
      66           0 :         nActPos = nStt;
      67           0 :         if( ( bBack = (nStt > nEnd )) )
      68             :         {
      69           0 :             sal_uLong n = nStt; nStt = nEnd; nEnd = n;
      70             :         }
      71           0 :         ::StartProgress( STR_STATSTR_SEARCH, nStt, nEnd, 0 );
      72           0 :     }
      73             : 
      74           0 :     _PercentHdl( const SwPaM& rPam )
      75           0 :         : pDSh( (SwDocShell*)rPam.GetDoc()->GetDocShell() )
      76             :     {
      77             :         sal_uLong nStt, nEnd;
      78           0 :         if( rPam.GetPoint()->nNode == rPam.GetMark()->nNode )
      79             :         {
      80           0 :             bNodeIdx = false;
      81           0 :             nStt = rPam.GetMark()->nContent.GetIndex();
      82           0 :             nEnd = rPam.GetPoint()->nContent.GetIndex();
      83             :         }
      84             :         else
      85             :         {
      86           0 :             bNodeIdx = true;
      87           0 :             nStt = rPam.GetMark()->nNode.GetIndex();
      88           0 :             nEnd = rPam.GetPoint()->nNode.GetIndex();
      89             :         }
      90           0 :         nActPos = nStt;
      91           0 :         if( ( bBack = (nStt > nEnd )) )
      92             :         {
      93           0 :             sal_uLong n = nStt; nStt = nEnd; nEnd = n;
      94             :         }
      95           0 :         ::StartProgress( STR_STATSTR_SEARCH, nStt, nEnd, pDSh );
      96           0 :     }
      97             : 
      98           0 :     ~_PercentHdl()                      { ::EndProgress( pDSh ); }
      99             : 
     100           0 :     void NextPos( sal_uLong nPos ) const
     101           0 :         { ::SetProgressState( bBack ? nActPos - nPos : nPos, pDSh ); }
     102             : 
     103           0 :     void NextPos( SwPosition& rPos ) const
     104             :         {
     105             :             sal_uLong nPos;
     106           0 :             if( bNodeIdx )
     107           0 :                 nPos = rPos.nNode.GetIndex();
     108             :             else
     109           0 :                 nPos = rPos.nContent.GetIndex();
     110           0 :             ::SetProgressState( bBack ? nActPos - nPos : nPos, pDSh );
     111           0 :         }
     112             : };
     113             : 
     114      165294 : SwCursor::SwCursor( const SwPosition &rPos, SwPaM* pRing, bool bColumnSel )
     115             :     : SwPaM( rPos, pRing ), pSavePos( 0 ), mnRowSpanOffset( 0 ), nCursorBidiLevel( 0 ),
     116      165294 :     mbColumnSelection( bColumnSel )
     117             : {
     118      165294 : }
     119             : 
     120             : // @@@ semantic: no copy ctor.
     121           0 : SwCursor::SwCursor( SwCursor& rCpy )
     122             :     : SwPaM( rCpy ), pSavePos( 0 ), mnRowSpanOffset( rCpy.mnRowSpanOffset ),
     123           0 :     nCursorBidiLevel( rCpy.nCursorBidiLevel ), mbColumnSelection( rCpy.mbColumnSelection )
     124             : {
     125           0 : }
     126             : 
     127      330839 : SwCursor::~SwCursor()
     128             : {
     129      330586 :     while( pSavePos )
     130             :     {
     131           0 :         _SwCursor_SavePos* pNxt = pSavePos->pNext;
     132           0 :         delete pSavePos;
     133           0 :         pSavePos = pNxt;
     134             :     }
     135      165546 : }
     136             : 
     137         253 : SwCursor* SwCursor::Create( SwPaM* pRing ) const
     138             : {
     139         253 :     return new SwCursor( *GetPoint(), pRing, false );
     140             : }
     141             : 
     142          14 : bool SwCursor::IsReadOnlyAvailable() const
     143             : {
     144          14 :     return false;
     145             : }
     146             : 
     147         165 : sal_Bool SwCursor::IsSkipOverHiddenSections() const
     148             : {
     149         165 :     return sal_True;
     150             : }
     151             : 
     152         165 : sal_Bool SwCursor::IsSkipOverProtectSections() const
     153             : {
     154         165 :     return !IsReadOnlyAvailable();
     155             : }
     156             : 
     157             : // CreateNewSavePos is virtual so that derived classes of cursor can implement
     158             : // own SaveObjects if needed and validate them in the virtual check routines.
     159       58664 : void SwCursor::SaveState()
     160             : {
     161       58664 :     _SwCursor_SavePos* pNew = CreateNewSavePos();
     162       58664 :     pNew->pNext = pSavePos;
     163       58664 :     pSavePos = pNew;
     164       58664 : }
     165             : 
     166       58664 : void SwCursor::RestoreState()
     167             : {
     168       58664 :     if( pSavePos ) // Robust
     169             :     {
     170       58664 :         _SwCursor_SavePos* pDel = pSavePos;
     171       58664 :         pSavePos = pSavePos->pNext;
     172       58664 :         delete pDel;
     173             :     }
     174       58664 : }
     175             : 
     176       58664 : _SwCursor_SavePos* SwCursor::CreateNewSavePos() const
     177             : {
     178       58664 :     return new _SwCursor_SavePos( *this );
     179             : }
     180             : 
     181             : /// determine if point is outside of the node-array's content area
     182           8 : sal_Bool SwCursor::IsNoCntnt() const
     183             : {
     184          16 :     return GetPoint()->nNode.GetIndex() <
     185          16 :             GetDoc()->GetNodes().GetEndOfExtras().GetIndex();
     186             : }
     187             : 
     188       43734 : bool SwCursor::IsSelOvrCheck(int)
     189             : {
     190       43734 :     return false;
     191             : }
     192             : 
     193             : // extracted from IsSelOvr()
     194          23 : bool SwTableCursor::IsSelOvrCheck(int eFlags)
     195             : {
     196          23 :     SwNodes& rNds = GetDoc()->GetNodes();
     197             :     // check sections of nodes array
     198          46 :     if( (nsSwCursorSelOverFlags::SELOVER_CHECKNODESSECTION & eFlags)
     199          23 :         && HasMark() )
     200             :     {
     201           8 :         SwNodeIndex aOldPos( rNds, GetSavePos()->nNode );
     202           8 :         if( !CheckNodesRange( aOldPos, GetPoint()->nNode, true ))
     203             :         {
     204           0 :             GetPoint()->nNode = aOldPos;
     205           0 :             GetPoint()->nContent.Assign( GetCntntNode(), GetSavePos()->nCntnt );
     206           0 :             return true;
     207           8 :         }
     208             :     }
     209          23 :     return SwCursor::IsSelOvrCheck(eFlags);
     210             : }
     211             : 
     212       43734 : sal_Bool SwCursor::IsSelOvr( int eFlags )
     213             : {
     214       43734 :     SwDoc* pDoc = GetDoc();
     215       43734 :     SwNodes& rNds = pDoc->GetNodes();
     216             : 
     217       43734 :     sal_Bool bSkipOverHiddenSections = IsSkipOverHiddenSections();
     218       43734 :     sal_Bool bSkipOverProtectSections = IsSkipOverProtectSections();
     219             : 
     220       43734 :     if ( IsSelOvrCheck( eFlags ) )
     221             :     {
     222           0 :         return sal_True;
     223             :     }
     224             : 
     225      105604 :     if( pSavePos->nNode != GetPoint()->nNode.GetIndex() &&
     226             :         // (1997) in UI-ReadOnly everything is allowed
     227       61870 :         ( !pDoc->GetDocShell() || !pDoc->GetDocShell()->IsReadOnlyUI() ))
     228             :     {
     229             :         // check new sections
     230       30935 :         SwNodeIndex& rPtIdx = GetPoint()->nNode;
     231       30935 :         const SwSectionNode* pSectNd = rPtIdx.GetNode().FindSectionNode();
     232       30935 :         if( pSectNd &&
     233           4 :             ((bSkipOverHiddenSections && pSectNd->GetSection().IsHiddenFlag() ) ||
     234           0 :             (bSkipOverProtectSections && pSectNd->GetSection().IsProtectFlag() )))
     235             :         {
     236           0 :             if( 0 == ( nsSwCursorSelOverFlags::SELOVER_CHANGEPOS & eFlags ) )
     237             :             {
     238             :                 // then we're already done
     239           0 :                 RestoreSavePos();
     240           0 :                 return sal_True;
     241             :             }
     242             : 
     243             :             // set cursor to new position:
     244           0 :             SwNodeIndex aIdx( rPtIdx );
     245           0 :             sal_Int32 nCntntPos = pSavePos->nCntnt;
     246           0 :             bool bGoNxt = pSavePos->nNode < rPtIdx.GetIndex();
     247             :             SwCntntNode* pCNd = bGoNxt
     248           0 :                 ? rNds.GoNextSection( &rPtIdx, bSkipOverHiddenSections, bSkipOverProtectSections)
     249           0 :                 : rNds.GoPrevSection( &rPtIdx, bSkipOverHiddenSections, bSkipOverProtectSections);
     250           0 :             if( !pCNd && ( nsSwCursorSelOverFlags::SELOVER_ENABLEREVDIREKTION & eFlags ))
     251             :             {
     252           0 :                 bGoNxt = !bGoNxt;
     253           0 :                 pCNd = bGoNxt ? rNds.GoNextSection( &rPtIdx, bSkipOverHiddenSections, bSkipOverProtectSections)
     254           0 :                     : rNds.GoPrevSection( &rPtIdx, bSkipOverHiddenSections, bSkipOverProtectSections);
     255             :             }
     256             : 
     257           0 :             bool bIsValidPos = 0 != pCNd;
     258           0 :             const bool bValidNodesRange = bIsValidPos &&
     259           0 :                 ::CheckNodesRange( rPtIdx, aIdx, true );
     260           0 :             if( !bValidNodesRange )
     261             :             {
     262           0 :                 rPtIdx = pSavePos->nNode;
     263           0 :                 if( 0 == ( pCNd = rPtIdx.GetNode().GetCntntNode() ) )
     264             :                 {
     265           0 :                     bIsValidPos = false;
     266           0 :                     nCntntPos = 0;
     267           0 :                     rPtIdx = aIdx;
     268           0 :                     if( 0 == ( pCNd = rPtIdx.GetNode().GetCntntNode() ) )
     269             :                     {
     270             :                         // then to the beginning of the document
     271           0 :                         rPtIdx = rNds.GetEndOfExtras();
     272           0 :                         pCNd = rNds.GoNext( &rPtIdx );
     273             :                     }
     274             :                 }
     275             :             }
     276             : 
     277             :             // register ContentIndex:
     278           0 :             const sal_Int32 nTmpPos = bIsValidPos ? (bGoNxt ? 0 : pCNd->Len()) : nCntntPos;
     279           0 :             GetPoint()->nContent.Assign( pCNd, nTmpPos );
     280           0 :             if( !bIsValidPos || !bValidNodesRange ||
     281           0 :                 IsInProtectTable( sal_True ) )
     282           0 :                 return sal_True;
     283             :         }
     284             : 
     285             :         // is there a protected section in the section?
     286       30935 :         if( HasMark() && bSkipOverProtectSections)
     287             :         {
     288           0 :             sal_uLong nSttIdx = GetMark()->nNode.GetIndex(),
     289           0 :                 nEndIdx = GetPoint()->nNode.GetIndex();
     290           0 :             if( nEndIdx <= nSttIdx )
     291             :             {
     292           0 :                 sal_uLong nTmp = nSttIdx;
     293           0 :                 nSttIdx = nEndIdx;
     294           0 :                 nEndIdx = nTmp;
     295             :             }
     296             : 
     297           0 :             const SwSectionFmts& rFmts = pDoc->GetSections();
     298           0 :             for( sal_uInt16 n = 0; n < rFmts.size(); ++n )
     299             :             {
     300           0 :                 const SwSectionFmt* pFmt = rFmts[n];
     301           0 :                 const SvxProtectItem& rProtect = pFmt->GetProtect();
     302           0 :                 if( rProtect.IsCntntProtected() )
     303             :                 {
     304           0 :                     const SwFmtCntnt& rCntnt = pFmt->GetCntnt(sal_False);
     305             :                     OSL_ENSURE( rCntnt.GetCntntIdx(), "No SectionNode?" );
     306           0 :                     sal_uLong nIdx = rCntnt.GetCntntIdx()->GetIndex();
     307           0 :                     if( nSttIdx <= nIdx && nEndIdx >= nIdx )
     308             :                     {
     309             :                         // if it is no linked section then we cannot select it
     310           0 :                         const SwSection& rSect = *pFmt->GetSection();
     311           0 :                         if( CONTENT_SECTION == rSect.GetType() )
     312             :                         {
     313           0 :                             RestoreSavePos();
     314           0 :                             return sal_True;
     315             :                         }
     316             :                     }
     317             :                 }
     318             :             }
     319             :         }
     320             :     }
     321             : 
     322       43734 :     const SwNode* pNd = &GetPoint()->nNode.GetNode();
     323       43734 :     if( pNd->IsCntntNode() && !dynamic_cast<SwUnoCrsr*>(this) )
     324             :     {
     325         165 :         const SwCntntFrm* pFrm = ((SwCntntNode*)pNd)->getLayoutFrm( pDoc->GetCurrentLayout() );
     326         330 :         if( pFrm && pFrm->IsValid()
     327         145 :             && 0 == pFrm->Frm().Height()
     328         165 :             && 0 != ( nsSwCursorSelOverFlags::SELOVER_CHANGEPOS & eFlags ) )
     329             :         {
     330             :             // skip to the next/prev valid paragraph with a layout
     331           0 :             SwNodeIndex& rPtIdx = GetPoint()->nNode;
     332           0 :             bool bGoNxt = pSavePos->nNode < rPtIdx.GetIndex();
     333           0 :             while( 0 != ( pFrm = ( bGoNxt ? pFrm->GetNextCntntFrm() : pFrm->GetPrevCntntFrm() ))
     334           0 :                    && 0 == pFrm->Frm().Height() )
     335             :                 ;
     336             : 
     337             :             // #i72394# skip to prev/next valid paragraph with a layout in case
     338             :             // the first search did not succeed:
     339           0 :             if( !pFrm )
     340             :             {
     341           0 :                 bGoNxt = !bGoNxt;
     342           0 :                 pFrm = ((SwCntntNode*)pNd)->getLayoutFrm( pDoc->GetCurrentLayout() );
     343           0 :                 while ( pFrm && 0 == pFrm->Frm().Height() )
     344             :                 {
     345             :                     pFrm = bGoNxt ? pFrm->GetNextCntntFrm()
     346           0 :                         :   pFrm->GetPrevCntntFrm();
     347             :                 }
     348             :             }
     349             : 
     350           0 :             SwCntntNode* pCNd = (pFrm != NULL) ? (SwCntntNode*)pFrm->GetNode() : NULL;
     351           0 :             if ( pCNd != NULL )
     352             :             {
     353             :                 // set this CntntNode as new position
     354           0 :                 rPtIdx = *pCNd;
     355           0 :                 pNd = pCNd;
     356             : 
     357             :                 // assign corresponding ContentIndex
     358           0 :                 const sal_Int32 nTmpPos = bGoNxt ? 0 : pCNd->Len();
     359           0 :                 GetPoint()->nContent.Assign( pCNd, nTmpPos );
     360             : 
     361           0 :                 if ( rPtIdx.GetIndex() == pSavePos->nNode
     362           0 :                      && nTmpPos == pSavePos->nCntnt )
     363             :                 {
     364             :                     // new position equals saved one
     365             :                     // --> trigger restore of saved pos by setting <pFrm> to NULL - see below
     366           0 :                     pFrm = NULL;
     367             :                 }
     368             : 
     369           0 :                 if ( IsInProtectTable( sal_True ) )
     370             :                 {
     371             :                     // new position in protected table
     372             :                     // --> trigger restore of saved pos by setting <pFrm> to NULL - see below
     373           0 :                     pFrm = NULL;
     374             :                 }
     375             :             }
     376             :         }
     377             : 
     378         165 :         if( !pFrm )
     379             :         {
     380           0 :             DeleteMark();
     381           0 :             RestoreSavePos();
     382           0 :             return sal_True; // we need a frame
     383             :         }
     384             :     }
     385             : 
     386             :     // is the cursor allowed to be in a protected node?
     387       43734 :     if( 0 == ( nsSwCursorSelOverFlags::SELOVER_CHANGEPOS & eFlags ) && !IsAtValidPos() )
     388             :     {
     389           0 :         DeleteMark();
     390           0 :         RestoreSavePos();
     391           0 :         return sal_True;
     392             :     }
     393             : 
     394       43734 :     if( !HasMark() )
     395       11516 :         return sal_False;
     396             : 
     397             :     // check for invalid sections
     398       32218 :     if( !::CheckNodesRange( GetMark()->nNode, GetPoint()->nNode, true ))
     399             :     {
     400           0 :         DeleteMark();
     401           0 :         RestoreSavePos();
     402           0 :         return sal_True; // we need a frame
     403             :     }
     404             : 
     405       96654 :     if( (pNd = &GetMark()->nNode.GetNode())->IsCntntNode()
     406       32218 :         && !((SwCntntNode*)pNd)->getLayoutFrm( pDoc->GetCurrentLayout() )
     407       92367 :         && !dynamic_cast<SwUnoCrsr*>(this) )
     408             :     {
     409           0 :         DeleteMark();
     410           0 :         RestoreSavePos();
     411           0 :         return sal_True; // we need a frame
     412             :     }
     413             : 
     414             :     // assure that selection is only inside an InputField or contains the InputField completely
     415             :     {
     416       32218 :         const SwTxtAttr* pInputFldTxtAttrAtPoint = NULL;
     417       32218 :         SwTxtNode* pTxtNdAtPoint = GetPoint()->nNode.GetNode().GetTxtNode();
     418       32218 :         if ( pTxtNdAtPoint != NULL )
     419             :         {
     420             :             pInputFldTxtAttrAtPoint =
     421       32218 :                 pTxtNdAtPoint->GetTxtAttrAt( GetPoint()->nContent.GetIndex(), RES_TXTATR_INPUTFIELD, SwTxtNode::PARENT );
     422             :         }
     423             : 
     424       32218 :         const SwTxtAttr* pInputFldTxtAttrAtMark = NULL;
     425       32218 :         SwTxtNode* pTxtNdAtMark = GetMark()->nNode.GetNode().GetTxtNode();
     426       32218 :         if ( pTxtNdAtMark != NULL )
     427             :         {
     428             :             pInputFldTxtAttrAtMark =
     429       32218 :                 pTxtNdAtMark->GetTxtAttrAt( GetMark()->nContent.GetIndex(), RES_TXTATR_INPUTFIELD, SwTxtNode::PARENT );
     430             :         }
     431             : 
     432       32218 :         if ( pInputFldTxtAttrAtPoint != pInputFldTxtAttrAtMark )
     433             :         {
     434             :             const sal_uLong nRefNodeIdx =
     435           0 :                 ( nsSwCursorSelOverFlags::SELOVER_TOGGLE & eFlags )
     436             :                 ? pSavePos->nNode
     437           0 :                 : GetMark()->nNode.GetIndex();
     438             :             const sal_Int32 nRefContentIdx =
     439           0 :                 ( nsSwCursorSelOverFlags::SELOVER_TOGGLE & eFlags )
     440             :                 ? pSavePos->nCntnt
     441           0 :                 : GetMark()->nContent.GetIndex();
     442             :             const bool bIsForwardSelection =
     443           0 :                 nRefNodeIdx < GetPoint()->nNode.GetIndex()
     444           0 :                 || ( nRefNodeIdx == GetPoint()->nNode.GetIndex()
     445           0 :                      && nRefContentIdx < GetPoint()->nContent.GetIndex() );
     446             : 
     447           0 :             if ( pInputFldTxtAttrAtPoint != NULL )
     448             :             {
     449             :                 const sal_Int32 nNewPointPos =
     450           0 :                     bIsForwardSelection ? *(pInputFldTxtAttrAtPoint->End()) : *(pInputFldTxtAttrAtPoint->GetStart());
     451           0 :                 GetPoint()->nContent.Assign( pTxtNdAtPoint, nNewPointPos );
     452             :             }
     453             : 
     454           0 :             if ( pInputFldTxtAttrAtMark != NULL )
     455             :             {
     456             :                 const sal_Int32 nNewMarkPos =
     457           0 :                     bIsForwardSelection ? *(pInputFldTxtAttrAtMark->GetStart()) : *(pInputFldTxtAttrAtMark->End());
     458           0 :                 GetMark()->nContent.Assign( pTxtNdAtMark, nNewMarkPos );
     459             :             }
     460             :         }
     461             :     }
     462             : 
     463       32218 :     const SwTableNode* pPtNd = GetPoint()->nNode.GetNode().FindTableNode();
     464       32218 :     const SwTableNode* pMrkNd = GetMark()->nNode.GetNode().FindTableNode();
     465             :     // both in no or in same table node
     466       32218 :     if( ( !pMrkNd && !pPtNd ) || pPtNd == pMrkNd )
     467       32218 :         return sal_False;
     468             : 
     469             :     // in different tables or only mark in table
     470           0 :     if( ( pPtNd && pMrkNd ) || pMrkNd )
     471             :     {
     472             :         // not allowed, so go back to old position
     473           0 :         RestoreSavePos();
     474             :         // Crsr stays at old position
     475           0 :         return sal_True;
     476             :     }
     477             : 
     478             :     // Note: this cannot happen in TableMode
     479           0 :     if( pPtNd )     // if only Point in Table then go behind/in front of table
     480             :     {
     481           0 :         if( nsSwCursorSelOverFlags::SELOVER_CHANGEPOS & eFlags )
     482             :         {
     483           0 :             sal_Bool bSelTop = GetPoint()->nNode.GetIndex() <
     484           0 :                 (( nsSwCursorSelOverFlags::SELOVER_TOGGLE & eFlags ) ? pSavePos->nNode
     485           0 :                 : GetMark()->nNode.GetIndex());
     486             : 
     487             :             do { // loop for table after table
     488           0 :                 sal_uLong nSEIdx = pPtNd->EndOfSectionIndex();
     489           0 :                 sal_uLong nSttEndTbl = nSEIdx + 1;
     490             : 
     491           0 :                 if( bSelTop )
     492           0 :                     nSttEndTbl = rNds[ nSEIdx ]->StartOfSectionIndex() - 1;
     493             : 
     494           0 :                 GetPoint()->nNode = nSttEndTbl;
     495           0 :                 const SwNode* pMyNd = GetNode();
     496             : 
     497           0 :                 if( pMyNd->IsSectionNode() || ( pMyNd->IsEndNode() &&
     498           0 :                     pMyNd->StartOfSectionNode()->IsSectionNode() ) )
     499             :                 {
     500           0 :                     pMyNd = bSelTop
     501           0 :                         ? rNds.GoPrevSection( &GetPoint()->nNode,true,false )
     502           0 :                         : rNds.GoNextSection( &GetPoint()->nNode,true,false );
     503             : 
     504             :                     /* #i12312# Handle failure of Go{Prev|Next}Section */
     505           0 :                     if ( 0 == pMyNd)
     506           0 :                         break;
     507             : 
     508           0 :                     if( 0 != ( pPtNd = pMyNd->FindTableNode() ))
     509           0 :                         continue;
     510             :                 }
     511             : 
     512             :                 // we permit these
     513           0 :                 if( pMyNd->IsCntntNode() &&
     514           0 :                     ::CheckNodesRange( GetMark()->nNode,
     515           0 :                     GetPoint()->nNode, true ))
     516             :                 {
     517             :                     // table in table
     518           0 :                     const SwTableNode* pOuterTableNd = pMyNd->FindTableNode();
     519           0 :                     if ( pOuterTableNd )
     520           0 :                         pMyNd = pOuterTableNd;
     521             :                     else
     522             :                     {
     523           0 :                         SwCntntNode* pCNd = (SwCntntNode*)pMyNd;
     524           0 :                         GetPoint()->nContent.Assign( pCNd, bSelTop ? pCNd->Len() : 0 );
     525           0 :                         return sal_False;
     526             :                     }
     527             :                 }
     528           0 :                 if( bSelTop
     529           0 :                     ? ( !pMyNd->IsEndNode() || 0 == ( pPtNd = pMyNd->FindTableNode() ))
     530             :                     : 0 == ( pPtNd = pMyNd->GetTableNode() ))
     531           0 :                     break;
     532           0 :             } while( true );
     533             :         }
     534             : 
     535             :         // stay on old position
     536           0 :         RestoreSavePos();
     537           0 :         return sal_True;
     538             :     }
     539             : 
     540           0 :     return sal_False;
     541             : }
     542             : 
     543       43972 : sal_Bool SwCursor::IsInProtectTable( sal_Bool bMove, sal_Bool bChgCrsr )
     544             : {
     545       43972 :     SwCntntNode* pCNd = GetCntntNode();
     546       43972 :     if( !pCNd )
     547           0 :         return sal_False;
     548             : 
     549             :     // No table, no protected cell:
     550       43972 :     const SwTableNode* pTableNode = pCNd->FindTableNode();
     551       43972 :     if ( !pTableNode )
     552       34810 :         return sal_False;
     553             : 
     554             :     // Current position == last save position?
     555        9162 :     if ( pSavePos->nNode == GetPoint()->nNode.GetIndex() )
     556        6551 :         return sal_False;
     557             : 
     558             :     // Check for convered cell:
     559        2611 :     bool bInCoveredCell = false;
     560        2611 :     const SwStartNode* pTmpSttNode = pCNd->FindTableBoxStartNode();
     561             :     OSL_ENSURE( pTmpSttNode, "In table, therefore I expect to get a SwTableBoxStartNode" );
     562        2611 :     const SwTableBox* pBox = pTmpSttNode ? pTableNode->GetTable().GetTblBox( pTmpSttNode->GetIndex() ) : 0; //Robust #151355
     563        2611 :     if ( pBox && pBox->getRowSpan() < 1 ) // Robust #151270
     564          13 :         bInCoveredCell = true;
     565             : 
     566             :     // Positions of covered cells are not acceptable:
     567        2611 :     if ( !bInCoveredCell )
     568             :     {
     569             :         // Position not protected?
     570        2598 :         if ( !pCNd->IsProtect() )
     571        2598 :             return sal_False;
     572             : 
     573             :         // Cursor in protected cells allowed?
     574           0 :         if ( IsReadOnlyAvailable() )
     575           0 :             return sal_False;
     576             :     }
     577             : 
     578             :     // If we reach this point, we are in a protected or covered table cell!
     579             : 
     580          13 :     if( !bMove )
     581             :     {
     582           0 :         if( bChgCrsr )
     583             :             // restore the last save position
     584           0 :             RestoreSavePos();
     585             : 
     586           0 :         return sal_True; // Crsr stays at old position
     587             :     }
     588             : 
     589             :     // We are in a protected table cell. Traverse top to bottom?
     590          13 :     if( pSavePos->nNode < GetPoint()->nNode.GetIndex() )
     591             :     {
     592             :         // search next valid box
     593             :         // if there is another StartNode after the EndNode of a cell then
     594             :         // there is another cell
     595          13 :         SwNodeIndex aCellStt( *GetNode()->FindTableBoxStartNode()->EndOfSectionNode(), 1 );
     596          13 :         bool bProt = true;
     597             : GoNextCell:
     598           0 :         do {
     599          13 :             if( !aCellStt.GetNode().IsStartNode() )
     600           5 :                 break;
     601           8 :             ++aCellStt;
     602           8 :             if( 0 == ( pCNd = aCellStt.GetNode().GetCntntNode() ))
     603           0 :                 pCNd = aCellStt.GetNodes().GoNext( &aCellStt );
     604           8 :             if( !( bProt = pCNd->IsProtect() ))
     605           8 :                 break;
     606           0 :             aCellStt.Assign( *pCNd->FindTableBoxStartNode()->EndOfSectionNode(), 1 );
     607             :         } while( bProt );
     608             : 
     609             : SetNextCrsr:
     610          18 :         if( !bProt ) // found free cell
     611             :         {
     612          13 :             GetPoint()->nNode = aCellStt;
     613          13 :             SwCntntNode* pTmpCNd = GetCntntNode();
     614          13 :             if( pTmpCNd )
     615             :             {
     616          13 :                 GetPoint()->nContent.Assign( pTmpCNd, 0 );
     617          13 :                 return sal_False;
     618             :             }
     619             :             return IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE |
     620           0 :                              nsSwCursorSelOverFlags::SELOVER_CHANGEPOS );
     621             :         }
     622             :         // end of table, so go to next node
     623           5 :         ++aCellStt;
     624             :         SwNode* pNd;
     625           5 :         if( ( pNd = &aCellStt.GetNode())->IsEndNode() || HasMark())
     626             :         {
     627             :             // if only table in FlyFrame or SSelection then stay on old position
     628           0 :             if( bChgCrsr )
     629           0 :                 RestoreSavePos();
     630           0 :             return sal_True;
     631             :         }
     632           5 :         else if( pNd->IsTableNode() && aCellStt++ )
     633           0 :             goto GoNextCell;
     634             : 
     635           5 :         bProt = false; // index is now on a content node
     636           5 :         goto SetNextCrsr;
     637             :     }
     638             : 
     639             :     // search for the previous valid box
     640             :     {
     641             :         // if there is another EndNode in front of the StartNode than there
     642             :         // exists a previous cell
     643           0 :         SwNodeIndex aCellStt( *GetNode()->FindTableBoxStartNode(), -1 );
     644             :         SwNode* pNd;
     645           0 :         bool bProt = true;
     646             : GoPrevCell:
     647           0 :         do {
     648           0 :             if( !( pNd = &aCellStt.GetNode())->IsEndNode() )
     649           0 :                 break;
     650           0 :             aCellStt.Assign( *pNd->StartOfSectionNode(), +1 );
     651           0 :             if( 0 == ( pCNd = aCellStt.GetNode().GetCntntNode() ))
     652           0 :                 pCNd = pNd->GetNodes().GoNext( &aCellStt );
     653           0 :             if( !( bProt = pCNd->IsProtect() ))
     654           0 :                 break;
     655           0 :             aCellStt.Assign( *pNd->FindTableBoxStartNode(), -1 );
     656             :         } while( bProt );
     657             : 
     658             : SetPrevCrsr:
     659           0 :         if( !bProt ) // found free cell
     660             :         {
     661           0 :             GetPoint()->nNode = aCellStt;
     662           0 :             SwCntntNode* pTmpCNd = GetCntntNode();
     663           0 :             if( pTmpCNd )
     664             :             {
     665           0 :                 GetPoint()->nContent.Assign( pTmpCNd, 0 );
     666           0 :                 return sal_False;
     667             :             }
     668             :             return IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE |
     669           0 :                              nsSwCursorSelOverFlags::SELOVER_CHANGEPOS );
     670             :         }
     671             :         // at the beginning of a table, so go to next node
     672           0 :         aCellStt--;
     673           0 :         if( ( pNd = &aCellStt.GetNode())->IsStartNode() || HasMark() )
     674             :         {
     675             :             // if only table in FlyFrame or SSelection then stay on old position
     676           0 :             if( bChgCrsr )
     677           0 :                 RestoreSavePos();
     678           0 :             return sal_True;
     679             :         }
     680           0 :         else if( pNd->StartOfSectionNode()->IsTableNode() && aCellStt-- )
     681           0 :             goto GoPrevCell;
     682             : 
     683           0 :         bProt = false; // index is now on a content node
     684           0 :         goto SetPrevCrsr;
     685             :     }
     686             : }
     687             : 
     688             : /// Return <true> if cursor can be set to this position
     689          23 : bool SwCursor::IsAtValidPos( bool bPoint ) const
     690             : {
     691          23 :     const SwDoc* pDoc = GetDoc();
     692          23 :     const SwPosition* pPos = bPoint ? GetPoint() : GetMark();
     693          23 :     const SwNode* pNd = &pPos->nNode.GetNode();
     694             : 
     695          23 :     if( pNd->IsCntntNode() && !((SwCntntNode*)pNd)->getLayoutFrm( pDoc->GetCurrentLayout() ) &&
     696           0 :         !dynamic_cast<const SwUnoCrsr*>(this) )
     697             :     {
     698           0 :         return false;
     699             :     }
     700             : 
     701             :     // #i45129# - in UI-ReadOnly everything is allowed
     702          23 :     if( !pDoc->GetDocShell() || !pDoc->GetDocShell()->IsReadOnlyUI() )
     703          23 :         return true;
     704             : 
     705           0 :     const bool bCrsrInReadOnly = IsReadOnlyAvailable();
     706           0 :     if( !bCrsrInReadOnly && pNd->IsProtect() )
     707           0 :         return false;
     708             : 
     709           0 :     const SwSectionNode* pSectNd = pNd->FindSectionNode();
     710           0 :     if( pSectNd && (pSectNd->GetSection().IsHiddenFlag() ||
     711           0 :                     ( !bCrsrInReadOnly && pSectNd->GetSection().IsProtectFlag() )))
     712           0 :         return false;
     713             : 
     714           0 :     return true;
     715             : }
     716             : 
     717          44 : void SwCursor::SaveTblBoxCntnt( const SwPosition* ) {}
     718             : 
     719             : /// set range for search in document
     720           9 : SwMoveFnCollection* SwCursor::MakeFindRange( SwDocPositions nStart,
     721             :                                 SwDocPositions nEnd, SwPaM* pRange ) const
     722             : {
     723           9 :     pRange->SetMark();
     724           9 :     FillFindPos( nStart, *pRange->GetMark() );
     725           9 :     FillFindPos( nEnd, *pRange->GetPoint() );
     726             : 
     727             :     // determine direction of search
     728           5 :     return ( DOCPOS_START == nStart || DOCPOS_OTHERSTART == nStart ||
     729           5 :               (DOCPOS_CURR == nStart &&
     730           0 :                 (DOCPOS_END == nEnd || DOCPOS_OTHEREND == nEnd ) ))
     731          18 :                 ? fnMoveForward : fnMoveBackward;
     732             : }
     733             : 
     734           5 : static sal_uLong lcl_FindSelection( SwFindParas& rParas, SwCursor* pCurCrsr,
     735             :                         SwMoveFn fnMove, SwCursor*& pFndRing,
     736             :                         SwPaM& aRegion, FindRanges eFndRngs,
     737             :                         sal_Bool bInReadOnly, sal_Bool& bCancel )
     738             : {
     739           5 :     SwDoc* pDoc = pCurCrsr->GetDoc();
     740           5 :     bool const bDoesUndo = pDoc->GetIDocumentUndoRedo().DoesUndo();
     741           5 :     int nFndRet = 0;
     742           5 :     sal_uLong nFound = 0;
     743           5 :     const bool bSrchBkwrd = fnMove == fnMoveBackward;
     744           5 :     SwPaM *pTmpCrsr = pCurCrsr, *pSaveCrsr = pCurCrsr;
     745             : 
     746             :     // only create progress bar for ShellCrsr
     747           5 :     bool bIsUnoCrsr = 0 != dynamic_cast<SwUnoCrsr*>(pCurCrsr);
     748           5 :     _PercentHdl* pPHdl = 0;
     749           5 :     sal_uInt16 nCrsrCnt = 0;
     750           5 :     if( FND_IN_SEL & eFndRngs )
     751             :     {
     752           0 :         while( pCurCrsr != ( pTmpCrsr = (SwPaM*)pTmpCrsr->GetNext() ))
     753           0 :             ++nCrsrCnt;
     754           0 :         if( nCrsrCnt && !bIsUnoCrsr )
     755           0 :             pPHdl = new _PercentHdl( 0, nCrsrCnt, pDoc->GetDocShell() );
     756             :     }
     757             :     else
     758           5 :         pSaveCrsr = (SwPaM*)pSaveCrsr->GetPrev();
     759             : 
     760           5 :     bool bEnd = false;
     761           4 :     do {
     762           5 :         aRegion.SetMark();
     763             :         // independent from search direction: SPoint is always bigger than mark
     764             :         // if the search area is valid
     765           5 :         SwPosition *pSttPos = aRegion.GetMark(),
     766           5 :                         *pEndPos = aRegion.GetPoint();
     767           5 :         *pSttPos = *pTmpCrsr->Start();
     768           5 :         *pEndPos = *pTmpCrsr->End();
     769           5 :         if( bSrchBkwrd )
     770           0 :             aRegion.Exchange();
     771             : 
     772           5 :         if( !nCrsrCnt && !pPHdl && !bIsUnoCrsr )
     773           0 :             pPHdl = new _PercentHdl( aRegion );
     774             : 
     775             :         // as long as found and not at same position
     776         263 :         while(  *pSttPos <= *pEndPos &&
     777             :                 0 != ( nFndRet = rParas.Find( pCurCrsr, fnMove,
     778         248 :                                             &aRegion, bInReadOnly )) &&
     779         116 :                 ( !pFndRing ||
     780          35 :                     *pFndRing->GetPoint() != *pCurCrsr->GetPoint() ||
     781           0 :                     *pFndRing->GetMark() != *pCurCrsr->GetMark() ))
     782             :         {
     783          81 :             if( !( FIND_NO_RING & nFndRet ))
     784             :             {
     785             :                 // #i24084# - create ring similar to the one in CreateCrsr
     786          37 :                 SwCursor* pNew = pCurCrsr->Create( pFndRing );
     787          37 :                 if( !pFndRing )
     788           2 :                     pFndRing = pNew;
     789             : 
     790          37 :                 pNew->SetMark();
     791          37 :                 *pNew->GetMark() = *pCurCrsr->GetMark();
     792             :             }
     793             : 
     794          81 :             ++nFound;
     795             : 
     796          81 :             if( !( eFndRngs & FND_IN_SELALL) )
     797             :             {
     798           0 :                 bEnd = true;
     799           0 :                 break;
     800             :             }
     801             : 
     802          81 :             if ((coSrchRplcThreshold == nFound)
     803           0 :                 && pDoc->GetIDocumentUndoRedo().DoesUndo()
     804          81 :                 && rParas.IsReplaceMode())
     805             :             {
     806           0 :                 short nRet = pCurCrsr->MaxReplaceArived();
     807           0 :                 if( RET_YES == nRet )
     808             :                 {
     809           0 :                     pDoc->GetIDocumentUndoRedo().DelAllUndoObj();
     810           0 :                     pDoc->GetIDocumentUndoRedo().DoUndo(false);
     811             :                 }
     812             :                 else
     813             :                 {
     814           0 :                     bEnd = true;
     815           0 :                     if(RET_CANCEL == nRet)
     816             :                     {
     817           0 :                         bCancel = sal_True;
     818             :                     }
     819           0 :                     break;
     820             :                 }
     821             :             }
     822             : 
     823          81 :             if( bSrchBkwrd )
     824             :                 // move pEndPos in front of the found area
     825           0 :                 *pEndPos = *pCurCrsr->Start();
     826             :             else
     827             :                 // move pSttPos behind the found area
     828          81 :                 *pSttPos = *pCurCrsr->End();
     829             : 
     830          81 :             if( *pSttPos == *pEndPos )
     831             :                 // in area but at the end => done
     832           0 :                 break;
     833             : 
     834          81 :             if( !nCrsrCnt && pPHdl )
     835             :             {
     836           0 :                 pPHdl->NextPos( *aRegion.GetMark() );
     837             :             }
     838             :         }
     839             : 
     840           5 :         if( bEnd || !( eFndRngs & ( FND_IN_SELALL | FND_IN_SEL )) )
     841             :             break;
     842             : 
     843           4 :         pTmpCrsr = ((SwPaM*)pTmpCrsr->GetNext());
     844           4 :         if( nCrsrCnt && pPHdl )
     845             :         {
     846           0 :             pPHdl->NextPos( ++pPHdl->nActPos );
     847             :         }
     848             : 
     849             :     } while( pTmpCrsr != pSaveCrsr );
     850             : 
     851           5 :     if( nFound && !pFndRing ) // if no ring should be created
     852           2 :         pFndRing = pCurCrsr->Create();
     853             : 
     854           5 :     delete pPHdl;
     855           5 :     pDoc->GetIDocumentUndoRedo().DoUndo(bDoesUndo);
     856           5 :     return nFound;
     857             : }
     858             : 
     859           5 : static bool lcl_MakeSelFwrd( const SwNode& rSttNd, const SwNode& rEndNd,
     860             :                         SwPaM& rPam, bool bFirst )
     861             : {
     862           5 :     if( rSttNd.GetIndex() + 1 == rEndNd.GetIndex() )
     863           0 :         return false;
     864             : 
     865           5 :     SwNodes& rNds = rPam.GetDoc()->GetNodes();
     866           5 :     rPam.DeleteMark();
     867             :     SwCntntNode* pCNd;
     868           5 :     if( !bFirst )
     869             :     {
     870           5 :         rPam.GetPoint()->nNode = rSttNd;
     871           5 :         pCNd = rNds.GoNext( &rPam.GetPoint()->nNode );
     872           5 :         if( !pCNd )
     873           0 :             return false;
     874           5 :         pCNd->MakeStartIndex( &rPam.GetPoint()->nContent );
     875             :     }
     876           0 :     else if( rSttNd.GetIndex() > rPam.GetPoint()->nNode.GetIndex() ||
     877           0 :              rPam.GetPoint()->nNode.GetIndex() >= rEndNd.GetIndex() )
     878             :         // not in this section
     879           0 :         return false;
     880             : 
     881           5 :     rPam.SetMark();
     882           5 :     rPam.GetPoint()->nNode = rEndNd;
     883           5 :     pCNd = rNds.GoPrevious( &rPam.GetPoint()->nNode );
     884           5 :     if( !pCNd )
     885           0 :         return false;
     886           5 :     pCNd->MakeEndIndex( &rPam.GetPoint()->nContent );
     887             : 
     888           5 :     return *rPam.GetMark() < *rPam.GetPoint();
     889             : }
     890             : 
     891           0 : static bool lcl_MakeSelBkwrd( const SwNode& rSttNd, const SwNode& rEndNd,
     892             :                         SwPaM& rPam, bool bFirst )
     893             : {
     894           0 :     if( rEndNd.GetIndex() + 1 == rSttNd.GetIndex() )
     895           0 :         return false;
     896             : 
     897           0 :     SwNodes& rNds = rPam.GetDoc()->GetNodes();
     898           0 :     rPam.DeleteMark();
     899             :     SwCntntNode* pCNd;
     900           0 :     if( !bFirst )
     901             :     {
     902           0 :         rPam.GetPoint()->nNode = rSttNd;
     903           0 :         pCNd = rNds.GoPrevious( &rPam.GetPoint()->nNode );
     904           0 :         if( !pCNd )
     905           0 :             return false;
     906           0 :         pCNd->MakeEndIndex( &rPam.GetPoint()->nContent );
     907             :     }
     908           0 :     else if( rEndNd.GetIndex() > rPam.GetPoint()->nNode.GetIndex() ||
     909           0 :              rPam.GetPoint()->nNode.GetIndex() >= rSttNd.GetIndex() )
     910           0 :         return false;       // not in this section
     911             : 
     912           0 :     rPam.SetMark();
     913           0 :     rPam.GetPoint()->nNode = rEndNd;
     914           0 :     pCNd = rNds.GoNext( &rPam.GetPoint()->nNode );
     915           0 :     if( !pCNd )
     916           0 :         return false;
     917           0 :     pCNd->MakeStartIndex( &rPam.GetPoint()->nContent );
     918             : 
     919           0 :     return *rPam.GetPoint() < *rPam.GetMark();
     920             : }
     921             : 
     922             : // this method "searches" for all use cases because in SwFindParas is always the
     923             : // correct parameters and respective search method
     924           9 : sal_uLong SwCursor::FindAll( SwFindParas& rParas,
     925             :                             SwDocPositions nStart, SwDocPositions nEnde,
     926             :                             FindRanges eFndRngs, sal_Bool& bCancel )
     927             : {
     928           9 :     bCancel = sal_False;
     929           9 :     SwCrsrSaveState aSaveState( *this );
     930             : 
     931             :     // create region without adding it to the ring
     932          18 :     SwPaM aRegion( *GetPoint() );
     933           9 :     SwMoveFn fnMove = MakeFindRange( nStart, nEnde, &aRegion );
     934             : 
     935           9 :     sal_uLong nFound = 0;
     936           9 :     const bool bMvBkwrd = fnMove == fnMoveBackward;
     937           9 :     sal_Bool bInReadOnly = IsReadOnlyAvailable();
     938             : 
     939           9 :     SwCursor* pFndRing = 0;
     940           9 :     SwNodes& rNds = GetDoc()->GetNodes();
     941             : 
     942             :     // search in sections?
     943           9 :     if( FND_IN_SEL & eFndRngs )
     944             :     {
     945             :         // if string was not found in region then get all sections (cursors
     946             :         // stays unchanged)
     947           0 :         if( 0 == ( nFound = lcl_FindSelection( rParas, this, fnMove,
     948             :                                                 pFndRing, aRegion, eFndRngs,
     949           0 :                                                 bInReadOnly, bCancel ) ))
     950           0 :             return nFound;
     951             : 
     952             :         // found string at least once; it's all in new Crsr ring thus delete old one
     953           0 :         while( GetNext() != this )
     954           0 :             delete GetNext();
     955             : 
     956           0 :         *GetPoint() = *pFndRing->GetPoint();
     957           0 :         SetMark();
     958           0 :         *GetMark() = *pFndRing->GetMark();
     959           0 :         pFndRing->MoveRingTo( this );
     960           0 :         delete pFndRing;
     961             :     }
     962           9 :     else if( FND_IN_OTHER & eFndRngs )
     963             :     {
     964             :         // put cursor as copy of current into ring
     965             :         // chaining points always to first created, so forward
     966             :         SAL_WNODEPRECATED_DECLARATIONS_PUSH
     967           1 :         std::auto_ptr< SwCursor > pSav( Create( this ) ); // save the current cursor
     968             :         SAL_WNODEPRECATED_DECLARATIONS_POP
     969             : 
     970             :         // if already outside of body text search from this position or start at
     971             :         // 1. base section
     972           2 :         if( bMvBkwrd
     973           0 :             ? lcl_MakeSelBkwrd( rNds.GetEndOfExtras(),
     974           0 :                     *rNds.GetEndOfPostIts().StartOfSectionNode(),
     975           0 :                      *this, rNds.GetEndOfExtras().GetIndex() >=
     976           0 :                     GetPoint()->nNode.GetIndex() )
     977           1 :             : lcl_MakeSelFwrd( *rNds.GetEndOfPostIts().StartOfSectionNode(),
     978           1 :                     rNds.GetEndOfExtras(), *this,
     979           1 :                     rNds.GetEndOfExtras().GetIndex() >=
     980           2 :                     GetPoint()->nNode.GetIndex() ))
     981             :         {
     982             :             nFound = lcl_FindSelection( rParas, this, fnMove, pFndRing,
     983           1 :                                         aRegion, eFndRngs, bInReadOnly, bCancel );
     984             :         }
     985             : 
     986           1 :         if( !nFound )
     987             :         {
     988             :             // put back the old one
     989           1 :             *GetPoint() = *pSav->GetPoint();
     990           1 :             if( pSav->HasMark() )
     991             :             {
     992           0 :                 SetMark();
     993           0 :                 *GetMark() = *pSav->GetMark();
     994             :             }
     995             :             else
     996           1 :                 DeleteMark();
     997           1 :             return 0;
     998             :         }
     999           0 :         pSav.release();
    1000             : 
    1001           0 :         if( !( FND_IN_SELALL & eFndRngs ))
    1002             :         {
    1003             :             // there should only be a single one, thus add it
    1004             :             // independent from search direction: SPoint is always bigger than
    1005             :             // mark if the search area is valid
    1006           0 :             *GetPoint() = *pFndRing->GetPoint();
    1007           0 :             SetMark();
    1008           0 :             *GetMark() = *pFndRing->GetMark();
    1009             :         }
    1010             :         else
    1011             :         {
    1012             :             // found string at least once; it's all in new Crsr ring thus delete old one
    1013           0 :             while( GetNext() != this )
    1014           0 :                 delete GetNext();
    1015             : 
    1016           0 :             *GetPoint() = *pFndRing->GetPoint();
    1017           0 :             SetMark();
    1018           0 :             *GetMark() = *pFndRing->GetMark();
    1019           0 :             pFndRing->MoveRingTo( this );
    1020             :         }
    1021           0 :         delete pFndRing;
    1022             :     }
    1023           8 :     else if( FND_IN_SELALL & eFndRngs )
    1024             :     {
    1025             :         SAL_WNODEPRECATED_DECLARATIONS_PUSH
    1026           4 :         ::std::auto_ptr< SwCursor> pSav( Create( this ) );  // save the current cursor
    1027             :         SAL_WNODEPRECATED_DECLARATIONS_POP
    1028             : 
    1029           4 :         const SwNode* pSttNd = ( FND_IN_BODYONLY & eFndRngs )
    1030           0 :                             ? rNds.GetEndOfContent().StartOfSectionNode()
    1031           4 :                             : rNds.GetEndOfPostIts().StartOfSectionNode();
    1032             : 
    1033           8 :         if( bMvBkwrd
    1034           0 :             ? lcl_MakeSelBkwrd( rNds.GetEndOfContent(), *pSttNd, *this, false )
    1035           4 :             : lcl_MakeSelFwrd( *pSttNd, rNds.GetEndOfContent(), *this, false ))
    1036             :         {
    1037             :             nFound = lcl_FindSelection( rParas, this, fnMove, pFndRing,
    1038           4 :                                         aRegion, eFndRngs, bInReadOnly, bCancel );
    1039             :         }
    1040             : 
    1041           4 :         if( !nFound )
    1042             :         {
    1043             :             // put back the old one
    1044           0 :             *GetPoint() = *pSav->GetPoint();
    1045           0 :             if( pSav->HasMark() )
    1046             :             {
    1047           0 :                 SetMark();
    1048           0 :                 *GetMark() = *pSav->GetMark();
    1049             :             }
    1050             :             else
    1051           0 :                 DeleteMark();
    1052           0 :             return 0;
    1053             :         }
    1054           4 :         pSav.release();
    1055          12 :         while( GetNext() != this )
    1056           4 :             delete GetNext();
    1057             : 
    1058           4 :         *GetPoint() = *pFndRing->GetPoint();
    1059           4 :         SetMark();
    1060           4 :         *GetMark() = *pFndRing->GetMark();
    1061           4 :         pFndRing->MoveRingTo( this );
    1062           4 :         delete pFndRing;
    1063             :     }
    1064             :     else
    1065             :     {
    1066             :         // if a GetMark is set then keep the GetMark of the found object
    1067             :         // This allows spanning an area with this search.
    1068           4 :         SwPosition aMarkPos( *GetMark() );
    1069           4 :         const bool bMarkPos = HasMark() && !eFndRngs;
    1070             : 
    1071           8 :         if( 0 != (nFound = rParas.Find( this, fnMove,
    1072           4 :                                         &aRegion, bInReadOnly ) ? 1 : 0)
    1073           4 :             && bMarkPos )
    1074           0 :             *GetMark() = aMarkPos;
    1075             :     }
    1076             : 
    1077           8 :     if( nFound && SwCursor::IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE ) )
    1078           0 :         nFound = 0;
    1079          17 :     return nFound;
    1080             : }
    1081             : 
    1082          18 : void SwCursor::FillFindPos( SwDocPositions ePos, SwPosition& rPos ) const
    1083             : {
    1084          18 :     bool bIsStart = true;
    1085          18 :     SwCntntNode* pCNd = 0;
    1086          18 :     SwNodes& rNds = GetDoc()->GetNodes();
    1087             : 
    1088          18 :     switch( ePos )
    1089             :     {
    1090             :     case DOCPOS_START:
    1091           4 :         rPos.nNode = *rNds.GetEndOfContent().StartOfSectionNode();
    1092           4 :         pCNd = rNds.GoNext( &rPos.nNode );
    1093           4 :         break;
    1094             :     case DOCPOS_END:
    1095           9 :         rPos.nNode = rNds.GetEndOfContent();
    1096           9 :         pCNd = rNds.GoPrevious( &rPos.nNode );
    1097           9 :         bIsStart = false;
    1098           9 :         break;
    1099             :     case DOCPOS_OTHERSTART:
    1100           0 :         rPos.nNode = *rNds[ sal_uLong(0) ];
    1101           0 :         pCNd = rNds.GoNext( &rPos.nNode );
    1102           0 :         break;
    1103             :     case DOCPOS_OTHEREND:
    1104           0 :         rPos.nNode = *rNds.GetEndOfContent().StartOfSectionNode();
    1105           0 :         pCNd = rNds.GoPrevious( &rPos.nNode );
    1106           0 :         bIsStart = false;
    1107           0 :         break;
    1108             :     default:
    1109           5 :         rPos = *GetPoint();
    1110             :     }
    1111             : 
    1112          18 :     if( pCNd )
    1113             :     {
    1114          13 :         rPos.nContent.Assign( pCNd, bIsStart ? 0 : pCNd->Len() );
    1115             :     }
    1116          18 : }
    1117             : 
    1118           0 : short SwCursor::MaxReplaceArived()
    1119             : {
    1120           0 :     return RET_YES;
    1121             : }
    1122             : 
    1123           5 : sal_Bool SwCursor::IsStartWord( sal_Int16 nWordType ) const
    1124             : {
    1125           5 :     return IsStartWordWT( nWordType );
    1126             : }
    1127             : 
    1128           0 : sal_Bool SwCursor::IsEndWord( sal_Int16 nWordType ) const
    1129             : {
    1130           0 :     return IsEndWordWT( nWordType );
    1131             : }
    1132             : 
    1133           0 : sal_Bool SwCursor::IsInWord( sal_Int16 nWordType ) const
    1134             : {
    1135           0 :     return IsInWordWT( nWordType );
    1136             : }
    1137             : 
    1138           0 : sal_Bool SwCursor::GoStartWord()
    1139             : {
    1140           0 :     return GoStartWordWT( WordType::ANYWORD_IGNOREWHITESPACES );
    1141             : }
    1142             : 
    1143           0 : sal_Bool SwCursor::GoEndWord()
    1144             : {
    1145           0 :     return GoEndWordWT( WordType::ANYWORD_IGNOREWHITESPACES );
    1146             : }
    1147             : 
    1148           3 : sal_Bool SwCursor::GoNextWord()
    1149             : {
    1150           3 :     return GoNextWordWT( WordType::ANYWORD_IGNOREWHITESPACES );
    1151             : }
    1152             : 
    1153           0 : sal_Bool SwCursor::GoPrevWord()
    1154             : {
    1155           0 :     return GoPrevWordWT( WordType::ANYWORD_IGNOREWHITESPACES );
    1156             : }
    1157             : 
    1158           0 : sal_Bool SwCursor::SelectWord( SwViewShell* pViewShell, const Point* pPt )
    1159             : {
    1160           0 :     return SelectWordWT( pViewShell, WordType::ANYWORD_IGNOREWHITESPACES, pPt );
    1161             : }
    1162             : 
    1163          18 : sal_Bool SwCursor::IsStartWordWT( sal_Int16 nWordType ) const
    1164             : {
    1165          18 :     sal_Bool bRet = sal_False;
    1166          18 :     const SwTxtNode* pTxtNd = GetNode()->GetTxtNode();
    1167          18 :     if( pTxtNd && g_pBreakIt->GetBreakIter().is() )
    1168             :     {
    1169          18 :         const sal_Int32 nPtPos = GetPoint()->nContent.GetIndex();
    1170          36 :         bRet = g_pBreakIt->GetBreakIter()->isBeginWord(
    1171          18 :                             pTxtNd->GetTxt(), nPtPos,
    1172          18 :                             g_pBreakIt->GetLocale( pTxtNd->GetLang( nPtPos )),
    1173          36 :                             nWordType );
    1174             :     }
    1175          18 :     return bRet;
    1176             : }
    1177             : 
    1178          25 : sal_Bool SwCursor::IsEndWordWT( sal_Int16 nWordType ) const
    1179             : {
    1180          25 :     sal_Bool bRet = sal_False;
    1181          25 :     const SwTxtNode* pTxtNd = GetNode()->GetTxtNode();
    1182          25 :     if( pTxtNd && g_pBreakIt->GetBreakIter().is() )
    1183             :     {
    1184          25 :         const sal_Int32 nPtPos = GetPoint()->nContent.GetIndex();
    1185          50 :         bRet = g_pBreakIt->GetBreakIter()->isEndWord(
    1186          25 :                             pTxtNd->GetTxt(), nPtPos,
    1187          25 :                             g_pBreakIt->GetLocale( pTxtNd->GetLang( nPtPos ) ),
    1188          50 :                             nWordType );
    1189             : 
    1190             :     }
    1191          25 :     return bRet;
    1192             : }
    1193             : 
    1194           0 : sal_Bool SwCursor::IsInWordWT( sal_Int16 nWordType ) const
    1195             : {
    1196           0 :     sal_Bool bRet = sal_False;
    1197           0 :     const SwTxtNode* pTxtNd = GetNode()->GetTxtNode();
    1198           0 :     if( pTxtNd && g_pBreakIt->GetBreakIter().is() )
    1199             :     {
    1200           0 :         const sal_Int32 nPtPos = GetPoint()->nContent.GetIndex();
    1201           0 :         Boundary aBoundary = g_pBreakIt->GetBreakIter()->getWordBoundary(
    1202           0 :                             pTxtNd->GetTxt(), nPtPos,
    1203           0 :                             g_pBreakIt->GetLocale( pTxtNd->GetLang( nPtPos ) ),
    1204             :                             nWordType,
    1205           0 :                             sal_True );
    1206             : 
    1207           0 :         bRet = aBoundary.startPos != aBoundary.endPos &&
    1208           0 :                 aBoundary.startPos <= nPtPos &&
    1209           0 :                     nPtPos <= aBoundary.endPos;
    1210           0 :         if(bRet)
    1211             :         {
    1212           0 :             const CharClass& rCC = GetAppCharClass();
    1213           0 :             bRet = rCC.isLetterNumeric( pTxtNd->GetTxt(), aBoundary.startPos );
    1214             :         }
    1215             :     }
    1216           0 :     return bRet;
    1217             : }
    1218             : 
    1219           0 : sal_Bool SwCursor::IsStartEndSentence( bool bEnd ) const
    1220             : {
    1221             :     sal_Bool bRet = bEnd ?
    1222           0 :                     GetCntntNode() && GetPoint()->nContent == GetCntntNode()->Len() :
    1223           0 :                     GetPoint()->nContent.GetIndex() == 0;
    1224             : 
    1225           0 :     if( !bRet )
    1226             :     {
    1227           0 :         SwCursor aCrsr(*GetPoint(), 0, false);
    1228           0 :         SwPosition aOrigPos = *aCrsr.GetPoint();
    1229           0 :         aCrsr.GoSentence( bEnd ? SwCursor::END_SENT : SwCursor::START_SENT );
    1230           0 :         bRet = aOrigPos == *aCrsr.GetPoint();
    1231             :     }
    1232           0 :     return bRet;
    1233             : }
    1234             : 
    1235           5 : sal_Bool SwCursor::GoStartWordWT( sal_Int16 nWordType )
    1236             : {
    1237           5 :     sal_Bool bRet = sal_False;
    1238           5 :     const SwTxtNode* pTxtNd = GetNode()->GetTxtNode();
    1239           5 :     if( pTxtNd && g_pBreakIt->GetBreakIter().is() )
    1240             :     {
    1241           5 :         SwCrsrSaveState aSave( *this );
    1242           5 :         sal_Int32 nPtPos = GetPoint()->nContent.GetIndex();
    1243          10 :         nPtPos = g_pBreakIt->GetBreakIter()->getWordBoundary(
    1244           5 :                             pTxtNd->GetTxt(), nPtPos,
    1245           5 :                             g_pBreakIt->GetLocale( pTxtNd->GetLang( nPtPos ) ),
    1246             :                             nWordType,
    1247          10 :                             sal_False ).startPos;
    1248             : 
    1249           5 :         if (nPtPos < pTxtNd->GetTxt().getLength() && nPtPos >= 0)
    1250             :         {
    1251           5 :             GetPoint()->nContent = nPtPos;
    1252           5 :             if( !IsSelOvr() )
    1253           5 :                 bRet = sal_True;
    1254           5 :         }
    1255             :     }
    1256           5 :     return bRet;
    1257             : }
    1258             : 
    1259          12 : sal_Bool SwCursor::GoEndWordWT( sal_Int16 nWordType )
    1260             : {
    1261          12 :     sal_Bool bRet = sal_False;
    1262          12 :     const SwTxtNode* pTxtNd = GetNode()->GetTxtNode();
    1263          12 :     if( pTxtNd && g_pBreakIt->GetBreakIter().is() )
    1264             :     {
    1265          12 :         SwCrsrSaveState aSave( *this );
    1266          12 :         sal_Int32 nPtPos = GetPoint()->nContent.GetIndex();
    1267          24 :         nPtPos = g_pBreakIt->GetBreakIter()->getWordBoundary(
    1268          12 :                             pTxtNd->GetTxt(), nPtPos,
    1269          12 :                             g_pBreakIt->GetLocale( pTxtNd->GetLang( nPtPos ) ),
    1270             :                             nWordType,
    1271          24 :                             sal_True ).endPos;
    1272             : 
    1273          24 :         if (nPtPos <= pTxtNd->GetTxt().getLength() && nPtPos >= 0 &&
    1274          12 :             GetPoint()->nContent.GetIndex() != nPtPos )
    1275             :         {
    1276          12 :             GetPoint()->nContent = nPtPos;
    1277          12 :             if( !IsSelOvr() )
    1278          12 :                 bRet = sal_True;
    1279          12 :         }
    1280             :     }
    1281          12 :     return bRet;
    1282             : }
    1283             : 
    1284           7 : sal_Bool SwCursor::GoNextWordWT( sal_Int16 nWordType )
    1285             : {
    1286           7 :     sal_Bool bRet = sal_False;
    1287           7 :     const SwTxtNode* pTxtNd = GetNode()->GetTxtNode();
    1288           7 :     if( pTxtNd && g_pBreakIt->GetBreakIter().is() )
    1289             :     {
    1290           7 :         SwCrsrSaveState aSave( *this );
    1291           7 :         sal_Int32 nPtPos = GetPoint()->nContent.GetIndex();
    1292             : 
    1293          14 :         nPtPos = g_pBreakIt->GetBreakIter()->nextWord(
    1294           7 :                                 pTxtNd->GetTxt(), nPtPos,
    1295           7 :             g_pBreakIt->GetLocale( pTxtNd->GetLang( nPtPos, 1 ) ),
    1296          14 :                     nWordType ).startPos;
    1297             : 
    1298           7 :         if (nPtPos < pTxtNd->GetTxt().getLength() && nPtPos >= 0)
    1299             :         {
    1300           4 :             GetPoint()->nContent = nPtPos;
    1301           4 :             if( !IsSelOvr() )
    1302           4 :                 bRet = sal_True;
    1303           7 :         }
    1304             :     }
    1305           7 :     return bRet;
    1306             : }
    1307             : 
    1308           5 : sal_Bool SwCursor::GoPrevWordWT( sal_Int16 nWordType )
    1309             : {
    1310           5 :     sal_Bool bRet = sal_False;
    1311           5 :     const SwTxtNode* pTxtNd = GetNode()->GetTxtNode();
    1312           5 :     if( pTxtNd && g_pBreakIt->GetBreakIter().is() )
    1313             :     {
    1314           5 :         SwCrsrSaveState aSave( *this );
    1315           5 :         sal_Int32 nPtPos = GetPoint()->nContent.GetIndex();
    1316           5 :         const sal_Int32 nPtStart = nPtPos;
    1317             : 
    1318           5 :         if( nPtPos )
    1319           5 :             --nPtPos;
    1320          10 :         nPtPos = g_pBreakIt->GetBreakIter()->previousWord(
    1321           5 :                                 pTxtNd->GetTxt(), nPtStart,
    1322           5 :             g_pBreakIt->GetLocale( pTxtNd->GetLang( nPtPos, 1 ) ),
    1323          10 :                     nWordType ).startPos;
    1324             : 
    1325           5 :         if (nPtPos < pTxtNd->GetTxt().getLength() && nPtPos >= 0)
    1326             :         {
    1327           5 :             GetPoint()->nContent = nPtPos;
    1328           5 :             if( !IsSelOvr() )
    1329           5 :                 bRet = sal_True;
    1330           5 :         }
    1331             :     }
    1332           5 :     return bRet;
    1333             : }
    1334             : 
    1335           0 : sal_Bool SwCursor::SelectWordWT( SwViewShell* pViewShell, sal_Int16 nWordType, const Point* pPt )
    1336             : {
    1337           0 :     SwCrsrSaveState aSave( *this );
    1338             : 
    1339           0 :     sal_Bool bRet = sal_False;
    1340           0 :     sal_Bool bForward = sal_True;
    1341           0 :     DeleteMark();
    1342           0 :     const SwRootFrm* pLayout = pViewShell->GetLayout();
    1343           0 :     if( pPt && 0 != pLayout )
    1344             :     {
    1345             :         // set the cursor to the layout position
    1346           0 :         Point aPt( *pPt );
    1347           0 :         pLayout->GetCrsrOfst( GetPoint(), aPt );
    1348             :     }
    1349             : 
    1350           0 :     const SwTxtNode* pTxtNd = GetNode()->GetTxtNode();
    1351           0 :     if( pTxtNd && g_pBreakIt->GetBreakIter().is() )
    1352             :     {
    1353             :         // Should we select the whole fieldmark?
    1354           0 :         const IDocumentMarkAccess* pMarksAccess = GetDoc()->getIDocumentMarkAccess( );
    1355           0 :         sw::mark::IMark* pMark = GetPoint() ? pMarksAccess->getFieldmarkFor( *GetPoint( ) ) : NULL;
    1356           0 :         if ( pMark )
    1357             :         {
    1358           0 :             const SwPosition rStart = pMark->GetMarkStart();
    1359           0 :             GetPoint()->nNode = rStart.nNode;
    1360           0 :             GetPoint()->nContent = rStart.nContent;
    1361           0 :             GetPoint()->nContent++; // Don't select the start delimiter
    1362             : 
    1363           0 :             const SwPosition rEnd = pMark->GetMarkEnd();
    1364             : 
    1365           0 :             if ( rStart != rEnd )
    1366             :             {
    1367           0 :                 SetMark();
    1368           0 :                 GetMark()->nNode = rEnd.nNode;
    1369           0 :                 GetMark()->nContent = rEnd.nContent;
    1370           0 :                 GetMark()->nContent--; //Don't select the end delimiter
    1371             :             }
    1372           0 :             bRet = sal_True;
    1373             :         }
    1374             :         else
    1375             :         {
    1376           0 :             const sal_Int32 nPtPos = GetPoint()->nContent.GetIndex();
    1377           0 :             Boundary aBndry( g_pBreakIt->GetBreakIter()->getWordBoundary(
    1378           0 :                                 pTxtNd->GetTxt(), nPtPos,
    1379           0 :                                 g_pBreakIt->GetLocale( pTxtNd->GetLang( nPtPos ) ),
    1380             :                                 nWordType,
    1381           0 :                                 bForward ));
    1382             : 
    1383           0 :             if( aBndry.startPos != aBndry.endPos )
    1384             :             {
    1385           0 :                 GetPoint()->nContent = aBndry.endPos;
    1386           0 :                 if( !IsSelOvr() )
    1387             :                 {
    1388           0 :                     SetMark();
    1389           0 :                     GetMark()->nContent = aBndry.startPos;
    1390           0 :                     if( !IsSelOvr() )
    1391           0 :                         bRet = sal_True;
    1392             :                 }
    1393             :             }
    1394             :         }
    1395             :     }
    1396             : 
    1397           0 :     if( !bRet )
    1398             :     {
    1399           0 :         DeleteMark();
    1400           0 :         RestoreSavePos();
    1401             :     }
    1402           0 :     return bRet;
    1403             : }
    1404             : 
    1405          22 : static OUString lcl_MaskDeletedRedlines( const SwTxtNode* pTxtNd )
    1406             : {
    1407          22 :     OUString aRes;
    1408          22 :     if (pTxtNd)
    1409             :     {
    1410             :         //mask deleted redlines
    1411          22 :         OUString sNodeText(pTxtNd->GetTxt());
    1412          22 :         const SwDoc& rDoc = *pTxtNd->GetDoc();
    1413          22 :         const bool nShowChg = IDocumentRedlineAccess::IsShowChanges( rDoc.GetRedlineMode() );
    1414          22 :         if ( nShowChg )
    1415             :         {
    1416          22 :             sal_uInt16 nAct = rDoc.GetRedlinePos( *pTxtNd, USHRT_MAX );
    1417          22 :             for ( ; nAct < rDoc.GetRedlineTbl().size(); nAct++ )
    1418             :             {
    1419           0 :                 const SwRangeRedline* pRed = rDoc.GetRedlineTbl()[ nAct ];
    1420           0 :                 if ( pRed->Start()->nNode > pTxtNd->GetIndex() )
    1421           0 :                     break;
    1422             : 
    1423           0 :                 if( nsRedlineType_t::REDLINE_DELETE == pRed->GetType() )
    1424             :                 {
    1425             :                     sal_Int32 nStart, nEnd;
    1426           0 :                     pRed->CalcStartEnd( pTxtNd->GetIndex(), nStart, nEnd );
    1427             : 
    1428           0 :                     while ( nStart < nEnd && nStart < sNodeText.getLength() )
    1429           0 :                         sNodeText = sNodeText.replaceAt( nStart++, 1, OUString(CH_TXTATR_INWORD) );
    1430             :                 }
    1431             :             }
    1432             :         }
    1433          22 :         aRes = sNodeText;
    1434             :     }
    1435          22 :     return aRes;
    1436             : }
    1437             : 
    1438          22 : sal_Bool SwCursor::GoSentence( SentenceMoveType eMoveType )
    1439             : {
    1440          22 :     sal_Bool bRet = sal_False;
    1441          22 :     const SwTxtNode* pTxtNd = GetNode()->GetTxtNode();
    1442          22 :     if( pTxtNd && g_pBreakIt->GetBreakIter().is() )
    1443             :     {
    1444          22 :         OUString sNodeText( lcl_MaskDeletedRedlines( pTxtNd ) );
    1445             : 
    1446          43 :         SwCrsrSaveState aSave( *this );
    1447          22 :         sal_Int32 nPtPos = GetPoint()->nContent.GetIndex();
    1448          22 :         switch ( eMoveType )
    1449             :         {
    1450             :         case START_SENT: /* when modifying: see also ExpandToSentenceBorders below! */
    1451           8 :             nPtPos = g_pBreakIt->GetBreakIter()->beginOfSentence(
    1452             :                                     sNodeText,
    1453             :                                     nPtPos, g_pBreakIt->GetLocale(
    1454           4 :                                             pTxtNd->GetLang( nPtPos ) ));
    1455           4 :             break;
    1456             :         case END_SENT: /* when modifying: see also ExpandToSentenceBorders below! */
    1457          14 :             nPtPos = g_pBreakIt->GetBreakIter()->endOfSentence(
    1458             :                                     sNodeText,
    1459             :                                     nPtPos, g_pBreakIt->GetLocale(
    1460           7 :                                                 pTxtNd->GetLang( nPtPos ) ));
    1461           7 :             break;
    1462             :         case NEXT_SENT:
    1463             :             {
    1464          10 :                 nPtPos = g_pBreakIt->GetBreakIter()->endOfSentence(
    1465             :                                         sNodeText,
    1466             :                                         nPtPos, g_pBreakIt->GetLocale(
    1467           5 :                                                     pTxtNd->GetLang( nPtPos ) ));
    1468          15 :                 while (nPtPos>=0 && ++nPtPos < sNodeText.getLength()
    1469           7 :                        && sNodeText[nPtPos] == ' ' /*isWhiteSpace( aTxt.GetChar(nPtPos)*/ )
    1470             :                     ;
    1471           5 :                 break;
    1472             :             }
    1473             :         case PREV_SENT:
    1474          12 :             nPtPos = g_pBreakIt->GetBreakIter()->beginOfSentence(
    1475             :                                     sNodeText,
    1476             :                                     nPtPos, g_pBreakIt->GetLocale(
    1477           6 :                                                 pTxtNd->GetLang( nPtPos ) ));
    1478           6 :             if (nPtPos == 0)
    1479           1 :                 return sal_False;   // the previous sentence is not in this paragraph
    1480           5 :             if (nPtPos > 0)
    1481          10 :                 nPtPos = g_pBreakIt->GetBreakIter()->beginOfSentence(
    1482             :                                     sNodeText,
    1483             :                                     nPtPos - 1, g_pBreakIt->GetLocale(
    1484           5 :                                                 pTxtNd->GetLang( nPtPos ) ));
    1485           5 :             break;
    1486             :         }
    1487             : 
    1488             :         // it is allowed to place the PaM just behind the last
    1489             :         // character in the text thus <= ...Len
    1490          21 :         if (nPtPos <= pTxtNd->GetTxt().getLength() && nPtPos >= 0)
    1491             :         {
    1492          21 :             GetPoint()->nContent = nPtPos;
    1493          21 :             if( !IsSelOvr() )
    1494          21 :                 bRet = sal_True;
    1495          21 :         }
    1496             :     }
    1497          21 :     return bRet;
    1498             : }
    1499             : 
    1500           0 : sal_Bool SwCursor::ExpandToSentenceBorders()
    1501             : {
    1502           0 :     sal_Bool bRes = sal_False;
    1503           0 :     const SwTxtNode* pStartNd = Start()->nNode.GetNode().GetTxtNode();
    1504           0 :     const SwTxtNode* pEndNd   = End()->nNode.GetNode().GetTxtNode();
    1505           0 :     if (pStartNd && pEndNd && g_pBreakIt->GetBreakIter().is())
    1506             :     {
    1507           0 :         if (!HasMark())
    1508           0 :             SetMark();
    1509             : 
    1510           0 :         OUString sStartText( lcl_MaskDeletedRedlines( pStartNd ) );
    1511           0 :         OUString sEndText( pStartNd == pEndNd? sStartText : lcl_MaskDeletedRedlines( pEndNd ) );
    1512             : 
    1513           0 :         SwCrsrSaveState aSave( *this );
    1514           0 :         sal_Int32 nStartPos = Start()->nContent.GetIndex();
    1515           0 :         sal_Int32 nEndPos   = End()->nContent.GetIndex();
    1516             : 
    1517           0 :         nStartPos = g_pBreakIt->GetBreakIter()->beginOfSentence(
    1518             :                                 sStartText, nStartPos,
    1519           0 :                                 g_pBreakIt->GetLocale( pStartNd->GetLang( nStartPos ) ) );
    1520           0 :         nEndPos   = g_pBreakIt->GetBreakIter()->endOfSentence(
    1521             :                                 sEndText, nEndPos,
    1522           0 :                                 g_pBreakIt->GetLocale( pEndNd->GetLang( nEndPos ) ) );
    1523             : 
    1524             :         // it is allowed to place the PaM just behind the last
    1525             :         // character in the text thus <= ...Len
    1526           0 :         bool bChanged = false;
    1527           0 :         if (nStartPos <= pStartNd->GetTxt().getLength() && nStartPos >= 0)
    1528             :         {
    1529           0 :             GetMark()->nContent = nStartPos;
    1530           0 :             bChanged = true;
    1531             :         }
    1532           0 :         if (nEndPos <= pEndNd->GetTxt().getLength() && nEndPos >= 0)
    1533             :         {
    1534           0 :             GetPoint()->nContent = nEndPos;
    1535           0 :             bChanged = true;
    1536             :         }
    1537           0 :         if (bChanged && !IsSelOvr())
    1538           0 :             bRes = sal_True;
    1539             :     }
    1540           0 :     return bRes;
    1541             : }
    1542             : 
    1543           4 : sal_Bool SwTableCursor::LeftRight( sal_Bool bLeft, sal_uInt16 nCnt, sal_uInt16 /*nMode*/,
    1544             :     sal_Bool /*bVisualAllowed*/, sal_Bool /*bSkipHidden*/, sal_Bool /*bInsertCrsr*/ )
    1545             : {
    1546           2 :     return bLeft ? GoPrevCell( nCnt )
    1547           6 :                  : GoNextCell( nCnt );
    1548             : }
    1549             : 
    1550             : // calculate cursor bidi level: extracted from LeftRight()
    1551             : const SwCntntFrm*
    1552          40 : SwCursor::DoSetBidiLevelLeftRight(
    1553             :     sal_Bool & io_rbLeft, sal_Bool bVisualAllowed, sal_Bool bInsertCrsr)
    1554             : {
    1555             :     // calculate cursor bidi level
    1556          40 :     const SwCntntFrm* pSttFrm = NULL;
    1557          40 :     SwNode& rNode = GetPoint()->nNode.GetNode();
    1558             : 
    1559          40 :     if( rNode.IsTxtNode() )
    1560             :     {
    1561          40 :         const SwTxtNode& rTNd = *rNode.GetTxtNode();
    1562          40 :         SwIndex& rIdx = GetPoint()->nContent;
    1563          40 :         sal_Int32 nPos = rIdx.GetIndex();
    1564             : 
    1565          40 :         const SvtCTLOptions& rCTLOptions = SW_MOD()->GetCTLOptions();
    1566          40 :         if ( bVisualAllowed && rCTLOptions.IsCTLFontEnabled() &&
    1567             :              SvtCTLOptions::MOVEMENT_VISUAL ==
    1568           0 :              rCTLOptions.GetCTLCursorMovement() )
    1569             :         {
    1570             :             // for visual cursor travelling (used in bidi layout)
    1571             :             // we first have to convert the logic to a visual position
    1572           0 :             Point aPt;
    1573           0 :             pSttFrm = rTNd.getLayoutFrm( GetDoc()->GetCurrentLayout(), &aPt, GetPoint() );
    1574           0 :             if( pSttFrm )
    1575             :             {
    1576           0 :                 sal_uInt8 nCrsrLevel = GetCrsrBidiLevel();
    1577           0 :                 bool bForward = ! io_rbLeft;
    1578             :                 ((SwTxtFrm*)pSttFrm)->PrepareVisualMove( nPos, nCrsrLevel,
    1579           0 :                                                          bForward, bInsertCrsr );
    1580           0 :                 rIdx = nPos;
    1581           0 :                 SetCrsrBidiLevel( nCrsrLevel );
    1582           0 :                 io_rbLeft = ! bForward;
    1583             :             }
    1584             :         }
    1585             :         else
    1586             :         {
    1587          40 :             const SwScriptInfo* pSI = SwScriptInfo::GetScriptInfo( rTNd );
    1588          40 :             if ( pSI )
    1589             :             {
    1590             :                 const sal_Int32 nMoveOverPos = io_rbLeft ?
    1591           9 :                                                ( nPos ? nPos - 1 : 0 ) :
    1592          30 :                                                 nPos;
    1593          21 :                 SetCrsrBidiLevel( pSI->DirType( nMoveOverPos ) );
    1594             :             }
    1595             :         }
    1596             :     }
    1597          40 :     return pSttFrm;
    1598             : }
    1599             : 
    1600       30179 : sal_Bool SwCursor::LeftRight( sal_Bool bLeft, sal_uInt16 nCnt, sal_uInt16 nMode,
    1601             :                           sal_Bool bVisualAllowed,sal_Bool bSkipHidden, sal_Bool bInsertCrsr )
    1602             : {
    1603             :     // calculate cursor bidi level
    1604       30179 :     SwNode& rNode = GetPoint()->nNode.GetNode();
    1605             :     const SwCntntFrm* pSttFrm = // may side-effect bLeft!
    1606       30179 :         DoSetBidiLevelLeftRight(bLeft, bVisualAllowed, bInsertCrsr);
    1607             : 
    1608             :     // can the cursor be moved n times?
    1609       30179 :     SwCrsrSaveState aSave( *this );
    1610       30179 :     SwMoveFn fnMove = bLeft ? fnMoveBackward : fnMoveForward;
    1611             : 
    1612             :     SwGoInDoc fnGo;
    1613       30179 :     if ( bSkipHidden )
    1614          21 :         fnGo = CRSR_SKIP_CELLS == nMode ? fnGoCntntCellsSkipHidden : fnGoCntntSkipHidden;
    1615             :     else
    1616       30158 :         fnGo = CRSR_SKIP_CELLS == nMode ? fnGoCntntCells : fnGoCntnt;
    1617             : 
    1618      165581 :     while( nCnt )
    1619             :     {
    1620      106271 :         SwNodeIndex aOldNodeIdx( GetPoint()->nNode );
    1621             : 
    1622      106271 :         if ( !Move( fnMove, fnGo ) )
    1623        1048 :             break;
    1624             : 
    1625             :         // If we were located inside a covered cell but our position has been
    1626             :         // corrected, we check if the last move has moved the cursor to a
    1627             :         // different table cell. In this case we set the cursor to the stored
    1628             :         // covered position and redo the move:
    1629      105223 :         if ( mnRowSpanOffset )
    1630             :         {
    1631           0 :             const SwNode* pOldTabBoxSttNode = aOldNodeIdx.GetNode().FindTableBoxStartNode();
    1632           0 :             const SwTableNode* pOldTabSttNode = pOldTabBoxSttNode ? pOldTabBoxSttNode->FindTableNode() : 0;
    1633           0 :             const SwNode* pNewTabBoxSttNode = GetPoint()->nNode.GetNode().FindTableBoxStartNode();
    1634           0 :             const SwTableNode* pNewTabSttNode = pNewTabBoxSttNode ? pNewTabBoxSttNode->FindTableNode() : 0;
    1635             : 
    1636           0 :             const bool bCellChanged = pOldTabSttNode && pNewTabSttNode &&
    1637           0 :                                       pOldTabSttNode == pNewTabSttNode &&
    1638           0 :                                       pOldTabBoxSttNode && pNewTabBoxSttNode &&
    1639           0 :                                       pOldTabBoxSttNode != pNewTabBoxSttNode;
    1640             : 
    1641           0 :             if ( bCellChanged )
    1642             :             {
    1643             :                 // Set cursor to start/end of covered cell:
    1644           0 :                 SwTableBox* pTableBox = pOldTabBoxSttNode->GetTblBox();
    1645           0 :                 if ( pTableBox && pTableBox->getRowSpan() > 1 )
    1646             :                 {
    1647           0 :                     pTableBox = & pTableBox->FindEndOfRowSpan( pOldTabSttNode->GetTable(), (sal_uInt16)(pTableBox->getRowSpan() + mnRowSpanOffset ) );
    1648           0 :                     SwNodeIndex& rPtIdx = GetPoint()->nNode;
    1649           0 :                     SwNodeIndex aNewIdx( *pTableBox->GetSttNd() );
    1650           0 :                     rPtIdx = aNewIdx;
    1651             : 
    1652           0 :                     GetDoc()->GetNodes().GoNextSection( &rPtIdx, false, false );
    1653           0 :                     SwCntntNode* pCntntNode = GetCntntNode();
    1654           0 :                     if ( pCntntNode )
    1655             :                     {
    1656           0 :                         GetPoint()->nContent.Assign( pCntntNode, bLeft ? pCntntNode->Len() : 0 );
    1657             : 
    1658             :                         // Redo the move:
    1659           0 :                         if ( !Move( fnMove, fnGo ) )
    1660           0 :                             break;
    1661           0 :                     }
    1662             :                 }
    1663           0 :                 mnRowSpanOffset = 0;
    1664             :             }
    1665             :         }
    1666             : 
    1667             :         // Check if I'm inside a covered cell. Correct cursor if necessary and
    1668             :         // store covered cell:
    1669      105223 :         const SwNode* pTableBoxStartNode = GetPoint()->nNode.GetNode().FindTableBoxStartNode();
    1670      105223 :         if ( pTableBoxStartNode )
    1671             :         {
    1672         156 :             const SwTableBox* pTableBox = pTableBoxStartNode->GetTblBox();
    1673         156 :             if ( pTableBox && pTableBox->getRowSpan() < 1 )
    1674             :             {
    1675             :                 // Store the row span offset:
    1676           0 :                 mnRowSpanOffset = pTableBox->getRowSpan();
    1677             : 
    1678             :                 // Move cursor to non-covered cell:
    1679           0 :                 const SwTableNode* pTblNd = pTableBoxStartNode->FindTableNode();
    1680           0 :                 pTableBox = & pTableBox->FindStartOfRowSpan( pTblNd->GetTable(), USHRT_MAX );
    1681           0 :                  SwNodeIndex& rPtIdx = GetPoint()->nNode;
    1682           0 :                 SwNodeIndex aNewIdx( *pTableBox->GetSttNd() );
    1683           0 :                 rPtIdx = aNewIdx;
    1684             : 
    1685           0 :                 GetDoc()->GetNodes().GoNextSection( &rPtIdx, false, false );
    1686           0 :                 SwCntntNode* pCntntNode = GetCntntNode();
    1687           0 :                 if ( pCntntNode )
    1688             :                 {
    1689           0 :                     GetPoint()->nContent.Assign( pCntntNode, bLeft ? pCntntNode->Len() : 0 );
    1690           0 :                 }
    1691             :             }
    1692             :         }
    1693      105223 :         --nCnt;
    1694      105223 :     }
    1695             : 
    1696             :     // here come some special rules for visual cursor travelling
    1697       30179 :     if ( pSttFrm )
    1698             :     {
    1699           0 :         SwNode& rTmpNode = GetPoint()->nNode.GetNode();
    1700           0 :         if ( &rTmpNode != &rNode && rTmpNode.IsTxtNode() )
    1701             :         {
    1702           0 :             Point aPt;
    1703           0 :             const SwCntntFrm* pEndFrm = ((SwTxtNode&)rTmpNode).getLayoutFrm( GetDoc()->GetCurrentLayout(), &aPt, GetPoint() );
    1704           0 :             if ( pEndFrm )
    1705             :             {
    1706           0 :                 if ( ! pEndFrm->IsRightToLeft() != ! pSttFrm->IsRightToLeft() )
    1707             :                 {
    1708           0 :                     if ( ! bLeft )
    1709           0 :                         pEndFrm->RightMargin( this );
    1710             :                     else
    1711           0 :                         pEndFrm->LeftMargin( this );
    1712             :                 }
    1713             :             }
    1714             :         }
    1715             :     }
    1716             : 
    1717       59310 :     return 0 == nCnt && !IsInProtectTable( sal_True ) &&
    1718             :             !IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE |
    1719       59310 :                        nsSwCursorSelOverFlags::SELOVER_CHANGEPOS );
    1720             : }
    1721             : 
    1722             : // calculate cursor bidi level: extracted from UpDown()
    1723           0 : void SwCursor::DoSetBidiLevelUpDown()
    1724             : {
    1725           0 :     SwNode& rNode = GetPoint()->nNode.GetNode();
    1726           0 :     if ( rNode.IsTxtNode() )
    1727             :     {
    1728             :         const SwScriptInfo* pSI =
    1729           0 :             SwScriptInfo::GetScriptInfo( (SwTxtNode&)rNode );
    1730           0 :         if ( pSI )
    1731             :         {
    1732           0 :             SwIndex& rIdx = GetPoint()->nContent;
    1733           0 :             const sal_Int32 nPos = rIdx.GetIndex();
    1734             : 
    1735           0 :             if (nPos && nPos <
    1736           0 :                     static_cast<SwTxtNode&>(rNode).GetTxt().getLength())
    1737             :             {
    1738           0 :                 const sal_uInt8 nCurrLevel = pSI->DirType( nPos );
    1739           0 :                 const sal_uInt8 nPrevLevel = pSI->DirType( nPos - 1 );
    1740             : 
    1741           0 :                 if ( nCurrLevel % 2 != nPrevLevel % 2 )
    1742             :                 {
    1743             :                     // set cursor level to the lower of the two levels
    1744           0 :                     SetCrsrBidiLevel( std::min( nCurrLevel, nPrevLevel ) );
    1745             :                 }
    1746             :                 else
    1747           0 :                     SetCrsrBidiLevel( nCurrLevel );
    1748             :             }
    1749             :         }
    1750             :     }
    1751           0 : }
    1752             : 
    1753           3 : bool SwCursor::UpDown( bool bUp, sal_uInt16 nCnt,
    1754             :                             Point* pPt, long nUpDownX )
    1755             : {
    1756           3 :     SwTableCursor* pTblCrsr = dynamic_cast<SwTableCursor*>(this);
    1757           3 :     bool bAdjustTableCrsr = false;
    1758             : 
    1759             :     // If the point/mark of the table cursor in the same box then set cursor to
    1760             :     // beginning of the box
    1761           6 :     if( pTblCrsr && GetNode( true )->StartOfSectionNode() ==
    1762           3 :                     GetNode( false )->StartOfSectionNode() )
    1763             :     {
    1764           3 :         if ( End() != GetPoint() )
    1765           0 :             Exchange();
    1766           3 :         bAdjustTableCrsr = true;
    1767             :     }
    1768             : 
    1769           3 :     bool bRet = false;
    1770           3 :     Point aPt;
    1771           3 :     if( pPt )
    1772           0 :         aPt = *pPt;
    1773           3 :     SwCntntFrm* pFrm = GetCntntNode()->getLayoutFrm( GetDoc()->GetCurrentLayout(), &aPt, GetPoint() );
    1774             : 
    1775           3 :     if( pFrm )
    1776             :     {
    1777           3 :         SwCrsrSaveState aSave( *this );
    1778             : 
    1779           3 :         if( !pPt )
    1780             :         {
    1781           3 :             SwRect aTmpRect;
    1782           3 :             pFrm->GetCharRect( aTmpRect, *GetPoint() );
    1783           3 :             aPt = aTmpRect.Pos();
    1784             : 
    1785           3 :             nUpDownX = pFrm->IsVertical() ?
    1786           0 :                 aPt.getY() - pFrm->Frm().Top() :
    1787           3 :                 aPt.getX() - pFrm->Frm().Left();
    1788             :         }
    1789             : 
    1790             :         // It is allowed to move footnotes in other footnotes but not sections
    1791           3 :         const bool bChkRange = pFrm->IsInFtn() && !HasMark();
    1792           6 :         const SwPosition aOldPos( *GetPoint() );
    1793           3 :         const bool bInReadOnly = IsReadOnlyAvailable();
    1794             : 
    1795           3 :         if ( bAdjustTableCrsr && !bUp )
    1796             :         {
    1797             :             // Special case: We have a table cursor but the start box has more
    1798             :             // than one paragraph. If we want to go down, we have to set the
    1799             :             // point to the last frame in the table box. This is only necessary
    1800             :             // if we do not already have a table selection
    1801           1 :             const SwStartNode* pTblNd = GetNode( true )->FindTableBoxStartNode();
    1802             :             OSL_ENSURE( pTblNd, "pTblCrsr without SwTableNode?" );
    1803             : 
    1804           1 :             if ( pTblNd ) // safety first
    1805             :             {
    1806           1 :                 const SwNode* pEndNd = pTblNd->EndOfSectionNode();
    1807           1 :                 GetPoint()->nNode = *pEndNd;
    1808           1 :                 pTblCrsr->Move( fnMoveBackward, fnGoNode );
    1809           1 :                    pFrm = GetCntntNode()->getLayoutFrm( GetDoc()->GetCurrentLayout(), &aPt, GetPoint() );
    1810             :             }
    1811             :         }
    1812             : 
    1813          12 :         while( nCnt &&
    1814           2 :                (bUp ? pFrm->UnitUp( this, nUpDownX, bInReadOnly )
    1815          10 :                     : pFrm->UnitDown( this, nUpDownX, bInReadOnly ) ) &&
    1816           3 :                 CheckNodesRange( aOldPos.nNode, GetPoint()->nNode, bChkRange ))
    1817             :         {
    1818           3 :                pFrm = GetCntntNode()->getLayoutFrm( GetDoc()->GetCurrentLayout(), &aPt, GetPoint() );
    1819           3 :             --nCnt;
    1820             :         }
    1821             : 
    1822             :         // iterate over whole number of items?
    1823           6 :         if( !nCnt && !IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE |
    1824           3 :                                 nsSwCursorSelOverFlags::SELOVER_CHANGEPOS ) )
    1825             :         {
    1826           3 :             if( !pTblCrsr )
    1827             :             {
    1828             :                 // try to position the cursor at half of the char-rect's height
    1829           0 :                 pFrm = GetCntntNode()->getLayoutFrm( GetDoc()->GetCurrentLayout(), &aPt, GetPoint() );
    1830           0 :                 SwCrsrMoveState eTmpState( MV_UPDOWN );
    1831           0 :                 eTmpState.bSetInReadOnly = bInReadOnly;
    1832           0 :                 SwRect aTmpRect;
    1833           0 :                 pFrm->GetCharRect( aTmpRect, *GetPoint(), &eTmpState );
    1834           0 :                 if ( pFrm->IsVertical() )
    1835             :                 {
    1836           0 :                     aPt.setX(aTmpRect.Center().getX());
    1837           0 :                     pFrm->Calc();
    1838           0 :                     aPt.setY(pFrm->Frm().Top() + nUpDownX);
    1839             :                 }
    1840             :                 else
    1841             :                 {
    1842           0 :                     aPt.setY(aTmpRect.Center().getY());
    1843           0 :                     pFrm->Calc();
    1844           0 :                     aPt.setX(pFrm->Frm().Left() + nUpDownX);
    1845             :                 }
    1846           0 :                 pFrm->GetCrsrOfst( GetPoint(), aPt, &eTmpState );
    1847             :             }
    1848           3 :             bRet = !IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE | nsSwCursorSelOverFlags::SELOVER_CHANGEPOS );
    1849             :         }
    1850             :         else
    1851           0 :             *GetPoint() = aOldPos;
    1852             : 
    1853           6 :         DoSetBidiLevelUpDown(); // calculate cursor bidi level
    1854             :     }
    1855           3 :     return bRet;
    1856             : }
    1857             : 
    1858           0 : sal_Bool SwCursor::LeftRightMargin( sal_Bool bLeft, sal_Bool bAPI )
    1859             : {
    1860           0 :     Point aPt;
    1861           0 :     SwCntntFrm * pFrm = GetCntntNode()->getLayoutFrm( GetDoc()->GetCurrentLayout(), &aPt, GetPoint() );
    1862             : 
    1863             :     // calculate cursor bidi level
    1864           0 :     if ( pFrm )
    1865           0 :         SetCrsrBidiLevel( pFrm->IsRightToLeft() ? 1 : 0 );
    1866             : 
    1867           0 :     SwCrsrSaveState aSave( *this );
    1868             :     return pFrm
    1869           0 :            && (bLeft ? pFrm->LeftMargin( this ) : pFrm->RightMargin( this, bAPI ) )
    1870           0 :            && !IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE | nsSwCursorSelOverFlags::SELOVER_CHANGEPOS );
    1871             : }
    1872             : 
    1873           0 : sal_Bool SwCursor::IsAtLeftRightMargin( sal_Bool bLeft, sal_Bool bAPI ) const
    1874             : {
    1875           0 :     sal_Bool bRet = sal_False;
    1876           0 :     Point aPt;
    1877           0 :     SwCntntFrm * pFrm = GetCntntNode()->getLayoutFrm( GetDoc()->GetCurrentLayout(), &aPt, GetPoint() );
    1878           0 :     if( pFrm )
    1879             :     {
    1880           0 :         SwPaM aPam( *GetPoint() );
    1881           0 :         if( !bLeft && aPam.GetPoint()->nContent.GetIndex() )
    1882           0 :             aPam.GetPoint()->nContent--;
    1883           0 :         bRet = (bLeft ? pFrm->LeftMargin( &aPam )
    1884           0 :                       : pFrm->RightMargin( &aPam, bAPI ))
    1885           0 :                 && *aPam.GetPoint() == *GetPoint();
    1886             :     }
    1887           0 :     return bRet;
    1888             : }
    1889             : 
    1890          44 : sal_Bool SwCursor::SttEndDoc( sal_Bool bStt )
    1891             : {
    1892          44 :     SwCrsrSaveState aSave( *this );
    1893             :     // Never jump over section boundaries during selection!
    1894             :     // Can the cursor still moved on?
    1895          44 :     SwMoveFn fnMove = bStt ? fnMoveBackward : fnMoveForward;
    1896          96 :     sal_Bool bRet = (!HasMark() || !IsNoCntnt() ) &&
    1897          88 :                     Move( fnMove, fnGoDoc ) &&
    1898         132 :                     !IsInProtectTable( sal_True ) &&
    1899             :                     !IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE |
    1900             :                                nsSwCursorSelOverFlags::SELOVER_CHANGEPOS |
    1901          88 :                                nsSwCursorSelOverFlags::SELOVER_ENABLEREVDIREKTION );
    1902          44 :     return bRet;
    1903             : }
    1904             : 
    1905           4 : sal_Bool SwCursor::GoPrevNextCell( sal_Bool bNext, sal_uInt16 nCnt )
    1906             : {
    1907           4 :     const SwTableNode* pTblNd = GetPoint()->nNode.GetNode().FindTableNode();
    1908           4 :     if( !pTblNd )
    1909           0 :         return sal_False;
    1910             : 
    1911             :     // If there is another EndNode in front of the cell's StartNode then there
    1912             :     // exists a previous cell
    1913           4 :     SwCrsrSaveState aSave( *this );
    1914           4 :     SwNodeIndex& rPtIdx = GetPoint()->nNode;
    1915             : 
    1916          12 :     while( nCnt-- )
    1917             :     {
    1918           4 :         const SwNode* pTableBoxStartNode = rPtIdx.GetNode().FindTableBoxStartNode();
    1919           4 :         const SwTableBox* pTableBox = pTableBoxStartNode->GetTblBox();
    1920             : 
    1921             :         // Check if we have to move the cursor to a covered cell before
    1922             :         // proceeding:
    1923           4 :         if ( mnRowSpanOffset )
    1924             :         {
    1925           0 :             if ( pTableBox && pTableBox->getRowSpan() > 1 )
    1926             :             {
    1927           0 :                 pTableBox = & pTableBox->FindEndOfRowSpan( pTblNd->GetTable(), (sal_uInt16)(pTableBox->getRowSpan() + mnRowSpanOffset) );
    1928           0 :                 SwNodeIndex aNewIdx( *pTableBox->GetSttNd() );
    1929           0 :                 rPtIdx = aNewIdx;
    1930           0 :                 pTableBoxStartNode = rPtIdx.GetNode().FindTableBoxStartNode();
    1931             :             }
    1932           0 :             mnRowSpanOffset = 0;
    1933             :         }
    1934             : 
    1935             :         const SwNode* pTmpNode = bNext ?
    1936             :                                  pTableBoxStartNode->EndOfSectionNode() :
    1937           4 :                                  pTableBoxStartNode;
    1938             : 
    1939           4 :         SwNodeIndex aCellIdx( *pTmpNode, bNext ? 1 : -1 );
    1940           4 :         if(  (bNext && !aCellIdx.GetNode().IsStartNode()) ||
    1941           2 :             (!bNext && !aCellIdx.GetNode().IsEndNode()) )
    1942           0 :             return sal_False;
    1943             : 
    1944           4 :         rPtIdx = bNext ? aCellIdx : SwNodeIndex(*aCellIdx.GetNode().StartOfSectionNode());
    1945             : 
    1946           4 :         pTableBoxStartNode = rPtIdx.GetNode().FindTableBoxStartNode();
    1947           4 :         pTableBox = pTableBoxStartNode->GetTblBox();
    1948           4 :         if ( pTableBox && pTableBox->getRowSpan() < 1 )
    1949             :         {
    1950           0 :             mnRowSpanOffset = pTableBox->getRowSpan();
    1951             :             // move cursor to non-covered cell:
    1952           0 :             pTableBox = & pTableBox->FindStartOfRowSpan( pTblNd->GetTable(), USHRT_MAX );
    1953           0 :             SwNodeIndex aNewIdx( *pTableBox->GetSttNd() );
    1954           0 :             rPtIdx = aNewIdx;
    1955             :         }
    1956           4 :     }
    1957             : 
    1958           4 :     ++rPtIdx;
    1959           4 :     if( !rPtIdx.GetNode().IsCntntNode() )
    1960           0 :         GetDoc()->GetNodes().GoNextSection( &rPtIdx, true, false );
    1961           4 :     GetPoint()->nContent.Assign( GetCntntNode(), 0 );
    1962             : 
    1963           4 :     return !IsInProtectTable( sal_True );
    1964             : }
    1965             : 
    1966           0 : bool SwTableCursor::GotoTable( const OUString& )
    1967             : {
    1968           0 :     return false; // invalid action
    1969             : }
    1970             : 
    1971           9 : bool SwCursor::GotoTable( const OUString& rName )
    1972             : {
    1973           9 :     bool bRet = false;
    1974           9 :     if ( !HasMark() )
    1975             :     {
    1976           9 :         SwTable* pTmpTbl = SwTable::FindTable( GetDoc()->FindTblFmtByName( rName ) );
    1977           9 :         if( pTmpTbl )
    1978             :         {
    1979             :             // a table in a normal nodes array
    1980           9 :             SwCrsrSaveState aSave( *this );
    1981          18 :             GetPoint()->nNode = *pTmpTbl->GetTabSortBoxes()[ 0 ]->
    1982          18 :                                 GetSttNd()->FindTableNode();
    1983           9 :             Move( fnMoveForward, fnGoCntnt );
    1984           9 :             bRet = !IsSelOvr();
    1985             :         }
    1986             :     }
    1987           9 :     return bRet;
    1988             : }
    1989             : 
    1990           3 : sal_Bool SwCursor::GotoTblBox( const OUString& rName )
    1991             : {
    1992           3 :     sal_Bool bRet = sal_False;
    1993           3 :     const SwTableNode* pTblNd = GetPoint()->nNode.GetNode().FindTableNode();
    1994           3 :     if( pTblNd )
    1995             :     {
    1996             :         // retrieve box by name
    1997           3 :         const SwTableBox* pTblBox = pTblNd->GetTable().GetTblBox( rName );
    1998           9 :         if( pTblBox && pTblBox->GetSttNd() &&
    1999           3 :             ( !pTblBox->GetFrmFmt()->GetProtect().IsCntntProtected() ||
    2000           0 :               IsReadOnlyAvailable() ) )
    2001             :         {
    2002           3 :             SwCrsrSaveState aSave( *this );
    2003           3 :             GetPoint()->nNode = *pTblBox->GetSttNd();
    2004           3 :             Move( fnMoveForward, fnGoCntnt );
    2005           3 :             bRet = !IsSelOvr();
    2006             :         }
    2007             :     }
    2008           3 :     return bRet;
    2009             : }
    2010             : 
    2011       32034 : sal_Bool SwCursor::MovePara(SwWhichPara fnWhichPara, SwPosPara fnPosPara )
    2012             : {
    2013             :     // for optimization test something before
    2014       32034 :     const SwNode* pNd = &GetPoint()->nNode.GetNode();
    2015       32034 :     bool bShortCut = false;
    2016       32034 :     if ( fnWhichPara == fnParaCurr )
    2017             :     {
    2018             :         // #i41048#
    2019             :         // If fnWhichPara == fnParaCurr then (*fnWhichPara)( *this, fnPosPara )
    2020             :         // can already move the cursor to a different text node. In this case
    2021             :         // we better check if IsSelOvr().
    2022       21407 :         const SwCntntNode* pCntntNd = pNd->GetCntntNode();
    2023       21407 :         if ( pCntntNd )
    2024             :         {
    2025       21407 :             const sal_Int32 nSttEnd = fnPosPara == fnMoveForward ? 0 : pCntntNd->Len();
    2026       21407 :             if ( GetPoint()->nContent.GetIndex() != nSttEnd )
    2027       21407 :                 bShortCut = true;
    2028             :         }
    2029             :     }
    2030             :     else
    2031             :     {
    2032       21254 :         if ( pNd->IsTxtNode() &&
    2033       21254 :              pNd->GetNodes()[ pNd->GetIndex() +
    2034       21254 :                     (fnWhichPara == fnParaNext ? 1 : -1 ) ]->IsTxtNode() )
    2035        4702 :             bShortCut = true;
    2036             :     }
    2037             : 
    2038       32034 :     if ( bShortCut )
    2039       26109 :         return (*fnWhichPara)( *this, fnPosPara );
    2040             : 
    2041             :     // else we must use the SaveStructure, because the next/prev is not
    2042             :     // a same node type.
    2043        5925 :     SwCrsrSaveState aSave( *this );
    2044        9373 :     return (*fnWhichPara)( *this, fnPosPara ) &&
    2045        9373 :             !IsInProtectTable( sal_True ) &&
    2046             :             !IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE |
    2047        9373 :                        nsSwCursorSelOverFlags::SELOVER_CHANGEPOS );
    2048             : }
    2049             : 
    2050       22351 : sal_Bool SwCursor::MoveSection( SwWhichSection fnWhichSect,
    2051             :                                 SwPosSection fnPosSect)
    2052             : {
    2053       22351 :     SwCrsrSaveState aSave( *this );
    2054       33671 :     return (*fnWhichSect)( *this, fnPosSect ) &&
    2055       33671 :             !IsInProtectTable( sal_True ) &&
    2056             :             !IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE |
    2057       33671 :                        nsSwCursorSelOverFlags::SELOVER_CHANGEPOS );
    2058             : }
    2059             : 
    2060           0 : void SwCursor::RestoreSavePos()
    2061             : {
    2062             :     // This method is not supposed to be used in cases when nodes may be
    2063             :     // deleted; detect such cases, but do not crash (example: fdo#40831).
    2064           0 :     sal_uLong uNodeCount = GetPoint()->nNode.GetNodes().Count();
    2065             :     OSL_ENSURE(!pSavePos || pSavePos->nNode < uNodeCount,
    2066             :         "SwCursor::RestoreSavePos: invalid node: "
    2067             :         "probably something was deleted; consider using SwUnoCrsr instead");
    2068           0 :     if( pSavePos && pSavePos->nNode < uNodeCount )
    2069             :     {
    2070           0 :         GetPoint()->nNode = pSavePos->nNode;
    2071             : 
    2072           0 :         sal_Int32 nIdx = 0;
    2073           0 :         if ( GetCntntNode() )
    2074             :         {
    2075           0 :             if ( pSavePos->nCntnt <= GetCntntNode()->Len() )
    2076           0 :                 nIdx = pSavePos->nCntnt;
    2077             :             else
    2078             :             {
    2079           0 :                 nIdx = GetCntntNode()->Len();
    2080             :                 OSL_FAIL("SwCursor::RestoreSavePos: invalid content index");
    2081             :             }
    2082             :         }
    2083           0 :         GetPoint()->nContent.Assign( GetCntntNode(), nIdx );
    2084             :     }
    2085           0 : }
    2086             : 
    2087          40 : SwTableCursor::SwTableCursor( const SwPosition &rPos, SwPaM* pRing )
    2088          40 :     : SwCursor( rPos, pRing, false )
    2089             : {
    2090          40 :     bParked = sal_False;
    2091          40 :     bChg = sal_False;
    2092          40 :     nTblPtNd = 0, nTblMkNd = 0;
    2093          40 :     nTblPtCnt = 0, nTblMkCnt = 0;
    2094          40 : }
    2095             : 
    2096          40 : SwTableCursor::~SwTableCursor() {}
    2097             : 
    2098             : static bool
    2099          17 : lcl_SeekEntry(const SwSelBoxes& rTmp, SwStartNode const*const pSrch,
    2100             :         size_t & o_rFndPos)
    2101             : {
    2102          17 :     sal_uLong nIdx = pSrch->GetIndex();
    2103             : 
    2104          17 :     size_t nO = rTmp.size();
    2105          17 :     if( nO > 0 )
    2106             :     {
    2107          11 :         nO--;
    2108          11 :         size_t nU = 0;
    2109          26 :         while( nU <= nO )
    2110             :         {
    2111          14 :             size_t nM = nU + ( nO - nU ) / 2;
    2112          14 :             if( rTmp[ nM ]->GetSttNd() == pSrch )
    2113             :             {
    2114           5 :                 o_rFndPos = nM;
    2115           5 :                 return true;
    2116             :             }
    2117           9 :             else if( rTmp[ nM ]->GetSttIdx() < nIdx )
    2118           4 :                 nU = nM + 1;
    2119           5 :             else if( nM == 0 )
    2120           5 :                 return false;
    2121             :             else
    2122           0 :                 nO = nM - 1;
    2123             :         }
    2124             :     }
    2125           7 :     return false;
    2126             : }
    2127             : 
    2128          47 : SwCursor* SwTableCursor::MakeBoxSels( SwCursor* pAktCrsr )
    2129             : {
    2130          47 :     if( bChg )
    2131             :     {
    2132          47 :         if( bParked )
    2133             :         {
    2134             :             // move back into content
    2135           0 :             Exchange();
    2136           0 :             Move( fnMoveForward );
    2137           0 :             Exchange();
    2138           0 :             Move( fnMoveForward );
    2139           0 :             bParked = sal_False;
    2140             :         }
    2141             : 
    2142          47 :         bChg = sal_False;
    2143             : 
    2144             :         // create temporary copies so that all boxes that
    2145             :         // have already cursors can be removed
    2146          47 :         SwSelBoxes aTmp(m_SelectedBoxes);
    2147             : 
    2148             :         // compare old and new ones
    2149          47 :         SwNodes& rNds = pAktCrsr->GetDoc()->GetNodes();
    2150             :         const SwStartNode* pSttNd;
    2151          47 :         SwPaM* pCur = pAktCrsr;
    2152          58 :         do {
    2153             :             size_t nPos;
    2154          58 :             bool bDel = false;
    2155          58 :             pSttNd = pCur->GetPoint()->nNode.GetNode().FindTableBoxStartNode();
    2156          75 :             if( !pCur->HasMark() || !pSttNd ||
    2157          17 :                 pSttNd != pCur->GetMark()->nNode.GetNode().FindTableBoxStartNode() )
    2158          41 :                 bDel = true;
    2159             : 
    2160          17 :             else if( lcl_SeekEntry( aTmp, pSttNd, nPos ))
    2161             :             {
    2162           5 :                 SwNodeIndex aIdx( *pSttNd, 1 );
    2163           5 :                 const SwNode* pNd = &aIdx.GetNode();
    2164           5 :                 if( !pNd->IsCntntNode() )
    2165           0 :                     pNd = rNds.GoNextSection( &aIdx, true, false );
    2166             : 
    2167           5 :                 SwPosition* pPos = pCur->GetMark();
    2168           5 :                 if( pNd != &pPos->nNode.GetNode() )
    2169           0 :                     pPos->nNode = *pNd;
    2170           5 :                 pPos->nContent.Assign( (SwCntntNode*)pNd, 0 );
    2171             : 
    2172           5 :                 aIdx.Assign( *pSttNd->EndOfSectionNode(), - 1 );
    2173           5 :                 if( !( pNd = &aIdx.GetNode())->IsCntntNode() )
    2174           0 :                     pNd = rNds.GoPrevSection( &aIdx, true, false );
    2175             : 
    2176           5 :                 pPos = pCur->GetPoint();
    2177           5 :                 if( pNd != &pPos->nNode.GetNode() )
    2178           0 :                     pPos->nNode = *pNd;
    2179           5 :                 pPos->nContent.Assign( (SwCntntNode*)pNd, ((SwCntntNode*)pNd)->Len() );
    2180             : 
    2181           5 :                 aTmp.erase( aTmp.begin() + nPos );
    2182             :             }
    2183             :             else
    2184          12 :                 bDel = true;
    2185             : 
    2186          58 :             pCur = (SwPaM*)pCur->GetNext();
    2187          58 :             if( bDel )
    2188             :             {
    2189          53 :                 SwPaM* pDel = (SwPaM*)pCur->GetPrev();
    2190             : 
    2191          53 :                 if( pDel == pAktCrsr )
    2192          43 :                     pAktCrsr->DeleteMark();
    2193             :                 else
    2194          10 :                     delete pDel;
    2195             :             }
    2196             :         } while ( pAktCrsr != pCur );
    2197             : 
    2198         312 :         for (size_t nPos = 0; nPos < aTmp.size(); ++nPos)
    2199             :         {
    2200         265 :             pSttNd = aTmp[ nPos ]->GetSttNd();
    2201             : 
    2202         265 :             SwNodeIndex aIdx( *pSttNd, 1 );
    2203         265 :             if( &aIdx.GetNodes() != &rNds )
    2204           0 :                 break;
    2205         265 :             const SwNode* pNd = &aIdx.GetNode();
    2206         265 :             if( !pNd->IsCntntNode() )
    2207           0 :                 pNd = rNds.GoNextSection( &aIdx, true, false );
    2208             : 
    2209         336 :             SwPaM *const pNew = (pAktCrsr->GetNext() == pAktCrsr && !pAktCrsr->HasMark())
    2210             :                 ? pAktCrsr
    2211         488 :                 : pAktCrsr->Create( pAktCrsr );
    2212         265 :             pNew->GetPoint()->nNode = *pNd;
    2213         265 :             pNew->GetPoint()->nContent.Assign( (SwCntntNode*)pNd, 0 );
    2214         265 :             pNew->SetMark();
    2215             : 
    2216         265 :             SwPosition* pPos = pNew->GetPoint();
    2217         265 :             pPos->nNode.Assign( *pSttNd->EndOfSectionNode(), - 1 );
    2218         265 :             if( !( pNd = &pPos->nNode.GetNode())->IsCntntNode() )
    2219           0 :                 pNd = rNds.GoPrevSection( &pPos->nNode, true, false );
    2220             : 
    2221         265 :             pPos->nContent.Assign( (SwCntntNode*)pNd, ((SwCntntNode*)pNd)->Len() );
    2222         312 :         }
    2223             :     }
    2224          47 :     return pAktCrsr;
    2225             : }
    2226             : 
    2227         266 : void SwTableCursor::InsertBox( const SwTableBox& rTblBox )
    2228             : {
    2229         266 :     SwTableBox* pBox = (SwTableBox*)&rTblBox;
    2230         266 :     m_SelectedBoxes.insert(pBox);
    2231         266 :     bChg = sal_True;
    2232         266 : }
    2233             : 
    2234          16 : void SwTableCursor::DeleteBox(size_t const nPos)
    2235             : {
    2236          16 :     m_SelectedBoxes.erase(m_SelectedBoxes.begin() + nPos);
    2237          16 :     bChg = sal_True;
    2238          16 : }
    2239             : 
    2240         413 : bool SwTableCursor::NewTableSelection()
    2241             : {
    2242         413 :     bool bRet = false;
    2243         413 :     const SwNode *pStart = GetCntntNode()->FindTableBoxStartNode();
    2244         413 :     const SwNode *pEnd = GetCntntNode(false)->FindTableBoxStartNode();
    2245         413 :     if( pStart && pEnd )
    2246             :     {
    2247         413 :         const SwTableNode *pTableNode = pStart->FindTableNode();
    2248         826 :         if( pTableNode == pEnd->FindTableNode() &&
    2249         413 :             pTableNode->GetTable().IsNewModel() )
    2250             :         {
    2251         413 :             bRet = true;
    2252         413 :             SwSelBoxes aNew(m_SelectedBoxes);
    2253         413 :             pTableNode->GetTable().CreateSelection( pStart, pEnd, aNew,
    2254         413 :                 SwTable::SEARCH_NONE, false );
    2255         413 :             ActualizeSelection( aNew );
    2256             :         }
    2257             :     }
    2258         413 :     return bRet;
    2259             : }
    2260             : 
    2261         413 : void SwTableCursor::ActualizeSelection( const SwSelBoxes &rNew )
    2262             : {
    2263         413 :     size_t nOld = 0, nNew = 0;
    2264        2594 :     while (nOld < m_SelectedBoxes.size() && nNew < rNew.size())
    2265             :     {
    2266        1768 :         SwTableBox const*const pPOld = m_SelectedBoxes[ nOld ];
    2267        1768 :         const SwTableBox* pPNew = rNew[ nNew ];
    2268        1768 :         if( pPOld == pPNew )
    2269             :         {   // this box will stay
    2270        1758 :             ++nOld;
    2271        1758 :             ++nNew;
    2272             :         }
    2273          10 :         else if( pPOld->GetSttIdx() < pPNew->GetSttIdx() )
    2274             :         {
    2275           5 :             DeleteBox( nOld ); // this box has to go
    2276             :         }
    2277             :         else
    2278             :         {
    2279           5 :             InsertBox( *pPNew ); // this is a new one
    2280           5 :             ++nOld;
    2281           5 :             ++nNew;
    2282             :         }
    2283             :     }
    2284             : 
    2285         833 :     while (nOld < m_SelectedBoxes.size())
    2286             :     {
    2287           7 :         DeleteBox( nOld ); // some more to delete
    2288             :     }
    2289             : 
    2290         674 :     for ( ; nNew < rNew.size(); ++nNew ) // some more to insert
    2291             :     {
    2292         261 :         InsertBox( *rNew[ nNew ] );
    2293             :     }
    2294         413 : }
    2295             : 
    2296         193 : sal_Bool SwTableCursor::IsCrsrMovedUpdt()
    2297             : {
    2298         193 :     if( !IsCrsrMoved() )
    2299         185 :         return sal_False;
    2300             : 
    2301           8 :     nTblMkNd = GetMark()->nNode.GetIndex();
    2302           8 :     nTblPtNd = GetPoint()->nNode.GetIndex();
    2303           8 :     nTblMkCnt = GetMark()->nContent.GetIndex();
    2304           8 :     nTblPtCnt = GetPoint()->nContent.GetIndex();
    2305           8 :     return sal_True;
    2306             : }
    2307             : 
    2308             : /// park table cursor on the boxes' start node
    2309           0 : void SwTableCursor::ParkCrsr()
    2310             : {
    2311             :     // de-register index from text node
    2312           0 :     SwNode* pNd = &GetPoint()->nNode.GetNode();
    2313           0 :     if( !pNd->IsStartNode() )
    2314           0 :         pNd = pNd->StartOfSectionNode();
    2315           0 :     GetPoint()->nNode = *pNd;
    2316           0 :     GetPoint()->nContent.Assign( 0, 0 );
    2317             : 
    2318           0 :     pNd = &GetMark()->nNode.GetNode();
    2319           0 :     if( !pNd->IsStartNode() )
    2320           0 :         pNd = pNd->StartOfSectionNode();
    2321           0 :     GetMark()->nNode = *pNd;
    2322           0 :     GetMark()->nContent.Assign( 0, 0 );
    2323             : 
    2324           0 :     bChg = sal_True;
    2325           0 :     bParked = sal_True;
    2326           0 : }
    2327             : 
    2328          18 : sal_Bool SwTableCursor::HasReadOnlyBoxSel() const
    2329             : {
    2330          18 :     sal_Bool bRet = sal_False;
    2331          88 :     for (size_t n = m_SelectedBoxes.size(); n; )
    2332             :     {
    2333          52 :         if (m_SelectedBoxes[--n]->GetFrmFmt()->GetProtect().IsCntntProtected())
    2334             :         {
    2335           0 :             bRet = sal_True;
    2336           0 :             break;
    2337             :         }
    2338             :     }
    2339          18 :     return bRet;
    2340             : }
    2341             : 
    2342             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10