[gtk+] Add GtkFontChooser:font-desc property



commit abd9242f3358aad1de4521bd6787643ac82b69db
Author: Christian Persch <chpe gnome org>
Date:   Mon Sep 12 00:13:26 2011 +0200

    Add GtkFontChooser:font-desc property
    
    Add a way to set/get the font as a PangoFontDescription.

 docs/reference/gtk/gtk3-sections.txt |    2 +
 gtk/gtk.symbols                      |    2 +
 gtk/gtkfontbutton.c                  |  133 ++++++++++++++++++++---------
 gtk/gtkfontchooser.c                 |   83 +++++++++++++++++-
 gtk/gtkfontchooser.h                 |    6 ++
 gtk/gtkfontchooserutils.c            |    3 +
 gtk/gtkfontchooserutils.h            |    1 +
 gtk/gtkfontchooserwidget.c           |  159 ++++++++++++++++++++--------------
 tests/testfontchooser.c              |   35 +++++++-
 tests/testfontchooserdialog.c        |   44 +++++++++
 10 files changed, 357 insertions(+), 111 deletions(-)
---
diff --git a/docs/reference/gtk/gtk3-sections.txt b/docs/reference/gtk/gtk3-sections.txt
index fa5079c..ee5fb84 100644
--- a/docs/reference/gtk/gtk3-sections.txt
+++ b/docs/reference/gtk/gtk3-sections.txt
@@ -1485,6 +1485,8 @@ gtk_font_chooser_get_face
 gtk_font_chooser_get_size
 gtk_font_chooser_get_font
 gtk_font_chooser_set_font
+gtk_font_chooser_get_font_desc
+gtk_font_chooser_set_font_desc
 gtk_font_chooser_get_preview_text
 gtk_font_chooser_set_preview_text
 gtk_font_chooser_get_show_preview_entry
diff --git a/gtk/gtk.symbols b/gtk/gtk.symbols
index 217e295..0ef3c46 100644
--- a/gtk/gtk.symbols
+++ b/gtk/gtk.symbols
@@ -1052,12 +1052,14 @@ gtk_font_chooser_dialog_new
 gtk_font_chooser_get_face
 gtk_font_chooser_get_family
 gtk_font_chooser_get_font
+gtk_font_chooser_get_font_desc
 gtk_font_chooser_get_preview_text
 gtk_font_chooser_get_show_preview_entry
 gtk_font_chooser_get_size
 gtk_font_chooser_get_type
 gtk_font_chooser_set_filter_func
 gtk_font_chooser_set_font
+gtk_font_chooser_set_font_desc
 gtk_font_chooser_set_preview_text
 gtk_font_chooser_set_show_preview_entry
 gtk_font_chooser_widget_get_type
diff --git a/gtk/gtkfontbutton.c b/gtk/gtkfontbutton.c
index e05223c..022b991 100644
--- a/gtk/gtkfontbutton.c
+++ b/gtk/gtkfontbutton.c
@@ -61,7 +61,7 @@
 struct _GtkFontButtonPrivate 
 {
   gchar         *title;
-  
+
   gchar         *fontname;
   
   guint         use_font : 1;
@@ -75,13 +75,14 @@ struct _GtkFontButtonPrivate
   GtkWidget     *font_label;
   GtkWidget     *size_label;
 
-  PangoFontFamily   *font_family;
-  PangoFontFace     *font_face;
-  gint               font_size;
-  gchar             *preview_text;
-  GtkFontFilterFunc  font_filter;
-  gpointer           font_filter_data;
-  GDestroyNotify     font_filter_data_destroy;
+  PangoFontDescription *font_desc;
+  PangoFontFamily      *font_family;
+  PangoFontFace        *font_face;
+  gint                  font_size;
+  gchar                *preview_text;
+  GtkFontFilterFunc     font_filter;
+  gpointer              font_filter_data;
+  GDestroyNotify        font_filter_data_destroy;
 };
 
 /* Signals */
@@ -245,6 +246,51 @@ gtk_font_button_font_chooser_set_filter_func (GtkFontChooser    *chooser,
 }
 
 static void
+gtk_font_button_take_font_desc (GtkFontButton        *font_button,
+                                PangoFontDescription *font_desc)
+{
+  GtkFontButtonPrivate *priv = font_button->priv;
+  GObject *object = G_OBJECT (font_button);
+
+  if (priv->font_desc && font_desc &&
+      pango_font_description_equal (priv->font_desc, font_desc))
+    {
+      pango_font_description_free (font_desc);
+      return;
+    }
+
+  g_object_freeze_notify (object);
+
+  if (priv->font_desc)
+    pango_font_description_free (priv->font_desc);
+  if (font_desc)
+    priv->font_desc = font_desc; /* adopted */
+  else
+    priv->font_desc = pango_font_description_from_string (_("Sans 12"));
+
+  g_free (priv->fontname);
+  priv->fontname = pango_font_description_to_string (priv->font_desc);
+
+  gtk_font_button_update_font_info (font_button);
+
+  if (priv->font_dialog)
+    gtk_font_chooser_set_font_desc (GTK_FONT_CHOOSER (priv->font_dialog),
+                                    priv->font_desc);
+
+  g_object_notify (G_OBJECT (font_button), "font");
+  g_object_notify (G_OBJECT (font_button), "font-desc");
+  g_object_notify (G_OBJECT (font_button), "font-name");
+
+  g_object_thaw_notify (object);
+}
+
+static const PangoFontDescription *
+gtk_font_button_get_font_desc (GtkFontButton *font_button)
+{
+  return font_button->priv->font_desc;
+}
+
+static void
 gtk_font_button_font_chooser_notify (GObject    *object,
                                      GParamSpec *pspec,
                                      gpointer    user_data)
