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