include/sfx2/objsh.hxx                                               |    2 
 officecfg/registry/data/org/openoffice/Office/UI/Controller.xcu      |   28 
+++++
 officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu |   11 ++
 officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu  |   16 +++
 sc/source/ui/docshell/docsh.cxx                                      |    2 
 sc/source/ui/inc/docsh.hxx                                           |    2 
 sfx2/source/control/unoctitm.cxx                                     |    2 
 sfx2/source/doc/objxtor.cxx                                          |    2 
 sw/UIConfig_swriter.mk                                               |    1 
 sw/inc/IDocumentRedlineAccess.hxx                                    |    4 
 sw/inc/cmdid.h                                                       |    3 
 sw/inc/docsh.hxx                                                     |    2 
 sw/inc/editsh.hxx                                                    |    2 
 sw/qa/extras/tiledrendering/tiledrendering.cxx                       |   47 
+++++++--
 sw/sdi/_viewsh.sdi                                                   |   19 +++
 sw/sdi/swriter.sdi                                                   |   51 
++++++++++
 sw/source/core/doc/DocumentRedlineManager.cxx                        |   26 
+++--
 sw/source/core/edit/edredln.cxx                                      |    4 
 sw/source/core/inc/DocumentRedlineManager.hxx                        |    4 
 sw/source/uibase/app/docsh.cxx                                       |    6 -
 sw/source/uibase/inc/wrtsh.hxx                                       |    2 
 sw/source/uibase/uiview/view2.cxx                                    |   21 
+++-
 sw/source/uibase/uiview/viewstat.cxx                                 |    8 +
 sw/source/uibase/wrtsh/select.cxx                                    |    4 
 sw/uiconfig/swriter/popupmenu/recordtrackedchanges.xml               |   13 ++
 25 files changed, 246 insertions(+), 36 deletions(-)

New commits:
commit b2a22d06b324e7375cf2013af9ceaef5092b74c5
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Tue Mar 4 08:59:28 2025 +0100
Commit:     Caolán McNamara <caolan.mcnam...@collabora.com>
CommitDate: Wed Mar 5 09:37:52 2025 +0100

    cool#11226 sw per-view redline on: allow both per-view and per-doc
    
    Have two windows for a document, record changes in one view, and be
    surprised that now this is not turned on in the other view since commit
    ae6d396552cd3cebd7fba4942e6ca2fd5de579af (cool#11226 sw per-view redline
    on: add view-aware getter, 2025-03-03).
    
    Adding the ability to record changes per-view is intentional, but it was
    not a deliberate choice to also remove the old per-document recording.
    
    Fix this by turning the "is recording on" UI into a tristate, so the
    user can enable recording for all document windows or just the current
    document window -- similar to how showing changes can be off, inline and
    there are also 2 more on-margin options.
    
    The state of the new UNO commands still has to be implemented.
    
    Change-Id: I1e5271d4cc8900a28c7a8da8d34e00fec9e2e1b0
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182455
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Tested-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/include/sfx2/objsh.hxx b/include/sfx2/objsh.hxx
index 3922a820a7dd..4b245a63a057 100644
--- a/include/sfx2/objsh.hxx
+++ b/include/sfx2/objsh.hxx
@@ -690,7 +690,7 @@ public:
     // slots used for Calc:         FID_CHG_RECORD, SID_CHG_PROTECT
     virtual bool    IsChangeRecording(SfxViewShell* pViewShell = nullptr) 
const;
     virtual bool    HasChangeRecordProtection() const;
-    virtual void    SetChangeRecording( bool bActivate, bool bLockAllViews = 
false );
+    virtual void    SetChangeRecording( bool bActivate, bool bLockAllViews = 
false, bool bRecordAllViews = true );
     virtual void    SetProtectionPassword( const OUString &rPassword );
     virtual bool    GetProtectionHash( /*out*/ css::uno::Sequence< sal_Int8 > 
&rPasswordHash );
 
diff --git a/officecfg/registry/data/org/openoffice/Office/UI/Controller.xcu 
b/officecfg/registry/data/org/openoffice/Office/UI/Controller.xcu
index 2d99b67a7368..afda5d02e4f9 100644
--- a/officecfg/registry/data/org/openoffice/Office/UI/Controller.xcu
+++ b/officecfg/registry/data/org/openoffice/Office/UI/Controller.xcu
@@ -579,6 +579,20 @@
           <value>statisticsmenu</value>
         </prop>
       </node>
+      <node oor:name="c46" oor:op="replace">
+        <prop oor:name="Command">
+          <value>.uno:RecordTrackedChangesMenu</value>
+        </prop>
+        <prop oor:name="Module">
+          <value/>
+        </prop>
+        <prop oor:name="Controller">
+          <value>com.sun.star.comp.framework.ResourceMenuController</value>
+        </prop>
+        <prop oor:name="Value">
+          <value>recordtrackedchanges</value>
+        </prop>
+      </node>
       <node oor:name="WindowListMenu" oor:op="replace">
         <prop oor:name="Command">
           <value>.uno:WindowList</value>
