]> Pileus Git - ~andy/gtk/blob - gtk/gtkfontchooser.c
cadb5cd6a03561bb2705ffe3bf3a64d57f949bbe
[~andy/gtk] / gtk / gtkfontchooser.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 #include "gtkalignment.h"
61 #include "gtkscale.h"
62 #include "gtkbox.h"
63 #include "gtkspinbutton.h"
64 #include "gtkwidget.h"
65
66 /**
67  * SECTION:gtkfontsel
68  * @Short_description: A widget for selecting fonts
69  * @Title: GtkFontSelection
70  * @See_also: #GtkFontSelectionDialog
71  *
72  * The #GtkFontSelection widget lists the available fonts, styles and sizes,
73  * allowing the user to select a font.
74  * It is used in the #GtkFontSelectionDialog widget to provide a dialog box for
75  * selecting fonts.
76  *
77  * To set the font which is initially selected, use
78  * gtk_font_selection_set_font_name().
79  *
80  * To get the selected font use gtk_font_selection_get_font_name().
81  *
82  * To change the text which is shown in the preview area, use
83  * gtk_font_selection_set_preview_text().
84  */
85
86
87 struct _GtkFontSelectionPrivate
88 {
89   GtkWidget *search_entry;
90   GtkWidget *family_face_list;
91   GtkWidget *size_slider;
92   GtkWidget *size_spin;
93   GtkWidget *preview;
94
95   GtkListStore *model;  
96   GtkTreeModel *filter;
97
98   gint             size;
99   PangoFontFace   *face;
100   PangoFontFamily *family;
101   
102   gboolean         ignore_slider;
103
104 #ifndef GTK_DISABLE_DEPRECATED
105   GtkWidget    *size_list;
106   GtkWidget    *font_list;
107   GtkWidget    *face_list;
108
109   GtkListStore *_size_model;
110   GtkListStore *_font_model;
111   GtkListStore *_face_model;
112
113   gboolean      ignore_size;
114   gboolean      ignore_face;
115   gboolean      ignore_font;
116 #endif
117 };
118
119
120 struct _GtkFontSelectionDialogPrivate
121 {
122   GtkWidget *fontsel;
123
124   GtkWidget *ok_button;
125   GtkWidget *apply_button;
126   GtkWidget *cancel_button;
127 };
128
129
130 #define DEFAULT_FONT_NAME "Sans 10"
131 #define MAX_FONT_SIZE 999
132
133 /* This is the initial fixed height and the top padding of the preview entry */
134 #define PREVIEW_HEIGHT 72
135 #define PREVIEW_TOP_PADDING 6
136
137 /* Widget default geometry */
138 #define FONTSEL_WIDTH           540
139 #define FONTSEL_HEIGHT          408
140
141 /* These are the sizes of the font, style & size lists. */
142 #define FONT_LIST_HEIGHT  136
143 #define FONT_LIST_WIDTH   190
144 #define FONT_STYLE_LIST_WIDTH 170
145 #define FONT_SIZE_LIST_WIDTH  60
146
147 #define ROW_FORMAT_STRING "<span weight=\"bold\" size=\"small\" foreground=\"%s\">%s</span>\n<span size=\"x-large\" font_desc=\"%s\">%s</span>"
148
149 /* These are what we use as the standard font sizes, for the size list.
150  */
151 #define FONT_SIZES_LENGTH 14
152 static const gint font_sizes[] = {
153   6, 8, 9, 10, 11, 12, 13, 14, 16, 20, 24, 36, 48, 72
154 };
155
156 enum {
157    PROP_0,
158    PROP_FONT_NAME,
159    PROP_PREVIEW_TEXT
160 };
161
162
163 enum {
164   FAMILY_COLUMN,
165   FACE_COLUMN,
166   PREVIEW_TEXT_COLUMN,
167   PREVIEW_TITLE_COLUMN
168 };
169
170 static void  gtk_font_selection_set_property       (GObject         *object,
171                                                     guint            prop_id,
172                                                     const GValue    *value,
173                                                     GParamSpec      *pspec);
174 static void  gtk_font_selection_get_property       (GObject         *object,
175                                                     guint            prop_id,
176                                                     GValue          *value,
177                                                     GParamSpec      *pspec);
178 static void  gtk_font_selection_finalize           (GObject         *object);
179
180 #if 0
181 static void  gtk_font_selection_screen_changed     (GtkWidget       *widget,
182                                                     GdkScreen       *previous_screen);
183 static void  gtk_font_selection_style_updated      (GtkWidget      *widget);
184 #endif
185
186 static void  gtk_font_selection_ref_family        (GtkFontSelection *fontsel,
187                                                    PangoFontFamily  *family);
188 static void  gtk_font_selection_ref_face          (GtkFontSelection *fontsel,
189                                                    PangoFontFace    *face);
190
191 static void gtk_font_selection_bootstrap_fontlist (GtkFontSelection *fontsel);
192
193 #ifndef GTK_DISABLE_DEPRECATED
194 static void update_font_list_selection            (GtkFontSelection *fontsel);
195 static void update_size_list_selection            (GtkFontSelection *fontsel);
196 static void update_face_model                     (GtkFontSelection *fontsel,
197                                                    gboolean          first);
198 #endif
199
200 G_DEFINE_TYPE (GtkFontSelection, gtk_font_selection, GTK_TYPE_VBOX)
201
202 static void
203 gtk_font_selection_class_init (GtkFontSelectionClass *klass)
204 {
205   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
206
207 #if 0
208   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
209   widget_class->screen_changed = gtk_font_selection_screen_changed;
210   widget_class->style_updated = gtk_font_selection_style_updated;
211 #endif
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   g_object_class_install_property (gobject_class,
218                                    PROP_FONT_NAME,
219                                    g_param_spec_string ("font-name",
220                                                         P_("Font name"),
221                                                         P_("The string that represents this font"),
222                                                         DEFAULT_FONT_NAME,
223                                                         GTK_PARAM_READWRITE));
224   g_object_class_install_property (gobject_class,
225                                    PROP_PREVIEW_TEXT,
226                                    g_param_spec_string ("preview-text",
227                                                         P_("Preview text"),
228                                                         P_("The text to display in order to demonstrate the selected font"),
229                                                         pango_language_get_sample_string (NULL),
230                                                         GTK_PARAM_READWRITE));
231
232   g_type_class_add_private (klass, sizeof (GtkFontSelectionPrivate));
233 }
234
235 static void 
236 gtk_font_selection_set_property (GObject         *object,
237                                  guint            prop_id,
238                                  const GValue    *value,
239                                  GParamSpec      *pspec)
240 {
241   GtkFontSelection *fontsel;
242
243   fontsel = GTK_FONT_SELECTION (object);
244
245   switch (prop_id)
246     {
247     case PROP_FONT_NAME:
248       gtk_font_selection_set_font_name (fontsel, g_value_get_string (value));
249       break;
250     case PROP_PREVIEW_TEXT:
251       gtk_font_selection_set_preview_text (fontsel, g_value_get_string (value));
252       break;
253     default:
254       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
255       break;
256     }
257 }
258
259 static void
260 gtk_font_selection_get_property (GObject         *object,
261                                  guint            prop_id,
262                                  GValue          *value,
263                                  GParamSpec      *pspec)
264 {
265   GtkFontSelection *fontsel;
266
267   fontsel = GTK_FONT_SELECTION (object);
268
269   switch (prop_id)
270     {
271     case PROP_FONT_NAME:
272       g_value_take_string (value, gtk_font_selection_get_font_name (fontsel));
273       break;
274     case PROP_PREVIEW_TEXT:
275       g_value_set_string (value, gtk_font_selection_get_preview_text (fontsel));
276       break;
277     default:
278       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
279       break;
280     }
281 }
282
283 void
284 refilter_and_focus (GtkFontSelectionPrivate *priv)
285 {
286   GtkTreeIter  iter;
287   GtkTreeView *treeview = GTK_TREE_VIEW (priv->family_face_list);
288   GtkTreePath *path = gtk_tree_path_new ();
289
290   gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (priv->filter));
291
292   if (!path)
293     return;
294
295   gtk_tree_view_get_cursor (treeview, &path, NULL);
296
297   if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->filter), &iter, path))
298     {
299       gtk_tree_path_free (path);
300       return;
301     }
302
303   gtk_tree_view_scroll_to_cell (treeview, path, NULL, FALSE, 0.0, 0.0);
304   gtk_tree_path_free (path);
305 }
306
307 void
308 deleted_text_cb (GtkEntryBuffer *buffer,
309                  guint           position,
310                  guint           n_chars,
311                  gpointer        user_data)
312 {
313   GtkFontSelectionPrivate *priv  = (GtkFontSelectionPrivate*)user_data;
314   GtkWidget               *entry = priv->search_entry;
315   
316   if (gtk_entry_buffer_get_length (buffer) == 0)
317     {
318       gtk_entry_set_icon_from_stock (GTK_ENTRY (entry),
319                                      GTK_ENTRY_ICON_SECONDARY,
320                                      GTK_STOCK_FIND);
321     }
322
323   gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (priv->filter));
324 }
325
326 void
327 inserted_text_cb (GtkEntryBuffer *buffer,
328                   guint           position,
329                   gchar          *chars,
330                   guint           n_chars,
331                   gpointer        user_data) 
332 {
333   GtkFontSelectionPrivate *priv  = (GtkFontSelectionPrivate*)user_data;
334   GtkWidget               *entry = priv->search_entry;
335
336   if (g_strcmp0 (gtk_entry_get_icon_stock (GTK_ENTRY (entry), GTK_ENTRY_ICON_SECONDARY),
337                  GTK_STOCK_CLEAR))
338     gtk_entry_set_icon_from_stock (GTK_ENTRY (entry),
339                                    GTK_ENTRY_ICON_SECONDARY,
340                                    GTK_STOCK_CLEAR);
341
342
343   gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (priv->filter));
344 }
345
346 void
347 icon_press_cb (GtkEntry             *entry,
348                GtkEntryIconPosition  pos,
349                GdkEvent             *event,
350                gpointer              user_data)
351 {
352   gtk_entry_buffer_delete_text (gtk_entry_get_buffer (entry), 0, -1);
353 }
354
355 void
356 slider_change_cb (GtkAdjustment *adjustment, gpointer data)
357 {
358   GtkFontSelectionPrivate *priv = (GtkFontSelectionPrivate*)data;
359
360   /* If we set the silder value manually, we ignore this callback */
361   if (priv->ignore_slider)
362     {
363       priv->ignore_slider = FALSE;
364       return;
365     }
366
367   gtk_adjustment_set_value (gtk_spin_button_get_adjustment( GTK_SPIN_BUTTON(priv->size_spin)),
368                             gtk_adjustment_get_value (adjustment));
369 }
370
371 void
372 spin_change_cb (GtkAdjustment *adjustment, gpointer data)
373 {
374   PangoFontDescription    *desc;
375   GtkFontSelection        *fontsel = (GtkFontSelection*)data;
376   GtkFontSelectionPrivate *priv    = fontsel->priv;
377
378   gdouble size = gtk_adjustment_get_value (adjustment);
379   
380   GtkAdjustment *slider_adj = gtk_range_get_adjustment (GTK_RANGE (priv->size_slider));
381
382   /* We ignore the slider value change callback for both of this set_value call */
383   priv->ignore_slider = TRUE;
384   if (size < gtk_adjustment_get_lower (slider_adj))
385     gtk_adjustment_set_value (slider_adj, gtk_adjustment_get_lower (slider_adj));
386   else if (size > gtk_adjustment_get_upper (slider_adj))
387     gtk_adjustment_set_value (slider_adj, gtk_adjustment_get_upper (slider_adj));
388   else
389     gtk_adjustment_set_value (slider_adj, size);
390
391   priv->size = ((gint)gtk_adjustment_get_value (adjustment)) * PANGO_SCALE;
392
393   desc = pango_context_get_font_description (gtk_widget_get_pango_context (priv->preview));
394   pango_font_description_set_size (desc, priv->size);
395   gtk_widget_override_font (priv->preview, desc);
396
397   priv->ignore_size = TRUE;
398   update_size_list_selection (fontsel);
399   
400   gtk_widget_queue_draw (priv->preview);
401 }
402
403 void
404 set_range_marks (GtkFontSelectionPrivate *priv,
405                  GtkWidget* size_slider,
406                  gint* sizes,
407                  gint length)
408 {
409   GtkAdjustment *adj;
410   gint i;
411   gdouble value;
412   
413   if (length<2)
414     {
415       sizes = (gint*)font_sizes;
416       length = FONT_SIZES_LENGTH;
417     }
418   
419   gtk_scale_clear_marks (GTK_SCALE (size_slider));
420   
421   adj = gtk_range_get_adjustment(GTK_RANGE (size_slider));
422   
423   gtk_adjustment_set_lower (adj, (gdouble) sizes[0]);
424   gtk_adjustment_set_upper (adj, (gdouble) sizes[length-1]);
425
426   value = gtk_adjustment_get_value (adj);
427   if (value > (gdouble) sizes[length-1])
428     {
429       gtk_adjustment_set_value (adj, (gdouble) sizes[length-1]);
430       priv->ignore_slider = TRUE;
431     }
432   else if (value < (gdouble) sizes[0])
433     {
434       gtk_adjustment_set_value (adj, (gdouble) sizes[0]);
435       priv->ignore_slider = TRUE; 
436     }
437   
438 #ifndef GTK_DISABLE_DEPRECATED
439   if (!priv->_size_model)
440     {
441       for (i=0; i<length; i++)
442         gtk_scale_add_mark (GTK_SCALE (size_slider),
443                             (gdouble) sizes[i],
444                             GTK_POS_BOTTOM, NULL);
445     }
446   else
447     {
448       GString *size_str = g_string_new (NULL);
449       gtk_list_store_clear (priv->_size_model);
450       
451       for (i=0; i<length; i++)
452         {
453           GtkTreeIter iter;
454
455           g_string_printf (size_str, "%d", sizes[i]);
456
457           gtk_scale_add_mark (GTK_SCALE (size_slider),
458                               (gdouble) sizes[i],
459                               GTK_POS_BOTTOM, NULL);
460
461           gtk_list_store_append (priv->_size_model, &iter);
462           gtk_list_store_set (priv->_size_model, &iter,
463                               0, sizes[i],
464                               1, size_str->str,
465                               -1);
466         }
467       g_string_free (size_str, TRUE);
468     }
469 #else
470   for (i=0; i<length; i++)
471     gtk_scale_add_mark (GTK_SCALE (size_slider),
472                         (gdouble) sizes[i],
473                         GTK_POS_BOTTOM, NULL);
474 #endif
475 }
476
477 void
478 cursor_changed_cb (GtkTreeView *treeview, gpointer data)
479 {
480   PangoFontFamily      *family;
481   PangoFontFace        *face;
482   PangoFontDescription *desc;
483   
484   gint *sizes;
485   gint  i, n_sizes;
486
487   GtkTreeIter iter;
488   GtkTreePath *path = gtk_tree_path_new ();
489   
490   GtkFontSelection *fontsel = (GtkFontSelection*)data;
491   
492   gtk_tree_view_get_cursor (treeview, &path, NULL);
493   
494   if (!path)
495     return;
496
497   if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (fontsel->priv->filter), &iter, path))
498     {
499       gtk_tree_path_free (path);
500       return;
501     } 
502   
503   
504   gtk_tree_model_get (GTK_TREE_MODEL (fontsel->priv->filter), &iter,
505                       FACE_COLUMN, &face,
506                       FAMILY_COLUMN, &family,
507                       -1);
508
509   gtk_tree_view_scroll_to_cell (treeview, path, NULL, FALSE, 0.0, 0.0);
510
511   gtk_tree_path_free (path);
512   path = NULL;
513   
514   if (!face || !family)
515     {
516       g_object_unref (face);
517       g_object_unref (family);
518       return;
519     }
520
521   desc = pango_font_face_describe (face);
522   pango_font_description_set_size (desc, fontsel->priv->size);
523   gtk_widget_override_font (fontsel->priv->preview, desc);
524
525   pango_font_face_list_sizes (face, &sizes, &n_sizes);
526   /* It seems not many fonts actually have a sane set of sizes */
527   for (i=0; i<n_sizes; i++)
528     sizes[i] = sizes[i] / PANGO_SCALE;
529   
530   set_range_marks (fontsel->priv, fontsel->priv->size_slider, sizes, n_sizes);
531
532   gtk_font_selection_ref_family (fontsel, family);
533   gtk_font_selection_ref_face   (fontsel, face);
534
535 #ifndef GTK_DISABLE_DEPRECATED
536   if (fontsel->priv->_font_model)
537     update_font_list_selection (fontsel);
538 #endif
539
540   /* Free resources */
541   g_object_unref ((gpointer)family);
542   g_object_unref ((gpointer)face);
543   pango_font_description_free(desc);
544 }
545
546 gboolean
547 zoom_preview_cb (GtkWidget *scrolled_window, GdkEventScroll *event, gpointer data)
548 {
549   GtkFontSelectionPrivate *priv = (GtkFontSelectionPrivate*)data;
550
551   GtkAdjustment *adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->size_spin));
552
553   if (event->direction == GDK_SCROLL_UP || event->direction == GDK_SCROLL_RIGHT)
554     gtk_adjustment_set_value (adj,
555                               gtk_adjustment_get_value (adj) +
556                               gtk_adjustment_get_step_increment (adj));
557   else if (event->direction == GDK_SCROLL_DOWN || event->direction == GDK_SCROLL_LEFT)
558     gtk_adjustment_set_value (adj,
559                               gtk_adjustment_get_value (adj) -
560                               gtk_adjustment_get_step_increment (adj));
561   return TRUE;
562 }
563
564 static void
565 gtk_font_selection_init (GtkFontSelection *fontsel)
566 {
567   GtkFontSelectionPrivate *priv;
568   PangoFontDescription    *font_desc;
569   GtkWidget               *scrolled_win;
570   GtkWidget               *preview_and_size;
571   GtkWidget               *size_controls;
572
573   fontsel->priv = G_TYPE_INSTANCE_GET_PRIVATE (fontsel,
574                                                GTK_TYPE_FONT_SELECTION,
575                                                GtkFontSelectionPrivate);
576
577   priv = fontsel->priv;
578
579 #ifndef GTK_DISABLE_DEPRECATED
580   priv->size_list = NULL;
581   priv->font_list = NULL;
582   priv->face_list = NULL;
583
584   priv->_size_model = NULL;
585   priv->_font_model = NULL;
586   priv->_face_model = NULL;
587
588   priv->ignore_size = FALSE;
589   priv->ignore_face = FALSE;
590   priv->ignore_font = FALSE;
591 #endif /* GTK_DISABLE_DEPRECATED */
592
593   /* Getting the default size */
594   font_desc  = pango_context_get_font_description (gtk_widget_get_pango_context (GTK_WIDGET (fontsel)));
595   priv->size = pango_font_description_get_size (font_desc);
596   priv->face = NULL;
597   priv->family = NULL;
598
599   gtk_widget_push_composite_child ();
600
601   /* Creating fundamental widgets for the private struct */
602   priv->search_entry = gtk_entry_new ();
603   priv->family_face_list = gtk_tree_view_new ();
604   priv->preview = gtk_entry_new ();
605   priv->size_slider = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL,
606                                                 (gdouble) font_sizes[0],
607                                                 (gdouble) font_sizes[FONT_SIZES_LENGTH - 1],
608                                                 1.0);
609
610   priv->size_spin = gtk_spin_button_new_with_range (0.0, (gdouble)(G_MAXINT / PANGO_SCALE), 1.0);
611
612   /** Bootstrapping widget layout **/
613   gtk_box_set_spacing (GTK_BOX (fontsel), 6);
614   gtk_box_pack_start (GTK_BOX (fontsel), priv->search_entry, FALSE, TRUE, 0);
615
616   /* Main font family/face view */
617   scrolled_win = gtk_scrolled_window_new (NULL, NULL);
618   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
619                                   GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
620   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win),
621                                        GTK_SHADOW_ETCHED_IN);
622   gtk_container_add (GTK_CONTAINER (scrolled_win), priv->family_face_list);
623
624   /* Alignment for the preview and size controls */
625   gtk_box_pack_start (GTK_BOX (fontsel), scrolled_win, TRUE, TRUE, 0);
626
627   preview_and_size = gtk_vbox_new (TRUE, 0);
628   gtk_box_set_homogeneous (GTK_BOX (preview_and_size), FALSE);
629   gtk_box_set_spacing (GTK_BOX (preview_and_size), 6);
630
631   /* The preview entry needs a scrolled window to make sure we have a */
632   scrolled_win = gtk_scrolled_window_new (NULL, NULL);
633   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
634                                   GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
635   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win),
636                                        GTK_SHADOW_ETCHED_IN);
637   gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_win),
638                                          priv->preview);
639   gtk_box_pack_start (GTK_BOX (preview_and_size), scrolled_win, FALSE, FALSE, 0);
640   
641   /* Setting the size requests for various widgets */
642   gtk_widget_set_size_request (GTK_WIDGET (fontsel), FONTSEL_WIDTH, FONTSEL_HEIGHT);
643   gtk_widget_set_size_request (scrolled_win,  -1, PREVIEW_HEIGHT);
644   gtk_widget_set_size_request (priv->preview, -1, PREVIEW_HEIGHT - 6);
645
646   /* Unset the frame on the preview entry */
647   gtk_entry_set_has_frame (GTK_ENTRY (priv->preview), FALSE);
648
649   /* Packing the slider and the spin in a hbox */
650   size_controls = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
651   gtk_scale_set_draw_value (GTK_SCALE (priv->size_slider), FALSE);
652   gtk_box_set_spacing (GTK_BOX (size_controls), 6);
653   gtk_box_pack_start  (GTK_BOX (size_controls), priv->size_slider, TRUE, TRUE, 0);
654   gtk_box_pack_start  (GTK_BOX (size_controls), priv->size_spin, FALSE, TRUE, 0);
655   
656   gtk_widget_set_valign (priv->size_spin, GTK_ALIGN_START);
657
658   gtk_box_pack_start (GTK_BOX (preview_and_size), size_controls, FALSE, FALSE, 0);
659
660   gtk_box_pack_start (GTK_BOX (fontsel), GTK_WIDGET(preview_and_size), FALSE, TRUE, 0);
661   
662   gtk_adjustment_set_value (gtk_range_get_adjustment (GTK_RANGE (priv->size_slider)),
663                             (gdouble)(priv->size / PANGO_SCALE));
664   gtk_adjustment_set_value (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->size_spin)),
665                             (gdouble)(priv->size / PANGO_SCALE));
666
667   gtk_widget_show_all (GTK_WIDGET (fontsel));
668   gtk_widget_hide (GTK_WIDGET (fontsel));
669
670   /* Treeview column and model bootstrapping */
671   gtk_font_selection_bootstrap_fontlist (fontsel);
672   
673   /* Set default preview text */
674   gtk_entry_set_text (GTK_ENTRY (priv->preview),
675                       pango_language_get_sample_string (NULL));
676   
677   /* Set search icon and place holder text */
678   gtk_entry_set_icon_from_stock (GTK_ENTRY (priv->search_entry),
679                                  GTK_ENTRY_ICON_SECONDARY,
680                                  GTK_STOCK_FIND);
681   gtk_entry_set_placeholder_text (GTK_ENTRY (priv->search_entry), _("Search font name"));
682   
683   /** Callback connections **/
684   /* Connect to callback for the live search text entry */
685   g_signal_connect (G_OBJECT (gtk_entry_get_buffer (GTK_ENTRY (priv->search_entry))),
686                     "deleted-text", G_CALLBACK (deleted_text_cb), priv);
687   g_signal_connect (G_OBJECT (gtk_entry_get_buffer (GTK_ENTRY (priv->search_entry))),
688                     "inserted-text", G_CALLBACK (inserted_text_cb), priv);
689   g_signal_connect (G_OBJECT (priv->search_entry),
690                     "icon-press", G_CALLBACK (icon_press_cb), priv);
691
692   /* Size controls callbacks */
693   g_signal_connect (G_OBJECT (gtk_range_get_adjustment (GTK_RANGE (priv->size_slider))),
694                     "value-changed", G_CALLBACK (slider_change_cb), priv);
695   g_signal_connect (G_OBJECT (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->size_spin))),
696                     "value-changed", G_CALLBACK (spin_change_cb), fontsel);
697   priv->ignore_slider = FALSE;
698   
699   /* Font selection callback */
700   g_signal_connect (G_OBJECT (priv->family_face_list), "cursor-changed",
701                     G_CALLBACK (cursor_changed_cb),    fontsel);
702
703   /* Zoom on preview scroll*/
704   g_signal_connect (G_OBJECT (scrolled_win),      "scroll-event",
705                     G_CALLBACK (zoom_preview_cb), priv);
706
707   g_signal_connect (G_OBJECT (priv->size_slider), "scroll-event",
708                     G_CALLBACK (zoom_preview_cb), priv);
709
710   set_range_marks (priv, priv->size_slider, (gint*)font_sizes, FONT_SIZES_LENGTH);
711
712   /* Set default focus */
713   gtk_widget_pop_composite_child();
714 }
715
716 /**
717  * gtk_font_selection_new:
718  *
719  * Creates a new #GtkFontSelection.
720  *
721  * Return value: a new #GtkFontSelection
722  */
723 GtkWidget *
724 gtk_font_selection_new (void)
725 {
726   GtkFontSelection *fontsel;
727   
728   fontsel = g_object_new (GTK_TYPE_FONT_SELECTION, NULL);
729   
730   return GTK_WIDGET (fontsel);
731 }
732
733 static int
734 cmp_families (const void *a, const void *b)
735 {
736   const char *a_name = pango_font_family_get_name (*(PangoFontFamily **)a);
737   const char *b_name = pango_font_family_get_name (*(PangoFontFamily **)b);
738
739   return g_utf8_collate (a_name, b_name);
740 }
741
742 static void 
743 populate_list (GtkTreeView* treeview, GtkListStore* model)
744 {
745   GtkStyleContext      *style_context;
746   GdkRGBA               g_color;
747   PangoColor            p_color;
748   gchar                *color_string;
749   PangoFontDescription *default_font;
750
751   GtkTreeIter   match_row;
752   GtkTreePath  *path;
753
754   gint n_families, i;  
755   PangoFontFamily **families;
756
757   GString     *tmp = g_string_new (NULL);
758   GString     *family_and_face = g_string_new (NULL);
759
760   pango_context_list_families (gtk_widget_get_pango_context (GTK_WIDGET (treeview)),
761                                &families,
762                                &n_families);
763
764   qsort (families, n_families, sizeof (PangoFontFamily *), cmp_families);
765
766   gtk_list_store_clear (model);
767
768   /* Get row header font color */
769   style_context = gtk_widget_get_style_context (GTK_WIDGET (treeview));
770   gtk_style_context_get_color (style_context,
771                                GTK_STATE_FLAG_NORMAL | GTK_STATE_FLAG_INSENSITIVE,
772                                &g_color);
773
774   p_color.red   = (guint16)((gdouble)G_MAXUINT16 * g_color.red);
775   p_color.green = (guint16)((gdouble)G_MAXUINT16 * g_color.green);
776   p_color.blue  = (guint16)((gdouble)G_MAXUINT16 * g_color.blue);
777   color_string  = pango_color_to_string (&p_color);
778
779   /* Get theme font */
780   default_font  = (PangoFontDescription*) gtk_style_context_get_font (style_context,
781                                                                       GTK_STATE_NORMAL);
782
783   /* Iterate over families and faces */
784   for (i=0; i<n_families; i++)
785     {
786       GtkTreeIter     iter;
787       PangoFontFace **faces;
788       
789       int             j, n_faces;
790       const gchar    *fam_name = pango_font_family_get_name (families[i]);
791
792       pango_font_family_list_faces (families[i], &faces, &n_faces);
793       
794       for (j=0; j<n_faces; j++)
795         {
796           PangoFontDescription *pango_desc = pango_font_face_describe (faces[j]);
797           const gchar *face_name = pango_font_face_get_face_name (faces[j]);
798           gchar       *font_desc = pango_font_description_to_string (pango_desc);
799           
800           /* foreground_color, family_name, face_name, desc, sample string */
801           g_string_printf (family_and_face, "%s %s",
802                                             fam_name,
803                                             face_name);
804           
805           g_string_printf (tmp, ROW_FORMAT_STRING,
806                                 color_string,
807                                 family_and_face->str,
808                                 font_desc,
809                                 pango_language_get_sample_string (NULL));
810
811           gtk_list_store_append (model, &iter);
812           gtk_list_store_set (model, &iter,
813                               FAMILY_COLUMN, families[i],
814                               FACE_COLUMN, faces[j],
815                               PREVIEW_TITLE_COLUMN, family_and_face->str,
816                               PREVIEW_TEXT_COLUMN, tmp->str,
817                               -1);
818
819           /* Select the first font or the default font/face from the style context */
820           if ((i == 0 && j == 0) ||
821               (!strcmp (fam_name, pango_font_description_get_family (default_font)) && j == 0))
822             match_row = iter;
823
824           pango_font_description_free(pango_desc);
825           g_free (font_desc);
826         }
827
828       g_free (faces);
829     }
830
831   path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &match_row);
832
833   if (path)
834   {
835     gtk_tree_view_set_cursor (treeview, path, NULL, FALSE);
836     gtk_tree_view_scroll_to_cell (treeview, path, NULL, FALSE, 0.0, 0.0);
837     gtk_tree_path_free(path);
838   }
839
840   g_string_free (family_and_face, TRUE);
841   g_string_free (tmp, TRUE);
842   g_free (color_string);
843   g_free (families);
844 }
845
846 gboolean
847 visible_func (GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
848 {
849   gboolean result = FALSE;
850   GtkFontSelectionPrivate *priv = (GtkFontSelectionPrivate*) data;
851
852   const gchar *search_text = (const gchar*)gtk_entry_get_text (GTK_ENTRY (priv->search_entry));
853   gchar       *font_name;
854   gchar       *font_name_casefold;
855   gchar       *search_text_casefold;
856
857   gtk_tree_model_get (model, iter,
858                       PREVIEW_TITLE_COLUMN, &font_name,
859                       -1);
860
861   /* Covering some corner cases to speed up the result */
862   if (font_name == NULL ||
863       strlen (search_text) > strlen (font_name))
864     {
865       g_free (font_name);
866       return FALSE;
867     }  
868   if (strlen (search_text) == 0)
869     {
870       g_free (font_name);
871       return TRUE;
872     }
873   
874   font_name_casefold = g_utf8_casefold (font_name, -1);
875   search_text_casefold = g_utf8_casefold (search_text, -1);
876   
877   if (g_strrstr (font_name_casefold, search_text_casefold))
878     result = TRUE;
879
880   g_free (search_text_casefold);
881   g_free (font_name_casefold);
882   g_free (font_name);
883   return result;
884 }
885
886 static void
887 gtk_font_selection_bootstrap_fontlist (GtkFontSelection* fontsel)
888 {
889   GtkTreeView       *treeview = GTK_TREE_VIEW (fontsel->priv->family_face_list);
890   GtkCellRenderer   *cell;
891   GtkTreeViewColumn *col;
892
893   fontsel->priv->model = gtk_list_store_new (4,
894                                              PANGO_TYPE_FONT_FAMILY,
895                                              PANGO_TYPE_FONT_FACE,
896                                              G_TYPE_STRING,
897                                              G_TYPE_STRING);
898
899   fontsel->priv->filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fontsel->priv->model),
900                                                      NULL);
901   g_object_unref (fontsel->priv->model);
902
903   gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (fontsel->priv->filter),
904                                           visible_func,
905                                           (gpointer)fontsel->priv,
906                                           NULL);
907
908   gtk_tree_view_set_model (treeview, GTK_TREE_MODEL (fontsel->priv->filter));
909   g_object_unref (fontsel->priv->filter);
910
911   gtk_tree_view_set_rules_hint      (treeview, TRUE);
912   gtk_tree_view_set_headers_visible (treeview, FALSE);
913
914   cell = gtk_cell_renderer_text_new ();
915   col = gtk_tree_view_column_new_with_attributes ("Family",
916                                                   cell,
917                                                   "markup", PREVIEW_TEXT_COLUMN,
918                                                   NULL);
919                                                   
920   g_object_set (cell, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
921
922   gtk_tree_view_append_column (treeview, col);
923
924   populate_list (treeview, fontsel->priv->model);
925 }
926
927
928 static void
929 gtk_font_selection_finalize (GObject *object)
930 {
931   GtkFontSelection *fontsel = GTK_FONT_SELECTION (object);
932
933   gtk_font_selection_ref_family (fontsel, NULL);
934   gtk_font_selection_ref_face (fontsel, NULL);
935
936 #ifndef GTK_DISABLE_DEPRECATED
937   if (fontsel->priv->size_list)
938     {
939       g_object_unref (fontsel->priv->size_list);
940       g_object_unref (fontsel->priv->font_list);
941       g_object_unref (fontsel->priv->face_list);
942     }
943 #endif
944
945   G_OBJECT_CLASS (gtk_font_selection_parent_class)->finalize (object);
946 }
947
948 #if 0
949 static void
950 gtk_font_selection_screen_changed (GtkWidget *widget,
951                                    GdkScreen *previous_screen)
952 {
953   return;
954 }
955
956 static void
957 gtk_font_selection_style_updated (GtkWidget *widget)
958 {
959   /*GTK_WIDGET_CLASS (gtk_font_selection_parent_class)->style_updated (widget);*/
960   return;
961 }
962 #endif 
963
964 static void
965 gtk_font_selection_ref_family (GtkFontSelection *fontsel,
966                                PangoFontFamily  *family)
967 {
968   GtkFontSelectionPrivate *priv = fontsel->priv;
969
970   if (family)
971     family = g_object_ref (family);
972   if (priv->family)
973     g_object_unref (priv->family);
974   priv->family = family;
975 }
976
977 static void
978 gtk_font_selection_ref_face (GtkFontSelection *fontsel,
979                              PangoFontFace    *face)
980 {
981   GtkFontSelectionPrivate *priv = fontsel->priv;
982
983   if (face)
984     face = g_object_ref (face);
985   if (priv->face)
986     g_object_unref (priv->face);
987   priv->face = face;
988 }
989
990 #ifndef GTK_DISABLE_DEPRECATED
991 static void
992 populate_font_model (GtkFontSelection *fontsel)
993 {
994   gint                      n_families, i;
995   PangoFontFamily         **families;
996   GtkFontSelectionPrivate  *priv = fontsel->priv;
997   GtkTreePath              *path;
998
999   pango_context_list_families (gtk_widget_get_pango_context (GTK_WIDGET (fontsel)),
1000                                &families,
1001                                &n_families);
1002
1003   qsort (families, n_families, sizeof (PangoFontFamily *), cmp_families);
1004
1005   gtk_list_store_clear (priv->_font_model);
1006   
1007   for (i=0; i<n_families; i++)
1008     {
1009       GtkTreeIter  iter;
1010
1011       gtk_list_store_append (priv->_font_model, &iter);
1012       gtk_list_store_set (priv->_font_model, &iter,
1013                           0, families[i],
1014                           1, pango_font_family_get_name (families[i]),
1015                           -1);
1016       if (priv->family &&
1017           !strcmp (pango_font_family_get_name (families[i]),
1018                    pango_font_family_get_name (priv->family)))
1019         {
1020           path = gtk_tree_model_get_path (GTK_TREE_MODEL (priv->_face_model),
1021                                           &iter);
1022           if (path)
1023             {
1024               GtkWidget *tv = gtk_bin_get_child (GTK_BIN (priv->font_list));
1025               gtk_tree_view_set_cursor (GTK_TREE_VIEW (tv),
1026                                         path,
1027                                         NULL,
1028                                         FALSE);
1029               gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (tv),
1030                                             path, NULL, FALSE, 0.0, 0.0);
1031               gtk_tree_path_free (path);
1032             }
1033         }
1034     }
1035
1036   g_free (families);
1037 }
1038
1039 static void
1040 update_font_list_selection (GtkFontSelection *fontsel)
1041 {
1042   GtkTreeIter              iter;
1043   gboolean                 valid;
1044   GtkFontSelectionPrivate *priv = fontsel->priv;
1045   gchar                   *family_name;
1046
1047   valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->_font_model), &iter);
1048   while (valid)
1049     {
1050       GtkWidget   *tv;
1051       GtkTreePath *path;
1052       gtk_tree_model_get (GTK_TREE_MODEL (priv->_font_model), &iter,
1053                           1, &family_name,
1054                           -1);
1055       if (strcmp (family_name, pango_font_family_get_name (priv->family)))
1056         {
1057           gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->_font_model), &iter);
1058           g_free (family_name);
1059           continue;
1060         }
1061       path = gtk_tree_model_get_path (GTK_TREE_MODEL (priv->_font_model), &iter);
1062
1063       if (!path)
1064         {
1065           g_free (family_name);
1066           break;
1067         }
1068
1069       tv = gtk_bin_get_child (GTK_BIN (priv->font_list));
1070
1071       priv->ignore_font = TRUE;
1072       gtk_tree_view_set_cursor (GTK_TREE_VIEW (tv), path, NULL, FALSE);
1073       gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (tv), path, NULL, FALSE, 0.0, 0.0);
1074
1075       /* Free resources */
1076       gtk_tree_path_free (path);
1077       g_free (family_name);
1078       break;
1079     }
1080
1081   update_face_model (fontsel, FALSE);
1082 }
1083
1084 static void
1085 update_face_model (GtkFontSelection *fontsel, gboolean first)
1086 {
1087   GtkFontSelectionPrivate  *priv = fontsel->priv;
1088   PangoFontFace           **faces;
1089   int                       i, n_faces;
1090
1091   pango_font_family_list_faces (priv->family, &faces, &n_faces);
1092
1093   gtk_list_store_clear (priv->_face_model);
1094
1095   for (i=0; i<n_faces; i++)
1096     {
1097       GtkTreeIter  iter;
1098
1099       gtk_list_store_append (priv->_face_model, &iter);
1100       gtk_list_store_set (priv->_face_model, &iter,
1101                           0, faces[i],
1102                           1, pango_font_face_get_face_name (faces[i]),
1103                           -1);
1104
1105       if (!first && faces[i] == priv->face ||
1106           first && i == 0)
1107         {
1108           GtkTreePath *path;
1109           GtkWidget *tv;
1110
1111           path = gtk_tree_model_get_path (GTK_TREE_MODEL (priv->_face_model), &iter);
1112           if (!path)
1113             continue;
1114
1115           tv = gtk_bin_get_child (GTK_BIN (priv->face_list));
1116
1117           if (!first)
1118             priv->ignore_face = TRUE;
1119
1120           gtk_tree_view_set_cursor (GTK_TREE_VIEW (tv), path, NULL, FALSE);
1121
1122           gtk_tree_path_free (path);
1123
1124           if (first)
1125             gtk_font_selection_ref_face (fontsel, faces[i]);
1126         }
1127     }
1128   update_size_list_selection (fontsel);
1129   g_free (faces);
1130 }
1131
1132 static void
1133 update_size_list_selection (GtkFontSelection *fontsel)
1134 {
1135   GtkTreeIter              iter;
1136   gboolean                 valid;
1137   GtkFontSelectionPrivate *priv = fontsel->priv;
1138   gchar                   *family_name;
1139   GtkWidget               *tv = gtk_bin_get_child (GTK_BIN (priv->size_list));
1140
1141   gtk_tree_selection_unselect_all (gtk_tree_view_get_selection (tv));
1142
1143   valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->_size_model), &iter);
1144   while (valid)
1145     {
1146       gint         size;
1147       gtk_tree_model_get (GTK_TREE_MODEL (priv->_size_model), &iter,
1148                           0, &size,
1149                           -1);
1150
1151       if (size * PANGO_SCALE == priv->size)
1152         {
1153           GtkTreePath *path;
1154
1155
1156           path = gtk_tree_model_get_path (GTK_TREE_MODEL (priv->_size_model), &iter);
1157           if (!path)
1158             break;
1159
1160  
1161           priv->ignore_size = TRUE;
1162           gtk_tree_view_set_cursor (GTK_TREE_VIEW (tv), path, NULL, FALSE);
1163
1164           gtk_tree_path_free (path);
1165           break;
1166         }
1167       valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->_size_model), &iter);
1168     }
1169 }
1170
1171
1172 static void
1173 select_family_and_face (GtkFontSelection *fontsel)
1174 {
1175   GtkTreeIter              iter;
1176   gboolean                 valid;
1177   GtkFontSelectionPrivate *priv = fontsel->priv;
1178   PangoFontFace           *face;
1179   PangoFontFamily         *family;
1180
1181   gtk_entry_set_text (priv->search_entry, "");
1182
1183   valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->filter), &iter);
1184   while (valid)
1185     {
1186       gint         size;
1187       gtk_tree_model_get (GTK_TREE_MODEL (priv->filter), &iter,
1188                           FACE_COLUMN,   &face,
1189                           FAMILY_COLUMN, &family, 
1190                           -1);
1191
1192       if (face == priv->face && family == priv->family)
1193         {
1194           GtkTreePath *path;
1195
1196           path = gtk_tree_model_get_path (GTK_TREE_MODEL (priv->filter), &iter);
1197           if (!path)
1198           {
1199             g_object_unref (face);
1200             g_object_unref (family);
1201             break;
1202           }
1203
1204           priv->ignore_size = TRUE;
1205           gtk_tree_view_set_cursor (GTK_TREE_VIEW (priv->family_face_list), path, NULL, FALSE);
1206
1207           gtk_tree_path_free (path);
1208           g_object_unref (face);
1209           g_object_unref (family);
1210           break;
1211         }
1212
1213       g_object_unref (face);
1214       g_object_unref (family);
1215       valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->filter), &iter);
1216     }
1217 }
1218
1219
1220 static void
1221 family_list_cursor_changed_cb (GtkTreeView *treeview, gpointer data)
1222 {
1223   GtkWidget        *tv;
1224   GtkTreeIter       iter;
1225   GtkTreePath      *path;
1226   GtkFontSelection *fontsel = (GtkFontSelection*)data;
1227   PangoFontFamily  *font;
1228
1229   if (fontsel->priv->ignore_font)
1230     {
1231       fontsel->priv->ignore_font = FALSE;
1232       return;
1233     }
1234
1235   tv = gtk_bin_get_child (GTK_BIN (fontsel->priv->font_list));
1236   gtk_tree_view_get_cursor (GTK_TREE_VIEW (tv), &path, NULL);
1237
1238   if (!path)
1239     return;
1240
1241   gtk_tree_model_get_iter (GTK_TREE_MODEL (fontsel->priv->_font_model),
1242                            &iter,
1243                            path);
1244   
1245   gtk_tree_model_get (GTK_TREE_MODEL (fontsel->priv->_font_model), &iter,
1246                       0, &font,
1247                       -1);
1248
1249   gtk_font_selection_ref_family (fontsel, font);
1250   update_face_model (fontsel, TRUE);
1251
1252   fontsel->priv->ignore_font = TRUE;
1253   select_family_and_face (fontsel);
1254
1255   gtk_tree_path_free (path);
1256   g_object_unref (font);
1257 }
1258
1259 static void
1260 face_list_cursor_changed_cb (GtkTreeView *treeview, gpointer data)
1261 {
1262   GtkWidget        *tv;
1263   GtkTreeIter       iter;
1264   GtkTreePath      *path;
1265   GtkFontSelection *fontsel = (GtkFontSelection*)data;
1266   PangoFontFace    *face;
1267
1268   if (fontsel->priv->ignore_face)
1269     {
1270       fontsel->priv->ignore_face = FALSE;
1271       return;
1272     }
1273
1274   tv = gtk_bin_get_child (GTK_BIN (fontsel->priv->face_list));
1275   gtk_tree_view_get_cursor (GTK_TREE_VIEW (tv), &path, NULL);
1276
1277   if (!path)
1278     return;
1279
1280   gtk_tree_model_get_iter (GTK_TREE_MODEL (fontsel->priv->_face_model),
1281                            &iter,
1282                            path);
1283   
1284   gtk_tree_model_get (GTK_TREE_MODEL (fontsel->priv->_face_model), &iter,
1285                       0, &face,
1286                       -1);
1287
1288   gtk_font_selection_ref_face (fontsel, face);
1289
1290   fontsel->priv->ignore_face = TRUE;
1291   select_family_and_face (fontsel);
1292
1293   gtk_tree_path_free (path);
1294   g_object_unref (face);
1295 }
1296
1297 static void
1298 size_list_cursor_changed_cb (GtkTreeView *treeview, gpointer data)
1299 {
1300   GtkWidget        *tv;
1301   GtkTreeIter       iter;
1302   GtkTreePath      *path;
1303   GtkFontSelection *fontsel = (GtkFontSelection*)data;
1304   gint              value;
1305
1306   if (fontsel->priv->ignore_size)
1307     {
1308       fontsel->priv->ignore_size = FALSE;
1309       return;
1310     }
1311
1312   tv = gtk_bin_get_child (GTK_BIN (fontsel->priv->size_list));
1313   gtk_tree_view_get_cursor (GTK_TREE_VIEW (tv), &path, NULL);
1314
1315   if (!path)
1316     return;
1317
1318   gtk_tree_model_get_iter (GTK_TREE_MODEL (fontsel->priv->_size_model),
1319                            &iter,
1320                            path);
1321   
1322   gtk_tree_model_get (GTK_TREE_MODEL (fontsel->priv->_size_model), &iter,
1323                       0, &value,
1324                       -1);
1325
1326   gtk_spin_button_set_value (fontsel->priv->size_spin, value);
1327   gtk_tree_path_free (path);
1328 }
1329
1330 static void
1331 initialize_deprecated_widgets (GtkFontSelection *fontsel)
1332 {
1333   GtkTreeViewColumn       *col;
1334   GtkCellRenderer         *cell;
1335   GtkFontSelectionPrivate *priv = fontsel->priv;
1336
1337   GtkWidget *size_list;
1338   GtkWidget *font_list;
1339   GtkWidget *face_list;
1340
1341   priv->_size_model = gtk_list_store_new (2, G_TYPE_INT, G_TYPE_STRING);
1342   priv->_font_model = gtk_list_store_new (2, PANGO_TYPE_FONT_FAMILY, G_TYPE_STRING);
1343   priv->_face_model = gtk_list_store_new (2, PANGO_TYPE_FONT_FACE,   G_TYPE_STRING);
1344
1345   size_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (priv->_size_model));
1346   font_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (priv->_font_model));
1347   face_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (priv->_face_model));
1348
1349   g_object_unref (priv->_size_model);
1350   g_object_unref (priv->_font_model);
1351   g_object_unref (priv->_face_model);
1352
1353   col = gtk_tree_view_column_new_with_attributes ("Size",
1354                                                   gtk_cell_renderer_text_new (),
1355                                                   "text", 1,
1356                                                   NULL);
1357   gtk_tree_view_append_column (GTK_TREE_VIEW (size_list), col);
1358
1359   col = gtk_tree_view_column_new_with_attributes ("Family",
1360                                                   gtk_cell_renderer_text_new (),
1361                                                   "text", 1,
1362                                                   NULL);
1363   gtk_tree_view_append_column (GTK_TREE_VIEW (font_list), col);
1364
1365   col = gtk_tree_view_column_new_with_attributes ("Face",
1366                                                   gtk_cell_renderer_text_new (),
1367                                                   "text", 1,
1368                                                   NULL);
1369   gtk_tree_view_append_column (GTK_TREE_VIEW (face_list), col);
1370
1371
1372   priv->font_list = gtk_scrolled_window_new (NULL, NULL);
1373   priv->face_list = gtk_scrolled_window_new (NULL, NULL);
1374   priv->size_list = gtk_scrolled_window_new (NULL, NULL);
1375
1376   gtk_container_add (GTK_CONTAINER (priv->font_list), font_list);
1377   gtk_container_add (GTK_CONTAINER (priv->face_list), face_list);
1378   gtk_container_add (GTK_CONTAINER (priv->size_list), size_list);
1379
1380   g_signal_connect (G_OBJECT (font_list), "cursor-changed",
1381                     G_CALLBACK (family_list_cursor_changed_cb), fontsel);
1382
1383   g_signal_connect (G_OBJECT (face_list), "cursor-changed",
1384                     G_CALLBACK (face_list_cursor_changed_cb), fontsel);
1385
1386   g_signal_connect (G_OBJECT (size_list), "cursor-changed",
1387                     G_CALLBACK (size_list_cursor_changed_cb), fontsel);
1388
1389   populate_font_model (fontsel);
1390   cursor_changed_cb (priv->family_face_list, priv);
1391 }
1392
1393 #endif /* GTK_DISABLE_DEPRECATED */
1394
1395 /*****************************************************************************
1396  * These functions are the main public interface for getting/setting the font.
1397  *****************************************************************************/
1398
1399 /**
1400  * gtk_font_selection_get_family:
1401  * @fontsel: a #GtkFontSelection
1402  *
1403  * Gets the #PangoFontFamily representing the selected font family.
1404  *
1405  * Return value: (transfer none): A #PangoFontFamily representing the
1406  *     selected font family. Font families are a collection of font
1407  *     faces. The returned object is owned by @fontsel and must not
1408  *     be modified or freed.
1409  *
1410  * Since: 2.14
1411  */
1412 PangoFontFamily *
1413 gtk_font_selection_get_family (GtkFontSelection *fontsel)
1414 {
1415   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1416
1417   return fontsel->priv->family;
1418 }
1419
1420 /**
1421  * gtk_font_selection_get_face:
1422  * @fontsel: a #GtkFontSelection
1423  *
1424  * Gets the #PangoFontFace representing the selected font group
1425  * details (i.e. family, slant, weight, width, etc).
1426  *
1427  * Return value: (transfer none): A #PangoFontFace representing the
1428  *     selected font group details. The returned object is owned by
1429  *     @fontsel and must not be modified or freed.
1430  *
1431  * Since: 2.14
1432  */
1433 PangoFontFace *
1434 gtk_font_selection_get_face (GtkFontSelection *fontsel)
1435 {
1436   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1437
1438   return fontsel->priv->face;
1439 }
1440
1441 /**
1442  * gtk_font_selection_get_size:
1443  * @fontsel: a #GtkFontSelection
1444  *
1445  * The selected font size.
1446  *
1447  * Return value: A n integer representing the selected font size,
1448  *     or -1 if no font size is selected.
1449  *
1450  * Since: 2.14
1451  **/
1452 gint
1453 gtk_font_selection_get_size (GtkFontSelection *fontsel)
1454 {
1455   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), -1);
1456
1457   return fontsel->priv->size;
1458 }
1459
1460 /**
1461  * gtk_font_selection_get_font_name:
1462  * @fontsel: a #GtkFontSelection
1463  * 
1464  * Gets the currently-selected font name. 
1465  *
1466  * Note that this can be a different string than what you set with 
1467  * gtk_font_selection_set_font_name(), as the font selection widget may 
1468  * normalize font names and thus return a string with a different structure. 
1469  * For example, "Helvetica Italic Bold 12" could be normalized to 
1470  * "Helvetica Bold Italic 12". Use pango_font_description_equal()
1471  * if you want to compare two font descriptions.
1472  * 
1473  * Return value: (transfer full) (allow-none): A string with the name of the
1474  *     current font, or %NULL if  no font is selected. You must free this
1475  *     string with g_free().
1476  */
1477 gchar *
1478 gtk_font_selection_get_font_name (GtkFontSelection *fontsel)
1479 {
1480   if (!fontsel->priv->family)
1481     return NULL;
1482
1483   return g_strdup (pango_font_family_get_name (fontsel->priv->family));
1484 }
1485
1486 /* This sets the current font, then selecting the appropriate list rows. */
1487
1488 /**
1489  * gtk_font_selection_set_font_name:
1490  * @fontsel: a #GtkFontSelection
1491  * @fontname: a font name like "Helvetica 12" or "Times Bold 18"
1492  * 
1493  * Sets the currently-selected font. 
1494  *
1495  * Note that the @fontsel needs to know the screen in which it will appear 
1496  * for this to work; this can be guaranteed by simply making sure that the 
1497  * @fontsel is inserted in a toplevel window before you call this function.
1498  * 
1499  * Return value: %TRUE if the font could be set successfully; %FALSE if no 
1500  *     such font exists or if the @fontsel doesn't belong to a particular 
1501  *     screen yet.
1502  */
1503 gboolean
1504 gtk_font_selection_set_font_name (GtkFontSelection *fontsel,
1505           const gchar      *fontname)
1506 {
1507 #if 0
1508   PangoFontFamily *family = NULL;
1509   PangoFontFace *face = NULL;
1510   PangoFontDescription *new_desc;
1511 #endif
1512
1513   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), FALSE);
1514
1515   return TRUE;
1516 }
1517
1518 /**
1519  * gtk_font_selection_get_preview_text:
1520  * @fontsel: a #GtkFontSelection
1521  *
1522  * Gets the text displayed in the preview area.
1523  * 
1524  * Return value: the text displayed in the preview area. 
1525  *     This string is owned by the widget and should not be 
1526  *     modified or freed 
1527  */
1528 G_CONST_RETURN gchar*
1529 gtk_font_selection_get_preview_text (GtkFontSelection *fontsel)
1530 {
1531   return NULL;
1532 }
1533
1534
1535 /**
1536  * gtk_font_selection_set_preview_text:
1537  * @fontsel: a #GtkFontSelection
1538  * @text: the text to display in the preview area 
1539  *
1540  * Sets the text displayed in the preview area.
1541  * The @text is used to show how the selected font looks.
1542  */
1543 void
1544 gtk_font_selection_set_preview_text  (GtkFontSelection *fontsel,
1545               const gchar      *text)
1546 {
1547 #if 0
1548   GtkFontSelectionPrivate *priv;
1549
1550   g_return_if_fail (GTK_IS_FONT_SELECTION (fontsel));
1551   g_return_if_fail (text != NULL);
1552
1553   priv = fontsel->priv;
1554 #endif
1555 }
1556
1557 #ifndef GTK_DISABLE_DEPRECATED
1558
1559 /**
1560  * gtk_font_selection_get_family_list:
1561  * @fontsel: a #GtkFontSelection
1562  *
1563  * This returns the #GtkTreeView that lists font families, for
1564  * example, 'Sans', 'Serif', etc.
1565  *
1566  * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1567  *
1568  * Deprecated: 3.2
1569  */
1570 GtkWidget *
1571 gtk_font_selection_get_family_list (GtkFontSelection *fontsel)
1572 {
1573   GtkFontSelectionPrivate *priv = fontsel->priv;
1574   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1575   if (!priv->font_list)
1576     initialize_deprecated_widgets (fontsel);
1577
1578   return priv->font_list;
1579 }
1580
1581 /**
1582  * gtk_font_selection_get_face_list:
1583  * @fontsel: a #GtkFontSelection
1584  *
1585  * This returns the #GtkTreeView which lists all styles available for
1586  * the selected font. For example, 'Regular', 'Bold', etc.
1587  * 
1588  * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1589  *
1590  * Deprecated: 3.2
1591  */
1592 GtkWidget *
1593 gtk_font_selection_get_face_list (GtkFontSelection *fontsel)
1594 {
1595   GtkFontSelectionPrivate *priv = fontsel->priv;
1596   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1597   if (!priv->face_list)
1598     initialize_deprecated_widgets (fontsel);
1599
1600   return priv->face_list;
1601 }
1602
1603 /**
1604  * gtk_font_selection_get_size_entry:
1605  * @fontsel: a #GtkFontSelection
1606  *
1607  * This returns the #GtkEntry used to allow the user to edit the font
1608  * number manually instead of selecting it from the list of font sizes.
1609  *
1610  * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1611  *
1612  * Deprecated: 3.2
1613  */
1614 GtkWidget *
1615 gtk_font_selection_get_size_entry (GtkFontSelection *fontsel)
1616 {
1617   GtkFontSelectionPrivate *priv = fontsel->priv;
1618   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1619
1620   return priv->size_spin;
1621 }
1622
1623 /**
1624  * gtk_font_selection_get_size_list:
1625  * @fontsel: a #GtkFontSelection
1626  *
1627  * This returns the #GtkTreeeView used to list font sizes.
1628  *
1629  * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1630  *
1631  * Deprecated: 3.2
1632  */
1633 GtkWidget *
1634 gtk_font_selection_get_size_list (GtkFontSelection *fontsel)
1635 {
1636   GtkFontSelectionPrivate *priv = fontsel->priv;
1637   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1638   if (!priv->size_list)
1639     initialize_deprecated_widgets (fontsel);
1640
1641   return priv->size_list;
1642 }
1643
1644 /**
1645  * gtk_font_selection_get_preview_entry:
1646  * @fontsel: a #GtkFontSelection
1647  *
1648  * This returns the #GtkEntry used to display the font as a preview.
1649  *
1650  * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1651  *
1652  * Deprecated: 3.2
1653  */
1654 GtkWidget *
1655 gtk_font_selection_get_preview_entry (GtkFontSelection *fontsel)
1656 {
1657   GtkFontSelectionPrivate *priv = fontsel->priv;
1658   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1659
1660   return priv->preview;
1661 }
1662
1663 #endif /* GTK_DISABLE_DEPRECATED */
1664
1665 /**
1666  * SECTION:gtkfontseldlg
1667  * @Short_description: A dialog box for selecting fonts
1668  * @Title: GtkFontSelectionDialog
1669  * @See_also: #GtkFontSelection, #GtkDialog
1670  *
1671  * The #GtkFontSelectionDialog widget is a dialog box for selecting a font.
1672  *
1673  * To set the font which is initially selected, use
1674  * gtk_font_selection_dialog_set_font_name().
1675  *
1676  * To get the selected font use gtk_font_selection_dialog_get_font_name().
1677  *
1678  * To change the text which is shown in the preview area, use
1679  * gtk_font_selection_dialog_set_preview_text().
1680  *
1681  * <refsect2 id="GtkFontSelectionDialog-BUILDER-UI">
1682  * <title>GtkFontSelectionDialog as GtkBuildable</title>
1683  * The GtkFontSelectionDialog implementation of the GtkBuildable interface
1684  * exposes the embedded #GtkFontSelection as internal child with the
1685  * name "font_selection". It also exposes the buttons with the names
1686  * "ok_button", "cancel_button" and "apply_button".
1687  * </refsect2>
1688  */
1689
1690 static void gtk_font_selection_dialog_buildable_interface_init     (GtkBuildableIface *iface);
1691 static GObject * gtk_font_selection_dialog_buildable_get_internal_child (GtkBuildable *buildable,
1692                     GtkBuilder   *builder,
1693                     const gchar  *childname);
1694
1695 G_DEFINE_TYPE_WITH_CODE (GtkFontSelectionDialog, gtk_font_selection_dialog,
1696        GTK_TYPE_DIALOG,
1697        G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
1698             gtk_font_selection_dialog_buildable_interface_init))
1699
1700 static GtkBuildableIface *parent_buildable_iface;
1701
1702 static void
1703 gtk_font_selection_dialog_class_init (GtkFontSelectionDialogClass *klass)
1704 {
1705   g_type_class_add_private (klass, sizeof (GtkFontSelectionDialogPrivate));
1706 }
1707
1708 static void
1709 gtk_font_selection_dialog_init (GtkFontSelectionDialog *fontseldiag)
1710 {
1711   GtkFontSelectionDialogPrivate *priv;
1712   GtkDialog *dialog = GTK_DIALOG (fontseldiag);
1713   GtkWidget *action_area, *content_area;
1714
1715   fontseldiag->priv = G_TYPE_INSTANCE_GET_PRIVATE (fontseldiag,
1716                                                    GTK_TYPE_FONT_SELECTION_DIALOG,
1717                                                    GtkFontSelectionDialogPrivate);
1718   priv = fontseldiag->priv;
1719
1720   content_area = gtk_dialog_get_content_area (dialog);
1721   action_area = gtk_dialog_get_action_area (dialog);
1722
1723   gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
1724   gtk_box_set_spacing (GTK_BOX (content_area), 2); /* 2 * 5 + 2 = 12 */
1725   gtk_container_set_border_width (GTK_CONTAINER (action_area), 5);
1726   gtk_box_set_spacing (GTK_BOX (action_area), 6);
1727
1728   gtk_widget_push_composite_child ();
1729
1730   gtk_window_set_resizable (GTK_WINDOW (fontseldiag), TRUE);
1731
1732   /* Create the content area */
1733   priv->fontsel = gtk_font_selection_new ();
1734   gtk_container_set_border_width (GTK_CONTAINER (priv->fontsel), 5);
1735   gtk_widget_show (priv->fontsel);
1736   gtk_box_pack_start (GTK_BOX (content_area),
1737           priv->fontsel, TRUE, TRUE, 0);
1738
1739   /* Create the action area */
1740   priv->cancel_button = gtk_dialog_add_button (dialog,
1741                                                GTK_STOCK_CANCEL,
1742                                                GTK_RESPONSE_CANCEL);
1743
1744   priv->apply_button = gtk_dialog_add_button (dialog,
1745                                               GTK_STOCK_APPLY,
1746                                               GTK_RESPONSE_APPLY);
1747   gtk_widget_hide (priv->apply_button);
1748
1749   priv->ok_button = gtk_dialog_add_button (dialog,
1750                                            GTK_STOCK_OK,
1751                                            GTK_RESPONSE_OK);
1752   gtk_widget_grab_default (priv->ok_button);
1753
1754   gtk_dialog_set_alternative_button_order (GTK_DIALOG (fontseldiag),
1755              GTK_RESPONSE_OK,
1756              GTK_RESPONSE_APPLY,
1757              GTK_RESPONSE_CANCEL,
1758              -1);
1759
1760   gtk_window_set_title (GTK_WINDOW (fontseldiag),
1761                         _("Font Selection"));
1762
1763   gtk_widget_pop_composite_child ();
1764 }
1765
1766 /**
1767  * gtk_font_selection_dialog_new:
1768  * @title: the title of the dialog window 
1769  *
1770  * Creates a new #GtkFontSelectionDialog.
1771  *
1772  * Return value: a new #GtkFontSelectionDialog
1773  */
1774 GtkWidget*
1775 gtk_font_selection_dialog_new (const gchar *title)
1776 {
1777   GtkFontSelectionDialog *fontseldiag;
1778   
1779   fontseldiag = g_object_new (GTK_TYPE_FONT_SELECTION_DIALOG, NULL);
1780
1781   if (title)
1782     gtk_window_set_title (GTK_WINDOW (fontseldiag), title);
1783   
1784   return GTK_WIDGET (fontseldiag);
1785 }
1786
1787 /**
1788  * gtk_font_selection_dialog_get_font_selection:
1789  * @fsd: a #GtkFontSelectionDialog
1790  *
1791  * Retrieves the #GtkFontSelection widget embedded in the dialog.
1792  *
1793  * Returns: (transfer none): the embedded #GtkFontSelection
1794  *
1795  * Since: 2.22
1796  **/
1797 GtkWidget*
1798 gtk_font_selection_dialog_get_font_selection (GtkFontSelectionDialog *fsd)
1799 {
1800   g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1801
1802   return fsd->priv->fontsel;
1803 }
1804
1805
1806 /**
1807  * gtk_font_selection_dialog_get_ok_button:
1808  * @fsd: a #GtkFontSelectionDialog
1809  *
1810  * Gets the 'OK' button.
1811  *
1812  * Return value: (transfer none): the #GtkWidget used in the dialog
1813  *     for the 'OK' button.
1814  *
1815  * Since: 2.14
1816  */
1817 GtkWidget *
1818 gtk_font_selection_dialog_get_ok_button (GtkFontSelectionDialog *fsd)
1819 {
1820   g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1821
1822   return fsd->priv->ok_button;
1823 }
1824
1825 /**
1826  * gtk_font_selection_dialog_get_cancel_button:
1827  * @fsd: a #GtkFontSelectionDialog
1828  *
1829  * Gets the 'Cancel' button.
1830  *
1831  * Return value: (transfer none): the #GtkWidget used in the dialog
1832  *     for the 'Cancel' button.
1833  *
1834  * Since: 2.14
1835  */
1836 GtkWidget *
1837 gtk_font_selection_dialog_get_cancel_button (GtkFontSelectionDialog *fsd)
1838 {
1839   g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1840
1841   return fsd->priv->cancel_button;
1842 }
1843
1844 static void
1845 gtk_font_selection_dialog_buildable_interface_init (GtkBuildableIface *iface)
1846 {
1847   parent_buildable_iface = g_type_interface_peek_parent (iface);
1848   iface->get_internal_child = gtk_font_selection_dialog_buildable_get_internal_child;
1849 }
1850
1851 static GObject *
1852 gtk_font_selection_dialog_buildable_get_internal_child (GtkBuildable *buildable,
1853               GtkBuilder   *builder,
1854               const gchar  *childname)
1855 {
1856   GtkFontSelectionDialogPrivate *priv;
1857
1858   priv = GTK_FONT_SELECTION_DIALOG (buildable)->priv;
1859
1860   if (g_strcmp0 (childname, "ok_button") == 0)
1861     return G_OBJECT (priv->ok_button);
1862   else if (g_strcmp0 (childname, "cancel_button") == 0)
1863     return G_OBJECT (priv->cancel_button);
1864   else if (g_strcmp0 (childname, "apply_button") == 0)
1865     return G_OBJECT (priv->apply_button);
1866   else if (g_strcmp0 (childname, "font_selection") == 0)
1867     return G_OBJECT (priv->fontsel);
1868
1869   return parent_buildable_iface->get_internal_child (buildable, builder, childname);
1870 }
1871
1872 /**
1873  * gtk_font_selection_dialog_get_font_name:
1874  * @fsd: a #GtkFontSelectionDialog
1875  * 
1876  * Gets the currently-selected font name.
1877  *
1878  * Note that this can be a different string than what you set with 
1879  * gtk_font_selection_dialog_set_font_name(), as the font selection widget
1880  * may normalize font names and thus return a string with a different 
1881  * structure. For example, "Helvetica Italic Bold 12" could be normalized 
1882  * to "Helvetica Bold Italic 12".  Use pango_font_description_equal()
1883  * if you want to compare two font descriptions.
1884  * 
1885  * Return value: A string with the name of the current font, or %NULL if no 
1886  *     font is selected. You must free this string with g_free().
1887  */
1888 gchar*
1889 gtk_font_selection_dialog_get_font_name (GtkFontSelectionDialog *fsd)
1890 {
1891   GtkFontSelectionDialogPrivate *priv;
1892
1893   g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1894
1895   priv = fsd->priv;
1896
1897   return gtk_font_selection_get_font_name (GTK_FONT_SELECTION (priv->fontsel));
1898 }
1899
1900 /**
1901  * gtk_font_selection_dialog_set_font_name:
1902  * @fsd: a #GtkFontSelectionDialog
1903  * @fontname: a font name like "Helvetica 12" or "Times Bold 18"
1904  *
1905  * Sets the currently selected font. 
1906  * 
1907  * Return value: %TRUE if the font selected in @fsd is now the
1908  *     @fontname specified, %FALSE otherwise. 
1909  */
1910 gboolean
1911 gtk_font_selection_dialog_set_font_name (GtkFontSelectionDialog *fsd,
1912            const gchar          *fontname)
1913 {
1914   GtkFontSelectionDialogPrivate *priv;
1915
1916   g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), FALSE);
1917   g_return_val_if_fail (fontname, FALSE);
1918
1919   priv = fsd->priv;
1920
1921   return gtk_font_selection_set_font_name (GTK_FONT_SELECTION (priv->fontsel), fontname);
1922 }
1923
1924 /**
1925  * gtk_font_selection_dialog_get_preview_text:
1926  * @fsd: a #GtkFontSelectionDialog
1927  *
1928  * Gets the text displayed in the preview area.
1929  * 
1930  * Return value: the text displayed in the preview area. 
1931  *     This string is owned by the widget and should not be 
1932  *     modified or freed 
1933  */
1934 G_CONST_RETURN gchar*
1935 gtk_font_selection_dialog_get_preview_text (GtkFontSelectionDialog *fsd)
1936 {
1937   GtkFontSelectionDialogPrivate *priv;
1938
1939   g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1940
1941   priv = fsd->priv;
1942
1943   return gtk_font_selection_get_preview_text (GTK_FONT_SELECTION (priv->fontsel));
1944 }
1945
1946 /**
1947  * gtk_font_selection_dialog_set_preview_text:
1948  * @fsd: a #GtkFontSelectionDialog
1949  * @text: the text to display in the preview area
1950  *
1951  * Sets the text displayed in the preview area. 
1952  */
1953 void
1954 gtk_font_selection_dialog_set_preview_text (GtkFontSelectionDialog *fsd,
1955               const gchar            *text)
1956 {
1957   GtkFontSelectionDialogPrivate *priv;
1958
1959   g_return_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd));
1960   g_return_if_fail (text != NULL);
1961
1962   priv = fsd->priv;
1963
1964   gtk_font_selection_set_preview_text (GTK_FONT_SELECTION (priv->fontsel), text);
1965 }