diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/dive.h | 3 | ||||
-rw-r--r-- | core/divelist.c | 82 | ||||
-rw-r--r-- | core/divelist.h | 5 | ||||
-rw-r--r-- | core/profile.c | 2 | ||||
-rw-r--r-- | core/subsurface-qt/DiveListNotifier.h | 19 |
5 files changed, 78 insertions, 33 deletions
diff --git a/core/dive.h b/core/dive.h index 3077c5bce..48cbaa740 100644 --- a/core/dive.h +++ b/core/dive.h @@ -440,9 +440,8 @@ struct dive_table { extern struct dive_table dive_table, downloadTable; extern struct dive displayed_dive; extern struct dive_site displayed_dive_site; -extern int selected_dive; extern unsigned int dc_number; -#define current_dive (get_dive(selected_dive)) +extern struct dive *current_dive; #define current_dc (get_dive_dc(current_dive, dc_number)) #define displayed_dc (get_dive_dc(&displayed_dive, dc_number)) diff --git a/core/divelist.c b/core/divelist.c index 1c6ad9fc0..72685b40f 100644 --- a/core/divelist.c +++ b/core/divelist.c @@ -32,14 +32,18 @@ * void delete_single_dive(int idx) * void add_single_dive(int idx, struct dive *dive) * struct dive *merge_two_dives(struct dive *a, struct dive *b) - * void select_dive(int idx) - * void deselect_dive(int idx) + * void select_dive(struct dive *dive) + * void deselect_dive(struct dive *dive) * void mark_divelist_changed(int changed) * int unsaved_changes() * void remove_autogen_trips() * void sort_table(struct dive_table *table) * bool is_trip_before_after(const struct dive *dive, bool before) +<<<<<<< HEAD * void delete_dive_from_table(struct dive_table *table, int idx) +======= + * int find_next_visible_dive(timestamp_t when); +>>>>>>> Undo: select dives after add, remove, merge, split dive commands */ #include <unistd.h> #include <stdio.h> @@ -1058,7 +1062,8 @@ void delete_dive_from_table(struct dive_table *table, int idx) /* this removes a dive from the dive table and trip-list but doesn't * free the resources associated with the dive. It returns a pointer - * to the unregistered dive. */ + * to the unregistered dive. The returned dive has the selection- + * and hidden-flags cleared. */ struct dive *unregister_dive(int idx) { struct dive *dive = get_dive(idx); @@ -1068,6 +1073,7 @@ struct dive *unregister_dive(int idx) unregister_dive_from_table(&dive_table, idx); if (dive->selected) amount_selected--; + dive->selected = false; return dive; } @@ -1079,7 +1085,7 @@ void delete_single_dive(int idx) if (!dive) return; /* this should never happen */ if (dive->selected) - deselect_dive(idx); + deselect_dive(dive); dive = unregister_dive(idx); free_dive(dive); } @@ -1104,6 +1110,7 @@ struct dive **grow_dive_table(struct dive_table *table) * ordered reverse-chronologically */ int dive_get_insertion_index(struct dive *dive) { + /* we might want to use binary search here */ for (int i = 0; i < dive_table.nr; i++) { if (dive->when <= dive_table.dives[i]->when) return i; @@ -1235,42 +1242,42 @@ struct dive *merge_two_dives(struct dive *a, struct dive *b) return res; } -void select_dive(int idx) +void select_dive(struct dive *dive) { - struct dive *dive = get_dive(idx); - if (dive) { - /* never select an invalid dive that isn't displayed */ - if (!dive->selected) { - dive->selected = 1; - amount_selected++; - } - selected_dive = idx; + if (dive && !dive->selected) { + dive->selected = 1; + amount_selected++; + current_dive = dive; } } -void deselect_dive(int idx) +void deselect_dive(struct dive *dive) { - struct dive *dive = get_dive(idx); + int idx; if (dive && dive->selected) { dive->selected = 0; if (amount_selected) amount_selected--; - if (selected_dive == idx && amount_selected > 0) { + if (current_dive == dive && amount_selected > 0) { /* pick a different dive as selected */ + int selected_dive = idx = get_divenr(dive); while (--selected_dive >= 0) { dive = get_dive(selected_dive); - if (dive && dive->selected) + if (dive && dive->selected) { + current_dive = dive; return; + } } selected_dive = idx; while (++selected_dive < dive_table.nr) { dive = get_dive(selected_dive); - if (dive && dive->selected) + if (dive && dive->selected) { + current_dive = dive; return; + } } } - if (amount_selected == 0) - selected_dive = -1; + current_dive = NULL; } } @@ -1280,7 +1287,7 @@ void deselect_dives_in_trip(struct dive_trip *trip) if (!trip) return; for (dive = trip->dives; dive; dive = dive->next) - deselect_dive(get_divenr(dive)); + deselect_dive(dive); } void select_dives_in_trip(struct dive_trip *trip) @@ -1290,7 +1297,7 @@ void select_dives_in_trip(struct dive_trip *trip) return; for (dive = trip->dives; dive; dive = dive->next) if (!dive->hidden_by_filter) - select_dive(get_divenr(dive)); + select_dive(dive); } void filter_dive(struct dive *d, bool shown) @@ -1299,7 +1306,7 @@ void filter_dive(struct dive *d, bool shown) return; d->hidden_by_filter = !shown; if (!shown && d->selected) - deselect_dive(get_divenr(d)); + deselect_dive(d); } @@ -1610,6 +1617,7 @@ int get_dive_nr_at_idx(int idx) void set_dive_nr_for_current_dive() { + int selected_dive = get_divenr(current_dive); if (dive_table.nr == 1) current_dive->number = 1; else if (selected_dive == dive_table.nr - 1 && get_dive(dive_table.nr - 2)->number) @@ -1719,3 +1727,31 @@ timestamp_t get_surface_interval(timestamp_t when) return 0; return when - prev_end; } + +/* Find visible dive close to given date. First search towards older, + * then newer dives. */ +struct dive *find_next_visible_dive(timestamp_t when) +{ + int i, j; + + if (!dive_table.nr) + return NULL; + + /* we might want to use binary search here */ + for (i = 0; i < dive_table.nr; i++) { + if (when <= get_dive(i)->when) + break; + } + + for (j = i - 1; j > 0; j--) { + if (!get_dive(j)->hidden_by_filter) + return get_dive(j); + } + + for (j = i; j < dive_table.nr; j++) { + if (!get_dive(j)->hidden_by_filter) + return get_dive(j); + } + + return NULL; +} diff --git a/core/divelist.h b/core/divelist.h index 9449e36e2..a99394d5c 100644 --- a/core/divelist.h +++ b/core/divelist.h @@ -36,8 +36,8 @@ extern dive_trip_t *get_trip_for_new_dive(struct dive *new_dive, bool *allocated extern void autogroup_dives(void); extern struct dive *merge_two_dives(struct dive *a, struct dive *b); extern bool consecutive_selected(); -extern void select_dive(int idx); -extern void deselect_dive(int idx); +extern void select_dive(struct dive *dive); +extern void deselect_dive(struct dive *dive); extern void select_dives_in_trip(struct dive_trip *trip); extern void deselect_dives_in_trip(struct dive_trip *trip); extern void filter_dive(struct dive *d, bool shown); @@ -51,6 +51,7 @@ extern int get_dive_nr_at_idx(int idx); extern void set_dive_nr_for_current_dive(); extern timestamp_t get_surface_interval(timestamp_t when); extern void delete_dive_from_table(struct dive_table *table, int idx); +extern struct dive *find_next_visible_dive(timestamp_t when); int get_min_datafile_version(); void reset_min_datafile_version(); diff --git a/core/profile.c b/core/profile.c index af7ebe271..84c77d68b 100644 --- a/core/profile.c +++ b/core/profile.c @@ -27,7 +27,7 @@ #define MAX_PROFILE_DECO 7200 -int selected_dive = -1; /* careful: 0 is a valid value */ +struct dive *current_dive = NULL; unsigned int dc_number = 0; static struct plot_data *last_pi_entry_new = NULL; diff --git a/core/subsurface-qt/DiveListNotifier.h b/core/subsurface-qt/DiveListNotifier.h index fe5ea0e22..35ecf108d 100644 --- a/core/subsurface-qt/DiveListNotifier.h +++ b/core/subsurface-qt/DiveListNotifier.h @@ -17,10 +17,10 @@ signals: // Note that there are no signals for trips being added / created / time-shifted, // because these events never happen without a dive being added / created / time-shifted. - // We send one divesAdded, divesDeleted, divesChanged and divesTimeChanged signal per trip - // (non-associated dives being considered part of the null trip). This is ideal for the - // tree-view, but might be not-so-perfect for the list view, if trips intermingle or - // the deletion spans multiple trips. But most of the time only dives of a single trip + // We send one divesAdded, divesDeleted, divesChanged and divesTimeChanged, divesSelected + // signal per trip (non-associated dives being considered part of the null trip). This is + // ideal for the tree-view, but might be not-so-perfect for the list view, if trips intermingle + // or the deletion spans multiple trips. But most of the time only dives of a single trip // will be affected and trips don't overlap, so these considerations are moot. // Notes: // - The dives are always sorted by start-time. @@ -31,7 +31,16 @@ signals: void divesMovedBetweenTrips(dive_trip *from, dive_trip *to, bool deleteFrom, bool createTo, const QVector<dive *> &dives); void divesTimeChanged(dive_trip *trip, timestamp_t delta, const QVector<dive *> &dives); - // This signal is sent if the selection of dives and/or the current dive changed + // Selection-signals come in two kinds: + // - divesSelected, divesDeselected and currentDiveChanged are finer grained and are + // called batch-wise per trip (except currentDiveChanged, of course). These signals + // are used by the dive-list model and view to correctly highlight the correct dives. + // - selectionChanged() is called once at the end of commands if either the selection + // or the current dive changed. It is used by the main-window / profile to update + // their data. + void divesSelected(dive_trip *trip, const QVector<dive *> &dives); + void divesDeselected(dive_trip *trip, const QVector<dive *> &dives); + void currentDiveChanged(); void selectionChanged(); public: // Desktop uses the QTreeView class to present the list of dives. The layout |