[Libreoffice-commits] core.git: Branch 'private/kohei/excel-2003-xml-orcus-filter' - sc/inc sc/source

Kohei Yoshida kohei.yoshida at gmail.com
Sun Dec 17 18:01:09 UTC 2017


 sc/inc/documentimport.hxx               |   10 -
 sc/source/core/data/documentimport.cxx  |   42 ++++
 sc/source/filter/inc/orcusinterface.hxx |   51 ++++-
 sc/source/filter/orcus/interface.cxx    |  294 +++++++++++++++++++++++++-------
 4 files changed, 324 insertions(+), 73 deletions(-)

New commits:
commit bf89c9bc69413ff09f2198be6ab70734cbf4821d
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Dec 13 22:27:03 2017 -0500

    Defer cell value insertion until later.
    
    Because Calc's formula engine expects all named expressions to be
    present at the time of re-calculations, we need to delay insertion
    of cell values until after the named expressions are inserted into
    the document.
    
    Change-Id: I54c7d3dc86b3e2c5c192337b1cebfbdfb901ab1f

diff --git a/sc/inc/documentimport.hxx b/sc/inc/documentimport.hxx
index b4c35e1f99b5..d881da37cf2d 100644
--- a/sc/inc/documentimport.hxx
+++ b/sc/inc/documentimport.hxx
@@ -96,7 +96,15 @@ public:
     void setNumericCell(const ScAddress& rPos, double fVal);
     void setStringCell(const ScAddress& rPos, const OUString& rStr);
     void setEditCell(const ScAddress& rPos, EditTextObject* pEditText);
-    void setFormulaCell(const ScAddress& rPos, const OUString& rFormula, formula::FormulaGrammar::Grammar eGrammar);
+
+    void setFormulaCell(
+        const ScAddress& rPos, const OUString& rFormula, formula::FormulaGrammar::Grammar eGrammar,
+        const double* pResult = nullptr );
+
+    void setFormulaCell(
+        const ScAddress& rPos, const OUString& rFormula, formula::FormulaGrammar::Grammar eGrammar,
+        const OUString& rResult );
+
     void setFormulaCell(const ScAddress& rPos, ScTokenArray* pArray);
     void setFormulaCell(const ScAddress& rPos, ScFormulaCell* pCell);
 
diff --git a/sc/source/core/data/documentimport.cxx b/sc/source/core/data/documentimport.cxx
index 183f3e1650af..6208789f416e 100644
--- a/sc/source/core/data/documentimport.cxx
+++ b/sc/source/core/data/documentimport.cxx
@@ -25,9 +25,7 @@
 
 #include <svl/sharedstringpool.hxx>
 #include <svl/languageoptions.hxx>
