officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu |   14 +++
 sw/inc/cmdid.h                                                      |    2 
 sw/inc/editsh.hxx                                                   |    1 
 sw/inc/swmodule.hxx                                                 |    2 
 sw/qa/core/edit/edit.cxx                                            |   39 
++++++++++
 sw/sdi/_viewsh.sdi                                                  |    6 +
 sw/sdi/swriter.sdi                                                  |   19 ++++
 sw/source/core/edit/edredln.cxx                                     |   23 
+++++
 sw/source/uibase/uiview/view2.cxx                                   |    5 +
 9 files changed, 109 insertions(+), 2 deletions(-)

New commits:
commit 7af8b3d3305fe8344cb9339269c5dc3f1cd44650
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Tue Mar 18 08:49:46 2025 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Wed Mar 19 14:42:04 2025 +0100

    cool#11357 sw redline reinstate: implement this for a single insert
    
    When reviewing a document with tracked changes, sometimes we want to
    reject a change with history, which is currently hard to do on the UI.
    
    For a single insert, a workaround is to select the insert redline and
    then press delete, that'll create a delete redline on top of the insert
    one.
    
    Fix the problem by adding a new .uno:ReinstateTrackedChange UNO command
    that does this for the insert redline under cursor.
    
    More cases (e.g. handle all selected insert redlines) are still to be
    handled.
    
    Change-Id: I61dbe38bcfffc9a0a9cf009531d8bf28cfd1e13b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/183115
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git 
a/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu 
b/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu
index ef3152896a4d..25d5472d8ec0 100644
--- a/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu
+++ b/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu
@@ -304,6 +304,20 @@
           <value>1</value>
         </prop>
       </node>
+      <node oor:name=".uno:ReinstateTrackedChange" oor:op="replace">
+        <prop oor:name="Label" oor:type="xs:string">
+          <value xml:lang="en-US">Reinstate</value>
+        </prop>
+        <prop oor:name="TooltipLabel" oor:type="xs:string">
+          <value xml:lang="en-US">Reinstate Track Change</value>
+        </prop>
+        <prop oor:name="PopupLabel" oor:type="xs:string">
+          <value xml:lang="en-US">Reinstate Change</value>
+        </prop>
+        <prop oor:name="Properties" oor:type="xs:int">
+          <value>1</value>
+        </prop>
+      </node>
       <node oor:name=".uno:NextTrackedChange" oor:op="replace">
         <prop oor:name="Label" oor:type="xs:string">
           <value xml:lang="en-US">Next</value>
diff --git a/sw/inc/cmdid.h b/sw/inc/cmdid.h
index 079f0d0f00bf..70dd4728e9f3 100644
--- a/sw/inc/cmdid.h
+++ b/sw/inc/cmdid.h
@@ -143,7 +143,7 @@ class SwUINumRuleItem;
 #define FN_NUM_CONTINUE              (FN_EDIT2 + 36)    /* continue previous 
numbering */
 #define FN_REDLINE_ACCEPT_DIRECT     (FN_EDIT2 + 37)    /* accept redline at 
current position*/
 #define FN_REDLINE_REJECT_DIRECT     (FN_EDIT2 + 38)    /* reject redline at 
current position*/
-// free
+#define FN_REDLINE_REINSTATE_DIRECT  (FN_EDIT2 + 39)    /* reinstate redline 
at current position*/
 // free
 #define FN_REDLINE_NEXT_CHANGE       (FN_EDIT2 + 41)    /* Go to the next 
change */
 #define FN_REDLINE_PREV_CHANGE       (FN_EDIT2 + 42)    /* Go to the previous 
change */
diff --git a/sw/inc/editsh.hxx b/sw/inc/editsh.hxx
index 6ad93013acca..c9444a3e0f78 100644
--- a/sw/inc/editsh.hxx
+++ b/sw/inc/editsh.hxx
@@ -959,6 +959,7 @@ public:
     SW_DLLPUBLIC bool RejectRedline( SwRedlineTable::size_type nPos );
     bool AcceptRedlinesInSelection();
     bool RejectRedlinesInSelection();
+    void ReinstateRedline(SwRedlineTable::size_type nPos);
 
     /** Search Redline for this Data and @return position in array.
      If not found, return SwRedlineTable::npos. */
