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