@@ -807,6 +821,20 @@
           <value>.uno:ShowTrackedChangesMenu</value>
         </prop>
       </node>
+      <node oor:name="RecordTrackedChangesController" oor:op="replace">
+        <prop oor:name="Command">
+          <value>.uno:TrackChanges</value>
+        </prop>
+        <prop oor:name="Module">
+          <value/>
+        </prop>
+        <prop oor:name="Controller">
+          
<value>com.sun.star.comp.framework.GenericPopupToolbarController</value>
+        </prop>
+        <prop oor:name="Value">
+          <value>.uno:RecordTrackedChangesMenu</value>
+        </prop>
+      </node>
       <node oor:name="ConnectorToolBox" oor:op="replace">
         <prop oor:name="Command">
           <value>.uno:ConnectorToolbox</value>
diff --git 
a/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu 
b/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu
index 33887fc92394..4b1fae3b1074 100644
--- a/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu
+++ b/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu
@@ -6980,6 +6980,17 @@ bit 3 (0x8): #define 
UICOMMANDDESCRIPTION_PROPERTIES_TOGGLEBUTTON 8
           <value>1</value>
         </prop>
       </node>
+      <node oor:name=".uno:RecordTrackedChangesMenu" oor:op="replace">
+        <prop oor:name="Label" oor:type="xs:string">
+          <value xml:lang="en-US">Change record mode</value>
+        </prop>
+        <prop oor:name="ContextLabel" oor:type="xs:string">
+          <value xml:lang="en-US">Record mode</value>
+        </prop>
+        <prop oor:name="Properties" oor:type="xs:int">
+          <value>1</value>
+        </prop>
+      </node>
       <node oor:name=".uno:AVMediaPlayer" oor:op="replace">
         <prop oor:name="Label" oor:type="xs:string">
           <value xml:lang="en-US">Me~dia Player</value>
diff --git 
a/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu 
b/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu
index 3c541c1c8eea..f1b60c455faa 100644
--- a/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu
+++ b/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu
@@ -922,6 +922,22 @@
           <value xml:lang="en-US">~Insertions In Margin</value>
         </prop>
       </node>
+      <node oor:name=".uno:TrackChangesInThisView" oor:op="replace">
+        <prop oor:name="Label" oor:type="xs:string">
+          <value xml:lang="en-US">Record changes in this view</value>
+        </prop>
+        <prop oor:name="ContextLabel" oor:type="xs:string">
+          <value xml:lang="en-US">~Changes in this view</value>
+        </prop>
+      </node>
+      <node oor:name=".uno:TrackChangesInAllViews" oor:op="replace">
+        <prop oor:name="Label" oor:type="xs:string">
+          <value xml:lang="en-US">Record changes in all views</value>
+        </prop>
+        <prop oor:name="ContextLabel" oor:type="xs:string">
+          <value xml:lang="en-US">~Changes in all views</value>
+        </prop>
+      </node>
       <node oor:name=".uno:ToggleObjectLayer" oor:op="replace">
         <prop oor:name="Label" oor:type="xs:string">
           <value xml:lang="en-US">Change Position</value>
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index 71d46c36cb27..3720fa2ee685 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -3383,7 +3383,7 @@ bool ScDocShell::HasChangeRecordProtection() const
     return bRes;
 }
 
-void ScDocShell::SetChangeRecording( bool bActivate, bool /*bLockAllViews*/ )
+void ScDocShell::SetChangeRecording( bool bActivate, bool /*bLockAllViews*/, 
bool /*bRecordAllViews*/ )
 {
     bool bOldChangeRecording = IsChangeRecording();
 
diff --git a/sc/source/ui/inc/docsh.hxx b/sc/source/ui/inc/docsh.hxx
index b443d8db5624..127700949474 100644
--- a/sc/source/ui/inc/docsh.hxx
+++ b/sc/source/ui/inc/docsh.hxx
@@ -427,7 +427,7 @@ public:
     // see also:    FID_CHG_RECORD, SID_CHG_PROTECT
     virtual bool    IsChangeRecording(SfxViewShell* pViewShell = nullptr) 
const override;
     virtual bool    HasChangeRecordProtection() const override;
-    virtual void    SetChangeRecording( bool bActivate, bool bLockAllViews = 
false ) override;
+    virtual void    SetChangeRecording( bool bActivate, bool bLockAllViews = 
false, bool bRecordAllViews = true ) override;
     virtual void    SetProtectionPassword( const OUString &rPassword ) 
override;
     virtual bool    GetProtectionHash( /*out*/ css::uno::Sequence< sal_Int8 > 
&rPasswordHash ) override;
 
diff --git a/sfx2/source/control/unoctitm.cxx b/sfx2/source/control/unoctitm.cxx
index 86f0e10d0a42..26a8e694fd12 100644
--- a/sfx2/source/control/unoctitm.cxx
+++ b/sfx2/source/control/unoctitm.cxx
@@ -1158,6 +1158,8 @@ const std::map<std::u16string_view, KitUnoCommand>& 
GetKitUnoCommandList()
         { u"Underline", { PayloadType::IsActivePayload, true } },
         { u"ModifiedStatus", { PayloadType::IsActivePayload, true } },
         { u"TrackChanges", { PayloadType::IsActivePayload, true } },
+        { u"TrackChangesInThisView", { PayloadType::IsActivePayload, true } },
+        { u"TrackChangesInAllViews", { PayloadType::IsActivePayload, true } },
         { u"ShowTrackedChanges", { PayloadType::IsActivePayload, true } },
         { u"AlignLeft", { PayloadType::IsActivePayload, true } },
         { u"AlignHorizontalCenter", { PayloadType::IsActivePayload, true } },
diff --git a/sfx2/source/doc/objxtor.cxx b/sfx2/source/doc/objxtor.cxx
index 486a9bae26cb..ec1441aad050 100644
--- a/sfx2/source/doc/objxtor.cxx
+++ b/sfx2/source/doc/objxtor.cxx
@@ -1108,7 +1108,7 @@ bool SfxObjectShell::HasChangeRecordProtection() const
 }
 
 
