sw/inc/IDocumentRedlineAccess.hxx              |    4 +-
 sw/qa/extras/tiledrendering/tiledrendering.cxx |   26 +++++++++++++
 sw/source/core/doc/DocumentRedlineManager.cxx  |   47 +++++++++++++++++++------
 sw/source/core/edit/edredln.cxx                |    7 ++-
 sw/source/core/inc/DocumentRedlineManager.hxx  |    4 +-
 5 files changed, 72 insertions(+), 16 deletions(-)

New commits:
commit a67519e2053fae13945df64c959e975bb1298833
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Mon Mar 10 10:18:10 2025 +0100
Commit:     Caolán McNamara <caolan.mcnam...@collabora.com>
CommitDate: Mon Mar 10 20:44:32 2025 +0100

    cool#11226 sw per-view redline on: support this-view <-> all-views 
transition
    
    Have 2 views, enable "this view" recording in view 1, then try to
    transition to "all views" still in view 1, nothing happens.
    
    This is because SwEditShell::SetRedlineFlags() checks if the redline
    flags would change (for this view) and since they don't change, we
    return early.
    
    Fix the problem by passing a "record mode change" bool around, which is
    set when when we keep recording on, but would switch between this-view
    vs all-views to still update the various views accordingly.
    
    Note that we have 3 states here, with the following intention:
    - off: if we transition to this, all views go to off
    - this view: transitioning to this from "off" just enables the current
      view, but transitioning to this from "all-views" turns off all views
    - all-views: if we transition to this, all views go to on
    Now all the 6 transitions between the 3 states is meant to work without
    surprises.
    
    Change-Id: I6e4d9e40f7008f680c476825a4d15dab12c6dadc
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182726
    Tested-by: Caolán McNamara <caolan.mcnam...@collabora.com>
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/sw/inc/IDocumentRedlineAccess.hxx 
b/sw/inc/IDocumentRedlineAccess.hxx
index c1147b000a36..804678479ab1 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, bool 
bRecordAllViews = true) = 0;
+    virtual void SetRedlineFlags_intern(/*[in]*/RedlineFlags eMode, bool 
bRecordAllViews = true, bool bRecordModeChange = false) = 0;
 
     /** Set a new redline mode.
 
         @param eMode
         [in] the new redline mode.
     */
