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