From ab1813a4454cbe639e99eaee7cd1115bfed1cf8f Mon Sep 17 00:00:00 2001 From: Miika Turkia Date: Sun, 7 May 2017 09:41:27 +0300 Subject: Move intdup to qthelper Signed-off-by: Miika Turkia --- core/qthelper.cpp | 9 +++++++++ core/qthelper.h | 1 + 2 files changed, 10 insertions(+) (limited to 'core') diff --git a/core/qthelper.cpp b/core/qthelper.cpp index 79fc0effc..993ecbf7d 100644 --- a/core/qthelper.cpp +++ b/core/qthelper.cpp @@ -1509,3 +1509,12 @@ QString getUUID() uuidString.replace("{", "").replace("}", ""); return uuidString; } + +char *intdup(int index) +{ + char tmpbuf[21]; + + snprintf(tmpbuf, sizeof(tmpbuf) - 2, "%d", index); + tmpbuf[20] = 0; + return strdup(tmpbuf); +} diff --git a/core/qthelper.h b/core/qthelper.h index 9788bb55d..a85294963 100644 --- a/core/qthelper.h +++ b/core/qthelper.h @@ -46,5 +46,6 @@ extern "C" enum deco_mode decoMode(); extern "C" void subsurface_mkdir(const char *dir); void init_proxy(); QString getUUID(); +char *intdup(int index); #endif // QTHELPER_H -- cgit v1.2.3-70-g09d2 From 0dfa448d8c7132bd0058a6fb3bc820fdde2a4759 Mon Sep 17 00:00:00 2001 From: Miika Turkia Date: Sun, 7 May 2017 13:41:09 +0300 Subject: Refactor Seabear import Moving the GUI independent Seabear import functionality to Subsurface core. This will allow Robert to call it directly from download from DC. Tested with H3 against released and daily versions of Subsurface. The result differs somewhat, but it is actually fixing 2 bugs: - Temperature was mis-interpreted previously - Sample interval for a dive with 1 second interval was parsed incorrectly Signed-off-by: Miika Turkia --- core/dive.h | 1 + core/file.c | 21 ++++++++ core/qthelper.cpp | 91 +++++++++++++++++++++++++++++++++ core/qthelper.h | 1 + core/qthelperfromc.h | 1 + desktop-widgets/divelogimportdialog.cpp | 51 +----------------- 6 files changed, 116 insertions(+), 50 deletions(-) (limited to 'core') diff --git a/core/dive.h b/core/dive.h index fa6133bd3..4402788c2 100644 --- a/core/dive.h +++ b/core/dive.h @@ -704,6 +704,7 @@ extern int parse_dlf_buffer(unsigned char *buffer, size_t size); extern int parse_file(const char *filename); extern int parse_csv_file(const char *filename, char **params, int pnr, const char *csvtemplate); +extern int parse_seabear_log(const char *filename); extern int parse_seabear_csv_file(const char *filename, char **params, int pnr, const char *csvtemplate); extern int parse_txt_file(const char *filename, const char *csv); extern int parse_manual_file(const char *filename, char **params, int pnr); diff --git a/core/file.c b/core/file.c index ba2956d60..6dc082fc7 100644 --- a/core/file.c +++ b/core/file.c @@ -1055,6 +1055,27 @@ int parse_csv_file(const char *filename, char **params, int pnr, const char *csv } #define SBPARAMS 40 +int parse_seabear_log(const char *filename) +{ + char *params[SBPARAMS]; + int pnr = 0; + + pnr = parse_seabear_header(filename, params, pnr); + + if (parse_seabear_csv_file(filename, params, pnr, "csv") < 0) { + return -1; + } + // Seabear CSV stores NDL and TTS in Minutes, not seconds + struct dive *dive = dive_table.dives[dive_table.nr - 1]; + for(int s_nr = 0 ; s_nr < dive->dc.samples ; s_nr++) { + struct sample *sample = dive->dc.sample + s_nr; + sample->ndl.seconds *= 60; + sample->tts.seconds *= 60; + } + + return 0; +} + int parse_seabear_csv_file(const char *filename, char **params, int pnr, const char *csvtemplate) { int ret, i; diff --git a/core/qthelper.cpp b/core/qthelper.cpp index 993ecbf7d..0673a78ce 100644 --- a/core/qthelper.cpp +++ b/core/qthelper.cpp @@ -1510,6 +1510,97 @@ QString getUUID() return uuidString; } +int parse_seabear_header(const char *filename, char **params, int pnr) +{ + QFile f(filename); + + f.open(QFile::ReadOnly); + QString parseLine = f.readLine(); + + /* + * Parse header - currently only interested in sample + * interval and hardware version. If we have old format + * the interval value is missing from the header. + */ + + while ((parseLine = f.readLine().trimmed()).length() > 0 && !f.atEnd()) { + if (parseLine.contains("//Hardware Version: ")) { + params[pnr++] = strdup("hw"); + params[pnr++] = strdup(parseLine.replace(QString::fromLatin1("//Hardware Version: "), QString::fromLatin1("\"Seabear ")).trimmed().append("\"").toUtf8().data()); + break; + } + } + + /* + * Note that we scan over the "Log interval" on purpose + */ + + while ((parseLine = f.readLine().trimmed()).length() > 0 && !f.atEnd()) { + if (parseLine.contains("//Log interval: ")) { + params[pnr++] = strdup("delta"); + params[pnr++] = strdup(parseLine.remove(QString::fromLatin1("//Log interval: ")).trimmed().remove(QString::fromLatin1(" s")).toUtf8().data()); + } + } + + /* + * Parse CSV fields + */ + + parseLine = f.readLine().trimmed(); + + QStringList currColumns = parseLine.split(';'); + unsigned short index = 0; + Q_FOREACH (QString columnText, currColumns) { + if (columnText == "Time") { + params[pnr++] = strdup("timeField"); + params[pnr++] = intdup(index++); + } else if (columnText == "Depth") { + params[pnr++] = strdup("depthField"); + params[pnr++] = intdup(index++); + } else if (columnText == "Temperature") { + params[pnr++] = strdup("tempField"); + params[pnr++] = intdup(index++); + } else if (columnText == "NDT") { + params[pnr++] = strdup("ndlField"); + params[pnr++] = intdup(index++); + } else if (columnText == "TTS") { + params[pnr++] = strdup("ttsField"); + params[pnr++] = intdup(index++); + } else if (columnText == "pO2_1") { + params[pnr++] = strdup("o2sensor1Field"); + params[pnr++] = intdup(index++); + } else if (columnText == "pO2_2") { + params[pnr++] = strdup("o2sensor2Field"); + params[pnr++] = intdup(index++); + } else if (columnText == "pO2_3") { + params[pnr++] = strdup("o2sensor3Field"); + params[pnr++] = intdup(index++); + } else if (columnText == "Ceiling") { + /* TODO: Add support for dive computer reported ceiling*/ + params[pnr++] = strdup("ceilingField"); + params[pnr++] = intdup(index++); + } else if (columnText == "Tank pressure") { + params[pnr++] = strdup("pressureField"); + params[pnr++] = intdup(index++); + } else { + // We do not know about this value + qDebug() << "Seabear import found an un-handled field: " << columnText; + } + } + + /* Separator is ';' and the index for that in DiveLogImportDialog constructor is 2 */ + params[pnr++] = strdup("separatorIndex"); + params[pnr++] = intdup(2); + + /* And metric units */ + params[pnr++] = strdup("units"); + params[pnr++] = intdup(0); + + params[pnr] = NULL; + f.close(); + return pnr; +} + char *intdup(int index) { char tmpbuf[21]; diff --git a/core/qthelper.h b/core/qthelper.h index a85294963..8d06ce93e 100644 --- a/core/qthelper.h +++ b/core/qthelper.h @@ -47,5 +47,6 @@ extern "C" void subsurface_mkdir(const char *dir); void init_proxy(); QString getUUID(); char *intdup(int index); +extern "C" int parse_seabear_header(const char *filename, char **params, int pnr); #endif // QTHELPER_H diff --git a/core/qthelperfromc.h b/core/qthelperfromc.h index 4b2ef3d53..91fbde415 100644 --- a/core/qthelperfromc.h +++ b/core/qthelperfromc.h @@ -20,5 +20,6 @@ char *hashfile_name_string(); char *picturedir_string(); const char *subsurface_user_agent(); enum deco_mode decoMode(); +int parse_seabear_header(const char *filename, char **params, int pnr); #endif // QTHELPERFROMC_H diff --git a/desktop-widgets/divelogimportdialog.cpp b/desktop-widgets/divelogimportdialog.cpp index 9a455fcdb..51046216f 100644 --- a/desktop-widgets/divelogimportdialog.cpp +++ b/desktop-widgets/divelogimportdialog.cpp @@ -846,58 +846,9 @@ void DiveLogImportDialog::on_buttonBox_accepted() if (ui->knownImports->currentText() != "Manual import") { for (int i = 0; i < fileNames.size(); ++i) { if (ui->knownImports->currentText() == "Seabear CSV") { - char *params[40]; - int pnr = 0; - params[pnr++] = strdup("timeField"); - params[pnr++] = intdup(r.indexOf(tr("Sample time"))); - params[pnr++] = strdup("depthField"); - params[pnr++] = intdup(r.indexOf(tr("Sample depth"))); - params[pnr++] = strdup("tempField"); - params[pnr++] = intdup(r.indexOf(tr("Sample temperature"))); - params[pnr++] = strdup("po2Field"); - params[pnr++] = intdup(r.indexOf(tr("Sample pO₂"))); - params[pnr++] = strdup("o2sensor1Field"); - params[pnr++] = intdup(r.indexOf(tr("Sample sensor1 pO₂"))); - params[pnr++] = strdup("o2sensor2Field"); - params[pnr++] = intdup(r.indexOf(tr("Sample sensor2 pO₂"))); - params[pnr++] = strdup("o2sensor3Field"); - params[pnr++] = intdup(r.indexOf(tr("Sample sensor3 pO₂"))); - params[pnr++] = strdup("cnsField"); - params[pnr++] = intdup(r.indexOf(tr("Sample CNS"))); - params[pnr++] = strdup("ndlField"); - params[pnr++] = intdup(r.indexOf(tr("Sample NDL"))); - params[pnr++] = strdup("ttsField"); - params[pnr++] = intdup(r.indexOf(tr("Sample TTS"))); - params[pnr++] = strdup("stopdepthField"); - params[pnr++] = intdup(r.indexOf(tr("Sample stopdepth"))); - params[pnr++] = strdup("pressureField"); - params[pnr++] = intdup(r.indexOf(tr("Sample pressure"))); - params[pnr++] = strdup("setpointFiend"); - params[pnr++] = intdup(-1); - params[pnr++] = strdup("separatorIndex"); - params[pnr++] = intdup(ui->CSVSeparator->currentIndex()); - params[pnr++] = strdup("units"); - params[pnr++] = intdup(ui->CSVUnits->currentIndex()); - params[pnr++] = strdup("delta"); - params[pnr++] = strdup(delta.toUtf8().data()); - if (hw.length()) { - params[pnr++] = strdup("hw"); - params[pnr++] = strdup(hw.toUtf8().data()); - } - params[pnr++] = NULL; + parse_seabear_log(fileNames[i].toUtf8().data()); - if (parse_seabear_csv_file(fileNames[i].toUtf8().data(), - params, pnr - 1, "csv") < 0) { - return; - } - // Seabear CSV stores NDL and TTS in Minutes, not seconds - struct dive *dive = dive_table.dives[dive_table.nr - 1]; - for(int s_nr = 0 ; s_nr < dive->dc.samples ; s_nr++) { - struct sample *sample = dive->dc.sample + s_nr; - sample->ndl.seconds *= 60; - sample->tts.seconds *= 60; - } } else { char *params[49]; int pnr = 0; -- cgit v1.2.3-70-g09d2 From cef56c6290c82b882181bf7477ee96ad4fa65dcd Mon Sep 17 00:00:00 2001 From: Miika Turkia Date: Sun, 7 May 2017 14:19:58 +0300 Subject: Import dive number from Seabear CSV file Signed-off-by: Miika Turkia --- core/qthelper.cpp | 13 +++++++++++++ xslt/csv2xml.xslt | 7 +++++++ 2 files changed, 20 insertions(+) (limited to 'core') diff --git a/core/qthelper.cpp b/core/qthelper.cpp index 0673a78ce..cbfbd2f72 100644 --- a/core/qthelper.cpp +++ b/core/qthelper.cpp @@ -1517,6 +1517,19 @@ int parse_seabear_header(const char *filename, char **params, int pnr) f.open(QFile::ReadOnly); QString parseLine = f.readLine(); + /* + * Parse dive number from Seabear CSV header + */ + + while ((parseLine = f.readLine().trimmed()).length() > 0 && !f.atEnd()) { + if (parseLine.contains("//DIVE NR: ")) { + qDebug() << "DEBGU: " << parseLine; + params[pnr++] = strdup("diveNro"); + params[pnr++] = strdup(parseLine.replace(QString::fromLatin1("//DIVE NR: "), QString::fromLatin1("")).toUtf8().data()); + break; + } + } + /* * Parse header - currently only interested in sample * interval and hardware version. If we have old format diff --git a/xslt/csv2xml.xslt b/xslt/csv2xml.xslt index 960f48395..fadb5f443 100644 --- a/xslt/csv2xml.xslt +++ b/xslt/csv2xml.xslt @@ -26,6 +26,7 @@ + @@ -111,6 +112,12 @@ + + + + + + -- cgit v1.2.3-70-g09d2 From 6e1c00078dc440ca96745315455b731ca3a5fa09 Mon Sep 17 00:00:00 2001 From: Miika Turkia Date: Sun, 7 May 2017 15:34:27 +0300 Subject: Add dive mode support for Seabear import Signed-off-by: Miika Turkia --- core/qthelper.cpp | 16 +++++++++++++++- xslt/csv2xml.xslt | 18 ++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) (limited to 'core') diff --git a/core/qthelper.cpp b/core/qthelper.cpp index cbfbd2f72..41c9d310b 100644 --- a/core/qthelper.cpp +++ b/core/qthelper.cpp @@ -1545,13 +1545,27 @@ int parse_seabear_header(const char *filename, char **params, int pnr) } /* - * Note that we scan over the "Log interval" on purpose + * Grab the sample interval */ while ((parseLine = f.readLine().trimmed()).length() > 0 && !f.atEnd()) { if (parseLine.contains("//Log interval: ")) { params[pnr++] = strdup("delta"); params[pnr++] = strdup(parseLine.remove(QString::fromLatin1("//Log interval: ")).trimmed().remove(QString::fromLatin1(" s")).toUtf8().data()); + break; + } + } + + /* + * Dive mode, can be: OC, APNEA, BOTTOM TIMER, CCR, CCR SENSORBOARD + * Note that we scan over the "Log interval" on purpose + */ + + while ((parseLine = f.readLine().trimmed()).length() > 0 && !f.atEnd()) { + QString needle = "//Mode: "; + if (parseLine.contains(needle)) { + params[pnr++] = strdup("diveMode"); + params[pnr++] = strdup(parseLine.replace(needle, QString::fromLatin1("")).prepend("\"").append("\"").toUtf8().data()); } } diff --git a/xslt/csv2xml.xslt b/xslt/csv2xml.xslt index fadb5f443..efe7c37ef 100644 --- a/xslt/csv2xml.xslt +++ b/xslt/csv2xml.xslt @@ -27,6 +27,7 @@ + @@ -144,6 +145,23 @@ + + + + + + + + + + + + + + + + + -- cgit v1.2.3-70-g09d2 From 221f67206b847373aa768fb201aa88410aa59801 Mon Sep 17 00:00:00 2001 From: Miika Turkia Date: Sun, 7 May 2017 15:53:35 +0300 Subject: Make parsing of Seabear header more robust This should work even if some header line is missing from some DC. Signed-off-by: Miika Turkia --- core/qthelper.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'core') diff --git a/core/qthelper.cpp b/core/qthelper.cpp index 41c9d310b..b597921b6 100644 --- a/core/qthelper.cpp +++ b/core/qthelper.cpp @@ -1529,6 +1529,7 @@ int parse_seabear_header(const char *filename, char **params, int pnr) break; } } + f.seek(0); /* * Parse header - currently only interested in sample @@ -1543,6 +1544,7 @@ int parse_seabear_header(const char *filename, char **params, int pnr) break; } } + f.seek(0); /* * Grab the sample interval @@ -1555,6 +1557,7 @@ int parse_seabear_header(const char *filename, char **params, int pnr) break; } } + f.seek(0); /* * Dive mode, can be: OC, APNEA, BOTTOM TIMER, CCR, CCR SENSORBOARD @@ -1568,6 +1571,10 @@ int parse_seabear_header(const char *filename, char **params, int pnr) params[pnr++] = strdup(parseLine.replace(needle, QString::fromLatin1("")).prepend("\"").append("\"").toUtf8().data()); } } + f.seek(0); + + while ((parseLine = f.readLine().trimmed()).length() > 0 && !f.atEnd()) { + } /* * Parse CSV fields -- cgit v1.2.3-70-g09d2 From d851549d9ce33f7a9c2329ab19efbf40dd56b8de Mon Sep 17 00:00:00 2001 From: Miika Turkia Date: Sun, 7 May 2017 15:54:36 +0300 Subject: Remove debug output Signed-off-by: Miika Turkia --- core/qthelper.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'core') diff --git a/core/qthelper.cpp b/core/qthelper.cpp index b597921b6..e5a046a05 100644 --- a/core/qthelper.cpp +++ b/core/qthelper.cpp @@ -1523,7 +1523,6 @@ int parse_seabear_header(const char *filename, char **params, int pnr) while ((parseLine = f.readLine().trimmed()).length() > 0 && !f.atEnd()) { if (parseLine.contains("//DIVE NR: ")) { - qDebug() << "DEBGU: " << parseLine; params[pnr++] = strdup("diveNro"); params[pnr++] = strdup(parseLine.replace(QString::fromLatin1("//DIVE NR: "), QString::fromLatin1("")).toUtf8().data()); break; -- cgit v1.2.3-70-g09d2 From c832973df5a8b22ea58bafba088835592aca632e Mon Sep 17 00:00:00 2001 From: Miika Turkia Date: Sun, 7 May 2017 16:27:41 +0300 Subject: Fix NDL and TTS for Seabear import Apparently the refactoring changed these values to be returned directly in seconds. Not sure why, but luckily we have test cases that discovered the change. Signed-off-by: Miika Turkia --- core/file.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'core') diff --git a/core/file.c b/core/file.c index 6dc082fc7..cde47cfef 100644 --- a/core/file.c +++ b/core/file.c @@ -1065,13 +1065,6 @@ int parse_seabear_log(const char *filename) if (parse_seabear_csv_file(filename, params, pnr, "csv") < 0) { return -1; } - // Seabear CSV stores NDL and TTS in Minutes, not seconds - struct dive *dive = dive_table.dives[dive_table.nr - 1]; - for(int s_nr = 0 ; s_nr < dive->dc.samples ; s_nr++) { - struct sample *sample = dive->dc.sample + s_nr; - sample->ndl.seconds *= 60; - sample->tts.seconds *= 60; - } return 0; } -- cgit v1.2.3-70-g09d2