[gnome-builder] prefs: implement preferences search
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] prefs: implement preferences search
- Date: Mon, 21 Dec 2015 07:43:55 +0000 (UTC)
commit 427c33ab16443c65621783574f7af1856486e46c
Author: Christian Hergert <christian hergert me>
Date: Tue Nov 10 19:52:37 2015 -0800
prefs: implement preferences search
data/ui/ide-preferences-perspective.ui | 30 +++++++---
libide/preferences/ide-preferences-bin-private.h | 6 +-
libide/preferences/ide-preferences-bin.c | 26 +++++++++
libide/preferences/ide-preferences-bin.h | 12 +++-
libide/preferences/ide-preferences-entry.c | 25 ++++++++
libide/preferences/ide-preferences-font-button.c | 22 +++++++
libide/preferences/ide-preferences-group-private.h | 7 ++-
libide/preferences/ide-preferences-group.c | 57 +++++++++++++++++++
libide/preferences/ide-preferences-page-private.h | 7 ++-
libide/preferences/ide-preferences-page.c | 16 +++++
libide/preferences/ide-preferences-perspective.c | 59 ++++++++++++++++++++
libide/preferences/ide-preferences-spin-button.c | 25 ++++++++
libide/preferences/ide-preferences-switch.c | 25 ++++++++
13 files changed, 298 insertions(+), 19 deletions(-)
---
diff --git a/data/ui/ide-preferences-perspective.ui b/data/ui/ide-preferences-perspective.ui
index 2dd065c..52513b4 100644
--- a/data/ui/ide-preferences-perspective.ui
+++ b/data/ui/ide-preferences-perspective.ui
@@ -40,15 +40,27 @@
<object class="IdeWorkbenchHeaderBar" id="titlebar">
<property name="visible">true</property>
<child>
- <object class="GtkButton" id="back_button">
- <property name="action-name">perspective.go-back</property>
- <child>
- <object class="GtkImage">
- <property name="icon-name">go-previous-symbolic</property>
- <property name="visible">true</property>
- </object>
- </child>
- </object>
+ <object class="GtkButton" id="back_button">
+ <property name="action-name">perspective.go-back</property>
+ <style>
+ <class name="image-button"/>
+ </style>
+ <child>
+ <object class="GtkImage">
+ <property name="icon-name">go-previous-symbolic</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="title">
+ <object class="GtkSearchEntry" id="search_entry">
+ <property name="hexpand">true</property>
+ <property name="margin-end">6</property>
+ <property name="margin-start">6</property>
+ <property name="max-width-chars">50</property>
+ <property name="visible">true</property>
+ </object>
</child>
</object>
</interface>
diff --git a/libide/preferences/ide-preferences-bin-private.h
b/libide/preferences/ide-preferences-bin-private.h
index a005bfd..d748a00 100644
--- a/libide/preferences/ide-preferences-bin-private.h
+++ b/libide/preferences/ide-preferences-bin-private.h
@@ -23,8 +23,10 @@
G_BEGIN_DECLS
-void _ide_preferences_bin_set_map (IdePreferencesBin *self,
- GHashTable *map);
+void _ide_preferences_bin_set_map (IdePreferencesBin *self,
+ GHashTable *map);
+gboolean _ide_preferences_bin_matches (IdePreferencesBin *self,
+ IdePatternSpec *spec);
G_END_DECLS
diff --git a/libide/preferences/ide-preferences-bin.c b/libide/preferences/ide-preferences-bin.c
index 98615ee..64a7246 100644
--- a/libide/preferences/ide-preferences-bin.c
+++ b/libide/preferences/ide-preferences-bin.c
@@ -393,3 +393,29 @@ _ide_preferences_bin_set_map (IdePreferencesBin *self,
ide_preferences_bin_reload (self);
}
}
+
+gboolean
+_ide_preferences_bin_matches (IdePreferencesBin *self,
+ IdePatternSpec *spec)
+{
+ IdePreferencesBinPrivate *priv = ide_preferences_bin_get_instance_private (self);
+
+ g_return_val_if_fail (IDE_IS_PREFERENCES_BIN (self), FALSE);
+
+ if (spec == NULL)
+ return TRUE;
+
+ if (priv->keywords && ide_pattern_spec_match (spec, priv->keywords))
+ return TRUE;
+
+ if (priv->schema_id && ide_pattern_spec_match (spec, priv->schema_id))
+ return TRUE;
+
+ if (priv->path && ide_pattern_spec_match (spec, priv->path))
+ return TRUE;
+
+ if (IDE_PREFERENCES_BIN_GET_CLASS (self)->matches)
+ return IDE_PREFERENCES_BIN_GET_CLASS (self)->matches (self, spec);
+
+ return FALSE;
+}
diff --git a/libide/preferences/ide-preferences-bin.h b/libide/preferences/ide-preferences-bin.h
index bab0725..c014817 100644
--- a/libide/preferences/ide-preferences-bin.h
+++ b/libide/preferences/ide-preferences-bin.h
@@ -21,6 +21,8 @@
#include <gtk/gtk.h>
+#include "ide-pattern-spec.h"
+
G_BEGIN_DECLS
#define IDE_TYPE_PREFERENCES_BIN (ide_preferences_bin_get_type())
@@ -31,10 +33,12 @@ struct _IdePreferencesBinClass
{
GtkBinClass parent_class;
- void (*connect) (IdePreferencesBin *self,
- GSettings *settings);
- void (*disconnect) (IdePreferencesBin *self,
- GSettings *settings);
+ void (*connect) (IdePreferencesBin *self,
+ GSettings *settings);
+ void (*disconnect) (IdePreferencesBin *self,
+ GSettings *settings);
+ gboolean (*matches) (IdePreferencesBin *self,
+ IdePatternSpec *spec);
};
G_END_DECLS
diff --git a/libide/preferences/ide-preferences-entry.c b/libide/preferences/ide-preferences-entry.c
index 6f4755b..ba1d1ca 100644
--- a/libide/preferences/ide-preferences-entry.c
+++ b/libide/preferences/ide-preferences-entry.c
@@ -115,15 +115,40 @@ ide_preferences_entry_changed (IdePreferencesEntry *self,
g_signal_emit (self, signals [CHANGED], 0, text);
}
+static gboolean
+ide_preferences_entry_matches (IdePreferencesBin *bin,
+ IdePatternSpec *spec)
+{
+ IdePreferencesEntry *self = (IdePreferencesEntry *)bin;
+ IdePreferencesEntryPrivate *priv = ide_preferences_entry_get_instance_private (self);
+ const gchar *tmp;
+
+ g_assert (IDE_IS_PREFERENCES_ENTRY (self));
+ g_assert (spec != NULL);
+
+ tmp = gtk_label_get_label (priv->title);
+ if (tmp && ide_pattern_spec_match (spec, tmp))
+ return TRUE;
+
+ tmp = gtk_entry_get_text (GTK_ENTRY (priv->entry));
+ if (tmp && ide_pattern_spec_match (spec, tmp))
+ return TRUE;
+
+ return FALSE;
+}
+
static void
ide_preferences_entry_class_init (IdePreferencesEntryClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ IdePreferencesBinClass *bin_class = IDE_PREFERENCES_BIN_CLASS (klass);
object_class->get_property = ide_preferences_entry_get_property;
object_class->set_property = ide_preferences_entry_set_property;
+ bin_class->matches = ide_preferences_entry_matches;
+
signals [ACTIVATE] =
g_signal_new_class_handler ("activate",
G_TYPE_FROM_CLASS (klass),
diff --git a/libide/preferences/ide-preferences-font-button.c
b/libide/preferences/ide-preferences-font-button.c
index 3396b9b..adeb90f 100644
--- a/libide/preferences/ide-preferences-font-button.c
+++ b/libide/preferences/ide-preferences-font-button.c
@@ -139,6 +139,27 @@ ide_preferences_font_button_disconnect (IdePreferencesBin *bin,
self->handler = 0;
}
+static gboolean
+ide_preferences_font_button_matches (IdePreferencesBin *bin,
+ IdePatternSpec *spec)
+{
+ IdePreferencesFontButton *self = (IdePreferencesFontButton *)bin;
+ const gchar *tmp;
+
+ g_assert (IDE_IS_PREFERENCES_FONT_BUTTON (self));
+ g_assert (spec != NULL);
+
+ tmp = gtk_label_get_label (self->title);
+ if (tmp && ide_pattern_spec_match (spec, tmp))
+ return TRUE;
+
+ tmp = gtk_label_get_label (self->font_family);
+ if (tmp && ide_pattern_spec_match (spec, tmp))
+ return TRUE;
+
+ return FALSE;
+}
+
static void
ide_preferences_font_button_finalize (GObject *object)
{
@@ -209,6 +230,7 @@ ide_preferences_font_button_class_init (IdePreferencesFontButtonClass *klass)
bin_class->connect = ide_preferences_font_button_connect;
bin_class->disconnect = ide_preferences_font_button_disconnect;
+ bin_class->matches = ide_preferences_font_button_matches;
signals [ACTIVATE] =
g_signal_new_class_handler ("activate",
diff --git a/libide/preferences/ide-preferences-group-private.h
b/libide/preferences/ide-preferences-group-private.h
index cf7c277..50d2c4d 100644
--- a/libide/preferences/ide-preferences-group-private.h
+++ b/libide/preferences/ide-preferences-group-private.h
@@ -19,12 +19,15 @@
#ifndef IDE_PREFERENCES_GROUP_PRIVATE_H
#define IDE_PREFERENCES_GROUP_PRIVATE_H
+#include "ide-pattern-spec.h"
#include "ide-preferences-group.h"
G_BEGIN_DECLS
-void _ide_preferences_group_set_map (IdePreferencesGroup *self,
- GHashTable *map);
+void _ide_preferences_group_set_map (IdePreferencesGroup *self,
+ GHashTable *map);
+guint _ide_preferences_group_refilter (IdePreferencesGroup *self,
+ IdePatternSpec *spec);
G_END_DECLS
diff --git a/libide/preferences/ide-preferences-group.c b/libide/preferences/ide-preferences-group.c
index c82d0d8..d826d17 100644
--- a/libide/preferences/ide-preferences-group.c
+++ b/libide/preferences/ide-preferences-group.c
@@ -19,6 +19,7 @@
#include "ide-preferences-bin.h"
#include "ide-preferences-bin-private.h"
#include "ide-preferences-group.h"
+#include "ide-preferences-group-private.h"
struct _IdePreferencesGroup
{
@@ -251,3 +252,59 @@ _ide_preferences_group_set_map (IdePreferencesGroup *self,
_ide_preferences_bin_set_map (IDE_PREFERENCES_BIN (widget), map);
}
}
+
+static void
+ide_preferences_group_refilter_cb (GtkWidget *widget,
+ gpointer user_data)
+{
+ IdePreferencesBin *bin = NULL;
+ struct {
+ IdePatternSpec *spec;
+ guint matches;
+ } *lookup = user_data;
+ gboolean matches;
+
+ if (IDE_IS_PREFERENCES_BIN (widget))
+ bin = IDE_PREFERENCES_BIN (widget);
+ else if (GTK_IS_BIN (widget) && IDE_IS_PREFERENCES_BIN (gtk_bin_get_child (GTK_BIN (widget))))
+ bin = IDE_PREFERENCES_BIN (gtk_bin_get_child (GTK_BIN (widget)));
+ else
+ return;
+
+ if (lookup->spec == NULL)
+ matches = TRUE;
+ else
+ matches = _ide_preferences_bin_matches (bin, lookup->spec);
+
+ gtk_widget_set_visible (widget, matches);
+
+ lookup->matches += matches;
+}
+
+guint
+_ide_preferences_group_refilter (IdePreferencesGroup *self,
+ IdePatternSpec *spec)
+{
+ struct {
+ IdePatternSpec *spec;
+ guint matches;
+ } lookup = { spec, 0 };
+ const gchar *tmp;
+
+ g_return_val_if_fail (IDE_IS_PREFERENCES_GROUP (self), 0);
+
+ tmp = gtk_label_get_label (self->title);
+ if (spec && tmp && ide_pattern_spec_match (spec, tmp))
+ lookup.spec = NULL;
+
+ gtk_container_foreach (GTK_CONTAINER (self->list_box),
+ ide_preferences_group_refilter_cb,
+ &lookup);
+ gtk_container_foreach (GTK_CONTAINER (self->box),
+ ide_preferences_group_refilter_cb,
+ &lookup);
+
+ gtk_widget_set_visible (GTK_WIDGET (self), lookup.matches > 0);
+
+ return lookup.matches;
+}
diff --git a/libide/preferences/ide-preferences-page-private.h
b/libide/preferences/ide-preferences-page-private.h
index df52ae3..50bfbf1 100644
--- a/libide/preferences/ide-preferences-page-private.h
+++ b/libide/preferences/ide-preferences-page-private.h
@@ -19,12 +19,15 @@
#ifndef IDE_PREFERENCES_PAGE_PRIVATE_H
#define IDE_PREFERENCES_PAGE_PRIVATE_H
+#include "ide-pattern-spec.h"
#include "ide-preferences-page.h"
G_BEGIN_DECLS
-void _ide_preferences_page_set_map (IdePreferencesPage *self,
- GHashTable *map);
+void _ide_preferences_page_set_map (IdePreferencesPage *self,
+ GHashTable *map);
+void _ide_preferences_page_refilter (IdePreferencesPage *self,
+ IdePatternSpec *spec);
G_END_DECLS
diff --git a/libide/preferences/ide-preferences-page.c b/libide/preferences/ide-preferences-page.c
index c241759..c2cf64e 100644
--- a/libide/preferences/ide-preferences-page.c
+++ b/libide/preferences/ide-preferences-page.c
@@ -173,3 +173,19 @@ _ide_preferences_page_set_map (IdePreferencesPage *self,
while (g_hash_table_iter_next (&iter, NULL, (gpointer *)&group))
_ide_preferences_group_set_map (group, map);
}
+
+void
+_ide_preferences_page_refilter (IdePreferencesPage *self,
+ IdePatternSpec *spec)
+{
+ IdePreferencesGroup *group;
+ GHashTableIter iter;
+ guint count = 0;
+
+ g_return_if_fail (IDE_IS_PREFERENCES_PAGE (self));
+
+ g_hash_table_iter_init (&iter, self->groups_by_name);
+ while (g_hash_table_iter_next (&iter, NULL, (gpointer *)&group))
+ count += _ide_preferences_group_refilter (group, spec);
+ gtk_widget_set_visible (GTK_WIDGET (self), count > 0);
+}
diff --git a/libide/preferences/ide-preferences-perspective.c
b/libide/preferences/ide-preferences-perspective.c
index da83684..a3fe059 100644
--- a/libide/preferences/ide-preferences-perspective.c
+++ b/libide/preferences/ide-preferences-perspective.c
@@ -21,6 +21,8 @@
#include <glib/gi18n.h>
#include <libpeas/peas.h>
+#include "ide-macros.h"
+#include "ide-pattern-spec.h"
#include "ide-perspective.h"
#include "ide-preferences.h"
#include "ide-preferences-addin.h"
@@ -48,6 +50,7 @@ struct _IdePreferencesPerspective
GtkButton *back_button;
GtkStack *page_stack;
GtkStackSwitcher *page_stack_sidebar;
+ GtkSearchEntry *search_entry;
GtkStack *subpage_stack;
GtkStack *top_stack;
IdeWorkbenchHeaderBar *titlebar;
@@ -60,6 +63,39 @@ G_DEFINE_TYPE_EXTENDED (IdePreferencesPerspective, ide_preferences_perspective,
G_IMPLEMENT_INTERFACE (IDE_TYPE_PREFERENCES, ide_preferences_iface_init)
G_IMPLEMENT_INTERFACE (IDE_TYPE_PERSPECTIVE, ide_perspective_iface_init))
+static void
+ide_preferences_perspective_refilter_cb (GtkWidget *widget,
+ gpointer user_data)
+{
+ IdePreferencesPage *page = (IdePreferencesPage *)widget;
+ IdePatternSpec *spec = user_data;
+
+ g_assert (IDE_IS_PREFERENCES_PAGE (page));
+
+ _ide_preferences_page_refilter (page, spec);
+}
+
+static void
+ide_preferences_perspective_refilter (IdePreferencesPerspective *self,
+ const gchar *search_text)
+{
+ IdePatternSpec *spec = NULL;
+
+ g_assert (IDE_IS_PREFERENCES_PERSPECTIVE (self));
+
+ if (search_text != NULL)
+ spec = ide_pattern_spec_new (search_text);
+
+ gtk_container_foreach (GTK_CONTAINER (self->page_stack),
+ ide_preferences_perspective_refilter_cb,
+ spec);
+ gtk_container_foreach (GTK_CONTAINER (self->subpage_stack),
+ ide_preferences_perspective_refilter_cb,
+ spec);
+
+ g_clear_pointer (&spec, ide_pattern_spec_unref);
+}
+
static gint
sort_by_priority (gconstpointer a,
gconstpointer b,
@@ -160,6 +196,7 @@ ide_preferences_perspective_class_init (IdePreferencesPerspectiveClass *klass)
gtk_widget_class_bind_template_child (widget_class, IdePreferencesPerspective, back_button);
gtk_widget_class_bind_template_child (widget_class, IdePreferencesPerspective, page_stack_sidebar);
gtk_widget_class_bind_template_child (widget_class, IdePreferencesPerspective, page_stack);
+ gtk_widget_class_bind_template_child (widget_class, IdePreferencesPerspective, search_entry);
gtk_widget_class_bind_template_child (widget_class, IdePreferencesPerspective, subpage_stack);
gtk_widget_class_bind_template_child (widget_class, IdePreferencesPerspective, titlebar);
gtk_widget_class_bind_template_child (widget_class, IdePreferencesPerspective, top_stack);
@@ -179,6 +216,22 @@ go_back_activate (GSimpleAction *action,
}
static void
+ide_preferences_perspective_search_entry_changed (IdePreferencesPerspective *self,
+ GtkSearchEntry *search_entry)
+{
+ const gchar *text;
+
+ g_assert (IDE_IS_PREFERENCES_PERSPECTIVE (self));
+ g_assert (GTK_IS_SEARCH_ENTRY (search_entry));
+
+ text = gtk_entry_get_text (GTK_ENTRY (search_entry));
+ if (ide_str_empty0 (text))
+ text = NULL;
+
+ ide_preferences_perspective_refilter (self, text);
+}
+
+static void
ide_preferences_perspective_init (IdePreferencesPerspective *self)
{
static const GActionEntry entries[] = {
@@ -187,6 +240,12 @@ ide_preferences_perspective_init (IdePreferencesPerspective *self)
gtk_widget_init_template (GTK_WIDGET (self));
+ g_signal_connect_object (self->search_entry,
+ "changed",
+ G_CALLBACK (ide_preferences_perspective_search_entry_changed),
+ self,
+ G_CONNECT_SWAPPED);
+
g_signal_connect_object (self->page_stack,
"notify::visible-child",
G_CALLBACK (ide_preferences_perspective_notify_visible_child),
diff --git a/libide/preferences/ide-preferences-spin-button.c
b/libide/preferences/ide-preferences-spin-button.c
index 5f7af7c..0f42ed4 100644
--- a/libide/preferences/ide-preferences-spin-button.c
+++ b/libide/preferences/ide-preferences-spin-button.c
@@ -240,6 +240,30 @@ ide_preferences_spin_button_disconnect (IdePreferencesBin *bin,
self->handler = 0;
}
+static gboolean
+ide_preferences_spin_button_matches (IdePreferencesBin *bin,
+ IdePatternSpec *spec)
+{
+ IdePreferencesSpinButton *self = (IdePreferencesSpinButton *)bin;
+ const gchar *tmp;
+
+ g_assert (IDE_IS_PREFERENCES_SPIN_BUTTON (self));
+ g_assert (spec != NULL);
+
+ tmp = gtk_label_get_label (self->title);
+ if (tmp && ide_pattern_spec_match (spec, tmp))
+ return TRUE;
+
+ tmp = gtk_label_get_label (self->subtitle);
+ if (tmp && ide_pattern_spec_match (spec, tmp))
+ return TRUE;
+
+ if (self->key && ide_pattern_spec_match (spec, self->key))
+ return TRUE;
+
+ return FALSE;
+}
+
static void
ide_preferences_spin_button_finalize (GObject *object)
{
@@ -318,6 +342,7 @@ ide_preferences_spin_button_class_init (IdePreferencesSpinButtonClass *klass)
bin_class->connect = ide_preferences_spin_button_connect;
bin_class->disconnect = ide_preferences_spin_button_disconnect;
+ bin_class->matches = ide_preferences_spin_button_matches;
signals [ACTIVATE] =
g_signal_new_class_handler ("activate",
diff --git a/libide/preferences/ide-preferences-switch.c b/libide/preferences/ide-preferences-switch.c
index 04d8c6c..cabac74 100644
--- a/libide/preferences/ide-preferences-switch.c
+++ b/libide/preferences/ide-preferences-switch.c
@@ -242,6 +242,30 @@ ide_preferences_switch_activate (IdePreferencesSwitch *self)
}
+static gboolean
+ide_preferences_switch_matches (IdePreferencesBin *bin,
+ IdePatternSpec *spec)
+{
+ IdePreferencesSwitch *self = (IdePreferencesSwitch *)bin;
+ const gchar *tmp;
+
+ g_assert (IDE_IS_PREFERENCES_SWITCH (self));
+ g_assert (spec != NULL);
+
+ tmp = gtk_label_get_label (self->title);
+ if (tmp && ide_pattern_spec_match (spec, tmp))
+ return TRUE;
+
+ tmp = gtk_label_get_label (self->subtitle);
+ if (tmp && ide_pattern_spec_match (spec, tmp))
+ return TRUE;
+
+ if (self->key && ide_pattern_spec_match (spec, self->key))
+ return TRUE;
+
+ return FALSE;
+}
+
static void
ide_preferences_switch_finalize (GObject *object)
{
@@ -342,6 +366,7 @@ ide_preferences_switch_class_init (IdePreferencesSwitchClass *klass)
bin_class->connect = ide_preferences_switch_connect;
bin_class->disconnect = ide_preferences_switch_disconnect;
+ bin_class->matches = ide_preferences_switch_matches;
signals [ACTIVATED] =
g_signal_new_class_handler ("activated",
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]