]> Pileus Git - ~andy/gtk/blob - gtk/gtkfontsel.c
gtk/gtkfontsel.c: Use accessor functions to access GtkWindow
[~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 "gtkprivate.h"
62 #include "gtkbuildable.h"
63
64 struct _GtkFontSelectionPriv
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 _GtkFontSelectionDialogPriv
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 (GtkFontSelectionPriv));
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   GtkFontSelectionPriv *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                                                GtkFontSelectionPriv);
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   GtkFontSelectionPriv *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   GtkFontSelectionPriv *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   GtkFontSelectionPriv *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   GtkFontSelectionPriv *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   GtkFontSelectionPriv *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   GtkFontSelectionPriv *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   GtkFontSelectionPriv *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   GtkFontSelectionPriv *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   GtkFontSelectionPriv *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   GtkFontSelectionPriv *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   GtkFontSelectionPriv *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   GtkFontSelectionPriv *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   GtkFontSelectionPriv *priv = fontsel->priv;
1169   GtkRcStyle *rc_style;
1170   gint new_height;
1171   GtkRequisition old_requisition;
1172   GtkWidget *preview_entry = priv->preview_entry;
1173   const gchar *text;
1174
1175   gtk_widget_get_child_requisition (preview_entry, &old_requisition);
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_size_request (preview_entry, NULL);
1184   
1185   /* We don't ever want to be over MAX_PREVIEW_HEIGHT pixels high. */
1186   new_height = CLAMP (preview_entry->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: 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: 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: 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: 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: 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: A #PangoFontFamily representing the selected font
1303  *     family. Font families are a collection of font faces. The 
1304  *     returned object is owned by @fontsel and must not be modified 
1305  *     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: A #PangoFontFace representing the selected font 
1325  *     group details. The returned object is owned by @fontsel and
1326  *     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   GtkFontSelectionPriv *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   GtkFontSelectionPriv *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   GtkFontSelectionPriv *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 (GtkFontSelectionDialogPriv));
1604 }
1605
1606 static void
1607 gtk_font_selection_dialog_init (GtkFontSelectionDialog *fontseldiag)
1608 {
1609   GtkFontSelectionDialogPriv *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                                                    GtkFontSelectionDialogPriv);
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_dialog_set_has_separator (dialog, FALSE);
1622   gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
1623   gtk_box_set_spacing (GTK_BOX (content_area), 2); /* 2 * 5 + 2 = 12 */
1624   gtk_container_set_border_width (GTK_CONTAINER (action_area), 5);
1625   gtk_box_set_spacing (GTK_BOX (action_area), 6);
1626
1627   gtk_widget_push_composite_child ();
1628
1629   gtk_window_set_resizable (GTK_WINDOW (fontseldiag), TRUE);
1630
1631   /* Create the content area */
1632   priv->fontsel = gtk_font_selection_new ();
1633   gtk_container_set_border_width (GTK_CONTAINER (priv->fontsel), 5);
1634   gtk_widget_show (priv->fontsel);
1635   gtk_box_pack_start (GTK_BOX (content_area),
1636                       priv->fontsel, TRUE, TRUE, 0);
1637
1638   /* Create the action area */
1639   priv->cancel_button = gtk_dialog_add_button (dialog,
1640                                                GTK_STOCK_CANCEL,
1641                                                GTK_RESPONSE_CANCEL);
1642
1643   priv->apply_button = gtk_dialog_add_button (dialog,
1644                                               GTK_STOCK_APPLY,
1645                                               GTK_RESPONSE_APPLY);
1646   gtk_widget_hide (priv->apply_button);
1647
1648   priv->ok_button = gtk_dialog_add_button (dialog,
1649                                            GTK_STOCK_OK,
1650                                            GTK_RESPONSE_OK);
1651   gtk_widget_grab_default (priv->ok_button);
1652
1653   gtk_dialog_set_alternative_button_order (GTK_DIALOG (fontseldiag),
1654                                            GTK_RESPONSE_OK,
1655                                            GTK_RESPONSE_APPLY,
1656                                            GTK_RESPONSE_CANCEL,
1657                                            -1);
1658
1659   gtk_window_set_title (GTK_WINDOW (fontseldiag),
1660                         _("Font Selection"));
1661
1662   gtk_widget_pop_composite_child ();
1663
1664   _gtk_dialog_set_ignore_separator (dialog, TRUE);
1665 }
1666
1667 /**
1668  * gtk_font_selection_dialog_new:
1669  * @title: the title of the dialog window 
1670  *
1671  * Creates a new #GtkFontSelectionDialog.
1672  *
1673  * Return value: a new #GtkFontSelectionDialog
1674  */
1675 GtkWidget*
1676 gtk_font_selection_dialog_new (const gchar *title)
1677 {
1678   GtkFontSelectionDialog *fontseldiag;
1679   
1680   fontseldiag = g_object_new (GTK_TYPE_FONT_SELECTION_DIALOG, NULL);
1681
1682   if (title)
1683     gtk_window_set_title (GTK_WINDOW (fontseldiag), title);
1684   
1685   return GTK_WIDGET (fontseldiag);
1686 }
1687
1688 /**
1689  * gtk_font_selection_dialog_get_font_selection:
1690  * @colorsel: a #GtkFontSelectionDialog
1691  *
1692  * Retrieves the #GtkFontSelection widget embedded in the dialog.
1693  *
1694  * Returns: the embedded #GtkFontSelection
1695  *
1696  * Since: 2.22
1697  **/
1698 GtkWidget*
1699 gtk_font_selection_dialog_get_font_selection (GtkFontSelectionDialog *fsd)
1700 {
1701   g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1702
1703   return fsd->priv->fontsel;
1704 }
1705
1706
1707 /**
1708  * gtk_font_selection_dialog_get_ok_button:
1709  * @fsd: a #GtkFontSelectionDialog
1710  *
1711  * Gets the 'OK' button.
1712  *
1713  * Return value: the #GtkWidget used in the dialog 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: the #GtkWidget used in the dialog for the 'Cancel' button.
1732  *
1733  * Since: 2.14
1734  */
1735 GtkWidget *
1736 gtk_font_selection_dialog_get_cancel_button (GtkFontSelectionDialog *fsd)
1737 {
1738   g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1739
1740   return fsd->priv->cancel_button;
1741 }
1742
1743 static void
1744 gtk_font_selection_dialog_buildable_interface_init (GtkBuildableIface *iface)
1745 {
1746   parent_buildable_iface = g_type_interface_peek_parent (iface);
1747   iface->get_internal_child = gtk_font_selection_dialog_buildable_get_internal_child;
1748 }
1749
1750 static GObject *
1751 gtk_font_selection_dialog_buildable_get_internal_child (GtkBuildable *buildable,
1752                                                         GtkBuilder   *builder,
1753                                                         const gchar  *childname)
1754 {
1755   GtkFontSelectionDialogPriv *priv;
1756
1757   priv = GTK_FONT_SELECTION_DIALOG (buildable)->priv;
1758
1759   if (g_strcmp0 (childname, "ok_button") == 0)
1760     return G_OBJECT (priv->ok_button);
1761   else if (g_strcmp0 (childname, "cancel_button") == 0)
1762     return G_OBJECT (priv->cancel_button);
1763   else if (g_strcmp0 (childname, "apply_button") == 0)
1764     return G_OBJECT (priv->apply_button);
1765   else if (g_strcmp0 (childname, "font_selection") == 0)
1766     return G_OBJECT (priv->fontsel);
1767
1768   return parent_buildable_iface->get_internal_child (buildable, builder, childname);
1769 }
1770
1771 /**
1772  * gtk_font_selection_dialog_get_font_name:
1773  * @fsd: a #GtkFontSelectionDialog
1774  * 
1775  * Gets the currently-selected font name.
1776  *
1777  * Note that this can be a different string than what you set with 
1778  * gtk_font_selection_dialog_set_font_name(), as the font selection widget
1779  * may normalize font names and thus return a string with a different 
1780  * structure. For example, "Helvetica Italic Bold 12" could be normalized 
1781  * to "Helvetica Bold Italic 12".  Use pango_font_description_equal()
1782  * if you want to compare two font descriptions.
1783  * 
1784  * Return value: A string with the name of the current font, or %NULL if no 
1785  *     font is selected. You must free this string with g_free().
1786  */
1787 gchar*
1788 gtk_font_selection_dialog_get_font_name (GtkFontSelectionDialog *fsd)
1789 {
1790   GtkFontSelectionDialogPriv *priv;
1791
1792   g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1793
1794   priv = fsd->priv;
1795
1796   return gtk_font_selection_get_font_name (GTK_FONT_SELECTION (priv->fontsel));
1797 }
1798
1799 /**
1800  * gtk_font_selection_dialog_set_font_name:
1801  * @fsd: a #GtkFontSelectionDialog
1802  * @fontname: a font name like "Helvetica 12" or "Times Bold 18"
1803  *
1804  * Sets the currently selected font. 
1805  * 
1806  * Return value: %TRUE if the font selected in @fsd is now the
1807  *     @fontname specified, %FALSE otherwise. 
1808  */
1809 gboolean
1810 gtk_font_selection_dialog_set_font_name (GtkFontSelectionDialog *fsd,
1811                                          const gchar            *fontname)
1812 {
1813   GtkFontSelectionDialogPriv *priv;
1814
1815   g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), FALSE);
1816   g_return_val_if_fail (fontname, FALSE);
1817
1818   priv = fsd->priv;
1819
1820   return gtk_font_selection_set_font_name (GTK_FONT_SELECTION (priv->fontsel), fontname);
1821 }
1822
1823 /**
1824  * gtk_font_selection_dialog_get_preview_text:
1825  * @fsd: a #GtkFontSelectionDialog
1826  *
1827  * Gets the text displayed in the preview area.
1828  * 
1829  * Return value: the text displayed in the preview area. 
1830  *     This string is owned by the widget and should not be 
1831  *     modified or freed 
1832  */
1833 G_CONST_RETURN gchar*
1834 gtk_font_selection_dialog_get_preview_text (GtkFontSelectionDialog *fsd)
1835 {
1836   GtkFontSelectionDialogPriv *priv;
1837
1838   g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1839
1840   priv = fsd->priv;
1841
1842   return gtk_font_selection_get_preview_text (GTK_FONT_SELECTION (priv->fontsel));
1843 }
1844
1845 /**
1846  * gtk_font_selection_dialog_set_preview_text:
1847  * @fsd: a #GtkFontSelectionDialog
1848  * @text: the text to display in the preview area
1849  *
1850  * Sets the text displayed in the preview area. 
1851  */
1852 void
1853 gtk_font_selection_dialog_set_preview_text (GtkFontSelectionDialog *fsd,
1854                                             const gchar            *text)
1855 {
1856   GtkFontSelectionDialogPriv *priv;
1857
1858   g_return_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd));
1859   g_return_if_fail (text != NULL);
1860
1861   priv = fsd->priv;
1862
1863   gtk_font_selection_set_preview_text (GTK_FONT_SELECTION (priv->fontsel), text);
1864 }