[Libreoffice-commits] core.git: Branch 'private/mst/sw_redlinehide_2' - 3 commits - sw/inc sw/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Wed Sep 12 16:03:54 UTC 2018


 sw/inc/crsrsh.hxx                 |   12 -
 sw/inc/swcrsr.hxx                 |   42 +--
 sw/source/core/crsr/crsrsh.cxx    |    3 
 sw/source/core/crsr/crstrvl1.cxx  |   64 ++++-
 sw/source/core/crsr/swcrsr.cxx    |  434 +++++++++++++++++++++++++-------------
 sw/source/core/crsr/trvlfnfl.cxx  |   10 
 sw/source/core/crsr/viscrs.cxx    |    3 
 sw/source/core/edit/eddel.cxx     |    2 
 sw/source/core/frmedt/fecopy.cxx  |    2 
 sw/source/core/unocore/unoobj.cxx |    4 
 sw/source/core/unocore/unotbl.cxx |    7 
 11 files changed, 389 insertions(+), 194 deletions(-)

New commits:
commit 1a1019a24ffa3cee2c0308e2f0f0327e88767e82
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Wed Sep 12 17:52:36 2018 +0200
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Wed Sep 12 18:01:31 2018 +0200

    sw_redlinehide_2: view cursor movement, Word/Sentence functions
    
    E.g. Ctrl+Left/Right, Ctrl+Shift+Del/Backspace, double-click to select
    word...
    
    These are all implemented in SwCursor, so they need a layout passed to
    them from the SwViewShell.
    
    There was a bug in the while loop in SwCursor::GoSentence() case
    NEXT_SENT that triggered assert in the mapping code when the
    endOfSentence() returned the length of the SwTextNode but then it was
    incremented once more.
    
    Change-Id: Ic3866860a8c07774dce35952271c207eb6e7d182

diff --git a/sw/inc/crsrsh.hxx b/sw/inc/crsrsh.hxx
index f975533ac6e9..8b736656dec9 100644
--- a/sw/inc/crsrsh.hxx
+++ b/sw/inc/crsrsh.hxx
@@ -250,8 +250,18 @@ private:
 
     SAL_DLLPRIVATE bool isInHiddenTextFrame(SwShellCursor* pShellCursor);
 
-typedef bool (SwCursor:: *FNCursor)();
+    SAL_DLLPRIVATE bool GoStartWordImpl();
+    SAL_DLLPRIVATE bool GoEndWordImpl();
+    SAL_DLLPRIVATE bool GoNextWordImpl();
+    SAL_DLLPRIVATE bool GoPrevWordImpl();
+    SAL_DLLPRIVATE bool GoNextSentenceImpl();
+    SAL_DLLPRIVATE bool GoEndSentenceImpl();
+    SAL_DLLPRIVATE bool GoStartSentenceImpl();
+
+    typedef bool (SwCursor::*FNCursor)();
+    typedef bool (SwCursorShell::*FNCursorShell)();
     SAL_DLLPRIVATE bool CallCursorFN( FNCursor );
+    SAL_DLLPRIVATE bool CallCursorShellFN( FNCursorShell );
 
     SAL_DLLPRIVATE const SwRangeRedline* GotoRedline_( SwRedlineTable::size_type nArrPos, bool bSelect );
 
diff --git a/sw/inc/swcrsr.hxx b/sw/inc/swcrsr.hxx
index 9ec86d6f5f77..6eccacf8f1e3 100644
--- a/sw/inc/swcrsr.hxx
+++ b/sw/inc/swcrsr.hxx
@@ -131,25 +131,18 @@ public:
                 const SfxItemSet* rReplSet = nullptr );
 
     // UI versions
-    bool IsStartWord( sal_Int16 nWordType ) const;
-    bool IsEndWord( sal_Int16 nWordType  ) const;
-    bool IsInWord( sal_Int16 nWordType ) const;
-    bool IsStartEndSentence( bool bEnd ) const;
-    bool GoStartWord();
-    bool GoEndWord();
-    bool GoNextWord();
-    bool GoPrevWord();
+    bool IsStartEndSentence(bool bEnd, SwRootFrame const* pLayout) const;
     bool SelectWord( SwViewShell const * pViewShell, const Point* pPt );
 
     // API versions of above functions (will be used with a different
     // WordType for the break iterator)
-    bool IsStartWordWT( sal_Int16 nWordType ) const;
-    bool IsEndWordWT( sal_Int16 nWordType ) const;
-    bool IsInWordWT( sal_Int16 nWordType ) const;
-    bool GoStartWordWT( sal_Int16 nWordType );
-    bool GoEndWordWT( sal_Int16 nWordType );
-    bool GoNextWordWT( sal_Int16 nWordType );
-    bool GoPrevWordWT( sal_Int16 nWordType );
+    bool IsStartWordWT(sal_Int16 nWordType, SwRootFrame const* pLayout = nullptr) const;
+    bool IsEndWordWT(sal_Int16 nWordType, SwRootFrame const* pLayout = nullptr) const;
+    bool IsInWordWT(sal_Int16 nWordType, SwRootFrame const* pLayout = nullptr) const;
+    bool GoStartWordWT(sal_Int16 nWordType, SwRootFrame const* pLayout = nullptr);
+    bool GoEndWordWT(sal_Int16 nWordType, SwRootFrame const* pLayout = nullptr);
+    bool GoNextWordWT(sal_Int16 nWordType, SwRootFrame const* pLayout = nullptr);
+    bool GoPrevWordWT(sal_Int16 nWordType, SwRootFrame const* pLayout = nullptr);
     bool SelectWordWT( SwViewShell const * pViewShell, sal_Int16 nWordType, const Point* pPt );
 
     enum SentenceMoveType
@@ -159,11 +152,8 @@ public:
         START_SENT,
         END_SENT
     };
