]> Pileus Git - ~andy/gtk/blob - gtk/gtkfontsel.c
394ff4559fc10df1bdafd2445ccd9f24387186bd
[~andy/gtk] / gtk / gtkfontsel.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * Massively updated for Pango by Owen Taylor, May 2000
5  * GtkFontSelection widget for Gtk+, by Damon Chaplin, May 1998.
6  * Based on the GnomeFontSelector widget, by Elliot Lee, but major changes.
7  * The GnomeFontSelector was derived from app/text_tool.c in the GIMP.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the
21  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22  * Boston, MA 02111-1307, USA.
23  */
24
25 /*
26  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
27  * file for a list of people on the GTK+ Team.  See the ChangeLog
28  * files for a list of changes.  These files are distributed with
29  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
30  */
31
32 #include "config.h"
33 #include <stdlib.h>
34 #include <glib/gprintf.h>
35 #include <string.h>
36
37 #include <atk/atk.h>
38
39 #include "gdk/gdk.h"
40 #include "gdk/gdkkeysyms.h"
41
42 #include "gtkfontsel.h"
43
44 #include "gtkbutton.h"
45 #include "gtkcellrenderertext.h"
46 #include "gtkentry.h"
47 #include "gtkframe.h"
48 #include "gtkhbbox.h"
49 #include "gtkhbox.h"
50 #include "gtklabel.h"
51 #include "gtkliststore.h"
52 #include "gtkrc.h"
53 #include "gtkstock.h"
54 #include "gtktable.h"
55 #include "gtktreeselection.h"
56 #include "gtktreeview.h"
57 #include "gtkvbox.h"
58 #include "gtkscrolledwindow.h"
59 #include "gtkintl.h"
60 #include "gtkaccessible.h"
61 #include "gtkbuildable.h"
62 #include "gtkprivate.h"
63
64 struct _GtkFontSelectionPrivate
65 {
66   GtkWidget *font_entry;        /* Used _get_family_entry() for consistency, -mr */
67   GtkWidget *font_style_entry;  /* Used _get_face_entry() for consistency, -mr */
68
69   GtkWidget *size_entry;
70   GtkWidget *preview_entry;
71
72   GtkWidget *family_list;
73   GtkWidget *face_list;
74   GtkWidget *size_list;
75
76   PangoFontFamily *family;      /* Current family */
77   PangoFontFace *face;          /* Current face */
78
79   gint size;
80 };
81
82
83 struct _GtkFontSelectionDialogPrivate
84 {
85   GtkWidget *fontsel;
86
87   GtkWidget *ok_button;
88   GtkWidget *apply_button;
89   GtkWidget *cancel_button;
90 };
91
92
93 /* We don't enable the font and style entries because they don't add
94  * much in terms of visible effect and have a weird effect on keynav.
95  * the Windows font selector has entries similarly positioned but they
96  * act in conjunction with the associated lists to form a single focus
97  * location.
98  */
99 #undef INCLUDE_FONT_ENTRIES
100
101 /* This is the default text shown in the preview entry, though the user
102    can set it. Remember that some fonts only have capital letters. */
103 #define PREVIEW_TEXT N_("abcdefghijk ABCDEFGHIJK")
104
105 #define DEFAULT_FONT_NAME "Sans 10"
106
107 /* This is the initial and maximum height of the preview entry (it expands
108    when large font sizes are selected). Initial height is also the minimum. */
109 #define INITIAL_PREVIEW_HEIGHT 44
110 #define MAX_PREVIEW_HEIGHT 300
111
112 /* These are the sizes of the font, style & size lists. */
113 #define FONT_LIST_HEIGHT        136
114 #define FONT_LIST_WIDTH         190
115 #define FONT_STYLE_LIST_WIDTH   170
116 #define FONT_SIZE_LIST_WIDTH    60
117
118 /* These are what we use as the standard font sizes, for the size list.
119  */
120 static const guint16 font_sizes[] = {
121   6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 22, 24, 26, 28,
122   32, 36, 40, 48, 56, 64, 72
123 };
124
125 enum {
126    PROP_0,
127    PROP_FONT_NAME,
128    PROP_PREVIEW_TEXT
129 };
130
131
132 enum {
133   FAMILY_COLUMN,
134   FAMILY_NAME_COLUMN
135 };
136
137 enum {
138   FACE_COLUMN,
139   FACE_NAME_COLUMN
140 };
141
142 enum {
143   SIZE_COLUMN
144 };
145
146 static void    gtk_font_selection_set_property       (GObject         *object,
147                                                       guint            prop_id,
148                                                       const GValue    *value,
149                                                       GParamSpec      *pspec);
150 static void    gtk_font_selection_get_property       (GObject         *object,
151                                                       guint            prop_id,
152                                                       GValue          *value,
153                                                       GParamSpec      *pspec);
154 static void    gtk_font_selection_finalize           (GObject         *object);
155 static void    gtk_font_selection_screen_changed     (GtkWidget       *widget,
156                                                       GdkScreen       *previous_screen);
157 static void    gtk_font_selection_style_set          (GtkWidget      *widget,
158                                                       GtkStyle       *prev_style);
159
160 /* These are the callbacks & related functions. */
161 static void     gtk_font_selection_select_font           (GtkTreeSelection *selection,
162                                                           gpointer          data);
163 static void     gtk_font_selection_show_available_fonts  (GtkFontSelection *fs);
164
165 static void     gtk_font_selection_show_available_styles (GtkFontSelection *fs);
166 static void     gtk_font_selection_select_best_style     (GtkFontSelection *fs,
167                                                           gboolean          use_first);
168 static void     gtk_font_selection_select_style          (GtkTreeSelection *selection,
169                                                           gpointer          data);
170
171 static void     gtk_font_selection_select_best_size      (GtkFontSelection *fs);
172 static void     gtk_font_selection_show_available_sizes  (GtkFontSelection *fs,
173                                                           gboolean          first_time);
174 static void     gtk_font_selection_size_activate         (GtkWidget        *w,
175                                                           gpointer          data);
176 static gboolean gtk_font_selection_size_focus_out        (GtkWidget        *w,
177                                                           GdkEventFocus    *event,
178                                                           gpointer          data);
179 static void     gtk_font_selection_select_size           (GtkTreeSelection *selection,
180                                                           gpointer          data);
181
182 static void     gtk_font_selection_scroll_on_map         (GtkWidget        *w,
183                                                           gpointer          data);
184
185 static void     gtk_font_selection_preview_changed       (GtkWidget        *entry,
186                                                           GtkFontSelection *fontsel);
187 static void     gtk_font_selection_scroll_to_selection   (GtkFontSelection *fontsel);
188
189
190 /* Misc. utility functions. */
191 static void    gtk_font_selection_load_font          (GtkFontSelection *fs);
192 static void    gtk_font_selection_update_preview     (GtkFontSelection *fs);
193
194 static PangoFontDescription *gtk_font_selection_get_font_description (GtkFontSelection *fontsel);
195 static gboolean gtk_font_selection_select_font_desc  (GtkFontSelection      *fontsel,
196                                                       PangoFontDescription  *new_desc,
197                                                       PangoFontFamily      **pfamily,
198                                                       PangoFontFace        **pface);
199 static void     gtk_font_selection_reload_fonts          (GtkFontSelection *fontsel);
200 static void     gtk_font_selection_ref_family            (GtkFontSelection *fontsel,
201                                                           PangoFontFamily  *family);
202 static void     gtk_font_selection_ref_face              (GtkFontSelection *fontsel,
203                                                           PangoFontFace    *face);
204
205 G_DEFINE_TYPE (GtkFontSelection, gtk_font_selection, GTK_TYPE_VBOX)
206
207 static void
208 gtk_font_selection_class_init (GtkFontSelectionClass *klass)
209 {
210   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
211   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
212
213   gobject_class->finalize = gtk_font_selection_finalize;
214   gobject_class->set_property = gtk_font_selection_set_property;
215   gobject_class->get_property = gtk_font_selection_get_property;
216
217   widget_class->screen_changed = gtk_font_selection_screen_changed;
218   widget_class->style_set = gtk_font_selection_style_set;
219    
220   g_object_class_install_property (gobject_class,
221                                    PROP_FONT_NAME,
222                                    g_param_spec_string ("font-name",
223                                                         P_("Font name"),
224                                                         P_("The string that represents this font"),
225                                                         DEFAULT_FONT_NAME,
226                                                         GTK_PARAM_READWRITE));
227   g_object_class_install_property (gobject_class,
228                                    PROP_PREVIEW_TEXT,
229                                    g_param_spec_string ("preview-text",
230                                                         P_("Preview text"),
231                                                         P_("The text to display in order to demonstrate the selected font"),
232                                                         _(PREVIEW_TEXT),
233                                                         GTK_PARAM_READWRITE));
234
235   g_type_class_add_private (klass, sizeof (GtkFontSelectionPrivate));
236 }
237
238 static void 
239 gtk_font_selection_set_property (GObject         *object,
240                                  guint            prop_id,
241                                  const GValue    *value,
242                                  GParamSpec      *pspec)
243 {
244   GtkFontSelection *fontsel;
245
246   fontsel = GTK_FONT_SELECTION (object);
247
248   switch (prop_id)
249     {
250     case PROP_FONT_NAME:
251       gtk_font_selection_set_font_name (fontsel, g_value_get_string (value));
252       break;
253     case PROP_PREVIEW_TEXT:
254       gtk_font_selection_set_preview_text (fontsel, g_value_get_string (value));
255       break;
256     default:
257       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
258       break;
259     }
260 }
261
262 static void gtk_font_selection_get_property (GObject         *object,
263                                              guint            prop_id,
264                                              GValue          *value,
265                                              GParamSpec      *pspec)
266 {
267   GtkFontSelection *fontsel;
268
269   fontsel = GTK_FONT_SELECTION (object);
270
271   switch (prop_id)
272     {
273     case PROP_FONT_NAME:
274       g_value_take_string (value, gtk_font_selection_get_font_name (fontsel));
275       break;
276     case PROP_PREVIEW_TEXT:
277       g_value_set_string (value, gtk_font_selection_get_preview_text (fontsel));
278       break;
279     default:
280       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
281       break;
282     }
283 }
284
285 /* Handles key press events on the lists, so that we can trap Enter to
286  * activate the default button on our own.
287  */
288 static gboolean
289 list_row_activated (GtkWidget *widget)
290 {
291   GtkWidget *default_widget, *focus_widget;
292   GtkWindow *window;
293   
294   window = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (widget)));
295   if (!gtk_widget_is_toplevel (GTK_WIDGET (window)))
296     window = NULL;
297
298   if (window)
299     {
300       default_widget = gtk_window_get_default_widget (window);
301       focus_widget = gtk_window_get_focus (window);
302
303       if (widget != default_widget &&
304           !(widget == focus_widget && (!default_widget || !gtk_widget_get_sensitive (default_widget))))
305         gtk_window_activate_default (window);
306     }
307
308   return TRUE;
309 }
310
311 static void
312 gtk_font_selection_init (GtkFontSelection *fontsel)
313 {
314   GtkFontSelectionPrivate *priv;
315   GtkWidget *scrolled_win;
316   GtkWidget *text_box;
317   GtkWidget *table, *label;
318   GtkWidget *font_label, *style_label;
319   GtkWidget *vbox;
320   GtkListStore *model;
321   GtkTreeViewColumn *column;
322   GList *focus_chain = NULL;
323   AtkObject *atk_obj;
324
325   fontsel->priv = G_TYPE_INSTANCE_GET_PRIVATE (fontsel,
326                                                GTK_TYPE_FONT_SELECTION,
327                                                GtkFontSelectionPrivate);
328   priv = fontsel->priv;
329
330   gtk_widget_push_composite_child ();
331
332   gtk_box_set_spacing (GTK_BOX (fontsel), 12);
333   priv->size = 12 * PANGO_SCALE;
334   
335   /* Create the table of font, style & size. */
336   table = gtk_table_new (3, 3, FALSE);
337   gtk_widget_show (table);
338   gtk_table_set_row_spacings (GTK_TABLE (table), 6);
339   gtk_table_set_col_spacings (GTK_TABLE (table), 12);
340   gtk_box_pack_start (GTK_BOX (fontsel), table, TRUE, TRUE, 0);
341
342 #ifdef INCLUDE_FONT_ENTRIES
343   priv->font_entry = gtk_entry_new ();
344   gtk_editable_set_editable (GTK_EDITABLE (priv->font_entry), FALSE);
345   gtk_widget_set_size_request (priv->font_entry, 20, -1);
346   gtk_widget_show (priv->font_entry);
347   gtk_table_attach (GTK_TABLE (table), priv->font_entry, 0, 1, 1, 2,
348                     GTK_FILL, 0, 0, 0);
349   
350   priv->font_style_entry = gtk_entry_new ();
351   gtk_editable_set_editable (GTK_EDITABLE (priv->font_style_entry), FALSE);
352   gtk_widget_set_size_request (priv->font_style_entry, 20, -1);
353   gtk_widget_show (priv->font_style_entry);
354   gtk_table_attach (GTK_TABLE (table), priv->font_style_entry, 1, 2, 1, 2,
355                     GTK_FILL, 0, 0, 0);
356 #endif /* INCLUDE_FONT_ENTRIES */
357   
358   priv->size_entry = gtk_entry_new ();
359   gtk_widget_set_size_request (priv->size_entry, 20, -1);
360   gtk_widget_show (priv->size_entry);
361   gtk_table_attach (GTK_TABLE (table), priv->size_entry, 2, 3, 1, 2,
362                     GTK_FILL, 0, 0, 0);
363   g_signal_connect (priv->size_entry, "activate",
364                     G_CALLBACK (gtk_font_selection_size_activate),
365                     fontsel);
366   g_signal_connect_after (priv->size_entry, "focus-out-event",
367                           G_CALLBACK (gtk_font_selection_size_focus_out),
368                           fontsel);
369   
370   font_label = gtk_label_new_with_mnemonic (_("_Family:"));
371   gtk_misc_set_alignment (GTK_MISC (font_label), 0.0, 0.5);
372   gtk_widget_show (font_label);
373   gtk_table_attach (GTK_TABLE (table), font_label, 0, 1, 0, 1,
374                     GTK_FILL, 0, 0, 0);  
375
376   style_label = gtk_label_new_with_mnemonic (_("_Style:"));
377   gtk_misc_set_alignment (GTK_MISC (style_label), 0.0, 0.5);
378   gtk_widget_show (style_label);
379   gtk_table_attach (GTK_TABLE (table), style_label, 1, 2, 0, 1,
380                     GTK_FILL, 0, 0, 0);
381   
382   label = gtk_label_new_with_mnemonic (_("Si_ze:"));
383   gtk_label_set_mnemonic_widget (GTK_LABEL (label),
384                                  priv->size_entry);
385   gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
386   gtk_widget_show (label);
387   gtk_table_attach (GTK_TABLE (table), label, 2, 3, 0, 1,
388                     GTK_FILL, 0, 0, 0);
389   
390   
391   /* Create the lists  */
392
393   model = gtk_list_store_new (2,
394                               G_TYPE_OBJECT,  /* FAMILY_COLUMN */
395                               G_TYPE_STRING); /* FAMILY_NAME_COLUMN */
396   priv->family_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
397   g_object_unref (model);
398
399   g_signal_connect (priv->family_list, "row-activated",
400                     G_CALLBACK (list_row_activated), fontsel);
401
402   column = gtk_tree_view_column_new_with_attributes ("Family",
403                                                      gtk_cell_renderer_text_new (),
404                                                      "text", FAMILY_NAME_COLUMN,
405                                                      NULL);
406   gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
407   gtk_tree_view_append_column (GTK_TREE_VIEW (priv->family_list), column);
408
409   gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->family_list), FALSE);
410   gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->family_list)),
411                                GTK_SELECTION_BROWSE);
412   
413   gtk_label_set_mnemonic_widget (GTK_LABEL (font_label), priv->family_list);
414
415   scrolled_win = gtk_scrolled_window_new (NULL, NULL);
416   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), GTK_SHADOW_IN);
417   gtk_widget_set_size_request (scrolled_win,
418                                FONT_LIST_WIDTH, FONT_LIST_HEIGHT);
419   gtk_container_add (GTK_CONTAINER (scrolled_win), priv->family_list);
420   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
421                                   GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
422   gtk_widget_show (priv->family_list);
423   gtk_widget_show (scrolled_win);
424
425   gtk_table_attach (GTK_TABLE (table), scrolled_win, 0, 1, 1, 3,
426                     GTK_EXPAND | GTK_FILL,
427                     GTK_EXPAND | GTK_FILL, 0, 0);
428   focus_chain = g_list_append (focus_chain, scrolled_win);
429   
430   model = gtk_list_store_new (2,
431                               G_TYPE_OBJECT,  /* FACE_COLUMN */
432                               G_TYPE_STRING); /* FACE_NAME_COLUMN */
433   priv->face_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
434   g_object_unref (model);
435   g_signal_connect (priv->face_list, "row-activated",
436                     G_CALLBACK (list_row_activated), fontsel);
437
438   gtk_label_set_mnemonic_widget (GTK_LABEL (style_label), priv->face_list);
439
440   column = gtk_tree_view_column_new_with_attributes ("Face",
441                                                      gtk_cell_renderer_text_new (),
442                                                      "text", FACE_NAME_COLUMN,
443                                                      NULL);
444   gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
445   gtk_tree_view_append_column (GTK_TREE_VIEW (priv->face_list), column);
446
447   gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->face_list), FALSE);
448   gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->face_list)),
449                                GTK_SELECTION_BROWSE);
450   
451   scrolled_win = gtk_scrolled_window_new (NULL, NULL);
452   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), GTK_SHADOW_IN);
453   gtk_widget_set_size_request (scrolled_win,
454                                FONT_STYLE_LIST_WIDTH, FONT_LIST_HEIGHT);
455   gtk_container_add (GTK_CONTAINER (scrolled_win), priv->face_list);
456   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
457                                   GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
458   gtk_widget_show (priv->face_list);
459   gtk_widget_show (scrolled_win);
460   gtk_table_attach (GTK_TABLE (table), scrolled_win, 1, 2, 1, 3,
461                     GTK_EXPAND | GTK_FILL,
462                     GTK_EXPAND | GTK_FILL, 0, 0);
463   focus_chain = g_list_append (focus_chain, scrolled_win);
464   
465   focus_chain = g_list_append (focus_chain, priv->size_entry);
466
467   model = gtk_list_store_new (1, G_TYPE_INT);
468   priv->size_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
469   g_object_unref (model);
470   g_signal_connect (priv->size_list, "row-activated",
471                     G_CALLBACK (list_row_activated), fontsel);
472
473   column = gtk_tree_view_column_new_with_attributes ("Size",
474                                                      gtk_cell_renderer_text_new (),
475                                                      "text", SIZE_COLUMN,
476                                                      NULL);
477   gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
478   gtk_tree_view_append_column (GTK_TREE_VIEW (priv->size_list), column);
479
480   gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->size_list), FALSE);
481   gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->size_list)),
482                                GTK_SELECTION_BROWSE);
483   
484   scrolled_win = gtk_scrolled_window_new (NULL, NULL);
485   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), GTK_SHADOW_IN);
486   gtk_container_add (GTK_CONTAINER (scrolled_win), priv->size_list);
487   gtk_widget_set_size_request (scrolled_win, -1, FONT_LIST_HEIGHT);
488   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
489                                   GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
490   gtk_widget_show (priv->size_list);
491   gtk_widget_show (scrolled_win);
492   gtk_table_attach (GTK_TABLE (table), scrolled_win, 2, 3, 2, 3,
493                     GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
494   focus_chain = g_list_append (focus_chain, scrolled_win);
495
496   gtk_container_set_focus_chain (GTK_CONTAINER (table), focus_chain);
497   g_list_free (focus_chain);
498   
499   /* Insert the fonts. */
500   g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->family_list)), "changed",
501                     G_CALLBACK (gtk_font_selection_select_font), fontsel);
502
503   g_signal_connect_after (priv->family_list, "map",
504                           G_CALLBACK (gtk_font_selection_scroll_on_map),
505                           fontsel);
506   
507   g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->face_list)), "changed",
508                     G_CALLBACK (gtk_font_selection_select_style), fontsel);
509
510   g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->size_list)), "changed",
511                     G_CALLBACK (gtk_font_selection_select_size), fontsel);
512   atk_obj = gtk_widget_get_accessible (priv->size_list);
513   if (GTK_IS_ACCESSIBLE (atk_obj))
514     {
515       /* Accessibility support is enabled.
516        * Make the label ATK_RELATON_LABEL_FOR for the size list as well.
517        */
518       AtkObject *atk_label;
519       AtkRelationSet *relation_set;
520       AtkRelation *relation;
521       AtkObject *obj_array[1];
522
523       atk_label = gtk_widget_get_accessible (label);
524       relation_set = atk_object_ref_relation_set (atk_obj);
525       relation = atk_relation_set_get_relation_by_type (relation_set, ATK_RELATION_LABELLED_BY);
526       if (relation)
527         {
528           atk_relation_add_target (relation, atk_label);
529         }
530       else 
531         {
532           obj_array[0] = atk_label;
533           relation = atk_relation_new (obj_array, 1, ATK_RELATION_LABELLED_BY);
534           atk_relation_set_add (relation_set, relation);
535         }
536       g_object_unref (relation_set);
537
538       relation_set = atk_object_ref_relation_set (atk_label);
539       relation = atk_relation_set_get_relation_by_type (relation_set, ATK_RELATION_LABEL_FOR);
540       if (relation)
541         {
542           atk_relation_add_target (relation, atk_obj);
543         }
544       else 
545         {
546           obj_array[0] = atk_obj;
547           relation = atk_relation_new (obj_array, 1, ATK_RELATION_LABEL_FOR);
548           atk_relation_set_add (relation_set, relation);
549         }
550       g_object_unref (relation_set);
551     }    
552       
553
554   vbox = gtk_vbox_new (FALSE, 6);
555   gtk_widget_show (vbox);
556   gtk_box_pack_start (GTK_BOX (fontsel), vbox, FALSE, TRUE, 0);
557   
558   /* create the text entry widget */
559   label = gtk_label_new_with_mnemonic (_("_Preview:"));
560   gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
561   gtk_widget_show (label);
562   gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 0);
563   
564   text_box = gtk_hbox_new (FALSE, 0);
565   gtk_widget_show (text_box);
566   gtk_box_pack_start (GTK_BOX (vbox), text_box, FALSE, TRUE, 0);
567   
568   priv->preview_entry = gtk_entry_new ();
569   gtk_label_set_mnemonic_widget (GTK_LABEL (label), priv->preview_entry);
570   gtk_entry_set_text (GTK_ENTRY (priv->preview_entry), _(PREVIEW_TEXT));
571   
572   gtk_widget_show (priv->preview_entry);
573   g_signal_connect (priv->preview_entry, "changed",
574                     G_CALLBACK (gtk_font_selection_preview_changed), fontsel);
575   gtk_widget_set_size_request (priv->preview_entry,
576                                -1, INITIAL_PREVIEW_HEIGHT);
577   gtk_box_pack_start (GTK_BOX (text_box), priv->preview_entry,
578                       TRUE, TRUE, 0);
579   gtk_widget_pop_composite_child();
580 }
581
582 /**
583  * gtk_font_selection_new:
584  *
585  * Creates a new #GtkFontSelection.
586  *
587  * Return value: a n ew #GtkFontSelection
588  */
589 GtkWidget *
590 gtk_font_selection_new (void)
591 {
592   GtkFontSelection *fontsel;
593   
594   fontsel = g_object_new (GTK_TYPE_FONT_SELECTION, NULL);
595   
596   return GTK_WIDGET (fontsel);
597 }
598
599 static void
600 gtk_font_selection_finalize (GObject *object)
601 {
602   GtkFontSelection *fontsel = GTK_FONT_SELECTION (object);
603
604   gtk_font_selection_ref_family (fontsel, NULL);
605   gtk_font_selection_ref_face (fontsel, NULL);
606
607   G_OBJECT_CLASS (gtk_font_selection_parent_class)->finalize (object);
608 }
609
610 static void
611 gtk_font_selection_ref_family (GtkFontSelection *fontsel,
612                                PangoFontFamily  *family)
613 {
614   GtkFontSelectionPrivate *priv = fontsel->priv;
615
616   if (family)
617     family = g_object_ref (family);
618   if (priv->family)
619     g_object_unref (priv->family);
620   priv->family = family;
621 }
622
623 static void gtk_font_selection_ref_face (GtkFontSelection *fontsel,
624                                          PangoFontFace    *face)
625 {
626   GtkFontSelectionPrivate *priv = fontsel->priv;
627
628   if (face)
629     face = g_object_ref (face);
630   if (priv->face)
631     g_object_unref (priv->face);
632   priv->face = face;
633 }
634
635 static void
636 gtk_font_selection_reload_fonts (GtkFontSelection *fontsel)
637 {
638   if (gtk_widget_has_screen (GTK_WIDGET (fontsel)))
639     {
640       PangoFontDescription *desc;
641       desc = gtk_font_selection_get_font_description (fontsel);
642
643       gtk_font_selection_show_available_fonts (fontsel);
644       gtk_font_selection_show_available_sizes (fontsel, TRUE);
645       gtk_font_selection_show_available_styles (fontsel);
646
647       gtk_font_selection_select_font_desc (fontsel, desc, NULL, NULL);
648       gtk_font_selection_scroll_to_selection (fontsel);
649
650       pango_font_description_free (desc);
651     }
652 }
653
654 static void
655 gtk_font_selection_screen_changed (GtkWidget *widget,
656                                    GdkScreen *previous_screen)
657 {
658   gtk_font_selection_reload_fonts (GTK_FONT_SELECTION (widget));
659 }
660
661 static void
662 gtk_font_selection_style_set (GtkWidget *widget,
663                               GtkStyle  *prev_style)
664 {
665   /* Maybe fonts where installed or removed... */
666   gtk_font_selection_reload_fonts (GTK_FONT_SELECTION (widget));
667 }
668
669 static void
670 gtk_font_selection_preview_changed (GtkWidget        *entry,
671                                     GtkFontSelection *fontsel)
672 {
673   g_object_notify (G_OBJECT (fontsel), "preview-text");
674 }
675
676 static void
677 scroll_to_selection (GtkTreeView *tree_view)
678 {
679   GtkTreeSelection *selection = gtk_tree_view_get_selection (tree_view);
680   GtkTreeModel *model;
681   GtkTreeIter iter;
682
683   if (gtk_tree_selection_get_selected (selection, &model, &iter))
684     {
685       GtkTreePath *path = gtk_tree_model_get_path (model, &iter);
686       gtk_tree_view_scroll_to_cell (tree_view, path, NULL, TRUE, 0.5, 0.5);
687       gtk_tree_path_free (path);
688     }
689 }
690
691 static void
692 set_cursor_to_iter (GtkTreeView *view,
693                     GtkTreeIter *iter)
694 {
695   GtkTreeModel *model = gtk_tree_view_get_model (view);
696   GtkTreePath *path = gtk_tree_model_get_path (model, iter);
697   
698   gtk_tree_view_set_cursor (view, path, NULL, FALSE);
699
700   gtk_tree_path_free (path);
701 }
702
703 static void
704 gtk_font_selection_scroll_to_selection (GtkFontSelection *fontsel)
705 {
706   GtkFontSelectionPrivate *priv = fontsel->priv;
707
708   /* Try to scroll the font family list to the selected item */
709   scroll_to_selection (GTK_TREE_VIEW (priv->family_list));
710
711   /* Try to scroll the font family list to the selected item */
712   scroll_to_selection (GTK_TREE_VIEW (priv->face_list));
713
714   /* Try to scroll the font family list to the selected item */
715   scroll_to_selection (GTK_TREE_VIEW (priv->size_list));
716 /* This is called when the list is mapped. Here we scroll to the current
717    font if necessary. */
718 }
719
720 static void
721 gtk_font_selection_scroll_on_map (GtkWidget             *widget,
722                                   gpointer               data)
723 {
724   gtk_font_selection_scroll_to_selection (GTK_FONT_SELECTION (data));
725 }
726
727 /* This is called when a family is selected in the list. */
728 static void
729 gtk_font_selection_select_font (GtkTreeSelection *selection,
730                                 gpointer          data)
731 {
732   GtkFontSelection *fontsel;
733   GtkFontSelectionPrivate *priv;
734   GtkTreeModel *model;
735   GtkTreeIter iter;
736 #ifdef INCLUDE_FONT_ENTRIES
737   const gchar *family_name;
738 #endif
739
740   fontsel = GTK_FONT_SELECTION (data);
741   priv = fontsel->priv;
742
743   if (gtk_tree_selection_get_selected (selection, &model, &iter))
744     {
745       PangoFontFamily *family;
746
747       gtk_tree_model_get (model, &iter, FAMILY_COLUMN, &family, -1);
748       if (priv->family != family)
749         {
750           gtk_font_selection_ref_family (fontsel, family);
751
752 #ifdef INCLUDE_FONT_ENTRIES
753           family_name = pango_font_family_get_name (priv->family);
754           gtk_entry_set_text (GTK_ENTRY (priv->font_entry), family_name);
755 #endif
756
757           gtk_font_selection_show_available_styles (fontsel);
758           gtk_font_selection_select_best_style (fontsel, TRUE);
759         }
760
761       g_object_unref (family);
762     }
763 }
764
765 static int
766 cmp_families (const void *a, const void *b)
767 {
768   const char *a_name = pango_font_family_get_name (*(PangoFontFamily **)a);
769   const char *b_name = pango_font_family_get_name (*(PangoFontFamily **)b);
770   
771   return g_utf8_collate (a_name, b_name);
772 }
773
774 static void
775 gtk_font_selection_show_available_fonts (GtkFontSelection *fontsel)
776 {
777   GtkFontSelectionPrivate *priv = fontsel->priv;
778   GtkListStore *model;
779   PangoFontFamily **families;
780   PangoFontFamily *match_family = NULL;
781   gint n_families, i;
782   GtkTreeIter match_row;
783
784   model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (priv->family_list)));
785
786   pango_context_list_families (gtk_widget_get_pango_context (GTK_WIDGET (fontsel)),
787                                &families, &n_families);
788   qsort (families, n_families, sizeof (PangoFontFamily *), cmp_families);
789
790   gtk_list_store_clear (model);
791
792   for (i=0; i<n_families; i++)
793     {
794       const gchar *name = pango_font_family_get_name (families[i]);
795       GtkTreeIter iter;
796
797       gtk_list_store_append (model, &iter);
798       gtk_list_store_set (model, &iter,
799                           FAMILY_COLUMN, families[i],
800                           FAMILY_NAME_COLUMN, name,
801                           -1);
802       
803       if (i == 0 || !g_ascii_strcasecmp (name, "sans"))
804         {
805           match_family = families[i];
806           match_row = iter;
807         }
808     }
809
810   gtk_font_selection_ref_family (fontsel, match_family);
811   if (match_family)
812     {
813       set_cursor_to_iter (GTK_TREE_VIEW (priv->family_list), &match_row);
814 #ifdef INCLUDE_FONT_ENTRIES
815       gtk_entry_set_text (GTK_ENTRY (priv->font_entry), 
816                           pango_font_family_get_name (match_family));
817 #endif /* INCLUDE_FONT_ENTRIES */
818     }
819
820   g_free (families);
821 }
822
823 static int
824 compare_font_descriptions (const PangoFontDescription *a, const PangoFontDescription *b)
825 {
826   int val = strcmp (pango_font_description_get_family (a), pango_font_description_get_family (b));
827   if (val != 0)
828     return val;
829
830   if (pango_font_description_get_weight (a) != pango_font_description_get_weight (b))
831     return pango_font_description_get_weight (a) - pango_font_description_get_weight (b);
832
833   if (pango_font_description_get_style (a) != pango_font_description_get_style (b))
834     return pango_font_description_get_style (a) - pango_font_description_get_style (b);
835   
836   if (pango_font_description_get_stretch (a) != pango_font_description_get_stretch (b))
837     return pango_font_description_get_stretch (a) - pango_font_description_get_stretch (b);
838
839   if (pango_font_description_get_variant (a) != pango_font_description_get_variant (b))
840     return pango_font_description_get_variant (a) - pango_font_description_get_variant (b);
841
842   return 0;
843 }
844
845 static int
846 faces_sort_func (const void *a, const void *b)
847 {
848   PangoFontDescription *desc_a = pango_font_face_describe (*(PangoFontFace **)a);
849   PangoFontDescription *desc_b = pango_font_face_describe (*(PangoFontFace **)b);
850   
851   int ord = compare_font_descriptions (desc_a, desc_b);
852
853   pango_font_description_free (desc_a);
854   pango_font_description_free (desc_b);
855
856   return ord;
857 }
858
859 static gboolean
860 font_description_style_equal (const PangoFontDescription *a,
861                               const PangoFontDescription *b)
862 {
863   return (pango_font_description_get_weight (a) == pango_font_description_get_weight (b) &&
864           pango_font_description_get_style (a) == pango_font_description_get_style (b) &&
865           pango_font_description_get_stretch (a) == pango_font_description_get_stretch (b) &&
866           pango_font_description_get_variant (a) == pango_font_description_get_variant (b));
867 }
868
869 /* This fills the font style list with all the possible style combinations
870    for the current font family. */
871 static void
872 gtk_font_selection_show_available_styles (GtkFontSelection *fontsel)
873 {
874   GtkFontSelectionPrivate *priv = fontsel->priv;
875   gint n_faces, i;
876   PangoFontFace **faces;
877   PangoFontDescription *old_desc;
878   GtkListStore *model;
879   GtkTreeIter match_row;
880   PangoFontFace *match_face = NULL;
881
882   model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (priv->face_list)));
883
884   if (priv->face)
885     old_desc = pango_font_face_describe (priv->face);
886   else
887     old_desc= NULL;
888
889   pango_font_family_list_faces (priv->family, &faces, &n_faces);
890   qsort (faces, n_faces, sizeof (PangoFontFace *), faces_sort_func);
891
892   gtk_list_store_clear (model);
893
894   for (i=0; i < n_faces; i++)
895     {
896       GtkTreeIter iter;
897       const gchar *str = pango_font_face_get_face_name (faces[i]);
898
899       gtk_list_store_append (model, &iter);
900       gtk_list_store_set (model, &iter,
901                           FACE_COLUMN, faces[i],
902                           FACE_NAME_COLUMN, str,
903                           -1);
904
905       if (i == 0)
906         {
907           match_row = iter;
908           match_face = faces[i];
909         }
910       else if (old_desc)
911         {
912           PangoFontDescription *tmp_desc = pango_font_face_describe (faces[i]);
913           
914           if (font_description_style_equal (tmp_desc, old_desc))
915             {
916               match_row = iter;
917               match_face = faces[i];
918             }
919       
920           pango_font_description_free (tmp_desc);
921         }
922     }
923
924   if (old_desc)
925     pango_font_description_free (old_desc);
926
927   gtk_font_selection_ref_face (fontsel, match_face);
928   if (match_face)
929     {
930 #ifdef INCLUDE_FONT_ENTRIES
931       const gchar *str = pango_font_face_get_face_name (priv->face);
932
933       gtk_entry_set_text (GTK_ENTRY (priv->font_style_entry), str);
934 #endif
935       set_cursor_to_iter (GTK_TREE_VIEW (priv->face_list), &match_row);
936     }
937
938   g_free (faces);
939 }
940
941 /* This selects a style when the user selects a font. It just uses the first
942    available style at present. I was thinking of trying to maintain the
943    selected style, e.g. bold italic, when the user selects different fonts.
944    However, the interface is so easy to use now I'm not sure it's worth it.
945    Note: This will load a font. */
946 static void
947 gtk_font_selection_select_best_style (GtkFontSelection *fontsel,
948                                       gboolean          use_first)
949 {
950   GtkFontSelectionPrivate *priv = fontsel->priv;
951   GtkTreeIter iter;
952   GtkTreeModel *model;
953
954   model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->face_list));
955
956   if (gtk_tree_model_get_iter_first (model, &iter))
957     {
958       set_cursor_to_iter (GTK_TREE_VIEW (priv->face_list), &iter);
959       scroll_to_selection (GTK_TREE_VIEW (priv->face_list));
960     }
961
962   gtk_font_selection_show_available_sizes (fontsel, FALSE);
963   gtk_font_selection_select_best_size (fontsel);
964 }
965
966
967 /* This is called when a style is selected in the list. */
968 static void
969 gtk_font_selection_select_style (GtkTreeSelection *selection,
970                                  gpointer          data)
971 {
972   GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
973   GtkTreeModel *model;
974   GtkTreeIter iter;
975
976   if (gtk_tree_selection_get_selected (selection, &model, &iter))
977     {
978       PangoFontFace *face;
979       
980       gtk_tree_model_get (model, &iter, FACE_COLUMN, &face, -1);
981       gtk_font_selection_ref_face (fontsel, face);
982       g_object_unref (face);
983     }
984
985   gtk_font_selection_show_available_sizes (fontsel, FALSE);
986   gtk_font_selection_select_best_size (fontsel);
987 }
988
989 static void
990 gtk_font_selection_show_available_sizes (GtkFontSelection *fontsel,
991                                          gboolean          first_time)
992 {
993   GtkFontSelectionPrivate *priv = fontsel->priv;
994   gint i;
995   GtkListStore *model;
996   gchar buffer[128];
997   gchar *p;
998
999   model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (priv->size_list)));
1000
1001   /* Insert the standard font sizes */
1002   if (first_time)
1003     {
1004       gtk_list_store_clear (model);
1005
1006       for (i = 0; i < G_N_ELEMENTS (font_sizes); i++)
1007         {
1008           GtkTreeIter iter;
1009
1010           gtk_list_store_append (model, &iter);
1011           gtk_list_store_set (model, &iter, SIZE_COLUMN, font_sizes[i], -1);
1012
1013           if (font_sizes[i] * PANGO_SCALE == priv->size)
1014             set_cursor_to_iter (GTK_TREE_VIEW (priv->size_list), &iter);
1015         }
1016     }
1017   else
1018     {
1019       GtkTreeIter iter;
1020       gboolean found = FALSE;
1021
1022       gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &iter);
1023       for (i = 0; i < G_N_ELEMENTS (font_sizes) && !found; i++)
1024         {
1025           if (font_sizes[i] * PANGO_SCALE == priv->size)
1026             {
1027               set_cursor_to_iter (GTK_TREE_VIEW (priv->size_list), &iter);
1028               found = TRUE;
1029             }
1030
1031           gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &iter);
1032         }
1033
1034       if (!found)
1035         {
1036           GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->size_list));
1037           gtk_tree_selection_unselect_all (selection);
1038         }
1039     }
1040
1041   /* Set the entry to the new size, rounding to 1 digit,
1042    * trimming of trailing 0's and a trailing period
1043    */
1044   g_snprintf (buffer, sizeof (buffer), "%.1f", priv->size / (1.0 * PANGO_SCALE));
1045   if (strchr (buffer, '.'))
1046     {
1047       p = buffer + strlen (buffer) - 1;
1048       while (*p == '0')
1049         p--;
1050       if (*p == '.')
1051         p--;
1052       p[1] = '\0';
1053     }
1054
1055   /* Compare, to avoid moving the cursor unecessarily */
1056   if (strcmp (gtk_entry_get_text (GTK_ENTRY (priv->size_entry)), buffer) != 0)
1057     gtk_entry_set_text (GTK_ENTRY (priv->size_entry), buffer);
1058 }
1059
1060 static void
1061 gtk_font_selection_select_best_size (GtkFontSelection *fontsel)
1062 {
1063   gtk_font_selection_load_font (fontsel);  
1064 }
1065
1066 static void
1067 gtk_font_selection_set_size (GtkFontSelection *fontsel,
1068                              gint              new_size)
1069 {
1070   GtkFontSelectionPrivate *priv = fontsel->priv;
1071
1072   if (priv->size != new_size)
1073     {
1074       priv->size = new_size;
1075
1076       gtk_font_selection_show_available_sizes (fontsel, FALSE);      
1077       gtk_font_selection_load_font (fontsel);
1078     }
1079 }
1080
1081 /* If the user hits return in the font size entry, we change to the new font
1082    size. */
1083 static void
1084 gtk_font_selection_size_activate (GtkWidget   *w,
1085                                   gpointer     data)
1086 {
1087   GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
1088   GtkFontSelectionPrivate *priv = fontsel->priv;
1089   gint new_size;
1090   const gchar *text;
1091
1092   text = gtk_entry_get_text (GTK_ENTRY (priv->size_entry));
1093   new_size = MAX (0.1, atof (text) * PANGO_SCALE + 0.5);
1094
1095   if (priv->size != new_size)
1096     gtk_font_selection_set_size (fontsel, new_size);
1097   else 
1098     list_row_activated (w);
1099 }
1100
1101 static gboolean
1102 gtk_font_selection_size_focus_out (GtkWidget     *w,
1103                                    GdkEventFocus *event,
1104                                    gpointer       data)
1105 {
1106   GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
1107   GtkFontSelectionPrivate *priv = fontsel->priv;
1108   gint new_size;
1109   const gchar *text;
1110
1111   text = gtk_entry_get_text (GTK_ENTRY (priv->size_entry));
1112   new_size = MAX (0.1, atof (text) * PANGO_SCALE + 0.5);
1113
1114   gtk_font_selection_set_size (fontsel, new_size);
1115
1116   return TRUE;
1117 }
1118
1119 /* This is called when a size is selected in the list. */
1120 static void
1121 gtk_font_selection_select_size (GtkTreeSelection *selection,
1122                                 gpointer          data)
1123 {
1124   GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
1125   GtkTreeModel *model;
1126   GtkTreeIter iter;
1127   gint new_size;
1128
1129   if (gtk_tree_selection_get_selected (selection, &model, &iter))
1130     {
1131       gtk_tree_model_get (model, &iter, SIZE_COLUMN, &new_size, -1);
1132       gtk_font_selection_set_size (fontsel, new_size * PANGO_SCALE);
1133     }
1134 }
1135
1136 static void
1137 gtk_font_selection_load_font (GtkFontSelection *fontsel)
1138 {
1139   gtk_font_selection_update_preview (fontsel);
1140 }
1141
1142 static PangoFontDescription *
1143 gtk_font_selection_get_font_description (GtkFontSelection *fontsel)
1144 {
1145   GtkFontSelectionPrivate *priv = fontsel->priv;
1146   PangoFontDescription *font_desc;
1147
1148   if (priv->face)
1149     {
1150       font_desc = pango_font_face_describe (priv->face);
1151       pango_font_description_set_size (font_desc, priv->size);
1152     }
1153   else
1154     font_desc = pango_font_description_from_string (DEFAULT_FONT_NAME);
1155
1156   return font_desc;
1157 }
1158
1159 /* This sets the font in the preview entry to the selected font, and tries to
1160    make sure that the preview entry is a reasonable size, i.e. so that the
1161    text can be seen with a bit of space to spare. But it tries to avoid
1162    resizing the entry every time the font changes.
1163    This also used to shrink the preview if the font size was decreased, but
1164    that made it awkward if the user wanted to resize the window themself. */
1165 static void
1166 gtk_font_selection_update_preview (GtkFontSelection *fontsel)
1167 {
1168   GtkFontSelectionPrivate *priv = fontsel->priv;
1169   GtkRcStyle *rc_style;
1170   gint new_height;
1171   GtkRequisition old_requisition, new_requisition;
1172   GtkWidget *preview_entry = priv->preview_entry;
1173   const gchar *text;
1174
1175   gtk_widget_get_preferred_size (preview_entry, &old_requisition, NULL);
1176
1177   rc_style = gtk_rc_style_new ();
1178   rc_style->font_desc = gtk_font_selection_get_font_description (fontsel);
1179   
1180   gtk_widget_modify_style (preview_entry, rc_style);
1181   g_object_unref (rc_style);
1182
1183   gtk_widget_get_preferred_size (preview_entry, &new_requisition, NULL);
1184   
1185   /* We don't ever want to be over MAX_PREVIEW_HEIGHT pixels high. */
1186   new_height = CLAMP (new_requisition.height, INITIAL_PREVIEW_HEIGHT, MAX_PREVIEW_HEIGHT);
1187
1188   if (new_height > old_requisition.height || new_height < old_requisition.height - 30)
1189     gtk_widget_set_size_request (preview_entry, -1, new_height);
1190   
1191   /* This sets the preview text, if it hasn't been set already. */
1192   text = gtk_entry_get_text (GTK_ENTRY (preview_entry));
1193   if (strlen (text) == 0)
1194     gtk_entry_set_text (GTK_ENTRY (preview_entry), _(PREVIEW_TEXT));
1195   gtk_editable_set_position (GTK_EDITABLE (preview_entry), 0);
1196 }
1197
1198
1199 /*****************************************************************************
1200  * These functions are the main public interface for getting/setting the font.
1201  *****************************************************************************/
1202
1203 /**
1204  * gtk_font_selection_get_family_list:
1205  * @fontsel: a #GtkFontSelection
1206  *
1207  * This returns the #GtkTreeView that lists font families, for
1208  * example, 'Sans', 'Serif', etc.
1209  *
1210  * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1211  *
1212  * Since: 2.14
1213  */
1214 GtkWidget *
1215 gtk_font_selection_get_family_list (GtkFontSelection *fontsel)
1216 {
1217   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1218
1219   return fontsel->priv->family_list;
1220 }
1221
1222 /**
1223  * gtk_font_selection_get_face_list:
1224  * @fontsel: a #GtkFontSelection
1225  *
1226  * This returns the #GtkTreeView which lists all styles available for
1227  * the selected font. For example, 'Regular', 'Bold', etc.
1228  * 
1229  * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1230  *
1231  * Since: 2.14
1232  */
1233 GtkWidget *
1234 gtk_font_selection_get_face_list (GtkFontSelection *fontsel)
1235 {
1236   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1237
1238   return fontsel->priv->face_list;
1239 }
1240
1241 /**
1242  * gtk_font_selection_get_size_entry:
1243  * @fontsel: a #GtkFontSelection
1244  *
1245  * This returns the #GtkEntry used to allow the user to edit the font
1246  * number manually instead of selecting it from the list of font sizes.
1247  *
1248  * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1249  *
1250  * Since: 2.14
1251  */
1252 GtkWidget *
1253 gtk_font_selection_get_size_entry (GtkFontSelection *fontsel)
1254 {
1255   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1256
1257   return fontsel->priv->size_entry;
1258 }
1259
1260 /**
1261  * gtk_font_selection_get_size_list:
1262  * @fontsel: a #GtkFontSelection
1263  *
1264  * This returns the #GtkTreeeView used to list font sizes.
1265  *
1266  * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1267  *
1268  * Since: 2.14
1269  */
1270 GtkWidget *
1271 gtk_font_selection_get_size_list (GtkFontSelection *fontsel)
1272 {
1273   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1274
1275   return fontsel->priv->size_list;
1276 }
1277
1278 /**
1279  * gtk_font_selection_get_preview_entry:
1280  * @fontsel: a #GtkFontSelection
1281  *
1282  * This returns the #GtkEntry used to display the font as a preview.
1283  *
1284  * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1285  *
1286  * Since: 2.14
1287  */
1288 GtkWidget *
1289 gtk_font_selection_get_preview_entry (GtkFontSelection *fontsel)
1290 {
1291   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1292
1293   return fontsel->priv->preview_entry;
1294 }
1295
1296 /**
1297  * gtk_font_selection_get_family:
1298  * @fontsel: a #GtkFontSelection
1299  *
1300  * Gets the #PangoFontFamily representing the selected font family.
1301  *
1302  * Return value: (transfer none): A #PangoFontFamily representing the
1303  *     selected font family. Font families are a collection of font
1304  *     faces. The returned object is owned by @fontsel and must not
1305  *     be modified or freed.
1306  *
1307  * Since: 2.14
1308  */
1309 PangoFontFamily *
1310 gtk_font_selection_get_family (GtkFontSelection *fontsel)
1311 {
1312   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1313
1314   return fontsel->priv->family;
1315 }
1316
1317 /**
1318  * gtk_font_selection_get_face:
1319  * @fontsel: a #GtkFontSelection
1320  *
1321  * Gets the #PangoFontFace representing the selected font group
1322  * details (i.e. family, slant, weight, width, etc).
1323  *
1324  * Return value: (transfer none): A #PangoFontFace representing the
1325  *     selected font group details. The returned object is owned by
1326  *     @fontsel and must not be modified or freed.
1327  *
1328  * Since: 2.14
1329  */
1330 PangoFontFace *
1331 gtk_font_selection_get_face (GtkFontSelection *fontsel)
1332 {
1333   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1334
1335   return fontsel->priv->face;
1336 }
1337
1338 /**
1339  * gtk_font_selection_get_size:
1340  * @fontsel: a #GtkFontSelection
1341  *
1342  * The selected font size.
1343  *
1344  * Return value: A n integer representing the selected font size,
1345  *     or -1 if no font size is selected.
1346  *
1347  * Since: 2.14
1348  **/
1349 gint
1350 gtk_font_selection_get_size (GtkFontSelection *fontsel)
1351 {
1352   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), -1);
1353
1354   return fontsel->priv->size;
1355 }
1356
1357 /**
1358  * gtk_font_selection_get_font_name:
1359  * @fontsel: a #GtkFontSelection
1360  * 
1361  * Gets the currently-selected font name. 
1362  *
1363  * Note that this can be a different string than what you set with 
1364  * gtk_font_selection_set_font_name(), as the font selection widget may 
1365  * normalize font names and thus return a string with a different structure. 
1366  * For example, "Helvetica Italic Bold 12" could be normalized to 
1367  * "Helvetica Bold Italic 12". Use pango_font_description_equal()
1368  * if you want to compare two font descriptions.
1369  * 
1370  * Return value: A string with the name of the current font, or %NULL if 
1371  *     no font is selected. You must free this string with g_free().
1372  */
1373 gchar *
1374 gtk_font_selection_get_font_name (GtkFontSelection *fontsel)
1375 {
1376   gchar *result;
1377   
1378   PangoFontDescription *font_desc = gtk_font_selection_get_font_description (fontsel);
1379   result = pango_font_description_to_string (font_desc);
1380   pango_font_description_free (font_desc);
1381
1382   return result;
1383 }
1384
1385 /* This selects the appropriate list rows.
1386    First we check the fontname is valid and try to find the font family
1387    - i.e. the name in the main list. If we can't find that, then just return.
1388    Next we try to set each of the properties according to the fontname.
1389    Finally we select the font family & style in the lists. */
1390 static gboolean
1391 gtk_font_selection_select_font_desc (GtkFontSelection      *fontsel,
1392                                      PangoFontDescription  *new_desc,
1393                                      PangoFontFamily      **pfamily,
1394                                      PangoFontFace        **pface)
1395 {
1396   GtkFontSelectionPrivate *priv = fontsel->priv;
1397   PangoFontFamily *new_family = NULL;
1398   PangoFontFace *new_face = NULL;
1399   PangoFontFace *fallback_face = NULL;
1400   GtkTreeModel *model;
1401   GtkTreeIter iter;
1402   GtkTreeIter match_iter;
1403   gboolean valid;
1404   const gchar *new_family_name;
1405
1406   new_family_name = pango_font_description_get_family (new_desc);
1407
1408   if (!new_family_name)
1409     return FALSE;
1410
1411   /* Check to make sure that this is in the list of allowed fonts 
1412    */
1413   model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->family_list));
1414   for (valid = gtk_tree_model_get_iter_first (model, &iter);
1415        valid;
1416        valid = gtk_tree_model_iter_next (model, &iter))
1417     {
1418       PangoFontFamily *family;
1419       
1420       gtk_tree_model_get (model, &iter, FAMILY_COLUMN, &family, -1);
1421       
1422       if (g_ascii_strcasecmp (pango_font_family_get_name (family),
1423                               new_family_name) == 0)
1424         new_family = g_object_ref (family);
1425
1426       g_object_unref (family);
1427       
1428       if (new_family)
1429         break;
1430     }
1431
1432   if (!new_family)
1433     return FALSE;
1434
1435   if (pfamily)
1436     *pfamily = new_family;
1437   else
1438     g_object_unref (new_family);
1439   set_cursor_to_iter (GTK_TREE_VIEW (priv->family_list), &iter);
1440   gtk_font_selection_show_available_styles (fontsel);
1441
1442   model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->face_list));
1443   for (valid = gtk_tree_model_get_iter_first (model, &iter);
1444        valid;
1445        valid = gtk_tree_model_iter_next (model, &iter))
1446     {
1447       PangoFontFace *face;
1448       PangoFontDescription *tmp_desc;
1449       
1450       gtk_tree_model_get (model, &iter, FACE_COLUMN, &face, -1);
1451       tmp_desc = pango_font_face_describe (face);
1452       
1453       if (font_description_style_equal (tmp_desc, new_desc))
1454         new_face = g_object_ref (face);
1455       
1456       if (!fallback_face)
1457         {
1458           fallback_face = g_object_ref (face);
1459           match_iter = iter;
1460         }
1461       
1462       pango_font_description_free (tmp_desc);
1463       g_object_unref (face);
1464       
1465       if (new_face)
1466         {
1467           match_iter = iter;
1468           break;
1469         }
1470     }
1471
1472   if (!new_face)
1473     new_face = fallback_face;
1474   else if (fallback_face)
1475     g_object_unref (fallback_face);
1476
1477   if (pface)
1478     *pface = new_face;
1479   else if (new_face)
1480     g_object_unref (new_face);
1481   set_cursor_to_iter (GTK_TREE_VIEW (priv->face_list), &match_iter);  
1482
1483   gtk_font_selection_set_size (fontsel, pango_font_description_get_size (new_desc));
1484
1485   return TRUE;
1486 }
1487
1488
1489 /* This sets the current font, then selecting the appropriate list rows. */
1490
1491 /**
1492  * gtk_font_selection_set_font_name:
1493  * @fontsel: a #GtkFontSelection
1494  * @fontname: a font name like "Helvetica 12" or "Times Bold 18"
1495  * 
1496  * Sets the currently-selected font. 
1497  *
1498  * Note that the @fontsel needs to know the screen in which it will appear 
1499  * for this to work; this can be guaranteed by simply making sure that the 
1500  * @fontsel is inserted in a toplevel window before you call this function.
1501  * 
1502  * Return value: %TRUE if the font could be set successfully; %FALSE if no 
1503  *     such font exists or if the @fontsel doesn't belong to a particular 
1504  *     screen yet.
1505  */
1506 gboolean
1507 gtk_font_selection_set_font_name (GtkFontSelection *fontsel,
1508                                   const gchar      *fontname)
1509 {
1510   PangoFontFamily *family = NULL;
1511   PangoFontFace *face = NULL;
1512   PangoFontDescription *new_desc;
1513   
1514   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), FALSE);
1515
1516   if (!gtk_widget_has_screen (GTK_WIDGET (fontsel)))
1517     return FALSE;
1518
1519   new_desc = pango_font_description_from_string (fontname);
1520
1521   if (gtk_font_selection_select_font_desc (fontsel, new_desc, &family, &face))
1522     {
1523       gtk_font_selection_ref_family (fontsel, family);
1524       if (family)
1525         g_object_unref (family);
1526
1527       gtk_font_selection_ref_face (fontsel, face);
1528       if (face)
1529         g_object_unref (face);
1530     }
1531
1532   pango_font_description_free (new_desc);
1533   
1534   g_object_notify (G_OBJECT (fontsel), "font-name");
1535
1536   return TRUE;
1537 }
1538
1539 /**
1540  * gtk_font_selection_get_preview_text:
1541  * @fontsel: a #GtkFontSelection
1542  *
1543  * Gets the text displayed in the preview area.
1544  * 
1545  * Return value: the text displayed in the preview area. 
1546  *     This string is owned by the widget and should not be 
1547  *     modified or freed 
1548  */
1549 G_CONST_RETURN gchar*
1550 gtk_font_selection_get_preview_text (GtkFontSelection *fontsel)
1551 {
1552   GtkFontSelectionPrivate *priv;
1553
1554   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1555
1556   priv = fontsel->priv;
1557
1558   return gtk_entry_get_text (GTK_ENTRY (priv->preview_entry));
1559 }
1560
1561
1562 /**
1563  * gtk_font_selection_set_preview_text:
1564  * @fontsel: a #GtkFontSelection
1565  * @text: the text to display in the preview area 
1566  *
1567  * Sets the text displayed in the preview area.
1568  * The @text is used to show how the selected font looks.
1569  */
1570 void
1571 gtk_font_selection_set_preview_text  (GtkFontSelection *fontsel,
1572                                       const gchar      *text)
1573 {
1574   GtkFontSelectionPrivate *priv;
1575
1576   g_return_if_fail (GTK_IS_FONT_SELECTION (fontsel));
1577   g_return_if_fail (text != NULL);
1578
1579   priv = fontsel->priv;
1580
1581   gtk_entry_set_text (GTK_ENTRY (priv->preview_entry), text);
1582 }
1583
1584 /*****************************************************************************
1585  * GtkFontSelectionDialog
1586  *****************************************************************************/
1587
1588 static void gtk_font_selection_dialog_buildable_interface_init     (GtkBuildableIface *iface);
1589 static GObject * gtk_font_selection_dialog_buildable_get_internal_child (GtkBuildable *buildable,
1590                                                                           GtkBuilder   *builder,
1591                                                                           const gchar  *childname);
1592
1593 G_DEFINE_TYPE_WITH_CODE (GtkFontSelectionDialog, gtk_font_selection_dialog,
1594                          GTK_TYPE_DIALOG,
1595                          G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
1596                                                 gtk_font_selection_dialog_buildable_interface_init))
1597
1598 static GtkBuildableIface *parent_buildable_iface;
1599
1600 static void
1601 gtk_font_selection_dialog_class_init (GtkFontSelectionDialogClass *klass)
1602 {
1603   g_type_class_add_private (klass, sizeof (GtkFontSelectionDialogPrivate));
1604 }
1605
1606 static void
1607 gtk_font_selection_dialog_init (GtkFontSelectionDialog *fontseldiag)
1608 {
1609   GtkFontSelectionDialogPrivate *priv;
1610   GtkDialog *dialog = GTK_DIALOG (fontseldiag);
1611   GtkWidget *action_area, *content_area;
1612
1613   fontseldiag->priv = G_TYPE_INSTANCE_GET_PRIVATE (fontseldiag,
1614                                                    GTK_TYPE_FONT_SELECTION_DIALOG,
1615                                                    GtkFontSelectionDialogPrivate);
1616   priv = fontseldiag->priv;
1617
1618   content_area = gtk_dialog_get_content_area (dialog);
1619   action_area = gtk_dialog_get_action_area (dialog);
1620
1621   gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
1622   gtk_box_set_spacing (GTK_BOX (content_area), 2); /* 2 * 5 + 2 = 12 */
1623   gtk_container_set_border_width (GTK_CONTAINER (action_area), 5);
1624   gtk_box_set_spacing (GTK_BOX (action_area), 6);
1625
1626   gtk_widget_push_composite_child ();
1627
1628   gtk_window_set_resizable (GTK_WINDOW (fontseldiag), TRUE);
1629
1630   /* Create the content area */
1631   priv->fontsel = gtk_font_selection_new ();
1632   gtk_container_set_border_width (GTK_CONTAINER (priv->fontsel), 5);
1633   gtk_widget_show (priv->fontsel);
1634   gtk_box_pack_start (GTK_BOX (content_area),
1635                       priv->fontsel, TRUE, TRUE, 0);
1636
1637   /* Create the action area */
1638   priv->cancel_button = gtk_dialog_add_button (dialog,
1639                                                GTK_STOCK_CANCEL,
1640                                                GTK_RESPONSE_CANCEL);
1641
1642   priv->apply_button = gtk_dialog_add_button (dialog,
1643                                               GTK_STOCK_APPLY,
1644                                               GTK_RESPONSE_APPLY);
1645   gtk_widget_hide (priv->apply_button);
1646
1647   priv->ok_button = gtk_dialog_add_button (dialog,
1648                                            GTK_STOCK_OK,
1649                                            GTK_RESPONSE_OK);
1650   gtk_widget_grab_default (priv->ok_button);
1651
1652   gtk_dialog_set_alternative_button_order (GTK_DIALOG (fontseldiag),
1653                                            GTK_RESPONSE_OK,
1654                                            GTK_RESPONSE_APPLY,
1655                                            GTK_RESPONSE_CANCEL,
1656                                            -1);
1657
1658   gtk_window_set_title (GTK_WINDOW (fontseldiag),
1659                         _("Font Selection"));
1660
1661   gtk_widget_pop_composite_child ();
1662 }
1663
1664 /**
1665  * gtk_font_selection_dialog_new:
1666  * @title: the title of the dialog window 
1667  *
1668  * Creates a new #GtkFontSelectionDialog.
1669  *
1670  * Return value: a new #GtkFontSelectionDialog
1671  */
1672 GtkWidget*
1673 gtk_font_selection_dialog_new (const gchar *title)
1674 {
1675   GtkFontSelectionDialog *fontseldiag;
1676   
1677   fontseldiag = g_object_new (GTK_TYPE_FONT_SELECTION_DIALOG, NULL);
1678
1679   if (title)
1680     gtk_window_set_title (GTK_WINDOW (fontseldiag), title);
1681   
1682   return GTK_WIDGET (fontseldiag);
1683 }
1684
1685 /**
1686  * gtk_font_selection_dialog_get_font_selection:
1687  * @fsd: a #GtkFontSelectionDialog
1688  *
1689  * Retrieves the #GtkFontSelection widget embedded in the dialog.
1690  *
1691  * Returns: (transfer none): the embedded #GtkFontSelection
1692  *
1693  * Since: 2.22
1694  **/
1695 GtkWidget*
1696 gtk_font_selection_dialog_get_font_selection (GtkFontSelectionDialog *fsd)
1697 {
1698   g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1699
1700   return fsd->priv->fontsel;
1701 }
1702
1703
1704 /**
1705  * gtk_font_selection_dialog_get_ok_button:
1706  * @fsd: a #GtkFontSelectionDialog
1707  *
1708  * Gets the 'OK' button.
1709  *
1710  * Return value: (transfer none): the #GtkWidget used in the dialog
1711  *     for the 'OK' button.
1712  *
1713  * Since: 2.14
1714  */
1715 GtkWidget *
1716 gtk_font_selection_dialog_get_ok_button (GtkFontSelectionDialog *fsd)
1717 {
1718   g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1719
1720   return fsd->priv->ok_button;
1721 }
1722
1723 /**
1724  * gtk_font_selection_dialog_get_cancel_button:
1725  * @fsd: a #GtkFontSelectionDialog
1726  *
1727  * Gets the 'Cancel' button.
1728  *
1729  * Return value: (transfer none): the #GtkWidget used in the dialog
1730  *     for the 'Cancel' button.
1731  *
1732  * Since: 2.14
1733  */
1734 GtkWidget *
1735 gtk_font_selection_dialog_get_cancel_button (GtkFontSelectionDialog *fsd)
1736 {
1737   g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1738
1739   return fsd->priv->cancel_button;
1740 }
1741
1742 static void
1743 gtk_font_selection_dialog_buildable_interface_init (GtkBuildableIface *iface)
1744 {
1745   parent_buildable_iface = g_type_interface_peek_parent (iface);
1746   iface->get_internal_child = gtk_font_selection_dialog_buildable_get_internal_child;
1747 }
1748
1749 static GObject *
1750 gtk_font_selection_dialog_buildable_get_internal_child (GtkBuildable *buildable,
1751                                                         GtkBuilder   *builder,
1752                                                         const gchar  *childname)
1753 {
1754   GtkFontSelectionDialogPrivate *priv;
1755
1756   priv = GTK_FONT_SELECTION_DIALOG (buildable)->priv;
1757
1758   if (g_strcmp0 (childname, "ok_button") == 0)
1759     return G_OBJECT (priv->ok_button);
1760   else if (g_strcmp0 (childname, "cancel_button") == 0)
1761     return G_OBJECT (priv->cancel_button);
1762   else if (g_strcmp0 (childname, "apply_button") == 0)
1763     return G_OBJECT (priv->apply_button);
1764   else if (g_strcmp0 (childname, "font_selection") == 0)
1765     return G_OBJECT (priv->fontsel);
1766
1767   return parent_buildable_iface->get_internal_child (buildable, builder, childname);
1768 }
1769
1770 /**
1771  * gtk_font_selection_dialog_get_font_name:
1772  * @fsd: a #GtkFontSelectionDialog
1773  * 
1774  * Gets the currently-selected font name.
1775  *
1776  * Note that this can be a different string than what you set with 
1777  * gtk_font_selection_dialog_set_font_name(), as the font selection widget
1778  * may normalize font names and thus return a string with a different 
1779  * structure. For example, "Helvetica Italic Bold 12" could be normalized 
1780  * to "Helvetica Bold Italic 12".  Use pango_font_description_equal()
1781  * if you want to compare two font descriptions.
1782  * 
1783  * Return value: A string with the name of the current font, or %NULL if no 
1784  *     font is selected. You must free this string with g_free().
1785  */
1786 gchar*
1787 gtk_font_selection_dialog_get_font_name (GtkFontSelectionDialog *fsd)
1788 {
1789   GtkFontSelectionDialogPrivate *priv;
1790
1791   g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1792
1793   priv = fsd->priv;
1794
1795   return gtk_font_selection_get_font_name (GTK_FONT_SELECTION (priv->fontsel));
1796 }
1797
1798 /**
1799  * gtk_font_selection_dialog_set_font_name:
1800  * @fsd: a #GtkFontSelectionDialog
1801  * @fontname: a font name like "Helvetica 12" or "Times Bold 18"
1802  *
1803  * Sets the currently selected font. 
1804  * 
1805  * Return value: %TRUE if the font selected in @fsd is now the
1806  *     @fontname specified, %FALSE otherwise. 
1807  */
1808 gboolean
1809 gtk_font_selection_dialog_set_font_name (GtkFontSelectionDialog *fsd,
1810                                          const gchar            *fontname)
1811 {
1812   GtkFontSelectionDialogPrivate *priv;
1813
1814   g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), FALSE);
1815   g_return_val_if_fail (fontname, FALSE);
1816
1817   priv = fsd->priv;
1818
1819   return gtk_font_selection_set_font_name (GTK_FONT_SELECTION (priv->fontsel), fontname);
1820 }
1821
1822 /**
1823  * gtk_font_selection_dialog_get_preview_text:
1824  * @fsd: a #GtkFontSelectionDialog
1825  *
1826  * Gets the text displayed in the preview area.
1827  * 
1828  * Return value: the text displayed in the preview area. 
1829  *     This string is owned by the widget and should not be 
1830  *     modified or freed 
1831  */
1832 G_CONST_RETURN gchar*
1833 gtk_font_selection_dialog_get_preview_text (GtkFontSelectionDialog *fsd)
1834 {
1835   GtkFontSelectionDialogPrivate *priv;
1836
1837   g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1838
1839   priv = fsd->priv;
1840
1841   return gtk_font_selection_get_preview_text (GTK_FONT_SELECTION (priv->fontsel));
1842 }
1843
1844 /**
1845  * gtk_font_selection_dialog_set_preview_text:
1846  * @fsd: a #GtkFontSelectionDialog
1847  * @text: the text to display in the preview area
1848  *
1849  * Sets the text displayed in the preview area. 
1850  */
1851 void
1852 gtk_font_selection_dialog_set_preview_text (GtkFontSelectionDialog *fsd,
1853                                             const gchar            *text)
1854 {
1855   GtkFontSelectionDialogPrivate *priv;
1856
1857   g_return_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd));
1858   g_return_if_fail (text != NULL);
1859
1860   priv = fsd->priv;
1861
1862   gtk_font_selection_set_preview_text (GTK_FONT_SELECTION (priv->fontsel), text);
1863 }