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

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Thu Aug 2 16:46:23 UTC 2018


 sw/source/core/inc/frmtool.hxx    |   11 +++++
 sw/source/core/layout/frmtool.cxx |   42 ++++++++++++++++++-
 sw/source/core/layout/wsfrm.cxx   |   80 ++++++++++++++++++++++++++++++++++++--
 3 files changed, 125 insertions(+), 8 deletions(-)

New commits:
commit b0e300c54a1ebb0c7ea02f64e16d8b3bf394d9d7
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Thu Aug 2 17:09:53 2018 +0200
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Aug 2 17:10:25 2018 +0200

    sw_redlinehide_2: show/hide flys in redlines
    
    The old implementation would not actually hide at-char flys but move
    the anchor, which is clearly not ideal; better to hide them.
    
    Change-Id: If21d0360e04857752a2c84f5329eadfad7818ac8

diff --git a/sw/source/core/inc/frmtool.hxx b/sw/source/core/inc/frmtool.hxx
index 0ffe4a75c0f6..e692bb900ef6 100644
--- a/sw/source/core/inc/frmtool.hxx
+++ b/sw/source/core/inc/frmtool.hxx
@@ -45,6 +45,8 @@ class GraphicAttr;
 class SwPageDesc;
 class SwFrameFormats;
 class SwRegionRects;
+class SwTextNode;
+namespace sw { struct Extent; }
 
 #define FAR_AWAY (SAL_MAX_INT32 - 20000)  // initial position of a Fly
 #define BROWSE_HEIGHT (56700L * 10L) // 10 Meters
@@ -55,6 +57,15 @@ class SwRegionRects;
 void AppendObjs( const SwFrameFormats *pTable, sal_uLong nIndex,
                        SwFrame *pFrame, SwPageFrame *pPage, SwDoc* doc );
 
+void AppendObjsOfNode(SwFrameFormats const* pTable, sal_uLong nIndex,
+        SwFrame * pFrame, SwPageFrame * pPage, SwDoc * pDoc,
+        std::vector<sw::Extent>::const_iterator * pIter,
+        std::vector<sw::Extent>::const_iterator const* pEnd);
+
+void RemoveHiddenObjsOfNode(SwTextNode const& rNode,
+        std::vector<sw::Extent>::const_iterator * pIter,
+        std::vector<sw::Extent>::const_iterator const* pEnd);
+
 // draw background with brush or graphics
 // The 6th parameter indicates that the method should consider background
 // transparency, saved in the color of the brush item.