-void SfxObjectShell::SetChangeRecording( bool /*bActivate*/, bool 
/*bLockAllViews*/ )
+void SfxObjectShell::SetChangeRecording( bool /*bActivate*/, bool 
/*bLockAllViews*/, bool /*bRecordAllViews*/ )
 {
     // currently this function needs to be overwritten by Writer and Calc only
     SAL_WARN( "sfx.doc", "function not implemented" );
diff --git a/sw/UIConfig_swriter.mk b/sw/UIConfig_swriter.mk
index a371b4928ea5..2035d751480c 100644
--- a/sw/UIConfig_swriter.mk
+++ b/sw/UIConfig_swriter.mk
@@ -31,6 +31,7 @@ $(eval $(call gb_UIConfig_add_popupmenufiles,modules/swriter,\
        sw/uiconfig/swriter/popupmenu/table \
        sw/uiconfig/swriter/popupmenu/text \
        sw/uiconfig/swriter/popupmenu/showtrackedchanges \
+       sw/uiconfig/swriter/popupmenu/recordtrackedchanges \
 ))
 
 $(eval $(call gb_UIConfig_add_statusbarfiles,modules/swriter,\
diff --git a/sw/inc/IDocumentRedlineAccess.hxx 
b/sw/inc/IDocumentRedlineAccess.hxx
index ede30c26d39e..c1147b000a36 100644
--- a/sw/inc/IDocumentRedlineAccess.hxx
+++ b/sw/inc/IDocumentRedlineAccess.hxx
@@ -107,14 +107,14 @@ public:
         @param eMode
         [in] the new redline mode.
     */
-    virtual void SetRedlineFlags_intern(/*[in]*/RedlineFlags eMode) = 0;
+    virtual void SetRedlineFlags_intern(/*[in]*/RedlineFlags eMode, bool 
bRecordAllViews = true) = 0;
 
     /** Set a new redline mode.
 
         @param eMode
         [in] the new redline mode.
     */
-    virtual void SetRedlineFlags(/*[in]*/RedlineFlags eMode) = 0;
+    virtual void SetRedlineFlags(/*[in]*/RedlineFlags eMode, bool 
bRecordAllViews = true) = 0;
 
     /** Query if redlining is on.
 
diff --git a/sw/inc/cmdid.h b/sw/inc/cmdid.h
index 398d0eaa22e2..3d974afcd127 100644
--- a/sw/inc/cmdid.h
+++ b/sw/inc/cmdid.h
@@ -205,6 +205,9 @@ class SwUINumRuleItem;
 #define FN_SET_TRACKED_DELETIONS_IN_MARGIN     (FN_VIEW + 68)  /* Show final 
text (deletions in margin) */
 #define FN_SET_TRACKED_INSERTIONS_IN_MARGIN    (FN_VIEW + 69)  /* Show 
original text (insertions in margin) */
 #define FN_OUTLINE_LEVELS_SHOWN                (FN_VIEW + 70)
+#define FN_RECORD_TRACKED_CHANGES_MENU         (FN_VIEW + 71)  /* Menu for the 
track changes record modes */
+#define FN_TRACK_CHANGES_IN_THIS_VIEW          (FN_VIEW + 72)  /* Record track 
changes only in this view */
+#define FN_TRACK_CHANGES_IN_ALL_VIEWS          (FN_VIEW + 73)  /* Record track 
changes only in all views */
 
 // Region: Insert
 #define FN_INSERT_BOOKMARK      (FN_INSERT + 2 )  /* Bookmark */
diff --git a/sw/inc/docsh.hxx b/sw/inc/docsh.hxx
index 17b1b26f6e99..5140bd9daa99 100644
--- a/sw/inc/docsh.hxx
+++ b/sw/inc/docsh.hxx
@@ -323,7 +323,7 @@ public:
      see also:    FN_REDLINE_ON, FN_REDLINE_ON */
     virtual bool    IsChangeRecording(SfxViewShell* pViewShell = nullptr) 
const override;
     virtual bool    HasChangeRecordProtection() const override;
-    virtual void    SetChangeRecording( bool bActivate, bool bLockAllViews = 
false ) override;
+    virtual void    SetChangeRecording( bool bActivate, bool bLockAllViews = 
false, bool bRecordAllViews = true ) override;
     virtual void    SetProtectionPassword( const OUString &rPassword ) 
override;
     virtual bool    GetProtectionHash( /*out*/ css::uno::Sequence< sal_Int8 > 
&rPasswordHash ) override;
 
diff --git a/sw/inc/editsh.hxx b/sw/inc/editsh.hxx
index 2b753530159a..c83839db4431 100644
--- a/sw/inc/editsh.hxx
+++ b/sw/inc/editsh.hxx
@@ -951,7 +951,7 @@ public:
 
     /// For Redlining.
     RedlineFlags GetRedlineFlags() const;
-    void SetRedlineFlags( RedlineFlags eMode );
+    void SetRedlineFlags( RedlineFlags eMode, bool bRecordAllViews = true );
     bool IsRedlineOn() const;
     SwRedlineTable::size_type GetRedlineCount() const;
     const SwRangeRedline& GetRedline( SwRedlineTable::size_type nPos ) const;
diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx 
b/sw/qa/extras/tiledrendering/tiledrendering.cxx
index 5cfdbec5d6e4..030bb6a589a8 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx
@@ -4850,7 +4850,7 @@ CPPUNIT_TEST_FIXTURE(SwTiledRenderingTest, 
testTrackChangesPerViewEnableOne)
     SfxLokHelper::setView(nView1);
     aView1.m_aStateChanges.clear();
     aView2.m_aStateChanges.clear();
-    comphelper::dispatchCommand(".uno:TrackChanges", {});
+    comphelper::dispatchCommand(".uno:TrackChangesInThisView", {});
 
     // Then make sure view1 gets a state track changes state change, but not 
view2:
     // Filter out .uno:ModifiedStatus=true, which is not interesting here.
@@ -4860,13 +4860,13 @@ CPPUNIT_TEST_FIXTURE(SwTiledRenderingTest, 
testTrackChangesPerViewEnableOne)
     CPPUNIT_ASSERT(aRecord2.empty());
 
     // And given a reset state (both view1 and view2 recording is disabled):
-    comphelper::dispatchCommand(".uno:TrackChanges", {});
+    comphelper::dispatchCommand(".uno:TrackChangesInThisView", {});
 
     // When recording changes in view2:
     SfxLokHelper::setView(nView2);
     aView1.m_aStateChanges.clear();
     aView2.m_aStateChanges.clear();
-    comphelper::dispatchCommand(".uno:TrackChanges", {});
+    comphelper::dispatchCommand(".uno:TrackChangesInThisView", {});
 
     // Then make sure view2 gets a state track changes state change, but not 
view1:
     CPPUNIT_ASSERT(aView1.m_aStateChanges.empty());
@@ -4886,13 +4886,13 @@ CPPUNIT_TEST_FIXTURE(SwTiledRenderingTest, 
testTrackChangesPerViewEnableBoth)
     int nView2 = SfxLokHelper::getView();
     SwWrtShell* pWrtShell2 = pXTextDocument->GetDocShell()->GetWrtShell();
     SfxLokHelper::setView(nView1);
-    comphelper::dispatchCommand(".uno:TrackChanges", {});
+    comphelper::dispatchCommand(".uno:TrackChangesInThisView", {});
     SfxLokHelper::setView(nView2);
     CPPUNIT_ASSERT(pWrtShell1->GetViewOptions()->IsRedlineRecordingOn());
     CPPUNIT_ASSERT(!pWrtShell2->GetViewOptions()->IsRedlineRecordingOn());
 
     // When turning on track changes for view2:
-    comphelper::dispatchCommand(".uno:TrackChanges", {});
+    comphelper::dispatchCommand(".uno:TrackChangesInThisView", {});
 
     // Then make sure both views have track changes turned on:
     CPPUNIT_ASSERT(pWrtShell1->GetViewOptions()->IsRedlineRecordingOn());
@@ -4915,7 +4915,7 @@ CPPUNIT_TEST_FIXTURE(SwTiledRenderingTest, 
testTrackChangesPerViewInsert)
     int nView2 = SfxLokHelper::getView();
     SwWrtShell* pWrtShell2 = pXTextDocument->GetDocShell()->GetWrtShell();
     SfxLokHelper::setView(nView1);
-    comphelper::dispatchCommand(".uno:TrackChanges", {});
+    comphelper::dispatchCommand(".uno:TrackChangesInThisView", {});
 
     // When view 1 types:
     pWrtShell1->SttEndDoc(/*bStt=*/true);
@@ -4949,7 +4949,7 @@ CPPUNIT_TEST_FIXTURE(SwTiledRenderingTest, 
testTrackChangesPerViewDelete)
     int nView2 = SfxLokHelper::getView();
     SwWrtShell* pWrtShell2 = pXTextDocument->GetDocShell()->GetWrtShell();
     SfxLokHelper::setView(nView1);
-    comphelper::dispatchCommand(".uno:TrackChanges", {});
+    comphelper::dispatchCommand(".uno:TrackChangesInThisView", {});
 
     // When view 1 deletes:
     pWrtShell1->SttEndDoc(/*bStt=*/true);
@@ -4971,6 +4971,39 @@ CPPUNIT_TEST_FIXTURE(SwTiledRenderingTest, 
testTrackChangesPerViewDelete)
     CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(1), 
pWrtShell2->GetRedlineCount());
 }
 
+CPPUNIT_TEST_FIXTURE(SwTiledRenderingTest, testTrackChangesPerDocInsert)
+{
+    // Given 2 views, view 1 turns on per-doc change recording:
+    SwXTextDocument* pXTextDocument = createDoc();
+    CPPUNIT_ASSERT(pXTextDocument);
+    ViewCallback aView1;
+    int nView1 = SfxLokHelper::getView();
+    SwWrtShell* pWrtShell1 = pXTextDocument->GetDocShell()->GetWrtShell();
+    pWrtShell1->Insert(u"X"_ustr);
+    SfxLokHelper::createView();
+    ViewCallback aView2;
+    int nView2 = SfxLokHelper::getView();
+    SwWrtShell* pWrtShell2 = pXTextDocument->GetDocShell()->GetWrtShell();
+    SfxLokHelper::setView(nView1);
+    comphelper::dispatchCommand(".uno:TrackChanges", {});
+
+    // When view 1 types:
+    pWrtShell1->SttEndDoc(/*bStt=*/true);
+    pWrtShell1->Insert(u"A"_ustr);
+    // Then make sure a redline is created:
+    CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(1), 
pWrtShell1->GetRedlineCount());
+
+    // When view 2 types:
+    SfxLokHelper::setView(nView2);
+    pWrtShell2->SttEndDoc(/*bStt=*/false);
+    pWrtShell2->Insert(u"Z"_ustr);
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 2
+    // - Actual  : 1
+    // i.e. track changes recording was unconditionally per-view.
+    CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(2), 
pWrtShell2->GetRedlineCount());
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/sdi/_viewsh.sdi b/sw/sdi/_viewsh.sdi
index 0a9e92dea48f..30070158d0d5 100644
--- a/sw/sdi/_viewsh.sdi
+++ b/sw/sdi/_viewsh.sdi
@@ -149,6 +149,25 @@ interface BaseTextEditView
         StateMethod = GetState ;
         DisableFlags="SfxDisableFlags::SwOnMailboxEditor";
     ]
