]> Pileus Git - ~andy/gtk/blob - gtk/gtkfontchooser.c
f7ab292ada202c60aae44ea8ae4370e62d57d5d3
[~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
105
106 struct _GtkFontSelectionDialogPrivate
107 {
108   GtkWidget *fontsel;
109
110   GtkWidget *ok_button;
111   GtkWidget *apply_button;
112   GtkWidget *cancel_button;
113 };
114
115
116 #define DEFAULT_FONT_NAME "Sans 10"
117 #define MAX_FONT_SIZE 999
118
119 /* This is the initial fixed height and the top padding of the preview entry */
120 #define PREVIEW_HEIGHT 84
121 #define PREVIEW_TOP_PADDING 6
122
123 /* These are the sizes of the font, style & size lists. */
124 #define FONT_LIST_HEIGHT        136
125 #define FONT_LIST_WIDTH         190
126 #define FONT_STYLE_LIST_WIDTH   170
127 #define FONT_SIZE_LIST_WIDTH    60
128
129 #define ROW_FORMAT_STRING "<span weight=\"bold\" size=\"small\" foreground=\"%s\">%s</span>\n<span size=\"x-large\" font_desc=\"%s\">%s</span>"
130
131 /* These are what we use as the standard font sizes, for the size list.
132  */
133 #define FONT_SIZES_LENGTH 14
134 static const gint font_sizes[] = {
135   6, 8, 9, 10, 11, 12, 13, 14, 16, 20, 24, 36, 48, 72
136 };
137
138 enum {
139    PROP_0,
140    PROP_FONT_NAME,
141    PROP_PREVIEW_TEXT
142 };
143
144
145 enum {
146   FAMILY_COLUMN,
147   FACE_COLUMN,
148   PREVIEW_TEXT_COLUMN,
149   PREVIEW_TITLE_COLUMN,
150   /*FIXME: Remove two strings after deprecation removal */
151   FAMILY_NAME_COLUMN,
152   FACE_NAME_COLUMN
153 };
154
155 static void  gtk_font_selection_set_property       (GObject         *object,
156                                                                       guint            prop_id,
157                                                                       const GValue    *value,
158                                                                       GParamSpec      *pspec);
159 static void  gtk_font_selection_get_property       (GObject         *object,
160                                                                                   guint            prop_id,
161                                                                                   GValue          *value,
162                                                                                   GParamSpec      *pspec);
163 static void  gtk_font_selection_finalize                 (GObject         *object);
164
165 #if 0
166 static void  gtk_font_selection_screen_changed     (GtkWidget         *widget,
167                                                     GdkScreen       *previous_screen);
168 static void  gtk_font_selection_style_updated      (GtkWidget      *widget);
169 #endif
170
171 static void  gtk_font_selection_ref_family        (GtkFontSelection *fontsel,
172                                                    PangoFontFamily  *family);
173 static void  gtk_font_selection_ref_face          (GtkFontSelection *fontsel,
174                                                    PangoFontFace    *face);
175
176 static void gtk_font_selection_bootstrap_fontlist (GtkFontSelection *fontsel);
177
178 G_DEFINE_TYPE (GtkFontSelection, gtk_font_selection, GTK_TYPE_VBOX)
179
180 static void
181 gtk_font_selection_class_init (GtkFontSelectionClass *klass)
182 {
183   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
184
185 #if 0
186   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
187   widget_class->screen_changed = gtk_font_selection_screen_changed;
188   widget_class->style_updated = gtk_font_selection_style_updated;
189 #endif
190
191   gobject_class->finalize = gtk_font_selection_finalize;
192   gobject_class->set_property = gtk_font_selection_set_property;
193   gobject_class->get_property = gtk_font_selection_get_property;
194
195   g_object_class_install_property (gobject_class,
196                                    PROP_FONT_NAME,
197                                    g_param_spec_string ("font-name",
198                                                         P_("Font name"),
199                                                         P_("The string that represents this font"),
200                                                         DEFAULT_FONT_NAME,
201                                                         GTK_PARAM_READWRITE));
202   g_object_class_install_property (gobject_class,
203                                    PROP_PREVIEW_TEXT,
204                                    g_param_spec_string ("preview-text",
205                                                         P_("Preview text"),
206                                                         P_("The text to display in order to demonstrate the selected font"),
207                                                         pango_language_get_sample_string (NULL),
208                                                         GTK_PARAM_READWRITE));
209
210   g_type_class_add_private (klass, sizeof (GtkFontSelectionPrivate));
211 }
212
213 static void 
214 gtk_font_selection_set_property (GObject         *object,
215                                                    guint            prop_id,
216                                                    const GValue    *value,
217                                                    GParamSpec      *pspec)
218 {
219   GtkFontSelection *fontsel;
220
221   fontsel = GTK_FONT_SELECTION (object);
222
223   switch (prop_id)
224     {
225     case PROP_FONT_NAME:
226       gtk_font_selection_set_font_name (fontsel, g_value_get_string (value));
227       break;
228     case PROP_PREVIEW_TEXT:
229       gtk_font_selection_set_preview_text (fontsel, g_value_get_string (value));
230       break;
231     default:
232       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
233       break;
234     }
235 }
236
237 static void
238 gtk_font_selection_get_property (GObject         *object,
239                                                    guint            prop_id,
240                                                    GValue          *value,
241                                                    GParamSpec      *pspec)
242 {
243   GtkFontSelection *fontsel;
244
245   fontsel = GTK_FONT_SELECTION (object);
246
247   switch (prop_id)
248     {
249     case PROP_FONT_NAME:
250       g_value_take_string (value, gtk_font_selection_get_font_name (fontsel));
251       break;
252     case PROP_PREVIEW_TEXT:
253       g_value_set_string (value, gtk_font_selection_get_preview_text (fontsel));
254       break;
255     default:
256       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
257       break;
258     }
259 }
260
261 void
262 refilter_and_focus (GtkFontSelectionPrivate *priv)
263 {
264   GtkTreeIter  iter;
265   GtkTreeView *treeview = GTK_TREE_VIEW (priv->family_face_list);
266   GtkTreePath *path = gtk_tree_path_new ();
267
268   gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (priv->filter));
269
270   if (!path)
271     return;
272
273   gtk_tree_view_get_cursor (treeview, &path, NULL);
274
275   if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->filter), &iter, path))
276     {
277       gtk_tree_path_free (path);
278       return;
279     }
280
281   gtk_tree_view_scroll_to_cell (treeview, path, NULL, FALSE, 0.0, 0.0);
282   gtk_tree_path_free (path);
283 }
284
285 void
286 deleted_text_cb (GtkEntryBuffer *buffer,
287                  guint           position,
288                  guint           n_chars,
289                  gpointer        user_data)
290 {
291   GtkFontSelectionPrivate *priv  = (GtkFontSelectionPrivate*)user_data;
292   GtkWidget               *entry = priv->search_entry;
293   
294   if (gtk_entry_buffer_get_length (buffer) == 0)
295     {
296       gtk_entry_set_icon_from_stock (GTK_ENTRY (entry),
297                                      GTK_ENTRY_ICON_SECONDARY,
298                                      GTK_STOCK_FIND);
299     }
300
301   gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (priv->filter));
302 }
303
304 void
305 inserted_text_cb (GtkEntryBuffer *buffer,
306                   guint           position,
307                   gchar          *chars,
308                   guint           n_chars,
309                   gpointer        user_data) 
310 {
311   GtkFontSelectionPrivate *priv  = (GtkFontSelectionPrivate*)user_data;
312   GtkWidget               *entry = priv->search_entry;
313
314   if (g_strcmp0 (gtk_entry_get_icon_stock (GTK_ENTRY (entry), GTK_ENTRY_ICON_SECONDARY),
315                  GTK_STOCK_CLEAR))
316     gtk_entry_set_icon_from_stock (GTK_ENTRY (entry),
317                                    GTK_ENTRY_ICON_SECONDARY,
318                                    GTK_STOCK_CLEAR);
319
320
321   gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (priv->filter));
322 }
323
324 void
325 icon_press_cb (GtkEntry             *entry,
326                GtkEntryIconPosition  pos,
327                GdkEvent             *event,
328                gpointer              user_data)
329 {
330   gtk_entry_buffer_delete_text (gtk_entry_get_buffer (entry), 0, -1);
331 }
332
333 void
334 slider_change_cb (GtkAdjustment *adjustment, gpointer data)
335 {
336   GtkFontSelectionPrivate *priv = (GtkFontSelectionPrivate*)data;
337
338   /* If we set the silder value manually, we ignore this callback */
339   if (priv->ignore_slider)
340     {
341       priv->ignore_slider = FALSE;
342       return;
343     }
344
345   gtk_adjustment_set_value (gtk_spin_button_get_adjustment( GTK_SPIN_BUTTON(priv->size_spin)),
346                             gtk_adjustment_get_value (adjustment));
347 }
348
349 void
350 spin_change_cb (GtkAdjustment *adjustment, gpointer data)
351 {
352   PangoFontDescription *desc;
353   GtkFontSelectionPrivate *priv = (GtkFontSelectionPrivate*)data;
354
355   gdouble size = gtk_adjustment_get_value (adjustment);
356   
357   GtkAdjustment *slider_adj = gtk_range_get_adjustment (GTK_RANGE (priv->size_slider));
358
359   /* We ignore the slider value change callback for both of this set_value call */
360   priv->ignore_slider = TRUE;
361   if (size < gtk_adjustment_get_lower (slider_adj))
362     gtk_adjustment_set_value (slider_adj, gtk_adjustment_get_lower (slider_adj));
363   else if (size > gtk_adjustment_get_upper (slider_adj))
364     gtk_adjustment_set_value (slider_adj, gtk_adjustment_get_upper (slider_adj));
365   else
366     gtk_adjustment_set_value (slider_adj, size);
367
368   priv->size = ((gint)gtk_adjustment_get_value (adjustment)) * PANGO_SCALE;
369
370   desc = pango_context_get_font_description (gtk_widget_get_pango_context (priv->preview));
371   pango_font_description_set_size (desc, priv->size);
372   gtk_widget_override_font (priv->preview, desc);
373   
374   gtk_widget_queue_draw (priv->preview);
375 }
376
377 void
378 set_range_marks (GtkFontSelectionPrivate *priv,
379                  GtkWidget* size_slider,
380                  gint* sizes,
381                  gint length)
382 {
383   GtkAdjustment *adj;
384   gint i;
385   gdouble value;
386   
387   if (length<2)
388     {
389       sizes = (gint*)font_sizes;
390       length = FONT_SIZES_LENGTH;
391     }
392   
393   gtk_scale_clear_marks (GTK_SCALE (size_slider));
394   
395   adj = gtk_range_get_adjustment(GTK_RANGE (size_slider));
396   
397   gtk_adjustment_set_lower (adj, (gdouble) sizes[0]);
398   gtk_adjustment_set_upper (adj, (gdouble) sizes[length-1]);
399
400   value = gtk_adjustment_get_value (adj);
401   if (value > (gdouble) sizes[length-1])
402     {
403       gtk_adjustment_set_value (adj, (gdouble) sizes[length-1]);
404       priv->ignore_slider = TRUE;
405     }
406   else if (value < (gdouble) sizes[0])
407     {
408       gtk_adjustment_set_value (adj, (gdouble) sizes[0]);
409       priv->ignore_slider = TRUE; 
410     }
411   
412   for (i=0; i<length; i++)
413     gtk_scale_add_mark (GTK_SCALE (size_slider),
414                         (gdouble) sizes[i],
415                         GTK_POS_BOTTOM, NULL);
416                         
417 }
418
419 void
420 cursor_changed_cb (GtkTreeView *treeview, gpointer data)
421 {
422   PangoFontFamily      *family;
423   PangoFontFace        *face;
424   PangoFontDescription *desc;
425   
426   gint *sizes;
427   gint  i, n_sizes;
428
429   GtkTreeIter iter;
430   GtkTreePath *path = gtk_tree_path_new ();
431   
432   GtkFontSelection        *fontsel = (GtkFontSelection*)data;
433   
434   gtk_tree_view_get_cursor (treeview, &path, NULL);
435   
436   if (!path)
437     return;
438
439   if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (fontsel->priv->filter), &iter, path))
440     {
441       gtk_tree_path_free (path);
442       return;
443     } 
444   
445   
446   gtk_tree_model_get (GTK_TREE_MODEL (fontsel->priv->filter), &iter,
447                       FACE_COLUMN, &face,
448                       FAMILY_COLUMN, &family,
449                       -1);
450
451   gtk_tree_view_scroll_to_cell (treeview, path, NULL, FALSE, 0.0, 0.0);
452
453   gtk_tree_path_free (path);
454   path = NULL;
455   
456   if (!face || !family)
457     {
458       g_object_unref (face);
459       g_object_unref (family);
460       return;
461     }
462
463   desc = pango_font_face_describe (face);
464   pango_font_description_set_size (desc, fontsel->priv->size);
465   gtk_widget_override_font (fontsel->priv->preview, desc);
466
467   pango_font_face_list_sizes (face, &sizes, &n_sizes);
468   /* It seems not many fonts actually have a sane set of sizes */
469   for (i=0; i<n_sizes; i++)
470     sizes[i] = sizes[i] / PANGO_SCALE;
471   
472   set_range_marks (fontsel->priv, fontsel->priv->size_slider, sizes, n_sizes);
473
474   gtk_font_selection_ref_family (fontsel, family);
475   gtk_font_selection_ref_face  (fontsel,   face);
476
477   /* Free resources */
478   g_object_unref ((gpointer)face);
479   pango_font_description_free(desc);
480 }
481
482 gboolean
483 zoom_preview_cb (GtkWidget *scrolled_window, GdkEventScroll *event, gpointer data)
484 {
485   GtkFontSelectionPrivate *priv = (GtkFontSelectionPrivate*)data;
486
487   GtkAdjustment *adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->size_spin));
488
489   if (event->direction == GDK_SCROLL_UP || event->direction == GDK_SCROLL_RIGHT)
490     gtk_adjustment_set_value (adj,
491                               gtk_adjustment_get_value (adj) +
492                               gtk_adjustment_get_step_increment (adj));
493   else if (event->direction == GDK_SCROLL_DOWN || event->direction == GDK_SCROLL_LEFT)
494     gtk_adjustment_set_value (adj,
495                               gtk_adjustment_get_value (adj) -
496                               gtk_adjustment_get_step_increment (adj));
497   return TRUE;
498 }
499
500 static void
501 gtk_font_selection_init (GtkFontSelection *fontsel)
502 {
503   GtkFontSelectionPrivate *priv;
504   PangoFontDescription    *font_desc;
505   GtkWidget               *scrolled_win;
506   GtkWidget               *alignment;
507   GtkWidget               *preview_and_size;
508   GtkWidget               *size_controls;
509 #if 0
510   GList                   *focus_chain = NULL;
511   AtkObject *atk_obj;
512 #endif
513
514   fontsel->priv = G_TYPE_INSTANCE_GET_PRIVATE (fontsel,
515                                                GTK_TYPE_FONT_SELECTION,
516                                                GtkFontSelectionPrivate);
517   priv = fontsel->priv;
518   gtk_widget_push_composite_child ();
519
520   /* Creating fundamental widgets for the private struct */
521   priv->search_entry = gtk_entry_new ();
522   priv->family_face_list = gtk_tree_view_new ();
523   priv->preview = gtk_entry_new ();
524   priv->size_slider = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL,
525                                                 (gdouble) font_sizes[0],
526                                                 (gdouble) font_sizes[FONT_SIZES_LENGTH - 1],
527                                                 1.0);
528
529   priv->size_spin = gtk_spin_button_new_with_range (0.0, (gdouble)(G_MAXINT / PANGO_SCALE), 1.0);
530
531   /** Bootstrapping widget layout **/
532   gtk_box_set_spacing (GTK_BOX (fontsel), 6);
533   gtk_box_pack_start (GTK_BOX (fontsel), priv->search_entry, FALSE, TRUE, 0);
534
535   /* Main font family/face view */
536   scrolled_win = gtk_scrolled_window_new (NULL, NULL);
537   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
538                                   GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
539   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win),
540                                        GTK_SHADOW_ETCHED_IN);
541   gtk_container_add (GTK_CONTAINER (scrolled_win), priv->family_face_list);
542
543   /* Alignment for the preview and size controls */
544   alignment = gtk_alignment_new (0.5, 0.5, 1.0, 1.0);
545   gtk_alignment_set_padding (GTK_ALIGNMENT (alignment),
546                              PREVIEW_TOP_PADDING, 0, 0, 0);
547   gtk_box_pack_start (GTK_BOX (fontsel), scrolled_win, TRUE, TRUE, 0);
548
549   preview_and_size = gtk_vbox_new (TRUE, 0);
550   gtk_box_set_homogeneous (GTK_BOX (preview_and_size), FALSE);
551   
552   /* The preview entry needs a scrolled window to make sure we have a */
553   scrolled_win = gtk_scrolled_window_new (NULL, NULL);
554   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
555                                   GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
556   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win),
557                                        GTK_SHADOW_ETCHED_IN);
558   gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_win),
559                                          priv->preview);
560   gtk_box_pack_start (GTK_BOX (preview_and_size), scrolled_win, FALSE, FALSE, 0);
561   
562   /* Setting the size requests for various widgets */
563   gtk_widget_set_size_request (GTK_WIDGET (fontsel), 462, 462);
564   gtk_widget_set_size_request (scrolled_win,  -1, PREVIEW_HEIGHT);
565   gtk_widget_set_size_request (priv->preview, -1, PREVIEW_HEIGHT - 6);
566
567   /* Unset the frame on the preview entry */
568   gtk_entry_set_has_frame (GTK_ENTRY (priv->preview), FALSE);
569
570   /* Packing the slider and the spin in a hbox */
571   size_controls = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
572   gtk_scale_set_draw_value (GTK_SCALE (priv->size_slider), FALSE);
573   gtk_box_pack_start (GTK_BOX (size_controls), priv->size_slider, TRUE, TRUE, 0);
574   gtk_box_pack_start (GTK_BOX (size_controls), priv->size_spin, FALSE, TRUE, 0);
575   
576   gtk_widget_set_valign (priv->size_spin, GTK_ALIGN_START);
577
578   gtk_box_pack_start (GTK_BOX (preview_and_size), size_controls, FALSE, FALSE, 0);
579   gtk_container_add (GTK_CONTAINER (alignment), preview_and_size);
580
581   gtk_box_pack_start (GTK_BOX (fontsel), GTK_WIDGET(alignment), FALSE, TRUE, 0);
582
583   /* Getting the default size */
584   font_desc  = pango_context_get_font_description (gtk_widget_get_pango_context (GTK_WIDGET (fontsel)));
585   priv->size = pango_font_description_get_size (font_desc);
586   priv->face = NULL;
587   priv->family = NULL;
588   
589   gtk_adjustment_set_value (gtk_range_get_adjustment (GTK_RANGE (priv->size_slider)),
590                             (gdouble)(priv->size / PANGO_SCALE));
591   gtk_adjustment_set_value (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->size_spin)),
592                             (gdouble)(priv->size / PANGO_SCALE));
593
594   gtk_widget_show_all (GTK_WIDGET (fontsel));
595   gtk_widget_hide (GTK_WIDGET (fontsel));
596
597   /* Treeview column and model bootstrapping */
598   gtk_font_selection_bootstrap_fontlist (fontsel);
599   
600   /* Set default preview text */
601   gtk_entry_set_text (GTK_ENTRY (priv->preview),
602                       pango_language_get_sample_string (NULL));
603   
604   /* Set search icon and place holder text */
605   gtk_entry_set_icon_from_stock (GTK_ENTRY (priv->search_entry),
606                                  GTK_ENTRY_ICON_SECONDARY,
607                                  GTK_STOCK_FIND);
608   gtk_entry_set_placeholder_text (GTK_ENTRY (priv->search_entry), _("Search font name"));
609   
610   /** Callback connections **/
611   /* Connect to callback for the live search text entry */
612   g_signal_connect (G_OBJECT (gtk_entry_get_buffer (GTK_ENTRY (priv->search_entry))),
613                     "deleted-text", G_CALLBACK (deleted_text_cb), priv);
614   g_signal_connect (G_OBJECT (gtk_entry_get_buffer (GTK_ENTRY (priv->search_entry))),
615                     "inserted-text", G_CALLBACK (inserted_text_cb), priv);
616   g_signal_connect (G_OBJECT (priv->search_entry),
617                     "icon-press", G_CALLBACK (icon_press_cb), priv);
618
619   /* Size controls callbacks */
620   g_signal_connect (G_OBJECT (gtk_range_get_adjustment (GTK_RANGE (priv->size_slider))),
621                     "value-changed", G_CALLBACK (slider_change_cb), priv);
622   g_signal_connect (G_OBJECT (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->size_spin))),
623                     "value-changed", G_CALLBACK (spin_change_cb), priv);
624   priv->ignore_slider = FALSE;
625   
626   /* Font selection callback */
627   g_signal_connect (G_OBJECT (priv->family_face_list), "cursor-changed",
628                     G_CALLBACK (cursor_changed_cb),    fontsel);
629
630   /* Zoom on preview scroll*/
631   g_signal_connect (G_OBJECT (scrolled_win),      "scroll-event",
632                     G_CALLBACK (zoom_preview_cb), priv);
633
634   g_signal_connect (G_OBJECT (priv->size_slider), "scroll-event",
635                     G_CALLBACK (zoom_preview_cb), priv);
636
637   set_range_marks (priv, priv->size_slider, (gint*)font_sizes, FONT_SIZES_LENGTH);
638
639   /* Set default focus */
640   gtk_widget_pop_composite_child();
641 }
642
643 /**
644  * gtk_font_selection_new:
645  *
646  * Creates a new #GtkFontSelection.
647  *
648  * Return value: a new #GtkFontSelection
649  */
650 GtkWidget *
651 gtk_font_selection_new (void)
652 {
653   GtkFontSelection *fontsel;
654   
655   fontsel = g_object_new (GTK_TYPE_FONT_SELECTION, NULL);
656   
657   return GTK_WIDGET (fontsel);
658 }
659
660 static int
661 cmp_families (const void *a, const void *b)
662 {
663   const char *a_name = pango_font_family_get_name (*(PangoFontFamily **)a);
664   const char *b_name = pango_font_family_get_name (*(PangoFontFamily **)b);
665
666   return g_utf8_collate (a_name, b_name);
667 }
668
669 static void 
670 populate_list (GtkTreeView* treeview, GtkListStore* model)
671 {
672   GtkStyleContext *style_context;
673   GdkRGBA          g_color;
674   PangoColor       p_color;
675   gchar            *color_string;
676
677   GtkTreeIter   match_row;
678   GtkTreePath  *path;
679
680   gint n_families, i;  
681   PangoFontFamily **families;
682
683   GString     *tmp = g_string_new (NULL);
684   GString     *family_and_face = g_string_new (NULL);
685
686   pango_context_list_families (gtk_widget_get_pango_context (GTK_WIDGET (treeview)),
687                                &families,
688                                &n_families);
689
690   qsort (families, n_families, sizeof (PangoFontFamily *), cmp_families);
691
692   gtk_list_store_clear (model);
693
694   /* Get row header font color */
695   style_context = gtk_widget_get_style_context (GTK_WIDGET (treeview));
696   gtk_style_context_get_color (style_context,
697                                GTK_STATE_FLAG_NORMAL |GTK_STATE_FLAG_INSENSITIVE,
698                                &g_color);
699
700   p_color.red   = (guint16)((gdouble)G_MAXUINT16 * g_color.red);
701   p_color.green = (guint16)((gdouble)G_MAXUINT16 * g_color.green);
702   p_color.blue  = (guint16)((gdouble)G_MAXUINT16 * g_color.blue);
703   color_string  = pango_color_to_string (&p_color);
704
705   /* Iterate over families and faces */
706   for (i=0; i<n_families; i++)
707     {
708       GtkTreeIter     iter;
709       PangoFontFace **faces;
710       
711       int             j, n_faces;
712       const gchar    *fam_name = pango_font_family_get_name (families[i]);
713
714       pango_font_family_list_faces (families[i], &faces, &n_faces);
715       
716       for (j=0; j<n_faces; j++)
717         {
718           PangoFontDescription *pango_desc = pango_font_face_describe (faces[j]);
719           const gchar *face_name = pango_font_face_get_face_name (faces[j]);
720           gchar       *font_desc = pango_font_description_to_string (pango_desc);
721           
722           /* foreground_color, family_name, face_name, desc, sample string */
723           g_string_printf (family_and_face, "%s %s",
724                                             fam_name,
725                                             face_name);
726           
727           g_string_printf (tmp, ROW_FORMAT_STRING,
728                                 color_string,
729                                 family_and_face->str,
730                                 font_desc,
731                                 pango_language_get_sample_string (NULL));
732
733           gtk_list_store_append (model, &iter);
734           gtk_list_store_set (model, &iter,
735                               FAMILY_COLUMN, families[i],
736                               FACE_COLUMN, faces[j],
737                               PREVIEW_TITLE_COLUMN, family_and_face->str,
738                               PREVIEW_TEXT_COLUMN, tmp->str,
739                               /** FIXME: FAMILY_NAME_COLUMN and FACE_NAME_COLUMN
740                                   are needed only until we remove the deprecated
741                                   API **/
742                               FAMILY_NAME_COLUMN, fam_name,
743                               FACE_NAME_COLUMN, face_name,
744                               -1);
745
746           if ((i == 0 && j == 0) ||
747               (!g_ascii_strcasecmp (face_name, "sans") && j == 0))
748             {
749               match_row = iter;
750             }
751
752           pango_font_description_free(pango_desc);
753           g_free (font_desc);
754         }
755
756       g_free (faces);
757     }
758
759   path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &match_row);
760   
761   if (path)
762   {
763     gtk_tree_view_set_cursor (treeview, path, NULL, FALSE);
764     gtk_tree_path_free(path);
765   }
766
767
768   g_string_free (family_and_face, TRUE);
769   g_string_free (tmp, TRUE);
770   g_free (color_string);
771   g_free (families);
772 }
773
774 gboolean
775 visible_func (GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
776 {
777   gboolean result = FALSE;
778   GtkFontSelectionPrivate *priv = (GtkFontSelectionPrivate*) data;
779
780   const gchar *search_text = (const gchar*)gtk_entry_get_text (GTK_ENTRY (priv->search_entry));
781   gchar       *font_name;
782   gchar       *font_name_casefold;
783   gchar       *search_text_casefold;
784
785   gtk_tree_model_get (model, iter,
786                       FAMILY_NAME_COLUMN, &font_name,
787                       -1);
788
789   /* Covering some corner cases to speed up the result */
790   if (font_name == NULL ||
791       strlen (search_text) > strlen (font_name))
792     {
793       g_free (font_name);
794       return FALSE;
795     }  
796   if (strlen (search_text) == 0)
797     {
798       g_free (font_name);
799       return TRUE;
800     }
801   
802   font_name_casefold = g_utf8_casefold (font_name, -1);
803   search_text_casefold = g_utf8_casefold (search_text, -1);
804   
805   if (g_strrstr (font_name_casefold, search_text_casefold))
806     result = TRUE;
807
808   g_free (search_text_casefold);
809   g_free (font_name_casefold);
810   g_free (font_name);
811   return result;
812 }
813
814 static void
815 gtk_font_selection_bootstrap_fontlist (GtkFontSelection* fontsel)
816 {
817   GtkTreeView       *treeview = GTK_TREE_VIEW (fontsel->priv->family_face_list);
818   GtkCellRenderer   *cell;
819   GtkTreeViewColumn *col;
820
821   fontsel->priv->model = gtk_list_store_new (6,
822                                              PANGO_TYPE_FONT_FAMILY,
823                                              PANGO_TYPE_FONT_FACE,
824                                              G_TYPE_STRING,
825                                              G_TYPE_STRING,
826                                              /*FIXME: Remove two strings after deprecation removal */
827                                              G_TYPE_STRING,
828                                              G_TYPE_STRING);
829
830   fontsel->priv->filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fontsel->priv->model),
831                                                      NULL);
832   g_object_unref (fontsel->priv->model);
833
834   gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (fontsel->priv->filter),
835                                           visible_func,
836                                           (gpointer)fontsel->priv,
837                                           NULL);
838
839   gtk_tree_view_set_model (treeview, GTK_TREE_MODEL (fontsel->priv->filter));
840   g_object_unref (fontsel->priv->filter);
841
842   gtk_tree_view_set_rules_hint      (treeview, TRUE);
843   gtk_tree_view_set_headers_visible (treeview, FALSE);
844
845   cell = gtk_cell_renderer_text_new ();
846   col = gtk_tree_view_column_new_with_attributes ("Family",
847                                                   cell,
848                                                   "markup", PREVIEW_TEXT_COLUMN,
849                                                   NULL);
850                                                   
851
852   g_object_set (cell, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
853
854   gtk_tree_view_append_column (treeview, col);
855
856   populate_list (treeview, fontsel->priv->model);
857 }
858
859
860 static void
861 gtk_font_selection_finalize (GObject *object)
862 {
863   GtkFontSelection *fontsel = GTK_FONT_SELECTION (object);
864
865   gtk_font_selection_ref_family (fontsel, NULL);
866   gtk_font_selection_ref_face (fontsel, NULL);
867
868   G_OBJECT_CLASS (gtk_font_selection_parent_class)->finalize (object);
869 }
870
871 #if 0
872 static void
873 gtk_font_selection_screen_changed (GtkWidget *widget,
874                                    GdkScreen *previous_screen)
875 {
876   return;
877 }
878
879 static void
880 gtk_font_selection_style_updated (GtkWidget *widget)
881 {
882   /*GTK_WIDGET_CLASS (gtk_font_selection_parent_class)->style_updated (widget);*/
883   return;
884 }
885 #endif 
886
887 static void
888 gtk_font_selection_ref_family (GtkFontSelection *fontsel,
889                                PangoFontFamily  *family)
890 {
891   GtkFontSelectionPrivate *priv = fontsel->priv;
892
893   if (family)
894     family = g_object_ref (family);
895   if (priv->family)
896     g_object_unref (priv->family);
897   priv->family = family;
898 }
899
900 static void
901 gtk_font_selection_ref_face (GtkFontSelection *fontsel,
902                              PangoFontFace    *face)
903 {
904   GtkFontSelectionPrivate *priv = fontsel->priv;
905
906   if (face)
907     face = g_object_ref (face);
908   if (priv->face)
909     g_object_unref (priv->face);
910   priv->face = face;
911 }
912
913 /*****************************************************************************
914  * These functions are the main public interface for getting/setting the font.
915  *****************************************************************************/
916
917 /**
918  * gtk_font_selection_get_family_list:
919  * @fontsel: a #GtkFontSelection
920  *
921  * This returns the #GtkTreeView that lists font families, for
922  * example, 'Sans', 'Serif', etc.
923  *
924  * Return value: (transfer none): A #GtkWidget that is part of @fontsel
925  *
926  * Deprecated: 3.2
927  */
928 GtkWidget *
929 gtk_font_selection_get_family_list (GtkFontSelection *fontsel)
930 {
931   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
932
933   return NULL;
934 }
935
936 /**
937  * gtk_font_selection_get_face_list:
938  * @fontsel: a #GtkFontSelection
939  *
940  * This returns the #GtkTreeView which lists all styles available for
941  * the selected font. For example, 'Regular', 'Bold', etc.
942  * 
943  * Return value: (transfer none): A #GtkWidget that is part of @fontsel
944  *
945  * Deprecated: 3.2
946  */
947 GtkWidget *
948 gtk_font_selection_get_face_list (GtkFontSelection *fontsel)
949 {
950   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
951
952   return NULL;
953 }
954
955 /**
956  * gtk_font_selection_get_size_entry:
957  * @fontsel: a #GtkFontSelection
958  *
959  * This returns the #GtkEntry used to allow the user to edit the font
960  * number manually instead of selecting it from the list of font sizes.
961  *
962  * Return value: (transfer none): A #GtkWidget that is part of @fontsel
963  *
964  * Deprecated: 3.2
965  */
966 GtkWidget *
967 gtk_font_selection_get_size_entry (GtkFontSelection *fontsel)
968 {
969   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
970
971   return NULL;
972 }
973
974 /**
975  * gtk_font_selection_get_size_list:
976  * @fontsel: a #GtkFontSelection
977  *
978  * This returns the #GtkTreeeView used to list font sizes.
979  *
980  * Return value: (transfer none): A #GtkWidget that is part of @fontsel
981  *
982  * Deprecated: 3.2
983  */
984 GtkWidget *
985 gtk_font_selection_get_size_list (GtkFontSelection *fontsel)
986 {
987   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
988
989   return NULL;
990 }
991
992 /**
993  * gtk_font_selection_get_preview_entry:
994  * @fontsel: a #GtkFontSelection
995  *
996  * This returns the #GtkEntry used to display the font as a preview.
997  *
998  * Return value: (transfer none): A #GtkWidget that is part of @fontsel
999  *
1000  * Deprecated: 3.2
1001  */
1002 GtkWidget *
1003 gtk_font_selection_get_preview_entry (GtkFontSelection *fontsel)
1004 {
1005   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1006
1007   return NULL;
1008 }
1009
1010 /**
1011  * gtk_font_selection_get_family:
1012  * @fontsel: a #GtkFontSelection
1013  *
1014  * Gets the #PangoFontFamily representing the selected font family.
1015  *
1016  * Return value: (transfer none): A #PangoFontFamily representing the
1017  *     selected font family. Font families are a collection of font
1018  *     faces. The returned object is owned by @fontsel and must not
1019  *     be modified or freed.
1020  *
1021  * Since: 2.14
1022  */
1023 PangoFontFamily *
1024 gtk_font_selection_get_family (GtkFontSelection *fontsel)
1025 {
1026   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1027
1028   return NULL;
1029 }
1030
1031 /**
1032  * gtk_font_selection_get_face:
1033  * @fontsel: a #GtkFontSelection
1034  *
1035  * Gets the #PangoFontFace representing the selected font group
1036  * details (i.e. family, slant, weight, width, etc).
1037  *
1038  * Return value: (transfer none): A #PangoFontFace representing the
1039  *     selected font group details. The returned object is owned by
1040  *     @fontsel and must not be modified or freed.
1041  *
1042  * Since: 2.14
1043  */
1044 PangoFontFace *
1045 gtk_font_selection_get_face (GtkFontSelection *fontsel)
1046 {
1047   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1048
1049   return NULL;
1050 }
1051
1052 /**
1053  * gtk_font_selection_get_size:
1054  * @fontsel: a #GtkFontSelection
1055  *
1056  * The selected font size.
1057  *
1058  * Return value: A n integer representing the selected font size,
1059  *     or -1 if no font size is selected.
1060  *
1061  * Since: 2.14
1062  **/
1063 gint
1064 gtk_font_selection_get_size (GtkFontSelection *fontsel)
1065 {
1066   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), -1);
1067
1068   return fontsel->priv->size;
1069 }
1070
1071 /**
1072  * gtk_font_selection_get_font_name:
1073  * @fontsel: a #GtkFontSelection
1074  * 
1075  * Gets the currently-selected font name. 
1076  *
1077  * Note that this can be a different string than what you set with 
1078  * gtk_font_selection_set_font_name(), as the font selection widget may 
1079  * normalize font names and thus return a string with a different structure. 
1080  * For example, "Helvetica Italic Bold 12" could be normalized to 
1081  * "Helvetica Bold Italic 12". Use pango_font_description_equal()
1082  * if you want to compare two font descriptions.
1083  * 
1084  * Return value: (transfer full) (allow-none): A string with the name of the
1085  *     current font, or %NULL if  no font is selected. You must free this
1086  *     string with g_free().
1087  */
1088 gchar *
1089 gtk_font_selection_get_font_name (GtkFontSelection *fontsel)
1090 {
1091   if (!fontsel->priv->family)
1092     return NULL;
1093
1094   return g_strdup (pango_font_family_get_name (fontsel->priv->family));
1095 }
1096
1097 /* This sets the current font, then selecting the appropriate list rows. */
1098
1099 /**
1100  * gtk_font_selection_set_font_name:
1101  * @fontsel: a #GtkFontSelection
1102  * @fontname: a font name like "Helvetica 12" or "Times Bold 18"
1103  * 
1104  * Sets the currently-selected font. 
1105  *
1106  * Note that the @fontsel needs to know the screen in which it will appear 
1107  * for this to work; this can be guaranteed by simply making sure that the 
1108  * @fontsel is inserted in a toplevel window before you call this function.
1109  * 
1110  * Return value: %TRUE if the font could be set successfully; %FALSE if no 
1111  *     such font exists or if the @fontsel doesn't belong to a particular 
1112  *     screen yet.
1113  */
1114 gboolean
1115 gtk_font_selection_set_font_name (GtkFontSelection *fontsel,
1116                                   const gchar      *fontname)
1117 {
1118 #if 0
1119   PangoFontFamily *family = NULL;
1120   PangoFontFace *face = NULL;
1121   PangoFontDescription *new_desc;
1122 #endif
1123
1124   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), FALSE);
1125
1126   return TRUE;
1127 }
1128
1129 /**
1130  * gtk_font_selection_get_preview_text:
1131  * @fontsel: a #GtkFontSelection
1132  *
1133  * Gets the text displayed in the preview area.
1134  * 
1135  * Return value: the text displayed in the preview area. 
1136  *     This string is owned by the widget and should not be 
1137  *     modified or freed 
1138  */
1139 G_CONST_RETURN gchar*
1140 gtk_font_selection_get_preview_text (GtkFontSelection *fontsel)
1141 {
1142   return NULL;
1143 }
1144
1145
1146 /**
1147  * gtk_font_selection_set_preview_text:
1148  * @fontsel: a #GtkFontSelection
1149  * @text: the text to display in the preview area 
1150  *
1151  * Sets the text displayed in the preview area.
1152  * The @text is used to show how the selected font looks.
1153  */
1154 void
1155 gtk_font_selection_set_preview_text  (GtkFontSelection *fontsel,
1156                                       const gchar      *text)
1157 {
1158 #if 0
1159   GtkFontSelectionPrivate *priv;
1160
1161   g_return_if_fail (GTK_IS_FONT_SELECTION (fontsel));
1162   g_return_if_fail (text != NULL);
1163
1164   priv = fontsel->priv;
1165 #endif
1166 }
1167
1168
1169 /**
1170  * SECTION:gtkfontseldlg
1171  * @Short_description: A dialog box for selecting fonts
1172  * @Title: GtkFontSelectionDialog
1173  * @See_also: #GtkFontSelection, #GtkDialog
1174  *
1175  * The #GtkFontSelectionDialog widget is a dialog box for selecting a font.
1176  *
1177  * To set the font which is initially selected, use
1178  * gtk_font_selection_dialog_set_font_name().
1179  *
1180  * To get the selected font use gtk_font_selection_dialog_get_font_name().
1181  *
1182  * To change the text which is shown in the preview area, use
1183  * gtk_font_selection_dialog_set_preview_text().
1184  *
1185  * <refsect2 id="GtkFontSelectionDialog-BUILDER-UI">
1186  * <title>GtkFontSelectionDialog as GtkBuildable</title>
1187  * The GtkFontSelectionDialog implementation of the GtkBuildable interface
1188  * exposes the embedded #GtkFontSelection as internal child with the
1189  * name "font_selection". It also exposes the buttons with the names
1190  * "ok_button", "cancel_button" and "apply_button".
1191  * </refsect2>
1192  */
1193
1194 static void gtk_font_selection_dialog_buildable_interface_init     (GtkBuildableIface *iface);
1195 static GObject * gtk_font_selection_dialog_buildable_get_internal_child (GtkBuildable *buildable,
1196                                                                           GtkBuilder   *builder,
1197                                                                           const gchar  *childname);
1198
1199 G_DEFINE_TYPE_WITH_CODE (GtkFontSelectionDialog, gtk_font_selection_dialog,
1200                          GTK_TYPE_DIALOG,
1201                          G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
1202                                                 gtk_font_selection_dialog_buildable_interface_init))
1203
1204 static GtkBuildableIface *parent_buildable_iface;
1205
1206 static void
1207 gtk_font_selection_dialog_class_init (GtkFontSelectionDialogClass *klass)
1208 {
1209   g_type_class_add_private (klass, sizeof (GtkFontSelectionDialogPrivate));
1210 }
1211
1212 static void
1213 gtk_font_selection_dialog_init (GtkFontSelectionDialog *fontseldiag)
1214 {
1215   GtkFontSelectionDialogPrivate *priv;
1216   GtkDialog *dialog = GTK_DIALOG (fontseldiag);
1217   GtkWidget *action_area, *content_area;
1218
1219   fontseldiag->priv = G_TYPE_INSTANCE_GET_PRIVATE (fontseldiag,
1220                                                    GTK_TYPE_FONT_SELECTION_DIALOG,
1221                                                    GtkFontSelectionDialogPrivate);
1222   priv = fontseldiag->priv;
1223
1224   content_area = gtk_dialog_get_content_area (dialog);
1225   action_area = gtk_dialog_get_action_area (dialog);
1226
1227   gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
1228   gtk_box_set_spacing (GTK_BOX (content_area), 2); /* 2 * 5 + 2 = 12 */
1229   gtk_container_set_border_width (GTK_CONTAINER (action_area), 5);
1230   gtk_box_set_spacing (GTK_BOX (action_area), 6);
1231
1232   gtk_widget_push_composite_child ();
1233
1234   gtk_window_set_resizable (GTK_WINDOW (fontseldiag), TRUE);
1235
1236   /* Create the content area */
1237   priv->fontsel = gtk_font_selection_new ();
1238   gtk_container_set_border_width (GTK_CONTAINER (priv->fontsel), 5);
1239   gtk_widget_show (priv->fontsel);
1240   gtk_box_pack_start (GTK_BOX (content_area),
1241                       priv->fontsel, TRUE, TRUE, 0);
1242
1243   /* Create the action area */
1244   priv->cancel_button = gtk_dialog_add_button (dialog,
1245                                                GTK_STOCK_CANCEL,
1246                                                GTK_RESPONSE_CANCEL);
1247
1248   priv->apply_button = gtk_dialog_add_button (dialog,
1249                                               GTK_STOCK_APPLY,
1250                                               GTK_RESPONSE_APPLY);
1251   gtk_widget_hide (priv->apply_button);
1252
1253   priv->ok_button = gtk_dialog_add_button (dialog,
1254                                            GTK_STOCK_OK,
1255                                            GTK_RESPONSE_OK);
1256   gtk_widget_grab_default (priv->ok_button);
1257
1258   gtk_dialog_set_alternative_button_order (GTK_DIALOG (fontseldiag),
1259                                            GTK_RESPONSE_OK,
1260                                            GTK_RESPONSE_APPLY,
1261                                            GTK_RESPONSE_CANCEL,
1262                                            -1);
1263
1264   gtk_window_set_title (GTK_WINDOW (fontseldiag),
1265                         _("Font Selection"));
1266
1267   gtk_widget_pop_composite_child ();
1268 }
1269
1270 /**
1271  * gtk_font_selection_dialog_new:
1272  * @title: the title of the dialog window 
1273  *
1274  * Creates a new #GtkFontSelectionDialog.
1275  *
1276  * Return value: a new #GtkFontSelectionDialog
1277  */
1278 GtkWidget*
1279 gtk_font_selection_dialog_new (const gchar *title)
1280 {
1281   GtkFontSelectionDialog *fontseldiag;
1282   
1283   fontseldiag = g_object_new (GTK_TYPE_FONT_SELECTION_DIALOG, NULL);
1284
1285   if (title)
1286     gtk_window_set_title (GTK_WINDOW (fontseldiag), title);
1287   
1288   return GTK_WIDGET (fontseldiag);
1289 }
1290
1291 /**
1292  * gtk_font_selection_dialog_get_font_selection:
1293  * @fsd: a #GtkFontSelectionDialog
1294  *
1295  * Retrieves the #GtkFontSelection widget embedded in the dialog.
1296  *
1297  * Returns: (transfer none): the embedded #GtkFontSelection
1298  *
1299  * Since: 2.22
1300  **/
1301 GtkWidget*
1302 gtk_font_selection_dialog_get_font_selection (GtkFontSelectionDialog *fsd)
1303 {
1304   g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1305
1306   return fsd->priv->fontsel;
1307 }
1308
1309
1310 /**
1311  * gtk_font_selection_dialog_get_ok_button:
1312  * @fsd: a #GtkFontSelectionDialog
1313  *
1314  * Gets the 'OK' button.
1315  *
1316  * Return value: (transfer none): the #GtkWidget used in the dialog
1317  *     for the 'OK' button.
1318  *
1319  * Since: 2.14
1320  */
1321 GtkWidget *
1322 gtk_font_selection_dialog_get_ok_button (GtkFontSelectionDialog *fsd)
1323 {
1324   g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1325
1326   return fsd->priv->ok_button;
1327 }
1328
1329 /**
1330  * gtk_font_selection_dialog_get_cancel_button:
1331  * @fsd: a #GtkFontSelectionDialog
1332  *
1333  * Gets the 'Cancel' button.
1334  *
1335  * Return value: (transfer none): the #GtkWidget used in the dialog
1336  *     for the 'Cancel' button.
1337  *
1338  * Since: 2.14
1339  */
1340 GtkWidget *
1341 gtk_font_selection_dialog_get_cancel_button (GtkFontSelectionDialog *fsd)
1342 {
1343   g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1344
1345   return fsd->priv->cancel_button;
1346 }
1347
1348 static void
1349 gtk_font_selection_dialog_buildable_interface_init (GtkBuildableIface *iface)
1350 {
1351   parent_buildable_iface = g_type_interface_peek_parent (iface);
1352   iface->get_internal_child = gtk_font_selection_dialog_buildable_get_internal_child;
1353 }
1354
1355 static GObject *
1356 gtk_font_selection_dialog_buildable_get_internal_child (GtkBuildable *buildable,
1357                                                         GtkBuilder   *builder,
1358                                                         const gchar  *childname)
1359 {
1360   GtkFontSelectionDialogPrivate *priv;
1361
1362   priv = GTK_FONT_SELECTION_DIALOG (buildable)->priv;
1363
1364   if (g_strcmp0 (childname, "ok_button") == 0)
1365     return G_OBJECT (priv->ok_button);
1366   else if (g_strcmp0 (childname, "cancel_button") == 0)
1367     return G_OBJECT (priv->cancel_button);
1368   else if (g_strcmp0 (childname, "apply_button") == 0)
1369     return G_OBJECT (priv->apply_button);
1370   else if (g_strcmp0 (childname, "font_selection") == 0)
1371     return G_OBJECT (priv->fontsel);
1372
1373   return parent_buildable_iface->get_internal_child (buildable, builder, childname);
1374 }
1375
1376 /**
1377  * gtk_font_selection_dialog_get_font_name:
1378  * @fsd: a #GtkFontSelectionDialog
1379  * 
1380  * Gets the currently-selected font name.
1381  *
1382  * Note that this can be a different string than what you set with 
1383  * gtk_font_selection_dialog_set_font_name(), as the font selection widget
1384  * may normalize font names and thus return a string with a different 
1385  * structure. For example, "Helvetica Italic Bold 12" could be normalized 
1386  * to "Helvetica Bold Italic 12".  Use pango_font_description_equal()
1387  * if you want to compare two font descriptions.
1388  * 
1389  * Return value: A string with the name of the current font, or %NULL if no 
1390  *     font is selected. You must free this string with g_free().
1391  */
1392 gchar*
1393 gtk_font_selection_dialog_get_font_name (GtkFontSelectionDialog *fsd)
1394 {
1395   GtkFontSelectionDialogPrivate *priv;
1396
1397   g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1398
1399   priv = fsd->priv;
1400
1401   return gtk_font_selection_get_font_name (GTK_FONT_SELECTION (priv->fontsel));
1402 }
1403
1404 /**
1405  * gtk_font_selection_dialog_set_font_name:
1406  * @fsd: a #GtkFontSelectionDialog
1407  * @fontname: a font name like "Helvetica 12" or "Times Bold 18"
1408  *
1409  * Sets the currently selected font. 
1410  * 
1411  * Return value: %TRUE if the font selected in @fsd is now the
1412  *     @fontname specified, %FALSE otherwise. 
1413  */
1414 gboolean
1415 gtk_font_selection_dialog_set_font_name (GtkFontSelectionDialog *fsd,
1416                                          const gchar            *fontname)
1417 {
1418   GtkFontSelectionDialogPrivate *priv;
1419
1420   g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), FALSE);
1421   g_return_val_if_fail (fontname, FALSE);
1422
1423   priv = fsd->priv;
1424
1425   return gtk_font_selection_set_font_name (GTK_FONT_SELECTION (priv->fontsel), fontname);
1426 }
1427
1428 /**
1429  * gtk_font_selection_dialog_get_preview_text:
1430  * @fsd: a #GtkFontSelectionDialog
1431  *
1432  * Gets the text displayed in the preview area.
1433  * 
1434  * Return value: the text displayed in the preview area. 
1435  *     This string is owned by the widget and should not be 
1436  *     modified or freed 
1437  */
1438 G_CONST_RETURN gchar*
1439 gtk_font_selection_dialog_get_preview_text (GtkFontSelectionDialog *fsd)
1440 {
1441   GtkFontSelectionDialogPrivate *priv;
1442
1443   g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1444
1445   priv = fsd->priv;
1446
1447   return gtk_font_selection_get_preview_text (GTK_FONT_SELECTION (priv->fontsel));
1448 }
1449
1450 /**
1451  * gtk_font_selection_dialog_set_preview_text:
1452  * @fsd: a #GtkFontSelectionDialog
1453  * @text: the text to display in the preview area
1454  *
1455  * Sets the text displayed in the preview area. 
1456  */
1457 void
1458 gtk_font_selection_dialog_set_preview_text (GtkFontSelectionDialog *fsd,
1459                                             const gchar            *text)
1460 {
1461   GtkFontSelectionDialogPrivate *priv;
1462
1463   g_return_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd));
1464   g_return_if_fail (text != NULL);
1465
1466   priv = fsd->priv;
1467
1468   gtk_font_selection_set_preview_text (GTK_FONT_SELECTION (priv->fontsel), text);
1469 }