summaryrefslogtreecommitdiff
path: root/sw/source/core/layout/wsfrm.cxx
diff options
context:
space:
mode:
authorMichael Stahl <Michael.Stahl@cib.de>2018-08-02 17:09:53 +0200
committerMichael Stahl <Michael.Stahl@cib.de>2018-09-19 10:18:23 +0200
commit464ef392f901c6e2ad3d32df8b039f2226073cf4 (patch)
treefb576dd0a3c444fc55b631ad84dd2b8120693439 /sw/source/core/layout/wsfrm.cxx
parent6182e030417bb48f767203957bab1cb48fa18b14 (diff)
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
Diffstat (limited to 'sw/source/core/layout/wsfrm.cxx')
-rw-r--r--sw/source/core/layout/wsfrm.cxx117
1 files changed, 103 insertions, 14 deletions
diff --git a/sw/source/core/layout/wsfrm.cxx b/sw/source/core/layout/wsfrm.cxx
index 52ffc1b1f5bd..71a6a524c313 100644
--- a/sw/source/core/layout/wsfrm.cxx
+++ b/sw/source/core/layout/wsfrm.cxx
@@ -4173,7 +4173,15 @@ static void UnHideRedlines(SwRootFrame & rLayout,
{
if (pFrame->getRootFrame() == &rLayout)
{
- frames.push_back(pFrame);
+ if (pFrame->IsFollow())
+ {
+ frames.push_back(pFrame);
+ } // when hiding, the loop must remove the anchored flys
+ else // *before* resetting SetMergedPara anywhere - else
+ { // the fly deletion code will access multiple of the
+ // frames with inconsistent MergedPara and assert
+ frames.insert(frames.begin(), pFrame);
+ }
}
}
// this messes with pRegisteredIn so do it outside SwIterator
@@ -4185,30 +4193,111 @@ 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));
+ }
+ auto const pMerged(pFrame->GetMergedPara());
+ if (pMerged
+ // do this only *once*, for the *last* frame
+ // otherwise AppendObj would create multiple frames for fly-frames!
+ && !pFrame->GetFollow())
+ {
+ // 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
{
if (auto const& pMergedPara = pFrame->GetMergedPara())
{
- // the new text frames don't exist yet, so at this point
- // we can only delete the footnote frames so they don't
- // point to the merged SwTextFrame any more...
- SwTextNode const* pNode(&rTextNode);
- for (auto const& rExtent : pMergedPara->extents)
+ // SwFlyAtContentFrame::Modify() always appends to
+ // the master frame, so do the same here.
+ // (RemoveFootnotesForNode must be called at least once)
+ if (!pFrame->IsFollow())
{
- if (rExtent.pNode != pNode)
+ // the new text frames don't exist yet, so at this point
+ // we can only delete the footnote frames so they don't
+ // point to the merged SwTextFrame any more...
+ SwTextNode const* pNode(&rTextNode);
+ for (auto const& rExtent : pMergedPara->extents)
+ {
+ 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())
{
- sw::RemoveFootnotesForNode(*pFrame, *rExtent.pNode, nullptr);
- pNode = rExtent.pNode;
+ 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?
}
}
}