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