summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@gmail.com>2012-11-09 22:10:54 -0500
committerKohei Yoshida <kohei.yoshida@gmail.com>2012-11-28 13:28:29 -0500
commitf10c5f33c17093bac8dd09b1a3b6ea39bdb6020c (patch)
tree367a5d7b5b3f9344878707c3b4a86ba10d4015a2 /sc
parenteb85e45358d641a9beb246a97c3144b3d4a591ee (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.hxx3
-rw-r--r--sc/source/core/tool/orcusxml.cxx2
-rw-r--r--sc/source/filter/orcus/orcusfiltersimpl.cxx67
-rw-r--r--sc/source/ui/xmlsource/xmlsourcedlg.cxx75
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)