[gnome-builder/wip/chergert/grep: 4/10] grep: add toggle all/none support and per-item toggles



commit f28b146721f3f14035112354ba277a9adc4ee16b
Author: Christian Hergert <chergert redhat com>
Date:   Fri Oct 26 12:35:24 2018 -0700

    grep: add toggle all/none support and per-item toggles

 src/plugins/grep/gbp-grep-model.c | 59 ++++++++++++++++++++++++-
 src/plugins/grep/gbp-grep-model.h |  5 +++
 src/plugins/grep/gbp-grep-panel.c | 91 +++++++++++++++++++++++++++++++++++----
 3 files changed, 145 insertions(+), 10 deletions(-)
---
diff --git a/src/plugins/grep/gbp-grep-model.c b/src/plugins/grep/gbp-grep-model.c
index 728cc6853..5bc14ef72 100644
--- a/src/plugins/grep/gbp-grep-model.c
+++ b/src/plugins/grep/gbp-grep-model.c
@@ -37,6 +37,9 @@ struct _GbpGrepModel
   GFile *directory;
   gchar *query;
   Index *index;
+  GHashTable *toggled;
+
+  guint mode;
 
   guint has_scanned : 1;
   guint use_regex : 1;
@@ -61,6 +64,11 @@ enum {
   N_PROPS
 };
 
+enum {
+  MODE_NONE,
+  MODE_ALL,
+};
+
 static GParamSpec *properties [N_PROPS];
 
 static void
@@ -91,6 +99,7 @@ gbp_grep_model_finalize (GObject *object)
   g_clear_object (&self->directory);
   g_clear_pointer (&self->index, index_free);
   g_clear_pointer (&self->query, g_free);
+  g_clear_pointer (&self->toggled, g_hash_table_unref);
 
   G_OBJECT_CLASS (gbp_grep_model_parent_class)->finalize (object);
 }
@@ -217,6 +226,8 @@ gbp_grep_model_class_init (GbpGrepModelClass *klass)
 static void
 gbp_grep_model_init (GbpGrepModel *self)
 {
+  self->mode = MODE_ALL;
+  self->toggled = g_hash_table_new (NULL, NULL);
 }
 
 const gchar *
@@ -616,6 +627,48 @@ gbp_grep_model_scan_finish (GbpGrepModel  *self,
   return self->index != NULL;
 }
 
+void
+gbp_grep_model_select_all (GbpGrepModel *self)
+{
+  g_return_if_fail (GBP_IS_GREP_MODEL (self));
+
+  self->mode = MODE_ALL;
+  g_hash_table_remove_all (self->toggled);
+}
+
+void
+gbp_grep_model_select_none (GbpGrepModel *self)
+{
+  g_return_if_fail (GBP_IS_GREP_MODEL (self));
+
+  self->mode = MODE_NONE;
+  g_hash_table_remove_all (self->toggled);
+}
+
+void
+gbp_grep_model_toggle_row (GbpGrepModel *self,
+                           GtkTreeIter  *iter)
+{
+  g_return_if_fail (GBP_IS_GREP_MODEL (self));
+  g_return_if_fail (iter != NULL);
+
+  if (g_hash_table_contains (self->toggled, iter->user_data))
+    g_hash_table_remove (self->toggled, iter->user_data);
+  else
+    g_hash_table_add (self->toggled, iter->user_data);
+}
+
+void
+gbp_grep_model_toggle_mode (GbpGrepModel *self)
+{
+  g_return_if_fail (GBP_IS_GREP_MODEL (self));
+
+  if (self->mode == MODE_ALL)
+    gbp_grep_model_select_none (self);
+  else
+    gbp_grep_model_select_all (self);
+}
+
 static GtkTreeModelFlags
 gbp_grep_model_get_flags (GtkTreeModel *tree_model)
 {
@@ -706,9 +759,11 @@ gbp_grep_model_get_value (GtkTreeModel *tree_model,
     }
   else if (column == 1)
     {
+      gboolean b = self->mode;
+      if (g_hash_table_contains (self->toggled, iter->user_data))
+        b = !b;
       g_value_init (value, G_TYPE_BOOLEAN);
-      /* TODO: Make this toggle'able */
-      g_value_set_boolean (value, TRUE);
+      g_value_set_boolean (value, b);
     }
 }
 
