diff options
author | Berthold Stoeger <bstoeger@mail.tuwien.ac.at> | 2018-11-08 16:58:33 +0100 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2018-11-18 16:50:09 -0800 |
commit | 6b283e598a3a08c6133d66b5d5617370296e7d0e (patch) | |
tree | 685ccf1fd839d72471b179bf12aa72d2bdcec7de | |
parent | bc7afebc23477ef23f2b9741bf45b2180cbafe15 (diff) | |
download | subsurface-6b283e598a3a08c6133d66b5d5617370296e7d0e.tar.gz |
Dive list: replace dive-list of trips by a table
The dives of each trip were kept in a list. Replace this by a
struct dive_table. This will make it significantly easier to
keep the dives of a trip in sorted state.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
-rw-r--r-- | core/dive.h | 15 | ||||
-rw-r--r-- | core/divelist.c | 86 | ||||
-rw-r--r-- | core/save-html.c | 3 | ||||
-rw-r--r-- | core/subsurface-qt/DiveObjectHelper.cpp | 4 | ||||
-rw-r--r-- | desktop-widgets/command_divelist.cpp | 12 | ||||
-rw-r--r-- | mobile-widgets/qmlmanager.cpp | 6 | ||||
-rw-r--r-- | qt-models/divelistmodel.cpp | 2 | ||||
-rw-r--r-- | qt-models/divetripmodel.cpp | 11 | ||||
-rw-r--r-- | qt-models/filtermodels.cpp | 4 |
9 files changed, 63 insertions, 80 deletions
diff --git a/core/dive.h b/core/dive.h index 07223322f..790d39d7f 100644 --- a/core/dive.h +++ b/core/dive.h @@ -286,13 +286,18 @@ typedef enum { NUM_TRIPFLAGS } tripflag_t; +struct dive_table { + int nr, allocated; + struct dive **dives; +}; + typedef struct dive_trip { timestamp_t when; char *location; char *notes; - struct dive *dives; - int nrdives, showndives; + struct dive_table dives; + int showndives; /* Used by the io-routines to mark trips that have already been written. */ bool saved; bool autogen; @@ -306,7 +311,6 @@ struct dive { int number; tripflag_t tripflag; dive_trip_t *divetrip; - struct dive *next, **pprev; bool selected; bool hidden_by_filter; timestamp_t when; @@ -428,11 +432,6 @@ extern const struct units SI_units, IMPERIAL_units; extern const struct units *get_units(void); extern int run_survey, verbose, quit, force_root; -struct dive_table { - int nr, allocated; - struct dive **dives; -}; - extern struct dive_table dive_table, downloadTable; extern struct dive displayed_dive; extern unsigned int dc_number; diff --git a/core/divelist.c b/core/divelist.c index 986257c4f..48b54ea66 100644 --- a/core/divelist.c +++ b/core/divelist.c @@ -476,6 +476,15 @@ static void add_dive_to_deco(struct deco_state *ds, struct dive *dive) } } +static int get_idx_in_table(const struct dive_table *table, const struct dive *dive) +{ + for (int i = 0; i < table->nr; ++i) { + if (table->dives[i] == dive) + return i; + } + return -1; +} + int get_divenr(const struct dive *dive) { int i; @@ -735,7 +744,7 @@ void dump_trip_list(void) trip->autogen ? "autogen " : "", ++i, trip->location, tm.tm_year, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, - trip->nrdives, trip); + trip->dives.nr, trip); last_time = trip->when; } printf("-----\n"); @@ -775,7 +784,7 @@ void unregister_trip(dive_trip_t *trip) { dive_trip_t **p, *tmp; - assert(!trip->dives); + assert(!trip->dives.nr); /* Remove the trip from the list of trips */ p = &dive_trip_list; @@ -796,14 +805,7 @@ static void delete_trip(dive_trip_t *trip) void find_new_trip_start_time(dive_trip_t *trip) { - struct dive *dive = trip->dives; - timestamp_t when = dive->when; - - while ((dive = dive->next) != NULL) { - if (dive->when < when) - when = dive->when; - } - trip->when = when; + trip->when = trip->dives.nr > 0 ? trip->dives.dives[0]->when : 0; } /* check if we have a trip right before / after this dive */ @@ -844,33 +846,35 @@ struct dive *last_selected_dive() return ret; } +static void unregister_dive_from_table(struct dive_table *table, int idx) +{ + int i; + for (i = idx; i < table->nr - 1; i++) + table->dives[i] = table->dives[i + 1]; + table->dives[--table->nr] = NULL; +} + /* remove a dive from the trip it's associated to, but don't delete the * trip if this was the last dive in the trip. the caller is responsible - * for removing the trip, if the trip->nrdives went to 0. + * for removing the trip, if the trip->dives.nr went to 0. */ struct dive_trip *unregister_dive_from_trip(struct dive *dive, short was_autogen) { - struct dive *next, **pprev; dive_trip_t *trip = dive->divetrip; + int idx; if (!trip) return NULL; - /* Remove the dive from the trip's list of dives */ - next = dive->next; - pprev = dive->pprev; - *pprev = next; - if (next) - next->pprev = pprev; - + idx = get_idx_in_table(&trip->dives, dive); + if (idx) + unregister_dive_from_table(&trip->dives, idx); dive->divetrip = NULL; if (was_autogen) dive->tripflag = TF_NONE; else dive->tripflag = NO_TRIP; - assert(trip->nrdives > 0); - --trip->nrdives; - if (trip->nrdives > 0 && trip->when == dive->when) + if (trip->dives.nr > 0 && trip->when == dive->when) find_new_trip_start_time(trip); return trip; } @@ -878,7 +882,7 @@ struct dive_trip *unregister_dive_from_trip(struct dive *dive, short was_autogen void remove_dive_from_trip(struct dive *dive, short was_autogen) { struct dive_trip *trip = unregister_dive_from_trip(dive, was_autogen); - if (trip && trip->nrdives == 0) + if (trip && trip->dives.nr == 0) delete_trip(trip); } @@ -887,20 +891,9 @@ void add_dive_to_trip(struct dive *dive, dive_trip_t *trip) if (dive->divetrip == trip) return; remove_dive_from_trip(dive, false); - trip->nrdives++; - trip->showndives++; + add_dive_to_table(&trip->dives, -1, dive); dive->divetrip = trip; dive->tripflag = ASSIGNED_TRIP; - - /* Add it to the trip's list of dives*/ - dive->next = trip->dives; - if (dive->next) - dive->next->pprev = &dive->next; - trip->dives = dive; - dive->pprev = &trip->dives; - - if (dive->when && trip->when > dive->when) - trip->when = dive->when; } dive_trip_t *alloc_trip(void) @@ -1036,7 +1029,7 @@ void autogroup_dives(void) if (!autogroup) return; - for(i = 0; (trip = get_dives_to_autogroup(i, &from, &to, &alloc)) != NULL; i = to) { + for (i = 0; (trip = get_dives_to_autogroup(i, &from, &to, &alloc)) != NULL; i = to) { /* If this was newly allocated, add trip to list */ if (alloc) insert_trip(trip); @@ -1048,14 +1041,6 @@ void autogroup_dives(void) #endif } -static void unregister_dive_from_table(struct dive_table *table, int idx) -{ - int i; - for (i = idx; i < table->nr - 1; i++) - table->dives[i] = table->dives[i + 1]; - table->dives[--table->nr] = NULL; -} - /* Remove a dive from a dive table. This assumes that the * dive was already removed from any trip and deselected. * It simply shrinks the table and frees the trip */ @@ -1298,11 +1283,10 @@ void deselect_dive(struct dive *dive) void deselect_dives_in_trip(struct dive_trip *trip) { - struct dive *dive; if (!trip) return; - for (dive = trip->dives; dive; dive = dive->next) - deselect_dive(dive); + for (int i = 0; i < trip->dives.nr; ++i) + deselect_dive(trip->dives.dives[i]); } void select_dives_in_trip(struct dive_trip *trip) @@ -1310,9 +1294,11 @@ void select_dives_in_trip(struct dive_trip *trip) struct dive *dive; if (!trip) return; - for (dive = trip->dives; dive; dive = dive->next) + for (int i = 0; i < trip->dives.nr; ++i) { + dive = trip->dives.dives[i]; if (!dive->hidden_by_filter) select_dive(dive); + } } void filter_dive(struct dive *d, bool shown) @@ -1340,8 +1326,8 @@ void combine_trips(struct dive_trip *trip_a, struct dive_trip *trip_b) } /* this also removes the dives from trip_b and eventually * calls delete_trip(trip_b) when the last dive has been moved */ - while (trip_b->dives) - add_dive_to_trip(trip_b->dives, trip_a); + while (trip_b->dives.nr > 0) + add_dive_to_trip(trip_b->dives.dives[0], trip_a); } /* Out of two strings, copy the string that is not empty (if any). */ diff --git a/core/save-html.c b/core/save-html.c index ea46d49ea..ec5751453 100644 --- a/core/save-html.c +++ b/core/save-html.c @@ -408,7 +408,8 @@ void write_trip(struct membuffer *b, dive_trip_t *trip, int *dive_no, bool selec char *separator = ""; bool found_sel_dive = 0; - for (dive = trip->dives; dive != NULL; dive = dive->next) { + for (int i = 0; i < trip->dives.nr; i++) { + dive = trip->dives.dives[i]; if (!dive->selected && selected_only) continue; diff --git a/core/subsurface-qt/DiveObjectHelper.cpp b/core/subsurface-qt/DiveObjectHelper.cpp index 41d4cebd9..b254ed13f 100644 --- a/core/subsurface-qt/DiveObjectHelper.cpp +++ b/core/subsurface-qt/DiveObjectHelper.cpp @@ -350,7 +350,7 @@ QString DiveObjectHelper::tripMeta() const if (title.isEmpty()) { // so use the date range QString firstYear = firstTime.toString("yyyy"); - QDateTime lastTime = QDateTime::fromMSecsSinceEpoch(1000*dt->dives->when, Qt::UTC); + QDateTime lastTime = QDateTime::fromMSecsSinceEpoch(1000*dt->dives.dives[0]->when, Qt::UTC); QString lastMonth = lastTime.toString("MMM"); QString lastYear = lastTime.toString("yyyy"); if (lastMonth == firstMonth && lastYear == firstYear) @@ -368,7 +368,7 @@ QString DiveObjectHelper::tripMeta() const int DiveObjectHelper::tripNrDives() const { struct dive_trip *dt = m_dive->divetrip; - return dt ? dt->nrdives : 0; + return dt ? dt->dives.nr : 0; } int DiveObjectHelper::maxcns() const diff --git a/desktop-widgets/command_divelist.cpp b/desktop-widgets/command_divelist.cpp index 3d1aae2e7..d5fbc2139 100644 --- a/desktop-widgets/command_divelist.cpp +++ b/desktop-widgets/command_divelist.cpp @@ -66,7 +66,7 @@ DiveToAdd DiveListBase::removeDive(struct dive *d) // remove dive from trip - if this is the last dive in the trip // remove the whole trip. res.trip = unregister_dive_from_trip(d, false); - if (res.trip && res.trip->nrdives == 0) { + if (res.trip && res.trip->dives.nr == 0) { unregister_trip(res.trip); // Remove trip from backend res.tripToAdd.reset(res.trip); // Take ownership of trip } @@ -231,7 +231,7 @@ static OwningTripPtr moveDiveToTrip(DiveToTrip &diveToTrip) // Remove dive from trip - if this is the last dive in the trip, remove the whole trip. dive_trip *trip = unregister_dive_from_trip(diveToTrip.dive, false); - if (trip && trip->nrdives == 0) { + if (trip && trip->dives.nr == 0) { unregister_trip(trip); // Remove trip from backend res.reset(trip); } @@ -737,10 +737,10 @@ MergeTrips::MergeTrips(dive_trip *trip1, dive_trip *trip2) return; dive_trip *newTrip = combine_trips_create(trip1, trip2); divesToMove.tripsToAdd.emplace_back(newTrip); - for (dive *d = trip1->dives; d; d = d->next) - divesToMove.divesToMove.push_back( { d, newTrip } ); - for (dive *d = trip2->dives; d; d = d->next) - divesToMove.divesToMove.push_back( { d, newTrip } ); + for (int i = 0; i < trip1->dives.nr; ++i) + divesToMove.divesToMove.push_back( { trip1->dives.dives[i], newTrip } ); + for (int i = 0; i < trip2->dives.nr; ++i) + divesToMove.divesToMove.push_back( { trip2->dives.dives[i], newTrip } ); } SplitDives::SplitDives(dive *d, duration_t time) diff --git a/mobile-widgets/qmlmanager.cpp b/mobile-widgets/qmlmanager.cpp index 8bae01d86..cc98286a2 100644 --- a/mobile-widgets/qmlmanager.cpp +++ b/mobile-widgets/qmlmanager.cpp @@ -1275,8 +1275,6 @@ bool QMLManager::undoDelete(int id) struct dive_trip *trip = deletedDive->divetrip; tripflag_t tripflag = deletedDive->tripflag; // this gets overwritten in add_dive_to_trip() deletedDive->divetrip = NULL; - deletedDive->next = NULL; - deletedDive->pprev = NULL; add_dive_to_trip(deletedDive, trip); deletedDive->tripflag = tripflag; } @@ -1309,11 +1307,11 @@ void QMLManager::deleteDive(int id) memset(deletedTrip, 0, sizeof(struct dive_trip)); } // if this is the last dive in that trip, remember the trip as well - if (d->divetrip && d->divetrip->nrdives == 1) { + if (d->divetrip && d->divetrip->dives.nr == 1) { *deletedTrip = *d->divetrip; deletedTrip->location = copy_string(d->divetrip->location); deletedTrip->notes = copy_string(d->divetrip->notes); - deletedTrip->nrdives = 0; + deletedTrip->dives.nr = 0; deletedDive->divetrip = deletedTrip; } DiveListModel::instance()->removeDiveById(id); diff --git a/qt-models/divelistmodel.cpp b/qt-models/divelistmodel.cpp index 75eb9137a..b12786fa9 100644 --- a/qt-models/divelistmodel.cpp +++ b/qt-models/divelistmodel.cpp @@ -100,7 +100,7 @@ void DiveListSortModel::updateDivesShownInTrips() struct dive_trip *dt = dive_trip_list; int rc = rowCount(); while (dt) { - dt->showndives = rc ? 0 : dt->nrdives; + dt->showndives = rc ? 0 : dt->dives.nr; dt = dt->next; } for (int i = 0; i < rowCount(); i++) { diff --git a/qt-models/divetripmodel.cpp b/qt-models/divetripmodel.cpp index 7c5bb4efb..6eadbbb24 100644 --- a/qt-models/divetripmodel.cpp +++ b/qt-models/divetripmodel.cpp @@ -57,20 +57,19 @@ QVariant DiveTripModel::tripData(const dive_trip *trip, int column, int role) switch (column) { case DiveTripModel::NR: QString shownText; - struct dive *d = trip->dives; int countShown = 0; - while (d) { + for (int i = 0; i < trip->dives.nr; ++i) { + struct dive *d = trip->dives.dives[i]; if (!d->hidden_by_filter) countShown++; oneDayTrip &= is_same_day (trip->when, d->when); - d = d->next; } - if (countShown < trip->nrdives) + if (countShown < trip->dives.nr) shownText = tr("(%1 shown)").arg(countShown); if (!empty_string(trip->location)) - return QString(trip->location) + ", " + get_trip_date_string(trip->when, trip->nrdives, oneDayTrip) + " "+ shownText; + return QString(trip->location) + ", " + get_trip_date_string(trip->when, trip->dives.nr, oneDayTrip) + " "+ shownText; else - return get_trip_date_string(trip->when, trip->nrdives, oneDayTrip) + shownText; + return get_trip_date_string(trip->when, trip->dives.nr, oneDayTrip) + shownText; } } diff --git a/qt-models/filtermodels.cpp b/qt-models/filtermodels.cpp index d335d3f7c..d485684f3 100644 --- a/qt-models/filtermodels.cpp +++ b/qt-models/filtermodels.cpp @@ -634,8 +634,8 @@ bool MultiFilterSortModel::filterAcceptsRow(int source_row, const QModelIndex &s return false; // Oops. Neither dive nor trip, something is seriously wrong. // Show the trip if any dive is visible - for (d = trip->dives; d; d = d->next) { - if (!d->hidden_by_filter) + for (int i = 0; i < trip->dives.nr; ++i) { + if (!trip->dives.dives[i]->hidden_by_filter) return true; } return false; |