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

Kohei Yoshida kohei.yoshida at gmail.com
Sat Dec 9 18:40:32 UTC 2017


 sc/source/filter/inc/orcusinterface.hxx |   22 +++++
 sc/source/filter/orcus/interface.cxx    |  118 +++++++++++++++++++++++---------
 2 files changed, 107 insertions(+), 33 deletions(-)

New commits:
commit ca625b897e971c9ab704c4afdf2ff1b4297f8d3f
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Sat Dec 9 13:38:27 2017 -0500

    Implement a reference resolver for orcus.
    
    Orcus uses this to resolve cell addresses for some ops.
    
    Change-Id: I6ee9667ad994fb830e545ba3368004866a048c25

diff --git a/sc/source/filter/inc/orcusinterface.hxx b/sc/source/filter/inc/orcusinterface.hxx
index 465014b0caf4..5bc3951e7c35 100644
--- a/sc/source/filter/inc/orcusinterface.hxx
+++ b/sc/source/filter/inc/orcusinterface.hxx
@@ -47,6 +47,8 @@ class XStatusIndicator;
 class ScOrcusGlobalSettings : public orcus::spreadsheet::iface::import_global_settings
 {
     ScDocumentImport& mrDoc;
+    formula::FormulaGrammar::Grammar meCalcGrammar;
+    orcus::spreadsheet::formula_grammar_t meOrcusGrammar;
 
 public:
     ScOrcusGlobalSettings(ScDocumentImport& rDoc);
@@ -55,6 +57,23 @@ public:
 
     virtual void set_default_formula_grammar(orcus::spreadsheet::formula_grammar_t grammar) override;
     virtual orcus::spreadsheet::formula_grammar_t get_default_formula_grammar() const override;
+
+    formula::FormulaGrammar::Grammar getCalcGrammar() const
+    {
+        return meCalcGrammar;
+    }
+};
+
+class ScOrcusRefResolver : public orcus::spreadsheet::iface::import_reference_resolver
+{
+    const ScDocumentImport& mrDoc;
+    const ScOrcusGlobalSettings& mrGlobalSettings;
+
+public:
+    ScOrcusRefResolver( const ScDocumentImport& rDoc, const ScOrcusGlobalSettings& rGS );
+
+    orcus::spreadsheet::address_t resolve_address(const char* p, size_t n);
+    orcus::spreadsheet::range_t resolve_range(const char* p, size_t n);
 };
 
 class ScOrcusSharedStrings : public orcus::spreadsheet::iface::import_shared_strings
@@ -202,7 +221,7 @@ class ScOrcusSheet : public orcus::spreadsheet::iface::import_sheet
 public:
     ScOrcusSheet(ScDocumentImport& rDoc, SCTAB nTab, ScOrcusFactory& rFactory);
 
-    virtual orcus::spreadsheet::iface::import_auto_filter* get_auto_filter() override { return &maAutoFilter; }
+    virtual orcus::spreadsheet::iface::import_auto_filter* get_auto_filter() override;
     virtual orcus::spreadsheet::iface::import_table* get_table() override;
     virtual orcus::spreadsheet::iface::import_sheet_properties* get_sheet_properties() override;
     virtual orcus::spreadsheet::iface::import_conditional_format* get_conditional_format() override;
@@ -497,6 +516,7 @@ class ScOrcusFactory : public orcus::spreadsheet::iface::import_factory
 
     StringCellCaches maStringCells;
     ScOrcusGlobalSettings maGlobalSettings;
+    ScOrcusRefResolver maRefResolver;
     ScOrcusSharedStrings maSharedStrings;
     std::vector< std::unique_ptr<ScOrcusSheet> > maSheets;
     ScOrcusStyles maStyles;
diff --git a/sc/source/filter/orcus/interface.cxx b/sc/source/filter/orcus/interface.cxx
index c31eb3720ff8..1e917963ccc2 100644
--- a/sc/source/filter/orcus/interface.cxx
+++ b/sc/source/filter/orcus/interface.cxx
@@ -58,20 +58,97 @@ using namespace com::sun::star;
 
 namespace os = orcus::spreadsheet;
 
-ScOrcusGlobalSettings::ScOrcusGlobalSettings(ScDocumentImport& rDoc) : mrDoc(rDoc) {}
+namespace {
+
+formula::FormulaGrammar::Grammar getCalcGrammarFromOrcus( os::formula_grammar_t grammar )
+{
+    formula::FormulaGrammar::Grammar eGrammar = formula::FormulaGrammar::GRAM_ODFF;
+    switch(grammar)
+    {
+        case orcus::spreadsheet::formula_grammar_t::ods:
+            eGrammar = formula::FormulaGrammar::GRAM_ODFF;
+            break;
+        case orcus::spreadsheet::formula_grammar_t::xlsx_2007:
+        case orcus::spreadsheet::formula_grammar_t::xlsx_2010:
+            eGrammar = formula::FormulaGrammar::GRAM_OOXML;
+            break;
+        case orcus::spreadsheet::formula_grammar_t::gnumeric:
+            eGrammar = formula::FormulaGrammar::GRAM_ENGLISH_XL_A1;
+            break;
+        case orcus::spreadsheet::formula_grammar_t::xls_xml:
+            eGrammar = formula::FormulaGrammar::GRAM_ENGLISH_XL_R1C1;
+            break;
+        case orcus::spreadsheet::formula_grammar_t::unknown:
+            break;
+    }
+
+    return eGrammar;
+}
+
+}
+
+ScOrcusGlobalSettings::ScOrcusGlobalSettings(ScDocumentImport& rDoc) :
+    mrDoc(rDoc), meOrcusGrammar(os::formula_grammar_t::unknown) {}
 
 void ScOrcusGlobalSettings::set_origin_date(int year, int month, int day)
 {
     mrDoc.setOriginDate(year, month, day);
 }
 
