LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sw/source/core/crsr - crsrsh.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 621 1703 36.5 %
Date: 2013-07-09 Functions: 55 115 47.8 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10