diff options
author | Berthold Stoeger <bstoeger@mail.tuwien.ac.at> | 2019-03-03 15:12:22 +0100 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2019-04-12 18:19:07 +0300 |
commit | 82af1b2377cec03a989f86b8009d4ac226c6541e (patch) | |
tree | a875f194f7174c8673b2f7bd5cc43aa8ca3c51c6 | |
parent | 37146c5742503becf75468fb07aab56011cb9101 (diff) | |
download | subsurface-82af1b2377cec03a989f86b8009d4ac226c6541e.tar.gz |
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 <bstoeger@mail.tuwien.ac.at>
-rw-r--r-- | core/dive.h | 8 | ||||
-rw-r--r-- | core/divelist.c | 65 | ||||
-rw-r--r-- | core/divelist.h | 8 | ||||
-rw-r--r-- | core/divesite.c | 67 | ||||
-rw-r--r-- | core/divesite.h | 9 | ||||
-rw-r--r-- | core/downloadfromdcthread.cpp | 5 | ||||
-rw-r--r-- | core/downloadfromdcthread.h | 2 | ||||
-rw-r--r-- | desktop-widgets/command.cpp | 4 | ||||
-rw-r--r-- | desktop-widgets/command.h | 2 | ||||
-rw-r--r-- | desktop-widgets/command_base.h | 4 | ||||
-rw-r--r-- | desktop-widgets/command_divelist.cpp | 102 | ||||
-rw-r--r-- | desktop-widgets/command_divelist.h | 33 | ||||
-rw-r--r-- | desktop-widgets/divelogimportdialog.cpp | 13 | ||||
-rw-r--r-- | desktop-widgets/downloadfromdivecomputer.cpp | 5 | ||||
-rw-r--r-- | desktop-widgets/mainwindow.cpp | 5 | ||||
-rw-r--r-- | desktop-widgets/subsurfacewebservices.cpp | 5 | ||||
-rw-r--r-- | mobile-widgets/qml/DownloadFromDiveComputer.qml | 2 | ||||
-rw-r--r-- | mobile-widgets/qmlmanager.cpp | 5 | ||||
-rw-r--r-- | qt-models/diveimportedmodel.cpp | 8 | ||||
-rw-r--r-- | qt-models/diveimportedmodel.h | 3 | ||||
-rw-r--r-- | tests/testmerge.cpp | 18 | ||||
-rw-r--r-- | tests/testrenumber.cpp | 10 |
22 files changed, 269 insertions, 114 deletions
diff --git a/core/dive.h b/core/dive.h index d40e53043..03d6fc2df 100644 --- a/core/dive.h +++ b/core/dive.h @@ -758,15 +758,17 @@ extern void average_max_depth(struct diveplan *dive, int *avg_depth, int *max_de #ifdef __cplusplus } -/* Make pointers to dive, dive_trip and dive_table "Qt metatypes" so that they can - * be passed through QVariants and through QML. +/* Make pointers to dive, dive_trip, dive_table, trip_table and dive_site_table + * "Qt metatypes" so that they can be passed through QVariants and through QML. * Note: we have to use the typedef "dive_table_t" instead of "struct dive_table", * because MOC removes the "struct", but dive_table is already the name of a global - * variable, leading to compilation errors. Likewise for "struct trip_table". */ + * variable, leading to compilation errors. Likewise for "struct trip_table" and + * "struct dive_site_table". */ Q_DECLARE_METATYPE(struct dive *); Q_DECLARE_METATYPE(struct dive_trip *); Q_DECLARE_METATYPE(dive_table_t *); Q_DECLARE_METATYPE(trip_table_t *); +Q_DECLARE_METATYPE(dive_site_table_t *); #endif diff --git a/core/divelist.c b/core/divelist.c index 8e1ba1628..09f08acd0 100644 --- a/core/divelist.c +++ b/core/divelist.c @@ -1518,17 +1518,18 @@ static bool merge_dive_tables(struct dive_table *dives_from, struct dive_table * /* Merge the dives of the trip "from" and the dive_table "dives_from" into the trip "to" * and dive_table "dives_to". If "prefer_imported" is true, dive data of "from" takes * precedence */ -void add_imported_dives(struct dive_table *import_table, struct trip_table *import_trip_table, int flags) +void add_imported_dives(struct dive_table *import_table, struct trip_table *import_trip_table, struct dive_site_table *import_sites_table, int flags) { int i, idx; struct dive_table dives_to_add = { 0 }; struct dive_table dives_to_remove = { 0 }; struct trip_table trips_to_add = { 0 }; + struct dive_site_table dive_sites_to_add = { 0 }; /* Process imported dives and generate lists of dives * to-be-added and to-be-removed */ - process_imported_dives(import_table, import_trip_table, flags, - &dives_to_add, &dives_to_remove, &trips_to_add); + process_imported_dives(import_table, import_trip_table, import_sites_table, flags, + &dives_to_add, &dives_to_remove, &trips_to_add, &dive_sites_to_add); /* Add new dives to trip, so that trips don't get deleted * on deletion of old dives */ @@ -1560,6 +1561,11 @@ void add_imported_dives(struct dive_table *import_table, struct trip_table *impo insert_trip(trips_to_add.trips[i], &trip_table); trips_to_add.nr = 0; + /* Add new dive sites */ + for (i = 0; i < dive_sites_to_add.nr; i++) + register_dive_site(dive_sites_to_add.dive_sites[i]); + dive_sites_to_add.nr = 0; + /* We might have deleted the old selected dive. * Choose the newest dive as selected (if any) */ current_dive = dive_table.nr > 0 ? dive_table.dives[dive_table.nr - 1] : NULL; @@ -1600,21 +1606,23 @@ bool try_to_merge_trip(struct dive_trip *trip_import, struct dive_table *import_ } /* Process imported dives: take a table of dives to be imported and - * generate three lists: + * generate four lists: * 1) Dives to be added * 2) Dives to be removed * 3) Trips to be added + * 4) Dive sites to be added * The dives to be added are owning (i.e. the caller is responsible * for freeing them). - * The dives and trips in "import_table" and "import_trip_table" are - * consumed. On return, both tables have size 0. - * "import_trip_table" may be NULL if all dives are not associated + * The dives, trips and sites in "import_table", "import_trip_table" + * and "import_sites_table" are consumed. On return, the tables have + * size 0. "import_trip_table" may be NULL if all dives are not associated * with a trip. - * The output parameters should be empty - if not, their content + * The output tables should be empty - if not, their content * will be cleared! * - * Note: The new dives will have their divetrip-field set, but will - * *not* be part of the trip. The caller has to add them to the trip. + * Note: The new dives will have their divetrip- and divesites-fields + * set, but will *not* be part of the trip and site. The caller has to + * add them to the trip and site. * * The lists are generated by merging dives if possible. This is * performed trip-wise. Finer control on merging is provided by @@ -1629,10 +1637,11 @@ bool try_to_merge_trip(struct dive_trip *trip_import, struct dive_table *import_ * - If IMPORT_ADD_TO_NEW_TRIP is true, dives that are not assigned * to a trip will be added to a newly generated trip. */ -void process_imported_dives(struct dive_table *import_table, struct trip_table *import_trip_table, int flags, +void process_imported_dives(struct dive_table *import_table, struct trip_table *import_trip_table, + struct dive_site_table *import_sites_table, int flags, /* output parameters: */ struct dive_table *dives_to_add, struct dive_table *dives_to_remove, - struct trip_table *trips_to_add) + struct trip_table *trips_to_add, struct dive_site_table *sites_to_add) { int i, j, nr, start_renumbering_at = 0; struct dive_trip *trip_import, *new_trip; @@ -1651,6 +1660,7 @@ void process_imported_dives(struct dive_table *import_table, struct trip_table * clear_table(dives_to_add); clear_table(dives_to_remove); clear_trip_table(trips_to_add); + clear_dive_site_table(sites_to_add); /* Check if any of the new dives has a number. This will be * important later to decide if we want to renumber the added @@ -1687,6 +1697,37 @@ void process_imported_dives(struct dive_table *import_table, struct trip_table * preexisting = dive_table.nr; /* Remember old size for renumbering */ + /* If dive sites already exist, use the existing versions. */ + for (i = 0; i < import_sites_table->nr; i++) { + struct dive_site *new_ds = import_sites_table->dive_sites[i]; + struct dive_site *old_ds = get_same_dive_site(new_ds); + + /* Check if it dive site is actually used by new dives. */ + for (j = 0; j < import_table->nr; j++) { + if (import_table->dives[j]->dive_site == new_ds) + break; + } + + if (j == import_table->nr) { + /* Dive site not even used - free it and go to next. */ + free_dive_site(new_ds); + continue; + } + + if (!old_ds) { + /* Dive site doesn't exist. Add it to list of dive sites to be added. */ + add_dive_site_to_table(new_ds, sites_to_add); + continue; + } + /* Dive site already exists - use the old and free the new. */ + for (j = 0; j < import_table->nr; j++) { + if (import_table->dives[j]->dive_site == new_ds) + import_table->dives[j]->dive_site = old_ds; + } + free_dive_site(new_ds); + } + import_sites_table->nr = 0; /* All dive sites were consumed */ + /* Merge overlapping trips. Since both trip tables are sorted, we * could be smarter here, but realistically not a whole lot of trips * will be imported so do a simple n*m loop until someone complains. diff --git a/core/divelist.h b/core/divelist.h index e1ff706f7..1880856df 100644 --- a/core/divelist.h +++ b/core/divelist.h @@ -23,10 +23,12 @@ extern void process_loaded_dives(); #define IMPORT_IS_DOWNLOADED (1 << 1) #define IMPORT_MERGE_ALL_TRIPS (1 << 2) #define IMPORT_ADD_TO_NEW_TRIP (1 << 3) -extern void add_imported_dives(struct dive_table *import_table, struct trip_table *import_trip_table, int flags); -extern void process_imported_dives(struct dive_table *import_table, struct trip_table *import_trip_table, int flags, +extern void add_imported_dives(struct dive_table *import_table, struct trip_table *import_trip_table, struct dive_site_table *import_sites_table, + int flags); +extern void process_imported_dives(struct dive_table *import_table, struct trip_table *import_trip_table, struct dive_site_table *import_sites_table, + int flags, struct dive_table *dives_to_add, struct dive_table *dives_to_remove, - struct trip_table *trips_to_add); + struct trip_table *trips_to_add, struct dive_site_table *sites_to_add); extern char *get_dive_gas_string(const struct dive *dive); extern struct dive **grow_dive_table(struct dive_table *table); diff --git a/core/divesite.c b/core/divesite.c index 9baabd872..bf99ed395 100644 --- a/core/divesite.c +++ b/core/divesite.c @@ -117,14 +117,13 @@ static uint32_t dive_site_getUniqId(struct dive_site_table *ds_table) return id; } -/* we never allow a second dive site with the same uuid */ -struct dive_site *alloc_or_get_dive_site(uint32_t uuid, struct dive_site_table *ds_table) +void register_dive_site(struct dive_site *ds) { - struct dive_site *ds; - - if (uuid && (ds = get_dive_site_by_uuid(uuid, ds_table)) != NULL) - return ds; + add_dive_site_to_table(ds, &dive_site_table); +} +void add_dive_site_to_table(struct dive_site *ds, struct dive_site_table *ds_table) +{ int nr = ds_table->nr; int allocated = ds_table->allocated; struct dive_site **sites = ds_table->dive_sites; @@ -137,11 +136,23 @@ struct dive_site *alloc_or_get_dive_site(uint32_t uuid, struct dive_site_table * ds_table->dive_sites = sites; ds_table->allocated = allocated; } + sites[nr] = ds; + ds_table->nr = nr + 1; +} + +/* we never allow a second dive site with the same uuid */ +struct dive_site *alloc_or_get_dive_site(uint32_t uuid, struct dive_site_table *ds_table) +{ + struct dive_site *ds; + + if (uuid && (ds = get_dive_site_by_uuid(uuid, ds_table)) != NULL) + return ds; + ds = calloc(1, sizeof(*ds)); if (!ds) exit(1); - sites[nr] = ds; - ds_table->nr = nr + 1; + add_dive_site_to_table(ds, ds_table); + // we should always be called with a valid uuid except in the special // case where we want to copy a dive site into the memory we allocated // here - then we need to pass in 0 and create a temporary uuid here @@ -195,12 +206,16 @@ void free_dive_site(struct dive_site *ds) } } -void delete_dive_site(struct dive_site *ds, struct dive_site_table *ds_table) +void unregister_dive_site(struct dive_site *ds) +{ + remove_dive_site_from_table(ds, &dive_site_table); +} + +void remove_dive_site_from_table(struct dive_site *ds, struct dive_site_table *ds_table) { int nr = ds_table->nr; for (int i = 0; i < nr; i++) { if (ds == get_dive_site(i, ds_table)) { - free_dive_site(ds); if (nr - 1 > i) memmove(&ds_table->dive_sites[i], &ds_table->dive_sites[i+1], @@ -211,6 +226,14 @@ void delete_dive_site(struct dive_site *ds, struct dive_site_table *ds_table) } } +void delete_dive_site(struct dive_site *ds, struct dive_site_table *ds_table) +{ + if (!ds) + return; + remove_dive_site_from_table(ds, ds_table); + free_dive_site(ds); +} + static uint32_t create_divesite_uuid(const char *name, timestamp_t divetime) { if (name == NULL) @@ -291,6 +314,30 @@ static void merge_string(char **a, char **b) free(s1); } +/* Used to check on import if two dive sites are equivalent. + * Since currently no merging is performed, be very conservative + * and only consider equal dive sites that are exactly the same. + * Taxonomy is not compared, as no taxonomy is generated on + * import. + */ +static bool same_dive_site(const struct dive_site *a, const struct dive_site *b) +{ + return same_string(a->name, b->name) + && same_location(&a->location, &b->location) + && same_string(a->description, b->description) + && same_string(a->notes, b->notes); +} + +struct dive_site *get_same_dive_site(const struct dive_site *site) +{ + int i; + struct dive_site *ds; + for_each_dive_site (i, ds, &dive_site_table) + if (same_dive_site(ds, site)) + return ds; + return NULL; +} + void merge_dive_site(struct dive_site *a, struct dive_site *b) { if (!has_location(&a->location)) a->location = b->location; diff --git a/core/divesite.h b/core/divesite.h index ba4cd32a5..1f841a7d2 100644 --- a/core/divesite.h +++ b/core/divesite.h @@ -24,10 +24,10 @@ struct dive_site struct taxonomy_data taxonomy; }; -struct dive_site_table { +typedef struct dive_site_table { int nr, allocated; struct dive_site **dive_sites; -}; +} dive_site_table_t; extern struct dive_site_table dive_site_table; @@ -45,6 +45,10 @@ static inline struct dive_site *get_dive_site(int nr, struct dive_site_table *ds int get_divesite_idx(const struct dive_site *ds, struct dive_site_table *ds_table); struct dive_site *get_dive_site_by_uuid(uint32_t uuid, struct dive_site_table *ds_table); void dive_site_table_sort(struct dive_site_table *ds_table); +void add_dive_site_to_table(struct dive_site *ds, struct dive_site_table *ds_table); +void remove_dive_site_from_table(struct dive_site *ds, struct dive_site_table *ds_table); +void register_dive_site(struct dive_site *ds); +void unregister_dive_site(struct dive_site *ds); struct dive_site *alloc_or_get_dive_site(uint32_t uuid, struct dive_site_table *ds_table); int nr_of_dives_at_dive_site(struct dive_site *ds, bool select_only); bool is_dive_site_used(struct dive_site *ds, bool select_only); @@ -56,6 +60,7 @@ struct dive_site *get_dive_site_by_name(const char *name, struct dive_site_table struct dive_site *get_dive_site_by_gps(const location_t *, struct dive_site_table *ds_table); struct dive_site *get_dive_site_by_gps_and_name(char *name, const location_t *, struct dive_site_table *ds_table); struct dive_site *get_dive_site_by_gps_proximity(const location_t *, int distance, struct dive_site_table *ds_table); +struct dive_site *get_same_dive_site(const struct dive_site *); bool dive_site_is_empty(struct dive_site *ds); void copy_dive_site_taxonomy(struct dive_site *orig, struct dive_site *copy); void copy_dive_site(struct dive_site *orig, struct dive_site *copy); diff --git a/core/downloadfromdcthread.cpp b/core/downloadfromdcthread.cpp index 5b336dee5..f2a65ac5f 100644 --- a/core/downloadfromdcthread.cpp +++ b/core/downloadfromdcthread.cpp @@ -306,6 +306,11 @@ struct dive_table *DownloadThread::table() return &downloadTable; } +struct dive_site_table *DownloadThread::sites() +{ + return &diveSiteTable; +} + QString DCDeviceData::vendor() const { return data.vendor; diff --git a/core/downloadfromdcthread.h b/core/downloadfromdcthread.h index e4cfb2351..d14a5402b 100644 --- a/core/downloadfromdcthread.h +++ b/core/downloadfromdcthread.h @@ -59,6 +59,7 @@ private: class DownloadThread : public QThread { Q_OBJECT Q_PROPERTY(dive_table_t *table READ table CONSTANT) + Q_PROPERTY(dive_site_table_t *sites READ sites CONSTANT) public: DownloadThread(); @@ -66,6 +67,7 @@ public: DCDeviceData *data(); struct dive_table *table(); + struct dive_site_table *sites(); QString error; private: 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<struct dive*> &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<struct dive*> &divesToDelete); void shiftTime(const QVector<dive *> &changedDives, int amount); void renumberDives(const QVector<QPair<dive *, int>> &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<dive, DiveDeleter> OwningDivePtr; typedef std::unique_ptr<dive_trip, TripDeleter> OwningTripPtr; +typedef std::unique_ptr<dive_site, DiveSiteDeleter> 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<dive *> &divesToDelete) +DivesAndTripsToAdd DiveListBase::removeDives(DivesAndSitesToRemove &divesAndSitesToDelete) { std::vector<DiveToAdd> divesToAdd; std::vector<OwningTripPtr> tripsToAdd; - divesToAdd.reserve(divesToDelete.size()); + std::vector<OwningDiveSitePtr> 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<dive *> &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<dive *> DiveListBase::addDives(DivesAndTripsToAdd &toAdd) +DivesAndSitesToRemove DiveListBase::addDives(DivesAndTripsToAdd &toAdd) { std::vector<dive *> res; + std::vector<dive_site *> 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<dive *> 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<std::pair<dive_trip *, dive *>> dives; @@ -175,7 +192,7 @@ std::vector<dive *> 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<dive *> 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<dive *> 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<struct dive*> &divesToDeleteIn) : divesToDelete(divesToDeleteIn.toStdVector()) +DeleteDive::DeleteDive(const QVector<struct dive*> &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<dive *, 2> 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<dive *, 2> 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<dive *, 2> doSplitDives(const dive *d, duration_t time) @@ -1003,7 +1027,7 @@ MergeDives::MergeDives(const QVector <dive *> &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<DiveToAdd> dives; std::vector<OwningTripPtr> trips; + std::vector<OwningDiveSitePtr> sites; +}; + +// Dives and sites that have to be removed for a command +struct DivesAndSitesToRemove { + std::vector<dive *> dives; + std::vector<dive_site *> 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<OwningTripPtr> &tripsToAdd); dive *addDive(DiveToAdd &d); - DivesAndTripsToAdd removeDives(std::vector<dive *> &divesToDelete); - std::vector<dive *> 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<dive *> &selection, dive *currentDive); @@ -90,7 +97,7 @@ private: DivesAndTripsToAdd divesToAdd; // For undo - std::vector<dive *> divesToRemove; + DivesAndSitesToRemove divesAndSitesToRemove; std::vector<dive *> 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<dive *> divesToRemove; + DivesAndSitesToRemove divesAndSitesToRemove; + + // For redo + std::vector<OwningDiveSitePtr> sitesToAdd; // For undo + std::vector<dive_site *> sitesToRemove; std::vector<dive *> selection; dive * currentDive; }; @@ -122,7 +133,7 @@ private: bool workToBeDone() override; // For redo - std::vector<struct dive*> divesToDelete; + DivesAndSitesToRemove divesToDelete; std::vector<OwningTripPtr> 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<dive *> 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<dive *> 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<dive *> 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<dive *> 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<QString, QString> 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; diff --git a/mobile-widgets/qml/DownloadFromDiveComputer.qml b/mobile-widgets/qml/DownloadFromDiveComputer.qml index a1403b07d..2377db951 100644 --- a/mobile-widgets/qml/DownloadFromDiveComputer.qml +++ b/mobile-widgets/qml/DownloadFromDiveComputer.qml @@ -28,7 +28,7 @@ Kirigami.Page { id: downloadThread onFinished : { - importModel.repopulate(table) + importModel.repopulate(table, sites) progressBar.visible = false if (dcImportModel.rowCount() > 0) { console.log(dcImportModel.rowCount() + " dive downloaded") diff --git a/mobile-widgets/qmlmanager.cpp b/mobile-widgets/qmlmanager.cpp index 9603a2ad0..4db9cbb63 100644 --- a/mobile-widgets/qmlmanager.cpp +++ b/mobile-widgets/qmlmanager.cpp @@ -341,8 +341,9 @@ void QMLManager::mergeLocalRepo() char *filename = NOCLOUD_LOCALSTORAGE; struct dive_table table = { 0 }; struct trip_table trips = { 0 }; - parse_file(filename, &table, &trips, &dive_site_table); - add_imported_dives(&table, &trips, IMPORT_MERGE_ALL_TRIPS); + struct dive_site_table sites = { 0 }; + parse_file(filename, &table, &trips, &sites); + add_imported_dives(&table, &trips, &sites, IMPORT_MERGE_ALL_TRIPS); } void QMLManager::copyAppLogToClipboard() diff --git a/qt-models/diveimportedmodel.cpp b/qt-models/diveimportedmodel.cpp index 2001f031e..5de0f7cb4 100644 --- a/qt-models/diveimportedmodel.cpp +++ b/qt-models/diveimportedmodel.cpp @@ -4,7 +4,8 @@ DiveImportedModel::DiveImportedModel(QObject *o) : QAbstractTableModel(o), firstIndex(0), lastIndex(-1), - diveTable(nullptr) + diveTable(nullptr), + sitesTable(nullptr) { } @@ -127,11 +128,12 @@ void DiveImportedModel::clearTable() endRemoveRows(); } -void DiveImportedModel::repopulate(dive_table_t *table) +void DiveImportedModel::repopulate(dive_table_t *table, struct dive_site_table *sites) { beginResetModel(); diveTable = table; + sitesTable = sites; firstIndex = 0; lastIndex = diveTable->nr - 1; checkStates.resize(diveTable->nr); @@ -158,7 +160,7 @@ void DiveImportedModel::recordDives() } // TODO: Might want to let the user select IMPORT_ADD_TO_NEW_TRIP - add_imported_dives(diveTable, nullptr, IMPORT_PREFER_IMPORTED | IMPORT_IS_DOWNLOADED); + add_imported_dives(diveTable, nullptr, sitesTable, IMPORT_PREFER_IMPORTED | IMPORT_IS_DOWNLOADED); } QHash<int, QByteArray> DiveImportedModel::roleNames() const { diff --git a/qt-models/diveimportedmodel.h b/qt-models/diveimportedmodel.h index 0c5ba34cd..8b0038478 100644 --- a/qt-models/diveimportedmodel.h +++ b/qt-models/diveimportedmodel.h @@ -20,7 +20,7 @@ public: Qt::ItemFlags flags(const QModelIndex &index) const; Q_INVOKABLE void clearTable(); QHash<int, QByteArray> roleNames() const; - Q_INVOKABLE void repopulate(dive_table_t *table); + Q_INVOKABLE void repopulate(dive_table_t *table, dive_site_table_t *sites); Q_INVOKABLE void recordDives(); public slots: @@ -34,6 +34,7 @@ private: int lastIndex; std::vector<char> checkStates; // char instead of bool to avoid silly pessimization of std::vector. struct dive_table *diveTable; + struct dive_site_table *sitesTable; }; #endif diff --git a/tests/testmerge.cpp b/tests/testmerge.cpp index 70f22ee73..c8a103c82 100644 --- a/tests/testmerge.cpp +++ b/tests/testmerge.cpp @@ -23,10 +23,11 @@ void TestMerge::testMergeEmpty() */ struct dive_table table = { 0 }; struct trip_table trips = { 0 }; - QCOMPARE(parse_file(SUBSURFACE_TEST_DATA "/dives/test47.xml", &table, &trips, &dive_site_table), 0); - add_imported_dives(&table, &trips, IMPORT_MERGE_ALL_TRIPS); - QCOMPARE(parse_file(SUBSURFACE_TEST_DATA "/dives/test48.xml", &table, &trips, &dive_site_table), 0); - add_imported_dives(&table, &trips, IMPORT_MERGE_ALL_TRIPS); + struct dive_site_table sites = { 0 }; + QCOMPARE(parse_file(SUBSURFACE_TEST_DATA "/dives/test47.xml", &table, &trips, &sites), 0); + add_imported_dives(&table, &trips, &sites, IMPORT_MERGE_ALL_TRIPS); + QCOMPARE(parse_file(SUBSURFACE_TEST_DATA "/dives/test48.xml", &table, &trips, &sites), 0); + add_imported_dives(&table, &trips, &sites, IMPORT_MERGE_ALL_TRIPS); QCOMPARE(save_dives("./testmerge47+48.ssrf"), 0); QFile org(SUBSURFACE_TEST_DATA "/dives/test47+48.xml"); org.open(QFile::ReadOnly); @@ -48,10 +49,11 @@ void TestMerge::testMergeBackwards() */ struct dive_table table = { 0 }; struct trip_table trips = { 0 }; - QCOMPARE(parse_file(SUBSURFACE_TEST_DATA "/dives/test48.xml", &table, &trips, &dive_site_table), 0); - add_imported_dives(&table, &trips, IMPORT_MERGE_ALL_TRIPS); - QCOMPARE(parse_file(SUBSURFACE_TEST_DATA "/dives/test47.xml", &table, &trips, &dive_site_table), 0); - add_imported_dives(&table, &trips, IMPORT_MERGE_ALL_TRIPS); + struct dive_site_table sites = { 0 }; + QCOMPARE(parse_file(SUBSURFACE_TEST_DATA "/dives/test48.xml", &table, &trips, &sites), 0); + add_imported_dives(&table, &trips, &sites, IMPORT_MERGE_ALL_TRIPS); + QCOMPARE(parse_file(SUBSURFACE_TEST_DATA "/dives/test47.xml", &table, &trips, &sites), 0); + add_imported_dives(&table, &trips, &sites, IMPORT_MERGE_ALL_TRIPS); QCOMPARE(save_dives("./testmerge47+48.ssrf"), 0); QFile org(SUBSURFACE_TEST_DATA "/dives/test47+48.xml"); org.open(QFile::ReadOnly); diff --git a/tests/testrenumber.cpp b/tests/testrenumber.cpp index d674c4922..71f4e2952 100644 --- a/tests/testrenumber.cpp +++ b/tests/testrenumber.cpp @@ -15,8 +15,9 @@ void TestRenumber::testMerge() { struct dive_table table = { 0 }; struct trip_table trips = { 0 }; - QCOMPARE(parse_file(SUBSURFACE_TEST_DATA "/dives/test47b.xml", &table, &trip_table, &dive_site_table), 0); - add_imported_dives(&table, &trips, IMPORT_MERGE_ALL_TRIPS); + struct dive_site_table sites = { 0 }; + QCOMPARE(parse_file(SUBSURFACE_TEST_DATA "/dives/test47b.xml", &table, &trips, &sites), 0); + add_imported_dives(&table, &trips, &sites, IMPORT_MERGE_ALL_TRIPS); QCOMPARE(dive_table.nr, 1); QCOMPARE(unsaved_changes(), 1); mark_divelist_changed(false); @@ -26,8 +27,9 @@ void TestRenumber::testMergeAndAppend() { struct dive_table table = { 0 }; struct trip_table trips = { 0 }; - QCOMPARE(parse_file(SUBSURFACE_TEST_DATA "/dives/test47c.xml", &table, &trip_table, &dive_site_table), 0); - add_imported_dives(&table, &trips, IMPORT_MERGE_ALL_TRIPS); + struct dive_site_table sites = { 0 }; + QCOMPARE(parse_file(SUBSURFACE_TEST_DATA "/dives/test47c.xml", &table, &trips, &sites), 0); + add_imported_dives(&table, &trips, &sites, IMPORT_MERGE_ALL_TRIPS); QCOMPARE(dive_table.nr, 2); QCOMPARE(unsaved_changes(), 1); struct dive *d = get_dive(1); |