summaryrefslogtreecommitdiff
path: root/src/av-cp/entry-completion.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/av-cp/entry-completion.c')
-rw-r--r--src/av-cp/entry-completion.c184
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