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

Generated by: LCOV version 1.11