sc/source/ui/docshell/dbdocfun.cxx | 32 ++++---- sc/source/ui/docshell/docsh5.cxx | 4 - sc/source/ui/inc/undodat.hxx | 11 +- sc/source/ui/undo/undodat.cxx | 144 +++++++++++++++++++------------------ sc/source/ui/view/dbfunc3.cxx | 8 -- 5 files changed, 101 insertions(+), 98 deletions(-)
New commits: commit 5ec4c2397d6099ade3347478f5e2e291eee59198 Author: Balazs Varga <[email protected]> AuthorDate: Fri Nov 21 15:25:59 2025 +0100 Commit: Balazs Varga <[email protected]> CommitDate: Mon Nov 24 21:39:58 2025 +0100 Table style: fix dbdata undo/redo change have leftover or missing autofilter flags on header cells. Also repaint full sheet when it is necessary instead of repaint only the ranges. Clean-up. Change-Id: I30d1d664a23e7d84629a87ea4d00f808d85b480c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/194334 Reviewed-by: Balazs Varga <[email protected]> Tested-by: Jenkins CollaboraOffice <[email protected]> diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx index bfbeffa2f335..0d0045c4b9cd 100644 --- a/sc/source/ui/docshell/dbdocfun.cxx +++ b/sc/source/ui/docshell/dbdocfun.cxx @@ -114,7 +114,7 @@ bool ScDBDocFunc::AddDBRange( const OUString& rName, const ScRange& rRange ) { rDocShell.GetUndoManager()->AddUndoAction( std::make_unique<ScUndoDBData>( &rDocShell, rName, std::move(pUndoColl), - std::make_unique<ScDBCollection>( *pDocColl ) ) ); + rName, std::make_unique<ScDBCollection>( *pDocColl ) ) ); } aModificator.SetDocumentModified(); @@ -150,7 +150,7 @@ bool ScDBDocFunc::DeleteDBRange(const OUString& rName) { rDocShell.GetUndoManager()->AddUndoAction( std::make_unique<ScUndoDBData>( &rDocShell, rName, std::move(pUndoColl), - std::make_unique<ScDBCollection>( *pDocColl ) ) ); + rName, std::make_unique<ScDBCollection>( *pDocColl ) ) ); } aModificator.SetDocumentModified(); @@ -193,8 +193,8 @@ bool ScDBDocFunc::RenameDBRange( const OUString& rOld, const OUString& rNew ) if (bUndo) { rDocShell.GetUndoManager()->AddUndoAction( - std::make_unique<ScUndoDBData>( &rDocShell, rNew, std::move(pUndoColl), - std::make_unique<ScDBCollection>( *pDocColl ) ) ); + std::make_unique<ScUndoDBData>( &rDocShell, rOld, std::move(pUndoColl), + rNew, std::make_unique<ScDBCollection>( *pDocColl ) ) ); } else pUndoColl.reset(); @@ -237,8 +237,12 @@ void ScDBDocFunc::ModifyDBData( const ScDBData& rNewData ) bool bNewAutoFilter = rNewData.HasAutoFilter(); std::unique_ptr<ScDBCollection> pUndoColl; + OUString sOldName; if (bUndo) + { pUndoColl.reset( new ScDBCollection( *pDocColl ) ); + sOldName = pData->GetName(); + } *pData = rNewData; if (bAreaChanged || bOldAutoFilter != bNewAutoFilter) { @@ -259,14 +263,14 @@ void ScDBDocFunc::ModifyDBData( const ScDBData& rNewData ) } } - rDocShell.PostPaint(aOldRange, PaintPartFlags::Grid | PaintPartFlags::Left | PaintPartFlags::Top - | PaintPartFlags::Size); + rDocShell.PostPaint(ScRange(0, 0, aOldRange.aStart.Tab(), rDoc.MaxCol(), rDoc.MaxRow(), aOldRange.aEnd.Tab()), + PaintPartFlags::Grid | PaintPartFlags::Left | PaintPartFlags::Top | PaintPartFlags::Size); if (bUndo) { rDocShell.GetUndoManager()->AddUndoAction( - std::make_unique<ScUndoDBData>( &rDocShell, rNewData.GetName(), std::move(pUndoColl), - std::make_unique<ScDBCollection>( *pDocColl ) ) ); + std::make_unique<ScUndoDBData>( &rDocShell, sOldName, std::move(pUndoColl), + rNewData.GetName(), std::make_unique<ScDBCollection>( *pDocColl ) ) ); } aModificator.SetDocumentModified(); @@ -305,8 +309,8 @@ void ScDBDocFunc::ModifyAllDBData( const ScDBCollection& rNewColl, const std::ve if (bRecord) { rDocShell.GetUndoManager()->AddUndoAction( - std::make_unique<ScUndoDBData>(&rDocShell, OUString(), std::move(pUndoColl), - std::make_unique<ScDBCollection>(rNewColl))); + std::make_unique<ScUndoDBData>(&rDocShell, u""_ustr, std::move(pUndoColl), + u""_ustr, std::make_unique<ScDBCollection>(rNewColl))); } } @@ -1280,7 +1284,6 @@ void ScDBDocFunc::DoTableSubTotals( SCTAB nTab, const ScDBData& rNewData, const ScSubTotalParam aNewParam; rNewData.GetSubTotalParam(aNewParam); // end of range is being changed ScDocumentUniquePtr pUndoDoc; - std::unique_ptr<ScRangeName> pUndoRange; std::unique_ptr<ScDBCollection> pUndoDB; if (bRecord) // secure old data @@ -1299,10 +1302,7 @@ void ScDBDocFunc::DoTableSubTotals( SCTAB nTab, const ScDBData& rNewData, const rDoc.CopyToDocument(0, 0, 0, rDoc.MaxCol(), rDoc.MaxRow(), nTabCount - 1, InsertDeleteFlags::FORMULA, false, *pUndoDoc); - // ranges of DB and other - ScRangeName* pDocRange = rDoc.GetRangeName(); - if (!pDocRange->empty()) - pUndoRange.reset(new ScRangeName(*pDocRange)); + // ranges of DB ScDBCollection* pDocDB = rDoc.GetDBCollection(); if (!pDocDB->empty()) pUndoDB.reset(new ScDBCollection(*pDocDB)); @@ -1326,7 +1326,7 @@ void ScDBDocFunc::DoTableSubTotals( SCTAB nTab, const ScDBData& rNewData, const { ScDBCollection* pDocDB = rDoc.GetDBCollection(); rDocShell.GetUndoManager()->AddUndoAction(std::make_unique<ScUndoTableTotals>( - &rDocShell, nTab, rParam, aNewParam.nRow2, std::move(pUndoDoc), std::move(pUndoRange), + &rDocShell, nTab, rParam, aNewParam.nRow2, std::move(pUndoDoc), std::move(pUndoDB), std::make_unique<ScDBCollection>(*pDocDB))); } diff --git a/sc/source/ui/docshell/docsh5.cxx b/sc/source/ui/docshell/docsh5.cxx index 6c8874577980..4339e8964df9 100644 --- a/sc/source/ui/docshell/docsh5.cxx +++ b/sc/source/ui/docshell/docsh5.cxx @@ -324,8 +324,8 @@ ScDBData* ScDocShell::GetDBData( const ScRange& rMarked, ScGetDBMode eMode, ScGe { m_pDocument->CompileHybridFormula(); - GetUndoManager()->AddUndoAction( std::make_unique<ScUndoDBData>( this, OUString(), - std::move(pUndoColl), + GetUndoManager()->AddUndoAction( std::make_unique<ScUndoDBData>( this, u""_ustr, + std::move(pUndoColl), pNoNameData ? pNoNameData->GetName() : u""_ustr, std::make_unique<ScDBCollection>( *pColl ) ) ); } diff --git a/sc/source/ui/inc/undodat.hxx b/sc/source/ui/inc/undodat.hxx index 3b7826ef43ae..8d9e251c6e29 100644 --- a/sc/source/ui/inc/undodat.hxx +++ b/sc/source/ui/inc/undodat.hxx @@ -211,7 +211,6 @@ public: ScUndoTableTotals(ScDocShell* pNewDocShell, SCTAB nNewTab, const ScSubTotalParam& rNewParam, SCROW nNewEndY, ScDocumentUniquePtr pNewUndoDoc, - std::unique_ptr<ScRangeName> pNewUndoRange, std::unique_ptr<ScDBCollection> pNewUndoDB, std::unique_ptr<ScDBCollection> pNewRedoDB); @@ -227,7 +226,6 @@ private: ScSubTotalParam aParam; // The original passed parameter SCROW nNewEndRow; // Size of result ScDocumentUniquePtr xUndoDoc; - std::unique_ptr<ScRangeName> xUndoRange; std::unique_ptr<ScDBCollection> xUndoDB; std::unique_ptr<ScDBCollection> xRedoDB; }; @@ -285,8 +283,8 @@ public: class ScUndoDBData: public ScSimpleUndo { public: - ScUndoDBData( ScDocShell* pNewDocShell, const OUString& rName, - std::unique_ptr<ScDBCollection> pNewUndoColl, + ScUndoDBData( ScDocShell* pNewDocShell, const OUString& rNewUndoName, + std::unique_ptr<ScDBCollection> pNewUndoColl, const OUString& rNewRedoName, std::unique_ptr<ScDBCollection> pNewRedoColl ); virtual ~ScUndoDBData() override; @@ -298,9 +296,12 @@ public: virtual OUString GetComment() const override; private: - OUString aDBName; + OUString aUndoName; std::unique_ptr<ScDBCollection> pUndoColl; + OUString aRedoName; std::unique_ptr<ScDBCollection> pRedoColl; + + void DoChange(const bool bUndo); }; class ScUndoImportData: public ScSimpleUndo diff --git a/sc/source/ui/undo/undodat.cxx b/sc/source/ui/undo/undodat.cxx index 588b755f17b5..8f6e34791a95 100644 --- a/sc/source/ui/undo/undodat.cxx +++ b/sc/source/ui/undo/undodat.cxx @@ -750,7 +750,6 @@ bool ScUndoSubTotals::CanRepeat(SfxRepeatTarget& /* rTarget */) const ScUndoTableTotals::ScUndoTableTotals(ScDocShell* pNewDocShell, SCTAB nNewTab, const ScSubTotalParam& rNewParam, SCROW nNewEndY, ScDocumentUniquePtr pNewUndoDoc, - std::unique_ptr<ScRangeName> pNewUndoRange, std::unique_ptr<ScDBCollection> pNewUndoDB, std::unique_ptr<ScDBCollection> pNewRedoDB) : ScDBFuncUndo(pNewDocShell, ScRange(rNewParam.nCol1, rNewParam.nRow1, nNewTab, @@ -759,7 +758,6 @@ ScUndoTableTotals::ScUndoTableTotals(ScDocShell* pNewDocShell, SCTAB nNewTab, , aParam(rNewParam) , nNewEndRow(nNewEndY) , xUndoDoc(std::move(pNewUndoDoc)) - , xUndoRange(std::move(pNewUndoRange)) , xUndoDB(std::move(pNewUndoDB)) , xRedoDB(std::move(pNewRedoDB)) { @@ -792,8 +790,6 @@ void ScUndoTableTotals::Undo() xUndoDoc->UndoToDocument(aParam.nCol1, aParam.nRow1 + 1, nTab, aParam.nCol2, aParam.nRow2, nTab, InsertDeleteFlags::ALL, false, rDoc); - if (xUndoRange) - rDoc.SetRangeName(std::unique_ptr<ScRangeName>(new ScRangeName(*xUndoRange))); if (xUndoDB) rDoc.SetDBCollection(std::unique_ptr<ScDBCollection>(new ScDBCollection(*xUndoDB)), true); @@ -1106,12 +1102,13 @@ bool ScUndoAutoFilter::CanRepeat(SfxRepeatTarget& /* rTarget */) const } // change database sections (dialog) -ScUndoDBData::ScUndoDBData( ScDocShell* pNewDocShell, const OUString& aName, - std::unique_ptr<ScDBCollection> pNewUndoColl, +ScUndoDBData::ScUndoDBData( ScDocShell* pNewDocShell, const OUString& rNewUndoName, + std::unique_ptr<ScDBCollection> pNewUndoColl, const OUString& rNewRedoName, std::unique_ptr<ScDBCollection> pNewRedoColl ) : ScSimpleUndo( pNewDocShell ), - aDBName( aName ), + aUndoName( rNewUndoName ), pUndoColl( std::move(pNewUndoColl) ), + aRedoName( rNewRedoName ), pRedoColl( std::move(pNewRedoColl) ) { } @@ -1128,92 +1125,101 @@ OUString ScUndoDBData::GetComment() const void ScUndoDBData::Undo() { BeginUndo(); - - ScDocument& rDoc = pDocShell->GetDocument(); - - bool bOldAutoCalc = rDoc.GetAutoCalc(); - rDoc.SetAutoCalc( false ); // Avoid unnecessary calculations - rDoc.PreprocessDBDataUpdate(); - rDoc.SetDBCollection( std::unique_ptr<ScDBCollection>(new ScDBCollection(*pUndoColl)), true ); - rDoc.CompileHybridFormula(); - rDoc.SetAutoCalc( bOldAutoCalc ); - - if (const ScDBData* pDBData - = pUndoColl->getNamedDBs().findByUpperName(ScGlobal::getCharClass().uppercase(aDBName))) - { - const ScTableStyleParam* pTableStyleInfo = pDBData->GetTableStyleInfo(); - if (pTableStyleInfo) - { - ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell(); - if (pViewShell) - { - ScRange aRange; - pDBData->GetArea(aRange); - SCTAB nTab = aRange.aStart.Tab(); - SCTAB nVisTab = pViewShell->GetViewData().GetTabNumber(); - if (nVisTab != nTab) - pViewShell->SetTabNo(nTab); - - pDocShell->PostPaint(0, 0, nTab, rDoc.MaxCol(), rDoc.MaxRow(), nTab, - PaintPartFlags::Grid | PaintPartFlags::Left - | PaintPartFlags::Top | PaintPartFlags::Size); - } - } - } - + DoChange(true); SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScDbAreasChanged ) ); - EndUndo(); } void ScUndoDBData::Redo() { BeginRedo(); + DoChange(false); + SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScDbAreasChanged ) ); + EndRedo(); +} - ScDocument& rDoc = pDocShell->GetDocument(); +void ScUndoDBData::Repeat(SfxRepeatTarget& /* rTarget */) +{ +} + +bool ScUndoDBData::CanRepeat(SfxRepeatTarget& /* rTarget */) const +{ + return false; // is not possible +} + +void ScUndoDBData::DoChange( const bool bUndo ) +{ + ScDBCollection* pWorkRefData = bUndo ? pUndoColl.get() : pRedoColl.get(); + ScDBCollection* pOldRefData = bUndo ? pRedoColl.get() : pUndoColl.get(); + ScDocument& rDoc = pDocShell->GetDocument(); bool bOldAutoCalc = rDoc.GetAutoCalc(); - rDoc.SetAutoCalc( false ); // Avoid unnecessary calculations + rDoc.SetAutoCalc(false); // Avoid unnecessary calculations rDoc.PreprocessDBDataUpdate(); - rDoc.SetDBCollection( std::unique_ptr<ScDBCollection>(new ScDBCollection(*pRedoColl)), true ); + rDoc.SetDBCollection(std::unique_ptr<ScDBCollection>(new ScDBCollection(*pWorkRefData)), true); rDoc.CompileHybridFormula(); - rDoc.SetAutoCalc( bOldAutoCalc ); + rDoc.SetAutoCalc(bOldAutoCalc); - if (const ScDBData* pDBData - = pRedoColl->getNamedDBs().findByUpperName(ScGlobal::getCharClass().uppercase(aDBName))) + const OUString& rWorkName = bUndo ? aUndoName : aRedoName; + const OUString& rOldName = bUndo ? aRedoName : aUndoName; + + if (const ScDBData* pDBData = pWorkRefData->getNamedDBs().findByUpperName( + ScGlobal::getCharClass().uppercase(rWorkName))) { - const ScTableStyleParam* pTableStyleInfo = pDBData->GetTableStyleInfo(); - if (pTableStyleInfo) + ScRange aOldRange; + if (const ScDBData* pOldDBData = pOldRefData->getNamedDBs().findByUpperName( + ScGlobal::getCharClass().uppercase(rOldName))) + { + ScRange aNewRange; + pOldDBData->GetArea(aOldRange); + pDBData->GetArea(aNewRange); + bool bAreaChanged = (aOldRange != aNewRange); + bool bOldAutoFilter = pOldDBData->HasAutoFilter(); + bool bNewAutoFilter = pDBData->HasAutoFilter(); + + if (bAreaChanged || bOldAutoFilter != bNewAutoFilter) + { + if (bAreaChanged) + rDoc.CompileDBFormula(); + if (bOldAutoFilter && !bNewAutoFilter) + { + rDoc.RemoveFlagsTab(aOldRange.aStart.Col(), aOldRange.aStart.Row(), + aOldRange.aEnd.Col(), aOldRange.aEnd.Row(), + aOldRange.aStart.Tab(), ScMF::Auto); + } + else if (bOldAutoFilter && bNewAutoFilter) + { + rDoc.RemoveFlagsTab(aOldRange.aStart.Col(), aOldRange.aStart.Row(), + aOldRange.aEnd.Col(), aOldRange.aEnd.Row(), + aOldRange.aStart.Tab(), ScMF::Auto); + rDoc.ApplyFlagsTab(aNewRange.aStart.Col(), aNewRange.aStart.Row(), + aNewRange.aEnd.Col(), aNewRange.aStart.Row(), + aNewRange.aStart.Tab(), ScMF::Auto); + } + else if (!bOldAutoFilter && bNewAutoFilter) + { + rDoc.ApplyFlagsTab(aNewRange.aStart.Col(), aNewRange.aStart.Row(), + aNewRange.aEnd.Col(), aNewRange.aStart.Row(), + aNewRange.aStart.Tab(), ScMF::Auto); + } + } + } + + if (const ScTableStyleParam* pTableStyleInfo = pDBData->GetTableStyleInfo()) { ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell(); - if (pViewShell) + if (pViewShell && aOldRange.IsValid()) { - ScRange aRange; - pDBData->GetArea(aRange); - SCTAB nTab = aRange.aStart.Tab(); + SCTAB nTab = aOldRange.aStart.Tab(); SCTAB nVisTab = pViewShell->GetViewData().GetTabNumber(); if (nVisTab != nTab) pViewShell->SetTabNo(nTab); - pDocShell->PostPaint(0, 0, nTab, rDoc.MaxCol(), rDoc.MaxRow(), nTab, - PaintPartFlags::Grid | PaintPartFlags::Left - | PaintPartFlags::Top | PaintPartFlags::Size); + pDocShell->PostPaint(ScRange(0, 0, nTab, rDoc.MaxCol(), rDoc.MaxRow(), nTab), + PaintPartFlags::Grid | PaintPartFlags::Left | PaintPartFlags::Top | PaintPartFlags::Size); } } } - - SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScDbAreasChanged ) ); - - EndRedo(); -} - -void ScUndoDBData::Repeat(SfxRepeatTarget& /* rTarget */) -{ -} - -bool ScUndoDBData::CanRepeat(SfxRepeatTarget& /* rTarget */) const -{ - return false; // is not possible } ScUndoImportData::ScUndoImportData( ScDocShell* pNewDocShell, SCTAB nNewTab, diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx index 8428509c8aa1..14cc7a545467 100644 --- a/sc/source/ui/view/dbfunc3.cxx +++ b/sc/source/ui/view/dbfunc3.cxx @@ -639,7 +639,6 @@ void ScDBFunc::DoTableSubTotals( const ScDBData& rNewData, const ScSubTotalParam ScSubTotalParam aNewParam; rNewData.GetSubTotalParam(aNewParam); // change end of range ScDocumentUniquePtr pUndoDoc; - std::unique_ptr<ScRangeName> pUndoRange; std::unique_ptr<ScDBCollection> pUndoDB; if (bRecord) // record old data @@ -657,10 +656,7 @@ void ScDBFunc::DoTableSubTotals( const ScDBData& rNewData, const ScSubTotalParam rDoc.CopyToDocument(0, 0, 0, rDoc.MaxCol(), rDoc.MaxRow(), nTabCount - 1, InsertDeleteFlags::FORMULA, false, *pUndoDoc); - // database and other ranges - ScRangeName* pDocRange = rDoc.GetRangeName(); - if (!pDocRange->empty()) - pUndoRange.reset(new ScRangeName(*pDocRange)); + // database ranges ScDBCollection* pDocDB = rDoc.GetDBCollection(); if (!pDocDB->empty()) pUndoDB.reset(new ScDBCollection(*pDocDB)); @@ -683,7 +679,7 @@ void ScDBFunc::DoTableSubTotals( const ScDBData& rNewData, const ScSubTotalParam { ScDBCollection* pDocDB = rDoc.GetDBCollection(); pDocSh->GetUndoManager()->AddUndoAction(std::make_unique<ScUndoTableTotals>( - pDocSh, nTab, rParam, aNewParam.nRow2, std::move(pUndoDoc), std::move(pUndoRange), + pDocSh, nTab, rParam, aNewParam.nRow2, std::move(pUndoDoc), std::move(pUndoDB), std::make_unique<ScDBCollection>(*pDocDB))); }