diff --git a/sw/inc/swmodule.hxx b/sw/inc/swmodule.hxx
index 6d39a3dc76c5..6199f964d2fe 100644
--- a/sw/inc/swmodule.hxx
+++ b/sw/inc/swmodule.hxx
@@ -204,7 +204,7 @@ public:
     /// See SwXTextDocument::getTrackedChangeAuthors().
     void                GetRedlineAuthorInfo(tools::JsonWriter& rJsonWriter);
     std::size_t         InsertRedlineAuthor(const OUString& rAuthor);
-    void                SetRedlineAuthor(const OUString& rAuthor); // for unit 
tests
+    SW_DLLPUBLIC void   SetRedlineAuthor(const OUString& rAuthor); // for unit 
tests
 
     void                GetInsertAuthorAttr(std::size_t nAuthor, SfxItemSet 
&rSet);
     void                GetDeletedAuthorAttr(std::size_t nAuthor, SfxItemSet 
&rSet);
diff --git a/sw/qa/core/edit/edit.cxx b/sw/qa/core/edit/edit.cxx
index b8ad7ff58743..10705063a001 100644
--- a/sw/qa/core/edit/edit.cxx
+++ b/sw/qa/core/edit/edit.cxx
@@ -13,6 +13,9 @@
 #include <view.hxx>
 #include <wrtsh.hxx>
 #include <unotxdoc.hxx>
+#include <IDocumentRedlineAccess.hxx>
+#include <swmodule.hxx>
+#include <redline.hxx>
 
 namespace
 {
@@ -78,6 +81,42 @@ CPPUNIT_TEST_FIXTURE(Test, testDeleteSelNormalize)
     CPPUNIT_ASSERT_EQUAL(nExpectedCharPos, rCursor.nContent.GetIndex());
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testRedlineReinstateSingleInsert)
+{
+    // Given a document with a single insertion:
+    createSwDoc();
+    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
+    pWrtShell->Insert("aaa");
+    SwModule* pModule = SwModule::get();
+    pModule->SetRedlineAuthor("Alice");
+    RedlineFlags nMode = pWrtShell->GetRedlineFlags();
+    pWrtShell->SetRedlineFlags(nMode | RedlineFlags::On);
+    pWrtShell->Insert("bbb");
+    pWrtShell->SetRedlineFlags(nMode);
+    pWrtShell->Insert("ccc");
+
+    // When a 2nd user reinstates that change:
+    pModule->SetRedlineAuthor("Bob");
+    pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 4, 
/*bBasicCall=*/false);
+    dispatchCommand(mxComponent, ".uno:ReinstateTrackedChange", {});
+
+    // Then make sure this results in a delete on top of an insert:
+    SwDoc* pDoc = pWrtShell->GetDoc();
+    IDocumentRedlineAccess& rIDRA = pDoc->getIDocumentRedlineAccess();
+    SwRedlineTable& rRedlines = rIDRA.GetRedlineTable();
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rRedlines.size());
+    const SwRangeRedline* pRedline = rRedlines[0];
+    const SwRedlineData& rRedlineData = pRedline->GetRedlineData(0);
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 1 (Delete)
+    // - Actual  : 0 (Insert)
+    // i.e. reinstate didn't happen.
+    CPPUNIT_ASSERT_EQUAL(RedlineType::Delete, rRedlineData.GetType());
+    CPPUNIT_ASSERT(rRedlineData.Next());
+    const SwRedlineData& rInnerRedlineData = *rRedlineData.Next();
+    CPPUNIT_ASSERT_EQUAL(RedlineType::Insert, rInnerRedlineData.GetType());
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/sw/sdi/_viewsh.sdi b/sw/sdi/_viewsh.sdi
index 052473088128..c342557adc1c 100644
--- a/sw/sdi/_viewsh.sdi
+++ b/sw/sdi/_viewsh.sdi
@@ -211,6 +211,12 @@ interface BaseTextEditView
         StateMethod = GetState ;
         DisableFlags="SfxDisableFlags::SwOnMailboxEditor";
     ]
