[gtk/suggestion-entry: 28/29] suggestionentry: Work better without a filter
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/suggestion-entry: 28/29] suggestionentry: Work better without a filter
- Date: Fri, 10 Jul 2020 18:01:30 +0000 (UTC)
commit 09d1129f4ff8061a0ffb651ed11d46242560d9ea
Author: Matthias Clasen <mclasen redhat com>
Date: Fri Jul 10 00:39:17 2020 -0400
suggestionentry: Work better without a filter
Make it possible to use the suggestion entry
by doing filtering in the model yourself, and
set use-filter to FALSE. We are still getting
the popup behavior, but inserting prefixes
can't be guaranteed to work well if the
filtering isn't doing prefix matching.
gtk/gtksuggestionentry.c | 99 ++++++++++++++++++++++++++----------------------
gtk/gtksuggestionentry.h | 13 ++++---
2 files changed, 61 insertions(+), 51 deletions(-)
---
diff --git a/gtk/gtksuggestionentry.c b/gtk/gtksuggestionentry.c
index 7ed76d0c13..9c93d1ab14 100644
--- a/gtk/gtksuggestionentry.c
+++ b/gtk/gtksuggestionentry.c
@@ -68,9 +68,18 @@
* the suggestions in the model, controlled by a few properties. If
* #GtkSuggestionEntry:use-filter is set to %FALSE, the popup will not
* be filtered against the entry contents, and will always show all
- * suggestions. If #GtkSuggestionEntry:insert-prefix is set to %TRUE,
+ * suggestions (unless you do your own filtering). The filtering that
+ * is done by GtkSuggestionEntry if use-filter is %TRUE is case-insensitive
+ * and matches a prefix of the strings returned by the expression given
+ * in #GtkSuggestionEntry:expression.
+ *
+ * If #GtkSuggestionEntry:insert-prefix is set to %TRUE,
* GtkSuggestionEntry will automatically inserted the longest common
- * prefix of all matching suggestions into the entry as you type.
+ * prefix of all matching suggestions into the entry as you type. You
+ * probably want to turn this off when you are doing your own filtering,
+ * since it makes the assumption that the filtering is doing prefix
+ * matching.
+ *
* If #GtkSuggestionEntry:insert-selection is set to %TRUE,
* GtkSuggestionEntry will automatically insert the current selection
* from the popup into the entry.
@@ -111,6 +120,7 @@ struct _GtkSuggestionEntry
GtkWidget *popup;
GtkWidget *list;
+ char *search;
char *prefix;
gulong changed_id;
@@ -187,6 +197,7 @@ gtk_suggestion_entry_dispose (GObject *object)
g_clear_object (&self->filter_model);
g_clear_object (&self->selection);
+ g_clear_pointer (&self->search, g_free);
g_clear_pointer (&self->prefix, g_free);
G_OBJECT_CLASS (gtk_suggestion_entry_parent_class)->dispose (object);
@@ -569,16 +580,20 @@ text_changed_idle (gpointer data)
text = gtk_editable_get_text (GTK_EDITABLE (self->entry));
len = g_utf8_strlen (text, -1);
+
+ g_free (self->search);
+ self->search = g_strdup (text);
+
filter = gtk_filter_list_model_get_filter (self->filter_model);
- if (filter)
- gtk_string_filter_set_search (GTK_STRING_FILTER (filter), text);
+ if (GTK_IS_STRING_FILTER (filter))
+ gtk_string_filter_set_search (GTK_STRING_FILTER (filter), self->search);
matches = g_list_model_get_n_items (G_LIST_MODEL (self->selection));
if (len < self->minimum_length)
gtk_suggestion_entry_set_popup_visible (self, FALSE);
else
- gtk_suggestion_entry_set_popup_visible (self, self->use_filter && matches > 0);
+ gtk_suggestion_entry_set_popup_visible (self, matches > 0);
gtk_widget_action_set_enabled (GTK_WIDGET (self), "popup.show", matches > 0);
@@ -703,9 +718,14 @@ gtk_suggestion_entry_key_pressed (GtkEventControllerKey *controller,
text = self->prefix ? self->prefix : "";
gtk_editable_set_text (GTK_EDITABLE (self->entry), text);
+
+ g_free (self->search);
+ self->search = g_strdup (text);
+
filter = gtk_filter_list_model_get_filter (self->filter_model);
- if (filter)
- gtk_string_filter_set_search (GTK_STRING_FILTER (filter), text);
+ if (GTK_IS_STRING_FILTER (filter))
+ gtk_string_filter_set_search (GTK_STRING_FILTER (filter), self->search);
+
g_clear_pointer (&self->prefix, g_free);
gtk_editable_set_position (GTK_EDITABLE (self->entry), -1);
@@ -981,37 +1001,36 @@ search_changed (GObject *object,
static void
update_filter (GtkSuggestionEntry *self)
{
- if (self->filter_model)
- {
- GtkExpression *expression;
- GtkFilter *filter;
-
- if (!self->use_filter)
- expression = NULL;
- else if (self->expression)
- expression = gtk_expression_ref (self->expression);
- else if (GTK_IS_STRING_LIST (self->model))
- expression = gtk_property_expression_new (GTK_TYPE_STRING_OBJECT, NULL, "string");
- else
- expression = NULL;
-
- if (expression)
- {
- filter = gtk_string_filter_new ();
- gtk_string_filter_set_match_mode (GTK_STRING_FILTER (filter), GTK_STRING_FILTER_MATCH_MODE_PREFIX);
- gtk_string_filter_set_ignore_case (GTK_STRING_FILTER (filter), TRUE);
+ GtkFilter *filter;
+ GtkExpression *expression;
- gtk_string_filter_set_expression (GTK_STRING_FILTER (filter), expression);
- g_signal_connect (filter, "notify::search", G_CALLBACK (search_changed), self);
- }
- else
- filter = NULL;
+ if (!self->filter_model)
+ return;
- gtk_filter_list_model_set_filter (GTK_FILTER_LIST_MODEL (self->filter_model), filter);
+ if (!self->use_filter)
+ expression = NULL;
+ else if (self->expression)
+ expression = gtk_expression_ref (self->expression);
+ else if (GTK_IS_STRING_LIST (self->model))
+ expression = gtk_property_expression_new (GTK_TYPE_STRING_OBJECT, NULL, "string");
+ else
+ expression = NULL;
- g_clear_object (&filter);
- g_clear_pointer (&expression, gtk_expression_unref);
+ if (expression)
+ {
+ filter = gtk_string_filter_new ();
+ gtk_string_filter_set_match_mode (GTK_STRING_FILTER (filter), GTK_STRING_FILTER_MATCH_MODE_PREFIX);
+ gtk_string_filter_set_ignore_case (GTK_STRING_FILTER (filter), TRUE);
+ gtk_string_filter_set_expression (GTK_STRING_FILTER (filter), expression);
+ g_signal_connect (filter, "notify::search", G_CALLBACK (search_changed), self);
}
+ else
+ filter = NULL;
+
+ gtk_filter_list_model_set_filter (GTK_FILTER_LIST_MODEL (self->filter_model), filter);
+
+ g_clear_pointer (&expression, gtk_expression_unref);
+ g_clear_object (&filter);
}
static void
@@ -1156,26 +1175,16 @@ static void
update_prefix (GtkSuggestionEntry *self)
{
const char *text;
- const char *search;
char *prefix;
- GtkFilter *filter;
if (!self->insert_prefix)
return;
- if (!self->use_filter)
- return;
-
- filter = gtk_filter_list_model_get_filter (self->filter_model);
- if (!filter)
- return;
-
g_signal_handler_block (self->entry, self->changed_id);
- search = gtk_string_filter_get_search (GTK_STRING_FILTER (filter));
text = gtk_editable_get_text (GTK_EDITABLE (self->entry));
- prefix = compute_prefix (self, search, text);
+ prefix = compute_prefix (self, self->search, text);
insert_prefix (self, prefix);
g_free (prefix);
diff --git a/gtk/gtksuggestionentry.h b/gtk/gtksuggestionentry.h
index 4e7d534bc2..48bd4e97b7 100644
--- a/gtk/gtksuggestionentry.h
+++ b/gtk/gtksuggestionentry.h
@@ -24,6 +24,7 @@
#error "Only <gtk/gtk.h> can be included directly."
#endif
+#include <gtk/gtkfilter.h>
#include <gtk/gtkexpression.h>
#include <gtk/gtklistitemfactory.h>
#include <gtk/gtkwidget.h>
@@ -61,16 +62,16 @@ GtkListItemFactory *
gtk_suggestion_entry_get_factory (GtkSuggestionEntry *self);
GDK_AVAILABLE_IN_ALL
-void gtk_suggestion_entry_set_expression (GtkSuggestionEntry *self,
- GtkExpression *expression);
+void gtk_suggestion_entry_set_use_filter (GtkSuggestionEntry *self,
+ gboolean use_ilter);
GDK_AVAILABLE_IN_ALL
-GtkExpression * gtk_suggestion_entry_get_expression (GtkSuggestionEntry *self);
+gboolean gtk_suggestion_entry_get_use_filter (GtkSuggestionEntry *self);
GDK_AVAILABLE_IN_ALL
-void gtk_suggestion_entry_set_use_filter (GtkSuggestionEntry *self,
- gboolean use_filter);
+void gtk_suggestion_entry_set_expression (GtkSuggestionEntry *self,
+ GtkExpression *expression);
GDK_AVAILABLE_IN_ALL
-gboolean gtk_suggestion_entry_get_use_filter (GtkSuggestionEntry *self);
+GtkExpression * gtk_suggestion_entry_get_expression (GtkSuggestionEntry *self);
GDK_AVAILABLE_IN_ALL
void gtk_suggestion_entry_set_insert_selection (GtkSuggestionEntry *self,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]