aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dive.h2
-rw-r--r--parse-xml.c71
-rw-r--r--qt-ui/mainwindow.cpp19
-rw-r--r--qt-ui/mainwindow.h1
4 files changed, 68 insertions, 25 deletions
diff --git a/dive.h b/dive.h
index 8247a5f50..91c160e1f 100644
--- a/dive.h
+++ b/dive.h
@@ -49,6 +49,8 @@ extern "C" {
#endif
extern int last_xml_version;
+extern bool abort_read_of_old_file;
+extern bool v2_question_shown;
enum dive_comp_type {OC, CCR, PSCR, FREEDIVE, NUM_DC_TYPE}; // Flags (Open-circuit and Closed-circuit-rebreather) for setting dive computer type
enum cylinderuse {OC_GAS, DILUENT, OXYGEN, NUM_GAS_USE}; // The different uses for cylinders
diff --git a/parse-xml.c b/parse-xml.c
index 2e7882ece..90559d6c4 100644
--- a/parse-xml.c
+++ b/parse-xml.c
@@ -22,6 +22,8 @@
int verbose, quit;
int metric = 1;
int last_xml_version = -1;
+bool abort_read_of_old_file = false;
+bool v2_question_shown = false;
static xmlDoc *test_xslt_transforms(xmlDoc *doc, const char **params);
@@ -1669,44 +1671,54 @@ static void userid_stop(void)
in_userid = false;
}
-static void entry(const char *name, char *buf)
+static bool entry(const char *name, char *buf)
{
if (!strncmp(name, "version.program", sizeof("version.program") - 1) ||
- !strncmp(name, "version.divelog", sizeof("version.divelog") - 1))
+ !strncmp(name, "version.divelog", sizeof("version.divelog") - 1)) {
last_xml_version = atoi(buf);
+ if (last_xml_version < 3 && !v2_question_shown) {
+ // let's ask the user what they want to do about reverse geo coding
+ // and warn them that opening older XML files can take a while
+ // since C code shouldn't call the UI we set a global flag and bail
+ // from reading the file for now
+ abort_read_of_old_file = true;
+ return false;
+ }
+ }
if (in_userid) {
try_to_fill_userid(name, buf);
- return;
+ return true;
}
if (in_settings) {
try_to_fill_dc_settings(name, buf);
try_to_match_autogroup(name, buf);
- return;
+ return true;
}
if (cur_dive_site) {
try_to_fill_dive_site(&cur_dive_site, name, buf);
- return;
+ return true;
}
if (!cur_event.deleted) {
try_to_fill_event(name, buf);
- return;
+ return true;
}
if (cur_sample) {
try_to_fill_sample(cur_sample, name, buf);
- return;
+ return true;
}
if (cur_dc) {
try_to_fill_dc(cur_dc, name, buf);
- return;
+ return true;
}
if (cur_dive) {
try_to_fill_dive(cur_dive, name, buf);
- return;
+ return true;
}
if (cur_trip) {
try_to_fill_trip(&cur_trip, name, buf);
- return;
+ return true;
}
+ return true;
}
static const char *nodename(xmlNode *node, char *buf, int len)
@@ -1748,7 +1760,7 @@ static const char *nodename(xmlNode *node, char *buf, int len)
#define MAXNAME 32
-static void visit_one_node(xmlNode *node)
+static bool visit_one_node(xmlNode *node)
{
char *content;
static char buffer[MAXNAME];
@@ -1756,28 +1768,29 @@ static void visit_one_node(xmlNode *node)
content = node->content;
if (!content || xmlIsBlankNode(node))
- return;
+ return true;
name = nodename(node, buffer, sizeof(buffer));
- entry(name, content);
+ return entry(name, content);
}
-static void traverse(xmlNode *root);
+static bool traverse(xmlNode *root);
-static void traverse_properties(xmlNode *node)
+static bool traverse_properties(xmlNode *node)
{
xmlAttr *p;
+ bool ret = true;
for (p = node->properties; p; p = p->next)
- traverse(p->children);
+ if ((ret = traverse(p->children)) == false)
+ break;
+ return ret;
}
-static void visit(xmlNode *n)
+static bool visit(xmlNode *n)
{
- visit_one_node(n);
- traverse_properties(n);
- traverse(n->children);
+ return visit_one_node(n) && traverse_properties(n) && traverse(n->children);
}
static void DivingLog_importer(void)
@@ -1840,15 +1853,17 @@ static struct nesting {
{ NULL, }
};
-static void traverse(xmlNode *root)
+static bool traverse(xmlNode *root)
{
xmlNode *n;
+ bool ret = true;
for (n = root; n; n = n->next) {
struct nesting *rule = nesting;
if (!n->name) {
- visit(n);
+ if ((ret = visit(n)) == false)
+ break;
continue;
}
@@ -1860,10 +1875,12 @@ static void traverse(xmlNode *root)
if (rule->start)
rule->start();
- visit(n);
+ if ((ret = visit(n)) == false)
+ break;
if (rule->end)
rule->end();
}
+ return ret;
}
/* Per-file reset */
@@ -1910,6 +1927,7 @@ int parse_xml_buffer(const char *url, const char *buffer, int size,
{
xmlDoc *doc;
const char *res = preprocess_divelog_de(buffer);
+ int ret = 0;
target_table = table;
doc = xmlReadMemory(res, strlen(res), url, NULL, 0);
@@ -1924,11 +1942,14 @@ int parse_xml_buffer(const char *url, const char *buffer, int size,
reset_all();
dive_start();
doc = test_xslt_transforms(doc, params);
- traverse(xmlDocGetRootElement(doc));
+ if (!traverse(xmlDocGetRootElement(doc))) {
+ // we decided to give up on parsing... why?
+ ret = -1;
+ }
dive_end();
xmlFreeDoc(doc);
- return 0;
+ return ret;
}
void parse_mkvi_buffer(struct membuffer *txt, struct membuffer *csv, const char *starttime)
diff --git a/qt-ui/mainwindow.cpp b/qt-ui/mainwindow.cpp
index 648ead174..7b204626c 100644
--- a/qt-ui/mainwindow.cpp
+++ b/qt-ui/mainwindow.cpp
@@ -1345,6 +1345,18 @@ void MainWindow::importTxtFiles(const QStringList fileNames)
refreshDisplay();
}
+void MainWindow::showV2Dialog()
+{
+ // here we need to ask the user if / how they want to do the reverse geo coding
+ // for now this is just a warning that things could take a long time
+ QMessageBox d(QMessageBox::Information,
+ tr("Welcom to Subsurface %1").arg(subsurface_version()),
+ tr("Importing data files from earlier versions of Subsurface can take a significant amount of time"),
+ QMessageBox::Ok,
+ this);
+ d.exec();
+}
+
void MainWindow::loadFiles(const QStringList fileNames)
{
if (fileNames.isEmpty())
@@ -1362,6 +1374,13 @@ void MainWindow::loadFiles(const QStringList fileNames)
set_filename(fileNamePtr.data(), true);
setTitle(MWTF_FILENAME);
} else {
+ if (!v2_question_shown && abort_read_of_old_file) {
+ v2_question_shown = true;
+ abort_read_of_old_file = false;
+ showV2Dialog();
+ i--; // so we re-try this file
+ continue;
+ }
failedParses.append(fileNames.at(i));
}
}
diff --git a/qt-ui/mainwindow.h b/qt-ui/mainwindow.h
index 85a63123b..5f4567f76 100644
--- a/qt-ui/mainwindow.h
+++ b/qt-ui/mainwindow.h
@@ -90,6 +90,7 @@ public:
void printPlan();
void checkSurvey(QSettings *s);
void setApplicationState(const QByteArray& state);
+ void showV2Dialog();
QUndoStack *undoStack;
private
slots: