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