[gnome-builder/wip/greeter] greeter: implement searching with IdePatternSpec



commit b1ec92d364d782324568100be7e7dc89f52a7f57
Author: Christian Hergert <christian hergert me>
Date:   Sun May 10 13:16:50 2015 -0700

    greeter: implement searching with IdePatternSpec
    
    This builds a small index of information about the project row when
    attaching the "project-info" gproperty. We then use that run of text
    to do a pattern match when the search entry changes.

 data/ui/gb-greeter-window.ui         |    2 +-
 src/greeter/gb-greeter-project-row.c |   62 ++++++++++++++++++++++++++++++++--
 src/greeter/gb-greeter-project-row.h |    1 +
 src/greeter/gb-greeter-window.c      |   58 +++++++++++++++++++++++++++++++
 4 files changed, 119 insertions(+), 4 deletions(-)
---
diff --git a/data/ui/gb-greeter-window.ui b/data/ui/gb-greeter-window.ui
index 4a640e9..4d14d12 100644
--- a/data/ui/gb-greeter-window.ui
+++ b/data/ui/gb-greeter-window.ui
@@ -72,7 +72,7 @@
             <property name="vexpand">false</property>
             <property name="search-mode-enabled" bind-source="search_button" bind-property="active" 
bind-flags="bidirectional"/>
             <child internal-child="entry">
-              <object class="GtkSearchEntry">
+              <object class="GtkSearchEntry" id="search_entry">
                 <property name="placeholder-text"></property>
                 <property name="width-chars">45</property>
               </object>
diff --git a/src/greeter/gb-greeter-project-row.c b/src/greeter/gb-greeter-project-row.c
index 0ab374e..5bb2496 100644
--- a/src/greeter/gb-greeter-project-row.c
+++ b/src/greeter/gb-greeter-project-row.c
@@ -33,7 +33,7 @@ struct _GbGreeterProjectRow
 
   IdeProjectInfo *project_info;
   EggBindingSet  *bindings;
-  GFile          *home_dir;
+  gchar          *search_text;
 
   GtkLabel       *date_label;
   GtkLabel       *description_label;
@@ -62,6 +62,49 @@ gb_greeter_project_row_get_project_info (GbGreeterProjectRow *self)
 }
 
 static void
+gb_greeter_project_row_create_search_text (GbGreeterProjectRow *self,
+                                           IdeProjectInfo      *project_info)
+{
+  const gchar *tmp;
+  IdeDoap *doap;
+  GString *str;
+
+  g_assert (GB_IS_GREETER_PROJECT_ROW (self));
+
+  str = g_string_new (NULL);
+
+  if ((tmp = ide_project_info_get_name (project_info)))
+    {
+      g_autofree gchar *downcase = g_utf8_strdown (g_strdup (tmp), -1);
+
+      g_string_append (str, tmp);
+      g_string_append (str, " ");
+      g_string_append (str, downcase);
+      g_string_append (str, " ");
+    }
+
+  if ((tmp = ide_project_info_get_description (project_info)))
+    {
+      g_string_append (str, tmp);
+      g_string_append (str, " ");
+    }
+
+  doap = ide_project_info_get_doap (project_info);
+
+  if (doap != NULL)
+    {
+      if ((tmp = ide_doap_get_description (doap)))
+        {
+          g_string_append (str, tmp);
+          g_string_append (str, " ");
+        }
+    }
+
+  g_free (self->search_text);
+  self->search_text = g_strdelimit (g_string_free (str, FALSE), "\n", ' ');
+}
+
+static void
 gb_greeter_project_row_add_languages (GbGreeterProjectRow *self,
                                       IdeProjectInfo      *project_info)
 {
@@ -103,8 +146,13 @@ gb_greeter_project_row_set_project_info (GbGreeterProjectRow *self,
   if (g_set_object (&self->project_info, project_info))
     {
       egg_binding_set_set_source (self->bindings, project_info);
+
       if (project_info != NULL)
-        gb_greeter_project_row_add_languages (self, project_info);
+        {
+          gb_greeter_project_row_add_languages (self, project_info);
+          gb_greeter_project_row_create_search_text (self, project_info);
+        }
+
       g_object_notify_by_pspec (G_OBJECT (self), gParamSpecs [PROP_PROJECT_INFO]);
     }
 }
@@ -163,6 +211,14 @@ truncate_location (GBinding     *binding,
   return TRUE;
 }
 
+const gchar *
+gb_greeter_project_row_get_search_text (GbGreeterProjectRow *self)
+{
+  g_return_val_if_fail (GB_IS_GREETER_PROJECT_ROW (self), NULL);
+
+  return self->search_text;
+}
+
 static void
 gb_greeter_project_row_finalize (GObject *object)
 {
@@ -170,7 +226,7 @@ gb_greeter_project_row_finalize (GObject *object)
 
   g_clear_object (&self->project_info);
   g_clear_object (&self->bindings);
-  g_clear_object (&self->home_dir);
+  g_clear_pointer (&self->search_text, g_free);
 
   G_OBJECT_CLASS (gb_greeter_project_row_parent_class)->finalize (object);
 }
diff --git a/src/greeter/gb-greeter-project-row.h b/src/greeter/gb-greeter-project-row.h
index acab4ac..0d424af 100644
--- a/src/greeter/gb-greeter-project-row.h
+++ b/src/greeter/gb-greeter-project-row.h
@@ -29,6 +29,7 @@ G_BEGIN_DECLS
 G_DECLARE_FINAL_TYPE (GbGreeterProjectRow, gb_greeter_project_row, GB, GREETER_PROJECT_ROW, GtkListBoxRow)
 
 IdeProjectInfo *gb_greeter_project_row_get_project_info (GbGreeterProjectRow *self);
+const gchar    *gb_greeter_project_row_get_search_text  (GbGreeterProjectRow *self);
 
 G_END_DECLS
 
diff --git a/src/greeter/gb-greeter-window.c b/src/greeter/gb-greeter-window.c
index 37e0d19..e875175 100644
--- a/src/greeter/gb-greeter-window.c
+++ b/src/greeter/gb-greeter-window.c
@@ -34,10 +34,12 @@ struct _GbGreeterWindow
 
   EggSignalGroup       *signal_group;
   IdeRecentProjects    *recent_projects;
+  IdePatternSpec       *pattern_spec;
 
   GtkWidget            *header_bar;
   GtkListBox           *my_projects_list_box;
   GtkListBox           *other_projects_list_box;
+  GtkSearchEntry       *search_entry;
 };
 
 G_DEFINE_TYPE (GbGreeterWindow, gb_greeter_window, GTK_TYPE_APPLICATION_WINDOW)