@@ -417,7 +463,6 @@ gtk_font_button_init (GtkFontButton *font_button)
                                                    GtkFontButtonPrivate);
 
   /* Initialize fields */
-  font_button->priv->fontname = g_strdup (_("Sans 12"));
   font_button->priv->use_font = FALSE;
   font_button->priv->use_size = FALSE;
   font_button->priv->show_style = TRUE;
@@ -432,10 +477,9 @@ gtk_font_button_init (GtkFontButton *font_button)
   font_button->priv->inside = gtk_font_button_create_inside (font_button);
   gtk_container_add (GTK_CONTAINER (font_button), font_button->priv->inside);
 
-  gtk_font_button_update_font_info (font_button);  
+  gtk_font_button_take_font_desc (font_button, NULL);
 }
 
-
 static void
 gtk_font_button_finalize (GObject *object)
 {
@@ -447,7 +491,7 @@ gtk_font_button_finalize (GObject *object)
 
   g_free (font_button->priv->fontname);
   font_button->priv->fontname = NULL;
-  
+
   g_free (font_button->priv->title);
   font_button->priv->title = NULL;
 
@@ -464,6 +508,10 @@ gtk_font_button_finalize (GObject *object)
     g_object_unref (font_button->priv->font_face);
   font_button->priv->font_face = NULL;
 
+  if (font_button->priv->font_desc)
+    pango_font_description_free (font_button->priv->font_desc);
+  font_button->priv->font_desc = NULL;
+
   G_OBJECT_CLASS (gtk_font_button_parent_class)->finalize (object);
 }
 
