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