sw/source/core/inc/frmtool.hxx | 2 sw/source/core/layout/trvlfrm.cxx | 5 +- sw/source/core/layout/wsfrm.cxx | 83 +++++++++++++++++++++----------------- 3 files changed, 54 insertions(+), 36 deletions(-)
New commits: commit e0c9804b0d6336fa7c511e8410ffbfad3bdceec2 Author: Michael Stahl <michael.st...@cib.de> AuthorDate: Tue Aug 7 16:40:02 2018 +0200 Commit: Michael Stahl <michael.st...@cib.de> CommitDate: Tue Aug 7 16:40:02 2018 +0200 sw_redlinehide_2: handle flys anchored in flys There is no way to iterate over the nodes-array such that flys are ordered wrt. the flys in whose content they are anchored; this makes it hard to ensure that flys anchored in flys are handled only once. For the Hide implementation, when the flys anchored to a non-first merged SwTextNode in a fly are inserted, ensure that the content of the same fly is skipped if it happens to come later in the nodes-array. For the Show implementation, the ::MakeFrames() would call AppendAllObj() anyway; suppress that and manually call it at the end, which should avoid the problem. Change-Id: I7fb31cf14ef26c095fa7e09edd4ab530add9f253 diff --git a/sw/source/core/inc/frmtool.hxx b/sw/source/core/inc/frmtool.hxx index e692bb900ef6..05b2dc237253 100644 --- a/sw/source/core/inc/frmtool.hxx +++ b/sw/source/core/inc/frmtool.hxx @@ -66,6 +66,8 @@ void RemoveHiddenObjsOfNode(SwTextNode const& rNode, std::vector<sw::Extent>::const_iterator * pIter, std::vector<sw::Extent>::const_iterator const* pEnd); +void AppendAllObjs(const SwFrameFormats* pTable, const SwFrame* pSib); + // 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/wsfrm.cxx b/sw/source/core/layout/wsfrm.cxx index 8ac1ea46178a..b62812ceac06 100644 --- a/sw/source/core/layout/wsfrm.cxx +++ b/sw/source/core/layout/wsfrm.cxx @@ -40,6 +40,7 @@ #include <txtftn.hxx> #include <fmtftn.hxx> #include <fmtsrnd.hxx> +#include <fmtcntnt.hxx> #include <ftnfrm.hxx> #include <tabfrm.hxx> #include <flyfrms.hxx> @@ -4166,7 +4167,8 @@ void SwRootFrame::InvalidateAllObjPos() } static void UnHideRedlines(SwRootFrame & rLayout, - SwNodes & rNodes, SwNode const& rEndOfSectionNode) + SwNodes & rNodes, SwNode const& rEndOfSectionNode, + std::set<sal_uLong> *const pSkipped) { assert(rEndOfSectionNode.IsEndNode()); for (sal_uLong i = rEndOfSectionNode.StartOfSectionNode()->GetIndex() + 1; @@ -4251,6 +4253,20 @@ static void UnHideRedlines(SwRootFrame & rLayout, pNode->GetIndex(), pFrame, pPage, rTextNode.GetDoc(), &iterFirst, &iter); + if (pSkipped) + { + // if a fly has been added by AppendObjsOfNode, it must be skipped; if not, then it doesn't matter if it's skipped or not because it has no frames and because of that it would be skipped anyway + if (auto const pFlys = pNode->GetAnchoredFlys()) + { + for (auto const pFly : *pFlys) + { + if (pFly->Which() != RES_DRAWFRMFMT) + { + pSkipped->insert(pFly->GetContent().GetContentIdx()->GetIndex()); + } + } + } + } } if (iter == pMerged->extents.end()) { @@ -4302,33 +4318,8 @@ static void UnHideRedlines(SwRootFrame & 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); + // rely on AppendAllObjs call at the end to add + // all flys in first node that are hidden } pFrame->SetMergedPara(nullptr); // ??? TODO recreate? or is invalidate enough? @@ -4356,6 +4347,7 @@ static void UnHideRedlines(SwRootFrame & rLayout, } else { + assert(!rNode.IsContentNode() || !rNode.GetContentNode()->getLayoutFrame(&rLayout)); sal_uLong j = i + 1; for ( ; j < rEndOfSectionNode.GetIndex(); ++j) { @@ -4368,7 +4360,10 @@ static void UnHideRedlines(SwRootFrame & rLayout, // InsertCnt_ also checks for hidden sections SwNodeIndex const start(rNodes, i); SwNodeIndex const end(rNodes, j); + assert(!bDontCreateObjects); + bDontCreateObjects = true; // suppress here, to be called once ::MakeFrames(rLayout.GetFormat()->GetDoc(), start, end); + bDontCreateObjects = false; i = j - 1; // will be incremented again } } @@ -4376,7 +4371,8 @@ static void UnHideRedlines(SwRootFrame & rLayout, } static void UnHideRedlinesExtras(SwRootFrame & rLayout, - SwNodes & rNodes, SwNode const& rEndOfExtraSectionNode) + SwNodes & rNodes, SwNode const& rEndOfExtraSectionNode, + std::set<sal_uLong> *const pSkipped) { assert(rEndOfExtraSectionNode.IsEndNode()); for (sal_uLong i = rEndOfExtraSectionNode.StartOfSectionNode()->GetIndex() @@ -4386,8 +4382,8 @@ static void UnHideRedlinesExtras(SwRootFrame & rLayout, assert(rStartNode.IsStartNode()); assert(rStartNode.GetRedlineMergeFlag() == SwNode::Merge::None); SwNode const& rEndNode(*rStartNode.EndOfSectionNode()); + bool bSkip(pSkipped ? pSkipped->find(i) != pSkipped->end() : false); i = rEndNode.GetIndex(); - bool bSkip(false); for (sal_uLong j = rStartNode.GetIndex() + 1; j < i; ++j) { // note: SwStartNode has no way to access the frames, so check @@ -4411,7 +4407,7 @@ static void UnHideRedlinesExtras(SwRootFrame & rLayout, } if (!bSkip) { - UnHideRedlines(rLayout, rNodes, rEndNode); + UnHideRedlines(rLayout, rNodes, rEndNode, pSkipped); } } } @@ -4459,9 +4455,20 @@ void SwRootFrame::SetHideRedlines(bool const bHideRedlines) // * flys anchored in flys : arrgh // * problem is flys that *did* already exist but with redlines in them // ... flys that don't exist are created by MakeFrames (and completely!) - UnHideRedlinesExtras(*this, rNodes, rNodes.GetEndOfInserts()); - UnHideRedlinesExtras(*this, rNodes, rNodes.GetEndOfAutotext()); - UnHideRedlines(*this, rNodes, rNodes.GetEndOfContent()); + // flys before footnotes: because footnotes may contain flys but not + // vice-versa; alas flys may contain flys, so we skip some of them + // if they have already been created from scratch via their anchor flys. + std::set<sal_uLong> skippedFlys; + UnHideRedlinesExtras(*this, rNodes, rNodes.GetEndOfAutotext(), + // when un-hiding, delay all fly frame creation to AppendAllObjs below + IsHideRedlines() ? &skippedFlys : nullptr); + UnHideRedlinesExtras(*this, rNodes, rNodes.GetEndOfInserts(), nullptr); + UnHideRedlines(*this, rNodes, rNodes.GetEndOfContent(), nullptr); + + if (!IsHideRedlines()) + { // create all previously hidden flys at once + AppendAllObjs(rDoc.GetSpzFrameFormats(), this); + } // InvalidateAllContent(SwInvalidateFlags::Size); // ??? TODO what to invalidate? this is the big hammer } commit e151b18c39b1d85461ff067fe8e1924e948fb159 Author: Michael Stahl <michael.st...@cib.de> AuthorDate: Tue Aug 7 16:10:23 2018 +0200 Commit: Michael Stahl <michael.st...@cib.de> CommitDate: Tue Aug 7 16:10:23 2018 +0200 no redlines, nothing to do Change-Id: Ib3d1a9c4fdc12b6f6073b17625cefa37212294b8 diff --git a/sw/source/core/layout/wsfrm.cxx b/sw/source/core/layout/wsfrm.cxx index aabcc91f1930..8ac1ea46178a 100644 --- a/sw/source/core/layout/wsfrm.cxx +++ b/sw/source/core/layout/wsfrm.cxx @@ -30,6 +30,7 @@ #include <viewopt.hxx> #include <IDocumentSettingAccess.hxx> #include <IDocumentFieldsAccess.hxx> +#include <IDocumentRedlineAccess.hxx> #include <fesh.hxx> #include <docsh.hxx> #include <ftninfo.hxx> @@ -4422,7 +4423,12 @@ void SwRootFrame::SetHideRedlines(bool const bHideRedlines) return; } mbHideRedlines = bHideRedlines; - SwNodes /*const*/& rNodes(GetFormat()->GetDoc()->GetNodes()); + SwDoc & rDoc(*GetFormat()->GetDoc()); + if (rDoc.getIDocumentRedlineAccess().GetRedlineTable().empty()) + { + return; + } + SwNodes /*const*/& rNodes(rDoc.GetNodes()); // Hide->Show: clear MergedPara, create frames // Show->Hide: call CheckParaRedlineMerge, delete frames // TODO how to traverse commit 2edd30d11db8051bdf934eb7ec79587b98364a4f Author: Michael Stahl <michael.st...@cib.de> AuthorDate: Tue Aug 7 10:33:08 2018 +0200 Commit: Michael Stahl <michael.st...@cib.de> CommitDate: Tue Aug 7 10:33:08 2018 +0200 sw: avoid asserts from SwSortedObjs::Insert() The first frame is almost certainly already inserted in line 2057; This causes "<SwSortedObjs::Insert()> - already contains object". Change-Id: I4a785accdec033865da971bf25d0ebe06ec2e765 diff --git a/sw/source/core/layout/trvlfrm.cxx b/sw/source/core/layout/trvlfrm.cxx index 22273e0173e6..bb11037d85e0 100644 --- a/sw/source/core/layout/trvlfrm.cxx +++ b/sw/source/core/layout/trvlfrm.cxx @@ -2492,7 +2492,10 @@ void SwRootFrame::CalcFrameRects(SwShellCursor &rCursor) if ( pContent->IsInFly() ) { const SwAnchoredObject* pObj = pContent->FindFlyFrame(); - aSortObjs.Insert( *const_cast<SwAnchoredObject*>(pObj) ); + if (!aSortObjs.Contains(*pObj)) + { // is this even possible, assuming valid cursor pos.? + aSortObjs.Insert( *const_cast<SwAnchoredObject*>(pObj) ); + } } // Consider only frames which have the same IsInDocBody value like pStartFrame _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits