X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkfontbutton.c;h=f65b905b2d45a8e1fda13b49f8ba9a40ecf87374;hb=HEAD;hp=d49c62d775c2c3bfa19253bc47d1962ba1e604a8;hpb=277a6f4701f43cc70bb57bd39ee783f75370442e;p=~andy%2Fgtk diff --git a/gtk/gtkfontbutton.c b/gtk/gtkfontbutton.c index d49c62d77..f65b905b2 100644 --- a/gtk/gtkfontbutton.c +++ b/gtk/gtkfontbutton.c @@ -16,8 +16,7 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA. + * License along with this library. If not, see . */ /* * Modified by the GTK+ Team and others 2003. See the AUTHORS @@ -26,43 +25,63 @@ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. */ -#include +#include "config.h" #include "gtkfontbutton.h" -#include "gtksignal.h" #include "gtkmain.h" -#include "gtkalignment.h" -#include "gtkhbox.h" +#include "gtkbox.h" #include "gtklabel.h" -#include "gtkvseparator.h" -#include "gtkfontsel.h" +#include "gtkfontchooser.h" +#include "gtkfontchooserdialog.h" #include "gtkimage.h" #include "gtkmarshalers.h" +#include "gtkseparator.h" #include "gtkprivate.h" #include "gtkintl.h" -#include "gtkalias.h" #include #include +#include "gtkfontchooserutils.h" + + +/** + * SECTION:gtkfontbutton + * @Short_description: A button to launch a font chooser dialog + * @Title: GtkFontButton + * @See_also: #GtkFontChooserDialog, #GtkColorButton. + * + * The #GtkFontButton is a button which displays the currently selected + * font an allows to open a font chooser dialog to change the font. + * It is suitable widget for selecting a font in a preference dialog. + */ -#define GTK_FONT_BUTTON_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_FONT_BUTTON, GtkFontButtonPrivate)) struct _GtkFontButtonPrivate { gchar *title; - + gchar *fontname; guint use_font : 1; guint use_size : 1; guint show_style : 1; guint show_size : 1; + guint show_preview_entry : 1; GtkWidget *font_dialog; GtkWidget *inside; GtkWidget *font_label; GtkWidget *size_label; + + 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 */ @@ -84,8 +103,6 @@ enum }; /* Prototypes */ -static void gtk_font_button_init (GtkFontButton *font_button); -static void gtk_font_button_class_init (GtkFontButtonClass *klass); static void gtk_font_button_finalize (GObject *object); static void gtk_font_button_get_property (GObject *object, guint param_id, @@ -99,9 +116,8 @@ static void gtk_font_button_set_property (GObject *object, static void gtk_font_button_clicked (GtkButton *button); /* Dialog response functions */ -static void dialog_ok_clicked (GtkWidget *widget, - gpointer data); -static void dialog_cancel_clicked (GtkWidget *widget, +static void response_cb (GtkDialog *dialog, + gint response_id, gpointer data); static void dialog_destroy (GtkWidget *widget, gpointer data); @@ -111,51 +127,290 @@ static GtkWidget *gtk_font_button_create_inside (GtkFontButton *gfs); static void gtk_font_button_label_use_font (GtkFontButton *gfs); static void gtk_font_button_update_font_info (GtkFontButton *gfs); -static gpointer parent_class = NULL; static guint font_button_signals[LAST_SIGNAL] = { 0 }; -GType -gtk_font_button_get_type (void) +static void +clear_font_data (GtkFontButton *font_button) { - static GType font_button_type = 0; - - if (!font_button_type) + GtkFontButtonPrivate *priv = font_button->priv; + + if (priv->font_family) + g_object_unref (priv->font_family); + priv->font_family = NULL; + + if (priv->font_face) + g_object_unref (priv->font_face); + priv->font_face = NULL; + + if (priv->font_desc) + pango_font_description_free (priv->font_desc); + priv->font_desc = NULL; + + g_free (priv->fontname); + priv->fontname = NULL; +} + +static void +clear_font_filter_data (GtkFontButton *font_button) +{ + GtkFontButtonPrivate *priv = font_button->priv; + + if (priv->font_filter_data_destroy) + priv->font_filter_data_destroy (priv->font_filter_data); + priv->font_filter = NULL; + priv->font_filter_data = NULL; + priv->font_filter_data_destroy = NULL; +} + +static gboolean +font_description_style_equal (const PangoFontDescription *a, + const PangoFontDescription *b) +{ + return (pango_font_description_get_weight (a) == pango_font_description_get_weight (b) && + pango_font_description_get_style (a) == pango_font_description_get_style (b) && + pango_font_description_get_stretch (a) == pango_font_description_get_stretch (b) && + pango_font_description_get_variant (a) == pango_font_description_get_variant (b)); +} + +static void +gtk_font_button_update_font_data (GtkFontButton *font_button) +{ + GtkFontButtonPrivate *priv = font_button->priv; + PangoFontFamily **families; + PangoFontFace **faces; + gint n_families, n_faces, i; + const gchar *family; + + g_assert (priv->font_desc != NULL); + + priv->fontname = pango_font_description_to_string (priv->font_desc); + + family = pango_font_description_get_family (priv->font_desc); + if (family == NULL) + return; + + n_families = 0; + families = NULL; + pango_context_list_families (gtk_widget_get_pango_context (GTK_WIDGET (font_button)), + &families, &n_families); + n_faces = 0; + faces = NULL; + for (i = 0; i < n_families; i++) { - static const GTypeInfo font_button_info = - { - sizeof (GtkFontButtonClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) gtk_font_button_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (GtkFontButton), - 0, /* n_preallocs */ - (GInstanceInitFunc) gtk_font_button_init, - }; - - font_button_type = - g_type_register_static (GTK_TYPE_BUTTON, I_("GtkFontButton"), - &font_button_info, 0); + const gchar *name = pango_font_family_get_name (families[i]); + + if (!g_ascii_strcasecmp (name, family)) + { + priv->font_family = g_object_ref (families[i]); + + pango_font_family_list_faces (families[i], &faces, &n_faces); + break; + } } - - return font_button_type; + g_free (families); + + for (i = 0; i < n_faces; i++) + { + PangoFontDescription *tmp_desc = pango_font_face_describe (faces[i]); + + if (font_description_style_equal (tmp_desc, priv->font_desc)) + { + priv->font_face = g_object_ref (faces[i]); + + pango_font_description_free (tmp_desc); + break; + } + else + pango_font_description_free (tmp_desc); + } + + g_free (faces); } +static gchar * +gtk_font_button_get_preview_text (GtkFontButton *font_button) +{ + GtkFontButtonPrivate *priv = font_button->priv; + + if (priv->font_dialog) + return gtk_font_chooser_get_preview_text (GTK_FONT_CHOOSER (priv->font_dialog)); + + return g_strdup (priv->preview_text); +} + +static void +gtk_font_button_set_preview_text (GtkFontButton *font_button, + const gchar *preview_text) +{ + GtkFontButtonPrivate *priv = font_button->priv; + + if (priv->font_dialog) + { + gtk_font_chooser_set_preview_text (GTK_FONT_CHOOSER (priv->font_dialog), + preview_text); + return; + } + + g_free (priv->preview_text); + priv->preview_text = g_strdup (preview_text); +} + + +static gboolean +gtk_font_button_get_show_preview_entry (GtkFontButton *font_button) +{ + GtkFontButtonPrivate *priv = font_button->priv; + + if (priv->font_dialog) + return gtk_font_chooser_get_show_preview_entry (GTK_FONT_CHOOSER (priv->font_dialog)); + + return priv->show_preview_entry; +} + +static void +gtk_font_button_set_show_preview_entry (GtkFontButton *font_button, + gboolean show) +{ + GtkFontButtonPrivate *priv = font_button->priv; + + if (priv->font_dialog) + gtk_font_chooser_set_show_preview_entry (GTK_FONT_CHOOSER (priv->font_dialog), show); + else + priv->show_preview_entry = show != FALSE; +} + +static PangoFontFamily * +gtk_font_button_font_chooser_get_font_family (GtkFontChooser *chooser) +{ + GtkFontButton *font_button = GTK_FONT_BUTTON (chooser); + GtkFontButtonPrivate *priv = font_button->priv; + + return priv->font_family; +} + +static PangoFontFace * +gtk_font_button_font_chooser_get_font_face (GtkFontChooser *chooser) +{ + GtkFontButton *font_button = GTK_FONT_BUTTON (chooser); + GtkFontButtonPrivate *priv = font_button->priv; + + return priv->font_face; +} + +static int +gtk_font_button_font_chooser_get_font_size (GtkFontChooser *chooser) +{ + GtkFontButton *font_button = GTK_FONT_BUTTON (chooser); + GtkFontButtonPrivate *priv = font_button->priv; + + return priv->font_size; +} + +static void +gtk_font_button_font_chooser_set_filter_func (GtkFontChooser *chooser, + GtkFontFilterFunc filter_func, + gpointer filter_data, + GDestroyNotify data_destroy) +{ + GtkFontButton *font_button = GTK_FONT_BUTTON (chooser); + GtkFontButtonPrivate *priv = font_button->priv; + + if (priv->font_dialog) + { + gtk_font_chooser_set_filter_func (GTK_FONT_CHOOSER (priv->font_dialog), + filter_func, + filter_data, + data_destroy); + return; + } + + clear_font_filter_data (font_button); + priv->font_filter = filter_func; + priv->font_filter_data = filter_data; + 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); + + clear_font_data (font_button); + + if (font_desc) + priv->font_desc = font_desc; /* adopted */ + else + priv->font_desc = pango_font_description_from_string (_("Sans 12")); + + if (pango_font_description_get_size_is_absolute (priv->font_desc)) + priv->font_size = pango_font_description_get_size (priv->font_desc); + else + priv->font_size = pango_font_description_get_size (priv->font_desc) / PANGO_SCALE; + + gtk_font_button_update_font_data (font_button); + 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) +{ + /* We do not forward the notification of the "font" property to the dialog! */ + if (pspec->name == I_("preview-text") || + pspec->name == I_("show-preview-entry")) + g_object_notify_by_pspec (user_data, pspec); +} + +static void +gtk_font_button_font_chooser_iface_init (GtkFontChooserIface *iface) +{ + iface->get_font_family = gtk_font_button_font_chooser_get_font_family; + iface->get_font_face = gtk_font_button_font_chooser_get_font_face; + iface->get_font_size = gtk_font_button_font_chooser_get_font_size; + iface->set_filter_func = gtk_font_button_font_chooser_set_filter_func; +} + +G_DEFINE_TYPE_WITH_CODE (GtkFontButton, gtk_font_button, GTK_TYPE_BUTTON, + G_IMPLEMENT_INTERFACE (GTK_TYPE_FONT_CHOOSER, + gtk_font_button_font_chooser_iface_init)) static void gtk_font_button_class_init (GtkFontButtonClass *klass) { - GtkObjectClass *object_class; GObjectClass *gobject_class; GtkButtonClass *button_class; - object_class = (GtkObjectClass *) klass; gobject_class = (GObjectClass *) klass; button_class = (GtkButtonClass *) klass; - parent_class = g_type_class_peek_parent (klass); - gobject_class->finalize = gtk_font_button_finalize; gobject_class->set_property = gtk_font_button_set_property; gobject_class->get_property = gtk_font_button_get_property; @@ -164,10 +419,12 @@ gtk_font_button_class_init (GtkFontButtonClass *klass) klass->font_set = NULL; + _gtk_font_chooser_install_properties (gobject_class); + /** * GtkFontButton:title: * - * The title of the font selection dialog. + * The title of the font chooser dialog. * * Since: 2.4 */ @@ -175,7 +432,7 @@ gtk_font_button_class_init (GtkFontButtonClass *klass) PROP_TITLE, g_param_spec_string ("title", P_("Title"), - P_("The title of the font selection dialog"), + P_("The title of the font chooser dialog"), _("Pick a Font"), (GTK_PARAM_READABLE | GTK_PARAM_WRITABLE))); @@ -199,7 +456,8 @@ gtk_font_button_class_init (GtkFontButtonClass *klass) /** * GtkFontButton:use-font: * - * If this property is set to %TRUE, the label will be drawn in the selected font. + * If this property is set to %TRUE, the label will be drawn + * in the selected font. * * Since: 2.4 */ @@ -214,7 +472,8 @@ gtk_font_button_class_init (GtkFontButtonClass *klass) /** * GtkFontButton:use-size: * - * If this property is set to %TRUE, the label will be drawn with the selected font size. + * If this property is set to %TRUE, the label will be drawn + * with the selected font size. * * Since: 2.4 */ @@ -229,8 +488,9 @@ gtk_font_button_class_init (GtkFontButtonClass *klass) /** * GtkFontButton:show-style: * - * If this property is set to %TRUE, the name of the selected font style will be shown in the label. For - * a more WYSIWIG way to show the selected style, see the ::use-font property. + * If this property is set to %TRUE, the name of the selected font style + * will be shown in the label. For a more WYSIWYG way to show the selected + * style, see the ::use-font property. * * Since: 2.4 */ @@ -244,8 +504,9 @@ gtk_font_button_class_init (GtkFontButtonClass *klass) /** * GtkFontButton:show-size: * - * If this property is set to %TRUE, the selected font size will be shown in the label. For - * a more WYSIWIG way to show the selected size, see the ::use-size property. + * If this property is set to %TRUE, the selected font size will be shown + * in the label. For a more WYSIWYG way to show the selected size, see the + * ::use-size property. * * Since: 2.4 */ @@ -261,8 +522,13 @@ gtk_font_button_class_init (GtkFontButtonClass *klass) * GtkFontButton::font-set: * @widget: the object which received the signal. * - * The ::font-set signal is emitted when the user selects a font. When handling this signal, - * use gtk_font_button_get_font_name() to find out which font was just selected. + * The ::font-set signal is emitted when the user selects a font. + * When handling this signal, use gtk_font_button_get_font_name() + * to find out which font was just selected. + * + * Note that this signal is only emitted when the user + * changes the font. If you need to react to programmatic font changes + * as well, use the notify::font-name signal. * * Since: 2.4 */ @@ -280,24 +546,28 @@ gtk_font_button_class_init (GtkFontButtonClass *klass) static void gtk_font_button_init (GtkFontButton *font_button) { - font_button->priv = GTK_FONT_BUTTON_GET_PRIVATE (font_button); + font_button->priv = G_TYPE_INSTANCE_GET_PRIVATE (font_button, + GTK_TYPE_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; font_button->priv->show_size = TRUE; + font_button->priv->show_preview_entry = FALSE; font_button->priv->font_dialog = NULL; + font_button->priv->font_family = NULL; + font_button->priv->font_face = NULL; + font_button->priv->font_size = -1; font_button->priv->title = g_strdup (_("Pick a Font")); 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) { @@ -307,13 +577,16 @@ gtk_font_button_finalize (GObject *object) gtk_widget_destroy (font_button->priv->font_dialog); font_button->priv->font_dialog = NULL; - g_free (font_button->priv->fontname); - font_button->priv->fontname = NULL; - g_free (font_button->priv->title); font_button->priv->title = NULL; - - G_OBJECT_CLASS (parent_class)->finalize (object); + + clear_font_data (font_button); + clear_font_filter_data (font_button); + + g_free (font_button->priv->preview_text); + font_button->priv->preview_text = NULL; + + G_OBJECT_CLASS (gtk_font_button_parent_class)->finalize (object); } static void @@ -323,12 +596,22 @@ gtk_font_button_set_property (GObject *object, GParamSpec *pspec) { GtkFontButton *font_button = GTK_FONT_BUTTON (object); - + switch (param_id) { + case GTK_FONT_CHOOSER_PROP_PREVIEW_TEXT: + gtk_font_button_set_preview_text (font_button, g_value_get_string (value)); + break; + case GTK_FONT_CHOOSER_PROP_SHOW_PREVIEW_ENTRY: + gtk_font_button_set_show_preview_entry (font_button, g_value_get_boolean (value)); + break; 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)); break; @@ -360,9 +643,19 @@ gtk_font_button_get_property (GObject *object, switch (param_id) { + case GTK_FONT_CHOOSER_PROP_PREVIEW_TEXT: + g_value_set_string (value, gtk_font_button_get_preview_text (font_button)); + break; + case GTK_FONT_CHOOSER_PROP_SHOW_PREVIEW_ENTRY: + g_value_set_boolean (value, gtk_font_button_get_show_preview_entry (font_button)); + break; 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)); break; @@ -402,7 +695,7 @@ gtk_font_button_new (void) /** * gtk_font_button_new_with_font: - * @fontname: Name of font to display in font selection dialog + * @fontname: Name of font to display in font chooser dialog * * Creates a new font picker widget. * @@ -413,15 +706,15 @@ gtk_font_button_new (void) GtkWidget * gtk_font_button_new_with_font (const gchar *fontname) { - return g_object_new (GTK_TYPE_FONT_BUTTON, "font_name", fontname, NULL); + return g_object_new (GTK_TYPE_FONT_BUTTON, "font-name", fontname, NULL); } /** * gtk_font_button_set_title: * @font_button: a #GtkFontButton - * @title: a string containing the font selection dialog title + * @title: a string containing the font chooser dialog title * - * Sets the title for the font selection dialog. + * Sets the title for the font chooser dialog. * * Since: 2.4 */ @@ -447,13 +740,13 @@ gtk_font_button_set_title (GtkFontButton *font_button, * gtk_font_button_get_title: * @font_button: a #GtkFontButton * - * Retrieves the title of the font selection dialog. + * Retrieves the title of the font chooser dialog. * * Returns: an internal copy of the title string which must not be freed. * * Since: 2.4 */ -G_CONST_RETURN gchar* +const gchar* gtk_font_button_get_title (GtkFontButton *font_button) { g_return_val_if_fail (GTK_IS_FONT_BUTTON (font_button), NULL); @@ -500,12 +793,9 @@ gtk_font_button_set_use_font (GtkFontButton *font_button, { font_button->priv->use_font = use_font; - if (use_font) - gtk_font_button_label_use_font (font_button); - else - gtk_widget_set_style (font_button->priv->font_label, NULL); + gtk_font_button_label_use_font (font_button); - g_object_notify (G_OBJECT (font_button), "use-font"); + g_object_notify (G_OBJECT (font_button), "use-font"); } } @@ -539,7 +829,7 @@ gtk_font_button_get_use_size (GtkFontButton *font_button) */ void gtk_font_button_set_use_size (GtkFontButton *font_button, - gboolean use_size) + gboolean use_size) { g_return_if_fail (GTK_IS_FONT_BUTTON (font_button)); @@ -548,8 +838,7 @@ gtk_font_button_set_use_size (GtkFontButton *font_button, { font_button->priv->use_size = use_size; - if (font_button->priv->use_font) - gtk_font_button_label_use_font (font_button); + gtk_font_button_label_use_font (font_button); g_object_notify (G_OBJECT (font_button), "use-size"); } @@ -654,29 +943,33 @@ gtk_font_button_set_show_size (GtkFontButton *font_button, * gtk_font_button_get_font_name: * @font_button: a #GtkFontButton * - * Retrieves the name of the currently selected font. + * Retrieves the name of the currently selected font. This name includes + * style and size information as well. If you want to render something + * with the font, use this string with pango_font_description_from_string() . + * If you're interested in peeking certain values (family name, + * style, size, weight) just query these properties from the + * #PangoFontDescription object. * * Returns: an internal copy of the font name which must not be freed. * * Since: 2.4 */ -G_CONST_RETURN gchar * +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; } /** * gtk_font_button_set_font_name: * @font_button: a #GtkFontButton - * @fontname: Name of font to display in font selection dialog + * @fontname: Name of font to display in font chooser dialog * * Sets or updates the currently-displayed font in font picker dialog. * - * Returns: Return value of gtk_font_selection_dialog_set_font_name() if the - * font selection dialog exists, otherwise %FALSE. + * Returns: %TRUE * * Since: 2.4 */ @@ -684,107 +977,131 @@ gboolean gtk_font_button_set_font_name (GtkFontButton *font_button, const gchar *fontname) { - gboolean result; - 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) - result = gtk_font_selection_dialog_set_font_name (GTK_FONT_SELECTION_DIALOG (font_button->priv->font_dialog), - font_button->priv->fontname); - else - result = FALSE; - 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 result; + return TRUE; } static void gtk_font_button_clicked (GtkButton *button) { - GtkFontSelectionDialog *font_dialog; - GtkFontButton *font_button = GTK_FONT_BUTTON (button); + GtkFontChooser *font_dialog; + GtkFontButton *font_button = GTK_FONT_BUTTON (button); + GtkFontButtonPrivate *priv = font_button->priv; if (!font_button->priv->font_dialog) { GtkWidget *parent; parent = gtk_widget_get_toplevel (GTK_WIDGET (font_button)); - - font_button->priv->font_dialog = gtk_font_selection_dialog_new (font_button->priv->title); - - font_dialog = GTK_FONT_SELECTION_DIALOG (font_button->priv->font_dialog); - - if (parent) - gtk_window_set_transient_for (GTK_WINDOW (font_dialog), GTK_WINDOW (parent)); - - /* If there is a grabbed window, set new dialog as modal */ - if (gtk_grab_get_current ()) - gtk_window_set_modal (GTK_WINDOW (font_dialog), TRUE); - - g_signal_connect (font_dialog->ok_button, "clicked", - G_CALLBACK (dialog_ok_clicked), font_button); - g_signal_connect (font_dialog->cancel_button, "clicked", - G_CALLBACK (dialog_cancel_clicked), font_button); + + priv->font_dialog = gtk_font_chooser_dialog_new (priv->title, NULL); + font_dialog = GTK_FONT_CHOOSER (font_button->priv->font_dialog); + + gtk_font_chooser_set_show_preview_entry (font_dialog, priv->show_preview_entry); + + if (priv->preview_text) + { + gtk_font_chooser_set_preview_text (font_dialog, priv->preview_text); + g_free (priv->preview_text); + priv->preview_text = NULL; + } + + if (priv->font_filter) + { + gtk_font_chooser_set_filter_func (font_dialog, + priv->font_filter, + priv->font_filter_data, + priv->font_filter_data_destroy); + priv->font_filter = NULL; + priv->font_filter_data = NULL; + priv->font_filter_data_destroy = NULL; + } + + if (gtk_widget_is_toplevel (parent) && GTK_IS_WINDOW (parent)) + { + if (GTK_WINDOW (parent) != gtk_window_get_transient_for (GTK_WINDOW (font_dialog))) + gtk_window_set_transient_for (GTK_WINDOW (font_dialog), GTK_WINDOW (parent)); + + gtk_window_set_modal (GTK_WINDOW (font_dialog), + gtk_window_get_modal (GTK_WINDOW (parent))); + } + + g_signal_connect (font_dialog, "notify", + G_CALLBACK (gtk_font_button_font_chooser_notify), button); + + g_signal_connect (font_dialog, "response", + G_CALLBACK (response_cb), font_button); + g_signal_connect (font_dialog, "destroy", G_CALLBACK (dialog_destroy), font_button); } - if (!GTK_WIDGET_VISIBLE (font_button->priv->font_dialog)) + if (!gtk_widget_get_visible (font_button->priv->font_dialog)) { - font_dialog = GTK_FONT_SELECTION_DIALOG (font_button->priv->font_dialog); - - gtk_font_selection_dialog_set_font_name (font_dialog, font_button->priv->fontname); - + font_dialog = GTK_FONT_CHOOSER (font_button->priv->font_dialog); + gtk_font_chooser_set_font_desc (font_dialog, font_button->priv->font_desc); } gtk_window_present (GTK_WINDOW (font_button->priv->font_dialog)); } + static void -dialog_ok_clicked (GtkWidget *widget, - gpointer data) +response_cb (GtkDialog *dialog, + gint response_id, + gpointer data) { 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); - - g_free (font_button->priv->fontname); - font_button->priv->fontname = gtk_font_selection_dialog_get_font_name (GTK_FONT_SELECTION_DIALOG (font_button->priv->font_dialog)); - + + if (response_id != GTK_RESPONSE_OK) + return; + + font_chooser = GTK_FONT_CHOOSER (priv->font_dialog); + object = G_OBJECT (font_chooser); + + g_object_freeze_notify (object); + + clear_font_data (font_button); + + priv->font_desc = gtk_font_chooser_get_font_desc (font_chooser); + if (priv->font_desc) + priv->fontname = pango_font_description_to_string (priv->font_desc); + priv->font_family = gtk_font_chooser_get_font_family (font_chooser); + if (priv->font_family) + g_object_ref (priv->font_family); + priv->font_face = gtk_font_chooser_get_font_face (font_chooser); + if (priv->font_face) + g_object_ref (priv->font_face); + priv->font_size = gtk_font_chooser_get_font_size (font_chooser); + /* Set label font */ 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"); - - /* Emit font_set signal */ - g_signal_emit (font_button, font_button_signals[FONT_SET], 0); -} + g_object_thaw_notify (object); -static void -dialog_cancel_clicked (GtkWidget *widget, - gpointer data) -{ - GtkFontButton *font_button = GTK_FONT_BUTTON (data); - - gtk_widget_hide (font_button->priv->font_dialog); + /* Emit font_set signal */ + g_signal_emit (font_button, font_button_signals[FONT_SET], 0); } static void dialog_destroy (GtkWidget *widget, - gpointer data) + gpointer data) { GtkFontButton *font_button = GTK_FONT_BUTTON (data); @@ -799,8 +1116,8 @@ gtk_font_button_create_inside (GtkFontButton *font_button) gtk_widget_push_composite_child (); - widget = gtk_hbox_new (FALSE, 0); - + widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + font_button->priv->font_label = gtk_label_new (_("Font")); gtk_label_set_justify (GTK_LABEL (font_button->priv->font_label), GTK_JUSTIFY_LEFT); @@ -808,7 +1125,7 @@ gtk_font_button_create_inside (GtkFontButton *font_button) if (font_button->priv->show_size) { - gtk_box_pack_start (GTK_BOX (widget), gtk_vseparator_new (), FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (widget), gtk_separator_new (GTK_ORIENTATION_VERTICAL), FALSE, FALSE, 0); font_button->priv->size_label = gtk_label_new ("14"); gtk_box_pack_start (GTK_BOX (widget), font_button->priv->size_label, FALSE, FALSE, 5); } @@ -825,103 +1142,50 @@ gtk_font_button_label_use_font (GtkFontButton *font_button) { PangoFontDescription *desc; - if (!font_button->priv->use_font) - return; - - desc = pango_font_description_from_string (font_button->priv->fontname); - - if (!font_button->priv->use_size) - pango_font_description_unset_fields (desc, PANGO_FONT_MASK_SIZE); + if (font_button->priv->use_font) + { + desc = pango_font_description_copy (font_button->priv->font_desc); - gtk_widget_modify_font (font_button->priv->font_label, desc); + if (!font_button->priv->use_size) + pango_font_description_unset_fields (desc, PANGO_FONT_MASK_SIZE); + } + else + desc = NULL; - pango_font_description_free (desc); -} + gtk_widget_override_font (font_button->priv->font_label, desc); -static gboolean -font_description_style_equal (const PangoFontDescription *a, - const PangoFontDescription *b) -{ - return (pango_font_description_get_weight (a) == pango_font_description_get_weight (b) && - pango_font_description_get_style (a) == pango_font_description_get_style (b) && - pango_font_description_get_stretch (a) == pango_font_description_get_stretch (b) && - pango_font_description_get_variant (a) == pango_font_description_get_variant (b)); + if (desc) + pango_font_description_free (desc); } static void gtk_font_button_update_font_info (GtkFontButton *font_button) { - PangoFontDescription *desc; - const gchar *family; - gchar *style; + GtkFontButtonPrivate *priv = font_button->priv; gchar *family_style; - - desc = pango_font_description_from_string (font_button->priv->fontname); - family = pango_font_description_get_family (desc); - -#if 0 - /* This gives the wrong names, e.g. Italic when the font selection - * dialog displayed Oblique. - */ - pango_font_description_unset_fields (desc, PANGO_FONT_MASK_FAMILY | PANGO_FONT_MASK_SIZE); - style = pango_font_description_to_string (desc); - gtk_label_set_text (GTK_LABEL (font_button->priv->style_label), style); -#endif - style = NULL; - if (font_button->priv->show_style && family) + g_assert (priv->font_desc != NULL); + + if (priv->show_style) { - PangoFontFamily **families; - PangoFontFace **faces; - gint n_families, n_faces, i; - - n_families = 0; - pango_context_list_families (gtk_widget_get_pango_context (GTK_WIDGET (font_button)), - &families, &n_families); - n_faces = 0; - faces = NULL; - for (i = 0; i < n_families; i++) - { - const gchar *name = pango_font_family_get_name (families[i]); - - if (!g_ascii_strcasecmp (name, family)) - { - pango_font_family_list_faces (families[i], &faces, &n_faces); - break; - } - } - g_free (families); - - for (i = 0; i < n_faces; i++) - { - PangoFontDescription *tmp_desc = pango_font_face_describe (faces[i]); - - if (font_description_style_equal (tmp_desc, desc)) - { - style = g_strdup (pango_font_face_get_face_name (faces[i])); - pango_font_description_free (tmp_desc); - break; - } - else - pango_font_description_free (tmp_desc); - } - g_free (faces); - } + PangoFontDescription *desc = pango_font_description_copy_static (priv->font_desc); - if (style == NULL || !g_ascii_strcasecmp (style, "Regular")) - family_style = g_strdup (family); + pango_font_description_unset_fields (desc, PANGO_FONT_MASK_SIZE); + family_style = pango_font_description_to_string (desc); + pango_font_description_free (desc); + } else - family_style = g_strdup_printf ("%s %s", family, style); - + family_style = g_strdup (pango_font_description_get_family (priv->font_desc)); + gtk_label_set_text (GTK_LABEL (font_button->priv->font_label), family_style); - - g_free (style); g_free (family_style); if (font_button->priv->show_size) { - gchar *size = g_strdup_printf ("%d", - pango_font_description_get_size (desc) / PANGO_SCALE); + /* mirror Pango, which doesn't translate this either */ + gchar *size = g_strdup_printf ("%g%s", + pango_font_description_get_size (priv->font_desc) / (double)PANGO_SCALE, + pango_font_description_get_size_is_absolute (priv->font_desc) ? "px" : ""); gtk_label_set_text (GTK_LABEL (font_button->priv->size_label), size); @@ -929,9 +1193,4 @@ gtk_font_button_update_font_info (GtkFontButton *font_button) } gtk_font_button_label_use_font (font_button); - - pango_font_description_free (desc); } - -#define __GTK_FONT_BUTTON_C__ -#include "gtkaliasdef.c"