+    FN_TRACK_CHANGES_IN_THIS_VIEW
+    [
+        ExecMethod = Execute ;
+        StateMethod = GetState ;
+        DisableFlags="SfxDisableFlags::SwOnProtectedCursor";
+    ]
+    FN_TRACK_CHANGES_IN_ALL_VIEWS
+    [
+        ExecMethod = Execute ;
+        StateMethod = GetState ;
+        DisableFlags="SfxDisableFlags::SwOnProtectedCursor";
+    ]
+    FN_RECORD_TRACKED_CHANGES_MENU
+    [
+        ExecMethod = Execute ;
+        StateMethod = GetState ;
+        DisableFlags="SfxDisableFlags::SwOnProtectedCursor";
+    ]
+
     FN_REDLINE_SHOW // status()
     [
         ExecMethod = Execute;
diff --git a/sw/sdi/swriter.sdi b/sw/sdi/swriter.sdi
index 03d8b8d2c818..45750265e8eb 100644
--- a/sw/sdi/swriter.sdi
+++ b/sw/sdi/swriter.sdi
@@ -8528,6 +8528,57 @@ SfxBoolItem SetTrackedInsertionsInMargin 
FN_SET_TRACKED_INSERTIONS_IN_MARGIN
     GroupId = SfxGroupId::View;
 ]
 
