From c68f5f7bc2861549ff40fc256f52d9d59fb3a808 Mon Sep 17 00:00:00 2001 From: Christian Tellefsen Date: Tue, 2 Oct 2012 01:12:37 +0200 Subject: [PATCH] Refactored GtkEntry autocompletion functions from storage/disk.c to gui/gtkentry.h. --- src/CMakeLists.txt | 1 + src/imageio/storage/disk.c | 179 ++----------------------------------- 2 files changed, 6 insertions(+), 174 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 00b2172f306e..89d42cac7af5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -70,6 +70,7 @@ FILE(GLOB SOURCE_FILES "dtgtk/resetlabel.c" "gui/accelerators.c" "gui/contrast.c" + "gui/gtkentry.c" "gui/guides.c" "gui/gtk.c" "gui/preferences.c" diff --git a/src/imageio/storage/disk.c b/src/imageio/storage/disk.c index 6369ebc19706..5472458dae26 100644 --- a/src/imageio/storage/disk.c +++ b/src/imageio/storage/disk.c @@ -1,6 +1,6 @@ /* This file is part of darktable, - copyright (c) 2009--2011 johannes hanika. + copyright (c) 2009--2012 johannes hanika. darktable is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -27,6 +27,7 @@ #include "control/control.h" #include "control/conf.h" #include "gui/gtk.h" +#include "gui/gtkentry.h" #include "dtgtk/button.h" #include "dtgtk/paint.h" #include @@ -88,160 +89,6 @@ button_clicked (GtkWidget *widget, dt_imageio_module_storage_t *self) gtk_widget_destroy (filechooser); } -typedef struct completion_spec -{ - gchar *varname; - gchar *description; -} completion_spec; - -typedef enum -{ - COMPL_VARNAME = 0, - COMPL_DESCRIPTION -} CompletionSpecCol; - -/** Called when the user selects a variable from the autocomplete list. */ -static gboolean -on_match_select(GtkEntryCompletion *widget, - GtkTreeModel *model, - GtkTreeIter *iter, - gpointer user_data) -{ - - const gchar *varname; - GtkEditable *e = (GtkEditable*) gtk_entry_completion_get_entry(widget); - gchar *s = gtk_editable_get_chars(e, 0, -1); - gint cur_pos = gtk_editable_get_position(e); - gint p = cur_pos; - gchar *end; - gint del_end_pos = -1; - - GValue value = {0, }; - gtk_tree_model_get_value(model, iter, COMPL_VARNAME, &value); - varname = g_value_get_string(&value); - - for (p = cur_pos; p - 2 > 0; p--) - { - if (strncmp(s + p - 2, "$(", 2) == 0) - { - break; - } - } - - end = s + cur_pos; - - if (end) - { - del_end_pos = end - s + 1; - } - else - { - del_end_pos = cur_pos; - } - - gchar *addtext = (gchar*) g_malloc(strlen(varname) + 2); - sprintf(addtext, "%s)", varname); - - gtk_editable_delete_text(e, p, del_end_pos); - gtk_editable_insert_text(e, addtext, -1, &p); - gtk_editable_set_position(e, p); - g_value_unset(&value); - return TRUE; -} - -/** - * Case insensitive substring search for a completion match. - * - * Based on the default matching function in GtkEntryCompletion. - * - * This function is called once for each iter in the GtkEntryCompletion's - * list of completion entries (model). - * - * @param completion Completion object to apply this function on - * @param key Complete string from the GtkEntry. - * @param iter Item in list of autocomplete database to compare key against. - * @param user_data Unused. - */ -static gboolean -on_match_func (GtkEntryCompletion *completion, const gchar *key, - GtkTreeIter *iter, gpointer user_data) -{ - gchar *item = NULL; - gchar *normalized_string; - gchar *case_normalized_string; - gboolean ret = FALSE; - GtkTreeModel *model = gtk_entry_completion_get_model (completion); - - GtkEditable *e = (GtkEditable*) gtk_entry_completion_get_entry(completion); - gint cur_pos = gtk_editable_get_position(e); /* returns 1..* */ - gint p = cur_pos; - gint var_start; - gboolean var_present = FALSE; - - for (p = cur_pos; p >= 0; p--) - { - gchar *ss = gtk_editable_get_chars(e, p, cur_pos); - if (strncmp(ss, "$(", 2) == 0) - { - var_start = p+2; - var_present = TRUE; - g_free(ss); - break; - } - g_free(ss); - } - - if (var_present) - { - gchar *varname = gtk_editable_get_chars(e, var_start, cur_pos); - - gtk_tree_model_get (model, iter, COMPL_VARNAME, &item, -1); - - if (item != NULL) - { - // Do utf8-safe case insensitive string compare. - // Shamelessly stolen from GtkEntryCompletion. - normalized_string = g_utf8_normalize (item, -1, G_NORMALIZE_ALL); - - if (normalized_string != NULL) - { - case_normalized_string = g_utf8_casefold (normalized_string, -1); - - if (!g_ascii_strncasecmp(varname, case_normalized_string, - strlen (varname))) - ret = TRUE; - - g_free (case_normalized_string); - } - g_free (normalized_string); - } - g_free (varname); - } - g_free (item); - - return ret; -} - - -static gchar * -build_tooltip_text (const gchar *header, const completion_spec *compl_list) -{ - const unsigned int tooltip_len = 1024; - gchar *tt = g_malloc0_n(tooltip_len, sizeof(gchar)); - completion_spec const *p; - - g_strlcat(tt, header, sizeof(tt)*tooltip_len); - g_strlcat(tt, "\n", sizeof(tt)*tooltip_len); - - for(p = compl_list; p->description != NULL; p++) - { - g_strlcat(tt, p->description, sizeof(tt)*tooltip_len); - g_strlcat(tt, "\n", sizeof(tt)*tooltip_len); - } - - return tt; -} - void gui_init (dt_imageio_module_storage_t *self) { @@ -259,15 +106,7 @@ gui_init (dt_imageio_module_storage_t *self) g_free(dir); } - GtkEntryCompletion *completion = gtk_entry_completion_new(); - GtkListStore *model = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); - GtkTreeIter iter; - - gtk_entry_completion_set_text_column(completion, COMPL_DESCRIPTION); - gtk_entry_set_completion(GTK_ENTRY(widget), completion); - g_signal_connect(G_OBJECT(completion), "match-selected", G_CALLBACK(on_match_select), NULL); - - completion_spec compl_list[] = + dt_gtkentry_completion_spec compl_list[] = { { "ROLL_NAME", _("$(ROLL_NAME) - roll of the input image") }, { "FILE_FOLDER", _("$(FILE_FOLDER) - folder containing the input image") }, @@ -294,17 +133,9 @@ gui_init (dt_imageio_module_storage_t *self) { NULL, NULL } }; + dt_gtkentry_setup_completion(GTK_ENTRY(widget), compl_list); - for(completion_spec *l=compl_list; l && l->varname; l++) - { - gtk_list_store_append(model, &iter); - gtk_list_store_set(model, &iter, COMPL_VARNAME, l->varname, - COMPL_DESCRIPTION, l->description, -1); - } - gtk_entry_completion_set_model(completion, GTK_TREE_MODEL(model)); - gtk_entry_completion_set_match_func(completion, on_match_func, NULL, NULL); - - char *tooltip_text = build_tooltip_text ( + char *tooltip_text = dt_gtkentry_build_completion_tooltip_text ( _("enter the path where to put exported images\nrecognized variables:"), compl_list);