]> Pileus Git - ~andy/gtk/blob - gtk/gtkfontbutton.c
Add GtkFontChooser:font-desc property
[~andy/gtk] / gtk / gtkfontbutton.c
1 /* 
2  * GTK - The GIMP Toolkit
3  * Copyright (C) 1998 David Abilleira Freijeiro <odaf@nexo.es>
4  * All rights reserved.
5  *
6  * Based on gnome-color-picker by Federico Mena <federico@nuclecu.unam.mx>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
21  */
22 /*
23  * Modified by the GTK+ Team and others 2003.  See the AUTHORS
24  * file for a list of people on the GTK+ Team.  See the ChangeLog
25  * files for a list of changes.  These files are distributed with
26  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
27  */
28
29 #include "config.h"
30
31 #include "gtkfontbutton.h"
32
33 #include "gtkmain.h"
34 #include "gtkbox.h"
35 #include "gtklabel.h"
36 #include "gtkfontchooser.h"
37 #include "gtkfontchooserdialog.h"
38 #include "gtkimage.h"
39 #include "gtkmarshalers.h"
40 #include "gtkseparator.h"
41 #include "gtkprivate.h"
42 #include "gtkintl.h"
43
44 #include <string.h>
45 #include <stdio.h>
46 #include "gtkfontchooserutils.h"
47
48
49 /**
50  * SECTION:gtkfontbutton
51  * @Short_description: A button to launch a font chooser dialog
52  * @Title: GtkFontButton
53  * @See_also: #GtkFontChooserDialog, #GtkColorButton.
54  *
55  * The #GtkFontButton is a button which displays the currently selected
56  * font an allows to open a font chooser dialog to change the font.
57  * It is suitable widget for selecting a font in a preference dialog.
58  */
59
60
61 struct _GtkFontButtonPrivate 
62 {
63   gchar         *title;
64
65   gchar         *fontname;
66   
67   guint         use_font : 1;
68   guint         use_size : 1;
69   guint         show_style : 1;
70   guint         show_size : 1;
71   guint         show_preview_entry : 1;
72    
73   GtkWidget     *font_dialog;
74   GtkWidget     *inside;
75   GtkWidget     *font_label;
76   GtkWidget     *size_label;
77
78   PangoFontDescription *font_desc;
79   PangoFontFamily      *font_family;
80   PangoFontFace        *font_face;
81   gint                  font_size;
82   gchar                *preview_text;
83   GtkFontFilterFunc     font_filter;
84   gpointer              font_filter_data;
85   GDestroyNotify        font_filter_data_destroy;
86 };
87
88 /* Signals */
89 enum 
90 {
91   FONT_SET,
92   LAST_SIGNAL
93 };
94
95 enum 
96 {
97   PROP_0,
98   PROP_TITLE,
99   PROP_FONT_NAME,
100   PROP_USE_FONT,
101   PROP_USE_SIZE,
102   PROP_SHOW_STYLE,
103   PROP_SHOW_SIZE
104 };
105
106 /* Prototypes */
107 static void gtk_font_button_finalize               (GObject            *object);
108 static void gtk_font_button_get_property           (GObject            *object,
109                                                     guint               param_id,
110                                                     GValue             *value,
111                                                     GParamSpec         *pspec);
112 static void gtk_font_button_set_property           (GObject            *object,
113                                                     guint               param_id,
114                                                     const GValue       *value,
115                                                     GParamSpec         *pspec);
116
117 static void gtk_font_button_clicked                 (GtkButton         *button);
118
119 /* Dialog response functions */
120 static void response_cb                             (GtkDialog         *dialog,
121                                                      gint               response_id,
122                                                      gpointer           data);
123 static void dialog_destroy                          (GtkWidget         *widget,
124                                                      gpointer           data);
125
126 /* Auxiliary functions */
127 static GtkWidget *gtk_font_button_create_inside     (GtkFontButton     *gfs);
128 static void gtk_font_button_label_use_font          (GtkFontButton     *gfs);
129 static void gtk_font_button_update_font_info        (GtkFontButton     *gfs);
130
131 static guint font_button_signals[LAST_SIGNAL] = { 0 };
132
133 static void
134 clear_font_filter_data (GtkFontButton *font_button)
135 {
136   GtkFontButtonPrivate *priv = font_button->priv;
137
138   if (priv->font_filter_data_destroy)
139     priv->font_filter_data_destroy (priv->font_filter_data);
140   priv->font_filter = NULL;
141   priv->font_filter_data = NULL;
142   priv->font_filter_data_destroy = NULL;
143 }
144
145 static gchar *
146 gtk_font_button_get_preview_text (GtkFontButton *font_button)
147 {
148   GtkFontButtonPrivate *priv = font_button->priv;
149
150   if (priv->font_dialog)
151     return gtk_font_chooser_get_preview_text (GTK_FONT_CHOOSER (priv->font_dialog));
152
153   return g_strdup (priv->preview_text);
154 }
155
156 static void
157 gtk_font_button_set_preview_text (GtkFontButton *font_button,
158                                   const gchar   *preview_text)
159 {
160   GtkFontButtonPrivate *priv = font_button->priv;
161
162   if (priv->font_dialog)
163     {
164       gtk_font_chooser_set_preview_text (GTK_FONT_CHOOSER (priv->font_dialog),
165                                          preview_text);
166       return;
167     }
168
169   g_free (priv->preview_text);
170   priv->preview_text = g_strdup (preview_text);
171 }
172
173
174 static gboolean
175 gtk_font_button_get_show_preview_entry (GtkFontButton *font_button)
176 {
177   GtkFontButtonPrivate *priv = font_button->priv;
178
179   if (priv->font_dialog)
180     return gtk_font_chooser_get_show_preview_entry (GTK_FONT_CHOOSER (priv->font_dialog));
181
182   return priv->show_preview_entry;
183 }
184
185 static void
186 gtk_font_button_set_show_preview_entry (GtkFontButton *font_button,
187                                         gboolean       show)
188 {
189   GtkFontButtonPrivate *priv = font_button->priv;
190
191   if (priv->font_dialog)
192     return gtk_font_chooser_set_show_preview_entry (GTK_FONT_CHOOSER (priv->font_dialog), show);
193
194   priv->show_preview_entry = show != FALSE;
195 }
196
197 static PangoFontFamily *
198 gtk_font_button_font_chooser_get_font_family (GtkFontChooser *chooser)
199 {
200   GtkFontButton *font_button = GTK_FONT_BUTTON (chooser);
201   GtkFontButtonPrivate *priv = font_button->priv;
202
203   return priv->font_family;
204 }
205
206 static PangoFontFace *
207 gtk_font_button_font_chooser_get_font_face (GtkFontChooser *chooser)
208 {
209   GtkFontButton *font_button = GTK_FONT_BUTTON (chooser);
210   GtkFontButtonPrivate *priv = font_button->priv;
211
212   return priv->font_face;
213 }
214
215 static int
216 gtk_font_button_font_chooser_get_font_size (GtkFontChooser *chooser)
217 {
218   GtkFontButton *font_button = GTK_FONT_BUTTON (chooser);
219   GtkFontButtonPrivate *priv = font_button->priv;
220
221   return priv->font_size;
222 }
223
224 static void
225 gtk_font_button_font_chooser_set_filter_func (GtkFontChooser    *chooser,
226                                               GtkFontFilterFunc  filter_func,
227                                               gpointer           filter_data,
228                                               GDestroyNotify     data_destroy)
229 {
230   GtkFontButton *font_button = GTK_FONT_BUTTON (chooser);
231   GtkFontButtonPrivate *priv = font_button->priv;
232
233   if (priv->font_dialog)
234     {
235       gtk_font_chooser_set_filter_func (GTK_FONT_CHOOSER (priv->font_dialog),
236                                         filter_func,
237                                         filter_data,
238                                         data_destroy);
239       return;
240     }
241
242   clear_font_filter_data (font_button);
243   priv->font_filter = filter_func;
244   priv->font_filter_data = filter_data;
245   priv->font_filter_data_destroy = data_destroy;
246 }
247
248 static void
249 gtk_font_button_take_font_desc (GtkFontButton        *font_button,
250                                 PangoFontDescription *font_desc)
251 {
252   GtkFontButtonPrivate *priv = font_button->priv;
253   GObject *object = G_OBJECT (font_button);
254
255   if (priv->font_desc && font_desc &&
256       pango_font_description_equal (priv->font_desc, font_desc))
257     {
258       pango_font_description_free (font_desc);
259       return;
260     }
261
262   g_object_freeze_notify (object);
263
264   if (priv->font_desc)
265     pango_font_description_free (priv->font_desc);
266   if (font_desc)
267     priv->font_desc = font_desc; /* adopted */
268   else
269     priv->font_desc = pango_font_description_from_string (_("Sans 12"));
270
271   g_free (priv->fontname);
272   priv->fontname = pango_font_description_to_string (priv->font_desc);
273
274   gtk_font_button_update_font_info (font_button);
275
276   if (priv->font_dialog)
277     gtk_font_chooser_set_font_desc (GTK_FONT_CHOOSER (priv->font_dialog),
278                                     priv->font_desc);
279
280   g_object_notify (G_OBJECT (font_button), "font");
281   g_object_notify (G_OBJECT (font_button), "font-desc");
282   g_object_notify (G_OBJECT (font_button), "font-name");
283
284   g_object_thaw_notify (object);
285 }
286
287 static const PangoFontDescription *
288 gtk_font_button_get_font_desc (GtkFontButton *font_button)
289 {
290   return font_button->priv->font_desc;
291 }
292
293 static void
294 gtk_font_button_font_chooser_notify (GObject    *object,
295                                      GParamSpec *pspec,
296                                      gpointer    user_data)
297 {
298   /* We do not forward the notification of the "font" property to the dialog! */
299   if (pspec->name == I_("preview-text") ||
300       pspec->name == I_("show-preview-entry"))
301     g_object_notify_by_pspec (user_data, pspec);
302 }
303
304 static void
305 gtk_font_button_font_chooser_iface_init (GtkFontChooserIface *iface)
306 {
307   iface->get_font_family = gtk_font_button_font_chooser_get_font_family;
308   iface->get_font_face = gtk_font_button_font_chooser_get_font_face;
309   iface->get_font_size = gtk_font_button_font_chooser_get_font_size;
310   iface->set_filter_func = gtk_font_button_font_chooser_set_filter_func;
311 }
312
313 G_DEFINE_TYPE_WITH_CODE (GtkFontButton, gtk_font_button, GTK_TYPE_BUTTON,
314                          G_IMPLEMENT_INTERFACE (GTK_TYPE_FONT_CHOOSER,
315                                                 gtk_font_button_font_chooser_iface_init))
316
317 static void
318 gtk_font_button_class_init (GtkFontButtonClass *klass)
319 {
320   GObjectClass *gobject_class;
321   GtkButtonClass *button_class;
322   
323   gobject_class = (GObjectClass *) klass;
324   button_class = (GtkButtonClass *) klass;
325
326   gobject_class->finalize = gtk_font_button_finalize;
327   gobject_class->set_property = gtk_font_button_set_property;
328   gobject_class->get_property = gtk_font_button_get_property;
329   
330   button_class->clicked = gtk_font_button_clicked;
331   
332   klass->font_set = NULL;
333
334   _gtk_font_chooser_install_properties (gobject_class);
335
336   /**
337    * GtkFontButton:title:
338    * 
339    * The title of the font chooser dialog.
340    *
341    * Since: 2.4
342    */
343   g_object_class_install_property (gobject_class,
344                                    PROP_TITLE,
345                                    g_param_spec_string ("title",
346                                                         P_("Title"),
347                                                         P_("The title of the font chooser dialog"),
348                                                         _("Pick a Font"),
349                                                         (GTK_PARAM_READABLE |
350                                                          GTK_PARAM_WRITABLE)));
351
352   /**
353    * GtkFontButton:font-name:
354    * 
355    * The name of the currently selected font.
356    *
357    * Since: 2.4
358    */
359   g_object_class_install_property (gobject_class,
360                                    PROP_FONT_NAME,
361                                    g_param_spec_string ("font-name",
362                                                         P_("Font name"),
363                                                         P_("The name of the selected font"),
364                                                         P_("Sans 12"),
365                                                         (GTK_PARAM_READABLE |
366                                                          GTK_PARAM_WRITABLE)));
367
368   /**
369    * GtkFontButton:use-font:
370    * 
371    * If this property is set to %TRUE, the label will be drawn 
372    * in the selected font.
373    *
374    * Since: 2.4
375    */
376   g_object_class_install_property (gobject_class,
377                                    PROP_USE_FONT,
378                                    g_param_spec_boolean ("use-font",
379                                                          P_("Use font in label"),
380                                                          P_("Whether the label is drawn in the selected font"),
381                                                          FALSE,
382                                                          GTK_PARAM_READWRITE));
383
384   /**
385    * GtkFontButton:use-size:
386    * 
387    * If this property is set to %TRUE, the label will be drawn 
388    * with the selected font size.
389    *
390    * Since: 2.4
391    */
392   g_object_class_install_property (gobject_class,
393                                    PROP_USE_SIZE,
394                                    g_param_spec_boolean ("use-size",
395                                                          P_("Use size in label"),
396                                                          P_("Whether the label is drawn with the selected font size"),
397                                                          FALSE,
398                                                          GTK_PARAM_READWRITE));
399
400   /**
401    * GtkFontButton:show-style:
402    * 
403    * If this property is set to %TRUE, the name of the selected font style 
404    * will be shown in the label. For a more WYSIWYG way to show the selected 
405    * style, see the ::use-font property. 
406    *
407    * Since: 2.4
408    */
409   g_object_class_install_property (gobject_class,
410                                    PROP_SHOW_STYLE,
411                                    g_param_spec_boolean ("show-style",
412                                                          P_("Show style"),
413                                                          P_("Whether the selected font style is shown in the label"),
414                                                          TRUE,
415                                                          GTK_PARAM_READWRITE));
416   /**
417    * GtkFontButton:show-size:
418    * 
419    * If this property is set to %TRUE, the selected font size will be shown 
420    * in the label. For a more WYSIWYG way to show the selected size, see the 
421    * ::use-size property. 
422    *
423    * Since: 2.4
424    */
425   g_object_class_install_property (gobject_class,
426                                    PROP_SHOW_SIZE,
427                                    g_param_spec_boolean ("show-size",
428                                                          P_("Show size"),
429                                                          P_("Whether selected font size is shown in the label"),
430                                                          TRUE,
431                                                          GTK_PARAM_READWRITE));
432
433   /**
434    * GtkFontButton::font-set:
435    * @widget: the object which received the signal.
436    * 
437    * The ::font-set signal is emitted when the user selects a font. 
438    * When handling this signal, use gtk_font_button_get_font_name() 
439    * to find out which font was just selected.
440    *
441    * Note that this signal is only emitted when the <emphasis>user</emphasis>
442    * changes the font. If you need to react to programmatic font changes
443    * as well, use the notify::font-name signal.
444    *
445    * Since: 2.4
446    */
447   font_button_signals[FONT_SET] = g_signal_new (I_("font-set"),
448                                                 G_TYPE_FROM_CLASS (gobject_class),
449                                                 G_SIGNAL_RUN_FIRST,
450                                                 G_STRUCT_OFFSET (GtkFontButtonClass, font_set),
451                                                 NULL, NULL,
452                                                 g_cclosure_marshal_VOID__VOID,
453                                                 G_TYPE_NONE, 0);
454   
455   g_type_class_add_private (gobject_class, sizeof (GtkFontButtonPrivate));
456 }
457
458 static void
459 gtk_font_button_init (GtkFontButton *font_button)
460 {
461   font_button->priv = G_TYPE_INSTANCE_GET_PRIVATE (font_button,
462                                                    GTK_TYPE_FONT_BUTTON,
463                                                    GtkFontButtonPrivate);
464
465   /* Initialize fields */
466   font_button->priv->use_font = FALSE;
467   font_button->priv->use_size = FALSE;
468   font_button->priv->show_style = TRUE;
469   font_button->priv->show_size = TRUE;
470   font_button->priv->show_preview_entry = FALSE;
471   font_button->priv->font_dialog = NULL;
472   font_button->priv->font_family = NULL;
473   font_button->priv->font_face = NULL;
474   font_button->priv->font_size = -1;
475   font_button->priv->title = g_strdup (_("Pick a Font"));
476
477   font_button->priv->inside = gtk_font_button_create_inside (font_button);
478   gtk_container_add (GTK_CONTAINER (font_button), font_button->priv->inside);
479
480   gtk_font_button_take_font_desc (font_button, NULL);
481 }
482
483 static void
484 gtk_font_button_finalize (GObject *object)
485 {
486   GtkFontButton *font_button = GTK_FONT_BUTTON (object);
487
488   if (font_button->priv->font_dialog != NULL) 
489     gtk_widget_destroy (font_button->priv->font_dialog);
490   font_button->priv->font_dialog = NULL;
491
492   g_free (font_button->priv->fontname);
493   font_button->priv->fontname = NULL;
494
495   g_free (font_button->priv->title);
496   font_button->priv->title = NULL;
497
498   clear_font_filter_data (font_button);
499
500   g_free (font_button->priv->preview_text);
501   font_button->priv->preview_text = NULL;
502
503   if (font_button->priv->font_family)
504     g_object_unref (font_button->priv->font_family);
505   font_button->priv->font_family = NULL;
506
507   if (font_button->priv->font_face)
508     g_object_unref (font_button->priv->font_face);
509   font_button->priv->font_face = NULL;
510
511   if (font_button->priv->font_desc)
512     pango_font_description_free (font_button->priv->font_desc);
513   font_button->priv->font_desc = NULL;
514
515   G_OBJECT_CLASS (gtk_font_button_parent_class)->finalize (object);
516 }
517
518 static void
519 gtk_font_button_set_property (GObject      *object,
520                               guint         param_id,
521                               const GValue *value,
522                               GParamSpec   *pspec)
523 {
524   GtkFontButton *font_button = GTK_FONT_BUTTON (object);
525
526   switch (param_id) 
527     {
528     case GTK_FONT_CHOOSER_PROP_PREVIEW_TEXT:
529       gtk_font_button_set_preview_text (font_button, g_value_get_string (value));
530       break;
531     case GTK_FONT_CHOOSER_PROP_SHOW_PREVIEW_ENTRY:
532       gtk_font_button_set_show_preview_entry (font_button, g_value_get_boolean (value));
533       break;
534     case PROP_TITLE:
535       gtk_font_button_set_title (font_button, g_value_get_string (value));
536       break;
537     case GTK_FONT_CHOOSER_PROP_FONT_DESC:
538       gtk_font_button_take_font_desc (font_button, g_value_dup_boxed (value));
539       break;
540     case GTK_FONT_CHOOSER_PROP_FONT:
541     case PROP_FONT_NAME:
542       gtk_font_button_set_font_name (font_button, g_value_get_string (value));
543       break;
544     case PROP_USE_FONT:
545       gtk_font_button_set_use_font (font_button, g_value_get_boolean (value));
546       break;
547     case PROP_USE_SIZE:
548       gtk_font_button_set_use_size (font_button, g_value_get_boolean (value));
549       break;
550     case PROP_SHOW_STYLE:
551       gtk_font_button_set_show_style (font_button, g_value_get_boolean (value));
552       break;
553     case PROP_SHOW_SIZE:
554       gtk_font_button_set_show_size (font_button, g_value_get_boolean (value));
555       break;
556     default:
557       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
558       break;
559   }
560 }
561
562 static void
563 gtk_font_button_get_property (GObject    *object,
564                               guint       param_id,
565                               GValue     *value,
566                               GParamSpec *pspec)
567 {
568   GtkFontButton *font_button = GTK_FONT_BUTTON (object);
569   
570   switch (param_id) 
571     {
572     case GTK_FONT_CHOOSER_PROP_PREVIEW_TEXT:
573       g_value_set_string (value, gtk_font_button_get_preview_text (font_button));
574       break;
575     case GTK_FONT_CHOOSER_PROP_SHOW_PREVIEW_ENTRY:
576       g_value_set_boolean (value, gtk_font_button_get_show_preview_entry (font_button));
577       break;
578     case PROP_TITLE:
579       g_value_set_string (value, gtk_font_button_get_title (font_button));
580       break;
581     case GTK_FONT_CHOOSER_PROP_FONT_DESC:
582       g_value_set_boxed (value, gtk_font_button_get_font_desc (font_button));
583       break;
584     case GTK_FONT_CHOOSER_PROP_FONT:
585     case PROP_FONT_NAME:
586       g_value_set_string (value, gtk_font_button_get_font_name (font_button));
587       break;
588     case PROP_USE_FONT:
589       g_value_set_boolean (value, gtk_font_button_get_use_font (font_button));
590       break;
591     case PROP_USE_SIZE:
592       g_value_set_boolean (value, gtk_font_button_get_use_size (font_button));
593       break;
594     case PROP_SHOW_STYLE:
595       g_value_set_boolean (value, gtk_font_button_get_show_style (font_button));
596       break;
597     case PROP_SHOW_SIZE:
598       g_value_set_boolean (value, gtk_font_button_get_show_size (font_button));
599       break;
600     default:
601       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
602       break;
603     }
604
605
606
607 /**
608  * gtk_font_button_new:
609  *
610  * Creates a new font picker widget.
611  *
612  * Returns: a new font picker widget.
613  *
614  * Since: 2.4
615  */
616 GtkWidget *
617 gtk_font_button_new (void)
618 {
619   return g_object_new (GTK_TYPE_FONT_BUTTON, NULL);
620
621
622 /**
623  * gtk_font_button_new_with_font:
624  * @fontname: Name of font to display in font chooser dialog
625  *
626  * Creates a new font picker widget.
627  *
628  * Returns: a new font picker widget.
629  *
630  * Since: 2.4
631  */
632 GtkWidget *
633 gtk_font_button_new_with_font (const gchar *fontname)
634 {
635   return g_object_new (GTK_TYPE_FONT_BUTTON, "font-name", fontname, NULL);
636
637
638 /**
639  * gtk_font_button_set_title:
640  * @font_button: a #GtkFontButton
641  * @title: a string containing the font chooser dialog title
642  *
643  * Sets the title for the font chooser dialog.  
644  *
645  * Since: 2.4
646  */
647 void
648 gtk_font_button_set_title (GtkFontButton *font_button, 
649                            const gchar   *title)
650 {
651   gchar *old_title;
652   g_return_if_fail (GTK_IS_FONT_BUTTON (font_button));
653   
654   old_title = font_button->priv->title;
655   font_button->priv->title = g_strdup (title);
656   g_free (old_title);
657   
658   if (font_button->priv->font_dialog)
659     gtk_window_set_title (GTK_WINDOW (font_button->priv->font_dialog),
660                           font_button->priv->title);
661
662   g_object_notify (G_OBJECT (font_button), "title");
663
664
665 /**
666  * gtk_font_button_get_title:
667  * @font_button: a #GtkFontButton
668  *
669  * Retrieves the title of the font chooser dialog.
670  *
671  * Returns: an internal copy of the title string which must not be freed.
672  *
673  * Since: 2.4
674  */
675 const gchar*
676 gtk_font_button_get_title (GtkFontButton *font_button)
677 {
678   g_return_val_if_fail (GTK_IS_FONT_BUTTON (font_button), NULL);
679
680   return font_button->priv->title;
681
682
683 /**
684  * gtk_font_button_get_use_font:
685  * @font_button: a #GtkFontButton
686  *
687  * Returns whether the selected font is used in the label.
688  *
689  * Returns: whether the selected font is used in the label.
690  *
691  * Since: 2.4
692  */
693 gboolean
694 gtk_font_button_get_use_font (GtkFontButton *font_button)
695 {
696   g_return_val_if_fail (GTK_IS_FONT_BUTTON (font_button), FALSE);
697
698   return font_button->priv->use_font;
699
700
701 /**
702  * gtk_font_button_set_use_font:
703  * @font_button: a #GtkFontButton
704  * @use_font: If %TRUE, font name will be written using font chosen.
705  *
706  * If @use_font is %TRUE, the font name will be written using the selected font.  
707  *
708  * Since: 2.4
709  */
710 void  
711 gtk_font_button_set_use_font (GtkFontButton *font_button,
712                               gboolean       use_font)
713 {
714   g_return_if_fail (GTK_IS_FONT_BUTTON (font_button));
715   
716   use_font = (use_font != FALSE);
717   
718   if (font_button->priv->use_font != use_font) 
719     {
720       font_button->priv->use_font = use_font;
721
722       if (use_font)
723         gtk_font_button_label_use_font (font_button);
724       else
725         gtk_widget_set_style (font_button->priv->font_label, NULL);
726  
727      g_object_notify (G_OBJECT (font_button), "use-font");
728     }
729
730
731
732 /**
733  * gtk_font_button_get_use_size:
734  * @font_button: a #GtkFontButton
735  *
736  * Returns whether the selected size is used in the label.
737  *
738  * Returns: whether the selected size is used in the label.
739  *
740  * Since: 2.4
741  */
742 gboolean
743 gtk_font_button_get_use_size (GtkFontButton *font_button)
744 {
745   g_return_val_if_fail (GTK_IS_FONT_BUTTON (font_button), FALSE);
746
747   return font_button->priv->use_size;
748
749
750 /**
751  * gtk_font_button_set_use_size:
752  * @font_button: a #GtkFontButton
753  * @use_size: If %TRUE, font name will be written using the selected size.
754  *
755  * If @use_size is %TRUE, the font name will be written using the selected size.
756  *
757  * Since: 2.4
758  */
759 void  
760 gtk_font_button_set_use_size (GtkFontButton *font_button,
761                               gboolean       use_size)
762 {
763   g_return_if_fail (GTK_IS_FONT_BUTTON (font_button));
764   
765   use_size = (use_size != FALSE);
766   if (font_button->priv->use_size != use_size) 
767     {
768       font_button->priv->use_size = use_size;
769
770       if (font_button->priv->use_font)
771         gtk_font_button_label_use_font (font_button);
772
773       g_object_notify (G_OBJECT (font_button), "use-size");
774     }
775
776
777 /**
778  * gtk_font_button_get_show_style:
779  * @font_button: a #GtkFontButton
780  * 
781  * Returns whether the name of the font style will be shown in the label.
782  * 
783  * Return value: whether the font style will be shown in the label.
784  *
785  * Since: 2.4
786  **/
787 gboolean 
788 gtk_font_button_get_show_style (GtkFontButton *font_button)
789 {
790   g_return_val_if_fail (GTK_IS_FONT_BUTTON (font_button), FALSE);
791
792   return font_button->priv->show_style;
793 }
794
795 /**
796  * gtk_font_button_set_show_style:
797  * @font_button: a #GtkFontButton
798  * @show_style: %TRUE if font style should be displayed in label.
799  *
800  * If @show_style is %TRUE, the font style will be displayed along with name of the selected font.
801  *
802  * Since: 2.4
803  */
804 void
805 gtk_font_button_set_show_style (GtkFontButton *font_button,
806                                 gboolean       show_style)
807 {
808   g_return_if_fail (GTK_IS_FONT_BUTTON (font_button));
809   
810   show_style = (show_style != FALSE);
811   if (font_button->priv->show_style != show_style) 
812     {
813       font_button->priv->show_style = show_style;
814       
815       gtk_font_button_update_font_info (font_button);
816   
817       g_object_notify (G_OBJECT (font_button), "show-style");
818     }
819
820
821
822 /**
823  * gtk_font_button_get_show_size:
824  * @font_button: a #GtkFontButton
825  * 
826  * Returns whether the font size will be shown in the label.
827  * 
828  * Return value: whether the font size will be shown in the label.
829  *
830  * Since: 2.4
831  **/
832 gboolean 
833 gtk_font_button_get_show_size (GtkFontButton *font_button)
834 {
835   g_return_val_if_fail (GTK_IS_FONT_BUTTON (font_button), FALSE);
836
837   return font_button->priv->show_size;
838 }
839
840 /**
841  * gtk_font_button_set_show_size:
842  * @font_button: a #GtkFontButton
843  * @show_size: %TRUE if font size should be displayed in dialog.
844  *
845  * If @show_size is %TRUE, the font size will be displayed along with the name of the selected font.
846  *
847  * Since: 2.4
848  */
849 void
850 gtk_font_button_set_show_size (GtkFontButton *font_button,
851                                gboolean       show_size)
852 {
853   g_return_if_fail (GTK_IS_FONT_BUTTON (font_button));
854   
855   show_size = (show_size != FALSE);
856
857   if (font_button->priv->show_size != show_size) 
858     {
859       font_button->priv->show_size = show_size;
860
861       gtk_container_remove (GTK_CONTAINER (font_button), font_button->priv->inside);
862       font_button->priv->inside = gtk_font_button_create_inside (font_button);
863       gtk_container_add (GTK_CONTAINER (font_button), font_button->priv->inside);
864       
865       gtk_font_button_update_font_info (font_button);
866
867       g_object_notify (G_OBJECT (font_button), "show-size");
868     }
869
870
871
872 /**
873  * gtk_font_button_get_font_name:
874  * @font_button: a #GtkFontButton
875  *
876  * Retrieves the name of the currently selected font. This name includes
877  * style and size information as well. If you want to render something
878  * with the font, use this string with pango_font_description_from_string() .
879  * If you're interested in peeking certain values (family name,
880  * style, size, weight) just query these properties from the
881  * #PangoFontDescription object.
882  *
883  * Returns: an internal copy of the font name which must not be freed.
884  *
885  * Since: 2.4
886  */
887 const gchar *
888 gtk_font_button_get_font_name (GtkFontButton *font_button)
889 {
890   g_return_val_if_fail (GTK_IS_FONT_BUTTON (font_button), NULL);
891
892   return font_button->priv->fontname;
893 }
894
895 /**
896  * gtk_font_button_set_font_name:
897  * @font_button: a #GtkFontButton
898  * @fontname: Name of font to display in font chooser dialog
899  *
900  * Sets or updates the currently-displayed font in font picker dialog.
901  *
902  * Returns: %TRUE
903  *
904  * Since: 2.4
905  */
906 gboolean 
907 gtk_font_button_set_font_name (GtkFontButton *font_button,
908                                const gchar    *fontname)
909 {
910   PangoFontDescription *font_desc;
911
912   g_return_val_if_fail (GTK_IS_FONT_BUTTON (font_button), FALSE);
913   g_return_val_if_fail (fontname != NULL, FALSE);
914
915   font_desc = pango_font_description_from_string (fontname);
916   gtk_font_button_take_font_desc (font_button, font_desc);
917
918   return TRUE;
919 }
920
921 static void
922 gtk_font_button_clicked (GtkButton *button)
923 {
924   GtkFontChooser *font_dialog;
925   GtkFontButton  *font_button = GTK_FONT_BUTTON (button);
926   GtkFontButtonPrivate *priv = font_button->priv;
927   
928   if (!font_button->priv->font_dialog) 
929     {
930       GtkWidget *parent;
931       
932       parent = gtk_widget_get_toplevel (GTK_WIDGET (font_button));
933
934       priv->font_dialog = gtk_font_chooser_dialog_new (priv->title, NULL);
935       font_dialog = GTK_FONT_CHOOSER (font_button->priv->font_dialog);
936
937       gtk_font_chooser_set_show_preview_entry (font_dialog, priv->show_preview_entry);
938
939       if (priv->preview_text)
940         {
941           gtk_font_chooser_set_preview_text (font_dialog, priv->preview_text);
942           g_free (priv->preview_text);
943           priv->preview_text = NULL;
944         }
945
946       if (priv->font_filter)
947         {
948           gtk_font_chooser_set_filter_func (font_dialog,
949                                             priv->font_filter,
950                                             priv->font_filter_data,
951                                             priv->font_filter_data_destroy);
952           priv->font_filter = NULL;
953           priv->font_filter_data = NULL;
954           priv->font_filter_data_destroy = NULL;
955         }
956
957       if (gtk_widget_is_toplevel (parent) && GTK_IS_WINDOW (parent))
958         {
959           if (GTK_WINDOW (parent) != gtk_window_get_transient_for (GTK_WINDOW (font_dialog)))
960             gtk_window_set_transient_for (GTK_WINDOW (font_dialog), GTK_WINDOW (parent));
961
962           gtk_window_set_modal (GTK_WINDOW (font_dialog),
963                                 gtk_window_get_modal (GTK_WINDOW (parent)));
964         }
965
966       g_signal_connect (font_dialog, "notify",
967                         G_CALLBACK (gtk_font_button_font_chooser_notify), button);
968
969       g_signal_connect (font_dialog, "response",
970                         G_CALLBACK (response_cb), font_button);
971
972       g_signal_connect (font_dialog, "destroy",
973                         G_CALLBACK (dialog_destroy), font_button);
974     }
975   
976   if (!gtk_widget_get_visible (font_button->priv->font_dialog))
977     {
978       font_dialog = GTK_FONT_CHOOSER (font_button->priv->font_dialog);
979       gtk_font_chooser_set_font_desc (font_dialog, font_button->priv->font_desc);
980     } 
981
982   gtk_window_present (GTK_WINDOW (font_button->priv->font_dialog));
983 }
984
985
986 static void
987 response_cb (GtkDialog *dialog,
988              gint       response_id,
989              gpointer   data)
990 {
991   GtkFontButton *font_button = GTK_FONT_BUTTON (data);
992   GtkFontButtonPrivate *priv = font_button->priv;
993   GtkFontChooser *font_chooser;
994   GObject *object;
995
996   gtk_widget_hide (font_button->priv->font_dialog);
997
998   if (response_id != GTK_RESPONSE_OK)
999     return;
1000
1001   font_chooser = GTK_FONT_CHOOSER (priv->font_dialog);
1002   object = G_OBJECT (font_chooser);
1003
1004   g_object_freeze_notify (object);
1005
1006   if (priv->font_desc)
1007     pango_font_description_free (priv->font_desc);
1008   priv->font_desc = gtk_font_chooser_get_font_desc (font_chooser);
1009
1010   g_free (priv->fontname);
1011   priv->fontname = pango_font_description_to_string (priv->font_desc);
1012
1013   if (priv->font_family)
1014     g_object_unref (priv->font_family);
1015   priv->font_family = gtk_font_chooser_get_family (font_chooser);
1016   if (priv->font_family)
1017     g_object_ref (priv->font_family);
1018
1019   if (priv->font_face)
1020     g_object_unref (priv->font_face);
1021   priv->font_face = gtk_font_chooser_get_face (font_chooser);
1022   if (priv->font_face)
1023     g_object_ref (priv->font_face);
1024
1025   priv->font_size = gtk_font_chooser_get_size (font_chooser);
1026
1027   /* Set label font */
1028   gtk_font_button_update_font_info (font_button);
1029
1030   g_object_notify (G_OBJECT (font_button), "font");
1031   g_object_notify (G_OBJECT (font_button), "font-desc");
1032   g_object_notify (G_OBJECT (font_button), "font-name");
1033
1034   g_object_thaw_notify (object);
1035
1036   /* Emit font_set signal */
1037   g_signal_emit (font_button, font_button_signals[FONT_SET], 0);
1038 }
1039
1040 static void
1041 dialog_destroy (GtkWidget *widget,
1042                 gpointer   data)
1043 {
1044   GtkFontButton *font_button = GTK_FONT_BUTTON (data);
1045     
1046   /* Dialog will get destroyed so reference is not valid now */
1047   font_button->priv->font_dialog = NULL;
1048
1049
1050 static GtkWidget *
1051 gtk_font_button_create_inside (GtkFontButton *font_button)
1052 {
1053   GtkWidget *widget;
1054   
1055   gtk_widget_push_composite_child ();
1056
1057   widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
1058
1059   font_button->priv->font_label = gtk_label_new (_("Font"));
1060   
1061   gtk_label_set_justify (GTK_LABEL (font_button->priv->font_label), GTK_JUSTIFY_LEFT);
1062   gtk_box_pack_start (GTK_BOX (widget), font_button->priv->font_label, TRUE, TRUE, 5);
1063
1064   if (font_button->priv->show_size) 
1065     {
1066       gtk_box_pack_start (GTK_BOX (widget), gtk_separator_new (GTK_ORIENTATION_VERTICAL), FALSE, FALSE, 0);
1067       font_button->priv->size_label = gtk_label_new ("14");
1068       gtk_box_pack_start (GTK_BOX (widget), font_button->priv->size_label, FALSE, FALSE, 5);
1069     }
1070
1071   gtk_widget_show_all (widget);
1072
1073   gtk_widget_pop_composite_child ();
1074
1075   return widget;
1076
1077
1078 static void
1079 gtk_font_button_label_use_font (GtkFontButton *font_button)
1080 {
1081   PangoFontDescription *desc;
1082
1083   if (!font_button->priv->use_font)
1084     return;
1085
1086   desc = pango_font_description_copy (font_button->priv->font_desc);
1087
1088   if (!font_button->priv->use_size)
1089     pango_font_description_unset_fields (desc, PANGO_FONT_MASK_SIZE);
1090
1091   gtk_widget_modify_font (font_button->priv->font_label, desc);
1092
1093   pango_font_description_free (desc);
1094 }
1095
1096 static gboolean
1097 font_description_style_equal (const PangoFontDescription *a,
1098                               const PangoFontDescription *b)
1099 {
1100   return (pango_font_description_get_weight (a) == pango_font_description_get_weight (b) &&
1101           pango_font_description_get_style (a) == pango_font_description_get_style (b) &&
1102           pango_font_description_get_stretch (a) == pango_font_description_get_stretch (b) &&
1103           pango_font_description_get_variant (a) == pango_font_description_get_variant (b));
1104 }
1105
1106 static void
1107 gtk_font_button_update_font_info (GtkFontButton *font_button)
1108 {
1109   const PangoFontDescription *desc;
1110   const gchar *family;
1111   gchar *style;
1112   gchar *family_style;
1113
1114   desc = font_button->priv->font_desc;
1115   g_assert (desc != NULL);
1116
1117   family = pango_font_description_get_family (desc);
1118   
1119 #if 0
1120   /* This gives the wrong names, e.g. Italic when the font chooser
1121    * dialog displayed Oblique.
1122    */
1123   pango_font_description_unset_fields (desc, PANGO_FONT_MASK_FAMILY | PANGO_FONT_MASK_SIZE);
1124   style = pango_font_description_to_string (desc);
1125   gtk_label_set_text (GTK_LABEL (font_button->priv->style_label), style);      
1126 #endif
1127
1128   style = NULL;
1129   if (font_button->priv->show_style && family) 
1130     {
1131       PangoFontFamily **families;
1132       PangoFontFace **faces;
1133       gint n_families, n_faces, i;
1134
1135       n_families = 0;
1136       families = NULL;
1137       pango_context_list_families (gtk_widget_get_pango_context (GTK_WIDGET (font_button)),
1138                                    &families, &n_families);
1139       n_faces = 0;
1140       faces = NULL;
1141       for (i = 0; i < n_families; i++) 
1142         {
1143           const gchar *name = pango_font_family_get_name (families[i]);
1144           
1145           if (!g_ascii_strcasecmp (name, family)) 
1146             {
1147               pango_font_family_list_faces (families[i], &faces, &n_faces);
1148               break;
1149             }
1150         }
1151       g_free (families);
1152       
1153       for (i = 0; i < n_faces; i++) 
1154         {
1155           PangoFontDescription *tmp_desc = pango_font_face_describe (faces[i]);
1156           
1157           if (font_description_style_equal (tmp_desc, desc)) 
1158             {
1159               style = g_strdup (pango_font_face_get_face_name (faces[i]));
1160               pango_font_description_free (tmp_desc);
1161               break;
1162             }
1163           else
1164             pango_font_description_free (tmp_desc);
1165         }
1166       g_free (faces);
1167     }
1168
1169   if (style == NULL || !g_ascii_strcasecmp (style, "Regular"))
1170     family_style = g_strdup (family);
1171   else
1172     family_style = g_strdup_printf ("%s %s", family, style);
1173   
1174   gtk_label_set_text (GTK_LABEL (font_button->priv->font_label), family_style);
1175   
1176   g_free (style);
1177   g_free (family_style);
1178
1179   if (font_button->priv->show_size) 
1180     {
1181       gchar *size = g_strdup_printf ("%g",
1182                                      pango_font_description_get_size (desc) / (double)PANGO_SCALE);
1183       
1184       gtk_label_set_text (GTK_LABEL (font_button->priv->size_label), size);
1185       
1186       g_free (size);
1187     }
1188
1189   gtk_font_button_label_use_font (font_button);
1190