mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
Dive list: unify sorting in core and Qt-model
Ultimately, we want to use a single dive-list and not replicate it in the Qt-model code. To this goal, let's start with using the same sort function. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
parent
0cca36377b
commit
f836b9ae97
4 changed files with 58 additions and 7 deletions
|
@ -563,6 +563,7 @@ extern struct sample *add_sample(const struct sample *sample, int time, struct d
|
|||
extern void add_sample_pressure(struct sample *sample, int sensor, int mbar);
|
||||
extern int legacy_format_o2pressures(const struct dive *dive, const struct divecomputer *dc);
|
||||
|
||||
extern bool dive_less_than(const struct dive *a, const struct dive *b);
|
||||
extern void sort_table(struct dive_table *table);
|
||||
extern struct dive *fixup_dive(struct dive *dive);
|
||||
extern void fixup_dc_duration(struct divecomputer *dc);
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
* void mark_divelist_changed(int changed)
|
||||
* int unsaved_changes()
|
||||
* void remove_autogen_trips()
|
||||
* bool dive_less_than(const struct dive *a, const struct dive *b)
|
||||
* void sort_table(struct dive_table *table)
|
||||
* bool is_trip_before_after(const struct dive *dive, bool before)
|
||||
<<<<<<< HEAD
|
||||
|
@ -1682,16 +1683,42 @@ void clear_dive_file_data()
|
|||
saved_git_id = "";
|
||||
}
|
||||
|
||||
static int sortfn(const void *_a, const void *_b)
|
||||
/* This function defines the sort ordering of dives. The core
|
||||
* and the UI models should use the same sort function, which
|
||||
* should be stable. This is not crucial at the moment, as the
|
||||
* indices in core and UI are independent, but ultimately we
|
||||
* probably want to unify the models.
|
||||
* After editing a key used in this sort-function, the order of
|
||||
* the dives must be re-astablished.
|
||||
* Currently, this does a lexicographic sort on the (start-time, id)
|
||||
* tuple. "id" is a stable, strictly increasing unique number, that
|
||||
* is handed out when a dive is added to the system.
|
||||
* We might also consider sorting by end-time and other criteria,
|
||||
* but see the caveat above (editing means rearrangement of the dives).
|
||||
*/
|
||||
static int comp_dives(const struct dive *a, const struct dive *b)
|
||||
{
|
||||
const struct dive *a = (const struct dive *)*(void **)_a;
|
||||
const struct dive *b = (const struct dive *)*(void **)_b;
|
||||
|
||||
if (a->when < b->when)
|
||||
return -1;
|
||||
if (a->when > b->when)
|
||||
return 1;
|
||||
return 0;
|
||||
if (a->id < b->id)
|
||||
return -1;
|
||||
if (a->id > b->id)
|
||||
return 1;
|
||||
return 0; /* this should not happen for a != b */
|
||||
}
|
||||
|
||||
bool dive_less_than(const struct dive *a, const struct dive *b)
|
||||
{
|
||||
return comp_dives(a, b) < 0;
|
||||
}
|
||||
|
||||
static int sortfn(const void *_a, const void *_b)
|
||||
{
|
||||
const struct dive *a = (const struct dive *)*(const void **)_a;
|
||||
const struct dive *b = (const struct dive *)*(const void **)_b;
|
||||
return comp_dives(a, b);
|
||||
}
|
||||
|
||||
void sort_table(struct dive_table *table)
|
||||
|
|
|
@ -926,7 +926,7 @@ void DiveTripModel::addDivesToTrip(int trip, const QVector<dive *> &dives)
|
|||
// Either this is outside of a trip or we're in list mode.
|
||||
// Thus, add dives at the top-level in batches
|
||||
addInBatches(items[trip].dives, dives,
|
||||
[](dive *d, dive *d2) { return d->when >= d2->when; }, // comp
|
||||
[](dive *d, dive *d2) { return !dive_less_than(d, d2); }, // comp
|
||||
[&](std::vector<dive *> &items, const QVector<dive *> &dives, int idx, int from, int to) { // inserter
|
||||
beginInsertRows(parent, idx, idx + to - from - 1);
|
||||
items.insert(items.begin() + idx, dives.begin() + from, dives.begin() + to);
|
||||
|
@ -934,6 +934,19 @@ void DiveTripModel::addDivesToTrip(int trip, const QVector<dive *> &dives)
|
|||
});
|
||||
}
|
||||
|
||||
// This function is used to compare a dive to an arbitrary entry (dive or trip).
|
||||
// For comparing two dives, use the core function dive_less_than_entry, which
|
||||
// effectively sorts by timestamp.
|
||||
// If comparing to a trip, the policy for equal-times is to place the dives
|
||||
// before the trip in the case of equal timestamps.
|
||||
bool DiveTripModel::dive_before_entry(const dive *d, const Item &entry)
|
||||
{
|
||||
// Dives at the same time come before trips, therefore use the "<=" operator.
|
||||
if (entry.trip)
|
||||
return d->when <= entry.trip->when;
|
||||
return !dive_less_than(d, entry.getDive());
|
||||
}
|
||||
|
||||
void DiveTripModel::divesAdded(dive_trip *trip, bool addTrip, const QVector<dive *> &divesIn)
|
||||
{
|
||||
// The dives come from the backend sorted by start-time. But our model is sorted
|
||||
|
@ -946,7 +959,7 @@ void DiveTripModel::divesAdded(dive_trip *trip, bool addTrip, const QVector<dive
|
|||
// Either this is outside of a trip or we're in list mode.
|
||||
// Thus, add dives at the top-level in batches
|
||||
addInBatches(items, dives,
|
||||
[](dive *d, const Item &entry) { return d->when >= entry.when(); }, // comp
|
||||
&dive_before_entry, // comp
|
||||
[&](std::vector<Item> &items, const QVector<dive *> &dives, int idx, int from, int to) { // inserter
|
||||
beginInsertRows(QModelIndex(), idx, idx + to - from - 1);
|
||||
items.insert(items.begin() + idx, dives.begin() + from, dives.begin() + to);
|
||||
|
|
|
@ -138,6 +138,14 @@ private:
|
|||
// quite inconvenient to access.
|
||||
// 2) If "trip" is null, this is a dive and dives is supposed to contain exactly
|
||||
// one element, which is the corresponding dive.
|
||||
//
|
||||
// Top-level items are ordered by timestamp. For dives, the core function
|
||||
// dive_less_than is used, which guarantees a stable ordering even in the
|
||||
// case of equal timestamps. For dives and trips, place dives before trips
|
||||
// in the case of an equal timestamp. For trips with equal timestamps, the
|
||||
// order is currently undefined. This is currently not a problem, because
|
||||
// the core doesn't have a list of sorted trips. But nevertheless something
|
||||
// to keep in mind.
|
||||
struct Item {
|
||||
dive_trip *trip;
|
||||
std::vector<dive *> dives; // std::vector<> instead of QVector for insert() with three iterators
|
||||
|
@ -148,6 +156,8 @@ private:
|
|||
dive *getDive() const; // Helper function: returns top-level-dive or null
|
||||
timestamp_t when() const; // Helper function: start time of dive *or* trip
|
||||
};
|
||||
// Comparison function between dive and arbitrary entry
|
||||
static bool dive_before_entry(const dive *d, const Item &entry);
|
||||
|
||||
// Access trips and dives
|
||||
int findTripIdx(const dive_trip *trip) const;
|
||||
|
|
Loading…
Add table
Reference in a new issue