@@ -486,6 +534,9 @@ gtk_font_button_set_property (GObject      *object,
     case PROP_TITLE:
       gtk_font_button_set_title (font_button, g_value_get_string (value));
       break;
+    case GTK_FONT_CHOOSER_PROP_FONT_DESC:
+      gtk_font_button_take_font_desc (font_button, g_value_dup_boxed (value));
+      break;
     case GTK_FONT_CHOOSER_PROP_FONT:
     case PROP_FONT_NAME:
       gtk_font_button_set_font_name (font_button, g_value_get_string (value));
@@ -527,6 +578,9 @@ gtk_font_button_get_property (GObject    *object,
     case PROP_TITLE:
       g_value_set_string (value, gtk_font_button_get_title (font_button));
       break;
+    case GTK_FONT_CHOOSER_PROP_FONT_DESC:
+      g_value_set_boxed (value, gtk_font_button_get_font_desc (font_button));
+      break;
     case GTK_FONT_CHOOSER_PROP_FONT:
     case PROP_FONT_NAME:
       g_value_set_string (value, gtk_font_button_get_font_name (font_button));
@@ -834,7 +888,7 @@ const gchar *
 gtk_font_button_get_font_name (GtkFontButton *font_button)
 {
   g_return_val_if_fail (GTK_IS_FONT_BUTTON (font_button), NULL);
-  
+
   return font_button->priv->fontname;
 }
 
@@ -845,8 +899,7 @@ gtk_font_button_get_font_name (GtkFontButton *font_button)
  *
  * Sets or updates the currently-displayed font in font picker dialog.
  *
- * Returns: Return value of gtk_font_chooser_dialog_set_font_name() if the
- * font chooser dialog exists, otherwise %FALSE.
+ * Returns: %TRUE
  *
  * Since: 2.4
  */
@@ -854,26 +907,13 @@ gboolean
 gtk_font_button_set_font_name (GtkFontButton *font_button,
                                const gchar    *fontname)
 {
-  gchar *old_fontname;
+  PangoFontDescription *font_desc;
 
   g_return_val_if_fail (GTK_IS_FONT_BUTTON (font_button), FALSE);
   g_return_val_if_fail (fontname != NULL, FALSE);
-  
-  if (g_ascii_strcasecmp (font_button->priv->fontname, fontname)) 
-    {
-      old_fontname = font_button->priv->fontname;
-      font_button->priv->fontname = g_strdup (fontname);
-      g_free (old_fontname);
-    }
-  
-  gtk_font_button_update_font_info (font_button);
-  
-  if (font_button->priv->font_dialog)
-    gtk_font_chooser_set_font (GTK_FONT_CHOOSER (font_button->priv->font_dialog),
-                               font_button->priv->fontname);
 
-  g_object_notify (G_OBJECT (font_button), "font");
-  g_object_notify (G_OBJECT (font_button), "font-name");
+  font_desc = pango_font_description_from_string (fontname);
+  gtk_font_button_take_font_desc (font_button, font_desc);
 
   return TRUE;
 }
@@ -936,7 +976,7 @@ gtk_font_button_clicked (GtkButton *button)
   if (!gtk_widget_get_visible (font_button->priv->font_dialog))
     {
       font_dialog = GTK_FONT_CHOOSER (font_button->priv->font_dialog);
-      gtk_font_chooser_set_font (font_dialog, font_button->priv->fontname);
+      gtk_font_chooser_set_font_desc (font_dialog, font_button->priv->font_desc);
     } 
 
   gtk_window_present (GTK_WINDOW (font_button->priv->font_dialog));
@@ -951,6 +991,7 @@ response_cb (GtkDialog *dialog,
   GtkFontButton *font_button = GTK_FONT_BUTTON (data);
   GtkFontButtonPrivate *priv = font_button->priv;
   GtkFontChooser *font_chooser;
+  GObject *object;
 
   gtk_widget_hide (font_button->priv->font_dialog);
 
@@ -958,9 +999,16 @@ response_cb (GtkDialog *dialog,
     return;
 
   font_chooser = GTK_FONT_CHOOSER (priv->font_dialog);
+  object = G_OBJECT (font_chooser);
+
+  g_object_freeze_notify (object);
+
+  if (priv->font_desc)
+    pango_font_description_free (priv->font_desc);
+  priv->font_desc = gtk_font_chooser_get_font_desc (font_chooser);
 
   g_free (priv->fontname);
-  priv->fontname = gtk_font_chooser_get_font (font_chooser);
+  priv->fontname = pango_font_description_to_string (priv->font_desc);
 
   if (priv->font_family)
     g_object_unref (priv->font_family);
@@ -980,8 +1028,11 @@ response_cb (GtkDialog *dialog,
   gtk_font_button_update_font_info (font_button);
 
   g_object_notify (G_OBJECT (font_button), "font");
+  g_object_notify (G_OBJECT (font_button), "font-desc");
   g_object_notify (G_OBJECT (font_button), "font-name");
-  
+
+  g_object_thaw_notify (object);
+
   /* Emit font_set signal */
   g_signal_emit (font_button, font_button_signals[FONT_SET], 0);
 }
@@ -1032,8 +1083,8 @@ gtk_font_button_label_use_font (GtkFontButton *font_button)
   if (!font_button->priv->use_font)
     return;
 
-  desc = pango_font_description_from_string (font_button->priv->fontname);
-  
+  desc = pango_font_description_copy (font_button->priv->font_desc);
+
   if (!font_button->priv->use_size)
     pango_font_description_unset_fields (desc, PANGO_FONT_MASK_SIZE);
 
@@ -1055,12 +1106,14 @@ font_description_style_equal (const PangoFontDescription *a,
 static void
 gtk_font_button_update_font_info (GtkFontButton *font_button)
 {
-  PangoFontDescription *desc;
+  const PangoFontDescription *desc;
   const gchar *family;
   gchar *style;
   gchar *family_style;
-  
-  desc = pango_font_description_from_string (font_button->priv->fontname);
+
+  desc = font_button->priv->font_desc;
+  g_assert (desc != NULL);
+
   family = pango_font_description_get_family (desc);
   
 #if 0
@@ -1134,6 +1187,4 @@ gtk_font_button_update_font_info (GtkFontButton *font_button)
     }
 
   gtk_font_button_label_use_font (font_button);
-  
-  pango_font_description_free (desc);
 } 
diff --git a/gtk/gtkfontchooser.c b/gtk/gtkfontchooser.c
index dc7d2ec..1c42427 100644
--- a/gtk/gtkfontchooser.c
+++ b/gtk/gtkfontchooser.c
@@ -56,14 +56,37 @@ G_DEFINE_INTERFACE (GtkFontChooser, gtk_font_chooser, G_TYPE_OBJECT);
 static void
 gtk_font_chooser_default_init (GtkFontChooserInterface *iface)
 {
+  /**
+   * GtkFontChooser:font:
+   *
+   * The font description as a string, e.g. "Sans Italic 12".
+   */
   g_object_interface_install_property
      (iface,
       g_param_spec_string ("font",
                           P_("Font"),
-                          P_("The string that represents this font"),
-                          GTK_FONT_CHOOSER_DEFAULT_FONT_NAME,
+                           P_("Font description as a string, e.g. \"Sans Italic 12\""),
+                           GTK_FONT_CHOOSER_DEFAULT_FONT_NAME,
+                           GTK_PARAM_READWRITE));
+
+  /**
+   * GtkFontChooser:font-desc:
+   *
+   * The font description as a #PangoFontDescription.
+   */
+  g_object_interface_install_property
+     (iface,
+      g_param_spec_boxed ("font-desc",
+                          P_("Font"),
+                          P_("Font description as a PangoFontDescription struct"),
+                          PANGO_TYPE_FONT_DESCRIPTION,
                           GTK_PARAM_READWRITE));
 
+  /**
+   * GtkFontChooser:preview-text:
+   *
+   * The string with which to preview the font.
+   */
   g_object_interface_install_property
      (iface,
       g_param_spec_string ("preview-text",
@@ -72,6 +95,11 @@ gtk_font_chooser_default_init (GtkFontChooserInterface *iface)
                           pango_language_get_sample_string (NULL),
                           GTK_PARAM_READWRITE));
 
+  /**
+   * GtkFontChooser:show-preview-entry:
+   *
+   * Whether to show an entry to change the preview text.
+   */
   g_object_interface_install_property
      (iface,
       g_param_spec_boolean ("show-preview-entry",
@@ -216,6 +244,57 @@ gtk_font_chooser_set_font (GtkFontChooser *fontchooser,
 }
 
 /**
+ * gtk_font_chooser_get_font_desc:
+ * @fontchooser: a #GtkFontChooser
+ *
+ * Gets the currently-selected font.
+ *
+ * Note that this can be a different string than what you set with
+ * gtk_font_chooser_set_font(), as the font chooser widget may
+ * normalize font names and thus return a string with a different
+ * structure. For example, "Helvetica Italic Bold 12" could be
+ * normalized to "Helvetica Bold Italic 12".
+ *
+ * Use pango_font_description_equal() if you want to compare two
+ * font descriptions.
+ *
+ * Return value: (transfer full) (allow-none): A #PangoFontDescription for the
+ *     current font, or %NULL if  no font is selected.
+ *
+ * Since: 3.2
+ */
+PangoFontDescription *
+gtk_font_chooser_get_font_desc (GtkFontChooser *fontchooser)
+{
+  PangoFontDescription *font_desc;
+
+  g_return_val_if_fail (GTK_IS_FONT_CHOOSER (fontchooser), NULL);
+
+  g_object_get (fontchooser, "font-desc", &font_desc, NULL);
+
+  return font_desc;
+}
+
+/**
+ * gtk_font_chooser_set_font_desc:
+ * @fontchooser: a #GtkFontChooser
+ * @font_desc: a #PangoFontDescription
+ *
+ * Sets the currently-selected font from @font_desc.
+ *
+ * Since: 3.2
+ */
+void
+gtk_font_chooser_set_font_desc (GtkFontChooser             *fontchooser,
+                                const PangoFontDescription *font_desc)
+{
+  g_return_if_fail (GTK_IS_FONT_CHOOSER (fontchooser));
+  g_return_if_fail (font_desc != NULL);
+
+  g_object_set (fontchooser, "font-desc", font_desc, NULL);
+}
+
+/**
  * gtk_font_chooser_get_preview_text:
  * @fontchooser: a #GtkFontChooser
  *
diff --git a/gtk/gtkfontchooser.h b/gtk/gtkfontchooser.h
index b436bed..b47b65c 100644
--- a/gtk/gtkfontchooser.h
+++ b/gtk/gtkfontchooser.h
@@ -81,6 +81,12 @@ GType            gtk_font_chooser_get_type                 (void) G_GNUC_CONST;
 PangoFontFamily *gtk_font_chooser_get_family               (GtkFontChooser   *fontchooser);
 PangoFontFace   *gtk_font_chooser_get_face                 (GtkFontChooser   *fontchooser);
 gint             gtk_font_chooser_get_size                 (GtkFontChooser   *fontchooser);
+
+PangoFontDescription *
+                 gtk_font_chooser_get_font_desc            (GtkFontChooser             *fontchooser);
+void             gtk_font_chooser_set_font_desc            (GtkFontChooser             *fontchooser,
+                                                            const PangoFontDescription *font_desc);
+
 gchar*           gtk_font_chooser_get_font                 (GtkFontChooser   *fontchooser);
 
 void             gtk_font_chooser_set_font                 (GtkFontChooser   *fontchooser,
diff --git a/gtk/gtkfontchooserutils.c b/gtk/gtkfontchooserutils.c
index 15bc770..c82b8bf 100644
--- a/gtk/gtkfontchooserutils.c
+++ b/gtk/gtkfontchooserutils.c
@@ -115,6 +115,9 @@ _gtk_font_chooser_install_properties (GObjectClass *klass)
                                     GTK_FONT_CHOOSER_PROP_FONT,
                                     "font");
   g_object_class_override_property (klass,
+                                    GTK_FONT_CHOOSER_PROP_FONT_DESC,
+                                    "font-desc");
+  g_object_class_override_property (klass,
                                     GTK_FONT_CHOOSER_PROP_PREVIEW_TEXT,
                                     "preview-text");
   g_object_class_override_property (klass,
diff --git a/gtk/gtkfontchooserutils.h b/gtk/gtkfontchooserutils.h
index f574f14..dc9fdff 100644
--- a/gtk/gtkfontchooserutils.h
+++ b/gtk/gtkfontchooserutils.h
@@ -36,6 +36,7 @@ G_BEGIN_DECLS
 typedef enum {
   GTK_FONT_CHOOSER_PROP_FIRST           = 0x4000,
   GTK_FONT_CHOOSER_PROP_FONT,
+  GTK_FONT_CHOOSER_PROP_FONT_DESC,
   GTK_FONT_CHOOSER_PROP_PREVIEW_TEXT,
   GTK_FONT_CHOOSER_PROP_SHOW_PREVIEW_ENTRY,
   GTK_FONT_CHOOSER_PROP_LAST
diff --git a/gtk/gtkfontchooserwidget.c b/gtk/gtkfontchooserwidget.c
index 956f596..0fe20d2 100644
--- a/gtk/gtkfontchooserwidget.c
+++ b/gtk/gtkfontchooserwidget.c
@@ -54,17 +54,18 @@
  * SECTION:gtkfontchooser
  * @Short_description: A widget for selecting fonts
  * @Title: GtkFontChooserWidget
- * @See_also: #GtkFontChooserWidgetDialog
+ * @See_also: #GtkFontChooserDialog
  *
  * The #GtkFontChooserWidget widget lists the available fonts,
  * styles and sizes, allowing the user to select a font. It is
- * used in the #GtkFontChooserWidgetDialog widget to provide a
+ * used in the #GtkFontChooserDialog widget to provide a
  * dialog box for selecting fonts.
  *
  * To set the font which is initially selected, use
- * gtk_font_chooser_set_font().
+ * gtk_font_chooser_set_font() or gtk_font_chooser_set_font_desc().
  *
- * To get the selected font use gtk_font_chooser_get_font().
+ * To get the selected font use gtk_font_chooser_get_font() or
+ * gtk_font_chooser_get_font_desc().
  *
  * To change the text which is shown in the preview area, use
  * gtk_font_chooser_set_preview_text().
@@ -90,7 +91,7 @@ struct _GtkFontChooserWidgetPrivate
   GtkWidget *size_spin;
   GtkWidget *size_slider;
 
-  gchar           *fontname;
+  PangoFontDescription *font_desc;
   gint             size;
   PangoFontFace   *face;
   PangoFontFamily *family;
@@ -146,12 +147,17 @@ static void gtk_font_chooser_widget_style_updated        (GtkWidget       *widge
 
 static void gtk_font_chooser_widget_bootstrap_fontlist   (GtkFontChooserWidget *fontchooser);
 
-static void gtk_font_chooser_widget_select_font_name     (GtkFontChooserWidget *fontchooser);
+static void gtk_font_chooser_widget_select_font          (GtkFontChooserWidget *fontchooser);
 
 static gchar   *gtk_font_chooser_widget_get_font         (GtkFontChooser *chooser);
 static void     gtk_font_chooser_widget_set_font         (GtkFontChooser *chooser,
                                                           const gchar     *fontname);
 
+static PangoFontDescription *gtk_font_chooser_widget_get_font_desc  (GtkFontChooser       *chooser);
+static void                  gtk_font_chooser_widget_take_font_desc (GtkFontChooser       *chooser,
+                                                                     PangoFontDescription *font_desc);
+
+
 static const gchar *gtk_font_chooser_widget_get_preview_text (GtkFontChooserWidget *fontchooser);
 static void         gtk_font_chooser_widget_set_preview_text (GtkFontChooserWidget *fontchooser,
                                                               const gchar          *text);
@@ -198,6 +204,9 @@ gtk_font_chooser_widget_set_property (GObject         *object,
     case GTK_FONT_CHOOSER_PROP_FONT:
       gtk_font_chooser_widget_set_font (GTK_FONT_CHOOSER (fontchooser), g_value_get_string (value));
       break;
+    case GTK_FONT_CHOOSER_PROP_FONT_DESC:
+      gtk_font_chooser_widget_take_font_desc (GTK_FONT_CHOOSER (fontchooser), g_value_dup_boxed (value));
+      break;
     case GTK_FONT_CHOOSER_PROP_PREVIEW_TEXT:
       gtk_font_chooser_widget_set_preview_text (fontchooser, g_value_get_string (value));
       break;
@@ -223,6 +232,9 @@ gtk_font_chooser_widget_get_property (GObject         *object,
     case GTK_FONT_CHOOSER_PROP_FONT:
       g_value_take_string (value, gtk_font_chooser_widget_get_font (GTK_FONT_CHOOSER (fontchooser)));
       break;
+    case GTK_FONT_CHOOSER_PROP_FONT_DESC:
+      g_value_set_boxed (value, gtk_font_chooser_widget_get_font_desc (GTK_FONT_CHOOSER (fontchooser)));
+      break;
     case GTK_FONT_CHOOSER_PROP_PREVIEW_TEXT:
       g_value_set_string (value, gtk_font_chooser_widget_get_preview_text (fontchooser));
       break;
@@ -317,7 +329,8 @@ spin_change_cb (GtkAdjustment *adjustment,
   gtk_widget_override_font (priv->preview, desc);
 
   g_object_notify (G_OBJECT (fontchooser), "font");
-
+  g_object_notify (G_OBJECT (fontchooser), "font-desc");
+  
   /* If the new value is lower than the lower bound of the slider, we set
    * the slider adjustment to the lower bound value if it is not already set
    */
@@ -416,7 +429,6 @@ cursor_changed_cb (GtkTreeView *treeview,
       return;
     }
 
-
   gtk_tree_model_get (GTK_TREE_MODEL (priv->filter_model), &iter,
                       FACE_COLUMN, &face,
                       FAMILY_COLUMN, &family,
@@ -456,9 +468,12 @@ cursor_changed_cb (GtkTreeView *treeview,
     g_object_unref (priv->face);
   priv->face = face;
 
-  pango_font_description_free (desc);
+  if (priv->font_desc)
+    pango_font_description_free (priv->font_desc);
+  priv->font_desc = desc;
 
   g_object_notify (G_OBJECT (fontchooser), "font");
+  g_object_notify (G_OBJECT (fontchooser), "font-desc");
 }
 
 static gboolean
@@ -511,7 +526,7 @@ gtk_font_chooser_widget_init (GtkFontChooserWidget *fontchooser)
 {
   GIcon                   *icon;
   GtkFontChooserWidgetPrivate   *priv;
-  PangoFontDescription    *font_desc;
+  const PangoFontDescription *font_desc;
   GtkWidget               *scrolled_win;
   GtkWidget               *grid;
 
@@ -530,6 +545,7 @@ gtk_font_chooser_widget_init (GtkFontChooserWidget *fontchooser)
   priv->size = pango_font_description_get_size (font_desc);
   priv->face = NULL;
   priv->family = NULL;
+  priv->font_desc = NULL;
 
   gtk_widget_push_composite_child ();
 
@@ -655,6 +671,8 @@ gtk_font_chooser_widget_init (GtkFontChooserWidget *fontchooser)
 
   /* Set default focus */
   gtk_widget_pop_composite_child ();
+
+  gtk_font_chooser_widget_take_font_desc (GTK_FONT_CHOOSER (fontchooser), NULL);
 }
 
 /**
@@ -885,7 +903,7 @@ gtk_font_chooser_widget_bootstrap_fontlist (GtkFontChooserWidget *fontchooser)
   gtk_tree_view_set_headers_visible (treeview, FALSE);
 
   cell = gtk_cell_renderer_text_new ();
-  col = gtk_tree_view_column_new_with_attributes ("Family",
+  col = gtk_tree_view_column_new_with_attributes (_("Font Family"),
                                                   cell,
                                                   "markup", PREVIEW_TEXT_COLUMN,
                                                   NULL);
@@ -919,8 +937,8 @@ gtk_font_chooser_widget_finalize (GObject *object)
   GtkFontChooserWidget *fontchooser = GTK_FONT_CHOOSER_WIDGET (object);
   GtkFontChooserWidgetPrivate *priv = fontchooser->priv;
 
-  if (priv->fontname)
-    g_free (priv->fontname);
+  if (priv->font_desc)
+    pango_font_description_free (priv->font_desc);
 
   if (priv->family)
     g_object_unref (priv->family);
@@ -936,16 +954,21 @@ gtk_font_chooser_widget_finalize (GObject *object)
 
 static void
 gtk_font_chooser_widget_screen_changed (GtkWidget *widget,
-                                 GdkScreen *previous_screen)
+                                        GdkScreen *previous_screen)
 {
   GtkFontChooserWidget *fontchooser = GTK_FONT_CHOOSER_WIDGET (widget);
   GtkFontChooserWidgetPrivate *priv = fontchooser->priv;
+  void (* screen_changed) (GtkWidget *, GdkScreen *) =
+    GTK_WIDGET_CLASS (gtk_font_chooser_widget_parent_class)->screen_changed;
+
+  if (screen_changed)
+    screen_changed (widget, previous_screen);
 
   populate_list (fontchooser,
                  GTK_TREE_VIEW (priv->family_face_list),
                  priv->model);
 
-  gtk_font_chooser_widget_select_font_name (fontchooser);
+  gtk_font_chooser_widget_select_font (fontchooser);
 }
 
 static void
@@ -988,69 +1011,77 @@ static gchar *
 gtk_font_chooser_widget_get_font (GtkFontChooser *chooser)
 {
   GtkFontChooserWidget *fontchooser = GTK_FONT_CHOOSER_WIDGET (chooser);
-  gchar                *font_name;
-  gchar                *font_desc_name;
-  PangoFontDescription *desc;
 
-  if (!fontchooser->priv->face)
-    return g_strdup (GTK_FONT_CHOOSER_DEFAULT_FONT_NAME);
-
-  desc = pango_font_face_describe (fontchooser->priv->face);
-  font_desc_name = pango_font_description_to_string (desc);
-  pango_font_description_free (desc);
+  return pango_font_description_to_string (fontchooser->priv->font_desc);
+}
 
-  font_name = g_strdup_printf ("%s %d", font_desc_name, fontchooser->priv->size / PANGO_SCALE);
-  g_free (font_desc_name);
+static PangoFontDescription *
+gtk_font_chooser_widget_get_font_desc (GtkFontChooser *chooser)
+{
+  GtkFontChooserWidget *fontchooser = GTK_FONT_CHOOSER_WIDGET (chooser);
 
-  return font_name;
+  return fontchooser->priv->font_desc;
 }
 
 static void
 gtk_font_chooser_widget_set_font (GtkFontChooser *chooser,
                                   const gchar    *fontname)
 {
+  PangoFontDescription *font_desc;
+
+  font_desc = pango_font_description_from_string (fontname);
+  gtk_font_chooser_widget_take_font_desc (chooser, font_desc);
+}
+
+static void
+gtk_font_chooser_widget_take_font_desc (GtkFontChooser        *chooser,
+                                        PangoFontDescription *font_desc)
+{
   GtkFontChooserWidget *fontchooser = GTK_FONT_CHOOSER_WIDGET (chooser);
   GtkFontChooserWidgetPrivate *priv = fontchooser->priv;
 
-  if (priv->fontname)
-    g_free (priv->fontname);
-  priv->fontname = g_strdup (fontname);
+  if (font_desc && priv->font_desc &&
+      pango_font_description_equal (font_desc, priv->font_desc))
+    {
+      pango_font_description_free (font_desc);
+      return;
+    }
 
-  if (gtk_widget_has_screen (GTK_WIDGET (fontchooser)))
-    gtk_font_chooser_widget_select_font_name (fontchooser);
+  if (priv->font_desc)
+    pango_font_description_free (priv->font_desc);
+  if (font_desc)
+    priv->font_desc = font_desc; /* adopted */
+  else
+    priv->font_desc = pango_font_description_from_string (GTK_FONT_CHOOSER_DEFAULT_FONT_NAME);
 
-  g_object_notify (G_OBJECT (fontchooser), "font");
+  gtk_font_chooser_widget_select_font (fontchooser);
 }
 
 static void
-gtk_font_chooser_widget_select_font_name (GtkFontChooserWidget *fontchooser)
+gtk_font_chooser_widget_select_font (GtkFontChooserWidget *fontchooser)
 {
   GtkFontChooserWidgetPrivate *priv = fontchooser->priv;
+  const PangoFontDescription *desc;
+  const gchar *family_name;
+  gint font_size;
+  gboolean font_size_is_absolute;
   GtkTreeIter iter;
   gboolean valid;
-  gchar *family_name;
-  PangoFontDescription *desc;
   gboolean found = FALSE;
 
-  if (priv->fontname)
-    desc = pango_font_description_from_string (priv->fontname);
-  else
-    desc = pango_font_description_from_string (GTK_FONT_CHOOSER_DEFAULT_FONT_NAME);
-
-  family_name = (gchar*)pango_font_description_get_family (desc);
-
-  g_free (priv->fontname);
-  priv->fontname = NULL;
+  desc = priv->font_desc;
+  g_assert (desc != NULL);
 
-  if (!family_name)
-    {
-      pango_font_description_free (desc);
-      return;
-    }
+  font_size = pango_font_description_get_size (desc);
+  font_size_is_absolute = pango_font_description_get_size_is_absolute (desc);
+  family_name = pango_font_description_get_family (desc);
 
   /* We make sure the filter is clear */
   gtk_entry_set_text (GTK_ENTRY (priv->search_entry), "");
 
+  if (!family_name)
+    goto deselect;
+
   /* We find the matching family/face */
   for (valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->filter_model), &iter);
        valid;
@@ -1064,24 +1095,21 @@ gtk_font_chooser_widget_select_font_name (GtkFontChooserWidget *fontchooser)
                           -1);
 
       tmp_desc = pango_font_face_describe (face);
-      if (pango_font_description_get_size_is_absolute (desc))
-        pango_font_description_set_absolute_size (tmp_desc,
-                                                  pango_font_description_get_size (desc));
+      if (font_size_is_absolute)
+        pango_font_description_set_absolute_size (tmp_desc, font_size);
       else
-        pango_font_description_set_size (tmp_desc,
-                                         pango_font_description_get_size (desc));
+        pango_font_description_set_size (tmp_desc, font_size);
 
       if (pango_font_description_equal (desc, tmp_desc))
         {
           GtkTreePath *path;
-          gint size = pango_font_description_get_size (desc);
 
-          if (size)
+          if (font_size)
             {
-              if (pango_font_description_get_size_is_absolute (desc))
-                size = size * PANGO_SCALE;
+              if (font_size_is_absolute)
+                font_size *= PANGO_SCALE;
               gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->size_spin),
-                                         size / PANGO_SCALE);
+                                         font_size / PANGO_SCALE);
             }
 
           path = gtk_tree_model_get_path (GTK_TREE_MODEL (priv->filter_model), &iter);
@@ -1111,21 +1139,24 @@ gtk_font_chooser_widget_select_font_name (GtkFontChooserWidget *fontchooser)
         break;
     }
 
-  pango_font_description_free (desc);
+deselect:
+  if (!found)
+    {
+      gtk_tree_selection_unselect_all
+        (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->family_face_list)));
+    }
 }
 
 static const gchar*
 gtk_font_chooser_widget_get_preview_text (GtkFontChooserWidget *fontchooser)
 {
-  return (const gchar*)fontchooser->priv->preview_text;
+  return fontchooser->priv->preview_text;
 }
 
 static void
 gtk_font_chooser_widget_set_preview_text (GtkFontChooserWidget *fontchooser,
                                           const gchar          *text)
 {
-  g_return_if_fail (text != NULL);
-
   g_free (fontchooser->priv->preview_text);
   fontchooser->priv->preview_text = g_strdup (text);
 
diff --git a/tests/testfontchooser.c b/tests/testfontchooser.c
index 4ff3668..be81e1b 100644
--- a/tests/testfontchooser.c
+++ b/tests/testfontchooser.c
@@ -21,9 +21,28 @@
 #include "prop-editor.h"
 
 static void
-notify_font_name_cb (GObject *fontchooser, GParamSpec *pspec, gpointer data)
+notify_font_cb (GtkFontChooser *fontchooser, GParamSpec *pspec, gpointer data)
 {
-  g_debug ("Changed font name %s", gtk_font_chooser_get_font (GTK_FONT_CHOOSER (fontchooser)));
+  PangoFontFamily *family;
+  PangoFontFace *face;
+
+  g_debug ("Changed font name %s", gtk_font_chooser_get_font (fontchooser));
+
+  family = gtk_font_chooser_get_family (fontchooser);
+  face = gtk_font_chooser_get_face (fontchooser);
+  if (family)
+    {
+       g_debug ("  Family: %s is-monospace:%s",
+                pango_font_family_get_name (family),
+                pango_font_family_is_monospace (family) ? "true" : "false");
+    }
+  else
+    g_debug ("  No font family!");
+
+  if (face)
+    g_debug ("  Face description: %s", pango_font_face_get_face_name (face));
+  else
+    g_debug ("  No font face!");
 }
 
 static void
@@ -32,6 +51,12 @@ notify_preview_text_cb (GObject *fontchooser, GParamSpec *pspec, gpointer data)
   g_debug ("Changed preview text %s", gtk_font_chooser_get_preview_text (GTK_FONT_CHOOSER (fontchooser)));
 }
 
