diff options
Diffstat (limited to 'src/av-cp/entry-completion.c')
-rw-r--r-- | src/av-cp/entry-completion.c | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/src/av-cp/entry-completion.c b/src/av-cp/entry-completion.c new file mode 100644 index 0000000..7c9aaba --- /dev/null +++ b/src/av-cp/entry-completion.c @@ -0,0 +1,184 @@ +#include "entry-completion.h" + +static void +entry_completion_constructed (GObject *self); + +struct _EntryCompletion +{ + GtkEntryCompletion parent_instance; + + GtkListStore *store; +}; + +G_DEFINE_TYPE (EntryCompletion, entry_completion, GTK_TYPE_ENTRY_COMPLETION) + +enum { + PROP_0, + N_PROPS +}; + +static GParamSpec *properties [N_PROPS]; + +EntryCompletion * +entry_completion_new (void) +{ + return g_object_new (ENTRY_TYPE_COMPLETION, NULL); +} + +static void +entry_completion_finalize (GObject *object) +{ + G_OBJECT_CLASS (entry_completion_parent_class)->finalize (object); +} + +static void +entry_completion_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +entry_completion_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static gboolean +entry_completion_on_match_selected (GtkEntryCompletion *self, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data) +{ + char *match = NULL; + GtkEntry *entry = gtk_entry_completion_get_entry (self); + gtk_tree_model_get (model, iter, 0, &match, -1); + + char *old_text = g_strdup (gtk_entry_get_text (entry)); + char *needle = strrchr (old_text, ' '); + if (needle != NULL) { + needle++; + *needle = '\0'; + } + + char *new_text = g_strconcat (needle == NULL ? "" : old_text, match, NULL); + gtk_entry_set_text (entry, new_text); + gtk_editable_set_position (GTK_EDITABLE (entry), strlen (new_text)); + g_free (new_text); + g_free (old_text); + + return TRUE; +} + +static void +entry_completion_class_init (EntryCompletionClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->constructed = entry_completion_constructed; + object_class->finalize = entry_completion_finalize; + object_class->get_property = entry_completion_get_property; + object_class->set_property = entry_completion_set_property; + + GtkEntryCompletionClass *entry_class = GTK_ENTRY_COMPLETION_CLASS (klass); + entry_class->match_selected = entry_completion_on_match_selected; +} + +static gboolean +entry_completion_on_match (GtkEntryCompletion *self, const char *key, GtkTreeIter *iter, gpointer user_data) +{ + GtkTreeModel *model = gtk_entry_completion_get_model (self); + char *candidate; + GtkEntry *entry = gtk_entry_completion_get_entry (self); + gboolean retval = FALSE; + + gtk_tree_model_get (model, iter, 0, &candidate, -1); + + char *needle = strrchr (key, ' '); + if (needle != NULL) { + if ((needle - key)> gtk_editable_get_position (GTK_EDITABLE (entry))) { + g_print ("Position wrong\n"); + goto out; + } + needle++; + } else { + needle = key; + } + + if (strlen(needle) == 0) { + goto out; + } + + retval = g_str_has_prefix (candidate, needle); + +out: + g_free (candidate); + + return retval; +} + +static void +entry_completion_init (EntryCompletion *self) +{ +} + +static void +entry_completion_constructed (GObject *object) +{ + EntryCompletion *self = ENTRY_COMPLETION (object); + + if (G_OBJECT_CLASS (entry_completion_parent_class)->constructed != NULL) { + G_OBJECT_CLASS (entry_completion_parent_class)->constructed (G_OBJECT (self)); + } + + gtk_entry_completion_set_match_func (GTK_ENTRY_COMPLETION (self), + entry_completion_on_match, + NULL, + NULL); + + self->store = gtk_list_store_new (1, G_TYPE_STRING); + + gtk_entry_completion_set_model (GTK_ENTRY_COMPLETION (self), GTK_TREE_MODEL (self->store)); + gtk_entry_completion_set_text_column (GTK_ENTRY_COMPLETION (self), 0); +} + +void +entry_completion_set_search_criteria (EntryCompletion *self, char** criteria) +{ + GtkTreeIter iter; + gtk_list_store_clear (self->store); + // Prefill ListStore with the search expression keywords + gtk_list_store_insert_with_values (self->store, &iter, -1, + 0, "and", -1); + gtk_list_store_insert_with_values (self->store, &iter, -1, + 0, "or", -1); + gtk_list_store_insert_with_values (self->store, &iter, -1, + 0, "contains", -1); + gtk_list_store_insert_with_values (self->store, &iter, -1, + 0, "doesNotContain", -1); + gtk_list_store_insert_with_values (self->store, &iter, -1, + 0, "derivedFrom", -1); + gtk_list_store_insert_with_values (self->store, &iter, -1, + 0, "exists", -1); + gtk_list_store_insert_with_values (self->store, &iter, -1, + 0, "true", -1); + gtk_list_store_insert_with_values (self->store, &iter, -1, + 0, "false", -1); + + char **it = criteria; + while (*it != NULL) { + gtk_list_store_insert_with_values (self->store, &iter, -1, + 0, *it, -1); + it++; + } +}
\ No newline at end of file |