summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLászló Németh <nemeth@numbertext.org>2020-11-03 20:52:38 +0100
committerLászló Németh <nemeth@numbertext.org>2020-11-05 08:29:08 +0100
commitac84cf7dda4a5150ff23e112ee16f00b8de8ec7c (patch)
tree1c44f930650a95547b0d8091afecade2e288ae99
parent2e32f4ed5af16a68c97a50806a42ffa2d10f1d7a (diff)
tdf#83419 sw change tracking: fix bad autocorrect
In Show Changes mode, automatic sentence capitalization (or correction of two initial capitals) could change the first (or second) letter of a tracked deletion in sentence (or word) starting position. Change-Id: I9146a5c78abf69e758661fcf17f42564bd87a73e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/105273 Tested-by: Jenkins Reviewed-by: László Németh <nemeth@numbertext.org>
-rw-r--r--sw/qa/extras/uiwriter/data/redline-autocorrect.fodt24
-rw-r--r--sw/qa/extras/uiwriter/uiwriter.cxx65
-rw-r--r--sw/source/core/edit/acorrect.cxx30
3 files changed, 119 insertions, 0 deletions
diff --git a/sw/qa/extras/uiwriter/data/redline-autocorrect.fodt b/sw/qa/extras/uiwriter/data/redline-autocorrect.fodt
new file mode 100644
index 000000000000..ce874d299a8f
--- /dev/null
+++ b/sw/qa/extras/uiwriter/data/redline-autocorrect.fodt
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:officeooo="http://openoffice.org/2009/office" office:version="1.2" office:mimetype="application/vnd.oasis.opendocument.text" xmlns:dc="http://purl.org/dc/elements/1.1/">
+ <office:styles>
+ <style:style style:name="Standard" style:family="paragraph" style:class="text"/>
+ <style:default-style style:family="paragraph">
+ <style:text-properties fo:language="en" fo:country="US"/>
+ </style:default-style>
+ </office:styles>
+ <office:body>
+ <office:text>
+ <text:tracked-changes text:track-changes="false">
+ <text:changed-region xml:id="ct94099223789984" text:id="ct94099223789984">
+ <text:deletion>
+ <office:change-info>
+ <dc:creator>NL</dc:creator>
+ <dc:date>2020-11-03T19:19:05</dc:date>
+ </office:change-info>
+ </text:deletion>
+ </text:changed-region>
+ </text:tracked-changes>
+ <text:p text:style-name="P1"><text:change-start text:change-id="ct94099223789984"/>t<text:change-end text:change-id="ct94099223789984"/>s</text:p>
+ </office:text>
+ </office:body>
+</office:document>
diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx
index 2e23f46b3314..aca558b923a6 100644
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -390,6 +390,7 @@ public:
void testInconsistentBookmark();
void testInsertLongDateFormat();
void testSpellOnlineParameter();
+ void testRedlineAutoCorrect();
#if HAVE_FEATURE_PDFIUM
void testInsertPdf();
#endif
@@ -616,6 +617,7 @@ public:
CPPUNIT_TEST(testTdf133589);
CPPUNIT_TEST(testInsertLongDateFormat);
CPPUNIT_TEST(testSpellOnlineParameter);
+ CPPUNIT_TEST(testRedlineAutoCorrect);
#if HAVE_FEATURE_PDFIUM
CPPUNIT_TEST(testInsertPdf);
#endif
@@ -7586,6 +7588,69 @@ void SwUiWriterTest::testSpellOnlineParameter()
CPPUNIT_ASSERT_EQUAL(!bSet, pOpt->IsOnlineSpell());
}
+void SwUiWriterTest::testRedlineAutoCorrect()
+{
+ SwDoc* pDoc = createDoc("redline-autocorrect.fodt");
+
+ dispatchCommand(mxComponent, ".uno:GoToEndOfDoc", {});
+
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+
+ // show tracked deletion
+ RedlineFlags const nMode(pWrtShell->GetRedlineFlags() | RedlineFlags::On);
+ CPPUNIT_ASSERT(nMode & (RedlineFlags::ShowDelete | RedlineFlags::ShowInsert));
+ pWrtShell->SetRedlineFlags(nMode);
+ CPPUNIT_ASSERT(nMode & RedlineFlags::ShowDelete);
+
+ SwAutoCorrect corr(*SvxAutoCorrCfg::Get().GetAutoCorrect());
+ pWrtShell->AutoCorrect(corr, ' ');
+ sal_uLong nIndex = pWrtShell->GetCursor()->GetNode().GetIndex();
+
+ // tdf#83419 This was "Ts " removing the deletion of "t" silently by sentence capitalization
+ OUString sReplaced("ts ");
+ CPPUNIT_ASSERT_EQUAL(sReplaced,
+ static_cast<SwTextNode*>(pDoc->GetNodes()[nIndex])->GetText());
+
+ // hide delete redlines
+ pWrtShell->SetRedlineFlags(nMode & ~RedlineFlags::ShowDelete);
+
+ // repeat it with not visible redlining
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+
+ pWrtShell->AutoCorrect(corr, ' ');
+ nIndex = pWrtShell->GetCursor()->GetNode().GetIndex();
+
+ sReplaced = "S ";
+ CPPUNIT_ASSERT_EQUAL(sReplaced, static_cast<SwTextNode*>(pDoc->GetNodes()[nIndex])->GetText());
+
+ // show delete redlines
+ pWrtShell->SetRedlineFlags(nMode);
+ nIndex = pWrtShell->GetCursor()->GetNode().GetIndex();
+
+ // This still keep the tracked deletion, capitalize only the visible text "s"
+ sReplaced = "tS ";
+ CPPUNIT_ASSERT_EQUAL(sReplaced, static_cast<SwTextNode*>(pDoc->GetNodes()[nIndex])->GetText());
+
+ // repeat it with visible redlining and word auto replacement of "tset"
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+
+ pWrtShell->Insert("et");
+ pWrtShell->AutoCorrect(corr, ' ');
+ // This was "Ttest" removing the tracked deletion silently.
+ sReplaced = "ttest ";
+ nIndex = pWrtShell->GetCursor()->GetNode().GetIndex();
+ CPPUNIT_ASSERT_EQUAL(sReplaced, static_cast<SwTextNode*>(pDoc->GetNodes()[nIndex])->GetText());
+
+ // tracked deletions after the correction point doesn't affect autocorrect
+ dispatchCommand(mxComponent, ".uno:GoToStartOfDoc", {});
+ pWrtShell->Insert("a");
+ pWrtShell->AutoCorrect(corr, ' ');
+ sReplaced = "A ttest ";
+ nIndex = pWrtShell->GetCursor()->GetNode().GetIndex();
+ CPPUNIT_ASSERT_EQUAL(sReplaced, static_cast<SwTextNode*>(pDoc->GetNodes()[nIndex])->GetText());
+}
+
void SwUiWriterTest::testTdf108423()
{
SwDoc* pDoc = createDoc();
diff --git a/sw/source/core/edit/acorrect.cxx b/sw/source/core/edit/acorrect.cxx
index fad647eee8c0..7ae0a778a59b 100644
--- a/sw/source/core/edit/acorrect.cxx
+++ b/sw/source/core/edit/acorrect.cxx
@@ -226,6 +226,36 @@ bool SwAutoCorrDoc::ReplaceRange( sal_Int32 nPos, sal_Int32 nSourceLength, const
}
}
+ // tdf#83419 avoid bad autocorrect with visible redlines
+ // e.g. replacing the first letter of the tracked deletion
+ // with its capitalized (and not deleted) version.
+ if ( bDoReplace )
+ {
+ const OUString& rOrigText = pos.first->GetText();
+ // GetRedlineText() doesn't contain dummy characters, so handle them
+ sal_Int32 nLengthCorrection = 0;
+ for (sal_Int32 n = 0; n < rOrigText.getLength(); ++n)
+ {
+ sal_Unicode const Char = rOrigText[n];
+ if ( CH_TXTATR_BREAKWORD == Char || CH_TXTATR_INWORD == Char )
+ ++nLengthCorrection;
+ }
+ sal_Int32 nDelChars = rOrigText.getLength() - nLengthCorrection -
+ pos.first->GetRedlineText().getLength();
+ // Are there tracked deletions before the correction point?
+ if ( nDelChars > 0 && pos.first->GetRedlineText().compareTo( nLengthCorrection == 0
+ ? rOrigText
+ : rOrigText.replaceAll(OUString(CH_TXTATR_INWORD), "")
+ .replaceAll(OUString(CH_TXTATR_BREAKWORD), ""),
+ pos.second + nSourceLength + nDelChars ) != 0 &&
+ // and are they visible?
+ pFrame->GetText().compareTo(
+ rOrigText, pos.second + nSourceLength + nDelChars + nLengthCorrection) == 0 )
+ {
+ bDoReplace = false;
+ }
+ }
+
if ( bDoReplace )
{
SwDoc* pDoc = m_rEditSh.GetDoc();