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
