Kaydet (Commit) f4569ff5 authored tarafından Tomaž Vajngerl's avatar Tomaž Vajngerl

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
üst 2f823d45
...@@ -45,9 +45,10 @@ static const char* lclAnovaLabels[] = ...@@ -45,9 +45,10 @@ static const char* lclAnovaLabels[] =
"Source of Variation", "SS", "df", "MS", "F", "P-value", "F critical", NULL "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 strWildcardNumber("%NUMBER%");
static const OUString strColumnLabelTemplate("Column %NUMBER%"); static const OUString strColumnLabelTemplate("Column %NUMBER%");
static const OUString strWildcardRange("%RANGE%"); static const OUString strRowLabelTemplate("Row %NUMBER%");
OUString lclCreateMultiParameterFormula( OUString lclCreateMultiParameterFormula(
ScRangeList& aRangeList, const OUString& aFormulaTemplate, ScRangeList& aRangeList, const OUString& aFormulaTemplate,
...@@ -94,14 +95,9 @@ void ScAnalysisOfVarianceDialog::CalculateInputAndWriteToOutput( ) ...@@ -94,14 +95,9 @@ void ScAnalysisOfVarianceDialog::CalculateInputAndWriteToOutput( )
svl::IUndoManager* pUndoManager = pDocShell->GetUndoManager(); svl::IUndoManager* pUndoManager = pDocShell->GetUndoManager();
pUndoManager->EnterListAction( aUndo, aUndo ); pUndoManager->EnterListAction( aUndo, aUndo );
ScAddress aStart = mInputRange.aStart;
ScAddress aEnd = mInputRange.aEnd;
AddressWalkerWriter output(mOutputAddress, pDocShell, mDocument); AddressWalkerWriter output(mOutputAddress, pDocShell, mDocument);
FormulaTemplate aTemplate(mDocument, mAddressDetails); FormulaTemplate aTemplate(mDocument, mAddressDetails);
SCROW inTab = aStart.Tab();
// Write labels // Write labels
for(sal_Int32 i = 0; lclBasicStatisticsLabels[i] != NULL; i++) for(sal_Int32 i = 0; lclBasicStatisticsLabels[i] != NULL; i++)
{ {
...@@ -112,19 +108,27 @@ void ScAnalysisOfVarianceDialog::CalculateInputAndWriteToOutput( ) ...@@ -112,19 +108,27 @@ void ScAnalysisOfVarianceDialog::CalculateInputAndWriteToOutput( )
ScRangeList aRangeList; 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 // Write statistic formulas for columns
for (SCCOL inCol = aStart.Col(); inCol <= aEnd.Col(); inCol++) for( ; pIterator->hasNext(); pIterator->next() )
{ {
output.resetColumn(); 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); pDocShell->GetDocFunc().SetStringCell(output.current(), aTemplate.getTemplate(), true);
output.nextColumn(); output.nextColumn();
ScRange aColumnRange( ScRange aColumnRange = pIterator->get();
ScAddress(inCol, aStart.Row(), inTab),
ScAddress(inCol, aEnd.Row(), inTab)
);
aRangeList.Append(aColumnRange); aRangeList.Append(aColumnRange);
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <svl/zforlist.hxx> #include <svl/zforlist.hxx>
#include <svl/undo.hxx> #include <svl/undo.hxx>
#include <boost/random.hpp> #include <boost/random.hpp>
#include <boost/scoped_ptr.hpp>
#include "formulacell.hxx" #include "formulacell.hxx"
#include "rangelst.hxx" #include "rangelst.hxx"
...@@ -86,8 +87,6 @@ void ScDescriptiveStatisticsDialog::CalculateInputAndWriteToOutput( ) ...@@ -86,8 +87,6 @@ void ScDescriptiveStatisticsDialog::CalculateInputAndWriteToOutput( )
AddressWalkerWriter aOutput(mOutputAddress, pDocShell, mDocument); AddressWalkerWriter aOutput(mOutputAddress, pDocShell, mDocument);
FormulaTemplate aTemplate(mDocument, mAddressDetails); FormulaTemplate aTemplate(mDocument, mAddressDetails);
SCROW inTab = mInputRange.aStart.Tab();
for(sal_Int32 i = 0; lclCalcDefinitions[i].aFormula != NULL; i++) for(sal_Int32 i = 0; lclCalcDefinitions[i].aFormula != NULL; i++)
{ {
OUString aLabel(SC_STRLOAD(RID_STATISTICS_DLGS, lclCalcDefinitions[i].aCalculationNameId)); OUString aLabel(SC_STRLOAD(RID_STATISTICS_DLGS, lclCalcDefinitions[i].aCalculationNameId));
...@@ -96,19 +95,20 @@ void ScDescriptiveStatisticsDialog::CalculateInputAndWriteToOutput( ) ...@@ -96,19 +95,20 @@ void ScDescriptiveStatisticsDialog::CalculateInputAndWriteToOutput( )
} }
aOutput.nextColumn(); 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(); 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++) for(sal_Int32 i = 0; lclCalcDefinitions[i].aFormula != NULL; i++)
{ {
aTemplate.setTemplate(lclCalcDefinitions[i].aFormula); aTemplate.setTemplate(lclCalcDefinitions[i].aFormula);
aTemplate.applyRange(strWildcardRange, aColumnRange); aTemplate.applyRange(strWildcardRange, pIterator->get());
aOutput.writeFormula(aTemplate.getTemplate()); aOutput.writeFormula(aTemplate.getTemplate());
aOutput.nextRow(); aOutput.nextRow();
} }
......
...@@ -52,14 +52,9 @@ void ScExponentialSmoothingDialog::CalculateInputAndWriteToOutput( ) ...@@ -52,14 +52,9 @@ void ScExponentialSmoothingDialog::CalculateInputAndWriteToOutput( )
svl::IUndoManager* pUndoManager = pDocShell->GetUndoManager(); svl::IUndoManager* pUndoManager = pDocShell->GetUndoManager();
pUndoManager->EnterListAction( aUndo, aUndo ); pUndoManager->EnterListAction( aUndo, aUndo );
ScAddress aStart = mInputRange.aStart;
ScAddress aEnd = mInputRange.aEnd;
AddressWalkerWriter output(mOutputAddress, pDocShell, mDocument); AddressWalkerWriter output(mOutputAddress, pDocShell, mDocument);
FormulaTemplate aTemplate(mDocument, mAddressDetails); FormulaTemplate aTemplate(mDocument, mAddressDetails);
SCROW inTab = aStart.Tab();
// Smoothing factor // Smoothing factor
double aSmoothingFactor = mpSmoothingFactor->GetValue() / 100.0; double aSmoothingFactor = mpSmoothingFactor->GetValue() / 100.0;
...@@ -70,37 +65,39 @@ void ScExponentialSmoothingDialog::CalculateInputAndWriteToOutput( ) ...@@ -70,37 +65,39 @@ void ScExponentialSmoothingDialog::CalculateInputAndWriteToOutput( )
// Exponential Smoothing // Exponential Smoothing
output.push(); 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(); output.resetRow();
SCROW inRow = aStart.Row(); ScRange aCurrentRange = pIterator->get();
if (false) if (false)
{ {
ScRange aColumnRange (
ScAddress(inCol, mInputRange.aStart.Row(), inTab),
ScAddress(inCol, mInputRange.aEnd.Row(), inTab));
aTemplate.setTemplate("=AVERAGE(%RANGE%)"); aTemplate.setTemplate("=AVERAGE(%RANGE%)");
aTemplate.applyRange("%RANGE%", aColumnRange); aTemplate.applyRange("%RANGE%", aCurrentRange);
output.writeFormula(aTemplate.getTemplate()); output.writeFormula(aTemplate.getTemplate());
} }
else else
{ {
ScAddress aFirstValueAddress(inCol, mInputRange.aStart.Row(), inTab);
aTemplate.setTemplate("=%VAR%"); aTemplate.setTemplate("=%VAR%");
aTemplate.applyAddress("%VAR%", aFirstValueAddress); aTemplate.applyAddress("%VAR%", aCurrentRange.aStart);
output.writeFormula(aTemplate.getTemplate()); output.writeFormula(aTemplate.getTemplate());
} }
output.nextRow(); 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.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("%PREVIOUS_OUTPUT%", output.current(0, -1));
aTemplate.applyAddress("%VALUE%", aSmoothingFactorAddress); aTemplate.applyAddress("%VALUE%", aSmoothingFactorAddress);
......
...@@ -145,4 +145,128 @@ void AddressWalkerWriter::writeValue(double aValue) ...@@ -145,4 +145,128 @@ void AddressWalkerWriter::writeValue(double aValue)
mpDocShell->GetDocFunc().SetValueCell(mCurrentAddress, aValue, true); 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: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
...@@ -75,6 +75,72 @@ public: ...@@ -75,6 +75,72 @@ public:
void writeValue(double aValue); 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 #endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment