summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMichael Warner <michael.warner.ut+libreoffice@gmail.com>2022-04-11 00:18:25 -0400
committerXisco Fauli <xiscofauli@libreoffice.org>2022-05-11 22:59:59 +0200
commit49ddbc94a088344bf69444445a0300342ea3f184 (patch)
tree686c82dd39c9153473da2926afe2745434f10005 /sw
parent2d63a011ed161a01419a40ab2fbb88796d59b20a (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 'sw')
-rw-r--r--sw/qa/extras/uiwriter/uiwriter4.cxx116
-rw-r--r--sw/source/core/txtnode/txtedt.cxx6
2 files changed, 122 insertions, 0 deletions
diff --git a/sw/qa/extras/uiwriter/uiwriter4.cxx b/sw/qa/extras/uiwriter/uiwriter4.cxx
index f6791e4ebb02..e3a625be7b30 100644
--- a/sw/qa/extras/uiwriter/uiwriter4.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter4.cxx
@@ -356,6 +356,122 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testTdf147196)
lcl_translitTest(*pDoc, *pCursor, TF::TITLE_CASE));
}
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testTdf148148)
+{
+ using TF = TransliterationFlags;
+ SwDoc* pDoc = createSwDoc();
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+
+ pWrtShell->SttEndDoc(/*bStt=*/false);
+ pWrtShell->Insert(" text");
+
+ /* Test what happens when node contains text but selection does not contain any text */
+ pWrtShell->StartOfSection();
+ SwShellCursor* pCursor = pWrtShell->getShellCursor(false);
+ pCursor->SetMark();
+ for (int i = 0; i < 3; i++)
+ {
+ pCursor->Move(fnMoveForward);
+ }
+ CPPUNIT_ASSERT_EQUAL(OUString(" text"), lcl_translitTest(*pDoc, *pCursor, TF::TITLE_CASE));
+ CPPUNIT_ASSERT_EQUAL(OUString(" text"), lcl_translitTest(*pDoc, *pCursor, TF::SENTENCE_CASE));
+ CPPUNIT_ASSERT_EQUAL(OUString(" text"),
+ lcl_translitTest(*pDoc, *pCursor, TF::LOWERCASE_UPPERCASE));
+ CPPUNIT_ASSERT_EQUAL(OUString(" text"),
+ lcl_translitTest(*pDoc, *pCursor, TF::UPPERCASE_LOWERCASE));
+
+ /* Test what happens when node contains text but selection does not contain any text */
+ pDoc = createSwDoc();
+ pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+ pWrtShell->SttEndDoc(/*bStt=*/false);
+ pWrtShell->Insert("text ");
+
+ pWrtShell->StartOfSection();
+ pCursor = pWrtShell->getShellCursor(false);
+ for (int i = 0; i < 4; i++)
+ {
+ pCursor->Move(fnMoveForward);
+ }
+ pCursor->SetMark();
+ for (int i = 0; i < 2; i++)
+ {
+ pCursor->Move(fnMoveForward);
+ }
+
+ CPPUNIT_ASSERT_EQUAL(OUString("text "), lcl_translitTest(*pDoc, *pCursor, TF::SENTENCE_CASE));
+ CPPUNIT_ASSERT_EQUAL(OUString("text "), lcl_translitTest(*pDoc, *pCursor, TF::TITLE_CASE));
+ CPPUNIT_ASSERT_EQUAL(OUString("text "),
+ lcl_translitTest(*pDoc, *pCursor, TF::LOWERCASE_UPPERCASE));
+ CPPUNIT_ASSERT_EQUAL(OUString("text "),
+ lcl_translitTest(*pDoc, *pCursor, TF::UPPERCASE_LOWERCASE));
+
+ /* Test what happens when node contains only non-word text but selection does not contain any text */
+ pDoc = createSwDoc();
+ pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+ pWrtShell->SttEndDoc(/*bStt=*/false);
+ pWrtShell->Insert("-1 ");
+
+ pWrtShell->StartOfSection();
+ pCursor = pWrtShell->getShellCursor(false);
+ for (int i = 0; i < 2; i++)
+ {
+ pCursor->Move(fnMoveForward);
+ }
+ pCursor->SetMark();
+ for (int i = 0; i < 2; i++)
+ {
+ pCursor->Move(fnMoveForward);
+ }
+
+ CPPUNIT_ASSERT_EQUAL(OUString("-1 "), lcl_translitTest(*pDoc, *pCursor, TF::SENTENCE_CASE));
+ CPPUNIT_ASSERT_EQUAL(OUString("-1 "), lcl_translitTest(*pDoc, *pCursor, TF::TITLE_CASE));
+ CPPUNIT_ASSERT_EQUAL(OUString("-1 "),
+ lcl_translitTest(*pDoc, *pCursor, TF::LOWERCASE_UPPERCASE));
+ CPPUNIT_ASSERT_EQUAL(OUString("-1 "),
+ lcl_translitTest(*pDoc, *pCursor, TF::UPPERCASE_LOWERCASE));
+
+ pDoc = createSwDoc();
+ pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+ pWrtShell->SttEndDoc(/*bStt=*/false);
+ pWrtShell->Insert(" -1");
+
+ pWrtShell->StartOfSection();
+ pCursor = pWrtShell->getShellCursor(false);
+ pCursor->SetMark();
+ for (int i = 0; i < 2; i++)
+ {
+ pCursor->Move(fnMoveForward);
+ }
+
+ CPPUNIT_ASSERT_EQUAL(OUString(" -1"), lcl_translitTest(*pDoc, *pCursor, TF::SENTENCE_CASE));
+ CPPUNIT_ASSERT_EQUAL(OUString(" -1"), lcl_translitTest(*pDoc, *pCursor, TF::TITLE_CASE));
+ CPPUNIT_ASSERT_EQUAL(OUString(" -1"),
+ lcl_translitTest(*pDoc, *pCursor, TF::LOWERCASE_UPPERCASE));
+ CPPUNIT_ASSERT_EQUAL(OUString(" -1"),
+ lcl_translitTest(*pDoc, *pCursor, TF::UPPERCASE_LOWERCASE));
+
+ /* Test what happens when node and selection contains only non-word text */
+ pDoc = createSwDoc();
+ pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+ pWrtShell->SttEndDoc(/*bStt=*/false);
+ pWrtShell->Insert(" -1");
+
+ pWrtShell->StartOfSection();
+ pCursor = pWrtShell->getShellCursor(false);
+ pCursor->SetMark();
+ for (int i = 0; i < 5; i++)
+ {
+ pCursor->Move(fnMoveForward);
+ }
+
+ CPPUNIT_ASSERT_EQUAL(OUString(" -1"), lcl_translitTest(*pDoc, *pCursor, TF::SENTENCE_CASE));
+ CPPUNIT_ASSERT_EQUAL(OUString(" -1"), lcl_translitTest(*pDoc, *pCursor, TF::TITLE_CASE));
+ CPPUNIT_ASSERT_EQUAL(OUString(" -1"),
+ lcl_translitTest(*pDoc, *pCursor, TF::LOWERCASE_UPPERCASE));
+ CPPUNIT_ASSERT_EQUAL(OUString(" -1"),
+ lcl_translitTest(*pDoc, *pCursor, TF::UPPERCASE_LOWERCASE));
+}
+
CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testTdf96943)
{
// Enable hide whitespace mode.
diff --git a/sw/source/core/txtnode/txtedt.cxx b/sw/source/core/txtnode/txtedt.cxx
index 28b633755a7d..1188daef9821 100644
--- a/sw/source/core/txtnode/txtedt.cxx
+++ b/sw/source/core/txtnode/txtedt.cxx
@@ -1756,6 +1756,12 @@ void SwTextNode::TransliterateText(
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 >= selEnd || aEndBndry.endPos <= selStart) {
+ return;
+ }
+
// prevent going outside of the user's selection, which may
// start in the middle of a word
aSttBndry.startPos = std::max(aSttBndry.startPos, selStart);