<div dir="ltr">One more thing. If I first import "stig dykker logg.lvd" that I sent you, then click on a dive or three, and then import "griffon.lvd", Subsurface crashes:<div><br></div><div><div>Thread 0 Crashed:: Dispatch queue: com.apple.main-thread</div><div>0 org.hohndel.subsurface <span class="" style="white-space:pre"> </span>0x00000001000157a7 try_to_open_liquivision + 3895</div><div>1 org.hohndel.subsurface <span class="" style="white-space:pre"> </span>0x0000000100010fde parse_file + 1358</div><div>2 org.hohndel.subsurface <span class="" style="white-space:pre"> </span>0x000000010007be3c MainWindow::importFiles(QStringList) + 300</div><div>3 org.hohndel.subsurface <span class="" style="white-space:pre"> </span>0x000000010007c4e3 MainWindow::on_actionImportDiveLog_triggered() + 931</div><div>4 org.hohndel.subsurface <span class="" style="white-space:pre"> </span>0x0000000100131310 MainWindow::qt_metacall(QMetaObject::Call, int, void**) + 80</div><div>5 QtCore <span class="" style="white-space:pre"> </span>0x00000001034faf86 QMetaObject::activate(QObject*, int, int, void**) + 2374</div><div>6 QtWidgets <span class="" style="white-space:pre"> </span>0x0000000103e6faef QAction::activate(QAction::ActionEvent) + 271</div><div>7 QtWidgets <span class="" style="white-space:pre"> </span>0x0000000103e6ff54 QAction::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) + 404</div><div>8 QtCore <span class="" style="white-space:pre"> </span>0x00000001034fb015 QMetaObject::activate(QObject*, int, int, void**) + 2517</div><div>9 libqcocoa.dylib <span class="" style="white-space:pre"> </span>0x00000001069ec310 -[QCocoaMenuDelegate itemFired:] + 112</div><div>10 libsystem_trace.dylib <span class="" style="white-space:pre"> </span>0x00007fff8b09ccd7 _os_activity_initiate + 75</div><div>11 com.apple.AppKit <span class="" style="white-space:pre"> </span>0x00007fff91c6b5e7 -[NSApplication sendAction:to:from:] + 410</div><div>12 com.apple.AppKit <span class="" style="white-space:pre"> </span>0x00007fff91c8572a -[NSMenuItem _corePerformAction] + 382</div><div>13 com.apple.AppKit <span class="" style="white-space:pre"> </span>0x00007fff91c85447 -[NSCarbonMenuImpl performActionWithHighlightingForItemAtIndex:] + 114</div><div>14 libsystem_trace.dylib <span class="" style="white-space:pre"> </span>0x00007fff8b09ccd7 _os_activity_initiate + 75</div><div>15 com.apple.AppKit <span class="" style="white-space:pre"> </span>0x00007fff91cd2ce6 -[NSMenu performActionForItemAtIndex:] + 131</div><div>16 com.apple.AppKit <span class="" style="white-space:pre"> </span>0x00007fff91cd2c56 -[NSMenu _internalPerformActionForItemAtIndex:] + 35</div><div>17 com.apple.AppKit <span class="" style="white-space:pre"> </span>0x00007fff91cd2aa2 -[NSCarbonMenuImpl _carbonCommandProcessEvent:handlerCallRef:] + 107</div><div>18 com.apple.AppKit <span class="" style="white-space:pre"> </span>0x00007fff91c7b03b NSSLMMenuEventHandler + 724</div><div>19 com.apple.HIToolbox <span class="" style="white-space:pre"> </span>0x00007fff925c232c DispatchEventToHandlers(EventTargetRec*, OpaqueEventRef*, HandlerCallRec*) + 1260</div><div>20 com.apple.HIToolbox <span class="" style="white-space:pre"> </span>0x00007fff925c176e SendEventToEventTargetInternal(OpaqueEventRef*, OpaqueEventTargetRef*, HandlerCallRec*) + 386</div><div>21 com.apple.HIToolbox <span class="" style="white-space:pre"> </span>0x00007fff925d6286 SendEventToEventTarget + 40</div><div>22 com.apple.HIToolbox <span class="" style="white-space:pre"> </span>0x00007fff9260b795 SendHICommandEvent(unsigned int, HICommand const*, unsigned int, unsigned int, unsigned char, void const*, OpaqueEventTargetRef*, OpaqueEventTargetRef*, OpaqueEventRef**) + 428</div><div>23 com.apple.HIToolbox <span class="" style="white-space:pre"> </span>0x00007fff9263ee8d SendMenuCommandWithContextAndModifiers + 59</div><div>24 com.apple.HIToolbox <span class="" style="white-space:pre"> </span>0x00007fff9263ee34 SendMenuItemSelectedEvent + 188</div><div>25 com.apple.HIToolbox <span class="" style="white-space:pre"> </span>0x00007fff9263ed06 FinishMenuSelection(SelectionData*, MenuResult*, MenuResult*) + 96</div><div>26 com.apple.HIToolbox <span class="" style="white-space:pre"> </span>0x00007fff926468b1 MenuSelectCore(MenuData*, Point, double, unsigned int, OpaqueMenuRef**, unsigned short*) + 702</div><div>27 com.apple.HIToolbox <span class="" style="white-space:pre"> </span>0x00007fff9264649e _HandleMenuSelection2 + 446</div><div>28 com.apple.AppKit <span class="" style="white-space:pre"> </span>0x00007fff91c00e6e _NSHandleCarbonMenuEvent + 277</div><div>29 com.apple.AppKit <span class="" style="white-space:pre"> </span>0x00007fff91a9cb90 _DPSNextEvent + 1843</div><div>30 com.apple.AppKit <span class="" style="white-space:pre"> </span>0x00007fff91a9bfd0 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 194</div><div>31 com.apple.AppKit <span class="" style="white-space:pre"> </span>0x00007fff91a8ff73 -[NSApplication run] + 594</div><div>32 libqcocoa.dylib <span class="" style="white-space:pre"> </span>0x00000001069e891d QCocoaEventDispatcher::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) + 2189</div><div>33 QtCore <span class="" style="white-space:pre"> </span>0x00000001034c565d QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) + 381</div><div>34 QtCore <span class="" style="white-space:pre"> </span>0x00000001034c863c QCoreApplication::exec() + 364</div><div>35 org.hohndel.subsurface <span class="" style="white-space:pre"> </span>0x0000000100018d42 main + 1698</div><div>36 org.hohndel.subsurface <span class="" style="white-space:pre"> </span>0x0000000100006894 start + 52</div></div><div><br></div><div><br></div><div>Henrik</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Nov 7, 2014 at 6:18 PM, Henrik Brautaset Aronsen <span dir="ltr"><<a href="mailto:subsurface@henrik.synth.no" target="_blank">subsurface@henrik.synth.no</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>It works fine with the files I tried. Just a couple of things:</div><div><br></div>I think you need to add ...<br><br> extern int try_to_open_liquivision(const char *filename, struct memblock *mem);<br><br>... in file.h, my compiler complains:<br><br> file.c:361:10: warning: implicit declaration of function 'try_to_open_liquivision' is invalid in C99.<br><br>Also, there seems to be a = vs == problem in:<br><br> liquivision.c:225:23: note: use '=' to turn this equality comparison into an assignment<span class=""><br> sample-><a href="http://depth.mm" target="_blank">depth.mm</a> == array_uint16_le(ds + (d - 1) * 2) * 10; // cm->mm<br><br><br></span><span class="HOEnZb"><font color="#888888">Henrik</font></span><div><div class="h5"><br><br><br>On Fri, Nov 7, 2014 at 6:10 PM, Henrik Brautaset Aronsen <<a href="mailto:subsurface@henrik.synth.no" target="_blank">subsurface@henrik.synth.no</a>> wrote:<br>><br>> Great work!<br>><br>> H<br>><br>> On Fri, Nov 7, 2014 at 5:30 PM, John Van Ostrand <<a href="mailto:john@vanostrand.com" target="_blank">john@vanostrand.com</a>> wrote:<br>>><br>>> Support includes cylinder pressures and works for v3.0 log files.<br>>> ---<br>>> CMakeLists.txt | 1 +<br>>> file.c | 2 +<br>>> liquivision.c | 352 +++++++++++++++++++++++++++++++++++++++++++++++++++<br>>> qt-ui/mainwindow.cpp | 8 +-<br>>> <a href="http://subsurface.pro" target="_blank">subsurface.pro</a> | 1 +<br>>> 5 files changed, 361 insertions(+), 3 deletions(-)<br>>> create mode 100644 liquivision.c<br>>><br>>> diff --git a/CMakeLists.txt b/CMakeLists.txt<br>>> index c04e968..868ad4f 100644<br>>> --- a/CMakeLists.txt<br>>> +++ b/CMakeLists.txt<br>>> @@ -85,6 +85,7 @@ SET(SUBSURFACE_CORE_LIB_SRCS<br>>> equipment.c<br>>> file.c<br>>> libdivecomputer.c<br>>> + liquivision.c<br>>> load-git.c<br>>> membuffer.c<br>>> parse-xml.c<br>>> diff --git a/file.c b/file.c<br>>> index bab7909..dadc11f 100644<br>>> --- a/file.c<br>>> +++ b/file.c<br>>> @@ -357,6 +357,8 @@ static int open_by_filename(const char *filename, const char *fmt, struct memblo<br>>> /* Cochran export comma-separated-value files */<br>>> if (!strcasecmp(fmt, "DPT"))<br>>> return try_to_open_csv(filename, mem, CSV_DEPTH);<br>>> + if (!strcasecmp(fmt, "LVD"))<br>>> + return try_to_open_liquivision(filename, mem);<br>>> if (!strcasecmp(fmt, "TMP"))<br>>> return try_to_open_csv(filename, mem, CSV_TEMP);<br>>> if (!strcasecmp(fmt, "HP1"))<br>>> diff --git a/liquivision.c b/liquivision.c<br>>> new file mode 100644<br>>> index 0000000..bb71bfd<br>>> --- /dev/null<br>>> +++ b/liquivision.c<br>>> @@ -0,0 +1,352 @@<br>>> +#include <string.h><br>>> +<br>>> +#include "dive.h"<br>>> +#include "divelist.h"<br>>> +#include "file.h"<br>>> +<br>>> +<br>>> +// Convert bytes into an INT<br>>> +#define array_uint16_le(p) ((unsigned int) (p)[0] \<br>>> + + ((p)[1]<<8) )<br>>> +#define array_uint32_le(p) ((unsigned int) (p)[0] \<br>>> + + ((p)[1]<<8) + ((p)[2]<<16) \<br>>> + + ((p)[3]<<24))<br>>> +<br>>> +<br>>> +static void<br>>> +parse_dives (int log_version, const unsigned char *buf, unsigned int buf_size) {<br>>> + unsigned int ptr = 0;<br>>> + unsigned char model;<br>>> +<br>>> + struct dive *dive;<br>>> + struct divecomputer *dc;<br>>> + struct sample *sample;<br>>> +<br>>> + while (ptr < buf_size) {<br>>> + dive = alloc_dive();<br>>> + dc = &dive->dc;<br>>> +<br>>> + // Model 0=Xen, 1,2=Xeo, 4=Lynx, other=Liquivision<br>>> + model = *(buf + ptr);<br>>> + switch (model) {<br>>> + case 0:<br>>> + dc->model = "Xen";<br>>> + break;<br>>> + case 1:<br>>> + case 2:<br>>> + dc->model = "Xeo";<br>>> + break;<br>>> + case 4:<br>>> + dc->model = "Lynx";<br>>> + break;<br>>> + default:<br>>> + dc->model = "LiquiVision";<br>>> + break;<br>>> + }<br>>> + ptr++;<br>>> +<br>>> + // Dive location, assemble Location and Place<br>>> + unsigned int len, place_len;<br>>> + len = array_uint32_le(buf + ptr);<br>>> + ptr += 4;<br>>> + place_len = array_uint32_le(buf + ptr + len);<br>>> +<br>>> + if (len && place_len) {<br>>> + dive->location = malloc(len + place_len + 4);<br>>> + memset(dive->location, 0, len + place_len + 4);<br>>> + memcpy(dive->location, buf + ptr, len);<br>>> + memcpy(dive->location + len, ", ", 2);<br>>> + memcpy(dive->location + len + 2, buf + ptr + len + 4, place_len);<br>>> + } else if (len) {<br>>> + dive->location = strndup(buf + ptr, len);<br>>> + } else if (place_len) {<br>>> + dive->location = strndup(buf + ptr + len + 4, place_len);<br>>> + }<br>>> +<br>>> + ptr += len + 4 + place_len;<br>>> +<br>>> + // Dive comment<br>>> + len = array_uint32_le(buf + ptr);<br>>> + ptr += 4;<br>>> +<br>>> + // Blank notes are better than the default text<br>>> + if (len && strncmp(buf + ptr, "Comment ...", 11)) {<br>>> + dive->notes = strndup(buf + ptr, len);<br>>> + }<br>>> + ptr += len;<br>>> +<br>>> + dive->id = array_uint32_le(buf + ptr);<br>>> + ptr += 4;<br>>> +<br>>> + dive->number = array_uint16_le(buf + ptr) + 1;<br>>> + ptr += 2;<br>>> +<br>>> + dive->duration.seconds = array_uint32_le(buf + ptr); // seconds<br>>> + ptr += 4;<br>>> +<br>>> + dive-><a href="http://maxdepth.mm" target="_blank">maxdepth.mm</a> = array_uint16_le(buf + ptr) * 10; // cm->mm<br>>> + ptr += 2;<br>>> +<br>>> + dive-><a href="http://meandepth.mm" target="_blank">meandepth.mm</a> = array_uint16_le(buf + ptr) * 10; // cm->mm<br>>> + ptr += 2;<br>>> +<br>>> + dive->when = array_uint32_le(buf + ptr);<br>>> + ptr += 4;<br>>> +<br>>> + //unsigned int end_time = array_uint32_le(buf + ptr);<br>>> + ptr += 4;<br>>> +<br>>> + //unsigned int sit = array_uint32_le(buf + ptr);<br>>> + ptr += 4;<br>>> + //if (sit == 0xffffffff) {<br>>> + //}<br>>> +<br>>> + dive->surface_pressure.mbar = array_uint16_le(buf + ptr); // ???<br>>> + ptr += 2;<br>>> +<br>>> + //unsigned int rep_dive = array_uint16_le(buf + ptr);<br>>> + ptr += 2;<br>>> +<br>>> + dive->mintemp.mkelvin = C_to_mkelvin((float)array_uint16_le(buf + ptr)/10);// C->mK<br>>> + ptr += 2;<br>>> +<br>>> + dive->maxtemp.mkelvin = C_to_mkelvin((float)array_uint16_le(buf + ptr)/10);// C->mK<br>>> + ptr += 2;<br>>> +<br>>> + dive->salinity = *(buf + ptr); // ???<br>>> + ptr += 1;<br>>> +<br>>> + unsigned int sample_count = array_uint32_le(buf + ptr);<br>>> + ptr += 4;<br>>> +<br>>> + // Sample interval<br>>> + unsigned char sample_interval;<br>>> + sample_interval = 1;<br>>> +<br>>> + unsigned char intervals[6] = {1,2,5,10,30,60};<br>>> + if (*(buf + ptr) < 6)<br>>> + sample_interval = intervals[*(buf + ptr)];<br>>> + ptr += 1;<br>>> +<br>>> + float start_cns = 0;<br>>> + unsigned char dive_mode = 0, algorithm = 0;<br>>> + if (array_uint32_le(buf + ptr) != sample_count) {<br>>> + // Xeo, with CNS and OTU<br>>> + start_cns = *(float *) (buf + ptr);<br>>> + ptr += 4;<br>>> + dive->cns = *(float *) (buf + ptr); // end cns<br>>> + ptr += 4;<br>>> + dive->otu = *(float *) (buf + ptr);<br>>> + ptr += 4;<br>>> + dive_mode = *(buf + ptr++); // 0=Deco, 1=Gauge, 2=None<br>>> + algorithm = *(buf + ptr++); // 0=ZH-L16C+GF<br>>> + sample_count = array_uint32_le(buf + ptr);<br>>> + }<br>>> + ptr += 4;<br>>> +<br>>> + // Parse dive samples<br>>> + const unsigned char *ds = buf + ptr;<br>>> + const unsigned char *ts = buf + ptr + sample_count * 2 + 4;<br>>> + const unsigned char *ps = buf + ptr + sample_count * 4 + 4;<br>>> + unsigned int ps_count = array_uint32_le(ps);<br>>> + ps += 4;<br>>> +<br>>> + // Bump ptr<br>>> + ptr += sample_count * 4 + 4;<br>>> +<br>>> + // Handle events<br>>> + unsigned int event;<br>>> + unsigned int ps_ptr;<br>>> + ps_ptr = 0;<br>>> +<br>>> + unsigned int d = 0, e;<br>>> + int event_time, mbar, sensor;<br>>> +<br>>> + // Loop through events<br>>> + for (e = 0; e < ps_count; e++) {<br>>> + // Get event<br>>> + event = array_uint16_le(ps + ps_ptr);<br>>> + ps_ptr += 2;<br>>> +<br>>> + switch (event) {<br>>> + case 0x0002: // Unknown<br>>> + case 0x0004: // Unknown<br>>> + ps_ptr += 4;<br>>> + continue;<br>>> + case 0x0005: // Unknown<br>>> + ps_ptr += 6;<br>>> + continue;<br>>> + case 0x0007: // Gas<br>>> + // 4 byte time<br>>> + // 1 byte O2, 1 bye He<br>>> + ps_ptr += 6;<br>>> + continue;<br>>> + case 0x0008:<br>>> + // 4 byte time<br>>> + // 2 byte gas set point 2<br>>> + ps_ptr += 6;<br>>> + continue;<br>>> + case 0x000f:<br>>> + // Tank pressure<br>>> + event_time = array_uint32_le(ps + ps_ptr);<br>>> + sensor = 0; //array_uint16_le(ps + ps_ptr + 4);<br>>> + mbar = array_uint16_le(ps + ps_ptr + 6) * 10; // cb->mb<br>>> + // 1 byte PSR<br>>> + // 1 byte ST<br>>> + ps_ptr += 10;<br>>> + break;<br>>> + case 0x0010:<br>>> + ps_ptr += 26;<br>>> + continue;<br>>> + case 0x0015: // Unknown<br>>> + ps_ptr += 2;<br>>> + continue;<br>>> + default:<br>>> + ps_ptr += 4;<br>>> + continue;<br>>> + }<br>>> +<br>>> + int sample_time, next_time, last_time;<br>>> + int depth_mm, last_depth, temp_mk, last_temp;<br>>> +<br>>> + while (true) {<br>>> + sample = prepare_sample(dc);<br>>> +<br>>> + // Get sample times<br>>> + sample_time = d * sample_interval;<br>>> + depth_mm = array_uint16_le(ds + d * 2) * 10; // cm->mm<br>>> + temp_mk = C_to_mkelvin(array_uint16_le(ts + d * 2) / 10); // dC->mK<br>>> + next_time = (d < sample_count - 1 ? (d + 1) * sample_interval : sample_time);<br>>> + last_time = (d ? (d - 1) * sample_interval : 0);<br>>> +<br>>> + if (d == sample_count) {<br>>> + // We still have events to record<br>>> + sample->time.seconds = event_time;<br>>> + sample-><a href="http://depth.mm" target="_blank">depth.mm</a> == array_uint16_le(ds + (d - 1) * 2) * 10; // cm->mm<br>>> + sample->temperature.mkelvin = C_to_mkelvin(array_uint16_le(ts + (d - 1) * 2) / 10); // dC->mK<br>>> + sample->sensor = sensor;<br>>> + sample->cylinderpressure.mbar = mbar;<br>>> + finish_sample(dc);<br>>> +<br>>> + break;<br>>> + } else if (event_time > sample_time) {<br>>> + // Record sample and loop<br>>> + sample->time.seconds = sample_time;<br>>> + sample-><a href="http://depth.mm" target="_blank">depth.mm</a> = depth_mm;<br>>> + sample->temperature.mkelvin = temp_mk;<br>>> + finish_sample(dc);<br>>> + d++;<br>>> +<br>>> + continue;<br>>> + } else if (event_time == sample_time) {<br>>> + sample->time.seconds = sample_time;<br>>> + sample-><a href="http://depth.mm" target="_blank">depth.mm</a> = depth_mm;<br>>> + sample->temperature.mkelvin = temp_mk;<br>>> + sample->sensor = sensor;<br>>> + sample->cylinderpressure.mbar = mbar;<br>>> + finish_sample(dc);<br>>> +<br>>> + break;<br>>> + } else { // Event is prior to sample<br>>> + sample->time.seconds = event_time;<br>>> + sample->sensor = sensor;<br>>> + sample->cylinderpressure.mbar = mbar;<br>>> + if (last_time == sample_time) {<br>>> + sample-><a href="http://depth.mm" target="_blank">depth.mm</a> = depth_mm;<br>>> + sample->temperature.mkelvin = temp_mk;<br>>> + } else {<br>>> + // Extrapolate<br>>> + last_depth = array_uint16_le(ds + (d - 1) * 2) * 10; // cm->mm<br>>> + last_temp = C_to_mkelvin(array_uint16_le(ts + (d - 1) * 2) / 10); // dC->mK<br>>> + sample-><a href="http://depth.mm" target="_blank">depth.mm</a> = last_depth + (depth_mm - last_depth)<br>>> + * (event_time - last_time) / sample_interval;<br>>> + sample->temperature.mkelvin = last_temp + (temp_mk - last_temp)<br>>> + * (event_time - last_time) / sample_interval;<br>>> + }<br>>> + finish_sample(dc);<br>>> +<br>>> + break;<br>>> + }<br>>> + } // while (true);<br>>> + } // for each event sample<br>>> +<br>>> + // record trailing depth samples<br>>> + for ( ;d < sample_count; d++) {<br>>> + sample = prepare_sample(dc);<br>>> + sample->time.seconds = d * sample_interval;<br>>> +<br>>> + sample-><a href="http://depth.mm" target="_blank">depth.mm</a> = array_uint16_le(ds + d * 2) * 10; // cm->mm<br>>> + sample->temperature.mkelvin =<br>>> + C_to_mkelvin((float)array_uint16_le(ts + d * 2) / 10);<br>>> + finish_sample(dc);<br>>> + }<br>>> +<br>>> + if (log_version == 3 && model == 4) {<br>>> + // Advance to begin of next dive<br>>> + switch (array_uint16_le(ps + ps_ptr)) {<br>>> + case 0x0000:<br>>> + ps_ptr += 5;<br>>> + break;<br>>> + case 0x0100:<br>>> + ps_ptr += 7;<br>>> + break;<br>>> + case 0x0200:<br>>> + ps_ptr += 9;<br>>> + break;<br>>> + case 0x0300:<br>>> + ps_ptr += 11;<br>>> + break;<br>>> + case 0x0b0b:<br>>> + ps_ptr += 27;<br>>> + break;<br>>> + }<br>>> +<br>>> + while (*(ps + ps_ptr) != 0x04)<br>>> + ps_ptr++;<br>>> + }<br>>> +<br>>> + // End dive<br>>> + dive->downloaded = true;<br>>> + record_dive(dive);<br>>> + mark_divelist_changed(true);<br>>> +<br>>> + // Advance ptr for next dive<br>>> + ptr += ps_ptr + 4;<br>>> + } // while<br>>> +<br>>> + save_dives("/tmp/test.xml");<br>>> +}<br>>> +<br>>> +<br>>> +int<br>>> +try_to_open_liquivision(const char *filename, struct memblock *mem)<br>>> +{<br>>> + void *name;<br>>> + const unsigned char *buf = mem->buffer;<br>>> + unsigned int buf_size = mem->size;<br>>> + unsigned int ptr;<br>>> + int log_version;<br>>> +<br>>> + // Get name<br>>> + unsigned int len = array_uint32_le(buf);<br>>> + if (len) {<br>>> + name = malloc(len);<br>>> + strncpy(name, buf + 4, len);<br>>> + }<br>>> + ptr = 4 + len;<br>>> +<br>>> + unsigned int dive_count = array_uint32_le(buf + ptr);<br>>> + if (dive_count == 0xffffffff) {<br>>> + // File version 3.0<br>>> + log_version = 3;<br>>> + ptr += 6;<br>>> + dive_count = array_uint32_le(buf + ptr);<br>>> + } else {<br>>> + log_version = 2;<br>>> + }<br>>> + ptr += 4;<br>>> +<br>>> + parse_dives(log_version, buf + ptr, buf_size - ptr);<br>>> +<br>>> + return 1;<br>>> +}<br>>> diff --git a/qt-ui/mainwindow.cpp b/qt-ui/mainwindow.cpp<br>>> index cc2d970..5811d4e 100644<br>>> --- a/qt-ui/mainwindow.cpp<br>>> +++ b/qt-ui/mainwindow.cpp<br>>> @@ -725,7 +725,8 @@ QString MainWindow::filter()<br>>> QString f;<br>>> f += "ALL ( *.ssrf *.xml *.XML *.uddf *.udcf *.UDFC *.jlb *.JLB ";<br>>> f += "*.sde *.SDE *.dld *.DLD ";<br>>> - f += "*.db *.can";<br>>> + f += "*.db *.can ";<br>>> + f += "*.lvd ";<br>>> f += ");;";<br>>><br>>> f += "Subsurface (*.ssrf);;";<br>>> @@ -737,7 +738,8 @@ QString MainWindow::filter()<br>>> f += "SDE (*.sde *.SDE);;";<br>>> f += "DLD (*.dld *.DLD);;";<br>>> f += "DB (*.db);;";<br>>> - f += "CAN (*.can)";<br>>> + f += "CAN (*.can);;";<br>>> + f += "LVD (*.lvd)";<br>>><br>>> return f;<br>>> }<br>>> @@ -1247,7 +1249,7 @@ void MainWindow::loadFiles(const QStringList fileNames)<br>>> void MainWindow::on_actionImportDiveLog_triggered()<br>>> {<br>>> QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Open dive log file"), lastUsedDir(),<br>>> - tr("Dive log files (*.xml *.uddf *.udcf *.csv *.jlb *.dld *.sde *.db *.can);;"<br>>> + tr("Dive log files (*.xml *.uddf *.udcf *.csv *.jlb *.dld *.sde *.db *.can *.lvd);;"<br>>> "XML files (*.xml);;UDDF/UDCF files(*.uddf *.udcf);;JDiveLog files(*.jlb);;"<br>>> "Suunto files(*.sde *.db);;CSV files(*.csv);;MkVI files(*.txt);;All files(*)"));<br>>><br>>> diff --git a/<a href="http://subsurface.pro" target="_blank">subsurface.pro</a> b/<a href="http://subsurface.pro" target="_blank">subsurface.pro</a><br>>> index 7b38fd6..07e7b29 100644<br>>> --- a/<a href="http://subsurface.pro" target="_blank">subsurface.pro</a><br>>> +++ b/<a href="http://subsurface.pro" target="_blank">subsurface.pro</a><br>>> @@ -120,6 +120,7 @@ SOURCES = \<br>>> file.c \<br>>> gettextfromc.cpp \<br>>> libdivecomputer.c \<br>>> + liquivision.c \<br>>> load-git.c \<br>>> main.cpp \<br>>> membuffer.c \<br>>> --<br>>> 1.8.3.1<br>>><br>>> _______________________________________________<br>>> subsurface mailing list<br>>> <a href="mailto:subsurface@subsurface-divelog.org" target="_blank">subsurface@subsurface-divelog.org</a><br>>> <a href="http://lists.subsurface-divelog.org/cgi-bin/mailman/listinfo/subsurface" target="_blank">http://lists.subsurface-divelog.org/cgi-bin/mailman/listinfo/subsurface</a><br>><br>><br></div></div></div>
</blockquote></div><br></div>