Kaydet (Commit) 83cbbc6d authored tarafından Eike Rathke's avatar Eike Rathke

tdf#96475 restore the EmptyDisplayedAsString condition during load

So also "empty" result cells with a number format applied are displayed empty,
instead of 1899-12-30 for example.

Change-Id: I5280d0213b8a809a04c5cb152ded58028706493a
üst ed5a8df7
......@@ -341,6 +341,13 @@ public:
SetHybridString() or SetHybridFormula(), use SetHybridDouble() first
for performance reasons.*/
void SetHybridString( const svl::SharedString& r );
/** For import only: set an empty cell result to be displayed as empty string.
If for whatever reason you have to use both, SetHybridDouble() and
SetHybridEmptyDisplayedAsString() or SetHybridFormula(), use
SetHybridDouble() first for performance reasons and use
SetHybridEmptyDisplayedAsString() last because SetHybridDouble() and
SetHybridString() will override it.*/
void SetHybridEmptyDisplayedAsString();
/** For import only: set a temporary formula string to be compiled later.
If for whatever reason you have to use both, SetHybridDouble() and
SetHybridString() or SetHybridFormula(), use SetHybridDouble() first
......
......@@ -188,7 +188,7 @@ public:
const OUString& GetHybridFormula() const;
/** Should only be used by import filters, best in the order
SetHybridDouble(), SetHybridString(), or only SetHybridString() for
SetHybridDouble(), SetHybridString(), or only SetHybridFormula() for
formula string to be compiled later. */
SC_DLLPUBLIC void SetHybridDouble( double f );
......@@ -197,6 +197,11 @@ public:
SetHybridFormula() for formula string to be compiled later. */
SC_DLLPUBLIC void SetHybridString( const svl::SharedString & rStr );
/** Should only be used by import filters, best in the order
SetHybridDouble(), SetHybridFormula(),
SetHybridEmptyDisplayedAsString() must be last. */
SC_DLLPUBLIC void SetHybridEmptyDisplayedAsString();
/** Should only be used by import filters, best in the order
SetHybridDouble(), SetHybridString()/SetHybridFormula(), or only
SetHybridFormula() for formula string to be compiled later. */
......
......@@ -388,11 +388,13 @@ private:
double mfDouble;
svl::SharedString maString;
OUString maFormula;
bool mbEmptyDisplayedAsString;
public:
ScHybridCellToken(
double f, const svl::SharedString & rStr, const OUString & rFormula );
double f, const svl::SharedString & rStr, const OUString & rFormula, bool bEmptyDisplayedAsString );
const OUString& GetFormula() const { return maFormula; }
bool IsEmptyDisplayedAsString() const { return mbEmptyDisplayedAsString; }
virtual double GetDouble() const override;
virtual svl::SharedString GetString() const override;
......
......@@ -2464,6 +2464,11 @@ void ScFormulaCell::SetHybridString( const svl::SharedString& r )
aResult.SetHybridString( r);
}
void ScFormulaCell::SetHybridEmptyDisplayedAsString()
{
aResult.SetHybridEmptyDisplayedAsString();
}
void ScFormulaCell::SetHybridFormula( const OUString& r,
const formula::FormulaGrammar::Grammar eGrammar )
{
......
......@@ -243,14 +243,27 @@ bool ScFormulaResult::IsEmptyDisplayedAsString() const
{
if (mbEmpty)
return mbEmptyDisplayedAsString;
if (GetType() == formula::svMatrixCell)
switch (GetType())
{
// don't need to test for mpToken here, GetType() already did it
const ScEmptyCellToken* p = dynamic_cast<const ScEmptyCellToken*>(
static_cast<const ScMatrixCellResultToken*>(
mpToken)->GetUpperLeftToken().get());
if (p)
return p->IsDisplayedAsString();
case formula::svMatrixCell:
{
// don't need to test for mpToken here, GetType() already did it
const ScEmptyCellToken* p = dynamic_cast<const ScEmptyCellToken*>(
static_cast<const ScMatrixCellResultToken*>(
mpToken)->GetUpperLeftToken().get());
if (p)
return p->IsDisplayedAsString();
}
break;
case formula::svHybridCell:
{
const ScHybridCellToken* p = dynamic_cast<const ScHybridCellToken*>(mpToken);
if (p)
return p->IsEmptyDisplayedAsString();
}
break;
default:
break;
}
return false;
}
......@@ -505,7 +518,7 @@ void ScFormulaResult::SetHybridDouble( double f )
svl::SharedString aString = GetString();
OUString aFormula( GetHybridFormula());
mpToken->DecRef();
mpToken = new ScHybridCellToken( f, aString, aFormula);
mpToken = new ScHybridCellToken( f, aString, aFormula, false);
mpToken->IncRef();
}
}
......@@ -525,7 +538,24 @@ void ScFormulaResult::SetHybridString( const svl::SharedString& rStr )
ResetToDefaults();
if (mbToken && mpToken)
mpToken->DecRef();
mpToken = new ScHybridCellToken( f, rStr, aFormula);
mpToken = new ScHybridCellToken( f, rStr, aFormula, false);
mpToken->IncRef();
mbToken = true;
}
void ScFormulaResult::SetHybridEmptyDisplayedAsString()
{
// Obtain values before changing anything.
double f = GetDouble();
OUString aFormula( GetHybridFormula());
svl::SharedString aStr = GetString();
ResetToDefaults();
if (mbToken && mpToken)
mpToken->DecRef();
// XXX NOTE: we can't use mbEmpty and mbEmptyDisplayedAsString here because
// GetType() intentionally returns svEmptyCell if mbEmpty==true. So stick
// it into the ScHybridCellToken.
mpToken = new ScHybridCellToken( f, aStr, aFormula, true);
mpToken->IncRef();
mbToken = true;
}
......@@ -538,7 +568,7 @@ void ScFormulaResult::SetHybridFormula( const OUString & rFormula )
ResetToDefaults();
if (mbToken && mpToken)
mpToken->DecRef();
mpToken = new ScHybridCellToken( f, aStr, rFormula);
mpToken = new ScHybridCellToken( f, aStr, rFormula, false);
mpToken->IncRef();
mbToken = true;
}
......
......@@ -1154,11 +1154,14 @@ void ScMatrixFormulaCellToken::ResetResult()
}
ScHybridCellToken::ScHybridCellToken(
double f, const svl::SharedString & rStr, const OUString & rFormula ) :
double f, const svl::SharedString & rStr, const OUString & rFormula, bool bEmptyDisplayedAsString ) :
FormulaToken( formula::svHybridCell ),
mfDouble( f ), maString( rStr ),
maFormula( rFormula )
maFormula( rFormula ),
mbEmptyDisplayedAsString( bEmptyDisplayedAsString)
{
// caller, make up your mind..
assert( !bEmptyDisplayedAsString || (f == 0.0 && rStr.getString().isEmpty()));
}
double ScHybridCellToken::GetDouble() const { return mfDouble; }
......
......@@ -165,7 +165,8 @@ ScXMLTableRowCellContext::ScXMLTableRowCellContext( ScXMLImport& rImport,
mbCheckWithCompilerForError(false),
mbEditEngineHasText(false),
mbHasFormatRuns(false),
mbHasStyle(false)
mbHasStyle(false),
mbPossibleEmptyDisplay(false)
{
rtl::math::setNan(&fValue); // NaN by default
......@@ -1028,6 +1029,8 @@ void ScXMLTableRowCellContext::SetFormulaCell(ScFormulaCell* pFCell) const
else if (rtl::math::isFinite(fValue))
{
pFCell->SetHybridDouble(fValue);
if (mbPossibleEmptyDisplay && fValue == 0.0)
pFCell->SetHybridEmptyDisplayedAsString();
pFCell->ResetDirty();
}
}
......@@ -1452,12 +1455,24 @@ void ScXMLTableRowCellContext::AddFormulaCell( const ScAddress& rCellPos )
// Libreoffice 4.1+ with ODF1.2 extended write however calcext:value-type="error" in that case
void ScXMLTableRowCellContext::HasSpecialCaseFormulaText()
{
if (!mbEditEngineHasText || mbNewValueType)
if (!mbEditEngineHasText)
return;
OUString aStr = GetFirstParagraph();
const OUString aStr = GetFirstParagraph();
if (aStr.isEmpty() || aStr.startsWith("Err:"))
if (mbNewValueType)
{
if (aStr.isEmpty())
mbPossibleEmptyDisplay = true;
return;
}
if (aStr.isEmpty())
{
mbPossibleErrorCell = true;
mbPossibleEmptyDisplay = true;
}
else if (aStr.startsWith("Err:"))
mbPossibleErrorCell = true;
else if (aStr.startsWith("#"))
mbCheckWithCompilerForError = true;
......
......@@ -96,6 +96,7 @@ class ScXMLTableRowCellContext : public ScXMLImportContext
bool mbEditEngineHasText;
bool mbHasFormatRuns;
bool mbHasStyle;
bool mbPossibleEmptyDisplay;
void DoMerge(const ScAddress& rScCellPos, const SCCOL nCols, const SCROW nRows);
......
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