diff options
author | Kohei Yoshida <kohei.yoshida@gmail.com> | 2013-04-09 19:17:03 -0400 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@gmail.com> | 2013-04-13 01:54:36 -0400 |
commit | 05f4bb6cdd5617db8db0c3d5279cff373cec949b (patch) | |
tree | 770a2f3eb498daaa21aa4d726f5f5665eef22a47 /sc | |
parent | 644f122a2d2b49f3aff9755093872bb38565ee5d (diff) |
Defer string cell import until the end when importing via orcus.
This is because orcus imports cells before it imports the string table.
Change-Id: I1b85be2d9832b9a9a52961ece735de8cd980b893
Diffstat (limited to 'sc')
-rw-r--r-- | sc/source/filter/inc/orcusinterface.hxx | 28 | ||||
-rw-r--r-- | sc/source/filter/orcus/interface.cxx | 66 |
2 files changed, 64 insertions, 30 deletions
diff --git a/sc/source/filter/inc/orcusinterface.hxx b/sc/source/filter/inc/orcusinterface.hxx index 0de1fcc29b35..313331c90abb 100644 --- a/sc/source/filter/inc/orcusinterface.hxx +++ b/sc/source/filter/inc/orcusinterface.hxx @@ -21,13 +21,16 @@ class ScDocument; class ScOrcusSheet; +class ScOrcusFactory; class ScRangeData; class ScOrcusSharedStrings : public orcus::spreadsheet::iface::import_shared_strings { - std::vector<OUString> maSharedStrings; + std::vector<OUString>& mrStrings; public: + ScOrcusSharedStrings(std::vector<OUString>& rStrings); + virtual size_t append(const char* s, size_t n); virtual size_t add(const char* s, size_t n); @@ -38,20 +41,18 @@ public: virtual void append_segment(const char* s, size_t n); virtual size_t commit_segments(); - - const OUString& getByIndex(size_t index) const; }; class ScOrcusSheet : public orcus::spreadsheet::iface::import_sheet { ScDocument& mrDoc; SCTAB mnTab; - ScOrcusSharedStrings& mrSharedStrings; + ScOrcusFactory& mrFactory; typedef std::map<size_t, ScRangeData*> SharedFormulaContainer; SharedFormulaContainer maSharedFormulas; public: - ScOrcusSheet(ScDocument& rDoc, SCTAB nTab, ScOrcusSharedStrings& rSharedStrings); + ScOrcusSheet(ScDocument& rDoc, SCTAB nTab, ScOrcusFactory& rFactory); // Orcus import interface virtual void set_auto(orcus::spreadsheet::row_t row, orcus::spreadsheet::col_t col, const char* p, size_t n); @@ -152,9 +153,21 @@ public: class ScOrcusFactory : public orcus::spreadsheet::iface::import_factory { + struct StringCellCache + { + ScAddress maPos; + size_t mnIndex; + + StringCellCache(const ScAddress& rPos, size_t nIndex); + }; + + typedef std::vector<StringCellCache> StringCellCaches; + ScDocument& mrDoc; - boost::ptr_vector<ScOrcusSheet> maSheets; + std::vector<OUString> maStrings; + StringCellCaches maStringCells; ScOrcusSharedStrings maSharedStrings; + boost::ptr_vector<ScOrcusSheet> maSheets; ScOrcusStyles maStyles; public: @@ -164,6 +177,9 @@ public: virtual orcus::spreadsheet::iface::import_sheet* get_sheet(const char *sheet_name, size_t sheet_name_length); virtual orcus::spreadsheet::iface::import_shared_strings* get_shared_strings(); virtual orcus::spreadsheet::iface::import_styles* get_styles(); + virtual void finalize(); + + void pushStringCell(const ScAddress& rPos, size_t nStrIndex); }; #endif diff --git a/sc/source/filter/orcus/interface.cxx b/sc/source/filter/orcus/interface.cxx index 5e48208ac2d8..45f23049cef2 100644 --- a/sc/source/filter/orcus/interface.cxx +++ b/sc/source/filter/orcus/interface.cxx @@ -13,14 +13,18 @@ #include "formulacell.hxx" #include "rangenam.hxx" #include "tokenarray.hxx" -#include <formula/token.hxx> +#include "stringutil.hxx" +#include <formula/token.hxx> using orcus::spreadsheet::row_t; using orcus::spreadsheet::col_t; using orcus::spreadsheet::formula_grammar_t; -ScOrcusFactory::ScOrcusFactory(ScDocument& rDoc) : mrDoc(rDoc) {} +ScOrcusFactory::StringCellCache::StringCellCache(const ScAddress& rPos, size_t nIndex) : + maPos(rPos), mnIndex(nIndex) {} + +ScOrcusFactory::ScOrcusFactory(ScDocument& rDoc) : mrDoc(rDoc), maSharedStrings(maStrings) {} orcus::spreadsheet::iface::import_sheet* ScOrcusFactory::append_sheet(const char* sheet_name, size_t sheet_name_length) { @@ -29,7 +33,7 @@ orcus::spreadsheet::iface::import_sheet* ScOrcusFactory::append_sheet(const char return NULL; SCTAB nTab = mrDoc.GetTableCount() - 1; - maSheets.push_back(new ScOrcusSheet(mrDoc, nTab, maSharedStrings)); + maSheets.push_back(new ScOrcusSheet(mrDoc, nTab, *this)); return &maSheets.back(); } @@ -61,7 +65,7 @@ orcus::spreadsheet::iface::import_sheet* ScOrcusFactory::get_sheet(const char* s return &(*it); // Create a new orcus sheet instance for this. - maSheets.push_back(new ScOrcusSheet(mrDoc, nTab, maSharedStrings)); + maSheets.push_back(new ScOrcusSheet(mrDoc, nTab, *this)); return &maSheets.back(); } @@ -76,8 +80,28 @@ orcus::spreadsheet::iface::import_styles* ScOrcusFactory::get_styles() return &maStyles; } -ScOrcusSheet::ScOrcusSheet(ScDocument& rDoc, SCTAB nTab, ScOrcusSharedStrings& rSharedStrings) : - mrDoc(rDoc), mnTab(nTab), mrSharedStrings(rSharedStrings) {} +void ScOrcusFactory::finalize() +{ + ScSetStringParam aParam; + aParam.setTextInput(); + StringCellCaches::const_iterator it = maStringCells.begin(), itEnd = maStringCells.end(); + for (; it != itEnd; ++it) + { + if (it->mnIndex >= maStrings.size()) + // String index out-of-bound! Something is up. + continue; + + mrDoc.SetString(it->maPos, maStrings[it->mnIndex], &aParam); + } +} + +void ScOrcusFactory::pushStringCell(const ScAddress& rPos, size_t nStrIndex) +{ + maStringCells.push_back(StringCellCache(rPos, nStrIndex)); +} + +ScOrcusSheet::ScOrcusSheet(ScDocument& rDoc, SCTAB nTab, ScOrcusFactory& rFactory) : + mrDoc(rDoc), mnTab(nTab), mrFactory(rFactory) {} void ScOrcusSheet::set_auto(row_t row, col_t col, const char* p, size_t n) { @@ -199,13 +223,12 @@ void ScOrcusSheet::set_array_formula( void ScOrcusSheet::set_string(row_t row, col_t col, size_t sindex) { - // Calc does not yet support shared strings so we have to - // workaround by importing shared strings into a temporary - // shared string container and writing into calc model as - // normal string + // 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. - const OUString& rSharedString = mrSharedStrings.getByIndex(sindex); - mrDoc.SetTextCell(ScAddress(col,row,mnTab), rSharedString); + mrFactory.pushStringCell(ScAddress(col, row, mnTab), sindex); } void ScOrcusSheet::set_value(row_t row, col_t col, double value) @@ -218,28 +241,23 @@ void ScOrcusSheet::set_bool(row_t row, col_t col, bool value) mrDoc.SetValue(col, row, mnTab, value ? 1.0 : 0.0); } +ScOrcusSharedStrings::ScOrcusSharedStrings(std::vector<OUString>& rStrings) : + mrStrings(rStrings) {} + size_t ScOrcusSharedStrings::append(const char* s, size_t n) { OUString aNewString(s, n, RTL_TEXTENCODING_UTF8); - maSharedStrings.push_back(aNewString); + mrStrings.push_back(aNewString); - return maSharedStrings.size() - 1; + return mrStrings.size() - 1; } size_t ScOrcusSharedStrings::add(const char* s, size_t n) { OUString aNewString(s, n, RTL_TEXTENCODING_UTF8); - maSharedStrings.push_back(aNewString); - - return maSharedStrings.size() - 1; -} - -const OUString& ScOrcusSharedStrings::getByIndex(size_t nIndex) const -{ - if(nIndex < maSharedStrings.size()) - return maSharedStrings[nIndex]; + mrStrings.push_back(aNewString); - return EMPTY_OUSTRING; + return mrStrings.size() - 1; } void ScOrcusSharedStrings::set_segment_bold(bool /*b*/) |