[PATCH] Different logic for dive selection when trips are expanded

Lubomir I. Ivanov neolit123 at gmail.com
Mon Feb 18 15:34:18 PST 2013


From: "Lubomir I. Ivanov" <neolit123 at gmail.com>

Currently we don't have a good way to visually pre-select all dives
in a trip when a trip row is expanded, due to GTK "foreach" issues.
While we can still select all dives for processing, when a trip
is collapsed, there is no need for visual selection for these dives.
On the other hand we still need to show some profile and stats data
when a trip row is selected and expanded at the same time.

To do that we override row_collapsed_cb() and row_expanded_cb()
in a slightly different way. row_expanded_cb() now automatically
selects the first dive in trip, but only if that trip is selected.
On the other hand row_collapsed_cb() takes care of the child dives,
to be de-selected if the trip is not selected or selected if the trip
is selected but collapsing.

Signed-off-by: Lubomir I. Ivanov <neolit123 at gmail.com>
---

This is just an idea of a patch, which keeps the profile and statistics
better consistent for user interaction with a selected, expanded trip.
It pretty much maps the selection of the first dive in a trip to the trip
row (can be observed with the stats widget open).

What it doesn't do consistently is to keep the selected number of dives
in a trip the same when a trip is expanded or collapsed.

Say, if a trip has 4 dives, the selection forms as:
- when trip is collapsed:
0 visual (hidden), 4 for data (all dives)
- when trip is expanded:
0 visual, 1 for data (the first dive)

Also it does not preserve the selection of a dive, which is part of collapsing
trip.

---
 divelist.c | 94 ++++++++++++++++++++++++++++----------------------------------
 1 file changed, 43 insertions(+), 51 deletions(-)

diff --git a/divelist.c b/divelist.c
index b5fe48e..5bad8bf 100644
--- a/divelist.c
+++ b/divelist.c
@@ -72,6 +72,9 @@ enum {

 static void turn_dive_into_trip(GtkTreePath *path);
 static void merge_dive_into_trip_above_cb(GtkWidget *menuitem, GtkTreePath *path);
+static dive_trip_t *find_trip_by_time(timestamp_t when);
+static void select_dive(int idx);
+static void deselect_dive(int idx);

 #ifdef DEBUG_MODEL
 static gboolean dump_model_entry(GtkTreeModel *model, GtkTreePath *path,
@@ -161,60 +164,49 @@ static struct dive *dive_from_path(GtkTreePath *path)

 }

-/* make sure that if we expand a summary row that is selected, the children show
-   up as selected, too */
+/* on expanding a trip deselect all but the first dive */
 static void row_expanded_cb(GtkTreeView *tree_view, GtkTreeIter *iter, GtkTreePath *path, gpointer data)
 {
-	GtkTreeIter child;
-	GtkTreeModel *model = MODEL(dive_list);
-	GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dive_list.tree_view));
+	int i;
+	timestamp_t when;
+	struct dive *dive;

-	if (!gtk_tree_model_iter_children(model, &child, iter))
+	gtk_tree_model_get(MODEL(dive_list), iter, DIVE_DATE, &when, -1);
+	dive_trip_t *trip = find_trip_by_time(when);
+	if (!trip || !trip->selected)
 		return;
-
-	do {
-		int idx;
-		struct dive *dive;
-
-		gtk_tree_model_get(model, &child, DIVE_INDEX, &idx, -1);
-		dive = get_dive(idx);
-
-		if (dive->selected)
-			gtk_tree_selection_select_iter(selection, &child);
-		else
-			gtk_tree_selection_unselect_iter(selection, &child);
-	} while (gtk_tree_model_iter_next(model, &child));
-}
-
-static int selected_children(GtkTreeModel *model, GtkTreeIter *iter)
-{
-	GtkTreeIter child;
-
-	if (!gtk_tree_model_iter_children(model, &child, iter))
-		return FALSE;
-
-	do {
-		int idx;
-		struct dive *dive;
-
-		gtk_tree_model_get(model, &child, DIVE_INDEX, &idx, -1);
-		dive = get_dive(idx);
-
-		if (dive->selected)
-			return TRUE;
-	} while (gtk_tree_model_iter_next(model, &child));
-	return FALSE;
+	for_each_dive(i, dive)
+		if (dive->divetrip == trip) {
+			if (!i)
+				select_dive(i);
+			else
+				deselect_dive(i);
+		}
+	process_selected_dives();
+	repaint_dive();
 }

-/* Make sure that if we collapse a summary row with any selected children, the row
-   shows up as selected too */
+/* on collapsing a trip deselect all dives within or if the trip was selected select all dives */
 static void row_collapsed_cb(GtkTreeView *tree_view, GtkTreeIter *iter, GtkTreePath *path, gpointer data)
 {
-	GtkTreeModel *model = MODEL(dive_list);
-	GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dive_list.tree_view));
+	int i;
+	timestamp_t when;
+	struct dive *dive;

-	if (selected_children(model, iter))
-		gtk_tree_selection_select_iter(selection, iter);
+	gtk_tree_model_get(MODEL(dive_list), iter, DIVE_DATE, &when, -1);
+	dive_trip_t *trip = find_trip_by_time(when);
+	if (!trip)
+		return;
+	for_each_dive(i, dive) {
+		if (dive->divetrip == trip) {
+			if (trip->selected)
+				select_dive(i);
+			else
+				deselect_dive(i);
+		}
+	}
+	process_selected_dives();
+	repaint_dive();
 }

 const char *star_strings[] = {
@@ -2713,12 +2705,8 @@ static gboolean modify_selection_cb(GtkTreeSelection *selection, GtkTreeModel *m
 		dive_trip_t *trip = find_trip_by_time(when);
 		if (!trip)
 			return TRUE;
-
 		trip->selected = 0;
-		/* 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 TRUE;
-		/* Otherwise, consider each dive under it deselected */
+		/* Consider each dive under it deselected */
 		for_each_dive(i, dive) {
 			if (dive->divetrip == trip)
 				deselect_dive(i);
@@ -2746,7 +2734,11 @@ static void entry_selected(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *
 		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;
+			for_each_dive(i, dive)
+				if (dive->divetrip == trip) {
+					select_dive(i);
+					return;
+				}
 		/* Otherwise, consider each dive under it selected */
 		for_each_dive(i, dive) {
 			if (dive->divetrip == trip)
--
1.7.11.msysgit.0



More information about the subsurface mailing list