aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Dirk Hohndel <dirk@hohndel.org>2015-02-25 10:05:37 +0100
committerGravatar Dirk Hohndel <dirk@hohndel.org>2015-02-25 10:05:37 +0100
commit0ed4356fc28b9cf9474bbbfcdeb9bc49ff83b9ec (patch)
tree84d41603ad6daa8f12159da4692de8b1d31a35fa
parentd15641a6facce67b48c5ae5e7bc56d2ed7492e67 (diff)
downloadsubsurface-0ed4356fc28b9cf9474bbbfcdeb9bc49ff83b9ec.tar.gz
Display slowness warning before opening a V2 file
This is somewhat invasive as aborting the XML file read requires us to report things up the recursive parsing chain. What we really need to do here is to ask the user how they want to use the data from reverse geo lookup. But for now we only warn about the fact that this can take a while. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-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: