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