diff options
author | Markus Mohrhard <markus.mohrhard@googlemail.com> | 2013-05-07 00:59:48 +0200 |
---|---|---|
committer | Markus Mohrhard <markus.mohrhard@googlemail.com> | 2013-06-02 03:24:56 +0200 |
commit | 1a663077de77bdbb7edfe2283d9e9bc93e90594f (patch) | |
tree | bb7ecb4df6e776f0a38ec3e5749a4fe3bdb5ec24 /sc | |
parent | 58545dee13cd54ac7e2d7e776efdc46534086e11 (diff) |
initial work on removing some ScFormulaCell instances
These cells where using a ScFormulaCell to calculate the result of a
formula and get the number format. Use the new ScSimpleFormulaCalculator
which is a simplified version that has only a few limitations.
Change-Id: I71f01b8fa10506234627a6512cb434800dceca6a
Diffstat (limited to 'sc')
-rw-r--r-- | sc/Library_sc.mk | 1 | ||||
-rw-r--r-- | sc/inc/simpleformulacalc.hxx | 54 | ||||
-rw-r--r-- | sc/source/core/data/simpleformulacalc.cxx | 100 | ||||
-rw-r--r-- | sc/source/core/tool/interpr4.cxx | 10 | ||||
-rw-r--r-- | sc/source/ui/app/inputhdl.cxx | 22 | ||||
-rw-r--r-- | sc/source/ui/formdlg/formula.cxx | 21 |
6 files changed, 179 insertions, 29 deletions
diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk index 373ba8a9abd5..9178c925d546 100644 --- a/sc/Library_sc.mk +++ b/sc/Library_sc.mk @@ -153,6 +153,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\ sc/source/core/data/postit \ sc/source/core/data/segmenttree \ sc/source/core/data/sheetevents \ + sc/source/core/data/simpleformulacalc \ sc/source/core/data/sortparam \ sc/source/core/data/stlpool \ sc/source/core/data/stlsheet \ diff --git a/sc/inc/simpleformulacalc.hxx b/sc/inc/simpleformulacalc.hxx new file mode 100644 index 000000000000..43ff6eac4acf --- /dev/null +++ b/sc/inc/simpleformulacalc.hxx @@ -0,0 +1,54 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef SC_SIMPLE_FORMULA_CALC_HXX +#define SC_SIMPLE_FORMULA_CALC_HXX + +#include <boost/scoped_ptr.hpp> +#include <formula/grammar.hxx> + +#include "address.hxx" +#include "formularesult.hxx" + +class ScDocument; +class ScTokenArray; + +class ScSimpleFormulaCalculator +{ +private: + short mnFormatType; + sal_uLong mnFormatIndex; + + bool mbCalculated; + boost::scoped_ptr<ScTokenArray> mpCode; + ScAddress maAddr; + ScDocument* mpDoc; + ScFormulaResult maResult; + +public: + ScSimpleFormulaCalculator(ScDocument* pDoc, const ScAddress& rAddr, + const OUString& rFormula, formula::FormulaGrammar::Grammar eGram = formula::FormulaGrammar::GRAM_DEFAULT); + ~ScSimpleFormulaCalculator(); + + void Calculate(); + bool IsValue(); + sal_uInt16 GetErrCode(); + double GetValue(); + OUString GetString(); + short GetFormatType() const { return mnFormatType; } + sal_uLong GetFormatIndex() const { return mnFormatIndex; } + + bool HasColRowName(); + + ScTokenArray* GetCode(); +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/data/simpleformulacalc.cxx b/sc/source/core/data/simpleformulacalc.cxx new file mode 100644 index 000000000000..1b2cd35f3b19 --- /dev/null +++ b/sc/source/core/data/simpleformulacalc.cxx @@ -0,0 +1,100 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "simpleformulacalc.hxx" +#include "document.hxx" +#include "tokenarray.hxx" +#include "interpre.hxx" +#include "compiler.hxx" + + +ScSimpleFormulaCalculator::ScSimpleFormulaCalculator( ScDocument* pDoc, const ScAddress& rAddr, + const OUString& rFormula, formula::FormulaGrammar::Grammar eGram ): + mbCalculated(false), + maAddr(rAddr), + mpDoc(pDoc) +{ + // compile already here + ScCompiler aComp(pDoc, rAddr); + aComp.SetGrammar(eGram); + mpCode.reset(aComp.CompileString(rFormula)); + if(!mpCode->GetCodeError() && mpCode->GetLen()) + aComp.CompileTokenArray(); +} + +ScSimpleFormulaCalculator::~ScSimpleFormulaCalculator() +{ +} + +void ScSimpleFormulaCalculator::Calculate() +{ + if(mbCalculated) + return; + + mbCalculated = true; + ScInterpreter aInt(NULL, mpDoc, maAddr, *mpCode.get()); + aInt.Interpret(); + + mnFormatType = aInt.GetRetFormatType(); + mnFormatIndex = aInt.GetRetFormatIndex(); + maResult.SetToken(aInt.GetResultToken().get()); +} + +bool ScSimpleFormulaCalculator::IsValue() +{ + Calculate(); + + return maResult.IsValue(); +} + +sal_uInt16 ScSimpleFormulaCalculator::GetErrCode() +{ + Calculate(); + + sal_uInt16 nErr = mpCode->GetCodeError(); + if (nErr) + return nErr; + return maResult.GetResultError(); +} + + +double ScSimpleFormulaCalculator::GetValue() +{ + Calculate(); + + if ((!mpCode->GetCodeError() || mpCode->GetCodeError() == errDoubleRef) && + !maResult.GetResultError()) + return maResult.GetDouble(); + + return 0.0; +} + +OUString ScSimpleFormulaCalculator::GetString() +{ + Calculate(); + + if ((!mpCode->GetCodeError() || mpCode->GetCodeError() == errDoubleRef) && + !maResult.GetResultError()) + return maResult.GetString(); + + return OUString(); +} + +bool ScSimpleFormulaCalculator::HasColRowName() +{ + mpCode->Reset(); + return mpCode->GetNextColRowName() != NULL; +} + +ScTokenArray* ScSimpleFormulaCalculator::GetCode() +{ + return mpCode.get(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx index d98b0441904a..7fd4ef7d0c3f 100644 --- a/sc/source/core/tool/interpr4.cxx +++ b/sc/source/core/tool/interpr4.cxx @@ -3724,8 +3724,14 @@ ScInterpreter::ScInterpreter( ScFormulaCell* pCell, ScDocument* pDoc, { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTTT" ); - sal_uInt8 cMatFlag = pMyFormulaCell->GetMatrixFlag(); - bMatrixFormula = ( cMatFlag == MM_FORMULA || cMatFlag == MM_FAKE ); + if(pMyFormulaCell) + { + sal_uInt8 cMatFlag = pMyFormulaCell->GetMatrixFlag(); + bMatrixFormula = ( cMatFlag == MM_FORMULA || cMatFlag == MM_FAKE ); + } + else + bMatrixFormula = false; + if (!bGlobalStackInUse) { bGlobalStackInUse = true; diff --git a/sc/source/ui/app/inputhdl.cxx b/sc/source/ui/app/inputhdl.cxx index 90cba301d99f..090d0cd4cf6f 100644 --- a/sc/source/ui/app/inputhdl.cxx +++ b/sc/source/ui/app/inputhdl.cxx @@ -70,7 +70,7 @@ #include "userlist.hxx" #include "rfindlst.hxx" #include "inputopt.hxx" -#include "formulacell.hxx" // fuer Formel-Preview +#include "simpleformulacalc.hxx" #include "compiler.hxx" // fuer Formel-Preview #include "editable.hxx" #include "funcdesc.hxx" @@ -1307,48 +1307,48 @@ static OUString lcl_Calculate( const OUString& rFormula, ScDocument* pDoc, const if(rFormula.isEmpty()) return String(); - boost::scoped_ptr<ScFormulaCell> pCell(new ScFormulaCell( pDoc, rPos, rFormula )); + boost::scoped_ptr<ScSimpleFormulaCalculator> pCalc( new ScSimpleFormulaCalculator( pDoc, rPos, rFormula ) ); // HACK! um bei ColRowNames kein #REF! zu bekommen, // wenn ein Name eigentlich als Bereich in die Gesamt-Formel // eingefuegt wird, bei der Einzeldarstellung aber als // single-Zellbezug interpretiert wird - bool bColRowName = pCell->HasColRowName(); + bool bColRowName = pCalc->HasColRowName(); if ( bColRowName ) { // ColRowName im RPN-Code? - if ( pCell->GetCode()->GetCodeLen() <= 1 ) + if ( pCalc->GetCode()->GetCodeLen() <= 1 ) { // ==1: einzelner ist als Parameter immer Bereich // ==0: es waere vielleicht einer, wenn.. OUStringBuffer aBraced; aBraced.append('('); aBraced.append(rFormula); aBraced.append(')'); - pCell.reset(new ScFormulaCell( pDoc, rPos, aBraced.makeStringAndClear() )); + pCalc.reset( new ScSimpleFormulaCalculator( pDoc, rPos, aBraced.makeStringAndClear() ) ); } else bColRowName = false; } - sal_uInt16 nErrCode = pCell->GetErrCode(); + sal_uInt16 nErrCode = pCalc->GetErrCode(); if ( nErrCode != 0 ) return ScGlobal::GetErrorString(nErrCode); SvNumberFormatter& aFormatter = *(pDoc->GetFormatTable()); OUString aValue; - if ( pCell->IsValue() ) + if ( pCalc->IsValue() ) { - double n = pCell->GetValue(); + double n = pCalc->GetValue(); sal_uLong nFormat = aFormatter.GetStandardFormat( n, 0, - pCell->GetFormatType(), ScGlobal::eLnge ); + pCalc->GetFormatType(), ScGlobal::eLnge ); aFormatter.GetInputLineString( n, nFormat, aValue ); //! display OutputString but insert InputLineString } else { - OUString aStr = pCell->GetString(); + OUString aStr = pCalc->GetString(); sal_uLong nFormat = aFormatter.GetStandardFormat( - pCell->GetFormatType(), ScGlobal::eLnge); + pCalc->GetFormatType(), ScGlobal::eLnge); { Color* pColor; aFormatter.GetOutputString( aStr, nFormat, diff --git a/sc/source/ui/formdlg/formula.cxx b/sc/source/ui/formdlg/formula.cxx index 6b04dc3435b9..522a277bf875 100644 --- a/sc/source/ui/formdlg/formula.cxx +++ b/sc/source/ui/formdlg/formula.cxx @@ -39,7 +39,7 @@ #include "scresid.hxx" #include "reffact.hxx" #include "document.hxx" -#include "formulacell.hxx" +#include "simpleformulacalc.hxx" #include "scmod.hxx" #include "inputhdl.hxx" #include "tabvwsh.hxx" @@ -184,8 +184,6 @@ ScFormulaDlg::ScFormulaDlg( SfxBindings* pB, SfxChildWindow* pCW, pData->SetMode( (sal_uInt16) eMode ); String rStrExp = GetMeText(); - pCell = new ScFormulaCell( pDoc, aCursorPos, rStrExp ); - Update(rStrExp); } @@ -241,8 +239,6 @@ void ScFormulaDlg::fill() SetMeText(rStrExp); - pCell = new ScFormulaCell( pDoc, aCursorPos, rStrExp ); - Update(); // Jetzt nochmals zurueckschalten, da evtl. neues Doc geoeffnet wurde! pScMod->SetRefInputHdl(NULL); @@ -260,8 +256,6 @@ ScFormulaDlg::~ScFormulaDlg() pScMod->SetRefInputHdl(NULL); StoreFormEditData(pData); } // if (pData) // wird nicht ueber Close zerstoert; - - delete pCell; } sal_Bool ScFormulaDlg::IsInputHdl(ScInputHandler* pHdl) @@ -316,24 +310,24 @@ sal_Bool ScFormulaDlg::Close() // -------------------------------------------------------------------------- bool ScFormulaDlg::calculateValue( const String& rStrExp, String& rStrResult ) { - boost::scoped_ptr<ScFormulaCell> pFCell( new ScFormulaCell( pDoc, aCursorPos, rStrExp ) ); + boost::scoped_ptr<ScSimpleFormulaCalculator> pFCell( new ScSimpleFormulaCalculator( pDoc, aCursorPos, rStrExp ) ); // HACK! um bei ColRowNames kein #REF! zu bekommen, // wenn ein Name eigentlich als Bereich in die Gesamt-Formel // eingefuegt wird, bei der Einzeldarstellung aber als // single-Zellbezug interpretiert wird - sal_Bool bColRowName = pCell->HasColRowName(); + sal_Bool bColRowName = pFCell->HasColRowName(); if ( bColRowName ) { // ColRowName im RPN-Code? - if ( pCell->GetCode()->GetCodeLen() <= 1 ) + if ( pFCell->GetCode()->GetCodeLen() <= 1 ) { // ==1: einzelner ist als Parameter immer Bereich // ==0: es waere vielleicht einer, wenn.. OUStringBuffer aBraced; aBraced.append('('); aBraced.append(rStrExp); aBraced.append(')'); - pFCell.reset( new ScFormulaCell( pDoc, aCursorPos, aBraced.makeStringAndClear() ) ); + pFCell.reset( new ScSimpleFormulaCalculator( pDoc, aCursorPos, aBraced.makeStringAndClear() ) ); } else bColRowName = false; @@ -371,11 +365,6 @@ bool ScFormulaDlg::calculateValue( const String& rStrExp, String& rStrResult ) else rStrResult += ScGlobal::GetErrorString(nErrCode); - if(!isUserMatrix() && pFCell->GetMatrixFlag()) - { - CheckMatrix(); - } - return true; } |