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>
     }
 }
 

Reply via email to