Kaydet (Commit) ae516fab authored tarafından Markus Mohrhard's avatar Markus Mohrhard

import inherited number formats with cached values, fdo#59724

Change-Id: I698f60daf4e591b57d8d99c130d2e524dc10c306
üst c3ea61ab
...@@ -58,6 +58,9 @@ enum StackVarEnum ...@@ -58,6 +58,9 @@ enum StackVarEnum
// and/or string result and a formula // and/or string result and a formula
// string to be compiled. // string to be compiled.
svHybridValueCell, // A temporary formula cell with an value
// and possibily a string representation
svExternalSingleRef, svExternalSingleRef,
svExternalDoubleRef, svExternalDoubleRef,
svExternalName, svExternalName,
......
...@@ -430,6 +430,7 @@ public: ...@@ -430,6 +430,7 @@ public:
// display as empty string if formula::svEmptyCell result // display as empty string if formula::svEmptyCell result
bool IsEmptyDisplayedAsString(); bool IsEmptyDisplayedAsString();
bool IsValue(); // also true if formula::svEmptyCell bool IsValue(); // also true if formula::svEmptyCell
bool IsHybridValueCell(); // for cells after import to deal with inherited number formats
double GetValue(); double GetValue();
double GetValueAlways(); // ignore errors double GetValueAlways(); // ignore errors
rtl::OUString GetString(); rtl::OUString GetString();
...@@ -493,6 +494,13 @@ public: ...@@ -493,6 +494,13 @@ public:
const formula::FormulaGrammar::Grammar eGrammar ) const formula::FormulaGrammar::Grammar eGrammar )
{ aResult.SetHybridFormula( r); eTempGrammar = 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 ) void SetResultMatrix( SCCOL nCols, SCROW nRows, const ScConstMatrixRef& pMat, formula::FormulaToken* pUL )
{ {
aResult.SetMatrix(nCols, nRows, pMat, pUL); aResult.SetMatrix(nCols, nRows, pMat, pUL);
......
...@@ -162,7 +162,7 @@ public: ...@@ -162,7 +162,7 @@ public:
ScConstMatrixRef GetMatrix() const; ScConstMatrixRef GetMatrix() const;
/** Return formula string if type formula::svHybridCell, else empty string. */ /** 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 /** Should only be used by import filters, best in the order
SetHybridDouble(), SetHybridString(), or only SetHybridString() for SetHybridDouble(), SetHybridString(), or only SetHybridString() for
...@@ -179,6 +179,8 @@ public: ...@@ -179,6 +179,8 @@ public:
SetHybridFormula() for formula string to be compiled later. */ SetHybridFormula() for formula string to be compiled later. */
SC_DLLPUBLIC void SetHybridFormula( const String & rFormula ); 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 ); 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 /** Get the const ScMatrixFormulaCellToken* if token is of that type, else
......
...@@ -414,26 +414,37 @@ public: ...@@ -414,26 +414,37 @@ public:
class SC_DLLPUBLIC ScHybridCellToken : public ScToken class SC_DLLPUBLIC ScHybridCellToken : public ScToken
{ {
private: private:
double fDouble; double mfDouble;
String aString; String maString;
String aFormula; OUString maFormula;
public: public:
ScHybridCellToken( double f, ScHybridCellToken( double f,
const String & rStr, const OUString & rStr,
const String & rFormula ) : const OUString & rFormula ) :
ScToken( formula::svHybridCell ), ScToken( formula::svHybridCell ),
fDouble( f ), aString( rStr ), mfDouble( f ), maString( rStr ),
aFormula( rFormula ) {} maFormula( rFormula ) {}
ScHybridCellToken( const ScHybridCellToken& r ) :
ScToken( r ), fDouble( r.fDouble), const OUString& GetFormula() const { return maFormula; }
aString( r.aString), aFormula( r.aFormula) {} virtual double GetDouble() const;
const String & GetFormula() const { return aFormula; } virtual const String& GetString() const;
virtual double GetDouble() const; virtual bool operator==( const formula::FormulaToken& rToken ) const;
virtual const String & GetString() const; virtual FormulaToken* Clone() const { return new ScHybridCellToken(*this); }
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 // Simplify argument passing to RefUpdate methods with ScSingleRefToken or
// ScDoubleRefToken // ScDoubleRefToken
......
...@@ -988,7 +988,7 @@ void ScFormulaCell::Compile( const rtl::OUString& rFormula, bool bNoListening, ...@@ -988,7 +988,7 @@ void ScFormulaCell::Compile( const rtl::OUString& rFormula, bool bNoListening,
delete pCodeOld; delete pCodeOld;
if( !pCode->GetCodeError() ) 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 { // not recursive CompileTokenArray/Compile/CompileTokenArray
if ( rFormula[0] == '=' ) if ( rFormula[0] == '=' )
pCode->AddBad( rFormula.copy(1) ); pCode->AddBad( rFormula.copy(1) );
...@@ -1012,7 +1012,7 @@ void ScFormulaCell::Compile( const rtl::OUString& rFormula, bool bNoListening, ...@@ -1012,7 +1012,7 @@ void ScFormulaCell::Compile( const rtl::OUString& rFormula, bool bNoListening,
void ScFormulaCell::CompileTokenArray( bool bNoListening ) void ScFormulaCell::CompileTokenArray( bool bNoListening )
{ {
// Not already compiled? // Not already compiled?
if( !pCode->GetLen() && aResult.GetHybridFormula().Len() ) if( !pCode->GetLen() && !aResult.GetHybridFormula().isEmpty() )
Compile( aResult.GetHybridFormula(), bNoListening, eTempGrammar); Compile( aResult.GetHybridFormula(), bNoListening, eTempGrammar);
else if( bCompile && !pDocument->IsClipOrUndo() && !pCode->GetCodeError() ) else if( bCompile && !pDocument->IsClipOrUndo() && !pCode->GetCodeError() )
{ {
...@@ -1120,7 +1120,7 @@ void ScFormulaCell::CalcAfterLoad() ...@@ -1120,7 +1120,7 @@ void ScFormulaCell::CalcAfterLoad()
{ {
bool bNewCompiled = false; bool bNewCompiled = false;
// If a Calc 1.0-doc is read, we have a result, but no token array // 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); Compile( aResult.GetHybridFormula(), true, eTempGrammar);
aResult.SetToken( NULL); aResult.SetToken( NULL);
...@@ -1469,7 +1469,7 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam ) ...@@ -1469,7 +1469,7 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
// This should only be a temporary condition and, since we set an // 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 // error, if ran into it again we'd bump into the dirty-clearing
// condition further down. // condition further down.
if ( !pCode->GetLen() && aResult.GetHybridFormula().Len() ) if ( !pCode->GetLen() && !aResult.GetHybridFormula().isEmpty() )
{ {
pCode->SetCodeError( errNoCode ); pCode->SetCodeError( errNoCode );
// This is worth an assertion; if encountered in daily work // This is worth an assertion; if encountered in daily work
......
...@@ -496,6 +496,11 @@ bool ScFormulaCell::IsValue() ...@@ -496,6 +496,11 @@ bool ScFormulaCell::IsValue()
return aResult.IsValue(); return aResult.IsValue();
} }
bool ScFormulaCell::IsHybridValueCell()
{
return aResult.GetType() == formula::svHybridValueCell;
}
double ScFormulaCell::GetValue() double ScFormulaCell::GetValue()
{ {
MaybeInterpret(); MaybeInterpret();
...@@ -1600,7 +1605,7 @@ void ScFormulaCell::CompileDBFormula( bool bCreateFormulaString ) ...@@ -1600,7 +1605,7 @@ void ScFormulaCell::CompileDBFormula( bool bCreateFormulaString )
SetHybridFormula( aFormula, formula::FormulaGrammar::GRAM_NATIVE); 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 ); Compile( aResult.GetHybridFormula(), false, eTempGrammar );
aResult.SetToken( NULL); aResult.SetToken( NULL);
...@@ -1647,7 +1652,7 @@ void ScFormulaCell::CompileNameFormula( bool bCreateFormulaString ) ...@@ -1647,7 +1652,7 @@ void ScFormulaCell::CompileNameFormula( bool bCreateFormulaString )
SetHybridFormula( aFormula, formula::FormulaGrammar::GRAM_NATIVE); 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 ); Compile( aResult.GetHybridFormula(), false, eTempGrammar );
aResult.SetToken( NULL); aResult.SetToken( NULL);
......
...@@ -125,6 +125,8 @@ void ScCellFormat::GetString( ScBaseCell* pCell, sal_uLong nFormat, rtl::OUStrin ...@@ -125,6 +125,8 @@ void ScCellFormat::GetString( ScBaseCell* pCell, sal_uLong nFormat, rtl::OUStrin
double fValue = pFCell->GetValue(); double fValue = pFCell->GetValue();
if ( !bNullVals && fValue == 0.0 ) if ( !bNullVals && fValue == 0.0 )
rString = rtl::OUString(); rString = rtl::OUString();
else if ( pFCell->IsHybridValueCell() )
rString = pFCell->GetString();
else else
rFormatter.GetOutputString( fValue, nFormat, rString, ppColor, bUseStarFormat ); rFormatter.GetOutputString( fValue, nFormat, rString, ppColor, bUseStarFormat );
} }
......
...@@ -268,6 +268,8 @@ bool ScFormulaResult::IsEmptyDisplayedAsString() const ...@@ -268,6 +268,8 @@ bool ScFormulaResult::IsEmptyDisplayedAsString() const
bool ScFormulaResult::IsValue() const bool ScFormulaResult::IsValue() const
{ {
formula::StackVar sv = GetCellResultType(); formula::StackVar sv = GetCellResultType();
if( sv == formula::svHybridValueCell )
return true;
return sv == formula::svDouble || sv == formula::svError || sv == formula::svEmptyCell; return sv == formula::svDouble || sv == formula::svError || sv == formula::svEmptyCell;
} }
...@@ -331,6 +333,8 @@ double ScFormulaResult::GetDouble() const ...@@ -331,6 +333,8 @@ double ScFormulaResult::GetDouble() const
switch (mpToken->GetType()) switch (mpToken->GetType())
{ {
case formula::svHybridCell: case formula::svHybridCell:
case formula::svHybridValueCell:
return mpToken->GetDouble();
return mpToken->GetDouble(); return mpToken->GetDouble();
case formula::svMatrixCell: case formula::svMatrixCell:
{ {
...@@ -359,6 +363,7 @@ const String & ScFormulaResult::GetString() const ...@@ -359,6 +363,7 @@ const String & ScFormulaResult::GetString() const
{ {
case formula::svString: case formula::svString:
case formula::svHybridCell: case formula::svHybridCell:
case formula::svHybridValueCell:
return mpToken->GetString(); return mpToken->GetString();
case formula::svMatrixCell: case formula::svMatrixCell:
{ {
...@@ -382,7 +387,7 @@ ScConstMatrixRef ScFormulaResult::GetMatrix() const ...@@ -382,7 +387,7 @@ ScConstMatrixRef ScFormulaResult::GetMatrix() const
return NULL; return NULL;
} }
const String & ScFormulaResult::GetHybridFormula() const const OUString& ScFormulaResult::GetHybridFormula() const
{ {
if (GetType() == formula::svHybridCell) if (GetType() == formula::svHybridCell)
{ {
...@@ -390,7 +395,7 @@ const String & ScFormulaResult::GetHybridFormula() const ...@@ -390,7 +395,7 @@ const String & ScFormulaResult::GetHybridFormula() const
if (p) if (p)
return p->GetFormula(); return p->GetFormula();
} }
return EMPTY_STRING; return EMPTY_OUSTRING;
} }
void ScFormulaResult::SetHybridDouble( double f ) void ScFormulaResult::SetHybridDouble( double f )
...@@ -443,6 +448,16 @@ void ScFormulaResult::SetHybridFormula( const String & rFormula ) ...@@ -443,6 +448,16 @@ void ScFormulaResult::SetHybridFormula( const String & rFormula )
mbToken = true; 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 ) void ScFormulaResult::SetMatrix( SCCOL nCols, SCROW nRows, const ScConstMatrixRef& pMat, formula::FormulaToken* pUL )
{ {
ResetToDefaults(); ResetToDefaults();
......
...@@ -1096,13 +1096,13 @@ void ScMatrixFormulaCellToken::SetUpperLeftDouble( double f ) ...@@ -1096,13 +1096,13 @@ void ScMatrixFormulaCellToken::SetUpperLeftDouble( double f )
} }
double ScHybridCellToken::GetDouble() const { return fDouble; } double ScHybridCellToken::GetDouble() const { return mfDouble; }
const String & ScHybridCellToken::GetString() const { return aString; } const String& ScHybridCellToken::GetString() const { return maString; }
bool ScHybridCellToken::operator==( const FormulaToken& r ) const bool ScHybridCellToken::operator==( const FormulaToken& r ) const
{ {
return FormulaToken::operator==( r ) && return FormulaToken::operator==( r ) &&
fDouble == r.GetDouble() && aString == r.GetString() && mfDouble == r.GetDouble() && maString == r.GetString() &&
aFormula == static_cast<const ScHybridCellToken &>(r).GetFormula(); maFormula == static_cast<const ScHybridCellToken &>(r).GetFormula();
} }
......
...@@ -352,9 +352,13 @@ SvXMLImportContext *ScXMLTableRowCellContext::CreateChildContext( sal_uInt16 nPr ...@@ -352,9 +352,13 @@ SvXMLImportContext *ScXMLTableRowCellContext::CreateChildContext( sal_uInt16 nPr
ScAddress aCellPos = rXMLImport.GetTables().GetCurrentCellPos(); 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; bIsFirstTextImport = true;
bHasTextImport = true; bHasTextImport = true;
...@@ -733,11 +737,13 @@ void ScXMLTableRowCellContext::SetFormulaCell(ScFormulaCell* pFCell) const ...@@ -733,11 +737,13 @@ void ScXMLTableRowCellContext::SetFormulaCell(ScFormulaCell* pFCell) const
} }
else if (!rtl::math::isNan(fValue)) else if (!rtl::math::isNan(fValue))
{ {
pFCell->SetHybridDouble(fValue); if( pOUTextContent )
pFCell->SetHybridValueString( fValue, *pOUTextContent );
else
pFCell->SetHybridDouble(fValue);
pFCell->ResetDirty(); pFCell->ResetDirty();
} }
pFCell->StartListeningTo(rXMLImport.GetDocument()); pFCell->StartListeningTo(rXMLImport.GetDocument());
// Leave the cell dirty when the cached result is not given.
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment