summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <michael.stahl@allotropia.de>2022-05-18 18:31:14 +0200
committerCaolán McNamara <caolanm@redhat.com>2022-05-20 21:28:13 +0200
commite940b48617b29b0bccf0491a1aa5162a10c2616b (patch)
treebb1e9ed9bc55b73f858fd3cc4dbfc1e9b3993f08
parent24d8300c1b5a44c4b30c1e062b449df8507d80dc (diff)
sw_fieldmarkhide: fix wrong handling of SwInsText for fieldmarks
For redlines, typically DocumentContentOperationsManager::InsertString() will insert text, and it explicitly removes any redlines on the text that has been inserted, hence it is always visible - so effectively the sw::MergedPara is updated correctly. However for fieldmarks the situation is different, if the insertion happens inside of the part that is hidden in the layout, then it must not be inserted into the sw::MergedPara. Try to figure out which part(s) of a fieldmark the insertion position is in and ignore the inserted text as appropriate in SwTextFrame::SwClientNotify(). Change-Id: Ic5066b20e9609f50438ca64ac7d2cbd09baeef23 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134611 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.stahl@allotropia.de> (cherry picked from commit 288ad999090d3f88d87f52ff9b292f473f869601) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134616 Reviewed-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r--sw/inc/hints.hxx4
-rw-r--r--sw/source/core/attr/hints.cxx7
-rw-r--r--sw/source/core/doc/docbm.cxx28
-rw-r--r--sw/source/core/inc/txtfrm.hxx3
-rw-r--r--sw/source/core/text/txtfrm.cxx44
-rw-r--r--sw/source/core/txtnode/ndtxt.cxx7
-rw-r--r--sw/source/core/txtnode/txtedt.cxx2
7 files changed, 74 insertions, 21 deletions
diff --git a/sw/inc/hints.hxx b/sw/inc/hints.hxx
index afaf1d9022d9..9c37399f68f6 100644
--- a/sw/inc/hints.hxx
+++ b/sw/inc/hints.hxx
@@ -80,8 +80,10 @@ class SwInsText final : public SwMsgPoolItem
public:
sal_Int32 nPos;
sal_Int32 nLen;
+ bool isInsideFieldmarkCommand;
+ bool isInsideFieldmarkResult;
- SwInsText( sal_Int32 nP, sal_Int32 nL );
+ SwInsText(sal_Int32 nP, sal_Int32 nL, bool isInFMCommand, bool isInFMResult);
};
class SwDelChr final : public SwMsgPoolItem
diff --git a/sw/source/core/attr/hints.cxx b/sw/source/core/attr/hints.cxx
index 81685b777033..8016037bfdb8 100644
--- a/sw/source/core/attr/hints.cxx
+++ b/sw/source/core/attr/hints.cxx
@@ -31,8 +31,11 @@ SwFormatChg::SwFormatChg( SwFormat* pFormat )
{
}
-SwInsText::SwInsText( sal_Int32 nP, sal_Int32 nL )
- : SwMsgPoolItem( RES_INS_TXT ), nPos( nP ), nLen( nL )
+SwInsText::SwInsText(sal_Int32 const nP, sal_Int32 const nL, bool const isInFMCommand, bool const isInFMResult)
+ : SwMsgPoolItem( RES_INS_TXT )
+ , nPos( nP ), nLen( nL )
+ , isInsideFieldmarkCommand(isInFMCommand)
+ , isInsideFieldmarkResult(isInFMResult)
{
}
diff --git a/sw/source/core/doc/docbm.cxx b/sw/source/core/doc/docbm.cxx
index e3c87f5ea065..0b8f5a39d158 100644
--- a/sw/source/core/doc/docbm.cxx
+++ b/sw/source/core/doc/docbm.cxx
@@ -1979,4 +1979,32 @@ void DelBookmarks(
}
}
+namespace sw {
+
+SwInsText MakeSwInsText(SwTextNode & rNode, sal_Int32 const nPos, sal_Int32 const nLen)
+{
+ SwCursor cursor(SwPosition(rNode, nPos), nullptr);
+ bool isInsideFieldmarkCommand(false);
+ bool isInsideFieldmarkResult(false);
+ while (auto const*const pMark = rNode.GetDoc().getIDocumentMarkAccess()->getFieldmarkFor(*cursor.GetPoint()))
+ {
+ if (sw::mark::FindFieldSep(*pMark) < *cursor.GetPoint())
+ {
+ isInsideFieldmarkResult = true;
+ }
+ else
+ {
+ isInsideFieldmarkCommand = true;
+ }
+ *cursor.GetPoint() = pMark->GetMarkStart();
+ if (!cursor.Left(1))
+ {
+ break;
+ }
+ }
+ return SwInsText(nPos, nLen, isInsideFieldmarkCommand, isInsideFieldmarkResult);
+}
+
+} // namespace sw
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx
index f1016eb9a1e0..9550a0e31ab9 100644
--- a/sw/source/core/inc/txtfrm.hxx
+++ b/sw/source/core/inc/txtfrm.hxx
@@ -30,6 +30,7 @@ namespace com::sun::star::linguistic2 { class XHyphenatedWord; }
namespace sw::mark { class IMark; }
class SwCharRange;
+class SwInsText;
class SwTextNode;
class SwTextAttrEnd;
class SwTextFormatter;
@@ -146,6 +147,8 @@ bool IsMarkHintHidden(SwRootFrame const& rLayout,
void RecreateStartTextFrames(SwTextNode & rNode);
+auto MakeSwInsText(SwTextNode & rNode, sal_Int32 nPos, sal_Int32 nLen) -> SwInsText;
+
/**
* Decides if rTextNode has a numbering which has layout-level values (e.g. Arabic, but not
* none or bullets).
diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx
index 3c3c82b4e1ac..fb177841728d 100644
--- a/sw/source/core/text/txtfrm.cxx
+++ b/sw/source/core/text/txtfrm.cxx
@@ -2144,28 +2144,44 @@ void SwTextFrame::SwClientNotify(SwModify const& rModify, SfxHint const& rHint)
sal_Int32 const nNPos = static_cast<const SwInsText*>(pNew)->nPos;
sal_Int32 const nNLen = static_cast<const SwInsText*>(pNew)->nLen;
nPos = MapModelToView(&rNode, nNPos);
- nLen = TextFrameIndex(nNLen);
- if (m_pMergedPara)
+ // unlike redlines, inserting into fieldmark must be explicitly handled
+ bool isHidden(false);
+ switch (getRootFrame()->GetFieldmarkMode())
{
- UpdateMergedParaForInsert(*m_pMergedPara, true, rNode, nNPos, nNLen);
+ case sw::FieldmarkMode::ShowCommand:
+ isHidden = static_cast<const SwInsText*>(pNew)->isInsideFieldmarkResult;
+ break;
+ case sw::FieldmarkMode::ShowResult:
+ isHidden = static_cast<const SwInsText*>(pNew)->isInsideFieldmarkCommand;
+ break;
+ case sw::FieldmarkMode::ShowBoth: // just to avoid the warning
+ break;
}
- if( IsIdxInside( nPos, nLen ) )
+ if (!isHidden)
{
- if( !nLen )
+ nLen = TextFrameIndex(nNLen);
+ if (m_pMergedPara)
{
- // Refresh NumPortions even when line is empty!
- if( nPos )
- InvalidateSize();
+ UpdateMergedParaForInsert(*m_pMergedPara, true, rNode, nNPos, nNLen);
+ }
+ if( IsIdxInside( nPos, nLen ) )
+ {
+ if( !nLen )
+ {
+ // Refresh NumPortions even when line is empty!
+ if( nPos )
+ InvalidateSize();
+ else
+ Prepare();
+ }
else
- Prepare();
+ InvalidateRange_( SwCharRange( nPos, nLen ), nNLen );
}
- else
- InvalidateRange_( SwCharRange( nPos, nLen ), nNLen );
+ lcl_SetScriptInval( *this, nPos );
+ bSetFieldsDirty = true;
+ lcl_ModifyOfst(*this, nPos, nLen, &o3tl::operator+<sal_Int32, Tag_TextFrameIndex>);
}
lcl_SetWrong( *this, rNode, nNPos, nNLen, true );
- lcl_SetScriptInval( *this, nPos );
- bSetFieldsDirty = true;
- lcl_ModifyOfst(*this, nPos, nLen, &o3tl::operator+<sal_Int32, Tag_TextFrameIndex>);
}
break;
case RES_DEL_CHR:
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index 0b05bd0d5cb8..8268afe96ae0 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -2328,7 +2328,7 @@ OUString SwTextNode::InsertText( const OUString & rStr, const SwIndex & rIdx,
if ( HasWriterListeners() )
{ // send this before messing with hints, which will send RES_UPDATE_ATTR
- SwInsText aHint( aPos, nLen );
+ SwInsText const aHint(sw::MakeSwInsText(*this, aPos, nLen));
CallSwClientNotify(sw::LegacyModifyHint(nullptr, &aHint));
}
@@ -2536,7 +2536,8 @@ 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);
+ // (also ignore fieldmarks, the caller will recreate frames)
+ SwInsText const aInsHint(nDestStart, nLen, false, false);
pDest->TriggerNodeUpdate(sw::LegacyModifyHint(nullptr, &aInsHint));
const sw::MoveText aMoveHint(pDest, nDestStart, nTextStartIdx, nLen);
CallSwClientNotify(aMoveHint);
@@ -3757,7 +3758,7 @@ void SwTextNode::ReplaceText( const SwIndex& rStart, const sal_Int32 nDelLen,
if (sInserted.getLength())
{
- SwInsText aHint( nStartPos, sInserted.getLength() );
+ SwInsText const aHint(sw::MakeSwInsText(*this, nStartPos, sInserted.getLength()));
CallSwClientNotify(sw::LegacyModifyHint(nullptr, &aHint));
}
}
diff --git a/sw/source/core/txtnode/txtedt.cxx b/sw/source/core/txtnode/txtedt.cxx
index 9fabb33aa6e1..74ae7cf1d3c2 100644
--- a/sw/source/core/txtnode/txtedt.cxx
+++ b/sw/source/core/txtnode/txtedt.cxx
@@ -1995,7 +1995,7 @@ void SwTextNode::ReplaceTextOnly( sal_Int32 nPos, sal_Int32 nLen,
SwDelText aDelHint( nPos, nTLen );
CallSwClientNotify(sw::LegacyModifyHint(nullptr, &aDelHint));
- SwInsText aHint( nPos, nTLen );
+ SwInsText const aHint(sw::MakeSwInsText(*this, nPos, nTLen));
CallSwClientNotify(sw::LegacyModifyHint(nullptr, &aHint));
}