diff options
author | Michael Warner <michael.warner.ut+libreoffice@gmail.com> | 2022-04-11 00:18:25 -0400 |
---|---|---|
committer | Xisco Fauli <xiscofauli@libreoffice.org> | 2022-05-11 22:59:59 +0200 |
commit | 49ddbc94a088344bf69444445a0300342ea3f184 (patch) | |
tree | 686c82dd39c9153473da2926afe2745434f10005 /editeng | |
parent | 2d63a011ed161a01419a40ab2fbb88796d59b20a (diff) |
tdf#148148: Applying Title Case when selection contains only spaces
Previously, if the user's selection does not contain any word
characters, but the node does contain characters outside of
the user's selection, then searching for the word boundaries
when applying title case could result in start and end points
that were incorrect. In Writer this results in title case
being applied to non-selected characters. In Calc this results
in a debug assertion being hit.
This commit prevents those issues by skipping transliteration
on the node in this case.
Change-Id: I20c5ef44793741c5863f838c13ba222452346a97
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132801
Tested-by: Jenkins
Tested-by: Julien Nabet <serval2412@yahoo.fr>
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Diffstat (limited to 'editeng')
-rw-r--r-- | editeng/qa/unit/core-test.cxx | 85 | ||||
-rw-r--r-- | editeng/source/editeng/impedit4.cxx | 7 |
2 files changed, 92 insertions, 0 deletions
diff --git a/editeng/qa/unit/core-test.cxx b/editeng/qa/unit/core-test.cxx index 8965b8c21ba6..2836c6ba81d6 100644 --- a/editeng/qa/unit/core-test.cxx +++ b/editeng/qa/unit/core-test.cxx @@ -99,6 +99,8 @@ public: void testTdf147196(); + void testTdf148148(); + DECL_STATIC_LINK( Test, CalcFieldValueHdl, EditFieldInfo*, void ); CPPUNIT_TEST_SUITE(Test); @@ -122,6 +124,7 @@ public: CPPUNIT_TEST(testLargeParaCopyPaste); CPPUNIT_TEST(testTransliterate); CPPUNIT_TEST(testTdf147196); + CPPUNIT_TEST(testTdf148148); CPPUNIT_TEST_SUITE_END(); private: @@ -1889,6 +1892,88 @@ void Test::testTdf147196() CPPUNIT_ASSERT_EQUAL(OUString("2.2 Publication Of Information - Caa\nSection 4.2 Of A Ca\'s Certificate Policy And/Or Certification Practice Statement Shall State The Ca\'s Policy Or Practice On Processing Caa Records For Fully Qualified Domain Names; That Policy Shall Be Consistent With These Requirements. \n\nIt Shall Clearly Specify The Set Of Issuer Domain Names That The Ca Recognises In Caa \"Issue\" Or \"Issuewild\" Records As Permitting It To Issue. The Ca Shall Log All Actions Taken, If Any, Consistent With Its Processing Practice."), editEng.GetText()); } +void Test::testTdf148148() +{ + using TF = TransliterationFlags; + EditEngine editEng( mpItemPool.get() ); + + /* Test what happens when node contains text but selection does not contain any text */ + int selStart = 0; + int selEnd = 3; + ESelection esel(0, selStart, 0, selEnd); + const OUString sText1(" text"); + editEng.SetText(sText1); + CPPUNIT_ASSERT_EQUAL(OUString(" "), editEng.GetText(esel)); + + CPPUNIT_ASSERT_EQUAL(OUString(" text"), lcl_translitTest(editEng, sText1, esel, TF::SENTENCE_CASE)); + CPPUNIT_ASSERT_EQUAL(OUString(" text"), lcl_translitTest(editEng, sText1, esel, TF::TITLE_CASE)); + CPPUNIT_ASSERT_EQUAL(OUString(" text"), lcl_translitTest(editEng, sText1, esel, TF::LOWERCASE_UPPERCASE)); + CPPUNIT_ASSERT_EQUAL(OUString(" text"), lcl_translitTest(editEng, sText1, esel, TF::UPPERCASE_LOWERCASE)); + + selStart = 4; + selEnd = 8; + esel = ESelection(0, selStart, 0, selEnd); + const OUString sText2("text "); + editEng.SetText(sText2); + CPPUNIT_ASSERT_EQUAL(OUString(" "), editEng.GetText(esel)); + + CPPUNIT_ASSERT_EQUAL(OUString("text "), lcl_translitTest(editEng, sText2, esel, TF::SENTENCE_CASE)); + CPPUNIT_ASSERT_EQUAL(OUString("text "), lcl_translitTest(editEng, sText2, esel, TF::TITLE_CASE)); + CPPUNIT_ASSERT_EQUAL(OUString("text "), lcl_translitTest(editEng, sText2, esel, TF::LOWERCASE_UPPERCASE)); + CPPUNIT_ASSERT_EQUAL(OUString("text "), lcl_translitTest(editEng, sText2, esel, TF::UPPERCASE_LOWERCASE)); + + /* Test what happens when node contains only non-word text but selection does not contain any text */ + selStart = 0; + selEnd = 3; + esel = ESelection(0, selStart, 0, selEnd); + const OUString sText3(" -1"); + editEng.SetText(sText3); + CPPUNIT_ASSERT_EQUAL(OUString(" "), editEng.GetText(esel)); + + CPPUNIT_ASSERT_EQUAL(OUString(" -1"), lcl_translitTest(editEng, sText3, esel, TF::SENTENCE_CASE)); + CPPUNIT_ASSERT_EQUAL(OUString(" -1"), lcl_translitTest(editEng, sText3, esel, TF::TITLE_CASE)); + CPPUNIT_ASSERT_EQUAL(OUString(" -1"), lcl_translitTest(editEng, sText3, esel, TF::LOWERCASE_UPPERCASE)); + CPPUNIT_ASSERT_EQUAL(OUString(" -1"), lcl_translitTest(editEng, sText3, esel, TF::UPPERCASE_LOWERCASE)); + + selStart = 2; + selEnd = 6; + esel = ESelection(0, selStart, 0, selEnd); + const OUString sText4("-1 "); + editEng.SetText(sText4); + CPPUNIT_ASSERT_EQUAL(OUString(" "), editEng.GetText(esel)); + + CPPUNIT_ASSERT_EQUAL(OUString("-1 "), lcl_translitTest(editEng, sText4, esel, TF::SENTENCE_CASE)); + CPPUNIT_ASSERT_EQUAL(OUString("-1 "), lcl_translitTest(editEng, sText4, esel, TF::TITLE_CASE)); + CPPUNIT_ASSERT_EQUAL(OUString("-1 "), lcl_translitTest(editEng, sText4, esel, TF::LOWERCASE_UPPERCASE)); + CPPUNIT_ASSERT_EQUAL(OUString("-1 "), lcl_translitTest(editEng, sText4, esel, TF::UPPERCASE_LOWERCASE)); + + /* Test what happens when node and selection contains only non-word text */ + selStart = 0; + selEnd = 5; + esel = ESelection(0, selStart, 0, selEnd); + const OUString sText5(" -1"); + editEng.SetText(sText3); + CPPUNIT_ASSERT_EQUAL(OUString(" -1"), editEng.GetText(esel)); + + CPPUNIT_ASSERT_EQUAL(OUString(" -1"), lcl_translitTest(editEng, sText5, esel, TF::SENTENCE_CASE)); + CPPUNIT_ASSERT_EQUAL(OUString(" -1"), lcl_translitTest(editEng, sText5, esel, TF::TITLE_CASE)); + CPPUNIT_ASSERT_EQUAL(OUString(" -1"), lcl_translitTest(editEng, sText5, esel, TF::LOWERCASE_UPPERCASE)); + CPPUNIT_ASSERT_EQUAL(OUString(" -1"), lcl_translitTest(editEng, sText5, esel, TF::UPPERCASE_LOWERCASE)); + + selStart = 0; + selEnd = 5; + esel = ESelection(0, selStart, 0, selEnd); + const OUString sText6("-1 "); + editEng.SetText(sText4); + CPPUNIT_ASSERT_EQUAL(OUString("-1 "), editEng.GetText(esel)); + + CPPUNIT_ASSERT_EQUAL(OUString("-1 "), lcl_translitTest(editEng, sText6, esel, TF::SENTENCE_CASE)); + CPPUNIT_ASSERT_EQUAL(OUString("-1 "), lcl_translitTest(editEng, sText6, esel, TF::TITLE_CASE)); + CPPUNIT_ASSERT_EQUAL(OUString("-1 "), lcl_translitTest(editEng, sText6, esel, TF::LOWERCASE_UPPERCASE)); + CPPUNIT_ASSERT_EQUAL(OUString("-1 "), lcl_translitTest(editEng, sText6, esel, TF::UPPERCASE_LOWERCASE)); + + +} CPPUNIT_TEST_SUITE_REGISTRATION(Test); diff --git a/editeng/source/editeng/impedit4.cxx b/editeng/source/editeng/impedit4.cxx index 03b8d511e5c3..35b6f6291687 100644 --- a/editeng/source/editeng/impedit4.cxx +++ b/editeng/source/editeng/impedit4.cxx @@ -2750,6 +2750,12 @@ EditSelection ImpEditEngine::TransliterateText( const EditSelection& rSelection, nWordType); } + /* Nothing to do if user selection lies entirely outside of word start and end boundary computed above. + * Skip this node, because otherwise the below logic for constraining to the selection will fail */ + if (aSttBndry.startPos >= aSel.Max().GetIndex() || aEndBndry.endPos <= aSel.Min().GetIndex()) { + continue; + } + // prevent going outside of the user's selection, which may // start or end in the middle of a word if (nNode == nStartNode) { @@ -2758,6 +2764,7 @@ EditSelection ImpEditEngine::TransliterateText( const EditSelection& rSelection, aEndBndry.startPos = std::max(aEndBndry.startPos, aSttBndry.startPos); aEndBndry.endPos = std::min(aEndBndry.endPos, aSel.Max().GetIndex()); } + i18n::Boundary aCurWordBndry( aSttBndry ); while (aCurWordBndry.endPos && aCurWordBndry.startPos <= aEndBndry.startPos) { |