core: use divelog struct in downloader code

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2022-11-12 12:44:29 +01:00 committed by bstoeger
parent a2845ece82
commit b56b7abcf5
11 changed files with 64 additions and 65 deletions

View file

@ -158,8 +158,7 @@ static dc_status_t dt_libdc_buffer(unsigned char *ptr, int prf_length, int dc_mo
* Parses a mem buffer extracting its data and filling a subsurface's dive structure. * Parses a mem buffer extracting its data and filling a subsurface's dive structure.
* Returns a pointer to last position in buffer, or NULL on failure. * Returns a pointer to last position in buffer, or NULL on failure.
*/ */
static unsigned char *dt_dive_parser(unsigned char *runner, struct dive *dt_dive, struct dive_site_table *sites, static unsigned char *dt_dive_parser(unsigned char *runner, struct dive *dt_dive, struct divelog *log, long maxbuf)
struct device_table *devices, long maxbuf)
{ {
int rc, profile_length, libdc_model; int rc, profile_length, libdc_model;
char *tmp_notes_str = NULL; char *tmp_notes_str = NULL;
@ -176,8 +175,7 @@ static unsigned char *dt_dive_parser(unsigned char *runner, struct dive *dt_dive
char is_nitrox = 0, is_O2 = 0, is_SCR = 0; char is_nitrox = 0, is_O2 = 0, is_SCR = 0;
device_data_t *devdata = calloc(1, sizeof(device_data_t)); device_data_t *devdata = calloc(1, sizeof(device_data_t));
devdata->sites = sites; devdata->log = log;
devdata->devices = devices;
/* /*
* Parse byte to byte till next dive entry * Parse byte to byte till next dive entry
@ -216,9 +214,9 @@ static unsigned char *dt_dive_parser(unsigned char *runner, struct dive *dt_dive
* Locality and Dive points. * Locality and Dive points.
*/ */
snprintf(buffer, sizeof(buffer), "%s, %s", locality, dive_point); snprintf(buffer, sizeof(buffer), "%s, %s", locality, dive_point);
ds = get_dive_site_by_name(buffer, sites); ds = get_dive_site_by_name(buffer, log->sites);
if (!ds) if (!ds)
ds = create_dive_site(buffer, sites); ds = create_dive_site(buffer, log->sites);
add_dive_to_dive_site(dt_dive, ds); add_dive_to_dive_site(dt_dive, ds);
free(locality); free(locality);
locality = NULL; locality = NULL;
@ -711,7 +709,7 @@ int datatrak_import(struct memblock *mem, struct memblock *wl_mem, struct divelo
while ((i < numdives) && ((long) runner < maxbuf)) { while ((i < numdives) && ((long) runner < maxbuf)) {
struct dive *ptdive = alloc_dive(); struct dive *ptdive = alloc_dive();
runner = dt_dive_parser(runner, ptdive, log->sites, log->devices, maxbuf); runner = dt_dive_parser(runner, ptdive, log, maxbuf);
if (wl_mem) if (wl_mem)
wlog_compl_parser(wl_mem, ptdive, i); wlog_compl_parser(wl_mem, ptdive, i);
if (runner == NULL) { if (runner == NULL) {

View file

@ -51,6 +51,16 @@ divelog::divelog(divelog &&log) :
move_dive_site_table(log.sites, sites); move_dive_site_table(log.sites, sites);
} }
struct divelog &divelog::operator=(divelog &&log)
{
move_dive_table(log.dives, dives);
move_trip_table(log.trips, trips);
move_dive_site_table(log.sites, sites);
devices = std::move(log.devices);
filter_presets = std::move(log.filter_presets);
return *this;
}
void divelog::clear() void divelog::clear()
{ {
while (dives->nr) while (dives->nr)

View file

@ -23,6 +23,7 @@ struct divelog {
divelog(); divelog();
~divelog(); ~divelog();
divelog(divelog &&log); // move constructor (argument is consumed). divelog(divelog &&log); // move constructor (argument is consumed).
divelog &operator=(divelog &&log); // move assignment (argument is consumed).
#endif #endif
}; };

View file

@ -80,9 +80,7 @@ static QString getTransportString(unsigned int transport)
return ts; return ts;
} }
DownloadThread::DownloadThread() : downloadTable({ 0 }), DownloadThread::DownloadThread() : m_data(DCDeviceData::instance())
diveSiteTable({ 0 }),
m_data(DCDeviceData::instance())
{ {
} }
@ -90,9 +88,7 @@ void DownloadThread::run()
{ {
auto internalData = m_data->internalData(); auto internalData = m_data->internalData();
internalData->descriptor = descriptorLookup[m_data->vendor().toLower() + m_data->product().toLower()]; internalData->descriptor = descriptorLookup[m_data->vendor().toLower() + m_data->product().toLower()];
internalData->download_table = &downloadTable; internalData->log = &log;
internalData->sites = &diveSiteTable;
internalData->devices = &deviceTable;
internalData->btname = strdup(m_data->devBluetoothName().toUtf8()); internalData->btname = strdup(m_data->devBluetoothName().toUtf8());
if (!internalData->descriptor) { if (!internalData->descriptor) {
qDebug() << "No download possible when DC type is unknown"; qDebug() << "No download possible when DC type is unknown";
@ -109,11 +105,9 @@ void DownloadThread::run()
qDebug() << "Starting download from " << getTransportString(transports); qDebug() << "Starting download from " << getTransportString(transports);
qDebug() << "downloading" << (internalData->force_download ? "all" : "only new") << "dives"; qDebug() << "downloading" << (internalData->force_download ? "all" : "only new") << "dives";
clear_dive_table(&downloadTable); clear_divelog(&log);
clear_dive_site_table(&diveSiteTable);
clear_device_table(&deviceTable);
Q_ASSERT(internalData->download_table != nullptr); Q_ASSERT(internalData->log != nullptr);
const char *errorText; const char *errorText;
import_thread_cancelled = false; import_thread_cancelled = false;
error.clear(); error.clear();
@ -125,9 +119,9 @@ void DownloadThread::run()
error = str_error(errorText, internalData->devname, internalData->vendor, internalData->product); error = str_error(errorText, internalData->devname, internalData->vendor, internalData->product);
qDebug() << "Finishing download thread:" << error; qDebug() << "Finishing download thread:" << error;
} else { } else {
if (!downloadTable.nr) if (!log.dives->nr)
error = tr("No new dives downloaded from dive computer"); error = tr("No new dives downloaded from dive computer");
qDebug() << "Finishing download thread:" << downloadTable.nr << "dives downloaded"; qDebug() << "Finishing download thread:" << log.dives->nr << "dives downloaded";
} }
qPrefDiveComputer::set_vendor(internalData->vendor); qPrefDiveComputer::set_vendor(internalData->vendor);
qPrefDiveComputer::set_product(internalData->product); qPrefDiveComputer::set_product(internalData->product);
@ -216,7 +210,7 @@ void show_computer_list()
DCDeviceData::DCDeviceData() DCDeviceData::DCDeviceData()
{ {
memset(&data, 0, sizeof(data)); memset(&data, 0, sizeof(data));
data.download_table = nullptr; data.log = nullptr;
data.diveid = 0; data.diveid = 0;
#if defined(BT_SUPPORT) #if defined(BT_SUPPORT)
data.bluetooth_mode = true; data.bluetooth_mode = true;

View file

@ -6,8 +6,7 @@
#include <QHash> #include <QHash>
#include <QLoggingCategory> #include <QLoggingCategory>
#include "divesite.h" #include "divelog.h"
#include "device.h"
#include "libdivecomputer.h" #include "libdivecomputer.h"
#include "connectionlistmodel.h" #include "connectionlistmodel.h"
#if BT_SUPPORT #if BT_SUPPORT
@ -74,9 +73,7 @@ public:
DCDeviceData *data(); DCDeviceData *data();
QString error; QString error;
struct dive_table downloadTable; struct divelog log;
struct dive_site_table diveSiteTable;
struct device_table deviceTable;
private: private:
DCDeviceData *m_data; DCDeviceData *m_data;

View file

@ -590,7 +590,7 @@ static void parse_string_field(device_data_t *devdata, struct dive *dive, dc_fie
if (location.lat.udeg && location.lon.udeg) { if (location.lat.udeg && location.lon.udeg) {
unregister_dive_from_dive_site(dive); unregister_dive_from_dive_site(dive);
add_dive_to_dive_site(dive, create_dive_site_with_gps(str->value, &location, devdata->sites)); add_dive_to_dive_site(dive, create_dive_site_with_gps(str->value, &location, devdata->log->sites));
} }
} }
} }
@ -847,7 +847,7 @@ static int dive_cb(const unsigned char *data, unsigned int size,
dive->dc.sample[1].temperature.mkelvin > dive->dc.sample[0].temperature.mkelvin) dive->dc.sample[1].temperature.mkelvin > dive->dc.sample[0].temperature.mkelvin)
dive->dc.sample[0].temperature.mkelvin = dive->dc.sample[1].temperature.mkelvin; dive->dc.sample[0].temperature.mkelvin = dive->dc.sample[1].temperature.mkelvin;
record_dive_to_table(dive, devdata->download_table); record_dive_to_table(dive, devdata->log->dives);
return true; return true;
error_exit: error_exit:
@ -1465,7 +1465,7 @@ const char *do_libdivecomputer_import(device_data_t *data)
/* TODO: Show the logfile to the user on error. */ /* TODO: Show the logfile to the user on error. */
dc_device_close(data->device); dc_device_close(data->device);
data->device = NULL; data->device = NULL;
if (!data->download_table->nr) if (!data->log->dives->nr)
dev_info(data, translate("gettextFromC", "No new dives downloaded from dive computer")); dev_info(data, translate("gettextFromC", "No new dives downloaded from dive computer"));
} }
dc_iostream_close(data->iostream); dc_iostream_close(data->iostream);

View file

@ -27,6 +27,7 @@ extern "C" {
#endif #endif
struct dive; struct dive;
struct divelog;
struct dive_computer; struct dive_computer;
struct devices; struct devices;
@ -46,9 +47,7 @@ typedef struct {
bool libdc_dump; bool libdc_dump;
bool bluetooth_mode; bool bluetooth_mode;
FILE *libdc_logfile; FILE *libdc_logfile;
struct dive_table *download_table; struct divelog *log;
struct dive_site_table *sites;
struct device_table *devices;
void *androidUsbDeviceDescriptor; void *androidUsbDeviceDescriptor;
} device_data_t; } device_data_t;

View file

@ -212,9 +212,9 @@ static struct dive *uemis_start_dive(uint32_t deviceid)
static struct dive *get_dive_by_uemis_diveid(device_data_t *devdata, uint32_t object_id) static struct dive *get_dive_by_uemis_diveid(device_data_t *devdata, uint32_t object_id)
{ {
for (int i = 0; i < devdata->download_table->nr; i++) { for (int i = 0; i < devdata->log->dives->nr; i++) {
if (object_id == devdata->download_table->dives[i]->dc.diveid) if (object_id == devdata->log->dives->dives[i]->dc.diveid)
return devdata->download_table->dives[i]; return devdata->log->dives->dives[i];
} }
return NULL; return NULL;
} }
@ -844,20 +844,20 @@ static bool uemis_delete_dive(device_data_t *devdata, uint32_t diveid)
{ {
struct dive *dive = NULL; struct dive *dive = NULL;
if (devdata->download_table->dives[devdata->download_table->nr - 1]->dc.diveid == diveid) { if (devdata->log->dives->dives[devdata->log->dives->nr - 1]->dc.diveid == diveid) {
/* we hit the last one in the array */ /* we hit the last one in the array */
dive = devdata->download_table->dives[devdata->download_table->nr - 1]; dive = devdata->log->dives->dives[devdata->log->dives->nr - 1];
} else { } else {
for (int i = 0; i < devdata->download_table->nr - 1; i++) { for (int i = 0; i < devdata->log->dives->nr - 1; i++) {
if (devdata->download_table->dives[i]->dc.diveid == diveid) { if (devdata->log->dives->dives[i]->dc.diveid == diveid) {
dive = devdata->download_table->dives[i]; dive = devdata->log->dives->dives[i];
for (int x = i; x < devdata->download_table->nr - 1; x++) for (int x = i; x < devdata->log->dives->nr - 1; x++)
devdata->download_table->dives[i] = devdata->download_table->dives[x + 1]; devdata->log->dives->dives[i] = devdata->log->dives->dives[x + 1];
} }
} }
} }
if (dive) { if (dive) {
devdata->download_table->dives[--devdata->download_table->nr] = NULL; devdata->log->dives->dives[--devdata->log->dives->nr] = NULL;
free_dive(dive); free_dive(dive);
return true; return true;
@ -997,7 +997,7 @@ static bool process_raw_buffer(device_data_t *devdata, uint32_t deviceid, char *
} else if (!is_log && dive && !strcmp(tag, "divespot_id")) { } else if (!is_log && dive && !strcmp(tag, "divespot_id")) {
int divespot_id = atoi(val); int divespot_id = atoi(val);
if (divespot_id != -1) { if (divespot_id != -1) {
struct dive_site *ds = create_dive_site("from Uemis", devdata->sites); struct dive_site *ds = create_dive_site("from Uemis", devdata->log->sites);
unregister_dive_from_dive_site(dive); unregister_dive_from_dive_site(dive);
add_dive_to_dive_site(dive, ds); add_dive_to_dive_site(dive, ds);
uemis_mark_divelocation(dive->dc.diveid, divespot_id, ds); uemis_mark_divelocation(dive->dc.diveid, divespot_id, ds);
@ -1016,13 +1016,13 @@ static bool process_raw_buffer(device_data_t *devdata, uint32_t deviceid, char *
* be a short read because of some error */ * be a short read because of some error */
if (done && ++bp < endptr && *bp != '{' && strstr(bp, "{{")) { if (done && ++bp < endptr && *bp != '{' && strstr(bp, "{{")) {
done = false; done = false;
record_dive_to_table(dive, devdata->download_table); record_dive_to_table(dive, devdata->log->dives);
dive = uemis_start_dive(deviceid); dive = uemis_start_dive(deviceid);
} }
} }
if (is_log) { if (is_log) {
if (dive->dc.diveid) { if (dive->dc.diveid) {
record_dive_to_table(dive, devdata->download_table); record_dive_to_table(dive, devdata->log->dives);
} else { /* partial dive */ } else { /* partial dive */
free_dive(dive); free_dive(dive);
free(buf); free(buf);
@ -1195,11 +1195,11 @@ static void get_uemis_divespot(device_data_t *devdata, const char *mountpath, in
* we search all existing divesites if we have one with the same name already. The function * we search all existing divesites if we have one with the same name already. The function
* returns the first found which is luckily not the newly created. * returns the first found which is luckily not the newly created.
*/ */
ods = get_dive_site_by_name(nds->name, devdata->sites); ods = get_dive_site_by_name(nds->name, devdata->log->sites);
if (ods) { if (ods) {
/* if the uuid's are the same, the new site is a duplicate and can be deleted */ /* if the uuid's are the same, the new site is a duplicate and can be deleted */
if (nds->uuid != ods->uuid) { if (nds->uuid != ods->uuid) {
delete_dive_site(nds, devdata->sites); delete_dive_site(nds, devdata->log->sites);
unregister_dive_from_dive_site(dive); unregister_dive_from_dive_site(dive);
add_dive_to_dive_site(dive, ods); add_dive_to_dive_site(dive, ods);
} }
@ -1209,14 +1209,14 @@ static void get_uemis_divespot(device_data_t *devdata, const char *mountpath, in
/* if we can't load the dive site details, delete the site we /* if we can't load the dive site details, delete the site we
* created in process_raw_buffer * created in process_raw_buffer
*/ */
delete_dive_site(dive->dive_site, devdata->sites); delete_dive_site(dive->dive_site, devdata->log->sites);
} }
} }
} }
static bool get_matching_dive(int idx, char *newmax, int *uemis_mem_status, device_data_t *data, const char *mountpath, const char deviceidnr) static bool get_matching_dive(int idx, char *newmax, int *uemis_mem_status, device_data_t *data, const char *mountpath, const char deviceidnr)
{ {
struct dive *dive = data->download_table->dives[idx]; struct dive *dive = data->log->dives->dives[idx];
char log_file_no_to_find[20]; char log_file_no_to_find[20];
char dive_to_read_buf[10]; char dive_to_read_buf[10];
bool found = false; bool found = false;
@ -1238,7 +1238,7 @@ static bool get_matching_dive(int idx, char *newmax, int *uemis_mem_status, devi
#if UEMIS_DEBUG & 16 #if UEMIS_DEBUG & 16
do_dump_buffer_to_file(mbuf, "Dive"); do_dump_buffer_to_file(mbuf, "Dive");
#endif #endif
*uemis_mem_status = get_memory(data->download_table, UEMIS_CHECK_SINGLE_DIVE); *uemis_mem_status = get_memory(data->log->dives, UEMIS_CHECK_SINGLE_DIVE);
if (*uemis_mem_status == UEMIS_MEM_OK) { if (*uemis_mem_status == UEMIS_MEM_OK) {
/* if the memory isn's completely full we can try to read more dive log vs. dive details /* if the memory isn's completely full we can try to read more dive log vs. dive details
* UEMIS_MEM_CRITICAL means not enough space for a full round but the dive details * UEMIS_MEM_CRITICAL means not enough space for a full round but the dive details
@ -1303,7 +1303,7 @@ static bool get_matching_dive(int idx, char *newmax, int *uemis_mem_status, devi
} else { } else {
/* At this point the memory of the UEMIS is full, let's cleanup all dive log files were /* At this point the memory of the UEMIS is full, let's cleanup all dive log files were
* we could not match the details to. */ * we could not match the details to. */
do_delete_dives(data->download_table, idx); do_delete_dives(data->log->dives, idx);
return false; return false;
} }
} }
@ -1363,7 +1363,7 @@ const char *do_uemis_import(device_data_t *data)
goto bail; goto bail;
param_buff[1] = "notempty"; param_buff[1] = "notempty";
newmax = uemis_get_divenr(deviceid, data->download_table, force_download); newmax = uemis_get_divenr(deviceid, data->log->dives, force_download);
if (verbose) if (verbose)
fprintf(stderr, "Uemis downloader: start looking at dive nr %s\n", newmax); fprintf(stderr, "Uemis downloader: start looking at dive nr %s\n", newmax);
@ -1379,12 +1379,12 @@ const char *do_uemis_import(device_data_t *data)
fprintf(debugfile, "d_u_i inner loop start %d end %d newmax %s\n", start, end, newmax); fprintf(debugfile, "d_u_i inner loop start %d end %d newmax %s\n", start, end, newmax);
#endif #endif
/* start at the last filled download table index */ /* start at the last filled download table index */
match_dive_and_log = data->download_table->nr; match_dive_and_log = data->log->dives->nr;
sprintf(newmax, "%d", start); sprintf(newmax, "%d", start);
param_buff[2] = newmax; param_buff[2] = newmax;
param_buff[3] = 0; param_buff[3] = 0;
success = uemis_get_answer(mountpath, "getDivelogs", 3, 0, &result); success = uemis_get_answer(mountpath, "getDivelogs", 3, 0, &result);
uemis_mem_status = get_memory(data->download_table, UEMIS_CHECK_DETAILS); uemis_mem_status = get_memory(data->log->dives, UEMIS_CHECK_DETAILS);
/* first, remove any leading garbage... this needs to start with a '{' */ /* first, remove any leading garbage... this needs to start with a '{' */
char *realmbuf = mbuf; char *realmbuf = mbuf;
if (mbuf) if (mbuf)
@ -1422,7 +1422,7 @@ const char *do_uemis_import(device_data_t *data)
* What the following part does is to optimize the mapping by using * What the following part does is to optimize the mapping by using
* dive_to_read = the dive details entry that need to be read using the object_id * dive_to_read = the dive details entry that need to be read using the object_id
* logFileNoToFind = map the logfilenr of the dive details with the object_id = diveid from the get dive logs */ * logFileNoToFind = map the logfilenr of the dive details with the object_id = diveid from the get dive logs */
for (int i = match_dive_and_log; i < data->download_table->nr; i++) { for (int i = match_dive_and_log; i < data->log->dives->nr; i++) {
bool success = get_matching_dive(i, newmax, &uemis_mem_status, data, mountpath, deviceidnr); bool success = get_matching_dive(i, newmax, &uemis_mem_status, data, mountpath, deviceidnr);
if (!success) if (!success)
break; break;
@ -1433,7 +1433,7 @@ const char *do_uemis_import(device_data_t *data)
start = end; start = end;
/* Do some memory checking here */ /* Do some memory checking here */
uemis_mem_status = get_memory(data->download_table, UEMIS_CHECK_LOG); uemis_mem_status = get_memory(data->log->dives, UEMIS_CHECK_LOG);
if (uemis_mem_status != UEMIS_MEM_OK) { if (uemis_mem_status != UEMIS_MEM_OK) {
#if UEMIS_DEBUG & 4 #if UEMIS_DEBUG & 4
fprintf(debugfile, "d_u_i out of memory, bailing\n"); fprintf(debugfile, "d_u_i out of memory, bailing\n");
@ -1447,7 +1447,7 @@ const char *do_uemis_import(device_data_t *data)
// Resetting to original state // Resetting to original state
filenr = 0; filenr = 0;
max_mem_used = -1; max_mem_used = -1;
uemis_mem_status = get_memory(data->download_table, UEMIS_CHECK_DETAILS); uemis_mem_status = get_memory(data->log->dives, UEMIS_CHECK_DETAILS);
if (!uemis_get_answer(mountpath, "getDeviceId", 0, 1, &result)) if (!uemis_get_answer(mountpath, "getDeviceId", 0, 1, &result))
goto bail; goto bail;
if (strcmp(deviceid, param_buff[0]) != 0) { if (strcmp(deviceid, param_buff[0]) != 0) {
@ -1490,7 +1490,7 @@ const char *do_uemis_import(device_data_t *data)
* be deleted from the download_table. * be deleted from the download_table.
*/ */
if (uemis_mem_status == UEMIS_MEM_FULL) if (uemis_mem_status == UEMIS_MEM_FULL)
do_delete_dives(data->download_table, match_dive_and_log); do_delete_dives(data->log->dives, match_dive_and_log);
#if UEMIS_DEBUG & 4 #if UEMIS_DEBUG & 4
fprintf(debugfile, "d_u_i out of memory, bailing instead of processing\n"); fprintf(debugfile, "d_u_i out of memory, bailing instead of processing\n");
#endif #endif
@ -1508,9 +1508,9 @@ const char *do_uemis_import(device_data_t *data)
/* Regardless on where we are with the memory situation, it's time now /* Regardless on where we are with the memory situation, it's time now
* to see if we have to clean some dead bodies from our download table */ * to see if we have to clean some dead bodies from our download table */
next_table_index = 0; next_table_index = 0;
while (next_table_index < data->download_table->nr) { while (next_table_index < data->log->dives->nr) {
if (data->download_table->dives[next_table_index]->hidden_by_filter) if (data->log->dives->dives[next_table_index]->hidden_by_filter)
uemis_delete_dive(data, data->download_table->dives[next_table_index]->dc.diveid); uemis_delete_dive(data, data->log->dives->dives[next_table_index]->dc.diveid);
else else
next_table_index++; next_table_index++;
} }
@ -1528,7 +1528,7 @@ bail:
} }
free(deviceid); free(deviceid);
free(reqtxt_path); free(reqtxt_path);
if (!data->download_table->nr) if (!data->log->dives->nr)
result = translate("gettextFromC", ERR_NO_FILES); result = translate("gettextFromC", ERR_NO_FILES);
return result; return result;
} }

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
#include "desktop-widgets/configuredivecomputerdialog.h" #include "desktop-widgets/configuredivecomputerdialog.h"
#include "core/device.h"
#include "core/qthelper.h" #include "core/qthelper.h"
#include "core/settings/qPrefDiveComputer.h" #include "core/settings/qPrefDiveComputer.h"
#include "desktop-widgets/mainwindow.h" #include "desktop-widgets/mainwindow.h"

View file

@ -2,6 +2,7 @@
#include "desktop-widgets/downloadfromdivecomputer.h" #include "desktop-widgets/downloadfromdivecomputer.h"
#include "commands/command.h" #include "commands/command.h"
#include "core/qthelper.h" #include "core/qthelper.h"
#include "core/device.h"
#include "core/divelist.h" #include "core/divelist.h"
#include "core/divelog.h" #include "core/divelog.h"
#include "core/settings/qPrefDiveComputer.h" #include "core/settings/qPrefDiveComputer.h"

View file

@ -125,9 +125,7 @@ void DiveImportedModel::downloadThreadFinished()
beginResetModel(); beginResetModel();
// Move the table data from thread to model // Move the table data from thread to model
move_dive_table(&thread.downloadTable, log.dives); log = std::move(thread.log);
move_dive_site_table(&thread.diveSiteTable, log.sites);
*log.devices = std::move(thread.deviceTable);
checkStates.resize(log.dives->nr); checkStates.resize(log.dives->nr);
std::fill(checkStates.begin(), checkStates.end(), true); std::fill(checkStates.begin(), checkStates.end(), true);