diff options
author | Michael Stahl <Michael.Stahl@cib.de> | 2018-08-02 17:09:53 +0200 |
---|---|---|
committer | Michael Stahl <Michael.Stahl@cib.de> | 2018-09-19 10:18:23 +0200 |
commit | 464ef392f901c6e2ad3d32df8b039f2226073cf4 (patch) | |
tree | fb576dd0a3c444fc55b631ad84dd2b8120693439 /sw/source/core/layout/wsfrm.cxx | |
parent | 6182e030417bb48f767203957bab1cb48fa18b14 (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.cxx | 117 |
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? } } } |