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