+SfxVoidItem RecordTrackedChangesMenu FN_RECORD_TRACKED_CHANGES_MENU
+()
+[
+    AutoUpdate = FALSE,
+    FastCall = TRUE,
+    ReadOnlyDoc = FALSE,
+    Toggle = FALSE,
+    Container = FALSE,
+    RecordAbsolute = FALSE,
+    RecordPerSet;
+
+    AccelConfig = TRUE,
+    MenuConfig = TRUE,
+    ToolBoxConfig = TRUE,
+    GroupId = SfxGroupId::View;
+]
+
+SfxBoolItem TrackChangesInThisView FN_TRACK_CHANGES_IN_THIS_VIEW
+()
+[
+    AutoUpdate = TRUE,
+    FastCall = TRUE,
+    ReadOnlyDoc = FALSE,
+    Toggle = FALSE,
+    Container = FALSE,
+    RecordAbsolute = FALSE,
+    RecordPerSet;
+
+    AccelConfig = TRUE,
+    MenuConfig = TRUE,
+    ToolBoxConfig = TRUE,
+    GroupId = SfxGroupId::View;
+]
+
+SfxBoolItem TrackChangesInAllViews FN_TRACK_CHANGES_IN_ALL_VIEWS
+()
+[
+    AutoUpdate = TRUE,
+    FastCall = TRUE,
+    ReadOnlyDoc = FALSE,
+    Toggle = FALSE,
+    Container = FALSE,
+    RecordAbsolute = FALSE,
+    RecordPerSet;
+
+    AccelConfig = TRUE,
+    MenuConfig = TRUE,
+    ToolBoxConfig = TRUE,
+    GroupId = SfxGroupId::View;
+]
+
 SfxBoolItem UseHeaderFooterMenu FN_USE_HEADERFOOTERMENU
 ()
 [
diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx 
b/sw/source/core/doc/DocumentRedlineManager.cxx
index f5c32a701981..8ffc68726082 100644
--- a/sw/source/core/doc/DocumentRedlineManager.cxx
+++ b/sw/source/core/doc/DocumentRedlineManager.cxx
@@ -1174,7 +1174,7 @@ RedlineFlags 
DocumentRedlineManager::GetRedlineFlags(const SwViewShell* pViewShe
     return eRedlineFlags;
 }
 
-void DocumentRedlineManager::SetRedlineFlags( RedlineFlags eMode )
+void DocumentRedlineManager::SetRedlineFlags( RedlineFlags eMode, bool 
bRecordAllViews )
 {
     if( GetRedlineFlags() == eMode )
         return;
@@ -1249,7 +1249,7 @@ void DocumentRedlineManager::SetRedlineFlags( 
RedlineFlags eMode )
 
         m_rDoc.SetInXMLImport( bSaveInXMLImportFlag );
     }
-    SetRedlineFlags_intern(eMode);
+    SetRedlineFlags_intern(eMode, bRecordAllViews);
     m_rDoc.getIDocumentState().SetModified();
 
     // #TODO - add 'SwExtraRedlineTable' also ?
@@ -1265,19 +1265,27 @@ bool DocumentRedlineManager::IsIgnoreRedline() const
     return bool(RedlineFlags::Ignore & GetRedlineFlags());
 }
 
