Skip to content

Commit

Permalink
Refactored GtkEntry autocompletion functions from storage/disk.c to g…
Browse files Browse the repository at this point in the history
…ui/gtkentry.h.
  • Loading branch information
christte committed Oct 1, 2012
1 parent a50dacd commit c68f5f7
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 174 deletions.
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
179 changes: 5 additions & 174 deletions src/imageio/storage/disk.c
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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 <stdio.h>
Expand Down Expand Up @@ -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)
{
Expand All @@ -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") },
Expand All @@ -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);

Expand Down

0 comments on commit c68f5f7

Please sign in to comment.