forked from AuroraMiddleware/gtk
Support inline-selection in entries (#318459)
Support inline-selection in entries (#318459) * gtk/gtkentry.c: * gtk/gtkentrycompletion.c: * gtk/gtkentrycompletion.h: * gtk/gtkentryprivate.h: When enabled cursor-match is emited when the cursor is on a possible completion on the list. The default implementation will replace the contents on the entry with the contents of the text column in the completion model. Review and improvements by Matthias Clasen. svn path=/trunk/; revision=17660
This commit is contained in:
parent
533d3fcc76
commit
f478d9f0f6
16
ChangeLog
16
ChangeLog
@ -1,3 +1,19 @@
|
||||
2007-04-27 Xan Lopez <xan@gnome.org>
|
||||
|
||||
Support inline-selection in entries (#318459)
|
||||
|
||||
* gtk/gtkentry.c:
|
||||
* gtk/gtkentrycompletion.c:
|
||||
* gtk/gtkentrycompletion.h:
|
||||
* gtk/gtkentryprivate.h:
|
||||
|
||||
When enabled cursor-match is emited when the cursor is on
|
||||
a possible completion on the list. The default implementation
|
||||
will replace the contents on the entry with the contents of
|
||||
the text column in the completion model.
|
||||
|
||||
Review and improvements by Matthias Clasen.
|
||||
|
||||
2007-04-27 Michael Natterer <mitch@imendio.com>
|
||||
|
||||
Merged heavily modified patch from maemo-gtk which enables opening
|
||||
|
@ -5679,6 +5679,22 @@ gtk_entry_completion_key_press (GtkWidget *widget,
|
||||
path = gtk_tree_path_new_from_indices (completion->priv->current_selected, -1);
|
||||
gtk_tree_view_set_cursor (GTK_TREE_VIEW (completion->priv->tree_view),
|
||||
path, NULL, FALSE);
|
||||
|
||||
if (completion->priv->inline_selection)
|
||||
{
|
||||
|
||||
GtkTreeIter iter;
|
||||
GtkTreeModel *model = NULL;
|
||||
GtkTreeSelection *sel;
|
||||
gboolean entry_set;
|
||||
|
||||
sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (completion->priv->tree_view));
|
||||
if (!gtk_tree_selection_get_selected (sel, &model, &iter))
|
||||
return FALSE;
|
||||
|
||||
g_signal_emit_by_name (completion, "cursor_on_match", model,
|
||||
&iter, &entry_set);
|
||||
}
|
||||
}
|
||||
else if (completion->priv->current_selected - matches >= 0)
|
||||
{
|
||||
@ -5693,11 +5709,23 @@ gtk_entry_completion_key_press (GtkWidget *widget,
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else if (event->keyval == GDK_Escape)
|
||||
else if (event->keyval == GDK_Escape ||
|
||||
event->keyval == GDK_Left ||
|
||||
event->keyval == GDK_KP_Left ||
|
||||
event->keyval == GDK_Right ||
|
||||
event->keyval == GDK_KP_Right)
|
||||
{
|
||||
_gtk_entry_reset_im_context (GTK_ENTRY (widget));
|
||||
_gtk_entry_completion_popdown (completion);
|
||||
|
||||
if (completion->priv->inline_selection)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else if (event->keyval == GDK_Tab ||
|
||||
@ -5750,7 +5778,7 @@ gtk_entry_completion_key_press (GtkWidget *widget,
|
||||
/* move the cursor to the end */
|
||||
gtk_editable_set_position (GTK_EDITABLE (widget), -1);
|
||||
|
||||
g_free (str);
|
||||
g_free (str);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@ -5880,12 +5908,18 @@ disconnect_completion_signals (GtkEntry *entry,
|
||||
G_CALLBACK (completion_changed), entry);
|
||||
if (completion->priv->changed_id > 0 &&
|
||||
g_signal_handler_is_connected (entry, completion->priv->changed_id))
|
||||
g_signal_handler_disconnect (entry, completion->priv->changed_id);
|
||||
{
|
||||
g_signal_handler_disconnect (entry, completion->priv->changed_id);
|
||||
completion->priv->changed_id = 0;
|
||||
}
|
||||
g_signal_handlers_disconnect_by_func (entry,
|
||||
G_CALLBACK (gtk_entry_completion_key_press), completion);
|
||||
if (completion->priv->insert_text_id > 0 &&
|
||||
g_signal_handler_is_connected (entry, completion->priv->insert_text_id))
|
||||
g_signal_handler_disconnect (entry, completion->priv->insert_text_id);
|
||||
{
|
||||
g_signal_handler_disconnect (entry, completion->priv->insert_text_id);
|
||||
completion->priv->insert_text_id = 0;
|
||||
}
|
||||
g_signal_handlers_disconnect_by_func (entry,
|
||||
G_CALLBACK (completion_insert_text_callback), completion);
|
||||
g_signal_handlers_disconnect_by_func (entry,
|
||||
@ -5919,6 +5953,7 @@ connect_completion_signals (GtkEntry *entry,
|
||||
g_signal_connect (entry, "focus_out_event",
|
||||
G_CALLBACK (accept_completion_callback), completion);
|
||||
}
|
||||
|
||||
g_signal_connect (completion, "notify",
|
||||
G_CALLBACK (completion_changed), entry);
|
||||
}
|
||||
|
@ -47,6 +47,7 @@ enum
|
||||
INSERT_PREFIX,
|
||||
MATCH_SELECTED,
|
||||
ACTION_ACTIVATED,
|
||||
CURSOR_ON_MATCH,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
@ -60,7 +61,8 @@ enum
|
||||
PROP_INLINE_COMPLETION,
|
||||
PROP_POPUP_COMPLETION,
|
||||
PROP_POPUP_SET_WIDTH,
|
||||
PROP_POPUP_SINGLE_MATCH
|
||||
PROP_POPUP_SINGLE_MATCH,
|
||||
PROP_INLINE_SELECTION
|
||||
};
|
||||
|
||||
#define GTK_ENTRY_COMPLETION_GET_PRIVATE(obj)(G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_ENTRY_COMPLETION, GtkEntryCompletionPrivate))
|
||||
@ -136,6 +138,9 @@ static gboolean gtk_entry_completion_match_selected (GtkEntryCompletion *co
|
||||
GtkTreeIter *iter);
|
||||
static gboolean gtk_entry_completion_real_insert_prefix (GtkEntryCompletion *completion,
|
||||
const gchar *prefix);
|
||||
static gboolean gtk_entry_completion_cursor_on_match (GtkEntryCompletion *completion,
|
||||
GtkTreeModel *model,
|
||||
GtkTreeIter *iter);
|
||||
|
||||
static guint entry_completion_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
@ -156,6 +161,7 @@ gtk_entry_completion_class_init (GtkEntryCompletionClass *klass)
|
||||
|
||||
klass->match_selected = gtk_entry_completion_match_selected;
|
||||
klass->insert_prefix = gtk_entry_completion_real_insert_prefix;
|
||||
klass->cursor_on_match = gtk_entry_completion_cursor_on_match;
|
||||
|
||||
/**
|
||||
* GtkEntryCompletion::insert-prefix:
|
||||
@ -210,6 +216,32 @@ gtk_entry_completion_class_init (GtkEntryCompletionClass *klass)
|
||||
G_TYPE_BOOLEAN, 2,
|
||||
GTK_TYPE_TREE_MODEL,
|
||||
GTK_TYPE_TREE_ITER);
|
||||
/**
|
||||
* GtkEntryCompletion::cursor-on-match:
|
||||
* @widget: the object which received the signal
|
||||
* @model: the #GtkTreeModel containing the matches
|
||||
* @iter: a #GtkTreeIter positioned at the selected match
|
||||
*
|
||||
* Gets emitted when a match from the cursor is on a match
|
||||
* of the list.The default behaviour is to replace the contents
|
||||
* of the entry with the contents of the text column in the row
|
||||
* pointed to by @iter.
|
||||
*
|
||||
* Return value: %TRUE if the signal has been handled
|
||||
*
|
||||
* Since: 2.12
|
||||
*/
|
||||
|
||||
entry_completion_signals[CURSOR_ON_MATCH] =
|
||||
g_signal_new (I_("cursor_on_match"),
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GtkEntryCompletionClass, cursor_on_match),
|
||||
_gtk_boolean_handled_accumulator, NULL,
|
||||
_gtk_marshal_BOOLEAN__OBJECT_BOXED,
|
||||
G_TYPE_BOOLEAN, 2,
|
||||
GTK_TYPE_TREE_MODEL,
|
||||
GTK_TYPE_TREE_ITER);
|
||||
|
||||
/**
|
||||
* GtkEntryCompletion::action-activated:
|
||||
@ -330,6 +362,21 @@ gtk_entry_completion_class_init (GtkEntryCompletionClass *klass)
|
||||
P_("If TRUE, the popup window will appear for a single match."),
|
||||
TRUE,
|
||||
GTK_PARAM_READWRITE));
|
||||
/**
|
||||
* GtkEntryCompletion:inline-selection:
|
||||
*
|
||||
* Determines whether the possible completions on the popup
|
||||
* will appear in the entry as you navigate through them.
|
||||
|
||||
* Since: 2.12
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_INLINE_SELECTION,
|
||||
g_param_spec_boolean ("inline-selection",
|
||||
P_("Inline selection"),
|
||||
P_("Your description here"),
|
||||
FALSE,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
g_type_class_add_private (object_class, sizeof (GtkEntryCompletionPrivate));
|
||||
}
|
||||
@ -364,6 +411,7 @@ gtk_entry_completion_init (GtkEntryCompletion *completion)
|
||||
priv->popup_completion = TRUE;
|
||||
priv->popup_set_width = TRUE;
|
||||
priv->popup_single_match = TRUE;
|
||||
priv->inline_selection = FALSE;
|
||||
|
||||
/* completions */
|
||||
priv->filter_model = NULL;
|
||||
@ -378,6 +426,7 @@ gtk_entry_completion_init (GtkEntryCompletion *completion)
|
||||
g_signal_connect (priv->tree_view, "motion_notify_event",
|
||||
G_CALLBACK (gtk_entry_completion_list_motion_notify),
|
||||
completion);
|
||||
|
||||
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->tree_view), FALSE);
|
||||
gtk_tree_view_set_hover_selection (GTK_TREE_VIEW (priv->tree_view), TRUE);
|
||||
|
||||
@ -505,6 +554,10 @@ gtk_entry_completion_set_property (GObject *object,
|
||||
priv->popup_single_match = g_value_get_boolean (value);
|
||||
break;
|
||||
|
||||
case PROP_INLINE_SELECTION:
|
||||
priv->inline_selection = g_value_get_boolean (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@ -550,6 +603,10 @@ gtk_entry_completion_get_property (GObject *object,
|
||||
g_value_set_boolean (value, gtk_entry_completion_get_popup_single_match (completion));
|
||||
break;
|
||||
|
||||
case PROP_INLINE_SELECTION:
|
||||
g_value_set_boolean (value, gtk_entry_completion_get_inline_selection (completion));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@ -1277,7 +1334,7 @@ gtk_entry_completion_list_motion_notify (GtkWidget *widget,
|
||||
{
|
||||
GtkEntryCompletion *completion = GTK_ENTRY_COMPLETION (data);
|
||||
|
||||
completion->priv->ignore_enter = FALSE;
|
||||
completion->priv->ignore_enter = FALSE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@ -1468,6 +1525,15 @@ gtk_entry_completion_match_selected (GtkEntryCompletion *completion,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_entry_completion_cursor_on_match (GtkEntryCompletion *completion,
|
||||
GtkTreeModel *model,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
gtk_entry_completion_insert_completion (completion, model, iter);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gchar *
|
||||
gtk_entry_completion_compute_prefix (GtkEntryCompletion *completion)
|
||||
@ -1565,6 +1631,65 @@ gtk_entry_completion_real_insert_prefix (GtkEntryCompletion *completion,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_entry_completion_insert_completion_text (GtkEntryCompletion *completion,
|
||||
const gchar *text)
|
||||
{
|
||||
GtkEntryCompletionPrivate *priv = completion->priv;
|
||||
gint len;
|
||||
|
||||
if (priv->changed_id > 0)
|
||||
{
|
||||
g_signal_handler_block (priv->entry,
|
||||
priv->changed_id);
|
||||
}
|
||||
|
||||
if (priv->insert_text_id > 0)
|
||||
{
|
||||
g_signal_handler_block (completion->priv->entry,
|
||||
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);
|
||||
|
||||
if (priv->changed_id > 0)
|
||||
{
|
||||
g_signal_handler_unblock (priv->entry,
|
||||
priv->changed_id);
|
||||
}
|
||||
|
||||
if (priv->insert_text_id > 0)
|
||||
{
|
||||
g_signal_handler_unblock (priv->entry,
|
||||
priv->insert_text_id);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
gtk_tree_model_get (model, iter,
|
||||
completion->priv->text_column, &str,
|
||||
-1);
|
||||
|
||||
gtk_entry_completion_insert_completion_text (completion, str);
|
||||
|
||||
g_free (str);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_entry_completion_insert_prefix:
|
||||
* @completion: a #GtkEntryCompletion
|
||||
@ -1573,6 +1698,7 @@ gtk_entry_completion_real_insert_prefix (GtkEntryCompletion *completion,
|
||||
*
|
||||
* Since: 2.6
|
||||
**/
|
||||
|
||||
void
|
||||
gtk_entry_completion_insert_prefix (GtkEntryCompletion *completion)
|
||||
{
|
||||
@ -1622,7 +1748,6 @@ gtk_entry_completion_set_inline_completion (GtkEntryCompletion *completion,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gtk_entry_completion_get_inline_completion:
|
||||
* @completion: a #GtkEntryCompletion
|
||||
@ -1782,6 +1907,29 @@ gtk_entry_completion_get_popup_single_match (GtkEntryCompletion *completion)
|
||||
return completion->priv->popup_single_match;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_entry_completion_set_inline_selection (GtkEntryCompletion *completion,
|
||||
gboolean inline_selection)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_ENTRY_COMPLETION (completion));
|
||||
|
||||
inline_selection = inline_selection != FALSE;
|
||||
|
||||
if (completion->priv->inline_selection != inline_selection)
|
||||
{
|
||||
completion->priv->inline_selection = inline_selection;
|
||||
|
||||
g_object_notify (G_OBJECT (completion), "inline-selection");
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_entry_completion_get_inline_selection (GtkEntryCompletion *completion)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_ENTRY_COMPLETION (completion), FALSE);
|
||||
|
||||
return completion->priv->inline_selection;
|
||||
}
|
||||
|
||||
#define __GTK_ENTRY_COMPLETION_C__
|
||||
#include "gtkaliasdef.c"
|
||||
|
@ -65,11 +65,13 @@ struct _GtkEntryCompletionClass
|
||||
gint index_);
|
||||
gboolean (* insert_prefix) (GtkEntryCompletion *completion,
|
||||
const gchar *prefix);
|
||||
gboolean (* cursor_on_match) (GtkEntryCompletion *completion,
|
||||
GtkTreeModel *model,
|
||||
GtkTreeIter *iter);
|
||||
|
||||
/* Padding for future expansion */
|
||||
void (*_gtk_reserved0) (void);
|
||||
void (*_gtk_reserved1) (void);
|
||||
void (*_gtk_reserved2) (void);
|
||||
};
|
||||
|
||||
/* core */
|
||||
@ -104,6 +106,9 @@ void gtk_entry_completion_delete_action (GtkEntryComplet
|
||||
void gtk_entry_completion_set_inline_completion (GtkEntryCompletion *completion,
|
||||
gboolean inline_completion);
|
||||
gboolean gtk_entry_completion_get_inline_completion (GtkEntryCompletion *completion);
|
||||
void gtk_entry_completion_set_inline_selection (GtkEntryCompletion *completion,
|
||||
gboolean inline_selection);
|
||||
gboolean gtk_entry_completion_get_inline_selection (GtkEntryCompletion *completion);
|
||||
void gtk_entry_completion_set_popup_completion (GtkEntryCompletion *completion,
|
||||
gboolean popup_completion);
|
||||
gboolean gtk_entry_completion_get_popup_completion (GtkEntryCompletion *completion);
|
||||
@ -114,7 +119,8 @@ 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);
|
||||
/* convenience */
|
||||
void gtk_entry_completion_set_text_column (GtkEntryCompletion *completion,
|
||||
gint column);
|
||||
|
@ -64,6 +64,8 @@ struct _GtkEntryCompletionPrivate
|
||||
guint popup_completion : 1;
|
||||
guint popup_set_width : 1;
|
||||
guint popup_single_match : 1;
|
||||
guint inline_selection : 1;
|
||||
|
||||
GSource *check_completion_idle;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user