summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--formula/inc/formula/token.hxx3
-rw-r--r--sc/inc/cell.hxx8
-rw-r--r--sc/inc/formularesult.hxx4
-rw-r--r--sc/inc/token.hxx45
-rw-r--r--sc/source/core/data/cell.cxx8
-rw-r--r--sc/source/core/data/cell2.cxx9
-rw-r--r--sc/source/core/tool/cellform.cxx2
-rw-r--r--sc/source/core/tool/formularesult.cxx19
-rw-r--r--sc/source/core/tool/token.cxx8
-rw-r--r--sc/source/filter/xml/xmlcelli.cxx14
10 files changed, 86 insertions, 34 deletions
diff --git a/formula/inc/formula/token.hxx b/formula/inc/formula/token.hxx
index b72234e8fae5..3a174d7b9d4f 100644
--- a/formula/inc/formula/token.hxx
+++ b/formula/inc/formula/token.hxx
@@ -58,6 +58,9 @@ enum StackVarEnum
// and/or string result and a formula
// string to be compiled.
+ svHybridValueCell, // A temporary formula cell with an value
+ // and possibily a string representation
+
svExternalSingleRef,
svExternalDoubleRef,
svExternalName,
diff --git a/sc/inc/cell.hxx b/sc/inc/cell.hxx
index 716b76f4113c..d146a98d2ee3 100644
--- a/sc/inc/cell.hxx
+++ b/sc/inc/cell.hxx
@@ -430,6 +430,7 @@ public:
// display as empty string if formula::svEmptyCell result
bool IsEmptyDisplayedAsString();
bool IsValue(); // also true if formula::svEmptyCell
+ bool IsHybridValueCell(); // for cells after import to deal with inherited number formats
double GetValue();
double GetValueAlways(); // ignore errors
rtl::OUString GetString();
@@ -493,6 +494,13 @@ public:
const formula::FormulaGrammar::Grammar eGrammar )
{ aResult.SetHybridFormula( r); eTempGrammar = eGrammar; }
+ /**
+ * For import only: use for formula cells that return a number
+ * formatted as some kind of string
+ */
+ void SetHybridValueString( double nVal, const OUString& r )
+ { aResult.SetHybridValueString( nVal, r ); }
+
void SetResultMatrix( SCCOL nCols, SCROW nRows, const ScConstMatrixRef& pMat, formula::FormulaToken* pUL )
{
aResult.SetMatrix(nCols, nRows, pMat, pUL);
diff --git a/sc/inc/formularesult.hxx b/sc/inc/formularesult.hxx
index 2128636816b6..673bcdbf84bc 100644
--- a/sc/inc/formularesult.hxx
+++ b/sc/inc/formularesult.hxx
@@ -162,7 +162,7 @@ public:
ScConstMatrixRef GetMatrix() const;
/** Return formula string if type formula::svHybridCell, else empty string. */
- const String& GetHybridFormula() const;
+ const OUString& GetHybridFormula() const;
/** Should only be used by import filters, best in the order
SetHybridDouble(), SetHybridString(), or only SetHybridString() for
@@ -179,6 +179,8 @@ public:
SetHybridFormula() for formula string to be compiled later. */
SC_DLLPUBLIC void SetHybridFormula( const String & rFormula );
+ void SetHybridValueString( double nVal, const OUString& rStr );
+
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
diff --git a/sc/inc/token.hxx b/sc/inc/token.hxx
index e08db6cb440c..a54055561bae 100644
--- a/sc/inc/token.hxx
+++ b/sc/inc/token.hxx
@@ -414,26 +414,37 @@ public:
class SC_DLLPUBLIC ScHybridCellToken : public ScToken
{
private:
- double fDouble;
- String aString;
- String aFormula;
+ double mfDouble;
+ String maString;
+ OUString maFormula;
public:
- ScHybridCellToken( double f,
- const String & rStr,
- const String & rFormula ) :
- ScToken( formula::svHybridCell ),
- fDouble( f ), aString( rStr ),
- aFormula( rFormula ) {}
- ScHybridCellToken( const ScHybridCellToken& r ) :
- ScToken( r ), fDouble( r.fDouble),
- aString( r.aString), aFormula( r.aFormula) {}
- const String & GetFormula() const { return aFormula; }
- virtual double GetDouble() const;
- virtual const String & GetString() const;
- virtual bool operator==( const formula::FormulaToken& rToken ) const;
- virtual FormulaToken* Clone() const { return new ScHybridCellToken(*this); }
+ ScHybridCellToken( double f,
+ const OUString & rStr,
+ const OUString & rFormula ) :
+ ScToken( formula::svHybridCell ),
+ mfDouble( f ), maString( rStr ),
+ maFormula( rFormula ) {}
+
+ const OUString& GetFormula() const { return maFormula; }
+ virtual double GetDouble() const;
+ virtual const String& GetString() const;
+ virtual bool operator==( const formula::FormulaToken& rToken ) const;
+ virtual FormulaToken* Clone() const { return new ScHybridCellToken(*this); }
};
+class SC_DLLPUBLIC ScHybridValueCellToken : public ScToken
+{
+private:
+ double mfValue;
+ String maString;
+public:
+ ScHybridValueCellToken (double f, const OUString& rStr ):
+ ScToken( formula::svHybridValueCell ),
+ mfValue( f ), maString( rStr ) {}
+
+ virtual double GetDouble() const { return mfValue; }
+ virtual const String & GetString() const { return maString; }
+};
// Simplify argument passing to RefUpdate methods with ScSingleRefToken or
// ScDoubleRefToken
diff --git a/sc/source/core/data/cell.cxx b/sc/source/core/data/cell.cxx
index ce073e2e29eb..2b0366c2f543 100644
--- a/sc/source/core/data/cell.cxx
+++ b/sc/source/core/data/cell.cxx
@@ -988,7 +988,7 @@ void ScFormulaCell::Compile( const rtl::OUString& rFormula, bool bNoListening,
delete pCodeOld;
if( !pCode->GetCodeError() )
{
- if ( !pCode->GetLen() && aResult.GetHybridFormula().Len() && rFormula == rtl::OUString(aResult.GetHybridFormula()) )
+ if ( !pCode->GetLen() && !aResult.GetHybridFormula().isEmpty() && rFormula == aResult.GetHybridFormula() )
{ // not recursive CompileTokenArray/Compile/CompileTokenArray
if ( rFormula[0] == '=' )
pCode->AddBad( rFormula.copy(1) );
@@ -1012,7 +1012,7 @@ void ScFormulaCell::Compile( const rtl::OUString& rFormula, bool bNoListening,
void ScFormulaCell::CompileTokenArray( bool bNoListening )
{
// Not already compiled?
- if( !pCode->GetLen() && aResult.GetHybridFormula().Len() )
+ if( !pCode->GetLen() && !aResult.GetHybridFormula().isEmpty() )
Compile( aResult.GetHybridFormula(), bNoListening, eTempGrammar);
else if( bCompile && !pDocument->IsClipOrUndo() && !pCode->GetCodeError() )
{
@@ -1120,7 +1120,7 @@ void ScFormulaCell::CalcAfterLoad()
{
bool bNewCompiled = false;
// If a Calc 1.0-doc is read, we have a result, but no token array
- if( !pCode->GetLen() && aResult.GetHybridFormula().Len() )
+ if( !pCode->GetLen() && !aResult.GetHybridFormula().isEmpty() )
{
Compile( aResult.GetHybridFormula(), true, eTempGrammar);
aResult.SetToken( NULL);
@@ -1469,7 +1469,7 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
// This should only be a temporary condition and, since we set an
// error, if ran into it again we'd bump into the dirty-clearing
// condition further down.
- if ( !pCode->GetLen() && aResult.GetHybridFormula().Len() )
+ if ( !pCode->GetLen() && !aResult.GetHybridFormula().isEmpty() )
{
pCode->SetCodeError( errNoCode );
// This is worth an assertion; if encountered in daily work
diff --git a/sc/source/core/data/cell2.cxx b/sc/source/core/data/cell2.cxx
index c43f0c12004d..73c960c62c96 100644
--- a/sc/source/core/data/cell2.cxx
+++ b/sc/source/core/data/cell2.cxx
@@ -496,6 +496,11 @@ bool ScFormulaCell::IsValue()
return aResult.IsValue();
}
+bool ScFormulaCell::IsHybridValueCell()
+{
+ return aResult.GetType() == formula::svHybridValueCell;
+}
+
double ScFormulaCell::GetValue()
{
MaybeInterpret();
@@ -1600,7 +1605,7 @@ void ScFormulaCell::CompileDBFormula( bool bCreateFormulaString )
SetHybridFormula( aFormula, formula::FormulaGrammar::GRAM_NATIVE);
}
}
- else if ( !pCode->GetLen() && aResult.GetHybridFormula().Len() )
+ else if ( !pCode->GetLen() && !aResult.GetHybridFormula().isEmpty() )
{
Compile( aResult.GetHybridFormula(), false, eTempGrammar );
aResult.SetToken( NULL);
@@ -1647,7 +1652,7 @@ void ScFormulaCell::CompileNameFormula( bool bCreateFormulaString )
SetHybridFormula( aFormula, formula::FormulaGrammar::GRAM_NATIVE);
}
}
- else if ( !pCode->GetLen() && aResult.GetHybridFormula().Len() )
+ else if ( !pCode->GetLen() && !aResult.GetHybridFormula().isEmpty() )
{
Compile( aResult.GetHybridFormula(), false, eTempGrammar );
aResult.SetToken( NULL);
diff --git a/sc/source/core/tool/cellform.cxx b/sc/source/core/tool/cellform.cxx
index 01dc61be7470..4a3ecc668d50 100644
--- a/sc/source/core/tool/cellform.cxx
+++ b/sc/source/core/tool/cellform.cxx
@@ -125,6 +125,8 @@ void ScCellFormat::GetString( ScBaseCell* pCell, sal_uLong nFormat, rtl::OUStrin
double fValue = pFCell->GetValue();
if ( !bNullVals && fValue == 0.0 )
rString = rtl::OUString();
+ else if ( pFCell->IsHybridValueCell() )
+ rString = pFCell->GetString();
else
rFormatter.GetOutputString( fValue, nFormat, rString, ppColor, bUseStarFormat );
}
diff --git a/sc/source/core/tool/formularesult.cxx b/sc/source/core/tool/formularesult.cxx
index 9e1032ec9d44..9139c9a1c20c 100644
--- a/sc/source/core/tool/formularesult.cxx
+++ b/sc/source/core/tool/formularesult.cxx
@@ -268,6 +268,8 @@ bool ScFormulaResult::IsEmptyDisplayedAsString() const
bool ScFormulaResult::IsValue() const
{
formula::StackVar sv = GetCellResultType();
+ if( sv == formula::svHybridValueCell )
+ return true;
return sv == formula::svDouble || sv == formula::svError || sv == formula::svEmptyCell;
}
@@ -331,6 +333,8 @@ double ScFormulaResult::GetDouble() const
switch (mpToken->GetType())
{
case formula::svHybridCell:
+ case formula::svHybridValueCell:
+ return mpToken->GetDouble();
return mpToken->GetDouble();
case formula::svMatrixCell:
{
@@ -359,6 +363,7 @@ const String & ScFormulaResult::GetString() const
{
case formula::svString:
case formula::svHybridCell:
+ case formula::svHybridValueCell:
return mpToken->GetString();
case formula::svMatrixCell:
{
@@ -382,7 +387,7 @@ ScConstMatrixRef ScFormulaResult::GetMatrix() const
return NULL;
}
-const String & ScFormulaResult::GetHybridFormula() const
+const OUString& ScFormulaResult::GetHybridFormula() const
{
if (GetType() == formula::svHybridCell)
{
@@ -390,7 +395,7 @@ const String & ScFormulaResult::GetHybridFormula() const
if (p)
return p->GetFormula();
}
- return EMPTY_STRING;
+ return EMPTY_OUSTRING;
}
void ScFormulaResult::SetHybridDouble( double f )
@@ -443,6 +448,16 @@ void ScFormulaResult::SetHybridFormula( const String & rFormula )
mbToken = true;
}
+void ScFormulaResult::SetHybridValueString( double nVal, const OUString& rStr )
+{
+ ResetToDefaults();
+ if (mbToken && mpToken)
+ mpToken->DecRef();
+ mpToken = new ScHybridValueCellToken( nVal, rStr );
+ mpToken->IncRef();
+ mbToken = true;
+}
+
void ScFormulaResult::SetMatrix( SCCOL nCols, SCROW nRows, const ScConstMatrixRef& pMat, formula::FormulaToken* pUL )
{
ResetToDefaults();
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 4ea3d4e056b6..8e8c329727ab 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -1096,13 +1096,13 @@ void ScMatrixFormulaCellToken::SetUpperLeftDouble( double f )
}
-double ScHybridCellToken::GetDouble() const { return fDouble; }
-const String & ScHybridCellToken::GetString() const { return aString; }
+double ScHybridCellToken::GetDouble() const { return mfDouble; }
+const String& ScHybridCellToken::GetString() const { return maString; }
bool ScHybridCellToken::operator==( const FormulaToken& r ) const
{
return FormulaToken::operator==( r ) &&
- fDouble == r.GetDouble() && aString == r.GetString() &&
- aFormula == static_cast<const ScHybridCellToken &>(r).GetFormula();
+ mfDouble == r.GetDouble() && maString == r.GetString() &&
+ maFormula == static_cast<const ScHybridCellToken &>(r).GetFormula();
}
diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx
index edf309bc9b94..e93f33df2112 100644
--- a/sc/source/filter/xml/xmlcelli.cxx
+++ b/sc/source/filter/xml/xmlcelli.cxx
@@ -352,9 +352,13 @@ SvXMLImportContext *ScXMLTableRowCellContext::CreateChildContext( sal_uInt16 nPr
ScAddress aCellPos = rXMLImport.GetTables().GetCurrentCellPos();
- if( ((nCellType == util::NumberFormat::TEXT) || bFormulaTextResult) )
+ if( ((nCellType == util::NumberFormat::TEXT) || pOUFormula) )
{
- if (!bHasTextImport)
+ if ( pOUFormula )
+ {
+ pContext = new ScXMLTextPContext(rXMLImport, nPrefix, rLName, xAttrList, this);
+ }
+ else if (!bHasTextImport)
{
bIsFirstTextImport = true;
bHasTextImport = true;
@@ -733,11 +737,13 @@ void ScXMLTableRowCellContext::SetFormulaCell(ScFormulaCell* pFCell) const
}
else if (!rtl::math::isNan(fValue))
{
- pFCell->SetHybridDouble(fValue);
+ if( pOUTextContent )
+ pFCell->SetHybridValueString( fValue, *pOUTextContent );
+ else
+ pFCell->SetHybridDouble(fValue);
pFCell->ResetDirty();
}
pFCell->StartListeningTo(rXMLImport.GetDocument());
- // Leave the cell dirty when the cached result is not given.
}
}