summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--divelist.c170
1 files changed, 56 insertions, 114 deletions
diff --git a/divelist.c b/divelist.c
index 82ef339d8..b31c9ac25 100644
--- a/divelist.c
+++ b/divelist.c
@@ -217,118 +217,6 @@ void row_collapsed_cb(GtkTreeView *tree_view, GtkTreeIter *iter, GtkTreePath *pa
gtk_tree_selection_select_iter(selection, iter);
}
-static GList *selection_changed = NULL;
-
-/*
- * This is called _before_ the selection is changed, for every single entry;
- *
- * We simply create a list of all changed entries, and make sure that the
- * group entries go at the end of the list.
- */
-gboolean modify_selection_cb(GtkTreeSelection *selection, GtkTreeModel *model,
- GtkTreePath *path, gboolean was_selected, gpointer userdata)
-{
- GtkTreeIter iter, *p;
-
- if (!gtk_tree_model_get_iter(model, &iter, path))
- return TRUE;
-
- /* Add the group entries to the end */
- p = gtk_tree_iter_copy(&iter);
- if (gtk_tree_model_iter_has_child(model, p))
- selection_changed = g_list_append(selection_changed, p);
- else
- selection_changed = g_list_prepend(selection_changed, p);
- return TRUE;
-}
-
-static void select_dive(struct dive *dive, int selected)
-{
- if (dive->selected != selected) {
- amount_selected += selected ? 1 : -1;
- dive->selected = selected;
- }
-}
-
-/*
- * This gets called when a dive group has changed selection.
- */
-static void select_dive_group(GtkTreeModel *model, GtkTreeSelection *selection, GtkTreeIter *iter, int selected)
-{
- int first = 1;
- GtkTreeIter child;
-
- if (selected == selected_children(model, iter))
- return;
-
- if (!gtk_tree_model_iter_children(model, &child, iter))
- return;
-
- do {
- int idx;
- struct dive *dive;
-
- gtk_tree_model_get(model, &child, DIVE_INDEX, &idx, -1);
- if (first && selected)
- selected_dive = idx;
- first = 0;
- dive = get_dive(idx);
- if (dive->selected == selected)
- continue;
-
- select_dive(dive, selected);
- if (selected)
- gtk_tree_selection_select_iter(selection, &child);
- else
- gtk_tree_selection_unselect_iter(selection, &child);
- } while (gtk_tree_model_iter_next(model, &child));
-}
-
-/*
- * This gets called _after_ the selections have changed, for each entry that
- * may have changed. Check if the gtk selection state matches our internal
- * selection state to verify.
- *
- * The group entries are at the end, this guarantees that we have handled
- * all the dives before we handle groups.
- */
-static void check_selection_cb(GtkTreeIter *iter, GtkTreeSelection *selection)
-{
- GtkTreeModel *model = MODEL(dive_list);
- struct dive *dive;
- int idx, gtk_selected;
-
- gtk_tree_model_get(model, iter,
- DIVE_INDEX, &idx,
- -1);
- dive = get_dive(idx);
- gtk_selected = gtk_tree_selection_iter_is_selected(selection, iter);
- if (idx < 0)
- select_dive_group(model, selection, iter, gtk_selected);
- else {
- select_dive(dive, gtk_selected);
- if (gtk_selected)
- selected_dive = idx;
- }
- gtk_tree_iter_free(iter);
-}
-
-/* this is called when gtk thinks that the selection has changed */
-static void selection_cb(GtkTreeSelection *selection, GtkTreeModel *model)
-{
- GList *changed = selection_changed;
-
- selection_changed = NULL;
- g_list_foreach(changed, (GFunc) check_selection_cb, selection);
- g_list_free(changed);
-#if DEBUG_SELECTION_TRACKING
- dump_selection();
-#endif
-
- process_selected_dives();
- repaint_dive();
-}
-
const char *star_strings[] = {
ZERO_STARS,
ONE_STARS,
@@ -2707,6 +2595,62 @@ static void sort_column_change_cb(GtkTreeSortable *treeview, gpointer data)
}
}
+static void select_dive(struct dive *dive)
+{
+ if (dive && !dive->selected) {
+ dive->selected = 1;
+ amount_selected++;
+ }
+}
+
+/* This gets called for each selected entry after a selection has changed */
+static void entry_selected(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
+{
+ int idx;
+ timestamp_t when;
+
+ gtk_tree_model_get(model, iter, DIVE_INDEX, &idx, DIVE_DATE, &when, -1);
+ if (idx < 0) {
+ int i;
+ struct dive *dive;
+ dive_trip_t *trip = find_trip_by_time(when);
+
+ if (!trip)
+ return;
+ trip->selected = 1;
+ /* If this is expanded, let the gtk selection happen for each dive under it */
+ if (gtk_tree_view_row_expanded(GTK_TREE_VIEW(dive_list.tree_view), path))
+ return;
+ /* Otherwise, consider each dive under it selected */
+ for_each_dive(i, dive) {
+ if (dive->divetrip == trip)
+ select_dive(dive);
+ }
+ } else {
+ select_dive(get_dive(idx));
+ }
+}
+
+/* this is called when gtk thinks that the selection has changed */
+static void selection_cb(GtkTreeSelection *selection, GtkTreeModel *model)
+{
+ int i;
+ struct dive *dive;
+
+ amount_selected = 0;
+ for_each_dive(i, dive)
+ dive->selected = 0;
+
+ gtk_tree_selection_selected_foreach(selection, entry_selected, model);
+
+#if DEBUG_SELECTION_TRACKING
+ dump_selection();
+#endif
+
+ process_selected_dives();
+ repaint_dive();
+}
+
GtkWidget *dive_list_create(void)
{
GtkTreeSelection *selection;
@@ -2794,8 +2738,6 @@ GtkWidget *dive_list_create(void)
g_signal_connect(dive_list.listmodel, "sort-column-changed", G_CALLBACK(sort_column_change_cb), NULL);
g_signal_connect(dive_list.treemodel, "sort-column-changed", G_CALLBACK(sort_column_change_cb), NULL);
- gtk_tree_selection_set_select_function(selection, modify_selection_cb, NULL, NULL);
-
dive_list.container_widget = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(dive_list.container_widget),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);