sc/Library_sc.mk                   |    1 
 sc/inc/FilterData.hxx              |   89 ++++++
 sc/inc/table.hxx                   |   28 --
 sc/source/core/data/FilterData.cxx |  493 +++++++++++++++++++++++++++++++++++++
 sc/source/core/data/document.cxx   |   18 -
 sc/source/core/data/table1.cxx     |   19 -
 sc/source/core/data/table2.cxx     |   72 ++---
 sc/source/core/data/table3.cxx     |   14 -
 sc/source/core/data/table5.cxx     |  450 +++------------------------------
 sc/source/core/data/table6.cxx     |    6 
 sc/source/core/data/table7.cxx     |    8 
 11 files changed, 711 insertions(+), 487 deletions(-)

New commits:
commit 554f434138d29ad59be74ab1d33f7e4bf5c01a3d
Author:     Tomaž Vajngerl <[email protected]>
AuthorDate: Thu Jun 26 00:56:15 2025 +0200
Commit:     Miklos Vajna <[email protected]>
CommitDate: Tue Aug 19 08:33:42 2025 +0200

    sc: move filter and hidden handling into new class FilterData
    
    Change-Id: Ia5c60a3595d452e0ead238975232d6ac2c353c5a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/186898
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <[email protected]>
    (cherry picked from commit aaa3c04806dde105f6d430db8ef5f5c5ce09e96e)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189324
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Miklos Vajna <[email protected]>

diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk
index 5a0aa6107562..3d63f7d6d603 100644
--- a/sc/Library_sc.mk
+++ b/sc/Library_sc.mk
@@ -161,6 +161,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
     sc/source/core/data/drwlayer \
     sc/source/core/data/edittextiterator \
     sc/source/core/data/fillinfo \
+    sc/source/core/data/FilterData \
     sc/source/core/data/formulacell \
     sc/source/core/data/formulaiter \
     sc/source/core/data/funcdesc \
