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