From abd9242f3358aad1de4521bd6787643ac82b69db Mon Sep 17 00:00:00 2001 From: Christian Persch Date: Mon, 12 Sep 2011 00:13:26 +0200 Subject: [PATCH] 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 fa5079c00..ee5fb8457 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 217e295b5..0ef3c464e 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 e05223ca7..022b99112 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 */ @@ -244,6 +245,51 @@ gtk_font_button_font_chooser_set_filter_func (GtkFontChooser *chooser, priv->font_filter_data_destroy = data_destroy; } +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, @@ -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 dc7d2ec6e..1c4242754 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", @@ -215,6 +243,57 @@ gtk_font_chooser_set_font (GtkFontChooser *fontchooser, g_object_set (fontchooser, "font", fontname, NULL); } +/** + * 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 b436bedb3..b47b65c1b 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 15bc77066..c82b8bf7c 100644 --- a/gtk/gtkfontchooserutils.c +++ b/gtk/gtkfontchooserutils.c @@ -114,6 +114,9 @@ _gtk_font_chooser_install_properties (GObjectClass *klass) g_object_class_override_property (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"); diff --git a/gtk/gtkfontchooserutils.h b/gtk/gtkfontchooserutils.h index f574f1455..dc9fdff0c 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 956f59629..0fe20d224 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 4ff3668b4..be81e1b71 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 bc7665252..1c58f129f 100644 --- a/tests/testfontchooserdialog.c +++ b/tests/testfontchooserdialog.c @@ -20,6 +20,43 @@ #include #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); -- 2.43.2