LCOV - code coverage report
Current view: top level - sw/source/core/crsr - crsrsh.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 709 1753 40.4 %
Date: 2014-04-11 Functions: 65 121 53.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <com/sun/star/util/SearchOptions.hpp>
      21             : #include <com/sun/star/text/XTextRange.hpp>
      22             : 
      23             : #include <hintids.hxx>
      24             : #include <svx/svdmodel.hxx>
      25             : #include <editeng/frmdiritem.hxx>
      26             : #include <SwSmartTagMgr.hxx>
      27             : #include <doc.hxx>
      28             : #include <rootfrm.hxx>
      29             : #include <pagefrm.hxx>
      30             : #include <cntfrm.hxx>
      31             : #include <viewimp.hxx>
      32             : #include <pam.hxx>
      33             : #include <swselectionlist.hxx>
      34             : #include <IBlockCursor.hxx>
      35             : #include "BlockCursor.hxx"
      36             : #include <ndtxt.hxx>
      37             : #include <flyfrm.hxx>
      38             : #include <dview.hxx>
      39             : #include <viewopt.hxx>
      40             : #include <frmtool.hxx>
      41             : #include <crsrsh.hxx>
      42             : #include <tabfrm.hxx>
      43             : #include <txtfrm.hxx>
      44             : #include <sectfrm.hxx>
      45             : #include <swtable.hxx>
      46             : #include <callnk.hxx>
      47             : #include <viscrs.hxx>
      48             : #include <section.hxx>
      49             : #include <docsh.hxx>
      50             : #include <scriptinfo.hxx>
      51             : #include <globdoc.hxx>
      52             : #include <pamtyp.hxx>
      53             : #include <mdiexp.hxx>
      54             : #include <fmteiro.hxx>
      55             : #include <wrong.hxx>
      56             : #include <unotextrange.hxx>
      57             : #include <vcl/svapp.hxx>
      58             : #include <vcl/settings.hxx>
      59             : #include <numrule.hxx>
      60             : #include <IGrammarContact.hxx>
      61             : #include <comphelper/flagguard.hxx>
      62             : #include <globals.hrc>
      63             : #include <comcore.hrc>
      64             : 
      65             : #if defined(ANDROID) || defined(IOS)
      66             : #include <touch/touch.h>
      67             : #endif
      68             : 
      69             : using namespace com::sun::star;
      70             : using namespace util;
      71             : 
      72      363099 : TYPEINIT2(SwCrsrShell,SwViewShell,SwModify);
      73             : 
      74             : /**
      75             :  * Delete all overlapping Cursors from a Cursor ring.
      76             :  * @param pointer to SwCursor (ring)
      77             :  */
      78             : void CheckRange( SwCursor* );
      79             : 
      80             : /**
      81             :  * Check if pCurCrsr points into already existing ranges and delete those.
      82             :  * @param Pointer to SwCursor object
      83             :  */
      84       27352 : void CheckRange( SwCursor* pCurCrsr )
      85             : {
      86       27352 :     const SwPosition *pStt = pCurCrsr->Start(),
      87       27352 :         *pEnd = pCurCrsr->GetPoint() == pStt ? pCurCrsr->GetMark() : pCurCrsr->GetPoint();
      88             : 
      89       27352 :     SwPaM *pTmpDel = 0,
      90       27352 :           *pTmp = (SwPaM*)pCurCrsr->GetNext();
      91             : 
      92             :     // Search the complete ring
      93       54716 :     while( pTmp != pCurCrsr )
      94             :     {
      95          12 :         const SwPosition *pTmpStt = pTmp->Start(),
      96          12 :                         *pTmpEnd = pTmp->GetPoint() == pTmpStt ?
      97          12 :                                         pTmp->GetMark() : pTmp->GetPoint();
      98          12 :         if( *pStt <= *pTmpStt )
      99             :         {
     100          24 :             if( *pEnd > *pTmpStt ||
     101          11 :                 ( *pEnd == *pTmpStt && *pEnd == *pTmpEnd ))
     102           1 :                 pTmpDel = pTmp;
     103             :         }
     104             :         else
     105           0 :             if( *pStt < *pTmpEnd )
     106           0 :                 pTmpDel = pTmp;
     107             : 
     108             :          // If Point or Mark is within the Crsr range, we need to remove the old
     109             :         // range. Take note that Point does not belong to the range anymore.
     110          12 :         pTmp = (SwPaM*)pTmp->GetNext();
     111          12 :         delete pTmpDel;         // Remove old range
     112          12 :         pTmpDel = 0;
     113             :     }
     114       27352 : }
     115             : 
     116             : // SwCrsrShell
     117             : 
     118           0 : SwPaM * SwCrsrShell::CreateCrsr()
     119             : {
     120             :     // don't create Crsr in a table Selection (sic!)
     121             :     OSL_ENSURE( !IsTableMode(), "in table Selection" );
     122             : 
     123             :     // New cursor as copy of current one. Add to the ring.
     124             :     // Links point to previously created one, ie forward.
     125           0 :     SwShellCrsr* pNew = new SwShellCrsr( *m_pCurCrsr );
     126             : 
     127             :     // Hide PaM logically, to avoid undoing the inverting from
     128             :     // copied PaM (#i75172#)
     129           0 :     pNew->swapContent(*m_pCurCrsr);
     130             : 
     131           0 :     m_pCurCrsr->DeleteMark();
     132             : 
     133           0 :     UpdateCrsr( SwCrsrShell::SCROLLWIN );
     134           0 :     return pNew;
     135             : }
     136             : 
     137             : /**
     138             :  * Delete current Cursor, making the following one the current.
     139             :  * Note, this function does not delete anything if there is no other cursor.
     140             :  * @return - returns true if there was another cursor and we deleted one.
     141             :  */
     142           0 : bool SwCrsrShell::DestroyCrsr()
     143             : {
     144             :     // don't delete Crsr within table selection
     145             :     OSL_ENSURE( !IsTableMode(), "in table Selection" );
     146             : 
     147             :     // Is there a next one? Don't do anything if not.
     148           0 :     if(m_pCurCrsr->GetNext() == m_pCurCrsr)
     149           0 :         return false;
     150             : 
     151           0 :     SwCallLink aLk( *this ); // watch Crsr-Moves
     152           0 :     SwCursor* pNextCrsr = (SwCursor*)m_pCurCrsr->GetNext();
     153           0 :     delete m_pCurCrsr;
     154           0 :     m_pCurCrsr = dynamic_cast<SwShellCrsr*>(pNextCrsr);
     155           0 :     UpdateCrsr();
     156           0 :     return true;
     157             : }
     158             : 
     159             : /**
     160             :  * Create and return a new shell cursor.
     161             :  * Simply returns the current shell cursor if there is no selection
     162             :  * (HasSelection()).
     163             :  */
     164           8 : SwPaM & SwCrsrShell::CreateNewShellCursor()
     165             : {
     166           8 :     if (HasSelection())
     167             :     {
     168           0 :         (void) CreateCrsr(); // n.b. returns old cursor
     169             :     }
     170           8 :     return *GetCrsr();
     171             : }
     172             : 
     173             : /**
     174             :  * Return the current shell cursor
     175             :  * @return - returns current `SwPaM` shell cursor
     176             :  */
     177           0 : SwPaM & SwCrsrShell::GetCurrentShellCursor()
     178             : {
     179           0 :     return *GetCrsr();
     180             : }
     181             : 
     182             : /**
     183             :  * Return pointer to the current shell cursor
     184             :  * @return - returns pointer to current `SwPaM` shell cursor
     185             :  */
     186      222941 : SwPaM* SwCrsrShell::GetCrsr( sal_Bool bMakeTblCrsr ) const
     187             : {
     188      222941 :     if( m_pTblCrsr )
     189             :     {
     190         198 :         if( bMakeTblCrsr && m_pTblCrsr->IsCrsrMovedUpdt() )
     191             :         {
     192             :             //don't re-create 'parked' cursors
     193             :             const SwCntntNode* pCNd;
     194          15 :             if( m_pTblCrsr->GetPoint()->nNode.GetIndex() &&
     195          10 :                 m_pTblCrsr->GetMark()->nNode.GetIndex() &&
     196          15 :                 0 != ( pCNd = m_pTblCrsr->GetCntntNode() ) && pCNd->getLayoutFrm( GetLayout() ) &&
     197          15 :                 0 != ( pCNd = m_pTblCrsr->GetCntntNode(false) ) && pCNd->getLayoutFrm( GetLayout() ) )
     198             :             {
     199           5 :                 SwShellTableCrsr* pTC = (SwShellTableCrsr*)m_pTblCrsr;
     200           5 :                 GetLayout()->MakeTblCrsrs( *pTC );
     201             :             }
     202             :         }
     203             : 
     204         198 :         if( m_pTblCrsr->IsChgd() )
     205             :         {
     206             :             const_cast<SwCrsrShell*>(this)->m_pCurCrsr =
     207           8 :                 dynamic_cast<SwShellCrsr*>(m_pTblCrsr->MakeBoxSels( m_pCurCrsr ));
     208             :         }
     209             :     }
     210      222941 :     return m_pCurCrsr;
     211             : }
     212             : 
     213       41265 : void SwCrsrShell::StartAction()
     214             : {
     215       41265 :     if( !ActionPend() )
     216             :     {
     217             :         // save for update of the ribbon bar
     218       25678 :         const SwNode& rNd = m_pCurCrsr->GetPoint()->nNode.GetNode();
     219       25678 :         m_nAktNode = rNd.GetIndex();
     220       25678 :         m_nAktCntnt = m_pCurCrsr->GetPoint()->nContent.GetIndex();
     221       25678 :         m_nAktNdTyp = rNd.GetNodeType();
     222       25678 :         m_bAktSelection = *m_pCurCrsr->GetPoint() != *m_pCurCrsr->GetMark();
     223       25678 :         if( rNd.IsTxtNode() )
     224       25678 :             m_nLeftFrmPos = SwCallLink::getLayoutFrm( GetLayout(), (SwTxtNode&)rNd, m_nAktCntnt, true );
     225             :         else
     226           0 :             m_nLeftFrmPos = 0;
     227             :     }
     228       41265 :     SwViewShell::StartAction(); // to the SwViewShell
     229       41265 : }
     230             : 
     231       41265 : void SwCrsrShell::EndAction( const sal_Bool bIdleEnd )
     232             : {
     233       41265 :     comphelper::FlagRestorationGuard g(mbSelectAll, StartsWithTable() && ExtendedSelectedAll(/*bFootnotes =*/ false));
     234       41265 :     sal_Bool bVis = m_bSVCrsrVis;
     235             : 
     236             :     // Idle-formatting?
     237       41265 :     if( bIdleEnd && Imp()->GetRegion() )
     238             :     {
     239           0 :         m_pCurCrsr->Hide();
     240             :     }
     241             : 
     242             :     // Update all invalid numberings before the last action
     243       41265 :     if( 1 == mnStartAction )
     244       25678 :         GetDoc()->UpdateNumRule();
     245             : 
     246             :     // #i76923#: Don't show the cursor in the SwViewShell::EndAction() - call.
     247             :     //           Only the UpdateCrsr shows the cursor.
     248       41265 :     sal_Bool bSavSVCrsrVis = m_bSVCrsrVis;
     249       41265 :     m_bSVCrsrVis = sal_False;
     250             : 
     251       41265 :     SwViewShell::EndAction( bIdleEnd );   // have SwViewShell go first
     252             : 
     253       41265 :     m_bSVCrsrVis = bSavSVCrsrVis;
     254             : 
     255       41265 :     if( ActionPend() )
     256             :     {
     257       15587 :         if( bVis )    // display SV-Cursor again
     258       15466 :             m_pVisCrsr->Show();
     259             : 
     260             :         // If there is still a ChgCall and just the "basic
     261             :         // parenthiszing(?) (Basic-Klammerung)" exists, call it. This
     262             :         // decouples the internal with the Basic-parenthising, the
     263             :         // Shells are switched.
     264       15587 :         if( !BasicActionPend() )
     265             :         {
     266             :             // Within a Basic action, one needs to update the cursor,
     267             :             // to e.g. create the table cursor. This is being done in
     268             :             // UpdateCrsr.
     269           0 :             UpdateCrsr( SwCrsrShell::CHKRANGE, bIdleEnd );
     270             : 
     271             :             {
     272             :                 // watch Crsr-Moves, call Link if needed, the DTOR is key here!
     273             :                 SwCallLink aLk( *this, m_nAktNode, m_nAktCntnt, (sal_uInt8)m_nAktNdTyp,
     274           0 :                                 m_nLeftFrmPos, m_bAktSelection );
     275             : 
     276             :             }
     277           0 :             if( m_bCallChgLnk && m_bChgCallFlag && m_aChgLnk.IsSet() )
     278             :             {
     279           0 :                 m_aChgLnk.Call( this );
     280           0 :                 m_bChgCallFlag = sal_False; // reset flag
     281             :             }
     282             :         }
     283       56852 :         return;
     284             :     }
     285             : 
     286       25678 :     sal_uInt16 nParm = SwCrsrShell::CHKRANGE;
     287       25678 :     if ( !bIdleEnd )
     288       23962 :         nParm |= SwCrsrShell::SCROLLWIN;
     289             : 
     290       25678 :     UpdateCrsr( nParm, bIdleEnd );      // Show Cursor changes
     291             : 
     292             :     {
     293       25678 :         SwCallLink aLk( *this );        // watch Crsr-Moves
     294       25678 :         aLk.nNode = m_nAktNode;           // call Link if needed
     295       25678 :         aLk.nNdTyp = (sal_uInt8)m_nAktNdTyp;
     296       25678 :         aLk.nCntnt = m_nAktCntnt;
     297       25678 :         aLk.nLeftFrmPos = m_nLeftFrmPos;
     298             : 
     299       25693 :         if( !m_nCrsrMove ||
     300          30 :             ( 1 == m_nCrsrMove && m_bInCMvVisportChgd ) )
     301             :             // display Cursor & Selektions again
     302       25666 :             ShowCrsrs( m_bSVCrsrVis ? sal_True : sal_False );
     303             :     }
     304             :     // call ChgCall if there is still one
     305       25678 :     if( m_bCallChgLnk && m_bChgCallFlag && m_aChgLnk.IsSet() )
     306             :     {
     307         595 :         m_aChgLnk.Call( this );
     308         595 :         m_bChgCallFlag = sal_False;       // reset flag
     309       25678 :     }
     310             : }
     311             : 
     312             : #ifdef DBG_UTIL
     313             : void SwCrsrShell::SttCrsrMove()
     314             : {
     315             :     OSL_ENSURE( m_nCrsrMove < USHRT_MAX, "To many nested CrsrMoves." );
     316             :     ++m_nCrsrMove;
     317             :     StartAction();
     318             : }
     319             : 
     320             : void SwCrsrShell::EndCrsrMove( const sal_Bool bIdleEnd )
     321             : {
     322             :     OSL_ENSURE( m_nCrsrMove, "EndCrsrMove() without SttCrsrMove()." );
     323             :     EndAction( bIdleEnd );
     324             :     if( !--m_nCrsrMove )
     325             :         m_bInCMvVisportChgd = sal_False;
     326             : }
     327             : #endif
     328             : 
     329          21 : sal_Bool SwCrsrShell::LeftRight( sal_Bool bLeft, sal_uInt16 nCnt, sal_uInt16 nMode,
     330             :                                  sal_Bool bVisualAllowed )
     331             : {
     332          21 :     if( IsTableMode() )
     333           0 :         return bLeft ? GoPrevCell() : GoNextCell();
     334             : 
     335          21 :     SwCallLink aLk( *this ); // watch Crsr-Moves; call Link if needed
     336          21 :     sal_Bool bRet = sal_False;
     337             : 
     338             :     // #i27615# Handle cursor in front of label.
     339          21 :     const SwTxtNode* pTxtNd = 0;
     340             : 
     341          21 :     if( m_pBlockCrsr )
     342           0 :         m_pBlockCrsr->clearPoints();
     343             : 
     344             :     // 1. CASE: Cursor is in front of label. A move to the right
     345             :     // will simply reset the bInFrontOfLabel flag:
     346          21 :     SwShellCrsr* pShellCrsr = getShellCrsr( true );
     347          21 :     if ( !bLeft && pShellCrsr->IsInFrontOfLabel() )
     348             :     {
     349           0 :         SetInFrontOfLabel( false );
     350           0 :         bRet = sal_True;
     351             :     }
     352             :     // 2. CASE: Cursor is at beginning of numbered paragraph. A move
     353             :     // to the left will simply set the bInFrontOfLabel flag:
     354          32 :     else if ( bLeft && 0 == pShellCrsr->GetPoint()->nContent.GetIndex() &&
     355           3 :              !pShellCrsr->IsInFrontOfLabel() && !pShellCrsr->HasMark() &&
     356          23 :              0 != ( pTxtNd = pShellCrsr->GetNode()->GetTxtNode() ) &&
     357           1 :              pTxtNd->HasVisibleNumberingOrBullet() )
     358             :     {
     359           0 :         SetInFrontOfLabel( true );
     360           0 :         bRet = sal_True;
     361             :     }
     362             :     // 3. CASE: Regular cursor move. Reset the bInFrontOfLabel flag:
     363             :     else
     364             :     {
     365          21 :         const sal_Bool bSkipHidden = !GetViewOptions()->IsShowHiddenChar();
     366             :         // #i107447#
     367             :         // To avoid loop the reset of <bInFrontOfLabel> flag is no longer
     368             :         // reflected in the return value <bRet>.
     369          21 :         const bool bResetOfInFrontOfLabel = SetInFrontOfLabel( false );
     370             :         bRet = pShellCrsr->LeftRight( bLeft, nCnt, nMode, bVisualAllowed,
     371          21 :                                       bSkipHidden, !IsOverwriteCrsr() );
     372          21 :         if ( !bRet && bLeft && bResetOfInFrontOfLabel )
     373             :         {
     374             :             // undo reset of <bInFrontOfLabel> flag
     375           0 :             SetInFrontOfLabel( true );
     376             :         }
     377             :     }
     378             : 
     379          21 :     if( bRet )
     380             :     {
     381          18 :         UpdateCrsr();
     382             :     }
     383             : 
     384          21 :     return bRet;
     385             : }
     386             : 
     387           0 : void SwCrsrShell::MarkListLevel( const OUString& sListId,
     388             :                                  const int nListLevel )
     389             : {
     390           0 :     if ( sListId != m_sMarkedListId ||
     391           0 :          nListLevel != m_nMarkedListLevel)
     392             :     {
     393           0 :         if ( !m_sMarkedListId.isEmpty() )
     394           0 :             mpDoc->MarkListLevel( m_sMarkedListId, m_nMarkedListLevel, false );
     395             : 
     396           0 :         if ( !sListId.isEmpty() )
     397             :         {
     398           0 :             mpDoc->MarkListLevel( sListId, nListLevel, true );
     399             :         }
     400             : 
     401           0 :         m_sMarkedListId = sListId;
     402           0 :         m_nMarkedListLevel = nListLevel;
     403             :     }
     404           0 : }
     405             : 
     406           0 : void SwCrsrShell::UpdateMarkedListLevel()
     407             : {
     408           0 :     SwTxtNode * pTxtNd = _GetCrsr()->GetNode()->GetTxtNode();
     409             : 
     410           0 :     if ( pTxtNd )
     411             :     {
     412           0 :         if ( !pTxtNd->IsNumbered() )
     413             :         {
     414           0 :             m_pCurCrsr->_SetInFrontOfLabel( false );
     415           0 :             MarkListLevel( OUString(), 0 );
     416             :         }
     417           0 :         else if ( m_pCurCrsr->IsInFrontOfLabel() )
     418             :         {
     419           0 :             if ( pTxtNd->IsInList() )
     420             :             {
     421             :                 OSL_ENSURE( pTxtNd->GetActualListLevel() >= 0 &&
     422             :                         pTxtNd->GetActualListLevel() < MAXLEVEL, "Which level?");
     423             :                 MarkListLevel( pTxtNd->GetListId(),
     424           0 :                                pTxtNd->GetActualListLevel() );
     425             :             }
     426             :         }
     427             :         else
     428             :         {
     429           0 :             MarkListLevel( OUString(), 0 );
     430             :         }
     431             :     }
     432           0 : }
     433             : 
     434           6 : void SwCrsrShell::FirePageChangeEvent(sal_uInt16 nOldPage, sal_uInt16 nNewPage)
     435             : {
     436             : #ifdef ACCESSIBLE_LAYOUT
     437             :     if( Imp()->IsAccessible() )
     438             :         Imp()->FirePageChangeEvent( nOldPage, nNewPage );
     439             : #else
     440             :     (void)nOldPage;
     441             :     (void)nNewPage;
     442             : #endif
     443           6 : }
     444             : 
     445           0 : void SwCrsrShell::FireColumnChangeEvent(sal_uInt16 nOldColumn, sal_uInt16 nNewColumn)
     446             : {
     447             : #ifdef ACCESSIBLE_LAYOUT
     448             :     if( Imp()->IsAccessible() )
     449             :         Imp()->FireColumnChangeEvent( nOldColumn,  nNewColumn);
     450             : #else
     451             :     (void)nOldColumn;
     452             :     (void)nNewColumn;
     453             : #endif
     454           0 : }
     455             : 
     456           0 : void SwCrsrShell::FireSectionChangeEvent(sal_uInt16 nOldSection, sal_uInt16 nNewSection)
     457             : {
     458             : #ifdef ACCESSIBLE_LAYOUT
     459             :     if( Imp()->IsAccessible() )
     460             :         Imp()->FireSectionChangeEvent( nOldSection, nNewSection );
     461             : #else
     462             :     (void)nOldSection;
     463             :     (void)nNewSection;
     464             : #endif
     465           0 : }
     466             : 
     467        5186 : bool SwCrsrShell::bColumnChange()
     468             : {
     469        5186 :     SwFrm* pCurrFrm = GetCurrFrm(sal_False);
     470             : 
     471        5186 :     if (pCurrFrm == NULL)
     472             :     {
     473           0 :         return false;
     474             :     }
     475             : 
     476        5186 :     SwFrm* pCurrCol=((SwFrm*)pCurrFrm)->FindColFrm();
     477             : 
     478       25939 :     while(pCurrCol== NULL && pCurrFrm!=NULL )
     479             :     {
     480       20753 :         SwLayoutFrm* pParent = pCurrFrm->GetUpper();
     481       20753 :         if(pParent!=NULL)
     482             :         {
     483       15567 :             pCurrCol=((SwFrm*)pParent)->FindColFrm();
     484       15567 :             pCurrFrm = (SwFrm*)pParent;
     485             :         }
     486             :         else
     487             :         {
     488        5186 :             break;
     489             :         }
     490             :     }
     491             : 
     492        5186 :     if(m_oldColFrm == pCurrCol)
     493        5186 :         return false;
     494             :     else
     495             :     {
     496           0 :         m_oldColFrm = pCurrCol;
     497           0 :         return true;
     498             :     }
     499             : }
     500             : 
     501           0 : bool SwCrsrShell::UpDown( bool bUp, sal_uInt16 nCnt )
     502             : {
     503           0 :     SET_CURR_SHELL( this );
     504           0 :     SwCallLink aLk( *this ); // watch Crsr-Moves; call Link if needed
     505             : 
     506           0 :     sal_Bool bTableMode = IsTableMode();
     507           0 :     SwShellCrsr* pTmpCrsr = getShellCrsr( true );
     508             : 
     509           0 :     bool bRet = pTmpCrsr->UpDown( bUp, nCnt );
     510             :     // #i40019# UpDown should always reset the bInFrontOfLabel flag:
     511           0 :     bRet |= SetInFrontOfLabel(false);
     512             : 
     513           0 :     if( m_pBlockCrsr )
     514           0 :         m_pBlockCrsr->clearPoints();
     515             : 
     516           0 :     if( bRet )
     517             :     {
     518           0 :         m_eMvState = MV_UPDOWN; // status for Crsr travelling - GetCrsrOfst
     519           0 :         if( !ActionPend() )
     520             :         {
     521           0 :             CrsrFlag eUpdtMode = SwCrsrShell::SCROLLWIN;
     522           0 :             if( !bTableMode )
     523             :                 eUpdtMode = (CrsrFlag) (eUpdtMode
     524           0 :                             | SwCrsrShell::UPDOWN | SwCrsrShell::CHKRANGE);
     525           0 :             UpdateCrsr( static_cast<sal_uInt16>(eUpdtMode) );
     526             :         }
     527             :     }
     528           0 :     return bRet;
     529             : }
     530             : 
     531           0 : sal_Bool SwCrsrShell::LRMargin( sal_Bool bLeft, sal_Bool bAPI)
     532             : {
     533           0 :     SwCallLink aLk( *this ); // watch Crsr-Moves; call Link if needed
     534           0 :     SET_CURR_SHELL( this );
     535           0 :     m_eMvState = MV_LEFTMARGIN; // status for Crsr travelling - GetCrsrOfst
     536             : 
     537           0 :     const sal_Bool bTableMode = IsTableMode();
     538           0 :     SwShellCrsr* pTmpCrsr = getShellCrsr( true );
     539             : 
     540           0 :     if( m_pBlockCrsr )
     541           0 :         m_pBlockCrsr->clearPoints();
     542             : 
     543             :     const bool bWasAtLM =
     544           0 :             ( 0 == _GetCrsr()->GetPoint()->nContent.GetIndex() );
     545             : 
     546           0 :     sal_Bool bRet = pTmpCrsr->LeftRightMargin( bLeft, bAPI );
     547             : 
     548           0 :     if ( bLeft && !bTableMode && bRet && bWasAtLM && !_GetCrsr()->HasMark() )
     549             :     {
     550           0 :         const SwTxtNode * pTxtNd = _GetCrsr()->GetNode()->GetTxtNode();
     551           0 :         if ( pTxtNd && pTxtNd->HasVisibleNumberingOrBullet() )
     552           0 :             SetInFrontOfLabel( true );
     553             :     }
     554           0 :     else if ( !bLeft )
     555             :     {
     556           0 :         bRet = SetInFrontOfLabel( false ) || bRet;
     557             :     }
     558             : 
     559           0 :     if( bRet )
     560             :     {
     561           0 :         UpdateCrsr();
     562             :     }
     563           0 :     return bRet;
     564             : }
     565             : 
     566           0 : sal_Bool SwCrsrShell::IsAtLRMargin( sal_Bool bLeft, sal_Bool bAPI ) const
     567             : {
     568           0 :     const SwShellCrsr* pTmpCrsr = getShellCrsr( true );
     569           0 :     return pTmpCrsr->IsAtLeftRightMargin( bLeft, bAPI );
     570             : }
     571             : 
     572          44 : sal_Bool SwCrsrShell::SttEndDoc( sal_Bool bStt )
     573             : {
     574          44 :     SwCallLink aLk( *this ); // watch Crsr-Moves; call Link if needed
     575             : 
     576          44 :     SwShellCrsr* pTmpCrsr = m_pBlockCrsr ? &m_pBlockCrsr->getShellCrsr() : m_pCurCrsr;
     577          44 :     sal_Bool bRet = pTmpCrsr->SttEndDoc( bStt );
     578          44 :     if( bRet )
     579             :     {
     580          44 :         if( bStt )
     581          11 :             pTmpCrsr->GetPtPos().Y() = 0; // set to 0 explicitly (table header)
     582          44 :         if( m_pBlockCrsr )
     583             :         {
     584           0 :             m_pBlockCrsr->clearPoints();
     585           0 :             RefreshBlockCursor();
     586             :         }
     587             : 
     588          44 :         UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
     589             :     }
     590          44 :     return bRet;
     591             : }
     592             : 
     593           8 : void SwCrsrShell::ExtendedSelectAll(bool bFootnotes)
     594             : {
     595           8 :     SwNodes& rNodes = GetDoc()->GetNodes();
     596           8 :     SwPosition* pPos = m_pCurCrsr->GetPoint();
     597           8 :     pPos->nNode = bFootnotes ? rNodes.GetEndOfPostIts() : rNodes.GetEndOfAutotext();
     598           8 :     pPos->nContent.Assign( rNodes.GoNext( &pPos->nNode ), 0 );
     599           8 :     pPos = m_pCurCrsr->GetMark();
     600           8 :     pPos->nNode = rNodes.GetEndOfContent();
     601           8 :     SwCntntNode* pCNd = rNodes.GoPrevious( &pPos->nNode );
     602           8 :     pPos->nContent.Assign( pCNd, pCNd ? pCNd->Len() : 0 );
     603           8 : }
     604             : 
     605        2085 : bool SwCrsrShell::ExtendedSelectedAll(bool bFootnotes)
     606             : {
     607        2085 :     SwNodes& rNodes = GetDoc()->GetNodes();
     608        2085 :     SwNodeIndex nNode = bFootnotes ? rNodes.GetEndOfPostIts() : rNodes.GetEndOfAutotext();
     609        2085 :     SwCntntNode* pStart = rNodes.GoNext(&nNode);
     610             : 
     611        2085 :     nNode = rNodes.GetEndOfContent();
     612        2085 :     SwCntntNode* pEnd = rNodes.GoPrevious(&nNode);
     613             : 
     614        2085 :     if (!pStart || !pEnd)
     615           0 :         return false;
     616             : 
     617        4170 :     SwPosition aStart(*pStart, 0);
     618        4170 :     SwPosition aEnd(*pEnd, pEnd->Len());
     619        2085 :     SwShellCrsr* pShellCrsr = getShellCrsr(false);
     620        4170 :     return aStart == *pShellCrsr->Start() && aEnd == *pShellCrsr->End();
     621             : }
     622             : 
     623       45118 : bool SwCrsrShell::StartsWithTable()
     624             : {
     625       45118 :     SwNodes& rNodes = GetDoc()->GetNodes();
     626       45118 :     SwNodeIndex nNode(rNodes.GetEndOfExtras());
     627       45118 :     SwCntntNode* pCntntNode = rNodes.GoNext(&nNode);
     628       45118 :     return pCntntNode->FindTableNode();
     629             : }
     630             : 
     631          27 : sal_Bool SwCrsrShell::MovePage( SwWhichPage fnWhichPage, SwPosPage fnPosPage )
     632             : {
     633          27 :     sal_Bool bRet = sal_False;
     634             : 
     635             :     // never jump of section borders at selection
     636          27 :     if( !m_pCurCrsr->HasMark() || !m_pCurCrsr->IsNoCntnt() )
     637             :     {
     638          27 :         SwCallLink aLk( *this ); // watch Crsr-Moves; call Link if needed
     639          54 :         SET_CURR_SHELL( this );
     640             : 
     641          54 :         SwCrsrSaveState aSaveState( *m_pCurCrsr );
     642          27 :         Point& rPt = m_pCurCrsr->GetPtPos();
     643             :         SwCntntFrm * pFrm = m_pCurCrsr->GetCntntNode()->
     644          27 :                             getLayoutFrm( GetLayout(), &rPt, m_pCurCrsr->GetPoint(), false );
     645          54 :         if( pFrm && sal_True == ( bRet = GetFrmInPage( pFrm, fnWhichPage,
     646          54 :                                                 fnPosPage, m_pCurCrsr )  ) &&
     647             :             !m_pCurCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE |
     648          27 :                                  nsSwCursorSelOverFlags::SELOVER_CHANGEPOS ))
     649          27 :             UpdateCrsr();
     650             :         else
     651          27 :             bRet = sal_False;
     652             :     }
     653          27 :     return bRet;
     654             : }
     655             : 
     656       27344 : bool SwCrsrShell::isInHiddenTxtFrm(SwShellCrsr* pShellCrsr)
     657             : {
     658       27344 :     SwCntntNode *pCNode = pShellCrsr->GetCntntNode();
     659             :     SwCntntFrm  *pFrm = pCNode ?
     660       27344 :         pCNode->getLayoutFrm( GetLayout(), &pShellCrsr->GetPtPos(), pShellCrsr->GetPoint(), false ) : 0;
     661       27344 :     return !pFrm || (pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsHiddenNow());
     662             : }
     663             : 
     664           0 : sal_Bool SwCrsrShell::MovePara(SwWhichPara fnWhichPara, SwPosPara fnPosPara )
     665             : {
     666           0 :     SwCallLink aLk( *this ); // watch Crsr-Moves; call Link if needed
     667           0 :     SwShellCrsr* pTmpCrsr = getShellCrsr( true );
     668           0 :     sal_Bool bRet = pTmpCrsr->MovePara( fnWhichPara, fnPosPara );
     669           0 :     if( bRet )
     670             :     {
     671             :         //keep going until we get something visible, i.e. skip
     672             :         //over hidden paragraphs, don't get stuck at the start
     673             :         //which is what SwCrsrShell::UpdateCrsrPos will reset
     674             :         //the position to if we pass it a position in an
     675             :         //invisible hidden paragraph field
     676           0 :         while (isInHiddenTxtFrm(pTmpCrsr))
     677             :         {
     678           0 :             if (!pTmpCrsr->MovePara(fnWhichPara, fnPosPara))
     679           0 :                 break;
     680             :         }
     681             : 
     682           0 :         UpdateCrsr();
     683             :     }
     684           0 :     return bRet;
     685             : }
     686             : 
     687          29 : sal_Bool SwCrsrShell::MoveSection( SwWhichSection fnWhichSect,
     688             :                                 SwPosSection fnPosSect)
     689             : {
     690          29 :     SwCallLink aLk( *this ); // watch Crsr-Moves; call Link if needed
     691          29 :     SwCursor* pTmpCrsr = getShellCrsr( true );
     692          29 :     sal_Bool bRet = pTmpCrsr->MoveSection( fnWhichSect, fnPosSect );
     693          29 :     if( bRet )
     694          14 :         UpdateCrsr();
     695          29 :     return bRet;
     696             : 
     697             : }
     698             : 
     699             : // position cursor
     700             : 
     701           0 : static SwFrm* lcl_IsInHeaderFooter( const SwNodeIndex& rIdx, Point& rPt )
     702             : {
     703           0 :     SwFrm* pFrm = 0;
     704           0 :     SwCntntNode* pCNd = rIdx.GetNode().GetCntntNode();
     705           0 :     if( pCNd )
     706             :     {
     707           0 :         SwCntntFrm *pCntFrm = pCNd->getLayoutFrm( pCNd->GetDoc()->GetCurrentLayout(), &rPt, 0, false );
     708           0 :         pFrm = pCntFrm ? pCntFrm->GetUpper() : NULL;
     709           0 :         while( pFrm && !pFrm->IsHeaderFrm() && !pFrm->IsFooterFrm() )
     710           0 :             pFrm = pFrm->IsFlyFrm() ? ((SwFlyFrm*)pFrm)->AnchorFrm()
     711           0 :                                     : pFrm->GetUpper();
     712             :     }
     713           0 :     return pFrm;
     714             : }
     715             : 
     716           0 : bool SwCrsrShell::IsInHeaderFooter( sal_Bool* pbInHeader ) const
     717             : {
     718           0 :     Point aPt;
     719           0 :     SwFrm* pFrm = ::lcl_IsInHeaderFooter( m_pCurCrsr->GetPoint()->nNode, aPt );
     720           0 :     if( pFrm && pbInHeader )
     721           0 :         *pbInHeader = pFrm->IsHeaderFrm();
     722           0 :     return 0 != pFrm;
     723             : }
     724             : 
     725           0 : int SwCrsrShell::SetCrsr( const Point &rLPt, sal_Bool bOnlyText, bool bBlock )
     726             : {
     727           0 :     SET_CURR_SHELL( this );
     728             : 
     729           0 :     SwShellCrsr* pCrsr = getShellCrsr( bBlock );
     730           0 :     SwPosition aPos( *pCrsr->GetPoint() );
     731           0 :     Point aPt( rLPt );
     732           0 :     Point & rAktCrsrPt = pCrsr->GetPtPos();
     733           0 :     SwCrsrMoveState aTmpState( IsTableMode() ? MV_TBLSEL :
     734           0 :                                     bOnlyText ?  MV_SETONLYTEXT : MV_NONE );
     735           0 :     aTmpState.bSetInReadOnly = IsReadOnlyAvailable();
     736             : 
     737           0 :     SwTxtNode * pTxtNd = pCrsr->GetNode()->GetTxtNode();
     738             : 
     739           0 :     if ( pTxtNd && !IsTableMode() &&
     740             :         // #i37515# No bInFrontOfLabel during selection
     741           0 :         !pCrsr->HasMark() &&
     742           0 :         pTxtNd->HasVisibleNumberingOrBullet() )
     743             :     {
     744           0 :         aTmpState.bInFrontOfLabel = sal_True; // #i27615#
     745             :     }
     746             :     else
     747             :     {
     748           0 :         aTmpState.bInFrontOfLabel = sal_False;
     749             :     }
     750             : 
     751           0 :     int bRet = CRSR_POSOLD |
     752           0 :                 ( GetLayout()->GetCrsrOfst( &aPos, aPt, &aTmpState )
     753           0 :                     ? 0 : CRSR_POSCHG );
     754             : 
     755           0 :     const bool bOldInFrontOfLabel = IsInFrontOfLabel();
     756           0 :     const bool bNewInFrontOfLabel = aTmpState.bInFrontOfLabel;
     757             : 
     758           0 :     pCrsr->SetCrsrBidiLevel( aTmpState.nCursorBidiLevel );
     759             : 
     760           0 :     if( MV_RIGHTMARGIN == aTmpState.eState )
     761           0 :         m_eMvState = MV_RIGHTMARGIN;
     762             :     // is the new position in header or footer?
     763           0 :     SwFrm* pFrm = lcl_IsInHeaderFooter( aPos.nNode, aPt );
     764           0 :     if( IsTableMode() && !pFrm && aPos.nNode.GetNode().StartOfSectionNode() ==
     765           0 :         pCrsr->GetPoint()->nNode.GetNode().StartOfSectionNode() )
     766             :         // same table column and not in header/footer -> back
     767           0 :         return bRet;
     768             : 
     769           0 :     if( m_pBlockCrsr && bBlock )
     770             :     {
     771           0 :         m_pBlockCrsr->setEndPoint( rLPt );
     772           0 :         if( !pCrsr->HasMark() )
     773           0 :             m_pBlockCrsr->setStartPoint( rLPt );
     774           0 :         else if( !m_pBlockCrsr->getStartPoint() )
     775           0 :             m_pBlockCrsr->setStartPoint( pCrsr->GetMkPos() );
     776             :     }
     777           0 :     if( !pCrsr->HasMark() )
     778             :     {
     779             :         // is at the same position and if in header/footer -> in the same
     780           0 :         if( aPos == *pCrsr->GetPoint() &&
     781             :             bOldInFrontOfLabel == bNewInFrontOfLabel )
     782             :         {
     783           0 :             if( pFrm )
     784             :             {
     785           0 :                 if( pFrm->Frm().IsInside( rAktCrsrPt ))
     786           0 :                     return bRet;
     787             :             }
     788           0 :             else if( aPos.nNode.GetNode().IsCntntNode() )
     789             :             {
     790             :                 // in the same frame?
     791           0 :                 SwFrm* pOld = ((SwCntntNode&)aPos.nNode.GetNode()).getLayoutFrm(
     792           0 :                                 GetLayout(), &m_aCharRect.Pos(), 0, false );
     793           0 :                 SwFrm* pNew = ((SwCntntNode&)aPos.nNode.GetNode()).getLayoutFrm(
     794           0 :                                 GetLayout(), &aPt, 0, false );
     795           0 :                 if( pNew == pOld )
     796           0 :                     return bRet;
     797             :             }
     798             :         }
     799             :     }
     800             :     else
     801             :     {
     802             :         // SSelection over not allowed sections or if in header/footer -> different
     803           0 :         if( !CheckNodesRange( aPos.nNode, pCrsr->GetMark()->nNode, true )
     804           0 :             || ( pFrm && !pFrm->Frm().IsInside( pCrsr->GetMkPos() ) ))
     805           0 :             return bRet;
     806             : 
     807             :         // is at same position but not in header/footer
     808           0 :         if( aPos == *pCrsr->GetPoint() )
     809           0 :             return bRet;
     810             :     }
     811             : 
     812           0 :     SwCallLink aLk( *this ); // watch Crsr-Moves; call Link if needed
     813           0 :     SwCrsrSaveState aSaveState( *pCrsr );
     814             : 
     815           0 :     *pCrsr->GetPoint() = aPos;
     816           0 :     rAktCrsrPt = aPt;
     817             : 
     818             :     // #i41424# Only update the marked number levels if necessary
     819             :     // Force update of marked number levels if necessary.
     820           0 :     if ( bNewInFrontOfLabel || bOldInFrontOfLabel )
     821           0 :         m_pCurCrsr->_SetInFrontOfLabel( !bNewInFrontOfLabel );
     822           0 :     SetInFrontOfLabel( bNewInFrontOfLabel );
     823             : 
     824           0 :     if( !pCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_CHANGEPOS ) )
     825             :     {
     826           0 :         sal_uInt16 nFlag = SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE;
     827           0 :         UpdateCrsr( nFlag );
     828           0 :         bRet &= ~CRSR_POSOLD;
     829             :     }
     830           0 :     else if( bOnlyText && !m_pCurCrsr->HasMark() )
     831             :     {
     832           0 :         if( FindValidCntntNode( bOnlyText ) )
     833             :         {
     834             :             // position cursor in a valid content
     835           0 :             if( aPos == *pCrsr->GetPoint() )
     836           0 :                 bRet = CRSR_POSOLD;
     837             :             else
     838             :             {
     839           0 :                 UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE );
     840           0 :                 bRet &= ~CRSR_POSOLD;
     841             :             }
     842             :         }
     843             :         else
     844             :         {
     845             :             // there is no valid content -> hide cursor
     846           0 :             m_pVisCrsr->Hide(); // always hide visible cursor
     847           0 :             m_eMvState = MV_NONE; // status for Crsr travelling
     848           0 :             m_bAllProtect = sal_True;
     849           0 :             if( GetDoc()->GetDocShell() )
     850             :             {
     851           0 :                 GetDoc()->GetDocShell()->SetReadOnlyUI( true );
     852           0 :                 CallChgLnk(); // notify UI
     853             :             }
     854             :         }
     855             :     }
     856           0 :     return bRet;
     857             : }
     858             : 
     859           1 : void SwCrsrShell::TblCrsrToCursor()
     860             : {
     861             :     OSL_ENSURE( m_pTblCrsr, "TblCrsrToCursor: Why?" );
     862           1 :     delete m_pTblCrsr, m_pTblCrsr = 0;
     863           1 : }
     864             : 
     865           0 : void SwCrsrShell::BlockCrsrToCrsr()
     866             : {
     867             :     OSL_ENSURE( m_pBlockCrsr, "BlockCrsrToCrsr: Why?" );
     868           0 :     if( m_pBlockCrsr && !HasSelection() )
     869             :     {
     870           0 :         SwPaM& rPam = m_pBlockCrsr->getShellCrsr();
     871           0 :         m_pCurCrsr->SetMark();
     872           0 :         *m_pCurCrsr->GetPoint() = *rPam.GetPoint();
     873           0 :         if( rPam.HasMark() )
     874           0 :             *m_pCurCrsr->GetMark() = *rPam.GetMark();
     875             :         else
     876           0 :             m_pCurCrsr->DeleteMark();
     877             :     }
     878           0 :     delete m_pBlockCrsr, m_pBlockCrsr = 0;
     879           0 : }
     880             : 
     881           0 : void SwCrsrShell::CrsrToBlockCrsr()
     882             : {
     883           0 :     if( !m_pBlockCrsr )
     884             :     {
     885           0 :         SwPosition aPos( *m_pCurCrsr->GetPoint() );
     886           0 :         m_pBlockCrsr = createBlockCursor( *this, aPos );
     887           0 :         SwShellCrsr &rBlock = m_pBlockCrsr->getShellCrsr();
     888           0 :         rBlock.GetPtPos() = m_pCurCrsr->GetPtPos();
     889           0 :         if( m_pCurCrsr->HasMark() )
     890             :         {
     891           0 :             rBlock.SetMark();
     892           0 :             *rBlock.GetMark() = *m_pCurCrsr->GetMark();
     893           0 :             rBlock.GetMkPos() = m_pCurCrsr->GetMkPos();
     894           0 :         }
     895             :     }
     896           0 :     m_pBlockCrsr->clearPoints();
     897           0 :     RefreshBlockCursor();
     898           0 : }
     899             : 
     900         126 : void SwCrsrShell::ClearMark()
     901             : {
     902             :     // is there any GetMark?
     903         126 :     if( m_pTblCrsr )
     904             :     {
     905           5 :         while( m_pCurCrsr->GetNext() != m_pCurCrsr )
     906           3 :             delete m_pCurCrsr->GetNext();
     907           1 :         m_pTblCrsr->DeleteMark();
     908             : 
     909           1 :         m_pCurCrsr->DeleteMark();
     910             : 
     911           1 :         *m_pCurCrsr->GetPoint() = *m_pTblCrsr->GetPoint();
     912           1 :         m_pCurCrsr->GetPtPos() = m_pTblCrsr->GetPtPos();
     913           1 :         delete m_pTblCrsr, m_pTblCrsr = 0;
     914           1 :         m_pCurCrsr->SwSelPaintRects::Show();
     915             :     }
     916             :     else
     917             :     {
     918         125 :         if( !m_pCurCrsr->HasMark() )
     919         208 :             return;
     920          43 :         m_pCurCrsr->DeleteMark();
     921          43 :         if( !m_nCrsrMove )
     922          42 :             m_pCurCrsr->SwSelPaintRects::Show();
     923             :     }
     924             : }
     925             : 
     926           0 : void SwCrsrShell::NormalizePam(sal_Bool bPointFirst)
     927             : {
     928           0 :     SwCallLink aLk( *this ); // watch Crsr-Moves; call Link if needed
     929           0 :     m_pCurCrsr->Normalize(bPointFirst);
     930           0 : }
     931             : 
     932           8 : void SwCrsrShell::SwapPam()
     933             : {
     934           8 :     SwCallLink aLk( *this ); // watch Crsr-Moves; call Link if needed
     935           8 :     m_pCurCrsr->Exchange();
     936           8 : }
     937             : 
     938             : //TODO: provide documentation
     939             : /** Search in the selected area for a Selection that covers the given point.
     940             : 
     941             :     If only a test run is made, then it checks if a SSelection exists but does
     942             :     not move the current cursor. In a normal run the cursor will be moved to the
     943             :     chosen SSelection.
     944             : 
     945             :     @param rPt      The point to search at.
     946             :     @param bTstOnly Should I only do a test run? If true so do not move cursor.
     947             :     @param bTstHit ???
     948             : */
     949           0 : sal_Bool SwCrsrShell::ChgCurrPam(
     950             :     const Point & rPt,
     951             :     sal_Bool bTstOnly,
     952             :     sal_Bool bTstHit )
     953             : {
     954           0 :     SET_CURR_SHELL( this );
     955             : 
     956             :     // check if the SPoint is in a table selection
     957           0 :     if( bTstOnly && m_pTblCrsr )
     958           0 :         return m_pTblCrsr->IsInside( rPt );
     959             : 
     960           0 :     SwCallLink aLk( *this ); // watch Crsr-Moves; call Link if needed
     961             :     // search position <rPt> in document
     962           0 :     SwPosition aPtPos( *m_pCurCrsr->GetPoint() );
     963           0 :     Point aPt( rPt );
     964             : 
     965           0 :     SwCrsrMoveState aTmpState( MV_NONE );
     966           0 :     aTmpState.bSetInReadOnly = IsReadOnlyAvailable();
     967           0 :     if ( !GetLayout()->GetCrsrOfst( &aPtPos, aPt, &aTmpState ) && bTstHit )
     968           0 :         return sal_False;
     969             : 
     970             :     // search in all selections for this position
     971           0 :     SwShellCrsr* pCmp = (SwShellCrsr*)m_pCurCrsr; // keep the pointer on cursor
     972           0 :     do {
     973           0 :         if( pCmp->HasMark() &&
     974           0 :             *pCmp->Start() <= aPtPos && *pCmp->End() > aPtPos )
     975             :         {
     976           0 :             if( bTstOnly || m_pCurCrsr == pCmp ) // is the current
     977           0 :                 return sal_True;               // return without update
     978             : 
     979           0 :             m_pCurCrsr = pCmp;
     980           0 :             UpdateCrsr(); // cursor is already at the right position
     981           0 :             return sal_True;
     982             :         }
     983           0 :     } while( m_pCurCrsr !=
     984           0 :         ( pCmp = dynamic_cast<SwShellCrsr*>(pCmp->GetNext()) ) );
     985           0 :     return sal_False;
     986             : }
     987             : 
     988         132 : void SwCrsrShell::KillPams()
     989             : {
     990             :     // Does any exist for deletion?
     991         132 :     if( !m_pTblCrsr && !m_pBlockCrsr && m_pCurCrsr->GetNext() == m_pCurCrsr )
     992         261 :         return;
     993             : 
     994           9 :     while( m_pCurCrsr->GetNext() != m_pCurCrsr )
     995           3 :         delete m_pCurCrsr->GetNext();
     996           3 :     m_pCurCrsr->SetColumnSelection( false );
     997             : 
     998           3 :     if( m_pTblCrsr )
     999             :     {
    1000             :         // delete the ring of cursors
    1001           3 :         m_pCurCrsr->DeleteMark();
    1002           3 :         *m_pCurCrsr->GetPoint() = *m_pTblCrsr->GetPoint();
    1003           3 :         m_pCurCrsr->GetPtPos() = m_pTblCrsr->GetPtPos();
    1004           3 :         delete m_pTblCrsr;
    1005           3 :         m_pTblCrsr = 0;
    1006             :     }
    1007           0 :     else if( m_pBlockCrsr )
    1008             :     {
    1009             :         // delete the ring of cursors
    1010           0 :         m_pCurCrsr->DeleteMark();
    1011           0 :         SwShellCrsr &rBlock = m_pBlockCrsr->getShellCrsr();
    1012           0 :         *m_pCurCrsr->GetPoint() = *rBlock.GetPoint();
    1013           0 :         m_pCurCrsr->GetPtPos() = rBlock.GetPtPos();
    1014           0 :         rBlock.DeleteMark();
    1015           0 :         m_pBlockCrsr->clearPoints();
    1016             :     }
    1017           3 :     UpdateCrsr( SwCrsrShell::SCROLLWIN );
    1018             : }
    1019             : 
    1020           0 : int SwCrsrShell::CompareCursor( CrsrCompareType eType ) const
    1021             : {
    1022           0 :     int nRet = 0;
    1023           0 :     const SwPosition *pFirst = 0, *pSecond = 0;
    1024           0 :     const SwPaM *pCur = GetCrsr(), *pStk = m_pCrsrStk;
    1025             :     // cursor on stack is needed if we compare against stack
    1026           0 :     if( pStk || ( eType == CurrPtCurrMk ) )
    1027             :     {
    1028           0 :         switch ( eType)
    1029             :         {
    1030             :         case StackPtStackMk:
    1031           0 :             pFirst = pStk->GetPoint();
    1032           0 :             pSecond = pStk->GetMark();
    1033           0 :             break;
    1034             :         case StackPtCurrPt:
    1035           0 :             pFirst = pStk->GetPoint();
    1036           0 :             pSecond = pCur->GetPoint();
    1037           0 :             break;
    1038             :         case StackPtCurrMk:
    1039           0 :             pFirst = pStk->GetPoint();
    1040           0 :             pSecond = pCur->GetMark();
    1041           0 :             break;
    1042             :         case StackMkCurrPt:
    1043           0 :             pFirst = pStk->GetMark();
    1044           0 :             pSecond = pCur->GetPoint();
    1045           0 :             break;
    1046             :         case StackMkCurrMk:
    1047           0 :             pFirst = pStk->GetMark();
    1048           0 :             pSecond = pStk->GetMark();
    1049           0 :             break;
    1050             :         case CurrPtCurrMk:
    1051           0 :             pFirst = pCur->GetPoint();
    1052           0 :             pSecond = pCur->GetMark();
    1053           0 :             break;
    1054             :         }
    1055             :     }
    1056           0 :     if( !pFirst || !pSecond )
    1057           0 :         nRet = INT_MAX;
    1058           0 :     else if( *pFirst < *pSecond )
    1059           0 :         nRet = -1;
    1060           0 :     else if( *pFirst == *pSecond )
    1061           0 :         nRet = 0;
    1062             :     else
    1063           0 :         nRet = 1;
    1064           0 :     return nRet;
    1065             : }
    1066             : 
    1067           0 : bool SwCrsrShell::IsSttPara() const
    1068           0 : {   return m_pCurCrsr->GetPoint()->nContent == 0; }
    1069             : 
    1070           0 : bool SwCrsrShell::IsEndPara() const
    1071           0 : {   return m_pCurCrsr->GetPoint()->nContent == m_pCurCrsr->GetCntntNode()->Len(); }
    1072             : 
    1073           0 : bool SwCrsrShell::IsEndOfTable() const
    1074             : {
    1075           0 :     if (IsTableMode() || IsBlockMode() || !IsEndPara())
    1076             :     {
    1077           0 :         return false;
    1078             :     }
    1079           0 :     SwTableNode const*const pTableNode( IsCrsrInTbl() );
    1080           0 :     if (!pTableNode)
    1081             :     {
    1082           0 :         return false;
    1083             :     }
    1084           0 :     SwEndNode const*const pEndTableNode(pTableNode->EndOfSectionNode());
    1085           0 :     SwNodeIndex const lastNode(*pEndTableNode, -2);
    1086             :     SAL_WARN_IF(!lastNode.GetNode().GetTxtNode(), "sw.core",
    1087             :             "text node expected");
    1088           0 :     return (lastNode == m_pCurCrsr->GetPoint()->nNode);
    1089             : }
    1090             : 
    1091          28 : bool SwCrsrShell::IsInFrontOfLabel() const
    1092             : {
    1093          28 :     return m_pCurCrsr->IsInFrontOfLabel();
    1094             : }
    1095             : 
    1096          28 : bool SwCrsrShell::SetInFrontOfLabel( bool bNew )
    1097             : {
    1098          28 :     if ( bNew != IsInFrontOfLabel() )
    1099             :     {
    1100           0 :         m_pCurCrsr->_SetInFrontOfLabel( bNew );
    1101           0 :         UpdateMarkedListLevel();
    1102           0 :         return true;
    1103             :     }
    1104          28 :     return false;
    1105             : }
    1106             : 
    1107           1 : sal_Bool SwCrsrShell::GotoPage( sal_uInt16 nPage )
    1108             : {
    1109           1 :     SET_CURR_SHELL( this );
    1110           2 :     SwCallLink aLk( *this ); // watch Crsr-Moves; call Link if needed
    1111           2 :     SwCrsrSaveState aSaveState( *m_pCurCrsr );
    1112           2 :     sal_Bool bRet = GetLayout()->SetCurrPage( m_pCurCrsr, nPage ) &&
    1113             :                     !m_pCurCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE |
    1114           2 :                                          nsSwCursorSelOverFlags::SELOVER_CHANGEPOS );
    1115           1 :     if( bRet )
    1116           1 :         UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
    1117           2 :     return bRet;
    1118             : }
    1119             : 
    1120           0 : sal_Bool SwCrsrShell::GetCharRectAt(SwRect& rRect, const SwPosition* pPos)
    1121             : {
    1122           0 :     SwCntntFrm* pFrm = GetCurrFrm();
    1123           0 :     return pFrm->GetCharRect( rRect, *pPos );
    1124             : }
    1125             : 
    1126         318 : void SwCrsrShell::GetPageNum( sal_uInt16 &rnPhyNum, sal_uInt16 &rnVirtNum,
    1127             :                               sal_Bool bAtCrsrPos, const sal_Bool bCalcFrm )
    1128             : {
    1129         318 :     SET_CURR_SHELL( this );
    1130             :     // page number: first visible page or the one at the cursor
    1131             :     const SwCntntFrm* pCFrm;
    1132         318 :     const SwPageFrm *pPg = 0;
    1133             : 
    1134         636 :     if( !bAtCrsrPos || 0 == (pCFrm = GetCurrFrm( bCalcFrm )) ||
    1135         318 :                        0 == (pPg   = pCFrm->FindPageFrm()) )
    1136             :     {
    1137           0 :         pPg = Imp()->GetFirstVisPage();
    1138           0 :         while( pPg && pPg->IsEmptyPage() )
    1139           0 :             pPg = (const SwPageFrm *)pPg->GetNext();
    1140             :     }
    1141             :     // pPg has to exist with a default of 1 for the special case "Writerstart"
    1142         318 :     rnPhyNum  = pPg? pPg->GetPhyPageNum() : 1;
    1143         318 :     rnVirtNum = pPg? pPg->GetVirtPageNum() : 1;
    1144         318 : }
    1145             : 
    1146           0 : sal_uInt16 SwCrsrShell::GetNextPrevPageNum( sal_Bool bNext )
    1147             : {
    1148           0 :     SET_CURR_SHELL( this );
    1149             :     // page number: first visible page or the one at the cursor
    1150           0 :     const SwPageFrm *pPg = Imp()->GetFirstVisPage();
    1151           0 :     if( pPg )
    1152             :     {
    1153           0 :         const SwTwips nPageTop = pPg->Frm().Top();
    1154             : 
    1155           0 :         if( bNext )
    1156             :         {
    1157             :             // go to next view layout row:
    1158           0 :             do
    1159             :             {
    1160           0 :                 pPg = (const SwPageFrm *)pPg->GetNext();
    1161             :             }
    1162           0 :             while( pPg && pPg->Frm().Top() == nPageTop );
    1163             : 
    1164           0 :             while( pPg && pPg->IsEmptyPage() )
    1165           0 :                 pPg = (const SwPageFrm *)pPg->GetNext();
    1166             :         }
    1167             :         else
    1168             :         {
    1169             :             // go to previous view layout row:
    1170           0 :             do
    1171             :             {
    1172           0 :                 pPg = (const SwPageFrm *)pPg->GetPrev();
    1173             :             }
    1174           0 :             while( pPg && pPg->Frm().Top() == nPageTop );
    1175             : 
    1176           0 :             while( pPg && pPg->IsEmptyPage() )
    1177           0 :                 pPg = (const SwPageFrm *)pPg->GetPrev();
    1178             :         }
    1179             :     }
    1180             :     // pPg has to exist with a default of 1 for the special case "Writerstart"
    1181           0 :     return pPg ? pPg->GetPhyPageNum() : USHRT_MAX;
    1182             : }
    1183             : 
    1184        1774 : sal_uInt16 SwCrsrShell::GetPageCnt()
    1185             : {
    1186        1774 :     SET_CURR_SHELL( this );
    1187             :     // return number of pages
    1188        1774 :     return GetLayout()->GetPageNum();
    1189             : }
    1190             : 
    1191             : /// go to the next SSelection
    1192           0 : sal_Bool SwCrsrShell::GoNextCrsr()
    1193             : {
    1194             :     // is there a ring of cursors?
    1195           0 :     if( m_pCurCrsr->GetNext() == m_pCurCrsr )
    1196           0 :         return sal_False;
    1197             : 
    1198           0 :     SET_CURR_SHELL( this );
    1199           0 :     SwCallLink aLk( *this ); // watch Crsr-Moves; call Link if needed
    1200           0 :     m_pCurCrsr = dynamic_cast<SwShellCrsr*>(m_pCurCrsr->GetNext());
    1201             : 
    1202             :     // #i24086#: show also all others
    1203           0 :     if( !ActionPend() )
    1204             :     {
    1205           0 :         UpdateCrsr();
    1206           0 :         m_pCurCrsr->Show();
    1207             :     }
    1208           0 :     return sal_True;
    1209             : }
    1210             : 
    1211             : /// go to the previous SSelection
    1212           0 : sal_Bool SwCrsrShell::GoPrevCrsr()
    1213             : {
    1214             :     // is there a ring of cursors?
    1215           0 :     if( m_pCurCrsr->GetNext() == m_pCurCrsr )
    1216           0 :         return sal_False;
    1217             : 
    1218           0 :     SET_CURR_SHELL( this );
    1219           0 :     SwCallLink aLk( *this ); // watch Crsr-Moves; call Link if needed
    1220           0 :     m_pCurCrsr = dynamic_cast<SwShellCrsr*>(m_pCurCrsr->GetPrev());
    1221             : 
    1222             :     // #i24086#: show also all others
    1223           0 :     if( !ActionPend() )
    1224             :     {
    1225           0 :         UpdateCrsr();
    1226           0 :         m_pCurCrsr->Show();
    1227             :     }
    1228           0 :     return sal_True;
    1229             : }
    1230             : 
    1231        3839 : void SwCrsrShell::Paint( const Rectangle &rRect)
    1232             : {
    1233        3839 :     comphelper::FlagRestorationGuard g(mbSelectAll, StartsWithTable() && ExtendedSelectedAll(/*bFootnotes =*/ false));
    1234        7678 :     SET_CURR_SHELL( this );
    1235             : 
    1236             :     // always switch off all cursors when painting
    1237        3839 :     SwRect aRect( rRect );
    1238             : 
    1239        3839 :     bool bVis = false;
    1240             :     // if a cursor is visible then hide the SV cursor
    1241        3839 :     if( m_pVisCrsr->IsVisible() && !aRect.IsOver( m_aCharRect ) )
    1242             :     {
    1243        2237 :         bVis = true;
    1244        2237 :         m_pVisCrsr->Hide();
    1245             :     }
    1246             : 
    1247             :     // re-paint area
    1248        3839 :     SwViewShell::Paint( rRect );
    1249             : 
    1250        3839 :     if( m_bHasFocus && !m_bBasicHideCrsr )
    1251             :     {
    1252        3824 :         SwShellCrsr* pAktCrsr = m_pTblCrsr ? m_pTblCrsr : m_pCurCrsr;
    1253             : 
    1254        3824 :         if( !ActionPend() )
    1255             :         {
    1256             :             // so that right/bottom borders will not be cropped
    1257        2882 :             pAktCrsr->Invalidate( VisArea() );
    1258        2882 :             pAktCrsr->Show();
    1259             :         }
    1260             :         else
    1261         942 :             pAktCrsr->Invalidate( aRect );
    1262             : 
    1263             :     }
    1264        3839 :     if( m_bSVCrsrVis && bVis ) // also show SV cursor again
    1265        5959 :         m_pVisCrsr->Show();
    1266        3839 : }
    1267             : 
    1268        5075 : void SwCrsrShell::VisPortChgd( const SwRect & rRect )
    1269             : {
    1270        5075 :     SET_CURR_SHELL( this );
    1271             :     bool bVis; // switch off all cursors when scrolling
    1272             : 
    1273             :     // if a cursor is visible then hide the SV cursor
    1274        5075 :     if( ( bVis = m_pVisCrsr->IsVisible() ) )
    1275        3666 :         m_pVisCrsr->Hide();
    1276             : 
    1277        5075 :     m_bVisPortChgd = sal_True;
    1278        5075 :     m_aOldRBPos.setX(VisArea().Right());
    1279        5075 :     m_aOldRBPos.setY(VisArea().Bottom());
    1280             : 
    1281             :     // For not having problems with the SV cursor, Update() is called for the
    1282             :     // Window in SwViewShell::VisPo...
    1283             :     // During painting no selections should be shown, thus the call is encapsulated. <- TODO: old artefact?
    1284        5075 :     SwViewShell::VisPortChgd( rRect ); // move area
    1285             : 
    1286        5075 :     if( m_bSVCrsrVis && bVis ) // show SV cursor again
    1287        3653 :         m_pVisCrsr->Show();
    1288             : 
    1289        5075 :     if( m_nCrsrMove )
    1290           1 :         m_bInCMvVisportChgd = sal_True;
    1291             : 
    1292        5075 :     m_bVisPortChgd = sal_False;
    1293        5075 : }
    1294             : 
    1295             : /** Set the cursor back into content.
    1296             : 
    1297             :     This should only be called if the cursor was move somewhere else (e.g. when
    1298             :     deleting a border). The new position is calculated from its current position
    1299             :     in the layout.
    1300             : */
    1301       27344 : void SwCrsrShell::UpdateCrsrPos()
    1302             : {
    1303       27344 :     SET_CURR_SHELL( this );
    1304       27344 :     ++mnStartAction;
    1305       27344 :     SwShellCrsr* pShellCrsr = getShellCrsr( true );
    1306       27344 :     Size aOldSz( GetDocSize() );
    1307             : 
    1308       27344 :     if( isInHiddenTxtFrm(pShellCrsr) )
    1309             :     {
    1310          30 :         SwCrsrMoveState aTmpState( MV_NONE );
    1311          30 :         aTmpState.bSetInReadOnly = IsReadOnlyAvailable();
    1312          60 :         GetLayout()->GetCrsrOfst( pShellCrsr->GetPoint(), pShellCrsr->GetPtPos(),
    1313          60 :                                      &aTmpState );
    1314          30 :         pShellCrsr->DeleteMark();
    1315             :     }
    1316       27344 :     IGrammarContact *pGrammarContact = GetDoc() ? GetDoc()->getGrammarContact() : 0;
    1317       27344 :     if( pGrammarContact )
    1318       27344 :         pGrammarContact->updateCursorPosition( *m_pCurCrsr->GetPoint() );
    1319       27344 :     --mnStartAction;
    1320       27344 :     if( aOldSz != GetDocSize() )
    1321           0 :         SizeChgNotify();
    1322       27344 : }
    1323             : 
    1324             : // #i65475# - if Point/Mark in hidden sections, move them out
    1325          22 : static void lcl_CheckHiddenSection( SwNodeIndex& rIdx )
    1326             : {
    1327          22 :     const SwSectionNode* pSectNd = rIdx.GetNode().FindSectionNode();
    1328          22 :     if( pSectNd && pSectNd->GetSection().IsHiddenFlag() )
    1329             :     {
    1330           0 :         SwNodeIndex aTmp( *pSectNd );
    1331             :         const SwNode* pFrmNd =
    1332           0 :         rIdx.GetNodes().FindPrvNxtFrmNode( aTmp, pSectNd->EndOfSectionNode() );
    1333             :         SAL_WARN_IF( !pFrmNd, "sw", "found no Node with Frames" );
    1334           0 :         rIdx = aTmp;
    1335             :     }
    1336          22 : }
    1337             : 
    1338             : /// Try to set the cursor to the next visible content node.
    1339          22 : static void lcl_CheckHiddenPara( SwPosition& rPos )
    1340             : {
    1341          22 :     SwNodeIndex aTmp( rPos.nNode );
    1342          22 :     SwTxtNode* pTxtNd = aTmp.GetNode().GetTxtNode();
    1343          44 :     while( pTxtNd && pTxtNd->HasHiddenCharAttribute( true ) )
    1344             :     {
    1345           0 :         SwCntntNode* pCntnt = aTmp.GetNodes().GoNext( &aTmp );
    1346           0 :         if ( pCntnt && pCntnt->IsTxtNode() )
    1347           0 :             pTxtNd = (SwTxtNode*)pCntnt;
    1348             :         else
    1349           0 :             pTxtNd = 0;
    1350             :     }
    1351             : 
    1352          22 :     if ( pTxtNd )
    1353          22 :         rPos = SwPosition( aTmp, SwIndex( pTxtNd, 0 ) );
    1354          22 : }
    1355             : 
    1356             : // #i27301# - helper class that notifies the accessibility about invalid text
    1357             : // selections in its destructor
    1358             : class SwNotifyAccAboutInvalidTextSelections
    1359             : {
    1360             :     private:
    1361             :         SwCrsrShell& mrCrsrSh;
    1362             : 
    1363             :     public:
    1364       27355 :         SwNotifyAccAboutInvalidTextSelections( SwCrsrShell& _rCrsrSh )
    1365       27355 :             : mrCrsrSh( _rCrsrSh )
    1366       27355 :         {}
    1367             : 
    1368       27355 :         ~SwNotifyAccAboutInvalidTextSelections()
    1369             :         {
    1370       27355 :             mrCrsrSh.InvalidateAccessibleParaTextSelection();
    1371       27355 :         }
    1372             : };
    1373             : 
    1374       27903 : void SwCrsrShell::UpdateCrsr( sal_uInt16 eFlags, sal_Bool bIdleEnd )
    1375             : {
    1376       27903 :     SET_CURR_SHELL( this );
    1377       27903 :     ClearUpCrsrs();
    1378             : 
    1379             :     // In a BasicAction the cursor must be updated, e.g. to create the
    1380             :     // TableCursor. EndAction now calls UpdateCrsr!
    1381       27903 :     if( ActionPend() && BasicActionPend() )
    1382             :     {
    1383         548 :         if ( eFlags & SwCrsrShell::READONLY )
    1384           5 :             m_bIgnoreReadonly = sal_True;
    1385         548 :         return; // if not then no update
    1386             :     }
    1387             : 
    1388       54699 :     SwNotifyAccAboutInvalidTextSelections aInvalidateTextSelections( *this );
    1389             : 
    1390       27355 :     if ( m_bIgnoreReadonly )
    1391             :     {
    1392           4 :         m_bIgnoreReadonly = sal_False;
    1393           4 :         eFlags |= SwCrsrShell::READONLY;
    1394             :     }
    1395             : 
    1396       27355 :     if( eFlags & SwCrsrShell::CHKRANGE )    // check all cursor moves for
    1397       27352 :         CheckRange( m_pCurCrsr );             // overlapping ranges
    1398             : 
    1399       27355 :     if( !bIdleEnd )
    1400       25639 :         CheckTblBoxCntnt();
    1401             : 
    1402             :     // If the current cursor is in a table and point/mark in different boxes,
    1403             :     // then the table mode is active (also if it is already active: m_pTblCrsr)
    1404       27355 :     SwPaM* pTstCrsr = getShellCrsr( true );
    1405       54990 :     if( pTstCrsr->HasMark() && !m_pBlockCrsr &&
    1406         164 :         mpDoc->IsIdxInTbl( pTstCrsr->GetPoint()->nNode ) &&
    1407          16 :           ( m_pTblCrsr ||
    1408          16 :             pTstCrsr->GetNode( true )->StartOfSectionNode() !=
    1409       27395 :             pTstCrsr->GetNode( false )->StartOfSectionNode() ) && !mbSelectAll)
    1410             :     {
    1411          11 :         SwShellCrsr* pITmpCrsr = getShellCrsr( true );
    1412          11 :         Point aTmpPt( pITmpCrsr->GetPtPos() );
    1413          11 :         Point aTmpMk( pITmpCrsr->GetMkPos() );
    1414          11 :         SwPosition* pPos = pITmpCrsr->GetPoint();
    1415             : 
    1416             :         // Bug 65475 (1999) - if Point/Mark in hidden sections, move them out
    1417          11 :         lcl_CheckHiddenSection( pPos->nNode );
    1418          11 :         lcl_CheckHiddenSection( pITmpCrsr->GetMark()->nNode );
    1419             : 
    1420             :         // Move cursor out of hidden paragraphs
    1421          11 :         if ( !GetViewOptions()->IsShowHiddenChar() )
    1422             :         {
    1423          11 :             lcl_CheckHiddenPara( *pPos );
    1424          11 :             lcl_CheckHiddenPara( *pITmpCrsr->GetMark() );
    1425             :         }
    1426             : 
    1427          11 :         SwCntntFrm *pTblFrm = pPos->nNode.GetNode().GetCntntNode()->
    1428          22 :                               getLayoutFrm( GetLayout(), &aTmpPt, pPos, false );
    1429             : 
    1430             :         OSL_ENSURE( pTblFrm, "Tabelle Crsr nicht im Content ??" );
    1431             : 
    1432             :         // --> Make code robust. The table cursor may point
    1433             :         // to a table in a currently inactive header.
    1434          11 :         SwTabFrm *pTab = pTblFrm ? pTblFrm->FindTabFrm() : 0;
    1435             : 
    1436          11 :         if ( pTab && pTab->GetTable()->GetRowsToRepeat() > 0 )
    1437             :         {
    1438             :             // First check if point is in repeated headline:
    1439           0 :             bool bInRepeatedHeadline = pTab->IsFollow() && pTab->IsInHeadline( *pTblFrm );
    1440             : 
    1441             :             // Second check if mark is in repeated headline:
    1442           0 :             if ( !bInRepeatedHeadline )
    1443             :             {
    1444             :                 SwCntntFrm* pMarkTblFrm = pITmpCrsr->GetCntntNode( false )->
    1445           0 :                     getLayoutFrm( GetLayout(), &aTmpMk, pITmpCrsr->GetMark(), false );
    1446             :                 OSL_ENSURE( pMarkTblFrm, "Tabelle Crsr nicht im Content ??" );
    1447             : 
    1448           0 :                 if ( pMarkTblFrm )
    1449             :                 {
    1450           0 :                     SwTabFrm* pMarkTab = pMarkTblFrm->FindTabFrm();
    1451             :                     OSL_ENSURE( pMarkTab, "Tabelle Crsr nicht im Content ??" );
    1452             : 
    1453             :                     // Make code robust:
    1454           0 :                     if ( pMarkTab )
    1455             :                     {
    1456           0 :                         bInRepeatedHeadline = pMarkTab->IsFollow() && pMarkTab->IsInHeadline( *pMarkTblFrm );
    1457             :                     }
    1458             :                 }
    1459             :             }
    1460             : 
    1461             :             // No table cursor in repeated headlines:
    1462           0 :             if ( bInRepeatedHeadline )
    1463             :             {
    1464           0 :                 pTblFrm = 0;
    1465             : 
    1466           0 :                 SwPosSection fnPosSect = *pPos <  *pITmpCrsr->GetMark()
    1467             :                                             ? fnSectionStart
    1468           0 :                                             : fnSectionEnd;
    1469             : 
    1470             :                 // then only select inside the Box
    1471           0 :                 if( m_pTblCrsr )
    1472             :                 {
    1473           0 :                     m_pCurCrsr->SetMark();
    1474           0 :                     *m_pCurCrsr->GetMark() = *m_pTblCrsr->GetMark();
    1475           0 :                     m_pCurCrsr->GetMkPos() = m_pTblCrsr->GetMkPos();
    1476           0 :                     m_pTblCrsr->DeleteMark();
    1477           0 :                     m_pTblCrsr->SwSelPaintRects::Hide();
    1478             :                 }
    1479             : 
    1480           0 :                 *m_pCurCrsr->GetPoint() = *m_pCurCrsr->GetMark();
    1481           0 :                 (*fnSectionCurr)( *m_pCurCrsr, fnPosSect );
    1482             :             }
    1483             :         }
    1484             : 
    1485             :         // we really want a table selection
    1486          11 :         if( pTab && pTblFrm )
    1487             :         {
    1488          11 :             if( !m_pTblCrsr )
    1489             :             {
    1490             :                 m_pTblCrsr = new SwShellTableCrsr( *this,
    1491           6 :                                 *m_pCurCrsr->GetMark(), m_pCurCrsr->GetMkPos(),
    1492           6 :                                 *pPos, aTmpPt );
    1493           3 :                 m_pCurCrsr->DeleteMark();
    1494           3 :                 m_pCurCrsr->SwSelPaintRects::Hide();
    1495             : 
    1496           3 :                 CheckTblBoxCntnt();
    1497           3 :                 if(!m_pTblCrsr)
    1498             :                 {
    1499             :                     SAL_WARN("sw", "fdo#74854: "
    1500             :                         "this should not happen, but better loose the selection "
    1501             :                         "rather than crashing");
    1502           0 :                     return;
    1503             :                 }
    1504             :             }
    1505             : 
    1506          11 :             SwCrsrMoveState aTmpState( MV_NONE );
    1507          11 :             aTmpState.bRealHeight = sal_True;
    1508          11 :             if( !pTblFrm->GetCharRect( m_aCharRect, *m_pTblCrsr->GetPoint(), &aTmpState ) )
    1509             :             {
    1510           0 :                 Point aCentrPt( m_aCharRect.Center() );
    1511           0 :                 aTmpState.bSetInReadOnly = IsReadOnlyAvailable();
    1512           0 :                 pTblFrm->GetCrsrOfst( m_pTblCrsr->GetPoint(), aCentrPt, &aTmpState );
    1513             :                 bool const bResult =
    1514           0 :                     pTblFrm->GetCharRect( m_aCharRect, *m_pTblCrsr->GetPoint() );
    1515             :                 OSL_ENSURE( bResult, "GetCharRect failed." );
    1516             :                 (void) bResult; // non-debug: unused
    1517             :             }
    1518             : 
    1519          11 :             m_pVisCrsr->Hide(); // always hide visible Cursor
    1520             :             // scroll Cursor to visible area
    1521          33 :             if( (eFlags & SwCrsrShell::SCROLLWIN) &&
    1522          11 :                 (HasSelection() || eFlags & SwCrsrShell::READONLY ||
    1523           0 :                  !IsCrsrReadonly()) )
    1524             :             {
    1525          11 :                 SwFrm* pBoxFrm = pTblFrm;
    1526          33 :                 while( pBoxFrm && !pBoxFrm->IsCellFrm() )
    1527          11 :                     pBoxFrm = pBoxFrm->GetUpper();
    1528          11 :                 if( pBoxFrm && pBoxFrm->Frm().HasArea() )
    1529          11 :                     MakeVisible( pBoxFrm->Frm() );
    1530             :                 else
    1531           0 :                     MakeVisible( m_aCharRect );
    1532             :             }
    1533             : 
    1534             :             // let Layout create the Cursors in the Boxes
    1535          11 :             if( m_pTblCrsr->IsCrsrMovedUpdt() )
    1536           3 :                 GetLayout()->MakeTblCrsrs( *m_pTblCrsr );
    1537          11 :             if( m_bHasFocus && !m_bBasicHideCrsr )
    1538          11 :                 m_pTblCrsr->Show();
    1539             : 
    1540             :             // set Cursor-Points to the new Positions
    1541          11 :             m_pTblCrsr->GetPtPos().setX(m_aCharRect.Left());
    1542          11 :             m_pTblCrsr->GetPtPos().setY(m_aCharRect.Top());
    1543             : 
    1544          11 :             if( m_bSVCrsrVis )
    1545             :             {
    1546          11 :                 m_aCrsrHeight.setX(0);
    1547          11 :                 m_aCrsrHeight.setY(aTmpState.aRealHeight.getY() < 0 ?
    1548          11 :                                   -m_aCharRect.Width() : m_aCharRect.Height());
    1549          11 :                 m_pVisCrsr->Show(); // show again
    1550             :             }
    1551          11 :             m_eMvState = MV_NONE;  // state for cursor travelling - GetCrsrOfst
    1552          11 :             if( pTblFrm && Imp()->IsAccessible() )
    1553           8 :                 Imp()->InvalidateAccessibleCursorPosition( pTblFrm );
    1554          11 :             return;
    1555             :         }
    1556             :     }
    1557             : 
    1558       27344 :     if( m_pTblCrsr )
    1559             :     {
    1560             :         // delete Ring
    1561           0 :         while( m_pCurCrsr->GetNext() != m_pCurCrsr )
    1562           0 :             delete m_pCurCrsr->GetNext();
    1563           0 :         m_pCurCrsr->DeleteMark();
    1564           0 :         *m_pCurCrsr->GetPoint() = *m_pTblCrsr->GetPoint();
    1565           0 :         m_pCurCrsr->GetPtPos() = m_pTblCrsr->GetPtPos();
    1566           0 :         delete m_pTblCrsr, m_pTblCrsr = 0;
    1567             :     }
    1568             : 
    1569       27344 :     m_pVisCrsr->Hide(); // always hide visible Cursor
    1570             : 
    1571             :     // are we perhaps in a protected / hidden Section ?
    1572             :     {
    1573       27344 :         SwShellCrsr* pShellCrsr = getShellCrsr( true );
    1574       27344 :         bool bChgState = true;
    1575       27344 :         const SwSectionNode* pSectNd = pShellCrsr->GetNode()->FindSectionNode();
    1576       27629 :         if( pSectNd && ( pSectNd->GetSection().IsHiddenFlag() ||
    1577         285 :             ( !IsReadOnlyAvailable() &&
    1578           0 :               pSectNd->GetSection().IsProtectFlag() &&
    1579           0 :              ( !mpDoc->GetDocShell() ||
    1580           0 :                !mpDoc->GetDocShell()->IsReadOnly() || m_bAllProtect )) ) )
    1581             :         {
    1582           0 :             if( !FindValidCntntNode( !HasDrawView() ||
    1583           0 :                     0 == Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount()))
    1584             :             {
    1585             :                 // everything protected/hidden -> special mode
    1586           0 :                 if( m_bAllProtect && !IsReadOnlyAvailable() &&
    1587           0 :                     pSectNd->GetSection().IsProtectFlag() )
    1588           0 :                     bChgState = false;
    1589             :                 else
    1590             :                 {
    1591           0 :                     m_eMvState = MV_NONE;     // state for cursor travelling
    1592           0 :                     m_bAllProtect = sal_True;
    1593           0 :                     if( GetDoc()->GetDocShell() )
    1594             :                     {
    1595           0 :                         GetDoc()->GetDocShell()->SetReadOnlyUI( true );
    1596           0 :                         CallChgLnk();       // notify UI!
    1597             :                     }
    1598           0 :                     return;
    1599             :                 }
    1600             :             }
    1601             :         }
    1602       27344 :         if( bChgState )
    1603             :         {
    1604       27344 :             sal_Bool bWasAllProtect = m_bAllProtect;
    1605       27344 :             m_bAllProtect = sal_False;
    1606       27344 :             if( bWasAllProtect && GetDoc()->GetDocShell() &&
    1607           0 :                 GetDoc()->GetDocShell()->IsReadOnlyUI() )
    1608             :             {
    1609           0 :                 GetDoc()->GetDocShell()->SetReadOnlyUI( false );
    1610           0 :                 CallChgLnk();       // notify UI!
    1611             :             }
    1612             :         }
    1613             :     }
    1614             : 
    1615       27344 :     UpdateCrsrPos();
    1616             : 
    1617             :     // The cursor must always point into content; there's some code
    1618             :     // that relies on this. (E.g. in SwEditShell::GetScriptType, which always
    1619             :     // loops _behind_ the last node in the selection, which always works if you
    1620             :     // are in content.) To achieve this, we'll force cursor(s) to point into
    1621             :     // content, if UpdateCrsrPos() hasn't already done so.
    1622       27344 :     SwPaM* pCmp = m_pCurCrsr;
    1623       27344 :     do
    1624             :     {
    1625             :         // start will move forwards, end will move backwards
    1626       27344 :         bool bPointIsStart = ( pCmp->Start() == pCmp->GetPoint() );
    1627             : 
    1628             :         // move point; forward if it's the start, backwards if it's the end
    1629       27344 :         if( ! pCmp->GetPoint()->nNode.GetNode().IsCntntNode() )
    1630             :             pCmp->Move( bPointIsStart ? fnMoveForward : fnMoveBackward,
    1631           0 :                         fnGoCntnt );
    1632             : 
    1633             :         // move mark (if exists); forward if it's the start, else backwards
    1634       27344 :         if( pCmp->HasMark() )
    1635             :         {
    1636         128 :             if( ! pCmp->GetMark()->nNode.GetNode().IsCntntNode() )
    1637             :             {
    1638           0 :                 pCmp->Exchange();
    1639           0 :                 pCmp->Move( !bPointIsStart ? fnMoveForward : fnMoveBackward,
    1640           0 :                             fnGoCntnt );
    1641           0 :                 pCmp->Exchange();
    1642             :             }
    1643             :         }
    1644             : 
    1645             :         // iterate to next PaM in ring
    1646       27344 :         pCmp = static_cast<SwPaM*>( pCmp->GetNext() );
    1647             :     }
    1648       27344 :     while( pCmp != m_pCurCrsr );
    1649             : 
    1650       27344 :     SwRect aOld( m_aCharRect );
    1651       27344 :     bool bFirst = true;
    1652             :     SwCntntFrm *pFrm;
    1653       27344 :     int nLoopCnt = 100;
    1654       27344 :     SwShellCrsr* pShellCrsr = getShellCrsr( true );
    1655             : 
    1656       27348 :     do {
    1657             :         bool bAgainst;
    1658       51770 :         do {
    1659       51770 :             bAgainst = false;
    1660       51770 :             pFrm = pShellCrsr->GetCntntNode()->getLayoutFrm( GetLayout(),
    1661      103540 :                         &pShellCrsr->GetPtPos(), pShellCrsr->GetPoint(), false );
    1662             :             // if the Frm doesn't exist anymore, the complete Layout has to be
    1663             :             // created, because there used to be a Frm here!
    1664       51770 :             if ( !pFrm )
    1665             :             {
    1666           0 :                 do
    1667             :                 {
    1668           0 :                     CalcLayout();
    1669           0 :                     pFrm = pShellCrsr->GetCntntNode()->getLayoutFrm( GetLayout(),
    1670           0 :                                 &pShellCrsr->GetPtPos(), pShellCrsr->GetPoint(), false );
    1671             :                 }  while( !pFrm );
    1672             :             }
    1673       51770 :             else if ( Imp()->IsIdleAction() )
    1674             :                 // Guarantee everything's properly formatted
    1675          16 :                 pFrm->PrepareCrsr();
    1676             : 
    1677             :             // In protected Fly? but ignore in case of frame selection
    1678      103540 :             if( !IsReadOnlyAvailable() && pFrm->IsProtected() &&
    1679           0 :                 ( !Imp()->GetDrawView() ||
    1680       51770 :                   !Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() ) &&
    1681           0 :                 (!mpDoc->GetDocShell() ||
    1682           0 :                  !mpDoc->GetDocShell()->IsReadOnly() || m_bAllProtect ) )
    1683             :             {
    1684             :                 // look for a valid position
    1685           0 :                 bool bChgState = true;
    1686           0 :                 if( !FindValidCntntNode(!HasDrawView() ||
    1687           0 :                     0 == Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount()))
    1688             :                 {
    1689             :                     // everything is protected / hidden -> special Mode
    1690           0 :                     if( m_bAllProtect )
    1691           0 :                         bChgState = false;
    1692             :                     else
    1693             :                     {
    1694           0 :                         m_eMvState = MV_NONE;     // state for crusor travelling
    1695           0 :                         m_bAllProtect = sal_True;
    1696           0 :                         if( GetDoc()->GetDocShell() )
    1697             :                         {
    1698           0 :                             GetDoc()->GetDocShell()->SetReadOnlyUI( true );
    1699           0 :                             CallChgLnk();       // notify UI!
    1700             :                         }
    1701           0 :                         return;
    1702             :                     }
    1703             :                 }
    1704             : 
    1705           0 :                 if( bChgState )
    1706             :                 {
    1707           0 :                     sal_Bool bWasAllProtect = m_bAllProtect;
    1708           0 :                     m_bAllProtect = sal_False;
    1709           0 :                     if( bWasAllProtect && GetDoc()->GetDocShell() &&
    1710           0 :                         GetDoc()->GetDocShell()->IsReadOnlyUI() )
    1711             :                     {
    1712           0 :                         GetDoc()->GetDocShell()->SetReadOnlyUI( false );
    1713           0 :                         CallChgLnk();       // notify UI!
    1714             :                     }
    1715           0 :                     m_bAllProtect = sal_False;
    1716           0 :                     bAgainst = true; // look for the right Frm again
    1717             :                 }
    1718             :             }
    1719             :         } while( bAgainst );
    1720             : 
    1721       51770 :         if( !( eFlags & SwCrsrShell::NOCALRECT ))
    1722             :         {
    1723       51770 :             SwCrsrMoveState aTmpState( m_eMvState );
    1724       51770 :             aTmpState.bSetInReadOnly = IsReadOnlyAvailable();
    1725       51770 :             aTmpState.bRealHeight = sal_True;
    1726       51770 :             aTmpState.bRealWidth = IsOverwriteCrsr();
    1727       51770 :             aTmpState.nCursorBidiLevel = pShellCrsr->GetCrsrBidiLevel();
    1728             : 
    1729             :             // #i27615#,#i30453#
    1730       51770 :             SwSpecialPos aSpecialPos;
    1731       51770 :             aSpecialPos.nExtendRange = SP_EXTEND_RANGE_BEFORE;
    1732       51770 :             if (pShellCrsr->IsInFrontOfLabel())
    1733             :             {
    1734           0 :                 aTmpState.pSpecialPos = &aSpecialPos;
    1735             :             }
    1736             : 
    1737       51770 :             if( !pFrm->GetCharRect( m_aCharRect, *pShellCrsr->GetPoint(), &aTmpState ) )
    1738             :             {
    1739         130 :                 Point& rPt = pShellCrsr->GetPtPos();
    1740         130 :                 rPt = m_aCharRect.Center();
    1741         130 :                 pFrm->GetCrsrOfst( pShellCrsr->GetPoint(), rPt, &aTmpState );
    1742             :             }
    1743             : 
    1744       51770 :             if( !pShellCrsr->HasMark() )
    1745       51516 :                 m_aCrsrHeight = aTmpState.aRealHeight;
    1746             :             else
    1747             :             {
    1748         254 :                 m_aCrsrHeight.setX(0);
    1749         254 :                 m_aCrsrHeight.setY(aTmpState.aRealHeight.getY() < 0 ?
    1750         254 :                                   -m_aCharRect.Width() : m_aCharRect.Height());
    1751             :             }
    1752             :         }
    1753             :         else
    1754             :         {
    1755           0 :             m_aCrsrHeight.setX(0);
    1756           0 :             m_aCrsrHeight.setY(m_aCharRect.Height());
    1757             :         }
    1758             : 
    1759       51770 :         if( !bFirst && aOld == m_aCharRect )
    1760       24422 :             break;
    1761             : 
    1762             :         // if the layout says that we are after the 100th iteration still in
    1763             :         // flow then we should always take the current position for granted.
    1764             :         // (see bug: 29658)
    1765       27348 :         if( !--nLoopCnt )
    1766             :         {
    1767             :             OSL_ENSURE( !this, "endless loop? CharRect != OldCharRect ");
    1768           0 :             break;
    1769             :         }
    1770       27348 :         aOld = m_aCharRect;
    1771       27348 :         bFirst = false;
    1772             : 
    1773             :         // update cursor Points to the new Positions
    1774       27348 :         pShellCrsr->GetPtPos().setX(m_aCharRect.Left());
    1775       27348 :         pShellCrsr->GetPtPos().setY(m_aCharRect.Top());
    1776             : 
    1777       27348 :         if( !(eFlags & SwCrsrShell::UPDOWN ))   // delete old Pos. of Up/Down
    1778             :         {
    1779       27348 :             pFrm->Calc();
    1780       27348 :             m_nUpDownX = pFrm->IsVertical() ?
    1781           0 :                        m_aCharRect.Top() - pFrm->Frm().Top() :
    1782       27348 :                        m_aCharRect.Left() - pFrm->Frm().Left();
    1783             :         }
    1784             : 
    1785             :         // scroll Cursor to visible area
    1786       76063 :         if( m_bHasFocus && eFlags & SwCrsrShell::SCROLLWIN &&
    1787       72794 :             (HasSelection() || eFlags & SwCrsrShell::READONLY ||
    1788       24199 :              !IsCrsrReadonly() || GetViewOptions()->IsSelectionInReadonly()) )
    1789             :         {
    1790             :             // in case of scrolling this EndAction doesn't show the SV cursor
    1791             :             // again, thus save and reset the flag here
    1792       24355 :             sal_Bool bSav = m_bSVCrsrVis;
    1793       24355 :             m_bSVCrsrVis = sal_False;
    1794       24355 :             MakeSelVisible();
    1795       24355 :             m_bSVCrsrVis = bSav;
    1796             :         }
    1797             : 
    1798       27348 :     } while( eFlags & SwCrsrShell::SCROLLWIN );
    1799             : 
    1800       27344 :     if( m_pBlockCrsr )
    1801           0 :         RefreshBlockCursor();
    1802             : 
    1803       27344 :     if( !bIdleEnd && m_bHasFocus && !m_bBasicHideCrsr )
    1804             :     {
    1805       25562 :         if( m_pTblCrsr )
    1806           0 :             m_pTblCrsr->SwSelPaintRects::Show();
    1807             :         else
    1808             :         {
    1809       25562 :             m_pCurCrsr->SwSelPaintRects::Show();
    1810       25562 :             if( m_pBlockCrsr )
    1811             :             {
    1812           0 :                 SwShellCrsr* pNxt = dynamic_cast<SwShellCrsr*>(m_pCurCrsr->GetNext());
    1813           0 :                 while( pNxt && pNxt != m_pCurCrsr )
    1814             :                 {
    1815           0 :                     pNxt->SwSelPaintRects::Show();
    1816           0 :                     pNxt = dynamic_cast<SwShellCrsr*>(pNxt->GetNext());
    1817             :                 }
    1818             :             }
    1819             :         }
    1820             :     }
    1821             : 
    1822       27344 :     m_eMvState = MV_NONE; // state for cursor tavelling - GetCrsrOfst
    1823             : 
    1824       27344 :     if( pFrm && Imp()->IsAccessible() )
    1825          70 :         Imp()->InvalidateAccessibleCursorPosition( pFrm );
    1826             : 
    1827             :     // switch from blinking cursor to read-only-text-selection cursor
    1828             :     static const long nNoBlinkTime = STYLE_CURSOR_NOBLINKTIME;
    1829       27344 :     const long nBlinkTime = GetOut()->GetSettings().GetStyleSettings().
    1830       27344 :                             GetCursorBlinkTime();
    1831             : 
    1832       54688 :     if ( (IsCrsrReadonly() && GetViewOptions()->IsSelectionInReadonly()) ==
    1833       27344 :         ( nBlinkTime != nNoBlinkTime ) )
    1834             :     {
    1835             :         // non blinking cursor in read only - text selection mode
    1836       27344 :         AllSettings aSettings = GetOut()->GetSettings();
    1837       54688 :         StyleSettings aStyleSettings = aSettings.GetStyleSettings();
    1838             :         const long nNewBlinkTime = nBlinkTime == nNoBlinkTime ?
    1839       27344 :                                    Application::GetSettings().GetStyleSettings().GetCursorBlinkTime() :
    1840       54688 :                                    nNoBlinkTime;
    1841       27344 :         aStyleSettings.SetCursorBlinkTime( nNewBlinkTime );
    1842       27344 :         aSettings.SetStyleSettings( aStyleSettings );
    1843       54688 :         GetOut()->SetSettings( aSettings );
    1844             :     }
    1845             : 
    1846       27344 :     if( m_bSVCrsrVis )
    1847       54383 :         m_pVisCrsr->Show(); // show again
    1848             : }
    1849             : 
    1850           0 : void SwCrsrShell::RefreshBlockCursor()
    1851             : {
    1852             :     OSL_ENSURE( m_pBlockCrsr, "Don't call me without a block cursor" );
    1853           0 :     SwShellCrsr &rBlock = m_pBlockCrsr->getShellCrsr();
    1854           0 :     Point aPt = rBlock.GetPtPos();
    1855           0 :     SwCntntFrm* pFrm = rBlock.GetCntntNode()->getLayoutFrm( GetLayout(), &aPt, rBlock.GetPoint(), false );
    1856           0 :     Point aMk;
    1857           0 :     if( m_pBlockCrsr->getEndPoint() && m_pBlockCrsr->getStartPoint() )
    1858             :     {
    1859           0 :         aPt = *m_pBlockCrsr->getStartPoint();
    1860           0 :         aMk = *m_pBlockCrsr->getEndPoint();
    1861             :     }
    1862             :     else
    1863             :     {
    1864           0 :         aPt = rBlock.GetPtPos();
    1865           0 :         if( pFrm )
    1866             :         {
    1867           0 :             if( pFrm->IsVertical() )
    1868           0 :                 aPt.setY(pFrm->Frm().Top() + GetUpDownX());
    1869             :             else
    1870           0 :                 aPt.setX(pFrm->Frm().Left() + GetUpDownX());
    1871             :         }
    1872           0 :         aMk = rBlock.GetMkPos();
    1873             :     }
    1874           0 :     SwRect aRect( aMk, aPt );
    1875           0 :     aRect.Justify();
    1876           0 :     SwSelectionList aSelList( pFrm );
    1877             : 
    1878           0 :     if( GetLayout()->FillSelection( aSelList, aRect ) )
    1879             :     {
    1880           0 :         SwCursor* pNxt = (SwCursor*)m_pCurCrsr->GetNext();
    1881           0 :         while( pNxt != m_pCurCrsr )
    1882             :         {
    1883           0 :             delete pNxt;
    1884           0 :             pNxt = (SwCursor*)m_pCurCrsr->GetNext();
    1885             :         }
    1886             : 
    1887           0 :         std::list<SwPaM*>::iterator pStart = aSelList.getStart();
    1888           0 :         std::list<SwPaM*>::iterator pPam = aSelList.getEnd();
    1889             :         OSL_ENSURE( pPam != pStart, "FillSelection should deliver at least one PaM" );
    1890           0 :         m_pCurCrsr->SetMark();
    1891           0 :         --pPam;
    1892             :         // If there is only one text portion inside the rectangle, a simple
    1893             :         // selection is created
    1894           0 :         if( pPam == pStart )
    1895             :         {
    1896           0 :             *m_pCurCrsr->GetPoint() = *(*pPam)->GetPoint();
    1897           0 :             if( (*pPam)->HasMark() )
    1898           0 :                 *m_pCurCrsr->GetMark() = *(*pPam)->GetMark();
    1899             :             else
    1900           0 :                 m_pCurCrsr->DeleteMark();
    1901           0 :             delete *pPam;
    1902           0 :             m_pCurCrsr->SetColumnSelection( false );
    1903             :         }
    1904             :         else
    1905             :         {
    1906             :             // The order of the SwSelectionList has to be preserved but
    1907             :             // the order inside the ring created by CreateCrsr() is not like
    1908             :             // exspected => First create the selections before the last one
    1909             :             // downto the first selection.
    1910             :             // At least create the cursor for the last selection
    1911           0 :             --pPam;
    1912           0 :             *m_pCurCrsr->GetPoint() = *(*pPam)->GetPoint(); // n-1 (if n == number of selections)
    1913           0 :             if( (*pPam)->HasMark() )
    1914           0 :                 *m_pCurCrsr->GetMark() = *(*pPam)->GetMark();
    1915             :             else
    1916           0 :                 m_pCurCrsr->DeleteMark();
    1917           0 :             delete *pPam;
    1918           0 :             m_pCurCrsr->SetColumnSelection( true );
    1919           0 :             while( pPam != pStart )
    1920             :             {
    1921           0 :                 --pPam;
    1922             : 
    1923           0 :                 SwShellCrsr* pNew = new SwShellCrsr( *m_pCurCrsr );
    1924           0 :                 pNew->insert( pNew->begin(), m_pCurCrsr->begin(),  m_pCurCrsr->end());
    1925           0 :                 m_pCurCrsr->clear();
    1926           0 :                 m_pCurCrsr->DeleteMark();
    1927             : 
    1928           0 :                 *m_pCurCrsr->GetPoint() = *(*pPam)->GetPoint(); // n-2, n-3, .., 2, 1
    1929           0 :                 if( (*pPam)->HasMark() )
    1930             :                 {
    1931           0 :                     m_pCurCrsr->SetMark();
    1932           0 :                     *m_pCurCrsr->GetMark() = *(*pPam)->GetMark();
    1933             :                 }
    1934             :                 else
    1935           0 :                     m_pCurCrsr->DeleteMark();
    1936           0 :                 m_pCurCrsr->SetColumnSelection( true );
    1937           0 :                 delete *pPam;
    1938             :             }
    1939             :             {
    1940           0 :                 SwShellCrsr* pNew = new SwShellCrsr( *m_pCurCrsr );
    1941           0 :                 pNew->insert( pNew->begin(), m_pCurCrsr->begin(), m_pCurCrsr->end() );
    1942           0 :                 m_pCurCrsr->clear();
    1943           0 :                 m_pCurCrsr->DeleteMark();
    1944             :             }
    1945           0 :             pPam = aSelList.getEnd();
    1946           0 :             --pPam;
    1947           0 :             *m_pCurCrsr->GetPoint() = *(*pPam)->GetPoint(); // n, the last selection
    1948           0 :             if( (*pPam)->HasMark() )
    1949             :             {
    1950           0 :                 m_pCurCrsr->SetMark();
    1951           0 :                 *m_pCurCrsr->GetMark() = *(*pPam)->GetMark();
    1952             :             }
    1953             :             else
    1954           0 :                 m_pCurCrsr->DeleteMark();
    1955           0 :             m_pCurCrsr->SetColumnSelection( true );
    1956           0 :             delete *pPam;
    1957             :         }
    1958           0 :     }
    1959           0 : }
    1960             : 
    1961             : /// create a copy of the cursor and save it in the stack
    1962          29 : void SwCrsrShell::Push()
    1963             : {
    1964             :     // fdo#60513: if we have a table cursor, copy that; else copy current.
    1965             :     // This seems to work because UpdateCrsr() will fix this up on Pop(),
    1966             :     // then MakeBoxSels() will re-create the current m_pCurCrsr cell ring.
    1967          29 :     SwShellCrsr *const pCurrent((m_pTblCrsr) ? m_pTblCrsr : m_pCurCrsr);
    1968          29 :     m_pCrsrStk = new SwShellCrsr( *this, *pCurrent->GetPoint(),
    1969          29 :                                     pCurrent->GetPtPos(), m_pCrsrStk );
    1970             : 
    1971          29 :     if (pCurrent->HasMark())
    1972             :     {
    1973           1 :         m_pCrsrStk->SetMark();
    1974           1 :         *m_pCrsrStk->GetMark() = *pCurrent->GetMark();
    1975             :     }
    1976          29 : }
    1977             : 
    1978             : /** delete cursor
    1979             : 
    1980             :     @param bOldCrsr If <true> so delete from stack, if <false> delete current
    1981             :                     and assign the one from stack as the new current cursor.
    1982             :     @return <true> if there was one on the stack, <false> otherwise
    1983             : */
    1984          29 : sal_Bool SwCrsrShell::Pop( sal_Bool bOldCrsr )
    1985             : {
    1986          29 :     SwCallLink aLk( *this ); // watch Crsr-Moves; call Link if needed
    1987             : 
    1988             :     // are there any left?
    1989          29 :     if( 0 == m_pCrsrStk )
    1990           0 :         return sal_False;
    1991             : 
    1992          29 :     SwShellCrsr *pTmp = 0, *pOldStk = m_pCrsrStk;
    1993             : 
    1994             :     // the successor becomes the current one
    1995          29 :     if( m_pCrsrStk->GetNext() != m_pCrsrStk )
    1996             :     {
    1997           0 :         pTmp = dynamic_cast<SwShellCrsr*>(m_pCrsrStk->GetNext());
    1998             :     }
    1999             : 
    2000          29 :     if( bOldCrsr ) // delete from stack
    2001           4 :         delete m_pCrsrStk;
    2002             : 
    2003          29 :     m_pCrsrStk = pTmp; // assign new one
    2004             : 
    2005          29 :     if( !bOldCrsr )
    2006             :     {
    2007          25 :         SwCrsrSaveState aSaveState( *m_pCurCrsr );
    2008             : 
    2009             :         // If the visible SSelection was not changed
    2010          26 :         if( pOldStk->GetPtPos() == m_pCurCrsr->GetPtPos() ||
    2011           1 :             pOldStk->GetPtPos() == m_pCurCrsr->GetMkPos() )
    2012             :         {
    2013             :             // move "Selections Rectangles"
    2014          25 :             m_pCurCrsr->insert( m_pCurCrsr->begin(), pOldStk->begin(), pOldStk->end() );
    2015          25 :             pOldStk->clear();
    2016             :         }
    2017             : 
    2018          25 :         if( pOldStk->HasMark() )
    2019             :         {
    2020           1 :             m_pCurCrsr->SetMark();
    2021           1 :             *m_pCurCrsr->GetMark() = *pOldStk->GetMark();
    2022           1 :             m_pCurCrsr->GetMkPos() = pOldStk->GetMkPos();
    2023             :         }
    2024             :         else
    2025             :             // no selection so revoke old one and set to old position
    2026          24 :             m_pCurCrsr->DeleteMark();
    2027          25 :         *m_pCurCrsr->GetPoint() = *pOldStk->GetPoint();
    2028          25 :         m_pCurCrsr->GetPtPos() = pOldStk->GetPtPos();
    2029          25 :         delete pOldStk;
    2030             : 
    2031          50 :         if( !m_pCurCrsr->IsInProtectTable( sal_True ) &&
    2032             :             !m_pCurCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE |
    2033          25 :                                  nsSwCursorSelOverFlags::SELOVER_CHANGEPOS ) )
    2034          25 :             UpdateCrsr(); // update current cursor
    2035             :     }
    2036          29 :     return sal_True;
    2037             : }
    2038             : 
    2039             : /** Combine two cursors
    2040             : 
    2041             :     Delete topmost from stack and use its GetMark in the current.
    2042             : */
    2043           0 : void SwCrsrShell::Combine()
    2044             : {
    2045             :     // any others left?
    2046           0 :     if( 0 == m_pCrsrStk )
    2047           0 :         return;
    2048             : 
    2049           0 :     SwCallLink aLk( *this ); // watch Crsr-Moves; call Link if needed
    2050             :     // rhbz#689053: IsSelOvr must restore the saved stack position, not the
    2051             :     // current one, because current point + stack mark may be invalid PaM
    2052           0 :     SwCrsrSaveState aSaveState(*m_pCrsrStk);
    2053             :     // stack cursor & current cursor in same Section?
    2054             :     assert(!m_pCrsrStk->HasMark() ||
    2055             :             CheckNodesRange(m_pCrsrStk->GetMark()->nNode,
    2056             :                             m_pCurCrsr->GetPoint()->nNode, true));
    2057           0 :     *m_pCrsrStk->GetPoint() = *m_pCurCrsr->GetPoint();
    2058           0 :     m_pCrsrStk->GetPtPos() = m_pCurCrsr->GetPtPos();
    2059             : 
    2060           0 :     SwShellCrsr * pTmp = 0;
    2061           0 :     if( m_pCrsrStk->GetNext() != m_pCrsrStk )
    2062             :     {
    2063           0 :         pTmp = dynamic_cast<SwShellCrsr*>(m_pCrsrStk->GetNext());
    2064             :     }
    2065           0 :     delete m_pCurCrsr;
    2066           0 :     m_pCurCrsr = m_pCrsrStk;
    2067           0 :     m_pCrsrStk->MoveTo(0); // remove from ring
    2068           0 :     m_pCrsrStk = pTmp;
    2069           0 :     if( !m_pCurCrsr->IsInProtectTable( sal_True ) &&
    2070             :         !m_pCurCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE |
    2071           0 :                              nsSwCursorSelOverFlags::SELOVER_CHANGEPOS ) )
    2072             :     {
    2073           0 :         UpdateCrsr(); // update current cursor
    2074           0 :     }
    2075             : }
    2076             : 
    2077        5404 : void SwCrsrShell::HideCrsrs()
    2078             : {
    2079        5404 :     if( !m_bHasFocus || m_bBasicHideCrsr )
    2080        5414 :         return;
    2081             : 
    2082             :     // if cursor is visible then hide SV cursor
    2083        5394 :     if( m_pVisCrsr->IsVisible() )
    2084             :     {
    2085        5042 :         SET_CURR_SHELL( this );
    2086        5042 :         m_pVisCrsr->Hide();
    2087             :     }
    2088             :     // revoke inversion of SSelection
    2089        5394 :     SwShellCrsr* pAktCrsr = m_pTblCrsr ? m_pTblCrsr : m_pCurCrsr;
    2090        5394 :     pAktCrsr->Hide();
    2091             : }
    2092             : 
    2093       30556 : void SwCrsrShell::ShowCrsrs( sal_Bool bCrsrVis )
    2094             : {
    2095       30556 :     if( !m_bHasFocus || m_bAllProtect || m_bBasicHideCrsr )
    2096       30631 :         return;
    2097             : 
    2098       30481 :     SET_CURR_SHELL( this );
    2099       30481 :     SwShellCrsr* pAktCrsr = m_pTblCrsr ? m_pTblCrsr : m_pCurCrsr;
    2100       30481 :     pAktCrsr->Show();
    2101             : 
    2102       30481 :     if( m_bSVCrsrVis && bCrsrVis ) // also show SV cursor again
    2103       26515 :         m_pVisCrsr->Show();
    2104             : }
    2105             : 
    2106         873 : void SwCrsrShell::ShowCrsr()
    2107             : {
    2108         873 :     if( !m_bBasicHideCrsr )
    2109             :     {
    2110         873 :         m_bSVCrsrVis = sal_True;
    2111         873 :         m_pCurCrsr->SetShowTxtInputFldOverlay( true );
    2112             : #if defined(ANDROID) || defined(IOS)
    2113             :         touch_ui_show_keyboard();
    2114             : #endif
    2115         873 :         UpdateCrsr();
    2116             :     }
    2117         873 : }
    2118             : 
    2119         356 : void SwCrsrShell::HideCrsr()
    2120             : {
    2121         356 :     if( !m_bBasicHideCrsr )
    2122             :     {
    2123         356 :         m_bSVCrsrVis = sal_False;
    2124             :         // possibly reverse selected areas!!
    2125         356 :         SET_CURR_SHELL( this );
    2126         356 :         m_pCurCrsr->SetShowTxtInputFldOverlay( false );
    2127         356 :         m_pVisCrsr->Hide();
    2128             : #if defined(ANDROID) || defined(IOS)
    2129             :         touch_ui_hide_keyboard();
    2130             : #endif
    2131             :     }
    2132         356 : }
    2133             : 
    2134        1720 : void SwCrsrShell::ShLooseFcs()
    2135             : {
    2136        1720 :     if( !m_bBasicHideCrsr )
    2137        1720 :         HideCrsrs();
    2138        1720 :     m_bHasFocus = sal_False;
    2139        1720 : }
    2140             : 
    2141        1720 : void SwCrsrShell::ShGetFcs( sal_Bool bUpdate )
    2142             : {
    2143        1720 :     m_bHasFocus = sal_True;
    2144        1720 :     if( !m_bBasicHideCrsr && VisArea().Width() )
    2145             :     {
    2146             :         UpdateCrsr( static_cast<sal_uInt16>( bUpdate ?
    2147             :                     SwCrsrShell::CHKRANGE|SwCrsrShell::SCROLLWIN
    2148        1206 :                     : SwCrsrShell::CHKRANGE ) );
    2149        1206 :         ShowCrsrs( m_bSVCrsrVis ? sal_True : sal_False );
    2150             :     }
    2151        1720 : }
    2152             : 
    2153             : /** Get current frame in which the cursor is positioned. */
    2154       15551 : SwCntntFrm *SwCrsrShell::GetCurrFrm( const sal_Bool bCalcFrm ) const
    2155             : {
    2156       15551 :     SET_CURR_SHELL( (SwViewShell*)this );
    2157       15551 :     SwCntntFrm *pRet = 0;
    2158       15551 :     SwCntntNode *pNd = m_pCurCrsr->GetCntntNode();
    2159       15551 :     if ( pNd )
    2160             :     {
    2161       15551 :         if ( bCalcFrm )
    2162             :         {
    2163        3548 :             const sal_uInt16* pST = &mnStartAction;
    2164        3548 :             ++(*((sal_uInt16*)pST));
    2165        3548 :             const Size aOldSz( GetDocSize() );
    2166        3548 :             pRet = pNd->getLayoutFrm( GetLayout(), &m_pCurCrsr->GetPtPos(), m_pCurCrsr->GetPoint() );
    2167        3548 :             --(*((sal_uInt16*)pST));
    2168        3548 :             if( aOldSz != GetDocSize() )
    2169           2 :                 ((SwCrsrShell*)this)->SizeChgNotify();
    2170             :         }
    2171             :         else
    2172       12003 :             pRet = pNd->getLayoutFrm( GetLayout(), &m_pCurCrsr->GetPtPos(), m_pCurCrsr->GetPoint(), false);
    2173             :     }
    2174       15551 :     return pRet;
    2175             : }
    2176             : 
    2177             : //TODO: provide documentation
    2178             : /** forward all attribute/format changes at the current node to the Link
    2179             : 
    2180             :     @param pOld ???
    2181             :     @param pNew ???
    2182             : */
    2183        3491 : void SwCrsrShell::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
    2184             : {
    2185             :     const sal_uInt16 nWhich = pOld ?
    2186             :                           pOld->Which() :
    2187             :                           pNew ?
    2188             :                           pNew->Which() :
    2189        3491 :                           sal::static_int_cast<sal_uInt16>(RES_MSG_BEGIN);
    2190             : 
    2191        3491 :     if( m_bCallChgLnk &&
    2192        3409 :         ( nWhich < RES_MSG_BEGIN || nWhich >= RES_MSG_END ||
    2193        3328 :             nWhich == RES_FMT_CHG || nWhich == RES_UPDATE_ATTR ||
    2194             :             nWhich == RES_ATTRSET_CHG ))
    2195             :         // messages are not forwarded
    2196             :         // #i6681#: RES_UPDATE_ATTR is implicitly unset in
    2197             :         // SwTxtNode::Insert(SwTxtHint*, sal_uInt16); we react here and thus do
    2198             :         // not need to send the expensive RES_FMT_CHG in Insert.
    2199        1249 :         CallChgLnk();
    2200             : 
    2201        3491 :     if( m_aGrfArrivedLnk.IsSet() &&
    2202        3457 :         ( RES_GRAPHIC_ARRIVED == nWhich || RES_GRAPHIC_SWAPIN == nWhich ))
    2203           0 :         m_aGrfArrivedLnk.Call( this );
    2204        3491 : }
    2205             : 
    2206             : /** Does the current cursor create a selection?
    2207             : 
    2208             :     This means checking if GetMark is set and if SPoint and GetMark differ.
    2209             : */
    2210       28832 : sal_Bool SwCrsrShell::HasSelection() const
    2211             : {
    2212       28832 :     const SwPaM* pCrsr = getShellCrsr( true );
    2213       57801 :     return( IsTableMode() || ( pCrsr->HasMark() &&
    2214         159 :             *pCrsr->GetPoint() != *pCrsr->GetMark())
    2215       29006 :         ? sal_True : sal_False );
    2216             : }
    2217             : 
    2218       23471 : void SwCrsrShell::CallChgLnk()
    2219             : {
    2220             :     // Do not make any call in start/end action but just remember the change.
    2221             :     // This will be taken care of in the end action.
    2222       23471 :     if( BasicActionPend() )
    2223       14342 :         m_bChgCallFlag = sal_True; // remember change
    2224        9129 :     else if( m_aChgLnk.IsSet() )
    2225             :     {
    2226        9128 :         if( m_bCallChgLnk )
    2227        9128 :             m_aChgLnk.Call( this );
    2228        9128 :         m_bChgCallFlag = sal_False; // reset flag
    2229             :     }
    2230       23471 : }
    2231             : 
    2232             : /// get selected text of a node at current cursor
    2233           0 : OUString SwCrsrShell::GetSelTxt() const
    2234             : {
    2235           0 :     OUString aTxt;
    2236           0 :     if( m_pCurCrsr->GetPoint()->nNode.GetIndex() ==
    2237           0 :         m_pCurCrsr->GetMark()->nNode.GetIndex() )
    2238             :     {
    2239           0 :         SwTxtNode* pTxtNd = m_pCurCrsr->GetNode()->GetTxtNode();
    2240           0 :         if( pTxtNd )
    2241             :         {
    2242           0 :             const sal_Int32 nStt = m_pCurCrsr->Start()->nContent.GetIndex();
    2243           0 :             aTxt = pTxtNd->GetExpandTxt( nStt,
    2244           0 :                     m_pCurCrsr->End()->nContent.GetIndex() - nStt );
    2245             :         }
    2246             :     }
    2247           0 :     return aTxt;
    2248             : }
    2249             : 
    2250             : /// get text only from current cursor position (until end of node)
    2251           0 : OUString SwCrsrShell::GetText() const
    2252             : {
    2253           0 :     OUString aTxt;
    2254           0 :     if( m_pCurCrsr->GetPoint()->nNode.GetIndex() ==
    2255           0 :         m_pCurCrsr->GetMark()->nNode.GetIndex() )
    2256             :     {
    2257           0 :         SwTxtNode* pTxtNd = m_pCurCrsr->GetNode()->GetTxtNode();
    2258           0 :         if( pTxtNd )
    2259           0 :             aTxt = pTxtNd->GetTxt().copy(
    2260           0 :                     m_pCurCrsr->GetPoint()->nContent.GetIndex() );
    2261             :     }
    2262           0 :     return aTxt;
    2263             : }
    2264             : 
    2265             : /** get the nth character of the current SSelection
    2266             : 
    2267             :     @param bEnd    Start counting from the end? From start otherwise.
    2268             :     @param nOffset position of the character
    2269             : */
    2270           2 : sal_Unicode SwCrsrShell::GetChar( sal_Bool bEnd, long nOffset )
    2271             : {
    2272           2 :     if( IsTableMode() ) // not possible in table mode
    2273           0 :         return 0;
    2274             : 
    2275           2 :     const SwPosition* pPos = !m_pCurCrsr->HasMark() ? m_pCurCrsr->GetPoint()
    2276           2 :                                 : bEnd ? m_pCurCrsr->End() : m_pCurCrsr->Start();
    2277           2 :     SwTxtNode* pTxtNd = pPos->nNode.GetNode().GetTxtNode();
    2278           2 :     if( !pTxtNd )
    2279           0 :         return 0;
    2280             : 
    2281           2 :     const sal_Int32 nPos = pPos->nContent.GetIndex();
    2282           2 :     const OUString& rStr = pTxtNd->GetTxt();
    2283           2 :     sal_Unicode cCh = 0;
    2284             : 
    2285           2 :     if (((nPos+nOffset) >= 0 ) && (nPos+nOffset) < rStr.getLength())
    2286           2 :         cCh = rStr[nPos + nOffset];
    2287             : 
    2288           2 :     return cCh;
    2289             : }
    2290             : 
    2291             : /** extend current SSelection by n characters
    2292             : 
    2293             :     @param bEnd   Start counting from the end? From start otherwise.
    2294             :     @param nCount Number of characters.
    2295             : */
    2296           0 : sal_Bool SwCrsrShell::ExtendSelection( sal_Bool bEnd, sal_Int32 nCount )
    2297             : {
    2298           0 :     if( !m_pCurCrsr->HasMark() || IsTableMode() )
    2299           0 :         return sal_False; // no selection
    2300             : 
    2301           0 :     SwPosition* pPos = bEnd ? m_pCurCrsr->End() : m_pCurCrsr->Start();
    2302           0 :     SwTxtNode* pTxtNd = pPos->nNode.GetNode().GetTxtNode();
    2303             :     OSL_ENSURE( pTxtNd, "no text node; how should this then be extended?" );
    2304             : 
    2305           0 :     sal_Int32 nPos = pPos->nContent.GetIndex();
    2306           0 :     if( bEnd )
    2307             :     {
    2308           0 :         if ((nPos + nCount) <= pTxtNd->GetTxt().getLength())
    2309           0 :             nPos = nPos + nCount;
    2310             :         else
    2311           0 :             return sal_False; // not possible
    2312             :     }
    2313           0 :     else if( nPos >= nCount )
    2314           0 :         nPos = nPos - nCount;
    2315             :     else
    2316           0 :         return sal_False; // not possible anymore
    2317             : 
    2318           0 :     SwCallLink aLk( *this ); // watch Crsr-Moves; call Link if needed
    2319             : 
    2320           0 :     pPos->nContent = nPos;
    2321           0 :     UpdateCrsr();
    2322             : 
    2323           0 :     return sal_True;
    2324             : }
    2325             : 
    2326             : /** Move visible cursor to given position in document.
    2327             : 
    2328             :     @param rPt The position to move the visible cursor to.
    2329             :     @return <sal_False> if SPoint was corrected by the layout.
    2330             : */
    2331           0 : sal_Bool SwCrsrShell::SetVisCrsr( const Point &rPt )
    2332             : {
    2333           0 :     SET_CURR_SHELL( this );
    2334           0 :     Point aPt( rPt );
    2335           0 :     SwPosition aPos( *m_pCurCrsr->GetPoint() );
    2336           0 :     SwCrsrMoveState aTmpState( MV_SETONLYTEXT );
    2337           0 :     aTmpState.bSetInReadOnly = IsReadOnlyAvailable();
    2338           0 :     aTmpState.bRealHeight = sal_True;
    2339             : 
    2340           0 :     const bool bRet = GetLayout()->GetCrsrOfst( &aPos, aPt /*, &aTmpState*/ );
    2341             : 
    2342           0 :     SetInFrontOfLabel( false ); // #i27615#
    2343             : 
    2344             :     // show only in TextNodes
    2345           0 :     SwTxtNode* pTxtNd = aPos.nNode.GetNode().GetTxtNode();
    2346           0 :     if( !pTxtNd )
    2347           0 :         return sal_False;
    2348             : 
    2349           0 :     const SwSectionNode* pSectNd = pTxtNd->FindSectionNode();
    2350           0 :     if( pSectNd && (pSectNd->GetSection().IsHiddenFlag() ||
    2351           0 :                     ( !IsReadOnlyAvailable() &&
    2352           0 :                       pSectNd->GetSection().IsProtectFlag())) )
    2353           0 :         return sal_False;
    2354             : 
    2355           0 :     SwCntntFrm *pFrm = pTxtNd->getLayoutFrm( GetLayout(), &aPt, &aPos );
    2356           0 :     if ( Imp()->IsIdleAction() )
    2357           0 :         pFrm->PrepareCrsr();
    2358           0 :     SwRect aTmp( m_aCharRect );
    2359             : 
    2360           0 :     pFrm->GetCharRect( m_aCharRect, aPos, &aTmpState );
    2361             : 
    2362             :     // #i10137#
    2363           0 :     if( aTmp == m_aCharRect && m_pVisCrsr->IsVisible() )
    2364           0 :         return sal_True;
    2365             : 
    2366           0 :     m_pVisCrsr->Hide(); // always hide visible cursor
    2367           0 :     if( IsScrollMDI( this, m_aCharRect ))
    2368             :     {
    2369           0 :         MakeVisible( m_aCharRect );
    2370           0 :         m_pCurCrsr->Show();
    2371             :     }
    2372             : 
    2373             :     {
    2374           0 :         if( aTmpState.bRealHeight )
    2375           0 :             m_aCrsrHeight = aTmpState.aRealHeight;
    2376             :         else
    2377             :         {
    2378           0 :             m_aCrsrHeight.setX(0);
    2379           0 :             m_aCrsrHeight.setY(m_aCharRect.Height());
    2380             :         }
    2381             : 
    2382           0 :         m_pVisCrsr->SetDragCrsr( true );
    2383           0 :         m_pVisCrsr->Show(); // show again
    2384             :     }
    2385           0 :     return bRet;
    2386             : }
    2387             : 
    2388           0 : sal_Bool SwCrsrShell::IsOverReadOnlyPos( const Point& rPt ) const
    2389             : {
    2390           0 :     Point aPt( rPt );
    2391           0 :     SwPaM aPam( *m_pCurCrsr->GetPoint() );
    2392           0 :     GetLayout()->GetCrsrOfst( aPam.GetPoint(), aPt );
    2393             :     // Formular view
    2394           0 :     return aPam.HasReadonlySel( GetViewOptions()->IsFormView() );
    2395             : }
    2396             : 
    2397             : /** Get the number of elements in the ring of cursors
    2398             : 
    2399             :     @param bAll If <false> get only spanned ones (= with selections) (Basic).
    2400             : */
    2401       13442 : sal_uInt16 SwCrsrShell::GetCrsrCnt( sal_Bool bAll ) const
    2402             : {
    2403       13442 :     Ring* pTmp = GetCrsr()->GetNext();
    2404           0 :     sal_uInt16 n = (bAll || ( m_pCurCrsr->HasMark() &&
    2405       26884 :                     *m_pCurCrsr->GetPoint() != *m_pCurCrsr->GetMark())) ? 1 : 0;
    2406       26938 :     while( pTmp != m_pCurCrsr )
    2407             :     {
    2408          54 :         if( bAll || ( ((SwPaM*)pTmp)->HasMark() &&
    2409           0 :                 *((SwPaM*)pTmp)->GetPoint() != *((SwPaM*)pTmp)->GetMark()))
    2410          54 :             ++n;
    2411          54 :         pTmp = pTmp->GetNext();
    2412             :     }
    2413       13442 :     return n;
    2414             : }
    2415             : 
    2416           0 : sal_Bool SwCrsrShell::IsStartOfDoc() const
    2417             : {
    2418           0 :     if( m_pCurCrsr->GetPoint()->nContent.GetIndex() )
    2419           0 :         return sal_False;
    2420             : 
    2421             :     // after EndOfIcons comes the content selection (EndNd+StNd+CntntNd)
    2422           0 :     SwNodeIndex aIdx( GetDoc()->GetNodes().GetEndOfExtras(), 2 );
    2423           0 :     if( !aIdx.GetNode().IsCntntNode() )
    2424           0 :         GetDoc()->GetNodes().GoNext( &aIdx );
    2425           0 :     return aIdx == m_pCurCrsr->GetPoint()->nNode;
    2426             : }
    2427             : 
    2428           0 : sal_Bool SwCrsrShell::IsEndOfDoc() const
    2429             : {
    2430           0 :     SwNodeIndex aIdx( GetDoc()->GetNodes().GetEndOfContent(), -1 );
    2431           0 :     SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
    2432           0 :     if( !pCNd )
    2433           0 :         pCNd = GetDoc()->GetNodes().GoPrevious( &aIdx );
    2434             : 
    2435           0 :     return aIdx == m_pCurCrsr->GetPoint()->nNode &&
    2436           0 :             pCNd->Len() == m_pCurCrsr->GetPoint()->nContent.GetIndex();
    2437             : }
    2438             : 
    2439             : /** Invalidate cursors
    2440             : 
    2441             :     Delete all created cursors, set table crsr and last crsr to their TextNode
    2442             :     (or StartNode?). They will then all re-created at the next ::GetCrsr() call.
    2443             : 
    2444             :     This is needed for Drag&Drop/ Clipboard-paste in tables.
    2445             : */
    2446           0 : sal_Bool SwCrsrShell::ParkTblCrsr()
    2447             : {
    2448           0 :     if( !m_pTblCrsr )
    2449           0 :         return sal_False;
    2450             : 
    2451           0 :     m_pTblCrsr->ParkCrsr();
    2452             : 
    2453           0 :     while( m_pCurCrsr->GetNext() != m_pCurCrsr )
    2454           0 :         delete m_pCurCrsr->GetNext();
    2455             : 
    2456             :     // *always* move cursor's Point and Mark
    2457           0 :     m_pCurCrsr->DeleteMark();
    2458           0 :     *m_pCurCrsr->GetPoint() = *m_pTblCrsr->GetPoint();
    2459             : 
    2460           0 :     return sal_True;
    2461             : }
    2462             : 
    2463           0 : void SwCrsrShell::_ParkPams( SwPaM* pDelRg, SwShellCrsr** ppDelRing )
    2464             : {
    2465           0 :     const SwPosition *pStt = pDelRg->Start(),
    2466           0 :         *pEnd = pDelRg->GetPoint() == pStt ? pDelRg->GetMark() : pDelRg->GetPoint();
    2467             : 
    2468           0 :     SwPaM *pTmpDel = 0, *pTmp = *ppDelRing;
    2469             : 
    2470             :     // search over the whole ring
    2471             :     bool bGoNext;
    2472           0 :     do {
    2473           0 :         const SwPosition *pTmpStt = pTmp->Start(),
    2474           0 :                         *pTmpEnd = pTmp->GetPoint() == pTmpStt ?
    2475           0 :                                         pTmp->GetMark() : pTmp->GetPoint();
    2476             :         // If a SPoint or GetMark are in a cursor area than cancel the old area.
    2477             :         // During comparison keep in mind that End() is outside the area.
    2478           0 :         if( *pStt <= *pTmpStt )
    2479             :         {
    2480           0 :             if( *pEnd > *pTmpStt ||
    2481           0 :                 ( *pEnd == *pTmpStt && *pEnd == *pTmpEnd ))
    2482           0 :                 pTmpDel = pTmp;
    2483             :         }
    2484             :         else
    2485           0 :             if( *pStt < *pTmpEnd )
    2486           0 :                 pTmpDel = pTmp;
    2487             : 
    2488           0 :         bGoNext = true;
    2489           0 :         if (pTmpDel) // is the pam in the range -> delete
    2490             :         {
    2491           0 :             sal_Bool bDelete = sal_True;
    2492           0 :             if( *ppDelRing == pTmpDel )
    2493             :             {
    2494           0 :                 if( *ppDelRing == m_pCurCrsr )
    2495             :                 {
    2496           0 :                     if( sal_True == ( bDelete = GoNextCrsr() ))
    2497             :                     {
    2498           0 :                         bGoNext = false;
    2499           0 :                         pTmp = (SwPaM*)pTmp->GetNext();
    2500             :                     }
    2501             :                 }
    2502             :                 else
    2503           0 :                     bDelete = sal_False; // never delete the StackCrsr
    2504             :             }
    2505             : 
    2506           0 :             if( bDelete )
    2507           0 :                 delete pTmpDel; // invalidate old area
    2508             :             else
    2509             :             {
    2510           0 :                 pTmpDel->DeleteMark();
    2511             :             }
    2512           0 :             pTmpDel = 0;
    2513             :         }
    2514           0 :         if( bGoNext )
    2515           0 :             pTmp = (SwPaM*)pTmp->GetNext();
    2516           0 :     } while( !bGoNext || *ppDelRing != pTmp );
    2517           0 : }
    2518             : 
    2519             : //TODO: provide documentation
    2520             : /** Remove selections and additional cursors of all shells.
    2521             : 
    2522             :     The remaining cursor of the shell is parked.
    2523             : 
    2524             :     @param rIdx ???
    2525             : */
    2526           0 : void SwCrsrShell::ParkCrsr( const SwNodeIndex &rIdx )
    2527             : {
    2528           0 :     SwNode *pNode = &rIdx.GetNode();
    2529             : 
    2530             :     // create a new PaM
    2531           0 :     SwPaM * pNew = new SwPaM( *GetCrsr()->GetPoint() );
    2532           0 :     if( pNode->GetStartNode() )
    2533             :     {
    2534           0 :         if( ( pNode = pNode->StartOfSectionNode())->IsTableNode() )
    2535             :         {
    2536             :             // the given node is in a table, thus park cursor to table node
    2537             :             // (outside of the table)
    2538           0 :             pNew->GetPoint()->nNode = *pNode->StartOfSectionNode();
    2539             :         }
    2540             :         else
    2541             :             // Also on the start node itself. Then we need to request the start
    2542             :             // node always via its end node! (StartOfSelection of StartNode is
    2543             :             // the parent)
    2544           0 :             pNew->GetPoint()->nNode = *pNode->EndOfSectionNode()->StartOfSectionNode();
    2545             :     }
    2546             :     else
    2547           0 :         pNew->GetPoint()->nNode = *pNode->StartOfSectionNode();
    2548           0 :     pNew->SetMark();
    2549           0 :     pNew->GetPoint()->nNode = *pNode->EndOfSectionNode();
    2550             : 
    2551             :     // take care of all shells
    2552           0 :     SwViewShell *pTmp = this;
    2553           0 :     do {
    2554           0 :         if( pTmp->IsA( TYPE( SwCrsrShell )))
    2555             :         {
    2556           0 :             SwCrsrShell* pSh = (SwCrsrShell*)pTmp;
    2557           0 :             if( pSh->m_pCrsrStk )
    2558           0 :                 pSh->_ParkPams( pNew, &pSh->m_pCrsrStk );
    2559             : 
    2560           0 :             pSh->_ParkPams( pNew, &pSh->m_pCurCrsr );
    2561           0 :             if( pSh->m_pTblCrsr )
    2562             :             {
    2563             :                 // set table cursor always to 0 and the current one always to
    2564             :                 // the beginning of the table
    2565           0 :                 SwPaM* pTCrsr = pSh->GetTblCrs();
    2566           0 :                 SwNode* pTblNd = pTCrsr->GetPoint()->nNode.GetNode().FindTableNode();
    2567           0 :                 if ( pTblNd )
    2568             :                 {
    2569           0 :                     pTCrsr->DeleteMark();
    2570           0 :                     pSh->m_pCurCrsr->GetPoint()->nNode = *pTblNd;
    2571             :                 }
    2572             :             }
    2573             :         }
    2574           0 :     } while ( this != (pTmp = (SwViewShell*)pTmp->GetNext() ));
    2575           0 :     delete pNew;
    2576           0 : }
    2577             : 
    2578             : /** Copy constructor
    2579             : 
    2580             :     Copy cursor position and add it to the ring.
    2581             :     All views of a document are in the ring of the shell.
    2582             : */
    2583           0 : SwCrsrShell::SwCrsrShell( SwCrsrShell& rShell, Window *pInitWin )
    2584             :     : SwViewShell( rShell, pInitWin )
    2585             :     , SwModify( 0 )
    2586             :     , m_pCrsrStk( 0 )
    2587             :     , m_pBlockCrsr( 0 )
    2588             :     , m_pTblCrsr( 0 )
    2589             :     , m_pBoxIdx( 0 )
    2590             :     , m_pBoxPtr( 0 )
    2591             :     , m_nUpDownX(0)
    2592             :     , m_nLeftFrmPos(0)
    2593             :     , m_nAktNode(0)
    2594             :     , m_nAktCntnt(0)
    2595             :     , m_nAktNdTyp(0)
    2596             :     , m_bAktSelection(false)
    2597             :     , m_nCrsrMove( 0 )
    2598             :     , m_nBasicActionCnt( 0 )
    2599             :     , m_eMvState( MV_NONE )
    2600             :     , m_sMarkedListId()
    2601             :     , m_nMarkedListLevel( 0 )
    2602           0 :     , m_oldColFrm(0)
    2603             : {
    2604           0 :     SET_CURR_SHELL( this );
    2605             :     // only keep the position of the current cursor of the copy shell
    2606           0 :     m_pCurCrsr = new SwShellCrsr( *this, *(rShell.m_pCurCrsr->GetPoint()) );
    2607           0 :     m_pCurCrsr->GetCntntNode()->Add( this );
    2608             : 
    2609             :     m_bAllProtect = m_bVisPortChgd = m_bChgCallFlag = m_bInCMvVisportChgd =
    2610             :     m_bGCAttr = m_bIgnoreReadonly = m_bSelTblCells = m_bBasicHideCrsr =
    2611           0 :     m_bOverwriteCrsr = sal_False;
    2612           0 :     m_bCallChgLnk = m_bHasFocus = m_bAutoUpdateCells = sal_True;
    2613           0 :     m_bSVCrsrVis = sal_True;
    2614           0 :     m_bSetCrsrInReadOnly = sal_True;
    2615           0 :     m_pVisCrsr = new SwVisCrsr( this );
    2616           0 :     m_bMacroExecAllowed = rShell.IsMacroExecAllowed();
    2617             : 
    2618             : #if defined(ANDROID) || defined(IOS)
    2619             :     HideCrsr();
    2620             : #endif
    2621           0 : }
    2622             : 
    2623             : /// default constructor
    2624        1732 : SwCrsrShell::SwCrsrShell( SwDoc& rDoc, Window *pInitWin,
    2625             :                             const SwViewOption *pInitOpt )
    2626             :     : SwViewShell( rDoc, pInitWin, pInitOpt )
    2627             :     , SwModify( 0 )
    2628             :     , m_pCrsrStk( 0 )
    2629             :     , m_pBlockCrsr( 0 )
    2630             :     , m_pTblCrsr( 0 )
    2631             :     , m_pBoxIdx( 0 )
    2632             :     , m_pBoxPtr( 0 )
    2633             :     , m_nUpDownX(0)
    2634             :     , m_nLeftFrmPos(0)
    2635             :     , m_nAktNode(0)
    2636             :     , m_nAktCntnt(0)
    2637             :     , m_nAktNdTyp(0)
    2638             :     , m_bAktSelection(false)
    2639             :     , m_nCrsrMove( 0 )
    2640             :     , m_nBasicActionCnt( 0 )
    2641             :     , m_eMvState( MV_NONE ) // state for crsr-travelling - GetCrsrOfst
    2642             :     , m_sMarkedListId()
    2643             :     , m_nMarkedListLevel( 0 )
    2644        1732 :     , m_oldColFrm(0)
    2645             : {
    2646        1732 :     SET_CURR_SHELL( this );
    2647             :     // create initial cursor and set it to first content position
    2648        1732 :     SwNodes& rNds = rDoc.GetNodes();
    2649             : 
    2650        3464 :     SwNodeIndex aNodeIdx( *rNds.GetEndOfContent().StartOfSectionNode() );
    2651        1732 :     SwCntntNode* pCNd = rNds.GoNext( &aNodeIdx ); // go to the first ContentNode
    2652             : 
    2653        1732 :     m_pCurCrsr = new SwShellCrsr( *this, SwPosition( aNodeIdx, SwIndex( pCNd, 0 )));
    2654             : 
    2655             :     // Register shell as dependent at current node. As a result all attribute
    2656             :     // changes can be forwarded via the Link.
    2657        1732 :     pCNd->Add( this );
    2658             : 
    2659             :     m_bAllProtect = m_bVisPortChgd = m_bChgCallFlag = m_bInCMvVisportChgd =
    2660             :     m_bGCAttr = m_bIgnoreReadonly = m_bSelTblCells = m_bBasicHideCrsr =
    2661        1732 :     m_bOverwriteCrsr = sal_False;
    2662        1732 :     m_bCallChgLnk = m_bHasFocus = m_bAutoUpdateCells = sal_True;
    2663        1732 :     m_bSVCrsrVis = sal_True;
    2664        1732 :     m_bSetCrsrInReadOnly = sal_True;
    2665             : 
    2666        1732 :     m_pVisCrsr = new SwVisCrsr( this );
    2667        3464 :     m_bMacroExecAllowed = true;
    2668             : 
    2669             : #if defined(ANDROID) || defined(IOS)
    2670             :     HideCrsr();
    2671             : #endif
    2672        1732 : }
    2673             : 
    2674        3462 : SwCrsrShell::~SwCrsrShell()
    2675             : {
    2676             :     // if it is not the last view then at least the field should be updated
    2677        1731 :     if( GetNext() != this )
    2678           0 :         CheckTblBoxCntnt( m_pCurCrsr->GetPoint() );
    2679             :     else
    2680        1731 :         ClearTblBoxCntnt();
    2681             : 
    2682        1731 :     delete m_pVisCrsr;
    2683        1731 :     delete m_pBlockCrsr;
    2684        1731 :     delete m_pTblCrsr;
    2685             : 
    2686             :     // release cursors
    2687        3463 :     while(m_pCurCrsr->GetNext() != m_pCurCrsr)
    2688           1 :         delete m_pCurCrsr->GetNext();
    2689        1731 :     delete m_pCurCrsr;
    2690             : 
    2691             :     // free stack
    2692        1731 :     if( m_pCrsrStk )
    2693             :     {
    2694           0 :         while( m_pCrsrStk->GetNext() != m_pCrsrStk )
    2695           0 :             delete m_pCrsrStk->GetNext();
    2696           0 :         delete m_pCrsrStk;
    2697             :     }
    2698             : 
    2699             :     // #i54025# - do not give a HTML parser that might potentially hang as
    2700             :     // a client at the cursor shell the chance to hang itself on a TextNode
    2701        1731 :     if( GetRegisteredIn() )
    2702        1731 :         GetRegisteredInNonConst()->Remove( this );
    2703        1731 : }
    2704             : 
    2705      140478 : SwShellCrsr* SwCrsrShell::getShellCrsr( bool bBlock )
    2706             : {
    2707      140478 :     if( m_pTblCrsr )
    2708          77 :         return m_pTblCrsr;
    2709      140401 :     if( m_pBlockCrsr && bBlock )
    2710           0 :         return &m_pBlockCrsr->getShellCrsr();
    2711      140401 :     return m_pCurCrsr;
    2712             : }
    2713             : 
    2714             : /** Should WaitPtr be switched on for the clipboard?
    2715             : 
    2716             :     Wait for TableMode, multiple selections and more than x selected paragraphs.
    2717             : */
    2718           1 : bool SwCrsrShell::ShouldWait() const
    2719             : {
    2720           1 :     if ( IsTableMode() || GetCrsrCnt() > 1 )
    2721           0 :         return true;
    2722             : 
    2723           1 :     if( HasDrawView() && GetDrawView()->GetMarkedObjectList().GetMarkCount() )
    2724           0 :         return true;
    2725             : 
    2726           1 :     SwPaM* pPam = GetCrsr();
    2727           1 :     return pPam->Start()->nNode.GetIndex() + 10 <
    2728           1 :             pPam->End()->nNode.GetIndex();
    2729             : }
    2730             : 
    2731           0 : size_t SwCrsrShell::UpdateTblSelBoxes()
    2732             : {
    2733           0 :     if (m_pTblCrsr && (m_pTblCrsr->IsChgd() || !m_pTblCrsr->GetSelectedBoxesCount()))
    2734             :     {
    2735           0 :          GetLayout()->MakeTblCrsrs( *m_pTblCrsr );
    2736             :     }
    2737           0 :     return (m_pTblCrsr) ? m_pTblCrsr->GetSelectedBoxesCount() : 0;
    2738             : }
    2739             : 
    2740             : /// show the current selected "object"
    2741       24355 : void SwCrsrShell::MakeSelVisible()
    2742             : {
    2743             :     OSL_ENSURE( m_bHasFocus, "no focus but cursor should be made visible?" );
    2744       24355 :     if( m_aCrsrHeight.Y() < m_aCharRect.Height() && m_aCharRect.Height() > VisArea().Height() )
    2745             :     {
    2746          20 :         SwRect aTmp( m_aCharRect );
    2747          20 :         long nDiff = m_aCharRect.Height() - VisArea().Height();
    2748          20 :         if( nDiff < m_aCrsrHeight.getX() )
    2749           0 :             aTmp.Top( nDiff + m_aCharRect.Top() );
    2750             :         else
    2751             :         {
    2752          20 :             aTmp.Top( m_aCrsrHeight.getX() + m_aCharRect.Top() );
    2753          20 :             aTmp.Height( m_aCrsrHeight.getY() );
    2754             :         }
    2755          20 :         if( !aTmp.HasArea() )
    2756             :         {
    2757           0 :             aTmp.SSize().Height() += 1;
    2758           0 :             aTmp.SSize().Width() += 1;
    2759             :         }
    2760          20 :         MakeVisible( aTmp );
    2761             :     }
    2762             :     else
    2763             :     {
    2764       24335 :         if( m_aCharRect.HasArea() )
    2765       24300 :             MakeVisible( m_aCharRect );
    2766             :         else
    2767             :         {
    2768          35 :             SwRect aTmp( m_aCharRect );
    2769          35 :             aTmp.SSize().Height() += 1; aTmp.SSize().Width() += 1;
    2770          35 :             MakeVisible( aTmp );
    2771             :         }
    2772             :     }
    2773       24355 : }
    2774             : 
    2775             : /// search a valid content position (not protected/hidden)
    2776           0 : sal_Bool SwCrsrShell::FindValidCntntNode( sal_Bool bOnlyText )
    2777             : {
    2778           0 :     if( m_pTblCrsr )
    2779             :     {
    2780             :         OSL_ENSURE( !this, "Did not remove table selection!" );
    2781           0 :         return sal_False;
    2782             :     }
    2783             : 
    2784             :     // #i45129# - everything is allowed in UI-readonly
    2785           0 :     if( !m_bAllProtect && GetDoc()->GetDocShell() &&
    2786           0 :         GetDoc()->GetDocShell()->IsReadOnlyUI() )
    2787           0 :         return sal_True;
    2788             : 
    2789           0 :     if( m_pCurCrsr->HasMark() )
    2790           0 :         ClearMark();
    2791             : 
    2792             :     // first check for frames
    2793           0 :     SwNodeIndex& rNdIdx = m_pCurCrsr->GetPoint()->nNode;
    2794           0 :     sal_uLong nNdIdx = rNdIdx.GetIndex(); // keep backup
    2795           0 :     SwNodes& rNds = mpDoc->GetNodes();
    2796           0 :     SwCntntNode* pCNd = rNdIdx.GetNode().GetCntntNode();
    2797             :     const SwCntntFrm * pFrm;
    2798             : 
    2799           0 :     if( pCNd && 0 != (pFrm = pCNd->getLayoutFrm( GetLayout(), 0, m_pCurCrsr->GetPoint(), false)) &&
    2800           0 :         !IsReadOnlyAvailable() && pFrm->IsProtected() &&
    2801           0 :         nNdIdx < rNds.GetEndOfExtras().GetIndex() )
    2802             :     {
    2803             :         // skip protected frame
    2804           0 :         SwPaM aPam( *m_pCurCrsr->GetPoint() );
    2805           0 :         aPam.SetMark();
    2806           0 :         aPam.GetMark()->nNode = rNds.GetEndOfContent();
    2807           0 :         aPam.GetPoint()->nNode = *pCNd->EndOfSectionNode();
    2808             : 
    2809           0 :         sal_Bool bFirst = sal_False;
    2810           0 :         if( 0 == (pCNd = ::GetNode( aPam, bFirst, fnMoveForward, sal_False )))
    2811             :         {
    2812           0 :             aPam.GetMark()->nNode = *rNds.GetEndOfPostIts().StartOfSectionNode();
    2813           0 :             pCNd = ::GetNode( aPam, bFirst, fnMoveBackward, sal_False );
    2814             :         }
    2815             : 
    2816           0 :         if( !pCNd ) // should *never* happen
    2817             :         {
    2818           0 :             rNdIdx = nNdIdx; // back to old node
    2819           0 :             return sal_False;
    2820             :         }
    2821           0 :         *m_pCurCrsr->GetPoint() = *aPam.GetPoint();
    2822             :     }
    2823           0 :     else if( bOnlyText && pCNd && pCNd->IsNoTxtNode() )
    2824             :     {
    2825             :         // set to beginning of document
    2826           0 :         rNdIdx = mpDoc->GetNodes().GetEndOfExtras();
    2827           0 :         m_pCurCrsr->GetPoint()->nContent.Assign( mpDoc->GetNodes().GoNext(
    2828           0 :                                                             &rNdIdx ), 0 );
    2829           0 :         nNdIdx = rNdIdx.GetIndex();
    2830             :     }
    2831             : 
    2832           0 :     sal_Bool bOk = sal_True;
    2833             : 
    2834             :     // #i9059# cursor may not stand in protected cells
    2835             :     //         (unless cursor in protected areas is OK.)
    2836           0 :     const SwTableNode* pTableNode = rNdIdx.GetNode().FindTableNode();
    2837           0 :     if( !IsReadOnlyAvailable()  &&
    2838           0 :         pTableNode != NULL  &&  rNdIdx.GetNode().IsProtect() )
    2839             :     {
    2840             :         // we're in a table, and we're in a protected area, so we're
    2841             :         // probably in a protected cell.
    2842             : 
    2843             :         // move forward into non-protected area.
    2844           0 :         SwPaM aPam( rNdIdx.GetNode(), 0 );
    2845           0 :         while( aPam.GetNode()->IsProtect() &&
    2846           0 :                aPam.Move( fnMoveForward, fnGoCntnt ) )
    2847             :             ; // nothing to do in the loop; the aPam.Move does the moving!
    2848             : 
    2849             :         // didn't work? then go backwards!
    2850           0 :         if( aPam.GetNode()->IsProtect() )
    2851             :         {
    2852           0 :             SwPaM aTmpPaM( rNdIdx.GetNode(), 0 );
    2853           0 :             aPam = aTmpPaM;
    2854           0 :             while( aPam.GetNode()->IsProtect() &&
    2855           0 :                    aPam.Move( fnMoveBackward, fnGoCntnt ) )
    2856           0 :                 ; // nothing to do in the loop; the aPam.Move does the moving!
    2857             :         }
    2858             : 
    2859             :         // if we're successful, set the new position
    2860           0 :         if( ! aPam.GetNode()->IsProtect() )
    2861             :         {
    2862           0 :             *m_pCurCrsr->GetPoint() = *aPam.GetPoint();
    2863           0 :         }
    2864             :     }
    2865             : 
    2866             :     // in a protected frame
    2867           0 :     const SwSectionNode* pSectNd = rNdIdx.GetNode().FindSectionNode();
    2868           0 :     if( pSectNd && ( pSectNd->GetSection().IsHiddenFlag() ||
    2869           0 :         ( !IsReadOnlyAvailable() &&
    2870           0 :            pSectNd->GetSection().IsProtectFlag() )) )
    2871             :     {
    2872             :         typedef SwCntntNode* (SwNodes:: *FNGoSection)( SwNodeIndex *, bool, bool ) const;
    2873           0 :         FNGoSection funcGoSection = &SwNodes::GoNextSection;
    2874             : 
    2875           0 :         bOk = sal_False;
    2876             : 
    2877           0 :         for( int nLoopCnt = 0; !bOk && nLoopCnt < 2; ++nLoopCnt )
    2878             :         {
    2879             :             bool bContinue;
    2880           0 :             do {
    2881           0 :                 bContinue = false;
    2882           0 :                 while( 0 != ( pCNd = (rNds.*funcGoSection)( &rNdIdx,
    2883           0 :                                             true, !IsReadOnlyAvailable() )) )
    2884             :                 {
    2885             :                     // moved inside a table -> check if it is protected
    2886           0 :                     if( pCNd->FindTableNode() )
    2887             :                     {
    2888           0 :                         SwCallLink aTmp( *this );
    2889           0 :                         SwCrsrSaveState aSaveState( *m_pCurCrsr );
    2890           0 :                         aTmp.nNdTyp = 0; // don't do anything in DTOR
    2891           0 :                         if( !m_pCurCrsr->IsInProtectTable( sal_True, sal_True ) )
    2892             :                         {
    2893           0 :                             const SwSectionNode* pSNd = pCNd->FindSectionNode();
    2894           0 :                             if( !pSNd || !pSNd->GetSection().IsHiddenFlag()
    2895           0 :                                 || (!IsReadOnlyAvailable()  &&
    2896           0 :                                     pSNd->GetSection().IsProtectFlag() ))
    2897             :                             {
    2898           0 :                                 bOk = sal_True;
    2899           0 :                                 break; // found non-protected cell
    2900             :                             }
    2901           0 :                             continue; // continue search
    2902           0 :                         }
    2903             :                     }
    2904             :                     else
    2905             :                     {
    2906           0 :                         bOk = sal_True;
    2907           0 :                         break; // found non-protected cell
    2908             :                     }
    2909             :                 }
    2910             : 
    2911           0 :                 if( bOk && rNdIdx.GetIndex() < rNds.GetEndOfExtras().GetIndex() )
    2912             :                 {
    2913             :                     // also check for Fly - might be protected as well
    2914           0 :                     if( 0 == (pFrm = pCNd->getLayoutFrm( GetLayout(), 0, 0, false)) ||
    2915           0 :                         ( !IsReadOnlyAvailable() && pFrm->IsProtected() ) ||
    2916           0 :                         ( bOnlyText && pCNd->IsNoTxtNode() ) )
    2917             :                     {
    2918             :                         // continue search
    2919           0 :                         bOk = sal_False;
    2920           0 :                         bContinue = true;
    2921             :                     }
    2922             :                 }
    2923             :             } while( bContinue );
    2924             : 
    2925           0 :             if( !bOk )
    2926             :             {
    2927           0 :                 if( !nLoopCnt )
    2928           0 :                     funcGoSection = &SwNodes::GoPrevSection;
    2929           0 :                 rNdIdx = nNdIdx;
    2930             :             }
    2931             :         }
    2932             :     }
    2933           0 :     if( bOk )
    2934             :     {
    2935           0 :         pCNd = rNdIdx.GetNode().GetCntntNode();
    2936           0 :         const sal_Int32 nCntnt = rNdIdx.GetIndex() < nNdIdx ? pCNd->Len() : 0;
    2937           0 :         m_pCurCrsr->GetPoint()->nContent.Assign( pCNd, nCntnt );
    2938             :     }
    2939             :     else
    2940             :     {
    2941           0 :         pCNd = rNdIdx.GetNode().GetCntntNode();
    2942             :         // if cursor in hidden frame, always move it
    2943           0 :         if( !pCNd || !pCNd->getLayoutFrm( GetLayout(), 0, 0, false) )
    2944             :         {
    2945           0 :             SwCrsrMoveState aTmpState( MV_NONE );
    2946           0 :             aTmpState.bSetInReadOnly = IsReadOnlyAvailable();
    2947           0 :             GetLayout()->GetCrsrOfst( m_pCurCrsr->GetPoint(), m_pCurCrsr->GetPtPos(),
    2948           0 :                                         &aTmpState );
    2949             :         }
    2950             :     }
    2951           0 :     return bOk;
    2952             : }
    2953             : 
    2954       81096 : sal_Bool SwCrsrShell::IsCrsrReadonly() const
    2955             : {
    2956      162166 :     if ( GetViewOptions()->IsReadonly() ||
    2957       81070 :          GetViewOptions()->IsFormView() /* Formula view */ )
    2958             :     {
    2959          26 :         SwFrm *pFrm = GetCurrFrm( sal_False );
    2960             :         const SwFlyFrm* pFly;
    2961             :         const SwSection* pSection;
    2962             : 
    2963          52 :         if( pFrm && pFrm->IsInFly() &&
    2964           0 :             (pFly = pFrm->FindFlyFrm())->GetFmt()->GetEditInReadonly().GetValue() &&
    2965           0 :             pFly->Lower() &&
    2966          26 :             !pFly->Lower()->IsNoTxtFrm() &&
    2967           0 :             !GetDrawView()->GetMarkedObjectList().GetMarkCount() )
    2968             :         {
    2969           0 :             return sal_False;
    2970             :         }
    2971             :         // edit in readonly sections
    2972          52 :         else if ( pFrm && pFrm->IsInSct() &&
    2973          26 :             0 != ( pSection = pFrm->FindSctFrm()->GetSection() ) &&
    2974           0 :             pSection->IsEditInReadonlyFlag() )
    2975             :         {
    2976           0 :             return sal_False;
    2977             :         }
    2978          26 :         else if ( !IsMultiSelection() && CrsrInsideInputFld() )
    2979             :         {
    2980           0 :             return sal_False;
    2981             :         }
    2982             : 
    2983          26 :         return sal_True;
    2984             :     }
    2985       81070 :     return sal_False;
    2986             : }
    2987             : 
    2988             : /// is the cursor allowed to enter ReadOnly sections?
    2989        1800 : void SwCrsrShell::SetReadOnlyAvailable( sal_Bool bFlag )
    2990             : {
    2991             :     // *never* switch in GlobalDoc
    2992        5400 :     if( (!GetDoc()->GetDocShell() ||
    2993        3600 :          !GetDoc()->GetDocShell()->IsA( SwGlobalDocShell::StaticType() )) &&
    2994        1800 :         bFlag != m_bSetCrsrInReadOnly )
    2995             :     {
    2996             :         // If the flag is switched off then all selections need to be
    2997             :         // invalidated. Otherwise we would trust that nothing protected is selected.
    2998           0 :         if( !bFlag )
    2999             :         {
    3000           0 :             ClearMark();
    3001             :         }
    3002           0 :         m_bSetCrsrInReadOnly = bFlag;
    3003           0 :         UpdateCrsr();
    3004             :     }
    3005        1800 : }
    3006             : 
    3007       14594 : sal_Bool SwCrsrShell::HasReadonlySel(bool bAnnotationMode) const
    3008             : {
    3009       14594 :     sal_Bool bRet = sal_False;
    3010       14594 :     if ( IsReadOnlyAvailable() || GetViewOptions()->IsFormView() )
    3011             :     {
    3012       14594 :         if ( m_pTblCrsr != NULL )
    3013             :         {
    3014          18 :             bRet = m_pTblCrsr->HasReadOnlyBoxSel()
    3015          18 :                    || m_pTblCrsr->HasReadonlySel( GetViewOptions()->IsFormView() );
    3016             :         }
    3017             :         else
    3018             :         {
    3019       14576 :             const SwPaM* pCrsr = m_pCurCrsr;
    3020             : 
    3021       14576 :             do
    3022             :             {
    3023       14576 :                 if( pCrsr->HasReadonlySel( GetViewOptions()->IsFormView(), bAnnotationMode ) )
    3024             :                 {
    3025          13 :                     bRet = sal_True;
    3026             :                 }
    3027             : 
    3028       14576 :                 pCrsr = (SwPaM*)pCrsr->GetNext();
    3029       14563 :             } while ( !bRet && pCrsr != m_pCurCrsr );
    3030             :         }
    3031             :     }
    3032       14594 :     return bRet;
    3033             : }
    3034             : 
    3035           0 : sal_Bool SwCrsrShell::IsSelFullPara() const
    3036             : {
    3037           0 :     sal_Bool bRet = sal_False;
    3038             : 
    3039           0 :     if( m_pCurCrsr->GetPoint()->nNode.GetIndex() ==
    3040           0 :         m_pCurCrsr->GetMark()->nNode.GetIndex() && m_pCurCrsr == m_pCurCrsr->GetNext() )
    3041             :     {
    3042           0 :         sal_Int32 nStt = m_pCurCrsr->GetPoint()->nContent.GetIndex();
    3043           0 :         sal_Int32 nEnd = m_pCurCrsr->GetMark()->nContent.GetIndex();
    3044           0 :         if( nStt > nEnd )
    3045             :         {
    3046           0 :             sal_Int32 nTmp = nStt;
    3047           0 :             nStt = nEnd;
    3048           0 :             nEnd = nTmp;
    3049             :         }
    3050           0 :         const SwCntntNode* pCNd = m_pCurCrsr->GetCntntNode();
    3051           0 :         bRet = pCNd && !nStt && nEnd == pCNd->Len();
    3052             :     }
    3053           0 :     return bRet;
    3054             : }
    3055             : 
    3056        8649 : short SwCrsrShell::GetTextDirection( const Point* pPt ) const
    3057             : {
    3058        8649 :     SwPosition aPos( *m_pCurCrsr->GetPoint() );
    3059        8649 :     Point aPt( pPt ? *pPt : m_pCurCrsr->GetPtPos() );
    3060        8649 :     if( pPt )
    3061             :     {
    3062           0 :         SwCrsrMoveState aTmpState( MV_NONE );
    3063           0 :         aTmpState.bSetInReadOnly = IsReadOnlyAvailable();
    3064             : 
    3065           0 :         GetLayout()->GetCrsrOfst( &aPos, aPt, &aTmpState );
    3066             :     }
    3067             : 
    3068        8649 :     return mpDoc->GetTextDirection( aPos, &aPt );
    3069             : }
    3070             : 
    3071        3769 : bool SwCrsrShell::IsInVerticalText( const Point* pPt ) const
    3072             : {
    3073        3769 :     const short nDir = GetTextDirection( pPt );
    3074        3769 :     return FRMDIR_VERT_TOP_RIGHT == nDir || FRMDIR_VERT_TOP_LEFT == nDir;
    3075             : }
    3076             : 
    3077        4880 : sal_Bool SwCrsrShell::IsInRightToLeftText( const Point* pPt ) const
    3078             : {
    3079        4880 :     const short nDir = GetTextDirection( pPt );
    3080             :     // GetTextDirection uses FRMDIR_VERT_TOP_LEFT to indicate RTL in
    3081             :     // vertical environment
    3082        4880 :     return FRMDIR_VERT_TOP_LEFT == nDir || FRMDIR_HORI_RIGHT_TOP == nDir;
    3083             : }
    3084             : 
    3085             : /// If the current cursor position is inside a hidden range, the hidden range
    3086             : /// is selected.
    3087           0 : bool SwCrsrShell::SelectHiddenRange()
    3088             : {
    3089           0 :     bool bRet = false;
    3090           0 :     if ( !GetViewOptions()->IsShowHiddenChar() && !m_pCurCrsr->HasMark() )
    3091             :     {
    3092           0 :         SwPosition& rPt = *(SwPosition*)m_pCurCrsr->GetPoint();
    3093           0 :         const SwTxtNode* pNode = rPt.nNode.GetNode().GetTxtNode();
    3094           0 :         if ( pNode )
    3095             :         {
    3096           0 :             const sal_Int32 nPos = rPt.nContent.GetIndex();
    3097             : 
    3098             :             // check if nPos is in hidden range
    3099             :             sal_Int32 nHiddenStart;
    3100             :             sal_Int32 nHiddenEnd;
    3101           0 :             SwScriptInfo::GetBoundsOfHiddenRange( *pNode, nPos, nHiddenStart, nHiddenEnd );
    3102           0 :             if ( COMPLETE_STRING != nHiddenStart )
    3103             :             {
    3104             :                 // make selection:
    3105           0 :                 m_pCurCrsr->SetMark();
    3106           0 :                 m_pCurCrsr->GetMark()->nContent = nHiddenEnd;
    3107           0 :                 bRet = true;
    3108             :             }
    3109             :         }
    3110             :     }
    3111             : 
    3112           0 :     return bRet;
    3113             : }
    3114             : 
    3115           0 : sal_uLong SwCrsrShell::Find( const SearchOptions& rSearchOpt,
    3116             :                              sal_Bool bSearchInNotes,
    3117             :                              SwDocPositions eStart, SwDocPositions eEnd,
    3118             :                              sal_Bool& bCancel,
    3119             :                              FindRanges eRng,
    3120             :                              int bReplace )
    3121             : {
    3122           0 :     if( m_pTblCrsr )
    3123           0 :         GetCrsr();
    3124           0 :     delete m_pTblCrsr, m_pTblCrsr = 0;
    3125           0 :     SwCallLink aLk( *this ); // watch Crsr-Moves; call Link if needed
    3126             :     sal_uLong nRet = m_pCurCrsr->Find( rSearchOpt, bSearchInNotes, eStart, eEnd,
    3127           0 :                                      bCancel, eRng, bReplace );
    3128           0 :     if( nRet || bCancel )
    3129           0 :         UpdateCrsr();
    3130           0 :     return nRet;
    3131             : }
    3132             : 
    3133           0 : sal_uLong SwCrsrShell::Find( const SwTxtFmtColl& rFmtColl,
    3134             :                              SwDocPositions eStart, SwDocPositions eEnd,
    3135             :                              sal_Bool& bCancel,
    3136             :                              FindRanges eRng,
    3137             :                              const SwTxtFmtColl* pReplFmt )
    3138             : {
    3139           0 :     if( m_pTblCrsr )
    3140           0 :         GetCrsr();
    3141           0 :     delete m_pTblCrsr, m_pTblCrsr = 0;
    3142           0 :     SwCallLink aLk( *this ); // watch Crsr-Moves; call Link if needed
    3143             :     sal_uLong nRet = m_pCurCrsr->Find( rFmtColl, eStart, eEnd, bCancel, eRng,
    3144           0 :                                      pReplFmt );
    3145           0 :     if( nRet )
    3146           0 :         UpdateCrsr();
    3147           0 :     return nRet;
    3148             : }
    3149             : 
    3150           0 : sal_uLong SwCrsrShell::Find( const SfxItemSet& rSet,
    3151             :                              sal_Bool bNoCollections,
    3152             :                              SwDocPositions eStart, SwDocPositions eEnd,
    3153             :                              sal_Bool& bCancel,
    3154             :                              FindRanges eRng,
    3155             :                              const SearchOptions* pSearchOpt,
    3156             :                              const SfxItemSet* rReplSet )
    3157             : {
    3158           0 :     if( m_pTblCrsr )
    3159           0 :         GetCrsr();
    3160           0 :     delete m_pTblCrsr, m_pTblCrsr = 0;
    3161           0 :     SwCallLink aLk( *this ); // watch Crsr-Moves; call Link if needed
    3162             :     sal_uLong nRet = m_pCurCrsr->Find( rSet, bNoCollections, eStart, eEnd,
    3163           0 :                                      bCancel, eRng, pSearchOpt, rReplSet );
    3164           0 :     if( nRet )
    3165           0 :         UpdateCrsr();
    3166           0 :     return nRet;
    3167             : }
    3168             : 
    3169           9 : void SwCrsrShell::SetSelection( const SwPaM& rCrsr )
    3170             : {
    3171           9 :     StartAction();
    3172           9 :     SwPaM* pCrsr = GetCrsr();
    3173           9 :     *pCrsr->GetPoint() = *rCrsr.GetPoint();
    3174           9 :     if(rCrsr.HasMark())
    3175             :     {
    3176           2 :         pCrsr->SetMark();
    3177           2 :         *pCrsr->GetMark() = *rCrsr.GetMark();
    3178             :     }
    3179           9 :     if((SwPaM*)rCrsr.GetNext() != &rCrsr)
    3180             :     {
    3181           0 :         const SwPaM *_pStartCrsr = (SwPaM*)rCrsr.GetNext();
    3182           0 :         do
    3183             :         {
    3184           0 :             SwPaM* pCurrentCrsr = CreateCrsr();
    3185           0 :             *pCurrentCrsr->GetPoint() = *_pStartCrsr->GetPoint();
    3186           0 :             if(_pStartCrsr->HasMark())
    3187             :             {
    3188           0 :                 pCurrentCrsr->SetMark();
    3189           0 :                 *pCurrentCrsr->GetMark() = *_pStartCrsr->GetMark();
    3190             :             }
    3191           0 :         } while( (_pStartCrsr=(SwPaM *)_pStartCrsr->GetNext()) != &rCrsr );
    3192             :     }
    3193           9 :     EndAction();
    3194           9 : }
    3195             : 
    3196           0 : static const SwStartNode* lcl_NodeContext( const SwNode& rNode )
    3197             : {
    3198           0 :     const SwStartNode *pRet = rNode.StartOfSectionNode();
    3199           0 :     while( pRet->IsSectionNode() || pRet->IsTableNode() ||
    3200           0 :         pRet->GetStartNodeType() == SwTableBoxStartNode )
    3201             :     {
    3202           0 :         pRet = pRet->StartOfSectionNode();
    3203             :     }
    3204           0 :     return pRet;
    3205             : }
    3206             : 
    3207             : /**
    3208             :    Checks if a position is valid. To be valid the position's node must
    3209             :    be a content node and the content must not be unregistered.
    3210             : 
    3211             :    @param aPos the position to check.
    3212             : */
    3213       28093 : bool sw_PosOk(const SwPosition & aPos)
    3214             : {
    3215       56186 :     return NULL != aPos.nNode.GetNode().GetCntntNode() &&
    3216       56186 :            aPos.nContent.GetIdxReg();
    3217             : }
    3218             : 
    3219             : /**
    3220             :    Checks if a PaM is valid. For a PaM to be valid its point must be
    3221             :    valid. Additionally if the PaM has a mark this has to be valid, too.
    3222             : 
    3223             :    @param aPam the PaM to check
    3224             : */
    3225          19 : static bool lcl_CrsrOk(SwPaM & aPam)
    3226             : {
    3227          38 :     return sw_PosOk(*aPam.GetPoint()) && (! aPam.HasMark()
    3228          38 :         || sw_PosOk(*aPam.GetMark()));
    3229             : }
    3230             : 
    3231       27903 : void SwCrsrShell::ClearUpCrsrs()
    3232             : {
    3233             :     // start of the ring
    3234       27903 :     SwPaM * pStartCrsr = GetCrsr();
    3235             :     // start loop with second entry of the ring
    3236       27903 :     SwPaM * pCrsr = (SwPaM *) pStartCrsr->GetNext();
    3237             :     SwPaM * pTmpCrsr;
    3238       27903 :     bool bChanged = false;
    3239             : 
    3240             :     // For all entries in the ring except the start entry delete the entry if
    3241             :     // it is invalid.
    3242       55825 :     while (pCrsr != pStartCrsr)
    3243             :     {
    3244          19 :         pTmpCrsr = (SwPaM *) pCrsr->GetNext();
    3245          19 :         if ( ! lcl_CrsrOk(*pCrsr))
    3246             :         {
    3247           0 :             delete pCrsr;
    3248           0 :             bChanged = true;
    3249             :         }
    3250          19 :         pCrsr = pTmpCrsr;
    3251             :     }
    3252             : 
    3253       27903 :     if( pStartCrsr->HasMark() && !sw_PosOk( *pStartCrsr->GetMark() ) )
    3254             :     {
    3255           0 :         pStartCrsr->DeleteMark();
    3256           0 :         bChanged = true;
    3257             :     }
    3258       27903 :     if( !sw_PosOk( *pStartCrsr->GetPoint() ) )
    3259             :     {
    3260           0 :         SwNodes & aNodes = GetDoc()->GetNodes();
    3261           0 :         const SwNode* pStart = lcl_NodeContext( pStartCrsr->GetPoint()->nNode.GetNode() );
    3262           0 :         SwNodeIndex aIdx( pStartCrsr->GetPoint()->nNode );
    3263           0 :         SwNode * pNode = aNodes.GoPrevious(&aIdx);
    3264           0 :         if( pNode == NULL || lcl_NodeContext( *pNode ) != pStart )
    3265           0 :             aNodes.GoNext( &aIdx );
    3266           0 :         if( pNode == NULL || lcl_NodeContext( *pNode ) != pStart )
    3267             :         {
    3268             :             // If the start entry of the ring is invalid replace it with a
    3269             :             // cursor pointing to the beginning of the first content node in the
    3270             :             // document.
    3271           0 :             aIdx = (*(aNodes.GetEndOfContent().StartOfSectionNode()));
    3272           0 :             pNode = aNodes.GoNext( &aIdx );
    3273             :         }
    3274           0 :         bool bFound = (pNode != NULL);
    3275             : 
    3276             :         OSL_ENSURE(bFound, "no content node found");
    3277             : 
    3278           0 :         if (bFound)
    3279             :         {
    3280           0 :             SwPaM aTmpPam(*pNode);
    3281           0 :             *pStartCrsr = aTmpPam;
    3282             :         }
    3283             : 
    3284           0 :         bChanged = true;
    3285             :     }
    3286             : 
    3287             :     // If at least one of the cursors in the ring have been deleted or replaced,
    3288             :     // remove the table cursor.
    3289       27903 :     if (m_pTblCrsr != NULL && bChanged)
    3290           0 :         TblCrsrToCursor();
    3291       27903 : }
    3292             : 
    3293           0 : OUString SwCrsrShell::GetCrsrDescr() const
    3294             : {
    3295           0 :     OUString aResult;
    3296             : 
    3297           0 :     if (IsMultiSelection())
    3298           0 :         aResult += SW_RES(STR_MULTISEL);
    3299             :     else
    3300           0 :         aResult = GetDoc()->GetPaMDescr(*GetCrsr());
    3301             : 
    3302           0 :     return aResult;
    3303             : }
    3304             : 
    3305           0 : static void lcl_FillRecognizerData( uno::Sequence< OUString >& rSmartTagTypes,
    3306             :                              uno::Sequence< uno::Reference< container::XStringKeyMap > >& rStringKeyMaps,
    3307             :                              const SwWrongList& rSmartTagList, sal_Int32 nCurrent )
    3308             : {
    3309             :     // Insert smart tag information
    3310           0 :     std::vector< OUString > aSmartTagTypes;
    3311           0 :     std::vector< uno::Reference< container::XStringKeyMap > > aStringKeyMaps;
    3312             : 
    3313           0 :     for ( sal_uInt16 i = 0; i < rSmartTagList.Count(); ++i )
    3314             :     {
    3315           0 :         const sal_Int32 nSTPos = rSmartTagList.Pos( i );
    3316           0 :         const sal_Int32 nSTLen = rSmartTagList.Len( i );
    3317             : 
    3318           0 :         if ( nSTPos <= nCurrent && nCurrent < nSTPos + nSTLen )
    3319             :         {
    3320           0 :             const SwWrongArea* pArea = rSmartTagList.GetElement( i );
    3321           0 :             if ( pArea )
    3322             :             {
    3323           0 :                 aSmartTagTypes.push_back( pArea->maType );
    3324           0 :                 aStringKeyMaps.push_back( pArea->mxPropertyBag );
    3325             :             }
    3326             :         }
    3327             :     }
    3328             : 
    3329           0 :     if ( !aSmartTagTypes.empty() )
    3330             :     {
    3331           0 :         rSmartTagTypes.realloc( aSmartTagTypes.size() );
    3332           0 :         rStringKeyMaps.realloc( aSmartTagTypes.size() );
    3333             : 
    3334           0 :         std::vector< OUString >::const_iterator aTypesIter = aSmartTagTypes.begin();
    3335           0 :         sal_uInt16 i = 0;
    3336           0 :         for ( aTypesIter = aSmartTagTypes.begin(); aTypesIter != aSmartTagTypes.end(); ++aTypesIter )
    3337           0 :             rSmartTagTypes[i++] = *aTypesIter;
    3338             : 
    3339           0 :         std::vector< uno::Reference< container::XStringKeyMap > >::const_iterator aMapsIter = aStringKeyMaps.begin();
    3340           0 :         i = 0;
    3341           0 :         for ( aMapsIter = aStringKeyMaps.begin(); aMapsIter != aStringKeyMaps.end(); ++aMapsIter )
    3342           0 :             rStringKeyMaps[i++] = *aMapsIter;
    3343           0 :     }
    3344           0 : }
    3345             : 
    3346           0 : static void lcl_FillTextRange( uno::Reference<text::XTextRange>& rRange,
    3347             :                    SwTxtNode& rNode, sal_Int32 nBegin, sal_Int32 nLen )
    3348             : {
    3349             :     // create SwPosition for nStartIndex
    3350           0 :     SwIndex aIndex( &rNode, nBegin );
    3351           0 :     SwPosition aStartPos( rNode, aIndex );
    3352             : 
    3353             :     // create SwPosition for nEndIndex
    3354           0 :     SwPosition aEndPos( aStartPos );
    3355           0 :     aEndPos.nContent = nBegin + nLen;
    3356             : 
    3357             :     const uno::Reference<text::XTextRange> xRange =
    3358           0 :         SwXTextRange::CreateXTextRange(*rNode.GetDoc(), aStartPos, &aEndPos);
    3359             : 
    3360           0 :     rRange = xRange;
    3361           0 : }
    3362             : 
    3363           0 : void SwCrsrShell::GetSmartTagTerm( uno::Sequence< OUString >& rSmartTagTypes,
    3364             :                                    uno::Sequence< uno::Reference< container::XStringKeyMap > >& rStringKeyMaps,
    3365             :                                    uno::Reference< text::XTextRange>& rRange ) const
    3366             : {
    3367           0 :     if ( !SwSmartTagMgr::Get().IsSmartTagsEnabled() )
    3368           0 :         return;
    3369             : 
    3370           0 :     SwPaM* pCrsr = GetCrsr();
    3371           0 :     SwPosition aPos( *pCrsr->GetPoint() );
    3372           0 :     SwTxtNode *pNode = aPos.nNode.GetNode().GetTxtNode();
    3373           0 :     if ( pNode && !pNode->IsInProtectSect() )
    3374             :     {
    3375           0 :         const SwWrongList *pSmartTagList = pNode->GetSmartTags();
    3376           0 :         if ( pSmartTagList )
    3377             :         {
    3378           0 :             sal_Int32 nCurrent = aPos.nContent.GetIndex();
    3379           0 :             sal_Int32 nBegin = nCurrent;
    3380           0 :             sal_Int32 nLen = 1;
    3381             : 
    3382           0 :             if( pSmartTagList->InWrongWord( nBegin, nLen ) && !pNode->IsSymbol(nBegin) )
    3383             :             {
    3384           0 :                 const sal_uInt16 nIndex = pSmartTagList->GetWrongPos( nBegin );
    3385           0 :                 const SwWrongList* pSubList = pSmartTagList->SubList( nIndex );
    3386           0 :                 if ( pSubList )
    3387             :                 {
    3388           0 :                     pSmartTagList = pSubList;
    3389           0 :                     nCurrent = 0;
    3390             :                 }
    3391             : 
    3392           0 :                 lcl_FillRecognizerData( rSmartTagTypes, rStringKeyMaps, *pSmartTagList, nCurrent );
    3393           0 :                 lcl_FillTextRange( rRange, *pNode, nBegin, nLen );
    3394             :             }
    3395             :         }
    3396           0 :     }
    3397             : }
    3398             : 
    3399             : // see also SwEditShell::GetCorrection( const Point* pPt, SwRect& rSelectRect )
    3400           0 : void SwCrsrShell::GetSmartTagTerm( const Point& rPt, SwRect& rSelectRect,
    3401             :                                    uno::Sequence< OUString >& rSmartTagTypes,
    3402             :                                    uno::Sequence< uno::Reference< container::XStringKeyMap > >& rStringKeyMaps,
    3403             :                                    uno::Reference<text::XTextRange>& rRange )
    3404             : {
    3405           0 :     if ( !SwSmartTagMgr::Get().IsSmartTagsEnabled() )
    3406           0 :         return;
    3407             : 
    3408           0 :     SwPaM* pCrsr = GetCrsr();
    3409           0 :     SwPosition aPos( *pCrsr->GetPoint() );
    3410           0 :     Point aPt( rPt );
    3411           0 :     SwCrsrMoveState eTmpState( MV_SETONLYTEXT );
    3412           0 :     SwSpecialPos aSpecialPos;
    3413           0 :     eTmpState.pSpecialPos = &aSpecialPos;
    3414             :     SwTxtNode *pNode;
    3415             :     const SwWrongList *pSmartTagList;
    3416             : 
    3417           0 :     if( GetLayout()->GetCrsrOfst( &aPos, aPt, &eTmpState ) &&
    3418           0 :         0 != (pNode = aPos.nNode.GetNode().GetTxtNode()) &&
    3419           0 :         0 != (pSmartTagList = pNode->GetSmartTags()) &&
    3420           0 :         !pNode->IsInProtectSect() )
    3421             :     {
    3422           0 :         sal_Int32 nCurrent = aPos.nContent.GetIndex();
    3423           0 :         sal_Int32 nBegin = nCurrent;
    3424           0 :         sal_Int32 nLen = 1;
    3425             : 
    3426           0 :         if( pSmartTagList->InWrongWord( nBegin, nLen ) && !pNode->IsSymbol(nBegin) )
    3427             :         {
    3428           0 :             const sal_uInt16 nIndex = pSmartTagList->GetWrongPos( nBegin );
    3429           0 :             const SwWrongList* pSubList = pSmartTagList->SubList( nIndex );
    3430           0 :             if ( pSubList )
    3431             :             {
    3432           0 :                 pSmartTagList = pSubList;
    3433           0 :                 nCurrent = eTmpState.pSpecialPos->nCharOfst;
    3434             :             }
    3435             : 
    3436           0 :             lcl_FillRecognizerData( rSmartTagTypes, rStringKeyMaps, *pSmartTagList, nCurrent );
    3437           0 :             lcl_FillTextRange( rRange, *pNode, nBegin, nLen );
    3438             : 
    3439             :             // get smarttag word
    3440           0 :             OUString aText( pNode->GetTxt().copy(nBegin, nLen) );
    3441             : 
    3442             :             //save the start and end positons of the line and the starting point
    3443           0 :             Push();
    3444           0 :             LeftMargin();
    3445           0 :             const sal_Int32 nLineStart = GetCrsr()->GetPoint()->nContent.GetIndex();
    3446           0 :             RightMargin();
    3447           0 :             const sal_Int32 nLineEnd = GetCrsr()->GetPoint()->nContent.GetIndex();
    3448           0 :             Pop(sal_False);
    3449             : 
    3450             :             // make sure the selection build later from the data below does not
    3451             :             // include "in word" character to the left and right in order to
    3452             :             // preserve those. Therefore count those "in words" in order to
    3453             :             // modify the selection accordingly.
    3454           0 :             const sal_Unicode* pChar = aText.getStr();
    3455           0 :             sal_Int32 nLeft = 0;
    3456           0 :             while (pChar && *pChar++ == CH_TXTATR_INWORD)
    3457           0 :                 ++nLeft;
    3458           0 :             pChar = aText.getLength() ? aText.getStr() + aText.getLength() - 1 : 0;
    3459           0 :             sal_Int32 nRight = 0;
    3460           0 :             while (pChar && *pChar-- == CH_TXTATR_INWORD)
    3461           0 :                 ++nRight;
    3462             : 
    3463           0 :             aPos.nContent = nBegin + nLeft;
    3464           0 :             pCrsr = GetCrsr();
    3465           0 :             *pCrsr->GetPoint() = aPos;
    3466           0 :             pCrsr->SetMark();
    3467           0 :             ExtendSelection( sal_True, nLen - nLeft - nRight );
    3468             :             // do not determine the rectangle in the current line
    3469           0 :             const sal_Int32 nWordStart = (nBegin + nLeft) < nLineStart ? nLineStart : nBegin + nLeft;
    3470             :             // take one less than the line end - otherwise the next line would
    3471             :             // be calculated
    3472           0 :             const sal_Int32 nWordEnd = (nBegin + nLen - nLeft - nRight) > nLineEnd ? nLineEnd : (nBegin + nLen - nLeft - nRight);
    3473           0 :             Push();
    3474           0 :             pCrsr->DeleteMark();
    3475           0 :             SwIndex& rContent = GetCrsr()->GetPoint()->nContent;
    3476           0 :             rContent = nWordStart;
    3477           0 :             SwRect aStartRect;
    3478           0 :             SwCrsrMoveState aState;
    3479           0 :             aState.bRealWidth = sal_True;
    3480           0 :             SwCntntNode* pCntntNode = pCrsr->GetCntntNode();
    3481           0 :             SwCntntFrm *pCntntFrame = pCntntNode->getLayoutFrm( GetLayout(), &rPt, pCrsr->GetPoint(), false);
    3482             : 
    3483           0 :             pCntntFrame->GetCharRect( aStartRect, *pCrsr->GetPoint(), &aState );
    3484           0 :             rContent = nWordEnd - 1;
    3485           0 :             SwRect aEndRect;
    3486           0 :             pCntntFrame->GetCharRect( aEndRect, *pCrsr->GetPoint(),&aState );
    3487           0 :             rSelectRect = aStartRect.Union( aEndRect );
    3488           0 :             Pop(sal_False);
    3489             :         }
    3490           0 :     }
    3491         111 : }
    3492             : 
    3493             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10