diff --git a/src/plugins/grep/gbp-grep-model.h b/src/plugins/grep/gbp-grep-model.h
index 76a99a38b..f992b5adc 100644
--- a/src/plugins/grep/gbp-grep-model.h
+++ b/src/plugins/grep/gbp-grep-model.h
@@ -47,6 +47,11 @@ void          gbp_grep_model_set_at_word_boundaries (GbpGrepModel         *self,
 const gchar  *gbp_grep_model_get_query              (GbpGrepModel         *self);
 void          gbp_grep_model_set_query              (GbpGrepModel         *self,
                                                      const gchar          *query);
+void          gbp_grep_model_select_all             (GbpGrepModel         *self);
+void          gbp_grep_model_select_none            (GbpGrepModel         *self);
+void          gbp_grep_model_toggle_mode            (GbpGrepModel         *self);
+void          gbp_grep_model_toggle_row             (GbpGrepModel         *self,
+                                                     GtkTreeIter          *iter);
 void          gbp_grep_model_scan_async             (GbpGrepModel         *self,
                                                      GCancellable         *cancellable,
                                                      GAsyncReadyCallback   callback,
diff --git a/src/plugins/grep/gbp-grep-panel.c b/src/plugins/grep/gbp-grep-panel.c
index 575cbf35d..4ca029988 100644
--- a/src/plugins/grep/gbp-grep-panel.c
+++ b/src/plugins/grep/gbp-grep-panel.c
@@ -28,8 +28,12 @@
 
 struct _GbpGrepPanel
 {
-  DzlDockWidget  parent_instance;
-  GtkTreeView   *tree_view;
+  DzlDockWidget      parent_instance;
+
+  /* Unowned references */
+  GtkTreeView       *tree_view;
+  GtkTreeViewColumn *toggle_column;
+  GtkCheckButton    *check;
 };
 
 enum {
@@ -210,6 +214,10 @@ gbp_grep_panel_row_activated_cb (GbpGrepPanel      *self,
   g_assert (GTK_IS_TREE_VIEW_COLUMN (column));
   g_assert (GTK_IS_TREE_VIEW (tree_view));
 
+  /* Ignore if this is the toggle checkbox column */
+  if (column == self->toggle_column)
+    return;
+
   if ((model = gtk_tree_view_get_model (tree_view)) &&
       gtk_tree_model_get_iter (model, &iter, path))
     {
@@ -239,6 +247,49 @@ gbp_grep_panel_row_activated_cb (GbpGrepPanel      *self,
     }
 }
 
+static void
+gbp_grep_panel_row_toggled_cb (GbpGrepPanel          *self,
+                               const gchar           *pathstr,
+                               GtkCellRendererToggle *toggle)
+{
+  GtkTreeModel *model;
+  GtkTreePath *path;
+  GtkTreeIter iter;
+
+  g_assert (GBP_IS_GREP_PANEL (self));
+  g_assert (pathstr != NULL);
+  g_assert (GTK_IS_CELL_RENDERER_TOGGLE (toggle));
+
+  path = gtk_tree_path_new_from_string (pathstr);
+  model = gtk_tree_view_get_model (self->tree_view);
+
+  if (gtk_tree_model_get_iter (model, &iter, path))
+    {
+      gbp_grep_model_toggle_row (GBP_GREP_MODEL (model), &iter);
+      gtk_widget_queue_resize (GTK_WIDGET (self->tree_view));
+    }
+
+  g_clear_pointer (&path, gtk_tree_path_free);
+}
+
+static void
+gbp_grep_panel_toggle_all_cb (GbpGrepPanel      *self,
+                              GtkTreeViewColumn *column)
+{
+  GtkToggleButton *toggle;
+  GtkTreeModel *model;
+
+  g_assert (GBP_IS_GREP_PANEL (self));
+  g_assert (GTK_IS_TREE_VIEW_COLUMN (column));
+
+  toggle = GTK_TOGGLE_BUTTON (self->check);
+  gtk_toggle_button_set_active (toggle, !gtk_toggle_button_get_active (toggle));
+
+  model = gtk_tree_view_get_model (self->tree_view);
+  gbp_grep_model_toggle_mode (GBP_GREP_MODEL (model));
+  gtk_widget_queue_resize (GTK_WIDGET (self->tree_view));
+}
+
 static void
 gbp_grep_panel_get_property (GObject    *object,
                              guint       prop_id,
@@ -312,12 +363,36 @@ gbp_grep_panel_init (GbpGrepPanel *self)
                            self,
                            G_CONNECT_SWAPPED);
 
-  column = gtk_tree_view_column_new ();
-  cell = gtk_cell_renderer_toggle_new ();
-  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), cell, TRUE);
-  gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (column), cell, "active", 1);
-  gtk_tree_view_column_set_expand (column, FALSE);
-  gtk_tree_view_append_column (self->tree_view, column);
+  self->check = g_object_new (GTK_TYPE_CHECK_BUTTON,
+                              "margin-bottom", 3,
+                              "margin-end", 6,
+                              "margin-start", 6,
+                              "margin-top", 3,
+                              "visible", TRUE,
+                              "active", TRUE,
+                              NULL);
+  self->toggle_column = g_object_new (GTK_TYPE_TREE_VIEW_COLUMN,
+                                      "visible", TRUE,
+                                      "clickable", TRUE,
+                                      "widget", self->check,
+                                      NULL);
+  g_signal_connect_object (self->toggle_column,
+                           "clicked",
+                           G_CALLBACK (gbp_grep_panel_toggle_all_cb),
+                           self,
+                           G_CONNECT_SWAPPED);
+  cell = g_object_new (GTK_TYPE_CELL_RENDERER_TOGGLE,
+                       "activatable", TRUE,
+                       NULL);
+  g_signal_connect_object (cell,
+                           "toggled",
+                           G_CALLBACK (gbp_grep_panel_row_toggled_cb),
+                           self,
+                           G_CONNECT_SWAPPED);
+  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (self->toggle_column), cell, TRUE);
+  gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (self->toggle_column), cell, "active", 1);
+  gtk_tree_view_column_set_expand (self->toggle_column, FALSE);
+  gtk_tree_view_append_column (self->tree_view, self->toggle_column);
 
   column = gtk_tree_view_column_new ();
   cell = gtk_cell_renderer_text_new ();


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