[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