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/tiledrendering2.cxx                      |   58 
++++++++--
 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 ++
 vcl/inc/strings.hrc                                                  |    2 
 26 files changed, 255 insertions(+), 40 deletions(-)

New commits:
commit 6686aa128eb22fefee660ca6913dec01a94741ca
Author:     Christian Lohmaier <lohmaier+libreoff...@googlemail.com>
AuthorDate: Wed Mar 5 11:36:27 2025 +0100
Commit:     Christian Lohmaier <lohmaier+libreoff...@googlemail.com>
CommitDate: Wed Mar 5 13:03:17 2025 +0100

    Revert "Resolves tdf#165517 - Rename Preferences to Settings on macOS"
    
    This reverts commit 11ecd11abab2a5f9e4779b36ca14420c644f923b.
    
    Reason for revert: requires coordingation to also rename in help
    and I also personally would like to have a clear statement that shows that 
impact on guides, wikipages, forum-posts, etc has also been addressed.
    
    Change-Id: I26b77e54923e9f33867148b37b80cfae64cc7ceb
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182528
    Tested-by: Jenkins
    Reviewed-by: Christian Lohmaier <lohmaier+libreoff...@googlemail.com>

diff --git a/vcl/inc/strings.hrc b/vcl/inc/strings.hrc
index 76bb4886effc..c4f173fc0f40 100644
--- a/vcl/inc/strings.hrc
+++ b/vcl/inc/strings.hrc
@@ -64,7 +64,7 @@
 #define SV_STDTEXT_SERVICENOTAVAILABLE               
NC_("SV_STDTEXT_SERVICENOTAVAILABLE", "The component (%s) could not be loaded.
Please start setup with the repair option.")
 
 #define SV_STDTEXT_ABOUT                             NC_("SV_STDTEXT_ABOUT", 
"About %PRODUCTNAME")
-#define SV_STDTEXT_PREFERENCES                       
NC_("SV_STDTEXT_PREFERENCES", "Settings...")
+#define SV_STDTEXT_PREFERENCES                       
NC_("SV_STDTEXT_PREFERENCES", "Preferences...")
 #define SV_STDTEXT_ALLFILETYPES                      
NC_("SV_STDTEXT_ALLFILETYPES", "Any type")
 
 #define SV_ACCESSERROR_NO_FONTS                      
NC_("SV_ACCESSERROR_NO_FONTS", "No fonts could be found on the system.")
commit 368e2e445c1941d37697cee05a50a34150d18015
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Tue Mar 4 08:59:28 2025 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Wed Mar 5 13:03:04 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/+/182527
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/include/sfx2/objsh.hxx b/include/sfx2/objsh.hxx
index 10b85c9964f3..475f4d81f7b2 100644
--- a/include/sfx2/objsh.hxx
+++ b/include/sfx2/objsh.hxx
@@ -696,7 +696,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 21fdf0298162..6babc6e31266 100644
--- a/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu
+++ b/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu
@@ -7021,6 +7021,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 9b2cefcc3ba6..bcacf991e058 100644
--- a/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu
+++ b/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu
@@ -925,6 +925,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 2157fb18a5aa..fbacb2ea2dab 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -3409,7 +3409,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 cbab1f0d8c40..ffb276a7ae43 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 976cd48ce152..c0e2dfbb4c73 100644
--- a/sfx2/source/control/unoctitm.cxx
+++ b/sfx2/source/control/unoctitm.cxx
@@ -1198,6 +1198,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 106743ee1850..9cc61dbfb9fc 100644
--- a/sfx2/source/doc/objxtor.cxx
+++ b/sfx2/source/doc/objxtor.cxx
@@ -1140,7 +1140,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 6bc32a541106..f6a9b99d55c7 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 340e57c8f5b4..5c7cda8f44af 100644
--- a/sw/inc/cmdid.h
+++ b/sw/inc/cmdid.h
@@ -206,6 +206,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 8bbc54837363..d6d54f136335 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 9d3a54c076b9..67e699a4deec 100644
--- a/sw/inc/editsh.hxx
+++ b/sw/inc/editsh.hxx
@@ -950,7 +950,7 @@ public:
 
     /// For Redlining.
     SW_DLLPUBLIC RedlineFlags GetRedlineFlags() const;
-    SW_DLLPUBLIC void SetRedlineFlags( RedlineFlags eMode );
+    SW_DLLPUBLIC void SetRedlineFlags( RedlineFlags eMode, bool 
bRecordAllViews = true );
     bool IsRedlineOn() const;
     SW_DLLPUBLIC SwRedlineTable::size_type GetRedlineCount() const;
     const SwRangeRedline& GetRedline( SwRedlineTable::size_type nPos ) const;
diff --git a/sw/qa/extras/tiledrendering/tiledrendering2.cxx 
b/sw/qa/extras/tiledrendering/tiledrendering2.cxx
index 8da396a393bb..1119ec2af287 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering2.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering2.cxx
@@ -388,7 +388,7 @@ CPPUNIT_TEST_FIXTURE(SwTiledRenderingTest, 
testTrackChangesPerViewEnableOne)
     SfxLokHelper::setView(nView1);
     aView1.m_aStateChanges.clear();
     aView2.m_aStateChanges.clear();
