[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.org
Date: Tue Jan 16 17:48:31 EET 2007
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 */


More information about the maemo-commits mailing list