sc: Sync sheet views after undo and redo

After undo or redo, we restore the default view table to a previous (or
future) state, which means we need to synchronize that change to the
sheet views. For that, calling the functionality of SyncSheetViews
should be enough to get them synchronized again. Sync is performed
in EndUndo and EndRedo.

Extracted the sheet view synchronization logic from Operation into
ScDocument::SyncSheetViews method. This allows the same sync logic
to be called from both Operations and undo/redo (ScSimpleUndo).

Change-Id: I67a2580631e547ece67e945883f038b1f9968689
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/201454
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/202092
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
(cherry picked from commit f6c8731a6ef27989ce5fc643d3def7f2947c510c)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/205528
Tested-by: Xisco Fauli <xiscofauli@libreoffice.org>
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
This commit is contained in:
Tomaž Vajngerl
2026-05-23 00:07:49 +02:00
committed by Xisco Fauli
parent 780e274c16
commit 40cd823766
5 changed files with 84 additions and 48 deletions
+8
View File
@@ -2458,6 +2458,14 @@ public:
/** Returns the sheet view ID for a given tab. */
SC_DLLPUBLIC sc::SheetViewID GetTableSheetViewID(SCTAB nTab) const;
/** Synchronizes all sheet views for the given default view table.
*
* Specifically, it goes through all sheet views and overwrites the
* content of the sheet view table with the content of default view table,
* then reapplies the sheet views's sorting and filtering for the auto-filter.
*/
void SyncSheetViews(SCTAB nDefaultViewTable);
private:
ScDocument(const ScDocument& r) = delete;
+54
View File
@@ -28,6 +28,10 @@
#include <bcaslot.hxx>
#include <broadcast.hxx>
#include <SheetViewManager.hxx>
#include <SheetView.hxx>
#include <dbdata.hxx>
#include <queryparam.hxx>
#include <sortparam.hxx>
#include <editeng/brushitem.hxx>
#include <editeng/colritem.hxx>
@@ -1216,4 +1220,54 @@ SCTAB ScDocument::GetSheetViewNumber(SCTAB nTab, sc::SheetViewID nID)
return -1;
}
void ScDocument::SyncSheetViews(SCTAB nDefaultViewTable)
{
std::shared_ptr<sc::SheetViewManager> pManager = GetSheetViewManager(nDefaultViewTable);
if (!pManager || pManager->isEmpty())
return;
// Iterate all valid sheet views
for (auto& rSheetView : pManager->iterateValidSheetViews())
{
SCTAB nSheetViewTab = rSheetView.getTableNumber();
// Get the current query (filter) state of the auto-filter
std::optional<ScQueryParam> oQueryParam;
ScDBData* pNoNameData = GetAnonymousDBData(nSheetViewTab);
if (pNoNameData && pNoNameData->HasAutoFilter())
{
if (pNoNameData->HasQueryParam())
{
oQueryParam.emplace();
pNoNameData->GetQueryParam(*oQueryParam);
}
}
// Overwrite the content from the default view table
OverwriteContent(nDefaultViewTable, nSheetViewTab);
// Revert the sorting of the default view table.
// It can happen that the default view was sorted after the sheet view
// was created.
if (auto const& rReorderParameters = rSheetView.getReorderParameters())
{
sc::ReorderParam aReorderParameters(*rReorderParameters);
aReorderParameters.maSortRange.aStart.SetTab(nSheetViewTab);
aReorderParameters.maSortRange.aEnd.SetTab(nSheetViewTab);
aReorderParameters.reverse();
Reorder(aReorderParameters);
}
// Sort the sheet view if it was sorted before
auto const& oSortParam = rSheetView.getSortParam();
if (oSortParam)
{
rSheetView.resetSortOrder();
Sort(nSheetViewTab, *oSortParam, false, false, nullptr, nullptr);
}
// Apply the stored query state (if available)
if (oQueryParam)
Query(nSheetViewTab, *oQueryParam, false, false);
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+2
View File
@@ -61,6 +61,8 @@ protected:
void BeginRedo();
void EndRedo();
void SyncSheetViews();
void BroadcastChanges( const ScRange& rRange );
/**
+3 -48
View File
@@ -10,18 +10,15 @@
#include <operation/Operation.hxx>
#include <operation/OperationType.hxx>
#include <SheetViewOperationsTester.hxx>
#include <address.hxx>
#include <dbdata.hxx>
#include <docsh.hxx>
#include <markdata.hxx>
#include <address.hxx>
#include <viewdata.hxx>
#include <SheetViewManager.hxx>
#include <SheetView.hxx>
#include <sal/log.hxx>
#include <dbdata.hxx>
#include <queryparam.hxx>
#include <sortparam.hxx>
namespace sc
{
namespace
@@ -196,49 +193,7 @@ void Operation::syncSheetViews()
auto& rDocument = mpViewData->GetDocument();
SCTAB nTab = mpViewData->GetDefaultViewTab();
std::shared_ptr<sc::SheetViewManager> pManager = rDocument.GetSheetViewManager(nTab);
if (!pManager || pManager->isEmpty())
return;
for (auto& rSheetView : pManager->iterateValidSheetViews())
{
SCTAB nSheetViewTab = rSheetView.getTableNumber();
std::optional<ScQueryParam> oQueryParam;
ScDBData* pNoNameData = rDocument.GetAnonymousDBData(nSheetViewTab);
if (pNoNameData && pNoNameData->HasAutoFilter())
{
if (pNoNameData->HasQueryParam())
{
oQueryParam.emplace();
pNoNameData->GetQueryParam(*oQueryParam);
}
}
rDocument.OverwriteContent(nTab, nSheetViewTab);
// Reverse the sorting of the default view in the sheet view
if (auto const& rReorderParameters = rSheetView.getReorderParameters())
{
sc::ReorderParam aReorderParameters(*rReorderParameters);
aReorderParameters.maSortRange.aStart.SetTab(nSheetViewTab);
aReorderParameters.maSortRange.aEnd.SetTab(nSheetViewTab);
aReorderParameters.reverse();
rDocument.Reorder(aReorderParameters);
}
auto const& oSortParam = rSheetView.getSortParam();
if (oSortParam)
{
// We need to reset the sort order for the sheet view as we will sort again
rSheetView.resetSortOrder();
rDocument.Sort(nSheetViewTab, *oSortParam, false, false, nullptr, nullptr);
}
if (oQueryParam)
rDocument.Query(nSheetViewTab, *oQueryParam, false, false);
}
rDocument.SyncSheetViews(nTab);
}
bool Operation::isInputOnSheetView() const { return getCurrentSheetView(mpViewData) != nullptr; }
+17
View File
@@ -124,6 +124,9 @@ namespace
void ScSimpleUndo::EndUndo()
{
// After undo we need to restore the sheet views as well.
SyncSheetViews();
{
// rhbz#1352881 Temporarily turn off undo generation during
// SetDocumentModified
@@ -156,6 +159,9 @@ void ScSimpleUndo::EndRedo()
if (pDetectiveUndo)
pDetectiveUndo->Redo();
// After redo we need to restore the sheet views as well.
SyncSheetViews();
{
// rhbz#1352881 Temporarily turn off undo generation during
// SetDocumentModified
@@ -174,6 +180,17 @@ void ScSimpleUndo::EndRedo()
rDocShell.SetInUndo( false );
}
void ScSimpleUndo::SyncSheetViews()
{
ScViewData* pViewData = ScDocShell::GetViewData();
if (!pViewData)
return;
ScDocument& rDocument = rDocShell.GetDocument();
SCTAB nDefaultViewTable = rDocument.GetDefaultViewTableNumber(pViewData->GetTabNumber());
rDocument.SyncSheetViews(nDefaultViewTable);
}
void ScSimpleUndo::BroadcastChanges( const ScRange& rRange )
{
ScDocument& rDoc = rDocShell.GetDocument();