gtk+ r21446 - in trunk: . docs/reference/gtk gtk



Author: carlosg
Date: Fri Sep 19 13:45:07 2008
New Revision: 21446
URL: http://svn.gnome.org/viewvc/gtk+?rev=21446&view=rev

Log:
2008-09-19  Carlos Garnacho  <carlos imendio com>

        Bug 83935 â GtkEntry's default invisible char should be U+25CF

        * gtk/gtkentry.c (find_invisible_char) (gtk_entry_init): Find a
        more suitable invisible char than '*' based on the used font.
        (gtk_entry_class_init) (gtk_entry_set_property)
        (gtk_entry_get_property): Add a "invisible-char-set" property.
        (gtk_entry_unset_invisible_char): New function, needed now that the
        default invisible char isn't fixed.
        * gtk/gtkentry.h:
        * gtk/gtk.symbols:
        * docs/reference/gtk/gtk-sections.txt: Add the new function.


Modified:
   trunk/ChangeLog
   trunk/docs/reference/gtk/gtk-sections.txt
   trunk/gtk/gtk.symbols
   trunk/gtk/gtkentry.c
   trunk/gtk/gtkentry.h

Modified: trunk/docs/reference/gtk/gtk-sections.txt
==============================================================================
--- trunk/docs/reference/gtk/gtk-sections.txt	(original)
+++ trunk/docs/reference/gtk/gtk-sections.txt	Fri Sep 19 13:45:07 2008
@@ -1228,6 +1228,7 @@
 gtk_entry_select_region
 gtk_entry_set_visibility
 gtk_entry_set_invisible_char
+gtk_entry_unset_invisible_char
 gtk_entry_set_editable
 gtk_entry_set_max_length
 gtk_entry_get_activates_default

Modified: trunk/gtk/gtk.symbols
==============================================================================
--- trunk/gtk/gtk.symbols	(original)
+++ trunk/gtk/gtk.symbols	Fri Sep 19 13:45:07 2008
@@ -1299,6 +1299,7 @@
 gtk_entry_text_index_to_layout_index
 gtk_entry_set_cursor_hadjustment
 gtk_entry_get_cursor_hadjustment
+gtk_entry_unset_invisible_char
 #endif
 #endif
 

Modified: trunk/gtk/gtkentry.c
==============================================================================
--- trunk/gtk/gtkentry.c	(original)
+++ trunk/gtk/gtkentry.c	Fri Sep 19 13:45:07 2008
@@ -87,6 +87,7 @@
   guint blink_time;  /* time in msec the cursor has blinked since last user event */
   guint interior_focus : 1;
   guint real_changed   : 1;
+  guint invisible_char_set : 1;
   guint change_count   : 8;
 
   gint focus_width;
@@ -135,7 +136,8 @@
   PROP_TRUNCATE_MULTILINE,
   PROP_SHADOW_TYPE,
   PROP_OVERWRITE_MODE,
-  PROP_TEXT_LENGTH
+  PROP_TEXT_LENGTH,
+  PROP_INVISIBLE_CHAR_SET
 };
 
 static guint signals[LAST_SIGNAL] = { 0 };
@@ -664,6 +666,20 @@
                                                       G_MAXUINT16,
                                                       0,
                                                       GTK_PARAM_READABLE));
+  /**
+   * GtkEntry:invisible-char-set:
+   *
+   * Whether the invisible char has been set for the #GtkEntry.
+   *
+   * Since: 2.16
+   */
+  g_object_class_install_property (gobject_class,
+                                   PROP_INVISIBLE_CHAR_SET,
+                                   g_param_spec_boolean ("invisible-char-set",
+                                                         P_("Invisible char set"),
+                                                         P_("Whether the invisible char has been set"),
+                                                         FALSE,
+                                                         GTK_PARAM_READWRITE));
 
   signals[POPULATE_POPUP] =
     g_signal_new (I_("populate-popup"),
@@ -1063,6 +1079,13 @@
       gtk_entry_set_overwrite_mode (entry, g_value_get_boolean (value));
       break;
 
+    case PROP_INVISIBLE_CHAR_SET:
+      if (g_value_get_boolean (value))
+        priv->invisible_char_set = TRUE;
+      else
+        gtk_entry_unset_invisible_char (entry);
+      break;
+
     case PROP_SCROLL_OFFSET:
     case PROP_CURSOR_POSITION:
     default:
@@ -1133,13 +1156,57 @@
     case PROP_TEXT_LENGTH:
       g_value_set_uint (value, entry->text_length);
       break;
-
+    case PROP_INVISIBLE_CHAR_SET:
+      g_value_set_boolean (value, priv->invisible_char_set);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
     }
 }
 
