From 5a96093f0ecee53432bdf35f247edd6deb501baf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A1szl=C3=B3=20N=C3=A9meth?= Date: Fri, 6 Nov 2020 19:14:45 +0100 Subject: [PATCH] tdf#130546 sw autocorrect: don't replace redlining MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit if it starts or ends within the removed text to avoid various problems, for example, reappearing deleted comma before ellipsis replacement: text[,]... -> text,...[,] or replacing words based on already deleted text: [tt]he -> [tt]the Add test/user-template/user/autocorr/acor_en-GB.dat unit test autocorrect definition with three dots to ellipsis replacement. Change-Id: I195922cb92bc29d3ded694fea4ca351244dab17b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/105424 Tested-by: Jenkins Reviewed-by: László Németh --- .../uiwriter/data/redline-autocorrect2.fodt | 24 +++++++++ sw/qa/extras/uiwriter/uiwriter.cxx | 46 +++++++++++++++++- sw/source/core/edit/acorrect.cxx | 26 +++++++++- test/Package_unittest.mk | 1 + .../user/autocorr/acor_en-GB.dat | Bin 0 -> 1786 bytes 5 files changed, 93 insertions(+), 4 deletions(-) create mode 100644 sw/qa/extras/uiwriter/data/redline-autocorrect2.fodt create mode 100644 test/user-template/user/autocorr/acor_en-GB.dat diff --git a/sw/qa/extras/uiwriter/data/redline-autocorrect2.fodt b/sw/qa/extras/uiwriter/data/redline-autocorrect2.fodt new file mode 100644 index 000000000000..4d65c5f465a2 --- /dev/null +++ b/sw/qa/extras/uiwriter/data/redline-autocorrect2.fodt @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + Unknown Author + 2020-11-03T19:19:05 + + + + + Lorem, + + + diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx index aca558b923a6..2acfc17b7082 100644 --- a/sw/qa/extras/uiwriter/uiwriter.cxx +++ b/sw/qa/extras/uiwriter/uiwriter.cxx @@ -391,6 +391,7 @@ public: void testInsertLongDateFormat(); void testSpellOnlineParameter(); void testRedlineAutoCorrect(); + void testRedlineAutoCorrect2(); #if HAVE_FEATURE_PDFIUM void testInsertPdf(); #endif @@ -618,6 +619,7 @@ public: CPPUNIT_TEST(testInsertLongDateFormat); CPPUNIT_TEST(testSpellOnlineParameter); CPPUNIT_TEST(testRedlineAutoCorrect); + CPPUNIT_TEST(testRedlineAutoCorrect2); #if HAVE_FEATURE_PDFIUM CPPUNIT_TEST(testInsertPdf); #endif @@ -7638,7 +7640,15 @@ void SwUiWriterTest::testRedlineAutoCorrect() pWrtShell->Insert("et"); pWrtShell->AutoCorrect(corr, ' '); // This was "Ttest" removing the tracked deletion silently. - sReplaced = "ttest "; + // Don't replace, if a redline starts or ends within the text. + sReplaced = "tset "; + nIndex = pWrtShell->GetCursor()->GetNode().GetIndex(); + CPPUNIT_ASSERT_EQUAL(sReplaced, static_cast(pDoc->GetNodes()[nIndex])->GetText()); + + // Otherwise replace it + pWrtShell->Insert("tset"); + pWrtShell->AutoCorrect(corr, ' '); + sReplaced = "tset test "; nIndex = pWrtShell->GetCursor()->GetNode().GetIndex(); CPPUNIT_ASSERT_EQUAL(sReplaced, static_cast(pDoc->GetNodes()[nIndex])->GetText()); @@ -7646,11 +7656,43 @@ void SwUiWriterTest::testRedlineAutoCorrect() dispatchCommand(mxComponent, ".uno:GoToStartOfDoc", {}); pWrtShell->Insert("a"); pWrtShell->AutoCorrect(corr, ' '); - sReplaced = "A ttest "; + sReplaced = "A tset test "; nIndex = pWrtShell->GetCursor()->GetNode().GetIndex(); CPPUNIT_ASSERT_EQUAL(sReplaced, static_cast(pDoc->GetNodes()[nIndex])->GetText()); } +void SwUiWriterTest::testRedlineAutoCorrect2() +{ + SwDoc* pDoc = createDoc("redline-autocorrect2.fodt"); + SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); + + dispatchCommand(mxComponent, ".uno:GoToEndOfDoc", {}); + + // 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->Insert("..."); + pWrtShell->AutoCorrect(corr, ' '); + sal_uLong nIndex = pWrtShell->GetCursor()->GetNode().GetIndex(); + + // This was "LoremLorem,…," (duplicating the deleted comma, but without deletion) + // Don't replace, if a redline starts or ends within the text. + OUString sReplaced = "Lorem,... "; + nIndex = pWrtShell->GetCursor()->GetNode().GetIndex(); + CPPUNIT_ASSERT_EQUAL(sReplaced, static_cast(pDoc->GetNodes()[nIndex])->GetText()); + + // Continue it: + pWrtShell->Insert("Lorem,..."); + pWrtShell->AutoCorrect(corr, ' '); + nIndex = pWrtShell->GetCursor()->GetNode().GetIndex(); + sReplaced = u"Lorem,... Lorem,… "; + CPPUNIT_ASSERT_EQUAL(sReplaced, static_cast(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 7ae0a778a59b..d7003ccfbaed 100644 --- a/sw/source/core/edit/acorrect.cxx +++ b/sw/source/core/edit/acorrect.cxx @@ -40,6 +40,8 @@ #include #include +#include +#include using namespace ::com::sun::star; @@ -427,8 +429,28 @@ bool SwAutoCorrDoc::ChgAutoCorrWord( sal_Int32& rSttPos, sal_Int32 nEndPos, const bool replaceLastChar = sFrameText.getLength() > nEndPos && pFnd->GetShort()[0] == ':' && pFnd->GetShort().endsWith(":"); - SwPaM aPam(pFrame->MapViewToModelPos(TextFrameIndex(rSttPos)), - pFrame->MapViewToModelPos(TextFrameIndex(nEndPos + (replaceLastChar ? 1 : 0)))); + SwPosition aStartPos( pFrame->MapViewToModelPos(TextFrameIndex(rSttPos) )); + SwPosition aEndPos( pFrame->MapViewToModelPos(TextFrameIndex(nEndPos + (replaceLastChar ? 1 : 0))) ); + SwPaM aPam(aStartPos, aEndPos); + + // don't replace, if a redline starts or ends within the original text + for ( SwRedlineTable::size_type nAct = + pDoc->getIDocumentRedlineAccess().GetRedlinePos( m_rCursor.GetNode(), RedlineType::Any ); + nAct < pDoc->getIDocumentRedlineAccess().GetRedlineTable().size(); ++nAct ) + { + const SwRangeRedline* pRed = pDoc->getIDocumentRedlineAccess().GetRedlineTable()[ nAct ]; + + if ( pRed->Start()->nNode > pTextNd->GetIndex() ) + break; + + // redline over the original text + if ( aStartPos < *pRed->End() && *pRed->Start() < aEndPos && + // starting or ending within the original text + ( aStartPos < *pRed->Start() || *pRed->End() < aEndPos ) ) + { + return bRet; + } + } if( pFnd->IsTextOnly() ) { diff --git a/test/Package_unittest.mk b/test/Package_unittest.mk index 5973615edfed..2aabc9272eb4 100644 --- a/test/Package_unittest.mk +++ b/test/Package_unittest.mk @@ -24,6 +24,7 @@ $(eval $(call gb_Package_add_file,test_unittest,unittest/user/autotext/en-US/sta $(eval $(call gb_Package_add_file,test_unittest,unittest/user/autotext/en-US/crdbus50.bau,user/autotext/en-US/crdbus50.bau)) $(eval $(call gb_Package_add_file,test_unittest,unittest/user/config/soffice.cfg/.dummy,empty-directory-dummy)) $(eval $(call gb_Package_add_file,test_unittest,unittest/user/autocorr/acor_en-US.dat,user/autocorr/acor_fr.dat)) +$(eval $(call gb_Package_add_file,test_unittest,unittest/user/autocorr/acor_en-GB.dat,user/autocorr/acor_en-GB.dat)) $(eval $(call gb_Package_add_file,test_unittest,unittest/user/config/soffice.cfg/modules/scalc/popupmenu/draw.xml,user/config/soffice.cfg/modules/scalc/popupmenu/draw.xml)) $(eval $(call gb_Package_add_file,test_unittest,unittest/user/config/soffice.cfg/modules/scalc/popupmenu/anchor.xml,user/config/soffice.cfg/modules/scalc/popupmenu/anchor.xml)) $(eval $(call gb_Package_add_file,test_unittest,unittest/user/config/soffice.cfg/modules/swriter/popupmenu/text.xml,user/config/soffice.cfg/modules/swriter/popupmenu/text.xml)) diff --git a/test/user-template/user/autocorr/acor_en-GB.dat b/test/user-template/user/autocorr/acor_en-GB.dat new file mode 100644 index 0000000000000000000000000000000000000000..b74f1834caacf541c32031f6f9156e46dd35f691 GIT binary patch literal 1786 zcmWIWW@h1H0D;2DbXPC~N^mg9FyvVGw)6;6}I2s;^Zv2i|26l=X-k+7v)B0 z?RSjUHZs&{5~wkmly^$RaL#4h=)-0o7x_%CF<6_m{blt3wWePgIv&1@+4^vfmdTXo zUP%ty9-KCa`B2C6r!h8shM?*(1(lnti{4CdGP-4Pr9)@)4ULB%zD-=GH(ma^*NJwG z52v@i<+tv&^Yz;%vaY!F#=i9@Th|Hx*q>OoJlSe;n)@x^Ba#P=D}Ow(7kbYM3J6G0 zPM@3>h#Zuhz<}^|4RO@<^mEe(2f{gE0Dv&guml;gR*&O;I?$YHKrD)EL~deUW?Cvz zn4Se1rQLyHT<#e|J_iGlhKF}GXKfF^=`!Ukr-j4e!``>tx3t{e>>+-8e*TZu&x*q4 z?5K{4be@-{FrmFvWuEDmSZ(f%S4)c8GM(g4>A!MunR8;13*T?uMY7jUoo#V#ZaTr| zZe(;vI*Z}!ysPJbF(OjHL7=OrRco@&2D;b~m;wZVu6D^!F3nBND?v#FQb5OIaq!%J zN3LcA5tr|lu0KvUdA?cYvB=v0f}Fyu>up&|o)h${XUVNmU)kE!xa(D3#Tgrk$h*rY z>b+<#40Alk60l|M>mFH=m~*9NO{-KkNyb*6b`wt8=(;N}*Q22+yQlcz&e<1t?K9Uk zdd^-aqVznP*URZ;|0FdB^WNh}Uv$K#eQn`NI>3?nw7c-?NBf#L2PAF_?vp#;@BiuU zan(v@geUoSmbsdLH;qgMdU65~ivc|u4D?`XUUI5yMRIBZs#l{q3$dm5%^TOBI2)+p zt*dqJ%=yisMpujjf;`T8pYuO?#(R4x7jNO^tpS_1Ki=ed>ZJdkc~qv0Dwk=3IMDw zg?Jt_Um}cN(&)m(fF+j#O$FsrJf>o11ca$u8a06x1g>lWG#ivH@R*I6UXjhd2Q(X7 b>IIq$O1&87va*4a3p)^o0{z<00^$Jxw=X!# literal 0 HcmV?d00001