diff options
author | Dirk Hohndel <dirk@hohndel.org> | 2015-02-25 10:05:37 +0100 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2015-02-25 10:05:37 +0100 |
commit | 0ed4356fc28b9cf9474bbbfcdeb9bc49ff83b9ec (patch) | |
tree | 84d41603ad6daa8f12159da4692de8b1d31a35fa | |
parent | d15641a6facce67b48c5ae5e7bc56d2ed7492e67 (diff) | |
download | subsurface-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.h | 2 | ||||
-rw-r--r-- | parse-xml.c | 71 | ||||
-rw-r--r-- | qt-ui/mainwindow.cpp | 19 | ||||
-rw-r--r-- | qt-ui/mainwindow.h | 1 |
4 files changed, 68 insertions, 25 deletions
@@ -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: |