summaryrefslogtreecommitdiff
path: root/sc/source
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@gmail.com>2013-01-09 11:17:09 -0500
committerKohei Yoshida <kohei.yoshida@gmail.com>2013-01-09 11:29:50 -0500
commitb6fbc8642928893ca608a35b802032cfe42e40bb (patch)
treed7b1c0185c1fcfcdee133e9375f65ea45665c2e8 /sc/source
parentb7d0dd5252bdec31fcc925037aa7916b9fffeca7 (diff)
fdo#58539: Correctly set cached matrix formula result.
During the import, a cached matrix value only has an empty matrix of correct geometry, plus the token type of the top-left cell. The rest of the elements are imported as hybrid values. For now, this seems to do the trick. In the future we may want to change it to fully populate the matrix cache value during the import, and skip setting the hybrid values for the non-top-left elements. This commit also make several other trivial changes: * Mark pRawToken mutable so that we can mark those IsFoo() methods const. * Move the ScCompiler instance from static instance to member of ScXMLImport. Since we don't need the instance to persist once the import is over, this is more appropriate. Change-Id: I1abde03c0fcd91b02ef4dbf8b5526f7965eaf19c
Diffstat (limited to 'sc/source')
-rw-r--r--sc/source/core/tool/compiler.cxx2
-rw-r--r--sc/source/core/tool/formularesult.cxx10
-rw-r--r--sc/source/core/tool/interpr1.cxx3
-rw-r--r--sc/source/filter/xml/xmlcelli.cxx30
-rw-r--r--sc/source/filter/xml/xmlimprt.cxx11
-rw-r--r--sc/source/filter/xml/xmlimprt.hxx8
6 files changed, 54 insertions, 10 deletions
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index 4656e2b2c1c0..6de041772e4e 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -3306,7 +3306,7 @@ bool ScCompiler::IsBoolean( const String& rName )
}
-bool ScCompiler::IsErrorConstant( const String& rName )
+bool ScCompiler::IsErrorConstant( const String& rName ) const
{
sal_uInt16 nError = GetErrorConstant( rName);
if (nError)
diff --git a/sc/source/core/tool/formularesult.cxx b/sc/source/core/tool/formularesult.cxx
index 3b94481c4041..9e1032ec9d44 100644
--- a/sc/source/core/tool/formularesult.cxx
+++ b/sc/source/core/tool/formularesult.cxx
@@ -443,6 +443,16 @@ void ScFormulaResult::SetHybridFormula( const String & rFormula )
mbToken = true;
}
+void ScFormulaResult::SetMatrix( SCCOL nCols, SCROW nRows, const ScConstMatrixRef& pMat, formula::FormulaToken* pUL )
+{
+ ResetToDefaults();
+ if (mbToken && mpToken)
+ mpToken->DecRef();
+ mpToken = new ScMatrixFormulaCellToken(nCols, nRows, pMat, pUL);
+ mpToken->IncRef();
+ mbToken = true;
+}
+
const ScMatrixFormulaCellToken* ScFormulaResult::GetMatrixFormulaCellToken() const
{
return (GetType() == formula::svMatrixCell ?
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 0b86108ada5b..ec85a01f7314 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -135,7 +135,10 @@ void ScInterpreter::ScIfJump()
SCSIZE nCols, nRows;
pMat->GetDimensions( nCols, nRows );
if ( nCols == 0 || nRows == 0 )
+ {
PushIllegalArgument();
+ return;
+ }
else if (pTokenMatrixMap && ((aMapIter = pTokenMatrixMap->find(
pCur)) != pTokenMatrixMap->end()))
xNew = (*aMapIter).second;
diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx
index e9375705e897..25579f2a5085 100644
--- a/sc/source/filter/xml/xmlcelli.cxx
+++ b/sc/source/filter/xml/xmlcelli.cxx
@@ -47,8 +47,6 @@
#include "scerrors.hxx"
#include "editutil.hxx"
#include "cell.hxx"
-#include "compiler.hxx"
-
#include <xmloff/xmltkmap.hxx>
#include <xmloff/xmltoken.hxx>
@@ -727,9 +725,7 @@ void ScXMLTableRowCellContext::SetFormulaCell(ScFormulaCell* pFCell) const
{
if( bFormulaTextResult && pOUTextValue )
{
- static ScCompiler aComp(NULL, ScAddress());
- aComp.SetGrammar(formula::FormulaGrammar::GRAM_ODFF);
- if(!aComp.IsErrorConstant(*pOUTextValue))
+ if (!GetScImport().IsFormulaErrorConstant(*pOUTextValue))
{
pFCell->SetHybridString( *pOUTextValue );
pFCell->ResetDirty();
@@ -1086,11 +1082,29 @@ void ScXMLTableRowCellContext::AddFormulaCell( const ScAddress& rCellPos )
std::min<SCROW>(rCellPos.Row() + nMatrixRows - 1, MAXROW),
pOUFormula->first, pOUFormula->second, eGrammar);
- //set the value/text of the first matrix position (top-left).
- //the value/text of the matrix reference cells will be set later.
+ // Set the value/text of the top-left matrix position in its
+ // cached result. For import, we only need to set the correct
+ // matrix geometry and the value type of the top-left element.
+
ScFormulaCell* pFCell =
static_cast<ScFormulaCell*>( rXMLImport.GetDocument()->GetCell(rCellPos) );
- SetFormulaCell(pFCell);
+
+ ScMatrixRef pMat(new ScMatrix(nMatrixCols, nMatrixRows));
+ if (bFormulaTextResult && pOUTextValue)
+ {
+ if (!GetScImport().IsFormulaErrorConstant(*pOUTextValue))
+ {
+ pFCell->SetResultMatrix(
+ nMatrixCols, nMatrixRows, pMat, new formula::FormulaStringToken(*pOUTextValue));
+ pFCell->ResetDirty();
+ }
+ }
+ else if (!rtl::math::isNan(fValue))
+ {
+ pFCell->SetResultMatrix(
+ nMatrixCols, nMatrixRows, pMat, new formula::FormulaDoubleToken(fValue));
+ pFCell->ResetDirty();
+ }
}
}
else
diff --git a/sc/source/filter/xml/xmlimprt.cxx b/sc/source/filter/xml/xmlimprt.cxx
index 7aae79ca597b..b7f229c9e4b9 100644
--- a/sc/source/filter/xml/xmlimprt.cxx
+++ b/sc/source/filter/xml/xmlimprt.cxx
@@ -2809,6 +2809,9 @@ throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::R
if (!pDoc)
throw lang::IllegalArgumentException();
+ mpComp.reset(new ScCompiler(pDoc, ScAddress()));
+ mpComp->SetGrammar(formula::FormulaGrammar::GRAM_ODFF);
+
bFromWrapper = pDoc->IsXMLFromWrapper(); // UnlockSolarMutex below still works normally
uno::Reference<document::XActionLockable> xActionLockable(xDoc, uno::UNO_QUERY);
@@ -3294,4 +3297,12 @@ void ScXMLImport::ExtractFormulaNamespaceGrammar(
reGrammar = eDefaultGrammar;
}
+bool ScXMLImport::IsFormulaErrorConstant( const OUString& rStr ) const
+{
+ if (!mpComp)
+ return false;
+
+ return mpComp->GetErrorConstant(rStr) > 0;
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlimprt.hxx b/sc/source/filter/xml/xmlimprt.hxx
index c202160f5d18..87f3f3e8d974 100644
--- a/sc/source/filter/xml/xmlimprt.hxx
+++ b/sc/source/filter/xml/xmlimprt.hxx
@@ -31,6 +31,7 @@
#include "xmlsubti.hxx"
#include "global.hxx"
#include "formula/grammar.hxx"
+#include "compiler.hxx"
#include "xmlstyle.hxx"
#include "XMLDetectiveContext.hxx"
@@ -46,6 +47,8 @@
#include <boost/unordered_map.hpp>
#include <boost/ptr_container/ptr_list.hpp>
#include <boost/ptr_container/ptr_map.hpp>
+#include <boost/noncopyable.hpp>
+#include <boost/scoped_ptr.hpp>
class ScMyStyleNumberFormats;
class XMLNumberFormatAttributesExportHelper;
@@ -732,7 +735,7 @@ typedef std::vector<ScMyImportValidation> ScMyImportValidations;
typedef std::list<SvXMLImportContext*> ScMyViewContextList;
class ScMyStylesImportHelper;
-class ScXMLImport: public SvXMLImport
+class ScXMLImport: public SvXMLImport, boost::noncopyable
{
typedef ::boost::unordered_map< ::rtl::OUString, sal_Int16, ::rtl::OUStringHash > CellTypeMap;
typedef ::boost::ptr_map<SCTAB, ScMyNamedExpressions> SheetNamedExpMap;
@@ -740,6 +743,7 @@ class ScXMLImport: public SvXMLImport
CellTypeMap aCellTypeMap;
ScDocument* pDoc;
+ boost::scoped_ptr<ScCompiler> mpComp; // For error-checking of cached string cell values.
ScXMLChangeTrackingImportHelper* pChangeTrackingImportHelper;
ScMyViewContextList aViewContextList;
ScMyStylesImportHelper* pStylesImportHelper;
@@ -1141,6 +1145,8 @@ public:
::formula::FormulaGrammar::Grammar& reGrammar,
const ::rtl::OUString& rAttrValue,
bool bRestrictToExternalNmsp = false ) const;
+
+ bool IsFormulaErrorConstant( const OUString& rStr ) const;
};
#endif