LCOV - code coverage report
Current view: top level - sw/source/core/crsr - crsrsh.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 788 1757 44.8 %
Date: 2014-11-03 Functions: 70 121 57.9 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10