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)));
     }
 

Reply via email to