Resolves: tdf#131372 Write "error cell" formula to OOXML

Change-Id: Iedbe0912ff28e6203bec0104c59b1102cf97daf9
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/91382
Reviewed-by: Eike Rathke <erack@redhat.com>
Tested-by: Jenkins
(cherry picked from commit 456f093975ce4e4266eb12b62590eaaba6f2de88)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/91390
Reviewed-by: Xisco FaulĂ­ <xiscofauli@libreoffice.org>
diff --git a/include/formula/FormulaCompiler.hxx b/include/formula/FormulaCompiler.hxx
index a2c6f6f..185dd7a 100644
--- a/include/formula/FormulaCompiler.hxx
+++ b/include/formula/FormulaCompiler.hxx
@@ -221,6 +221,7 @@ public:
    OpCode GetEnglishOpCode( const OUString& rName ) const;

    FormulaError GetErrorConstant( const OUString& rName ) const;
    void AppendErrorConstant( OUStringBuffer& rBuffer, FormulaError nError ) const;

    void EnableJumpCommandReorder( bool bEnable );
    void EnableStopOnError( bool bEnable );
@@ -305,8 +306,6 @@ protected:
    virtual void CreateStringFromIndex( OUStringBuffer& rBuffer, const FormulaToken* pToken ) const;
    virtual void LocalizeString( OUString& rName ) const;   // modify rName - input: exact name

    void AppendErrorConstant( OUStringBuffer& rBuffer, FormulaError nError ) const;

    bool   GetToken();
    OpCode NextToken();
    void PutCode( FormulaTokenRef& );
diff --git a/sc/source/filter/excel/xestream.cxx b/sc/source/filter/excel/xestream.cxx
index 19115bc..6b1e29a 100644
--- a/sc/source/filter/excel/xestream.cxx
+++ b/sc/source/filter/excel/xestream.cxx
@@ -795,15 +795,30 @@ OUString XclXmlUtils::ToOUString( const ScfUInt16Vec& rBuf, sal_Int32 nStart, sa
}

OUString XclXmlUtils::ToOUString(
    sc::CompileFormulaContext& rCtx, const ScAddress& rAddress, const ScTokenArray* pTokenArray )
    sc::CompileFormulaContext& rCtx, const ScAddress& rAddress, const ScTokenArray* pTokenArray,
    FormulaError nErrCode )
{
    ScCompiler aCompiler( rCtx, rAddress, const_cast<ScTokenArray&>(*pTokenArray));

    /* TODO: isn't this the same as passed in rCtx and thus superfluous? */
    aCompiler.SetGrammar(FormulaGrammar::GRAM_OOXML);

    OUStringBuffer aBuffer( pTokenArray->GetLen() * 5 );
    aCompiler.CreateStringFromTokenArray( aBuffer );
    sal_Int32 nLen = pTokenArray->GetLen();
    OUStringBuffer aBuffer( nLen ? (nLen * 5) : 8 );
    if (nLen)
        aCompiler.CreateStringFromTokenArray( aBuffer );
    else
    {
        if (nErrCode != FormulaError::NONE)
            aCompiler.AppendErrorConstant( aBuffer, nErrCode);
        else
        {
            // No code SHOULD be an "error cell", assert caller thought of that
            // and it really is.
            assert(!"No code and no error.");
        }
    }

    return aBuffer.makeStringAndClear();
}

diff --git a/sc/source/filter/excel/xetable.cxx b/sc/source/filter/excel/xetable.cxx
index 0a7e5cb..24079fb 100644
--- a/sc/source/filter/excel/xetable.cxx
+++ b/sc/source/filter/excel/xetable.cxx
@@ -1011,7 +1011,8 @@ void XclExpFormulaCell::SaveXml( XclExpXmlStream& rStrm )
                        (mxAddRec && mxAddRec->IsVolatile()) ) );
        }
        rWorksheet->writeEscaped( XclXmlUtils::ToOUString(
                    rStrm.GetRoot().GetCompileFormulaContext(), mrScFmlaCell.aPos, mrScFmlaCell.GetCode()));
                    rStrm.GetRoot().GetCompileFormulaContext(), mrScFmlaCell.aPos, mrScFmlaCell.GetCode(),
                    mrScFmlaCell.GetErrCode()));
        rWorksheet->endElement( XML_f );
    }

diff --git a/sc/source/filter/inc/xestream.hxx b/sc/source/filter/inc/xestream.hxx
index 2a2a07b..124aacb 100644
--- a/sc/source/filter/inc/xestream.hxx
+++ b/sc/source/filter/inc/xestream.hxx
@@ -27,6 +27,7 @@
#include <oox/core/xmlfilterbase.hxx>
#include <sax/fshelper.hxx>
#include <tools/stream.hxx>
#include <formula/errorcodes.hxx>
#include "ftools.hxx"

#include <filter/msfilter/mscodec.hxx>
@@ -262,7 +263,8 @@ public:

    static OUString ToOUString( const char* s );
    static OUString ToOUString( const ScfUInt16Vec& rBuffer, sal_Int32 nStart = 0, sal_Int32 nLength = -1 );
    static OUString ToOUString( sc::CompileFormulaContext& rCtx, const ScAddress& rAddress, const ScTokenArray* pTokenArray );
    static OUString ToOUString( sc::CompileFormulaContext& rCtx, const ScAddress& rAddress,
            const ScTokenArray* pTokenArray, FormulaError nErrCode = FormulaError::NONE );
    static OUString ToOUString( const XclExpString& s );

    template <class T>