[Libreoffice-commits] core.git: Branch 'private/mst/sw_redlinehide_2' - 6 commits - sw/source
Libreoffice Gerrit user
logerrit at kemper.freedesktop.org
Tue Aug 14 17:10:44 UTC 2018
sw/source/core/layout/ssfrm.cxx | 8 ++
sw/source/core/layout/wsfrm.cxx | 2
sw/source/core/text/redlnitr.cxx | 16 ++++-
sw/source/core/text/txtfrm.cxx | 7 +-
sw/source/core/txtnode/ndtxt.cxx | 118 +++++++++++++++++++++++++++++++++++----
sw/source/filter/xml/wrtxml.cxx | 9 ++
6 files changed, 144 insertions(+), 16 deletions(-)
New commits:
commit 14472006e5484ecaab3438b735bb3136112dcd94
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Tue Aug 14 19:07:27 2018 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Tue Aug 14 19:08:47 2018 +0200
RegisterToNode fix
Change-Id: I9f02bebac4318db77baf0561409da880288a0a09
diff --git a/sw/source/core/layout/ssfrm.cxx b/sw/source/core/layout/ssfrm.cxx
index b00851d7dd52..3a37ae92bc7f 100644
--- a/sw/source/core/layout/ssfrm.cxx
+++ b/sw/source/core/layout/ssfrm.cxx
@@ -443,8 +443,14 @@ SwContentFrame::~SwContentFrame()
void SwTextFrame::RegisterToNode(SwTextNode & rNode)
{
assert(&rNode != GetDep());
+ assert(!m_pMergedPara
+ || (m_pMergedPara->pFirstNode->GetIndex() < rNode.GetIndex())
+ || (rNode.GetIndex() + 1 == m_pMergedPara->pFirstNode->GetIndex()));
+ SwTextNode & rFirstNode(
+ (m_pMergedPara && m_pMergedPara->pFirstNode->GetIndex() < rNode.GetIndex())
+ ? *m_pMergedPara->pFirstNode
+ : rNode);
// sw_redlinehide: use New here, because the only caller also calls lcl_ChangeFootnoteRef
- SwTextNode & rFirstNode(m_pMergedPara ? *m_pMergedPara->pFirstNode : rNode);
m_pMergedPara = sw::CheckParaRedlineMerge(*this, rFirstNode, sw::FrameMode::New);
if (!m_pMergedPara)
{
commit ceb717ceee16d99b8f26fca7bfcadc5d1f22ae13
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Tue Aug 14 17:37:29 2018 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Tue Aug 14 19:08:47 2018 +0200
fix store flag in settings.xml too
Change-Id: I0b715b5255505ef5c3c8053e45cddd1365dbb791
diff --git a/sw/source/filter/xml/wrtxml.cxx b/sw/source/filter/xml/wrtxml.cxx
index 3a6f976f42c3..4f7a8d4dc55c 100644
--- a/sw/source/filter/xml/wrtxml.cxx
+++ b/sw/source/filter/xml/wrtxml.cxx
@@ -412,8 +412,15 @@ ErrCode SwXMLWriter::Write_( const uno::Reference < task::XStatusIndicator >& xS
nRedlineFlags = m_pDoc->getIDocumentRedlineAccess().GetRedlineFlags();
nRedlineFlags &= ~RedlineFlags::ShowMask;
nRedlineFlags |= RedlineFlags::ShowInsert;
- if ( *o3tl::doAccess<bool>(aAny) )
+ if (getenv("SW_REDLINEHIDE"))
+ {
nRedlineFlags |= RedlineFlags::ShowDelete;
+ }
+ else
+ {
+ if (*o3tl::doAccess<bool>(aAny))
+ nRedlineFlags |= RedlineFlags::ShowDelete;
+ }
m_pDoc->getIDocumentRedlineAccess().SetRedlineFlags( nRedlineFlags );
if (xStatusIndicator.is())
commit 9ca94c7a3efa7543b29e02d0803a1797970f89ea
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Tue Aug 14 15:58:35 2018 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Tue Aug 14 19:08:47 2018 +0200
sw_redlinehide_2: move SwInsText/SwDelText hint in CutImpl before attributes
An unfortunate incident involving a footnote accessing its old anchor
node's layout frame during InsertHint and the MapModelToViewPos needing
to have a mapping for this index...
6 SwTextFrame::MapModelToViewPos(SwPosition const&) const (this=0x8937760, rPos=SwPosition (node 41, offset 4)) at sw/source/core/text/txtfrm.cxx:1005
7 SwTextFrame::GetFrameAtPos(SwPosition const&) (this=0x8937760, rPos=SwPosition (node 41, offset 4)) at sw/source/core/text/frmcrsr.cxx:153
8 GetFrameOfModify(SwRootFrame const*, SwModify const&, SwFrameType, Point const*, SwPosition const*, bool) (pLayout=0x6a0a240, rMod=..., nFrameType=(SwFrameType::Txt | SwFrameType::NoTxt), pPoint=0x0, pPos=0x7ffcfa9d70a0, bCalcFrame=false) at sw/source/core/layout/frmtool.cxx:3517
9 SwContentNode::getLayoutFrame(SwRootFrame const*, Point const*, SwPosition const*, bool) const (this=0x6a67e20, _pRoot=0x6a0a240, pPoint=0x0, pPos=0x7ffcfa9d70a0, bCalcFrame=false) at sw/source/core/docnode/node.cxx:1137
10 SwFootnoteFrame::GetRefFromAttr() (this=0x8970a30) at sw/source/core/layout/ftnfrm.cxx:2839
11 SwContentNode::DelFrames(SwRootFrame const*, bool) (this=0x897ead0, pLayout=0x0, fromDtor=false) at sw/source/core/docnode/node.cxx:1419
12 SwTextNode::InsertHint(SwTextAttr*, SetAttrMode) (this=0x89ac890, pAttr=0x6a3ff60, nMode=(SetAttrMode::DONTREPLACE | SetAttrMode::NOTXTATRCHR)) at sw/source/core/txtnode/thints.cxx:1408
13 SwTextNode::CutImpl(SwTextNode*, SwIndex const&, SwIndex const&, int, bool) (this=0x6a67e20, pDest=0x89ac890, rDestStart=SwIndex (offset 2), rStart=SwIndex (offset 0), nLen=3, bUpdate=false) at sw/source/core/txtnode/ndtxt.cxx:2374
14 SwTextNode::CutText(SwTextNode*, SwIndex const&, int) (this=0x6a67e20, pDest=0x89ac890, rStart=SwIndex (offset 0), nLen=3) at sw/source/core/txtnode/ndtxt.cxx:2199
15 SwTextNode::JoinNext() (this=0x89ac890) at sw/source/core/txtnode/ndtxt.cxx:812
Change-Id: If0dc0f16eb124dc8a070b84684ee9ec9ab0dc70f
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index d57b9b266a90..a77cfe42382e 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -2306,6 +2306,13 @@ void SwTextNode::CutImpl( SwTextNode * const pDest, const SwIndex & rDestStart,
}
}
+ // notify frames - before moving hints, because footnotes
+ // want to find their anchor text frame in the follow chain
+ SwInsText aInsHint( nDestStart, nLen );
+ pDest->ModifyNotification( nullptr, &aInsHint );
+ SwDelText aDelHint( nTextStartIdx, nLen );
+ ModifyNotification( nullptr, &aDelHint );
+
// 2. move attributes
// Iterate over attribute array until the start of the attribute
// is behind the moved range
@@ -2441,12 +2448,6 @@ void SwTextNode::CutImpl( SwTextNode * const pDest, const SwIndex & rDestStart,
CHECK_SWPHINTS(this);
TryDeleteSwpHints();
-
- // notify layout frames
- SwInsText aInsHint( nDestStart, nLen );
- pDest->ModifyNotification( nullptr, &aInsHint );
- SwDelText aDelHint( nTextStartIdx, nLen );
- ModifyNotification( nullptr, &aDelHint );
}
void SwTextNode::EraseText(const SwIndex &rIdx, const sal_Int32 nCount,
commit f5aea792e265375452578fd163ef3c3f6458643c
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Tue Aug 14 15:48:31 2018 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Tue Aug 14 19:08:47 2018 +0200
sw_redlinehide_2: fix SplitNode handling of merged frames
The first branch is a bit easier, because it always moves the existing
frame onto the first node of the split anyway; the second branch may or
may not need to do that, but it has to move it just to be sure if it
needs to move it, which is a bit annoying...
Change-Id: Ib2fc69c2bd99dffa958f1620211ec657a8cc1be8
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index 6c7b07e4819b..d57b9b266a90 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -367,6 +367,7 @@ static void lcl_ChangeFootnoteRef( SwTextNode &rNode )
SwTextNode *SwTextNode::SplitContentNode(const SwPosition & rPos,
std::function<void (SwTextNode *, sw::mark::RestoreMode)> const*const pContentIndexRestore)
{
+ SwNode::Merge const eOldMergeFlag(GetRedlineMergeFlag());
bool parentIsOutline = IsOutline();
// create a node "in front" of me
@@ -480,6 +481,10 @@ SwTextNode *SwTextNode::SplitContentNode(const SwPosition & rPos,
{ // call before making frames and before RegisterToNode
(*pContentIndexRestore)(pNode, sw::mark::RestoreMode::NonFlys);
}
+ if (eOldMergeFlag != SwNode::Merge::None)
+ { // clear before making frames and before RegisterToNode
+ SetRedlineMergeFlag(SwNode::Merge::None);
+ } // now RegisterToNode will set merge flags in both nodes properly!
SwIterator<SwTextFrame, SwTextNode, sw::IteratorMode::UnwrapMulti> aIter(*this);
for (SwTextFrame* pFrame = aIter.First(); pFrame; pFrame = aIter.Next())
@@ -523,6 +528,7 @@ SwTextNode *SwTextNode::SplitContentNode(const SwPosition & rPos,
{
MoveTextAttr_To_AttrSet();
}
+ // in case there are frames, the RegisterToNode has set the merge flag
pNode->MakeFramesForAdjacentContentNode(*this);
lcl_ChangeFootnoteRef( *this );
if (pContentIndexRestore)
@@ -585,15 +591,61 @@ SwTextNode *SwTextNode::SplitContentNode(const SwPosition & rPos,
}
if (pContentIndexRestore)
- { // call before making frames
+ { // call before making frames and before RegisterToNode
(*pContentIndexRestore)(pNode, sw::mark::RestoreMode::NonFlys);
}
- if ( HasWriterListeners() )
+ std::vector<SwTextFrame*> frames;
+ SwIterator<SwTextFrame, SwTextNode, sw::IteratorMode::UnwrapMulti> aIter(*this);
+ for (SwTextFrame * pFrame = aIter.First(); pFrame; pFrame = aIter.Next())
+ {
+ frames.push_back(pFrame);
+ }
+ bool bNonMerged(false);
+ bool bRecreateThis(false);
+ for (SwTextFrame * pFrame : frames)
+ {
+ // sw_redlinehide: for this to work properly with hidden nodes,
+ // the frame needs to listen on them too.
+ // also: have to check the frame; this->GetRedlineMergeFlag()
+ // is None in case there's a delete redline inside the paragraph,
+ // but that could still result in a merged frame after split...
+ if (auto const pMergedPara = pFrame->GetMergedPara())
+ {
+ // Can't special case this == First here - that could (if
+ // both nodes are still merged by redline) lead to
+ // duplicate frames on "this".
+ // Update the extents with new node; also inits merge flag,
+ // so the MakeFramesForAdjacentContentNode below respects it
+ pFrame->RegisterToNode(*pNode);
+ if (!pFrame->GetMergedPara() ||
+ !pFrame->GetMergedPara()->listener.IsListeningTo(this))
+ {
+ // it's no longer listening - need to recreate frame
+ // (note this is idempotent, can be done once per frame)
+ SetRedlineMergeFlag(SwNode::Merge::None);
+ bRecreateThis = true;
+ }
+ }
+ else
+ {
+ bNonMerged = true;
+ }
+ }
+ assert(!(bNonMerged && bRecreateThis)); // 2 layouts not handled yet - maybe best to simply use the other branch then?
+ if (!frames.empty() && bNonMerged)
{
+ // the existing frame on "this" should have been updated by Cut
MakeFramesForAdjacentContentNode(*pNode);
+ lcl_ChangeFootnoteRef(*pNode);
+ }
+ else if (bRecreateThis)
+ {
+ assert(pNode->HasWriterListeners()); // was just moved there
+ pNode->MakeFramesForAdjacentContentNode(*this);
+ lcl_ChangeFootnoteRef(*this);
}
- lcl_ChangeFootnoteRef( *pNode );
+
if (pContentIndexRestore)
{ // call after making frames; listeners will take care of adding to the right frame
(*pContentIndexRestore)(pNode, sw::mark::RestoreMode::Flys);
@@ -601,6 +653,49 @@ SwTextNode *SwTextNode::SplitContentNode(const SwPosition & rPos,
}
{
+ // First
+ // -> First,NonFirst
+ // -> First,Hidden
+ // -> None,First
+ // Hidden
+ // -> Hidden,Hidden (if still inside merge rl)
+ // -> NonFirst,First (if redline was split)
+ // NonFirst
+ // -> NonFirst,First (if split after end of "incoming" redline &
+ // before start of "outgoing" redline)
+ // -> NonFirst,None (if split after end of "incoming" redline)
+ // -> NonFirst,Hidden (if split after start of "outgoing" redline)
+ // -> Hidden, NonFirst (if split before end of "incoming" redline)
+ // None
+ // -> None,None
+ // -> First,NonFirst (if splitting inside a delete redline)
+ SwNode::Merge const eFirst(pNode->GetRedlineMergeFlag());
+ SwNode::Merge const eSecond(GetRedlineMergeFlag());
+ switch (eOldMergeFlag)
+ {
+ case Merge::First:
+ assert((eFirst == Merge::First && eSecond == Merge::NonFirst)
+ || (eFirst == Merge::First && eSecond == Merge::Hidden)
+ || (eFirst == Merge::None && eSecond == Merge::First));
+ break;
+ case Merge::Hidden:
+ assert((eFirst == Merge::Hidden && eSecond == Merge::Hidden)
+ || (eFirst == Merge::NonFirst && eSecond == Merge::First));
+ break;
+ case Merge::NonFirst:
+ assert((eFirst == Merge::NonFirst && eSecond == Merge::First)
+ || (eFirst == Merge::NonFirst && eSecond == Merge::None)
+ || (eFirst == Merge::NonFirst && eSecond == Merge::Hidden)
+ || (eFirst == Merge::Hidden && eSecond == Merge::NonFirst));
+ break;
+ case Merge::None:
+ assert((eFirst == Merge::None && eSecond == Merge::None)
+ || (eFirst == Merge::First && eSecond == Merge::NonFirst));
+ break;
+ }
+ }
+
+ {
// Send Hint for PageDesc. This should be done in the Layout when
// pasting the frames, but that causes other problems that look
// expensive to solve.
commit 5d3d4854e4e263347c2d633c5cb9b3b6a3200a59
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Tue Aug 14 15:38:53 2018 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Tue Aug 14 15:38:53 2018 +0200
merge into "fix ordering of SplitNode usage of ContentIdxStore 2"
Change-Id: Ia6639e6bb2864cf518267f38eb805468e8de443b
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index 4d797a3a8d44..6c7b07e4819b 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -526,7 +526,7 @@ SwTextNode *SwTextNode::SplitContentNode(const SwPosition & rPos,
pNode->MakeFramesForAdjacentContentNode(*this);
lcl_ChangeFootnoteRef( *this );
if (pContentIndexRestore)
- { // call after making frames
+ { // call after making frames; listeners will take care of adding to the right frame
(*pContentIndexRestore)(pNode, sw::mark::RestoreMode::Flys);
}
}
@@ -595,7 +595,7 @@ SwTextNode *SwTextNode::SplitContentNode(const SwPosition & rPos,
}
lcl_ChangeFootnoteRef( *pNode );
if (pContentIndexRestore)
- { // call after making frames
+ { // call after making frames; listeners will take care of adding to the right frame
(*pContentIndexRestore)(pNode, sw::mark::RestoreMode::Flys);
}
}
commit 89b5b33af5120ec32277e7324185f87eb4f91fd9
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Tue Aug 14 11:20:46 2018 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Tue Aug 14 11:20:46 2018 +0200
sw_redlinehide_2: let's have MergedPara listen on hidden nodes
... in particular all SwTextNodes on the same nodes-array nesting level
as the first one; then UpdateMergedParaForInsert can handle insertions
there.
Change-Id: I59d12b87c1296c322ab1f21779240ec611919cb0
diff --git a/sw/source/core/layout/wsfrm.cxx b/sw/source/core/layout/wsfrm.cxx
index b7cde56120e1..1d308a50e937 100644
--- a/sw/source/core/layout/wsfrm.cxx
+++ b/sw/source/core/layout/wsfrm.cxx
@@ -4202,7 +4202,7 @@ static void UnHideRedlines(SwRootFrame & rLayout,
if (rLayout.IsHideRedlines())
{
assert(!pFrame->GetMergedPara() ||
- rNode.GetRedlineMergeFlag() == SwNode::Merge::NonFirst);
+ !rNode.IsCreateFrameWhenHidingRedlines());
if (rNode.IsCreateFrameWhenHidingRedlines())
{
{
diff --git a/sw/source/core/text/redlnitr.cxx b/sw/source/core/text/redlnitr.cxx
index 09480c84852e..58e42190f278 100644
--- a/sw/source/core/text/redlnitr.cxx
+++ b/sw/source/core/text/redlnitr.cxx
@@ -89,9 +89,23 @@ CheckParaRedlineMerge(SwTextFrame & rFrame, SwTextNode & rTextNode,
{
pNode->SetRedlineMergeFlag(SwNode::Merge::First);
} // else: was already set before
+ int nLevel(0);
for (sal_uLong j = pNode->GetIndex() + 1; j < pEnd->nNode.GetIndex(); ++j)
{
- pNode->GetNodes()[j]->SetRedlineMergeFlag(SwNode::Merge::Hidden);
+ SwNode *const pTmp(pNode->GetNodes()[j]);
+ if (pTmp->IsStartNode())
+ {
+ ++nLevel;
+ }
+ else if (pTmp->IsEndNode())
+ {
+ --nLevel;
+ }
+ else if (nLevel == 0 && pTmp->IsTextNode())
+ {
+ nodes.push_back(pTmp->GetTextNode());
+ }
+ pTmp->SetRedlineMergeFlag(SwNode::Merge::Hidden);
}
pNode = pEnd->nNode.GetNode().GetTextNode();
assert(pNode);
diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx
index f5aca5cc2c45..eba5ec65b400 100644
--- a/sw/source/core/text/txtfrm.cxx
+++ b/sw/source/core/text/txtfrm.cxx
@@ -724,6 +724,7 @@ namespace sw {
void UpdateMergedParaForInsert(MergedPara & rMerged,
SwTextNode const& rNode, sal_Int32 const nIndex, sal_Int32 const nLen)
{
+ assert(nLen); // can 0 happen?
assert(nIndex <= rNode.Len());
assert(nIndex + nLen <= rNode.Len());
assert(rMerged.pFirstNode->GetIndex() <= rNode.GetIndex() && rNode.GetIndex() <= rMerged.pLastNode->GetIndex());
@@ -754,7 +755,7 @@ void UpdateMergedParaForInsert(MergedPara & rMerged,
it->nEnd += nLen;
}
}
- else if (bFoundNode)
+ else if (rNode.GetIndex() < it->pNode->GetIndex() || bFoundNode)
{
itInsert = it;
break;
@@ -766,6 +767,10 @@ void UpdateMergedParaForInsert(MergedPara & rMerged,
{ // must be in a gap
rMerged.extents.emplace(itInsert, const_cast<SwTextNode*>(&rNode), nIndex, nIndex + nLen);
text.insert(nTFIndex, rNode.GetText().copy(nIndex, nLen));
+ if (rNode.GetIndex() < rMerged.pParaPropsNode->GetIndex())
+ { // text inserted before current para-props node
+ rMerged.pParaPropsNode = &rNode;
+ }
}
rMerged.mergedText = text.makeStringAndClear();
}
More information about the Libreoffice-commits
mailing list