sw/qa/uibase/shells/shells.cxx | 9 ++++++--- sw/source/uibase/uno/loktxdoc.cxx | 29 ++++++++++++++++++++++++----- 2 files changed, 30 insertions(+), 8 deletions(-)
New commits: commit 56a960e844cc096afbd43f287bd326e4b1169f73 Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Wed Jun 25 19:26:36 2025 +0500 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Thu Jun 26 13:56:01 2025 +0200 LOK Extract API: add textChanged to redline data extraction This is the string of the edited part itself: the added, removed, or formatted piece. Change-Id: Ib8afd86e814e6310a24c215ebf497b7ff0096e3b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/186985 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> (cherry picked from commit 4acfc011231e0b5bbee5ec5b6739a9137c611a48) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/187013 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/sw/qa/uibase/shells/shells.cxx b/sw/qa/uibase/shells/shells.cxx index 7dec82eebec7..aac1b5377474 100644 --- a/sw/qa/uibase/shells/shells.cxx +++ b/sw/qa/uibase/shells/shells.cxx @@ -911,7 +911,7 @@ CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testDocumentStructureExtractRedlines) CPPUNIT_ASSERT(it != docStructure.end()); const auto & [ name, change ] = *it; CPPUNIT_ASSERT_EQUAL("TrackChanges.ByIndex.0"s, name); - CPPUNIT_ASSERT_EQUAL(size_t(7), change.size()); + CPPUNIT_ASSERT_EQUAL(size_t(8), change.size()); CPPUNIT_ASSERT_EQUAL("Delete"s, change.get<std::string>("type")); CPPUNIT_ASSERT_EQUAL("2025-06-16T14:08:27"s, change.get<std::string>("dateTime")); CPPUNIT_ASSERT_EQUAL("Mike"s, change.get<std::string>("author")); @@ -923,6 +923,7 @@ CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testDocumentStructureExtractRedlines) auto text_after = change.get<std::string>("textAfter"); CPPUNIT_ASSERT_EQUAL(size_t(200), text_after.size()); CPPUNIT_ASSERT(text_after.starts_with(" blandit ")); + CPPUNIT_ASSERT_EQUAL("Donec"s, change.get<std::string>("textChanged")); ++it; } @@ -931,7 +932,7 @@ CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testDocumentStructureExtractRedlines) CPPUNIT_ASSERT(it != docStructure.end()); const auto & [ name, change ] = *it; CPPUNIT_ASSERT_EQUAL("TrackChanges.ByIndex.1"s, name); - CPPUNIT_ASSERT_EQUAL(size_t(7), change.size()); + CPPUNIT_ASSERT_EQUAL(size_t(8), change.size()); CPPUNIT_ASSERT_EQUAL("Format"s, change.get<std::string>("type")); CPPUNIT_ASSERT_EQUAL("2025-06-17T12:41:00"s, change.get<std::string>("dateTime")); CPPUNIT_ASSERT_EQUAL("Mike"s, change.get<std::string>("author")); @@ -943,6 +944,7 @@ CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testDocumentStructureExtractRedlines) auto text_after = change.get<std::string>("textAfter"); CPPUNIT_ASSERT_EQUAL(size_t(200), text_after.size()); CPPUNIT_ASSERT(text_after.starts_with(" eros ")); + CPPUNIT_ASSERT_EQUAL("pellentesque"s, change.get<std::string>("textChanged")); ++it; } @@ -951,7 +953,7 @@ CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testDocumentStructureExtractRedlines) CPPUNIT_ASSERT(it != docStructure.end()); const auto & [ name, change ] = *it; CPPUNIT_ASSERT_EQUAL("TrackChanges.ByIndex.2"s, name); - CPPUNIT_ASSERT_EQUAL(size_t(7), change.size()); + CPPUNIT_ASSERT_EQUAL(size_t(8), change.size()); CPPUNIT_ASSERT_EQUAL("Insert"s, change.get<std::string>("type")); CPPUNIT_ASSERT_EQUAL("2025-06-17T12:41:19"s, change.get<std::string>("dateTime")); CPPUNIT_ASSERT_EQUAL("Mike"s, change.get<std::string>("author")); @@ -962,6 +964,7 @@ CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testDocumentStructureExtractRedlines) CPPUNIT_ASSERT(text_before.ends_with(" est orci.")); auto text_after = change.get<std::string>("textAfter"); CPPUNIT_ASSERT(text_after.empty()); + CPPUNIT_ASSERT_EQUAL(" Sapienti sat."s, change.get<std::string>("textChanged")); ++it; } diff --git a/sw/source/uibase/uno/loktxdoc.cxx b/sw/source/uibase/uno/loktxdoc.cxx index 8891709d442d..19f2261f9d45 100644 --- a/sw/source/uibase/uno/loktxdoc.cxx +++ b/sw/source/uibase/uno/loktxdoc.cxx @@ -873,26 +873,45 @@ void GetDocStructureTrackChanges(tools::JsonWriter& rJsonWriter, const SwDocShel extractor.extract<OUString>(UNO_NAME_REDLINE_AUTHOR, "author"); extractor.extract<OUString>(UNO_NAME_REDLINE_DESCRIPTION, "description"); extractor.extract<OUString>(UNO_NAME_REDLINE_COMMENT, "comment"); - if (auto xStart = xRedlineProperties->getPropertyValue(UNO_NAME_REDLINE_START) - .query<css::text::XTextRange>()) + + auto xStart = xRedlineProperties->getPropertyValue(UNO_NAME_REDLINE_START) + .query<css::text::XTextRange>(); + auto xEnd = xRedlineProperties->getPropertyValue(UNO_NAME_REDLINE_END) + .query<css::text::XTextRange>(); + if (xStart) { auto xCursor = xStart->getText()->createTextCursorByRange(xStart); xCursor->goLeft(200, /*bExpand*/ true); rJsonWriter.put("textBefore", xCursor->getString()); } - if (auto xEnd = xRedlineProperties->getPropertyValue(UNO_NAME_REDLINE_END) - .query<css::text::XTextRange>()) + if (xEnd) { auto xCursor = xEnd->getText()->createTextCursorByRange(xEnd); xCursor->goRight(200, /*bExpand*/ true); rJsonWriter.put("textAfter", xCursor->getString()); } + OUString changeText; + if (xStart && xEnd) + { + // Read the added / formatted text from the main XText + auto xCursor = xStart->getText()->createTextCursorByRange(xStart); + xCursor->gotoRange(xEnd, /*bExpand*/ true); + changeText = xCursor->getString(); + } + if (changeText.isEmpty()) + { + // It is unlikely that we get here: the change text will be obtained above, + // even for deletion change + if (auto xRedlineText = xRedlineProperties->getPropertyValue(UNO_NAME_REDLINE_TEXT) + .query<css::text::XText>()) + changeText = xRedlineText->getString(); + } + rJsonWriter.put("textChanged", changeText); // write unconditionally // UNO_NAME_REDLINE_IDENTIFIER: OUString (the value of a pointer, not persistent) // UNO_NAME_REDLINE_MOVED_ID: sal_uInt32; 0 == not moved, 1 == moved, but don't have its pair, 2+ == unique ID // UNO_NAME_REDLINE_SUCCESSOR_DATA: uno::Sequence<beans::PropertyValue> // UNO_NAME_IS_IN_HEADER_FOOTER: bool // UNO_NAME_MERGE_LAST_PARA: bool - // UNO_NAME_REDLINE_TEXT: uno::Reference<text::XText> } }