[Libreoffice-commits] core.git: Branch 'private/mst/sw_redlinehide_2' - 64 commits - solenv/gbuild sw/inc sw/qa sw/source
Libreoffice Gerrit user
logerrit at kemper.freedesktop.org
Thu Sep 6 11:16:57 UTC 2018
Rebased ref, commits from common ancestor:
commit 953021f6ad5f13f8f40544a5ddc8605ff4a7a046
Author: Michael Stahl <mstahl at redhat.com>
AuthorDate: Wed May 20 13:18:42 2015 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Sep 6 13:13:24 2018 +0200
gbuild: allow recording of CppunitTests and PythonTests too
Since these don't use soffice they need to be tweaked to use RR varaiable.
Unfortunately rr crashes in some CppunitTest so don't enable that now.
Unfortunately rr crashes in PythonTest.
Change-Id: I2143618fa2181e36b6aaeded43637cb3481f5e47
diff --git a/solenv/gbuild/CppunitTest.mk b/solenv/gbuild/CppunitTest.mk
index 1ac3b210e149..8e130d481802 100644
--- a/solenv/gbuild/CppunitTest.mk
+++ b/solenv/gbuild/CppunitTest.mk
@@ -63,6 +63,10 @@ gb_CppunitTest_VALGRINDTOOL += --vgdb=yes --vgdb-error=0
endif
endif
+ifneq ($(strip $(RR)),)
+gb_CppunitTest_RR := rr record
+endif
+
# defined by platform
# gb_CppunitTest_get_filename
gb_CppunitTest_RUNTIMEDEPS := $(call gb_Executable_get_runtime_dependencies,cppunittester)
@@ -134,7 +138,8 @@ else
$(gb_CppunitTest_malloc_check) \
$(if $(strip $(PYTHON_URE)),\
PYTHONDONTWRITEBYTECODE=1) \
- $(ICECREAM_RUN) $(gb_CppunitTest_GDBTRACE) $(gb_CppunitTest_VALGRINDTOOL) $(gb_CppunitTest_CPPTESTCOMMAND) \
+ $(ICECREAM_RUN) $(gb_CppunitTest_GDBTRACE) $(gb_CppunitTest_VALGRINDTOOL) $(gb_CppunitTest_RR) \
+ $(gb_CppunitTest_CPPTESTCOMMAND) \
$(call gb_LinkTarget_get_target,$(call gb_CppunitTest_get_linktarget,$*)) \
$(call gb_CppunitTest__make_args) "-env:CPPUNITTESTTARGET=$@" \
$(if $(gb_CppunitTest_POSTGDBTRACE), \
diff --git a/solenv/gbuild/PythonTest.mk b/solenv/gbuild/PythonTest.mk
index c579a34ea6d5..a2bac3819e02 100644
--- a/solenv/gbuild/PythonTest.mk
+++ b/solenv/gbuild/PythonTest.mk
@@ -55,7 +55,7 @@ else
$(if $(filter-out MACOSX WNT,$(OS_FOR_BUILD)),$(if $(DISABLE_GUI),, \
SAL_USE_VCLPLUGIN=svp \
)) \
- $(gb_CppunitTest_GDBTRACE) $(gb_CppunitTest_VALGRINDTOOL) \
+ $(gb_CppunitTest_GDBTRACE) $(gb_CppunitTest_VALGRINDTOOL) $(gb_CppunitTest_RR) \
$(gb_PythonTest_COMMAND) \
$(if $(PYTHON_TEST_NAME),$(PYTHON_TEST_NAME),$(MODULES)) \
$(if $(gb_CppunitTest__interactive),, \
commit b3e360ba7aa4091e5cafa7be32828d70245c0d6c
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Thu Sep 6 12:58:18 2018 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Sep 6 13:13:24 2018 +0200
sw_redlinehide_2: update flys and footnotes on redline ops
Re-use some code that is already used elsewhere; for the
UpdateFramesForAddDeleteRedline(), the same code as for switching
the layout to Hide mode should work, for
UpdateFramesForRemoveDeleteRedline() use the code that is used for
SwTextNode::SplitContentNode().
Change-Id: I97601bfb63478cc999cf7017da0225b2dc62ad37
diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx b/sw/source/core/doc/DocumentRedlineManager.cxx
index caec50025ef1..d27a579d3e43 100644
--- a/sw/source/core/doc/DocumentRedlineManager.cxx
+++ b/sw/source/core/doc/DocumentRedlineManager.cxx
@@ -140,25 +140,34 @@ void UpdateFramesForAddDeleteRedline(SwPaM const& rPam)
pFrame->SetMergedPara(nullptr);
pFrame->SetMergedPara(sw::CheckParaRedlineMerge(
*pFrame, rFirstNode, sw::FrameMode::Existing));
+ // the first node of the new redline is not necessarily the first
+ // node of the merged frame, there could be another redline nearby
+ sw::AddRemoveFlysAnchoredToFrameStartingAtNode(*pFrame, *pStartNode, nullptr);
}
}
void UpdateFramesForRemoveDeleteRedline(SwDoc & rDoc, SwPaM const& rPam)
{
+ SwTextNode *const pStartNode(rPam.Start()->nNode.GetNode().GetTextNode());
+ std::vector<SwTextFrame*> frames;
+ std::set<SwRootFrame*> layouts;
+ SwIterator<SwTextFrame, SwTextNode, sw::IteratorMode::UnwrapMulti> aIter(*pStartNode);
+ for (SwTextFrame * pFrame = aIter.First(); pFrame; pFrame = aIter.Next())
+ {
+ if (pFrame->getRootFrame()->IsHideRedlines())
+ {
+ frames.push_back(pFrame);
+ layouts.insert(pFrame->getRootFrame());
+ }
+ }
+ if (frames.empty())
+ {
+ return;
+ }
if (rPam.GetPoint()->nNode != rPam.GetMark()->nNode)
{
// first, call CheckParaRedlineMerge on the first paragraph,
// to init flag on new merge range (if any) + 1st node post the merge
- SwTextNode *const pStartNode(rPam.Start()->nNode.GetNode().GetTextNode());
- std::vector<SwTextFrame*> frames;
- SwIterator<SwTextFrame, SwTextNode, sw::IteratorMode::UnwrapMulti> aIter(*pStartNode);
- for (SwTextFrame * pFrame = aIter.First(); pFrame; pFrame = aIter.Next())
- {
- if (pFrame->getRootFrame()->IsHideRedlines())
- {
- frames.push_back(pFrame);
- }
- }
for (SwTextFrame * pFrame : frames)
{
if (auto const pMergedPara = pFrame->GetMergedPara())
@@ -173,11 +182,22 @@ void UpdateFramesForRemoveDeleteRedline(SwDoc & rDoc, SwPaM const& rPam)
}
// now start node until end of merge + 1 has proper flags; MakeFrames
// should pick up from the next node in need of frames by checking flags
- if (!frames.empty())
+ SwNodeIndex const start(*pStartNode, +1);
+ SwNodeIndex const end(rPam.End()->nNode, +1); // end is exclusive
+ // note: this will also create frames for all currently hidden flys
+ // both on first and non-first nodes because it calls AppendAllObjs
+ ::MakeFrames(&rDoc, start, end);
+ // re-use this to move flys that are now on the wrong frame, with end
+ // of redline as "second" node; the nodes between start and end should
+ // be complete with MakeFrames already
+ sw::MoveMergedFlysAndFootnotes(frames, *pStartNode,
+ *rPam.End()->nNode.GetNode().GetTextNode(), false);
+ }
+ else
+ { // recreate flys in the one node the hard way...
+ for (auto const& pLayout : layouts)
{
- SwNodeIndex const start(*pStartNode, +1);
- SwNodeIndex const end(rPam.End()->nNode, +1); // end is exclusive
- ::MakeFrames(&rDoc, start, end);
+ AppendAllObjs(rDoc.GetSpzFrameFormats(), pLayout);
}
}
}
diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx
index a52bf0f14fa0..0b19178734d2 100644
--- a/sw/source/core/inc/txtfrm.hxx
+++ b/sw/source/core/inc/txtfrm.hxx
@@ -105,12 +105,19 @@ TextFrameIndex UpdateMergedParaForDelete(MergedPara & rMerged,
bool isRealDelete,
SwTextNode const& rNode, sal_Int32 nIndex, sal_Int32 nLen);
+void MoveMergedFlysAndFootnotes(std::vector<SwTextFrame*> const& rFrames,
+ SwTextNode const& rFirstNode, SwTextNode & rSecondNode, bool);
+
void MoveDeletedPrevFrames(SwTextNode & rDeletedPrev, SwTextNode & rNode);
void CheckResetRedlineMergeFlag(SwTextNode & rNode, bool bRecreateMerged);
void UpdateFramesForAddDeleteRedline(SwPaM const& rPam);
void UpdateFramesForRemoveDeleteRedline(SwDoc & rDoc, SwPaM const& rPam);
+void AddRemoveFlysAnchoredToFrameStartingAtNode(
+ SwTextFrame & rFrame, SwTextNode & rTextNode,
+ std::set<sal_uLong> *pSkipped);
+
} // namespace sw
/// Represents the visualization of a paragraph. Typical upper is an
diff --git a/sw/source/core/layout/wsfrm.cxx b/sw/source/core/layout/wsfrm.cxx
index 3e6ff2d4f565..e6fbd7c553dc 100644
--- a/sw/source/core/layout/wsfrm.cxx
+++ b/sw/source/core/layout/wsfrm.cxx
@@ -4167,6 +4167,74 @@ void SwRootFrame::InvalidateAllObjPos()
}
}
+namespace sw {
+
+/// rTextNode is the first one of the "new" merge - if rTextNode isn't the same
+/// as MergedPara::pFirstNode, then nodes before rTextNode have their flys
+/// already properly attached, so only the other nodes need handling here.
+void AddRemoveFlysAnchoredToFrameStartingAtNode(
+ SwTextFrame & rFrame, SwTextNode & rTextNode,
+ std::set<sal_uLong> *const pSkipped)
+{
+ auto const pMerged(rFrame.GetMergedPara());
+ if (pMerged
+ // do this only *once*, for the *last* frame
+ // otherwise AppendObj would create multiple frames for fly-frames!
+ && !rFrame.GetFollow())
+ {
+ assert(pMerged->pFirstNode->GetIndex() <= rTextNode.GetIndex()
+ && rTextNode.GetIndex() <= pMerged->pLastNode->GetIndex());
+ // 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(rFrame.FindPageFrame());
+ std::vector<sw::Extent>::const_iterator iterFirst(pMerged->extents.begin());
+ std::vector<sw::Extent>::const_iterator iter(iterFirst);
+ SwTextNode const* pNode(pMerged->pFirstNode);
+ 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 if (rTextNode.GetIndex() < pNode->GetIndex())
+ {
+ // pNode's frame has been deleted by CheckParaRedlineMerge()
+ AppendObjsOfNode(&rTable,
+ pNode->GetIndex(), &rFrame, 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())
+ {
+ break;
+ }
+ pNode = iter->pNode;
+ iterFirst = iter;
+ }
+ }
+ }
+}
+
+} // namespace sw
+
static void UnHideRedlines(SwRootFrame & rLayout,
SwNodes & rNodes, SwNode const& rEndOfSectionNode,
std::set<sal_uLong> *const pSkipped)
@@ -4226,59 +4294,7 @@ static void UnHideRedlines(SwRootFrame & rLayout,
}
}
}
- 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 (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())
- {
- break;
- }
- pNode = iter->pNode;
- iterFirst = iter;
- }
- }
- }
+ sw::AddRemoveFlysAnchoredToFrameStartingAtNode(*pFrame, rTextNode, pSkipped);
}
}
else
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index a8d672dda16e..9c16f081eb69 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -365,13 +365,18 @@ static void lcl_ChangeFootnoteRef( SwTextNode &rNode )
}
}
-namespace {
+namespace sw {
// check if there are flys on the existing frames (now on "pNode")
// that need to be moved to the new frames of "this"
void MoveMergedFlysAndFootnotes(std::vector<SwTextFrame*> const& rFrames,
- SwTextNode const& rFirstNode, SwTextNode const& rSecondNode)
+ SwTextNode const& rFirstNode, SwTextNode & rSecondNode,
+ bool isSplitNode)
{
+ if (!isSplitNode)
+ {
+ lcl_ChangeFootnoteRef(rSecondNode);
+ }
int nLevel(0);
for (sal_uLong nIndex = rSecondNode.GetIndex() + 1; ; ++nIndex)
{
@@ -608,7 +613,7 @@ SwTextNode *SwTextNode::SplitContentNode(const SwPosition & rPos,
}
if (eOldMergeFlag != SwNode::Merge::None)
{
- MoveMergedFlysAndFootnotes(frames, *pNode, *this);
+ MoveMergedFlysAndFootnotes(frames, *pNode, *this, true);
}
}
else
@@ -739,7 +744,7 @@ SwTextNode *SwTextNode::SplitContentNode(const SwPosition & rPos,
if (bRecreateThis)
{
- MoveMergedFlysAndFootnotes(frames, *pNode, *this);
+ MoveMergedFlysAndFootnotes(frames, *pNode, *this, true);
}
}
commit 0c07bb358b1dc365e034687bcda1c973ce887b1c
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Wed Sep 5 13:03:02 2018 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Sep 6 13:13:24 2018 +0200
sw: remove window invalidation from SwRedlineTable::DeleteAndDestroyAll()
This is called in 2 situations, from ClearDoc() and from SwDoc dtor.
In the latter case, there is no window any more, and in the former case,
surely something else must have invalidated it already.
Change-Id: Ideecdeb145171a4dafbec50a04d4ec5aa2acab82
diff --git a/sw/source/core/doc/docredln.cxx b/sw/source/core/doc/docredln.cxx
index 56dfd57a82f9..6fe4e815dc69 100644
--- a/sw/source/core/doc/docredln.cxx
+++ b/sw/source/core/doc/docredln.cxx
@@ -605,9 +605,6 @@ void SwRedlineTable::Remove( size_type nP )
void SwRedlineTable::DeleteAndDestroyAll()
{
- if (maVector.empty())
- return;
- SwDoc *const pDoc = maVector.front()->GetDoc();
while (!maVector.empty())
{
auto const pRedline = maVector.back();
@@ -615,14 +612,6 @@ void SwRedlineTable::DeleteAndDestroyAll()
LOKRedlineNotification(RedlineNotification::Remove, pRedline);
delete pRedline;
}
- if (pDoc && !pDoc->IsInDtor())
- {
- SwViewShell* pSh(pDoc->getIDocumentLayoutAccess().GetCurrentViewShell() );
- if (pSh)
- {
- pSh->InvalidateWindows(SwRect(0, 0, SAL_MAX_INT32, SAL_MAX_INT32));
- }
- }
}
void SwRedlineTable::DeleteAndDestroy(size_type const nP)
commit bec70c9eb1fee59aa0632b34cd91727e32398d9b
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Tue Sep 4 18:59:01 2018 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Sep 6 13:13:24 2018 +0200
sw: SwDocTest: adjust this so it actually tests something interesting
* test more than 1 paragraph, by calling SplitNode()
* enable Undo, because that's the more usual situation
* remove one mode that is identical to the previous one
* use SwUnoCursor because plain SwCursor isn't corrected when nodes
are deleted
* create a selection before calling Delete functions
Change-Id: If406bd8c37b005e431fbaebe82f297b051da1ed3
diff --git a/sw/qa/core/uwriter.cxx b/sw/qa/core/uwriter.cxx
index 1a6d18d35c3a..cc95e3ce1da2 100644
--- a/sw/qa/core/uwriter.cxx
+++ b/sw/qa/core/uwriter.cxx
@@ -35,6 +35,7 @@
#include <breakit.hxx>
#include <doc.hxx>
+#include <IDocumentUndoRedo.hxx>
#include <IDocumentRedlineAccess.hxx>
#include <IDocumentFieldsAccess.hxx>
#include <IDocumentStatistics.hxx>
@@ -1067,7 +1068,6 @@ void SwDocTest::randomTest()
RedlineFlags::NONE,
RedlineFlags::On | RedlineFlags::ShowMask,
RedlineFlags::On | RedlineFlags::Ignore,
- RedlineFlags::On | RedlineFlags::Ignore | RedlineFlags::ShowMask,
RedlineFlags::On | RedlineFlags::ShowInsert,
RedlineFlags::On | RedlineFlags::ShowDelete
};
@@ -1077,6 +1077,7 @@ void SwDocTest::randomTest()
for( size_t rlm = 0; rlm < SAL_N_ELEMENTS(modes); rlm++ )
{
+ m_pDoc->GetIDocumentUndoRedo().DoUndo(true);
m_pDoc->ClearDoc();
// setup redlining
@@ -1085,15 +1086,31 @@ void SwDocTest::randomTest()
for( int i = 0; i < 2000; i++ )
{
- SwCursor aCrs(getRandomPosition(m_pDoc, i/20), nullptr);
- aCrs.SetMark();
+ std::shared_ptr<SwUnoCursor> pCrs(
+ m_pDoc->CreateUnoCursor(getRandomPosition(m_pDoc, i/20)));
switch (getRand (i < 50 ? 3 : 6)) {
// insert ops first
case 0: {
- if (!m_pDoc->getIDocumentContentOperations().InsertString(aCrs, getRandString())) {
-// fprintf (stderr, "failed to insert string !\n");
+ OUString const tmp(getRandString());
+ sal_Int32 current(0);
+ sal_Int32 nextBreak(tmp.indexOf('\n'));
+ do
+ {
+ sal_Int32 const len((nextBreak == -1 ? tmp.getLength() : nextBreak - current));
+ if (0 < len)
+ {
+ m_pDoc->getIDocumentContentOperations().InsertString(
+ *pCrs, tmp.copy(current, len));
+ }
+ if (nextBreak != -1)
+ {
+ m_pDoc->getIDocumentContentOperations().SplitNode(*pCrs->GetPoint(), false);
+ current = nextBreak + 1;
+ nextBreak = tmp.indexOf('\n', current);
+ }
}
+ while (nextBreak != -1);
break;
}
case 1:
@@ -1106,19 +1123,27 @@ void SwDocTest::randomTest()
// movement / deletion ops later
case 3: // deletion
+ pCrs->SetMark();
switch (getRand(6)) {
case 0:
- m_pDoc->getIDocumentContentOperations().DelFullPara(aCrs);
+ *pCrs->GetMark() = getRandomPosition(m_pDoc, 42);
+ m_pDoc->getIDocumentContentOperations().DelFullPara(*pCrs);
break;
case 1:
- m_pDoc->getIDocumentContentOperations().DeleteRange(aCrs);
+ *pCrs->GetMark() = getRandomPosition(m_pDoc, 42);
+ m_pDoc->getIDocumentContentOperations().DeleteRange(*pCrs);
break;
case 2:
- m_pDoc->getIDocumentContentOperations().DeleteAndJoin(aCrs, !!getRand(1));
+ *pCrs->GetMark() = getRandomPosition(m_pDoc, 42);
+ m_pDoc->getIDocumentContentOperations().DeleteAndJoin(*pCrs, !!getRand(1));
break;
case 3:
default:
- m_pDoc->getIDocumentContentOperations().Overwrite(aCrs, getRandString());
+ OUString const tmp(getRandString());
+ if (tmp.getLength())
+ {
+ m_pDoc->getIDocumentContentOperations().Overwrite(*pCrs, tmp);
+ }
break;
}
break;
@@ -1131,7 +1156,7 @@ void SwDocTest::randomTest()
SwMoveFlags::REDLINES |
SwMoveFlags::NO_DELFRMS;
SwPosition aTo(getRandomPosition(m_pDoc, i/10));
- m_pDoc->getIDocumentContentOperations().MoveRange(aCrs, aTo, nFlags);
+ m_pDoc->getIDocumentContentOperations().MoveRange(*pCrs, aTo, nFlags);
break;
}
commit c25acede28b623051f6ebe4e99362057aa8e7257
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Tue Sep 4 18:55:13 2018 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Sep 6 13:13:24 2018 +0200
sw: SwRedlineTable::DeleteAndDestroy() is surprisingly dangerous
At least with the randomised test, it can happen that deleting one
redline will recursively delete other redlines that are located in
the hidden content section of the redline, or at least try to and
crash because those have already been deleted before.
The callers will either delete 1 redline, or delete all of them
via DeleteAndDestroyAll(), so put a safer loop into
DeleteAndDestroyAll() and have DeleteAndDestroy() only delete 1.
Change-Id: I9c4225544a43a4a03f4eb7b6f56e7fe848c8ca54
diff --git a/sw/inc/docary.hxx b/sw/inc/docary.hxx
index 20871385fa97..940789ad262e 100644
--- a/sw/inc/docary.hxx
+++ b/sw/inc/docary.hxx
@@ -345,7 +345,7 @@ public:
void Remove( size_type nPos );
void Remove( const SwRangeRedline* p );
- void DeleteAndDestroy( size_type nPos, size_type nLen = 1 );
+ void DeleteAndDestroy(size_type nPos);
void DeleteAndDestroyAll();
void dumpAsXml(struct _xmlTextWriter* pWriter) const;
@@ -389,7 +389,7 @@ public:
void Insert( SwExtraRedline* p );
- void DeleteAndDestroy( sal_uInt16 nPos, sal_uInt16 nLen = 1 );
+ void DeleteAndDestroy( sal_uInt16 nPos);
void DeleteAndDestroyAll();
void dumpAsXml(struct _xmlTextWriter* pWriter) const;
diff --git a/sw/source/core/doc/docredln.cxx b/sw/source/core/doc/docredln.cxx
index 950526187efc..56dfd57a82f9 100644
--- a/sw/source/core/doc/docredln.cxx
+++ b/sw/source/core/doc/docredln.cxx
@@ -605,26 +605,32 @@ void SwRedlineTable::Remove( size_type nP )
void SwRedlineTable::DeleteAndDestroyAll()
{
- DeleteAndDestroy(0, size());
-}
-
-void SwRedlineTable::DeleteAndDestroy( size_type nP, size_type nL )
-{
- SwDoc* pDoc = nullptr;
- if( !nP && nL && nL == size() )
- pDoc = maVector.front()->GetDoc();
-
- for( vector_type::const_iterator it = maVector.begin() + nP; it != maVector.begin() + nP + nL; ++it )
+ if (maVector.empty())
+ return;
+ SwDoc *const pDoc = maVector.front()->GetDoc();
+ while (!maVector.empty())
+ {
+ auto const pRedline = maVector.back();
+ maVector.erase(maVector.back());
+ LOKRedlineNotification(RedlineNotification::Remove, pRedline);
+ delete pRedline;
+ }
+ if (pDoc && !pDoc->IsInDtor())
{
- LOKRedlineNotification(RedlineNotification::Remove, *it);
- delete *it;
+ SwViewShell* pSh(pDoc->getIDocumentLayoutAccess().GetCurrentViewShell() );
+ if (pSh)
+ {
+ pSh->InvalidateWindows(SwRect(0, 0, SAL_MAX_INT32, SAL_MAX_INT32));
+ }
}
- maVector.erase( maVector.begin() + nP, maVector.begin() + nP + nL );
+}
- SwViewShell* pSh;
- if( pDoc && !pDoc->IsInDtor() &&
- nullptr != ( pSh = pDoc->getIDocumentLayoutAccess().GetCurrentViewShell() ) )
- pSh->InvalidateWindows( SwRect( 0, 0, SAL_MAX_INT32, SAL_MAX_INT32 ) );
+void SwRedlineTable::DeleteAndDestroy(size_type const nP)
+{
+ auto const pRedline = maVector[nP];
+ maVector.erase(maVector.begin() + nP);
+ LOKRedlineNotification(RedlineNotification::Remove, pRedline);
+ delete pRedline;
}
SwRedlineTable::size_type SwRedlineTable::FindNextOfSeqNo( size_type nSttPos ) const
@@ -1883,7 +1889,7 @@ void SwExtraRedlineTable::Insert( SwExtraRedline* p )
//p->CallDisplayFunc();
}
-void SwExtraRedlineTable::DeleteAndDestroy( sal_uInt16 nPos, sal_uInt16 nLen )
+void SwExtraRedlineTable::DeleteAndDestroy(sal_uInt16 const nPos)
{
/*
SwDoc* pDoc = 0;
@@ -1891,10 +1897,8 @@ void SwExtraRedlineTable::DeleteAndDestroy( sal_uInt16 nPos, sal_uInt16 nLen )
pDoc = front()->GetDoc();
*/
- for( std::vector<SwExtraRedline*>::iterator it = m_aExtraRedlines.begin() + nPos; it != m_aExtraRedlines.begin() + nPos + nLen; ++it )
- delete *it;
-
- m_aExtraRedlines.erase( m_aExtraRedlines.begin() + nPos, m_aExtraRedlines.begin() + nPos + nLen );
+ delete m_aExtraRedlines[nPos];
+ m_aExtraRedlines.erase(m_aExtraRedlines.begin() + nPos);
/*
SwViewShell* pSh;
@@ -1906,7 +1910,12 @@ void SwExtraRedlineTable::DeleteAndDestroy( sal_uInt16 nPos, sal_uInt16 nLen )
void SwExtraRedlineTable::DeleteAndDestroyAll()
{
- DeleteAndDestroy(0, m_aExtraRedlines.size());
+ while (!m_aExtraRedlines.empty())
+ {
+ auto const pRedline = m_aExtraRedlines.back();
+ m_aExtraRedlines.pop_back();
+ delete pRedline;
+ }
}
SwExtraRedline::~SwExtraRedline()
commit ed81bd445dab56b1eaeea43254174fedb9e2c6e4
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Tue Sep 4 18:52:56 2018 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Sep 6 13:13:24 2018 +0200
sw: SwUndoOverwrite ctor shouldn't DeleteRedline if ...
... it's at the end of the node already, similar to CanGrouping().
Change-Id: Ic7c6f5caa6e69e9414112cb245db97fd5d79e87d
diff --git a/sw/source/core/undo/unovwr.cxx b/sw/source/core/undo/unovwr.cxx
index bee06b365dd4..d5652ce85e6e 100644
--- a/sw/source/core/undo/unovwr.cxx
+++ b/sw/source/core/undo/unovwr.cxx
@@ -43,6 +43,13 @@ SwUndoOverwrite::SwUndoOverwrite( SwDoc* pDoc, SwPosition& rPos,
: SwUndo(SwUndoId::OVERWRITE, pDoc),
pRedlSaveData( nullptr ), bGroup( false )
{
+ SwTextNode *const pTextNd = rPos.nNode.GetNode().GetTextNode();
+ assert(pTextNd);
+ sal_Int32 const nTextNdLen = pTextNd->GetText().getLength();
+
+ nSttNode = rPos.nNode.GetIndex();
+ nSttContent = rPos.nContent.GetIndex();
+
if( !pDoc->getIDocumentRedlineAccess().IsIgnoreRedline() && !pDoc->getIDocumentRedlineAccess().GetRedlineTable().empty() )
{
SwPaM aPam( rPos.nNode, rPos.nContent.GetIndex(),
@@ -52,16 +59,13 @@ SwUndoOverwrite::SwUndoOverwrite( SwDoc* pDoc, SwPosition& rPos,
{
pRedlSaveData.reset();
}
+ if (nSttContent < nTextNdLen)
+ {
+ pDoc->getIDocumentRedlineAccess().DeleteRedline(aPam, false, USHRT_MAX);
+ }
}
- nSttNode = rPos.nNode.GetIndex();
- nSttContent = rPos.nContent.GetIndex();
-
- SwTextNode* pTextNd = rPos.nNode.GetNode().GetTextNode();
- OSL_ENSURE( pTextNd, "Overwrite not in a TextNode?" );
-
bInsChar = true;
- sal_Int32 nTextNdLen = pTextNd->GetText().getLength();
if( nSttContent < nTextNdLen ) // no pure insert?
{
aDelStr += OUStringLiteral1( pTextNd->GetText()[nSttContent] );
commit 873b1ed61ac8992b77f820cf604fa2def4c5f722
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Tue Sep 4 16:21:56 2018 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Sep 6 13:13:24 2018 +0200
sw: SwUndoOverwrite::CanGrouping() should ignore redlines for inserted
... characters; if the character is inserted at the end of the node,
the aPam end position will have an invalid index Len()+1 and
the DeleteRedline() will correct existing redlines onto that index,
which will assert later.
Change-Id: Ia31cd1937385fb10fd284e7add61c39f96b917ab
diff --git a/sw/source/core/undo/unovwr.cxx b/sw/source/core/undo/unovwr.cxx
index e2fb76a19f63..bee06b365dd4 100644
--- a/sw/source/core/undo/unovwr.cxx
+++ b/sw/source/core/undo/unovwr.cxx
@@ -120,6 +120,7 @@ bool SwUndoOverwrite::CanGrouping( SwDoc* pDoc, SwPosition& rPos,
rCC.isLetterNumeric( aInsStr, aInsStr.getLength()-1 ) )
return false;
+ if (!bInsChar && rPos.nContent.GetIndex() < pDelTextNd->GetText().getLength())
{
SwRedlineSaveDatas aTmpSav;
SwPaM aPam( rPos.nNode, rPos.nContent.GetIndex(),
commit 6065be5754dab67455acaa35b2751212861820a8
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Tue Sep 4 14:34:03 2018 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Sep 6 13:13:24 2018 +0200
sw: avoid updating redlines to be empty in Overwrite()
The problem is that SwIndexReg::Update will correct a 1-character
redline in the middle of the newly-inserted part of the overwrite string
into a 0-length redline, which then a later SwTextNode::Update() will
correct in such a way that the whole thing becomes unsorted.
Just delete redlines in the entire overwrite range, which should help;
the aPam actually deletes them in the *last* character only which
seems rather unintentional anyway.
Change-Id: I61b6b312998e0779651d30f636312ef13556428c
diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx
index 1bb52e00e186..dc45775cbf25 100644
--- a/sw/source/core/doc/DocumentContentOperationsManager.cxx
+++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx
@@ -2357,8 +2357,12 @@ bool DocumentContentOperationsManager::MoveAndJoin( SwPaM& rPaM, SwPosition& rPo
return bRet;
}
+// Overwrite only uses the point of the PaM, the mark is ignored; characters
+// are replaced from point until the end of the node; at the end of the node,
+// characters are inserted.
bool DocumentContentOperationsManager::Overwrite( const SwPaM &rRg, const OUString &rStr )
{
+ assert(rStr.getLength());
SwPosition& rPt = *const_cast<SwPosition*>(rRg.GetPoint());
if( m_rDoc.GetAutoCorrExceptWord() ) // Add to AutoCorrect
{
@@ -2382,6 +2386,7 @@ bool DocumentContentOperationsManager::Overwrite( const SwPaM &rRg, const OUStri
? pNode->GetpSwpHints()->Count() : 0;
SwDataChanged aTmp( rRg );
SwIndex& rIdx = rPt.nContent;
+ sal_Int32 const nActualStart(rIdx.GetIndex());
sal_Int32 nStart = 0;
bool bOldExpFlg = pNode->IsIgnoreDontExpand();
@@ -2443,14 +2448,14 @@ bool DocumentContentOperationsManager::Overwrite( const SwPaM &rRg, const OUStri
if (!m_rDoc.GetIDocumentUndoRedo().DoesUndo() &&
!m_rDoc.getIDocumentRedlineAccess().IsIgnoreRedline() && !m_rDoc.getIDocumentRedlineAccess().GetRedlineTable().empty())
{
- SwPaM aPam( rPt.nNode, nStart, rPt.nNode, rPt.nContent.GetIndex() );
+ SwPaM aPam(rPt.nNode, nActualStart, rPt.nNode, rPt.nContent.GetIndex());
m_rDoc.getIDocumentRedlineAccess().DeleteRedline( aPam, true, USHRT_MAX );
}
else if( m_rDoc.getIDocumentRedlineAccess().IsRedlineOn() )
{
// FIXME: this redline is WRONG: there is no DELETE, and the skipped
// characters are also included in aPam
- SwPaM aPam( rPt.nNode, nStart, rPt.nNode, rPt.nContent.GetIndex() );
+ SwPaM aPam(rPt.nNode, nActualStart, rPt.nNode, rPt.nContent.GetIndex());
m_rDoc.getIDocumentRedlineAccess().AppendRedline( new SwRangeRedline( nsRedlineType_t::REDLINE_INSERT, aPam ), true);
}
diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx b/sw/source/core/doc/DocumentRedlineManager.cxx
index dc196aadc9ed..caec50025ef1 100644
--- a/sw/source/core/doc/DocumentRedlineManager.cxx
+++ b/sw/source/core/doc/DocumentRedlineManager.cxx
@@ -82,6 +82,8 @@ using namespace com::sun::star;
for(SwRangeRedline* j : rTable)
{
// check for empty redlines
+ // note: these can destroy sorting in SwTextNode::Update()
+ // if there's another one wihout mark on the same pos.
OSL_ENSURE( ( *(j->GetPoint()) != *(j->GetMark()) ) ||
( j->GetContentIdx() != nullptr ),
ERROR_PREFIX "empty redline" );
commit 393ead12c00824fb0145fab7dd0d4f48c954ae60
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Tue Sep 4 11:51:02 2018 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Sep 6 13:13:24 2018 +0200
sw_redlinehide_2: SwDocTest: avoid deleting selections that ...
... start or end outside of the body in randomTest().
Also, it would be more interesting to delete parts of the one
paragraph, not always the whole thing.
Change-Id: I782bcde24e0ed542c32ae50b50997555fd32813f
diff --git a/sw/qa/core/uwriter.cxx b/sw/qa/core/uwriter.cxx
index f0055671a58a..1a6d18d35c3a 100644
--- a/sw/qa/core/uwriter.cxx
+++ b/sw/qa/core/uwriter.cxx
@@ -1041,12 +1041,20 @@ getRandomPosition(SwDoc *pDoc, int /* nOffset */)
{
const SwPosition aPos(pDoc->GetNodes().GetEndOfContent());
size_t nNodes = aPos.nNode.GetNode().GetIndex() - aPos.nNode.GetNode().StartOfSectionIndex();
- size_t n = comphelper::rng::uniform_size_distribution(0, nNodes);
+ // exclude body start/end node
+ size_t n = comphelper::rng::uniform_size_distribution(1, nNodes - 1);
SwPaM pam(aPos);
for (sal_uLong i = 0; i < n; ++i)
{
pam.Move(fnMoveBackward, GoInNode);
}
+ SwTextNode *const pTextNode(pam.GetPoint()->nNode.GetNode().GetTextNode());
+ assert(pTextNode);
+ int n2 = comphelper::rng::uniform_int_distribution(0, pTextNode->Len());
+ for (sal_Int32 i = 0; i < n2; ++i)
+ {
+ pam.Move(fnMoveBackward, GoInContent);
+ }
return *pam.GetPoint();
}
commit 816461162da2c23915ef2f2e29209454e17e981d
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Mon Sep 3 18:07:29 2018 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Sep 6 13:13:24 2018 +0200
sw_redlinehide_2: update frames on redline ops
When Delete redline is created, removed, accepted, rejected & undo/redo
of all of these, update all the text frames so they're merged or not,
as required.
Change-Id: I08aa6aea270a50d19f4bda0caf016870a42a8dd3
diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx
index 11af40aaa469..1bb52e00e186 100644
--- a/sw/source/core/doc/DocumentContentOperationsManager.cxx
+++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx
@@ -44,6 +44,7 @@
#include <fmtcnct.hxx>
#include <SwStyleNameMapper.hxx>
#include <redline.hxx>
+#include <txtfrm.hxx>
#include <unocrsr.hxx>
#include <mvsave.hxx>
#include <ndtxt.hxx>
@@ -3619,6 +3620,11 @@ bool DocumentContentOperationsManager::DeleteAndJoinWithRedlineImpl( SwPaM & rPa
m_rDoc.getIDocumentRedlineAccess().AppendRedline( new SwRangeRedline( nsRedlineType_t::REDLINE_DELETE, rPam ), true );
m_rDoc.getIDocumentState().SetModified();
+ // sw_redlinehide: 2 reasons why this is needed:
+ // 1. it's the first redline in node => RedlineDelText was sent but ignored
+ // 2. redline spans multiple nodes => must merge text frames
+ sw::UpdateFramesForAddDeleteRedline(rPam);
+
if (pUndo)
{
m_rDoc.GetIDocumentUndoRedo().EndUndo( SwUndoId::EMPTY, nullptr );
diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx b/sw/source/core/doc/DocumentRedlineManager.cxx
index ad9c292810a1..dc196aadc9ed 100644
--- a/sw/source/core/doc/DocumentRedlineManager.cxx
+++ b/sw/source/core/doc/DocumentRedlineManager.cxx
@@ -19,6 +19,7 @@
#include <DocumentRedlineManager.hxx>
#include <frmfmt.hxx>
#include <rootfrm.hxx>
+#include <txtfrm.hxx>
#include <doc.hxx>
#include <IDocumentUndoRedo.hxx>
#include <IDocumentState.hxx>
@@ -113,6 +114,74 @@ using namespace com::sun::star;
#endif
+namespace sw {
+
+void UpdateFramesForAddDeleteRedline(SwPaM const& rPam)
+{
+ SwTextNode *const pStartNode(rPam.Start()->nNode.GetNode().GetTextNode());
+ std::vector<SwTextFrame*> frames;
+ SwIterator<SwTextFrame, SwTextNode, sw::IteratorMode::UnwrapMulti> aIter(*pStartNode);
+ for (SwTextFrame * pFrame = aIter.First(); pFrame; pFrame = aIter.Next())
+ {
+ if (pFrame->getRootFrame()->IsHideRedlines())
+ {
+ frames.push_back(pFrame);
+ }
+ }
+ for (SwTextFrame * pFrame : frames)
+ {
+ SwTextNode & rFirstNode(pFrame->GetMergedPara()
+ ? *pFrame->GetMergedPara()->pFirstNode
+ : *pStartNode);
+ assert(rFirstNode.GetIndex() <= pStartNode->GetIndex());
+ // clear old one first to avoid DelFrames confusing updates & asserts...
+ pFrame->SetMergedPara(nullptr);
+ pFrame->SetMergedPara(sw::CheckParaRedlineMerge(
+ *pFrame, rFirstNode, sw::FrameMode::Existing));
+ }
+}
+
+void UpdateFramesForRemoveDeleteRedline(SwDoc & rDoc, SwPaM const& rPam)
+{
+ if (rPam.GetPoint()->nNode != rPam.GetMark()->nNode)
+ {
+ // first, call CheckParaRedlineMerge on the first paragraph,
+ // to init flag on new merge range (if any) + 1st node post the merge
+ SwTextNode *const pStartNode(rPam.Start()->nNode.GetNode().GetTextNode());
+ std::vector<SwTextFrame*> frames;
+ SwIterator<SwTextFrame, SwTextNode, sw::IteratorMode::UnwrapMulti> aIter(*pStartNode);
+ for (SwTextFrame * pFrame = aIter.First(); pFrame; pFrame = aIter.Next())
+ {
+ if (pFrame->getRootFrame()->IsHideRedlines())
+ {
+ frames.push_back(pFrame);
+ }
+ }
+ for (SwTextFrame * pFrame : frames)
+ {
+ if (auto const pMergedPara = pFrame->GetMergedPara())
+ {
+ assert(pMergedPara->pFirstNode->GetIndex() <= pStartNode->GetIndex());
+ // clear old one first to avoid DelFrames confusing updates & asserts...
+ SwTextNode & rFirstNode(*pMergedPara->pFirstNode);
+ pFrame->SetMergedPara(nullptr);
+ pFrame->SetMergedPara(sw::CheckParaRedlineMerge(
+ *pFrame, rFirstNode, sw::FrameMode::Existing));
+ }
+ }
+ // now start node until end of merge + 1 has proper flags; MakeFrames
+ // should pick up from the next node in need of frames by checking flags
+ if (!frames.empty())
+ {
+ SwNodeIndex const start(*pStartNode, +1);
+ SwNodeIndex const end(rPam.End()->nNode, +1); // end is exclusive
+ ::MakeFrames(&rDoc, start, end);
+ }
+ }
+}
+
+} // namespace sw
+
namespace
{
inline bool IsPrevPos( const SwPosition & rPos1, const SwPosition & rPos2 )
@@ -294,6 +363,7 @@ namespace
{
bool bRet = true;
SwRangeRedline* pRedl = rArr[ rPos ];
+ SwDoc& rDoc = *pRedl->GetDoc();
SwPosition *pRStt = nullptr, *pREnd = nullptr;
SwComparePosition eCmp = SwComparePosition::Outside;
if( pSttRng && pEndRng )
@@ -309,7 +379,6 @@ namespace
{
case nsRedlineType_t::REDLINE_INSERT:
{
- SwDoc& rDoc = *pRedl->GetDoc();
const SwPosition *pDelStt = nullptr, *pDelEnd = nullptr;
bool bDelRedl = false;
switch( eCmp )
@@ -390,6 +459,8 @@ namespace
{
SwRangeRedline* pNew = nullptr;
bool bCheck = false, bReplace = false;
+ SwPaM const updatePaM(pSttRng ? *pSttRng : *pRedl->Start(),
+ pEndRng ? *pEndRng : *pRedl->End());
switch( eCmp )
{
@@ -473,6 +544,8 @@ namespace
rArr.Remove( pRedl );
rArr.Insert( pRedl );
}
+
+ sw::UpdateFramesForRemoveDeleteRedline(rDoc, updatePaM);
}
break;
diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx
index 10bde328c903..a52bf0f14fa0 100644
--- a/sw/source/core/inc/txtfrm.hxx
+++ b/sw/source/core/inc/txtfrm.hxx
@@ -108,6 +108,9 @@ TextFrameIndex UpdateMergedParaForDelete(MergedPara & rMerged,
void MoveDeletedPrevFrames(SwTextNode & rDeletedPrev, SwTextNode & rNode);
void CheckResetRedlineMergeFlag(SwTextNode & rNode, bool bRecreateMerged);
+void UpdateFramesForAddDeleteRedline(SwPaM const& rPam);
+void UpdateFramesForRemoveDeleteRedline(SwDoc & rDoc, SwPaM const& rPam);
+
} // namespace sw
/// Represents the visualization of a paragraph. Typical upper is an
diff --git a/sw/source/core/undo/unredln.cxx b/sw/source/core/undo/unredln.cxx
index 58d2de808363..fb1d30f9f953 100644
--- a/sw/source/core/undo/unredln.cxx
+++ b/sw/source/core/undo/unredln.cxx
@@ -25,6 +25,7 @@
#include <swundo.hxx>
#include <pam.hxx>
#include <ndtxt.hxx>
+#include <txtfrm.hxx>
#include <UndoCore.hxx>
#include <UndoDelete.hxx>
#include <strings.hrc>
@@ -106,6 +107,17 @@ void SwUndoRedline::UndoImpl(::sw::UndoRedoContext & rContext)
}
SetPaM(rPam, true);
}
+
+ // update frames after calling SetSaveData
+ if (dynamic_cast<SwUndoRedlineDelete*>(this))
+ {
+ sw::UpdateFramesForRemoveDeleteRedline(rDoc, rPam);
+ }
+ else if (dynamic_cast<SwUndoAcceptRedline*>(this)
+ || dynamic_cast<SwUndoRejectRedline*>(this))
+ { // (can't check here if there's a delete redline being accepted)
+ sw::UpdateFramesForAddDeleteRedline(rPam);
+ }
}
void SwUndoRedline::RedoImpl(::sw::UndoRedoContext & rContext)
@@ -191,6 +203,7 @@ void SwUndoRedlineDelete::RedoRedlineImpl(SwDoc & rDoc, SwPaM & rPam)
{
rDoc.getIDocumentRedlineAccess().AppendRedline( new SwRangeRedline(*mpRedlData, rPam), false );
}
+ sw::UpdateFramesForAddDeleteRedline(rPam);
}
bool SwUndoRedlineDelete::CanGrouping( const SwUndoRedlineDelete& rNext )
commit 458e35da41e84e38febb758b0ce163faebb00bd2
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Mon Sep 3 15:12:29 2018 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Sep 6 13:13:24 2018 +0200
sw_redlinehide_2: remove a pointless level of indentation
Change-Id: I82893951b6e227ab1ed6423e08a0370561482cd8
diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx
index d9b9250d617a..11af40aaa469 100644
--- a/sw/source/core/doc/DocumentContentOperationsManager.cxx
+++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx
@@ -3563,92 +3563,89 @@ DocumentContentOperationsManager::~DocumentContentOperationsManager()
bool DocumentContentOperationsManager::DeleteAndJoinWithRedlineImpl( SwPaM & rPam, const bool )
{
- OSL_ENSURE( m_rDoc.getIDocumentRedlineAccess().IsRedlineOn(), "DeleteAndJoinWithRedline: redline off" );
+ assert(m_rDoc.getIDocumentRedlineAccess().IsRedlineOn());
- {
- SwUndoRedlineDelete* pUndo = nullptr;
- RedlineFlags eOld = m_rDoc.getIDocumentRedlineAccess().GetRedlineFlags();
- m_rDoc.GetDocumentRedlineManager().checkRedlining( eOld );
+ SwUndoRedlineDelete* pUndo = nullptr;
+ RedlineFlags eOld = m_rDoc.getIDocumentRedlineAccess().GetRedlineFlags();
+ m_rDoc.GetDocumentRedlineManager().checkRedlining( eOld );
- auto & rDMA(*m_rDoc.getIDocumentMarkAccess());
- std::vector<std::unique_ptr<SwUndo>> MarkUndos;
- for (auto iter = rDMA.getAnnotationMarksBegin();
- iter != rDMA.getAnnotationMarksEnd(); )
+ auto & rDMA(*m_rDoc.getIDocumentMarkAccess());
+ std::vector<std::unique_ptr<SwUndo>> MarkUndos;
+ for (auto iter = rDMA.getAnnotationMarksBegin();
+ iter != rDMA.getAnnotationMarksEnd(); )
+ {
+ // tdf#111524 remove annotation marks that have their field
+ // characters deleted
+ SwPosition const& rEndPos((**iter).GetMarkEnd());
+ if (*rPam.Start() < rEndPos && rEndPos <= *rPam.End())
{
- // tdf#111524 remove annotation marks that have their field
- // characters deleted
- SwPosition const& rEndPos((**iter).GetMarkEnd());
- if (*rPam.Start() < rEndPos && rEndPos <= *rPam.End())
+ if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
{
- if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
- {
- MarkUndos.emplace_back(o3tl::make_unique<SwUndoDeleteBookmark>(**iter));
- }
- // iter is into annotation mark vector so must be dereferenced!
- rDMA.deleteMark(&**iter);
- // this invalidates iter, have to start over...
- iter = rDMA.getAnnotationMarksBegin();
+ MarkUndos.emplace_back(o3tl::make_unique<SwUndoDeleteBookmark>(**iter));
}
- else
- { // marks are sorted by start
- if (*rPam.End() < (**iter).GetMarkStart())
- {
- break;
- }
- ++iter;
+ // iter is into annotation mark vector so must be dereferenced!
+ rDMA.deleteMark(&**iter);
+ // this invalidates iter, have to start over...
+ iter = rDMA.getAnnotationMarksBegin();
+ }
+ else
+ { // marks are sorted by start
+ if (*rPam.End() < (**iter).GetMarkStart())
+ {
+ break;
}
+ ++iter;
}
+ }
- if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
+ if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
+ {
+ /* please don't translate -- for cultural reasons this comment is protected
+ until the redline implementation is finally fixed some day */
+ //JP 06.01.98: MUSS noch optimiert werden!!!
+ m_rDoc.getIDocumentRedlineAccess().SetRedlineFlags(
+ RedlineFlags::On | RedlineFlags::ShowInsert | RedlineFlags::ShowDelete);
+ pUndo = new SwUndoRedlineDelete( rPam, SwUndoId::DELETE );
+ const SwRewriter aRewriter = pUndo->GetRewriter();
+ m_rDoc.GetIDocumentUndoRedo().StartUndo( SwUndoId::DELETE, &aRewriter );
+ for (auto& it : MarkUndos)
{
-
- /* please don't translate -- for cultural reasons this comment is protected
- until the redline implementation is finally fixed some day */
- //JP 06.01.98: MUSS noch optimiert werden!!!
- m_rDoc.getIDocumentRedlineAccess().SetRedlineFlags(
- RedlineFlags::On | RedlineFlags::ShowInsert | RedlineFlags::ShowDelete );
- pUndo = new SwUndoRedlineDelete( rPam, SwUndoId::DELETE );
- const SwRewriter aRewriter = pUndo->GetRewriter();
- m_rDoc.GetIDocumentUndoRedo().StartUndo( SwUndoId::DELETE, &aRewriter );
- for (auto& it : MarkUndos)
- {
- m_rDoc.GetIDocumentUndoRedo().AppendUndo(it.release());
- }
- m_rDoc.GetIDocumentUndoRedo().AppendUndo( pUndo );
+ m_rDoc.GetIDocumentUndoRedo().AppendUndo(it.release());
}
+ m_rDoc.GetIDocumentUndoRedo().AppendUndo( pUndo );
+ }
- if ( *rPam.GetPoint() != *rPam.GetMark() )
- m_rDoc.getIDocumentRedlineAccess().AppendRedline( new SwRangeRedline( nsRedlineType_t::REDLINE_DELETE, rPam ), true );
- m_rDoc.getIDocumentState().SetModified();
+ if (*rPam.GetPoint() != *rPam.GetMark())
+ m_rDoc.getIDocumentRedlineAccess().AppendRedline( new SwRangeRedline( nsRedlineType_t::REDLINE_DELETE, rPam ), true );
+ m_rDoc.getIDocumentState().SetModified();
- if ( pUndo )
+ if (pUndo)
+ {
+ m_rDoc.GetIDocumentUndoRedo().EndUndo( SwUndoId::EMPTY, nullptr );
+ // ??? why the hell is the AppendUndo not below the
+ // CanGrouping, so this hideous cleanup wouldn't be necessary?
+ // bah, this is redlining, probably changing this would break it...
+ if (m_rDoc.GetIDocumentUndoRedo().DoesGroupUndo())
{
- m_rDoc.GetIDocumentUndoRedo().EndUndo( SwUndoId::EMPTY, nullptr );
- // ??? why the hell is the AppendUndo not below the
- // CanGrouping, so this hideous cleanup wouldn't be necessary?
- // bah, this is redlining, probably changing this would break it...
- if ( m_rDoc.GetIDocumentUndoRedo().DoesGroupUndo() )
+ SwUndo * const pLastUndo( m_rDoc.GetUndoManager().GetLastUndo() );
+ SwUndoRedlineDelete *const pUndoRedlineDel( dynamic_cast<SwUndoRedlineDelete*>(pLastUndo) );
+ if (pUndoRedlineDel)
{
- SwUndo * const pLastUndo( m_rDoc.GetUndoManager().GetLastUndo() );
- SwUndoRedlineDelete * const pUndoRedlineDel( dynamic_cast< SwUndoRedlineDelete* >( pLastUndo ) );
- if ( pUndoRedlineDel )
+ bool const bMerged = pUndoRedlineDel->CanGrouping( *pUndo );
+ if (bMerged)
{
- bool const bMerged = pUndoRedlineDel->CanGrouping( *pUndo );
- if ( bMerged )
- {
- ::sw::UndoGuard const undoGuard( m_rDoc.GetIDocumentUndoRedo() );
- SwUndo const* const pDeleted = m_rDoc.GetUndoManager().RemoveLastUndo();
- OSL_ENSURE( pDeleted == pUndo, "DeleteAndJoinWithRedlineImpl: "
- "undo removed is not undo inserted?" );
- delete pDeleted;
- }
+ ::sw::UndoGuard const undoGuard( m_rDoc.GetIDocumentUndoRedo() );
+ SwUndo const*const pDeleted = m_rDoc.GetUndoManager().RemoveLastUndo();
+ OSL_ENSURE( pDeleted == pUndo, "DeleteAndJoinWithRedlineImpl: "
+ "undo removed is not undo inserted?" );
+ delete pDeleted;
}
}
- //JP 06.01.98: MUSS noch optimiert werden!!!
- m_rDoc.getIDocumentRedlineAccess().SetRedlineFlags( eOld );
}
- return true;
+ //JP 06.01.98: MUSS noch optimiert werden!!!
+ m_rDoc.getIDocumentRedlineAccess().SetRedlineFlags( eOld );
}
+ return true;
}
bool DocumentContentOperationsManager::DeleteAndJoinImpl( SwPaM & rPam,
commit a17c75e87b5d0a35f824eda6a5ca65a667be8b9b
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Mon Sep 3 12:18:25 2018 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Sep 6 13:13:24 2018 +0200
sw_redlinehide_2: handle delete-without-redline inside of redline
The problem is that the SwInsText/SwDelText do not transfer the
"deleted-ness" of the text from one node to the other in the
SwTextFrame, so add a new hint that is sent after SwInsText & before
SwDelText to move the info that is in the extents vector.
Change-Id: I32d8dbe52a18556d8dc2c50a47246a6600fdb355
diff --git a/sw/inc/hints.hxx b/sw/inc/hints.hxx
index bee0ebb1c21a..bdf2eceaa8a6 100644
--- a/sw/inc/hints.hxx
+++ b/sw/inc/hints.hxx
@@ -31,6 +31,7 @@ class SwNodes;
class SwPageFrame;
class SwFrame;
class SwHistory;
+class SwTextNode;
// Base class for all Message-Hints:
// "Overhead" of SfxPoolItem is handled here
@@ -95,6 +96,18 @@ public:
namespace sw {
+/// text is moved into pDestNode
+class MoveText : public SfxHint
+{
+public:
+ SwTextNode * pDestNode;
+ sal_Int32 nDestStart;
+ sal_Int32 nSourceStart;
+ sal_Int32 nLen;
+
+ MoveText(SwTextNode *pD, sal_Int32 nD, sal_Int32 nS, sal_Int32 nL);
+};
+
/// new delete redline is created
class RedlineDelText : public SfxHint
{
diff --git a/sw/source/core/attr/hints.cxx b/sw/source/core/attr/hints.cxx
index 7c1ff2a40aec..7746058a7e1e 100644
--- a/sw/source/core/attr/hints.cxx
+++ b/sw/source/core/attr/hints.cxx
@@ -48,6 +48,11 @@ SwDelText::SwDelText( sal_Int32 nS, sal_Int32 nL )
namespace sw {
+MoveText::MoveText(SwTextNode *const pD, sal_Int32 const nD, sal_Int32 const nS, sal_Int32 const nL)
+ : pDestNode(pD), nDestStart(nD), nSourceStart(nS), nLen(nL)
+{
+}
+
RedlineDelText::RedlineDelText(sal_Int32 const nS, sal_Int32 const nL)
: nStart(nS), nLen(nL)
{
diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx
index dcb4a632ef58..ef792d95d9ea 100644
--- a/sw/source/core/text/txtfrm.cxx
+++ b/sw/source/core/text/txtfrm.cxx
@@ -1656,6 +1656,72 @@ static void lcl_ModifyOfst(SwTextFrame* pFrame, TextFrameIndex const nPos, TextF
}
}
+namespace {
+
+void UpdateMergedParaForMove(sw::MergedPara & rMerged,
+ SwTextFrame & rTextFrame,
+ bool & o_rbRecalcFootnoteFlag,
+ SwTextNode const& rDestNode,
+ SwTextNode const& rNode,
+ sal_Int32 const nDestStart,
+ sal_Int32 const nSourceStart,
+ sal_Int32 const nLen)
+{
+ std::vector<std::pair<sal_Int32, sal_Int32>> deleted;
+ sal_Int32 const nSourceEnd(nSourceStart + nLen);
+ sal_Int32 nLastEnd(0);
+ for (auto it = rMerged.extents.begin(); it != rMerged.extents.end(); ++it)
+ {
+ if (it->pNode == &rNode)
+ {
+ sal_Int32 const nStart(std::max(nLastEnd, nSourceStart));
+ sal_Int32 const nEnd(std::min(it->nStart, nSourceEnd));
+ if (nStart < nEnd)
+ {
+ deleted.emplace_back(nStart, nEnd);
+ }
+ nLastEnd = it->nEnd;
+ if (nSourceEnd <= it->nEnd)
+ {
+ break;
+ }
+ }
+ else if (rNode.GetIndex() < it->pNode->GetIndex())
+ {
+ break;
+ }
+ }
+ if (nLastEnd != rNode.Len() + nLen) // add nLen, string was removed already
+ {
+ assert(rNode.Len() == 0 || nLastEnd < nSourceEnd);
+ if (nLastEnd < nSourceEnd)
+ {
+ deleted.emplace_back(std::max(nLastEnd, nSourceStart), nSourceEnd);
+ }
+ }
+ if (!deleted.empty())
+ {
+ o_rbRecalcFootnoteFlag = true;
+ for (auto it : deleted)
+ {
+ sal_Int32 const nStart(it.first - nSourceStart + nDestStart);
+ TextFrameIndex const nDeleted = UpdateMergedParaForDelete(rMerged, false,
+ rDestNode, nStart, it.second - it.first);
+ assert(nDeleted == it.second - it.first);
+ assert(nDeleted);
+ // InvalidateRange/lcl_SetScriptInval was called sufficiently for SwInsText
+ lcl_SetWrong(rTextFrame, rDestNode, nStart, -nDeleted, false);
+ if (rTextFrame.HasFollow())
+ {
+ TextFrameIndex const nIndex(sw::MapModelToView(rMerged, &rDestNode, nStart));
+ lcl_ModifyOfst(&rTextFrame, nIndex, nDeleted); // FIXME why positive?
+ }
+ }
+ }
+}
+
+} // namespace
+
/**
* Related: fdo#56031 filter out attribute changes that don't matter for
* humans/a11y to stop flooding the destination mortal with useless noise
@@ -1675,6 +1741,7 @@ void SwTextFrame::SwClientNotify(SwModify const& rModify, SfxHint const& rHint)
{
SfxPoolItem const* pOld(nullptr);
SfxPoolItem const* pNew(nullptr);
+ sw::MoveText const* pMoveText(nullptr);
sw::RedlineDelText const* pRedlineDelText(nullptr);
sw::RedlineUnDelText const* pRedlineUnDelText(nullptr);
@@ -1683,6 +1750,10 @@ void SwTextFrame::SwClientNotify(SwModify const& rModify, SfxHint const& rHint)
pOld = pHint->m_pOld;
pNew = pHint->m_pNew;
}
+ else if (auto const pHt = dynamic_cast<sw::MoveText const*>(&rHint))
+ {
+ pMoveText = pHt;
+ }
else if (auto const pHynt = dynamic_cast<sw::RedlineDelText const*>(&rHint))
{
pRedlineDelText = pHynt;
@@ -1805,6 +1876,27 @@ void SwTextFrame::SwClientNotify(SwModify const& rModify, SfxHint const& rHint)
lcl_ModifyOfst( this, nPos, nLen );
}
}
+ else if (pMoveText)
+ {
+ if (m_pMergedPara
+ && m_pMergedPara->pFirstNode->GetIndex() <= pMoveText->pDestNode->GetIndex()
+ && pMoveText->pDestNode->GetIndex() <= m_pMergedPara->pLastNode->GetIndex())
+ { // if it's not 2 nodes in merged frame, assume the target node doesn't have frames at all
+ assert(std::abs(static_cast<long>(rNode.GetIndex()) - static_cast<long>(pMoveText->pDestNode->GetIndex())) == 1);
+ UpdateMergedParaForMove(*m_pMergedPara,
+ *this,
+ bRecalcFootnoteFlag,
+ *pMoveText->pDestNode, rNode,
+ pMoveText->nDestStart,
+ pMoveText->nSourceStart,
+ pMoveText->nLen);
+ }
+ else
+ {
+ // there is a situation where this is okay: from JoinNext, which will then call CheckResetRedlineMergeFlag, which will then create merged from scratch for this frame
+ // assert(!m_pMergedPara || !getRootFrame()->IsHideRedlines() || !pMoveText->pDestNode->getLayoutFrame(getRootFrame()));
+ }
+ }
else switch (nWhich)
{
case RES_LINENUMBER:
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index 5f5869905b89..a8d672dda16e 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -2503,6 +2503,8 @@ void SwTextNode::CutImpl( SwTextNode * const pDest, const SwIndex & rDestStart,
// want to find their anchor text frame in the follow chain
SwInsText aInsHint( nDestStart, nLen );
pDest->ModifyNotification( nullptr, &aInsHint );
+ sw::MoveText const moveHint(pDest, nDestStart, nTextStartIdx, nLen);
+ CallSwClientNotify(moveHint);
SwDelText aDelHint( nTextStartIdx, nLen );
ModifyNotification( nullptr, &aDelHint );
commit c680b7f425d007663cd3cbad35fdbce0d88bd694
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Fri Aug 31 19:14:58 2018 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Sep 6 13:13:24 2018 +0200
sw_redlinehide_2: call CompressRedlines later in DeleteRange*
DocumentContentOperationsManager::DeleteRange* functions should call
CompressRedlines after sw_JoinText, because otherwise if there's a join,
the FillSaveData in SwUndoDelete ctor will split redlines that contain
the selection into 2, and they won't be recombined although CanCombine
is true for them.
If you do 2 operations, then on Undo of the second, SetSaveData
will restore the previous redlines and join them into 1, but then it will
assert because it expects 2 redlines, pointlessly split.
Change-Id: I1df3f2205b4f16904f66b5af1f3b9f0ccbaf24a0
diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx
index f6a2562983cd..d9b9250d617a 100644
--- a/sw/source/core/doc/DocumentContentOperationsManager.cxx
+++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx
@@ -1763,6 +1763,12 @@ void DocumentContentOperationsManager::DeleteSection( SwNode *pNode )
void DocumentContentOperationsManager::DeleteRange( SwPaM & rPam )
{
lcl_DoWithBreaks( *this, rPam, &DocumentContentOperationsManager::DeleteRangeImpl );
+
+ if (!m_rDoc.getIDocumentRedlineAccess().IsIgnoreRedline()
+ && !m_rDoc.getIDocumentRedlineAccess().GetRedlineTable().empty())
+ {
+ m_rDoc.getIDocumentRedlineAccess().CompressRedlines();
+ }
}
bool DocumentContentOperationsManager::DelFullPara( SwPaM& rPam )
@@ -3667,6 +3673,12 @@ bool DocumentContentOperationsManager::DeleteAndJoinImpl( SwPaM & rPam,
::sw_JoinText( rPam, bJoinPrev );
}
+ if (!m_rDoc.getIDocumentRedlineAccess().IsIgnoreRedline()
+ && !m_rDoc.getIDocumentRedlineAccess().GetRedlineTable().empty())
+ {
+ m_rDoc.getIDocumentRedlineAccess().CompressRedlines();
+ }
+
return true;
}
@@ -3859,8 +3871,6 @@ bool DocumentContentOperationsManager::DeleteRangeImplImpl(SwPaM & rPam)
} while( false );
- if( !m_rDoc.getIDocumentRedlineAccess().IsIgnoreRedline() && !m_rDoc.getIDocumentRedlineAccess().GetRedlineTable().empty() )
- m_rDoc.getIDocumentRedlineAccess().CompressRedlines();
m_rDoc.getIDocumentState().SetModified();
return true;
commit 4f016edcbdbdb417f623450cc461aff5f1c04fd4
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Wed Aug 22 17:09:02 2018 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Sep 6 13:13:24 2018 +0200
sw_redlinehide_2: SwUndoDelete
This is problematic because of the calls to SplitNode.
Ideally we'd want the SplitNode to create merged frames already, but
that doesn't seem to be easy to achieve; several problems with this are:
1. the redlines are only restored at the end of UndoImpl
2. even if we store another set of SwRedlineSaveDatas right before the
Join (while preventing the first SwRedlineSaveDatas from deleting
them), and restore them by passing a closure to SplitNode, there
are complaints about empty redlines, and also this case isn't
handled properly:
f<delete start>o<redline start>o
b<redline end>a<redline start>r
b<redline end>a<delete end>z
So instead, let SplitNode create whatever frames it does, and fix it up
at the end manually on the start node's frames.
This necessitates delaying the creation of the frames on the moved nodes
until the end too.
Change-Id: I8ba2967659cc2ddbe6f7c40e0447d79601498ed6
diff --git a/sw/source/core/undo/undel.cxx b/sw/source/core/undo/undel.cxx
index 7e942b427ecb..f4f6c5559d85 100644
--- a/sw/source/core/undo/undel.cxx
+++ b/sw/source/core/undo/undel.cxx
@@ -41,6 +41,9 @@
#include <sfx2/app.hxx>
#include <fldbas.hxx>
#include <fmtfld.hxx>
+#include <frmtool.hxx>
+#include <txtfrm.hxx>
+#include <rootfrm.hxx>
#include <strings.hrc>
#include <vector>
@@ -763,6 +766,7 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
SwNodeIndex aIdx(rDoc.GetNodes(), nCalcStt);
SwNode* pInsNd = &aIdx.GetNode();
+ SwNode* pMovedNode = nullptr;
{ // code block so that SwPosition is detached when deleting a Node
SwPosition aPos( aIdx );
@@ -838,7 +842,6 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
++aPos.nNode;
}
}
- SwNode* pMovedNode = nullptr;
if( m_nSectDiff )
{
sal_uLong nMoveIndex = aPos.nNode.GetIndex();
@@ -866,7 +869,11 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
{
SwNodeRange aRange( *m_pMvStt, 0, *m_pMvStt, m_nNode );
SwNodeIndex aCopyIndex( aPos.nNode, -1 );
- rDoc.GetUndoManager().GetUndoNodes().Copy_( aRange, aPos.nNode );
+ rDoc.GetUndoManager().GetUndoNodes().Copy_(aRange, aPos.nNode,
+ // sw_redlinehide: delay creating frames: the flags on the
+ // nodes aren't necessarily up-to-date, and the redlines
+ // from m_pRedlSaveData aren't applied yet...
+ false);
if( m_nReplaceDummy )
{
@@ -889,9 +896,6 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
}
}
- if( pMovedNode )
- lcl_MakeAutoFrames(*rDoc.GetSpzFrameFormats(), pMovedNode->GetIndex());
-
if( m_aSttStr )
{
aPos.nNode = nSttNode - m_nNdDiff + ( m_bJoinNext ? 0 : m_nReplaceDummy );
@@ -958,6 +962,52 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
if( m_pRedlSaveData )
SetSaveData(rDoc, *m_pRedlSaveData);
+ if (m_aSttStr && (!m_bFromTableCopy || 0 != m_nNode))
+ {
+ // only now do we have redlines in the document again; fix up the split
+ // frames
+ SwTextNode *const pStartNode(aIdx.GetNodes()[nSttNode]->GetTextNode());
+ assert(pStartNode);
+ std::vector<SwTextFrame*> frames;
+ SwIterator<SwTextFrame, SwTextNode, sw::IteratorMode::UnwrapMulti> aIter(*pStartNode);
+ for (SwTextFrame* pFrame = aIter.First(); pFrame; pFrame = aIter.Next())
+ {
+ if (pFrame->getRootFrame()->IsHideRedlines())
+ {
+ frames.push_back(pFrame);
+ }
+ }
+ for (SwTextFrame * pFrame : frames)
+ {
+ // SplitNode could have moved the original frame to the start node
+ // & created a new one on end, or could have created new frame on
+ // start node... grab start node's frame and recreate MergedPara.
+ SwTextNode & rFirstNode(pFrame->GetMergedPara()
+ ? *pFrame->GetMergedPara()->pFirstNode
+ : *pStartNode);
+ assert(rFirstNode.GetIndex() <= pStartNode->GetIndex());
+ pFrame->SetMergedPara(sw::CheckParaRedlineMerge(
+ *pFrame, rFirstNode, sw::FrameMode::Existing));
+ // note: this may or may not delete frames on the end node
+ }
+ }
+
+ // create frames after SetSaveData has recreated redlines
+ if (0 != m_nNode)
+ {
+ // don't include end node in the range: it may have been merged already
+ // by the start node, or it may be merged by one of the moved nodes,
+ // but if it isn't merged, its current frame(s) should be good...
+ SwNodeIndex const start(rDoc.GetNodes(), nSttNode + (m_bDelFullPara ? 0 : 1));
+ SwNodeIndex const end(rDoc.GetNodes(), nEndNode);
+ ::MakeFrames(&rDoc, start, end);
+ }
+
+ if (pMovedNode)
+ { // probably better do this after creating all frames
+ lcl_MakeAutoFrames(*rDoc.GetSpzFrameFormats(), pMovedNode->GetIndex());
+ }
+
AddUndoRedoPaM(rContext, true);
}
commit a94756ddcb29e993c426f98e195c54879c99e0bf
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Wed Aug 22 15:09:59 2018 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Sep 6 13:13:24 2018 +0200
sw_redlinehide_2: something about Join
Change-Id: I047b6008c5f0bb6e79c63421a4dba09ba8cf3320
Todo: remember what i was thinking when i wrote this
diff --git a/sw/source/core/doc/docedt.cxx b/sw/source/core/doc/docedt.cxx
index 89454ea879ae..54c6a1c56e74 100644
--- a/sw/source/core/doc/docedt.cxx
+++ b/sw/source/core/doc/docedt.cxx
@@ -412,7 +412,13 @@ bool sw_JoinText( SwPaM& rPam, bool bJoinPrev )
rPam.GetBound( false ) = aAlphaPos;
}
// delete the Node, at last!
+ SwNode::Merge const eOldMergeFlag(pOldTextNd->GetRedlineMergeFlag());
+ if (eOldMergeFlag == SwNode::Merge::First)
+ {
+ sw::MoveDeletedPrevFrames(*pOldTextNd, *pTextNd);
+ }
pDoc->GetNodes().Delete( aOldIdx );
+ sw::CheckResetRedlineMergeFlag(*pTextNd, eOldMergeFlag == SwNode::Merge::NonFirst);
}
else
{
diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx
index 028c3605aa50..10bde328c903 100644
--- a/sw/source/core/inc/txtfrm.hxx
+++ b/sw/source/core/inc/txtfrm.hxx
@@ -105,6 +105,9 @@ TextFrameIndex UpdateMergedParaForDelete(MergedPara & rMerged,
bool isRealDelete,
SwTextNode const& rNode, sal_Int32 nIndex, sal_Int32 nLen);
+void MoveDeletedPrevFrames(SwTextNode & rDeletedPrev, SwTextNode & rNode);
+void CheckResetRedlineMergeFlag(SwTextNode & rNode, bool bRecreateMerged);
+
} // namespace sw
/// Represents the visualization of a paragraph. Typical upper is an
@@ -726,7 +729,7 @@ public:
static void repaintTextFrames( const SwTextNode& rNode );
- void RegisterToNode( SwTextNode& );
+ void RegisterToNode(SwTextNode &, bool isForceNodeAsFirst = false);
virtual void dumpAsXmlAttributes(xmlTextWriterPtr writer) const override;
};
diff --git a/sw/source/core/layout/ssfrm.cxx b/sw/source/core/layout/ssfrm.cxx
index 3a37ae92bc7f..8b8e7bd22610 100644
--- a/sw/source/core/layout/ssfrm.cxx
+++ b/sw/source/core/layout/ssfrm.cxx
@@ -440,14 +440,19 @@ SwContentFrame::~SwContentFrame()
{
}
-void SwTextFrame::RegisterToNode(SwTextNode & rNode)
+void SwTextFrame::RegisterToNode(SwTextNode & rNode, bool const isForceNodeAsFirst)
{
+ if (isForceNodeAsFirst && m_pMergedPara)
+ { // nothing registered here, in particular no redlines
+ assert(m_pMergedPara->pFirstNode->GetIndex() + 1 == rNode.GetIndex());
+ assert(!m_pMergedPara->pFirstNode->HasAnyIndex());
+ }
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())
+ (!isForceNodeAsFirst && 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
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index a826aabcf625..5f5869905b89 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -830,8 +830,51 @@ void SwTextNode::MoveTextAttr_To_AttrSet()
}
-namespace {
+namespace sw {
+
+ // None,Node->None
+ // None,First->First
+ // First,NonFirst->First
+ // NonFirst,First->NonFirst
+ // NonFirst,None->NonFirst
+
+void MoveDeletedPrevFrames(SwTextNode & rDeletedPrev, SwTextNode & rNode)
+{
+ std::vector<SwTextFrame*> frames;
+ SwIterator<SwTextFrame, SwTextNode, sw::IteratorMode::UnwrapMulti> aIter(rDeletedPrev);
+ for (SwTextFrame* pFrame = aIter.First(); pFrame; pFrame = aIter.Next())
+ {
+ frames.push_back(pFrame);
+ }
+ {
+ auto frames2(frames);
+ SwIterator<SwTextFrame, SwTextNode, sw::IteratorMode::UnwrapMulti> aIt(rNode);
+ for (SwTextFrame* pFrame = aIt.First(); pFrame; pFrame = aIt.Next())
+ {
+ auto const it(std::find(frames2.begin(), frames2.end(), pFrame));
+ assert(it != frames2.end());
+ frames2.erase(it);
+ }
+ assert(frames2.empty());
+ }
+ for (SwTextFrame * pFrame : frames)
+ {
+ pFrame->RegisterToNode(rNode, true);
+#if 0
+ if (pFrame->m_pMergedPara && pFrame->m_pMergedPara->pFirstNode == &rDeletedPrev && GetIndex() <= pFrame->m_pMergedPara->pLastNode->GetIndex())
+ {
+ pFrame->listeners.StopListening(&rDeletedPrev);
+ pFrame->m_pMergedPara->pFirstNode = &rNode;
+ &rNode.SetRedlineMergeFlag(SwNodes::Merge::First);
+ }
+#endif
+ }
+}
+
+ /// not only fix the flag; if prev is First the frame is actually deleted!!!
+ // if prev is First : must not delete frame but move it
+ // if prev is NonFirst : must delete frame (if this is First/None) & merge into prev
void CheckResetRedlineMergeFlag(SwTextNode & rNode, bool const bRecreateMerged)
{
if (bRecreateMerged)
@@ -850,6 +893,9 @@ void CheckResetRedlineMergeFlag(SwTextNode & rNode, bool const bRecreateMerged)
assert(rFirstNode.GetIndex() <= rNode.GetIndex());
pFrame->SetMergedPara(sw::CheckParaRedlineMerge(
*pFrame, rFirstNode, sw::FrameMode::Existing));
+ assert(pFrame->GetMergedPara());
+ assert(pFrame->GetMergedPara()->listener.IsListeningTo(&rNode));
+ assert(rNode.GetIndex() <= pFrame->GetMergedPara()->pLastNode->GetIndex());
}
}
else if (rNode.GetRedlineMergeFlag() != SwNode::Merge::None)
@@ -1055,6 +1101,10 @@ void SwTextNode::JoinPrev()
pDoc->CorrAbs( aIdx, SwPosition( *this ), nLen, true );
}
SwNode::Merge const eOldMergeFlag(pTextNode->GetRedlineMergeFlag());
+ if (eOldMergeFlag == SwNode::Merge::First)
+ {
+ sw::MoveDeletedPrevFrames(*pTextNode, *this);
+ }
rNds.Delete(aIdx);
SetWrong( pList, false );
SetGrammarCheck( pList3, false );
commit 7822345a4dae69e8aa019bacf0c73e89a9ff09d7
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Wed Aug 22 15:04:18 2018 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Sep 6 13:13:24 2018 +0200
sw_redlinehide_2: DelFrames is called for hidden nodes too now
Change-Id: I9933d8b8ee29bb4da74819d7d2350a5b2b04aa09
diff --git a/sw/source/core/layout/wsfrm.cxx b/sw/source/core/layout/wsfrm.cxx
index 8d8a4072bcdd..3e6ff2d4f565 100644
--- a/sw/source/core/layout/wsfrm.cxx
+++ b/sw/source/core/layout/wsfrm.cxx
@@ -4348,8 +4348,9 @@ static void UnHideRedlines(SwRootFrame & rLayout,
{
if (rNode.IsContentNode())
{
- // note: no-op for NonFirst nodes, only Hidden will delete
- static_cast<SwContentNode&>(rNode).DelFrames(&rLayout);
+ // note: nothing to do here, already done
+ auto const pFrame(static_cast<SwContentNode&>(rNode).getLayoutFrame(&rLayout));
+ assert(!pFrame || static_cast<SwTextFrame*>(pFrame)->GetMergedPara()->pFirstNode != &rNode);
}
else if (rNode.IsTableNode())
{
commit efea694ce62de1b2d4c7449ea21a8cb6d2f12d2c
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Wed Aug 22 13:26:18 2018 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Sep 6 13:13:24 2018 +0200
Revert "this looks like a wrong path..."
This reverts commit 391b6325117483c73f6fd0fb2286b37aaeeb46e4.
diff --git a/sw/inc/IDocumentContentOperations.hxx b/sw/inc/IDocumentContentOperations.hxx
index b3204109a8a0..fb4006334a15 100644
--- a/sw/inc/IDocumentContentOperations.hxx
+++ b/sw/inc/IDocumentContentOperations.hxx
@@ -22,7 +22,6 @@
#include <sal/types.h>
#include <rtl/ustring.hxx>
-#include <functional>
#include "swtypes.hxx"
class SwPaM;
@@ -38,9 +37,6 @@ class SwFrameFormat;
class SwDrawFrameFormat;
class SwFlyFrameFormat;
class SwNodeIndex;
-class SwTextNode;
-
-namespace sw { namespace mark { enum class RestoreMode; } }
namespace utl { class TransliterationWrapper; }
namespace svt { class EmbeddedObjectRef; }
@@ -190,8 +186,7 @@ public:
/** Split a node at rPos (implemented only for TextNode).
*/
- virtual bool SplitNode(const SwPosition &rPos, bool bChkTableStart,
- std::function<void ()> const* pRedlineRestore = nullptr) = 0;
+ virtual bool SplitNode(const SwPosition &rPos, bool bChkTableStart) = 0;
virtual bool AppendTextNode(SwPosition& rPos) = 0;
diff --git a/sw/inc/IDocumentRedlineAccess.hxx b/sw/inc/IDocumentRedlineAccess.hxx
index d6c44b24e680..a68af07fb707 100644
--- a/sw/inc/IDocumentRedlineAccess.hxx
+++ b/sw/inc/IDocumentRedlineAccess.hxx
@@ -180,7 +180,7 @@ public:
virtual bool DeleteRedline(
/*[in]*/const SwPaM& rPam,
/*[in]*/bool bSaveInUndo,
- /*[in]*/sal_uInt16 nDelType, bool bIgnoreJoining = false) = 0;
+ /*[in]*/sal_uInt16 nDelType) = 0;
virtual bool DeleteRedline(
/*[in]*/const SwStartNode& rSection,
diff --git a/sw/inc/undobj.hxx b/sw/inc/undobj.hxx
index afb4ecee7184..2e84ff9c1d6e 100644
--- a/sw/inc/undobj.hxx
+++ b/sw/inc/undobj.hxx
@@ -119,11 +119,9 @@ public:
bool IsDelBox() const;
- enum class DelRange { Ignore, Delete, DeleteNonJoining };
// Save and set Redline data.
static bool FillSaveData( const SwPaM& rRange, SwRedlineSaveDatas& rSData,
- DelRange eDelRange = DelRange::Delete,
- bool bCopyNext = true );
+ bool bDelRange = true, bool bCopyNext = true );
static bool FillSaveDataForFormat( const SwPaM& , SwRedlineSaveDatas& );
static void SetSaveData( SwDoc& rDoc, SwRedlineSaveDatas& rSData );
static bool HasHiddenRedlines( const SwRedlineSaveDatas& rSData );
diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx
index 688318420c85..f6a2562983cd 100644
--- a/sw/source/core/doc/DocumentContentOperationsManager.cxx
+++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx
@@ -2831,8 +2831,7 @@ SwDrawFrameFormat* DocumentContentOperationsManager::InsertDrawObj(
return pFormat;
}
-bool DocumentContentOperationsManager::SplitNode( const SwPosition &rPos, bool bChkTableStart,
- std::function<void ()> const*const pRedlineRestore)
+bool DocumentContentOperationsManager::SplitNode( const SwPosition &rPos, bool bChkTableStart )
{
SwContentNode *pNode = rPos.nNode.GetNode().GetContentNode();
if(nullptr == pNode)
@@ -2966,10 +2965,6 @@ bool DocumentContentOperationsManager::SplitNode( const SwPosition &rPos, bool b
m_rDoc.getIDocumentRedlineAccess().SplitRedline(aPam);
}
}
- if (pRedlineRestore)
- {
- (*pRedlineRestore)();
- }
}
});
pNode->GetTextNode()->SplitContentNode(rPos, &restoreFunc);
diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx b/sw/source/core/doc/DocumentRedlineManager.cxx
index beb8728b0c9a..ad9c292810a1 100644
--- a/sw/source/core/doc/DocumentRedlineManager.cxx
+++ b/sw/source/core/doc/DocumentRedlineManager.cxx
@@ -1923,7 +1923,7 @@ bool DocumentRedlineManager::SplitRedline( const SwPaM& rRange )
}
bool DocumentRedlineManager::DeleteRedline( const SwPaM& rRange, bool bSaveInUndo,
- sal_uInt16 const nDelType, bool const bIgnoreJoining)
+ sal_uInt16 nDelType )
{
if( RedlineFlags::IgnoreDeleteRedlines & meRedlineFlags ||
!rRange.HasMark() || *rRange.GetMark() == *rRange.GetPoint() )
@@ -1956,13 +1956,6 @@ bool DocumentRedlineManager::DeleteRedline( const SwPaM& rRange, bool bSaveInUnd
SwPosition* pRStt = pRedl->Start(),
* pREnd = pRStt == pRedl->GetPoint() ? pRedl->GetMark()
: pRedl->GetPoint();
- if (bIgnoreJoining && pRStt->nNode != pREnd->nNode
- && pRStt->nNode.GetIndex() <= pStt->nNode.GetIndex()
- && pEnd->nNode.GetIndex() <= pREnd->nNode.GetIndex())
- {
- continue; // ignore node-joining redline
- }
-
switch( ComparePosition( *pStt, *pEnd, *pRStt, *pREnd ) )
{
case SwComparePosition::Equal:
diff --git a/sw/source/core/inc/DocumentContentOperationsManager.hxx b/sw/source/core/inc/DocumentContentOperationsManager.hxx
index 55f15ad3b79e..c60676617b78 100644
--- a/sw/source/core/inc/DocumentContentOperationsManager.hxx
+++ b/sw/source/core/inc/DocumentContentOperationsManager.hxx
@@ -78,8 +78,7 @@ public:
SwFlyFrameFormat* InsertOLE(const SwPaM &rRg, const OUString& rObjName, sal_Int64 nAspect, const SfxItemSet* pFlyAttrSet,
const SfxItemSet* pGrfAttrSet) override;
- bool SplitNode(const SwPosition &rPos, bool bChkTableStart,
- std::function<void ()> const* pRedlineRestore = nullptr) override;
+ bool SplitNode(const SwPosition &rPos, bool bChkTableStart) override;
bool AppendTextNode(SwPosition& rPos) override;
diff --git a/sw/source/core/inc/DocumentRedlineManager.hxx b/sw/source/core/inc/DocumentRedlineManager.hxx
index d9cdf7ca3e59..f534cccea3fd 100644
--- a/sw/source/core/inc/DocumentRedlineManager.hxx
+++ b/sw/source/core/inc/DocumentRedlineManager.hxx
@@ -61,7 +61,7 @@ public:
virtual bool DeleteRedline(
/*[in]*/const SwPaM& rPam,
/*[in]*/bool bSaveInUndo,
- /*[in]*/sal_uInt16 nDelType, bool bIgnoreJoining = false) override;
+ /*[in]*/sal_uInt16 nDelType) override;
virtual bool DeleteRedline(
/*[in]*/const SwStartNode& rSection,
diff --git a/sw/source/core/inc/UndoDelete.hxx b/sw/source/core/inc/UndoDelete.hxx
index 699bc09c21b1..f22832b18d54 100644
--- a/sw/source/core/inc/UndoDelete.hxx
+++ b/sw/source/core/inc/UndoDelete.hxx
@@ -40,7 +40,6 @@ class SwUndoDelete
std::unique_ptr<SwNodeIndex> m_pMvStt; // Position of Nodes in UndoNodes-Array
boost::optional<OUString> m_aSttStr, m_aEndStr;
std::unique_ptr<SwRedlineSaveDatas> m_pRedlSaveData;
- std::unique_ptr<SwRedlineSaveDatas> m_pRedlSaveDataAtEnd;
std::shared_ptr< ::sfx2::MetadatableUndo > m_pMetadataUndoStart;
std::shared_ptr< ::sfx2::MetadatableUndo > m_pMetadataUndoEnd;
diff --git a/sw/source/core/undo/undel.cxx b/sw/source/core/undo/undel.cxx
index 0b7e93979016..7e942b427ecb 100644
--- a/sw/source/core/undo/undel.cxx
+++ b/sw/source/core/undo/undel.cxx
@@ -32,8 +32,6 @@
#include <swundo.hxx>
#include <pam.hxx>
#include <ndtxt.hxx>
-#include <txtfrm.hxx>
-#include <rootfrm.hxx>
#include <UndoCore.hxx>
#include <rolbck.hxx>
#include <poolfmt.hxx>
@@ -121,15 +119,11 @@ SwUndoDelete::SwUndoDelete(
bCacheComment = false;
SwDoc * pDoc = rPam.GetDoc();
- bool bMustDelete(false);
if( !pDoc->getIDocumentRedlineAccess().IsIgnoreRedline() && !pDoc->getIDocumentRedlineAccess().GetRedlineTable().empty() )
{
m_pRedlSaveData.reset(new SwRedlineSaveDatas);
-// if (!FillSaveData(rPam, *m_pRedlSaveData, false /*true in 2nd call*/))
- bMustDelete = rPam.GetPoint()->nNode != rPam.GetMark()->nNode;
-// if (!FillSaveData(rPam, *m_pRedlSaveData, rPam.GetPoint()->nNode == rPam.GetMark()->nNode))
- if (!FillSaveData(rPam, *m_pRedlSaveData, SwUndo::DelRange::DeleteNonJoining))
+ if( !FillSaveData( rPam, *m_pRedlSaveData ))
{
m_pRedlSaveData.reset();
}
@@ -216,7 +210,7 @@ SwUndoDelete::SwUndoDelete(
if( !pSttTextNd && !pEndTextNd )
--rPam.GetPoint()->nNode;
-// rPam.DeleteMark(); // the SPoint is in the selection
+ rPam.DeleteMark(); // the SPoint is in the selection
if( !pEndTextNd )
nEndContent = 0;
@@ -360,22 +354,6 @@ SwUndoDelete::SwUndoDelete(
// is a history necessary here at all?
if( pHistory && !pHistory->Count() )
pHistory.reset();
-
- assert(pDoc->getIDocumentRedlineAccess().IsIgnoreRedline()
- || pDoc->getIDocumentRedlineAccess().GetRedlineTable().empty()
- || (pStt->nNode != pEnd->nNode) == bMustDelete);
- if (pStt->nNode != pEnd->nNode
- && !pDoc->getIDocumentRedlineAccess().IsIgnoreRedline()
- && !pDoc->getIDocumentRedlineAccess().GetRedlineTable().empty())
- { // horrible duplication that SplitNode can undo
- m_pRedlSaveDataAtEnd.reset(new SwRedlineSaveDatas);
- if (!FillSaveData(rPam, *m_pRedlSaveDataAtEnd))
- {
- m_pRedlSaveDataAtEnd.reset();
- }
- }
-
- rPam.DeleteMark(); // now it is no longer a range...
}
bool SwUndoDelete::SaveContent( const SwPosition* pStt, const SwPosition* pEnd,
@@ -506,7 +484,7 @@ bool SwUndoDelete::CanGrouping( SwDoc* pDoc, const SwPaM& rDelPam )
{
SwRedlineSaveDatas aTmpSav;
- const bool bSaved = FillSaveData(rDelPam, aTmpSav, SwUndo::DelRange::Ignore);
+ const bool bSaved = FillSaveData( rDelPam, aTmpSav, false );
bool bOk = ( !m_pRedlSaveData && !bSaved ) ||
( m_pRedlSaveData && bSaved &&
@@ -810,7 +788,6 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
pInsNd = nullptr; // do not delete Node!
bool bNodeMove = 0 != m_nNode;
- bool bRedlAtEndRestored(false);
if( m_aEndStr )
{
@@ -826,17 +803,7 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
if( m_aSttStr && !m_bFromTableCopy )
{
sal_uLong nOldIdx = aPos.nNode.GetIndex();
- // call this before messing with frames in SplitNode
- std::function<void ()> restoreFunc(
- [&]()
- {
- if (m_pRedlSaveDataAtEnd)
- {
- SetSaveData(rDoc, *m_pRedlSaveDataAtEnd);
- }
- });
- rDoc.getIDocumentContentOperations().SplitNode(aPos, false, &restoreFunc);
- bRedlAtEndRestored = true;
+ rDoc.getIDocumentContentOperations().SplitNode( aPos, false );
// After the split all objects are anchored at the first
// paragraph, but the pHistory of the fly frame formats relies
// on anchoring at the start of the selection
@@ -845,11 +812,6 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
lcl_ReAnchorAtContentFlyFrames(*rDoc.GetSpzFrameFormats(), aPos, nOldIdx);
pTextNd = aPos.nNode.GetNode().GetTextNode();
}
- else if (m_pRedlSaveDataAtEnd)
- {
- SetSaveData(rDoc, *m_pRedlSaveDataAtEnd);
- bRedlAtEndRestored = true;
- }
if( pTextNd )
{
OUString const ins( pTextNd->InsertText(*m_aEndStr, aPos.nContent,
@@ -868,30 +830,14 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
if (nSttContent < pNd->GetText().getLength())
{
sal_uLong nOldIdx = aPos.nNode.GetIndex();
- // call this before messing with frames in SplitNode
- std::function<void ()> restoreFunc(
- [&]()
- {
- if (m_pRedlSaveDataAtEnd)
- {
- SetSaveData(rDoc, *m_pRedlSaveDataAtEnd);
- }
- });
- rDoc.getIDocumentContentOperations().SplitNode(aPos, false, &restoreFunc);
- bRedlAtEndRestored = true;
+ rDoc.getIDocumentContentOperations().SplitNode( aPos, false );
if( m_bBackSp )
lcl_ReAnchorAtContentFlyFrames(*rDoc.GetSpzFrameFormats(), aPos, nOldIdx);
}
else
- {
++aPos.nNode;
- }
}
}
- if (!bRedlAtEndRestored && m_pRedlSaveDataAtEnd)
- {
- SetSaveData(rDoc, *m_pRedlSaveDataAtEnd);
- }
SwNode* pMovedNode = nullptr;
if( m_nSectDiff )
{
@@ -920,23 +866,7 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
{
SwNodeRange aRange( *m_pMvStt, 0, *m_pMvStt, m_nNode );
SwNodeIndex aCopyIndex( aPos.nNode, -1 );
- rDoc.GetUndoManager().GetUndoNodes().Copy_(aRange, aPos.nNode,
- // SplitNode would have inited this flag; at this point,
- // either all these nodes are Hidden or all are None
- // (it might be that in the None case, the 2nd SetSaveData
- // below will introduce new redlines...)
- false);
-#if 0
- aPos.nNode.GetRedlineMergeFlag() == SwNode::Merge::None);
-#endif
- if (aPos.nNode.GetNode().GetRedlineMergeFlag() != SwNode::Merge::None)
- {
- for (sal_uLong i = aCopyIndex.GetIndex() + m_nNode; aCopyIndex.GetIndex() < i; --i)
- {
- rDoc.GetNodes()[i]->SetRedlineMergeFlag(SwNode::Merge::Hidden);
- }
- }
- // TODO after the SetSaveData we need to check again ???
+ rDoc.GetUndoManager().GetUndoNodes().Copy_( aRange, aPos.nNode );
if( m_nReplaceDummy )
{
@@ -1026,62 +956,8 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
if( pInsNd )
rDoc.GetNodes().Delete( aIdx );
if( m_pRedlSaveData )
- {
SetSaveData(rDoc, *m_pRedlSaveData);
-#if 0
- if (m_aSttStr && (!m_bFromTableCopy || 0 != m_nNode))
- {
- // only now do we have redlines in the document again; fix up the frame
- SwTextNode *const pStartNode(aIdx.GetNodes()[nSttNode]->GetTextNode());
- SwTextNode *const pEndNode(aIdx.GetNodes()[nEndNode]->GetTextNode());
- // FIXME we need to fetch frame of end node????
- // the MakeCopy already creates frames of intermediate nodes depending on their flag... problem: deletion was with redlines shown, restore with hidden
- assert(pNode);
- std::vector<SwTextFrame*> frames;
- SwIterator<SwTextFrame, SwTextNode, sw::IteratorMode::UnwrapMulti> aIter(*pEndNode);
- for (SwTextFrame* pFrame = aIter.First(); pFrame; pFrame = aIter.Next())
- {
- if (pFrame->getRootFrame()->IsHideRedlines())
- {
- frames.push_back(pFrame);
- }
- }
- for (SwTextFrame * pFrame : frames)
- {
-// this is not going to work if there are intermediate nodes with frames pFrame->RegisterToNode(*pStartNode);
-#if 0
- SwTextNode & rFirstNode(pFrame->GetMergedPara()
- ? *pFrame->GetMergedPara()->pFirstNode
- : *pStartNode);
- assert(rFirstNode.GetIndex() <= pNode->GetIndex());
- pFrame->SetMergedPara(sw::CheckParaRedlineMerge(
- *pFrame, rFirstNode, sw::FrameMode::Existing));
-#endif
- }
- }
-#endif
- }
-
- // create frames after SetSaveData has recreated redlines
- if (0 != m_nNode)
- {
- SwNodeIndex const start(rDoc.GetNodes(), nSttNode + 1);
- SwNodeIndex const end(rDoc.GetNodes(), nEndNode);
- ::MakeFrames(&rDoc, start, end);
- }
-
- // ... plan: let SplitNode do whatever;
- // don't create frames on moved nodes;
- // after SetSaveData, call CheckRedline... on start node,
- // then MakeFrames
- // ... what about end node ? will be either properly merged or properly un-merged after handling start node, so just include it in MakeFrames range.
- //
- // The interesting case is
- // f<delete start>o<redline start>o
- // b<redline end>a<redline start>r
- // b<redline end>a<delete end>z
-
AddUndoRedoPaM(rContext, true);
}
diff --git a/sw/source/core/undo/undobj.cxx b/sw/source/core/undo/undobj.cxx
index 94299badd501..5afbde167ad2 100644
--- a/sw/source/core/undo/undobj.cxx
+++ b/sw/source/core/undo/undobj.cxx
@@ -1378,7 +1378,7 @@ void SwRedlineSaveData::RedlineToDoc( SwPaM const & rPam )
bool SwUndo::FillSaveData(
const SwPaM& rRange,
SwRedlineSaveDatas& rSData,
- DelRange const eDelRange,
+ bool bDelRange,
bool bCopyNext )
{
rSData.clear();
@@ -1403,10 +1403,9 @@ bool SwUndo::FillSaveData(
rSData.push_back(std::unique_ptr<SwRedlineSaveData, o3tl::default_delete<SwRedlineSaveData>>(new SwRedlineSaveData(eCmpPos, *pStt, *pEnd, *pRedl, bCopyNext)));
}
}
- if (!rSData.empty() && eDelRange != DelRange::Ignore)
+ if( !rSData.empty() && bDelRange )
{
- rRange.GetDoc()->getIDocumentRedlineAccess().DeleteRedline(
- rRange, false, USHRT_MAX, eDelRange == DelRange::DeleteNonJoining);
+ rRange.GetDoc()->getIDocumentRedlineAccess().DeleteRedline( rRange, false, USHRT_MAX );
}
return !rSData.empty();
}
diff --git a/sw/source/core/undo/unovwr.cxx b/sw/source/core/undo/unovwr.cxx
index 6e6a64fbd52a..e2fb76a19f63 100644
--- a/sw/source/core/undo/unovwr.cxx
+++ b/sw/source/core/undo/unovwr.cxx
@@ -48,7 +48,7 @@ SwUndoOverwrite::SwUndoOverwrite( SwDoc* pDoc, SwPosition& rPos,
SwPaM aPam( rPos.nNode, rPos.nContent.GetIndex(),
rPos.nNode, rPos.nContent.GetIndex()+1 );
pRedlSaveData.reset( new SwRedlineSaveDatas );
- if (!FillSaveData( aPam, *pRedlSaveData, SwUndo::DelRange::Ignore))
+ if( !FillSaveData( aPam, *pRedlSaveData, false ))
{
pRedlSaveData.reset();
}
@@ -125,7 +125,7 @@ bool SwUndoOverwrite::CanGrouping( SwDoc* pDoc, SwPosition& rPos,
SwPaM aPam( rPos.nNode, rPos.nContent.GetIndex(),
rPos.nNode, rPos.nContent.GetIndex()+1 );
- const bool bSaved = FillSaveData(aPam, aTmpSav, SwUndo::DelRange::Ignore);
+ const bool bSaved = FillSaveData( aPam, aTmpSav, false );
bool bOk = ( !pRedlSaveData && !bSaved ) ||
( pRedlSaveData && bSaved &&
diff --git a/sw/source/core/undo/unredln.cxx b/sw/source/core/undo/unredln.cxx
index 9bdad5c20299..58d2de808363 100644
--- a/sw/source/core/undo/unredln.cxx
+++ b/sw/source/core/undo/unredln.cxx
@@ -58,8 +58,7 @@ SwUndoRedline::SwUndoRedline( SwUndoId nUsrId, const SwPaM& rRange )
sal_uLong nEndExtra = rDoc.GetNodes().GetEndOfExtras().GetIndex();
mpRedlSaveData.reset( new SwRedlineSaveDatas );
- if (!FillSaveData(rRange, *mpRedlSaveData, SwUndo::DelRange::Ignore,
- SwUndoId::REJECT_REDLINE != mnUserId))
+ if( !FillSaveData( rRange, *mpRedlSaveData, false, SwUndoId::REJECT_REDLINE != mnUserId ))
{
mpRedlSaveData.reset();
}
@@ -119,8 +118,7 @@ void SwUndoRedline::RedoImpl(::sw::UndoRedoContext & rContext)
if( mpRedlSaveData && mbHiddenRedlines )
{
sal_uLong nEndExtra = rDoc.GetNodes().GetEndOfExtras().GetIndex();
- FillSaveData(rPam, *mpRedlSaveData, SwUndo::DelRange::Ignore,
- SwUndoId::REJECT_REDLINE != mnUserId);
+ FillSaveData(rPam, *mpRedlSaveData, false, SwUndoId::REJECT_REDLINE != mnUserId );
nEndExtra -= rDoc.GetNodes().GetEndOfExtras().GetIndex();
nSttNode -= nEndExtra;
@@ -399,7 +397,7 @@ SwUndoCompDoc::SwUndoCompDoc( const SwRangeRedline& rRedl )
}
pRedlSaveData.reset( new SwRedlineSaveDatas );
- if (!FillSaveData( rRedl, *pRedlSaveData, SwUndo::DelRange::Ignore))
+ if( !FillSaveData( rRedl, *pRedlSaveData, false ))
{
pRedlSaveData.reset();
}
diff --git a/sw/source/core/undo/unsect.cxx b/sw/source/core/undo/unsect.cxx
index b225ae42235e..f17cae630316 100644
--- a/sw/source/core/undo/unsect.cxx
+++ b/sw/source/core/undo/unsect.cxx
@@ -88,7 +88,7 @@ SwUndoInsSection::SwUndoInsSection(
SetRedlineFlags( rDoc.getIDocumentRedlineAccess().GetRedlineFlags() );
}
m_pRedlineSaveData.reset( new SwRedlineSaveDatas );
- if (!FillSaveData( rPam, *m_pRedlineSaveData, SwUndo::DelRange::Ignore))
+ if( !FillSaveData( rPam, *m_pRedlineSaveData, false ))
m_pRedlineSaveData.reset( nullptr );
if( !rPam.HasMark() )
commit ecb94c409fb24003c79128fc063306e4b045872c
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Wed Aug 22 13:22:29 2018 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Sep 6 13:13:24 2018 +0200
this looks like a wrong path...
Change-Id: I81181ecb8fa3bae47e9dc0d2a5b49b92608629e6
diff --git a/sw/inc/IDocumentContentOperations.hxx b/sw/inc/IDocumentContentOperations.hxx
index fb4006334a15..b3204109a8a0 100644
--- a/sw/inc/IDocumentContentOperations.hxx
+++ b/sw/inc/IDocumentContentOperations.hxx
@@ -22,6 +22,7 @@
#include <sal/types.h>
#include <rtl/ustring.hxx>
+#include <functional>
#include "swtypes.hxx"
class SwPaM;
@@ -37,6 +38,9 @@ class SwFrameFormat;
class SwDrawFrameFormat;
class SwFlyFrameFormat;
class SwNodeIndex;
+class SwTextNode;
+
+namespace sw { namespace mark { enum class RestoreMode; } }
namespace utl { class TransliterationWrapper; }
namespace svt { class EmbeddedObjectRef; }
@@ -186,7 +190,8 @@ public:
/** Split a node at rPos (implemented only for TextNode).
*/
- virtual bool SplitNode(const SwPosition &rPos, bool bChkTableStart) = 0;
+ virtual bool SplitNode(const SwPosition &rPos, bool bChkTableStart,
+ std::function<void ()> const* pRedlineRestore = nullptr) = 0;
virtual bool AppendTextNode(SwPosition& rPos) = 0;
diff --git a/sw/inc/IDocumentRedlineAccess.hxx b/sw/inc/IDocumentRedlineAccess.hxx
index a68af07fb707..d6c44b24e680 100644
--- a/sw/inc/IDocumentRedlineAccess.hxx
+++ b/sw/inc/IDocumentRedlineAccess.hxx
@@ -180,7 +180,7 @@ public:
virtual bool DeleteRedline(
/*[in]*/const SwPaM& rPam,
/*[in]*/bool bSaveInUndo,
- /*[in]*/sal_uInt16 nDelType) = 0;
+ /*[in]*/sal_uInt16 nDelType, bool bIgnoreJoining = false) = 0;
virtual bool DeleteRedline(
/*[in]*/const SwStartNode& rSection,
diff --git a/sw/inc/undobj.hxx b/sw/inc/undobj.hxx
index 2e84ff9c1d6e..afb4ecee7184 100644
--- a/sw/inc/undobj.hxx
+++ b/sw/inc/undobj.hxx
@@ -119,9 +119,11 @@ public:
bool IsDelBox() const;
+ enum class DelRange { Ignore, Delete, DeleteNonJoining };
// Save and set Redline data.
static bool FillSaveData( const SwPaM& rRange, SwRedlineSaveDatas& rSData,
... etc. - the rest is truncated
More information about the Libreoffice-commits
mailing list