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

Generated by: LCOV version 1.11