[libgd] Make multi range selection work right



commit b82e4c3722f4e83b429d9b72a9a20172fe3a7cd9
Author: Alexander Larsson <alexl redhat com>
Date:   Thu Apr 11 11:19:14 2013 +0200

    Make multi range selection work right
    
    When you range select you want the range to start from the last
    single selection you made, not from some random selected item. For instance
    If you first select item 3-5 and then 9-7 you want 7,8,9 selected
    not (like now) 6,7.
    
    We keep the column id of the last item we initially selected (i.e. no
    range select). If this item disappears or something we fall back on the
    old code.
    
    We can also simplify the selection_mode_select_range code a bit
    now that selection_mode_do_select_range handles ranges in any order.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=697645

 libgd/gd-main-view.c |   99 +++++++++++++++++++++++++++++++++-----------------
 1 files changed, 65 insertions(+), 34 deletions(-)
---
diff --git a/libgd/gd-main-view.c b/libgd/gd-main-view.c
index 8b54ca3..8f3407a 100644
--- a/libgd/gd-main-view.c
+++ b/libgd/gd-main-view.c
@@ -36,6 +36,8 @@ struct _GdMainViewPrivate {
   GtkTreeModel *model;
 
   gchar *button_press_item_path;
+
+  gchar *last_selected_id;
 };
 
 enum {
@@ -73,6 +75,7 @@ gd_main_view_finalize (GObject *obj)
   GdMainView *self = GD_MAIN_VIEW (obj);
 
   g_free (self->priv->button_press_item_path);
+  g_free (self->priv->last_selected_id);
 
   G_OBJECT_CLASS (gd_main_view_parent_class)->finalize (obj);
 }
@@ -366,50 +369,69 @@ selection_mode_select_range (GdMainView *self,
   GtkTreeIter other;
   gboolean found = FALSE;
   gboolean selected;
+  char *id;
 
-  other = *iter;
-  while (gtk_tree_model_iter_previous (self->priv->model, &other))
+  if (self->priv->last_selected_id != NULL &&
+      gtk_tree_model_get_iter_first (self->priv->model, &other))
     {
-      gtk_tree_model_get (self->priv->model, &other,
-                          GD_MAIN_COLUMN_SELECTED, &selected,
-                          -1);
-
-      if (selected)
-        {
-          found = TRUE;
-          break;
-        }
+      do
+       {
+         gtk_tree_model_get (self->priv->model, &other,
+                             GD_MAIN_COLUMN_ID, &id,
+                             -1);
+         if (g_strcmp0 (id, self->priv->last_selected_id) == 0)
+           {
+             g_free (id);
+             found = TRUE;
+             break;
+           }
+         g_free (id);
+       }
+      while (gtk_tree_model_iter_next (self->priv->model, &other));
     }
 
-  if (found)
+  if (!found)
     {
-      selection_mode_do_select_range (self, &other, iter);
-      return;
+      other = *iter;
+      while (gtk_tree_model_iter_previous (self->priv->model, &other))
+       {
+         gtk_tree_model_get (self->priv->model, &other,
+                             GD_MAIN_COLUMN_SELECTED, &selected,
+                             -1);
+
+         if (selected)
+           {
+             found = TRUE;
+             break;
+           }
+       }
     }
 
-  other = *iter;
-  while (gtk_tree_model_iter_next (self->priv->model, &other))
+  if (!found)
     {
-      gtk_tree_model_get (self->priv->model, &other,
-                          GD_MAIN_COLUMN_SELECTED, &selected,
-                          -1);
-      if (selected)
-        {
-          found = TRUE;
-          break;
-        }
+      other = *iter;
+      while (gtk_tree_model_iter_next (self->priv->model, &other))
+       {
+         gtk_tree_model_get (self->priv->model, &other,
+                             GD_MAIN_COLUMN_SELECTED, &selected,
+                             -1);
+         if (selected)
+           {
+             found = TRUE;
+             break;
+           }
+       }
     }
 
   if (found)
+    selection_mode_do_select_range (self, iter, &other);
+  else
     {
-      selection_mode_do_select_range (self, iter, &other);
-      return;
+      /* no other selected element found, just select the iter */
+      gtk_list_store_set (GTK_LIST_STORE (self->priv->model), iter,
+                         GD_MAIN_COLUMN_SELECTED, TRUE,
+                         -1);
     }
-
-  /* no other selected element found, just select the iter */
-  gtk_list_store_set (GTK_LIST_STORE (self->priv->model), iter,
-                      GD_MAIN_COLUMN_SELECTED, TRUE,
-                      -1);
 }
 
 static gboolean
@@ -419,6 +441,7 @@ toggle_selection_for_path (GdMainView *self,
 {
   gboolean selected;
   GtkTreeIter iter;
+  char *id;
 
   if (self->priv->model == NULL)
     return FALSE;
@@ -441,9 +464,17 @@ toggle_selection_for_path (GdMainView *self,
       if (select_range)
         selection_mode_select_range (self, &iter);
       else
-        gtk_list_store_set (GTK_LIST_STORE (self->priv->model), &iter,
-                            GD_MAIN_COLUMN_SELECTED, TRUE,
-                            -1);
+       {
+         gtk_tree_model_get (self->priv->model, &iter,
+                             GD_MAIN_COLUMN_ID, &id,
+                             -1);
+         g_free (self->priv->last_selected_id);
+         self->priv->last_selected_id = id;
+
+         gtk_list_store_set (GTK_LIST_STORE (self->priv->model), &iter,
+                             GD_MAIN_COLUMN_SELECTED, TRUE,
+                             -1);
+       }
     }
 
   g_signal_emit (self, signals[VIEW_SELECTION_CHANGED], 0);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]