-    comphelper::dispatchCommand(".uno:TrackChanges", {});
+    dispatchCommand(mxComponent, ".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.
@@ -398,17 +398,22 @@ 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", {});
+    uno::Sequence<beans::PropertyValue> aArgs = {
+        comphelper::makePropertyValue("TrackChanges", false),
+    };
+    dispatchCommand(mxComponent, ".uno:TrackChanges", aArgs);
 
     // When recording changes in view2:
     SfxLokHelper::setView(nView2);
     aView1.m_aStateChanges.clear();
     aView2.m_aStateChanges.clear();
-    comphelper::dispatchCommand(".uno:TrackChanges", {});
+    dispatchCommand(mxComponent, ".uno:TrackChangesInThisView", {});
 
-    // Then make sure view2 gets a state track changes state change, but not 
view1:
-    CPPUNIT_ASSERT(aView1.m_aStateChanges.empty());
-    CPPUNIT_ASSERT(!aView2.m_aStateChanges.empty());
+    // Then make sure view2 gets a 'track changes is now on' state change, but 
not view1:
+    aRecord1 = FilterStateChanges(aView1.m_aStateChanges, 
".uno:TrackChanges=true");
+    CPPUNIT_ASSERT(aRecord1.empty());
+    aRecord2 = FilterStateChanges(aView2.m_aStateChanges, 
".uno:TrackChanges=true");
+    CPPUNIT_ASSERT(!aRecord2.empty());
 }
 
 CPPUNIT_TEST_FIXTURE(SwTiledRenderingTest, testTrackChangesPerViewEnableBoth)
@@ -424,13 +429,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());
@@ -453,7 +458,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);
@@ -487,7 +492,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);
@@ -508,6 +513,39 @@ CPPUNIT_TEST_FIXTURE(SwTiledRenderingTest, 
testTrackChangesPerViewDelete)
     // i.e. the deletion in view 2 was recorded.
     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);
+    SwTestViewCallback aView1;
+    int nView1 = SfxLokHelper::getView();
+    SwWrtShell* pWrtShell1 = pXTextDocument->GetDocShell()->GetWrtShell();
+    pWrtShell1->Insert(u"X"_ustr);
+    SfxLokHelper::createView();
+    SwTestViewCallback 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();
diff --git a/sw/sdi/_viewsh.sdi b/sw/sdi/_viewsh.sdi
index 30116542a3e8..052473088128 100644
--- a/sw/sdi/_viewsh.sdi
+++ b/sw/sdi/_viewsh.sdi
@@ -168,6 +168,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 c7bfa5b9ad22..b2856ba521c0 100644
--- a/sw/sdi/swriter.sdi
+++ b/sw/sdi/swriter.sdi
@@ -8504,6 +8504,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 d61b134cbb36..f8072a0b6e3c 100644
--- a/sw/source/core/doc/DocumentRedlineManager.cxx
+++ b/sw/source/core/doc/DocumentRedlineManager.cxx
@@ -1171,7 +1171,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;
@@ -1244,7 +1244,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 ?
@@ -1260,19 +1260,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 15e4e6e79c84..ee91ca7c3f6f 100644
--- a/sw/source/uibase/app/docsh.cxx
+++ b/sw/source/uibase/app/docsh.cxx
@@ -1380,7 +1380,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();
@@ -1388,11 +1388,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 86487582fe80..ea8ec1a1166d 100644
--- a/sw/source/uibase/inc/wrtsh.hxx
+++ b/sw/source/uibase/inc/wrtsh.hxx
@@ -179,7 +179,7 @@ public:
     void    SetInsMode( bool bOn = true );
     void    ToggleInsMode() { SetInsMode( !m_bIns ); }
     bool    IsInsMode() const { return m_bIns; }
-    SW_DLLPUBLIC void SetRedlineFlagsAndCheckInsMode( RedlineFlags eMode );
+    SW_DLLPUBLIC void SetRedlineFlagsAndCheckInsMode( RedlineFlags eMode, bool 
bRecordAllViews = true );
 
     SW_DLLPUBLIC void EnterSelFrameMode(const Point *pStartDrag = nullptr);
     SW_DLLPUBLIC void LeaveSelFrameMode();
diff --git a/sw/source/uibase/uiview/view2.cxx 
b/sw/source/uibase/uiview/view2.cxx
index 0f4112c7ed47..4219a2415a5d 100644
--- a/sw/source/uibase/uiview/view2.cxx
+++ b/sw/source/uibase/uiview/view2.cxx
@@ -739,15 +739,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());
@@ -795,13 +807,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 691158242ed3..2909e8690714 100644
--- a/sw/source/uibase/uiview/viewstat.cxx
+++ b/sw/source/uibase/uiview/viewstat.cxx
@@ -357,6 +357,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 701cb23d487a..dd57576359f7 100644
--- a/sw/source/uibase/wrtsh/select.cxx
+++ b/sw/source/uibase/wrtsh/select.cxx
@@ -749,9 +749,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