+    FN_REDLINE_REINSTATE_DIRECT
+    [
+        ExecMethod = Execute ;
+        StateMethod = GetState ;
+        DisableFlags="SfxDisableFlags::SwOnMailboxEditor";
+    ]
     FN_REDLINE_NEXT_CHANGE
     [
         ExecMethod = Execute ;
diff --git a/sw/sdi/swriter.sdi b/sw/sdi/swriter.sdi
index cbc33ee85e34..baeae666cec0 100644
--- a/sw/sdi/swriter.sdi
+++ b/sw/sdi/swriter.sdi
@@ -8024,6 +8024,25 @@ SfxVoidItem AcceptTrackedChange FN_REDLINE_ACCEPT_DIRECT
     GroupId = SfxGroupId::Edit;
 ]
 
+SfxVoidItem ReinstateTrackedChange FN_REDLINE_REINSTATE_DIRECT
+( SfxUInt32Item ReinstateTrackedChange FN_REDLINE_REINSTATE_DIRECT )
+[
+    AutoUpdate = FALSE,
+    FastCall = FALSE,
+    ReadOnlyDoc = FALSE,
+    Toggle = FALSE,
+    Container = FALSE,
+    RecordAbsolute = FALSE,
+    RecordPerSet;
+    Asynchron;
+
+
+    AccelConfig = TRUE,
+    MenuConfig = TRUE,
+    ToolBoxConfig = TRUE,
+    GroupId = SfxGroupId::Edit;
+]
+
 SfxVoidItem AcceptAllTrackedChanges FN_REDLINE_ACCEPT_ALL
 [
     AutoUpdate = FALSE,
diff --git a/sw/source/core/edit/edredln.cxx b/sw/source/core/edit/edredln.cxx
index 037f8e0558f2..8d992e56ddef 100644
--- a/sw/source/core/edit/edredln.cxx
+++ b/sw/source/core/edit/edredln.cxx
@@ -80,6 +80,29 @@ bool SwEditShell::AcceptRedline( SwRedlineTable::size_type 
nPos )
     return bRet;
 }
 
+void SwEditShell::ReinstateRedline(SwRedlineTable::size_type nPos)
+{
+    CurrShell aCurr(this);
+    StartAllAction();
+
+    if (!IsRedlineOn())
+    {
+        RedlineFlags nMode = GetRedlineFlags();
+        SetRedlineFlags(nMode | RedlineFlags::On, /*bRecordAllViews=*/false);
+    }
+
+    const SwRangeRedline& rRedline = GetRedline(nPos);
+    SwPaM aPaM(*rRedline.GetPoint());
+    aPaM.SetMark();
+    *aPaM.GetMark() = *rRedline.GetMark();
+    if (rRedline.GetType() == RedlineType::Insert)
+    {
+        DeleteSel(aPaM, /*isArtificialSelection=*/true);
+    }
+
+    EndAllAction();
+}
+
 bool SwEditShell::RejectRedline( SwRedlineTable::size_type nPos )
 {
     CurrShell aCurr( this );
diff --git a/sw/source/uibase/uiview/view2.cxx 
b/sw/source/uibase/uiview/view2.cxx
index 4219a2415a5d..7dae30f73886 100644
--- a/sw/source/uibase/uiview/view2.cxx
+++ b/sw/source/uibase/uiview/view2.cxx
@@ -891,6 +891,7 @@ void SwView::Execute(SfxRequest &rReq)
         case FN_REDLINE_REJECT_DIRECT:
         case FN_REDLINE_ACCEPT_TONEXT:
         case FN_REDLINE_REJECT_TONEXT:
+        case FN_REDLINE_REINSTATE_DIRECT:
         {
             SwDoc *pDoc = m_pWrtShell->GetDoc();
             SwPaM *pCursor = m_pWrtShell->GetCursor();
@@ -1070,6 +1071,10 @@ void SwView::Execute(SfxRequest &rReq)
                 {
                     if (FN_REDLINE_ACCEPT_DIRECT == nSlot || 
FN_REDLINE_ACCEPT_TONEXT == nSlot)
                         m_pWrtShell->AcceptRedline(nRedline);
+                    else if (nSlot == FN_REDLINE_REINSTATE_DIRECT)
+                    {
+                        m_pWrtShell->ReinstateRedline(nRedline);
+                    }
                     else
                         m_pWrtShell->RejectRedline(nRedline);
                 }

Reply via email to