-
-#include <memory>
-#include <vector>
+#include <o3tl/make_unique.hxx>
 
 namespace {
 
@@ -271,7 +269,35 @@ void ScDocumentImport::setEditCell(const ScAddress& rPos, EditTextObject* pEditT
 }
 
 void ScDocumentImport::setFormulaCell(
-    const ScAddress& rPos, const OUString& rFormula, formula::FormulaGrammar::Grammar eGrammar)
+    const ScAddress& rPos, const OUString& rFormula, formula::FormulaGrammar::Grammar eGrammar,
+    const double* pResult )
+{
+    ScTable* pTab = mpImpl->mrDoc.FetchTable(rPos.Tab());
+    if (!pTab)
+        return;
+
+    sc::ColumnBlockPosition* pBlockPos = mpImpl->getBlockPosition(rPos.Tab(), rPos.Col());
+
+    if (!pBlockPos)
+        return;
+
+    std::unique_ptr<ScFormulaCell> pFC =
+        o3tl::make_unique<ScFormulaCell>(&mpImpl->mrDoc, rPos, rFormula, eGrammar);
+
+    if (pResult)
+    {
+        // Set cached result to this formula cell.
+        pFC->SetResultDouble(*pResult);
+    }
+
+    sc::CellStoreType& rCells = pTab->aCol[rPos.Col()].maCells;
+    pBlockPos->miCellPos =
+        rCells.set(pBlockPos->miCellPos, rPos.Row(), pFC.release());
+}
+
+void ScDocumentImport::setFormulaCell(
+    const ScAddress& rPos, const OUString& rFormula, formula::FormulaGrammar::Grammar eGrammar,
+    const OUString& rResult )
 {
     ScTable* pTab = mpImpl->mrDoc.FetchTable(rPos.Tab());
     if (!pTab)
@@ -282,9 +308,15 @@ void ScDocumentImport::setFormulaCell(
     if (!pBlockPos)
         return;
 
+    std::unique_ptr<ScFormulaCell> pFC =
+        o3tl::make_unique<ScFormulaCell>(&mpImpl->mrDoc, rPos, rFormula, eGrammar);
+
+    // Set cached result to this formula cell.
+    pFC->SetHybridString(mpImpl->mrDoc.GetSharedStringPool().intern(rResult));
+
     sc::CellStoreType& rCells = pTab->aCol[rPos.Col()].maCells;
     pBlockPos->miCellPos =
-        rCells.set(pBlockPos->miCellPos, rPos.Row(), new ScFormulaCell(&mpImpl->mrDoc, rPos, rFormula, eGrammar));
+        rCells.set(pBlockPos->miCellPos, rPos.Row(), pFC.release());
 }
 
 void ScDocumentImport::setFormulaCell(const ScAddress& rPos, ScTokenArray* pArray)
diff --git a/sc/source/filter/inc/orcusinterface.hxx b/sc/source/filter/inc/orcusinterface.hxx
index 64c3383708f2..8259b55f9d64 100644
--- a/sc/source/filter/inc/orcusinterface.hxx
+++ b/sc/source/filter/inc/orcusinterface.hxx
@@ -274,6 +274,8 @@ public:
     virtual orcus::spreadsheet::range_size_t get_sheet_size() const override;
 
     SCTAB getIndex() const { return mnTab; }
+
+    const sc::SharedFormulaGroups& getSharedFormulaGroups() const;
 };
 
 class ScOrcusStyles : public orcus::spreadsheet::iface::import_styles
