From dc04c9c3fa6c5dd075f2f1c0853ab1213b02f92c Mon Sep 17 00:00:00 2001 From: Jon Trowbridge Date: Tue, 5 Jun 2001 17:46:56 +0000 Subject: Small changes throughout to use ECompletionMatch. 2001-06-05 Jon Trowbridge * gal/e-text/e-entry.c: Small changes throughout to use ECompletionMatch. * gal/e-text/e-completion-view.c: Small changes throughout to use ECompletionMatch. * gal/e-text/e-completion.c: Small changes throughout to use ECompletionMatch. * gal/e-text/e-completion-match.h: * gal/e-text/e-completion-match.c: Added. A struct to contain completion matches. This lets us more easily pass around information between the various bits of completion machinery. svn path=/trunk/; revision=10118 --- widgets/text/e-completion-match.c | 184 ++++++++++++++++++++++++++++++++++++++ widgets/text/e-completion-match.h | 72 +++++++++++++++ widgets/text/e-completion-test.c | 10 ++- widgets/text/e-completion-view.c | 27 +++--- widgets/text/e-completion-view.h | 4 +- widgets/text/e-completion.c | 149 +++++++++--------------------- widgets/text/e-completion.h | 12 +-- widgets/text/e-entry.c | 16 ++-- widgets/text/e-entry.h | 2 +- widgets/text/e-text.c | 9 +- 10 files changed, 342 insertions(+), 143 deletions(-) create mode 100644 widgets/text/e-completion-match.c create mode 100644 widgets/text/e-completion-match.h diff --git a/widgets/text/e-completion-match.c b/widgets/text/e-completion-match.c new file mode 100644 index 0000000000..e00d5c8bdb --- /dev/null +++ b/widgets/text/e-completion-match.c @@ -0,0 +1,184 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ + +/* + * e-completion-match.c + * + * Copyright (C) 2001 Ximian, Inc. + * + * Developed by Jon Trowbridge + */ + +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + */ + +#include +#include +#include +#include "e-completion-match.h" + +static void +e_completion_match_destroy (ECompletionMatch *match) +{ + if (match) { + g_free (match->match_text); + g_free (match->menu_text); + if (match->destroy) + match->destroy (match); + g_free (match); + } +} + +void +e_completion_match_construct (ECompletionMatch *match) +{ + g_return_if_fail (match != NULL); + + match->match_text = NULL; + match->menu_text = NULL; + match->score = 0; + match->sort_major = 0; + match->sort_minor = 0; + match->user_data = NULL; + match->ref = 1; + match->destroy = NULL; +} + +void +e_completion_match_ref (ECompletionMatch *match) +{ + g_return_if_fail (match != NULL); + g_return_if_fail (match->ref > 0); + + ++match->ref; +} + +void +e_completion_match_unref (ECompletionMatch *match) +{ + g_return_if_fail (match != NULL); + g_return_if_fail (match->ref > 0); + + --match->ref; + if (match->ref == 0) { + e_completion_match_destroy (match); + } +} + +void +e_completion_match_set_text (ECompletionMatch *match, + const gchar *match_text, + const gchar *menu_text) +{ + g_return_if_fail (match != NULL); + + g_free (match->match_text); + g_free (match->menu_text); + + if (match_text == NULL) { + match_text = "Unknown_Match"; + } else if (! g_utf8_validate (match_text, 0, NULL)) { + match_text = "Invalid_UTF8"; + } + + if (menu_text == NULL) { + menu_text = match_text; + } else if (! g_utf8_validate (menu_text, 0, NULL)) { + menu_text = "Invalid_UTF8"; + } + + match->match_text = g_strdup (match_text); + match->menu_text = g_strdup (menu_text); +} + +const gchar * +e_completion_match_get_match_text (ECompletionMatch *match) +{ + return match ? match->match_text : "NULL_Match"; +} + +const gchar * +e_completion_match_get_menu_text (ECompletionMatch *match) +{ + return match ? match->menu_text : "NULL_Match"; +} + +gint +e_completion_match_compare (const ECompletionMatch *a, const ECompletionMatch *b) +{ + gint rv; + + /* Deal with NULL arguments. */ + if (!(a || b)) { + if (!(a && b)) + return 0; + return a ? -1 : 1; + } + + /* Sort the scores high->low. */ + if ( (rv = (b->score > a->score) - (a->score > b->score)) ) + return rv; + + if ( (rv = (b->sort_major < a->sort_major) - (a->sort_major < b->sort_major)) ) + return rv; + + if ( (rv = (b->sort_minor < a->sort_minor) - (a->sort_minor < b->sort_minor)) ) + return rv; + + return 0; +} + +/* Copied from the above, with one addition. */ +gint +e_completion_match_compare_alpha (const ECompletionMatch *a, const ECompletionMatch *b) +{ + gint rv; + + /* Deal with NULL arguments. */ + if (!(a || b)) { + if (!(a && b)) + return 0; + return a ? -1 : 1; + } + + /* Sort the scores high->low. */ + if ( (rv = (b->score > a->score) - (a->score > b->score)) ) + return rv; + + /* Consider the menu text in the sort. */ + if ( (rv = strcmp (a->menu_text, b->menu_text)) ) + return rv; + + if ( (rv = (b->sort_major < a->sort_major) - (a->sort_major < b->sort_major)) ) + return rv; + + if ( (rv = (b->sort_minor < a->sort_minor) - (a->sort_minor < b->sort_minor)) ) + return rv; + + return 0; +} + +ECompletionMatch * +e_completion_match_new (const gchar *match_text, const gchar *menu_text, double score) +{ + ECompletionMatch *match = g_new0 (ECompletionMatch, 1); + + e_completion_match_construct (match); + e_completion_match_set_text (match, match_text, menu_text); + match->score = score; + + return match; +} diff --git a/widgets/text/e-completion-match.h b/widgets/text/e-completion-match.h new file mode 100644 index 0000000000..4ec1733aca --- /dev/null +++ b/widgets/text/e-completion-match.h @@ -0,0 +1,72 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ + +/* + * e-completion-match.h + * + * Copyright (C) 2001 Ximian, Inc. + * + * Developed by Jon Trowbridge + */ + +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + */ + +#ifndef __E_COMPLETION_MATCH_H__ +#define __E_COMPLETION_MATCH_H__ + +#include +#include +#include + +BEGIN_GNOME_DECLS + +typedef struct _ECompletionMatch ECompletionMatch; + +struct _ECompletionMatch { + gchar *match_text; /* in utf8 */ + gchar *menu_text; /* in utf8 */ + double score; + gint sort_major; + gint sort_minor; + gpointer user_data; + + gint ref; + void (*destroy) (ECompletionMatch *); +}; + +typedef void (*ECompletionMatchFn) (ECompletionMatch *, gpointer closure); + +void e_completion_match_construct (ECompletionMatch *); +void e_completion_match_ref (ECompletionMatch *); +void e_completion_match_unref (ECompletionMatch *); + +void e_completion_match_set_text (ECompletionMatch *, const gchar *match_text, const gchar *label_text); +const gchar *e_completion_match_get_match_text (ECompletionMatch *); +const gchar *e_completion_match_get_menu_text (ECompletionMatch *); + +gint e_completion_match_compare (const ECompletionMatch *, const ECompletionMatch *); +gint e_completion_match_compare_alpha (const ECompletionMatch *, const ECompletionMatch *); + +ECompletionMatch *e_completion_match_new (const gchar *match_text, const gchar *menu_text, double score); + + + + +END_GNOME_DECLS + +#endif /* __E_COMPLETION_MATCH_H__ */ + diff --git a/widgets/text/e-completion-test.c b/widgets/text/e-completion-test.c index 8550e9a10f..7a5ed920cd 100644 --- a/widgets/text/e-completion-test.c +++ b/widgets/text/e-completion-test.c @@ -93,9 +93,13 @@ dict_check (gpointer ptr) && i < word_count && dict_info.count < 50 && g_strncasecmp (dict_info.txt, word_array[i], dict_info.len) == 0) { - e_completion_found_match_full (dict_info.complete, word_array[i], - dict_info.len / (double)strlen (word_array[i]), - NULL, NULL); + + ECompletionMatch *match = g_new (ECompletionMatch, 1); + e_completion_match_construct (match); + e_completion_match_set_text (match, word_array[i], NULL); + match->score = dict_info.len / (double)strlen (word_array[i]); + e_completion_found_match (dict_info.complete, match); + ++i; --limit; ++dict_info.count; diff --git a/widgets/text/e-completion-view.c b/widgets/text/e-completion-view.c index 2ffb19f3e3..50f1c6b469 100644 --- a/widgets/text/e-completion-view.c +++ b/widgets/text/e-completion-view.c @@ -143,9 +143,9 @@ e_completion_view_class_init (ECompletionViewClass *klass) GTK_RUN_LAST, object_class->type, GTK_SIGNAL_OFFSET (ECompletionViewClass, activate), - gtk_marshal_NONE__POINTER_POINTER, - GTK_TYPE_NONE, 2, - GTK_TYPE_POINTER, GTK_TYPE_POINTER); + gtk_marshal_NONE__POINTER, + GTK_TYPE_NONE, 1, + GTK_TYPE_POINTER); gtk_object_class_add_signals (object_class, e_completion_view_signals, E_COMPLETION_VIEW_LAST_SIGNAL); @@ -217,8 +217,9 @@ e_completion_view_clear_choices (ECompletionView *cv) g_return_if_fail (cv != NULL); g_return_if_fail (E_IS_COMPLETION_VIEW (cv)); - for (i = cv->choices; i != NULL; i = g_list_next (i)) - g_free (i->data); + for (i = cv->choices; i != NULL; i = g_list_next (i)) { + e_completion_match_unref ((ECompletionMatch *) i->data); + } g_list_free (cv->choices); cv->choices = NULL; @@ -293,12 +294,11 @@ e_completion_view_set_cursor_row (ECompletionView *cv, gint r) static void e_completion_view_select (ECompletionView *cv, gint r) { - const gchar *sel = (const gchar *) g_list_nth_data (cv->choices, r); - gpointer extra = e_completion_find_extra_data (cv->completion, sel); + ECompletionMatch *match = (ECompletionMatch *) g_list_nth_data (cv->choices, r); cv->selection = r; e_completion_view_set_cursor_row (cv, r); - gtk_signal_emit (GTK_OBJECT (cv), e_completion_view_signals[E_COMPLETION_VIEW_ACTIVATE], sel, extra); + gtk_signal_emit (GTK_OBJECT (cv), e_completion_view_signals[E_COMPLETION_VIEW_ACTIVATE], match); } static gint @@ -421,13 +421,14 @@ cancel_completion_cb (ECompletion *completion, gpointer user_data) } static void -completion_cb (ECompletion *completion, const gchar *text, gpointer extra_data, gpointer user_data) +completion_cb (ECompletion *completion, ECompletionMatch *match, gpointer user_data) { ECompletionView *cv = E_COMPLETION_VIEW (user_data); gint r = cv->choice_count; gboolean first = (cv->choices == NULL); - cv->choices = g_list_append (cv->choices, g_strdup (text)); + cv->choices = g_list_append (cv->choices, match); + e_completion_match_ref (match); ++cv->choice_count; e_table_model_row_inserted (cv->model, r); @@ -486,11 +487,11 @@ static gpointer table_value_at (ETableModel *etm, gint c, gint r, gpointer data) { ECompletionView *cv = E_COMPLETION_VIEW (data); - gpointer p; + ECompletionMatch *match; - p = g_list_nth_data (cv->choices, r); + match = (ECompletionMatch *) g_list_nth_data (cv->choices, r); - return p; + return (gpointer) e_completion_match_get_menu_text (match); } static gchar * diff --git a/widgets/text/e-completion-view.h b/widgets/text/e-completion-view.h index 57268125c5..fc3a2598bf 100644 --- a/widgets/text/e-completion-view.h +++ b/widgets/text/e-completion-view.h @@ -79,9 +79,9 @@ struct _ECompletionViewClass { void (*nonempty) (ECompletionView *cv); void (*added) (ECompletionView *cv); void (*full) (ECompletionView *cv); - void (*browse) (ECompletionView *cv, const gchar *text); + void (*browse) (ECompletionView *cv, ECompletionMatch *match); void (*unbrowse) (ECompletionView *cv); - void (*activate) (ECompletionView *cv, const gchar *text, gpointer extra_data); + void (*activate) (ECompletionView *cv, ECompletionMatch *match); }; GtkType e_completion_view_get_type (void); diff --git a/widgets/text/e-completion.c b/widgets/text/e-completion.c index a8038b8184..5aea08de98 100644 --- a/widgets/text/e-completion.c +++ b/widgets/text/e-completion.c @@ -27,7 +27,7 @@ #include -#include /* strcmp() */ +#include #include #include "e-completion.h" @@ -42,14 +42,6 @@ enum { static guint e_completion_signals[E_COMPLETION_LAST_SIGNAL] = { 0 }; -typedef struct _Match Match; -struct _Match { - gchar *text; - double score; - gpointer extra_data; - GtkDestroyNotify extra_destroy; -}; - struct _ECompletionPrivate { gboolean searching; gchar *search_text; @@ -64,13 +56,11 @@ static void e_completion_class_init (ECompletionClass *klass); static void e_completion_init (ECompletion *complete); static void e_completion_destroy (GtkObject *object); -static Match *match_new (const gchar *txt, double score, gpointer extra_data, GtkDestroyNotify extra_destroy); -static void match_free (Match *); static void match_list_free (GList *); -static void e_completion_add_match (ECompletion *complete, const gchar *txt, double score, gpointer extra_data, GtkDestroyNotify); +static void e_completion_add_match (ECompletion *complete, ECompletionMatch *); static void e_completion_clear_matches (ECompletion *complete); -static gboolean e_completion_sort_by_score (ECompletion *complete); +static gboolean e_completion_sort (ECompletion *complete); static void e_completion_restart (ECompletion *complete); static GtkObjectClass *parent_class; @@ -120,9 +110,9 @@ e_completion_class_init (ECompletionClass *klass) GTK_RUN_LAST, object_class->type, GTK_SIGNAL_OFFSET (ECompletionClass, completion), - gtk_marshal_NONE__POINTER_POINTER, - GTK_TYPE_NONE, 2, - GTK_TYPE_POINTER, GTK_TYPE_POINTER); + gtk_marshal_NONE__POINTER, + GTK_TYPE_NONE, 1, + GTK_TYPE_POINTER); e_completion_signals[E_COMPLETION_RESTART_COMPLETION] = gtk_signal_new ("restart_completion", @@ -176,56 +166,31 @@ e_completion_destroy (GtkObject *object) (parent_class->destroy) (object); } -static Match * -match_new (const gchar *text, double score, gpointer extra_data, GtkDestroyNotify extra_destroy) -{ - Match *m; - - if (text == NULL) - return NULL; - - m = g_new (Match, 1); - m->text = g_strdup (text); - m->score = score; - m->extra_data = extra_data; - m->extra_destroy = extra_destroy; - - return m; -} - -static void -match_free (Match *m) -{ - if (m) { - g_free (m->text); - if (m->extra_destroy) - m->extra_destroy (m->extra_data); - g_free (m); - } -} - static void match_list_free (GList *i) { while (i) { - match_free ( (Match *) i->data ); + e_completion_match_unref ((ECompletionMatch *) i->data); i = g_list_next (i); } } static void -e_completion_add_match (ECompletion *complete, const gchar *txt, double score, gpointer extra_data, GtkDestroyNotify extra_destroy) +e_completion_add_match (ECompletion *complete, ECompletionMatch *match) { - complete->priv->matches = g_list_append (complete->priv->matches, match_new (txt, score, extra_data, extra_destroy)); + g_return_if_fail (complete && E_IS_COMPLETION (complete)); + g_return_if_fail (match != NULL); + + complete->priv->matches = g_list_append (complete->priv->matches, match); if (complete->priv->match_count == 0) { - complete->priv->min_score = complete->priv->max_score = score; + complete->priv->min_score = complete->priv->max_score = match->score; } else { - complete->priv->min_score = MIN (complete->priv->min_score, score); - complete->priv->max_score = MAX (complete->priv->max_score, score); + complete->priv->min_score = MIN (complete->priv->min_score, match->score); + complete->priv->max_score = MAX (complete->priv->max_score, match->score); } @@ -321,7 +286,7 @@ e_completion_match_count (ECompletion *complete) } void -e_completion_foreach_match (ECompletion *complete, ECompletionMatchFn fn, gpointer user_data) +e_completion_foreach_match (ECompletion *complete, ECompletionMatchFn fn, gpointer closure) { GList *i; @@ -332,26 +297,8 @@ e_completion_foreach_match (ECompletion *complete, ECompletionMatchFn fn, gpoint return; for (i = complete->priv->matches; i != NULL; i = g_list_next (i)) { - Match *m = (Match *) i->data; - fn (m->text, m->score, m->extra_data, user_data); - } -} - -gpointer -e_completion_find_extra_data (ECompletion *complete, const gchar *text) -{ - GList *i; - - g_return_val_if_fail (complete != NULL, NULL); - g_return_val_if_fail (E_IS_COMPLETION (complete), NULL); - - for (i = complete->priv->matches; i != NULL; i = g_list_next (i)) { - Match *m = (Match *) i->data; - if (strcmp (m->text, text) == 0) - return m->extra_data; + fn ((ECompletionMatch *) i->data, closure); } - - return NULL; } ECompletion * @@ -360,33 +307,34 @@ e_completion_new (void) return E_COMPLETION (gtk_type_new (e_completion_get_type ())); } -static gint -score_cmp_fn (gconstpointer a, gconstpointer b) -{ - double sa = ((const Match *) a)->score; - double sb = ((const Match *) b)->score; - gint cmp = (sa < sb) - (sb < sa); - if (cmp == 0) - cmp = g_strcasecmp (((const Match *) a)->text, ((const Match *) b)->text); - return cmp; -} - static gboolean -e_completion_sort_by_score (ECompletion *complete) +e_completion_sort (ECompletion *complete) { GList *sort_list = NULL, *i, *j; gboolean diff; gint count; - /* If all scores are equal, there is nothing to do. */ - if (complete->priv->min_score == complete->priv->max_score) - return FALSE; + FILE *out = fopen ("/tmp/assbarn", "a"); + fprintf (out, "---------------------------------------\n"); for (i = complete->priv->matches; i != NULL; i = g_list_next (i)) { sort_list = g_list_append (sort_list, i->data); + { + ECompletionMatch *match = (ECompletionMatch *) i->data; + fprintf (out, "%s / %s / %g / %d / %d\n", + match->match_text, + match->menu_text, + match->score, + match->sort_major, + match->sort_minor); + } + + } - sort_list = g_list_sort (sort_list, score_cmp_fn); + fclose (out); + + sort_list = g_list_sort (sort_list, (GCompareFunc) e_completion_match_compare_alpha); diff = FALSE; @@ -420,44 +368,35 @@ e_completion_restart (ECompletion *complete) i = complete->priv->matches; while (i != NULL && count < complete->priv->limit) { - Match *m = (Match *) i->data; - gtk_signal_emit (GTK_OBJECT (complete), e_completion_signals[E_COMPLETION_COMPLETION], m->text, m->extra_data); - + ECompletionMatch *m = (ECompletionMatch *) i->data; + gtk_signal_emit (GTK_OBJECT (complete), e_completion_signals[E_COMPLETION_COMPLETION], m); i = g_list_next (i); ++count; } } void -e_completion_found_match (ECompletion *complete, const gchar *text) +e_completion_found_match (ECompletion *complete, ECompletionMatch *match) { g_return_if_fail (complete); g_return_if_fail (E_IS_COMPLETION (complete)); - g_return_if_fail (text != NULL); - - e_completion_found_match_full (complete, text, 0, NULL, NULL); -} - -void -e_completion_found_match_full (ECompletion *complete, const gchar *text, double score, gpointer extra_data, GtkDestroyNotify extra_destroy) -{ - g_return_if_fail (complete); - g_return_if_fail (E_IS_COMPLETION (complete)); - g_return_if_fail (text != NULL); + g_return_if_fail (match != NULL); if (! complete->priv->searching) { - g_warning ("e_completion_found_match(...,\"%s\",...) called outside of a search", text); + g_warning ("e_completion_found_match(...,\"%s\",...) called outside of a search", match->match_text); return; } - e_completion_add_match (complete, text, score, extra_data, extra_destroy); + e_completion_add_match (complete, match); /* For now, do nothing when we hit the limit --- just don't announce the incoming matches. */ if (complete->priv->match_count >= complete->priv->limit) { + e_completion_match_unref (match); return; } - gtk_signal_emit (GTK_OBJECT (complete), e_completion_signals[E_COMPLETION_COMPLETION], text, extra_data); + gtk_signal_emit (GTK_OBJECT (complete), e_completion_signals[E_COMPLETION_COMPLETION], match); + } void @@ -468,7 +407,7 @@ e_completion_end_search (ECompletion *complete) g_return_if_fail (complete->priv->searching); /* If sorting by score accomplishes anything, issue a restart right before we end. */ - if (e_completion_sort_by_score (complete)) + if (e_completion_sort (complete)) e_completion_restart (complete); gtk_signal_emit (GTK_OBJECT (complete), e_completion_signals[E_COMPLETION_END_COMPLETION]); diff --git a/widgets/text/e-completion.h b/widgets/text/e-completion.h index e101d6aa55..4a06059065 100644 --- a/widgets/text/e-completion.h +++ b/widgets/text/e-completion.h @@ -30,6 +30,7 @@ #include #include +#include "e-completion-match.h" BEGIN_GNOME_DECLS @@ -43,8 +44,6 @@ typedef struct _ECompletion ECompletion; typedef struct _ECompletionClass ECompletionClass; struct _ECompletionPrivate; -typedef void (*ECompletionMatchFn) (const gchar *text, double score, gpointer extra_data, gpointer user_data); - struct _ECompletion { GtkObject parent; @@ -56,7 +55,7 @@ struct _ECompletionClass { /* Signals */ void (*begin_completion) (ECompletion *comp, const gchar *search_text, gint pos, gint limit); - void (*completion) (ECompletion *comp, const gchar *match_text, gpointer extra_data); + void (*completion) (ECompletion *comp, ECompletionMatch *match); void (*restart_completion) (ECompletion *comp); void (*cancel_completion) (ECompletion *comp); void (*end_completion) (ECompletion *comp); @@ -72,7 +71,6 @@ const gchar *e_completion_search_text (ECompletion *comp); gint e_completion_search_text_pos (ECompletion *comp); gint e_completion_match_count (ECompletion *comp); void e_completion_foreach_match (ECompletion *comp, ECompletionMatchFn fn, gpointer user_data); -gpointer e_completion_find_extra_data (ECompletion *comp, const gchar *text); ECompletion *e_completion_new (void); @@ -81,10 +79,8 @@ ECompletion *e_completion_new (void); /* These functions should only be called by derived classes or search callbacks, or very bad things might happen. */ -void e_completion_found_match (ECompletion *comp, const gchar *completion_text); -void e_completion_found_match_full (ECompletion *comp, const gchar *completion_text, double score, - gpointer extra_data, GtkDestroyNotify extra_data_destructor); -void e_completion_end_search (ECompletion *comp); +void e_completion_found_match (ECompletion *comp, ECompletionMatch *); +void e_completion_end_search (ECompletion *comp); END_GNOME_DECLS diff --git a/widgets/text/e-entry.c b/widgets/text/e-entry.c index 633222d871..022efa15f7 100644 --- a/widgets/text/e-entry.c +++ b/widgets/text/e-entry.c @@ -508,7 +508,7 @@ e_entry_show_popup (EEntry *entry, gboolean visible) gtk_widget_show (pop); - if (! entry->priv->ptr_grab) { + if (getenv ("GAL_E_ENTRY_NO_GRABS_HACK") == NULL && !entry->priv->ptr_grab) { entry->priv->ptr_grab = (0 == gdk_pointer_grab (GTK_WIDGET (entry->priv->completion_view)->window, TRUE, grab_mask, NULL, NULL, GDK_CURRENT_TIME)); if (entry->priv->ptr_grab) { @@ -614,11 +614,11 @@ full_cb (ECompletionView *view, gpointer user_data) } static void -browse_cb (ECompletionView *view, const gchar *txt, gpointer user_data) +browse_cb (ECompletionView *view, ECompletionMatch *match, gpointer user_data) { EEntry *entry = E_ENTRY (user_data); - - if (txt == NULL) { + + if (match == NULL) { /* Requesting a completion. */ e_entry_start_completion (entry); return; @@ -630,7 +630,7 @@ browse_cb (ECompletionView *view, const gchar *txt, gpointer user_data) /* If there is no other handler in place, echo the selected completion in the entry. */ if (entry->priv->handler == NULL) - e_entry_set_text_quiet (entry, txt); + e_entry_set_text_quiet (entry, e_completion_match_get_match_text (match)); } static void @@ -651,7 +651,7 @@ unbrowse_cb (ECompletionView *view, gpointer user_data) } static void -activate_cb (ECompletionView *view, const gchar *txt, gpointer extra_data, gpointer user_data) +activate_cb (ECompletionView *view, ECompletionMatch *match, gpointer user_data) { EEntry *entry = E_ENTRY (user_data); @@ -662,9 +662,9 @@ activate_cb (ECompletionView *view, const gchar *txt, gpointer extra_data, gpoin e_entry_show_popup (entry, FALSE); if (entry->priv->handler) - entry->priv->handler (entry, txt, extra_data); + entry->priv->handler (entry, match); else - e_entry_set_text (entry, txt); + e_entry_set_text (entry, match->match_text); e_entry_cancel_delayed_completion (entry); } diff --git a/widgets/text/e-entry.h b/widgets/text/e-entry.h index 373a6843e9..948bb8a4b2 100644 --- a/widgets/text/e-entry.h +++ b/widgets/text/e-entry.h @@ -51,7 +51,7 @@ typedef struct _EEntry EEntry; typedef struct _EEntryClass EEntryClass; struct _EEntryPrivate; -typedef void (*EEntryCompletionHandler) (EEntry *entry, const gchar *text, gpointer extra_data); +typedef void (*EEntryCompletionHandler) (EEntry *entry, ECompletionMatch *match); struct _EEntry { GtkTable parent; diff --git a/widgets/text/e-text.c b/widgets/text/e-text.c index b2eb2ad3b0..f605a65a34 100644 --- a/widgets/text/e-text.c +++ b/widgets/text/e-text.c @@ -2962,7 +2962,7 @@ e_text_event (GnomeCanvasItem *item, GdkEvent *event) e_tep_event.key.time = key.time; e_tep_event.key.state = key.state; e_tep_event.key.keyval = key.keyval; - + // g_print ("etext got keyval \"%s\"\n", gdk_keyval_name (key.keyval)); /* This is probably ugly hack, but we have to handle UTF-8 input somehow */ @@ -2980,11 +2980,14 @@ e_text_event (GnomeCanvasItem *item, GdkEvent *event) _get_tep(text); ret = e_text_event_processor_handle_event (text->tep, &e_tep_event); - if (e_tep_event.key.string) g_free (e_tep_event.key.string); - if (event->type == GDK_KEY_PRESS) gtk_signal_emit (GTK_OBJECT (text), e_text_signals[E_TEXT_KEYPRESS], e_tep_event.key.keyval, e_tep_event.key.state); + + + if (e_tep_event.key.string) + g_free (e_tep_event.key.string); + return ret; } -- cgit v1.2.3