-void DocumentRedlineManager::SetRedlineFlags_intern(RedlineFlags eMode)
+void DocumentRedlineManager::SetRedlineFlags_intern(RedlineFlags eMode, bool 
bRecordAllViews)
 {
     SwDocShell* pDocShell = m_rDoc.GetDocShell();
     SwViewShell* pViewShell = pDocShell ? pDocShell->GetWrtShell() : nullptr;
     if (pViewShell)
     {
-        // Recording can be per-view, the rest is per-document.
-        auto bRedlineRecordingOn = bool(eMode & RedlineFlags::On);
-        SwViewOption aOpt(*pViewShell->GetViewOptions());
-        if (aOpt.IsRedlineRecordingOn() != bRedlineRecordingOn)
+        // Recording may be per-view, the rest is per-document.
+        for(SwViewShell& rSh : pViewShell->GetRingContainer())
         {
-            aOpt.SetRedlineRecordingOn(bRedlineRecordingOn);
-            pViewShell->ApplyViewOptions(aOpt);
+            if (!bRecordAllViews && &rSh != pViewShell)
+            {
+                continue;
+            }
+
+            auto bRedlineRecordingOn = bool(eMode & RedlineFlags::On);
+            SwViewOption aOpt(*rSh.GetViewOptions());
+            if (aOpt.IsRedlineRecordingOn() != bRedlineRecordingOn)
+            {
+                aOpt.SetRedlineRecordingOn(bRedlineRecordingOn);
+                rSh.ApplyViewOptions(aOpt);
+            }
         }
     }
 
diff --git a/sw/source/core/edit/edredln.cxx b/sw/source/core/edit/edredln.cxx
index 76f529dff7b0..3865fd94dcca 100644
--- a/sw/source/core/edit/edredln.cxx
+++ b/sw/source/core/edit/edredln.cxx
@@ -29,13 +29,13 @@ RedlineFlags SwEditShell::GetRedlineFlags() const
     return GetDoc()->getIDocumentRedlineAccess().GetRedlineFlags(this);
 }
 
-void SwEditShell::SetRedlineFlags( RedlineFlags eMode )
+void SwEditShell::SetRedlineFlags( RedlineFlags eMode, bool bRecordAllViews )
 {
     if( eMode != GetDoc()->getIDocumentRedlineAccess().GetRedlineFlags() )
     {
         CurrShell aCurr( this );
         StartAllAction();
-        GetDoc()->getIDocumentRedlineAccess().SetRedlineFlags( eMode );
+        GetDoc()->getIDocumentRedlineAccess().SetRedlineFlags( eMode, 
bRecordAllViews );
         EndAllAction();
     }
 }