+static gunichar
+find_invisible_char (GtkWidget *widget)
+{
+  PangoLayout *layout;
+  PangoAttrList *attr_list;
+  gint i;
+  gunichar invisible_chars [] = {
+    0x25cf, /* BLACK CIRCLE */
+    0x2022, /* BULLET */
+    0x2731, /* HEAVY ASTERISK */
+    0x273a  /* SIXTEEN POINTED ASTERISK */
+  };
+
+  layout = gtk_widget_create_pango_layout (widget, NULL);
+
+  attr_list = pango_attr_list_new ();
+  pango_attr_list_insert (attr_list, pango_attr_fallback_new (FALSE));
+
+  pango_layout_set_attributes (layout, attr_list);
+  pango_attr_list_unref (attr_list);
+
+  for (i = 0; i < G_N_ELEMENTS (invisible_chars); i++)
+    {
+      gchar text[7] = { 0, };
+      gint len, count;
+
+      len = g_unichar_to_utf8 (invisible_chars[i], text);
+      pango_layout_set_text (layout, text, len);
+
+      count = pango_layout_get_unknown_glyphs_count (layout);
+
+      if (count == 0)
+        {
+          g_object_unref (layout);
+          return invisible_chars[i];
+        }
+    }
+
+  g_object_unref (layout);
+  return '*';
+}
+
 static void
 gtk_entry_init (GtkEntry *entry)
 {
@@ -1153,7 +1220,7 @@
 
   entry->editable = TRUE;
   entry->visible = TRUE;
-  entry->invisible_char = '*';
+  entry->invisible_char = find_invisible_char (GTK_WIDGET (entry));
   entry->dnd_position = -1;
   entry->width_chars = -1;
   entry->is_cell_renderer = FALSE;
@@ -2441,7 +2508,10 @@
 
   priv->focus_width = focus_width;
   priv->interior_focus = interior_focus;
-  
+
+  if (!priv->invisible_char_set)
+    entry->invisible_char = find_invisible_char (GTK_WIDGET (entry));
+
   gtk_entry_recompute (entry);
 
   if (previous_style && GTK_WIDGET_REALIZED (widget))
@@ -4548,8 +4618,9 @@
  * as the invisible char, and will also appear that way when 
  * the text in the entry widget is copied elsewhere.
  *
- * The default invisible char is the asterisk '*', but it can
- * be changed with gtk_entry_set_invisible_char().
+ * By default, GTK+ picks the best invisible character available
+ * in the current font, but it can be changed with
+ * gtk_entry_set_invisible_char().
  */
 void
 gtk_entry_set_visibility (GtkEntry *entry,
@@ -4615,17 +4686,27 @@
  * Sets the character to use in place of the actual text when
  * gtk_entry_set_visibility() has been called to set text visibility
  * to %FALSE. i.e. this is the character used in "password mode" to
- * show the user how many characters have been typed. The default
- * invisible char is an asterisk ('*').  If you set the invisible char
- * to 0, then the user will get no feedback at all; there will be
- * no text on the screen as they type.
+ * show the user how many characters have been typed. By default, GTK+
+ * picks the best invisible char available in the current font. If you
+ * set the invisible char to 0, then the user will get no feedback
+ * at all; there will be no text on the screen as they type.
  **/
 void
 gtk_entry_set_invisible_char (GtkEntry *entry,
                               gunichar  ch)
 {
+  GtkEntryPrivate *priv;
+
   g_return_if_fail (GTK_IS_ENTRY (entry));
 
+  priv = GTK_ENTRY_GET_PRIVATE (entry);
+
+  if (!priv->invisible_char_set)
+    {
+      priv->invisible_char_set = TRUE;
+      g_object_notify (G_OBJECT (entry), "invisible-char-set");
+    }
+
   if (ch == entry->invisible_char)
     return;
 
@@ -4653,6 +4734,42 @@
 }
 
 /**
+ * gtk_entry_unset_invisible_char:
+ * @entry: a #GtkEntry
+ *
+ * Unsets the invisible char previously set with
+ * gtk_entry_set_invisible_char(). So that the
+ * default invisible char is used again.
+ *
+ * Since: 2.16
+ **/
+void
+gtk_entry_unset_invisible_char (GtkEntry *entry)
+{
+  GtkEntryPrivate *priv;
+  gunichar ch;
+
+  g_return_if_fail (GTK_IS_ENTRY (entry));
+
+  priv = GTK_ENTRY_GET_PRIVATE (entry);
+
+  if (!priv->invisible_char_set)
+    return;
+
+  priv->invisible_char_set = FALSE;
+  ch = find_invisible_char (GTK_WIDGET (entry));
+
+  if (entry->invisible_char != ch)
+    {
+      entry->invisible_char = ch;
+      g_object_notify (G_OBJECT (entry), "invisible-char");
+    }
+
+  g_object_notify (G_OBJECT (entry), "invisible-char-set");
+  gtk_entry_recompute (entry);
+}
+
+/**
  * gtk_entry_set_editable:
  * @entry: a #GtkEntry
  * @editable: %TRUE if the user is allowed to edit the text

Modified: trunk/gtk/gtkentry.h
==============================================================================
--- trunk/gtk/gtkentry.h	(original)
+++ trunk/gtk/gtkentry.h	Fri Sep 19 13:45:07 2008
@@ -160,6 +160,7 @@
 void       gtk_entry_set_invisible_char         (GtkEntry      *entry,
                                                  gunichar       ch);
 gunichar   gtk_entry_get_invisible_char         (GtkEntry      *entry);
+void       gtk_entry_unset_invisible_char       (GtkEntry      *entry);
 void       gtk_entry_set_has_frame              (GtkEntry      *entry,
                                                  gboolean       setting);
 gboolean   gtk_entry_get_has_frame              (GtkEntry      *entry);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]