-void ScOrcusGlobalSettings::set_default_formula_grammar(orcus::spreadsheet::formula_grammar_t /*grammar*/)
+void ScOrcusGlobalSettings::set_default_formula_grammar(os::formula_grammar_t grammar)
 {
+    meCalcGrammar = getCalcGrammarFromOrcus(grammar);
+    meOrcusGrammar = grammar;
 }
 
 orcus::spreadsheet::formula_grammar_t ScOrcusGlobalSettings::get_default_formula_grammar() const
 {
-    return orcus::spreadsheet::formula_grammar_t::unknown;
+    return meOrcusGrammar;
+}
+
+ScOrcusRefResolver::ScOrcusRefResolver( const ScDocumentImport& rDoc, const ScOrcusGlobalSettings& rGS ) :
+    mrDoc(rDoc), mrGlobalSettings(rGS) {}
+
+os::address_t ScOrcusRefResolver::resolve_address(const char* p, size_t n)
+{
+    OUString aStr(p, n, RTL_TEXTENCODING_UTF8);
+
+    ScAddress aAddr;
+    aAddr.Parse(aStr, nullptr,
+        formula::FormulaGrammar::extractRefConvention(
+            mrGlobalSettings.getCalcGrammar()));
+
+    os::address_t ret;
+
+    if (aAddr.IsValid())
+    {
+        ret.column = aAddr.Col();
+        ret.row = aAddr.Row();
+    }
+
+    return ret;
+}
+
+os::range_t ScOrcusRefResolver::resolve_range(const char* p, size_t n)
+{
+    OUString aStr(p, n, RTL_TEXTENCODING_UTF8);
+
+    ScRange aRange;
+    aRange.Parse(aStr, nullptr,
+        formula::FormulaGrammar::extractRefConvention(
+            mrGlobalSettings.getCalcGrammar()));
+
+    os::range_t ret;
+
+    if (aRange.IsValid())
+    {
+        ret.first.column = aRange.aStart.Col();
+        ret.first.row    = aRange.aStart.Row();
+        ret.last.column  = aRange.aEnd.Col();
+        ret.last.row     = aRange.aEnd.Row();
+    }
+
+    return ret;
 }
 
 ScOrcusFactory::StringCellCache::StringCellCache(const ScAddress& rPos, size_t nIndex) :
@@ -80,6 +157,7 @@ ScOrcusFactory::StringCellCache::StringCellCache(const ScAddress& rPos, size_t n
 ScOrcusFactory::ScOrcusFactory(ScDocument& rDoc) :
     maDoc(rDoc),
     maGlobalSettings(maDoc),
+    maRefResolver(maDoc, maGlobalSettings),
     maSharedStrings(*this),
     maStyles(rDoc),
     mnProgress(0) {}
@@ -487,6 +565,11 @@ void ScOrcusSheet::cellInserted()
     }
 }
 
+os::iface::import_auto_filter* ScOrcusSheet::get_auto_filter()
+{
+    return &maAutoFilter;
+}
+
 os::iface::import_table* ScOrcusSheet::get_table()
 {
     return nullptr;
@@ -569,35 +652,6 @@ void ScOrcusSheet::set_format(os::row_t row_start, os::col_t col_start,
     mrDoc.getDoc().ApplyPatternAreaTab(col_start, row_start, col_end, row_end, mnTab, aPattern);
 }
 
-namespace {
-
-formula::FormulaGrammar::Grammar getCalcGrammarFromOrcus( os::formula_grammar_t grammar )
-{
-    formula::FormulaGrammar::Grammar eGrammar = formula::FormulaGrammar::GRAM_ODFF;
-    switch(grammar)
-    {
-        case orcus::spreadsheet::formula_grammar_t::ods:
-            eGrammar = formula::FormulaGrammar::GRAM_ODFF;
-            break;
-        case orcus::spreadsheet::formula_grammar_t::xlsx_2007:
-        case orcus::spreadsheet::formula_grammar_t::xlsx_2010:
-            eGrammar = formula::FormulaGrammar::GRAM_OOXML;
-            break;
-        case orcus::spreadsheet::formula_grammar_t::gnumeric:
-            eGrammar = formula::FormulaGrammar::GRAM_ENGLISH_XL_A1;
-            break;
-        case orcus::spreadsheet::formula_grammar_t::xls_xml:
-            eGrammar = formula::FormulaGrammar::GRAM_ENGLISH_XL_R1C1;
-            break;
-        case orcus::spreadsheet::formula_grammar_t::unknown:
-            break;
-    }
-
-    return eGrammar;
-}
-
-}
-
 void ScOrcusSheet::set_formula(
     os::row_t row, os::col_t col, os::formula_grammar_t grammar, const char* p, size_t n)
 {


More information about the Libreoffice-commits mailing list