sc/inc/orcusxml.hxx | 3 - sc/source/core/tool/orcusxml.cxx | 2 sc/source/filter/orcus/orcusfiltersimpl.cxx | 67 ++++++++++++++++++++----- sc/source/ui/xmlsource/xmlsourcedlg.cxx | 75 +++++++++++++++++++++++----- 4 files changed, 122 insertions(+), 25 deletions(-)
New commits: commit b5f009b9cfbda95571fe05d26326c9ca0ca29650 Author: Kohei Yoshida <kohei.yosh...@gmail.com> Date: Fri Nov 9 22:10:54 2012 -0500 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 diff --git a/sc/inc/orcusxml.hxx b/sc/inc/orcusxml.hxx index 1a0b192..c3a981d 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 5ad41de..3f3c93c 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 2ced6b5..ba3701a 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 7821b9b..62d2f40 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) _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits