diff options
-rw-r--r-- | formula/inc/formula/FormulaCompiler.hxx | 3 | ||||
-rw-r--r-- | formula/source/core/api/FormulaCompiler.cxx | 2 | ||||
-rw-r--r-- | sc/inc/cell.hxx | 5 | ||||
-rw-r--r-- | sc/inc/compiler.hxx | 4 | ||||
-rw-r--r-- | sc/inc/formularesult.hxx | 2 | ||||
-rw-r--r-- | sc/inc/token.hxx | 4 | ||||
-rw-r--r-- | sc/source/core/tool/compiler.cxx | 2 | ||||
-rw-r--r-- | sc/source/core/tool/formularesult.cxx | 10 | ||||
-rw-r--r-- | sc/source/core/tool/interpr1.cxx | 3 | ||||
-rw-r--r-- | sc/source/filter/xml/xmlcelli.cxx | 30 | ||||
-rw-r--r-- | sc/source/filter/xml/xmlimprt.cxx | 11 | ||||
-rw-r--r-- | sc/source/filter/xml/xmlimprt.hxx | 8 |
12 files changed, 70 insertions, 14 deletions
diff --git a/formula/inc/formula/FormulaCompiler.hxx b/formula/inc/formula/FormulaCompiler.hxx index ce4157dae9c9..85295b244cb4 100644 --- a/formula/inc/formula/FormulaCompiler.hxx +++ b/formula/inc/formula/FormulaCompiler.hxx @@ -212,6 +212,8 @@ public: */ OpCode GetEnglishOpCode( const String& rName ) const; + sal_uInt16 GetErrorConstant( const String& rName ) const; + void SetCompileForFAP( bool bVal ) { bCompileForFAP = bVal; bIgnoreErrors = bVal; } @@ -265,7 +267,6 @@ protected: virtual void CreateStringFromIndex(rtl::OUStringBuffer& rBuffer,FormulaToken* pTokenP); virtual void LocalizeString( String& rName ); // modify rName - input: exact name - sal_uInt16 GetErrorConstant( const String& rName ); void AppendErrorConstant( rtl::OUStringBuffer& rBuffer, sal_uInt16 nError ); bool GetToken(); diff --git a/formula/source/core/api/FormulaCompiler.cxx b/formula/source/core/api/FormulaCompiler.cxx index 29b66945c799..f79201b6c673 100644 --- a/formula/source/core/api/FormulaCompiler.cxx +++ b/formula/source/core/api/FormulaCompiler.cxx @@ -816,7 +816,7 @@ void FormulaCompiler::OpCodeMap::copyFrom( const OpCodeMap& r ) } // ----------------------------------------------------------------------------- -sal_uInt16 FormulaCompiler::GetErrorConstant( const String& rName ) +sal_uInt16 FormulaCompiler::GetErrorConstant( const String& rName ) const { sal_uInt16 nError = 0; OpCodeHashMap::const_iterator iLook( mxSymbols->getHashMap()->find( rName)); diff --git a/sc/inc/cell.hxx b/sc/inc/cell.hxx index ee040a280014..716b76f4113c 100644 --- a/sc/inc/cell.hxx +++ b/sc/inc/cell.hxx @@ -493,6 +493,11 @@ public: const formula::FormulaGrammar::Grammar eGrammar ) { aResult.SetHybridFormula( r); eTempGrammar = eGrammar; } + void SetResultMatrix( SCCOL nCols, SCROW nRows, const ScConstMatrixRef& pMat, formula::FormulaToken* pUL ) + { + aResult.SetMatrix(nCols, nRows, pMat, pUL); + } + /** For import only: set a double result. Use this instead of SetHybridDouble() if there is no (temporary) formula string because the formula is present as a token array, as it diff --git a/sc/inc/compiler.hxx b/sc/inc/compiler.hxx index 4aa393d82ea6..d40d26166deb 100644 --- a/sc/inc/compiler.hxx +++ b/sc/inc/compiler.hxx @@ -320,7 +320,7 @@ private: sal_Unicode cSymbol[MAXSTRLEN]; // current Symbol String aFormula; // formula source code xub_StrLen nSrcPos; // tokenizer position (source code) - ScRawTokenRef pRawToken; + mutable ScRawTokenRef pRawToken; const CharClass* pCharClass; // which character classification is used for parseAnyToken sal_uInt16 mnPredetectedReference; // reference when reading ODF, 0 (none), 1 (single) or 2 (double) @@ -386,7 +386,7 @@ public: // Check if it is a valid english function name bool IsEnglishSymbol( const String& rName ); - bool IsErrorConstant( const String& ); + bool IsErrorConstant( const String& ) const; //! _either_ CompileForFAP _or_ AutoCorrection, _not_ both // #i101512# SetCompileForFAP is in formula::FormulaCompiler diff --git a/sc/inc/formularesult.hxx b/sc/inc/formularesult.hxx index c4f281fabb0c..2128636816b6 100644 --- a/sc/inc/formularesult.hxx +++ b/sc/inc/formularesult.hxx @@ -179,6 +179,8 @@ public: SetHybridFormula() for formula string to be compiled later. */ SC_DLLPUBLIC void SetHybridFormula( const String & rFormula ); + SC_DLLPUBLIC void SetMatrix( SCCOL nCols, SCROW nRows, const ScConstMatrixRef& pMat, formula::FormulaToken* pUL ); + /** Get the const ScMatrixFormulaCellToken* if token is of that type, else NULL. */ const ScMatrixFormulaCellToken* GetMatrixFormulaCellToken() const; diff --git a/sc/inc/token.hxx b/sc/inc/token.hxx index c8c87829860a..e08db6cb440c 100644 --- a/sc/inc/token.hxx +++ b/sc/inc/token.hxx @@ -350,6 +350,10 @@ private: SCROW nRows; SCCOL nCols; public: + ScMatrixFormulaCellToken( SCCOL nC, SCROW nR, const ScConstMatrixRef& pMat, formula::FormulaToken* pUL ) : + ScMatrixCellResultToken(pMat, pUL), + nRows(nR), nCols(nC) {} + ScMatrixFormulaCellToken( SCCOL nC, SCROW nR ) : ScMatrixCellResultToken( NULL, NULL ), nRows( nR ), nCols( nC ) {} 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 |