aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--widgets/text/e-completion-match.c184
-rw-r--r--widgets/text/e-completion-match.h72
-rw-r--r--widgets/text/e-completion-test.c10
-rw-r--r--widgets/text/e-completion-view.c27
-rw-r--r--widgets/text/e-completion-view.h4
-rw-r--r--widgets/text/e-completion.c149
-rw-r--r--widgets/text/e-completion.h12
-rw-r--r--widgets/text/e-entry.c16
-rw-r--r--widgets/text/e-entry.h2
-rw-r--r--widgets/text/e-text.c9
10 files changed, 342 insertions, 143 deletions
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 <trow@ximian.com>
+ */
+
+/*
+ * 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 <config.h>
+#include <gal/unicode/gunicode.h>
+#include <gal/widgets/e-unicode.h>
+#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 <trow@ximian.com>
+ */
+
+/*
+ * 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 <glib.h>
+#include <libgnome/gnome-defs.h>
+#include <gtk/gtkwidget.h>
+
+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 <config.h>
-#include <string.h> /* strcmp() */
+#include <stdio.h>
#include <gtk/gtk.h>
#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 <libgnome/gnome-defs.h>
#include <gtk/gtkobject.h>
+#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;
}