summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Berthold Stoeger <bstoeger@mail.tuwien.ac.at>2018-11-08 16:58:33 +0100
committerGravatar Dirk Hohndel <dirk@hohndel.org>2018-11-18 16:50:09 -0800
commit6b283e598a3a08c6133d66b5d5617370296e7d0e (patch)
tree685ccf1fd839d72471b179bf12aa72d2bdcec7de
parentbc7afebc23477ef23f2b9741bf45b2180cbafe15 (diff)
downloadsubsurface-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.h15
-rw-r--r--core/divelist.c86
-rw-r--r--core/save-html.c3
-rw-r--r--core/subsurface-qt/DiveObjectHelper.cpp4
-rw-r--r--desktop-widgets/command_divelist.cpp12
-rw-r--r--mobile-widgets/qmlmanager.cpp6
-rw-r--r--qt-models/divelistmodel.cpp2
-rw-r--r--qt-models/divetripmodel.cpp11
-rw-r--r--qt-models/filtermodels.cpp4
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;