editeng/qa/unit/core-test.cxx       |   12 +++++++++++-
 editeng/source/editeng/impedit4.cxx |   11 +++++++++++
 sw/qa/extras/uiwriter/uiwriter4.cxx |   23 ++++++++++++++++++++++-
 sw/source/core/txtnode/txtedt.cxx   |    8 ++++++++
 4 files changed, 52 insertions(+), 2 deletions(-)

New commits:
commit de5aa409353c839483df21d47254fd2a508ab7d9
Author:     Michael Warner <[email protected]>
AuthorDate: Sat Oct 2 09:34:34 2021 -0400
Commit:     Heiko Tietze <[email protected]>
CommitDate: Tue Feb 1 11:16:27 2022 +0100

    tdf#144851 Honor Selection When Applying Title Case Format
    
    Prevents Title Case formmating from occuring outside of a
    user's selection. This is relevant if the user has started
    or ended a selection in the middle of a word.
    
    Change-Id: I39d8f2445acf5d9bb225bf8e3b36e2eb3b518857
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/124102
    Tested-by: Jenkins
    Tested-by: Heiko Tietze <[email protected]>
    Reviewed-by: Heiko Tietze <[email protected]>

diff --git a/editeng/qa/unit/core-test.cxx b/editeng/qa/unit/core-test.cxx
index 896fa59810eb..f3500e01ce26 100644
--- a/editeng/qa/unit/core-test.cxx
+++ b/editeng/qa/unit/core-test.cxx
@@ -1820,13 +1820,23 @@ void Test::testTransliterate()
     CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones MET joe Smith. Time Passed."), 
lcl_translitTest(editEng, sText2, esel, TF::LOWERCASE_UPPERCASE));
     CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe Smith. Time Passed."), 
lcl_translitTest(editEng, sText2, esel, TF::UPPERCASE_LOWERCASE));
 
+    /* Test behavior when there is a selection that does not begin at a word 
boundary: "et" */
+    selStart = 12;
+    selEnd = 14;
+    esel = ESelection(0, selStart, 0, selEnd);
+    CPPUNIT_ASSERT_EQUAL(OUString("et"), editEng.GetText(esel));
+    CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones mEt joe Smith. Time Passed."), 
lcl_translitTest(editEng, sText2, esel, TF::SENTENCE_CASE));
+    CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones mEt joe Smith. Time Passed."), 
lcl_translitTest(editEng, sText2, esel, TF::TITLE_CASE));
+    CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones mET joe Smith. Time Passed."), 
lcl_translitTest(editEng, sText2, esel, TF::LOWERCASE_UPPERCASE));
+    CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe Smith. Time Passed."), 
lcl_translitTest(editEng, sText2, esel, TF::UPPERCASE_LOWERCASE));
+
     /* Test behavior when there is a selection that crosses a word boundary: 
"nes met joe Sm" */
     selStart = 7;
     selEnd = 21;
     esel = ESelection(0, selStart, 0, selEnd);
     CPPUNIT_ASSERT_EQUAL(OUString("nes met joe Sm"), editEng.GetText(esel));
     CPPUNIT_ASSERT_EQUAL(OUString("Mary JoNes met joe smith. Time Passed."), 
lcl_translitTest(editEng, sText2, esel, TF::SENTENCE_CASE));
-    CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones Met Joe Smith. Time Passed."), 
lcl_translitTest(editEng, sText2, esel, TF::TITLE_CASE));
+    CPPUNIT_ASSERT_EQUAL(OUString("Mary JoNes Met Joe Smith. Time Passed."), 
lcl_translitTest(editEng, sText2, esel, TF::TITLE_CASE));
     CPPUNIT_ASSERT_EQUAL(OUString("Mary JoNES MET JOE SMith. Time Passed."), 
lcl_translitTest(editEng, sText2, esel, TF::LOWERCASE_UPPERCASE));
     CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe smith. Time Passed."), 
lcl_translitTest(editEng, sText2, esel, TF::UPPERCASE_LOWERCASE));
 
diff --git a/editeng/source/editeng/impedit4.cxx 
b/editeng/source/editeng/impedit4.cxx
index 3012504bb028..1228924dc634 100644
--- a/editeng/source/editeng/impedit4.cxx
+++ b/editeng/source/editeng/impedit4.cxx
@@ -2738,6 +2738,14 @@ EditSelection ImpEditEngine::TransliterateText( const 
EditSelection& rSelection,
                         nWordType);
             }
 