diff --git a/sw/source/core/layout/frmtool.cxx b/sw/source/core/layout/frmtool.cxx
index ad8d07e2cc2f..9581aacb8e9d 100644
--- a/sw/source/core/layout/frmtool.cxx
+++ b/sw/source/core/layout/frmtool.cxx
@@ -1039,9 +1039,13 @@ static bool IsShown(sal_uLong const nIndex,
     std::vector<sw::Extent>::const_iterator const*const pEnd)
 {
     SwPosition const& rAnchor(*rAnch.GetContentAnchor());
+    if (rAnchor.nNode.GetIndex() != nIndex)
+    {
+        return false;
+    }
     if (pIter && rAnch.GetAnchorId() != RndStdIds::FLY_AT_PARA)
     {
-        // TODO are frames sorted by anchor positions perhaps?
+        // note: frames are not sorted by anchor position.
         assert(pEnd);
         assert(rAnch.GetAnchorId() != RndStdIds::FLY_AT_FLY);
         for ( ; *pIter != *pEnd; ++*pIter)
@@ -1049,8 +1053,13 @@ static bool IsShown(sal_uLong const nIndex,
             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)
+                // for AS_CHAR obviously must be <
+                // for AT_CHAR it is questionable whether < or <= should be used
+                // and there is the additional corner case of Len() to consider
+                // prefer < for now for symmetry (and inverted usage with
+                // "hidden") and handle special case explicitly
+                if (rAnchor.nContent.GetIndex() < (**pIter).nEnd
+                    || (**pIter).nEnd == (**pIter).pNode->Len())
                 {
                     return true;
                 }
@@ -1064,7 +1073,32 @@ static bool IsShown(sal_uLong const nIndex,
     }
     else
     {
-        return rAnch.GetContentAnchor()->nNode.GetIndex() == nIndex;
+        return true;
+    }
+}
+
+void RemoveHiddenObjsOfNode(SwTextNode const& rNode,
+    std::vector<sw::Extent>::const_iterator *const pIter,
+    std::vector<sw::Extent>::const_iterator const*const pEnd)
+{
+    std::vector<SwFrameFormat*> const*const pFlys(rNode.GetAnchoredFlys());
+    if (!pFlys)
+    {
+        return;
+    }
+    for (SwFrameFormat * pFrameFormat : *pFlys)
+    {
+        SwFormatAnchor const& rAnchor = pFrameFormat->GetAnchor();
+        if (rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR
+            || (rAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR
+                && RES_DRAWFRMFMT == pFrameFormat->Which()))
+        {
+            assert(rAnchor.GetContentAnchor()->nNode.GetIndex() == rNode.GetIndex());
+            if (!IsShown(rNode.GetIndex(), rAnchor, pIter, pEnd))
+            {
+                pFrameFormat->DelFrames();
+            }
+        }
     }
 }
 
diff --git a/sw/source/core/layout/wsfrm.cxx b/sw/source/core/layout/wsfrm.cxx
index 68d9e1e418f1..acb2f34f28c5 100644
--- a/sw/source/core/layout/wsfrm.cxx
+++ b/sw/source/core/layout/wsfrm.cxx
@@ -4193,9 +4193,47 @@ static void UnHideRedlines(SwRootFrame & rLayout,
                         rNode.GetRedlineMergeFlag() == SwNode::Merge::NonFirst);
                     if (rNode.IsCreateFrameWhenHidingRedlines())
                     {
-                        pFrame->SetMergedPara(CheckParaRedlineMerge(*pFrame,
-                                rTextNode, sw::FrameMode::Existing));
-                        // ??? TODO flys etc.
+                        {
+                            auto pMerged(CheckParaRedlineMerge(*pFrame,
+                                    rTextNode, sw::FrameMode::Existing));
+                            pFrame->SetMergedPara(std::move(pMerged));
+                        }
+                        if (auto const& pMerged = pFrame->GetMergedPara())
+                        {
+                            // add visible flys in non-first node to merged frame
+                            // (hidden flys remain and are deleted via DelFrames())
+                            SwFrameFormats& rTable(*rTextNode.GetDoc()->GetSpzFrameFormats());
+                            SwPageFrame *const pPage(pFrame->FindPageFrame());
+                            std::vector<sw::Extent>::const_iterator iterFirst(pMerged->extents.begin());
+                            std::vector<sw::Extent>::const_iterator iter(iterFirst);
+                            SwTextNode const* pNode(&rTextNode);
+                            for ( ; ; ++iter)
+                            {
+                                if (iter == pMerged->extents.end()
+                                    || iter->pNode != pNode)
+                                {
+                                    if (pNode == &rTextNode)
+                                    {   // remove existing hidden at-char anchored flys
+                                        RemoveHiddenObjsOfNode(
+                                            rTextNode, &iterFirst, &iter);
+                                    }
+                                    else
+                                    {
+                                        // pNode's frame has been deleted by CheckParaRedlineMerge()
+                                        AppendObjsOfNode(&rTable,
+                                            pNode->GetIndex(), pFrame, pPage,
+                                            rTextNode.GetDoc(),
+                                            &iterFirst, &iter);
+                                    }
+                                    if (iter == pMerged->extents.end())
+                                    {
+                                        break;
+                                    }
+                                    pNode = iter->pNode;
+                                    iterFirst = iter;
+                                }
+                            }
+                        }
                     }
                 }
                 else
@@ -4211,11 +4249,45 @@ static void UnHideRedlines(SwRootFrame & rLayout,
                             if (rExtent.pNode != pNode)
                             {
                                 sw::RemoveFootnotesForNode(*pFrame, *rExtent.pNode, nullptr);
+                                // similarly, remove the anchored flys
+                                if (auto const pFlys = rExtent.pNode->GetAnchoredFlys())
+                                {
+                                    for (SwFrameFormat * pFormat : *pFlys)
+                                    {
+                                        pFormat->DelFrames(/*&rLayout*/);
+                                    }
+                                }
                                 pNode = rExtent.pNode;
                             }
                         }
+                        // add all flys in first node that are hidden
+                        std::vector<sw::Extent> hidden;
+                        sal_Int32 nLast(0);
+                        for (auto const& rExtent : pMergedPara->extents)
+                        {
+                            if (rExtent.pNode != &rTextNode)
+                            {
+                                break;
+                            }
+                            if (rExtent.nStart != 0)
+                            {
+                                assert(rExtent.nStart != nLast);
+
+                                hidden.emplace_back(&rTextNode, nLast, rExtent.nStart);
+                            }
+                            nLast = rExtent.nEnd;
+                        }
+                        if (nLast != rTextNode.Len())
+                        {
+                            hidden.emplace_back(&rTextNode, nLast, rTextNode.Len());
+                        }
+                        SwFrameFormats& rTable(*rTextNode.GetDoc()->GetSpzFrameFormats());
+                        auto iterBegin(hidden.cbegin());
+                        auto const iterEnd(hidden.cend());
+                        AppendObjsOfNode(&rTable, rTextNode.GetIndex(), pFrame,
+                            pFrame->FindPageFrame(), rTextNode.GetDoc(),
+                            &iterBegin, &iterEnd);
                         pFrame->SetMergedPara(nullptr);
-                        // ??? TODO flys etc.
                         // ??? TODO recreate? or is invalidate enough?
                     }
                 }


More information about the Libreoffice-commits mailing list