sc/inc/global.hxx | 2 sc/inc/subtotalparam.hxx | 77 ++++++--- sc/source/core/data/sortparam.cxx | 10 - sc/source/core/data/subtotalparam.cxx | 181 ++++------------------- sc/source/core/data/table3.cxx | 67 +++----- sc/source/core/tool/dbdata.cxx | 14 - sc/source/filter/xml/XMLExportDatabaseRanges.cxx | 14 - sc/source/filter/xml/xmldrani.cxx | 26 --- sc/source/ui/dbgui/tpsubt.cxx | 19 +- sc/source/ui/docshell/dbdocfun.cxx | 4 sc/source/ui/unoobj/cellsuno.cxx | 24 +-- sc/source/ui/unoobj/datauno.cxx | 102 +++--------- sc/source/ui/view/dbfunc.cxx | 2 sc/source/ui/view/dbfunc3.cxx | 2 14 files changed, 195 insertions(+), 349 deletions(-)
New commits: commit 669c839a61e2742a9128aabba30e2b55be517d21 Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Wed Nov 27 21:37:06 2024 +0500 Commit: Mike Kaganski <mike.kagan...@collabora.com> CommitDate: Thu Nov 28 05:36:59 2024 +0100 Simplify ScSubTotalParam Change-Id: I4c1840e377711ad065c3042bddacb2028481b88d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/177433 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> diff --git a/sc/inc/global.hxx b/sc/inc/global.hxx index fd51ff15808b..e37b2dbaef58 100644 --- a/sc/inc/global.hxx +++ b/sc/inc/global.hxx @@ -860,7 +860,7 @@ enum ScQueryConnect SC_OR }; -enum ScSubTotalFunc +enum ScSubTotalFunc : sal_Int16 { SUBTOTAL_FUNC_NONE = 0, SUBTOTAL_FUNC_AVE = 1, diff --git a/sc/inc/subtotalparam.hxx b/sc/inc/subtotalparam.hxx index 3b379edb167d..df9f5ef390e3 100644 --- a/sc/inc/subtotalparam.hxx +++ b/sc/inc/subtotalparam.hxx @@ -11,35 +11,60 @@ #include "global.hxx" #include <memory> +#include <span> + +namespace com::sun::star::sheet { struct SubTotalColumn; } +namespace com::sun::star::uno { template <class E> class Sequence; } struct SC_DLLPUBLIC ScSubTotalParam { - SCCOL nCol1; ///< selected area - SCROW nRow1; - SCCOL nCol2; - SCROW nRow2; - sal_uInt16 nUserIndex; ///< index into list - bool bRemoveOnly:1; - bool bReplace:1; ///< replace existing results - bool bPagebreak:1; ///< page break at change of group - bool bCaseSens:1; - bool bDoSort:1; ///< presort - bool bSummaryBelow:1; ///< Summary below or above (default: below) - bool bAscending:1; ///< sort ascending - bool bUserDef:1; ///< sort user defined - bool bIncludePattern:1; ///< sort formats - bool bGroupActive[MAXSUBTOTAL]; ///< active groups - SCCOL nField[MAXSUBTOTAL]; ///< associated field - SCCOL nSubTotals[MAXSUBTOTAL]; ///< number of SubTotals - std::unique_ptr<SCCOL[]> pSubTotals[MAXSUBTOTAL]; ///< array of columns to be calculated - std::unique_ptr<ScSubTotalFunc[]> pFunctions[MAXSUBTOTAL]; ///< array of associated functions - - ScSubTotalParam(); - ScSubTotalParam( const ScSubTotalParam& r ); - - ScSubTotalParam& operator= ( const ScSubTotalParam& r ); - bool operator== ( const ScSubTotalParam& r ) const; - void Clear(); + SCCOL nCol1 = 0; ///< selected area + SCROW nRow1 = 0; + SCCOL nCol2 = 0; + SCROW nRow2 = 0; + sal_uInt16 nUserIndex = 0; ///< index into list + bool bRemoveOnly:1 = false; + bool bReplace:1 = true; ///< replace existing results + bool bPagebreak:1 = false; ///< page break at change of group + bool bCaseSens:1 = false; + bool bDoSort:1 = true; ///< presort + bool bSummaryBelow:1 = true; ///< Summary below or above (default: below) + bool bAscending:1 = true; ///< sort ascending + bool bUserDef:1 = false; ///< sort user defined + bool bIncludePattern:1 = false; ///< sort formats + + struct SubtotalGroup + { + bool bActive = false; ///< active groups + SCCOL nField = 0; ///< associated field + SCCOL nSubTotals = 0; ///< number of SubTotals + + using Pair = std::pair<SCCOL, ScSubTotalFunc>; + // array of columns to be calculated, and associated functions + std::unique_ptr<Pair[]> pSubTotals; + + SubtotalGroup() = default; + SubtotalGroup(const SubtotalGroup& r); + + SubtotalGroup& operator=(const SubtotalGroup& r); + bool operator==(const SubtotalGroup& r) const; + + void AllocSubTotals(SCCOL n); + void SetSubtotals(const css::uno::Sequence<css::sheet::SubTotalColumn>& seq); + + std::span<Pair> subtotals() { return std::span(pSubTotals.get(), nSubTotals); } + std::span<const Pair> subtotals() const { return std::span(pSubTotals.get(), nSubTotals); } + SCCOL& col(SCCOL n) { return subtotals()[n].first; } + SCCOL col(SCCOL n) const { return subtotals()[n].first; } + ScSubTotalFunc func(SCCOL n) const { return subtotals()[n].second; } + }; + SubtotalGroup aGroups[MAXSUBTOTAL]; + + ScSubTotalParam() = default; + ScSubTotalParam(const ScSubTotalParam&) = default; + + ScSubTotalParam& operator=(const ScSubTotalParam&) = default; + inline bool operator==(const ScSubTotalParam&) const = default; void SetSubTotals( sal_uInt16 nGroup, const SCCOL* ptrSubTotals, const ScSubTotalFunc* ptrFunctions, diff --git a/sc/source/core/data/sortparam.cxx b/sc/source/core/data/sortparam.cxx index 37e44794a4df..868cf38a8df8 100644 --- a/sc/source/core/data/sortparam.cxx +++ b/sc/source/core/data/sortparam.cxx @@ -173,23 +173,21 @@ ScSortParam::ScSortParam( const ScSubTotalParam& rSub, const ScSortParam& rOld ) aDataAreaExtras.mbCellFormats = rSub.bIncludePattern; aDataAreaExtras.resetArea(); - sal_uInt16 i; - // first the groups from the partial results if (rSub.bDoSort) - for (i=0; i<MAXSUBTOTAL; i++) - if (rSub.bGroupActive[i]) + for (const auto& group : rSub.aGroups) + if (group.bActive) { ScSortKeyState key; key.bDoSort = true; - key.nField = rSub.nField[i]; + key.nField = group.nField; key.bAscending = rSub.bAscending; key.aColorSortMode = ScColorSortMode::None; maKeyState.push_back(key); } // then the old settings - for (i=0; i < rOld.GetSortKeyCount(); i++) + for (sal_uInt16 i = 0; i < rOld.GetSortKeyCount(); i++) if (rOld.maKeyState[i].bDoSort) { SCCOLROW nThisField = rOld.maKeyState[i].nField; diff --git a/sc/source/core/data/subtotalparam.cxx b/sc/source/core/data/subtotalparam.cxx index ae28606d3643..a056871be521 100644 --- a/sc/source/core/data/subtotalparam.cxx +++ b/sc/source/core/data/subtotalparam.cxx @@ -7,162 +7,65 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include <sal/config.h> + +#include <dputil.hxx> #include <subtotalparam.hxx> #include <osl/diagnose.h> -ScSubTotalParam::ScSubTotalParam() -{ - for ( sal_uInt16 i=0; i<MAXSUBTOTAL; i++ ) - { - nSubTotals[i] = 0; - pSubTotals[i] = nullptr; - pFunctions[i] = nullptr; - } +#include <com/sun/star/sheet/SubTotalColumn.hpp> +#include <com/sun/star/uno/Sequence.hxx> - Clear(); -} - -ScSubTotalParam::ScSubTotalParam( const ScSubTotalParam& r ) : - nCol1(r.nCol1),nRow1(r.nRow1),nCol2(r.nCol2),nRow2(r.nRow2),nUserIndex(r.nUserIndex), - bRemoveOnly(r.bRemoveOnly),bReplace(r.bReplace),bPagebreak(r.bPagebreak),bCaseSens(r.bCaseSens), - bDoSort(r.bDoSort), bSummaryBelow(r.bSummaryBelow), bAscending(r.bAscending), bUserDef(r.bUserDef), - bIncludePattern(r.bIncludePattern) +ScSubTotalParam::SubtotalGroup::SubtotalGroup(const SubtotalGroup& r) + : bActive(r.bActive) + , nField(r.nField) { - for (sal_uInt16 i=0; i<MAXSUBTOTAL; i++) + if (r.nSubTotals > 0) { - bGroupActive[i] = r.bGroupActive[i]; - nField[i] = r.nField[i]; - - if ( (r.nSubTotals[i] > 0) && r.pSubTotals[i] && r.pFunctions[i] ) - { - nSubTotals[i] = r.nSubTotals[i]; - pSubTotals[i].reset(new SCCOL [r.nSubTotals[i]]); - pFunctions[i].reset(new ScSubTotalFunc [r.nSubTotals[i]]); - - for (SCCOL j=0; j<r.nSubTotals[i]; j++) - { - pSubTotals[i][j] = r.pSubTotals[i][j]; - pFunctions[i][j] = r.pFunctions[i][j]; - } - } - else - { - nSubTotals[i] = 0; - } + assert(r.pSubTotals); + AllocSubTotals(r.nSubTotals); + std::copy_n(r.pSubTotals.get(), r.nSubTotals, pSubTotals.get()); } } -void ScSubTotalParam::Clear() +ScSubTotalParam::SubtotalGroup& ScSubTotalParam::SubtotalGroup::operator=(const SubtotalGroup& r) { - nCol1=nCol2= 0; - nRow1=nRow2 = 0; - nUserIndex = 0; - bPagebreak=bCaseSens=bUserDef=bIncludePattern=bRemoveOnly = false; - bAscending=bReplace=bDoSort=bSummaryBelow = true; + bActive = r.bActive; + nField = r.nField; - for (sal_uInt16 i=0; i<MAXSUBTOTAL; i++) + AllocSubTotals(r.nSubTotals); + if (r.nSubTotals > 0) { - bGroupActive[i] = false; - nField[i] = 0; - - if ( (nSubTotals[i] > 0) && pSubTotals[i] && pFunctions[i] ) - { - for ( SCCOL j=0; j<nSubTotals[i]; j++ ) { - pSubTotals[i][j] = 0; - pFunctions[i][j] = SUBTOTAL_FUNC_NONE; - } - } + assert(r.pSubTotals); + std::copy_n(r.pSubTotals.get(), r.nSubTotals, pSubTotals.get()); } + + return *this; } -ScSubTotalParam& ScSubTotalParam::operator=( const ScSubTotalParam& r ) +bool ScSubTotalParam::SubtotalGroup::operator==(const SubtotalGroup& r) const { - if(this == &r) - return *this; - - nCol1 = r.nCol1; - nRow1 = r.nRow1; - nCol2 = r.nCol2; - nRow2 = r.nRow2; - bRemoveOnly = r.bRemoveOnly; - bReplace = r.bReplace; - bPagebreak = r.bPagebreak; - bCaseSens = r.bCaseSens; - bDoSort = r.bDoSort; - bSummaryBelow = r.bSummaryBelow; - bAscending = r.bAscending; - bUserDef = r.bUserDef; - nUserIndex = r.nUserIndex; - bIncludePattern = r.bIncludePattern; - - for (sal_uInt16 i=0; i<MAXSUBTOTAL; i++) - { - bGroupActive[i] = r.bGroupActive[i]; - nField[i] = r.nField[i]; - nSubTotals[i] = r.nSubTotals[i]; - - pSubTotals[i].reset(); - pFunctions[i].reset(); - - if ( r.nSubTotals[i] > 0 ) - { - pSubTotals[i].reset(new SCCOL [r.nSubTotals[i]]); - pFunctions[i].reset(new ScSubTotalFunc [r.nSubTotals[i]]); - - for (SCCOL j=0; j<r.nSubTotals[i]; j++) - { - pSubTotals[i][j] = r.pSubTotals[i][j]; - pFunctions[i][j] = r.pFunctions[i][j]; - } - } - else - { - nSubTotals[i] = 0; - } - } - - return *this; + return bActive == r.bActive && nField == r.nField && nSubTotals == r.nSubTotals + && (!nSubTotals + || std::equal(pSubTotals.get(), pSubTotals.get() + nSubTotals, r.pSubTotals.get())); } -bool ScSubTotalParam::operator==( const ScSubTotalParam& rOther ) const +void ScSubTotalParam::SubtotalGroup::AllocSubTotals(SCCOL n) { - bool bEqual = (nCol1 == rOther.nCol1) - && (nRow1 == rOther.nRow1) - && (nCol2 == rOther.nCol2) - && (nRow2 == rOther.nRow2) - && (nUserIndex == rOther.nUserIndex) - && (bRemoveOnly == rOther.bRemoveOnly) - && (bReplace == rOther.bReplace) - && (bPagebreak == rOther.bPagebreak) - && (bDoSort == rOther.bDoSort) - && (bSummaryBelow == rOther.bSummaryBelow) - && (bCaseSens == rOther.bCaseSens) - && (bAscending == rOther.bAscending) - && (bUserDef == rOther.bUserDef) - && (bIncludePattern== rOther.bIncludePattern); - - if ( bEqual ) + if (nSubTotals != n) { - bEqual = true; - for ( sal_uInt16 i=0; i<MAXSUBTOTAL && bEqual; i++ ) - { - bEqual = (bGroupActive[i] == rOther.bGroupActive[i]) - && (nField[i] == rOther.nField[i]) - && (nSubTotals[i] == rOther.nSubTotals[i]); - - if ( bEqual && (nSubTotals[i] > 0) ) - { - for (SCCOL j=0; (j<nSubTotals[i]) && bEqual; j++) - { - bEqual = pSubTotals[i][j] == rOther.pSubTotals[i][j] - && pFunctions[i][j] == rOther.pFunctions[i][j]; - } - } - } + nSubTotals = std::max(n, SCCOL(0)); + pSubTotals.reset(nSubTotals ? new std::pair<SCCOL, ScSubTotalFunc>[nSubTotals] : nullptr); } +} - return bEqual; +void ScSubTotalParam::SubtotalGroup::SetSubtotals(const css::uno::Sequence<css::sheet::SubTotalColumn>& seq) +{ + AllocSubTotals(seq.getLength()); + for (SCCOL i = 0; i < nSubTotals; ++i) + pSubTotals[i] = { seq[i].Column, + ScDPUtil::toSubTotalFunc(static_cast<ScGeneralFunction>(seq[i].Function)) }; } void ScSubTotalParam::SetSubTotals( sal_uInt16 nGroup, @@ -177,7 +80,7 @@ void ScSubTotalParam::SetSubTotals( sal_uInt16 nGroup, OSL_ENSURE( ptrFunctions, "ScSubTotalParam::SetSubTotals(): ptrFunctions == NULL!" ); OSL_ENSURE( (nCount > 0), - "ScSubTotalParam::SetSubTotals(): nCount <= 0!" ); + "ScSubTotalParam::SetSubTotals(): nCount == 0!" ); if ( !(ptrSubTotals && ptrFunctions && (nCount > 0) && (nGroup <= MAXSUBTOTAL)) ) return; @@ -186,15 +89,9 @@ void ScSubTotalParam::SetSubTotals( sal_uInt16 nGroup, if (nGroup != 0) nGroup--; - pSubTotals[nGroup].reset(new SCCOL[nCount]); - pFunctions[nGroup].reset(new ScSubTotalFunc[nCount]); - nSubTotals[nGroup] = static_cast<SCCOL>(nCount); - + aGroups[nGroup].AllocSubTotals(nCount); for ( sal_uInt16 i=0; i<nCount; i++ ) - { - pSubTotals[nGroup][i] = ptrSubTotals[i]; - pFunctions[nGroup][i] = ptrFunctions[i]; - } + aGroups[nGroup].pSubTotals[i] = { ptrSubTotals[i], ptrFunctions[i] }; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx index fed72506c2a3..f5b66a250ea7 100644 --- a/sc/source/core/data/table3.cxx +++ b/sc/source/core/data/table3.cxx @@ -1947,7 +1947,7 @@ struct RowEntry } -static TranslateId lcl_GetSubTotalStrId(int id) +static TranslateId lcl_GetSubTotalStrId(ScSubTotalFunc id) { switch ( id ) { @@ -1971,7 +1971,7 @@ static TranslateId lcl_GetSubTotalStrId(int id) } // Gets the string used for "Grand" results -static TranslateId lcl_GetGrandSubTotalStrId(int id) +static TranslateId lcl_GetGrandSubTotalStrId(ScSubTotalFunc id) { switch ( id ) { @@ -2011,20 +2011,16 @@ bool ScTable::DoSubTotals( ScSubTotalParam& rParam ) nEndRow -= nEmpty; sal_uInt16 nLevelCount = 0; // Number of levels - bool bDoThis = true; - for (sal_uInt16 i = 0; i < MAXSUBTOTAL && bDoThis; ++i) + for (const auto& group : rParam.aGroups) { - if (rParam.bGroupActive[i]) - nLevelCount = o3tl::sanitizing_inc(i); - else - bDoThis = false; + if (!group.bActive) + break; + ++nLevelCount; } if (nLevelCount==0) // do nothing return true; - SCCOL* nGroupCol = rParam.nField; // columns which will be used when grouping - // With (blank) as a separate category, subtotal rows from // the other columns must always be tested // (previously only when a column occurred more than once) @@ -2053,17 +2049,16 @@ bool ScTable::DoSubTotals( ScSubTotalParam& rParam ) { aRowEntry.nGroupNo = nLevelCount - nLevel - 1; + const auto& group = rParam.aGroups[aRowEntry.nGroupNo]; // how many results per level - SCCOL nResCount = rParam.nSubTotals[aRowEntry.nGroupNo]; - // result functions - ScSubTotalFunc* pResFunc = rParam.pFunctions[aRowEntry.nGroupNo].get(); + SCCOL nResCount = group.nSubTotals; if (nResCount > 0) // otherwise only sort { SCROW nAboveRows = rParam.bSummaryBelow ? nStartRow : nStartRow + nLevel; for (sal_uInt16 i = 0; i <= aRowEntry.nGroupNo; ++i) { - aSubString = GetString( nGroupCol[i], nAboveRows ); + aSubString = GetString(rParam.aGroups[i].nField, nAboveRows); if ( bIgnoreCase ) aCompString[i] = ScGlobal::getCharClass().uppercase( aSubString ); else @@ -2083,7 +2078,7 @@ bool ScTable::DoSubTotals( ScSubTotalParam& rParam ) OUString aString; for (sal_uInt16 i = 0; i <= aRowEntry.nGroupNo && !bChanged; ++i) { - aString = GetString( nGroupCol[i], nRow ); + aString = GetString(rParam.aGroups[i].nField, nRow); if (bIgnoreCase) aString = ScGlobal::getCharClass().uppercase(aString); // when sorting, blanks are separate group @@ -2145,17 +2140,17 @@ bool ScTable::DoSubTotals( ScSubTotalParam& rParam ) aOutString += " "; TranslateId pStrId = STR_TABLE_ERGEBNIS; if ( nResCount == 1 ) - pStrId = lcl_GetSubTotalStrId(pResFunc[0]); + pStrId = lcl_GetSubTotalStrId(group.func(0)); aOutString += ScResId(pStrId); - SetString( nGroupCol[aRowEntry.nGroupNo], aRowEntry.nDestRow, nTab, aOutString ); - ApplyStyle( nGroupCol[aRowEntry.nGroupNo], aRowEntry.nDestRow, pStyle ); + SetString(group.nField, aRowEntry.nDestRow, nTab, aOutString); + ApplyStyle(group.nField, aRowEntry.nDestRow, pStyle); ++nRow; ++nEndRow; aRowEntry.nSubStartRow = nRow; for (sal_uInt16 i = 0; i <= aRowEntry.nGroupNo; ++i) { - aSubString = GetString( nGroupCol[i], nRow ); + aSubString = GetString(rParam.aGroups[i].nField, nRow); if ( bIgnoreCase ) aCompString[i] = ScGlobal::getCharClass().uppercase( aSubString ); else @@ -2194,21 +2189,21 @@ bool ScTable::DoSubTotals( ScSubTotalParam& rParam ) for (sal_uInt16 nLevel = 0; nLevel<nLevelCount; nLevel++) { const sal_uInt16 nGroupNo = nLevelCount - nLevel - 1; - const ScSubTotalFunc* pResFunc = rParam.pFunctions[nGroupNo].get(); - if (!pResFunc) + const auto& group = rParam.aGroups[nGroupNo]; + if (!group.nSubTotals) { // No subtotal function given for this group => no formula or // label and do not insert a row. continue; } + aRowEntry.nGroupNo = nGroupNo; if (rParam.bSummaryBelow) { // increment end row nGlobalEndRow++; // add row entry for formula - aRowEntry.nGroupNo = nGroupNo; aRowEntry.nSubStartRow = nGlobalStartRow; aRowEntry.nFuncStart = nGlobalStartFunc; aRowEntry.nDestRow = nGlobalEndRow; @@ -2220,7 +2215,6 @@ bool ScTable::DoSubTotals( ScSubTotalParam& rParam ) else { // if we have Global summary we need to shift summary rows down - aRowEntry.nGroupNo = nGroupNo; aRowEntry.nSubStartRow = nGlobalStartRow - nGroupNo - 1; aRowEntry.nFuncStart = nGlobalStartFunc - nGroupNo - 1; aRowEntry.nDestRow = nGlobalStartRow - nGroupNo - 1; @@ -2236,9 +2230,9 @@ bool ScTable::DoSubTotals( ScSubTotalParam& rParam ) DBShowRow(aRowEntry.nDestRow, true); // insert label - OUString label = ScResId(lcl_GetGrandSubTotalStrId(pResFunc[0])); - SetString(nGroupCol[aRowEntry.nGroupNo], aRowEntry.nDestRow, nTab, label); - ApplyStyle(nGroupCol[aRowEntry.nGroupNo], aRowEntry.nDestRow, pStyle); + OUString label = ScResId(lcl_GetGrandSubTotalStrId(group.func(0))); + SetString(group.nField, aRowEntry.nDestRow, nTab, label); + ApplyStyle(group.nField, aRowEntry.nDestRow, pStyle); } } } @@ -2250,35 +2244,34 @@ bool ScTable::DoSubTotals( ScSubTotalParam& rParam ) aRef.Ref2.SetAbsTab(nTab); for (const auto& rRowEntry : aRowVector) { - SCCOL nResCount = rParam.nSubTotals[rRowEntry.nGroupNo]; - SCCOL* nResCols = rParam.pSubTotals[rRowEntry.nGroupNo].get(); - ScSubTotalFunc* pResFunc = rParam.pFunctions[rRowEntry.nGroupNo].get(); + const auto& group = rParam.aGroups[rRowEntry.nGroupNo]; + SCCOL nResCount = group.nSubTotals; for ( SCCOL nResult=0; nResult < nResCount; ++nResult ) { - aRef.Ref1.SetAbsCol(nResCols[nResult]); + aRef.Ref1.SetAbsCol(group.col(nResult)); aRef.Ref1.SetAbsRow(rRowEntry.nFuncStart); - aRef.Ref2.SetAbsCol(nResCols[nResult]); + aRef.Ref2.SetAbsCol(group.col(nResult)); aRef.Ref2.SetAbsRow(rRowEntry.nFuncEnd); ScTokenArray aArr(rDocument); aArr.AddOpCode( ocSubTotal ); aArr.AddOpCode( ocOpen ); - aArr.AddDouble( static_cast<double>(pResFunc[nResult]) ); + aArr.AddDouble( static_cast<double>(group.func(nResult)) ); aArr.AddOpCode( ocSep ); aArr.AddDoubleReference( aRef ); aArr.AddOpCode( ocClose ); aArr.AddOpCode( ocStop ); ScFormulaCell* pCell = new ScFormulaCell( - rDocument, ScAddress(nResCols[nResult], rRowEntry.nDestRow, nTab), aArr); + rDocument, ScAddress(group.col(nResult), rRowEntry.nDestRow, nTab), aArr); if ( rParam.bIncludePattern ) pCell->SetNeedNumberFormat(true); - SetFormulaCell(nResCols[nResult], rRowEntry.nDestRow, pCell); - if ( nResCols[nResult] != nGroupCol[rRowEntry.nGroupNo] ) + SetFormulaCell(group.col(nResult), rRowEntry.nDestRow, pCell); + if (group.col(nResult) != group.nField) { - ApplyStyle( nResCols[nResult], rRowEntry.nDestRow, pStyle ); + ApplyStyle(group.col(nResult), rRowEntry.nDestRow, pStyle); - lcl_RemoveNumberFormat( this, nResCols[nResult], rRowEntry.nDestRow ); + lcl_RemoveNumberFormat(this, group.col(nResult), rRowEntry.nDestRow); } } diff --git a/sc/source/core/tool/dbdata.cxx b/sc/source/core/tool/dbdata.cxx index 563ca6058465..b719cb056221 100644 --- a/sc/source/core/tool/dbdata.cxx +++ b/sc/source/core/tool/dbdata.cxx @@ -276,7 +276,7 @@ OUString ScDBData::GetOperations() const aBuf.append(ScResId(STR_OPERATION_SORT)); } - if (mpSubTotal->bGroupActive[0] && !mpSubTotal->bRemoveOnly) + if (mpSubTotal->aGroups[0].bActive && !mpSubTotal->bRemoveOnly) { if (!aBuf.isEmpty()) aBuf.append(", "); @@ -377,13 +377,13 @@ void ScDBData::MoveTo(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW n rEntry.bDoQuery = false; } } - for (sal_uInt16 i=0; i<MAXSUBTOTAL; i++) + for (auto& group : mpSubTotal->aGroups) { - mpSubTotal->nField[i] = sal::static_int_cast<SCCOL>( mpSubTotal->nField[i] + nDifX ); - if (mpSubTotal->nField[i] > nCol2) + group.nField += nDifX; + if (group.nField > nCol2) { - mpSubTotal->nField[i] = 0; - mpSubTotal->bGroupActive[i] = false; + group.nField = 0; + group.bActive = false; } } @@ -533,7 +533,7 @@ bool ScDBData::HasSortParam() const bool ScDBData::HasSubTotalParam() const { - return mpSubTotal && mpSubTotal->bGroupActive[0]; + return mpSubTotal && mpSubTotal->aGroups[0].bActive; } void ScDBData::UpdateMoveTab(SCTAB nOldPos, SCTAB nNewPos) diff --git a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx index d1817bc4ddc5..5deb8978da66 100644 --- a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx +++ b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx @@ -642,7 +642,7 @@ private: size_t nCount = 0; for (; nCount < MAXSUBTOTAL; ++nCount) { - if (!aParam.bGroupActive[nCount]) + if (!aParam.aGroups[nCount].bActive) break; } @@ -676,20 +676,20 @@ private: SvXMLElementExport aElemSGs(mrExport, XML_NAMESPACE_TABLE, XML_SORT_GROUPS, true, true); } - for (size_t i = 0; i < MAXSUBTOTAL; ++i) + for (auto& group : aParam.aGroups) { - if (!aParam.bGroupActive[i]) + if (!group.bActive) // We're done! break; - sal_Int32 nFieldCol = static_cast<sal_Int32>(aParam.nField[i]); + sal_Int32 nFieldCol = static_cast<sal_Int32>(group.nField); mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_GROUP_BY_FIELD_NUMBER, OUString::number(nFieldCol)); SvXMLElementExport aElemSTR(mrExport, XML_NAMESPACE_TABLE, XML_SUBTOTAL_RULE, true, true); - for (SCCOL j = 0, n = aParam.nSubTotals[i]; j < n; ++j) + for (SCCOL j = 0, n = group.nSubTotals; j < n; ++j) { - sal_Int32 nCol = static_cast<sal_Int32>(aParam.pSubTotals[i][j]); - ScSubTotalFunc eFunc = aParam.pFunctions[i][j]; + sal_Int32 nCol = static_cast<sal_Int32>(group.col(j)); + ScSubTotalFunc eFunc = group.func(j); mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, OUString::number(nCol)); OUString aFuncStr = ScXMLConverter::GetStringFromFunction(eFunc); diff --git a/sc/source/filter/xml/xmldrani.cxx b/sc/source/filter/xml/xmldrani.cxx index cce484918d21..8a91e8d44959 100644 --- a/sc/source/filter/xml/xmldrani.cxx +++ b/sc/source/filter/xml/xmldrani.cxx @@ -343,32 +343,14 @@ std::unique_ptr<ScDBData> ScXMLDatabaseRangeContext::ConvertToDBData(const OUStr { if (nPos >= MAXSUBTOTAL) break; + auto& group = aParam.aGroups[nPos]; const uno::Sequence<sheet::SubTotalColumn>& rColumns = rSubTotalRule.aSubTotalColumns; - sal_Int32 nColCount = rColumns.getLength(); sal_Int16 nGroupColumn = rSubTotalRule.nSubTotalRuleGroupFieldNumber; - aParam.bGroupActive[nPos] = true; - aParam.nField[nPos] = static_cast<SCCOL>(nGroupColumn); + group.bActive = true; + group.nField = static_cast<SCCOL>(nGroupColumn); - SCCOL nCount = static_cast<SCCOL>(nColCount); - aParam.nSubTotals[nPos] = nCount; - if (nCount != 0) - { - aParam.pSubTotals[nPos].reset(new SCCOL[nCount]); - aParam.pFunctions[nPos].reset(new ScSubTotalFunc[nCount]); - - const sheet::SubTotalColumn* pAry = rColumns.getConstArray(); - for (SCCOL i = 0; i < nCount; ++i) - { - aParam.pSubTotals[nPos][i] = static_cast<SCCOL>(pAry[i].Column); - aParam.pFunctions[nPos][i] = ScDPUtil::toSubTotalFunc(static_cast<ScGeneralFunction>(pAry[i].Function)); - } - } - else - { - aParam.pSubTotals[nPos].reset(); - aParam.pFunctions[nPos].reset(); - } + group.SetSubtotals(rColumns); ++nPos; } diff --git a/sc/source/ui/dbgui/tpsubt.cxx b/sc/source/ui/dbgui/tpsubt.cxx index e0fcf640f756..f911292c08f7 100644 --- a/sc/source/ui/dbgui/tpsubt.cxx +++ b/sc/source/ui/dbgui/tpsubt.cxx @@ -130,22 +130,19 @@ bool ScTpSubTotalGroup::DoReset( sal_uInt16 nGroupNo, const ScSubTotalParam & theSubTotalData( rArgSet.Get( nWhichSubTotals ).GetSubTotalData() ); - if ( theSubTotalData.bGroupActive[nGroupIdx] ) + if (theSubTotalData.aGroups[nGroupIdx].bActive) { - SCCOL nField = theSubTotalData.nField[nGroupIdx]; - SCCOL nSubTotals = theSubTotalData.nSubTotals[nGroupIdx]; - SCCOL* pSubTotals = theSubTotalData.pSubTotals[nGroupIdx].get(); - ScSubTotalFunc* pFunctions = theSubTotalData.pFunctions[nGroupIdx].get(); + const auto& group = theSubTotalData.aGroups[nGroupIdx]; - mxLbGroup->set_active( GetFieldSelPos( nField )+1 ); + mxLbGroup->set_active(GetFieldSelPos(group.nField) + 1); sal_uInt16 nFirstChecked = 0; - for ( sal_uInt16 i=0; i<nSubTotals; i++ ) + for (sal_uInt16 i = 0; i < group.nSubTotals; i++) { - sal_uInt16 nCheckPos = GetFieldSelPos( pSubTotals[i] ); + sal_uInt16 nCheckPos = GetFieldSelPos(group.col(i)); mxLbColumns->set_toggle(nCheckPos, TRISTATE_TRUE); - mxLbColumns->set_id(nCheckPos, OUString::number(FuncToLbPos(pFunctions[i]))); + mxLbColumns->set_id(nCheckPos, OUString::number(FuncToLbPos(group.func(i)))); if (i == 0 || nCheckPos < nFirstChecked) nFirstChecked = nCheckPos; @@ -206,8 +203,8 @@ bool ScTpSubTotalGroup::DoFillItemSet( sal_uInt16 nGroupNo, theSubTotalData.nRow1 = rSubTotalData.nRow1; theSubTotalData.nCol2 = rSubTotalData.nCol2; theSubTotalData.nRow2 = rSubTotalData.nRow2; - theSubTotalData.bGroupActive[nGroupIdx] = (nGroup != 0); - theSubTotalData.nField[nGroupIdx] = (nGroup != 0) + theSubTotalData.aGroups[nGroupIdx].bActive = (nGroup != 0); + theSubTotalData.aGroups[nGroupIdx].nField = (nGroup != 0) ? mnFieldArr[nGroup-1] : static_cast<SCCOL>(0); diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx index 357ad17417e6..bf6dd852614d 100644 --- a/sc/source/ui/docshell/dbdocfun.cxx +++ b/sc/source/ui/docshell/dbdocfun.cxx @@ -313,7 +313,7 @@ bool ScDBDocFunc::RepeatDB( const OUString& rDBName, bool bApi, bool bIsUnnamed, ScSubTotalParam aSubTotalParam; pDBData->GetSubTotalParam( aSubTotalParam ); - bool bSubTotal = aSubTotalParam.bGroupActive[0] && !aSubTotalParam.bRemoveOnly; + bool bSubTotal = aSubTotalParam.aGroups[0].bActive && !aSubTotalParam.bRemoveOnly; if ( bQuery || bSort || bSubTotal ) { @@ -796,7 +796,7 @@ bool ScDBDocFunc::Query( SCTAB nTab, const ScQueryParam& rQueryParam, ScSubTotalParam aSubTotalParam; pDBData->GetSubTotalParam( aSubTotalParam ); // partial results exist? - if ( aSubTotalParam.bGroupActive[0] && !aSubTotalParam.bRemoveOnly ) + if (aSubTotalParam.aGroups[0].bActive && !aSubTotalParam.bRemoveOnly) bKeepSub = true; } diff --git a/sc/source/ui/unoobj/cellsuno.cxx b/sc/source/ui/unoobj/cellsuno.cxx index 384671ea0d99..29f437e77529 100644 --- a/sc/source/ui/unoobj/cellsuno.cxx +++ b/sc/source/ui/unoobj/cellsuno.cxx @@ -5470,15 +5470,15 @@ uno::Reference<sheet::XSubTotalDescriptor> SAL_CALL ScCellRangeObj::createSubTot ScRange aDBRange; pData->GetArea(aDBRange); SCCOL nFieldStart = aDBRange.aStart.Col(); - for (sal_uInt16 i=0; i<MAXSUBTOTAL; i++) + for (auto& group : aParam.aGroups) { - if ( aParam.bGroupActive[i] ) + if (group.bActive) { - if ( aParam.nField[i] >= nFieldStart ) - aParam.nField[i] = sal::static_int_cast<SCCOL>( aParam.nField[i] - nFieldStart ); - for (SCCOL j=0; j<aParam.nSubTotals[i]; j++) - if ( aParam.pSubTotals[i][j] >= nFieldStart ) - aParam.pSubTotals[i][j] = sal::static_int_cast<SCCOL>( aParam.pSubTotals[i][j] - nFieldStart ); + if (group.nField >= nFieldStart) + group.nField -= nFieldStart; + for (SCCOL j = 0; j < group.nSubTotals; j++) + if (group.col(j) >= nFieldStart) + group.col(j) -= nFieldStart; } } pNew->SetParam(aParam); @@ -5507,13 +5507,13 @@ void SAL_CALL ScCellRangeObj::applySubTotals( // SubTotalDescriptor contains the counted fields inside the area SCCOL nFieldStart = aRange.aStart.Col(); - for (sal_uInt16 i=0; i<MAXSUBTOTAL; i++) + for (auto& group : aParam.aGroups) { - if ( aParam.bGroupActive[i] ) + if (group.bActive) { - aParam.nField[i] = sal::static_int_cast<SCCOL>( aParam.nField[i] + nFieldStart ); - for (SCCOL j=0; j<aParam.nSubTotals[i]; j++) - aParam.pSubTotals[i][j] = sal::static_int_cast<SCCOL>( aParam.pSubTotals[i][j] + nFieldStart ); + group.nField += nFieldStart; + for (SCCOL j = 0; j < group.nSubTotals; j++) + group.col(j) += nFieldStart; } } diff --git a/sc/source/ui/unoobj/datauno.cxx b/sc/source/ui/unoobj/datauno.cxx index db8946232706..99cb53d48222 100644 --- a/sc/source/ui/unoobj/datauno.cxx +++ b/sc/source/ui/unoobj/datauno.cxx @@ -459,7 +459,7 @@ sal_Int32 SAL_CALL ScSubTotalFieldObj::getGroupColumn() ScSubTotalParam aParam; xParent->GetData(aParam); - return aParam.nField[nPos]; + return aParam.aGroups[nPos].nField; } void SAL_CALL ScSubTotalFieldObj::setGroupColumn( sal_Int32 nGroupColumn ) @@ -468,7 +468,7 @@ void SAL_CALL ScSubTotalFieldObj::setGroupColumn( sal_Int32 nGroupColumn ) ScSubTotalParam aParam; xParent->GetData(aParam); - aParam.nField[nPos] = static_cast<SCCOL>(nGroupColumn); + aParam.aGroups[nPos].nField = static_cast<SCCOL>(nGroupColumn); xParent->PutData(aParam); } @@ -479,14 +479,13 @@ uno::Sequence<sheet::SubTotalColumn> SAL_CALL ScSubTotalFieldObj::getSubTotalCol ScSubTotalParam aParam; xParent->GetData(aParam); - SCCOL nCount = aParam.nSubTotals[nPos]; + SCCOL nCount = aParam.aGroups[nPos].nSubTotals; uno::Sequence<sheet::SubTotalColumn> aSeq(nCount); sheet::SubTotalColumn* pAry = aSeq.getArray(); for (SCCOL i=0; i<nCount; i++) { - pAry[i].Column = aParam.pSubTotals[nPos][i]; - pAry[i].Function = ScDataUnoConversion::SubTotalToGeneral( - aParam.pFunctions[nPos][i] ); + pAry[i].Column = aParam.aGroups[nPos].col(i); + pAry[i].Function = ScDataUnoConversion::SubTotalToGeneral(aParam.aGroups[nPos].func(i)); } return aSeq; } @@ -498,29 +497,8 @@ void SAL_CALL ScSubTotalFieldObj::setSubTotalColumns( ScSubTotalParam aParam; xParent->GetData(aParam); - sal_uInt32 nColCount = aSubTotalColumns.getLength(); - if ( nColCount <= sal::static_int_cast<sal_uInt32>(SCCOL_MAX) ) - { - SCCOL nCount = static_cast<SCCOL>(nColCount); - aParam.nSubTotals[nPos] = nCount; - if (nCount != 0) - { - aParam.pSubTotals[nPos].reset(new SCCOL[nCount]); - aParam.pFunctions[nPos].reset(new ScSubTotalFunc[nCount]); - - const sheet::SubTotalColumn* pAry = aSubTotalColumns.getConstArray(); - for (SCCOL i=0; i<nCount; i++) - { - aParam.pSubTotals[nPos][i] = static_cast<SCCOL>(pAry[i].Column); - aParam.pFunctions[nPos][i] = ScDPUtil::toSubTotalFunc(static_cast<ScGeneralFunction>(pAry[i].Function)); - } - } - else - { - aParam.pSubTotals[nPos].reset(); - aParam.pFunctions[nPos].reset(); - } - } + if (aSubTotalColumns.getLength() <= SCCOL_MAX) + aParam.aGroups[nPos].SetSubtotals(aSubTotalColumns); //! otherwise exception or so? (too many columns) xParent->PutData(aParam); @@ -550,8 +528,8 @@ void SAL_CALL ScSubTotalDescriptorBase::clear() ScSubTotalParam aParam; GetData(aParam); - for (bool & rn : aParam.bGroupActive) - rn = false; + for (auto& group : aParam.aGroups) + group.bActive = false; //! notify the field objects??? @@ -567,40 +545,17 @@ void SAL_CALL ScSubTotalDescriptorBase::addNew( GetData(aParam); sal_uInt16 nPos = 0; - while ( nPos < MAXSUBTOTAL && aParam.bGroupActive[nPos] ) + while (nPos < MAXSUBTOTAL && aParam.aGroups[nPos].bActive) ++nPos; - sal_uInt32 nColCount = aSubTotalColumns.getLength(); - - if ( nPos >= MAXSUBTOTAL || nColCount > sal::static_int_cast<sal_uInt32>(SCCOL_MAX) ) + if (nPos >= MAXSUBTOTAL || aSubTotalColumns.getLength() > SCCOL_MAX) // too many fields / columns throw uno::RuntimeException(); // no other exceptions specified + auto& group = aParam.aGroups[nPos]; - aParam.bGroupActive[nPos] = true; - aParam.nField[nPos] = static_cast<SCCOL>(nGroupColumn); - - aParam.pSubTotals[nPos].reset(); - aParam.pFunctions[nPos].reset(); - - SCCOL nCount = static_cast<SCCOL>(nColCount); - aParam.nSubTotals[nPos] = nCount; - if (nCount != 0) - { - aParam.pSubTotals[nPos].reset(new SCCOL[nCount]); - aParam.pFunctions[nPos].reset(new ScSubTotalFunc[nCount]); - - const sheet::SubTotalColumn* pAry = aSubTotalColumns.getConstArray(); - for (SCCOL i=0; i<nCount; i++) - { - aParam.pSubTotals[nPos][i] = static_cast<SCCOL>(pAry[i].Column); - aParam.pFunctions[nPos][i] = ScDPUtil::toSubTotalFunc(static_cast<ScGeneralFunction>(pAry[i].Function)); - } - } - else - { - aParam.pSubTotals[nPos].reset(); - aParam.pFunctions[nPos].reset(); - } + group.bActive = true; + group.nField = static_cast<SCCOL>(nGroupColumn); + group.SetSubtotals(aSubTotalColumns); PutData(aParam); } @@ -624,7 +579,7 @@ sal_Int32 SAL_CALL ScSubTotalDescriptorBase::getCount() GetData(aParam); sal_uInt16 nCount = 0; - while ( nCount < MAXSUBTOTAL && aParam.bGroupActive[nCount] ) + while ( nCount < MAXSUBTOTAL && aParam.aGroups[nCount].bActive ) ++nCount; return nCount; } @@ -1770,16 +1725,15 @@ void ScDatabaseRangeObj::GetSubTotalParam(ScSubTotalParam& rSubTotalParam) const ScRange aDBRange; pData->GetArea(aDBRange); SCCOL nFieldStart = aDBRange.aStart.Col(); - for (sal_uInt16 i=0; i<MAXSUBTOTAL; i++) + for (auto& group : rSubTotalParam.aGroups) { - if ( rSubTotalParam.bGroupActive[i] ) + if (group.bActive) { - if ( rSubTotalParam.nField[i] >= nFieldStart ) - rSubTotalParam.nField[i] = sal::static_int_cast<SCCOL>( rSubTotalParam.nField[i] - nFieldStart ); - for (SCCOL j=0; j<rSubTotalParam.nSubTotals[i]; j++) - if ( rSubTotalParam.pSubTotals[i][j] >= nFieldStart ) - rSubTotalParam.pSubTotals[i][j] = - sal::static_int_cast<SCCOL>( rSubTotalParam.pSubTotals[i][j] - nFieldStart ); + if (group.nField >= nFieldStart) + group.nField -= nFieldStart; + for (SCCOL j = 0; j < group.nSubTotals; j++) + if (group.col(j) >= nFieldStart) + group.col(j) -= nFieldStart; } } } @@ -1795,13 +1749,13 @@ void ScDatabaseRangeObj::SetSubTotalParam(const ScSubTotalParam& rSubTotalParam) ScRange aDBRange; pData->GetArea(aDBRange); SCCOL nFieldStart = aDBRange.aStart.Col(); - for (sal_uInt16 i=0; i<MAXSUBTOTAL; i++) + for (auto& group : aParam.aGroups) { - if ( aParam.bGroupActive[i] ) + if (group.bActive) { - aParam.nField[i] = sal::static_int_cast<SCCOL>( aParam.nField[i] + nFieldStart ); - for (SCCOL j=0; j<aParam.nSubTotals[i]; j++) - aParam.pSubTotals[i][j] = sal::static_int_cast<SCCOL>( aParam.pSubTotals[i][j] + nFieldStart ); + group.nField += nFieldStart; + for (SCCOL j = 0; j < group.nSubTotals; j++) + group.col(j) += nFieldStart; } } diff --git a/sc/source/ui/view/dbfunc.cxx b/sc/source/ui/view/dbfunc.cxx index 5f5a0621c9f6..0123cbf648f7 100644 --- a/sc/source/ui/view/dbfunc.cxx +++ b/sc/source/ui/view/dbfunc.cxx @@ -198,7 +198,7 @@ void ScDBFunc::UISort( const ScSortParam& rSortParam ) ScSubTotalParam aSubTotalParam; pDBData->GetSubTotalParam( aSubTotalParam ); - if (aSubTotalParam.bGroupActive[0] && !aSubTotalParam.bRemoveOnly) + if (aSubTotalParam.aGroups[0].bActive && !aSubTotalParam.bRemoveOnly) { // repeat subtotals, with new sortorder diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx index 7a2ba764a3e1..515a99add718 100644 --- a/sc/source/ui/view/dbfunc3.cxx +++ b/sc/source/ui/view/dbfunc3.cxx @@ -2123,7 +2123,7 @@ void ScDBFunc::RepeatDB( bool bRecord ) ScSubTotalParam aSubTotalParam; pDBData->GetSubTotalParam( aSubTotalParam ); - bool bSubTotal = aSubTotalParam.bGroupActive[0] && !aSubTotalParam.bRemoveOnly; + bool bSubTotal = aSubTotalParam.aGroups[0].bActive && !aSubTotalParam.bRemoveOnly; if ( bQuery || bSort || bSubTotal ) {