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

Michael Stahl Michael.Stahl at cib.de
Tue Jun 5 12:22:45 UTC 2018


Rebased ref, commits from common ancestor:
commit 26909eaf4780be3940bd07a6ace69ede8942f415
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Tue Jun 5 13:41:58 2018 +0200

    sw_redlinehide: send a hint to the SwTextFrame when Delete redline
    
    ... is created or updated; there is already a SwUpdateAttr
    hint being sent from SwRangeRedline::InvalidateRange(),
    but it doesn't contain any info about the redline other than the
    position; add a new hint sw::RedlineDelText and send it from there in
    addition to the existing one.
    
    Change-Id: I37150b2a5ca6a0e70ea4a5788f720f8522227631

diff --git a/sw/inc/hints.hxx b/sw/inc/hints.hxx
index 4da6408dfe99..dc31d7424756 100644
--- a/sw/inc/hints.hxx
+++ b/sw/inc/hints.hxx
@@ -93,6 +93,19 @@ public:
     SwDelText( sal_Int32 nS, sal_Int32 nL );
 };
 
+namespace sw {
+
+class RedlineDelText : public SfxHint
+{
+public:
+    sal_Int32 nStart;
+    sal_Int32 nLen;
+
+    RedlineDelText(sal_Int32 nS, sal_Int32 nL);
+};
+
+}
+
 class SwUpdateAttr : public SwMsgPoolItem
 {
 private:
diff --git a/sw/source/core/attr/hints.cxx b/sw/source/core/attr/hints.cxx
index 678db2590528..44c60ff0fd17 100644
--- a/sw/source/core/attr/hints.cxx
+++ b/sw/source/core/attr/hints.cxx
@@ -46,6 +46,15 @@ SwDelText::SwDelText( sal_Int32 nS, sal_Int32 nL )
 {
 }
 
+namespace sw {
+
+RedlineDelText::RedlineDelText(sal_Int32 const nS, sal_Int32 const nL)
+    : nStart(nS), nLen(nL)
+{
+}
+
+} // namespace sw
+
 SwUpdateAttr::SwUpdateAttr( sal_Int32 nS, sal_Int32 nE, sal_uInt16 nW )
     : SwMsgPoolItem( RES_UPDATE_ATTR ), m_nStart( nS ), m_nEnd( nE ), m_nWhichAttr( nW )
 {
diff --git a/sw/source/core/doc/docredln.cxx b/sw/source/core/doc/docredln.cxx
index ee9eab110262..ad1a5925d644 100644
--- a/sw/source/core/doc/docredln.cxx
+++ b/sw/source/core/doc/docredln.cxx
@@ -1270,6 +1270,15 @@ void SwRangeRedline::InvalidateRange()       // trigger the Layout
         if (pNode && pNode->IsTextNode())
         {
             SwTextNode* pNd = pNode->GetTextNode();
+
+            if (GetType() == nsRedlineType_t::REDLINE_DELETE)
+            {
+                sw::RedlineDelText const hint(
+                    n == nSttNd ? nSttCnt : 0,
+                    n == nEndNd ? nEndCnt : pNd->GetText().getLength());
+                pNd->CallSwClientNotify(hint);
+            }
+
             SwUpdateAttr aHt(
                 n == nSttNd ? nSttCnt : 0,
                 n == nEndNd ? nEndCnt : pNd->GetText().getLength(),
diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx
index 5491dc388c3c..beed09d42b0d 100644
--- a/sw/source/core/text/txtfrm.cxx
+++ b/sw/source/core/text/txtfrm.cxx
@@ -1509,18 +1509,30 @@ static bool isA11yRelevantAttribute(sal_uInt16 nWhich)
 // SwContentFrame::Modify() when appropriate.
 void SwTextFrame::SwClientNotify(SwModify const& rModify, SfxHint const& rHint)
 {
-    auto const pHint(dynamic_cast<sw::LegacyModifyHint const*>(&rHint));
-    assert(pHint); // TODO this is the only type expected here for now
+    SfxPoolItem const* pOld(nullptr);
+    SfxPoolItem const* pNew(nullptr);
+    sw::RedlineDelText const* pRedlineDelText(nullptr);
 
-    SfxPoolItem const*const pOld(pHint->m_pOld);
-    SfxPoolItem const*const pNew(pHint->m_pNew);
-    SwTextNode const& rNode(static_cast<SwTextNode const&>(rModify));
+    if (auto const pHint = dynamic_cast<sw::LegacyModifyHint const*>(&rHint))
+    {
+        pOld = pHint->m_pOld;
+        pNew = pHint->m_pNew;
+    }
+    else if (auto const pHynt = dynamic_cast<sw::RedlineDelText const*>(&rHint))
+    {
+        pRedlineDelText = pHynt;
+    }
+    else
+    {
+        assert(!"unexpected hint");
+    }
 
     if (m_pMergedPara)
     {
         assert(m_pMergedPara->listener.IsListeningTo(&rModify));
     }
 
+    SwTextNode const& rNode(static_cast<SwTextNode const&>(rModify));
     const sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
 
     // modifications concerning frame attributes are processed by the base class
@@ -1572,7 +1584,34 @@ void SwTextFrame::SwClientNotify(SwModify const& rModify, SfxHint const& rHint)
     bool bSetFieldsDirty = false;
     bool bRecalcFootnoteFlag = false;
 
-    switch( nWhich )
+    if (pRedlineDelText)
+    {
+        if (m_pMergedPara)
+        {
+            sal_Int32 const nNPos = pRedlineDelText->nStart;
+            sal_Int32 const nNLen = pRedlineDelText->nLen;
+            nPos = MapModelToView(&rNode, nNPos);
+            // update merged before doing anything else
+            nLen = UpdateMergedParaForDelete(*m_pMergedPara, rNode, nNPos, nNLen);
+            const sal_Int32 m = -nNLen;
+            if (nLen && IsIdxInside(nPos, nLen))
+            {
+                if (!nLen)
+                    InvalidateSize();
+                else
+                    InvalidateRange( SwCharRange(nPos, TextFrameIndex(1)), m );
+            }
+            lcl_SetWrong( *this, rNode, nNPos, m, true );
+            if (nLen)
+            {
+                lcl_SetScriptInval( *this, nPos );
+                bSetFieldsDirty = bRecalcFootnoteFlag = true;
+                if (HasFollow())
+                    lcl_ModifyOfst( this, nPos, nLen );
+            }
+        }
+    }
+    else switch (nWhich)
     {
         case RES_LINENUMBER:
         {
commit c116ccf850497eee1c568d0de2af81ecddb9b99f
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Mon May 7 17:44:44 2018 +0200

    hack in Show - not sure if...
    
    Change-Id: I6ca49cfe9c61b3562e87ca994b284e056c2bab54

diff --git a/sw/source/core/doc/docredln.cxx b/sw/source/core/doc/docredln.cxx
index c5731c36c457..ee9eab110262 100644
--- a/sw/source/core/doc/docredln.cxx
+++ b/sw/source/core/doc/docredln.cxx
@@ -60,6 +60,7 @@
 #include <txtfld.hxx>
 
 #include <flowfrm.hxx>
+#include <txtfrm.hxx>
 
 using namespace com::sun::star;
 
@@ -1663,6 +1664,20 @@ void SwRangeRedline::MoveFromSection(size_t nMyPos)
             *pItem = *Start();
         for( auto& pItem : aBehindArr )
             *pItem = *End();
+
+        // sw_redlinehide: assume that Show will only be called by filters;
+        // when it is called, ensure that no MergedPara instance survives
+        for (SwNodeIndex node = Start()->nNode; node.GetIndex() <= End()->nNode.GetIndex(); ++node)
+        {
+            if (SwTextNode const*const pNode = node.GetNode().GetTextNode())
+            {
+                SwIterator<SwTextFrame, SwTextNode, sw::IteratorMode::UnwrapMulti> aIter(*pNode);
+                for (SwTextFrame* pFrame = aIter.First(); pFrame; pFrame = aIter.Next())
+                {
+                    pFrame->SetMergedPara(nullptr);
+                }
+            }
+        }
     }
     else
         InvalidateRange();
commit 6a15c6b0196efd786024ab95803b03485554c633
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Thu May 17 13:00:33 2018 +0200

    sw_redlinehide: let the Show menu item toggle new mode
    
    Change-Id: I1201e84b231be17e6a5ec2294acfb1e3111c9ada

diff --git a/sw/source/uibase/uiview/view2.cxx b/sw/source/uibase/uiview/view2.cxx
index 90ca68a0f404..1d57aefdd498 100644
--- a/sw/source/uibase/uiview/view2.cxx
+++ b/sw/source/uibase/uiview/view2.cxx
@@ -140,6 +140,7 @@
 #include <vcl/settings.hxx>
 #include <i18nutil/searchopt.hxx>
 #include <paratr.hxx>
+#include <rootfrm.hxx>
 
 #include <memory>
 
@@ -639,7 +640,15 @@ void SwView::Execute(SfxRequest &rReq)
                 if( static_cast<const SfxBoolItem*>(pItem)->GetValue() )
                     nMode |= RedlineFlags::ShowDelete;
 
-                m_pWrtShell->SetRedlineFlagsAndCheckInsMode( nMode );
+                if (getenv("SW_REDLINEHIDE")) // TODO...
+                {
+                    m_pWrtShell->GetLayout()->SetHideRedlines(
+                        !static_cast<const SfxBoolItem*>(pItem)->GetValue());
+                    if (m_pWrtShell->IsRedlineOn())
+                        m_pWrtShell->SetInsMode();
+                }
+                else
+                    m_pWrtShell->SetRedlineFlagsAndCheckInsMode( nMode );
             }
             break;
         case FN_MAILMERGE_SENDMAIL_CHILDWINDOW:
commit d435881680b11b4b9f09e62e0a33213b67f0c40d
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Thu May 17 14:16:27 2018 +0200

    sw_redlinehide: very incomplete impl. of SwRootFrame::SetHideRedlines()
    
    Change-Id: Icff1b1aac20a0a6d3f957e7025f6a08a6d0edbee

diff --git a/sw/source/core/layout/wsfrm.cxx b/sw/source/core/layout/wsfrm.cxx
index a25bb8d7bb9f..2406868f5c4c 100644
--- a/sw/source/core/layout/wsfrm.cxx
+++ b/sw/source/core/layout/wsfrm.cxx
@@ -4171,6 +4171,47 @@ void SwRootFrame::SetHideRedlines(bool const bHideRedlines)
         return;
     }
     mbHideRedlines = bHideRedlines;
+    SwNodes const& rNodes(GetFormat()->GetDoc()->GetNodes());
+    // Hide->Show: clear MergedPara, create frames
+    // Show->Hide: call CheckParaRedlineMerge, delete frames
+    // TODO how to traverse
+    // * via layout
+    //      - but that won't find nodes that don't have frames in ->Show case
+    // * via nodes
+    //      - what about special sections before content? flys? footnotes?
+    //        is order of these predictable? flys not anchored in content?
+    // * ideally should call something existing that tries to create everything?
+    //      - is that done automatically somewhere already?
+    // * other direction ->Hide - delete frames!
+    // in-order traversal should init flags in nodes *before* the nodes are found
+    for (sal_uLong i = 0; i < rNodes.Count(); ++i)
+    {
+        SwNode *const pNode(rNodes[i]);
+        if (pNode->IsTextNode())
+        {
+            SwTextNode & rTextNode(*pNode->GetTextNode());
+            SwIterator<SwTextFrame, SwTextNode> aIter(rTextNode);
+            for (SwTextFrame * pFrame = aIter.First(); pFrame; pFrame = aIter.Next())
+            {
+                if (pFrame->getRootFrame() == this)
+                {
+                    if (mbHideRedlines && pNode->IsCreateFrameWhenHidingRedlines())
+                    {
+                        pFrame->SetMergedPara(CheckParaRedlineMerge(*pFrame, rTextNode));
+                    }
+                    else
+                    {
+                        if (pFrame->GetMergedPara())
+                        {
+                            pFrame->SetMergedPara(nullptr);
+                            rTextNode.DelFrames(); // FIXME only those in this layout?
+                        }
+                    }
+                }
+            }
+        }
+    }
+    InvalidateAllContent(SwInvalidateFlags::Size); // ??? TODO what to invalidate?
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 41a69a2d2f870884213aae8dd8bf53289862c243
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Fri Jun 1 22:45:55 2018 +0200

    sw_redlinehide: SwTextNode::Insert(): send SwInsText hint before
    
    ... adjusting hints, as the latter sends RES_UPDATE_ATTR hints
    and the ModelToViewPos() asserts because the mergedText is too short.
    
    Change-Id: I48bf6388ce69f3294decf96dc6dd11ba3bf4bc7b

diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index b044a7439429..a241caf00d4e 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -1993,6 +1993,12 @@ OUString SwTextNode::InsertText( const OUString & rStr, const SwIndex & rIdx,
         SetIgnoreDontExpand( bOldExpFlg );
     }
 
+    if ( HasWriterListeners() )
+    {   // send this before messing with hints, which will send RES_UPDATE_ATTR
+        SwInsText aHint( aPos, nLen );
+        NotifyClients( nullptr, &aHint );
+    }
+
     if ( HasHints() )
     {
         bool const bHadHints(!m_pSwpHints->CanBeDeleted());
@@ -2064,12 +2070,6 @@ OUString SwTextNode::InsertText( const OUString & rStr, const SwIndex & rIdx,
                 "SwTextNode::InsertText: unexpected loss of hints");
     }
 
-    if ( HasWriterListeners() )
-    {
-        SwInsText aHint( aPos, nLen );
-        NotifyClients( nullptr, &aHint );
-    }
-
     // By inserting a character, the hidden flags
     // at the TextNode can become invalid:
     SetCalcHiddenCharFlags();
commit 14d3331e2b5729b4e5cac55cec11a0f4d8e62cb0
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Fri Jun 1 22:41:06 2018 +0200

    sw_redlinehide: convert GetAttrSet() in txtfrm.cxx, frmtool.cxx
    
    Change-Id: I3541fa79ff48f6829fc459ab5bd8224c29c51cbb

diff --git a/sw/source/core/layout/frmtool.cxx b/sw/source/core/layout/frmtool.cxx
index cfafce5b3d51..3713439f3f53 100644
--- a/sw/source/core/layout/frmtool.cxx
+++ b/sw/source/core/layout/frmtool.cxx
@@ -738,8 +738,7 @@ SwContentNotify::SwContentNotify( SwContentFrame *pContentFrame ) :
         SwTextFrame* pTextFrame = static_cast<SwTextFrame*>(pContentFrame);
         if (!pTextFrame->GetDoc().getIDocumentSettingAccess().get(DocumentSettingId::OLD_LINE_SPACING))
         {
-            const SwAttrSet* pSet = pTextFrame->GetAttrSet();
-            const SvxLineSpacingItem &rSpace = pSet->GetLineSpacing();
+            const SvxLineSpacingItem &rSpace = pTextFrame->GetAttrSet()->GetLineSpacing();
             if ( rSpace.GetInterLineSpaceRule() == SvxInterLineSpaceRule::Prop )
             {
                 mbChkHeightOfLastLine = true;
diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx
index 4ca51820e0e8..5491dc388c3c 100644
--- a/sw/source/core/text/txtfrm.cxx
+++ b/sw/source/core/text/txtfrm.cxx
@@ -2997,7 +2997,8 @@ void SwTextFrame::CalcHeightOfLastLine( const bool _bUseFont )
     {
         // former determination of last line height for proprotional line
         // spacing - take height of font set at the paragraph
-        SwFont aFont( GetAttrSet(), pIDSA );
+        // FIXME actually ... must the font match across all nodes?
+        SwFont aFont( &GetTextNodeForParaProps()->GetSwAttrSet(), pIDSA );
 
         // we must ensure that the font is restored correctly on the OutputDevice
         // otherwise Last!=Owner could occur
@@ -3103,8 +3104,7 @@ long SwTextFrame::GetLineSpace( const bool _bNoPropLineSpace ) const
 {
     long nRet = 0;
 
-    const SwAttrSet* pSet = GetAttrSet();
-    const SvxLineSpacingItem &rSpace = pSet->GetLineSpacing();
+    const SvxLineSpacingItem &rSpace = GetTextNodeForParaProps()->GetSwAttrSet().GetLineSpacing();
 
     switch( rSpace.GetInterLineSpaceRule() )
     {
@@ -3205,7 +3205,7 @@ void SwTextFrame::ChgThisLines()
 
     if ( nNew != mnThisLines )
     {
-        if ( !IsInTab() && GetAttrSet()->GetLineNumber().IsCount() )
+        if (!IsInTab() && GetTextNodeForParaProps()->GetSwAttrSet().GetLineNumber().IsCount())
         {
             mnAllLines -= mnThisLines;
             mnThisLines = nNew;
@@ -3236,12 +3236,10 @@ void SwTextFrame::RecalcAllLines()
 {
     ValidateLineNum();
 
-    const SwAttrSet *pAttrSet = GetAttrSet();
-
     if ( !IsInTab() )
     {
         const sal_uLong nOld = GetAllLines();
-        const SwFormatLineNumber &rLineNum = pAttrSet->GetLineNumber();
+        const SwFormatLineNumber &rLineNum = GetTextNodeForParaProps()->GetSwAttrSet().GetLineNumber();
         sal_uLong nNewNum;
         const bool bRestart = GetDoc().GetLineNumberInfo().IsRestartEachPage();
 
commit 6ad922b26e189d8bbbb3ccbb459c965eb7a153fe
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Fri Jun 1 22:37:02 2018 +0200

    sw_redlinehide: move SwContentNode::GetNode() to SwNoTextNode
    
    SwTextNode's GetDep() may be a WriterMultiListener, which isn't even a
    node.
    
    SwTextNode has GetTextNodeForParaProps()/GetTextNodeFirst().
    
    Change-Id: Ica177a6a3cf7c886c9a8d2733fb9cb452a475450

diff --git a/sw/source/core/inc/cntfrm.hxx b/sw/source/core/inc/cntfrm.hxx
index 62413e38de8c..aa28f580f3ad 100644
--- a/sw/source/core/inc/cntfrm.hxx
+++ b/sw/source/core/inc/cntfrm.hxx
@@ -71,9 +71,6 @@ public:
     virtual void Cut() override;
     virtual void Paste( SwFrame* pParent, SwFrame* pSibling = nullptr ) override;
 
-    inline const SwContentNode *GetNode() const;
-    inline       SwContentNode *GetNode();
-
     inline const SwContentFrame *GetFollow() const;
     inline       SwContentFrame *GetFollow();
     SwTextFrame* FindMaster() const;
@@ -114,15 +111,6 @@ inline SwContentFrame* SwContentFrame::GetPrevContentFrame() const
         return const_cast<SwContentFrame*>(ImplGetNextContentFrame( false ));
 }
 
-inline SwContentNode *SwContentFrame::GetNode()
-{
-    return static_cast< SwContentNode* >( GetDep() );
-}
-inline const SwContentNode *SwContentFrame::GetNode() const
-{
-    return static_cast< const SwContentNode* >( GetDep() );
-}
-
 inline const SwContentFrame *SwContentFrame::GetFollow() const
 {
     return static_cast<const SwContentFrame*>(SwFlowFrame::GetFollow());
diff --git a/sw/source/core/inc/notxtfrm.hxx b/sw/source/core/inc/notxtfrm.hxx
index 9de5fd31abfe..eaa10653964b 100644
--- a/sw/source/core/inc/notxtfrm.hxx
+++ b/sw/source/core/inc/notxtfrm.hxx
@@ -54,6 +54,11 @@ protected:
 public:
     SwNoTextFrame( SwNoTextNode * const, SwFrame* );
 
+    const SwContentNode *GetNode() const
+        { return static_cast<SwContentNode const*>(GetDep()); }
+          SwContentNode *GetNode()
+        { return static_cast<SwContentNode      *>(GetDep()); }
+
     virtual bool LeftMargin(SwPaM *) const override;
     virtual bool RightMargin(SwPaM *, bool bAPI = false) const override;
 
diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx
index 9c0f787060f7..f6fbb686903e 100644
--- a/sw/source/core/inc/txtfrm.hxx
+++ b/sw/source/core/inc/txtfrm.hxx
@@ -398,9 +398,9 @@ public:
     const OUString& GetText() const;
     // TODO: remove GetTextNode
     SwTextNode *GetTextNode()
-        { return static_cast< SwTextNode* >( SwContentFrame::GetNode()); }
+        { return static_cast<SwTextNode*>(SwFrame::GetDep()); }
     const SwTextNode *GetTextNode() const
-        { return static_cast< const SwTextNode* >( SwContentFrame::GetNode()); }
+        { return static_cast<const SwTextNode*>(SwFrame::GetDep()); }
     SwTextNode const* GetTextNodeForParaProps() const;
     SwTextNode      * GetTextNodeFirst()
         { return const_cast<SwTextNode*>(const_cast<SwTextFrame const*>(this)->GetTextNodeFirst()); };
commit 70655844286e80f6dddf93374e664c1fec100ea9
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Fri May 4 13:45:09 2018 +0200

    sw_redlinehide: use FrameContainsNode in anchoredobjectposition.cxx
    
    Change-Id: I648810c1d5549d700a64f120a52416a951d56dca

diff --git a/sw/source/core/objectpositioning/anchoredobjectposition.cxx b/sw/source/core/objectpositioning/anchoredobjectposition.cxx
index 0bae1d1c8ade..f9fa2c8d11cd 100644
--- a/sw/source/core/objectpositioning/anchoredobjectposition.cxx
+++ b/sw/source/core/objectpositioning/anchoredobjectposition.cxx
@@ -947,7 +947,7 @@ SwTwips SwAnchoredObjectPosition::AdjustHoriRelPosForDrawAside(
     const sal_uInt32 nObjOrdNum = GetObject().GetOrdNum();
     const SwPageFrame* pObjPage = rFlyAtContentFrame.FindPageFrame();
     const SwFrame* pObjContext = ::FindContext( &rAnchorTextFrame, SwFrameType::Column );
-    sal_uLong nObjIndex = rAnchorTextFrame.GetTextNode()->GetIndex();
+    sal_uLong nObjIndex = rAnchorTextFrame.GetTextNodeFirst()->GetIndex();
     SwOrderIter aIter( pObjPage );
     const SwFlyFrame* pFly = static_cast<const SwVirtFlyDrawObj*>(aIter.Bottom())->GetFlyFrame();
     while ( pFly && nObjOrdNum > pFly->GetVirtDrawObj()->GetOrdNumDirect() )
@@ -1058,8 +1058,9 @@ bool SwAnchoredObjectPosition::DrawAsideFly( const SwFlyFrame* _pFly,
          ::FindContext( _pFly->GetAnchorFrame(), SwFrameType::Column ) == _pObjContext )
     {
         sal_uLong nOtherIndex =
-            static_cast<const SwTextFrame*>(_pFly->GetAnchorFrame())->GetTextNode()->GetIndex();
-        if( _nObjIndex >= nOtherIndex )
+            static_cast<const SwTextFrame*>(_pFly->GetAnchorFrame())->GetTextNodeFirst()->GetIndex();
+        if (sw::FrameContainsNode(static_cast<SwTextFrame const&>(*_pFly->GetAnchorFrame()), _nObjIndex)
+            || nOtherIndex < _nObjIndex)
         {
             const SwFormatHoriOrient& rHori = _pFly->GetFormat()->GetHoriOrient();
             sal_Int16 eOtherRelOrient = rHori.GetRelationOrient();
commit e6765c2cccf065e979a514a91b41aa93556d6bed
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Fri Jun 1 22:32:26 2018 +0200

    sw_redlinehide: convert GetNode(), use FrameContainsNode(), txtfly.cxx
    
    Change-Id: I0e4961acc191a764db74ede75e140e63ad1318a0

diff --git a/sw/source/core/layout/trvlfrm.cxx b/sw/source/core/layout/trvlfrm.cxx
index 39843fd25efb..fee388a696c1 100644
--- a/sw/source/core/layout/trvlfrm.cxx
+++ b/sw/source/core/layout/trvlfrm.cxx
@@ -692,7 +692,7 @@ static const SwContentFrame * lcl_MissProtectedFrames( const SwContentFrame *pCn
 static bool lcl_UpDown( SwPaM *pPam, const SwContentFrame *pStart,
                     GetNxtPrvCnt fnNxtPrv, bool bInReadOnly )
 {
-    OSL_ENSURE( &pPam->GetNode() == pStart->GetNode(),
+    OSL_ENSURE( FrameContainsNode(*pStart, pPam->GetNode().GetIndex()),
             "lcl_UpDown doesn't work for others." );
 
     const SwContentFrame *pCnt = nullptr;
diff --git a/sw/source/core/text/txtfly.cxx b/sw/source/core/text/txtfly.cxx
index c7d3f891fa0d..45950b93ec6b 100644
--- a/sw/source/core/text/txtfly.cxx
+++ b/sw/source/core/text/txtfly.cxx
@@ -834,9 +834,9 @@ bool SwTextFly::GetTop( const SwAnchoredObject* _pAnchoredObj,
                 // If possible determine Index via SwFormatAnchor because
                 // otherwise it's quite expensive.
                 if (ULONG_MAX == m_nCurrFrameNodeIndex)
-                    m_nCurrFrameNodeIndex = m_pCurrFrame->GetNode()->GetIndex();
+                    m_nCurrFrameNodeIndex = m_pCurrFrame->GetTextNodeFirst()->GetIndex();
 
-                if (nTmpIndex < m_nCurrFrameNodeIndex)
+                if (FrameContainsNode(*m_pCurrFrame, nTmpIndex) || nTmpIndex < m_nCurrFrameNodeIndex)
                     return true;
             }
         }
commit 27eb24fd03c4d843f089487ac7daf3ced8417d67
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Fri Jun 1 22:30:58 2018 +0200

    sw_redlinehide: iterate merged nodes in SwLayIdle::DoIdleJob_()
    
    Change-Id: I42924448749385bb0e5bc2c187e37053e104c0da

diff --git a/sw/source/core/layout/layact.cxx b/sw/source/core/layout/layact.cxx
index a4df2477ea01..e98f19ccb771 100644
--- a/sw/source/core/layout/layact.cxx
+++ b/sw/source/core/layout/layact.cxx
@@ -1847,19 +1847,50 @@ bool SwLayIdle::DoIdleJob_( const SwContentFrame *pCnt, IdleJobType eJob )
     if( !pCnt->IsTextFrame() )
         return false;
 
-    const SwTextNode* pTextNode = pCnt->GetNode()->GetTextNode();
+    SwTextFrame const*const pTextFrame(static_cast<SwTextFrame const*>(pCnt));
+    // sw_redlinehide: spell check only the nodes with visible content?
+    const SwTextNode* pTextNode = pTextFrame->GetTextNodeForParaProps();
 
     bool bProcess = false;
-    switch ( eJob )
+    for (size_t i = 0; pTextNode; )
     {
-        case ONLINE_SPELLING :
-            bProcess = pTextNode->IsWrongDirty(); break;
-        case AUTOCOMPLETE_WORDS :
-            bProcess = pTextNode->IsAutoCompleteWordDirty(); break;
-        case WORD_COUNT :
-            bProcess = pTextNode->IsWordCountDirty(); break;
-        case SMART_TAGS :
-            bProcess = pTextNode->IsSmartTagDirty(); break;
+        switch ( eJob )
+        {
+            case ONLINE_SPELLING :
+                bProcess = pTextNode->IsWrongDirty(); break;
+            case AUTOCOMPLETE_WORDS :
+                bProcess = pTextNode->IsAutoCompleteWordDirty(); break;
+            case WORD_COUNT :
+                bProcess = pTextNode->IsWordCountDirty(); break;
+            case SMART_TAGS :
+                bProcess = pTextNode->IsSmartTagDirty(); break;
+        }
+        if (bProcess)
+        {
+            break;
+        }
+        if (sw::MergedPara const* pMerged = pTextFrame->GetMergedPara())
+        {
+            while (true)
+            {
+                ++i;
+                if (i < pMerged->extents.size())
+                {
+                    if (pMerged->extents[i].pNode != pTextNode)
+                    {
+                        pTextNode = pMerged->extents[i].pNode;
+                        break;
+                    }
+                }
+                else
+                {
+                    pTextNode = nullptr;
+                    break;
+                }
+            }
+        }
+        else
+            pTextNode = nullptr;
     }
 
     if( bProcess )
commit 47141efee32587516ccb1686d7190ad679828267
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Fri Jun 1 22:29:16 2018 +0200

    sw_redlinehide: convert GetNode() in frmtool.cxx
    
    Change-Id: I6787ec787190ad297717ab01a78414cac34aa2cb

diff --git a/sw/source/core/layout/frmtool.cxx b/sw/source/core/layout/frmtool.cxx
index 12a5b322cc07..cfafce5b3d51 100644
--- a/sw/source/core/layout/frmtool.cxx
+++ b/sw/source/core/layout/frmtool.cxx
@@ -823,8 +823,8 @@ SwContentNotify::~SwContentNotify()
         SwViewShell *pSh  = pCnt->getRootFrame()->GetCurrShell();
         if ( pSh )
         {
-            SwOLENode *pNd;
-            if ( nullptr != (pNd = pCnt->GetNode()->GetOLENode()) &&
+            SwOLENode *const pNd(static_cast<SwNoTextFrame*>(pCnt)->GetNode()->GetOLENode());
+            if (nullptr != pNd &&
                  (pNd->GetOLEObj().IsOleRef() ||
                   pNd->IsOLESizeInvalid()) )
             {
@@ -882,7 +882,9 @@ SwContentNotify::~SwContentNotify()
     {
         pCnt->SetRetouche();    //fix(13870)
 
-        SwDoc *pDoc = pCnt->GetNode()->GetDoc();
+        SwDoc *const pDoc = pCnt->IsTextFrame()
+            ? &static_cast<SwTextFrame*>(pCnt)->GetDoc()
+            : static_cast<SwNoTextFrame*>(pCnt)->GetNode()->GetDoc();
         if ( !pDoc->GetSpzFrameFormats()->empty() &&
              pDoc->DoesContainAtPageObjWithContentAnchor() && !pDoc->getIDocumentState().IsNewDoc() )
         {
@@ -895,7 +897,6 @@ SwContentNotify::~SwContentNotify()
             // the page is known. Thus, this data can be corrected now.
 
             const SwPageFrame *pPage = nullptr;
-            SwNodeIndex *pIdx  = nullptr;
             SwFrameFormats *pTable = pDoc->GetSpzFrameFormats();
 
             for ( size_t i = 0; i < pTable->size(); ++i )
@@ -908,11 +909,7 @@ SwContentNotify::~SwContentNotify()
                     continue;
                 }
 
-                if ( !pIdx )
-                {
-                    pIdx = new SwNodeIndex( *pCnt->GetNode() );
-                }
-                if ( rAnch.GetContentAnchor()->nNode == *pIdx )
+                if (FrameContainsNode(*pCnt, rAnch.GetContentAnchor()->nNode.GetIndex()))
                 {
                     OSL_FAIL( "<SwContentNotify::~SwContentNotify()> - to page anchored object with content position." );
                     if ( !pPage )
@@ -929,7 +926,6 @@ SwContentNotify::~SwContentNotify()
                     }
                 }
             }
-            delete pIdx;
         }
     }
 
@@ -1829,7 +1825,9 @@ void MakeFrames( SwDoc *pDoc, const SwNodeIndex &rSttIdx,
 SwBorderAttrs::SwBorderAttrs(const SwModify *pMod, const SwFrame *pConstructor)
     : SwCacheObj(pMod)
     , m_rAttrSet(pConstructor->IsContentFrame()
-                    ? static_cast<const SwContentFrame*>(pConstructor)->GetNode()->GetSwAttrSet()
+                    ? pConstructor->IsTextFrame()
+                        ? static_cast<const SwTextFrame*>(pConstructor)->GetTextNodeForParaProps()->GetSwAttrSet()
+                        : static_cast<const SwNoTextFrame*>(pConstructor)->GetNode()->GetSwAttrSet()
                     : static_cast<const SwLayoutFrame*>(pConstructor)->GetFormat()->GetAttrSet())
     , m_rUL(m_rAttrSet.GetULSpace())
     // #i96772#
@@ -2206,14 +2204,20 @@ void SwBorderAttrs::GetBottomLine_( const SwFrame& _rFrame )
     m_nGetBottomLine = nRet;
 }
 
+static SwModify const* GetCacheOwner(SwFrame const& rFrame)
+{
+    return rFrame.IsContentFrame()
+        ? static_cast<SwModify const*>(rFrame.IsTextFrame()
+        // sw_redlinehide: presumably this caches the border attrs at the model level and can be shared across different layouts so we want the ParaProps node here
+            ? static_cast<const SwTextFrame&>(rFrame).GetTextNodeForParaProps()
+            : static_cast<const SwNoTextFrame&>(rFrame).GetNode())
+        : static_cast<SwModify const*>(static_cast<const SwLayoutFrame&>(rFrame).GetFormat());
+}
+
 SwBorderAttrAccess::SwBorderAttrAccess( SwCache &rCach, const SwFrame *pFrame ) :
     SwCacheAccess( rCach,
-                   (pFrame->IsContentFrame() ?
-                      const_cast<void*>(static_cast<void const *>(static_cast<const SwContentFrame*>(pFrame)->GetNode())) :
-                      const_cast<void*>(static_cast<void const *>(static_cast<const SwLayoutFrame*>(pFrame)->GetFormat()))),
-                   (pFrame->IsContentFrame() ?
-                      static_cast<SwModify const *>(static_cast<const SwContentFrame*>(pFrame)->GetNode())->IsInCache() :
-                      static_cast<SwModify const *>(static_cast<const SwLayoutFrame*>(pFrame)->GetFormat())->IsInCache()) ),
+        static_cast<void const *>(GetCacheOwner(*pFrame)),
+        GetCacheOwner(*pFrame)->IsInCache()),
     m_pConstructor( pFrame )
 {
 }
commit 92cc346573b956c3ef50364f9baa40e836ac3b12
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Fri Jun 1 22:26:52 2018 +0200

    sw_redlinehide: convert GetNode(), use FrameContainsNode() in flycnt.cxx
    
    Change-Id: I551d37c961149bb043bed4cde7b52822f5e3db81

diff --git a/sw/source/core/layout/flycnt.cxx b/sw/source/core/layout/flycnt.cxx
index 71cdcc029235..7e1f1079a686 100644
--- a/sw/source/core/layout/flycnt.cxx
+++ b/sw/source/core/layout/flycnt.cxx
@@ -20,6 +20,7 @@
 #include <tools/bigint.hxx>
 #include <pagefrm.hxx>
 #include <txtfrm.hxx>
+#include <notxtfrm.hxx>
 #include <doc.hxx>
 #include <pam.hxx>
 #include <IDocumentUndoRedo.hxx>
@@ -114,7 +115,11 @@ void SwFlyAtContentFrame::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pN
         // Search the new anchor using the NodeIdx; the relation between old
         // and new NodeIdx determines the search direction
         const SwNodeIndex aNewIdx( pAnch->GetContentAnchor()->nNode );
-        SwNodeIndex aOldIdx( *pContent->GetNode() );
+        SwNodeIndex aOldIdx( pContent->IsTextFrame()
+                // sw_redlinehide: can pick any node here, the compare with
+                // FrameContainsNode should catch it
+                ? *static_cast<SwTextFrame *>(pContent)->GetTextNodeFirst()
+                : *static_cast<SwNoTextFrame *>(pContent)->GetNode() );
 
         //fix: depending on which index was smaller, searching in the do-while
         //loop previously was done forward or backwards respectively. This however
@@ -122,12 +127,12 @@ void SwFlyAtContentFrame::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pN
         //is now done in only one direction. Getting hold of a frame from the node
         //is still possible if the new anchor could not be found. Chances are
         //good that this will be the correct one.
-        const bool bNext = aOldIdx < aNewIdx;
         // consider the case that at found anchor frame candidate already a
         // fly frame of the given fly format is registered.
         // consider, that <pContent> is the already
         // the new anchor frame.
-        bool bFound( aOldIdx == aNewIdx );
+        bool bFound( FrameContainsNode(*pContent, aNewIdx.GetIndex()) );
+        const bool bNext = !bFound && aOldIdx < aNewIdx;
         while ( pContent && !bFound )
         {
             do
@@ -140,11 +145,10 @@ void SwFlyAtContentFrame::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pN
                       ( bBodyFootnote != ( pContent->IsInDocBody() ||
                                            pContent->IsInFootnote() ) ) );
             if ( pContent )
-                aOldIdx = *pContent->GetNode();
+                bFound = FrameContainsNode(*pContent, aNewIdx.GetIndex());
 
             // check, if at found anchor frame candidate already a fly frame
             // of the given fly frame format is registered.
-            bFound = aOldIdx == aNewIdx;
             if (bFound && pContent && pContent->GetDrawObjs())
             {
                 SwFrameFormat* pMyFlyFrameFormat( &GetFrameFormat() );
@@ -1327,19 +1331,18 @@ void SwFlyAtContentFrame::SetAbsPos( const Point &rNew )
         SwPosition pos = *aAnch.GetContentAnchor();
         if( IsAutoPos() && pCnt->IsTextFrame() )
         {
+            SwTextFrame const*const pTextFrame(static_cast<SwTextFrame const*>(pCnt));
             SwCursorMoveState eTmpState( MV_SETONLYTEXT );
             Point aPt( rNew );
             if( pCnt->GetCursorOfst( &pos, aPt, &eTmpState )
-                && pos.nNode == *pCnt->GetNode() )
+                && FrameContainsNode(*pTextFrame, pos.nNode.GetIndex()))
             {
-                if ( pCnt->GetNode()->GetTextNode() != nullptr )
+                const SwTextAttr *const pTextInputField =
+                    pos.nNode.GetNode().GetTextNode()->GetTextAttrAt(
+                        pos.nContent.GetIndex(), RES_TXTATR_INPUTFIELD, SwTextNode::PARENT );
+                if (pTextInputField != nullptr)
                 {
-                    const SwTextAttr* pTextInputField =
-                        pCnt->GetNode()->GetTextNode()->GetTextAttrAt( pos.nContent.GetIndex(), RES_TXTATR_INPUTFIELD, SwTextNode::PARENT );
-                    if ( pTextInputField != nullptr )
-                    {
-                        pos.nContent = pTextInputField->GetStart();
-                    }
+                    pos.nContent = pTextInputField->GetStart();
                 }
                 ResetLastCharRectHeight();
                 if( text::RelOrientation::CHAR == pFormat->GetVertOrient().GetRelationOrient() )
@@ -1349,14 +1352,18 @@ void SwFlyAtContentFrame::SetAbsPos( const Point &rNew )
             }
             else
             {
-                pos.nNode = *pCnt->GetNode();
-                pos.nContent.Assign( pCnt->GetNode(), 0 );
+                pos = pTextFrame->MapViewToModelPos(TextFrameIndex(0));
             }
         }
-        else
+        else if (pCnt->IsTextFrame())
+        {
+            pos = static_cast<SwTextFrame const*>(pCnt)->MapViewToModelPos(TextFrameIndex(0));
+        }
+        else // is that even possible? maybe if there was a change of anchor type from AT_FLY or something?
         {
-            pos.nNode = *pCnt->GetNode();
-            pos.nContent.Assign( pCnt->GetNode(), 0 );
+            assert(pCnt->IsNoTextFrame());
+            pos.nNode = *static_cast<SwNoTextFrame*>(pCnt)->GetNode();
+            pos.nContent.Assign(static_cast<SwNoTextFrame*>(pCnt)->GetNode(), 0);
         }
         aAnch.SetAnchor( &pos );
 
commit d4d9aadf1e9fc9cdcb4133327405c156fcac6201
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Fri Jun 1 22:24:24 2018 +0200

    sw_redlinehide: convert GetNode() in SwFlowFrame::BwdMoveNecessary()
    
    Change-Id: Iaefed6ebee4f4cf47697c174abc275b1287f643f

diff --git a/sw/source/core/layout/flowfrm.cxx b/sw/source/core/layout/flowfrm.cxx
index 1dce5a5131ff..46af46fbe942 100644
--- a/sw/source/core/layout/flowfrm.cxx
+++ b/sw/source/core/layout/flowfrm.cxx
@@ -343,21 +343,28 @@ sal_uInt8 SwFlowFrame::BwdMoveNecessary( const SwPageFrame *pPage, const SwRect
                         if( ULONG_MAX == nIndex )
                         {
                             const SwNode *pNode;
-                            if ( m_rThis.IsContentFrame() )
-                                pNode = static_cast<SwContentFrame&>(m_rThis).GetNode();
+                            if (m_rThis.IsTextFrame())
+                                pNode = static_cast<SwTextFrame&>(m_rThis).GetTextNodeFirst();
+                            else if (m_rThis.IsNoTextFrame())
+                                pNode = static_cast<SwNoTextFrame&>(m_rThis).GetNode();
                             else if( m_rThis.IsSctFrame() )
                                 pNode = static_cast<SwSectionFormat*>(static_cast<SwSectionFrame&>(m_rThis).
                                         GetFormat())->GetSectionNode();
                             else
                             {
+                                assert(!m_rThis.IsContentFrame());
                                 OSL_ENSURE( m_rThis.IsTabFrame(), "new FowFrame?" );
                                 pNode = static_cast<SwTabFrame&>(m_rThis).GetTable()->
                                     GetTabSortBoxes()[0]->GetSttNd()->FindTableNode();
                             }
                             nIndex = pNode->GetIndex();
                         }
-                        if( nIndex < nTmpIndex )
+                        if (nIndex < nTmpIndex &&
+                            (!m_rThis.IsTextFrame() ||
+                             !FrameContainsNode(static_cast<SwTextFrame&>(m_rThis), nTmpIndex)))
+                        {
                             continue;
+                        }
                     }
                 }
                 else
commit 7f7a599f9f572f27d78f6e885ce0db86c2577617
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Fri Jun 1 22:22:48 2018 +0200

    sw_redlinehide: convert GetNode() in SwCursor::IsSelOvr()
    
    Change-Id: I3cca2091f4a3fe903bbd606c93a368662e997899

diff --git a/sw/source/core/crsr/swcrsr.cxx b/sw/source/core/crsr/swcrsr.cxx
index 91e9e2e61551..2b934cb6c576 100644
--- a/sw/source/core/crsr/swcrsr.cxx
+++ b/sw/source/core/crsr/swcrsr.cxx
@@ -39,6 +39,7 @@
 #include <cntfrm.hxx>
 #include <rootfrm.hxx>
 #include <txtfrm.hxx>
+#include <notxtfrm.hxx>
 #include <scriptinfo.hxx>
 #include <crstate.hxx>
 #include <docsh.hxx>
@@ -351,18 +352,31 @@ bool SwCursor::IsSelOvr( SwCursorSelOverFlags eFlags )
                 }
             }
 
-            SwContentNode* pCNd = (pFrame != nullptr) ? const_cast<SwContentNode*>(pFrame->GetNode()) : nullptr;
-            if ( pCNd != nullptr )
+            if (pFrame != nullptr)
             {
-                // set this ContentNode as new position
-                rPtIdx = *pCNd;
+                if (pFrame->IsTextFrame())
+                {
+                    SwTextFrame const*const pTextFrame(static_cast<SwTextFrame const*>(pFrame));
+                    *GetPoint() = pTextFrame->MapViewToModelPos(TextFrameIndex(
+                            bGoNxt ? 0 : pTextFrame->GetText().getLength()));
+                }
+                else
+                {
+                    assert(pFrame->IsNoTextFrame());
+                    SwContentNode *const pCNd = const_cast<SwContentNode*>(
+                        static_cast<SwNoTextFrame const*>(pFrame)->GetNode());
+                    assert(pCNd);
+
+                    // set this ContentNode as new position
+                    rPtIdx = *pCNd;
+                    // assign corresponding ContentIndex
+                    const sal_Int32 nTmpPos = bGoNxt ? 0 : pCNd->Len();
+                    GetPoint()->nContent.Assign( pCNd, nTmpPos );
+                }
 
-                // assign corresponding ContentIndex
-                const sal_Int32 nTmpPos = bGoNxt ? 0 : pCNd->Len();
-                GetPoint()->nContent.Assign( pCNd, nTmpPos );
 
                 if (rPtIdx.GetIndex() == m_vSavePos.back().nNode
-                    && nTmpPos == m_vSavePos.back().nContent)
+                    && GetPoint()->nContent.GetIndex() == m_vSavePos.back().nContent)
                 {
                     // new position equals saved one
                     // --> trigger restore of saved pos by setting <pFrame> to NULL - see below
commit 9944c8ae2d466486e3d03221b86eef21c8e181bc
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Fri Jun 1 22:16:28 2018 +0200

    sw_redlinehide: refactor AppendObjs to iterate merged paragraphs
    
    Change-Id: I5860b9791c0839d4b83eec6a3db0b2d1926d2ccd

diff --git a/sw/source/core/inc/flyfrm.hxx b/sw/source/core/inc/flyfrm.hxx
index 0c4c9319b3ed..c28dcd98b882 100644
--- a/sw/source/core/inc/flyfrm.hxx
+++ b/sw/source/core/inc/flyfrm.hxx
@@ -25,6 +25,7 @@
 #include <frmfmt.hxx>
 #include <anchoredobject.hxx>
 
+class SwFormatAnchor;
 class SwPageFrame;
 class SwFormatFrameSize;
 struct SwCursorMoveState;
@@ -58,7 +59,7 @@ bool CalcClipRect( const SdrObject *pSdrObj, SwRect &rRect, bool bMove = true );
 class SwFlyFrame : public SwLayoutFrame, public SwAnchoredObject
 {
     // is allowed to lock, implemented in frmtool.cxx
-    friend void AppendObjs   ( const SwFrameFormats *, sal_uLong, SwFrame *, SwPageFrame *, SwDoc* );
+    friend void AppendObj(SwFrame *const pFrame, SwPageFrame *const pPage, SwFrameFormat *const pFormat, const SwFormatAnchor & rAnch);
     friend void Notify( SwFlyFrame *, SwPageFrame *pOld, const SwRect &rOld,
                         const SwRect* pOldPrt );
 
diff --git a/sw/source/core/layout/frmtool.cxx b/sw/source/core/layout/frmtool.cxx
index bfdb15bc1a86..12a5b322cc07 100644
--- a/sw/source/core/layout/frmtool.cxx
+++ b/sw/source/core/layout/frmtool.cxx
@@ -973,38 +973,9 @@ SwContentNotify::~SwContentNotify()
     }
 }
 
-void AppendObjs( const SwFrameFormats *pTable, sal_uLong nIndex,
-                        SwFrame *pFrame, SwPageFrame *pPage, SwDoc* doc )
+// note this *cannot* be static because it's a friend
+void AppendObj(SwFrame *const pFrame, SwPageFrame *const pPage, SwFrameFormat *const pFormat, const SwFormatAnchor & rAnch)
 {
-#if OSL_DEBUG_LEVEL > 0
-    std::vector<SwFrameFormat*> checkFormats;
-    for ( size_t i = 0; i < pTable->size(); ++i )
-    {
-        SwFrameFormat *pFormat = (*pTable)[i];
-        const SwFormatAnchor &rAnch = pFormat->GetAnchor();
-        if ( rAnch.GetContentAnchor() &&
-             (rAnch.GetContentAnchor()->nNode.GetIndex() == nIndex) )
-        {
-            checkFormats.push_back( pFormat );
-        }
-    }
-#else
-    (void)pTable;
-#endif
-    SwNode const& rNode(*doc->GetNodes()[nIndex]);
-    std::vector<SwFrameFormat*> const*const pFlys(rNode.GetAnchoredFlys());
-    for (size_t it = 0; pFlys && it != pFlys->size(); )
-    {
-        SwFrameFormat *const pFormat = (*pFlys)[it];
-        const SwFormatAnchor &rAnch = pFormat->GetAnchor();
-        if ( rAnch.GetContentAnchor() &&
-             (rAnch.GetContentAnchor()->nNode.GetIndex() == nIndex) )
-        {
-#if OSL_DEBUG_LEVEL > 0
-            std::vector<SwFrameFormat*>::iterator checkPos = std::find( checkFormats.begin(), checkFormats.end(), pFormat );
-            assert( checkPos != checkFormats.end());
-            checkFormats.erase( checkPos );
-#endif
             const bool bFlyAtFly = rAnch.GetAnchorId() == RndStdIds::FLY_AT_FLY; // LAYER_IMPL
             //Is a frame or a SdrObject described?
             const bool bSdrObj = RES_DRAWFRMFMT == pFormat->Which();
@@ -1022,9 +993,8 @@ void AppendObjs( const SwFrameFormats *pTable, sal_uLong nIndex,
                 if ( bSdrObj && nullptr == (pSdrObj = pFormat->FindSdrObject()) )
                 {
                     OSL_ENSURE( !bSdrObj, "DrawObject not found." );
-                    ++it;
                     pFormat->GetDoc()->DelFrameFormat( pFormat );
-                    continue;
+                    return;
                 }
                 if ( pSdrObj )
                 {
@@ -1051,7 +1021,6 @@ void AppendObjs( const SwFrameFormats *pTable, sal_uLong nIndex,
 
                         pDrawVirtObj->ActionChanged();
                     }
-
                 }
                 else
                 {
@@ -1067,14 +1036,133 @@ void AppendObjs( const SwFrameFormats *pTable, sal_uLong nIndex,
                         ::RegistFlys( pPage, pFly );
                 }
             }
+}
+
+static bool IsShown(sal_uLong const nIndex,
+    const SwFormatAnchor & rAnch,
+    std::vector<sw::Extent>::const_iterator *const pIter,
+    std::vector<sw::Extent>::const_iterator const*const pEnd)
+{
+    SwPosition const& rAnchor(*rAnch.GetContentAnchor());
+    if (pIter && rAnch.GetAnchorId() != RndStdIds::FLY_AT_PARA)
+    {
+        // TODO are frames sorted by anchor positions perhaps?
+        assert(pEnd);
+        assert(rAnch.GetAnchorId() != RndStdIds::FLY_AT_FLY);
+        for ( ; *pIter != *pEnd; ++*pIter)
+        {
+            assert((**pIter).pNode->GetIndex() == nIndex);
+            if ((**pIter).nStart <= rAnchor.nContent.GetIndex())
+            {
+                // TODO off by one? need < for AS_CHAR but what for AT_CHAR?
+                if (rAnchor.nContent.GetIndex() < (**pIter).nEnd)
+                {
+                    return true;
+                }
+                else
+                {
+                    return false;
+                }
+            }
+        }
+        return false;
+    }
+    else
+    {
+        return rAnch.GetContentAnchor()->nNode.GetIndex() == nIndex;
+    }
+}
+
+void AppendObjsOfNode(SwFrameFormats const*const pTable, sal_uLong const nIndex,
+    SwFrame *const pFrame, SwPageFrame *const pPage, SwDoc *const pDoc,
+    std::vector<sw::Extent>::const_iterator *const pIter,
+    std::vector<sw::Extent>::const_iterator const*const pEnd)
+{
+#if OSL_DEBUG_LEVEL > 0
+    std::vector<SwFrameFormat*> checkFormats;
+    for ( size_t i = 0; i < pTable->size(); ++i )
+    {
+        SwFrameFormat *pFormat = (*pTable)[i];
+        const SwFormatAnchor &rAnch = pFormat->GetAnchor();
+        if ( rAnch.GetContentAnchor() &&
+            IsShown(nIndex, rAnch, pIter, pEnd))
+        {
+            checkFormats.push_back( pFormat );
+        }
+    }
+#else
+    (void)pTable;
+#endif
+
+    SwNode const& rNode(*pDoc->GetNodes()[nIndex]);
+    std::vector<SwFrameFormat*> const*const pFlys(rNode.GetAnchoredFlys());
+    for (size_t it = 0; pFlys && it != pFlys->size(); )
+    {
+        SwFrameFormat *const pFormat = (*pFlys)[it];
+        const SwFormatAnchor &rAnch = pFormat->GetAnchor();
+        if ( rAnch.GetContentAnchor() &&
+            IsShown(nIndex, rAnch, pIter, pEnd))
+        {
+#if OSL_DEBUG_LEVEL > 0
+            std::vector<SwFrameFormat*>::iterator checkPos = std::find( checkFormats.begin(), checkFormats.end(), pFormat );
+            assert( checkPos != checkFormats.end());
+            checkFormats.erase( checkPos );
+#endif
+            AppendObj(pFrame, pPage, pFormat, rAnch);
         }
         ++it;
     }
+
 #if OSL_DEBUG_LEVEL > 0
     assert( checkFormats.empty());
 #endif
 }
 
+
+void AppendObjs(const SwFrameFormats *const pTable, sal_uLong const nIndex,
+        SwFrame *const pFrame, SwPageFrame *const pPage, SwDoc *const pDoc)
+{
+    if (pFrame->IsTextFrame())
+    {
+        SwTextFrame const*const pTextFrame(static_cast<SwTextFrame const*>(pFrame));
+        if (sw::MergedPara const*const pMerged = pTextFrame->GetMergedPara())
+        {
+            std::vector<sw::Extent>::const_iterator iterFirst(pMerged->extents.begin());
+            std::vector<sw::Extent>::const_iterator iter(iterFirst);
+            SwTextNode const* pNode(nullptr);
+            for ( ; iter != pMerged->extents.end(); ++iter)
+            {
+                if (iter->pNode != pNode)
+                {
+                    if (pNode)
+                    {
+                        AppendObjsOfNode(pTable, pNode->GetIndex(), pFrame, pPage, pDoc, &iterFirst, &iter);
+                    }
+                    else
+                    {
+                        assert(nIndex == iter->pNode->GetIndex()); // first iteration
+                    }
+                    pNode = iter->pNode;
+                    iterFirst = iter;
+                }
+            }
+            if (!pNode)
+            {   // no extents?
+                pNode = pMerged->pFirstNode;
+            }
+            AppendObjsOfNode(pTable, pNode->GetIndex(), pFrame, pPage, pDoc, &iterFirst, &iter);
+        }
+        else
+        {
+            return AppendObjsOfNode(pTable, nIndex, pFrame, pPage, pDoc, nullptr, nullptr);
+        }
+    }
+    else
+    {
+        return AppendObjsOfNode(pTable, nIndex, pFrame, pPage, pDoc, nullptr, nullptr);
+    }
+}
+
 void AppendAllObjs(const SwFrameFormats* pTable, const SwFrame* pSib)
 {
     //Connecting of all Objects, which are described in the SpzTable with the
diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx
index 43723ef67518..9817b082b688 100644
--- a/sw/source/core/layout/tabfrm.cxx
+++ b/sw/source/core/layout/tabfrm.cxx
@@ -47,6 +47,7 @@
 #include <cellfrm.hxx>
 #include <flyfrms.hxx>
 #include <txtfrm.hxx>
+#include <notxtfrm.hxx>
 #include <htmltbl.hxx>
 #include <sectfrm.hxx>
 #include <fmtfollowtextflow.hxx>
@@ -1178,7 +1179,11 @@ bool SwTabFrame::Split( const SwTwips nCutPos, bool bTryToSplit, bool bTableRowK
                 SwContentFrame* pFrame = pHeadline->ContainsContent();
                 while( pFrame )
                 {
-                    nIndex = pFrame->GetNode()->GetIndex();
+                    // sw_redlinehide: the implementation of AppendObjs
+                    // takes care of iterating merged SwTextFrame
+                    nIndex = pFrame->IsTextFrame()
+                        ? static_cast<SwTextFrame*>(pFrame)->GetTextNodeFirst()->GetIndex()
+                        : static_cast<SwNoTextFrame*>(pFrame)->GetNode()->GetIndex();
                     AppendObjs( pTable, nIndex, pFrame, pPage, GetFormat()->GetDoc());
                     pFrame = pFrame->GetNextContentFrame();
                     if( !pHeadline->IsAnLower( pFrame ) )
commit 3ec289318b1151c87fb3a9cdbffe6d9dd975a881
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Fri Jun 1 22:03:42 2018 +0200

    sw_redlinehide: trivial convert to GetPageDescItem()/GetBreakItem()
    
    Change-Id: Ia652ff428c232b9307e41da8f6b9648f486f7179

diff --git a/sw/source/core/frmedt/fedesc.cxx b/sw/source/core/frmedt/fedesc.cxx
index 588dd8e1dd6b..2177047e19aa 100644
--- a/sw/source/core/frmedt/fedesc.cxx
+++ b/sw/source/core/frmedt/fedesc.cxx
@@ -68,7 +68,7 @@ void SwFEShell::ChgCurPageDesc( const SwPageDesc& rDesc )
         {
             if ( pFlow->IsInTab() )
                 pFlow = pFlow->FindTabFrame();
-            const SwFormatPageDesc& rPgDesc = pFlow->GetAttrSet()->GetPageDesc();
+            const SwFormatPageDesc& rPgDesc = pFlow->GetPageDescItem();
             if( rPgDesc.GetPageDesc() )
             {
                 // we found the culprit
diff --git a/sw/source/core/frmedt/fews.cxx b/sw/source/core/frmedt/fews.cxx
index 4d5743a2a957..9035c0e85f7c 100644
--- a/sw/source/core/frmedt/fews.cxx
+++ b/sw/source/core/frmedt/fews.cxx
@@ -369,7 +369,7 @@ void SwFEShell::SetPageOffset( sal_uInt16 nOffset )
         {
             if ( pFlow->IsInTab() )
                 pFlow = pFlow->FindTabFrame();
-            const SwFormatPageDesc& rPgDesc = pFlow->GetAttrSet()->GetPageDesc();
+            const SwFormatPageDesc& rPgDesc = pFlow->GetPageDescItem();
             if ( rPgDesc.GetNumOffset() )
             {
                 pDocLayout->SetVirtPageNum( true );
@@ -391,7 +391,7 @@ sal_uInt16 SwFEShell::GetPageOffset() const
         {
             if ( pFlow->IsInTab() )
                 pFlow = pFlow->FindTabFrame();
-            ::boost::optional<sal_uInt16> oNumOffset = pFlow->GetAttrSet()->GetPageDesc().GetNumOffset();
+            ::boost::optional<sal_uInt16> oNumOffset = pFlow->GetPageDescItem().GetNumOffset();
             if ( oNumOffset )
                 return oNumOffset.get();
         }
diff --git a/sw/source/core/layout/flowfrm.cxx b/sw/source/core/layout/flowfrm.cxx
index d7c651a7c597..1dce5a5131ff 100644
--- a/sw/source/core/layout/flowfrm.cxx
+++ b/sw/source/core/layout/flowfrm.cxx
@@ -841,7 +841,7 @@ bool SwFrame::WrongPageDesc( SwPageFrame* pNew )
     SwFlowFrame *pFlow = SwFlowFrame::CastFlowFrame( this );
     if ( !pFlow || !pFlow->IsFollow() )
     {
-        const SwFormatPageDesc &rFormatDesc = GetAttrSet()->GetPageDesc();
+        const SwFormatPageDesc &rFormatDesc = GetPageDescItem();
         pDesc = rFormatDesc.GetPageDesc();
         if( pDesc )
         {
@@ -870,7 +870,8 @@ bool SwFrame::WrongPageDesc( SwPageFrame* pNew )
     if ( pNewFlow && pNewFlow->GetFrame().IsInTab() )
         pNewFlow = pNewFlow->GetFrame().FindTabFrame();
     const SwPageDesc *pNewDesc= ( pNewFlow && !pNewFlow->IsFollow() )
-            ? pNewFlow->GetFrame().GetAttrSet()->GetPageDesc().GetPageDesc() : nullptr;
+            ? pNewFlow->GetFrame().GetPageDescItem().GetPageDesc()
+            : nullptr;
 
     SAL_INFO( "sw.pageframe", "WrongPageDesc p: " << pNew << " phys: " << pNew->GetPhyPageNum() );
     SAL_INFO( "sw.pageframe", "WrongPageDesc " << pNew->GetPageDesc() << " " << pDesc );
@@ -1130,7 +1131,6 @@ bool SwFlowFrame::IsPageBreak( bool bAct ) const
         const SwViewShell *pSh = m_rThis.getRootFrame()->GetCurrShell();
         if( pSh && pSh->GetViewOptions()->getBrowseMode() )
             return false;
-        const SwAttrSet *pSet = m_rThis.GetAttrSet();
 
         // Determine predecessor
         const SwFrame *pPrev = m_rThis.FindPrev();
@@ -1153,18 +1153,20 @@ bool SwFlowFrame::IsPageBreak( bool bAct ) const
             //for compatibility, also break at column break if no columns exist
             const IDocumentSettingAccess& rIDSA = m_rThis.GetUpper()->GetFormat()->getIDocumentSettingAccess();
             const bool bTreatSingleColumnBreakAsPageBreak = rIDSA.get(DocumentSettingId::TREAT_SINGLE_COLUMN_BREAK_AS_PAGE_BREAK);
-            const SvxBreak eBreak = pSet->GetBreak().GetBreak();
+            const SvxBreak eBreak = m_rThis.GetBreakItem().GetBreak();
             if ( eBreak == SvxBreak::PageBefore ||
                  eBreak == SvxBreak::PageBoth ||
                  ( bTreatSingleColumnBreakAsPageBreak && eBreak == SvxBreak::ColumnBefore && !m_rThis.FindColFrame() ))
                 return true;
             else
             {
-                const SvxBreak &ePrB = pPrev->GetAttrSet()->GetBreak().GetBreak();
+                const SvxBreak &ePrB = pPrev->GetBreakItem().GetBreak();
                 if ( ePrB == SvxBreak::PageAfter ||
                      ePrB == SvxBreak::PageBoth  ||
-                     pSet->GetPageDesc().GetPageDesc() )
+                    m_rThis.GetPageDescItem().GetPageDesc())
+                {
                     return true;
+                }
             }
         }
     }
@@ -1208,13 +1210,13 @@ bool SwFlowFrame::IsColBreak( bool bAct ) const
                         return false;
                 }
 
-                const SvxBreak eBreak = m_rThis.GetAttrSet()->GetBreak().GetBreak();
+                const SvxBreak eBreak = m_rThis.GetBreakItem().GetBreak();
                 if ( eBreak == SvxBreak::ColumnBefore ||
                      eBreak == SvxBreak::ColumnBoth )
                     return true;
                 else
                 {
-                    const SvxBreak &ePrB = pPrev->GetAttrSet()->GetBreak().GetBreak();
+                    const SvxBreak &ePrB = pPrev->GetBreakItem().GetBreak();
                     if ( ePrB == SvxBreak::ColumnAfter ||
                          ePrB == SvxBreak::ColumnBoth )
                         return true;
@@ -1998,7 +2000,7 @@ bool SwFlowFrame::MoveFwd( bool bMakePage, bool bPageBreak, bool bMoveAlways )
             // #i106452#
             // check page description not only in situation with sections.
             if ( !bSamePage &&
-                 ( m_rThis.GetAttrSet()->GetPageDesc().GetPageDesc() ||
+                 ( m_rThis.GetPageDescItem().GetPageDesc() ||
                    pOldPage->GetPageDesc()->GetFollow() != pNewPage->GetPageDesc() ) )
             {
                 SwFrame::CheckPageDescs( pNewPage, false );
@@ -2545,7 +2547,7 @@ bool SwFlowFrame::MoveBwd( bool &rbReformat )
                                             static_cast<SwPageFrame*>(pNewPage->GetNext());
                     SwFrame::CheckPageDescs( pStartPage, false);
                 }
-                else if ( m_rThis.GetAttrSet()->GetPageDesc().GetPageDesc() )
+                else if (m_rThis.GetPageDescItem().GetPageDesc())
                 {
                     // First page could get empty for example by disabling
                     // a section
diff --git a/sw/source/core/layout/laycache.cxx b/sw/source/core/layout/laycache.cxx
index 992dcfd52789..73c38c19f4eb 100644
--- a/sw/source/core/layout/laycache.cxx
+++ b/sw/source/core/layout/laycache.cxx
@@ -630,9 +630,8 @@ sal_uLong SwLayHelper::CalcPageCount()
 bool SwLayHelper::CheckInsertPage()
 {
     bool bEnd = nullptr == mrpPage->GetNext();
-    const SwAttrSet* pAttr = mrpFrame->GetAttrSet();
-    const SvxFormatBreakItem& rBrk = pAttr->GetBreak();
-    const SwFormatPageDesc& rDesc = pAttr->GetPageDesc();
+    const SvxFormatBreakItem& rBrk = mrpFrame->GetBreakItem();
+    const SwFormatPageDesc& rDesc = mrpFrame->GetPageDescItem();
     // #118195# Do not evaluate page description if frame
     // is a follow frame!
     const SwPageDesc* pDesc = mrpFrame->IsFlowFrame() &&
diff --git a/sw/source/core/layout/pagechg.cxx b/sw/source/core/layout/pagechg.cxx
index 11095f1dec62..036e3371e97c 100644
--- a/sw/source/core/layout/pagechg.cxx
+++ b/sw/source/core/layout/pagechg.cxx
@@ -770,7 +770,7 @@ SwPageDesc *SwPageFrame::FindPageDesc()
             SwFrame *pFlow = pFrame;
             if ( pFlow->IsInTab() )
                 pFlow = pFlow->FindTabFrame();
-            pRet = const_cast<SwPageDesc*>(pFlow->GetAttrSet()->GetPageDesc().GetPageDesc());
+            pRet = const_cast<SwPageDesc*>(pFlow->GetPageDescItem().GetPageDesc());
         }
         if ( !pRet )
             pRet = &GetFormat()->GetDoc()->GetPageDesc( 0 );
@@ -786,7 +786,7 @@ SwPageDesc *SwPageFrame::FindPageDesc()
     {
         SwFlowFrame *pTmp = SwFlowFrame::CastFlowFrame( pFlow );
         if ( !pTmp->IsFollow() )
-            pRet = const_cast<SwPageDesc*>(pFlow->GetAttrSet()->GetPageDesc().GetPageDesc());
+            pRet = const_cast<SwPageDesc*>(pFlow->GetPageDescItem().GetPageDesc());
     }
 
     //3. and 3.1
@@ -1288,7 +1288,8 @@ SwPageFrame *SwFrame::InsertPage( SwPageFrame *pPrevPage, bool bFootnote )
     // For ContentFrame take the one from format if provided,
     // otherwise from the Follow of the PrevPage
     if ( IsFlowFrame() && !SwFlowFrame::CastFlowFrame( this )->IsFollow() )
-    {   SwFormatPageDesc &rDesc = const_cast<SwFormatPageDesc&>(GetAttrSet()->GetPageDesc());
+    {
+        SwFormatPageDesc &rDesc = const_cast<SwFormatPageDesc&>(GetPageDescItem());
         pDesc = rDesc.GetPageDesc();
         if ( rDesc.GetNumOffset() )
         {
diff --git a/sw/source/core/layout/trvlfrm.cxx b/sw/source/core/layout/trvlfrm.cxx
index 240d57078038..39843fd25efb 100644
--- a/sw/source/core/layout/trvlfrm.cxx
+++ b/sw/source/core/layout/trvlfrm.cxx
@@ -1726,7 +1726,7 @@ bool SwFrame::WannaRightPage() const
         const SwFlowFrame *pTmp = SwFlowFrame::CastFlowFrame( pFlow );
         if ( !pTmp->IsFollow() )
         {
-            const SwFormatPageDesc& rPgDesc = pFlow->GetAttrSet()->GetPageDesc();
+            const SwFormatPageDesc& rPgDesc = pFlow->GetPageDescItem();
             pDesc = rPgDesc.GetPageDesc();
             oPgNum = rPgDesc.GetNumOffset();
         }
@@ -1852,7 +1852,7 @@ sal_uInt16 SwFrame::GetVirtPageNum() const
     }
     if ( pFrame )
     {
-        ::boost::optional<sal_uInt16> oNumOffset = pFrame->GetAttrSet()->GetPageDesc().GetNumOffset();
+        ::boost::optional<sal_uInt16> oNumOffset = pFrame->GetPageDescItem().GetNumOffset();
         if (oNumOffset)
         {
             return nPhyPage - pFrame->GetPhyPageNum() + oNumOffset.get();
diff --git a/sw/source/core/layout/wsfrm.cxx b/sw/source/core/layout/wsfrm.cxx
index bb04d4ed74db..a25bb8d7bb9f 100644
--- a/sw/source/core/layout/wsfrm.cxx
+++ b/sw/source/core/layout/wsfrm.cxx
@@ -2382,7 +2382,7 @@ void SwContentFrame::UpdateAttr_( const SfxPoolItem* pOld, const SfxPoolItem* pN
                 SwPageFrame *pPage = FindPageFrame();
                 if ( !GetPrev() )
                     CheckPageDescs( pPage );
-                if ( GetAttrSet()->GetPageDesc().GetNumOffset() )
+                if (GetPageDescItem().GetNumOffset())
                     static_cast<SwRootFrame*>(pPage->GetUpper())->SetVirtPageNum( true );
                 SwDocPosUpdate aMsgHint( pPage->getFrameArea().Top() );
                 pPage->GetFormat()->GetDoc()->getIDocumentFieldsAccess().UpdatePageFields( &aMsgHint );
commit db13fa395741cf0fdaa083f460d5291c088ef095
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Fri Jun 1 21:53:39 2018 +0200

    sw_redlinehide: refactor SwFlowFrame::IsKeep()
    
    This thing uses 2 items, a normal one and RES_BREAK, so they need to be
    passed in separately, a merged text frame does not necessarily have any
    item set with the matching items.
    
    Change-Id: I5e50ac60137ba8d94adeaee2ef015551d8a3bdd8

diff --git a/sw/source/core/inc/flowfrm.hxx b/sw/source/core/inc/flowfrm.hxx
index 818f0fb4f597..6f08a70bd39f 100644
--- a/sw/source/core/inc/flowfrm.hxx
+++ b/sw/source/core/inc/flowfrm.hxx
@@ -22,6 +22,8 @@
 
 #include "frmtool.hxx"
 
+class SvxFormatKeepItem;
+class SvxFormatBreakItem;
 class SwPageFrame;
 class SwRect;
 class SwBorderAttrs;
@@ -177,7 +179,9 @@ public:
     bool IsColBreak( bool bAct ) const;
 
     /** method to determine if a Keep needs to be considered (Breaks!) */
-    bool IsKeep( const SwAttrSet& rAttrs, bool bBreakCheck = false ) const;
+    bool IsKeep(SvxFormatKeepItem const& rKeep,
+                SvxFormatBreakItem const& rBreak,
+                bool bBreakCheck = false ) const;
 
     bool HasLockedFollow() const;
 
diff --git a/sw/source/core/layout/calcmove.cxx b/sw/source/core/layout/calcmove.cxx
index c00b5efe1758..2b56272bf49c 100644
--- a/sw/source/core/layout/calcmove.cxx
+++ b/sw/source/core/layout/calcmove.cxx
@@ -1214,7 +1214,7 @@ void SwContentFrame::MakeAll(vcl::RenderContext* /*pRenderContext*/)
         pNotify->SetBordersJoinedWithPrev();
     }
 
-    const bool bKeep = IsKeep( rAttrs.GetAttrSet() );
+    const bool bKeep = IsKeep(rAttrs.GetAttrSet().GetKeep(), GetBreakItem());
 
     SwSaveFootnoteHeight *pSaveFootnote = nullptr;
     if ( bFootnote )
@@ -2092,7 +2092,7 @@ bool SwContentFrame::WouldFit_( SwTwips nSpace,
             }
         }
 
-        if ( bRet && !bSplit && pFrame->IsKeep( rAttrs.GetAttrSet() ) )
+        if (bRet && !bSplit && pFrame->IsKeep(rAttrs.GetAttrSet().GetKeep(), GetBreakItem()))
         {
             if( bTstMove )
             {
diff --git a/sw/source/core/layout/flowfrm.cxx b/sw/source/core/layout/flowfrm.cxx
index 952708ae0342..d7c651a7c597 100644
--- a/sw/source/core/layout/flowfrm.cxx
+++ b/sw/source/core/layout/flowfrm.cxx
@@ -41,6 +41,7 @@
 #include <paratr.hxx>
 #include <ftnfrm.hxx>
 #include <txtfrm.hxx>
+#include <notxtfrm.hxx>
 #include <tabfrm.hxx>
 #include <pagedesc.hxx>
 #include <layact.hxx>
@@ -169,7 +170,9 @@ void SwFlowFrame::CheckKeep()
         pPre->InvalidatePos();
 }
 
-bool SwFlowFrame::IsKeep( const SwAttrSet& rAttrs, bool bCheckIfLastRowShouldKeep ) const
+bool SwFlowFrame::IsKeep(SvxFormatKeepItem const& rKeep,
+        SvxFormatBreakItem const& rBreak,
+        bool const bCheckIfLastRowShouldKeep) const
 {
     // 1. The keep attribute is ignored inside footnotes
     // 2. For compatibility reasons, the keep attribute is
@@ -180,7 +183,7 @@ bool SwFlowFrame::IsKeep( const SwAttrSet& rAttrs, bool bCheckIfLastRowShouldKee
     bool bKeep = bCheckIfLastRowShouldKeep ||
                  (  !m_rThis.IsInFootnote() &&
                     ( !m_rThis.IsInTab() || m_rThis.IsTabFrame() ) &&
-                    rAttrs.GetKeep().GetValue() );
+                    rKeep.GetValue() );
 
     OSL_ENSURE( !bCheckIfLastRowShouldKeep || m_rThis.IsTabFrame(),
             "IsKeep with bCheckIfLastRowShouldKeep should only be used for tabfrms" );
@@ -188,7 +191,7 @@ bool SwFlowFrame::IsKeep( const SwAttrSet& rAttrs, bool bCheckIfLastRowShouldKee
     // Ignore keep attribute if there are break situations:
     if ( bKeep )
     {
-        switch ( rAttrs.GetBreak().GetBreak() )
+        switch (rBreak.GetBreak())
         {
             case SvxBreak::ColumnAfter:
             case SvxBreak::ColumnBoth:
@@ -227,23 +230,24 @@ bool SwFlowFrame::IsKeep( const SwAttrSet& rAttrs, bool bCheckIfLastRowShouldKee
 
                 if ( bKeep )
                 {
-                    const SwAttrSet* pSet = nullptr;
-
+                    SvxFormatBreakItem const* pBreak;
+                    SwFormatPageDesc const* pPageDesc;
                     SwTabFrame* pTab = pNxt->IsInTab() ? pNxt->FindTabFrame() : nullptr;
-                    if (pTab)
+                    if (pTab && (!m_rThis.IsInTab() || m_rThis.FindTabFrame() != pTab))
                     {
-                        if ( ! m_rThis.IsInTab() || m_rThis.FindTabFrame() != pTab )
-                            pSet = &pTab->GetFormat()->GetAttrSet();
+                        const SwAttrSet *const pSet = &pTab->GetFormat()->GetAttrSet();
+                        pBreak = &pSet->GetBreak();
+                        pPageDesc = &pSet->GetPageDesc();
+                    }
+                    else
+                    {
+                        pBreak = &pNxt->GetBreakItem();
+                        pPageDesc = &pNxt->GetPageDescItem();
                     }
 
-                    if ( ! pSet )
-                        pSet = pNxt->GetAttrSet();
-
-                    assert(pSet && "No AttrSet to check keep attribute");
-
-                    if ( pSet->GetPageDesc().GetPageDesc() )
+                    if (pPageDesc->GetPageDesc())
                         bKeep = false;
-                    else switch ( pSet->GetBreak().GetBreak() )
+                    else switch (pBreak->GetBreak())
                     {
                         case SvxBreak::ColumnBefore:
                         case SvxBreak::ColumnBoth:
diff --git a/sw/source/core/layout/fly.cxx b/sw/source/core/layout/fly.cxx
index faba4d0e1aa4..74a2f6201e4b 100644
--- a/sw/source/core/layout/fly.cxx
+++ b/sw/source/core/layout/fly.cxx
@@ -1457,7 +1457,7 @@ void CalcContent( SwLayoutFrame *pLay, bool bNoColl )
                                !pTmpFlowFrame->IsJoinLocked() &&
                                !pTmpPrev->isFrameAreaPositionValid() &&
                                 pLay->IsAnLower( pTmpPrev ) &&
-                                pTmpPrevFlowFrame->IsKeep( *pTmpPrev->GetAttrSet() ) &&
+                                pTmpPrevFlowFrame->IsKeep(pTmpPrev->GetAttrSet()->GetKeep(), pTmpPrev->GetBreakItem()) &&
                                 pTmpPrevFlowFrame->IsKeepFwdMoveAllowed();
 
             // format floating screen objects anchored to the frame.
diff --git a/sw/source/core/layout/frmtool.cxx b/sw/source/core/layout/frmtool.cxx
index 6552f45a6e0a..bfdb15bc1a86 100644
--- a/sw/source/core/layout/frmtool.cxx
+++ b/sw/source/core/layout/frmtool.cxx
@@ -125,7 +125,8 @@ SwFrameNotify::~SwFrameNotify() COVERITY_NOEXCEPT_FALSE
                     if ( pPre && pPre->IsFlowFrame() )
                     {
                         // 1. pPre wants to keep with me:
-                        bool bInvalidPrePos = SwFlowFrame::CastFlowFrame( pPre )->IsKeep( *pPre->GetAttrSet() ) && pPre->GetIndPrev();
+                        bool bInvalidPrePos = SwFlowFrame::CastFlowFrame(pPre)->IsKeep(pPre->GetAttrSet()->GetKeep(), pPre->GetBreakItem())
+                            && pPre->GetIndPrev();
 
                         // 2. pPre is a table and the last row wants to keep with me:
                         if ( !bInvalidPrePos && pPre->IsTabFrame() )
diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx
index 501d756f714f..43723ef67518 100644
--- a/sw/source/core/layout/tabfrm.cxx
+++ b/sw/source/core/layout/tabfrm.cxx
@@ -1859,7 +1859,7 @@ void SwTabFrame::MakeAll(vcl::RenderContext* pRenderContext)
 
     // The beloved keep attribute
     const bool bEmulateTableKeep = AreAllRowsKeepWithNext( GetFirstNonHeadlineRow() );
-    const bool bKeep = IsKeep( pAttrs->GetAttrSet(), bEmulateTableKeep );
+    const bool bKeep = IsKeep(pAttrs->GetAttrSet().GetKeep(), GetBreakItem(), bEmulateTableKeep);
 
     // All rows should keep together
     const bool bDontSplit = !IsFollow() &&
@@ -2225,9 +2225,12 @@ void SwTabFrame::MakeAll(vcl::RenderContext* pRenderContext)
                     // 6. There is no section change behind the table (see IsKeep)
                     // 7. The last table row wants to keep with its next.
                     const SwRowFrame* pLastRow = static_cast<const SwRowFrame*>(GetLastLower());
-                    if ( pLastRow && IsKeep( pAttrs->GetAttrSet(), true ) &&
-                         pLastRow->ShouldRowKeepWithNext() )
+                    if (pLastRow
+                        && IsKeep(pAttrs->GetAttrSet().GetKeep(), GetBreakItem(), true)
+                        && pLastRow->ShouldRowKeepWithNext())
+                    {
                         bFormat = true;
+                    }
                 }
 
                 if ( bFormat )
commit b9d20243b80e55de61ca0322fabb82ab42ca516c
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Fri Jun 1 21:45:07 2018 +0200

    sw_redlinehide: add SwFrame::GetBreakItem()/GetPageDescItem()
    
    SwFrame::GetAttrSet() can work for merged text frame for most
    paragraph/frame items, but not for these two, which are special cased
    in the node joining code so they're always from the first node.
    
    Change-Id: Ib63203a67e15e208aa50bc46ae0f5a82d1b9081c

diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx
index eea4f733bc30..4f6375d664a9 100644
--- a/sw/source/core/inc/frame.hxx
+++ b/sw/source/core/inc/frame.hxx
@@ -51,6 +51,8 @@ class Color;
 class SwBorderAttrs;
 class SwCache;
 class SvxBrushItem;
+class SvxFormatBreakItem;
+class SwFormatPageDesc;
 class SwSelectionList;
 struct SwPosition;
 struct SwCursorMoveState;
@@ -631,7 +633,11 @@ public:
 
     void ReinitializeFrameSizeAttrFlags();
 
+    /// WARNING: this may not return correct RES_PAGEDESC/RES_BREAK items for
+    /// SwTextFrame, use GetBreakItem()/GetPageDescItem() instead
     const SwAttrSet *GetAttrSet() const;
+    virtual const SvxFormatBreakItem& GetBreakItem() const;
+    virtual const SwFormatPageDesc& GetPageDescItem() const;
 
     bool HasFixSize() const { return mbFixSize; }
 
diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx
index 6829f7007d9b..9c0f787060f7 100644
--- a/sw/source/core/inc/txtfrm.hxx
+++ b/sw/source/core/inc/txtfrm.hxx
@@ -269,6 +269,9 @@ protected:
 
 public:
 
+    virtual const SvxFormatBreakItem& GetBreakItem() const override;
+    virtual const SwFormatPageDesc& GetPageDescItem() const override;
+
     css::uno::Sequence< css::style::TabStop >  GetTabStopInfo( SwTwips CurrentPos ) override;
 
     /**
diff --git a/sw/source/core/layout/findfrm.cxx b/sw/source/core/layout/findfrm.cxx
index baca3edfa189..b720d9936a45 100644
--- a/sw/source/core/layout/findfrm.cxx
+++ b/sw/source/core/layout/findfrm.cxx
@@ -22,13 +22,14 @@
 #include <cellfrm.hxx>
 #include <rowfrm.hxx>
 #include <swtable.hxx>
-
+#include <notxtfrm.hxx>
 #include <tabfrm.hxx>
 #include <sectfrm.hxx>
 #include <flyfrms.hxx>
 #include <ftnfrm.hxx>
 #include <txtftn.hxx>
 #include <fmtftn.hxx>
+#include <fmtpdsc.hxx>
 #include <txtfrm.hxx>
 #include <calbck.hxx>
 #include <viewopt.hxx>
@@ -621,19 +622,52 @@ bool SwRootFrame::IsBetweenPages(const Point& rPt) const
     return false;
 }
 
+const SvxFormatBreakItem& SwFrame::GetBreakItem() const
+{
+    return GetAttrSet()->GetBreak();
+}
+
+const SwFormatPageDesc& SwFrame::GetPageDescItem() const
+{
+    return GetAttrSet()->GetPageDesc();
+}
+
+const SvxFormatBreakItem& SwTextFrame::GetBreakItem() const
+{
+    return GetTextNodeFirst()->GetSwAttrSet().GetBreak();
+}
+
+const SwFormatPageDesc& SwTextFrame::GetPageDescItem() const
+{
+    return GetTextNodeFirst()->GetSwAttrSet().GetPageDesc();
+}
+
 const SwAttrSet* SwFrame::GetAttrSet() const
 {
-    if ( IsContentFrame() )
-        return &static_cast<const SwContentFrame*>(this)->GetNode()->GetSwAttrSet();
+    if (IsTextFrame())
+    {
+        return &static_cast<const SwTextFrame*>(this)->GetTextNodeForParaProps()->GetSwAttrSet();
+    }
+    else if (IsNoTextFrame())
+    {
+        return &static_cast<const SwNoTextFrame*>(this)->GetNode()->GetSwAttrSet();
+    }
     else
+    {
+        assert(IsLayoutFrame());
         return &static_cast<const SwLayoutFrame*>(this)->GetFormat()->GetAttrSet();
+    }
 }
 
 drawinglayer::attribute::SdrAllFillAttributesHelperPtr SwFrame::getSdrAllFillAttributesHelper() const
 {
-    if(IsContentFrame())
+    if (IsTextFrame())
+    {
+        return static_cast<const SwTextFrame*>(this)->GetTextNodeForParaProps()->getSdrAllFillAttributesHelper();
+    }
+    else if (IsNoTextFrame())
     {
-        return static_cast< const SwContentFrame* >(this)->GetNode()->getSdrAllFillAttributesHelper();
+        return static_cast<const SwNoTextFrame*>(this)->GetNode()->getSdrAllFillAttributesHelper();
     }
     else
     {
commit 419a5ac9925ecd45a6feef49f0db10d72ae2461e
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Fri Jun 1 21:39:15 2018 +0200

    sw_redlinehide: add sw::FrameContainsNode()
    
    Change-Id: I13fde1bc95211ecbf5ff2a3f54cd85f41b5418d7

diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx
index fb433ecf8b04..6829f7007d9b 100644
--- a/sw/source/core/inc/txtfrm.hxx
+++ b/sw/source/core/inc/txtfrm.hxx
@@ -95,6 +95,8 @@ TextFrameIndex MapModelToView(MergedPara const&, SwTextNode const* pNode, sal_In
 
 std::unique_ptr<sw::MergedPara> CheckParaRedlineMerge(SwTextFrame & rFrame, SwTextNode & rTextNode);
 
+bool FrameContainsNode(SwContentFrame const& rFrame, sal_uLong nNodeIndex);
+
 } // namespace sw
 
 /// Represents the visualization of a paragraph. Typical upper is an
diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx
index e4d63da05fb7..4ca51820e0e8 100644
--- a/sw/source/core/text/txtfrm.cxx
+++ b/sw/source/core/text/txtfrm.cxx
@@ -59,6 +59,7 @@
 #include <ftninfo.hxx>
 #include <fmtline.hxx>
 #include <txtfrm.hxx>
+#include <notxtfrm.hxx>
 #include <sectfrm.hxx>
 #include "itrform2.hxx"
 #include "widorp.hxx"
@@ -282,6 +283,34 @@ namespace sw {
         }
     }
 
+    bool FrameContainsNode(SwContentFrame const& rFrame, sal_uLong const nNodeIndex)
+    {
+        if (rFrame.IsTextFrame())
+        {
+            SwTextFrame const& rTextFrame(static_cast<SwTextFrame const&>(rFrame));
+            if (sw::MergedPara const*const pMerged = rTextFrame.GetMergedPara())
+            {
+                sal_uLong const nFirst(pMerged->pFirstNode->GetIndex());
+                sal_uLong nLast(nFirst);
+                // FIXME is this actually the last one? what about delete RL that dels last node until end, what happens to its anchored objs?
+                if (!pMerged->extents.empty())
+                {
+                    nLast = pMerged->extents.back().pNode->GetIndex();
+                }
+                return (nFirst <= nNodeIndex && nNodeIndex <= nLast);
+            }
+            else
+            {
+                return rTextFrame.GetTextNodeFirst()->GetIndex() == nNodeIndex;
+            }
+        }
+        else
+        {
+            assert(rFrame.IsNoTextFrame());
+            return static_cast<SwNoTextFrame const&>(rFrame).GetNode()->GetIndex() == nNodeIndex;
+        }
+    }
+
 } // namespace sw
 
 /// Switches width and height of the text frame
@@ -1083,7 +1112,7 @@ bool sw_HideObj( const SwTextFrame& _rFrame,
              _rFrame.IsInDocBody() && !_rFrame.FindNextCnt() )
         {
             SwTextNode const& rNode(*rAnchorPos.nNode.GetNode().GetTextNode());
-//            assert(_rFrame.GetMergedPara() || &rNode == _rFrame.GetDep()); // simple consistency check
+            assert(FrameContainsNode(_rFrame, rNode.GetIndex()));
             sal_Int32 const nObjAnchorPos(rAnchorPos.nContent.GetIndex());
             const sal_Unicode cAnchorChar = nObjAnchorPos < rNode.Len()
                 ? rNode.GetText()[nObjAnchorPos]
commit 1f9bcef3618b6bbea3f5fc492ced7e4cb0982df9
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Fri Jun 1 21:32:22 2018 +0200

    sw_redlinehide: SwContentFrame::LeftMargin()/RightMargin() pure virtual
    
    ... because it's using GetNode().
    
    Change-Id: Iba99a2c4213d389e8b281b689f7bcfc6027baf28

diff --git a/sw/source/core/inc/cntfrm.hxx b/sw/source/core/inc/cntfrm.hxx
index cf3eae039e84..62413e38de8c 100644
--- a/sw/source/core/inc/cntfrm.hxx
+++ b/sw/source/core/inc/cntfrm.hxx
@@ -79,8 +79,8 @@ public:
     SwTextFrame* FindMaster() const;
 
     // layout dependent cursor travelling
-    virtual bool LeftMargin( SwPaM * ) const;
-    virtual bool RightMargin( SwPaM *, bool bAPI = false ) const;
+    virtual bool LeftMargin(SwPaM *) const = 0;
+    virtual bool RightMargin(SwPaM *, bool bAPI = false) const = 0;
     virtual bool UnitUp( SwPaM *, const SwTwips nOffset,
                          bool bSetInReadOnly ) const;
     virtual bool UnitDown( SwPaM *, const SwTwips nOffset,
diff --git a/sw/source/core/inc/notxtfrm.hxx b/sw/source/core/inc/notxtfrm.hxx
index 8685aa948895..9de5fd31abfe 100644
--- a/sw/source/core/inc/notxtfrm.hxx
+++ b/sw/source/core/inc/notxtfrm.hxx
@@ -54,6 +54,9 @@ protected:
 public:
     SwNoTextFrame( SwNoTextNode * const, SwFrame* );
 
+    virtual bool LeftMargin(SwPaM *) const override;
+    virtual bool RightMargin(SwPaM *, bool bAPI = false) const override;
+
     virtual void PaintSwFrame( vcl::RenderContext& rRenderContext, SwRect const&,
                         SwPrintData const*const pPrintData = nullptr ) const override;
     virtual bool GetCharRect( SwRect &, const SwPosition&,
diff --git a/sw/source/core/layout/trvlfrm.cxx b/sw/source/core/layout/trvlfrm.cxx
index 48689d421a93..240d57078038 100644
--- a/sw/source/core/layout/trvlfrm.cxx
+++ b/sw/source/core/layout/trvlfrm.cxx
@@ -615,7 +615,7 @@ bool SwFlyFrame::GetCursorOfst( SwPosition *pPos, Point &rPoint,
 }
 
 /** Layout dependent cursor travelling */
-bool SwContentFrame::LeftMargin(SwPaM *pPam) const
+bool SwNoTextFrame::LeftMargin(SwPaM *pPam) const
 {
     if( &pPam->GetNode() != GetNode() )
         return false;
@@ -624,7 +624,7 @@ bool SwContentFrame::LeftMargin(SwPaM *pPam) const
     return true;
 }
 
-bool SwContentFrame::RightMargin(SwPaM *pPam, bool) const
+bool SwNoTextFrame::RightMargin(SwPaM *pPam, bool) const
 {
     if( &pPam->GetNode() != GetNode() )
         return false;
diff --git a/sw/source/core/text/frmcrsr.cxx b/sw/source/core/text/frmcrsr.cxx
index c57764acb569..64b4721f3bab 100644
--- a/sw/source/core/text/frmcrsr.cxx
+++ b/sw/source/core/text/frmcrsr.cxx
@@ -670,7 +670,7 @@ bool SwTextFrame::GetCursorOfst(SwPosition* pPos, Point& rPoint,
 
 bool SwTextFrame::LeftMargin(SwPaM *pPam) const
 {
-    assert(&pPam->GetNode() == GetNode() || GetMergedPara());
+    assert(GetMergedPara() || &pPam->GetNode() == static_cast<SwContentNode const*>(GetDep()));
 
     SwTextFrame *pFrame = GetAdjFrameAtPos( const_cast<SwTextFrame*>(this), *pPam->GetPoint(),
                                      SwTextCursor::IsRightMargin() );
@@ -704,7 +704,7 @@ bool SwTextFrame::LeftMargin(SwPaM *pPam) const
 
 bool SwTextFrame::RightMargin(SwPaM *pPam, bool bAPI) const
 {
-    assert(&pPam->GetNode() == GetNode() || GetMergedPara());
+    assert(GetMergedPara() || &pPam->GetNode() == static_cast<SwContentNode const*>(GetDep()));
 
     SwTextFrame *pFrame = GetAdjFrameAtPos( const_cast<SwTextFrame*>(this), *pPam->GetPoint(),
                                      SwTextCursor::IsRightMargin() );
commit 59ec75b58b18609268fcc63239116b17c33b28bb
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Fri Jun 1 21:24:11 2018 +0200

    sw_redlinehide: make GetRegisteredIn() private in SwFrame
    
    Use GetDep() instead, which is a unique identifier in sw.
    
    Change-Id: I66e60a175165673c2962124fdec691b03a5f0e4a

diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx
index 482f60c8dca0..eea4f733bc30 100644
--- a/sw/source/core/inc/frame.hxx
+++ b/sw/source/core/inc/frame.hxx
@@ -313,6 +313,10 @@ class SW_DLLPUBLIC SwFrame : public SwFrameAreaDefinition, public SwClient, publ
     SwFrame       *mpNext;
     SwFrame       *mpPrev;
 
+    // sw_redlinehide: hide these dangerous SwClient functions
+    using SwClient::GetRegisteredInNonConst;
+    using SwClient::GetRegisteredIn;
+
     SwFrame *FindNext_();
     SwFrame *FindPrev_();
 
@@ -441,6 +445,8 @@ protected:
     virtual SwTwips ShrinkFrame( SwTwips, bool bTst = false, bool bInfo = false ) = 0;
     virtual SwTwips GrowFrame  ( SwTwips, bool bTst = false, bool bInfo = false ) = 0;
 
+    /// use these so we can grep for SwFrame's GetRegisteredIn accesses
+    /// beware that SwTextFrame may return sw::WriterMultiListener
     SwModify        *GetDep()       { return GetRegisteredInNonConst(); }
     const SwModify  *GetDep() const { return GetRegisteredIn(); }
 
diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx
index 7a2ed659c6ae..e4d63da05fb7 100644
--- a/sw/source/core/text/txtfrm.cxx
+++ b/sw/source/core/text/txtfrm.cxx
@@ -1083,7 +1083,7 @@ bool sw_HideObj( const SwTextFrame& _rFrame,
              _rFrame.IsInDocBody() && !_rFrame.FindNextCnt() )
         {
             SwTextNode const& rNode(*rAnchorPos.nNode.GetNode().GetTextNode());
-            assert(_rFrame.GetMergedPara() || &rNode == _rFrame.GetRegisteredIn()); // simple consistency check
+//            assert(_rFrame.GetMergedPara() || &rNode == _rFrame.GetDep()); // simple consistency check
             sal_Int32 const nObjAnchorPos(rAnchorPos.nContent.GetIndex());
             const sal_Unicode cAnchorChar = nObjAnchorPos < rNode.Len()
                 ? rNode.GetText()[nObjAnchorPos]
commit ed958e18eb0f0b78e8e089e80caa2a067d3c9489
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Fri Jun 1 21:19:07 2018 +0200

    sw_redlinehide: SwContentFrame::DestroyImpl()
    
    Change-Id: I4539ef0a7dc04de1c87cf6f54ca319dbdc719755

diff --git a/sw/source/core/layout/ssfrm.cxx b/sw/source/core/layout/ssfrm.cxx
index ea5108f1a848..3012bd954a94 100644
--- a/sw/source/core/layout/ssfrm.cxx
+++ b/sw/source/core/layout/ssfrm.cxx
@@ -414,9 +414,14 @@ SwContentFrame::SwContentFrame( SwContentNode * const pContent, SwFrame* pSib )
 
 void SwContentFrame::DestroyImpl()
 {
-    const SwContentNode* pCNd;
-    if( nullptr != ( pCNd = dynamic_cast<SwContentNode*>( GetRegisteredIn() ) ) &&
-        !pCNd->GetDoc()->IsInDtor() )
+    const SwContentNode* pCNd(dynamic_cast<SwContentNode*>(GetDep()));
+    if (nullptr == pCNd && IsTextFrame())
+    {
+        pCNd = static_cast<SwTextFrame*>(this)->GetTextNodeFirst();
+    }
+    // IsInDtor shouldn't be happening with ViewShell owning layout
+    assert(nullptr == pCNd || !pCNd->GetDoc()->IsInDtor());
+    if (nullptr != pCNd && !pCNd->GetDoc()->IsInDtor())
     {
         //Unregister from root if I'm still in turbo there.
         SwRootFrame *pRoot = getRootFrame();
commit cf4f0b017f8a754720de0ea4fd6060cfde9b1e10
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Fri Jun 1 20:52:35 2018 +0200

    sw_redlinehide: convert to GetDep()
    
    Change-Id: I3b128fe797e8fd6989821cfd540dc5e630e74d37

diff --git a/sw/source/core/layout/hffrm.cxx b/sw/source/core/layout/hffrm.cxx
index c2d2a46718c6..437b8992a243 100644
--- a/sw/source/core/layout/hffrm.cxx
+++ b/sw/source/core/layout/hffrm.cxx
@@ -688,7 +688,7 @@ void SwPageFrame::PrepareHeader()
     if ( !pLay )
         return;
 
-    const SwFormatHeader &rH = static_cast<SwFrameFormat*>(GetRegisteredIn())->GetHeader();
+    const SwFormatHeader &rH = static_cast<SwFrameFormat*>(GetDep())->GetHeader();
 
     const SwViewShell *pSh = getRootFrame()->GetCurrShell();
     const bool bOn = !(pSh && (pSh->GetViewOptions()->getBrowseMode() ||
@@ -729,7 +729,7 @@ void SwPageFrame::PrepareFooter()
     if ( !pLay )
         return;
 
-    const SwFormatFooter &rF = static_cast<SwFrameFormat*>(GetRegisteredIn())->GetFooter();
+    const SwFormatFooter &rF = static_cast<SwFrameFormat*>(GetDep())->GetFooter();
     while ( pLay->GetNext() )
         pLay = static_cast<SwLayoutFrame*>(pLay->GetNext());
 
diff --git a/sw/source/core/layout/newfrm.cxx b/sw/source/core/layout/newfrm.cxx
index ced2ab2b407e..37bea6e97e65 100644
--- a/sw/source/core/layout/newfrm.cxx
+++ b/sw/source/core/layout/newfrm.cxx
@@ -472,7 +472,7 @@ void SwRootFrame::DestroyImpl()
 
     if(pBlink)
         pBlink->FrameDelete( this );
-    SwFrameFormat *pRegisteredInNonConst = static_cast<SwFrameFormat*>(GetRegisteredInNonConst());
+    SwFrameFormat *pRegisteredInNonConst = static_cast<SwFrameFormat*>(GetDep());
     if ( pRegisteredInNonConst )
     {
         SwDoc *pDoc = pRegisteredInNonConst->GetDoc();
diff --git a/sw/source/core/layout/pagechg.cxx b/sw/source/core/layout/pagechg.cxx
index 653a58097f7a..11095f1dec62 100644
--- a/sw/source/core/layout/pagechg.cxx
+++ b/sw/source/core/layout/pagechg.cxx
@@ -2451,7 +2451,7 @@ bool SwPageFrame::IsOverHeaderFooterArea( const Point& rPt, FrameControlType &rC
     const bool bHideWhitespaceMode = pViewShell->GetViewOptions()->IsHideWhitespaceMode();
     if ( aHeaderArea.IsInside( rPt ) )
     {
-        if (!bHideWhitespaceMode || static_cast<const SwFrameFormat*>(GetRegisteredIn())->GetHeader().IsActive())
+        if (!bHideWhitespaceMode || static_cast<const SwFrameFormat*>(GetDep())->GetHeader().IsActive())
         {
             rControl = Header;
             return true;
@@ -2463,7 +2463,7 @@ bool SwPageFrame::IsOverHeaderFooterArea( const Point& rPt, FrameControlType &rC
                 Size( getFrameArea().Width(), getFrameArea().Bottom() - nLowerLimit ) );
 
         if ( aFooterArea.IsInside( rPt ) &&
-             (!bHideWhitespaceMode || static_cast<const SwFrameFormat*>(GetRegisteredIn())->GetFooter().IsActive()) )
+             (!bHideWhitespaceMode || static_cast<const SwFrameFormat*>(GetDep())->GetFooter().IsActive()) )
         {
             rControl = Footer;
             return true;
@@ -2488,7 +2488,7 @@ bool SwPageFrame::CheckPageHeightValidForHideWhitespace(SwTwips nDiff)
         if (nDiff < 0)
         {
             // Content frame doesn't fit the actual size, check if it fits the nominal one.
-            const SwFrameFormat* pPageFormat = static_cast<const SwFrameFormat*>(GetRegisteredIn());
+            const SwFrameFormat* pPageFormat = static_cast<const SwFrameFormat*>(GetDep());
             const Size& rPageSize = pPageFormat->GetFrameSize().GetSize();
             long nWhitespace = rPageSize.getHeight() - getFrameArea().Height();
             if (nWhitespace > -nDiff)
diff --git a/sw/source/core/layout/sectfrm.cxx b/sw/source/core/layout/sectfrm.cxx
index 8f68adf082c7..b12952b0114a 100644
--- a/sw/source/core/layout/sectfrm.cxx
+++ b/sw/source/core/layout/sectfrm.cxx
@@ -2556,7 +2556,7 @@ void SwSectionFrame::SwClientNotify( const SwModify& rMod, const SfxHint& rHint
     // #i117863#
     const SwSectionFrameMoveAndDeleteHint* pHint =
                     dynamic_cast<const SwSectionFrameMoveAndDeleteHint*>(&rHint);
-    if ( pHint && pHint->GetId() == SfxHintId::Dying && &rMod == GetRegisteredIn() )
+    if (pHint && pHint->GetId() == SfxHintId::Dying && &rMod == GetDep())
     {
         SwSectionFrame::MoveContentAndDelete( this, pHint->IsSaveContent() );
     }
diff --git a/sw/source/core/layout/ssfrm.cxx b/sw/source/core/layout/ssfrm.cxx
index a0b035ebaee7..ea5108f1a848 100644
--- a/sw/source/core/layout/ssfrm.cxx
+++ b/sw/source/core/layout/ssfrm.cxx
@@ -436,7 +436,7 @@ SwContentFrame::~SwContentFrame()
 
 void SwTextFrame::RegisterToNode(SwTextNode & rNode)
 {
-    assert(&rNode != GetRegisteredIn());
+    assert(&rNode != GetDep());
     m_pMergedPara = sw::CheckParaRedlineMerge(*this, rNode);
     rNode.Add( this );
 }
diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx
index 90cc289b2b21..501d756f714f 100644
--- a/sw/source/core/layout/tabfrm.cxx
+++ b/sw/source/core/layout/tabfrm.cxx
@@ -1480,12 +1480,14 @@ bool SwContentFrame::CalcLowers( SwLayoutFrame* pLay, const SwLayoutFrame* pDont
                 if ( !SwObjectFormatter::FormatObjsAtFrame( *pCnt,
                                                           *(pCnt->FindPageFrame()) ) )
                 {
-                    if ( pCnt->GetRegisteredIn() == pLoopControlCond )
+                    SwTextNode const*const pTextNode(
+                        static_cast<SwTextFrame*>(pCnt)->GetTextNodeFirst());
+                    if (pTextNode == pLoopControlCond)
                         ++nLoopControlRuns;
                     else
                     {
                         nLoopControlRuns = 0;
-                        pLoopControlCond = pCnt->GetRegisteredIn();
+                        pLoopControlCond = pTextNode;
                     }
 
                     if ( nLoopControlRuns < nLoopControlMax )
diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx
index 3326df94e423..7a2ed659c6ae 100644
--- a/sw/source/core/text/txtfrm.cxx
+++ b/sw/source/core/text/txtfrm.cxx
@@ -651,7 +651,7 @@ void SwTextFrame::DestroyImpl()
         }
         else
         {
-            SwTextNode *const pNode(static_cast<SwTextNode*>(GetRegisteredIn()));
+            SwTextNode *const pNode(static_cast<SwTextNode*>(GetDep()));
             if (pNode)
             {
                 RemoveFootnotesForNode(*this, *pNode);
commit f9585f1d2c18e5767966ef6a38870f0f1aec85f1
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Fri Jun 1 20:46:26 2018 +0200

    sw_redlinehide: convert SwDeletionChecker to GetDep()
    
    Such a lovely class!
    
    Change-Id: Id03795b1c62c35829cab093198daf082ca78d174

diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx
index b9d90f9a0f37..482f60c8dca0 100644
--- a/sw/source/core/inc/frame.hxx
+++ b/sw/source/core/inc/frame.hxx
@@ -287,6 +287,7 @@ class SW_DLLPUBLIC SwFrame : public SwFrameAreaDefinition, public SwClient, publ
     friend class SwFlowFrame;
     friend class SwLayoutFrame;
     friend class SwLooping;
+    friend class SwDeletionChecker; // for GetDep()
 
     // voids lower during creation of a column
     friend SwFrame *SaveContent( SwLayoutFrame *, SwFrame* pStart );
diff --git a/sw/source/core/inc/frmtool.hxx b/sw/source/core/inc/frmtool.hxx
index c0ecd3463b02..0ffe4a75c0f6 100644
--- a/sw/source/core/inc/frmtool.hxx
+++ b/sw/source/core/inc/frmtool.hxx
@@ -544,11 +544,7 @@ private:
     const SwModify* mpRegIn;
 
 public:
-    SwDeletionChecker( const SwFrame* pFrame )
-            : mpFrame( pFrame ),
-              mpRegIn( pFrame ? const_cast<SwFrame*>(pFrame)->GetRegisteredIn() : nullptr )
-    {
-    }
+    SwDeletionChecker(const SwFrame* pFrame);
 
     /**
      *  return
diff --git a/sw/source/core/layout/frmtool.cxx b/sw/source/core/layout/frmtool.cxx
index 277d155d06aa..6552f45a6e0a 100644
--- a/sw/source/core/layout/frmtool.cxx
+++ b/sw/source/core/layout/frmtool.cxx
@@ -3418,6 +3418,17 @@ const SwContentFrame* GetCellContent( const SwLayoutFrame& rCell )
     return pContent;
 }
 
+SwDeletionChecker::SwDeletionChecker(const SwFrame* pFrame)
+    : mpFrame( pFrame )
+    , mpRegIn( pFrame
+        ? pFrame->IsTextFrame()
+            // sw_redlinehide: GetDep() may be a member of SwTextFrame!
+            ? static_cast<SwTextFrame const*>(pFrame)->GetTextNodeFirst()
+            : const_cast<SwFrame*>(pFrame)->GetDep()
+        : nullptr )
+{
+}
+
 /// Can be used to check if a frame has been deleted
 bool SwDeletionChecker::HasBeenDeleted()
 {
commit ca86c8afa57a3eeaf9ca5febeb54f648c82868e9
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Fri Jun 1 20:40:15 2018 +0200

    sw_redlinehide: SwXFlatParagraphIterator::getNextPara() iterate ...
    
    ... the MergedPara here.
    
    Change-Id: I1a76c9d4a13277987218426a787b5b1b421d36ea

diff --git a/sw/source/core/unocore/unoflatpara.cxx b/sw/source/core/unocore/unoflatpara.cxx
index 425e894e60ac..a39cf00dee4c 100644
--- a/sw/source/core/unocore/unoflatpara.cxx
+++ b/sw/source/core/unocore/unoflatpara.cxx
@@ -39,6 +39,7 @@
 #include <unotextrange.hxx>
 #include <pagefrm.hxx>
 #include <cntfrm.hxx>
+#include <txtfrm.hxx>
 #include <rootfrm.hxx>
 #include <poolfmt.hxx>
 #include <pagedesc.hxx>
@@ -396,16 +397,46 @@ uno::Reference< text::XFlatParagraph > SwXFlatParagraphIterator::getNextPara()
 
                 while( pCnt && pCurrentPage->IsAnLower( pCnt ) )
                 {
-                    SwTextNode* pTextNode = pCnt->GetNode()->GetTextNode();
-
-                    if ( pTextNode &&
-                        ((mnType == text::TextMarkupType::SPELLCHECK &&
-                                pTextNode->IsWrongDirty()) ||
-                         (mnType == text::TextMarkupType::PROOFREADING &&
-                                pTextNode->IsGrammarCheckDirty())) )
+                    if (pCnt->IsTextFrame())
                     {
-                        pRet = pTextNode;
-                        break;
+                        SwTextFrame const*const pText(static_cast<SwTextFrame const*>(pCnt));
+                        if (sw::MergedPara const*const pMergedPara = pText->GetMergedPara()
+            )
+                        {
+                            SwTextNode * pTextNode(nullptr);
+                            for (auto const& e : pMergedPara->extents)
+                            {
+                                if (e.pNode != pTextNode)
+                                {
+                                    pTextNode = e.pNode;
+                                    if ((mnType == text::TextMarkupType::SPELLCHECK
+                                            && pTextNode->IsWrongDirty()) ||
+                                        (mnType == text::TextMarkupType::PROOFREADING
+                                             && pTextNode->IsGrammarCheckDirty()))
+                                    {
+                                        pRet = pTextNode;
+                                        break;
+                                    }
+                                }
+                            }
+                        }
+                        else
+                        {
+                            SwTextNode const*const pTextNode(pText->GetTextNodeFirst());
+                            if ((mnType == text::TextMarkupType::SPELLCHECK
+                                    && pTextNode->IsWrongDirty()) ||
+                                (mnType == text::TextMarkupType::PROOFREADING
+                                     && pTextNode->IsGrammarCheckDirty()))
+
+                            {
+                                pRet = const_cast<SwTextNode*>(pTextNode);
+                            }
+                        }
+
+                        if (pRet)
+                        {
+                            break;
+                        }
                     }
 
                     pCnt = pCnt->GetNextContentFrame();
commit b1793523edf10779f0d13c7249f36fb056a921a1
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Fri Jun 1 20:38:13 2018 +0200

    sw_redlinehide: trivial GetNode() in PageBreakWin.cxx
    
    Change-Id: I7bdf58d1f2233ab77a1b774a99aa068fe9438ae8

diff --git a/sw/source/uibase/docvw/PageBreakWin.cxx b/sw/source/uibase/docvw/PageBreakWin.cxx
index 1580fc4eb756..366c204f9dc8 100644
--- a/sw/source/uibase/docvw/PageBreakWin.cxx
+++ b/sw/source/uibase/docvw/PageBreakWin.cxx
@@ -12,6 +12,8 @@
 
 #include <cmdid.h>
 #include <cntfrm.hxx>
+#include <txtfrm.hxx>
+#include <notxtfrm.hxx>
 #include <DashedLine.hxx>
 #include <doc.hxx>
 #include <edtwin.hxx>
@@ -240,7 +242,9 @@ void SwPageBreakWin::Select()
                 rSh.ClearMark();
 
                 SwContentFrame *pCnt = const_cast< SwContentFrame* >( pBodyFrame->ContainsContent() );
-                SwContentNode* pNd = pCnt->GetNode();
+                SwContentNode* pNd = pCnt->IsTextFrame()
+                    ? static_cast<SwTextFrame*>(pCnt)->GetTextNodeFirst()
+                    : static_cast<SwNoTextFrame*>(pCnt)->GetNode();
                 rSh.SetSelection( *pNd );
 
                 SfxStringItem aItem(pEditWin->GetView().GetPool().GetWhich(FN_FORMAT_TABLE_DLG), "textflow");
@@ -254,7 +258,9 @@ void SwPageBreakWin::Select()
             else
             {
                 SwContentFrame *pCnt = const_cast< SwContentFrame* >( pBodyFrame->ContainsContent() );
-                SwContentNode* pNd = pCnt->GetNode();
+                SwContentNode* pNd = pCnt->IsTextFrame()
+                    ? static_cast<SwTextFrame*>(pCnt)->GetTextNodeFirst()
+                    : static_cast<SwNoTextFrame*>(pCnt)->GetNode();
 
                 SwPaM aPaM( *pNd );
                 SwPaMItem aPaMItem( pEditWin->GetView().GetPool( ).GetWhich( FN_PARAM_PAM ), &aPaM );
@@ -276,8 +282,11 @@ void SwPageBreakWin::Select()
 
         if ( pBodyFrame )
         {
+
             SwContentFrame *pCnt = const_cast< SwContentFrame* >( pBodyFrame->ContainsContent() );
-            SwContentNode* pNd = pCnt->GetNode();
+            SwContentNode* pNd = pCnt->IsTextFrame()
+                ? static_cast<SwTextFrame*>(pCnt)->GetTextNodeFirst()
+                : static_cast<SwNoTextFrame*>(pCnt)->GetNode();
 
             pNd->GetDoc()->GetIDocumentUndoRedo( ).StartUndo( SwUndoId::UI_DELETE_PAGE_BREAK, nullptr );
 
commit b2eb879e2d7883ef0f3604f34d447c60050be5a7
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Fri Jun 1 20:34:02 2018 +0200

    sw_redlinehide: trivial GetNode() in text
    
    Change-Id: Ied6e80e30ced49b11952c44c36e86e8575e42c0f

diff --git a/sw/source/core/text/frmcrsr.cxx b/sw/source/core/text/frmcrsr.cxx
index c7c53d83e4f9..c57764acb569 100644
--- a/sw/source/core/text/frmcrsr.cxx
+++ b/sw/source/core/text/frmcrsr.cxx
@@ -1368,7 +1368,7 @@ void SwTextFrame::FillCursorPos( SwFillData& rFill ) const
         aSet.Put( *GetTextNodeForParaProps()->GetpSwAttrSet() );
         aSet.SetParent( pSet );
         pSet = &aSet;
-        pFnt = new SwFont( pSet, GetNode()->getIDocumentSettingAccess() );
+        pFnt = new SwFont( pSet, &GetDoc().getIDocumentSettingAccess() );
     }
     else
     {
diff --git a/sw/source/core/text/guess.cxx b/sw/source/core/text/guess.cxx
index 9bcb7bd33fe3..14b1de671f54 100644
--- a/sw/source/core/text/guess.cxx
+++ b/sw/source/core/text/guess.cxx
@@ -80,7 +80,8 @@ bool SwTextGuess::Guess( const SwTextPortion& rPor, SwTextFormatInfo &rInf,
     // for LTR mode only
     if ( !rInf.GetTextFrame()->IsRightToLeft() )
     {
-        if ( rInf.GetTextFrame()->GetNode()->getIDocumentSettingAccess()->get( DocumentSettingId::MS_WORD_COMP_TRAILING_BLANKS ) )
+        if (rInf.GetTextFrame()->GetDoc().getIDocumentSettingAccess().get(
+                    DocumentSettingId::MS_WORD_COMP_TRAILING_BLANKS))
         {
             if ( rAdjust == SvxAdjust::Right || rAdjust == SvxAdjust::Center )
             {
@@ -380,7 +381,7 @@ bool SwTextGuess::Guess( const SwTextPortion& rPor, SwTextFormatInfo &rInf,
         }
 
         const ForbiddenCharacters aForbidden(
-                *rInf.GetTextFrame()->GetNode()->getIDocumentSettingAccess()->getForbiddenCharacters( aLang, true ) );

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list