Handle range references for group calculation. This is still untested.

Change-Id: I1eb1c217db66615028faa85720838579056dc150
This commit is contained in:
Kohei Yoshida
2013-04-29 19:19:48 -04:00
parent f07601a255
commit e38d20c1e1
3 changed files with 72 additions and 20 deletions

View File

@@ -12,11 +12,11 @@
namespace formula {
SingleVectorRefToken::SingleVectorRefToken( const double* pArray, size_t nLength ) :
FormulaToken(svSingleVectorRef, ocPush), mpArray(pArray), mnLength(nLength) {}
FormulaToken(svSingleVectorRef, ocPush), mpArray(pArray), mnArrayLength(nLength) {}
FormulaToken* SingleVectorRefToken::Clone() const
{
return new SingleVectorRefToken(mpArray, mnLength);
return new SingleVectorRefToken(mpArray, mnArrayLength);
}
const double* SingleVectorRefToken::GetArray() const
@@ -24,19 +24,19 @@ const double* SingleVectorRefToken::GetArray() const
return mpArray;
}
size_t SingleVectorRefToken::GetLength() const
size_t SingleVectorRefToken::GetArrayLength() const
{
return mnLength;
return mnArrayLength;
}
DoubleVectorRefToken::DoubleVectorRefToken(
const std::vector<const double*>& rArrays, size_t nRowSize, bool bAbsStart, bool bAbsEnd ) :
const std::vector<const double*>& rArrays, size_t nArrayLength, size_t nRefRowSize, bool bStartFixed, bool bEndFixed ) :
FormulaToken(svDoubleVectorRef, ocPush),
maArrays(rArrays), mnRowSize(nRowSize), mbAbsStart(bAbsStart), mbAbsEnd(bAbsEnd) {}
maArrays(rArrays), mnArrayLength(nArrayLength), mnRefRowSize(nRefRowSize), mbStartFixed(bStartFixed), mbEndFixed(bEndFixed) {}
FormulaToken* DoubleVectorRefToken::Clone() const
{
return new DoubleVectorRefToken(maArrays, mnRowSize, mbAbsStart, mbAbsEnd);
return new DoubleVectorRefToken(maArrays, mnArrayLength, mnRefRowSize, mbStartFixed, mbEndFixed);
}
const std::vector<const double*>& DoubleVectorRefToken::GetArrays() const
@@ -44,6 +44,26 @@ const std::vector<const double*>& DoubleVectorRefToken::GetArrays() const
return maArrays;
}
size_t DoubleVectorRefToken::GetArrayLength() const
{
return mnArrayLength;
}
size_t DoubleVectorRefToken::GetRefRowSize() const
{
return mnRefRowSize;
}
bool DoubleVectorRefToken::IsStartFixed() const
{
return mbStartFixed;
}
bool DoubleVectorRefToken::IsEndFixed() const
{
return mbEndFixed;
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View File

@@ -17,7 +17,7 @@ namespace formula {
class FORMULA_DLLPUBLIC SingleVectorRefToken : public FormulaToken
{
const double* mpArray;
size_t mnLength;
size_t mnArrayLength;
public:
SingleVectorRefToken( const double* pArray, size_t nLength );
@@ -25,7 +25,7 @@ public:
virtual FormulaToken* Clone() const;
const double* GetArray() const;
size_t GetLength() const;
size_t GetArrayLength() const;
};
/**
@@ -36,18 +36,23 @@ class FORMULA_DLLPUBLIC DoubleVectorRefToken : public FormulaToken
{
std::vector<const double*> maArrays;
size_t mnRowSize;
size_t mnArrayLength;
size_t mnRefRowSize;
bool mbAbsStart:1; /// whether or not the start row position is absolute.
bool mbAbsEnd:1; /// whether or not the end row position is absolute.
bool mbStartFixed:1; /// whether or not the start row position is absolute.
bool mbEndFixed:1; /// whether or not the end row position is absolute.
public:
DoubleVectorRefToken(
const std::vector<const double*>& rArrays, size_t nRowSize, bool bAbsStart, bool bAbsEnd );
const std::vector<const double*>& rArrays, size_t nArrayLength, size_t nRefRowSize, bool bStartFixed, bool bEndFixed );
virtual FormulaToken* Clone() const;
const std::vector<const double*>& GetArrays() const;
size_t GetArrayLength() const;
size_t GetRefRowSize() const;
bool IsStartFixed() const;
bool IsEndFixed() const;
};
}

View File

@@ -3030,24 +3030,25 @@ bool ScFormulaCell::InterpretFormulaGroup()
size_t nCols = aRef.Ref2.nCol - aRef.Ref1.nCol + 1;
std::vector<const double*> aArrays;
aArrays.reserve(nCols);
SCROW nLength = xGroup->mnLength;
SCROW nArrayLength = xGroup->mnLength;
SCROW nRefRowSize = aRef.Ref2.nRow - aRef.Ref1.nRow + 1;
if (!bAbsLast)
{
// range end position is relative. Extend it.
nLength += aRef.Ref2.nRow - aRef.Ref1.nRow;
// range end position is relative. Extend the array length.
nArrayLength += nRefRowSize - 1;
}
for (SCCOL i = aRef.Ref1.nCol; i <= aRef.Ref2.nCol; ++i)
{
aRefPos.SetCol(i);
const double* pArray = pDocument->FetchDoubleArray(aCxt, aRefPos, nLength);
const double* pArray = pDocument->FetchDoubleArray(aCxt, aRefPos, nArrayLength);
if (!pArray)
return false;
aArrays.push_back(pArray);
}
formula::DoubleVectorRefToken aTok(aArrays, nLength, bAbsFirst, bAbsLast);
formula::DoubleVectorRefToken aTok(aArrays, nArrayLength, nRefRowSize, bAbsFirst, bAbsLast);
aCode.AddToken(aTok);
}
else
@@ -3088,11 +3089,37 @@ bool ScFormulaCell::InterpretFormulaGroup()
{
const formula::SingleVectorRefToken* p2 = static_cast<const formula::SingleVectorRefToken*>(p);
const double* pArray = p2->GetArray();
aCode2.AddDouble(pArray[i]);
aCode2.AddDouble(i < p2->GetArrayLength() ? pArray[i] : 0.0);
}
break;
case svDoubleVectorRef:
return false;
{
const formula::DoubleVectorRefToken* p2 = static_cast<const formula::DoubleVectorRefToken*>(p);
const std::vector<const double*>& rArrays = p2->GetArrays();
size_t nColSize = rArrays.size();
size_t nRowStart = p2->IsStartFixed() ? 0 : i;
size_t nRowEnd = p2->GetRefRowSize() - 1;
if (!p2->IsEndFixed())
nRowEnd += i;
size_t nRowSize = nRowEnd - nRowStart + 1;
ScMatrixRef pMat(new ScMatrix(nColSize, nRowSize, 0.0));
for (size_t nCol = 0; nCol < nColSize; ++nCol)
{
const double* pArray = rArrays[nCol];
for (size_t nRow = 0; nRow < nRowSize; ++nRow)
{
if (nRowStart + nRow < p2->GetArrayLength())
{
double fVal = pArray[nRowStart+nRow];
pMat->PutDouble(fVal, nCol, nRow);
}
}
}
ScMatrixToken aTok(pMat);
aCode2.AddToken(aTok);
}
break;
default:
aCode2.AddToken(*p);