[Libreoffice-commits] core.git: Branch 'private/mst/sw_redlinehide_2' - 3 commits - sw/source
Libreoffice Gerrit user
logerrit at kemper.freedesktop.org
Tue Aug 7 15:23:09 UTC 2018
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.Stahl at cib.de>
AuthorDate: Tue Aug 7 16:40:02 2018 +0200
Commit: Michael Stahl <Michael.Stahl at 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.Stahl at cib.de>
AuthorDate: Tue Aug 7 16:10:23 2018 +0200
Commit: Michael Stahl <Michael.Stahl at 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.Stahl at cib.de>
AuthorDate: Tue Aug 7 10:33:08 2018 +0200
Commit: Michael Stahl <Michael.Stahl at 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
More information about the Libreoffice-commits
mailing list