[maemo-commits] [maemo-commits] r9138 - in projects/haf/branches/gtk+/maemo-gtk-2-10: . gtk
From: subversion at stage.maemo.org subversion at stage.maemo.orgDate: Tue Jan 16 17:48:31 EET 2007
- Previous message: [maemo-commits] r9137 - projects/haf/hafbuildbot
- Next message: [maemo-commits] r9139 - projects/haf/trunk/gtk+/gtk
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Author: mitch Date: 2007-01-16 17:48:27 +0200 (Tue, 16 Jan 2007) New Revision: 9138 Modified: projects/haf/branches/gtk+/maemo-gtk-2-10/ChangeLog projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkentry.c Log: 2007-01-16 Michael Natterer <mitch at imendio.com> * gtk/gtkentry.c: port over all IM, invalid-input and hildon-input-mode related changes with one small exception (commented on in the code). Modified: projects/haf/branches/gtk+/maemo-gtk-2-10/ChangeLog =================================================================== --- projects/haf/branches/gtk+/maemo-gtk-2-10/ChangeLog 2007-01-16 15:04:41 UTC (rev 9137) +++ projects/haf/branches/gtk+/maemo-gtk-2-10/ChangeLog 2007-01-16 15:48:27 UTC (rev 9138) @@ -1,3 +1,9 @@ +2007-01-16 Michael Natterer <mitch at imendio.com> + + * gtk/gtkentry.c: port over all IM, invalid-input and + hildon-input-mode related changes with one small exception + (commented on in the code). + 2007-01-14 Kristian Rietveld <kris at imendio.com> * gtk/gtktreeselection.c (tree_column_is_sensitive), Modified: projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkentry.c =================================================================== --- projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkentry.c 2007-01-16 15:04:41 UTC (rev 9137) +++ projects/haf/branches/gtk+/maemo-gtk-2-10/gtk/gtkentry.c 2007-01-16 15:48:27 UTC (rev 9138) @@ -105,6 +105,9 @@ COPY_CLIPBOARD, PASTE_CLIPBOARD, TOGGLE_OVERWRITE, + /* MAEMO START */ + INVALID_INPUT, + /* MAEMO END */ LAST_SIGNAL }; @@ -124,6 +127,9 @@ PROP_TEXT, PROP_XALIGN, PROP_TRUNCATE_MULTILINE + /* MAEMO START */ + , PROP_HILDON_INPUT_MODE + /* MAEMO END */ }; static guint signals[LAST_SIGNAL] = { 0 }; @@ -280,6 +286,13 @@ gint offset, gint n_chars, GtkEntry *entry); +/* MAEMO START */ +static gboolean gtk_entry_has_selection_cb (GtkIMContext *context, + GtkEntry *entry); +static void gtk_entry_clipboard_operation_cb (GtkIMContext *context, + GtkIMContextClipboardOperation op, + GtkEntry *entry); +/* MAEMO END */ /* Internal routines */ @@ -592,6 +605,25 @@ FALSE, GTK_PARAM_READWRITE)); + /* MAEMO START */ + /** + * GtkEntry:hildon-input-mode: + * + * Allowed characters and input mode for the entry. See #HildonGtkInputMode. + * + * Since: maemo 2.0 + **/ + g_object_class_install_property (gobject_class, + PROP_HILDON_INPUT_MODE, + g_param_spec_flags ("hildon-input-mode", + P_("Hildon input mode"), + P_("Define widget's input mode"), + GTK_TYPE_GTK_INPUT_MODE, + HILDON_GTK_INPUT_MODE_FULL | + HILDON_GTK_INPUT_MODE_AUTOCAP, + GTK_PARAM_READWRITE)); + /* MAEMO START */ + signals[POPULATE_POPUP] = g_signal_new (I_("populate_popup"), G_OBJECT_CLASS_TYPE (gobject_class), @@ -692,6 +724,27 @@ _gtk_marshal_VOID__VOID, G_TYPE_NONE, 0); + /* MAEMO START */ + /** + * GtkEntry::invalid-input: + * + * Emitted when the users enters a character that does not belong to the + * #HildonGtkInputMode of the entry, or the maximum number of characters + * has been reached. + * + * Since: maemo 1.0 + */ + signals[INVALID_INPUT] = + g_signal_new ("invalid_input", + G_OBJECT_CLASS_TYPE (gobject_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (GtkEntryClass, invalid_input), + NULL, NULL, + _gtk_marshal_VOID__ENUM, + G_TYPE_NONE, 1, + GTK_TYPE_INVALID_INPUT_TYPE); + /* MAEMO END */ + /* * Key bindings */ @@ -962,7 +1015,23 @@ break; case PROP_VISIBILITY: - gtk_entry_set_visibility (entry, g_value_get_boolean (value)); + /* MAEMO START */ + /* gtk_entry_set_visibility (entry, g_value_get_boolean (value)); */ + { + /* converting to hildon input mode first then through + * that mode changing function to reach compatible with + * the gtk original visibility changing + */ + HildonGtkInputMode mode = hildon_gtk_entry_get_input_mode (entry); + + if (g_value_get_boolean (value)) + mode &= ~HILDON_GTK_INPUT_MODE_INVISIBLE; + else + mode |= HILDON_GTK_INPUT_MODE_INVISIBLE; + + hildon_gtk_entry_set_input_mode (entry, mode); + } + /* MAEMO END */ break; case PROP_HAS_FRAME: @@ -997,6 +1066,12 @@ entry->truncate_multiline = g_value_get_boolean (value); break; + /* MAEMO START */ + case PROP_HILDON_INPUT_MODE: + hildon_gtk_entry_set_input_mode (entry, g_value_get_flags (value)); + break; + /* MAEMO END */ + case PROP_SCROLL_OFFSET: case PROP_CURSOR_POSITION: default: @@ -1057,6 +1132,11 @@ case PROP_TRUNCATE_MULTILINE: g_value_set_boolean (value, entry->truncate_multiline); break; + /* MAEMO START */ + case PROP_HILDON_INPUT_MODE: + g_value_set_flags (value, hildon_gtk_entry_get_input_mode (entry)); + break; + /* MAEMO END */ default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -1105,6 +1185,12 @@ G_CALLBACK (gtk_entry_retrieve_surrounding_cb), entry); g_signal_connect (entry->im_context, "delete_surrounding", G_CALLBACK (gtk_entry_delete_surrounding_cb), entry); + /* MAEMO START */ + g_signal_connect (entry->im_context, "has_selection", + G_CALLBACK (gtk_entry_has_selection_cb), entry); + g_signal_connect (entry->im_context, "clipboard_operation", + G_CALLBACK (gtk_entry_clipboard_operation_cb), entry); + /* MAEMO END */ } /* @@ -1620,6 +1706,18 @@ (entry->button && event->button != entry->button)) return FALSE; + /* MAEMO START */ + if (entry->editable) + { + if (hildon_gtk_im_context_filter_event (entry->im_context, + (GdkEvent *) event)) + { + entry->need_im_reset = TRUE; + return TRUE; + } + } + /* MAEMO END */ + entry->button = event->button; if (!GTK_WIDGET_HAS_FOCUS (widget)) @@ -1628,7 +1726,12 @@ gtk_widget_grab_focus (widget); entry->in_click = FALSE; } - + + /* MAEMO START */ + /* we need to reset IM context so pre-edit string can be committed */ + _gtk_entry_reset_im_context (entry); + /* MAEMO END */ + tmp_pos = gtk_entry_find_position (entry, event->x + entry->scroll_offset); if (event->button == 1) @@ -1640,8 +1743,10 @@ if (event->state & GDK_SHIFT_MASK) { - _gtk_entry_reset_im_context (entry); - + /* MAEMO START */ + /* _gtk_entry_reset_im_context (entry); */ + /* MAEMO END */ + if (!have_selection) /* select from the current position to the clicked position */ sel_start = sel_end = entry->current_pos; @@ -1745,6 +1850,13 @@ } else if (event->button == 3 && event->type == GDK_BUTTON_PRESS) { + /* MAEMO START */ + /* FIXME: maemo-gtk-2-6 has some obscure code here to prevent + * copy/cut for invisible entries, but that code looks bogus, left + * it out + */ + /* MAEMO END */ + gtk_entry_do_popup (entry, event); entry->button = 0; /* Don't wait for release, since the menu will gtk_grab_add */ @@ -1763,6 +1875,18 @@ if (event->window != entry->text_area || entry->button != event->button) return FALSE; + /* MAEMO START */ + if (entry->editable) + { + if (hildon_gtk_im_context_filter_event (entry->im_context, + (GdkEvent *) event)) + { + entry->need_im_reset = TRUE; + return TRUE; + } + } + /* MAEMO END */ + if (entry->in_drag) { gint tmp_pos = gtk_entry_find_position (entry, entry->drag_start_x); @@ -2241,9 +2365,11 @@ start = entry->text_length; if (end < 0) end = entry->text_length; - - _gtk_entry_reset_im_context (entry); + /* MAEMO START */ + /* _gtk_entry_reset_im_context (entry); */ + /* MAEMO END */ + gtk_entry_set_positions (entry, MIN (end, entry->text_length), MIN (start, entry->text_length)); @@ -2335,6 +2461,83 @@ g_free (password_hint); } +/* MAEMO START */ + +/* Returns TRUE if chr is valid in given input mode. Probably should be made + * public, but there's no good place for it and the input mode design might + * change, so for now we'll keep this here. + */ +static gboolean +hildon_gtk_input_mode_is_valid_char (HildonGtkInputMode mode, + gunichar chr) +{ + static const char *tele_chars_ascii = "pwPW/().-+*#?, "; + + if (g_unichar_isalpha (chr) || chr == ' ') + { + if ((mode & HILDON_GTK_INPUT_MODE_ALPHA) != 0) + return TRUE; + if ((mode & HILDON_GTK_INPUT_MODE_HEXA) != 0 && g_unichar_isxdigit(chr)) + return TRUE; + } + else if (g_unichar_isdigit (chr)) + { + if ((mode & (HILDON_GTK_INPUT_MODE_NUMERIC | + HILDON_GTK_INPUT_MODE_HEXA | + HILDON_GTK_INPUT_MODE_TELE)) != 0) + return TRUE; + } + else + { + /* special = anything else than alphanumeric/space */ + if ((mode & HILDON_GTK_INPUT_MODE_SPECIAL) != 0) + return TRUE; + + /* numeric also contains '-', but hexa doesn't */ + if ((mode & HILDON_GTK_INPUT_MODE_NUMERIC) != 0 && chr == '-') + return TRUE; + } + + /* check special tele chars last */ + if ((mode & HILDON_GTK_INPUT_MODE_TELE) != 0 && + strchr(tele_chars_ascii, chr) != NULL) + return TRUE; + + return FALSE; +} + +static gboolean +gtk_entry_filter_text (GtkEntry *entry, + const gchar *str, + gint length) +{ + HildonGtkInputMode input_mode; + + g_assert (GTK_IS_ENTRY (entry)); + + if (!length || !str) + return FALSE; + + if (!g_utf8_validate (str, -1, NULL)) + return FALSE; + + input_mode = hildon_gtk_entry_get_input_mode (entry); + while(length) + { + gunichar chr = g_utf8_get_char (str); + + if (!hildon_gtk_input_mode_is_valid_char (input_mode, chr)) + return FALSE; + + str = g_utf8_next_char (str); + length--; + } + + return TRUE; +} + +/* MAEMO END */ + /* Default signal handlers */ static void @@ -2352,9 +2555,24 @@ new_text_length = strlen (new_text); n_chars = g_utf8_strlen (new_text, new_text_length); + + /* MAEMO START */ + if (!gtk_entry_filter_text (entry, new_text, n_chars)) + { + g_signal_emit (entry, signals[INVALID_INPUT], 0, + GTK_INVALID_INPUT_MODE_RESTRICTION); + return; + } + /* MAEMO END */ + if (entry->text_max_length > 0 && n_chars + entry->text_length > entry->text_max_length) { - gdk_display_beep (gtk_widget_get_display (GTK_WIDGET (entry))); + /* MAEMO START */ + /* gdk_display_beep (gtk_widget_get_display (GTK_WIDGET (entry))); */ + g_signal_emit (entry, signals[INVALID_INPUT], 0, + GTK_INVALID_INPUT_MAX_CHARS_REACHED); + /* MAEMO END */ + n_chars = entry->text_max_length - entry->text_length; new_text_length = g_utf8_offset_to_pointer (new_text, n_chars) - new_text; } @@ -2649,9 +2867,12 @@ GtkEditable *editable = GTK_EDITABLE (entry); gint start_pos = entry->current_pos; gint end_pos = entry->current_pos; - - _gtk_entry_reset_im_context (entry); + /* MAEMO START */ + /* backspace should not clear the word completion */ + /* _gtk_entry_reset_im_context (entry); */ + /* MAEMO END */ + if (!entry->editable) return; @@ -2720,7 +2941,10 @@ GtkEditable *editable = GTK_EDITABLE (entry); gint prev_pos; - _gtk_entry_reset_im_context (entry); + /* MAEMO START */ + /* backspace should not clear the word completion */ + /* _gtk_entry_reset_im_context (entry); */ + /* MAEMO END */ if (!entry->editable || !entry->text) return; @@ -2934,6 +3158,40 @@ return TRUE; } +/* MAEMO START */ + +static gboolean +gtk_entry_has_selection_cb (GtkIMContext *context, + GtkEntry *entry) +{ + return gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), NULL, NULL); +} + +static void +gtk_entry_clipboard_operation_cb (GtkIMContext *context, + GtkIMContextClipboardOperation op, + GtkEntry *entry) +{ + /* Similar to gtk_editable_*_clipboard(), handle these by sending signals + * instead of directly calling our internal functions. That way the + * application can hook into them if needed. + */ + switch (op) + { + case GTK_IM_CONTEXT_CLIPBOARD_OP_COPY: + g_signal_emit_by_name (entry, "copy_clipboard"); + break; + case GTK_IM_CONTEXT_CLIPBOARD_OP_CUT: + g_signal_emit_by_name (entry, "cut_clipboard"); + break; + case GTK_IM_CONTEXT_CLIPBOARD_OP_PASTE: + g_signal_emit_by_name (entry, "paste_clipboard"); + break; + } +} + +/* MAEMO END */ + /* Internal functions */ @@ -3528,11 +3786,17 @@ void _gtk_entry_reset_im_context (GtkEntry *entry) { + /* MAEMO START */ +#if 0 if (entry->need_im_reset) { entry->need_im_reset = 0; gtk_im_context_reset (entry->im_context); } +#endif + /* We want reset to be sent more often */ + gtk_im_context_reset (entry->im_context); + /* MAEMO END */ } static gint @@ -4208,6 +4472,9 @@ { g_return_if_fail (GTK_IS_ENTRY (entry)); + /* MAEMO START */ +#if 0 + /* MAEMO END */ visible = visible != FALSE; if (entry->visible != visible) @@ -4239,8 +4506,26 @@ g_object_notify (G_OBJECT (entry), "visibility"); gtk_entry_recompute (entry); } + /* MAEMO START */ +#endif + g_object_set (G_OBJECT (entry), "visibility", visible, NULL); + /* MAEMO END */ } +/* MAEMO START */ +static void +gtk_entry_set_real_visibility (GtkEntry *entry, + gboolean visible) +{ + g_return_if_fail (GTK_IS_ENTRY (entry)); + + entry->visible = visible ? TRUE : FALSE; + g_object_notify (G_OBJECT (entry), "visibility"); + + gtk_entry_recompute (entry); + } +/* MAEMO END */ + /** * gtk_entry_get_visibility: * @entry: a #GtkEntry @@ -5839,15 +6124,33 @@ /* MAEMO START */ void -hildon_gtk_entry_set_input_mode (GtkEntry *entry, - HildonGtkInputMode input_mode) +hildon_gtk_entry_set_input_mode (GtkEntry *entry, + HildonGtkInputMode mode) { + g_return_if_fail (GTK_IS_ENTRY (entry)); + + if (hildon_gtk_entry_get_input_mode (entry) != mode) + { + gtk_entry_set_real_visibility (entry, + mode & HILDON_GTK_INPUT_MODE_INVISIBLE + ? FALSE : TRUE); + g_object_set (G_OBJECT (entry->im_context), + "hildon-input-mode", mode, NULL); + g_object_notify (G_OBJECT (entry), "hildon-input-mode"); + } } HildonGtkInputMode -hildon_gtk_entry_get_input_mode (GtkEntry *entry) +hildon_gtk_entry_get_input_mode (GtkEntry *entry) { - return 0; + HildonGtkInputMode mode; + + g_return_val_if_fail (GTK_IS_ENTRY (entry), FALSE); + + g_object_get (G_OBJECT (entry->im_context), + "hildon-input-mode", &mode, NULL); + + return mode; } /* MAEMO END */
- Previous message: [maemo-commits] r9137 - projects/haf/hafbuildbot
- Next message: [maemo-commits] r9139 - projects/haf/trunk/gtk+/gtk
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]