diff --git a/sw/source/core/inc/DocumentRedlineManager.hxx 
b/sw/source/core/inc/DocumentRedlineManager.hxx
index 5476c34e5407..34d9bb31cd98 100644
--- a/sw/source/core/inc/DocumentRedlineManager.hxx
+++ b/sw/source/core/inc/DocumentRedlineManager.hxx
@@ -38,9 +38,9 @@ public:
      */
     virtual RedlineFlags GetRedlineFlags(const SwViewShell* pViewShell = 
nullptr) const override;
 
-    virtual void SetRedlineFlags_intern(/*[in]*/RedlineFlags eMode) override;
+    virtual void SetRedlineFlags_intern(/*[in]*/RedlineFlags eMode, bool 
bRecordAllViews = true) override;
 
-    virtual void SetRedlineFlags(/*[in]*/RedlineFlags eMode) override;
+    virtual void SetRedlineFlags(/*[in]*/RedlineFlags eMode, bool 
bRecordAllViews = true) override;
 
     virtual bool IsRedlineOn() const override;
 
diff --git a/sw/source/uibase/app/docsh.cxx b/sw/source/uibase/app/docsh.cxx
index 6c64c98d0e74..f71093addeb4 100644
--- a/sw/source/uibase/app/docsh.cxx
+++ b/sw/source/uibase/app/docsh.cxx
@@ -1371,7 +1371,7 @@ bool SwDocShell::HasChangeRecordProtection() const
     return 
m_pWrtShell->getIDocumentRedlineAccess().GetRedlinePassword().hasElements();
 }
 
-void SwDocShell::SetChangeRecording( bool bActivate, bool bLockAllViews )
+void SwDocShell::SetChangeRecording( bool bActivate, bool bLockAllViews, bool 
bRecordAllViews )
 {
     RedlineFlags nOn = bActivate ? RedlineFlags::On : RedlineFlags::NONE;
     RedlineFlags nMode = m_pWrtShell->GetRedlineFlags();
@@ -1379,11 +1379,11 @@ void SwDocShell::SetChangeRecording( bool bActivate, 
bool bLockAllViews )
     {
         // tdf#107870: prevent jumping to cursor
         auto aViewGuard(LockAllViews());
-        m_pWrtShell->SetRedlineFlagsAndCheckInsMode( (nMode & 
~RedlineFlags::On) | nOn );
+        m_pWrtShell->SetRedlineFlagsAndCheckInsMode( (nMode & 
~RedlineFlags::On) | nOn, bRecordAllViews );
     }
     else
     {
-        m_pWrtShell->SetRedlineFlagsAndCheckInsMode( (nMode & 
~RedlineFlags::On) | nOn );
+        m_pWrtShell->SetRedlineFlagsAndCheckInsMode( (nMode & 
~RedlineFlags::On) | nOn, bRecordAllViews );
     }
 }
 
diff --git a/sw/source/uibase/inc/wrtsh.hxx b/sw/source/uibase/inc/wrtsh.hxx
index d527fda5ca24..ddbae7f59d3a 100644
--- a/sw/source/uibase/inc/wrtsh.hxx
+++ b/sw/source/uibase/inc/wrtsh.hxx
@@ -172,7 +172,7 @@ public:
     void    SetInsMode( bool bOn = true );
     void    ToggleInsMode() { SetInsMode( !m_bIns ); }
     bool    IsInsMode() const { return m_bIns; }
-    void    SetRedlineFlagsAndCheckInsMode( RedlineFlags eMode );
+    void    SetRedlineFlagsAndCheckInsMode( RedlineFlags eMode, bool 
bRecordAllViews = true );
 
     void    EnterSelFrameMode(const Point *pStartDrag = nullptr);
     void    LeaveSelFrameMode();
diff --git a/sw/source/uibase/uiview/view2.cxx 
b/sw/source/uibase/uiview/view2.cxx
index 039dbdf9665e..a2eebb647db3 100644
--- a/sw/source/uibase/uiview/view2.cxx
+++ b/sw/source/uibase/uiview/view2.cxx
@@ -766,15 +766,27 @@ void SwView::Execute(SfxRequest &rReq)
         }
         break;
         case FN_REDLINE_ON:
