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

Generated by: LCOV version 1.10