diff --git a/ChangeLog b/ChangeLog index eeca7b0cca..d7f0770540 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2007-04-28 Xan Lopez + + * gtk/gtkentry.c: + * gtk/gtkentrycompletion.c: + * gtk/gtkentrycompletion.h: + * gtk/gtkentryprivate.h: + + Rember the user input that triggered the completion, add + API to the retrieve it and reset the entry contents to it + if the user cancels the tentative completion during + the inline-selection. + 2007-04-27 Matthias Clasen * gdk/x11/gdkgeometry-x11.c: Factor out window movement diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c index 992ac6f00b..2a52c18b6f 100644 --- a/gtk/gtkentry.c +++ b/gtk/gtkentry.c @@ -5691,7 +5691,12 @@ gtk_entry_completion_key_press (GtkWidget *widget, sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (completion->priv->tree_view)); if (!gtk_tree_selection_get_selected (sel, &model, &iter)) return FALSE; - + + if (completion->priv->completion_prefix == NULL) + { + completion->priv->completion_prefix = g_strdup (gtk_entry_get_text (GTK_ENTRY (completion->priv->entry))); + } + g_signal_emit_by_name (completion, "cursor_on_match", model, &iter, &entry_set); } @@ -5720,10 +5725,23 @@ gtk_entry_completion_key_press (GtkWidget *widget, if (completion->priv->inline_selection) { + /* Escape rejects the tentative completion */ if (event->keyval == GDK_Escape) - gtk_editable_delete_selection (GTK_EDITABLE (widget)); - /* Move the cursor to the end */ - gtk_editable_set_position (GTK_EDITABLE (widget), -1); + { + gtk_entry_set_text (GTK_ENTRY (completion->priv->entry), completion->priv->completion_prefix); + } + + /* Move the cursor to the end for Right/Esc, to the + beginning for Left */ + if (event->keyval == GDK_Right || + event->keyval == GDK_KP_Right || + event->keyval == GDK_Escape) + gtk_editable_set_position (GTK_EDITABLE (widget), -1); + else + gtk_editable_set_position (GTK_EDITABLE (widget), 0); + + g_free (completion->priv->completion_prefix); + completion->priv->completion_prefix = NULL; } return TRUE; @@ -5737,7 +5755,13 @@ gtk_entry_completion_key_press (GtkWidget *widget, _gtk_entry_reset_im_context (GTK_ENTRY (widget)); _gtk_entry_completion_popdown (completion); - + + if (completion->priv->completion_prefix) + { + g_free (completion->priv->completion_prefix); + completion->priv->completion_prefix = NULL; + } + gtk_widget_child_focus (gtk_widget_get_toplevel (widget), dir); return TRUE; diff --git a/gtk/gtkentrycompletion.c b/gtk/gtkentrycompletion.c index f4d74d62f4..0760e04a7b 100644 --- a/gtk/gtkentrycompletion.c +++ b/gtk/gtkentrycompletion.c @@ -67,71 +67,71 @@ enum #define GTK_ENTRY_COMPLETION_GET_PRIVATE(obj)(G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_ENTRY_COMPLETION, GtkEntryCompletionPrivate)) -static void gtk_entry_completion_cell_layout_init (GtkCellLayoutIface *iface); -static void gtk_entry_completion_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void gtk_entry_completion_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void gtk_entry_completion_finalize (GObject *object); +static void gtk_entry_completion_cell_layout_init (GtkCellLayoutIface *iface); +static void gtk_entry_completion_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void gtk_entry_completion_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void gtk_entry_completion_finalize (GObject *object); -static void gtk_entry_completion_pack_start (GtkCellLayout *cell_layout, - GtkCellRenderer *cell, - gboolean expand); -static void gtk_entry_completion_pack_end (GtkCellLayout *cell_layout, - GtkCellRenderer *cell, - gboolean expand); -static void gtk_entry_completion_clear (GtkCellLayout *cell_layout); -static void gtk_entry_completion_add_attribute (GtkCellLayout *cell_layout, - GtkCellRenderer *cell, - const char *attribute, - gint column); -static void gtk_entry_completion_set_cell_data_func (GtkCellLayout *cell_layout, - GtkCellRenderer *cell, - GtkCellLayoutDataFunc func, - gpointer func_data, - GDestroyNotify destroy); -static void gtk_entry_completion_clear_attributes (GtkCellLayout *cell_layout, - GtkCellRenderer *cell); -static void gtk_entry_completion_reorder (GtkCellLayout *cell_layout, - GtkCellRenderer *cell, - gint position); +static void gtk_entry_completion_pack_start (GtkCellLayout *cell_layout, + GtkCellRenderer *cell, + gboolean expand); +static void gtk_entry_completion_pack_end (GtkCellLayout *cell_layout, + GtkCellRenderer *cell, + gboolean expand); +static void gtk_entry_completion_clear (GtkCellLayout *cell_layout); +static void gtk_entry_completion_add_attribute (GtkCellLayout *cell_layout, + GtkCellRenderer *cell, + const char *attribute, + gint column); +static void gtk_entry_completion_set_cell_data_func (GtkCellLayout *cell_layout, + GtkCellRenderer *cell, + GtkCellLayoutDataFunc func, + gpointer func_data, + GDestroyNotify destroy); +static void gtk_entry_completion_clear_attributes (GtkCellLayout *cell_layout, + GtkCellRenderer *cell); +static void gtk_entry_completion_reorder (GtkCellLayout *cell_layout, + GtkCellRenderer *cell, + gint position); -static gboolean gtk_entry_completion_visible_func (GtkTreeModel *model, - GtkTreeIter *iter, - gpointer data); -static gboolean gtk_entry_completion_popup_key_event (GtkWidget *widget, - GdkEventKey *event, - gpointer user_data); -static gboolean gtk_entry_completion_popup_button_press (GtkWidget *widget, - GdkEventButton *event, - gpointer user_data); -static gboolean gtk_entry_completion_list_button_press (GtkWidget *widget, - GdkEventButton *event, - gpointer user_data); -static gboolean gtk_entry_completion_action_button_press (GtkWidget *widget, - GdkEventButton *event, - gpointer user_data); -static void gtk_entry_completion_selection_changed (GtkTreeSelection *selection, - gpointer data); -static gboolean gtk_entry_completion_list_enter_notify (GtkWidget *widget, - GdkEventCrossing *event, - gpointer data); -static gboolean gtk_entry_completion_list_motion_notify (GtkWidget *widget, - GdkEventMotion *event, - gpointer data); -static void gtk_entry_completion_insert_action (GtkEntryCompletion *completion, - gint index, - const gchar *string, - gboolean markup); -static void gtk_entry_completion_action_data_func (GtkTreeViewColumn *tree_column, - GtkCellRenderer *cell, - GtkTreeModel *model, - GtkTreeIter *iter, - gpointer data); +static gboolean gtk_entry_completion_visible_func (GtkTreeModel *model, + GtkTreeIter *iter, + gpointer data); +static gboolean gtk_entry_completion_popup_key_event (GtkWidget *widget, + GdkEventKey *event, + gpointer user_data); +static gboolean gtk_entry_completion_popup_button_press (GtkWidget *widget, + GdkEventButton *event, + gpointer user_data); +static gboolean gtk_entry_completion_list_button_press (GtkWidget *widget, + GdkEventButton *event, + gpointer user_data); +static gboolean gtk_entry_completion_action_button_press (GtkWidget *widget, + GdkEventButton *event, + gpointer user_data); +static void gtk_entry_completion_selection_changed (GtkTreeSelection *selection, + gpointer data); +static gboolean gtk_entry_completion_list_enter_notify (GtkWidget *widget, + GdkEventCrossing *event, + gpointer data); +static gboolean gtk_entry_completion_list_motion_notify (GtkWidget *widget, + GdkEventMotion *event, + gpointer data); +static void gtk_entry_completion_insert_action (GtkEntryCompletion *completion, + gint index, + const gchar *string, + gboolean markup); +static void gtk_entry_completion_action_data_func (GtkTreeViewColumn *tree_column, + GtkCellRenderer *cell, + GtkTreeModel *model, + GtkTreeIter *iter, + gpointer data); static gboolean gtk_entry_completion_match_selected (GtkEntryCompletion *completion, GtkTreeModel *model, @@ -141,6 +141,11 @@ static gboolean gtk_entry_completion_real_insert_prefix (GtkEntryCompletion *co static gboolean gtk_entry_completion_cursor_on_match (GtkEntryCompletion *completion, GtkTreeModel *model, GtkTreeIter *iter); +static gboolean gtk_entry_completion_insert_completion (GtkEntryCompletion *completion, + GtkTreeModel *model, + GtkTreeIter *iter); +static void gtk_entry_completion_insert_completion_text (GtkEntryCompletion *completion, + const gchar *text); static guint entry_completion_signals[LAST_SIGNAL] = { 0 }; @@ -1631,13 +1636,34 @@ gtk_entry_completion_real_insert_prefix (GtkEntryCompletion *completion, return TRUE; } -void +/** + * gtk_entry_completion_get_completion_prefix: + * @completion: a #GtkEntryCompletion + * + * Get the original text entered by the user that triggered + * the completion or NULL if there's no completion ongoing. + * + * Since: 2.12 + **/ + +const gchar* +gtk_entry_completion_get_completion_prefix (GtkEntryCompletion *completion) +{ + g_return_val_if_fail (GTK_IS_ENTRY_COMPLETION (completion), NULL); + + return completion->priv->completion_prefix; +} + +static void gtk_entry_completion_insert_completion_text (GtkEntryCompletion *completion, const gchar *text) { GtkEntryCompletionPrivate *priv = completion->priv; + gchar *needle; gint len; + priv = completion->priv; + if (priv->changed_id > 0) { g_signal_handler_block (priv->entry, @@ -1650,9 +1676,15 @@ gtk_entry_completion_insert_completion_text (GtkEntryCompletion *completion, completion->priv->insert_text_id); } - gtk_editable_get_selection_bounds (GTK_EDITABLE (priv->entry), &len, NULL); gtk_entry_set_text (GTK_ENTRY (priv->entry), text); - gtk_editable_select_region (GTK_EDITABLE (priv->entry), len, -1); + needle = g_strstr_len (text, -1, completion->priv->completion_prefix); + if (needle) + { + len = g_utf8_strlen (text, -1) - g_utf8_strlen (needle, -1) + + g_utf8_strlen (priv->completion_prefix, -1); + gtk_editable_select_region (GTK_EDITABLE (priv->entry), + len, -1); + } if (priv->changed_id > 0) { @@ -1667,15 +1699,13 @@ gtk_entry_completion_insert_completion_text (GtkEntryCompletion *completion, } } -gboolean +static gboolean gtk_entry_completion_insert_completion (GtkEntryCompletion *completion, GtkTreeModel *model, GtkTreeIter *iter) { gchar *str = NULL; - g_return_val_if_fail (GTK_IS_TREE_MODEL (model), FALSE); - if (completion->priv->text_column < 0) return FALSE; diff --git a/gtk/gtkentrycompletion.h b/gtk/gtkentrycompletion.h index 26285d2ac6..19cacc8507 100644 --- a/gtk/gtkentrycompletion.h +++ b/gtk/gtkentrycompletion.h @@ -119,8 +119,7 @@ void gtk_entry_completion_set_popup_single_match (GtkEntryComplet gboolean popup_single_match); gboolean gtk_entry_completion_get_popup_single_match (GtkEntryCompletion *completion); -void gtk_entry_completion_insert_completion_text (GtkEntryCompletion *completion, - const gchar *text); +const gchar *gtk_entry_completion_get_completion_prefix (GtkEntryCompletion *completion); /* convenience */ void gtk_entry_completion_set_text_column (GtkEntryCompletion *completion, gint column); diff --git a/gtk/gtkentryprivate.h b/gtk/gtkentryprivate.h index 696f744401..a7678002b8 100644 --- a/gtk/gtkentryprivate.h +++ b/gtk/gtkentryprivate.h @@ -66,6 +66,8 @@ struct _GtkEntryCompletionPrivate guint popup_single_match : 1; guint inline_selection : 1; + gchar *completion_prefix; + GSource *check_completion_idle; };