+static void
+font_activated_cb (GtkFontChooser *chooser, const gchar *font_name, gpointer data)
+{
+  g_debug ("font-activated: %s", font_name);
+}
+
 int
 main (int argc, char *argv[])
 {
@@ -53,10 +78,12 @@ main (int argc, char *argv[])
 
   g_signal_connect (window, "delete-event",
                     G_CALLBACK (gtk_main_quit), NULL);
-  g_signal_connect (fontchooser, "notify::font-name",
-                    G_CALLBACK (notify_font_name_cb), NULL);
+  g_signal_connect (fontchooser, "notify::font",
+                    G_CALLBACK (notify_font_cb), NULL);
   g_signal_connect (fontchooser, "notify::preview-text",
                     G_CALLBACK (notify_preview_text_cb), NULL);
+  g_signal_connect (fontchooser, "font-activated",
+                    G_CALLBACK (font_activated_cb), NULL);
 
   gtk_font_chooser_set_font (GTK_FONT_CHOOSER (fontchooser), "Bitstream Vera Sans 45");
   gtk_font_chooser_set_preview_text (GTK_FONT_CHOOSER (fontchooser), "[user host ~]$ &>>");
diff --git a/tests/testfontchooserdialog.c b/tests/testfontchooserdialog.c
index bc76652..1c58f12 100644
--- a/tests/testfontchooserdialog.c
+++ b/tests/testfontchooserdialog.c
@@ -20,6 +20,43 @@
 #include <gtk/gtk.h>
 #include "prop-editor.h"
 
+static void
+notify_font_cb (GtkFontChooser *fontchooser, GParamSpec *pspec, gpointer data)
+{
+  PangoFontFamily *family;
+  PangoFontFace *face;
+
+  g_debug ("Changed font name %s", gtk_font_chooser_get_font (fontchooser));
+
+  family = gtk_font_chooser_get_family (fontchooser);
+  face = gtk_font_chooser_get_face (fontchooser);
+  if (family)
+    {
+       g_debug ("  Family: %s is-monospace:%s",
+                pango_font_family_get_name (family),
+                pango_font_family_is_monospace (family) ? "true" : "false");
+    }
+  else
+    g_debug ("  No font family!");
+
+  if (face)
+    g_debug ("  Face description: %s", pango_font_face_get_face_name (face));
+  else
+    g_debug ("  No font face!");
+}
+
+static void
+notify_preview_text_cb (GObject *fontchooser, GParamSpec *pspec, gpointer data)
+{
+  g_debug ("Changed preview text %s", gtk_font_chooser_get_preview_text (GTK_FONT_CHOOSER (fontchooser)));
+}
+
+static void
+font_activated_cb (GtkFontChooser *chooser, const gchar *font_name, gpointer data)
+{
+  g_debug ("font-activated: %s", font_name);
+}
+
 int
 main (int argc, char *argv[])
 {
@@ -33,6 +70,13 @@ main (int argc, char *argv[])
   gtk_container_add (GTK_CONTAINER (window), font_button);
   gtk_widget_show_all (window);
 
+  g_signal_connect (font_button, "notify::font",
+                    G_CALLBACK (notify_font_cb), NULL);
+  g_signal_connect (font_button, "notify::preview-text",
+                    G_CALLBACK (notify_preview_text_cb), NULL);
+  g_signal_connect (font_button, "font-activated",
+                    G_CALLBACK (font_activated_cb), NULL);
+
   g_signal_connect (window, "delete-event",
                     G_CALLBACK (gtk_main_quit), NULL);
 



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