-    bool GoSentence(SentenceMoveType eMoveType);
-    bool GoNextSentence(){return GoSentence(NEXT_SENT);}
-    bool GoEndSentence(){return GoSentence(END_SENT);}
-    bool GoStartSentence(){return GoSentence(START_SENT);}
-    bool ExpandToSentenceBorders();
+    bool GoSentence(SentenceMoveType eMoveType, SwRootFrame const*pLayout = nullptr);
+    bool ExpandToSentenceBorders(SwRootFrame const* pLayout);
 
     virtual bool LeftRight( bool bLeft, sal_uInt16 nCnt, sal_uInt16 nMode,
         bool bAllowVisual, bool bSkipHidden, bool bInsertCursor,
diff --git a/sw/source/core/crsr/crstrvl1.cxx b/sw/source/core/crsr/crstrvl1.cxx
index 8c69bb97b288..5654566769c8 100644
--- a/sw/source/core/crsr/crstrvl1.cxx
+++ b/sw/source/core/crsr/crstrvl1.cxx
@@ -20,59 +20,64 @@
 #include <crsrsh.hxx>
 #include <viscrs.hxx>
 
+#include <com/sun/star/i18n/WordType.hpp>
+
+using namespace ::com::sun::star::i18n;
+
 bool SwCursorShell::IsStartWord( sal_Int16 nWordType ) const
 {
-    return m_pCurrentCursor->IsStartWord( nWordType );
+    return m_pCurrentCursor->IsStartWordWT(nWordType, GetLayout());
 }
 bool SwCursorShell::IsEndWord( sal_Int16 nWordType ) const
 {
-    return m_pCurrentCursor->IsEndWord( nWordType );
+    return m_pCurrentCursor->IsEndWordWT(nWordType, GetLayout());
 }
 
 bool SwCursorShell::IsInWord( sal_Int16 nWordType ) const
 {
-    return m_pCurrentCursor->IsInWord( nWordType );
+    return m_pCurrentCursor->IsInWordWT(nWordType, GetLayout());
 }
 
 bool SwCursorShell::IsStartSentence() const
 {
-    return m_pCurrentCursor->IsStartEndSentence( false );
+    return m_pCurrentCursor->IsStartEndSentence(false, GetLayout());
 }
 bool SwCursorShell::IsEndSentence() const
 {
-    return m_pCurrentCursor->IsStartEndSentence( true );
+    return m_pCurrentCursor->IsStartEndSentence(true, GetLayout());
 }
 
 bool SwCursorShell::GoStartWord()
 {
-    return CallCursorFN( &SwCursor::GoStartWord );
+    return CallCursorShellFN( &SwCursorShell::GoStartWordImpl );
 }
 bool SwCursorShell::GoEndWord()
 {
-    return CallCursorFN( &SwCursor::GoEndWord );
+    return CallCursorShellFN( &SwCursorShell::GoEndWordImpl );
 }
 
 bool SwCursorShell::GoNextWord()
 {
-    return CallCursorFN( &SwCursor::GoNextWord );
+    return CallCursorShellFN( &SwCursorShell::GoNextWordImpl );
 }
 bool SwCursorShell::GoPrevWord()
 {
-    return CallCursorFN( &SwCursor::GoPrevWord );
+    return CallCursorShellFN( &SwCursorShell::GoPrevWordImpl );
 }
 
 bool SwCursorShell::GoNextSentence()
 {
-    return CallCursorFN( &SwCursor::GoNextSentence );
+    return CallCursorShellFN( &SwCursorShell::GoNextSentenceImpl );
 }
 
 bool SwCursorShell::GoEndSentence()
 {
-    return CallCursorFN( &SwCursor::GoEndSentence );
+    return CallCursorShellFN( &SwCursorShell::GoEndSentenceImpl );
 }
+
 bool SwCursorShell::GoStartSentence()
 {
-    return CallCursorFN( &SwCursor::GoStartSentence );
+    return CallCursorShellFN( &SwCursorShell::GoStartSentenceImpl );
 }
 
 bool SwCursorShell::SelectWord( const Point* pPt )
@@ -82,7 +87,40 @@ bool SwCursorShell::SelectWord( const Point* pPt )
 
 void SwCursorShell::ExpandToSentenceBorders()
 {
-    m_pCurrentCursor->ExpandToSentenceBorders();
+    m_pCurrentCursor->ExpandToSentenceBorders(GetLayout());
+}
+
+bool SwCursorShell::GoStartWordImpl()
+{
+    return getShellCursor(true)->GoStartWordWT(WordType::ANYWORD_IGNOREWHITESPACES, GetLayout());
+}
+
+bool SwCursorShell::GoEndWordImpl()
+{
+    return getShellCursor(true)->GoEndWordWT(WordType::ANYWORD_IGNOREWHITESPACES, GetLayout());
+}
+
+bool SwCursorShell::GoNextWordImpl()
+{
+    return getShellCursor(true)->GoNextWordWT(WordType::ANYWORD_IGNOREWHITESPACES, GetLayout());
+}
+
+bool SwCursorShell::GoPrevWordImpl()
+{
+    return getShellCursor(true)->GoPrevWordWT(WordType::ANYWORD_IGNOREWHITESPACES, GetLayout());
+}
+
+bool SwCursorShell::GoNextSentenceImpl()
+{
+    return getShellCursor(true)->GoSentence(SwCursor::NEXT_SENT, GetLayout());
+}
+bool SwCursorShell::GoEndSentenceImpl()
+{
+    return getShellCursor(true)->GoSentence(SwCursor::END_SENT, GetLayout());
+}
+bool SwCursorShell::GoStartSentenceImpl()
+{
+    return getShellCursor(true)->GoSentence(SwCursor::START_SENT, GetLayout());
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/crsr/swcrsr.cxx b/sw/source/core/crsr/swcrsr.cxx
index 9f1679254c55..d90ce94d9590 100644
--- a/sw/source/core/crsr/swcrsr.cxx
+++ b/sw/source/core/crsr/swcrsr.cxx
@@ -1117,70 +1117,100 @@ short SwCursor::MaxReplaceArived()
     return RET_YES;
 }
 
-bool SwCursor::IsStartWord( sal_Int16 nWordType ) const
-{
-    return IsStartWordWT( nWordType );
-}
-
-bool SwCursor::IsEndWord( sal_Int16 nWordType ) const
-{
-    return IsEndWordWT( nWordType );
-}
-
-bool SwCursor::IsInWord( sal_Int16 nWordType ) const
-{
-    return IsInWordWT( nWordType );
-}
-
-bool SwCursor::GoStartWord()
-{
-    return GoStartWordWT( WordType::ANYWORD_IGNOREWHITESPACES );
-}
-
-bool SwCursor::GoEndWord()
-{
-    return GoEndWordWT( WordType::ANYWORD_IGNOREWHITESPACES );
-}
-
-bool SwCursor::GoNextWord()
-{
-    return GoNextWordWT( WordType::ANYWORD_IGNOREWHITESPACES );
-}
+namespace {
+
+struct HideWrapper
+{
+    // either the frame's text or the node's text (possibly pre-filtered)
+    OUString const* m_pText;
+    // this is actually a TextFrameIndex but all of the i18n code uses sal_Int32
+    sal_Int32 m_nPtIndex;
+    // if mapping is needed, use this frame
+    SwTextFrame * m_pFrame;
+    // input in the constructor, output (via mapping) in the destructor
+    SwTextNode *& m_rpTextNode;
+    sal_Int32 & m_rPtPos;
+
+    HideWrapper(SwRootFrame const*const pLayout,
+            SwTextNode *& rpTextNode, sal_Int32 & rPtPos,
+            OUString const*const pFilteredNodeText = nullptr)
+        : m_pText(pFilteredNodeText)
+        , m_pFrame(nullptr)
+        , m_rpTextNode(rpTextNode)
+        , m_rPtPos(rPtPos)
+    {
+        if (pLayout && pLayout->IsHideRedlines())
+        {
+            m_pFrame = static_cast<SwTextFrame*>(rpTextNode->getLayoutFrame(pLayout));
+            m_pText = &m_pFrame->GetText();
+            m_nPtIndex = sal_Int32(m_pFrame->MapModelToView(rpTextNode, rPtPos));
+        }
+        else
+        {
+            if (!m_pText)
+            {
+                m_pText = &rpTextNode->GetText();
+            }
+            m_nPtIndex = rPtPos;
+        }
+    }
+    ~HideWrapper()
+    {
+        AssignBack(m_rpTextNode, m_rPtPos);
+    }
+    void AssignBack(SwTextNode *& rpTextNode, sal_Int32 & rPtPos)
+    {
+        if (0 <= m_nPtIndex && m_pFrame)
+        {
+            std::pair<SwTextNode*, sal_Int32> const pos(
+                    m_pFrame->MapViewToModel(TextFrameIndex(m_nPtIndex)));
+            rpTextNode = pos.first;
+            rPtPos = pos.second;
+        }
+        else
+        {
+            rPtPos = m_nPtIndex;
+        }
+    }
+};
 
-bool SwCursor::GoPrevWord()
-{
-    return GoPrevWordWT( WordType::ANYWORD_IGNOREWHITESPACES );
-}
+} // namespace
 
 bool SwCursor::SelectWord( SwViewShell const * pViewShell, const Point* pPt )
 {
     return SelectWordWT( pViewShell, WordType::ANYWORD_IGNOREWHITESPACES, pPt );
 }
 
-bool SwCursor::IsStartWordWT( sal_Int16 nWordType ) const
+bool SwCursor::IsStartWordWT(sal_Int16 nWordType, SwRootFrame const*const pLayout) const
 {
     bool bRet = false;
-    const SwTextNode* pTextNd = GetNode().GetTextNode();
+    SwTextNode* pTextNd = GetNode().GetTextNode();
     if (pTextNd)
     {
-        const sal_Int32 nPtPos = GetPoint()->nContent.GetIndex();
+        sal_Int32 nPtPos = GetPoint()->nContent.GetIndex();
+
+        HideWrapper w(pLayout, pTextNd, nPtPos);
+
         bRet = g_pBreakIt->GetBreakIter()->isBeginWord(
-                            pTextNd->GetText(), nPtPos,
+                            *w.m_pText, w.m_nPtIndex,
                             g_pBreakIt->GetLocale( pTextNd->GetLang( nPtPos )),
                             nWordType );
     }
     return bRet;
 }
 
-bool SwCursor::IsEndWordWT( sal_Int16 nWordType ) const
+bool SwCursor::IsEndWordWT(sal_Int16 nWordType, SwRootFrame const*const pLayout) const
 {
     bool bRet = false;
-    const SwTextNode* pTextNd = GetNode().GetTextNode();
+    SwTextNode* pTextNd = GetNode().GetTextNode();
     if (pTextNd)
     {
-        const sal_Int32 nPtPos = GetPoint()->nContent.GetIndex();
+        sal_Int32 nPtPos = GetPoint()->nContent.GetIndex();
+
+        HideWrapper w(pLayout, pTextNd, nPtPos);
+
         bRet = g_pBreakIt->GetBreakIter()->isEndWord(
-                            pTextNd->GetText(), nPtPos,
+                            *w.m_pText, w.m_nPtIndex,
                             g_pBreakIt->GetLocale( pTextNd->GetLang( nPtPos ) ),
                             nWordType );
 
@@ -1188,64 +1218,75 @@ bool SwCursor::IsEndWordWT( sal_Int16 nWordType ) const
     return bRet;
 }
 
-bool SwCursor::IsInWordWT( sal_Int16 nWordType ) const
+bool SwCursor::IsInWordWT(sal_Int16 nWordType, SwRootFrame const*const pLayout) const
 {
     bool bRet = false;
-    const SwTextNode* pTextNd = GetNode().GetTextNode();
+    SwTextNode* pTextNd = GetNode().GetTextNode();
     if (pTextNd)
     {
-        const sal_Int32 nPtPos = GetPoint()->nContent.GetIndex();
-        Boundary aBoundary = g_pBreakIt->GetBreakIter()->getWordBoundary(
-                            pTextNd->GetText(), nPtPos,
-                            g_pBreakIt->GetLocale( pTextNd->GetLang( nPtPos ) ),
-                            nWordType,
-                            true );
+        sal_Int32 nPtPos = GetPoint()->nContent.GetIndex();
 
-        bRet = aBoundary.startPos != aBoundary.endPos &&
-                aBoundary.startPos <= nPtPos &&
-                    nPtPos <= aBoundary.endPos;
+        {
+            HideWrapper w(pLayout, pTextNd, nPtPos);
+
+            Boundary aBoundary = g_pBreakIt->GetBreakIter()->getWordBoundary(
+                                *w.m_pText, w.m_nPtIndex,
+                                g_pBreakIt->GetLocale( pTextNd->GetLang( nPtPos ) ),
+                                nWordType,
+                                true );
+
+            bRet = aBoundary.startPos != aBoundary.endPos &&
+                    aBoundary.startPos <= w.m_nPtIndex &&
+                        w.m_nPtIndex <= aBoundary.endPos;
+            w.m_nPtIndex = aBoundary.startPos; // hack: convert startPos back...
+        }
         if(bRet)
         {
             const CharClass& rCC = GetAppCharClass();
-            bRet = rCC.isLetterNumeric( pTextNd->GetText(), aBoundary.startPos );
+            bRet = rCC.isLetterNumeric(pTextNd->GetText(), nPtPos);
         }
     }
     return bRet;
 }
 
-bool SwCursor::IsStartEndSentence( bool bEnd ) const
+bool SwCursor::IsStartEndSentence(bool bEnd, SwRootFrame const*const pLayout) const
 {
     bool bRet = bEnd ?
                     GetContentNode() && GetPoint()->nContent == GetContentNode()->Len() :
                     GetPoint()->nContent.GetIndex() == 0;
 
-    if( !bRet )
+    if ((pLayout != nullptr && pLayout->IsHideRedlines()) || !bRet)
     {
         SwCursor aCursor(*GetPoint(), nullptr);
         SwPosition aOrigPos = *aCursor.GetPoint();
-        aCursor.GoSentence( bEnd ? SwCursor::END_SENT : SwCursor::START_SENT );
+        aCursor.GoSentence(bEnd ? SwCursor::END_SENT : SwCursor::START_SENT, pLayout);
         bRet = aOrigPos == *aCursor.GetPoint();
     }
     return bRet;
 }
 
-bool SwCursor::GoStartWordWT( sal_Int16 nWordType )
+bool SwCursor::GoStartWordWT(sal_Int16 nWordType, SwRootFrame const*const pLayout)
 {
     bool bRet = false;
-    const SwTextNode* pTextNd = GetNode().GetTextNode();
+    SwTextNode* pTextNd = GetNode().GetTextNode();
     if (pTextNd)
     {
         SwCursorSaveState aSave( *this );
         sal_Int32 nPtPos = GetPoint()->nContent.GetIndex();
-        nPtPos = g_pBreakIt->GetBreakIter()->getWordBoundary(
-                            pTextNd->GetText(), nPtPos,
+
+        {
+            HideWrapper w(pLayout, pTextNd, nPtPos);
+
+            w.m_nPtIndex = g_pBreakIt->GetBreakIter()->getWordBoundary(
+                            *w.m_pText, w.m_nPtIndex,
                             g_pBreakIt->GetLocale( pTextNd->GetLang( nPtPos ) ),
                             nWordType,
                             false ).startPos;
+        }
 
         if (nPtPos < pTextNd->GetText().getLength() && nPtPos >= 0)
         {
-            GetPoint()->nContent = nPtPos;
+            *GetPoint() = SwPosition(*pTextNd, nPtPos);
             if( !IsSelOvr() )
                 bRet = true;
         }
@@ -1253,24 +1294,29 @@ bool SwCursor::GoStartWordWT( sal_Int16 nWordType )
     return bRet;
 }
 
-bool SwCursor::GoEndWordWT( sal_Int16 nWordType )
+bool SwCursor::GoEndWordWT(sal_Int16 nWordType, SwRootFrame const*const pLayout)
 {
     bool bRet = false;
-    const SwTextNode* pTextNd = GetNode().GetTextNode();
+    SwTextNode* pTextNd = GetNode().GetTextNode();
     if (pTextNd)
     {
         SwCursorSaveState aSave( *this );
         sal_Int32 nPtPos = GetPoint()->nContent.GetIndex();
-        nPtPos = g_pBreakIt->GetBreakIter()->getWordBoundary(
-                            pTextNd->GetText(), nPtPos,
+
+        {
+            HideWrapper w(pLayout, pTextNd, nPtPos);
+
+            w.m_nPtIndex = g_pBreakIt->GetBreakIter()->getWordBoundary(
+                            *w.m_pText, w.m_nPtIndex,
                             g_pBreakIt->GetLocale( pTextNd->GetLang( nPtPos ) ),
                             nWordType,
                             true ).endPos;
+        }
 
         if (nPtPos <= pTextNd->GetText().getLength() && nPtPos >= 0 &&
             GetPoint()->nContent.GetIndex() != nPtPos )
         {
-            GetPoint()->nContent = nPtPos;
+            *GetPoint() = SwPosition(*pTextNd, nPtPos);
             if( !IsSelOvr() )
                 bRet = true;
         }
@@ -1278,23 +1324,27 @@ bool SwCursor::GoEndWordWT( sal_Int16 nWordType )
     return bRet;
 }
 
-bool SwCursor::GoNextWordWT( sal_Int16 nWordType )
+bool SwCursor::GoNextWordWT(sal_Int16 nWordType, SwRootFrame const*const pLayout)
 {
     bool bRet = false;
-    const SwTextNode* pTextNd = GetNode().GetTextNode();
+    SwTextNode* pTextNd = GetNode().GetTextNode();
     if (pTextNd)
     {
         SwCursorSaveState aSave( *this );
         sal_Int32 nPtPos = GetPoint()->nContent.GetIndex();
 
-        nPtPos = g_pBreakIt->GetBreakIter()->nextWord(
-                                pTextNd->GetText(), nPtPos,
-            g_pBreakIt->GetLocale( pTextNd->GetLang( nPtPos, 1 ) ),
-                    nWordType ).startPos;
+        {
+            HideWrapper w(pLayout, pTextNd, nPtPos);
+
+            w.m_nPtIndex = g_pBreakIt->GetBreakIter()->nextWord(
+                        *w.m_pText, w.m_nPtIndex,
+                        g_pBreakIt->GetLocale( pTextNd->GetLang(nPtPos, 1) ),
+                        nWordType ).startPos;
+        }
 
         if (nPtPos <= pTextNd->GetText().getLength() && nPtPos >= 0)
         {
-            GetPoint()->nContent = nPtPos;
+            *GetPoint() = SwPosition(*pTextNd, nPtPos);
             if( !IsSelOvr() )
                 bRet = true;
         }
@@ -1302,26 +1352,34 @@ bool SwCursor::GoNextWordWT( sal_Int16 nWordType )
     return bRet;
 }
 
-bool SwCursor::GoPrevWordWT( sal_Int16 nWordType )
+bool SwCursor::GoPrevWordWT(sal_Int16 nWordType, SwRootFrame const*const pLayout)
 {
     bool bRet = false;
-    const SwTextNode* pTextNd = GetNode().GetTextNode();
+    SwTextNode* pTextNd = GetNode().GetTextNode();
     if (pTextNd)
     {
         SwCursorSaveState aSave( *this );
         sal_Int32 nPtPos = GetPoint()->nContent.GetIndex();
-        const sal_Int32 nPtStart = nPtPos;
 
-        if( nPtPos )
-            --nPtPos;
-        nPtPos = g_pBreakIt->GetBreakIter()->previousWord(
-                                pTextNd->GetText(), nPtStart,
-            g_pBreakIt->GetLocale( pTextNd->GetLang( nPtPos, 1 ) ),
-                    nWordType ).startPos;
+        {
+            HideWrapper w(pLayout, pTextNd, nPtPos);
+
+            const sal_Int32 nPtStart = w.m_nPtIndex;
+            if (w.m_nPtIndex)
+            {
+                --w.m_nPtIndex;
+                w.AssignBack(pTextNd, nPtPos);
+            }
+
+            w.m_nPtIndex = g_pBreakIt->GetBreakIter()->previousWord(
+                        *w.m_pText, nPtStart,
+                        g_pBreakIt->GetLocale( pTextNd->GetLang(nPtPos, 1) ),
+                                nWordType ).startPos;
+        }
 
         if (nPtPos < pTextNd->GetText().getLength() && nPtPos >= 0)
         {
-            GetPoint()->nContent = nPtPos;
+            *GetPoint() = SwPosition(*pTextNd, nPtPos);
             if( !IsSelOvr() )
                 bRet = true;
         }
@@ -1343,7 +1401,7 @@ bool SwCursor::SelectWordWT( SwViewShell const * pViewShell, sal_Int16 nWordType
         pLayout->GetCursorOfst( GetPoint(), aPt );
     }
 
-    const SwTextNode* pTextNd = GetNode().GetTextNode();
+    SwTextNode* pTextNd = GetNode().GetTextNode();
     if (pTextNd)
     {
         // Should we select the whole fieldmark?
@@ -1371,30 +1429,46 @@ bool SwCursor::SelectWordWT( SwViewShell const * pViewShell, sal_Int16 nWordType
         {
             bool bForward = true;
             sal_Int32 nPtPos = GetPoint()->nContent.GetIndex();
+
+            HideWrapper w(pViewShell->GetLayout(), pTextNd, nPtPos);
+
             Boundary aBndry( g_pBreakIt->GetBreakIter()->getWordBoundary(
-                                pTextNd->GetText(), nPtPos,
+                                *w.m_pText, w.m_nPtIndex,
                                 g_pBreakIt->GetLocale( pTextNd->GetLang( nPtPos ) ),
                                 nWordType,
                                 bForward ));
 
-            if (comphelper::LibreOfficeKit::isActive() && aBndry.startPos == aBndry.endPos && nPtPos > 0)
+            if (comphelper::LibreOfficeKit::isActive() && aBndry.startPos == aBndry.endPos && w.m_nPtIndex > 0)
             {
                 // nPtPos is the end of the paragraph, select the last word then.
-                --nPtPos;
+                --w.m_nPtIndex;
+                w.AssignBack(pTextNd, nPtPos);
+
                 aBndry = Boundary( g_pBreakIt->GetBreakIter()->getWordBoundary(
-                                    pTextNd->GetText(), nPtPos,
+                                    *w.m_pText, w.m_nPtIndex,
                                     g_pBreakIt->GetLocale( pTextNd->GetLang( nPtPos ) ),
                                     nWordType,
                                     bForward ));
+
             }
 
+            SwTextNode * pStartNode(pTextNd);
+            sal_Int32 nStartIndex;
+            w.m_nPtIndex = aBndry.startPos;
+            w.AssignBack(pStartNode, nStartIndex);
+
+            SwTextNode * pEndNode(pTextNd);
+            sal_Int32 nEndIndex;
+            w.m_nPtIndex = aBndry.endPos;
+            w.AssignBack(pEndNode, nEndIndex);
+
             if( aBndry.startPos != aBndry.endPos )
             {
-                GetPoint()->nContent = aBndry.endPos;
+                *GetPoint() = SwPosition(*pEndNode, nEndIndex);
                 if( !IsSelOvr() )
                 {
                     SetMark();
-                    GetMark()->nContent = aBndry.startPos;
+                    *GetMark() = SwPosition(*pStartNode, nStartIndex);
                     if (sw::mark::IMark* pAnnotationMark = pMarksAccess->getAnnotationMarkFor(*GetPoint()))
                     {
                         // An annotation mark covers the selected word. Check
@@ -1455,61 +1529,70 @@ static OUString lcl_MaskDeletedRedlines( const SwTextNode* pTextNd )
     return aRes;
 }
 
-bool SwCursor::GoSentence( SentenceMoveType eMoveType )
+bool SwCursor::GoSentence(SentenceMoveType eMoveType, SwRootFrame const*const pLayout)
 {
     bool bRet = false;
-    const SwTextNode* pTextNd = GetNode().GetTextNode();
+    SwTextNode* pTextNd = GetNode().GetTextNode();
     if (pTextNd)
     {
-        OUString sNodeText( lcl_MaskDeletedRedlines( pTextNd ) );
+        OUString const sNodeText(lcl_MaskDeletedRedlines(pTextNd));
 
         SwCursorSaveState aSave( *this );
         sal_Int32 nPtPos = GetPoint()->nContent.GetIndex();
-        switch ( eMoveType )
+
         {
-        case START_SENT: /* when modifying: see also ExpandToSentenceBorders below! */
-            nPtPos = g_pBreakIt->GetBreakIter()->beginOfSentence(
-                                    sNodeText,
-                                    nPtPos, g_pBreakIt->GetLocale(
-                                            pTextNd->GetLang( nPtPos ) ));
-            break;
-        case END_SENT: /* when modifying: see also ExpandToSentenceBorders below! */
-            nPtPos = g_pBreakIt->GetBreakIter()->endOfSentence(
-                                    sNodeText,
-                                    nPtPos, g_pBreakIt->GetLocale(
-                                                pTextNd->GetLang( nPtPos ) ));
-            break;
-        case NEXT_SENT:
+            HideWrapper w(pLayout, pTextNd, nPtPos, &sNodeText);
+
+            switch ( eMoveType )
             {
-                nPtPos = g_pBreakIt->GetBreakIter()->endOfSentence(
-                                        sNodeText,
-                                        nPtPos, g_pBreakIt->GetLocale(
-                                                    pTextNd->GetLang( nPtPos ) ));
-                while (nPtPos>=0 && ++nPtPos < sNodeText.getLength()
-                       && sNodeText[nPtPos] == ' ' /*isWhiteSpace( aText.GetChar(nPtPos)*/ )
-                    ;
+            case START_SENT: /* when modifying: see also ExpandToSentenceBorders below! */
+                w.m_nPtIndex = g_pBreakIt->GetBreakIter()->beginOfSentence(
+                            *w.m_pText, w.m_nPtIndex,
+                            g_pBreakIt->GetLocale(pTextNd->GetLang(nPtPos)));
+                break;
+            case END_SENT: /* when modifying: see also ExpandToSentenceBorders below! */
+                w.m_nPtIndex = g_pBreakIt->GetBreakIter()->endOfSentence(
+                            *w.m_pText, w.m_nPtIndex,
+                            g_pBreakIt->GetLocale(pTextNd->GetLang(nPtPos)));
+                break;
+            case NEXT_SENT:
+                {
+                    w.m_nPtIndex = g_pBreakIt->GetBreakIter()->endOfSentence(
+                            *w.m_pText, w.m_nPtIndex,
+                            g_pBreakIt->GetLocale(pTextNd->GetLang(nPtPos)));
+                    if (w.m_nPtIndex >= 0 && w.m_nPtIndex < w.m_pText->getLength())
+                    {
+                        do
+                        {
+                            ++w.m_nPtIndex;
+                        }
+                        while (w.m_nPtIndex < w.m_pText->getLength()
+                               && (*w.m_pText)[w.m_nPtIndex] == ' ');
+                    }
+                    break;
+                }
+            case PREV_SENT:
+                w.m_nPtIndex = g_pBreakIt->GetBreakIter()->beginOfSentence(
+                            *w.m_pText, w.m_nPtIndex,
+                            g_pBreakIt->GetLocale(pTextNd->GetLang(nPtPos)));
+
+                if (w.m_nPtIndex == 0)
+                    return false;   // the previous sentence is not in this paragraph
+                if (w.m_nPtIndex > 0)
+                {
+                    w.m_nPtIndex = g_pBreakIt->GetBreakIter()->beginOfSentence(
+                            *w.m_pText, w.m_nPtIndex - 1,
+                            g_pBreakIt->GetLocale(pTextNd->GetLang(nPtPos)));
+                }
                 break;
             }
-        case PREV_SENT:
-            nPtPos = g_pBreakIt->GetBreakIter()->beginOfSentence(
-                                    sNodeText,
-                                    nPtPos, g_pBreakIt->GetLocale(
-                                                pTextNd->GetLang( nPtPos ) ));
-            if (nPtPos == 0)
-                return false;   // the previous sentence is not in this paragraph
-            if (nPtPos > 0)
-                nPtPos = g_pBreakIt->GetBreakIter()->beginOfSentence(
-                                    sNodeText,
-                                    nPtPos - 1, g_pBreakIt->GetLocale(
-                                                pTextNd->GetLang( nPtPos ) ));
-            break;
         }
 
         // it is allowed to place the PaM just behind the last
         // character in the text thus <= ...Len
         if (nPtPos <= pTextNd->GetText().getLength() && nPtPos >= 0)
         {
-            GetPoint()->nContent = nPtPos;
+            *GetPoint() = SwPosition(*pTextNd, nPtPos);
             if( !IsSelOvr() )
                 bRet = true;
         }
@@ -1517,11 +1600,11 @@ bool SwCursor::GoSentence( SentenceMoveType eMoveType )
     return bRet;
 }
 
-bool SwCursor::ExpandToSentenceBorders()
+bool SwCursor::ExpandToSentenceBorders(SwRootFrame const*const pLayout)
 {
     bool bRes = false;
-    const SwTextNode* pStartNd = Start()->nNode.GetNode().GetTextNode();
-    const SwTextNode* pEndNd   = End()->nNode.GetNode().GetTextNode();
+    SwTextNode* pStartNd = Start()->nNode.GetNode().GetTextNode();
+    SwTextNode* pEndNd   = End()->nNode.GetNode().GetTextNode();
     if (pStartNd && pEndNd)
     {
         if (!HasMark())
@@ -1534,24 +1617,32 @@ bool SwCursor::ExpandToSentenceBorders()
         sal_Int32 nStartPos = Start()->nContent.GetIndex();
         sal_Int32 nEndPos   = End()->nContent.GetIndex();
 
-        nStartPos = g_pBreakIt->GetBreakIter()->beginOfSentence(
-                                sStartText, nStartPos,
+        {
+            HideWrapper w(pLayout, pStartNd, nStartPos, &sStartText);
+
+            w.m_nPtIndex = g_pBreakIt->GetBreakIter()->beginOfSentence(
+                                *w.m_pText, w.m_nPtIndex,
                                 g_pBreakIt->GetLocale( pStartNd->GetLang( nStartPos ) ) );
-        nEndPos   = g_pBreakIt->GetBreakIter()->endOfSentence(
-                                sEndText, nEndPos,
+        }
+        {
+            HideWrapper w(pLayout, pEndNd, nEndPos, &sEndText);
+
+            w.m_nPtIndex = g_pBreakIt->GetBreakIter()->endOfSentence(
+                                *w.m_pText, w.m_nPtIndex,
                                 g_pBreakIt->GetLocale( pEndNd->GetLang( nEndPos ) ) );
+        }
 
         // it is allowed to place the PaM just behind the last
         // character in the text thus <= ...Len
         bool bChanged = false;
         if (nStartPos <= pStartNd->GetText().getLength() && nStartPos >= 0)
         {
-            GetMark()->nContent = nStartPos;
+            *GetMark() = SwPosition(*pStartNd, nStartPos);
             bChanged = true;
         }
         if (nEndPos <= pEndNd->GetText().getLength() && nEndPos >= 0)
         {
-            GetPoint()->nContent = nEndPos;
+            *GetPoint() = SwPosition(*pEndNd, nEndPos);
             bChanged = true;
         }
         if (bChanged && !IsSelOvr())
diff --git a/sw/source/core/crsr/trvlfnfl.cxx b/sw/source/core/crsr/trvlfnfl.cxx
index c0fa6a288320..e327e73e3ab3 100644
--- a/sw/source/core/crsr/trvlfnfl.cxx
+++ b/sw/source/core/crsr/trvlfnfl.cxx
@@ -36,6 +36,16 @@
 #include "callnk.hxx"
 #include <svx/srchdlg.hxx>
 
+bool SwCursorShell::CallCursorShellFN( FNCursorShell fnCursor )
+{
+    SwCallLink aLk( *this ); // watch Cursor-Moves
+    bool bRet = (this->*fnCursor)();
+    if( bRet )
+        UpdateCursor( SwCursorShell::SCROLLWIN | SwCursorShell::CHKRANGE |
+                    SwCursorShell::READONLY );
+    return bRet;
+}
+
 bool SwCursorShell::CallCursorFN( FNCursor fnCursor )
 {
     SwCallLink aLk( *this ); // watch Cursor-Moves
diff --git a/sw/source/core/unocore/unoobj.cxx b/sw/source/core/unocore/unoobj.cxx
index c1c91b365bf0..680a336bb9d9 100644
--- a/sw/source/core/unocore/unoobj.cxx
+++ b/sw/source/core/unocore/unoobj.cxx
@@ -1434,9 +1434,9 @@ SwXTextCursor::gotoNextSentence(sal_Bool Expand)
     // if at the end of the sentence (i.e. at the space after the '.')
     // advance to next word in order for GoSentence to work properly
     // next time and have isStartOfSentence return true after this call
-    if (!rUnoCursor.IsStartWord(css::i18n::WordType::ANYWORD_IGNOREWHITESPACES))
+    if (!rUnoCursor.IsStartWordWT(css::i18n::WordType::ANYWORD_IGNOREWHITESPACES))
     {
-        const bool bNextWord = rUnoCursor.GoNextWord();
+        const bool bNextWord = rUnoCursor.GoNextWordWT(i18n::WordType::ANYWORD_IGNOREWHITESPACES);
         if (bWasEOS && !bNextWord)
         {
             bRet = false;
commit 8eb085f4c80515ffa20e36b7efbfd8b91229aa1a
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Wed Sep 12 11:28:06 2018 +0200
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Wed Sep 12 17:57:04 2018 +0200

    sw_redlinehide_2: adapt SwCursor::UpDown()
    
    Actually it already works, this is just a clean up to pass in the
    SwCursorShell's layout...
    
    Change-Id: I1a90bbe9966c7f4d5b5e959122ca1f995df93a45

diff --git a/sw/inc/swcrsr.hxx b/sw/inc/swcrsr.hxx
index 41aba80df7e5..9ec86d6f5f77 100644
--- a/sw/inc/swcrsr.hxx
+++ b/sw/inc/swcrsr.hxx
@@ -168,7 +168,7 @@ public:
     virtual bool LeftRight( bool bLeft, sal_uInt16 nCnt, sal_uInt16 nMode,
         bool bAllowVisual, bool bSkipHidden, bool bInsertCursor,
         SwRootFrame const* pLayout);
-    bool UpDown( bool bUp, sal_uInt16 nCnt, Point const * pPt, long nUpDownX );
+    bool UpDown(bool bUp, sal_uInt16 nCnt, Point const * pPt, long nUpDownX, SwRootFrame & rLayout);
     bool LeftRightMargin( bool bLeftMargin, bool bAPI );
     bool IsAtLeftRightMargin( bool bLeftMargin, bool bAPI ) const;
     bool SttEndDoc( bool bSttDoc );
diff --git a/sw/source/core/crsr/swcrsr.cxx b/sw/source/core/crsr/swcrsr.cxx
index a5ab87c2293f..9f1679254c55 100644
--- a/sw/source/core/crsr/swcrsr.cxx
+++ b/sw/source/core/crsr/swcrsr.cxx
@@ -1827,7 +1827,8 @@ void SwCursor::DoSetBidiLevelUpDown()
 }
 
 bool SwCursor::UpDown( bool bUp, sal_uInt16 nCnt,
-                       Point const * pPt, long nUpDownX )
+                       Point const * pPt, long nUpDownX,
+                       SwRootFrame & rLayout)
 {
     SwTableCursor* pTableCursor = dynamic_cast<SwTableCursor*>(this);
     bool bAdjustTableCursor = false;
@@ -1846,7 +1847,7 @@ bool SwCursor::UpDown( bool bUp, sal_uInt16 nCnt,
     Point aPt;
     if( pPt )
         aPt = *pPt;
-    SwContentFrame* pFrame = GetContentNode()->getLayoutFrame( GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout(), &aPt, GetPoint() );
+    SwContentFrame* pFrame = GetContentNode()->getLayoutFrame(&rLayout, &aPt, GetPoint());
 
     if( pFrame )
     {
@@ -1882,7 +1883,7 @@ bool SwCursor::UpDown( bool bUp, sal_uInt16 nCnt,
                 const SwNode* pEndNd = pTableNd->EndOfSectionNode();
                 GetPoint()->nNode = *pEndNd;
                 pTableCursor->Move( fnMoveBackward, GoInNode );
-                   pFrame = GetContentNode()->getLayoutFrame( GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout(), &aPt, GetPoint() );
+               pFrame = GetContentNode()->getLayoutFrame(&rLayout, &aPt, GetPoint());
             }
         }
 
@@ -1891,7 +1892,7 @@ bool SwCursor::UpDown( bool bUp, sal_uInt16 nCnt,
                     : pFrame->UnitDown( this, nUpDownX, bInReadOnly ) ) &&
                 CheckNodesRange( aOldPos.nNode, GetPoint()->nNode, bChkRange ))
         {
-               pFrame = GetContentNode()->getLayoutFrame( GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout(), &aPt, GetPoint() );
+               pFrame = GetContentNode()->getLayoutFrame(&rLayout, &aPt, GetPoint());
             --nCnt;
         }
 
@@ -1902,8 +1903,8 @@ bool SwCursor::UpDown( bool bUp, sal_uInt16 nCnt,
             if( !pTableCursor )
             {
                 // try to position the cursor at half of the char-rect's height
-                DisableCallbackAction a(*GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout());
-                pFrame = GetContentNode()->getLayoutFrame( GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout(), &aPt, GetPoint() );
+                DisableCallbackAction a(rLayout);
+                pFrame = GetContentNode()->getLayoutFrame(&rLayout, &aPt, GetPoint());
                 SwCursorMoveState eTmpState( MV_UPDOWN );
                 eTmpState.m_bSetInReadOnly = bInReadOnly;
                 SwRect aTmpRect;
@@ -1911,13 +1912,13 @@ bool SwCursor::UpDown( bool bUp, sal_uInt16 nCnt,
                 if ( pFrame->IsVertical() )
                 {
                     aPt.setX(aTmpRect.Center().getX());
-                    pFrame->Calc(pFrame->getRootFrame()->GetCurrShell()->GetOut());
+                    pFrame->Calc(rLayout.GetCurrShell()->GetOut());
                     aPt.setY(pFrame->getFrameArea().Top() + nUpDownX);
                 }
                 else
                 {
                     aPt.setY(aTmpRect.Center().getY());
-                    pFrame->Calc(pFrame->getRootFrame()->GetCurrShell()->GetOut());
+                    pFrame->Calc(rLayout.GetCurrShell()->GetOut());
                     aPt.setX(pFrame->getFrameArea().Left() + nUpDownX);
                 }
                 pFrame->GetCursorOfst( GetPoint(), aPt, &eTmpState );
diff --git a/sw/source/core/crsr/viscrs.cxx b/sw/source/core/crsr/viscrs.cxx
index 6e588b0dfd14..a27189ac1520 100644
--- a/sw/source/core/crsr/viscrs.cxx
+++ b/sw/source/core/crsr/viscrs.cxx
@@ -700,7 +700,8 @@ void SwShellCursor::SaveTableBoxContent( const SwPosition* pPos )
 bool SwShellCursor::UpDown( bool bUp, sal_uInt16 nCnt )
 {
     return SwCursor::UpDown( bUp, nCnt,
-                            &GetPtPos(), GetShell()->GetUpDownX() );
+                            &GetPtPos(), GetShell()->GetUpDownX(),
+                            *GetShell()->GetLayout());
 }
 
 // if <true> than the cursor can be set to the position.
diff --git a/sw/source/core/edit/eddel.cxx b/sw/source/core/edit/eddel.cxx
index 658a650c8048..126b5000a923 100644
--- a/sw/source/core/edit/eddel.cxx
+++ b/sw/source/core/edit/eddel.cxx
@@ -185,7 +185,7 @@ bool SwEditShell::Copy( SwEditShell* pDestShell )
                 if( nMove )
                 {
                     SwCursor aCursor( *pPos, nullptr);
-                    if( aCursor.UpDown( false, nMove, nullptr, 0 ) )
+                    if (aCursor.UpDown(false, nMove, nullptr, 0, *GetLayout()))
                     {
                         pInsertPos.reset( new SwPosition( *aCursor.GetPoint() ) );
                         aInsertList.push_back( pInsertPos );
diff --git a/sw/source/core/frmedt/fecopy.cxx b/sw/source/core/frmedt/fecopy.cxx
index b30bd26fffa6..d0f69864d9e0 100644
--- a/sw/source/core/frmedt/fecopy.cxx
+++ b/sw/source/core/frmedt/fecopy.cxx
@@ -761,7 +761,7 @@ bool SwFEShell::Paste( SwDoc* pClpDoc )
                     SwCursor aCursor( aStartPos, nullptr);
                     // Check if we find another insert position by moving
                     // down the last given position
-                    if( aCursor.UpDown( false, ++nMove, nullptr, 0 ) )
+                    if (aCursor.UpDown(false, ++nMove, nullptr, 0, *GetLayout()))
                         aInsertPos = *aCursor.GetPoint();
                     else // if there is no paragraph we have to create it
                         bCompletePara = nCount > 0;
diff --git a/sw/source/core/unocore/unotbl.cxx b/sw/source/core/unocore/unotbl.cxx
index 7f832ac8e0d4..e58b04a3a112 100644
--- a/sw/source/core/unocore/unotbl.cxx
+++ b/sw/source/core/unocore/unotbl.cxx
@@ -42,6 +42,7 @@
 #include <IDocumentContentOperations.hxx>
 #include <IDocumentFieldsAccess.hxx>
 #include <IDocumentState.hxx>
+#include <IDocumentLayoutAccess.hxx>
 #include <shellres.hxx>
 #include <docary.hxx>
 #include <ndole.hxx>
@@ -1602,7 +1603,8 @@ sal_Bool SwXTextTableCursor::goUp(sal_Int16 Count, sal_Bool bExpand)
     SwUnoCursor& rUnoCursor = GetCursor();
     SwUnoTableCursor& rTableCursor = dynamic_cast<SwUnoTableCursor&>(rUnoCursor);
     lcl_CursorSelect(rTableCursor, bExpand);
-    return rTableCursor.UpDown(true, Count, nullptr, 0);
+    return rTableCursor.UpDown(true, Count, nullptr, 0,
+        *rUnoCursor.GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout());
 }
 
 sal_Bool SwXTextTableCursor::goDown(sal_Int16 Count, sal_Bool bExpand)
@@ -1611,7 +1613,8 @@ sal_Bool SwXTextTableCursor::goDown(sal_Int16 Count, sal_Bool bExpand)
     SwUnoCursor& rUnoCursor = GetCursor();
     SwUnoTableCursor& rTableCursor = dynamic_cast<SwUnoTableCursor&>(rUnoCursor);
     lcl_CursorSelect(rTableCursor, bExpand);
-    return rTableCursor.UpDown(false, Count, nullptr, 0);
+    return rTableCursor.UpDown(false, Count, nullptr, 0,
+        *rUnoCursor.GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout());
 }
 
 void SwXTextTableCursor::gotoStart(sal_Bool bExpand)
commit 972952031c3767b728494280675f3e221245f366
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Wed Sep 12 10:44:38 2018 +0200
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Wed Sep 12 17:56:25 2018 +0200

    sw_redlinehide_2: view cursor movement, SwCursorShell::LeftRight()
    
    Just put a loop in SwCursor::LeftRight() to repeat a movement if
    it didn't actually advance the text frame index; the
    SwContentNode::GoPrevious()/GoNext() take into account hidden text
    attributes from SwScriptInfo, so this ought to result in end
    positions that are neither hidden by attributes nor by redlines.
    
    This requires passing the layout to SwCursor.
    
    Change-Id: Ieb623840f6390fa6f1c78b7458ad8dc6523a2744

diff --git a/sw/inc/swcrsr.hxx b/sw/inc/swcrsr.hxx
index ca6b18b325e9..41aba80df7e5 100644
--- a/sw/inc/swcrsr.hxx
+++ b/sw/inc/swcrsr.hxx
@@ -166,15 +166,16 @@ public:
     bool ExpandToSentenceBorders();
 
     virtual bool LeftRight( bool bLeft, sal_uInt16 nCnt, sal_uInt16 nMode,
-        bool bAllowVisual, bool bSkipHidden, bool bInsertCursor );
+        bool bAllowVisual, bool bSkipHidden, bool bInsertCursor,
+        SwRootFrame const* pLayout);
     bool UpDown( bool bUp, sal_uInt16 nCnt, Point const * pPt, long nUpDownX );
     bool LeftRightMargin( bool bLeftMargin, bool bAPI );
     bool IsAtLeftRightMargin( bool bLeftMargin, bool bAPI ) const;
     bool SttEndDoc( bool bSttDoc );
     bool GoPrevNextCell( bool bNext, sal_uInt16 nCnt );
 
-    bool Left( sal_uInt16 nCnt )   { return LeftRight( true, nCnt, CRSR_SKIP_CHARS, false/*bAllowVisual*/, false/*bSkipHidden*/, false ); }
-    bool Right( sal_uInt16 nCnt )  { return LeftRight( false, nCnt, CRSR_SKIP_CHARS, false/*bAllowVisual*/, false/*bSkipHidden*/, false ); }
+    bool Left( sal_uInt16 nCnt )   { return LeftRight( true, nCnt, CRSR_SKIP_CHARS, false/*bAllowVisual*/, false/*bSkipHidden*/, false, nullptr ); }
+    bool Right( sal_uInt16 nCnt )  { return LeftRight( false, nCnt, CRSR_SKIP_CHARS, false/*bAllowVisual*/, false/*bSkipHidden*/, false, nullptr ); }
     bool GoNextCell( sal_uInt16 nCnt = 1 )  { return GoPrevNextCell( true, nCnt ); }
     bool GoPrevCell( sal_uInt16 nCnt = 1 )  { return GoPrevNextCell( false, nCnt ); }
     virtual bool GotoTable( const OUString& rName );
@@ -274,7 +275,8 @@ public:
     virtual ~SwTableCursor() override;
 
     virtual bool LeftRight( bool bLeft, sal_uInt16 nCnt, sal_uInt16 nMode,
-        bool bAllowVisual, bool bSkipHidden, bool bInsertCursor ) override;
+        bool bAllowVisual, bool bSkipHidden, bool bInsertCursor,
+        SwRootFrame const*) override;
     virtual bool GotoTable( const OUString& rName ) override;
 
     void InsertBox( const SwTableBox& rTableBox );
diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx
index 2afbfdadbd08..f29462b9b268 100644
--- a/sw/source/core/crsr/crsrsh.cxx
+++ b/sw/source/core/crsr/crsrsh.cxx
@@ -357,7 +357,8 @@ bool SwCursorShell::LeftRight( bool bLeft, sal_uInt16 nCnt, sal_uInt16 nMode,
         // reflected in the return value <bRet>.
         const bool bResetOfInFrontOfLabel = SetInFrontOfLabel( false );
         bRet = pShellCursor->LeftRight( bLeft, nCnt, nMode, bVisualAllowed,
-                                      bSkipHidden, !IsOverwriteCursor() );
+                                      bSkipHidden, !IsOverwriteCursor(),
+                                      GetLayout());
         if ( !bRet && bLeft && bResetOfInFrontOfLabel )
         {
             // undo reset of <bInFrontOfLabel> flag
diff --git a/sw/source/core/crsr/swcrsr.cxx b/sw/source/core/crsr/swcrsr.cxx
index 2b934cb6c576..a5ab87c2293f 100644
--- a/sw/source/core/crsr/swcrsr.cxx
+++ b/sw/source/core/crsr/swcrsr.cxx
@@ -1561,7 +1561,8 @@ bool SwCursor::ExpandToSentenceBorders()
 }
 
 bool SwTableCursor::LeftRight( bool bLeft, sal_uInt16 nCnt, sal_uInt16 /*nMode*/,
-    bool /*bVisualAllowed*/, bool /*bSkipHidden*/, bool /*bInsertCursor*/ )
+    bool /*bVisualAllowed*/, bool /*bSkipHidden*/, bool /*bInsertCursor*/,
+    SwRootFrame const*)
 {
     return bLeft ? GoPrevCell( nCnt )
                  : GoNextCell( nCnt );
@@ -1623,7 +1624,8 @@ SwCursor::DoSetBidiLevelLeftRight(
 }
 
 bool SwCursor::LeftRight( bool bLeft, sal_uInt16 nCnt, sal_uInt16 nMode,
-                          bool bVisualAllowed,bool bSkipHidden, bool bInsertCursor )
+                          bool bVisualAllowed,bool bSkipHidden, bool bInsertCursor,
+                          SwRootFrame const*const pLayout)
 {
     // calculate cursor bidi level
     SwNode& rNode = GetPoint()->nNode.GetNode();
@@ -1640,13 +1642,59 @@ bool SwCursor::LeftRight( bool bLeft, sal_uInt16 nCnt, sal_uInt16 nMode,
     else
         fnGo = CRSR_SKIP_CELLS == nMode ? GoInContentCells : GoInContent;
 
+    SwTextFrame const* pFrame(nullptr);
+    if (pLayout)
+    {
+        pFrame = static_cast<SwTextFrame*>(rNode.GetContentNode()->getLayoutFrame(pLayout));
+        if (pFrame)
+        {
+            while (pFrame->GetPrecede())
+            {
+                pFrame = static_cast<SwTextFrame const*>(pFrame->GetPrecede());
+            }
+        }
+    }
+
     while( nCnt )
     {
         SwNodeIndex aOldNodeIdx( GetPoint()->nNode );
 
+        TextFrameIndex beforeIndex;
+        if (pFrame)
+        {
+            beforeIndex = pFrame->MapModelToViewPos(*GetPoint());
+        }
+
         if ( !Move( fnMove, fnGo ) )
             break;
 
+        if (pFrame)
+        {
+            SwTextFrame const* pNewFrame(static_cast<SwTextFrame const*>(
+                GetPoint()->nNode.GetNode().GetContentNode()->getLayoutFrame(pLayout)));
+            if (pNewFrame)
+            {
+                while (pNewFrame->GetPrecede())
+                {
+                    pNewFrame = static_cast<SwTextFrame const*>(pNewFrame->GetPrecede());
+                }
+            }
+            // sw_redlinehide: fully redline-deleted nodes don't have frames...
+            if (pFrame == pNewFrame || !pNewFrame)
+            {
+                if (!pNewFrame || beforeIndex == pFrame->MapModelToViewPos(*GetPoint()))
+                {
+                    continue; // moving inside delete redline, doesn't count...
+                }
+            }
+            else
+            {
+                // assume iteration is stable & returns the same frame
+                assert(!pFrame->IsAnFollow(pNewFrame) && !pNewFrame->IsAnFollow(pFrame));
+                pFrame = pNewFrame;
+            }
+        }
+
         // If we were located inside a covered cell but our position has been
         // corrected, we check if the last move has moved the cursor to a
         // different table cell. In this case we set the cursor to the stored


More information about the Libreoffice-commits mailing list