diff options
author | Kohei Yoshida <kohei.yoshida@gmail.com> | 2017-12-09 13:38:27 -0500 |
---|---|---|
committer | Kohei Yoshida <libreoffice@kohei.us> | 2017-12-18 19:03:40 +0100 |
commit | c7529c1ecab2d22ed10e83627884da6b08f84e6d (patch) | |
tree | 89dc897a3d01002fd821fb015fdae1390ad90254 | |
parent | f06be8e23f4aabba9386ac7f93133bf418cb36d6 (diff) |
Implement a reference resolver for orcus.
Orcus uses this to resolve cell addresses for some ops.
Change-Id: I6ee9667ad994fb830e545ba3368004866a048c25
Reviewed-on: https://gerrit.libreoffice.org/46662
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Kohei Yoshida <libreoffice@kohei.us>
-rw-r--r-- | sc/source/filter/inc/orcusinterface.hxx | 21 | ||||
-rw-r--r-- | sc/source/filter/orcus/interface.cxx | 124 |
2 files changed, 112 insertions, 33 deletions
diff --git a/sc/source/filter/inc/orcusinterface.hxx b/sc/source/filter/inc/orcusinterface.hxx index af5020c8ace4..e502d49296b1 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,22 @@ 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 ScOrcusGlobalSettings& mrGlobalSettings; + +public: + ScOrcusRefResolver( const ScOrcusGlobalSettings& rGS ); + + orcus::spreadsheet::address_t resolve_address(const char* p, size_t n) override; + orcus::spreadsheet::range_t resolve_range(const char* p, size_t n) override; }; class ScOrcusSharedStrings : public orcus::spreadsheet::iface::import_shared_strings @@ -202,7 +220,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 +515,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 ec93824093a2..d85308732fea 100644 --- a/sc/source/filter/orcus/interface.cxx +++ b/sc/source/filter/orcus/interface.cxx @@ -58,20 +58,103 @@ 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 ScOrcusGlobalSettings& rGS ) : + 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; + ret.column = 0; + ret.row = 0; + + 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; + ret.first.column = 0; + ret.first.row = 0; + ret.last.column = 0; + ret.last.row = 0; + + 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 +163,7 @@ ScOrcusFactory::StringCellCache::StringCellCache(const ScAddress& rPos, size_t n ScOrcusFactory::ScOrcusFactory(ScDocument& rDoc) : maDoc(rDoc), maGlobalSettings(maDoc), + maRefResolver(maGlobalSettings), maSharedStrings(*this), maStyles(rDoc), mnProgress(0) {} @@ -487,6 +571,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 +658,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) { |