summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarkus Mohrhard <markus.mohrhard@googlemail.com>2013-05-07 00:59:48 +0200
committerMarkus Mohrhard <markus.mohrhard@googlemail.com>2013-06-02 03:24:56 +0200
commit1a663077de77bdbb7edfe2283d9e9bc93e90594f (patch)
treebb7ecb4df6e776f0a38ec3e5749a4fe3bdb5ec24
parent58545dee13cd54ac7e2d7e776efdc46534086e11 (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
-rw-r--r--sc/Library_sc.mk1
-rw-r--r--sc/inc/simpleformulacalc.hxx54
-rw-r--r--sc/source/core/data/simpleformulacalc.cxx100
-rw-r--r--sc/source/core/tool/interpr4.cxx10
-rw-r--r--sc/source/ui/app/inputhdl.cxx22
-rw-r--r--sc/source/ui/formdlg/formula.cxx21
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;
}