diff options
author | László Németh <nemeth@numbertext.org> | 2020-11-03 20:52:38 +0100 |
---|---|---|
committer | László Németh <nemeth@numbertext.org> | 2020-11-05 08:29:08 +0100 |
commit | ac84cf7dda4a5150ff23e112ee16f00b8de8ec7c (patch) | |
tree | 1c44f930650a95547b0d8091afecade2e288ae99 /sw | |
parent | 2e32f4ed5af16a68c97a50806a42ffa2d10f1d7a (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>
Diffstat (limited to 'sw')
-rw-r--r-- | sw/qa/extras/uiwriter/data/redline-autocorrect.fodt | 24 | ||||
-rw-r--r-- | sw/qa/extras/uiwriter/uiwriter.cxx | 65 | ||||
-rw-r--r-- | sw/source/core/edit/acorrect.cxx | 30 |
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(); |