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

Generated by: LCOV version 1.10