]> Pileus Git - ~andy/gtk/blob - gtk/gtkfontchooser.c
GtkFontChooser: Add deprecated calls to the test
[~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   /*FIXME: Remove these two strings for 4.0 */
164   FAMILY_NAME_COLUMN,
165   FACE_NAME_COLUMN
166 };
167
168 static void  gtk_font_selection_set_property       (GObject         *object,
169                                                     guint            prop_id,
170                                                     const GValue    *value,
171                                                     GParamSpec      *pspec);
172 static void  gtk_font_selection_get_property       (GObject         *object,
173                                                     guint            prop_id,
174                                                     GValue          *value,
175                                                     GParamSpec      *pspec);
176 static void  gtk_font_selection_finalize           (GObject         *object);
177
178 #if 0
179 static void  gtk_font_selection_screen_changed     (GtkWidget       *widget,
180                                                     GdkScreen       *previous_screen);
181 static void  gtk_font_selection_style_updated      (GtkWidget      *widget);
182 #endif
183
184 static void  gtk_font_selection_ref_family        (GtkFontSelection *fontsel,
185                                                    PangoFontFamily  *family);
186 static void  gtk_font_selection_ref_face          (GtkFontSelection *fontsel,
187                                                    PangoFontFace    *face);
188
189 static void gtk_font_selection_bootstrap_fontlist (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 ("%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   /* Free resources */
520   g_object_unref ((gpointer)face);
521   pango_font_description_free(desc);
522 }
523
524 gboolean
525 zoom_preview_cb (GtkWidget *scrolled_window, GdkEventScroll *event, gpointer data)
526 {
527   GtkFontSelectionPrivate *priv = (GtkFontSelectionPrivate*)data;
528
529   GtkAdjustment *adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->size_spin));
530
531   if (event->direction == GDK_SCROLL_UP || event->direction == GDK_SCROLL_RIGHT)
532     gtk_adjustment_set_value (adj,
533                               gtk_adjustment_get_value (adj) +
534                               gtk_adjustment_get_step_increment (adj));
535   else if (event->direction == GDK_SCROLL_DOWN || event->direction == GDK_SCROLL_LEFT)
536     gtk_adjustment_set_value (adj,
537                               gtk_adjustment_get_value (adj) -
538                               gtk_adjustment_get_step_increment (adj));
539   return TRUE;
540 }
541
542 static void
543 gtk_font_selection_init (GtkFontSelection *fontsel)
544 {
545   GtkFontSelectionPrivate *priv;
546   PangoFontDescription    *font_desc;
547   GtkWidget               *scrolled_win;
548   GtkWidget               *alignment;
549   GtkWidget               *preview_and_size;
550   GtkWidget               *size_controls;
551
552   fontsel->priv = G_TYPE_INSTANCE_GET_PRIVATE (fontsel,
553                                                GTK_TYPE_FONT_SELECTION,
554                                                GtkFontSelectionPrivate);
555
556   priv = fontsel->priv;
557   priv->size_list = NULL;
558   priv->font_list = NULL;
559   priv->face_list = NULL;
560
561   priv->_size_model = NULL;
562   priv->_font_model = NULL;
563   priv->_face_model = NULL;
564
565   gtk_widget_push_composite_child ();
566
567   /* Creating fundamental widgets for the private struct */
568   priv->search_entry = gtk_entry_new ();
569   priv->family_face_list = gtk_tree_view_new ();
570   priv->preview = gtk_entry_new ();
571   priv->size_slider = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL,
572                                                 (gdouble) font_sizes[0],
573                                                 (gdouble) font_sizes[FONT_SIZES_LENGTH - 1],
574                                                 1.0);
575
576   priv->size_spin = gtk_spin_button_new_with_range (0.0, (gdouble)(G_MAXINT / PANGO_SCALE), 1.0);
577
578   /** Bootstrapping widget layout **/
579   gtk_box_set_spacing (GTK_BOX (fontsel), 6);
580   gtk_box_pack_start (GTK_BOX (fontsel), priv->search_entry, FALSE, TRUE, 0);
581
582   /* Main font family/face view */
583   scrolled_win = gtk_scrolled_window_new (NULL, NULL);
584   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
585                                   GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
586   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win),
587                                        GTK_SHADOW_ETCHED_IN);
588   gtk_container_add (GTK_CONTAINER (scrolled_win), priv->family_face_list);
589
590   /* Alignment for the preview and size controls */
591 /*  alignment = gtk_alignment_new (0.5, 0.5, 1.0, 1.0);
592   gtk_alignment_set_padding (GTK_ALIGNMENT (alignment),
593                              PREVIEW_TOP_PADDING, 0, 0, 0);*/
594   gtk_box_pack_start (GTK_BOX (fontsel), scrolled_win, TRUE, TRUE, 0);
595
596   preview_and_size = gtk_vbox_new (TRUE, 0);
597   gtk_box_set_homogeneous (GTK_BOX (preview_and_size), FALSE);
598   gtk_box_set_spacing (GTK_BOX (preview_and_size), 6);
599
600   /* The preview entry needs a scrolled window to make sure we have a */
601   scrolled_win = gtk_scrolled_window_new (NULL, NULL);
602   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
603                                   GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
604   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win),
605                                        GTK_SHADOW_ETCHED_IN);
606   gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_win),
607                                          priv->preview);
608   gtk_box_pack_start (GTK_BOX (preview_and_size), scrolled_win, FALSE, FALSE, 0);
609   
610   /* Setting the size requests for various widgets */
611   gtk_widget_set_size_request (GTK_WIDGET (fontsel), FONTSEL_WIDTH, FONTSEL_HEIGHT);
612   gtk_widget_set_size_request (scrolled_win,  -1, PREVIEW_HEIGHT);
613   gtk_widget_set_size_request (priv->preview, -1, PREVIEW_HEIGHT - 6);
614
615   /* Unset the frame on the preview entry */
616   gtk_entry_set_has_frame (GTK_ENTRY (priv->preview), FALSE);
617
618   /* Packing the slider and the spin in a hbox */
619   size_controls = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
620   gtk_scale_set_draw_value (GTK_SCALE (priv->size_slider), FALSE);
621   gtk_box_set_spacing (GTK_BOX (size_controls), 6);
622   gtk_box_pack_start  (GTK_BOX (size_controls), priv->size_slider, TRUE, TRUE, 0);
623   gtk_box_pack_start  (GTK_BOX (size_controls), priv->size_spin, FALSE, TRUE, 0);
624   
625   gtk_widget_set_valign (priv->size_spin, GTK_ALIGN_START);
626
627   gtk_box_pack_start (GTK_BOX (preview_and_size), size_controls, FALSE, FALSE, 0);
628 //  gtk_container_add (GTK_CONTAINER (alignment), preview_and_size);
629
630   gtk_box_pack_start (GTK_BOX (fontsel), GTK_WIDGET(preview_and_size), FALSE, TRUE, 0);
631
632   /* Getting the default size */
633   font_desc  = pango_context_get_font_description (gtk_widget_get_pango_context (GTK_WIDGET (fontsel)));
634   priv->size = pango_font_description_get_size (font_desc);
635   priv->face = NULL;
636   priv->family = NULL;
637   
638   gtk_adjustment_set_value (gtk_range_get_adjustment (GTK_RANGE (priv->size_slider)),
639                             (gdouble)(priv->size / PANGO_SCALE));
640   gtk_adjustment_set_value (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->size_spin)),
641                             (gdouble)(priv->size / PANGO_SCALE));
642
643   gtk_widget_show_all (GTK_WIDGET (fontsel));
644   gtk_widget_hide (GTK_WIDGET (fontsel));
645
646   /* Treeview column and model bootstrapping */
647   gtk_font_selection_bootstrap_fontlist (fontsel);
648   
649   /* Set default preview text */
650   gtk_entry_set_text (GTK_ENTRY (priv->preview),
651                       pango_language_get_sample_string (NULL));
652   
653   /* Set search icon and place holder text */
654   gtk_entry_set_icon_from_stock (GTK_ENTRY (priv->search_entry),
655                                  GTK_ENTRY_ICON_SECONDARY,
656                                  GTK_STOCK_FIND);
657   gtk_entry_set_placeholder_text (GTK_ENTRY (priv->search_entry), _("Search font name"));
658   
659   /** Callback connections **/
660   /* Connect to callback for the live search text entry */
661   g_signal_connect (G_OBJECT (gtk_entry_get_buffer (GTK_ENTRY (priv->search_entry))),
662                     "deleted-text", G_CALLBACK (deleted_text_cb), priv);
663   g_signal_connect (G_OBJECT (gtk_entry_get_buffer (GTK_ENTRY (priv->search_entry))),
664                     "inserted-text", G_CALLBACK (inserted_text_cb), priv);
665   g_signal_connect (G_OBJECT (priv->search_entry),
666                     "icon-press", G_CALLBACK (icon_press_cb), priv);
667
668   /* Size controls callbacks */
669   g_signal_connect (G_OBJECT (gtk_range_get_adjustment (GTK_RANGE (priv->size_slider))),
670                     "value-changed", G_CALLBACK (slider_change_cb), priv);
671   g_signal_connect (G_OBJECT (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->size_spin))),
672                     "value-changed", G_CALLBACK (spin_change_cb), priv);
673   priv->ignore_slider = FALSE;
674   
675   /* Font selection callback */
676   g_signal_connect (G_OBJECT (priv->family_face_list), "cursor-changed",
677                     G_CALLBACK (cursor_changed_cb),    fontsel);
678
679   /* Zoom on preview scroll*/
680   g_signal_connect (G_OBJECT (scrolled_win),      "scroll-event",
681                     G_CALLBACK (zoom_preview_cb), priv);
682
683   g_signal_connect (G_OBJECT (priv->size_slider), "scroll-event",
684                     G_CALLBACK (zoom_preview_cb), priv);
685
686   set_range_marks (priv, priv->size_slider, (gint*)font_sizes, FONT_SIZES_LENGTH);
687
688   /* Set default focus */
689   gtk_widget_pop_composite_child();
690 }
691
692 /**
693  * gtk_font_selection_new:
694  *
695  * Creates a new #GtkFontSelection.
696  *
697  * Return value: a new #GtkFontSelection
698  */
699 GtkWidget *
700 gtk_font_selection_new (void)
701 {
702   GtkFontSelection *fontsel;
703   
704   fontsel = g_object_new (GTK_TYPE_FONT_SELECTION, NULL);
705   
706   return GTK_WIDGET (fontsel);
707 }
708
709 static int
710 cmp_families (const void *a, const void *b)
711 {
712   const char *a_name = pango_font_family_get_name (*(PangoFontFamily **)a);
713   const char *b_name = pango_font_family_get_name (*(PangoFontFamily **)b);
714
715   return g_utf8_collate (a_name, b_name);
716 }
717
718 static void 
719 populate_list (GtkTreeView* treeview, GtkListStore* model)
720 {
721   GtkStyleContext *style_context;
722   GdkRGBA          g_color;
723   PangoColor       p_color;
724   gchar            *color_string;
725
726   GtkTreeIter   match_row;
727   GtkTreePath  *path;
728
729   gint n_families, i;  
730   PangoFontFamily **families;
731
732   GString     *tmp = g_string_new (NULL);
733   GString     *family_and_face = g_string_new (NULL);
734
735   pango_context_list_families (gtk_widget_get_pango_context (GTK_WIDGET (treeview)),
736                                &families,
737                                &n_families);
738
739   qsort (families, n_families, sizeof (PangoFontFamily *), cmp_families);
740
741   gtk_list_store_clear (model);
742
743   /* Get row header font color */
744   style_context = gtk_widget_get_style_context (GTK_WIDGET (treeview));
745   gtk_style_context_get_color (style_context,
746                                GTK_STATE_FLAG_NORMAL |GTK_STATE_FLAG_INSENSITIVE,
747                                &g_color);
748
749   p_color.red   = (guint16)((gdouble)G_MAXUINT16 * g_color.red);
750   p_color.green = (guint16)((gdouble)G_MAXUINT16 * g_color.green);
751   p_color.blue  = (guint16)((gdouble)G_MAXUINT16 * g_color.blue);
752   color_string  = pango_color_to_string (&p_color);
753
754   /* Iterate over families and faces */
755   for (i=0; i<n_families; i++)
756     {
757       GtkTreeIter     iter;
758       PangoFontFace **faces;
759       
760       int             j, n_faces;
761       const gchar    *fam_name = pango_font_family_get_name (families[i]);
762
763       pango_font_family_list_faces (families[i], &faces, &n_faces);
764       
765       for (j=0; j<n_faces; j++)
766         {
767           PangoFontDescription *pango_desc = pango_font_face_describe (faces[j]);
768           const gchar *face_name = pango_font_face_get_face_name (faces[j]);
769           gchar       *font_desc = pango_font_description_to_string (pango_desc);
770           
771           /* foreground_color, family_name, face_name, desc, sample string */
772           g_string_printf (family_and_face, "%s %s",
773                                             fam_name,
774                                             face_name);
775           
776           g_string_printf (tmp, ROW_FORMAT_STRING,
777                                 color_string,
778                                 family_and_face->str,
779                                 font_desc,
780                                 pango_language_get_sample_string (NULL));
781
782           gtk_list_store_append (model, &iter);
783           gtk_list_store_set (model, &iter,
784                               FAMILY_COLUMN, families[i],
785                               FACE_COLUMN, faces[j],
786                               PREVIEW_TITLE_COLUMN, family_and_face->str,
787                               PREVIEW_TEXT_COLUMN, tmp->str,
788                               /** FIXME: FAMILY_NAME_COLUMN and FACE_NAME_COLUMN
789                                   are needed only until we remove the deprecated
790                                   API **/
791                               FAMILY_NAME_COLUMN, fam_name,
792                               FACE_NAME_COLUMN, face_name,
793                               -1);
794
795           if ((i == 0 && j == 0) ||
796               (!g_ascii_strcasecmp (face_name, "sans") && j == 0))
797             {
798               match_row = iter;
799             }
800
801           pango_font_description_free(pango_desc);
802           g_free (font_desc);
803         }
804
805       g_free (faces);
806     }
807
808   path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &match_row);
809   
810   if (path)
811   {
812     gtk_tree_view_set_cursor (treeview, path, NULL, FALSE);
813     gtk_tree_path_free(path);
814   }
815
816
817   g_string_free (family_and_face, TRUE);
818   g_string_free (tmp, TRUE);
819   g_free (color_string);
820   g_free (families);
821 }
822
823 gboolean
824 visible_func (GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
825 {
826   gboolean result = FALSE;
827   GtkFontSelectionPrivate *priv = (GtkFontSelectionPrivate*) data;
828
829   const gchar *search_text = (const gchar*)gtk_entry_get_text (GTK_ENTRY (priv->search_entry));
830   gchar       *font_name;
831   gchar       *font_name_casefold;
832   gchar       *search_text_casefold;
833
834   gtk_tree_model_get (model, iter,
835                       PREVIEW_TITLE_COLUMN, &font_name,
836                       -1);
837
838   /* Covering some corner cases to speed up the result */
839   if (font_name == NULL ||
840       strlen (search_text) > strlen (font_name))
841     {
842       g_free (font_name);
843       return FALSE;
844     }  
845   if (strlen (search_text) == 0)
846     {
847       g_free (font_name);
848       return TRUE;
849     }
850   
851   font_name_casefold = g_utf8_casefold (font_name, -1);
852   search_text_casefold = g_utf8_casefold (search_text, -1);
853   
854   if (g_strrstr (font_name_casefold, search_text_casefold))
855     result = TRUE;
856
857   g_free (search_text_casefold);
858   g_free (font_name_casefold);
859   g_free (font_name);
860   return result;
861 }
862
863 static void
864 gtk_font_selection_bootstrap_fontlist (GtkFontSelection* fontsel)
865 {
866   GtkTreeView       *treeview = GTK_TREE_VIEW (fontsel->priv->family_face_list);
867   GtkCellRenderer   *cell;
868   GtkTreeViewColumn *col;
869
870   fontsel->priv->model = gtk_list_store_new (6,
871                                              PANGO_TYPE_FONT_FAMILY,
872                                              PANGO_TYPE_FONT_FACE,
873                                              G_TYPE_STRING,
874                                              G_TYPE_STRING,
875                                              /*FIXME: Remove two strings after deprecation removal */
876                                              G_TYPE_STRING,
877                                              G_TYPE_STRING);
878
879   fontsel->priv->filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fontsel->priv->model),
880                                                      NULL);
881   g_object_unref (fontsel->priv->model);
882
883   gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (fontsel->priv->filter),
884                                           visible_func,
885                                           (gpointer)fontsel->priv,
886                                           NULL);
887
888   gtk_tree_view_set_model (treeview, GTK_TREE_MODEL (fontsel->priv->filter));
889   g_object_unref (fontsel->priv->filter);
890
891   gtk_tree_view_set_rules_hint      (treeview, TRUE);
892   gtk_tree_view_set_headers_visible (treeview, FALSE);
893
894   cell = gtk_cell_renderer_text_new ();
895   col = gtk_tree_view_column_new_with_attributes ("Family",
896                                                   cell,
897                                                   "markup", PREVIEW_TEXT_COLUMN,
898                                                   NULL);
899                                                   
900
901   g_object_set (cell, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
902
903   gtk_tree_view_append_column (treeview, col);
904
905   populate_list (treeview, fontsel->priv->model);
906 }
907
908
909 static void
910 gtk_font_selection_finalize (GObject *object)
911 {
912   GtkFontSelection *fontsel = GTK_FONT_SELECTION (object);
913
914   gtk_font_selection_ref_family (fontsel, NULL);
915   gtk_font_selection_ref_face (fontsel, NULL);
916
917   G_OBJECT_CLASS (gtk_font_selection_parent_class)->finalize (object);
918 }
919
920 #if 0
921 static void
922 gtk_font_selection_screen_changed (GtkWidget *widget,
923                                    GdkScreen *previous_screen)
924 {
925   return;
926 }
927
928 static void
929 gtk_font_selection_style_updated (GtkWidget *widget)
930 {
931   /*GTK_WIDGET_CLASS (gtk_font_selection_parent_class)->style_updated (widget);*/
932   return;
933 }
934 #endif 
935
936 static void
937 gtk_font_selection_ref_family (GtkFontSelection *fontsel,
938                                PangoFontFamily  *family)
939 {
940   GtkFontSelectionPrivate *priv = fontsel->priv;
941
942   if (family)
943     family = g_object_ref (family);
944   if (priv->family)
945     g_object_unref (priv->family);
946   priv->family = family;
947 }
948
949 static void
950 gtk_font_selection_ref_face (GtkFontSelection *fontsel,
951                              PangoFontFace    *face)
952 {
953   GtkFontSelectionPrivate *priv = fontsel->priv;
954
955   if (face)
956     face = g_object_ref (face);
957   if (priv->face)
958     g_object_unref (priv->face);
959   priv->face = face;
960 }
961
962 /* These functions populate the deprecated widgets to maintain API compatibility */
963 static void
964 populate_font_model (GtkFontSelection *fontsel)
965 {
966   GtkFontSelectionPrivate *priv = fontsel->priv;
967 }
968
969 static void
970 update_font_model_selection (GtkFontSelection *fontsel)
971 {
972   GtkFontSelectionPrivate *priv = fontsel->priv;
973 }
974
975 static void
976 update_face_model (GtkFontSelection *fontsel)
977 {
978   GtkFontSelectionPrivate *priv = fontsel->priv;
979 }
980
981 static void
982 update_size_model (GtkFontSelection *fontsel)
983 {
984   GtkFontSelectionPrivate *priv = fontsel->priv;
985 }
986
987 static void
988 initialize_deprecated_widgets (GtkFontSelection *fontsel)
989 {
990   GtkFontSelectionPrivate *priv = fontsel->priv;
991
992   priv->_size_model = gtk_list_store_new (2, G_TYPE_INT, G_TYPE_STRING);
993   priv->_font_model = gtk_list_store_new (2, PANGO_TYPE_FONT_FAMILY, G_TYPE_STRING);
994   priv->_face_model = gtk_list_store_new (2, PANGO_TYPE_FONT_FACE,   G_TYPE_STRING);
995
996   priv->size_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (priv->_size_model));
997   priv->font_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (priv->_font_model));
998   priv->face_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (priv->_size_model));
999
1000   g_object_unref (priv->_size_model);
1001   g_object_unref (priv->_font_model);
1002   g_object_unref (priv->_face_model);
1003 }
1004
1005 static void
1006 destroy_deprecated_widgets (GtkFontSelection *fontsel)
1007 {
1008   GtkFontSelectionPrivate *priv = fontsel->priv;
1009
1010   g_object_unref (priv->size_list);
1011   g_object_unref (priv->font_list);
1012   g_object_unref (priv->face_list);
1013 }
1014
1015 /*****************************************************************************
1016  * These functions are the main public interface for getting/setting the font.
1017  *****************************************************************************/
1018
1019 /**
1020  * gtk_font_selection_get_family_list:
1021  * @fontsel: a #GtkFontSelection
1022  *
1023  * This returns the #GtkTreeView that lists font families, for
1024  * example, 'Sans', 'Serif', etc.
1025  *
1026  * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1027  *
1028  * Deprecated: 3.2
1029  */
1030 GtkWidget *
1031 gtk_font_selection_get_family_list (GtkFontSelection *fontsel)
1032 {
1033   GtkFontSelectionPrivate *priv = fontsel->priv;
1034   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1035
1036   return NULL;
1037 }
1038
1039 /**
1040  * gtk_font_selection_get_face_list:
1041  * @fontsel: a #GtkFontSelection
1042  *
1043  * This returns the #GtkTreeView which lists all styles available for
1044  * the selected font. For example, 'Regular', 'Bold', etc.
1045  * 
1046  * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1047  *
1048  * Deprecated: 3.2
1049  */
1050 GtkWidget *
1051 gtk_font_selection_get_face_list (GtkFontSelection *fontsel)
1052 {
1053   GtkFontSelectionPrivate *priv = fontsel->priv;
1054   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1055
1056   return NULL;
1057 }
1058
1059 /**
1060  * gtk_font_selection_get_size_entry:
1061  * @fontsel: a #GtkFontSelection
1062  *
1063  * This returns the #GtkEntry used to allow the user to edit the font
1064  * number manually instead of selecting it from the list of font sizes.
1065  *
1066  * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1067  *
1068  * Deprecated: 3.2
1069  */
1070 GtkWidget *
1071 gtk_font_selection_get_size_entry (GtkFontSelection *fontsel)
1072 {
1073   GtkFontSelectionPrivate *priv = fontsel->priv;
1074   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1075
1076   return priv->size_spin;
1077 }
1078
1079 /**
1080  * gtk_font_selection_get_size_list:
1081  * @fontsel: a #GtkFontSelection
1082  *
1083  * This returns the #GtkTreeeView used to list font sizes.
1084  *
1085  * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1086  *
1087  * Deprecated: 3.2
1088  */
1089 GtkWidget *
1090 gtk_font_selection_get_size_list (GtkFontSelection *fontsel)
1091 {
1092   GtkFontSelectionPrivate *priv = fontsel->priv;
1093   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1094
1095   return NULL;
1096 }
1097
1098 /**
1099  * gtk_font_selection_get_preview_entry:
1100  * @fontsel: a #GtkFontSelection
1101  *
1102  * This returns the #GtkEntry used to display the font as a preview.
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_preview_entry (GtkFontSelection *fontsel)
1110 {
1111   GtkFontSelectionPrivate *priv = fontsel->priv;
1112   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1113
1114   return priv->preview;
1115 }
1116
1117 /**
1118  * gtk_font_selection_get_family:
1119  * @fontsel: a #GtkFontSelection
1120  *
1121  * Gets the #PangoFontFamily representing the selected font family.
1122  *
1123  * Return value: (transfer none): A #PangoFontFamily representing the
1124  *     selected font family. Font families are a collection of font
1125  *     faces. The returned object is owned by @fontsel and must not
1126  *     be modified or freed.
1127  *
1128  * Since: 2.14
1129  */
1130 PangoFontFamily *
1131 gtk_font_selection_get_family (GtkFontSelection *fontsel)
1132 {
1133   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1134
1135   return NULL;
1136 }
1137
1138 /**
1139  * gtk_font_selection_get_face:
1140  * @fontsel: a #GtkFontSelection
1141  *
1142  * Gets the #PangoFontFace representing the selected font group
1143  * details (i.e. family, slant, weight, width, etc).
1144  *
1145  * Return value: (transfer none): A #PangoFontFace representing the
1146  *     selected font group details. The returned object is owned by
1147  *     @fontsel and must not be modified or freed.
1148  *
1149  * Since: 2.14
1150  */
1151 PangoFontFace *
1152 gtk_font_selection_get_face (GtkFontSelection *fontsel)
1153 {
1154   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1155
1156   return NULL;
1157 }
1158
1159 /**
1160  * gtk_font_selection_get_size:
1161  * @fontsel: a #GtkFontSelection
1162  *
1163  * The selected font size.
1164  *
1165  * Return value: A n integer representing the selected font size,
1166  *     or -1 if no font size is selected.
1167  *
1168  * Since: 2.14
1169  **/
1170 gint
1171 gtk_font_selection_get_size (GtkFontSelection *fontsel)
1172 {
1173   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), -1);
1174
1175   return fontsel->priv->size;
1176 }
1177
1178 /**
1179  * gtk_font_selection_get_font_name:
1180  * @fontsel: a #GtkFontSelection
1181  * 
1182  * Gets the currently-selected font name. 
1183  *
1184  * Note that this can be a different string than what you set with 
1185  * gtk_font_selection_set_font_name(), as the font selection widget may 
1186  * normalize font names and thus return a string with a different structure. 
1187  * For example, "Helvetica Italic Bold 12" could be normalized to 
1188  * "Helvetica Bold Italic 12". Use pango_font_description_equal()
1189  * if you want to compare two font descriptions.
1190  * 
1191  * Return value: (transfer full) (allow-none): A string with the name of the
1192  *     current font, or %NULL if  no font is selected. You must free this
1193  *     string with g_free().
1194  */
1195 gchar *
1196 gtk_font_selection_get_font_name (GtkFontSelection *fontsel)
1197 {
1198   if (!fontsel->priv->family)
1199     return NULL;
1200
1201   return g_strdup (pango_font_family_get_name (fontsel->priv->family));
1202 }
1203
1204 /* This sets the current font, then selecting the appropriate list rows. */
1205
1206 /**
1207  * gtk_font_selection_set_font_name:
1208  * @fontsel: a #GtkFontSelection
1209  * @fontname: a font name like "Helvetica 12" or "Times Bold 18"
1210  * 
1211  * Sets the currently-selected font. 
1212  *
1213  * Note that the @fontsel needs to know the screen in which it will appear 
1214  * for this to work; this can be guaranteed by simply making sure that the 
1215  * @fontsel is inserted in a toplevel window before you call this function.
1216  * 
1217  * Return value: %TRUE if the font could be set successfully; %FALSE if no 
1218  *     such font exists or if the @fontsel doesn't belong to a particular 
1219  *     screen yet.
1220  */
1221 gboolean
1222 gtk_font_selection_set_font_name (GtkFontSelection *fontsel,
1223           const gchar      *fontname)
1224 {
1225 #if 0
1226   PangoFontFamily *family = NULL;
1227   PangoFontFace *face = NULL;
1228   PangoFontDescription *new_desc;
1229 #endif
1230
1231   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), FALSE);
1232
1233   return TRUE;
1234 }
1235
1236 /**
1237  * gtk_font_selection_get_preview_text:
1238  * @fontsel: a #GtkFontSelection
1239  *
1240  * Gets the text displayed in the preview area.
1241  * 
1242  * Return value: the text displayed in the preview area. 
1243  *     This string is owned by the widget and should not be 
1244  *     modified or freed 
1245  */
1246 G_CONST_RETURN gchar*
1247 gtk_font_selection_get_preview_text (GtkFontSelection *fontsel)
1248 {
1249   return NULL;
1250 }
1251
1252
1253 /**
1254  * gtk_font_selection_set_preview_text:
1255  * @fontsel: a #GtkFontSelection
1256  * @text: the text to display in the preview area 
1257  *
1258  * Sets the text displayed in the preview area.
1259  * The @text is used to show how the selected font looks.
1260  */
1261 void
1262 gtk_font_selection_set_preview_text  (GtkFontSelection *fontsel,
1263               const gchar      *text)
1264 {
1265 #if 0
1266   GtkFontSelectionPrivate *priv;
1267
1268   g_return_if_fail (GTK_IS_FONT_SELECTION (fontsel));
1269   g_return_if_fail (text != NULL);
1270
1271   priv = fontsel->priv;
1272 #endif
1273 }
1274
1275
1276 /**
1277  * SECTION:gtkfontseldlg
1278  * @Short_description: A dialog box for selecting fonts
1279  * @Title: GtkFontSelectionDialog
1280  * @See_also: #GtkFontSelection, #GtkDialog
1281  *
1282  * The #GtkFontSelectionDialog widget is a dialog box for selecting a font.
1283  *
1284  * To set the font which is initially selected, use
1285  * gtk_font_selection_dialog_set_font_name().
1286  *
1287  * To get the selected font use gtk_font_selection_dialog_get_font_name().
1288  *
1289  * To change the text which is shown in the preview area, use
1290  * gtk_font_selection_dialog_set_preview_text().
1291  *
1292  * <refsect2 id="GtkFontSelectionDialog-BUILDER-UI">
1293  * <title>GtkFontSelectionDialog as GtkBuildable</title>
1294  * The GtkFontSelectionDialog implementation of the GtkBuildable interface
1295  * exposes the embedded #GtkFontSelection as internal child with the
1296  * name "font_selection". It also exposes the buttons with the names
1297  * "ok_button", "cancel_button" and "apply_button".
1298  * </refsect2>
1299  */
1300
1301 static void gtk_font_selection_dialog_buildable_interface_init     (GtkBuildableIface *iface);
1302 static GObject * gtk_font_selection_dialog_buildable_get_internal_child (GtkBuildable *buildable,
1303                     GtkBuilder   *builder,
1304                     const gchar  *childname);
1305
1306 G_DEFINE_TYPE_WITH_CODE (GtkFontSelectionDialog, gtk_font_selection_dialog,
1307        GTK_TYPE_DIALOG,
1308        G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
1309             gtk_font_selection_dialog_buildable_interface_init))
1310
1311 static GtkBuildableIface *parent_buildable_iface;
1312
1313 static void
1314 gtk_font_selection_dialog_class_init (GtkFontSelectionDialogClass *klass)
1315 {
1316   g_type_class_add_private (klass, sizeof (GtkFontSelectionDialogPrivate));
1317 }
1318
1319 static void
1320 gtk_font_selection_dialog_init (GtkFontSelectionDialog *fontseldiag)
1321 {
1322   GtkFontSelectionDialogPrivate *priv;
1323   GtkDialog *dialog = GTK_DIALOG (fontseldiag);
1324   GtkWidget *action_area, *content_area;
1325
1326   fontseldiag->priv = G_TYPE_INSTANCE_GET_PRIVATE (fontseldiag,
1327                                                    GTK_TYPE_FONT_SELECTION_DIALOG,
1328                                                    GtkFontSelectionDialogPrivate);
1329   priv = fontseldiag->priv;
1330
1331   content_area = gtk_dialog_get_content_area (dialog);
1332   action_area = gtk_dialog_get_action_area (dialog);
1333
1334   gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
1335   gtk_box_set_spacing (GTK_BOX (content_area), 2); /* 2 * 5 + 2 = 12 */
1336   gtk_container_set_border_width (GTK_CONTAINER (action_area), 5);
1337   gtk_box_set_spacing (GTK_BOX (action_area), 6);
1338
1339   gtk_widget_push_composite_child ();
1340
1341   gtk_window_set_resizable (GTK_WINDOW (fontseldiag), TRUE);
1342
1343   /* Create the content area */
1344   priv->fontsel = gtk_font_selection_new ();
1345   gtk_container_set_border_width (GTK_CONTAINER (priv->fontsel), 5);
1346   gtk_widget_show (priv->fontsel);
1347   gtk_box_pack_start (GTK_BOX (content_area),
1348           priv->fontsel, TRUE, TRUE, 0);
1349
1350   /* Create the action area */
1351   priv->cancel_button = gtk_dialog_add_button (dialog,
1352                                                GTK_STOCK_CANCEL,
1353                                                GTK_RESPONSE_CANCEL);
1354
1355   priv->apply_button = gtk_dialog_add_button (dialog,
1356                                               GTK_STOCK_APPLY,
1357                                               GTK_RESPONSE_APPLY);
1358   gtk_widget_hide (priv->apply_button);
1359
1360   priv->ok_button = gtk_dialog_add_button (dialog,
1361                                            GTK_STOCK_OK,
1362                                            GTK_RESPONSE_OK);
1363   gtk_widget_grab_default (priv->ok_button);
1364
1365   gtk_dialog_set_alternative_button_order (GTK_DIALOG (fontseldiag),
1366              GTK_RESPONSE_OK,
1367              GTK_RESPONSE_APPLY,
1368              GTK_RESPONSE_CANCEL,
1369              -1);
1370
1371   gtk_window_set_title (GTK_WINDOW (fontseldiag),
1372                         _("Font Selection"));
1373
1374   gtk_widget_pop_composite_child ();
1375 }
1376
1377 /**
1378  * gtk_font_selection_dialog_new:
1379  * @title: the title of the dialog window 
1380  *
1381  * Creates a new #GtkFontSelectionDialog.
1382  *
1383  * Return value: a new #GtkFontSelectionDialog
1384  */
1385 GtkWidget*
1386 gtk_font_selection_dialog_new (const gchar *title)
1387 {
1388   GtkFontSelectionDialog *fontseldiag;
1389   
1390   fontseldiag = g_object_new (GTK_TYPE_FONT_SELECTION_DIALOG, NULL);
1391
1392   if (title)
1393     gtk_window_set_title (GTK_WINDOW (fontseldiag), title);
1394   
1395   return GTK_WIDGET (fontseldiag);
1396 }
1397
1398 /**
1399  * gtk_font_selection_dialog_get_font_selection:
1400  * @fsd: a #GtkFontSelectionDialog
1401  *
1402  * Retrieves the #GtkFontSelection widget embedded in the dialog.
1403  *
1404  * Returns: (transfer none): the embedded #GtkFontSelection
1405  *
1406  * Since: 2.22
1407  **/
1408 GtkWidget*
1409 gtk_font_selection_dialog_get_font_selection (GtkFontSelectionDialog *fsd)
1410 {
1411   g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1412
1413   return fsd->priv->fontsel;
1414 }
1415
1416
1417 /**
1418  * gtk_font_selection_dialog_get_ok_button:
1419  * @fsd: a #GtkFontSelectionDialog
1420  *
1421  * Gets the 'OK' button.
1422  *
1423  * Return value: (transfer none): the #GtkWidget used in the dialog
1424  *     for the 'OK' button.
1425  *
1426  * Since: 2.14
1427  */
1428 GtkWidget *
1429 gtk_font_selection_dialog_get_ok_button (GtkFontSelectionDialog *fsd)
1430 {
1431   g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1432
1433   return fsd->priv->ok_button;
1434 }
1435
1436 /**
1437  * gtk_font_selection_dialog_get_cancel_button:
1438  * @fsd: a #GtkFontSelectionDialog
1439  *
1440  * Gets the 'Cancel' button.
1441  *
1442  * Return value: (transfer none): the #GtkWidget used in the dialog
1443  *     for the 'Cancel' button.
1444  *
1445  * Since: 2.14
1446  */
1447 GtkWidget *
1448 gtk_font_selection_dialog_get_cancel_button (GtkFontSelectionDialog *fsd)
1449 {
1450   g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1451
1452   return fsd->priv->cancel_button;
1453 }
1454
1455 static void
1456 gtk_font_selection_dialog_buildable_interface_init (GtkBuildableIface *iface)
1457 {
1458   parent_buildable_iface = g_type_interface_peek_parent (iface);
1459   iface->get_internal_child = gtk_font_selection_dialog_buildable_get_internal_child;
1460 }
1461
1462 static GObject *
1463 gtk_font_selection_dialog_buildable_get_internal_child (GtkBuildable *buildable,
1464               GtkBuilder   *builder,
1465               const gchar  *childname)
1466 {
1467   GtkFontSelectionDialogPrivate *priv;
1468
1469   priv = GTK_FONT_SELECTION_DIALOG (buildable)->priv;
1470
1471   if (g_strcmp0 (childname, "ok_button") == 0)
1472     return G_OBJECT (priv->ok_button);
1473   else if (g_strcmp0 (childname, "cancel_button") == 0)
1474     return G_OBJECT (priv->cancel_button);
1475   else if (g_strcmp0 (childname, "apply_button") == 0)
1476     return G_OBJECT (priv->apply_button);
1477   else if (g_strcmp0 (childname, "font_selection") == 0)
1478     return G_OBJECT (priv->fontsel);
1479
1480   return parent_buildable_iface->get_internal_child (buildable, builder, childname);
1481 }
1482
1483 /**
1484  * gtk_font_selection_dialog_get_font_name:
1485  * @fsd: a #GtkFontSelectionDialog
1486  * 
1487  * Gets the currently-selected font name.
1488  *
1489  * Note that this can be a different string than what you set with 
1490  * gtk_font_selection_dialog_set_font_name(), as the font selection widget
1491  * may normalize font names and thus return a string with a different 
1492  * structure. For example, "Helvetica Italic Bold 12" could be normalized 
1493  * to "Helvetica Bold Italic 12".  Use pango_font_description_equal()
1494  * if you want to compare two font descriptions.
1495  * 
1496  * Return value: A string with the name of the current font, or %NULL if no 
1497  *     font is selected. You must free this string with g_free().
1498  */
1499 gchar*
1500 gtk_font_selection_dialog_get_font_name (GtkFontSelectionDialog *fsd)
1501 {
1502   GtkFontSelectionDialogPrivate *priv;
1503
1504   g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1505
1506   priv = fsd->priv;
1507
1508   return gtk_font_selection_get_font_name (GTK_FONT_SELECTION (priv->fontsel));
1509 }
1510
1511 /**
1512  * gtk_font_selection_dialog_set_font_name:
1513  * @fsd: a #GtkFontSelectionDialog
1514  * @fontname: a font name like "Helvetica 12" or "Times Bold 18"
1515  *
1516  * Sets the currently selected font. 
1517  * 
1518  * Return value: %TRUE if the font selected in @fsd is now the
1519  *     @fontname specified, %FALSE otherwise. 
1520  */
1521 gboolean
1522 gtk_font_selection_dialog_set_font_name (GtkFontSelectionDialog *fsd,
1523            const gchar          *fontname)
1524 {
1525   GtkFontSelectionDialogPrivate *priv;
1526
1527   g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), FALSE);
1528   g_return_val_if_fail (fontname, FALSE);
1529
1530   priv = fsd->priv;
1531
1532   return gtk_font_selection_set_font_name (GTK_FONT_SELECTION (priv->fontsel), fontname);
1533 }
1534
1535 /**
1536  * gtk_font_selection_dialog_get_preview_text:
1537  * @fsd: a #GtkFontSelectionDialog
1538  *
1539  * Gets the text displayed in the preview area.
1540  * 
1541  * Return value: the text displayed in the preview area. 
1542  *     This string is owned by the widget and should not be 
1543  *     modified or freed 
1544  */
1545 G_CONST_RETURN gchar*
1546 gtk_font_selection_dialog_get_preview_text (GtkFontSelectionDialog *fsd)
1547 {
1548   GtkFontSelectionDialogPrivate *priv;
1549
1550   g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1551
1552   priv = fsd->priv;
1553
1554   return gtk_font_selection_get_preview_text (GTK_FONT_SELECTION (priv->fontsel));
1555 }
1556
1557 /**
1558  * gtk_font_selection_dialog_set_preview_text:
1559  * @fsd: a #GtkFontSelectionDialog
1560  * @text: the text to display in the preview area
1561  *
1562  * Sets the text displayed in the preview area. 
1563  */
1564 void
1565 gtk_font_selection_dialog_set_preview_text (GtkFontSelectionDialog *fsd,
1566               const gchar            *text)
1567 {
1568   GtkFontSelectionDialogPrivate *priv;
1569
1570   g_return_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd));
1571   g_return_if_fail (text != NULL);
1572
1573   priv = fsd->priv;
1574
1575   gtk_font_selection_set_preview_text (GTK_FONT_SELECTION (priv->fontsel), text);
1576 }