+            // prevent going outside of the user's selection, which may
+            // start or end in the middle of a word
+            if (nNode == nStartNode) {
+                aSttBndry.startPos = std::max(aSttBndry.startPos, 
aSel.Min().GetIndex());
+                aSttBndry.endPos   = std::min(aSttBndry.endPos,   
aSel.Max().GetIndex());
+                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)
             {
@@ -2768,6 +2776,9 @@ EditSelection ImpEditEngine::TransliterateText( const 
EditSelection& rSelection,
                 aCurWordBndry = _xBI->nextWord(aNodeStr, nCurrentStart,
                         GetLocale( EditPaM( pNode, nCurrentStart + 1 ) ),
                         nWordType);
+
+                /* Selection may end in the middle of a word */
+                aCurWordBndry.endPos = std::min(aCurWordBndry.endPos,   
aSel.Max().GetIndex());
             }
             DBG_ASSERT( nCurrentEnd >= aEndBndry.endPos, "failed to reach end 
of transliteration" );
         }
diff --git a/sw/qa/extras/uiwriter/uiwriter4.cxx 
b/sw/qa/extras/uiwriter/uiwriter4.cxx
index 4ee3cfff78b0..c1635b64ffad 100644
--- a/sw/qa/extras/uiwriter/uiwriter4.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter4.cxx
@@ -230,6 +230,27 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testTdf49033)
     CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe Smith. Time Passed."),
                          lcl_translitTest(*pDoc, *pCursor, 
TF::UPPERCASE_LOWERCASE));
 
+    /* -- Test behavior when there is a selection that does not begin at a 
word boundary: "et" -- */
+    for (int i = 0; i < 2; i++)
+        pCursor->Move(fnMoveBackward);
+    pCursor->SetMark();
+    for (int i = 0; i < 2; i++)
+        pCursor->Move(fnMoveForward);
+    pWrtShell->GetSelectedText(currentSelectedText);
+    CPPUNIT_ASSERT_EQUAL(OUString("et"), currentSelectedText);
+    CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones mEt joe Smith. Time Passed."),
+                         lcl_translitTest(*pDoc, *pCursor, TF::SENTENCE_CASE));
+    pDoc->GetIDocumentUndoRedo().Undo();
+    CPPUNIT_ASSERT_EQUAL(OUString("et"), currentSelectedText);
+    CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones mEt joe Smith. Time Passed."),
+                         lcl_translitTest(*pDoc, *pCursor, TF::TITLE_CASE));
+    pDoc->GetIDocumentUndoRedo().Undo();
+    CPPUNIT_ASSERT_EQUAL(OUString("et"), currentSelectedText);
+    CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones mET joe Smith. Time Passed."),
+                         lcl_translitTest(*pDoc, *pCursor, 
TF::LOWERCASE_UPPERCASE));
+    CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones met joe Smith. Time Passed."),
+                         lcl_translitTest(*pDoc, *pCursor, 
TF::UPPERCASE_LOWERCASE));
+
     /* -- Test behavior when there is a selection that crosses a word boundary 
-- */
     for (int i = 0; i < 7; i++)
         pCursor->Move(fnMoveBackward);
@@ -241,7 +262,7 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testTdf49033)
     CPPUNIT_ASSERT_EQUAL(OUString("nes met joe Sm"), currentSelectedText);
     CPPUNIT_ASSERT_EQUAL(OUString("Mary JoNes met joe smith. Time Passed."),
                          lcl_translitTest(*pDoc, *pCursor, TF::SENTENCE_CASE));
-    CPPUNIT_ASSERT_EQUAL(OUString("Mary Jones Met Joe Smith. Time Passed."),
+    CPPUNIT_ASSERT_EQUAL(OUString("Mary JoNes Met Joe Smith. Time Passed."),
                          lcl_translitTest(*pDoc, *pCursor, TF::TITLE_CASE));
     CPPUNIT_ASSERT_EQUAL(OUString("Mary JoNES MET JOE SMith. Time Passed."),
                          lcl_translitTest(*pDoc, *pCursor, 
TF::LOWERCASE_UPPERCASE));
diff --git a/sw/source/core/txtnode/txtedt.cxx 
b/sw/source/core/txtnode/txtedt.cxx
index f68518148749..1ed69cb78265 100644
--- a/sw/source/core/txtnode/txtedt.cxx
+++ b/sw/source/core/txtnode/txtedt.cxx
@@ -1756,6 +1756,11 @@ void SwTextNode::TransliterateText(
                     nWordType);
         }
 
+        // prevent going outside of the user's selection, which may
+        // start in the middle of a word
+        aSttBndry.startPos = std::max(aSttBndry.startPos, selStart);
+        aEndBndry.startPos = std::max(aSttBndry.startPos, aEndBndry.startPos);
+
         Boundary aCurWordBndry( aSttBndry );
         while (aCurWordBndry.startPos <= aEndBndry.startPos)
         {
@@ -1784,6 +1789,9 @@ void SwTextNode::TransliterateText(
                     GetText(), nStt,
                     g_pBreakIt->GetLocale(GetLang(nStt, 1)),
                     nWordType);
+
+            /* Selection may end in the middle of a word */
+            aCurWordBndry.endPos = std::min(aCurWordBndry.endPos, selEnd);
         }
     }
     else if (rTrans.getType() == TransliterationFlags::SENTENCE_CASE)

Reply via email to