summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2024-03-20 16:24:07 +0500
committerXisco Fauli <xiscofauli@libreoffice.org>2024-03-22 08:35:46 +0100
commit41586f2f417a2d55d6baa07d3885d2d117a16d1d (patch)
tree43a8180d346bdf947ebe5254693d1bb89d8fbb78
parent227e51b6b4b3e6664c6ed9cc72c85ff3c3d03ab9 (diff)
tdf#160278: restore cursor bounds properly
The passed string length is not a correct measure of how many steps should the selection expand in the resulting text: the cursor goes over glyphs, not over UTF-16 code units. Thus, it's easier to store the position prior to insertion, and restore it from the indexes. Change-Id: I1d592ff30199007ba3a99d7e1a6d2db2da35f1cb Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165056 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com> Signed-off-by: Xisco Fauli <xiscofauli@libreoffice.org> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165145
-rw-r--r--sw/qa/extras/unowriter/unowriter.cxx21
-rw-r--r--sw/source/core/unocore/unoobj.cxx12
2 files changed, 30 insertions, 3 deletions
diff --git a/sw/qa/extras/unowriter/unowriter.cxx b/sw/qa/extras/unowriter/unowriter.cxx
index 8bcadbaf4227..80b9e556f73b 100644
--- a/sw/qa/extras/unowriter/unowriter.cxx
+++ b/sw/qa/extras/unowriter/unowriter.cxx
@@ -1201,6 +1201,27 @@ CPPUNIT_TEST_FIXTURE(SwUnoWriter, testTdf129841)
CPPUNIT_ASSERT_EQUAL(aRefColor, aColor);
}
+CPPUNIT_TEST_FIXTURE(SwUnoWriter, testTdf160278)
+{
+ createSwDoc();
+ auto xTextDocument(mxComponent.queryThrow<css::text::XTextDocument>());
+ auto xText(xTextDocument->getText());
+ xText->setString(u"123"_ustr);
+ CPPUNIT_ASSERT_EQUAL(u"123"_ustr, xText->getString());
+ auto xCursor = xText->createTextCursorByRange(xText->getEnd());
+ xCursor->goLeft(1, true);
+ CPPUNIT_ASSERT_EQUAL(u"3"_ustr, xCursor->getString());
+ // Insert an SMP character U+1f702 (so it's two UTF-16 code units, 0xd83d 0xdf02):
+ xCursor->setString(u"🜂"_ustr);
+ // Without the fix, the replacement would expand the cursor one too many characters to the left,
+ // and the cursor text would become "2🜂", failing the next test:
+ CPPUNIT_ASSERT_EQUAL(u"🜂"_ustr, xCursor->getString());
+ xCursor->setString(u"test"_ustr);
+ CPPUNIT_ASSERT_EQUAL(u"test"_ustr, xCursor->getString());
+ // This test would fail, too; the text would be "1test":
+ CPPUNIT_ASSERT_EQUAL(u"12test"_ustr, xText->getString());
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unoobj.cxx b/sw/source/core/unocore/unoobj.cxx
index 49562c1d0284..df02c4773a15 100644
--- a/sw/source/core/unocore/unoobj.cxx
+++ b/sw/source/core/unocore/unoobj.cxx
@@ -752,13 +752,19 @@ void SwXTextCursor::DeleteAndInsert(std::u16string_view aText,
}
if(nTextLen)
{
+ // Store node and content indexes prior to insertion: to select the inserted text,
+ // we need to account for possible surrogate pairs, combining characters, etc.; it
+ // is easier to just restore the correct position from the indexes.
+ const auto start = pCurrent->Start();
+ const auto nodeIndex = start->GetNodeIndex();
+ const auto contentIndex = start->GetContentIndex();
const bool bSuccess(
SwUnoCursorHelper::DocInsertStringSplitCR(
- rDoc, *pCurrent, aText, bool(eMode & ::sw::DeleteAndInsertMode::ForceExpandHints)));
+ rDoc, SwPaM(*start, pCurrent), aText, bool(eMode & ::sw::DeleteAndInsertMode::ForceExpandHints)));
OSL_ENSURE( bSuccess, "Doc->Insert(Str) failed." );
- SwUnoCursorHelper::SelectPam(*pUnoCursor, true);
- pCurrent->Left(aText.size());
+ pCurrent->SetMark();
+ pCurrent->GetPoint()->Assign(nodeIndex, contentIndex);
}
pCurrent = pCurrent->GetNext();
} while (pCurrent != pUnoCursor);