diff options
author | Tomaž Vajngerl <quikee@gmail.com> | 2013-11-07 23:06:26 +0100 |
---|---|---|
committer | Tomaž Vajngerl <quikee@gmail.com> | 2013-11-11 23:22:32 +0100 |
commit | f4569ff5ee721683c6ba09b75fe0ce14e3203d3a (patch) | |
tree | f26ae6f65fc350907077460fa732071c7d715f37 /sc/source/ui | |
parent | 2f823d458de726d8e8f7c3684e3b1f15d0104e27 (diff) |
Iterators for data ranges and data cells.
This is needed to make data and iteration independent from the
data orientation (either columns or rows).
Change-Id: I03d0fca939ba9b051832668d229e4961c097add6
Diffstat (limited to 'sc/source/ui')
5 files changed, 230 insertions, 39 deletions
diff --git a/sc/source/ui/StatisticsDialogs/AnalysisOfVarianceDialog.cxx b/sc/source/ui/StatisticsDialogs/AnalysisOfVarianceDialog.cxx index 7709c5d6422d..4257165e6e5d 100644 --- a/sc/source/ui/StatisticsDialogs/AnalysisOfVarianceDialog.cxx +++ b/sc/source/ui/StatisticsDialogs/AnalysisOfVarianceDialog.cxx @@ -45,9 +45,10 @@ static const char* lclAnovaLabels[] = "Source of Variation", "SS", "df", "MS", "F", "P-value", "F critical", NULL }; +static const OUString strWildcardRange("%RANGE%"); static const OUString strWildcardNumber("%NUMBER%"); static const OUString strColumnLabelTemplate("Column %NUMBER%"); -static const OUString strWildcardRange("%RANGE%"); +static const OUString strRowLabelTemplate("Row %NUMBER%"); OUString lclCreateMultiParameterFormula( ScRangeList& aRangeList, const OUString& aFormulaTemplate, @@ -94,14 +95,9 @@ void ScAnalysisOfVarianceDialog::CalculateInputAndWriteToOutput( ) svl::IUndoManager* pUndoManager = pDocShell->GetUndoManager(); pUndoManager->EnterListAction( aUndo, aUndo ); - ScAddress aStart = mInputRange.aStart; - ScAddress aEnd = mInputRange.aEnd; - AddressWalkerWriter output(mOutputAddress, pDocShell, mDocument); FormulaTemplate aTemplate(mDocument, mAddressDetails); - SCROW inTab = aStart.Tab(); - // Write labels for(sal_Int32 i = 0; lclBasicStatisticsLabels[i] != NULL; i++) { @@ -112,19 +108,27 @@ void ScAnalysisOfVarianceDialog::CalculateInputAndWriteToOutput( ) ScRangeList aRangeList; + boost::scoped_ptr<DataRangeIterator> pIterator; + if (mGroupedBy == BY_COLUMN) + pIterator.reset(new DataRangeByColumnIterator(mInputRange)); + else + pIterator.reset(new DataRangeByRowIterator(mInputRange)); + // Write statistic formulas for columns - for (SCCOL inCol = aStart.Col(); inCol <= aEnd.Col(); inCol++) + for( ; pIterator->hasNext(); pIterator->next() ) { output.resetColumn(); - aTemplate.setTemplate(strColumnLabelTemplate); - aTemplate.applyString(strWildcardNumber, OUString::number(inCol - aStart.Col() + 1)); + + if (mGroupedBy == BY_COLUMN) + aTemplate.setTemplate(strColumnLabelTemplate); + else + aTemplate.setTemplate(strRowLabelTemplate); + + aTemplate.applyString(strWildcardNumber, OUString::number(pIterator->index() + 1)); pDocShell->GetDocFunc().SetStringCell(output.current(), aTemplate.getTemplate(), true); output.nextColumn(); - ScRange aColumnRange( - ScAddress(inCol, aStart.Row(), inTab), - ScAddress(inCol, aEnd.Row(), inTab) - ); + ScRange aColumnRange = pIterator->get(); aRangeList.Append(aColumnRange); diff --git a/sc/source/ui/StatisticsDialogs/DescriptiveStatisticsDialog.cxx b/sc/source/ui/StatisticsDialogs/DescriptiveStatisticsDialog.cxx index 19b4788bef76..d9a18a002e6f 100644 --- a/sc/source/ui/StatisticsDialogs/DescriptiveStatisticsDialog.cxx +++ b/sc/source/ui/StatisticsDialogs/DescriptiveStatisticsDialog.cxx @@ -12,6 +12,7 @@ #include <svl/zforlist.hxx> #include <svl/undo.hxx> #include <boost/random.hpp> +#include <boost/scoped_ptr.hpp> #include "formulacell.hxx" #include "rangelst.hxx" @@ -86,8 +87,6 @@ void ScDescriptiveStatisticsDialog::CalculateInputAndWriteToOutput( ) AddressWalkerWriter aOutput(mOutputAddress, pDocShell, mDocument); FormulaTemplate aTemplate(mDocument, mAddressDetails); - SCROW inTab = mInputRange.aStart.Tab(); - for(sal_Int32 i = 0; lclCalcDefinitions[i].aFormula != NULL; i++) { OUString aLabel(SC_STRLOAD(RID_STATISTICS_DLGS, lclCalcDefinitions[i].aCalculationNameId)); @@ -96,19 +95,20 @@ void ScDescriptiveStatisticsDialog::CalculateInputAndWriteToOutput( ) } aOutput.nextColumn(); - for (SCCOL inCol = mInputRange.aStart.Col(); inCol <= mInputRange.aEnd.Col(); inCol++) + boost::scoped_ptr<DataRangeIterator> pIterator; + if (mGroupedBy == BY_COLUMN) + pIterator.reset(new DataRangeByColumnIterator(mInputRange)); + else + pIterator.reset(new DataRangeByRowIterator(mInputRange)); + + for( ; pIterator->hasNext(); pIterator->next() ) { aOutput.resetRow(); - ScRange aColumnRange( - ScAddress(inCol, mInputRange.aStart.Row(), inTab), - ScAddress(inCol, mInputRange.aEnd.Row(), inTab) - ); - for(sal_Int32 i = 0; lclCalcDefinitions[i].aFormula != NULL; i++) { aTemplate.setTemplate(lclCalcDefinitions[i].aFormula); - aTemplate.applyRange(strWildcardRange, aColumnRange); + aTemplate.applyRange(strWildcardRange, pIterator->get()); aOutput.writeFormula(aTemplate.getTemplate()); aOutput.nextRow(); } diff --git a/sc/source/ui/StatisticsDialogs/ExponentialSmoothingDialog.cxx b/sc/source/ui/StatisticsDialogs/ExponentialSmoothingDialog.cxx index 9afeb48d99fc..34cfcf477e64 100644 --- a/sc/source/ui/StatisticsDialogs/ExponentialSmoothingDialog.cxx +++ b/sc/source/ui/StatisticsDialogs/ExponentialSmoothingDialog.cxx @@ -52,14 +52,9 @@ void ScExponentialSmoothingDialog::CalculateInputAndWriteToOutput( ) svl::IUndoManager* pUndoManager = pDocShell->GetUndoManager(); pUndoManager->EnterListAction( aUndo, aUndo ); - ScAddress aStart = mInputRange.aStart; - ScAddress aEnd = mInputRange.aEnd; - AddressWalkerWriter output(mOutputAddress, pDocShell, mDocument); FormulaTemplate aTemplate(mDocument, mAddressDetails); - SCROW inTab = aStart.Tab(); - // Smoothing factor double aSmoothingFactor = mpSmoothingFactor->GetValue() / 100.0; @@ -70,37 +65,39 @@ void ScExponentialSmoothingDialog::CalculateInputAndWriteToOutput( ) // Exponential Smoothing output.push(); - for (SCCOL inCol = aStart.Col(); inCol <= aEnd.Col(); inCol++) + boost::scoped_ptr<DataRangeIterator> pIterator; + if (mGroupedBy == BY_COLUMN) + pIterator.reset(new DataRangeByColumnIterator(mInputRange)); + else + pIterator.reset(new DataRangeByRowIterator(mInputRange)); + + for( ; pIterator->hasNext(); pIterator->next() ) { output.resetRow(); - SCROW inRow = aStart.Row(); + ScRange aCurrentRange = pIterator->get(); if (false) { - ScRange aColumnRange ( - ScAddress(inCol, mInputRange.aStart.Row(), inTab), - ScAddress(inCol, mInputRange.aEnd.Row(), inTab)); - aTemplate.setTemplate("=AVERAGE(%RANGE%)"); - aTemplate.applyRange("%RANGE%", aColumnRange); + aTemplate.applyRange("%RANGE%", aCurrentRange); output.writeFormula(aTemplate.getTemplate()); } else { - ScAddress aFirstValueAddress(inCol, mInputRange.aStart.Row(), inTab); - aTemplate.setTemplate("=%VAR%"); - aTemplate.applyAddress("%VAR%", aFirstValueAddress); + aTemplate.applyAddress("%VAR%", aCurrentRange.aStart); output.writeFormula(aTemplate.getTemplate()); } output.nextRow(); - for (inRow = aStart.Row() + 1; inRow <= aEnd.Row(); inRow++) + DataCellIterator aDataCellIterator = pIterator->iterateCells(); + + for (; aDataCellIterator.hasNext(); aDataCellIterator.next()) { aTemplate.setTemplate("=%VALUE% * %PREVIOUS_INPUT% + (1 - %VALUE%) * %PREVIOUS_OUTPUT%"); - aTemplate.applyAddress("%PREVIOUS_INPUT%", ScAddress(inCol, inRow - 1, inTab)); + aTemplate.applyAddress("%PREVIOUS_INPUT%", aDataCellIterator.get()); aTemplate.applyAddress("%PREVIOUS_OUTPUT%", output.current(0, -1)); aTemplate.applyAddress("%VALUE%", aSmoothingFactorAddress); diff --git a/sc/source/ui/StatisticsDialogs/TableFillingAndNavigationTools.cxx b/sc/source/ui/StatisticsDialogs/TableFillingAndNavigationTools.cxx index 05f43971bcac..bf5080b1d354 100644 --- a/sc/source/ui/StatisticsDialogs/TableFillingAndNavigationTools.cxx +++ b/sc/source/ui/StatisticsDialogs/TableFillingAndNavigationTools.cxx @@ -145,4 +145,128 @@ void AddressWalkerWriter::writeValue(double aValue) mpDocShell->GetDocFunc().SetValueCell(mCurrentAddress, aValue, true); } +// DataCellIterator + +DataCellIterator::DataCellIterator(ScRange aInputRange, bool aByColumn) : + mInputRange(aInputRange), + mByColumn(aByColumn) +{ + if(aByColumn) + mCol = aInputRange.aStart.Col(); + else + mRow = aInputRange.aStart.Row(); +} + +DataCellIterator::~DataCellIterator() +{} + +bool DataCellIterator::hasNext() +{ + if(mByColumn) + return mCol <= mInputRange.aEnd.Col(); + else + return mRow <= mInputRange.aEnd.Row(); +} + +void DataCellIterator::next() +{ + if(mByColumn) + mCol++; + else + mRow++; +} + +ScAddress DataCellIterator::get() +{ + if(mByColumn) + return ScAddress(mCol, mInputRange.aStart.Row(), mInputRange.aStart.Tab()); + else + return ScAddress(mInputRange.aStart.Col(), mRow, mInputRange.aStart.Tab()); +} + +ScAddress DataCellIterator::getRelative(int aDelta) +{ + if(mByColumn) + return ScAddress(mCol + aDelta, mInputRange.aStart.Row(), mInputRange.aStart.Tab()); + else + return ScAddress(mInputRange.aStart.Col(), mRow + aDelta, mInputRange.aStart.Tab()); +} + +// DataRangeIterator + +DataRangeIterator::DataRangeIterator(ScRange aInputRange) : + mInputRange(aInputRange), + mIndex(0) +{} + +DataRangeIterator::~DataRangeIterator() +{} + +sal_Int32 DataRangeIterator::index() +{ + return mIndex; +} + +// DataRangeByColumnIterator + +DataRangeByColumnIterator::DataRangeByColumnIterator(ScRange aInputRange) : + DataRangeIterator(aInputRange), + mCol(aInputRange.aStart.Col()) +{} + +bool DataRangeByColumnIterator::hasNext() +{ + return mCol <= mInputRange.aEnd.Col(); +} + +void DataRangeByColumnIterator::next() +{ + mCol++; + mIndex++; +} + +ScRange DataRangeByColumnIterator::get() +{ + return ScRange( + ScAddress(mCol, mInputRange.aStart.Row(), mInputRange.aStart.Tab()), + ScAddress(mCol, mInputRange.aEnd.Row(), mInputRange.aEnd.Tab()) + ); +} + +DataCellIterator DataRangeByColumnIterator::iterateCells() +{ + return DataCellIterator(get(), false); +} + +// DataRangeByRowIterator + +DataRangeByRowIterator::DataRangeByRowIterator(ScRange aInputRange) : + DataRangeIterator(aInputRange), + mRow(aInputRange.aStart.Row()) +{} + +bool DataRangeByRowIterator::hasNext() +{ + return mRow <= mInputRange.aEnd.Row(); +} + +void DataRangeByRowIterator::next() +{ + mRow++; + mIndex++; +} + +ScRange DataRangeByRowIterator::get() +{ + return ScRange( + ScAddress(mInputRange.aStart.Col(), mRow, mInputRange.aStart.Tab()), + ScAddress(mInputRange.aEnd.Col(), mRow, mInputRange.aEnd.Tab()) + ); +} + +DataCellIterator DataRangeByRowIterator::iterateCells() +{ + return DataCellIterator(get(), true); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/inc/TableFillingAndNavigationTools.hxx b/sc/source/ui/inc/TableFillingAndNavigationTools.hxx index ff95a58213d5..6354df956d4d 100644 --- a/sc/source/ui/inc/TableFillingAndNavigationTools.hxx +++ b/sc/source/ui/inc/TableFillingAndNavigationTools.hxx @@ -75,6 +75,72 @@ public: void writeValue(double aValue); }; +class DataCellIterator +{ +private: + ScRange mInputRange; + bool mByColumn; + SCCOL mCol; + SCROW mRow; + +public: + DataCellIterator(ScRange aInputRange, bool aByColumn); + virtual ~DataCellIterator(); + + virtual bool hasNext(); + virtual ScAddress get(); + virtual void next(); + virtual ScAddress getRelative(int aDelta); +}; + +class DataRangeIterator +{ +protected: + ScRange mInputRange; + sal_Int32 mIndex; + +public: + DataRangeIterator(ScRange aInputRange); + virtual ~DataRangeIterator(); + + virtual bool hasNext() = 0; + virtual ScRange get() = 0; + virtual void next() = 0; + virtual sal_Int32 index(); + + virtual DataCellIterator iterateCells() = 0; +}; + +class DataRangeByColumnIterator : public DataRangeIterator +{ +protected: + SCCOL mCol; + +public: + DataRangeByColumnIterator(ScRange aInputRange); + + virtual bool hasNext(); + virtual void next(); + virtual ScRange get(); + virtual DataCellIterator iterateCells(); +}; + +class DataRangeByRowIterator : public DataRangeIterator +{ +protected: + SCROW mRow; + +public: + DataRangeByRowIterator(ScRange aInputRange); + + virtual bool hasNext(); + virtual void next(); + virtual ScRange get(); + virtual DataCellIterator iterateCells(); +}; + + + #endif |