summaryrefslogtreecommitdiff
path: root/sw/source/core/text/txtfrm.cxx
diff options
context:
space:
mode:
authorMichael Stahl <Michael.Stahl@cib.de>2018-08-17 17:52:52 +0200
committerMichael Stahl <Michael.Stahl@cib.de>2018-09-19 10:18:27 +0200
commit4faf5ce05cfbbdc8df4c55135ac70d7c35527109 (patch)
treeab257d5f8c94368b382543ed262923a3cc33f5db /sw/source/core/text/txtfrm.cxx
parentf8cde353240758ce1b40302d56c2373e99bb8a55 (diff)
sw_redlinehide_2: invalidate when delete redline goes away
Add another new hint sw::RedlineUnDelText; the main use case is to send it from DocumentRedlineManager::DeleteRedline() so the view is updated accordingly. Change-Id: Ia490116588dc8d3c695ec83c0c2ce8497736f76e
Diffstat (limited to 'sw/source/core/text/txtfrm.cxx')
-rw-r--r--sw/source/core/text/txtfrm.cxx124
1 files changed, 110 insertions, 14 deletions
diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx
index 4a0ce81e2cb4..212fc0b40e28 100644
--- a/sw/source/core/text/txtfrm.cxx
+++ b/sw/source/core/text/txtfrm.cxx
@@ -722,15 +722,23 @@ SwTextFrame::~SwTextFrame()
namespace sw {
-static void UpdateMergedParaForInsert(MergedPara & rMerged,
+// 1. if real insert => correct nStart/nEnd for full nLen
+// 2. if rl un-delete => do not correct nStart/nEnd but just include un-deleted
+static TextFrameIndex UpdateMergedParaForInsert(MergedPara & rMerged,
+ bool const isRealInsert,
SwTextNode const& rNode, sal_Int32 const nIndex, sal_Int32 const nLen)
{
- assert(nLen); // can 0 happen?
+ assert(!isRealInsert || nLen); // can 0 happen? yes, for redline in empty node
assert(nIndex <= rNode.Len());
assert(nIndex + nLen <= rNode.Len());
assert(rMerged.pFirstNode->GetIndex() <= rNode.GetIndex() && rNode.GetIndex() <= rMerged.pLastNode->GetIndex());
+ if (!nLen)
+ {
+ return TextFrameIndex(0);
+ }
OUStringBuffer text(rMerged.mergedText);
sal_Int32 nTFIndex(0);
+ sal_Int32 nInserted(0);
bool bInserted(false);
bool bFoundNode(false);
auto itInsert(rMerged.extents.end());
@@ -738,22 +746,75 @@ static void UpdateMergedParaForInsert(MergedPara & rMerged,
{
if (it->pNode == &rNode)
{
- bFoundNode = true;
- if (it->nStart <= nIndex && nIndex <= it->nEnd)
- { // note: this can happen only once
- text.insert(nTFIndex + (nIndex - it->nStart),
- rNode.GetText().copy(nIndex, nLen));
- it->nEnd += nLen;
- bInserted = true;
+ if (isRealInsert)
+ {
+ bFoundNode = true;
+ if (it->nStart <= nIndex && nIndex <= it->nEnd)
+ { // note: this can happen only once
+ text.insert(nTFIndex + (nIndex - it->nStart),
+ rNode.GetText().copy(nIndex, nLen));
+ it->nEnd += nLen;
+ nInserted = nLen;
+ assert(!bInserted);
+ bInserted = true;
+ }
+ else if (nIndex < it->nStart)
+ {
+ if (itInsert == rMerged.extents.end())
+ {
+ itInsert = it;
+ }
+ it->nStart += nLen;
+ it->nEnd += nLen;
+ }
}
- else if (nIndex < it->nStart)
+ else
{
- if (itInsert == rMerged.extents.end())
+ assert(it == rMerged.extents.begin() || (it-1)->pNode != &rNode || (it-1)->nEnd < nIndex);
+ if (nIndex + nLen < it->nStart)
{
itInsert = it;
+ break;
+ }
+ if (nIndex < it->nStart)
+ {
+ text.insert(nTFIndex,
+ rNode.GetText().copy(nIndex, it->nStart - nIndex));
+ nInserted += it->nStart - nIndex;
+ it->nStart = nIndex;
+ bInserted = true;
+ }
+ assert(it->nStart <= nIndex);
+ if (nIndex <= it->nEnd)
+ {
+ nTFIndex += it->nEnd - it->nStart;
+ while (it->nEnd < nIndex + nLen)
+ {
+ auto *const pNext(
+ (it+1) != rMerged.extents.end() && (it+1)->pNode == it->pNode
+ ? &*(it+1)
+ : nullptr);
+ if (pNext && pNext->nStart <= nIndex + nLen)
+ {
+ text.insert(nTFIndex,
+ rNode.GetText().copy(it->nEnd, pNext->nStart - it->nEnd));
+ nTFIndex += pNext->nStart - it->nEnd;
+ nInserted += pNext->nStart - it->nEnd;
+ pNext->nStart = it->nStart;
+ it = rMerged.extents.erase(it);
+ }
+ else
+ {
+ text.insert(nTFIndex,
+ rNode.GetText().copy(it->nEnd, nIndex + nLen - it->nEnd));
+ nTFIndex += nIndex + nLen - it->nEnd;
+ nInserted += nIndex + nLen - it->nEnd;
+ it->nEnd = nIndex + nLen;
+ }
+ }
+ bInserted = true;
+ break;
}
- it->nStart += nLen;
- it->nEnd += nLen;
}
}
else if (rNode.GetIndex() < it->pNode->GetIndex() || bFoundNode)
@@ -768,12 +829,14 @@ static 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));
+ nInserted = nLen;
if (rNode.GetIndex() < rMerged.pParaPropsNode->GetIndex())
{ // text inserted before current para-props node
rMerged.pParaPropsNode = &rNode;
}
}
rMerged.mergedText = text.makeStringAndClear();
+ return TextFrameIndex(nInserted);
}
// 1. if real delete => correct nStart/nEnd for full nLen
@@ -1621,6 +1684,7 @@ void SwTextFrame::SwClientNotify(SwModify const& rModify, SfxHint const& rHint)
SfxPoolItem const* pOld(nullptr);
SfxPoolItem const* pNew(nullptr);
sw::RedlineDelText const* pRedlineDelText(nullptr);
+ sw::RedlineUnDelText const* pRedlineUnDelText(nullptr);
if (auto const pHint = dynamic_cast<sw::LegacyModifyHint const*>(&rHint))
{
@@ -1631,6 +1695,10 @@ void SwTextFrame::SwClientNotify(SwModify const& rModify, SfxHint const& rHint)
{
pRedlineDelText = pHynt;
}
+ else if (auto const pHnt = dynamic_cast<sw::RedlineUnDelText const*>(&rHint))
+ {
+ pRedlineUnDelText = pHnt;
+ }
else
{
assert(!"unexpected hint");
@@ -1717,6 +1785,34 @@ void SwTextFrame::SwClientNotify(SwModify const& rModify, SfxHint const& rHint)
}
}
}
+ else if (pRedlineUnDelText)
+ {
+ if (m_pMergedPara)
+ {
+ sal_Int32 const nNPos = pRedlineUnDelText->nStart;
+ sal_Int32 const nNLen = pRedlineUnDelText->nLen;
+ nPos = MapModelToView(&rNode, nNPos);
+ nLen = UpdateMergedParaForInsert(*m_pMergedPara, false, rNode, nNPos, nNLen);
+ if (IsIdxInside(nPos, nLen))
+ {
+ if (!nLen)
+ {
+ // Refresh NumPortions even when line is empty!
+ if (nPos)
+ InvalidateSize();
+ else
+ Prepare();
+ }
+ else
+ InvalidateRange_( SwCharRange( nPos, nLen ), nNLen );
+ }
+ lcl_SetWrong( *this, rNode, nNPos, nNLen, false );
+ lcl_SetScriptInval( *this, nPos );
+ bSetFieldsDirty = true;
+ if (HasFollow())
+ lcl_ModifyOfst( this, nPos, nLen );
+ }
+ }
else switch (nWhich)
{
case RES_LINENUMBER:
@@ -1733,7 +1829,7 @@ void SwTextFrame::SwClientNotify(SwModify const& rModify, SfxHint const& rHint)
nLen = TextFrameIndex(nNLen);
if (m_pMergedPara)
{
- UpdateMergedParaForInsert(*m_pMergedPara, rNode, nNPos, nNLen);
+ UpdateMergedParaForInsert(*m_pMergedPara, true, rNode, nNPos, nNLen);
}
if( IsIdxInside( nPos, nLen ) )
{