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