+        case FN_TRACK_CHANGES_IN_THIS_VIEW:
+        case FN_TRACK_CHANGES_IN_ALL_VIEWS:
         {
+            std::optional<bool> oOn;
             if( pArgs &&
                 SfxItemState::SET == pArgs->GetItemState(nSlot, false, &pItem 
))
+            {
+                oOn = static_cast<const SfxBoolItem*>(pItem)->GetValue();
+            }
+            else if (nSlot == FN_TRACK_CHANGES_IN_THIS_VIEW || nSlot == 
FN_TRACK_CHANGES_IN_ALL_VIEWS)
+            {
+                oOn = true;
+            }
+
+            if (oOn.has_value())
             {
                 IDocumentRedlineAccess& rIDRA = 
m_pWrtShell->getIDocumentRedlineAccess();
                 Sequence <sal_Int8> aPasswd = rIDRA.GetRedlinePassword();
                 if( aPasswd.hasElements() )
                 {
-                    OSL_ENSURE( !static_cast<const 
SfxBoolItem*>(pItem)->GetValue(), "SwView::Execute(): password set and 
redlining off doesn't match!" );
+                    OSL_ENSURE( !oOn.value(), "SwView::Execute(): password set 
and redlining off doesn't match!" );
 
                     // xmlsec05:    new password dialog
                     SfxPasswordDialog aPasswdDlg(GetFrameWeld());
@@ -822,13 +834,18 @@ void SwView::Execute(SfxRequest &rReq)
                 }
 
                 SwDocShell* pDocShell = GetDocShell();
-                pDocShell->SetChangeRecording( static_cast<const 
SfxBoolItem*>(pItem)->GetValue(), /*bLockAllViews=*/true );
+                bool bRecordAllViews = nSlot != FN_TRACK_CHANGES_IN_THIS_VIEW;
+                pDocShell->SetChangeRecording( oOn.value(), 
/*bLockAllViews=*/true, bRecordAllViews );
 
                 // Notify all view shells of this document, as the track 
changes mode is document-global.
                 for (SfxViewFrame* pViewFrame = 
SfxViewFrame::GetFirst(pDocShell); pViewFrame; pViewFrame = 
SfxViewFrame::GetNext(*pViewFrame, pDocShell))
                 {
                     pViewFrame->GetBindings().Invalidate(FN_REDLINE_ON);
                     pViewFrame->GetBindings().Update(FN_REDLINE_ON);
+                    
pViewFrame->GetBindings().Invalidate(FN_TRACK_CHANGES_IN_THIS_VIEW);
+                    
pViewFrame->GetBindings().Update(FN_TRACK_CHANGES_IN_THIS_VIEW);
+                    
pViewFrame->GetBindings().Invalidate(FN_TRACK_CHANGES_IN_ALL_VIEWS);
+                    
pViewFrame->GetBindings().Update(FN_TRACK_CHANGES_IN_ALL_VIEWS);
                 }
             }
         }
diff --git a/sw/source/uibase/uiview/viewstat.cxx 
b/sw/source/uibase/uiview/viewstat.cxx
index e7e8957846b1..fd568e6d7a1e 100644
--- a/sw/source/uibase/uiview/viewstat.cxx
+++ b/sw/source/uibase/uiview/viewstat.cxx
@@ -350,6 +350,14 @@ void SwView::GetState(SfxItemSet &rSet)
                 }
                 m_bForceChangesToolbar = false;
             break;
+            case FN_TRACK_CHANGES_IN_THIS_VIEW:
+            {
+            }
+            break;
+            case FN_TRACK_CHANGES_IN_ALL_VIEWS:
+            {
+            }
+            break;
             case FN_REDLINE_PROTECT :
                 rSet.Put( SfxBoolItem( nWhich, 
GetDocShell()->HasChangeRecordProtection() ) );
             break;
diff --git a/sw/source/uibase/wrtsh/select.cxx 
b/sw/source/uibase/wrtsh/select.cxx
index f5d01d196aae..13fe4c524837 100644
--- a/sw/source/uibase/wrtsh/select.cxx
+++ b/sw/source/uibase/wrtsh/select.cxx
@@ -769,9 +769,9 @@ void SwWrtShell::SetInsMode( bool bOn )
 }
 
 //Overwrite mode is incompatible with red-lining
-void SwWrtShell::SetRedlineFlagsAndCheckInsMode( RedlineFlags eMode )
+void SwWrtShell::SetRedlineFlagsAndCheckInsMode( RedlineFlags eMode, bool 
bRecordAllViews )
 {
-   SetRedlineFlags( eMode );
+   SetRedlineFlags( eMode, bRecordAllViews );
    if (IsRedlineOn())
        SetInsMode();
 }
diff --git a/sw/uiconfig/swriter/popupmenu/recordtrackedchanges.xml 
b/sw/uiconfig/swriter/popupmenu/recordtrackedchanges.xml
new file mode 100644
index 000000000000..f3132df4661d
--- /dev/null
+++ b/sw/uiconfig/swriter/popupmenu/recordtrackedchanges.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+-->
+<menu:menupopup xmlns:menu="http://openoffice.org/2001/menu";>
+  <menu:menuitem menu:id=".uno:TrackChangesInAllViews" menu:style="radio"/>
+  <menu:menuitem menu:id=".uno:TrackChangesInThisView" menu:style="radio"/>
+</menu:menupopup>

Reply via email to