-    virtual void SetRedlineFlags(/*[in]*/RedlineFlags eMode, bool 
bRecordAllViews = true) = 0;
+    virtual void SetRedlineFlags(/*[in]*/RedlineFlags eMode, bool 
bRecordAllViews = true, bool bRecordModeChange = false) = 0;
 
     /** Query if redlining is on.
 
diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx 
b/sw/qa/extras/tiledrendering/tiledrendering.cxx
index 1046c9ea27fe..deb6a3bfa284 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx
@@ -4901,6 +4901,32 @@ CPPUNIT_TEST_FIXTURE(SwTiledRenderingTest, 
testTrackChangesPerViewEnableBoth)
     CPPUNIT_ASSERT(pWrtShell2->GetViewOptions()->IsRedlineRecordingOn());
 }
 
+CPPUNIT_TEST_FIXTURE(SwTiledRenderingTest, 
testTrackChangesPerViewAllToOneTransition)
+{
+    // Given 2 views, recording is on in all views:
+    SwXTextDocument* pXTextDocument = createDoc();
+    CPPUNIT_ASSERT(pXTextDocument);
+    ViewCallback aView1;
+    int nView1 = SfxLokHelper::getView();
+    SwWrtShell* pWrtShell1 = pXTextDocument->GetDocShell()->GetWrtShell();
+    SfxLokHelper::createView();
+    ViewCallback aView2;
+    SwWrtShell* pWrtShell2 = pXTextDocument->GetDocShell()->GetWrtShell();
+    SfxLokHelper::setView(nView1);
+    comphelper::dispatchCommand(".uno:TrackChangesInAllViews", {});
+    CPPUNIT_ASSERT(pWrtShell1->GetViewOptions()->IsRedlineRecordingOn());
+    CPPUNIT_ASSERT(pWrtShell2->GetViewOptions()->IsRedlineRecordingOn());
+
+    // When limiting recording to just view 1:
+    comphelper::dispatchCommand(".uno:TrackChangesInThisView", {});
+
+    // Then make sure view 2 has recording off:
+    CPPUNIT_ASSERT(pWrtShell1->GetViewOptions()->IsRedlineRecordingOn());
+    // Without the accompanying fix in place, this test would have failed,
+    // .uno:TrackChangesInThisView didn't turn off recording for view 2.
+    CPPUNIT_ASSERT(!pWrtShell2->GetViewOptions()->IsRedlineRecordingOn());
+}
+
 CPPUNIT_TEST_FIXTURE(SwTiledRenderingTest, testTrackChangesPerViewInsert)
 {
     // Given 2 views, view 1 records changes, view does not record changes:
diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx 
b/sw/source/core/doc/DocumentRedlineManager.cxx
index 8ffc68726082..b38b8831f0eb 100644
--- a/sw/source/core/doc/DocumentRedlineManager.cxx
+++ b/sw/source/core/doc/DocumentRedlineManager.cxx
@@ -1174,9 +1174,9 @@ RedlineFlags 
DocumentRedlineManager::GetRedlineFlags(const SwViewShell* pViewShe
     return eRedlineFlags;
 }
 
-void DocumentRedlineManager::SetRedlineFlags( RedlineFlags eMode, bool 
bRecordAllViews )
+void DocumentRedlineManager::SetRedlineFlags( RedlineFlags eMode, bool 
bRecordAllViews, bool bRecordModeChange )
 {
-    if( GetRedlineFlags() == eMode )
+    if( GetRedlineFlags() == eMode && !bRecordModeChange )
         return;
 
     if( (RedlineFlags::ShowMask & GetRedlineFlags()) != 
(RedlineFlags::ShowMask & eMode)
@@ -1249,7 +1249,7 @@ void DocumentRedlineManager::SetRedlineFlags( 
RedlineFlags eMode, bool bRecordAl
 
         m_rDoc.SetInXMLImport( bSaveInXMLImportFlag );
     }
-    SetRedlineFlags_intern(eMode, bRecordAllViews);
+    SetRedlineFlags_intern(eMode, bRecordAllViews, bRecordModeChange);
     m_rDoc.getIDocumentState().SetModified();
 
     // #TODO - add 'SwExtraRedlineTable' also ?
@@ -1265,7 +1265,7 @@ bool DocumentRedlineManager::IsIgnoreRedline() const
     return bool(RedlineFlags::Ignore & GetRedlineFlags());
 }
 
-void DocumentRedlineManager::SetRedlineFlags_intern(RedlineFlags eMode, bool 
bRecordAllViews)
+void DocumentRedlineManager::SetRedlineFlags_intern(RedlineFlags eMode, bool 
bRecordAllViews, bool bRecordModeChange)
 {
     SwDocShell* pDocShell = m_rDoc.GetDocShell();
     SwViewShell* pViewShell = pDocShell ? pDocShell->GetWrtShell() : nullptr;
@@ -1274,16 +1274,43 @@ void 
DocumentRedlineManager::SetRedlineFlags_intern(RedlineFlags eMode, bool bRe
         // Recording may be per-view, the rest is per-document.
         for(SwViewShell& rSh : pViewShell->GetRingContainer())
         {
-            if (!bRecordAllViews && &rSh != pViewShell)
+            auto bRedlineRecordingOn = bool(eMode & RedlineFlags::On);
+            SwViewOption aOpt(*rSh.GetViewOptions());
+            bool bOn = aOpt.IsRedlineRecordingOn();
+            if (bRedlineRecordingOn)
+            {
+                // We'll want some kind of recording enabled.
+                if (bRecordAllViews)
+                {
+                    // Enable for all views: turn it on everywhere.
+                    bOn = true;
+                }
+                else
+                {
+                    // Enable it for this view was requested.
+                    if (bRecordModeChange)
+                    {
+                        // Transitioning from "all views" to "this view", turn 
it off everywhere
+                        // except in this view.
+                        bOn = &rSh == pViewShell;
+                    }
+                    else if (&rSh == pViewShell)
+                    {
+                        // Transitioning from "no record": just touch the 
current view, leave
+                        // others unchanged.
+                        bOn = true;
+                    }
+                }
+            }
+            else
             {
-                continue;
+                // Disable everywhere.
+                bOn = false;
             }
 
-            auto bRedlineRecordingOn = bool(eMode & RedlineFlags::On);
-            SwViewOption aOpt(*rSh.GetViewOptions());
-            if (aOpt.IsRedlineRecordingOn() != bRedlineRecordingOn)
+            if (aOpt.IsRedlineRecordingOn() != bOn)
             {
-                aOpt.SetRedlineRecordingOn(bRedlineRecordingOn);
+                aOpt.SetRedlineRecordingOn(bOn);
                 rSh.ApplyViewOptions(aOpt);
             }
         }
diff --git a/sw/source/core/edit/edredln.cxx b/sw/source/core/edit/edredln.cxx
index 3865fd94dcca..379f12a6932e 100644
--- a/sw/source/core/edit/edredln.cxx
+++ b/sw/source/core/edit/edredln.cxx
@@ -23,6 +23,7 @@
 #include <doc.hxx>
 #include <editsh.hxx>
 #include <frmtool.hxx>
+#include <docsh.hxx>
 
 RedlineFlags SwEditShell::GetRedlineFlags() const
 {
@@ -31,11 +32,13 @@ RedlineFlags SwEditShell::GetRedlineFlags() const
 
 void SwEditShell::SetRedlineFlags( RedlineFlags eMode, bool bRecordAllViews )
 {
-    if( eMode != GetDoc()->getIDocumentRedlineAccess().GetRedlineFlags() )
+    SwDocShell* pDocSh = GetDoc()->GetDocShell();
+    bool bRecordModeChange = bRecordAllViews != 
pDocSh->IsChangeRecording(nullptr, bRecordAllViews);
+    if( eMode != GetDoc()->getIDocumentRedlineAccess().GetRedlineFlags() || 
bRecordModeChange )
     {
         CurrShell aCurr( this );
         StartAllAction();
-        GetDoc()->getIDocumentRedlineAccess().SetRedlineFlags( eMode, 
bRecordAllViews );
+        GetDoc()->getIDocumentRedlineAccess().SetRedlineFlags( eMode, 
bRecordAllViews, bRecordModeChange );
         EndAllAction();
     }
 }
diff --git a/sw/source/core/inc/DocumentRedlineManager.hxx 
b/sw/source/core/inc/DocumentRedlineManager.hxx
index 34d9bb31cd98..3651da858126 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, bool 
bRecordAllViews = true) override;
+    virtual void SetRedlineFlags_intern(/*[in]*/RedlineFlags eMode, bool 
bRecordAllViews = true, bool bRecordModeChange = false) override;
 
-    virtual void SetRedlineFlags(/*[in]*/RedlineFlags eMode, bool 
bRecordAllViews = true) override;
+    virtual void SetRedlineFlags(/*[in]*/RedlineFlags eMode, bool 
bRecordAllViews = true, bool bRecordModeChange = false) override;
 
     virtual bool IsRedlineOn() const override;
 

Reply via email to