summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@collabora.com>2013-11-15 19:41:47 -0500
committerKohei Yoshida <kohei.yoshida@collabora.com>2013-11-18 17:25:40 -0500
commit3dab6fcbedf21c1d2971527f6f99fa46d3d45514 (patch)
treecc48f95d7e1a56d5b0fa96c93e7bdbd251d98b06
parent3f5987421e4d612012ec346ae280fb362239a5d6 (diff)
Handle matrix.
Change-Id: I084b2348b5c52151b0d0ea36d082ec2f2603e0d4
-rw-r--r--sc/qa/unit/ucalc_formula.cxx3
-rw-r--r--sc/source/core/tool/token.cxx94
2 files changed, 77 insertions, 20 deletions
diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx
index 91e4594d6803..7ae255472d4f 100644
--- a/sc/qa/unit/ucalc_formula.cxx
+++ b/sc/qa/unit/ucalc_formula.cxx
@@ -113,7 +113,8 @@ void Test::testFormulaCreateStringFromTokens()
"'Past Data'.B1+'2013'.B2*(1+'Kevin''s Data'.C10)",
"x+y*z", // named ranges
"SUM(sheetx;x;y;z)", // sheet local and global named ranges mixed
- "MAX(Table1)+MIN(Table2)*SUM(Table3)" // database ranges
+ "MAX(Table1)+MIN(Table2)*SUM(Table3)", // database ranges
+ "{1;TRUE;3|FALSE;5;\"Text\"|;;}", // inline matrix
};
boost::scoped_ptr<ScTokenArray> pArray;
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index b1d7e941f8d9..fcd2aea1ecdb 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -3193,6 +3193,30 @@ void ScTokenArray::CheckRelativeReferenceBounds(
namespace {
+void appendDouble( sc::TokenStringContext& rCxt, OUStringBuffer& rBuf, double fVal )
+{
+ if (rCxt.mxOpCodeMap->isEnglish())
+ {
+ rtl::math::doubleToUStringBuffer(
+ rBuf, fVal, rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max, '.', true);
+ }
+ else
+ {
+ SvtSysLocale aSysLocale;
+ rtl::math::doubleToUStringBuffer(
+ rBuf, fVal,
+ rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max,
+ aSysLocale.GetLocaleDataPtr()->getNumDecimalSep()[0], true);
+ }
+}
+
+void appendString( OUStringBuffer& rBuf, const OUString& rStr )
+{
+ rBuf.append(sal_Unicode('"'));
+ rBuf.append(rStr.replaceAll("\"", "\"\""));
+ rBuf.append(sal_Unicode('"'));
+}
+
void appendTokenByType( sc::TokenStringContext& rCxt, OUStringBuffer& rBuf, const FormulaToken& rToken, const ScAddress& rPos )
{
if (rToken.IsExternalRef())
@@ -3205,21 +3229,7 @@ void appendTokenByType( sc::TokenStringContext& rCxt, OUStringBuffer& rBuf, cons
switch (rToken.GetType())
{
case svDouble:
- {
- if (rCxt.mxOpCodeMap->isEnglish())
- {
- rtl::math::doubleToUStringBuffer(
- rBuf, rToken.GetDouble(), rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max, '.', true);
- }
- else
- {
- SvtSysLocale aSysLocale;
- rtl::math::doubleToUStringBuffer(
- rBuf, rToken.GetDouble(),
- rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max,
- aSysLocale.GetLocaleDataPtr()->getNumDecimalSep()[0], true);
- }
- }
+ appendDouble(rCxt, rBuf, rToken.GetDouble());
break;
case svString:
{
@@ -3230,9 +3240,7 @@ void appendTokenByType( sc::TokenStringContext& rCxt, OUStringBuffer& rBuf, cons
return;
}
- rBuf.append(sal_Unicode('"'));
- rBuf.append(aStr.replaceAll("\"", "\"\""));
- rBuf.append(sal_Unicode('"'));
+ appendString(rBuf, aStr);
}
break;
case svSingleRef:
@@ -3261,7 +3269,55 @@ void appendTokenByType( sc::TokenStringContext& rCxt, OUStringBuffer& rBuf, cons
}
break;
case svMatrix:
- // TODO : Implement this.
+ {
+ const ScMatrix* pMat = static_cast<const ScToken&>(rToken).GetMatrix();
+ if (!pMat)
+ return;
+
+ size_t nC, nMaxC, nR, nMaxR;
+ pMat->GetDimensions(nMaxC, nMaxR);
+
+ rBuf.append(rCxt.mxOpCodeMap->getSymbol(ocArrayOpen));
+ for (nR = 0 ; nR < nMaxR ; ++nR)
+ {
+ if (nR > 0)
+ {
+ rBuf.append(rCxt.mxOpCodeMap->getSymbol(ocArrayRowSep));
+ }
+
+ for (nC = 0 ; nC < nMaxC ; ++nC)
+ {
+ if (nC > 0)
+ {
+ rBuf.append(rCxt.mxOpCodeMap->getSymbol(ocArrayColSep));
+ }
+
+ if (pMat->IsValue(nC, nR))
+ {
+ if (pMat->IsBoolean(nC, nR))
+ {
+ bool bVal = pMat->GetDouble(nC, nR) != 0.0;
+ rBuf.append(rCxt.mxOpCodeMap->getSymbol(bVal ? ocTrue : ocFalse));
+ }
+ else
+ {
+ sal_uInt16 nErr = pMat->GetError(nC, nR);
+ if (nErr)
+ rBuf.append(ScGlobal::GetErrorString(nErr));
+ else
+ appendDouble(rCxt, rBuf, pMat->GetDouble(nC, nR));
+ }
+ }
+ else if (pMat->IsEmpty(nC, nR))
+ {
+ // Skip it.
+ }
+ else if (pMat->IsString(nC, nR))
+ appendString(rBuf, pMat->GetString(nC, nR).getString());
+ }
+ }
+ rBuf.append(rCxt.mxOpCodeMap->getSymbol(ocArrayClose));
+ }
break;
case svIndex:
{