diff options
author | Kohei Yoshida <kohei.yoshida@gmail.com> | 2012-11-09 22:10:54 -0500 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@gmail.com> | 2012-11-28 13:28:29 -0500 |
commit | f10c5f33c17093bac8dd09b1a3b6ea39bdb6020c (patch) | |
tree | 367a5d7b5b3f9344878707c3b4a86ba10d4015a2 /sc | |
parent | eb85e45358d641a9beb246a97c3144b3d4a591ee (diff) |
Register range links to orcus_xml too.
But range links fail to import. Looks like sheet names are corrupted.
I need to debug this...
Change-Id: If2aeb3b81db65749f05edfbdd2f3388be4f2539c
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/orcusxml.hxx | 3 | ||||
-rw-r--r-- | sc/source/core/tool/orcusxml.cxx | 2 | ||||
-rw-r--r-- | sc/source/filter/orcus/orcusfiltersimpl.cxx | 67 | ||||
-rw-r--r-- | sc/source/ui/xmlsource/xmlsourcedlg.cxx | 75 |
4 files changed, 122 insertions, 25 deletions
diff --git a/sc/inc/orcusxml.hxx b/sc/inc/orcusxml.hxx index 1a0b1927b71f..c3a981da3622 100644 --- a/sc/inc/orcusxml.hxx +++ b/sc/inc/orcusxml.hxx @@ -31,7 +31,8 @@ struct ScOrcusXMLTreeParam { EntryType meType; ScAddress maLinkedPos; /// linked cell position (invalid if unlinked) - bool mbRangeParent; + bool mbRangeParent:1; + bool mbLeafNode:1; /// Leaf if it has no child elements. Child Attributes don't count. SC_DLLPUBLIC EntryData(EntryType eType); }; diff --git a/sc/source/core/tool/orcusxml.cxx b/sc/source/core/tool/orcusxml.cxx index 5ad41de47cd6..3f3c93c159e2 100644 --- a/sc/source/core/tool/orcusxml.cxx +++ b/sc/source/core/tool/orcusxml.cxx @@ -12,7 +12,7 @@ #include "svtools/treelistbox.hxx" ScOrcusXMLTreeParam::EntryData::EntryData(EntryType eType) : - meType(eType), maLinkedPos(ScAddress::INITIALIZE_INVALID), mbRangeParent(false) {} + meType(eType), maLinkedPos(ScAddress::INITIALIZE_INVALID), mbRangeParent(false), mbLeafNode(true) {} ScOrcusXMLTreeParam::EntryData* ScOrcusXMLTreeParam::getUserData(SvTreeListEntry& rEntry) { diff --git a/sc/source/filter/orcus/orcusfiltersimpl.cxx b/sc/source/filter/orcus/orcusfiltersimpl.cxx index 2ced6b540845..ba3701a5b6d9 100644 --- a/sc/source/filter/orcus/orcusfiltersimpl.cxx +++ b/sc/source/filter/orcus/orcusfiltersimpl.cxx @@ -113,8 +113,11 @@ orcus::spreadsheet::iface::import_sheet* ScOrcusFactory::get_sheet(const char* s OUString aTabName(sheet_name, sheet_name_length, RTL_TEXTENCODING_UTF8); SCTAB nTab = -1; if (!mrDoc.GetTable(aTabName, nTab)) + { // Sheet by that name not found. + fprintf(stdout, "ScOrcusFactory::get_sheet: no such sheet!!! (%s)\n", rtl::OUStringToOString(aTabName, RTL_TEXTENCODING_UTF8).getStr()); return NULL; + } // See if we already have an orcus sheet instance by that index. boost::ptr_vector<ScOrcusSheet>::iterator it = @@ -211,11 +214,12 @@ bool ScOrcusFiltersImpl::importCSV(ScDocument& rDoc, const OUString& rPath) cons namespace { -void setUserDataToEntry( +ScOrcusXMLTreeParam::EntryData& setUserDataToEntry( SvTreeListEntry& rEntry, ScOrcusXMLTreeParam::UserDataStoreType& rStore, ScOrcusXMLTreeParam::EntryType eType) { rStore.push_back(new ScOrcusXMLTreeParam::EntryData(eType)); rEntry.SetUserData(&rStore.back()); + return rStore.back(); } void populateTree( @@ -229,7 +233,7 @@ void populateTree( // Can this ever happen!? return; - setUserDataToEntry( + ScOrcusXMLTreeParam::EntryData& rEntryData = setUserDataToEntry( *pEntry, rParam.maUserDataStore, bRepeat ? ScOrcusXMLTreeParam::ElementRepeat : ScOrcusXMLTreeParam::ElementDefault); @@ -266,6 +270,9 @@ void populateTree( rWalker.get_children(aNames); + // Non-leaf if it has child elements, leaf otherwise. + rEntryData.mbLeafNode = aNames.empty(); + // Insert child elements recursively. for (it = aNames.begin(), itEnd = aNames.end(); it != itEnd; ++it) { @@ -333,6 +340,22 @@ bool ScOrcusFiltersImpl::loadXMLStructure( return true; } +namespace { + +class InsertFieldPath : std::unary_function<OString, void> +{ + orcus::orcus_xml& mrFilter; +public: + InsertFieldPath(orcus::orcus_xml& rFilter) : mrFilter(rFilter) {} + void operator() (const OString& rPath) + { + fprintf(stdout, "InsertFieldPath::(): field path = '%s'\n", rPath.getStr()); + mrFilter.append_field_link(rPath.getStr()); + } +}; + +} + bool ScOrcusFiltersImpl::importXML( ScDocument& rDoc, const rtl::OUString& rPath, const ScOrcusImportXMLParam& rParam) const { @@ -344,18 +367,38 @@ bool ScOrcusFiltersImpl::importXML( orcus::orcus_xml filter(&aFactory, NULL); // Set cell links. - ScOrcusImportXMLParam::CellLinksType::const_iterator it = rParam.maCellLinks.begin(); - ScOrcusImportXMLParam::CellLinksType::const_iterator itEnd = rParam.maCellLinks.end(); + { + ScOrcusImportXMLParam::CellLinksType::const_iterator it = rParam.maCellLinks.begin(); + ScOrcusImportXMLParam::CellLinksType::const_iterator itEnd = rParam.maCellLinks.end(); + for (; it != itEnd; ++it) + { + const ScOrcusImportXMLParam::CellLink& rLink = *it; + OUString aTabName; + rDoc.GetName(rLink.maPos.Tab(), aTabName); + filter.set_cell_link( + rLink.maPath.getStr(), + rtl::OUStringToOString(aTabName, RTL_TEXTENCODING_UTF8).getStr(), + rLink.maPos.Row(), rLink.maPos.Col()); + } + } - for (; it != itEnd; ++it) + // Set range links. { - const ScOrcusImportXMLParam::CellLink& rLink = *it; - OUString aTabName; - rDoc.GetName(rLink.maPos.Tab(), aTabName); - filter.set_cell_link( - rLink.maPath.getStr(), - rtl::OUStringToOString(aTabName, RTL_TEXTENCODING_UTF8).getStr(), - rLink.maPos.Row(), rLink.maPos.Col()); + ScOrcusImportXMLParam::RangeLinksType::const_iterator it = rParam.maRangeLinks.begin(); + ScOrcusImportXMLParam::RangeLinksType::const_iterator itEnd = rParam.maRangeLinks.end(); + for (; it != itEnd; ++it) + { + const ScOrcusImportXMLParam::RangeLink& rLink = *it; + OUString aTabName; + rDoc.GetName(rLink.maPos.Tab(), aTabName); + filter.start_range( + rtl::OUStringToOString(aTabName, RTL_TEXTENCODING_UTF8).getStr(), + rLink.maPos.Row(), rLink.maPos.Col()); + + std::for_each(rLink.maFieldPaths.begin(), rLink.maFieldPaths.end(), InsertFieldPath(filter)); + + filter.commit_range(); + } } filter.read_file(path); diff --git a/sc/source/ui/xmlsource/xmlsourcedlg.cxx b/sc/source/ui/xmlsource/xmlsourcedlg.cxx index 7821b9b14b68..62d2f4070bd8 100644 --- a/sc/source/ui/xmlsource/xmlsourcedlg.cxx +++ b/sc/source/ui/xmlsource/xmlsourcedlg.cxx @@ -414,26 +414,79 @@ bool ScXMLSourceDlg::IsChildrenDirty(SvTreeListEntry* pEntry) const return false; } +namespace { + +/** + * Pick only the leaf elements. + */ +void getFieldLinks(ScOrcusImportXMLParam::RangeLink& rRangeLink, const SvTreeListBox& rTree, const SvTreeListEntry& rEntry) +{ + const SvTreeListEntries& rChildren = rEntry.GetChildEntries(); + if (rChildren.empty()) + // No more children. We're done. + return; + + SvTreeListEntries::const_iterator it = rChildren.begin(), itEnd = rChildren.end(); + for (; it != itEnd; ++it) + { + const SvTreeListEntry& rChild = *it; + OUString aPath = getXPath(rTree, rChild); + + const ScOrcusXMLTreeParam::EntryData* pUserData = ScOrcusXMLTreeParam::getUserData(rChild); + fprintf(stdout, "getFieldLinks: path = '%s' leaf = %d\n", rtl::OUStringToOString(aPath, RTL_TEXTENCODING_UTF8).getStr(), pUserData->mbLeafNode); + if (pUserData && pUserData->mbLeafNode) + { + if (!aPath.isEmpty()) + // XPath should never be empty anyway, but it won't hurt to check... + rRangeLink.maFieldPaths.push_back(rtl::OUStringToOString(aPath, RTL_TEXTENCODING_UTF8)); + } + + // Walk recursively. + getFieldLinks(rRangeLink, rTree, rChild); + } +} + +} + void ScXMLSourceDlg::OkPressed() { // Begin import. ScOrcusImportXMLParam aParam; - std::set<const SvTreeListEntry*>::const_iterator it = maCellLinks.begin(), itEnd = maCellLinks.end(); - for (; it != itEnd; ++it) + // Convert single cell links. { - const SvTreeListEntry& rEntry = **it; - OUString aPath = getXPath(maLbTree, rEntry); - const ScOrcusXMLTreeParam::EntryData* pUserData = ScOrcusXMLTreeParam::getUserData(rEntry); - ScAddress aPos = pUserData->maLinkedPos; - - aParam.maCellLinks.push_back( - ScOrcusImportXMLParam::CellLink( - aPos, rtl::OUStringToOString(aPath, RTL_TEXTENCODING_UTF8))); + std::set<const SvTreeListEntry*>::const_iterator it = maCellLinks.begin(), itEnd = maCellLinks.end(); + for (; it != itEnd; ++it) + { + const SvTreeListEntry& rEntry = **it; + OUString aPath = getXPath(maLbTree, rEntry); + const ScOrcusXMLTreeParam::EntryData* pUserData = ScOrcusXMLTreeParam::getUserData(rEntry); + + aParam.maCellLinks.push_back( + ScOrcusImportXMLParam::CellLink( + pUserData->maLinkedPos, rtl::OUStringToOString(aPath, RTL_TEXTENCODING_UTF8))); + } } - // TODO: Process range links. + // Convert range links. For now, an element with range link takes all its + // child elements as its fields. + { + std::set<const SvTreeListEntry*>::const_iterator it = maRangeLinks.begin(), itEnd = maRangeLinks.end(); + for (; it != itEnd; ++it) + { + const SvTreeListEntry& rEntry = **it; + const ScOrcusXMLTreeParam::EntryData* pUserData = ScOrcusXMLTreeParam::getUserData(rEntry); + + ScOrcusImportXMLParam::RangeLink aRangeLink; + aRangeLink.maPos = pUserData->maLinkedPos; + + // Go through all its child elements. + getFieldLinks(aRangeLink, maLbTree, rEntry); + + aParam.maRangeLinks.push_back(aRangeLink); + } + } ScOrcusFilters* pOrcus = ScFormatFilter::Get().GetOrcusFilters(); if (!pOrcus) |