summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@gmail.com>2013-04-29 19:19:48 -0400
committerKohei Yoshida <kohei.yoshida@gmail.com>2013-04-30 13:10:44 -0400
commite38d20c1e1146f2510f8482ea82fd0af3be67325 (patch)
tree2fb8c4ebf12f34bbd0f182c902b656a43a8d6719
parentf07601a255eaad729fdb2fffc36336a4cd364501 (diff)
Handle range references for group calculation. This is still untested.
Change-Id: I1eb1c217db66615028faa85720838579056dc150
-rw-r--r--formula/source/core/api/vectortoken.cxx34
-rw-r--r--include/formula/vectortoken.hxx17
-rw-r--r--sc/source/core/data/formulacell.cxx41
3 files changed, 72 insertions, 20 deletions
diff --git a/formula/source/core/api/vectortoken.cxx b/formula/source/core/api/vectortoken.cxx
index e016fd3700b0..74339397448b 100644
--- a/formula/source/core/api/vectortoken.cxx
+++ b/formula/source/core/api/vectortoken.cxx
@@ -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: */
diff --git a/include/formula/vectortoken.hxx b/include/formula/vectortoken.hxx
index db44355cf824..2679b4ef0e06 100644
--- a/include/formula/vectortoken.hxx
+++ b/include/formula/vectortoken.hxx
@@ -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;
};
}
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 598725350e7b..7e85225cd0db 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -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);