diff --git a/include/sfx2/objsh.hxx b/include/sfx2/objsh.hxx index badeddf332b7..8a7875640762 100644 --- a/include/sfx2/objsh.hxx +++ b/include/sfx2/objsh.hxx @@ -44,6 +44,7 @@ #include #include #include +#include #include @@ -696,7 +697,7 @@ public: // slots used for Calc: FID_CHG_RECORD, SID_CHG_PROTECT virtual bool IsChangeRecording(SfxViewShell* pViewShell = nullptr, bool bRecordAllViews = true) const; virtual bool HasChangeRecordProtection() const; - virtual void SetChangeRecording( bool bActivate, bool bLockAllViews = false, bool bRecordAllViews = true ); + virtual void SetChangeRecording( bool bActivate, bool bLockAllViews = false, SfxRedlineRecordingMode eRedlineRecordingMode = SfxRedlineRecordingMode::ViewAgnostic ); virtual void SetProtectionPassword( const OUString &rPassword ); virtual bool GetProtectionHash( /*out*/ css::uno::Sequence< sal_Int8 > &rPasswordHash ); diff --git a/include/sfx2/redlinerecordingmode.hxx b/include/sfx2/redlinerecordingmode.hxx new file mode 100644 index 000000000000..fabd741df4b2 --- /dev/null +++ b/include/sfx2/redlinerecordingmode.hxx @@ -0,0 +1,24 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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/. + * + */ + +#pragma once + +/// Decides how new redline flags affect the views +enum class SfxRedlineRecordingMode +{ + /// Model and current view only: to set new flags & restore old ones later + ViewAgnostic, + /// Have recording on in this view + ThisView, + /// Have recording on in all views + AllViews, +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx index e9ace1fdfd3d..eee54aacb342 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*/, bool /*bRecordAllViews*/ ) +void ScDocShell::SetChangeRecording( bool bActivate, bool /*bLockAllViews*/, SfxRedlineRecordingMode /*eRedlineRecordingMode*/) { bool bOldChangeRecording = IsChangeRecording(); diff --git a/sc/source/ui/inc/docsh.hxx b/sc/source/ui/inc/docsh.hxx index ee9c642fea2d..c29eba3d9160 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, bool bRecordAllViews = true) const override; virtual bool HasChangeRecordProtection() const override; - virtual void SetChangeRecording( bool bActivate, bool bLockAllViews = false, bool bRecordAllViews = true ) override; + virtual void SetChangeRecording( bool bActivate, bool bLockAllViews = false, SfxRedlineRecordingMode eRedlineRecordingMode = SfxRedlineRecordingMode::ViewAgnostic) override; virtual void SetProtectionPassword( const OUString &rPassword ) override; virtual bool GetProtectionHash( /*out*/ css::uno::Sequence< sal_Int8 > &rPasswordHash ) override; diff --git a/sfx2/source/doc/objxtor.cxx b/sfx2/source/doc/objxtor.cxx index 978bdbd5f579..71b372ca4b5e 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*/, bool /*bRecordAllViews*/ ) +void SfxObjectShell::SetChangeRecording( bool /*bActivate*/, bool /*bLockAllViews*/, SfxRedlineRecordingMode /*eRedlineRecordingMode*/) { // currently this function needs to be overwritten by Writer and Calc only SAL_WARN( "sfx.doc", "function not implemented" ); diff --git a/sw/inc/IDocumentRedlineAccess.hxx b/sw/inc/IDocumentRedlineAccess.hxx index 804678479ab1..7861a5858421 100644 --- a/sw/inc/IDocumentRedlineAccess.hxx +++ b/sw/inc/IDocumentRedlineAccess.hxx @@ -28,6 +28,7 @@ #include #include #include +#include #include "docary.hxx" @@ -107,14 +108,14 @@ public: @param eMode [in] the new redline mode. */ - virtual void SetRedlineFlags_intern(/*[in]*/RedlineFlags eMode, bool bRecordAllViews = true, bool bRecordModeChange = false) = 0; + virtual void SetRedlineFlags_intern(/*[in]*/RedlineFlags eMode, SfxRedlineRecordingMode eRedlineRecordingMode = SfxRedlineRecordingMode::ViewAgnostic, 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, bool bRecordModeChange = false) = 0; + virtual void SetRedlineFlags(/*[in]*/RedlineFlags eMode, SfxRedlineRecordingMode eRedlineRecordingMode = SfxRedlineRecordingMode::ViewAgnostic, bool bRecordModeChange = false) = 0; /** Query if redlining is on. diff --git a/sw/inc/docsh.hxx b/sw/inc/docsh.hxx index d67471627c5c..767234155d5f 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, bool bRecordAllViews = true) const override; virtual bool HasChangeRecordProtection() const override; - virtual void SetChangeRecording( bool bActivate, bool bLockAllViews = false, bool bRecordAllViews = true ) override; + virtual void SetChangeRecording( bool bActivate, bool bLockAllViews = false, SfxRedlineRecordingMode eRedlineRecordingMode = SfxRedlineRecordingMode::ViewAgnostic) 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 00ed2ad9dacf..3568be169fad 100644 --- a/sw/inc/editsh.hxx +++ b/sw/inc/editsh.hxx @@ -19,6 +19,8 @@ #ifndef INCLUDED_SW_INC_EDITSH_HXX #define INCLUDED_SW_INC_EDITSH_HXX +#include + #include "crsrsh.hxx" #include "charfmt.hxx" @@ -953,7 +955,7 @@ public: /// For Redlining. SW_DLLPUBLIC RedlineFlags GetRedlineFlags() const; - SW_DLLPUBLIC void SetRedlineFlags( RedlineFlags eMode, bool bRecordAllViews = true ); + SW_DLLPUBLIC void SetRedlineFlags( RedlineFlags eMode, SfxRedlineRecordingMode eRedlineRecordingMode = SfxRedlineRecordingMode::ViewAgnostic ); 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 5055dbdf8024..00ffe811b821 100644 --- a/sw/qa/extras/tiledrendering/tiledrendering2.cxx +++ b/sw/qa/extras/tiledrendering/tiledrendering2.cxx @@ -684,6 +684,33 @@ CPPUNIT_TEST_FIXTURE(SwTiledRenderingTest, testControlCodesCursor) // cursor when showing formatting marks. CPPUNIT_ASSERT(!aView1.m_bCursorVisible); } + +CPPUNIT_TEST_FIXTURE(SwTiledRenderingTest, testTrackChangesInsertUndo) +{ + // Given a document with 2 views, first view enables redline record for that view only: + SwXTextDocument* pXTextDocument = createDoc(); + CPPUNIT_ASSERT(pXTextDocument); + SwTestViewCallback aView1; + int nView1 = SfxLokHelper::getView(); + SwView* pView1 = pXTextDocument->GetDocShell()->GetView(); + SwWrtShell* pWrtShell1 = pXTextDocument->GetDocShell()->GetWrtShell(); + SfxLokHelper::createView(); + SwTestViewCallback aView2; + SfxLokHelper::setView(nView1); + comphelper::dispatchCommand(".uno:TrackChangesInThisView", {}); + + // When typing and undoing: + pWrtShell1->Insert(u"A"_ustr); + pWrtShell1->Undo(); + + // Then make sure the record mode doesn't change: + std::unique_ptr pItem; + pView1->GetViewFrame().GetBindings().QueryState(FN_TRACK_CHANGES_IN_THIS_VIEW, pItem); + CPPUNIT_ASSERT_EQUAL(static_cast(FN_TRACK_CHANGES_IN_THIS_VIEW), pItem->Which()); + // Without the accompanying fix in place, this test would have failed, undo changed "this view" + // record mode to "all views", which is unexpected. + CPPUNIT_ASSERT(dynamic_cast(pItem.get())->GetValue()); +} } CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx b/sw/source/core/doc/DocumentRedlineManager.cxx index 58f76bd4f0a1..c4d975df58ea 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, bool bRecordAllViews, bool bRecordModeChange ) +void DocumentRedlineManager::SetRedlineFlags( RedlineFlags eMode, SfxRedlineRecordingMode eRedlineRecordingMode, bool bRecordModeChange ) { if( GetRedlineFlags() == eMode && !bRecordModeChange ) return; @@ -1244,7 +1244,7 @@ void DocumentRedlineManager::SetRedlineFlags( RedlineFlags eMode, bool bRecordAl m_rDoc.SetInXMLImport( bSaveInXMLImportFlag ); } - SetRedlineFlags_intern(eMode, bRecordAllViews, bRecordModeChange); + SetRedlineFlags_intern(eMode, eRedlineRecordingMode, bRecordModeChange); m_rDoc.getIDocumentState().SetModified(); // #TODO - add 'SwExtraRedlineTable' also ? @@ -1260,12 +1260,25 @@ bool DocumentRedlineManager::IsIgnoreRedline() const return bool(RedlineFlags::Ignore & GetRedlineFlags()); } -void DocumentRedlineManager::SetRedlineFlags_intern(RedlineFlags eMode, bool bRecordAllViews, bool bRecordModeChange) +void DocumentRedlineManager::SetRedlineFlags_intern(RedlineFlags eMode, SfxRedlineRecordingMode eRedlineRecordingMode, bool bRecordModeChange) { SwDocShell* pDocShell = m_rDoc.GetDocShell(); SwViewShell* pViewShell = pDocShell ? pDocShell->GetWrtShell() : nullptr; - if (pViewShell) + if (pViewShell && eRedlineRecordingMode == SfxRedlineRecordingMode::ViewAgnostic) { + // Just set the requested flags on the model and on the current view, so setting flags & + // restoring them result in the same state (no matter if that was this-view or all-views). + auto bRedlineRecordingOn = bool(eMode & RedlineFlags::On); + SwViewOption aOpt(*pViewShell->GetViewOptions()); + if (aOpt.IsRedlineRecordingOn() != bRedlineRecordingOn) + { + aOpt.SetRedlineRecordingOn(bRedlineRecordingOn); + pViewShell->ApplyViewOptions(aOpt); + } + } + else if (pViewShell) + { + bool bRecordAllViews = eRedlineRecordingMode == SfxRedlineRecordingMode::AllViews; // Recording may be per-view, the rest is per-document. for(SwViewShell& rSh : pViewShell->GetRingContainer()) { diff --git a/sw/source/core/edit/edredln.cxx b/sw/source/core/edit/edredln.cxx index 8c1955cad571..bb50961de030 100644 --- a/sw/source/core/edit/edredln.cxx +++ b/sw/source/core/edit/edredln.cxx @@ -34,16 +34,21 @@ RedlineFlags SwEditShell::GetRedlineFlags() const return GetDoc()->getIDocumentRedlineAccess().GetRedlineFlags(this); } -void SwEditShell::SetRedlineFlags( RedlineFlags eMode, bool bRecordAllViews ) +void SwEditShell::SetRedlineFlags( RedlineFlags eMode, SfxRedlineRecordingMode eRedlineRecordingMode) { if (SwDocShell* pDocSh = GetDoc()->GetDocShell()) { - bool bRecordModeChange = bRecordAllViews != pDocSh->IsChangeRecording(nullptr, bRecordAllViews); + bool bRecordModeChange = false; + if (eRedlineRecordingMode != SfxRedlineRecordingMode::ViewAgnostic) + { + bool bRecordAllViews = eRedlineRecordingMode == SfxRedlineRecordingMode::AllViews; + bRecordModeChange = bRecordAllViews != pDocSh->IsChangeRecording(nullptr, bRecordAllViews); + } if( eMode != GetDoc()->getIDocumentRedlineAccess().GetRedlineFlags() || bRecordModeChange ) { CurrShell aCurr( this ); StartAllAction(); - GetDoc()->getIDocumentRedlineAccess().SetRedlineFlags( eMode, bRecordAllViews, bRecordModeChange ); + GetDoc()->getIDocumentRedlineAccess().SetRedlineFlags( eMode, eRedlineRecordingMode, bRecordModeChange ); EndAllAction(); } } @@ -135,7 +140,7 @@ void SwEditShell::ReinstateRedline(SwRedlineTable::size_type nPos) if (!IsRedlineOn()) { RedlineFlags nMode = GetRedlineFlags(); - SetRedlineFlags(nMode | RedlineFlags::On, /*bRecordAllViews=*/false); + SetRedlineFlags(nMode | RedlineFlags::On, SfxRedlineRecordingMode::ThisView); } SwRangeRedline& rRedline = GetRedline(nPos); @@ -237,7 +242,7 @@ void SwEditShell::ReinstateRedlinesInSelection() if (!IsRedlineOn()) { RedlineFlags nMode = GetRedlineFlags(); - SetRedlineFlags(nMode | RedlineFlags::On, /*bRecordAllViews=*/false); + SetRedlineFlags(nMode | RedlineFlags::On, SfxRedlineRecordingMode::ThisView); } SwPosition aCursorStart(*GetCursor()->Start()); diff --git a/sw/source/core/inc/DocumentRedlineManager.hxx b/sw/source/core/inc/DocumentRedlineManager.hxx index e55d9ca79e86..784189c9ff59 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, bool bRecordModeChange = false) override; + virtual void SetRedlineFlags_intern(/*[in]*/RedlineFlags eMode, SfxRedlineRecordingMode eRedlineRecordingMode = SfxRedlineRecordingMode::ViewAgnostic, bool bRecordModeChange = false) override; - virtual void SetRedlineFlags(/*[in]*/RedlineFlags eMode, bool bRecordAllViews = true, bool bRecordModeChange = false) override; + virtual void SetRedlineFlags(/*[in]*/RedlineFlags eMode, SfxRedlineRecordingMode eRedlineRecordingMode = SfxRedlineRecordingMode::ViewAgnostic, bool bRecordModeChange = false) override; virtual bool IsRedlineOn() const override; diff --git a/sw/source/uibase/app/docsh.cxx b/sw/source/uibase/app/docsh.cxx index a95be1457362..6fc966e19bdd 100644 --- a/sw/source/uibase/app/docsh.cxx +++ b/sw/source/uibase/app/docsh.cxx @@ -1399,7 +1399,7 @@ bool SwDocShell::HasChangeRecordProtection() const return m_pWrtShell->getIDocumentRedlineAccess().GetRedlinePassword().hasElements(); } -void SwDocShell::SetChangeRecording( bool bActivate, bool bLockAllViews, bool bRecordAllViews ) +void SwDocShell::SetChangeRecording( bool bActivate, bool bLockAllViews, SfxRedlineRecordingMode eRedlineRecordingMode) { RedlineFlags nOn = bActivate ? RedlineFlags::On : RedlineFlags::NONE; RedlineFlags nMode = m_pWrtShell->GetRedlineFlags(); @@ -1407,11 +1407,11 @@ void SwDocShell::SetChangeRecording( bool bActivate, bool bLockAllViews, bool bR { // tdf#107870: prevent jumping to cursor auto aViewGuard(LockAllViews()); - m_pWrtShell->SetRedlineFlagsAndCheckInsMode( (nMode & ~RedlineFlags::On) | nOn, bRecordAllViews ); + m_pWrtShell->SetRedlineFlagsAndCheckInsMode( (nMode & ~RedlineFlags::On) | nOn, eRedlineRecordingMode ); } else { - m_pWrtShell->SetRedlineFlagsAndCheckInsMode( (nMode & ~RedlineFlags::On) | nOn, bRecordAllViews ); + m_pWrtShell->SetRedlineFlagsAndCheckInsMode( (nMode & ~RedlineFlags::On) | nOn, eRedlineRecordingMode ); } } diff --git a/sw/source/uibase/inc/wrtsh.hxx b/sw/source/uibase/inc/wrtsh.hxx index ea8ec1a1166d..9b5ce7e9ba3f 100644 --- a/sw/source/uibase/inc/wrtsh.hxx +++ b/sw/source/uibase/inc/wrtsh.hxx @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -179,7 +180,7 @@ public: void SetInsMode( bool bOn = true ); void ToggleInsMode() { SetInsMode( !m_bIns ); } bool IsInsMode() const { return m_bIns; } - SW_DLLPUBLIC void SetRedlineFlagsAndCheckInsMode( RedlineFlags eMode, bool bRecordAllViews = true ); + SW_DLLPUBLIC void SetRedlineFlagsAndCheckInsMode( RedlineFlags eMode, SfxRedlineRecordingMode eRedlineRecordingMode = SfxRedlineRecordingMode::ViewAgnostic); 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 71424e12d751..44b47540a977 100644 --- a/sw/source/uibase/uiview/view2.cxx +++ b/sw/source/uibase/uiview/view2.cxx @@ -807,8 +807,12 @@ void SwView::Execute(SfxRequest &rReq) } SwDocShell* pDocShell = GetDocShell(); - bool bRecordAllViews = nSlot != FN_TRACK_CHANGES_IN_THIS_VIEW; - pDocShell->SetChangeRecording( oOn.value(), /*bLockAllViews=*/true, bRecordAllViews ); + SfxRedlineRecordingMode eRedlineRecordingMode = SfxRedlineRecordingMode::AllViews; + if (nSlot == FN_TRACK_CHANGES_IN_THIS_VIEW) + { + eRedlineRecordingMode = SfxRedlineRecordingMode::ThisView; + } + pDocShell->SetChangeRecording( oOn.value(), /*bLockAllViews=*/true, eRedlineRecordingMode ); // 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)) diff --git a/sw/source/uibase/wrtsh/select.cxx b/sw/source/uibase/wrtsh/select.cxx index dd57576359f7..3dfb059399d2 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, bool bRecordAllViews ) +void SwWrtShell::SetRedlineFlagsAndCheckInsMode( RedlineFlags eMode, SfxRedlineRecordingMode eRedlineRecordingMode ) { - SetRedlineFlags( eMode, bRecordAllViews ); + SetRedlineFlags( eMode, eRedlineRecordingMode ); if (IsRedlineOn()) SetInsMode(); }