From 82af1b2377cec03a989f86b8009d4ac226c6541e Mon Sep 17 00:00:00 2001 From: Berthold Stoeger Date: Sun, 3 Mar 2019 15:12:22 +0100 Subject: Undo: make undo-system dive site-aware As opposed to dive trips, dive sites were always directly added to the global table, even on import. Instead, parse the divesites into a distinct table and merge them on import. Currently, this does not do any merging of dive sites, i.e. dive sites are considered as either equal or different. Nevertheless, merging of data should be rather easy to implement and simply follow the code of the dive merging. Signed-off-by: Berthold Stoeger --- desktop-widgets/command.cpp | 4 +- desktop-widgets/command.h | 2 +- desktop-widgets/command_base.h | 4 ++ desktop-widgets/command_divelist.cpp | 102 +++++++++++++++++---------- desktop-widgets/command_divelist.h | 33 ++++++--- desktop-widgets/divelogimportdialog.cpp | 13 ++-- desktop-widgets/downloadfromdivecomputer.cpp | 5 +- desktop-widgets/mainwindow.cpp | 5 +- desktop-widgets/subsurfacewebservices.cpp | 5 +- 9 files changed, 108 insertions(+), 65 deletions(-) (limited to 'desktop-widgets') diff --git a/desktop-widgets/command.cpp b/desktop-widgets/command.cpp index 638be74d1..d8ec0812f 100644 --- a/desktop-widgets/command.cpp +++ b/desktop-widgets/command.cpp @@ -11,9 +11,9 @@ void addDive(dive *d, bool autogroup, bool newNumber) execute(new AddDive(d, autogroup, newNumber)); } -void importDives(struct dive_table *dives, struct trip_table *trips, int flags, const QString &source) +void importDives(struct dive_table *dives, struct trip_table *trips, struct dive_site_table *sites, int flags, const QString &source) { - execute(new ImportDives(dives, trips, flags, source)); + execute(new ImportDives(dives, trips, sites, flags, source)); } void deleteDive(const QVector &divesToDelete) diff --git a/desktop-widgets/command.h b/desktop-widgets/command.h index 4c6240a93..f2594787d 100644 --- a/desktop-widgets/command.h +++ b/desktop-widgets/command.h @@ -21,7 +21,7 @@ void addDive(dive *d, bool autogroup, bool newNumber); // If d->dive_trip is nul // distance are added to a trip. dive d is consumed (the structure is reset)! // If newNumber is true, the dive is assigned a new number, depending on the // insertion position. -void importDives(struct dive_table *dives, struct trip_table *trips, int flags, const QString &source); +void importDives(struct dive_table *dives, struct trip_table *trips, struct dive_site_table *sites, int flags, const QString &source); void deleteDive(const QVector &divesToDelete); void shiftTime(const QVector &changedDives, int amount); void renumberDives(const QVector> &divesToRenumber); diff --git a/desktop-widgets/command_base.h b/desktop-widgets/command_base.h index f965b8689..fbcc61f73 100644 --- a/desktop-widgets/command_base.h +++ b/desktop-widgets/command_base.h @@ -147,10 +147,14 @@ struct DiveDeleter { struct TripDeleter { void operator()(dive_trip *t) { free_trip(t); } }; +struct DiveSiteDeleter { + void operator()(dive_site *ds) { free_dive_site(ds); } +}; // Owning pointers to dive and dive_trip objects. typedef std::unique_ptr OwningDivePtr; typedef std::unique_ptr OwningTripPtr; +typedef std::unique_ptr OwningDiveSitePtr; // This is the base class of all commands. // It defines the Qt-translation functions diff --git a/desktop-widgets/command_divelist.cpp b/desktop-widgets/command_divelist.cpp index 96c5ead95..9a5a6d398 100644 --- a/desktop-widgets/command_divelist.cpp +++ b/desktop-widgets/command_divelist.cpp @@ -106,15 +106,23 @@ dive *DiveListBase::addDive(DiveToAdd &d) // returns a vector of corresponding DiveToAdd objects, which can later be readded. // Moreover, a vector of deleted trips is returned, if trips became empty. // The passed in vector is cleared. -DivesAndTripsToAdd DiveListBase::removeDives(std::vector &divesToDelete) +DivesAndTripsToAdd DiveListBase::removeDives(DivesAndSitesToRemove &divesAndSitesToDelete) { std::vector divesToAdd; std::vector tripsToAdd; - divesToAdd.reserve(divesToDelete.size()); + std::vector sitesToAdd; + divesToAdd.reserve(divesAndSitesToDelete.dives.size()); + sitesToAdd.reserve(divesAndSitesToDelete.sites.size()); - for (dive *d: divesToDelete) + for (dive *d: divesAndSitesToDelete.dives) divesToAdd.push_back(removeDive(d, tripsToAdd)); - divesToDelete.clear(); + divesAndSitesToDelete.dives.clear(); + + for (dive_site *ds: divesAndSitesToDelete.sites) { + unregister_dive_site(ds); + sitesToAdd.emplace_back(ds); + } + divesAndSitesToDelete.sites.clear(); // We send one dives-deleted signal per trip (see comments in DiveListNotifier.h). // Therefore, collect all dives in an array and sort by trip. @@ -131,17 +139,19 @@ DivesAndTripsToAdd DiveListBase::removeDives(std::vector &divesToDelete) { return ptr.get() == trip; }) != tripsToAdd.end(); emit diveListNotifier.divesDeleted(trip, deleteTrip, divesInTrip); }); - return { std::move(divesToAdd), std::move(tripsToAdd) }; + return { std::move(divesToAdd), std::move(tripsToAdd), std::move(sitesToAdd) }; } // This helper function is the counterpart fo removeDives(): it calls addDive() on a list // of dives to be (re)added and returns a vector of the added dives. It does this in reverse // order, so that trips are created appropriately and indexing is correct. // The passed in vector is cleared. -std::vector DiveListBase::addDives(DivesAndTripsToAdd &toAdd) +DivesAndSitesToRemove DiveListBase::addDives(DivesAndTripsToAdd &toAdd) { std::vector res; + std::vector sites; res.resize(toAdd.dives.size()); + sites.reserve(toAdd.sites.size()); // Now, add the dives // Note: the idiomatic STL-way would be std::transform, but let's use a loop since @@ -161,6 +171,13 @@ std::vector DiveListBase::addDives(DivesAndTripsToAdd &toAdd) } toAdd.trips.clear(); + // Finally, add any necessary dive sites + for (OwningDiveSitePtr &ds: toAdd.sites) { + sites.push_back(ds.get()); + register_dive_site(ds.release()); // Return ownership to backend + } + toAdd.sites.clear(); + // We send one dives-deleted signal per trip (see comments in DiveListNotifier.h). // Therefore, collect all dives in a array and sort by trip. std::vector> dives; @@ -175,7 +192,7 @@ std::vector DiveListBase::addDives(DivesAndTripsToAdd &toAdd) // Finally, emit the signal emit diveListNotifier.divesAdded(trip, createTrip, divesInTrip); }); - return res; + return { res, sites }; } // This helper function renumbers dives according to an array of id/number pairs. @@ -520,12 +537,12 @@ void AddDive::redoit() selection = getDiveSelection(); currentDive = current_dive; - divesToRemove = addDives(divesToAdd); + divesAndSitesToRemove = addDives(divesToAdd); sort_trip_table(&trip_table); // Though unlikely, adding a dive may reorder trips mark_divelist_changed(true); // Select the newly added dive - restoreSelection(divesToRemove, divesToRemove[0]); + restoreSelection(divesAndSitesToRemove.dives, divesAndSitesToRemove.dives[0]); // Exit from edit mode, but don't recalculate dive list // TODO: Remove edit mode @@ -535,7 +552,7 @@ void AddDive::redoit() void AddDive::undoit() { // Simply remove the dive that was previously added... - divesToAdd = removeDives(divesToRemove); + divesToAdd = removeDives(divesAndSitesToRemove); sort_trip_table(&trip_table); // Though unlikely, removing a dive may reorder trips // ...and restore the selection @@ -546,20 +563,26 @@ void AddDive::undoit() MainWindow::instance()->refreshDisplay(false); } -ImportDives::ImportDives(struct dive_table *dives, struct trip_table *trips, int flags, const QString &source) +ImportDives::ImportDives(struct dive_table *dives, struct trip_table *trips, struct dive_site_table *sites, int flags, const QString &source) { setText(tr("import %n dive(s) from %1", "", dives->nr).arg(source)); struct dive_table dives_to_add = { 0 }; struct dive_table dives_to_remove = { 0 }; struct trip_table trips_to_add = { 0 }; - process_imported_dives(dives, trips, flags, &dives_to_add, &dives_to_remove, &trips_to_add); + struct dive_site_table sites_to_add = { 0 }; + process_imported_dives(dives, trips, sites, flags, &dives_to_add, &dives_to_remove, &trips_to_add, &sites_to_add); // Add trips to the divesToAdd.trips structure divesToAdd.trips.reserve(trips_to_add.nr); for (int i = 0; i < trips_to_add.nr; ++i) divesToAdd.trips.emplace_back(trips_to_add.trips[i]); + // Add sites to the divesToAdd.sites structure + divesToAdd.sites.reserve(sites_to_add.nr); + for (int i = 0; i < sites_to_add.nr; ++i) + divesToAdd.sites.emplace_back(sites_to_add.dive_sites[i]); + // Add dives to the divesToAdd.dives structure divesToAdd.dives.reserve(dives_to_add.nr); for (int i = 0; i < dives_to_add.nr; ++i) { @@ -577,9 +600,9 @@ ImportDives::ImportDives(struct dive_table *dives, struct trip_table *trips, int } // Add dive to be deleted to the divesToRemove structure - divesToRemove.reserve(dives_to_remove.nr); + divesAndSitesToRemove.dives.reserve(dives_to_remove.nr); for (int i = 0; i < dives_to_remove.nr; ++i) - divesToRemove.push_back(dives_to_remove.dives[i]); + divesAndSitesToRemove.dives.push_back(dives_to_remove.dives[i]); } bool ImportDives::workToBeDone() @@ -592,31 +615,31 @@ void ImportDives::redoit() // Remember selection so that we can undo it currentDive = current_dive; - // Add new dives - std::vector divesToRemoveNew = addDives(divesToAdd); + // Add new dives and sites + DivesAndSitesToRemove divesAndSitesToRemoveNew = addDives(divesToAdd); - // Remove old dives - divesToAdd = removeDives(divesToRemove); + // Remove old dives and sites + divesToAdd = removeDives(divesAndSitesToRemove); // Select the newly added dives - restoreSelection(divesToRemoveNew, divesToRemoveNew.back()); + restoreSelection(divesAndSitesToRemoveNew.dives, divesAndSitesToRemoveNew.dives.back()); - // Remember dives to remove - divesToRemove = std::move(divesToRemoveNew); + // Remember dives and sites to remove + divesAndSitesToRemove = std::move(divesAndSitesToRemoveNew); mark_divelist_changed(true); } void ImportDives::undoit() { - // Add new dives - std::vector divesToRemoveNew = addDives(divesToAdd); + // Add new dives and sites + DivesAndSitesToRemove divesAndSitesToRemoveNew = addDives(divesToAdd); - // Remove old dives - divesToAdd = removeDives(divesToRemove); + // Remove old dives and sites + divesToAdd = removeDives(divesAndSitesToRemove); - // Remember dives to remove - divesToRemove = std::move(divesToRemoveNew); + // Remember dives and sites to remove + divesAndSitesToRemove = std::move(divesAndSitesToRemoveNew); // ...and restore the selection restoreSelection(selection, currentDive); @@ -624,14 +647,15 @@ void ImportDives::undoit() mark_divelist_changed(true); } -DeleteDive::DeleteDive(const QVector &divesToDeleteIn) : divesToDelete(divesToDeleteIn.toStdVector()) +DeleteDive::DeleteDive(const QVector &divesToDeleteIn) { - setText(tr("delete %n dive(s)", "", divesToDelete.size())); + divesToDelete.dives = divesToDeleteIn.toStdVector(); + setText(tr("delete %n dive(s)", "", divesToDelete.dives.size())); } bool DeleteDive::workToBeDone() { - return !divesToDelete.empty(); + return !divesToDelete.dives.empty(); } void DeleteDive::undoit() @@ -641,8 +665,8 @@ void DeleteDive::undoit() mark_divelist_changed(true); // Select all re-added dives and make the first one current - dive *currentDive = !divesToDelete.empty() ? divesToDelete[0] : nullptr; - restoreSelection(divesToDelete, currentDive); + dive *currentDive = !divesToDelete.dives.empty() ? divesToDelete.dives[0] : nullptr; + restoreSelection(divesToDelete.dives, currentDive); } void DeleteDive::redoit() @@ -853,7 +877,7 @@ SplitDivesBase::SplitDivesBase(dive *d, std::array newDives) if (idx1 == idx2 && dive_less_than(newDives[0], newDives[1])) ++idx2; - diveToSplit.push_back(d); + diveToSplit.dives.push_back(d); splitDives.dives.resize(2); splitDives.dives[0].dive.reset(newDives[0]); splitDives.dives[0].trip = d->divetrip; @@ -865,7 +889,7 @@ SplitDivesBase::SplitDivesBase(dive *d, std::array newDives) bool SplitDivesBase::workToBeDone() { - return !diveToSplit.empty(); + return !diveToSplit.dives.empty(); } void SplitDivesBase::redoit() @@ -875,7 +899,7 @@ void SplitDivesBase::redoit() mark_divelist_changed(true); // Select split dives and make first dive current - restoreSelection(divesToUnsplit, divesToUnsplit[0]); + restoreSelection(divesToUnsplit.dives, divesToUnsplit.dives[0]); } void SplitDivesBase::undoit() @@ -886,7 +910,7 @@ void SplitDivesBase::undoit() mark_divelist_changed(true); // Select unsplit dive and make it current - restoreSelection(diveToSplit, diveToSplit[0] ); + restoreSelection(diveToSplit.dives, diveToSplit.dives[0] ); } static std::array doSplitDives(const dive *d, duration_t time) @@ -1003,7 +1027,7 @@ MergeDives::MergeDives(const QVector &dives) mergedDive.dives[0].dive = std::move(d); mergedDive.dives[0].idx = get_divenr(dives[0]); mergedDive.dives[0].trip = preferred_trip; - divesToMerge = dives.toStdVector(); + divesToMerge.dives = dives.toStdVector(); } bool MergeDives::workToBeDone() @@ -1018,7 +1042,7 @@ void MergeDives::redoit() unmergedDives = removeDives(divesToMerge); // Select merged dive and make it current - restoreSelection(diveToUnmerge, diveToUnmerge[0]); + restoreSelection(diveToUnmerge.dives, diveToUnmerge.dives[0]); } void MergeDives::undoit() @@ -1028,7 +1052,7 @@ void MergeDives::undoit() renumberDives(divesToRenumber); // Select unmerged dives and make first one current - restoreSelection(divesToMerge, divesToMerge[0]); + restoreSelection(divesToMerge.dives, divesToMerge.dives[0]); } } // namespace Command diff --git a/desktop-widgets/command_divelist.h b/desktop-widgets/command_divelist.h index 7742cf729..8a70c69d3 100644 --- a/desktop-widgets/command_divelist.h +++ b/desktop-widgets/command_divelist.h @@ -19,10 +19,17 @@ struct DiveToAdd { int idx; // Position in divelist }; -// Multiple trips and dives that have to be added for a command +// Multiple trips, dives and dive sites that have to be added for a command struct DivesAndTripsToAdd { std::vector dives; std::vector trips; + std::vector sites; +}; + +// Dives and sites that have to be removed for a command +struct DivesAndSitesToRemove { + std::vector dives; + std::vector sites; }; // This helper structure describes a dive that should be moved to / removed from @@ -56,8 +63,8 @@ protected: // which set the selectionChanged flag if the added / removed dive was selected. DiveToAdd removeDive(struct dive *d, std::vector &tripsToAdd); dive *addDive(DiveToAdd &d); - DivesAndTripsToAdd removeDives(std::vector &divesToDelete); - std::vector addDives(DivesAndTripsToAdd &toAdd); + DivesAndTripsToAdd removeDives(DivesAndSitesToRemove &divesAndSitesToDelete); + DivesAndSitesToRemove addDives(DivesAndTripsToAdd &toAdd); // Set the selection to a given state. Set the selectionChanged flag if anything changed. void restoreSelection(const std::vector &selection, dive *currentDive); @@ -90,7 +97,7 @@ private: DivesAndTripsToAdd divesToAdd; // For undo - std::vector divesToRemove; + DivesAndSitesToRemove divesAndSitesToRemove; std::vector selection; dive * currentDive; }; @@ -98,7 +105,7 @@ private: class ImportDives : public DiveListBase { public: // Note: dives and trips are consumed - after the call they will be empty. - ImportDives(struct dive_table *dives, struct trip_table *trips, int flags, const QString &source); + ImportDives(struct dive_table *dives, struct trip_table *trips, struct dive_site_table *sites, int flags, const QString &source); private: void undoit() override; void redoit() override; @@ -106,9 +113,13 @@ private: // For redo and undo DivesAndTripsToAdd divesToAdd; - std::vector divesToRemove; + DivesAndSitesToRemove divesAndSitesToRemove; + + // For redo + std::vector sitesToAdd; // For undo + std::vector sitesToRemove; std::vector selection; dive * currentDive; }; @@ -122,7 +133,7 @@ private: bool workToBeDone() override; // For redo - std::vector divesToDelete; + DivesAndSitesToRemove divesToDelete; std::vector tripsToAdd; DivesAndTripsToAdd divesToAdd; @@ -197,7 +208,7 @@ private: // For each dive to split, we remove one from and put two dives into the backend // Note: we use a vector even though we split only a single dive, so // that we can reuse the multi-dive functions of the other commands. - std::vector diveToSplit; + DivesAndSitesToRemove diveToSplit; DivesAndTripsToAdd splitDives; // For undo @@ -205,7 +216,7 @@ private: // Note: we use a multi-dive structure even though we unsplit only a single dive, so // that we can reuse the multi-dive functions of the other commands. DivesAndTripsToAdd unsplitDive; - std::vector divesToUnsplit; + DivesAndSitesToRemove divesToUnsplit; }; class SplitDives : public SplitDivesBase { @@ -233,13 +244,13 @@ private: // Note: we use a multi-dives structure even though we add only a single dive, so // that we can reuse the multi-dive functions of the other commands. DivesAndTripsToAdd mergedDive; - std::vector divesToMerge; + DivesAndSitesToRemove divesToMerge; // For undo // Remove one and add a batch of dives // Note: we use a vector even though we remove only a single dive, so // that we can reuse the multi-dive functions of the other commands. - std::vector diveToUnmerge; + DivesAndSitesToRemove diveToUnmerge; DivesAndTripsToAdd unmergedDives; // For undo and redo diff --git a/desktop-widgets/divelogimportdialog.cpp b/desktop-widgets/divelogimportdialog.cpp index f1e616514..0bbb0dcb5 100644 --- a/desktop-widgets/divelogimportdialog.cpp +++ b/desktop-widgets/divelogimportdialog.cpp @@ -901,14 +901,15 @@ void DiveLogImportDialog::on_buttonBox_accepted() { struct dive_table table = { 0 }; struct trip_table trips = { 0 }; + struct dive_site_table sites = { 0 }; QStringList r = resultModel->result(); if (ui->knownImports->currentText() != "Manual import") { for (int i = 0; i < fileNames.size(); ++i) { if (ui->knownImports->currentText() == "Seabear CSV") { - parse_seabear_log(qPrintable(fileNames[i]), &table, &trips, &dive_site_table); + parse_seabear_log(qPrintable(fileNames[i]), &table, &trips, &sites); } else if (ui->knownImports->currentText() == "Poseidon MkVI") { QPair pair = poseidonFileNames(fileNames[i]); - parse_txt_file(qPrintable(pair.second), qPrintable(pair.first), &table, &trips, &dive_site_table); + parse_txt_file(qPrintable(pair.second), qPrintable(pair.first), &table, &trips, &sites); } else { char *params[49]; int pnr = 0; @@ -925,7 +926,7 @@ void DiveLogImportDialog::on_buttonBox_accepted() pnr = setup_csv_params(r, params, pnr); parse_csv_file(qPrintable(fileNames[i]), params, pnr - 1, specialCSV.contains(ui->knownImports->currentIndex()) ? qPrintable(CSVApps[ui->knownImports->currentIndex()].name) : "csv", - &table, &trips, &dive_site_table); + &table, &trips, &sites); } } } else { @@ -989,7 +990,7 @@ void DiveLogImportDialog::on_buttonBox_accepted() params[pnr++] = intdup(r.indexOf(tr("Rating"))); params[pnr++] = NULL; - parse_manual_file(qPrintable(fileNames[i]), params, pnr - 1, &table, &trips, &dive_site_table); + parse_manual_file(qPrintable(fileNames[i]), params, pnr - 1, &table, &trips, &sites); } else { char *params[51]; int pnr = 0; @@ -1006,13 +1007,13 @@ void DiveLogImportDialog::on_buttonBox_accepted() pnr = setup_csv_params(r, params, pnr); parse_csv_file(qPrintable(fileNames[i]), params, pnr - 1, specialCSV.contains(ui->knownImports->currentIndex()) ? qPrintable(CSVApps[ui->knownImports->currentIndex()].name) : "csv", - &table, &trips, &dive_site_table); + &table, &trips, &sites); } } } QString source = fileNames.size() == 1 ? fileNames[0] : tr("multiple files"); - Command::importDives(&table, &trips, IMPORT_MERGE_ALL_TRIPS, source); + Command::importDives(&table, &trips, &sites, IMPORT_MERGE_ALL_TRIPS, source); } TagDragDelegate::TagDragDelegate(QObject *parent) : QStyledItemDelegate(parent) diff --git a/desktop-widgets/downloadfromdivecomputer.cpp b/desktop-widgets/downloadfromdivecomputer.cpp index e28a90e26..6d9ba9288 100644 --- a/desktop-widgets/downloadfromdivecomputer.cpp +++ b/desktop-widgets/downloadfromdivecomputer.cpp @@ -484,7 +484,7 @@ void DownloadFromDCWidget::onDownloadThreadFinished() } ui.downloadCancelRetryButton->setText(tr("Retry download")); ui.downloadCancelRetryButton->setEnabled(true); - diveImportedModel->repopulate(thread.table()); + diveImportedModel->repopulate(thread.table(), thread.sites()); } void DownloadFromDCWidget::on_cancel_clicked() @@ -502,6 +502,7 @@ void DownloadFromDCWidget::on_ok_clicked() if (currentState != DONE && currentState != ERROR) return; struct dive_table *table = thread.table(); + struct dive_site_table *sites = thread.sites(); // delete non-selected dives int total = table->nr; @@ -520,7 +521,7 @@ void DownloadFromDCWidget::on_ok_clicked() flags |= IMPORT_PREFER_IMPORTED; if (ui.createNewTrip->isChecked()) flags |= IMPORT_ADD_TO_NEW_TRIP; - Command::importDives(table, nullptr, flags, data->devName()); + Command::importDives(table, nullptr, sites, flags, data->devName()); } if (ostcFirmwareCheck && currentState == DONE) diff --git a/desktop-widgets/mainwindow.cpp b/desktop-widgets/mainwindow.cpp index 8483dc3c4..de8ce9b0a 100644 --- a/desktop-widgets/mainwindow.cpp +++ b/desktop-widgets/mainwindow.cpp @@ -1648,13 +1648,14 @@ void MainWindow::importFiles(const QStringList fileNames) QByteArray fileNamePtr; struct dive_table table = { 0 }; struct trip_table trips = { 0 }; + struct dive_site_table sites = { 0 }; for (int i = 0; i < fileNames.size(); ++i) { fileNamePtr = QFile::encodeName(fileNames.at(i)); - parse_file(fileNamePtr.data(), &table, &trips, &dive_site_table); + parse_file(fileNamePtr.data(), &table, &trips, &sites); } QString source = fileNames.size() == 1 ? fileNames[0] : tr("multiple files"); - Command::importDives(&table, &trips, IMPORT_MERGE_ALL_TRIPS, source); + Command::importDives(&table, &trips, &sites, IMPORT_MERGE_ALL_TRIPS, source); } void MainWindow::loadFiles(const QStringList fileNames) diff --git a/desktop-widgets/subsurfacewebservices.cpp b/desktop-widgets/subsurfacewebservices.cpp index 4d438aa28..87db7947c 100644 --- a/desktop-widgets/subsurfacewebservices.cpp +++ b/desktop-widgets/subsurfacewebservices.cpp @@ -771,8 +771,9 @@ void DivelogsDeWebServices::buttonClicked(QAbstractButton *button) /* parse file and import dives */ struct dive_table table = { 0 }; struct trip_table trips = { 0 }; - parse_file(QFile::encodeName(zipFile.fileName()), &table, &trips, &dive_site_table); - Command::importDives(&table, &trips, IMPORT_MERGE_ALL_TRIPS, QStringLiteral("divelogs.de")); + struct dive_site_table sites = { 0 }; + parse_file(QFile::encodeName(zipFile.fileName()), &table, &trips, &sites); + Command::importDives(&table, &trips, &sites, IMPORT_MERGE_ALL_TRIPS, QStringLiteral("divelogs.de")); /* store last entered user/pass in config */ QSettings s; -- cgit v1.2.3-70-g09d2