@@ -59,6 +61,26 @@ gb_greeter_window_get_recent_projects (GbGreeterWindow *self)
 }
 
 static void
+gb_greeter_window__search_entry_changed (GbGreeterWindow *self,
+                                         GtkSearchEntry  *search_entry)
+{
+  const gchar *text;
+
+  g_assert (GB_IS_GREETER_WINDOW (self));
+  g_assert (GTK_IS_SEARCH_ENTRY (search_entry));
+
+  text = gtk_entry_get_text (GTK_ENTRY (search_entry));
+
+  g_clear_pointer (&self->pattern_spec, ide_pattern_spec_unref);
+
+  if (text != NULL)
+    self->pattern_spec = ide_pattern_spec_new (text);
+
+  gtk_list_box_invalidate_filter (self->my_projects_list_box);
+  gtk_list_box_invalidate_filter (self->other_projects_list_box);
+}
+
+static void
 gb_greeter_window__recent_projects_items_changed (GbGreeterWindow *self,
                                                   guint            position,
                                                   guint            removed,
@@ -137,11 +159,33 @@ gb_greeter_window_set_recent_projects (GbGreeterWindow   *self,
     }
 }
 
+static gboolean
+gb_greeter_window_filter_row (GtkListBoxRow *row,
+                              gpointer       user_data)
+{
+  GbGreeterWindow *self = user_data;
+  GbGreeterProjectRow *project_row = (GbGreeterProjectRow *)row;
+  const gchar *search_text;
+  gboolean ret;
+
+  g_assert (GB_IS_GREETER_WINDOW (self));
+  g_assert (GB_IS_GREETER_PROJECT_ROW (project_row));
+
+  if (self->pattern_spec == NULL)
+    return TRUE;
+
+  search_text = gb_greeter_project_row_get_search_text (project_row);
+  ret = ide_pattern_spec_match (self->pattern_spec, search_text);
+
+  return ret;
+}
+
 static void
 gb_greeter_window_finalize (GObject *object)
 {
   GbGreeterWindow *self = (GbGreeterWindow *)object;
 
+  g_clear_pointer (&self->pattern_spec, ide_pattern_spec_unref);
   g_clear_object (&self->signal_group);
   g_clear_object (&self->recent_projects);
 
@@ -209,6 +253,7 @@ gb_greeter_window_class_init (GbGreeterWindowClass *klass)
   gtk_widget_class_bind_template_child (widget_class, GbGreeterWindow, header_bar);
   gtk_widget_class_bind_template_child (widget_class, GbGreeterWindow, my_projects_list_box);
   gtk_widget_class_bind_template_child (widget_class, GbGreeterWindow, other_projects_list_box);
+  gtk_widget_class_bind_template_child (widget_class, GbGreeterWindow, search_entry);
 
   g_type_ensure (GB_TYPE_GREETER_PROJECT_ROW);
   g_type_ensure (GB_TYPE_SCROLLED_WINDOW);
@@ -226,6 +271,12 @@ gb_greeter_window_init (GbGreeterWindow *self)
 
   gtk_widget_init_template (GTK_WIDGET (self));
 
+  g_signal_connect_object (self->search_entry,
+                           "changed",
+                           G_CALLBACK (gb_greeter_window__search_entry_changed),
+                           self,
+                           G_CONNECT_SWAPPED);
+
   gtk_list_box_set_header_func (self->my_projects_list_box,
                                 gb_gtk_list_box_row_separator_func,
                                 NULL, NULL);
@@ -239,4 +290,11 @@ gb_greeter_window_init (GbGreeterWindow *self)
   gtk_list_box_set_sort_func (self->other_projects_list_box,
                               gb_greeter_window_sort_rows,
                               NULL, NULL);
+
+  gtk_list_box_set_filter_func (self->my_projects_list_box,
+                                gb_greeter_window_filter_row,
+                                self, NULL);
+  gtk_list_box_set_filter_func (self->other_projects_list_box,
+                                gb_greeter_window_filter_row,
+                                self, NULL);
 }


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