diff --git a/sc/inc/FilterData.hxx b/sc/inc/FilterData.hxx
new file mode 100644
index 000000000000..82e161738087
--- /dev/null
+++ b/sc/inc/FilterData.hxx
@@ -0,0 +1,89 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include "document.hxx"
+#include <memory>
+
+class ScFlatBoolRowSegments;
+class ScFlatBoolColSegments;
+class ScTable;
+
+/** Stores and handles which columns and rows are hidden or filtered in a 
sheet.
+ *
+ * Filtered are the rows or columns that get hidden (filtered) when using the
+ * auto-filter functionality. Hidden is when the user hides the column or row,
+ * manually from the UI or otherwise.
+ *
+ * Note that it is also set as hidden when it is filtered.
+ **/
+class FilterData
+{
+private:
+    ScTable& mrTable;
+
+    ScDocument& getDocument();
+    ScDocument const& getDocument() const;
+
+public:
+    FilterData(ScTable& rTable);
+
+    std::unique_ptr<ScFlatBoolColSegments> mpFilteredCols;
+    std::unique_ptr<ScFlatBoolRowSegments> mpFilteredRows;
+    std::unique_ptr<ScFlatBoolColSegments> mpHiddenCols;
+    std::unique_ptr<ScFlatBoolRowSegments> mpHiddenRows;
+
+    void makeReady();
+
+    OString dumpRowsAsString(OString const& rDefault);
+    OString dumpColsAsString(OString const& rDefault);
+
+    OString dumpHiddenRowsAsString(OString const& rDefault);
+    OString dumpHiddenColsAsString(OString const& rDefault);
+
+    bool setColFiltered(SCCOL nStartCol, SCCOL nEndCol, bool bFiltered);
+    bool setRowFiltered(SCROW nStartRow, SCROW nEndRow, bool bFiltered);
+
+    bool rowFiltered(SCROW nRow, SCROW* pFirstRow = nullptr, SCROW* pLastRow = 
nullptr) const;
+    bool columnFiltered(SCCOL nCol, SCCOL* pFirstCol = nullptr, SCCOL* 
pLastCol = nullptr) const;
+    bool hasFilteredRows(SCROW nStartRow, SCROW nEndRow) const;
+    void copyColFiltered(FilterData const& rFilter, SCCOL nStartCol, SCCOL 
nEndCol);
+    void copyRowFiltered(FilterData const& rFilter, SCROW nStartRow, SCROW 
nEndRow);
+    SCROW firstNonFilteredRow(SCROW nStartRow, SCROW nEndRow) const;
+    SCROW lastNonFilteredRow(SCROW nStartRow, SCROW nEndRow) const;
+    SCROW countNonFilteredRows(SCROW nStartRow, SCROW nEndRow) const;
+
+    bool rowHidden(SCROW nRow, SCROW* pFirstRow = nullptr, SCROW* pLastRow = 
nullptr) const;
+    bool rowHiddenLeaf(SCROW nRow, SCROW* pFirstRow = nullptr, SCROW* pLastRow 
= nullptr) const;
+    bool hasHiddenRows(SCROW nStartRow, SCROW nEndRow) const;
+    bool colHidden(SCCOL nCol, SCCOL* pFirstCol = nullptr, SCCOL* pLastCol = 
nullptr) const;
+    bool setColHidden(SCROW nStartCol, SCROW nEndCol, bool bHidden);
+    bool setRowHidden(SCROW nStartRow, SCROW nEndRow, bool bHidden);
+    void copyColHidden(FilterData const& rFilter, SCCOL nStartCol, SCCOL 
nEndCol);
+    void copyRowHidden(FilterData const& rFilter, SCROW nStartRow, SCROW 
nEndRow);
+
+    SCROW firstVisibleRow(SCROW nStartRow, SCROW nEndRow) const;
+    SCROW lastVisibleRow(SCROW nStartRow, SCROW nEndRow) const;
+    SCROW countVisibleRows(SCROW nStartRow, SCROW nEndRow) const;
+    SCCOL countVisibleCols(SCCOL nStartCol, SCCOL nEndCol) const;
+    SCCOLROW lastHiddenColRow(SCCOLROW nPos, bool bCol) const;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 944b1a9e211e..ccafa4a89fb2 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -35,7 +35,7 @@
 #include "SparklineList.hxx"
 #include "SolverSettings.hxx"
 #include "markdata.hxx"
-
+#include "FilterData.hxx"
 #include <algorithm>
 #include <atomic>
 #include <memory>
@@ -160,6 +160,9 @@ class ScTable
 private:
     typedef ::std::vector< ScRange > ScRangeVec;
 
+    SCTAB           nTab;
+    ScDocument&     rDocument;
+
     ScColContainer aCol;
 
     OUString aName;
@@ -191,10 +194,8 @@ private:
 
     std::unique_ptr<ScBitMaskCompressedArray<SCCOL, CRFlags>> mpColFlags;
     std::unique_ptr<ScBitMaskCompressedArray< SCROW, CRFlags>> pRowFlags;
-    std::unique_ptr<ScFlatBoolColSegments>  mpHiddenCols;
-    std::unique_ptr<ScFlatBoolRowSegments>  mpHiddenRows;
-    std::unique_ptr<ScFlatBoolColSegments>  mpFilteredCols;
-    std::unique_ptr<ScFlatBoolRowSegments>  mpFilteredRows;
+
+    FilterData maFilterData;
 
     ::std::set<SCROW>                      maRowPageBreaks;
     ::std::set<SCROW>                      maRowManualBreaks;
@@ -210,8 +211,6 @@ private:
     mutable SCCOL nTableAreaVisibleX;
     mutable SCROW nTableAreaVisibleY;
 
-    SCTAB           nTab;
-    ScDocument&     rDocument;
     std::unique_ptr<utl::TextSearch> pSearchText;
 
     mutable OUString aUpperName;             // #i62977# filled only on 
demand, reset in SetName
@@ -989,6 +988,9 @@ public:
     css::uno::Sequence<
         css::sheet::TablePageBreakData> GetRowBreakData() const;
 
+    void updateObjectsForColsChanged(SCCOL nStartCol, SCCOL nEndCol, bool 
bHidden, bool bChanged);
+    void updateObjectsForRowsChanged(SCROW nStartRow, SCROW nEndRow, bool 
bHidden, bool bChanged);
+
     bool        RowHidden(SCROW nRow, SCROW* pFirstRow = nullptr, SCROW* 
pLastRow = nullptr) const;
     bool        RowHiddenLeaf(SCROW nRow, SCROW* pFirstRow = nullptr, SCROW* 
pLastRow = nullptr) const;
     bool        HasHiddenRows(SCROW nStartRow, SCROW nEndRow) const;
@@ -1007,16 +1009,8 @@ public:
 
     SCCOLROW    LastHiddenColRow(SCCOLROW nPos, bool bCol) const;
 
-    bool        RowFiltered(SCROW nRow, SCROW* pFirstRow = nullptr, SCROW* 
pLastRow = nullptr) const;
-    bool        ColFiltered(SCCOL nCol, SCCOL* pFirstCol = nullptr, SCCOL* 
pLastCol = nullptr) const;
-    bool        HasFilteredRows(SCROW nStartRow, SCROW nEndRow) const;
-    void        CopyColFiltered(const ScTable& rTable, SCCOL nStartCol, SCCOL 
nEndCol);
-    void        CopyRowFiltered(const ScTable& rTable, SCROW nStartRow, SCROW 
nEndRow);
-    void        SetRowFiltered(SCROW nStartRow, SCROW nEndRow, bool bFiltered);
-    void        SetColFiltered(SCCOL nStartCol, SCCOL nEndCol, bool bFiltered);
-    SCROW       FirstNonFilteredRow(SCROW nStartRow, SCROW nEndRow) const;
-    SCROW       LastNonFilteredRow(SCROW nStartRow, SCROW nEndRow) const;
-    SCROW       CountNonFilteredRows(SCROW nStartRow, SCROW nEndRow) const;
+    FilterData& getFilterData() { return maFilterData; }
+    FilterData const& getFilterData() const { return maFilterData; }
 
     Color GetCellBackgroundColor(ScAddress aPos) const;
     Color GetCellTextColor(ScAddress aPos) const;
diff --git a/sc/source/core/data/FilterData.cxx 
b/sc/source/core/data/FilterData.cxx
new file mode 100644
index 000000000000..d6deca8bc9b2
--- /dev/null
+++ b/sc/source/core/data/FilterData.cxx
@@ -0,0 +1,493 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/types.h>
+
+#include <FilterData.hxx>
+#include <document.hxx>
+#include <table.hxx>
+#include <segmenttree.hxx>
+
+#include <vector>
+#include <memory>
+
+FilterData::FilterData(ScTable& rTable)
+    : mrTable(rTable)
+    , mpFilteredCols(new ScFlatBoolColSegments(getDocument().MaxCol()))
+    , mpFilteredRows(new ScFlatBoolRowSegments(getDocument().MaxRow()))
+    , mpHiddenCols(new ScFlatBoolColSegments(getDocument().MaxCol()))
+    , mpHiddenRows(new ScFlatBoolRowSegments(getDocument().MaxRow()))
+{
+}
+
+ScDocument& FilterData::getDocument() { return mrTable.GetDoc(); }
+ScDocument const& FilterData::getDocument() const { return mrTable.GetDoc(); }
+
+void FilterData::makeReady()
+{
+    mpFilteredCols->makeReady();
+    mpFilteredRows->makeReady();
+    mpHiddenCols->makeReady();
+    mpHiddenRows->makeReady();
+}
+
+OString FilterData::dumpColsAsString(OString const& rDefault)
+{
+    return mpFilteredCols ? mpFilteredCols->dumpAsString() : rDefault;
+}
+
+OString FilterData::dumpRowsAsString(OString const& rDefault)
+{
+    return mpFilteredRows ? mpFilteredRows->dumpAsString() : rDefault;
+}
+
+OString FilterData::dumpHiddenColsAsString(OString const& rDefault)
+{
+    return mpHiddenCols ? mpHiddenCols->dumpAsString() : rDefault;
+}
+
+OString FilterData::dumpHiddenRowsAsString(OString const& rDefault)
+{
+    return mpHiddenRows ? mpHiddenRows->dumpAsString() : rDefault;
+}
+
+bool FilterData::setColFiltered(SCCOL nStartCol, SCCOL nEndCol, bool bFiltered)
+{
+    if (bFiltered)
+        return mpFilteredCols->setTrue(nStartCol, nEndCol);
+    else
+        return mpFilteredCols->setFalse(nStartCol, nEndCol);
+}
+
+bool FilterData::setRowFiltered(SCROW nStartRow, SCROW nEndRow, bool bFiltered)
+{
+    if (bFiltered)
+        return mpFilteredRows->setTrue(nStartRow, nEndRow);
+    else
+        return mpFilteredRows->setFalse(nStartRow, nEndRow);
+}
+
+bool FilterData::rowFiltered(SCROW nRow, SCROW* pFirstRow, SCROW* pLastRow) 
const
+{
+    if (!getDocument().ValidRow(nRow))
+        return false;
+
+    ScFlatBoolRowSegments::RangeData aData;
+    if (!mpFilteredRows->getRangeData(nRow, aData))
+        // search failed.
+        return false;
+
+    if (pFirstRow)
+        *pFirstRow = aData.mnRow1;
+    if (pLastRow)
+        *pLastRow = aData.mnRow2;
+
+    return aData.mbValue;
+}
+
+bool FilterData::columnFiltered(SCCOL nCol, SCCOL* pFirstCol, SCCOL* pLastCol) 
const
+{
+    if (!getDocument().ValidCol(nCol))
+        return false;
+
+    ScFlatBoolColSegments::RangeData aData;
+    if (!mpFilteredCols->getRangeData(nCol, aData))
+        // search failed.
+        return false;
+
+    if (pFirstCol)
+        *pFirstCol = aData.mnCol1;
+    if (pLastCol)
+        *pLastCol = aData.mnCol2;
+
+    return aData.mbValue;
+}
+
+bool FilterData::hasFilteredRows(SCROW nStartRow, SCROW nEndRow) const
+{
+    SCROW nRow = nStartRow;
+    while (nRow <= nEndRow)
+    {
+        SCROW nLastRow = nRow;
+        bool bFiltered = rowFiltered(nRow, nullptr, &nLastRow);
+        if (bFiltered)
+            return true;
+
+        nRow = nLastRow + 1;
+    }
+    return false;
+}
+
+void FilterData::copyColFiltered(FilterData const& rFilter, SCCOL nStartCol, 
SCCOL nEndCol)
+{
+    SCCOL nCol = nStartCol;
+    while (nCol <= nEndCol)
+    {
+        SCCOL nLastCol = -1;
+        bool bFiltered = rFilter.columnFiltered(nCol, nullptr, &nLastCol);
+        if (nLastCol > nEndCol)
+            nLastCol = nEndCol;
+
+        setColFiltered(nCol, nLastCol, bFiltered);
+        nCol = nLastCol + 1;
+    }
+}
+
+void FilterData::copyRowFiltered(FilterData const& rFilter, SCROW nStartRow, 
SCROW nEndRow)
+{
+    SCROW nRow = nStartRow;
+    while (nRow <= nEndRow)
+    {
+        SCROW nLastRow = -1;
+        bool bFiltered = rFilter.rowFiltered(nRow, nullptr, &nLastRow);
+        if (nLastRow > nEndRow)
+            nLastRow = nEndRow;
+        setRowFiltered(nRow, nLastRow, bFiltered);
+        nRow = nLastRow + 1;
+    }
+}
+
+SCROW FilterData::firstNonFilteredRow(SCROW nStartRow, SCROW nEndRow) const
+{
+    SCROW nRow = nStartRow;
+    ScFlatBoolRowSegments::RangeData aData;
+    while (nRow <= nEndRow)
+    {
+        if (!getDocument().ValidRow(nRow))
+            break;
+
+        if (!mpFilteredRows->getRangeData(nRow, aData))
+            // failed to get range data.
+            break;
+
+        if (!aData.mbValue)
+            // non-filtered row found
+            return nRow;
+
+        nRow = aData.mnRow2 + 1;
+    }
+
+    return ::std::numeric_limits<SCROW>::max();
+}
+
+SCROW FilterData::lastNonFilteredRow(SCROW nStartRow, SCROW nEndRow) const
+{
+    SCROW nRow = nEndRow;
+    ScFlatBoolRowSegments::RangeData aData;
+    while (nRow >= nStartRow)
+    {
+        if (!getDocument().ValidRow(nRow))
+            break;
+
+        if (!mpFilteredRows->getRangeData(nRow, aData))
+            // failed to get range data.
+            break;
+
+        if (!aData.mbValue)
+            // non-filtered row found
+            return nRow;
+
+        nRow = aData.mnRow1 - 1;
+    }
+
+    return ::std::numeric_limits<SCROW>::max();
+}
+
+SCROW FilterData::countNonFilteredRows(SCROW nStartRow, SCROW nEndRow) const
+{
+    SCROW nCount = 0;
+    SCROW nRow = nStartRow;
+    ScFlatBoolRowSegments::RangeData aData;
+    while (nRow <= nEndRow)
+    {
+        if (!mpFilteredRows->getRangeData(nRow, aData))
+            break;
+
+        if (aData.mnRow2 > nEndRow)
+            aData.mnRow2 = nEndRow;
+
+        if (!aData.mbValue)
+            nCount += aData.mnRow2 - nRow + 1;
+
+        nRow = aData.mnRow2 + 1;
+    }
+    return nCount;
+}
+
+bool FilterData::rowHidden(SCROW nRow, SCROW* pFirstRow, SCROW* pLastRow) const
+{
+    if (!getDocument().ValidRow(nRow))
+    {
+        if (pFirstRow)
+            *pFirstRow = nRow;
+        if (pLastRow)
+            *pLastRow = nRow;
+        return true;
+    }
+
+    ScFlatBoolRowSegments::RangeData aData;
+    if (!mpHiddenRows->getRangeData(nRow, aData))
+    {
+        // search failed.
+        if (pFirstRow)
+            *pFirstRow = nRow;
+        if (pLastRow)
+            *pLastRow = nRow;
+        return true;
+    }
+
+    if (pFirstRow)
+        *pFirstRow = aData.mnRow1;
+    if (pLastRow)
+        *pLastRow = aData.mnRow2;
+
+    return aData.mbValue;
+}
+
+bool FilterData::rowHiddenLeaf(SCROW nRow, SCROW* pFirstRow, SCROW* pLastRow) 
const
+{
+    if (!getDocument().ValidRow(nRow))
+    {
+        if (pFirstRow)
+            *pFirstRow = nRow;
+        if (pLastRow)
+            *pLastRow = nRow;
+        return true;
+    }
+
+    ScFlatBoolRowSegments::RangeData aData;
+    if (!mpHiddenRows->getRangeDataLeaf(nRow, aData))
+    {
+        // search failed.
+        if (pFirstRow)
+            *pFirstRow = nRow;
+        if (pLastRow)
+            *pLastRow = nRow;
+        return true;
+    }
+
+    if (pFirstRow)
+        *pFirstRow = aData.mnRow1;
+    if (pLastRow)
+        *pLastRow = aData.mnRow2;
+
+    return aData.mbValue;
+}
+
+bool FilterData::hasHiddenRows(SCROW nStartRow, SCROW nEndRow) const
+{
+    SCROW nRow = nStartRow;
+    while (nRow <= nEndRow)
+    {
+        SCROW nLastRow = -1;
+        bool bHidden = rowHidden(nRow, nullptr, &nLastRow);
+        if (bHidden)
+            return true;
+
+        nRow = nLastRow + 1;
+    }
+    return false;
+}
+
+bool FilterData::colHidden(SCCOL nCol, SCCOL* pFirstCol, SCCOL* pLastCol) const
+{
+    if (!getDocument().ValidCol(nCol))
+        return true;
+
+    ScFlatBoolColSegments::RangeData aData;
+    if (!mpHiddenCols->getRangeData(nCol, aData))
+        return true;
+
+    if (pFirstCol)
+        *pFirstCol = aData.mnCol1;
+    if (pLastCol)
+        *pLastCol = aData.mnCol2;
+
+    return aData.mbValue;
+}
+
+bool FilterData::setRowHidden(SCROW nStartRow, SCROW nEndRow, bool bHidden)
+{
+    bool bChanged = false;
+    if (bHidden)
+        bChanged = mpHiddenRows->setTrue(nStartRow, nEndRow);
+    else
+        bChanged = mpHiddenRows->setFalse(nStartRow, nEndRow);
+
+    mrTable.updateObjectsForRowsChanged(nStartRow, nEndRow, bHidden, bChanged);
+
+    return bChanged;
+}
+
+bool FilterData::setColHidden(SCROW nStartCol, SCROW nEndCol, bool bHidden)
+{
+    bool bChanged = false;
+    if (bHidden)
+        bChanged = mpHiddenCols->setTrue(nStartCol, nEndCol);
+    else
+        bChanged = mpHiddenCols->setFalse(nStartCol, nEndCol);
+
+    mrTable.updateObjectsForColsChanged(nStartCol, nEndCol, bHidden, bChanged);
+
+    return bChanged;
+}
+
+void FilterData::copyColHidden(FilterData const& rFilter, SCCOL nStartCol, 
SCCOL nEndCol)
+{
+    SCCOL nCol = nStartCol;
+    while (nCol <= nEndCol)
+    {
+        SCCOL nLastCol = -1;
+        bool bHidden = rFilter.colHidden(nCol, nullptr, &nLastCol);
+        if (nLastCol > nEndCol)
+            nLastCol = nEndCol;
+
+        mrTable.SetColHidden(nCol, nLastCol, bHidden);
+        nCol = nLastCol + 1;
+    }
+}
+
+void FilterData::copyRowHidden(FilterData const& rFilter, SCROW nStartRow, 
SCROW nEndRow)
+{
+    SCROW nRow = nStartRow;
+    while (nRow <= nEndRow)
+    {
+        SCROW nLastRow = -1;
+        bool bHidden = rFilter.rowHidden(nRow, nullptr, &nLastRow);
+        if (nLastRow > nEndRow)
+            nLastRow = nEndRow;
+        mrTable.SetRowHidden(nRow, nLastRow, bHidden);
+        nRow = nLastRow + 1;
+    }
+}
+
+SCROW FilterData::firstVisibleRow(SCROW nStartRow, SCROW nEndRow) const
+{
+    SCROW nRow = nStartRow;
+    ScFlatBoolRowSegments::RangeData aData;
+    while (nRow <= nEndRow)
+    {
+        if (!getDocument().ValidRow(nRow))
+            break;
+
+        if (!mpHiddenRows->getRangeData(nRow, aData))
+            // failed to get range data.
+            break;
+
+        if (!aData.mbValue)
+            // visible row found
+            return nRow;
+
+        nRow = aData.mnRow2 + 1;
+    }
+
+    return ::std::numeric_limits<SCROW>::max();
+}
+
+SCROW FilterData::lastVisibleRow(SCROW nStartRow, SCROW nEndRow) const
+{
+    SCROW nRow = nEndRow;
+    ScFlatBoolRowSegments::RangeData aData;
+    while (nRow >= nStartRow)
+    {
+        if (!getDocument().ValidRow(nRow))
+            break;
+
+        if (!mpHiddenRows->getRangeData(nRow, aData))
+            // failed to get range data.
+            break;
+
+        if (!aData.mbValue)
+            // visible row found
+            return nRow;
+
+        nRow = aData.mnRow1 - 1;
+    }
+
+    return ::std::numeric_limits<SCROW>::max();
+}
+
+SCROW FilterData::countVisibleRows(SCROW nStartRow, SCROW nEndRow) const
+{
+    SCROW nCount = 0;
+    SCROW nRow = nStartRow;
+    ScFlatBoolRowSegments::RangeData aData;
+    while (nRow <= nEndRow)
+    {
+        if (!mpHiddenRows->getRangeData(nRow, aData))
+            break;
+
+        if (aData.mnRow2 > nEndRow)
+            aData.mnRow2 = nEndRow;
+
+        if (!aData.mbValue)
+            nCount += aData.mnRow2 - nRow + 1;
+
+        nRow = aData.mnRow2 + 1;
+    }
+    return nCount;
+}
+
+SCCOL FilterData::countVisibleCols(SCCOL nStartCol, SCCOL nEndCol) const
+{
+    assert(nStartCol <= nEndCol);
+    SCCOL nCount = 0;
+    SCCOL nCol = nStartCol;
+    ScFlatBoolColSegments::RangeData aData;
+    while (nCol <= nEndCol)
+    {
+        if (!mpHiddenCols->getRangeData(nCol, aData))
+            break;
+
+        if (aData.mnCol2 > nEndCol)
+            aData.mnCol2 = nEndCol;
+
+        if (!aData.mbValue)
+            nCount += aData.mnCol2 - nCol + 1;
+
+        nCol = aData.mnCol2 + 1;
+    }
+    return nCount;
+}
+
+SCCOLROW FilterData::lastHiddenColRow(SCCOLROW nPos, bool bCol) const
+{
+    if (bCol)
+    {
+        SCCOL nCol = static_cast<SCCOL>(nPos);
+        if (colHidden(nCol))
+        {
+            for (SCCOL i = nCol + 1; i <= getDocument().MaxCol(); ++i)
+            {
+                if (!colHidden(i))
+                    return i - 1;
+            }
+        }
+    }
+    else
+    {
+        SCROW nRow = static_cast<SCROW>(nPos);
+        SCROW nLastRow;
+        if (rowHidden(nRow, nullptr, &nLastRow))
+            return static_cast<SCCOLROW>(nLastRow);
+    }
+    return ::std::numeric_limits<SCCOLROW>::max();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index aadda2997080..e2a94a68b111 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -3279,7 +3279,7 @@ bool ScDocument::HasClipFilteredRows()
         {
             ScRange& rRange = rClipRanges[i];
             bool bAnswer
-                = maTabs[nCountTab]->HasFilteredRows(rRange.aStart.Row(), 
rRange.aEnd.Row());
+                = 
maTabs[nCountTab]->getFilterData().hasFilteredRows(rRange.aStart.Row(), 
rRange.aEnd.Row());
             if (bAnswer)
                 return true;
         }
@@ -4533,48 +4533,48 @@ SCROW ScDocument::CountVisibleRows(SCROW nStartRow, 
SCROW nEndRow, SCTAB nTab) c
 bool ScDocument::RowFiltered(SCROW nRow, SCTAB nTab, SCROW* pFirstRow, SCROW* 
pLastRow) const
 {
     if (const ScTable* pTable = FetchTable(nTab))
-        return pTable->RowFiltered(nRow, pFirstRow, pLastRow);
+        return pTable->getFilterData().rowFiltered(nRow, pFirstRow, pLastRow);
     return false;
 }
 
 bool ScDocument::HasFilteredRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab) 
const
 {
     if (const ScTable* pTable = FetchTable(nTab))
-        return pTable->HasFilteredRows(nStartRow, nEndRow);
+        return pTable->getFilterData().hasFilteredRows(nStartRow, nEndRow);
     return false;
 }
 
 bool ScDocument::ColFiltered(SCCOL nCol, SCTAB nTab) const
 {
     if (const ScTable* pTable = FetchTable(nTab))
-        return pTable->ColFiltered(nCol);
+        return pTable->getFilterData().columnFiltered(nCol);
     return false;
 }
 
 void ScDocument::SetRowFiltered(SCROW nStartRow, SCROW nEndRow, SCTAB nTab, 
bool bFiltered)
 {
     if (ScTable* pTable = FetchTable(nTab))
-        pTable->SetRowFiltered(nStartRow, nEndRow, bFiltered);
+        pTable->getFilterData().setRowFiltered(nStartRow, nEndRow, bFiltered);
 }
 
 SCROW ScDocument::FirstNonFilteredRow(SCROW nStartRow, SCROW nEndRow, SCTAB 
nTab) const
 {
     if (const ScTable* pTable = FetchTable(nTab))
-        return pTable->FirstNonFilteredRow(nStartRow, nEndRow);
+        return pTable->getFilterData().firstNonFilteredRow(nStartRow, nEndRow);
     return std::numeric_limits<SCROW>::max();
 }
 
 SCROW ScDocument::LastNonFilteredRow(SCROW nStartRow, SCROW nEndRow, SCTAB 
nTab) const
 {
     if (const ScTable* pTable = FetchTable(nTab))
-        return pTable->LastNonFilteredRow(nStartRow, nEndRow);
+        return pTable->getFilterData().lastNonFilteredRow(nStartRow, nEndRow);
     return std::numeric_limits<SCROW>::max();
 }
 
 SCROW ScDocument::CountNonFilteredRows(SCROW nStartRow, SCROW nEndRow, SCTAB 
nTab) const
 {
     if (const ScTable* pTable = FetchTable(nTab))
-        return pTable->CountNonFilteredRows(nStartRow, nEndRow);
+        return pTable->getFilterData().countNonFilteredRows(nStartRow, 
nEndRow);
     return 0;
 }
 
@@ -4645,7 +4645,7 @@ SCROW ScDocument::GetNextDifferentChangedRowFlagsWidth( 
SCTAB nTab, SCROW nStart
     if (!pRowFlagsArray)
         return 0;
 
-    if (!pTable->mpRowHeights || !pTable->mpHiddenRows)
+    if (!pTable->mpRowHeights || !pTable->maFilterData.mpHiddenRows)
         return 0;
 
     size_t nIndex;          // ignored
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index cf22133056cf..e0ca615e0095 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -61,8 +61,6 @@
 #include <vector>
 #include <memory>
 
-using ::std::vector;
-
 namespace {
 
 ScProgress* GetProgressBar(
@@ -239,6 +237,8 @@ bool SetOptimalHeightsToRows(
 
 ScTable::ScTable( ScDocument& rDoc, SCTAB nNewTab, const OUString& rNewName,
                     bool bColInfo, bool bRowInfo ) :
+    nTab(nNewTab),
+    rDocument(rDoc),
     aCol( rDoc.GetSheetLimits(), INITIALCOLCOUNT ),
     aName( rNewName ),
     aCodeName( rNewName ),
@@ -250,17 +250,11 @@ ScTable::ScTable( ScDocument& rDoc, SCTAB nNewTab, const 
OUString& rNewName,
     nRepeatStartY( SCROW_REPEAT_NONE ),
     nRepeatEndY( SCROW_REPEAT_NONE ),
     mnOptimalMinRowHeight(0),
-    mpRowHeights( static_cast<ScFlatUInt16RowSegments*>(nullptr) ),
-    mpHiddenCols(new ScFlatBoolColSegments(rDoc.MaxCol())),
-    mpHiddenRows(new ScFlatBoolRowSegments(rDoc.MaxRow())),
-    mpFilteredCols(new ScFlatBoolColSegments(rDoc.MaxCol())),
-    mpFilteredRows(new ScFlatBoolRowSegments(rDoc.MaxRow())),
+    maFilterData(*this),
     nTableAreaX( 0 ),
     nTableAreaY( 0 ),
     nTableAreaVisibleX( 0 ),
     nTableAreaVisibleY( 0 ),
-    nTab( nNewTab ),
-    rDocument( rDoc ),
     pSortCollator( nullptr ),
     nLockCount( 0 ),
     aScenarioColor( COL_LIGHTGRAY ),
@@ -2176,7 +2170,7 @@ void ScTable::ExtendPrintArea( OutputDevice* pDev,
         for (SCCOL nDataCol = nCol; 0 <= nDataCol && nDataCol >= 
aColData.mnCol1; --nDataCol)
         {
             SCCOL nPrintCol = nDataCol;
-            VisibleDataCellIterator aIter(rDocument, *mpHiddenRows, 
aCol[nDataCol]);
+            VisibleDataCellIterator aIter(rDocument, 
*maFilterData.mpHiddenRows, aCol[nDataCol]);
             ScRefCellValue aCell = aIter.reset(nStartRow);
             if (aCell.isEmpty())
                 // No visible cells found in this column.  Skip it.
@@ -2619,10 +2613,7 @@ bool ScTable::HandleRefArrayForParallelism( SCCOL nCol, 
SCROW nRow1, SCROW nRow2
     if ( !IsColValid( nCol ) || !ValidRow( nRow1 ) || !ValidRow( nRow2 ) )
         return false;
 
-    mpHiddenCols->makeReady();
-    mpHiddenRows->makeReady();
-    mpFilteredCols->makeReady();
-    mpFilteredRows->makeReady();
+    maFilterData.makeReady();
 
     return aCol[nCol].HandleRefArrayForParallelism(nRow1, nRow2, mxGroup, 
pDirtiedAddress);
 }
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index fe2c87f86aab..0efb2c006cbf 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -168,8 +168,8 @@ void ScTable::InsertRow( SCCOL nStartCol, SCCOL nEndCol, 
SCROW nStartRow, SCSIZE
         if (pOutlineTable)
             pOutlineTable->InsertRow( nStartRow, nSize );
 
-        mpFilteredRows->insertSegment(nStartRow, nSize);
-        mpHiddenRows->insertSegment(nStartRow, nSize);
+        maFilterData.mpFilteredRows->insertSegment(nStartRow, nSize);
+        maFilterData.mpHiddenRows->insertSegment(nStartRow, nSize);
 
         if (!maRowManualBreaks.empty())
         {
@@ -217,8 +217,8 @@ void ScTable::DeleteRow(
                 if (pUndoOutline)
                     *pUndoOutline = true;
 
-        mpFilteredRows->removeSegment(nStartRow, nStartRow+nSize);
-        mpHiddenRows->removeSegment(nStartRow, nStartRow+nSize);
+        maFilterData.mpFilteredRows->removeSegment(nStartRow, nStartRow+nSize);
+        maFilterData.mpHiddenRows->removeSegment(nStartRow, nStartRow+nSize);
 
         if (!maRowManualBreaks.empty())
         {
@@ -291,8 +291,8 @@ void ScTable::InsertCol(
         if (pOutlineTable)
             pOutlineTable->InsertCol( nStartCol, nSize );
 
-        mpHiddenCols->insertSegment(nStartCol, static_cast<SCCOL>(nSize));
-        mpFilteredCols->insertSegment(nStartCol, static_cast<SCCOL>(nSize));
+        maFilterData.mpHiddenCols->insertSegment(nStartCol, 
static_cast<SCCOL>(nSize));
+        maFilterData.mpFilteredCols->insertSegment(nStartCol, 
static_cast<SCCOL>(nSize));
 
         if (!maColManualBreaks.empty())
         {
@@ -371,8 +371,8 @@ void ScTable::DeleteCol(
                     *pUndoOutline = true;
 
         SCCOL nRmSize = nStartCol + static_cast<SCCOL>(nSize);
-        mpHiddenCols->removeSegment(nStartCol, nRmSize);
-        mpFilteredCols->removeSegment(nStartCol, nRmSize);
+        maFilterData.mpHiddenCols->removeSegment(nStartCol, nRmSize);
+        maFilterData.mpFilteredCols->removeSegment(nStartCol, nRmSize);
 
         if (!maColManualBreaks.empty())
         {
@@ -491,7 +491,7 @@ void ScTable::CopyToClip(
         pTable->mpColWidth->CopyFrom(*mpColWidth, 0, nCol2);
 
     pTable->CopyColHidden(*this, 0, nCol2);
-    pTable->CopyColFiltered(*this, 0, nCol2);
+    pTable->getFilterData().copyColFiltered(getFilterData(), 0, nCol2);
     if (pDBDataNoName)
         pTable->SetAnonymousDBData(std::unique_ptr<ScDBData>(new 
ScDBData(*pDBDataNoName)));
 
@@ -502,7 +502,7 @@ void ScTable::CopyToClip(
     }
 
     pTable->CopyRowHidden(*this, 0, nRow2);
-    pTable->CopyRowFiltered(*this, 0, nRow2);
+    pTable->getFilterData().copyRowFiltered(getFilterData(), 0, nRow2);
 
     // If necessary replace formulas with values
 
@@ -892,7 +892,7 @@ public:
             for (SCROW curRow = nTopRow; curRow <= 
static_cast<SCROW>(mnEndRow); ++curRow)
             {
                 // maybe this loop could be optimized
-                bool bFiltered = mrSrcTab.RowFiltered(curRow, nullptr, 
nullptr);
+                bool bFiltered = mrSrcTab.getFilterData().rowFiltered(curRow, 
nullptr, nullptr);
                 if (bFiltered)
                     rFilteredRows.push_back(curRow);
             }
@@ -901,7 +901,7 @@ public:
 
     void operator() (size_t nRow, double fVal)
     {
-        bool bFiltered = mrSrcTab.RowFiltered(nRow, nullptr, nullptr);
+        bool bFiltered = mrSrcTab.getFilterData().rowFiltered(nRow, nullptr, 
nullptr);
         if (!mbIncludeFiltered && bFiltered)
         {
             mnFilteredRows++;
@@ -920,7 +920,7 @@ public:
 
     void operator() (size_t nRow, const svl::SharedString& rStr)
     {
-        bool bFiltered = mrSrcTab.RowFiltered(nRow, nullptr, nullptr);
+        bool bFiltered = mrSrcTab.getFilterData().rowFiltered(nRow, nullptr, 
nullptr);
         if (!mbIncludeFiltered && bFiltered)
         {
             mnFilteredRows++;
@@ -939,7 +939,7 @@ public:
 
     void operator() (size_t nRow, const EditTextObject* p)
     {
-        bool bFiltered = mrSrcTab.RowFiltered(nRow, nullptr, nullptr);
+        bool bFiltered = mrSrcTab.getFilterData().rowFiltered(nRow, nullptr, 
nullptr);
         if (!mbIncludeFiltered && bFiltered)
         {
             mnFilteredRows++;
@@ -958,7 +958,7 @@ public:
 
     void operator() (size_t nRow, const ScFormulaCell* p)
     {
-        bool bFiltered = mrSrcTab.RowFiltered(nRow, nullptr, nullptr);
+        bool bFiltered = mrSrcTab.getFilterData().rowFiltered(nRow, nullptr, 
nullptr);
         if (!mbIncludeFiltered && bFiltered)
         {
             mnFilteredRows++;
@@ -990,7 +990,7 @@ public:
     {
         for (size_t curRow = nRow; curRow < nRow + nDataSize; ++curRow)
         {
-            bool bFiltered = mrSrcTab.RowFiltered(curRow, nullptr, nullptr);
+            bool bFiltered = mrSrcTab.getFilterData().rowFiltered(curRow, 
nullptr, nullptr);
             if (!mbIncludeFiltered && bFiltered)
             {
                 mnFilteredRows++;
@@ -1192,7 +1192,7 @@ void ScTable::TransposeColNotes(ScTable* pTransClip, 
SCCOL nCol1, SCCOL nCol, SC
                 size_t curRow = nBlockStart + nOffsetInBlock;
                 for (; itData != itDataEnd; ++itData, ++curRow)
                 {
-                    bool bFiltered = this->RowFiltered(curRow, nullptr, 
nullptr);
+                    bool bFiltered = getFilterData().rowFiltered(curRow, 
nullptr, nullptr);
                     if (!bIncludeFiltered && bFiltered)
                     {
                         nFilteredRows++;
@@ -1218,7 +1218,7 @@ void ScTable::TransposeColNotes(ScTable* pTransClip, 
SCCOL nCol1, SCCOL nCol, SC
                 size_t curRow = nBlockStart + nOffsetInBlock;
                 for (; itData != itDataEnd; ++itData, ++curRow)
                 {
-                    bool bFiltered = this->RowFiltered(curRow, nullptr, 
nullptr);
+                    bool bFiltered = getFilterData().rowFiltered(curRow, 
nullptr, nullptr);
                     if (!bIncludeFiltered && bFiltered)
                     {
                         nFilteredRows++;
@@ -1243,7 +1243,7 @@ void ScTable::TransposeColNotes(ScTable* pTransClip, 
SCCOL nCol1, SCCOL nCol, SC
             for (size_t curRow = nBlockStart + nOffsetInBlock;
                  curRow <= nBlockEnd && curRow <= nRowPos; ++curRow)
             {
-                bool bFiltered = this->RowFiltered(curRow, nullptr, nullptr);
+                bool bFiltered = getFilterData().rowFiltered(curRow, nullptr, 
nullptr);
                 if (!bIncludeFiltered && bFiltered && curRow < nBlockEnd)
                 {
                     nFilteredRows++;
@@ -1478,11 +1478,11 @@ void ScTable::CopyToTable(
             for (SCROW i = nRow1; i <= nRow2; ++i)
             {
                 SCROW nLastRow;
-                bool bFiltered = RowFiltered(i, nullptr, &nLastRow);
+                bool bFiltered = getFilterData().rowFiltered(i, nullptr, 
&nLastRow);
                 if (nLastRow >= nRow2)
                     // the last row shouldn't exceed the upper bound the 
caller specified.
                     nLastRow = nRow2;
-                pDestTab->SetRowFiltered(i, nLastRow, bFiltered);
+                pDestTab->getFilterData().setRowFiltered(i, nLastRow, 
bFiltered);
                 i = nLastRow;
             }
             pDestTab->SetRowManualBreaks( std::set(maRowManualBreaks) );
@@ -3761,7 +3761,7 @@ void ScTable::ShowRow(SCROW nRow, bool bShow)
         {
             SetRowHidden(nRow, nRow, !bShow);
             if (bShow)
-                SetRowFiltered(nRow, nRow, false);
+                getFilterData().setRowFiltered(nRow, nRow, false);
             ScChartListenerCollection* pCharts = 
rDocument.GetChartListenerCollection();
             if ( pCharts )
                 pCharts->SetRangeDirty(ScRange( 0, nRow, nTab, 
rDocument.MaxCol(), nRow, nTab ));
@@ -3781,7 +3781,7 @@ void ScTable::DBShowRow(SCROW nRow, bool bShow)
     {
         //  Always set filter flag; unchanged when Hidden
         bool bChanged = SetRowHidden(nRow, nRow, !bShow);
-        SetRowFiltered(nRow, nRow, !bShow);
+        getFilterData().setRowFiltered(nRow, nRow, !bShow);
 
         if (bChanged)
         {
@@ -3814,7 +3814,7 @@ void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, bool 
bShow)
         bool bChanged = ( bWasVis != bShow );
 
         SetRowHidden(nStartRow, nEndRow, !bShow);
-        SetRowFiltered(nStartRow, nEndRow, !bShow);
+        getFilterData().setRowFiltered(nStartRow, nEndRow, !bShow);
 
         if ( bChanged )
         {
@@ -3852,7 +3852,7 @@ void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, bool 
bShow)
 
         SetRowHidden(nStartRow, nEndRow, !bShow);
         if (bShow)
-            SetRowFiltered(nStartRow, nEndRow, false);
+            getFilterData().setRowFiltered(nStartRow, nEndRow, false);
 
         if ( bChanged )
         {
@@ -3871,7 +3871,7 @@ void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, bool 
bShow)
         // #i116164# set the flags for the whole range at once
         SetRowHidden(nRow1, nRow2, !bShow);
         if (bShow)
-            SetRowFiltered(nRow1, nRow2, false);
+            getFilterData().setRowFiltered(nRow1, nRow2, false);
     }
 }
 
@@ -3948,16 +3948,16 @@ SCROW ScTable::GetLastFlaggedRow() const
     if (!maRowManualBreaks.empty())
         nLastFound = ::std::max(nLastFound, *maRowManualBreaks.rbegin());
 
-    if (mpHiddenRows)
+    if (maFilterData.mpHiddenRows)
     {
-        SCROW nRow = mpHiddenRows->findLastTrue();
+        SCROW nRow = maFilterData.mpHiddenRows->findLastTrue();
         if (ValidRow(nRow))
             nLastFound = ::std::max(nLastFound, nRow);
     }
 
-    if (mpFilteredRows)
+    if (maFilterData.mpFilteredRows)
     {
-        SCROW nRow = mpFilteredRows->findLastTrue();
+        SCROW nRow = maFilterData.mpFilteredRows->findLastTrue();
         if (ValidRow(nRow))
             nLastFound = ::std::max(nLastFound, nRow);
     }
@@ -4029,7 +4029,7 @@ void ScTable::ExtendHidden( SCCOL& rX1, SCROW& rY1, 
SCCOL& rX2, SCROW& rY2 )
     if (rY1 > 0)
     {
         ScFlatBoolRowSegments::RangeData aData;
-        if (mpHiddenRows->getRangeData(rY1-1, aData) && aData.mbValue)
+        if (maFilterData.mpHiddenRows->getRangeData(rY1-1, aData) && 
aData.mbValue)
         {
             SCROW nStartRow = aData.mnRow1;
             if (ValidRow(nStartRow))
@@ -4054,7 +4054,7 @@ void ScTable::StripHidden( SCCOL& rX1, SCROW& rY1, SCCOL& 
rX2, SCROW& rY2 )
     if (rY1 < rY2)
     {
         ScFlatBoolRowSegments::RangeData aData;
-        if (mpHiddenRows->getRangeData(rY2, aData) && aData.mbValue)
+        if (maFilterData.mpHiddenRows->getRangeData(rY2, aData) && 
aData.mbValue)
         {
             SCROW nStartRow = aData.mnRow1;
             if (ValidRow(nStartRow) && nStartRow >= rY1)
@@ -4246,7 +4246,7 @@ bool ScTable::RefVisible(const ScFormulaCell* pCell)
         if (aRef.aStart.Col()==aRef.aEnd.Col() && 
aRef.aStart.Tab()==aRef.aEnd.Tab())
         {
             SCROW nEndRow;
-            if (!RowFiltered(aRef.aStart.Row(), nullptr, &nEndRow))
+            if (!getFilterData().rowFiltered(aRef.aStart.Row(), nullptr, 
&nEndRow))
                 // row not filtered.
                 nEndRow = ::std::numeric_limits<SCROW>::max();
 
@@ -4313,7 +4313,7 @@ ScRangeName* ScTable::GetRangeName() const
 tools::Long ScTable::GetRowOffset( SCROW nRow, bool bHiddenAsZero ) const
 {
     tools::Long n = 0;
-    if ( mpHiddenRows && mpRowHeights )
+    if (maFilterData.mpHiddenRows && mpRowHeights)
     {
         if (nRow == 0)
             return 0;
@@ -4357,7 +4357,7 @@ SCROW ScTable::GetRowForHeight(tools::Long nHeight) const
         // fetch hidden data range if necessary
         if (aHiddenRange.mnRow2 < nRow)
         {
-            if (!mpHiddenRows->getRangeData(nRow, aHiddenRange))
+            if (!maFilterData.mpHiddenRows->getRangeData(nRow, aHiddenRange))
                 // Failed to fetch the range data for whatever reason.
                 break;
         }
@@ -4439,7 +4439,7 @@ SCROW ScTable::GetRowForHeightPixels(SCROW nStartRow, 
tools::Long& rStartRowHeig
         // fetch hidden data range if necessary
         if (aHiddenRange.mnRow2 < nRow)
         {
-            if (!mpHiddenRows->getRangeData(nRow, aHiddenRange))
+            if (!maFilterData.mpHiddenRows->getRangeData(nRow, aHiddenRange))
                 // Failed to fetch the range data for whatever reason.
                 break;
         }
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index f5b66a250ea7..39decdf6e027 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -276,7 +276,7 @@ void initDataRows(
         {
             ScSortInfoArray::Row& rRow = rRows[nRow-nRow1];
             rRow.mbHidden = rTab.RowHidden(nRow);
-            rRow.mbFiltered = rTab.RowFiltered(nRow);
+            rRow.mbFiltered = rTab.getFilterData().rowFiltered(nRow);
         }
     }
 }
@@ -1077,7 +1077,7 @@ void ScTable::SortReorderByRow( ScSortInfoArray* pArray, 
SCCOL nCol1, SCCOL nCol
 
         // Remove all flags in the range first.
         SetRowHidden(nRow1, nRow2, false);
-        SetRowFiltered(nRow1, nRow2, false);
+        getFilterData().setRowFiltered(nRow1, nRow2, false);
 
         std::vector<sc::RowSpan> aSpans =
             sc::toSpanArray<SCROW,sc::RowSpan>(aRowFlags.maRowsHidden, nRow1);
@@ -1088,7 +1088,7 @@ void ScTable::SortReorderByRow( ScSortInfoArray* pArray, 
SCCOL nCol1, SCCOL nCol
         aSpans = sc::toSpanArray<SCROW,sc::RowSpan>(aRowFlags.maRowsFiltered, 
nRow1);
 
         for (const auto& rSpan : aSpans)
-            SetRowFiltered(rSpan.mnRow1, rSpan.mnRow2, true);
+            getFilterData().setRowFiltered(rSpan.mnRow1, rSpan.mnRow2, true);
 
         //Restore visibility state of objects
         restoreObjectsVisibility(aSortedCols, aBackup);
@@ -1282,7 +1282,7 @@ void ScTable::SortReorderByRowRefUpdate(
 
         // Remove all flags in the range first.
         SetRowHidden(nRow1, nRow2, false);
-        SetRowFiltered(nRow1, nRow2, false);
+        getFilterData().setRowFiltered(nRow1, nRow2, false);
 
         std::vector<sc::RowSpan> aSpans =
             sc::toSpanArray<SCROW,sc::RowSpan>(aRowFlags.maRowsHidden, nRow1);
@@ -1293,7 +1293,7 @@ void ScTable::SortReorderByRowRefUpdate(
         aSpans = sc::toSpanArray<SCROW,sc::RowSpan>(aRowFlags.maRowsFiltered, 
nRow1);
 
         for (const auto& rSpan : aSpans)
-            SetRowFiltered(rSpan.mnRow1, rSpan.mnRow2, true);
+            getFilterData().setRowFiltered(rSpan.mnRow1, rSpan.mnRow2, true);
 
         //Restore visibility state of objects
         restoreObjectsVisibility(aSortedCols, aBackup);
@@ -2158,7 +2158,7 @@ bool ScTable::DoSubTotals( ScSubTotalParam& rParam )
                         }
                     }
                 }
-                bBlockVis = !RowFiltered(nRow);
+                bBlockVis = !getFilterData().rowFiltered(nRow);
             }
         }
     }
@@ -3051,7 +3051,7 @@ void ScTable::UpdateSelectionFunction( ScFunctionData& 
rData, const ScMarkData&
         if (mpColFlags && ColHidden(nCol))
             continue;
 
-        aCol[nCol].UpdateSelectionFunction(aRanges, rData, *mpHiddenRows);
+        aCol[nCol].UpdateSelectionFunction(aRanges, rData, 
*maFilterData.mpHiddenRows);
     }
 }
 
diff --git a/sc/source/core/data/table5.cxx b/sc/source/core/data/table5.cxx
index 16ac890b7c5d..8067cb248bd8 100644
--- a/sc/source/core/data/table5.cxx
+++ b/sc/source/core/data/table5.cxx
@@ -201,7 +201,7 @@ void ScTable::UpdatePageBreaks(const ScRange* pUserArea)
     bool bRepeatRow = (nRepeatStartY != SCROW_REPEAT_NONE);
     bool bRowFound = false;
     tools::Long nSizeY = 0;
-    ScFlatBoolRowSegments::ForwardIterator aIterHidden(*mpHiddenRows);
+    ScFlatBoolRowSegments::ForwardIterator 
aIterHidden(*maFilterData.mpHiddenRows);
     ScFlatUInt16RowSegments::ForwardIterator aIterHeights(*mpRowHeights);
     SCROW nNextManualBreak = GetNextManualBreak(nStartRow); // -1 => no more 
manual breaks
     for (SCROW nY = nStartRow; nY <= nEndRow; ++nY)
@@ -486,106 +486,58 @@ Sequence<TablePageBreakData> ScTable::GetRowBreakData() 
const
 
 bool ScTable::RowHidden(SCROW nRow, SCROW* pFirstRow, SCROW* pLastRow) const
 {
-    if (!ValidRow(nRow))
-    {
-        if (pFirstRow)
-            *pFirstRow = nRow;
-        if (pLastRow)
-            *pLastRow = nRow;
-        return true;
-    }
-
-    ScFlatBoolRowSegments::RangeData aData;
-    if (!mpHiddenRows->getRangeData(nRow, aData))
-    {
-        // search failed.
-        if (pFirstRow)
-            *pFirstRow = nRow;
-        if (pLastRow)
-            *pLastRow = nRow;
-        return true;
-    }
-
-    if (pFirstRow)
-        *pFirstRow = aData.mnRow1;
-    if (pLastRow)
-        *pLastRow = aData.mnRow2;
-
-    return aData.mbValue;
+    return maFilterData.rowHidden(nRow, pFirstRow, pLastRow);
 }
 
 bool ScTable::RowHiddenLeaf(SCROW nRow, SCROW* pFirstRow, SCROW* pLastRow) 
const
 {
-    if (!ValidRow(nRow))
-    {
-        if (pFirstRow)
-            *pFirstRow = nRow;
-        if (pLastRow)
-            *pLastRow = nRow;
-        return true;
-    }
-
-    ScFlatBoolRowSegments::RangeData aData;
-    if (!mpHiddenRows->getRangeDataLeaf(nRow, aData))
-    {
-        // search failed.
-        if (pFirstRow)
-            *pFirstRow = nRow;
-        if (pLastRow)
-            *pLastRow = nRow;
-        return true;
-    }
-
-    if (pFirstRow)
-        *pFirstRow = aData.mnRow1;
-    if (pLastRow)
-        *pLastRow = aData.mnRow2;
-
-    return aData.mbValue;
+    return maFilterData.rowHiddenLeaf(nRow, pFirstRow, pLastRow);
 }
 
 bool ScTable::HasHiddenRows(SCROW nStartRow, SCROW nEndRow) const
 {
-    SCROW nRow = nStartRow;
-    while (nRow <= nEndRow)
-    {
-        SCROW nLastRow = -1;
-        bool bHidden = RowHidden(nRow, nullptr, &nLastRow);
-        if (bHidden)
-            return true;
-
-        nRow = nLastRow + 1;
-    }
-    return false;
+    return maFilterData.hasHiddenRows(nStartRow, nEndRow);
 }
 
 bool ScTable::ColHidden(SCCOL nCol, SCCOL* pFirstCol, SCCOL* pLastCol) const
 {
-    if (!ValidCol(nCol))
-        return true;
-
-    ScFlatBoolColSegments::RangeData aData;
-    if (!mpHiddenCols->getRangeData(nCol, aData))
-        return true;
+    return maFilterData.colHidden(nCol, pFirstCol, pLastCol);
+}
 
-    if (pFirstCol)
-        *pFirstCol = aData.mnCol1;
-    if (pLastCol)
-        *pLastCol = aData.mnCol2;
+void ScTable::updateObjectsForColsChanged(SCCOL nStartCol, SCCOL nEndCol, bool 
bHidden,
+                                          bool bChanged)
+{
+    // Cell anchored objects might change visibility
+    ScDrawLayer* pDrawLayer = GetDoc().GetDrawLayer();
+    if (pDrawLayer)
+    {
+        std::vector<SdrObject*> aColDrawObjects;
+        aColDrawObjects = pDrawLayer->GetObjectsAnchoredToCols(GetTab(), 
nStartCol, nEndCol);
+        for (auto aObj : aColDrawObjects)
+        {
+            ScDrawObjData* pData = ScDrawLayer::GetObjData(aObj);
+            if (pData)
+            {
+                if (bHidden)
+                    aObj->SetVisible(false);
+                else if (!GetDoc().RowHidden(pData->maStart.Row(), 
pData->maStart.Tab()))
+                {
+                    // Only change visibility if object is not hidden by a 
hidden row
+                    aObj->SetVisible(true);
+                }
+            }
+        }
+    }
 
-    return aData.mbValue;
+    if (bChanged)
+        SetStreamValid(false);
 }
 
-bool ScTable::SetRowHidden(SCROW nStartRow, SCROW nEndRow, bool bHidden)
+void ScTable::updateObjectsForRowsChanged(SCROW nStartRow, SCROW nEndRow, bool 
bHidden,
+                                          bool bChanged)
 {
-    bool bChanged = false;
-    if (bHidden)
-        bChanged = mpHiddenRows->setTrue(nStartRow, nEndRow);
-    else
-        bChanged = mpHiddenRows->setFalse(nStartRow, nEndRow);
-
     // Cell anchored objects might change visibility
-    ScDrawLayer* pDrawLayer = rDocument.GetDrawLayer();
+    ScDrawLayer* pDrawLayer = GetDoc().GetDrawLayer();
     if (pDrawLayer)
     {
         std::vector<SdrObject*> aRowDrawObjects;
@@ -615,78 +567,33 @@ bool ScTable::SetRowHidden(SCROW nStartRow, SCROW 
nEndRow, bool bHidden)
             // SfxHintId::ScHiddenRowsChanged, leaving the bulk will track
             // those and broadcast SfxHintId::ScDataChanged to notify all
             // dependents.
-            ScBulkBroadcast aBulkBroadcast(rDocument.GetBASM(), 
SfxHintId::ScDataChanged);
+            ScBulkBroadcast aBulkBroadcast(GetDoc().GetBASM(), 
SfxHintId::ScDataChanged);
             for (SCCOL i = 0; i < aCol.size(); i++)
             {
                 aCol[i].BroadcastRows(nStartRow, nEndRow, 
SfxHintId::ScHiddenRowsChanged);
             }
         }
     }
+}
 
-    return bChanged;
+bool ScTable::SetRowHidden(SCROW nStartRow, SCROW nEndRow, bool bHidden)
+{
+    return maFilterData.setRowHidden(nStartRow, nEndRow, bHidden);
 }
 
 void ScTable::SetColHidden(SCCOL nStartCol, SCCOL nEndCol, bool bHidden)
 {
-    bool bChanged = false;
-    if (bHidden)
-        bChanged = mpHiddenCols->setTrue(nStartCol, nEndCol);
-    else
-        bChanged = mpHiddenCols->setFalse(nStartCol, nEndCol);
-
-    // Cell anchored objects might change visibility
-    ScDrawLayer* pDrawLayer = rDocument.GetDrawLayer();
-    if (pDrawLayer)
-    {
-        std::vector<SdrObject*> aColDrawObjects;
-        aColDrawObjects = pDrawLayer->GetObjectsAnchoredToCols(GetTab(), 
nStartCol, nEndCol);
-        for (auto aObj : aColDrawObjects)
-        {
-            ScDrawObjData* pData = ScDrawLayer::GetObjData(aObj);
-            if (pData)
-            {
-                if (bHidden)
-                    aObj->SetVisible(false);
-                else if (!GetDoc().RowHidden(pData->maStart.Row(), 
pData->maStart.Tab()))
-                {
-                    // Only change visibility if object is not hidden by a 
hidden row
-                    aObj->SetVisible(true);
-                }
-            }
-        }
-    }
-
-    if (bChanged)
-        SetStreamValid(false);
+    maFilterData.setColHidden(nStartCol, nEndCol, bHidden);
 }
 
 void ScTable::CopyColHidden(const ScTable& rTable, SCCOL nStartCol, SCCOL 
nEndCol)
 {
-    SCCOL nCol = nStartCol;
-    while (nCol <= nEndCol)
-    {
-        SCCOL nLastCol = -1;
-        bool bHidden = rTable.ColHidden(nCol, nullptr, &nLastCol);
-        if (nLastCol > nEndCol)
-            nLastCol = nEndCol;
-
-        SetColHidden(nCol, nLastCol, bHidden);
-        nCol = nLastCol + 1;
-    }
+    return maFilterData.copyColHidden(rTable.getFilterData(), nStartCol, 
nEndCol);
 }
 
 void ScTable::CopyRowHidden(const ScTable& rTable, SCROW nStartRow, SCROW 
nEndRow)
 {
-    SCROW nRow = nStartRow;
-    while (nRow <= nEndRow)
-    {
-        SCROW nLastRow = -1;
-        bool bHidden = rTable.RowHidden(nRow, nullptr, &nLastRow);
-        if (nLastRow > nEndRow)
-            nLastRow = nEndRow;
-        SetRowHidden(nRow, nLastRow, bHidden);
-        nRow = nLastRow + 1;
-    }
+    return maFilterData.copyRowHidden(rTable.getFilterData(), nStartRow, 
nEndRow);
 }
 
 void ScTable::CopyRowHeight(const ScTable& rSrcTable, SCROW nStartRow, SCROW 
nEndRow,
@@ -711,69 +618,17 @@ void ScTable::CopyRowHeight(const ScTable& rSrcTable, 
SCROW nStartRow, SCROW nEn
 
 SCROW ScTable::FirstVisibleRow(SCROW nStartRow, SCROW nEndRow) const
 {
-    SCROW nRow = nStartRow;
-    ScFlatBoolRowSegments::RangeData aData;
-    while (nRow <= nEndRow)
-    {
-        if (!ValidRow(nRow))
-            break;
-
-        if (!mpHiddenRows->getRangeData(nRow, aData))
-            // failed to get range data.
-            break;
-
-        if (!aData.mbValue)
-            // visible row found
-            return nRow;
-
-        nRow = aData.mnRow2 + 1;
-    }
-
-    return ::std::numeric_limits<SCROW>::max();
+    return maFilterData.firstVisibleRow(nStartRow, nEndRow);
 }
 
 SCROW ScTable::LastVisibleRow(SCROW nStartRow, SCROW nEndRow) const
 {
-    SCROW nRow = nEndRow;
-    ScFlatBoolRowSegments::RangeData aData;
-    while (nRow >= nStartRow)
-    {
-        if (!ValidRow(nRow))
-            break;
-
-        if (!mpHiddenRows->getRangeData(nRow, aData))
-            // failed to get range data.
-            break;
-
-        if (!aData.mbValue)
-            // visible row found
-            return nRow;
-
-        nRow = aData.mnRow1 - 1;
-    }
-
-    return ::std::numeric_limits<SCROW>::max();
+    return maFilterData.lastVisibleRow(nStartRow, nEndRow);
 }
 
 SCROW ScTable::CountVisibleRows(SCROW nStartRow, SCROW nEndRow) const
 {
-    SCROW nCount = 0;
-    SCROW nRow = nStartRow;
-    ScFlatBoolRowSegments::RangeData aData;
-    while (nRow <= nEndRow)
-    {
-        if (!mpHiddenRows->getRangeData(nRow, aData))
-            break;
-
-        if (aData.mnRow2 > nEndRow)
-            aData.mnRow2 = nEndRow;
-
-        if (!aData.mbValue)
-            nCount += aData.mnRow2 - nRow + 1;
-
-        nRow = aData.mnRow2 + 1;
-    }
-    return nCount;
+    return maFilterData.countVisibleRows(nStartRow, nEndRow);
 }
 
 tools::Long ScTable::GetTotalRowHeight(SCROW nStartRow, SCROW nEndRow, bool 
bHiddenAsZero) const
@@ -783,7 +638,7 @@ tools::Long ScTable::GetTotalRowHeight(SCROW nStartRow, 
SCROW nEndRow, bool bHid
     ScFlatBoolRowSegments::RangeData aData;
     while (nRow <= nEndRow)
     {
-        if (!mpHiddenRows->getRangeData(nRow, aData))
+        if (!maFilterData.mpHiddenRows->getRangeData(nRow, aData))
             break;
 
         if (aData.mnRow2 > nEndRow)
@@ -801,211 +656,12 @@ tools::Long ScTable::GetTotalRowHeight(SCROW nStartRow, 
SCROW nEndRow, bool bHid
 
 SCCOL ScTable::CountVisibleCols(SCCOL nStartCol, SCCOL nEndCol) const
 {
-    assert(nStartCol <= nEndCol);
-    SCCOL nCount = 0;
-    SCCOL nCol = nStartCol;
-    ScFlatBoolColSegments::RangeData aData;
-    while (nCol <= nEndCol)
-    {
-        if (!mpHiddenCols->getRangeData(nCol, aData))
-            break;
-
-        if (aData.mnCol2 > nEndCol)
-            aData.mnCol2 = nEndCol;
-
-        if (!aData.mbValue)
-            nCount += aData.mnCol2 - nCol + 1;
-
-        nCol = aData.mnCol2 + 1;
-    }
-    return nCount;
+    return maFilterData.countVisibleCols(nStartCol, nEndCol);
 }
 
 SCCOLROW ScTable::LastHiddenColRow(SCCOLROW nPos, bool bCol) const
 {
-    if (bCol)
-    {
-        SCCOL nCol = static_cast<SCCOL>(nPos);
-        if (ColHidden(nCol))
-        {
-            for (SCCOL i = nCol + 1; i <= rDocument.MaxCol(); ++i)
-            {
-                if (!ColHidden(i))
-                    return i - 1;
-            }
-        }
-    }
-    else
-    {
-        SCROW nRow = static_cast<SCROW>(nPos);
-        SCROW nLastRow;
-        if (RowHidden(nRow, nullptr, &nLastRow))
-            return static_cast<SCCOLROW>(nLastRow);
-    }
-    return ::std::numeric_limits<SCCOLROW>::max();
-}
-
-bool ScTable::RowFiltered(SCROW nRow, SCROW* pFirstRow, SCROW* pLastRow) const
-{
-    if (!ValidRow(nRow))
-        return false;
-
-    ScFlatBoolRowSegments::RangeData aData;
-    if (!mpFilteredRows->getRangeData(nRow, aData))
-        // search failed.
-        return false;
-
-    if (pFirstRow)
-        *pFirstRow = aData.mnRow1;
-    if (pLastRow)
-        *pLastRow = aData.mnRow2;
-
-    return aData.mbValue;
-}
-
-bool ScTable::ColFiltered(SCCOL nCol, SCCOL* pFirstCol, SCCOL* pLastCol) const
-{
-    if (!ValidCol(nCol))
-        return false;
-
-    ScFlatBoolColSegments::RangeData aData;
-    if (!mpFilteredCols->getRangeData(nCol, aData))
-        // search failed.
-        return false;
-
-    if (pFirstCol)
-        *pFirstCol = aData.mnCol1;
-    if (pLastCol)
-        *pLastCol = aData.mnCol2;
-
-    return aData.mbValue;
-}
-
-bool ScTable::HasFilteredRows(SCROW nStartRow, SCROW nEndRow) const
-{
-    SCROW nRow = nStartRow;
-    while (nRow <= nEndRow)
-    {
-        SCROW nLastRow = nRow;
-        bool bFiltered = RowFiltered(nRow, nullptr, &nLastRow);
-        if (bFiltered)
-            return true;
-
-        nRow = nLastRow + 1;
-    }
-    return false;
-}
-
-void ScTable::CopyColFiltered(const ScTable& rTable, SCCOL nStartCol, SCCOL 
nEndCol)
-{
-    SCCOL nCol = nStartCol;
-    while (nCol <= nEndCol)
-    {
-        SCCOL nLastCol = -1;
-        bool bFiltered = rTable.ColFiltered(nCol, nullptr, &nLastCol);
-        if (nLastCol > nEndCol)
-            nLastCol = nEndCol;
-
-        SetColFiltered(nCol, nLastCol, bFiltered);
-        nCol = nLastCol + 1;
-    }
-}
-
-void ScTable::CopyRowFiltered(const ScTable& rTable, SCROW nStartRow, SCROW 
nEndRow)
-{
-    SCROW nRow = nStartRow;
-    while (nRow <= nEndRow)
-    {
-        SCROW nLastRow = -1;
-        bool bFiltered = rTable.RowFiltered(nRow, nullptr, &nLastRow);
-        if (nLastRow > nEndRow)
-            nLastRow = nEndRow;
-        SetRowFiltered(nRow, nLastRow, bFiltered);
-        nRow = nLastRow + 1;
-    }
-}
-
-void ScTable::SetRowFiltered(SCROW nStartRow, SCROW nEndRow, bool bFiltered)
-{
-    if (bFiltered)
-        mpFilteredRows->setTrue(nStartRow, nEndRow);
-    else
-        mpFilteredRows->setFalse(nStartRow, nEndRow);
-}
-
-void ScTable::SetColFiltered(SCCOL nStartCol, SCCOL nEndCol, bool bFiltered)
-{
-    if (bFiltered)
-        mpFilteredCols->setTrue(nStartCol, nEndCol);
-    else
-        mpFilteredCols->setFalse(nStartCol, nEndCol);
-}
-
-SCROW ScTable::FirstNonFilteredRow(SCROW nStartRow, SCROW nEndRow) const
-{
-    SCROW nRow = nStartRow;
-    ScFlatBoolRowSegments::RangeData aData;
-    while (nRow <= nEndRow)
-    {
-        if (!ValidRow(nRow))
-            break;
-
-        if (!mpFilteredRows->getRangeData(nRow, aData))
-            // failed to get range data.
-            break;
-
-        if (!aData.mbValue)
-            // non-filtered row found
-            return nRow;
-
-        nRow = aData.mnRow2 + 1;
-    }
-
-    return ::std::numeric_limits<SCROW>::max();
-}
-
-SCROW ScTable::LastNonFilteredRow(SCROW nStartRow, SCROW nEndRow) const
-{
-    SCROW nRow = nEndRow;
-    ScFlatBoolRowSegments::RangeData aData;
-    while (nRow >= nStartRow)
-    {
-        if (!ValidRow(nRow))
-            break;
-
-        if (!mpFilteredRows->getRangeData(nRow, aData))
-            // failed to get range data.
-            break;
-
-        if (!aData.mbValue)
-            // non-filtered row found
-            return nRow;
-
-        nRow = aData.mnRow1 - 1;
-    }
-
-    return ::std::numeric_limits<SCROW>::max();
-}
-
-SCROW ScTable::CountNonFilteredRows(SCROW nStartRow, SCROW nEndRow) const
-{
-    SCROW nCount = 0;
-    SCROW nRow = nStartRow;
-    ScFlatBoolRowSegments::RangeData aData;
-    while (nRow <= nEndRow)
-    {
-        if (!mpFilteredRows->getRangeData(nRow, aData))
-            break;
-
-        if (aData.mnRow2 > nEndRow)
-            aData.mnRow2 = nEndRow;
-
-        if (!aData.mbValue)
-            nCount += aData.mnRow2 - nRow + 1;
-
-        nRow = aData.mnRow2 + 1;
-    }
-    return nCount;
+    return maFilterData.lastHiddenColRow(nPos, bCol);
 }
 
 Color ScTable::GetCellBackgroundColor(ScAddress aPos) const
@@ -1146,10 +802,10 @@ void ScTable::SyncColRowFlags()
         mpColFlags->OrValue(rBreakPos, CRFlags::ManualBreak);
 
     // Hidden flags.
-    lcl_syncFlags(&rDocument, *mpHiddenCols, *mpHiddenRows, mpColFlags.get(), 
pRowFlags.get(),
-                  CRFlags::Hidden);
-    lcl_syncFlags(&rDocument, *mpFilteredCols, *mpFilteredRows, 
mpColFlags.get(), pRowFlags.get(),
-                  CRFlags::Filtered);
+    lcl_syncFlags(&rDocument, *maFilterData.mpHiddenCols, 
*maFilterData.mpHiddenRows,
+                  mpColFlags.get(), pRowFlags.get(), CRFlags::Hidden);
+    lcl_syncFlags(&rDocument, *maFilterData.mpFilteredCols, 
*maFilterData.mpFilteredRows,
+                  mpColFlags.get(), pRowFlags.get(), CRFlags::Filtered);
 }
 
 void ScTable::SetPageSize(const Size& rSize)
diff --git a/sc/source/core/data/table6.cxx b/sc/source/core/data/table6.cxx
index e6919485f0f4..970ae62e6467 100644
--- a/sc/source/core/data/table6.cxx
+++ b/sc/source/core/data/table6.cxx
@@ -281,7 +281,7 @@ void ScTable::SkipFilteredRows(SCROW& rRow, SCROW& 
rLastNonFilteredRow, bool bFo
             return;
 
         SCROW nLastRow = rRow;
-        if (RowFiltered(rRow, nullptr, &nLastRow))
+        if (getFilterData().rowFiltered(rRow, nullptr, &nLastRow))
             // move to the first non-filtered row.
             rRow = nLastRow + 1;
         else
@@ -297,7 +297,7 @@ void ScTable::SkipFilteredRows(SCROW& rRow, SCROW& 
rLastNonFilteredRow, bool bFo
             return;
 
         SCROW nFirstRow = rRow;
-        if (RowFiltered(rRow, &nFirstRow))
+        if (getFilterData().rowFiltered(rRow, &nFirstRow))
             // move to the first non-filtered row.
             rRow = nFirstRow - 1;
         else
@@ -1090,7 +1090,7 @@ bool ScTable::SearchRangeForAllEmptyCells(
             for (SCROW nRow = rRange.aStart.Row(); nRow <= nEndRow; ++nRow)
             {
                 SCROW nLastRow;
-                const bool bFiltered = RowFiltered(nRow, nullptr, &nLastRow);
+                const bool bFiltered = getFilterData().rowFiltered(nRow, 
nullptr, &nLastRow);
                 if (nLastRow > nEndRow)
                     nLastRow = nEndRow;
                 if (!bFiltered)
diff --git a/sc/source/core/data/table7.cxx b/sc/source/core/data/table7.cxx
index c41dcf9464a1..0f8cd8b06977 100644
--- a/sc/source/core/data/table7.cxx
+++ b/sc/source/core/data/table7.cxx
@@ -567,15 +567,15 @@ OString ScTable::dumpHiddenFiltered(bool bColumns, bool 
bHidden)
     if (bHidden)
     {
         if (bColumns)
-            return mpHiddenCols ? mpHiddenCols->dumpAsString() : 
aDefaultForCols;
+            return maFilterData.dumpHiddenColsAsString(aDefaultForCols);
 
-        return mpHiddenRows ? mpHiddenRows->dumpAsString() : aDefaultForRows;
+        return maFilterData.dumpHiddenRowsAsString(aDefaultForRows);
     }
 
     if (bColumns)
-        return mpFilteredCols ? mpFilteredCols->dumpAsString() : 
aDefaultForCols;
+        return maFilterData.dumpColsAsString(aDefaultForCols);
 
-    return mpFilteredRows ? mpFilteredRows->dumpAsString() : aDefaultForRows;
+    return maFilterData.dumpRowsAsString(aDefaultForRows);
 }
 
 OString ScTable::dumpColumnRowGroups(bool bColumns) const

Reply via email to