@@ -509,28 +511,51 @@ public:
 
 class ScOrcusFactory : public orcus::spreadsheet::iface::import_factory
 {
-    struct StringCellCache
+    struct CellStoreToken
     {
+        enum class Type
+        {
+            Auto,
+            Numeric,
+            String,
+            Formula,
+            FormulaWithResult,
+            SharedFormula,
+            SharedFormulaWithResult,
+            Matrix
+        };
+
         ScAddress maPos;
-        size_t mnIndex;
+        Type meType;
 
-        StringCellCache(const ScAddress& rPos, size_t nIndex);
+        OUString maStr1;
+        OUString maStr2;
+        double mfValue;
+
+        uint32_t mnIndex1;
+        uint32_t mnIndex2;
+        formula::FormulaGrammar::Grammar meGrammar;
+
+        CellStoreToken( const ScAddress& rPos, Type eType );
+        CellStoreToken( const ScAddress& rPos, double fValue );
+        CellStoreToken( const ScAddress& rPos, uint32_t nIndex );
+        CellStoreToken( const ScAddress& rPos, const OUString& rFormula, formula::FormulaGrammar::Grammar eGrammar );
     };
 
     typedef std::unordered_map<OUString, size_t> StringHashType;
-    typedef std::vector<StringCellCache> StringCellCaches;
+    typedef std::vector<CellStoreToken> CellStoreTokensType;
 
     ScDocumentImport maDoc;
 
     std::vector<OUString> maStrings;
     StringHashType maStringHash;
 
-    StringCellCaches maStringCells;
+    CellStoreTokensType maCellStoreTokens;
     ScOrcusGlobalSettings maGlobalSettings;
     ScOrcusRefResolver maRefResolver;
     ScOrcusSharedStrings maSharedStrings;
     ScOrcusNamedExpression maNamedExpressions;
-    std::vector< std::unique_ptr<ScOrcusSheet> > maSheets;
+    std::vector<std::unique_ptr<ScOrcusSheet>> maSheets;
     ScOrcusStyles maStyles;
 
     int mnProgress;
@@ -553,7 +578,19 @@ public:
     size_t appendString(const OUString& rStr);
     size_t addString(const OUString& rStr);
 
-    void pushStringCell(const ScAddress& rPos, size_t nStrIndex);
+    void pushCellStoreAutoToken( const ScAddress& rPos, const OUString& rVal );
+    void pushCellStoreToken( const ScAddress& rPos, uint32_t nStrIndex );
+    void pushCellStoreToken( const ScAddress& rPos, double fValue );
+    void pushCellStoreToken(
+        const ScAddress& rPos, const OUString& rFormula, formula::FormulaGrammar::Grammar eGrammar );
+
+    void pushSharedFormulaToken( const ScAddress& rPos, uint32_t nIndex );
+    void pushMatrixFormulaToken(
+        const ScAddress& rPos, const OUString& rFormula, formula::FormulaGrammar::Grammar eGrammar,
+        uint32_t nRowRange, uint32_t nColRange );
+
+    void pushFormulaResult( const ScAddress& rPos, double fValue );
+    void pushFormulaResult( const ScAddress& rPos, const OUString& rValue );
 
     void incrementProgress();
 
diff --git a/sc/source/filter/orcus/interface.cxx b/sc/source/filter/orcus/interface.cxx
index f57ca97eae65..78142ffea7e6 100644
--- a/sc/source/filter/orcus/interface.cxx
+++ b/sc/source/filter/orcus/interface.cxx
@@ -53,6 +53,7 @@
 #include <vcl/outdev.hxx>
 #include <tools/colordata.hxx>
 #include <tools/fontenum.hxx>
+#include <iostream>
 
 using namespace com::sun::star;
 
@@ -171,8 +172,27 @@ void ScOrcusNamedExpression::define_name(const char* p_name, size_t n_name, cons
     pNames->insert(pRange, false);
 }
 
-ScOrcusFactory::StringCellCache::StringCellCache(const ScAddress& rPos, size_t nIndex) :
-    maPos(rPos), mnIndex(nIndex) {}
+ScOrcusFactory::CellStoreToken::CellStoreToken( const ScAddress& rPos, Type eType ) :
+    maPos(rPos), meType(eType)
+{
+    rtl::math::setNan(&mfValue);
+}
+
+ScOrcusFactory::CellStoreToken::CellStoreToken( const ScAddress& rPos, double fValue ) :
+    maPos(rPos), meType(Type::Numeric), mfValue(fValue) {}
+
+ScOrcusFactory::CellStoreToken::CellStoreToken( const ScAddress& rPos, uint32_t nIndex ) :
+    maPos(rPos), meType(Type::String), mnIndex1(nIndex)
+{
+    rtl::math::setNan(&mfValue);
+}
+
+ScOrcusFactory::CellStoreToken::CellStoreToken(
+    const ScAddress& rPos, const OUString& rFormula, formula::FormulaGrammar::Grammar eGrammar ) :
+    maPos(rPos), meType(Type::Formula), maStr1(rFormula), meGrammar(eGrammar)
+{
+    rtl::math::setNan(&mfValue);
+}
 
 ScOrcusFactory::ScOrcusFactory(ScDocument& rDoc) :
     maDoc(rDoc),
@@ -275,16 +295,112 @@ orcus::spreadsheet::iface::import_styles* ScOrcusFactory::get_styles()
 
 void ScOrcusFactory::finalize()
 {
+    auto toFormulaCell = [this]( const CellStoreToken& rToken ) -> std::unique_ptr<ScFormulaCell>
+    {
+        const ScOrcusSheet& rSheet = *maSheets.at(rToken.maPos.Tab());
+        const sc::SharedFormulaGroups& rSFG = rSheet.getSharedFormulaGroups();
+        const ScTokenArray* pArray = rSFG.get(rToken.mnIndex1);
+        if (!pArray)
+            return std::unique_ptr<ScFormulaCell>();
+
+        return o3tl::make_unique<ScFormulaCell>(&maDoc.getDoc(), rToken.maPos, *pArray);
+    };
+
     int nCellCount = 0;
-    StringCellCaches::const_iterator it = maStringCells.begin(), itEnd = maStringCells.end();
-    for (; it != itEnd; ++it)
+
+    for (const CellStoreToken& rToken : maCellStoreTokens)
     {
-        if (it->mnIndex >= maStrings.size())
-            // String index out-of-bound!  Something is up.
-            continue;
+        switch (rToken.meType)
+        {
+            case CellStoreToken::Type::Auto:
+            {
+                maDoc.setAutoInput(rToken.maPos, rToken.maStr1);
+                ++nCellCount;
+                break;
+            }
+            case CellStoreToken::Type::String:
+            {
+                if (rToken.mnIndex1 >= maStrings.size())
+                    // String index out-of-bound!  Something is up.
+                    break;
+
+                maDoc.setStringCell(rToken.maPos, maStrings[rToken.mnIndex1]);
+                ++nCellCount;
+                break;
+            }
+            case CellStoreToken::Type::Numeric:
+            {
+                maDoc.setNumericCell(rToken.maPos, rToken.mfValue);
+                ++nCellCount;
+                break;
+            }
+            case CellStoreToken::Type::Formula:
+            {
+                maDoc.setFormulaCell(
+                    rToken.maPos, rToken.maStr1, rToken.meGrammar);
+
+                ++nCellCount;
+                break;
+            }
+            case CellStoreToken::Type::FormulaWithResult:
+            {
+                if (rtl::math::isFinite(rToken.mfValue))
+                    maDoc.setFormulaCell(rToken.maPos, rToken.maStr1, rToken.meGrammar, &rToken.mfValue);
+                else
+                    maDoc.setFormulaCell(rToken.maPos, rToken.maStr1, rToken.meGrammar, rToken.maStr2);
+
+                ++nCellCount;
+                break;
+            }
+            case CellStoreToken::Type::SharedFormula:
+            {
+                std::unique_ptr<ScFormulaCell> pCell = toFormulaCell(rToken);
+                if (!pCell)
+                    break;
+
+                maDoc.setFormulaCell(rToken.maPos, pCell.release());
+
+                ++nCellCount;
+                break;
+            }
+            case CellStoreToken::Type::SharedFormulaWithResult:
+            {
+                std::unique_ptr<ScFormulaCell> pCell = toFormulaCell(rToken);
+                if (!pCell)
+                    break;
+
+                if (rtl::math::isFinite(rToken.mfValue))
+                    pCell->SetResultDouble(rToken.mfValue);
+                else
+                    pCell->SetHybridString(
+                        maDoc.getDoc().GetSharedStringPool().intern(rToken.maStr2));
+
+                maDoc.setFormulaCell(rToken.maPos, pCell.release());
+
+                ++nCellCount;
+                break;
+            }
+            case CellStoreToken::Type::Matrix:
+            {
+                if (!rToken.mnIndex1 || !rToken.mnIndex2)
+                    break;
+
+                ScRange aRange(rToken.maPos);
+                aRange.aEnd.IncCol(rToken.mnIndex1-1);
+                aRange.aEnd.IncRow(rToken.mnIndex2-1);
+
+                ScCompiler aComp(&maDoc.getDoc(), aRange.aStart, rToken.meGrammar);
+                std::unique_ptr<ScTokenArray> pArray(aComp.CompileString(rToken.maStr1));
+                if (!pArray)
+                    break;
+
+                maDoc.setMatrixCells(aRange, *pArray, rToken.meGrammar);
+                break;
+            }
+            default:
+                ;
+        }
 
-        maDoc.setStringCell(it->maPos, maStrings[it->mnIndex]);
-        ++nCellCount;
         if (nCellCount == 100000)
         {
             incrementProgress();
@@ -317,9 +433,96 @@ size_t ScOrcusFactory::addString(const OUString& rStr)
     return appendString(rStr);
 }
 
-void ScOrcusFactory::pushStringCell(const ScAddress& rPos, size_t nStrIndex)
+void ScOrcusFactory::pushCellStoreAutoToken( const ScAddress& rPos, const OUString& rVal )
+{
+    maCellStoreTokens.emplace_back(rPos, CellStoreToken::Type::Auto);
+    maCellStoreTokens.back().maStr1 = rVal;
+}
+
+void ScOrcusFactory::pushCellStoreToken( const ScAddress& rPos, uint32_t nStrIndex )
+{
+    maCellStoreTokens.emplace_back(rPos, nStrIndex);
+}
+
+void ScOrcusFactory::pushCellStoreToken( const ScAddress& rPos, double fValue )
+{
+    maCellStoreTokens.emplace_back(rPos, fValue);
+}
+
+void ScOrcusFactory::pushCellStoreToken(
+    const ScAddress& rPos, const OUString& rFormula, formula::FormulaGrammar::Grammar eGrammar )
 {
-    maStringCells.emplace_back(rPos, nStrIndex);
+    maCellStoreTokens.emplace_back(rPos, rFormula, eGrammar);
+}
+
+void ScOrcusFactory::pushSharedFormulaToken( const ScAddress& rPos, uint32_t nIndex )
+{
+    maCellStoreTokens.emplace_back(rPos, CellStoreToken::Type::SharedFormula);
+    maCellStoreTokens.back().mnIndex1 = nIndex;
+}
+
+void ScOrcusFactory::pushMatrixFormulaToken(
+    const ScAddress& rPos, const OUString& rFormula, formula::FormulaGrammar::Grammar eGrammar,
+    uint32_t nRowRange, uint32_t nColRange )
+{
+    maCellStoreTokens.emplace_back(rPos, CellStoreToken::Type::Matrix);
+    CellStoreToken& rT = maCellStoreTokens.back();
+    rT.maStr1 = rFormula;
+    rT.meGrammar = eGrammar;
+    rT.mnIndex1 = nColRange;
+    rT.mnIndex2 = nRowRange;
+}
+
+void ScOrcusFactory::pushFormulaResult( const ScAddress& rPos, double fValue )
+{
+    // Formula result is expected to be pushed immediately following the
+    // formula token it belongs.
+    if (maCellStoreTokens.empty())
+        return;
+
+    CellStoreToken& rToken = maCellStoreTokens.back();
+    if (rToken.maPos != rPos)
+        return;
+
+    switch (rToken.meType)
+    {
+        case CellStoreToken::Type::Formula:
+            rToken.meType = CellStoreToken::Type::FormulaWithResult;
+            break;
+        case CellStoreToken::Type::SharedFormula:
+            rToken.meType = CellStoreToken::Type::SharedFormulaWithResult;
+            break;
+        default:
+            return;
+    }
+
+    rToken.mfValue = fValue;
+}
+
+void ScOrcusFactory::pushFormulaResult( const ScAddress& rPos, const OUString& rValue )
+{
+    // Formula result is expected to be pushed immediately following the
+    // formula token it belongs.
+    if (maCellStoreTokens.empty())
+        return;
+
+    CellStoreToken& rToken = maCellStoreTokens.back();
+    if (rToken.maPos != rPos)
+        return;
+
+    switch (rToken.meType)
+    {
+        case CellStoreToken::Type::Formula:
+            rToken.meType = CellStoreToken::Type::FormulaWithResult;
+            break;
+        case CellStoreToken::Type::SharedFormula:
+            rToken.meType = CellStoreToken::Type::SharedFormulaWithResult;
+            break;
+        default:
+            return;
+    }
+
+    rToken.maStr2 = rValue;
 }
 
 void ScOrcusFactory::incrementProgress()
@@ -614,30 +817,25 @@ os::iface::import_conditional_format* ScOrcusSheet::get_conditional_format()
 void ScOrcusSheet::set_auto(os::row_t row, os::col_t col, const char* p, size_t n)
 {
     OUString aVal(p, n, RTL_TEXTENCODING_UTF8);
-    mrDoc.setAutoInput(ScAddress(col, row, mnTab), aVal);
+    mrFactory.pushCellStoreAutoToken(ScAddress(col, row, mnTab), aVal);
     cellInserted();
 }
 
 void ScOrcusSheet::set_string(os::row_t row, os::col_t col, size_t sindex)
 {
-    // We need to defer string cells since the shared string pool is not yet
-    // populated at the time this method is called.  Orcus imports string
-    // table after the cells get imported.  We won't need to do this once we
-    // implement true shared strings in Calc core.
-
-    mrFactory.pushStringCell(ScAddress(col, row, mnTab), sindex);
+    mrFactory.pushCellStoreToken(ScAddress(col, row, mnTab), uint32_t(sindex));
     cellInserted();
 }
 
 void ScOrcusSheet::set_value(os::row_t row, os::col_t col, double value)
 {
-    mrDoc.setNumericCell(ScAddress(col, row, mnTab), value);
+    mrFactory.pushCellStoreToken(ScAddress(col, row, mnTab), value);
     cellInserted();
 }
 
 void ScOrcusSheet::set_bool(os::row_t row, os::col_t col, bool value)
 {
-    mrDoc.setNumericCell(ScAddress(col, row, mnTab), value ? 1.0 : 0.0);
+    mrFactory.pushCellStoreToken(ScAddress(col, row, mnTab), value ? 1.0 : 0.0);
     cellInserted();
 }
 
@@ -660,7 +858,7 @@ void ScOrcusSheet::set_date_time(
 
     fTime /= DATE_TIME_FACTOR;
 
-    mrDoc.setNumericCell(ScAddress(col, row, mnTab), nDateDiff + fTime);
+    mrFactory.pushCellStoreToken(ScAddress(col, row, mnTab), nDateDiff + fTime);
     cellInserted();
 }
 
@@ -686,35 +884,20 @@ void ScOrcusSheet::set_formula(
     os::row_t row, os::col_t col, os::formula_grammar_t grammar, const char* p, size_t n)
 {
     OUString aFormula(p, n, RTL_TEXTENCODING_UTF8);
-    formula::FormulaGrammar::Grammar eGrammar = getCalcGrammarFromOrcus( grammar );
-    mrDoc.setFormulaCell(ScAddress(col,row,mnTab), aFormula, eGrammar);
+    mrFactory.pushCellStoreToken(
+        ScAddress(col, row, mnTab), aFormula, getCalcGrammarFromOrcus(grammar));
     cellInserted();
 }
 
 void ScOrcusSheet::set_formula_result(os::row_t row, os::col_t col, const char* p, size_t n)
 {
-    ScFormulaCell* pCell = mrDoc.getDoc().GetFormulaCell(ScAddress(col, row, mnTab));
-    if (!pCell)
-    {
-        SAL_WARN("sc.orcus", "trying to set formula result for non formula "
-                "cell! Col: " << col << ";Row: " << row << ";Tab: " << mnTab);
-        return;
-    }
     OUString aResult( p, n, RTL_TEXTENCODING_UTF8);
-    pCell->SetHybridString(mrDoc.getDoc().GetSharedStringPool().intern(aResult));
+    mrFactory.pushFormulaResult(ScAddress(col, row, mnTab), aResult);
 }
 
-void ScOrcusSheet::set_formula_result(os::row_t row, os::col_t col, double /*val*/)
+void ScOrcusSheet::set_formula_result(os::row_t row, os::col_t col, double val)
 {
-    ScFormulaCell* pCell = mrDoc.getDoc().GetFormulaCell(ScAddress(col, row, mnTab));
-    if (!pCell)
-    {
-        SAL_WARN("sc.orcus", "trying to set formula result for non formula "
-                "cell! Col: " << col << ";Row: " << row << ";Tab: " << mnTab);
-        return;
-    }
-
-    // TODO: FIXME
+    mrFactory.pushFormulaResult(ScAddress(col, row, mnTab), val);
 }
 
 void ScOrcusSheet::set_shared_formula(
@@ -734,12 +917,8 @@ void ScOrcusSheet::set_shared_formula(
 
     maFormulaGroups.set(sindex, pArray);
 
-    ScFormulaCell* pCell = new ScFormulaCell(&mrDoc.getDoc(), aPos, *pArray);
-    mrDoc.setFormulaCell(aPos, pCell);
+    mrFactory.pushSharedFormulaToken(aPos, sindex);
     cellInserted();
-
-    // For now, orcus doesn't support setting cached result. Mark it for re-calculation.
-    pCell->SetDirty();
 }
 
 void ScOrcusSheet::set_shared_formula(
@@ -757,29 +936,19 @@ void ScOrcusSheet::set_shared_formula(os::row_t row, os::col_t col, size_t sinde
     if (!pArray)
         return;
 
-    ScFormulaCell* pCell = new ScFormulaCell(&mrDoc.getDoc(), aPos, *pArray);
-    mrDoc.setFormulaCell(aPos, pCell);
+    mrFactory.pushSharedFormulaToken(aPos, sindex);
     cellInserted();
-
-    // For now, orcus doesn't support setting cached result. Mark it for re-calculation.
-    pCell->SetDirty();
 }
 
 void ScOrcusSheet::set_array_formula(
     os::row_t row, os::col_t col, os::formula_grammar_t grammar,
     const char* p, size_t n, os::row_t array_rows, os::col_t array_cols)
 {
-    formula::FormulaGrammar::Grammar eGrammar = getCalcGrammarFromOrcus( grammar );
     OUString aFormula(p, n, RTL_TEXTENCODING_UTF8);
+    formula::FormulaGrammar::Grammar eGrammar = getCalcGrammarFromOrcus(grammar);
 
-    ScRange aRange(col, row, mnTab, col+array_cols, row + array_rows, mnTab);
-
-    ScCompiler aComp(&mrDoc.getDoc(), aRange.aStart, eGrammar);
-    std::unique_ptr<ScTokenArray> pArray(aComp.CompileString(aFormula));
-    if (!pArray)
-        return;
-
-    mrDoc.setMatrixCells(aRange, *pArray, eGrammar);
+    ScAddress aPos(col, row, mnTab);
+    mrFactory.pushMatrixFormulaToken(aPos, aFormula, eGrammar, array_rows, array_cols);
 }
 
 void ScOrcusSheet::set_array_formula(
@@ -797,6 +966,11 @@ orcus::spreadsheet::range_size_t ScOrcusSheet::get_sheet_size() const
     return ret;
 }
 
+const sc::SharedFormulaGroups& ScOrcusSheet::getSharedFormulaGroups() const
+{
+    return maFormulaGroups;
+}
+
 ScOrcusSharedStrings::ScOrcusSharedStrings(ScOrcusFactory& rFactory) :
     mrFactory(rFactory) {}
 


More information about the Libreoffice-commits mailing list