]> Pileus Git - ~andy/gtk/blob - gtk/gtkfontchooser.c
GtkFontChooser: Iterate over faces as well as families to list them
[~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
64
65 /**
66  * SECTION:gtkfontsel
67  * @Short_description: A widget for selecting fonts
68  * @Title: GtkFontSelection
69  * @See_also: #GtkFontSelectionDialog
70  *
71  * The #GtkFontSelection widget lists the available fonts, styles and sizes,
72  * allowing the user to select a font.
73  * It is used in the #GtkFontSelectionDialog widget to provide a dialog box for
74  * selecting fonts.
75  *
76  * To set the font which is initially selected, use
77  * gtk_font_selection_set_font_name().
78  *
79  * To get the selected font use gtk_font_selection_get_font_name().
80  *
81  * To change the text which is shown in the preview area, use
82  * gtk_font_selection_set_preview_text().
83  */
84
85
86 struct _GtkFontSelectionPrivate
87 {
88   GtkWidget *search_entry;
89   GtkWidget *family_face_list;
90   GtkWidget *size_slider;
91   GtkWidget *size_spin;
92   GtkWidget *preview;
93
94   gint             size;
95   PangoFontFace   *face;
96   PangoFontFamily *family;
97 };
98
99
100 struct _GtkFontSelectionDialogPrivate
101 {
102   GtkWidget *fontsel;
103
104   GtkWidget *ok_button;
105   GtkWidget *apply_button;
106   GtkWidget *cancel_button;
107 };
108
109
110 /* We don't enable the font and style entries because they don't add
111  * much in terms of visible effect and have a weird effect on keynav.
112  * the Windows font selector has entries similarly positioned but they
113  * act in conjunction with the associated lists to form a single focus
114  * location.
115  */
116 #undef INCLUDE_FONT_ENTRIES
117
118 /* This is the default text shown in the preview entry, though the user
119    can set it. Remember that some fonts only have capital letters. */
120 #define PREVIEW_TEXT N_("abcdefghijk ABCDEFGHIJK")
121
122 #define DEFAULT_FONT_NAME "Sans 10"
123
124 /* This is the initial fixed height and the top padding of the preview entry */
125 #define PREVIEW_HEIGHT 100
126 #define PREVIEW_TOP_PADDING 6
127
128 /* These are the sizes of the font, style & size lists. */
129 #define FONT_LIST_HEIGHT        136
130 #define FONT_LIST_WIDTH         190
131 #define FONT_STYLE_LIST_WIDTH   170
132 #define FONT_SIZE_LIST_WIDTH    60
133
134 #define ROW_FORMAT_STRING "<span foreground=\"%s\">%s %s</span>\n<span font_desc=\"%s\">%s</span>"
135
136 /* These are what we use as the standard font sizes, for the size list.
137  */
138 #define FONT_SIZES_LENGTH 25
139 static const guint16 font_sizes[] = {
140   6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 22, 24, 26, 28,
141   32, 36, 40, 48, 56, 64, 72
142 };
143
144 enum {
145    PROP_0,
146    PROP_FONT_NAME,
147    PROP_PREVIEW_TEXT
148 };
149
150
151 enum {
152   FAMILY_COLUMN,
153   FACE_COLUMN,
154   FAMILY_NAME_COLUMN,
155   TEXT_COLUMN
156 };
157
158 static void    gtk_font_selection_set_property       (GObject         *object,
159                                                       guint            prop_id,
160                                                       const GValue    *value,
161                                                       GParamSpec      *pspec);
162 static void    gtk_font_selection_get_property       (GObject         *object,
163                                                       guint            prop_id,
164                                                       GValue          *value,
165                                                       GParamSpec      *pspec);
166 static void    gtk_font_selection_finalize           (GObject         *object);
167 static void    gtk_font_selection_screen_changed     (GtkWidget       *widget,
168                                                       GdkScreen       *previous_screen);
169 static void    gtk_font_selection_style_updated      (GtkWidget      *widget);
170
171 static void     gtk_font_selection_ref_family            (GtkFontSelection *fontsel,
172                                                           PangoFontFamily  *family);
173 static void     gtk_font_selection_ref_face              (GtkFontSelection *fontsel,
174                                                           PangoFontFace    *face);
175 static void gtk_font_selection_bootstrap_fontlist (GtkTreeView* treeview);
176
177 G_DEFINE_TYPE (GtkFontSelection, gtk_font_selection, GTK_TYPE_VBOX)
178
179 static void
180 gtk_font_selection_class_init (GtkFontSelectionClass *klass)
181 {
182   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
183   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
184
185   gobject_class->finalize = gtk_font_selection_finalize;
186   gobject_class->set_property = gtk_font_selection_set_property;
187   gobject_class->get_property = gtk_font_selection_get_property;
188
189   widget_class->screen_changed = gtk_font_selection_screen_changed;
190   widget_class->style_updated = gtk_font_selection_style_updated;
191    
192   g_object_class_install_property (gobject_class,
193                                    PROP_FONT_NAME,
194                                    g_param_spec_string ("font-name",
195                                                         P_("Font name"),
196                                                         P_("The string that represents this font"),
197                                                         DEFAULT_FONT_NAME,
198                                                         GTK_PARAM_READWRITE));
199   g_object_class_install_property (gobject_class,
200                                    PROP_PREVIEW_TEXT,
201                                    g_param_spec_string ("preview-text",
202                                                         P_("Preview text"),
203                                                         P_("The text to display in order to demonstrate the selected font"),
204                                                         _(PREVIEW_TEXT),
205                                                         GTK_PARAM_READWRITE));
206
207   g_type_class_add_private (klass, sizeof (GtkFontSelectionPrivate));
208 }
209
210 static void 
211 gtk_font_selection_set_property (GObject         *object,
212                                  guint            prop_id,
213                                  const GValue    *value,
214                                  GParamSpec      *pspec)
215 {
216   GtkFontSelection *fontsel;
217
218   fontsel = GTK_FONT_SELECTION (object);
219
220   switch (prop_id)
221     {
222     case PROP_FONT_NAME:
223       gtk_font_selection_set_font_name (fontsel, g_value_get_string (value));
224       break;
225     case PROP_PREVIEW_TEXT:
226       gtk_font_selection_set_preview_text (fontsel, g_value_get_string (value));
227       break;
228     default:
229       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
230       break;
231     }
232 }
233
234 static void gtk_font_selection_get_property (GObject         *object,
235                                              guint            prop_id,
236                                              GValue          *value,
237                                              GParamSpec      *pspec)
238 {
239   GtkFontSelection *fontsel;
240
241   fontsel = GTK_FONT_SELECTION (object);
242
243   switch (prop_id)
244     {
245     case PROP_FONT_NAME:
246       g_value_take_string (value, gtk_font_selection_get_font_name (fontsel));
247       break;
248     case PROP_PREVIEW_TEXT:
249       g_value_set_string (value, gtk_font_selection_get_preview_text (fontsel));
250       break;
251     default:
252       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
253       break;
254     }
255 }
256
257 /* Handles key press events on the lists, so that we can trap Enter to
258  * activate the default button on our own.
259  */
260 static gboolean
261 list_row_activated (GtkWidget *widget)
262 {
263   GtkWidget *default_widget, *focus_widget;
264   GtkWindow *window;
265   
266   window = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (widget)));
267   if (!gtk_widget_is_toplevel (GTK_WIDGET (window)))
268     window = NULL;
269
270   if (window)
271     {
272       default_widget = gtk_window_get_default_widget (window);
273       focus_widget = gtk_window_get_focus (window);
274
275       if (widget != default_widget &&
276           !(widget == focus_widget && (!default_widget || !gtk_widget_get_sensitive (default_widget))))
277         gtk_window_activate_default (window);
278     }
279
280   return TRUE;
281 }
282
283 static void
284 gtk_font_selection_init (GtkFontSelection *fontsel)
285 {
286   GtkFontSelectionPrivate *priv;
287
288   GtkWidget               *scrolled_win;
289   GtkWidget               *alignment;
290   GtkWidget               *preview_and_size;
291   GtkWidget               *size_controls;
292   GList                   *focus_chain = NULL;
293   AtkObject *atk_obj;
294
295   fontsel->priv = G_TYPE_INSTANCE_GET_PRIVATE (fontsel,
296                                                GTK_TYPE_FONT_SELECTION,
297                                                GtkFontSelectionPrivate);
298   priv = fontsel->priv;
299   gtk_widget_push_composite_child ();
300
301   /* Creating fundamental widgets for the private struct */
302   priv->search_entry = gtk_entry_new ();
303   priv->family_face_list = gtk_tree_view_new ();
304   priv->preview = gtk_entry_new ();
305   priv->size_slider = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL,
306                                                 (gdouble) font_sizes[0],
307                                                 (gdouble) font_sizes[FONT_SIZES_LENGTH - 1],
308                                                 1.0);
309
310   priv->size_spin = gtk_spin_button_new (NULL, 1.0, 0);
311
312   /* Main font family/face view */
313   scrolled_win = gtk_scrolled_window_new (NULL, NULL);
314   gtk_container_add (GTK_CONTAINER (scrolled_win), priv->family_face_list);
315
316   /* Alignment for the preview and size controls */
317   alignment = gtk_alignment_new (0.5, 0.5, 1.0, 1.0);
318   gtk_alignment_set_padding (GTK_ALIGNMENT (alignment),
319                              PREVIEW_TOP_PADDING, 0, 0, 0);
320
321   preview_and_size = gtk_vbox_new (TRUE, 0);
322   gtk_box_set_homogeneous (GTK_BOX (preview_and_size), FALSE);
323   gtk_box_pack_start (GTK_BOX (preview_and_size), priv->preview, FALSE, TRUE, 0);
324   gtk_widget_set_size_request (priv->preview, -1, PREVIEW_HEIGHT);
325
326   /* Packing the slider and the spin in a hbox */
327   size_controls = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
328   gtk_scale_set_draw_value (GTK_SCALE (priv->size_slider), FALSE);
329   gtk_box_pack_start (GTK_BOX (size_controls), priv->size_slider, TRUE, TRUE, 0);
330   gtk_box_pack_start (GTK_BOX (size_controls), priv->size_spin, FALSE, TRUE, 0);
331
332   gtk_box_pack_start (GTK_BOX (preview_and_size), size_controls, FALSE, FALSE, 0);
333   gtk_container_add (GTK_CONTAINER (alignment), preview_and_size);
334
335   /* Packing everything in the selection */
336   gtk_box_pack_start (GTK_BOX (fontsel), priv->search_entry, FALSE, TRUE, 0);
337   gtk_box_pack_start (GTK_BOX (fontsel), scrolled_win, TRUE, TRUE, 0);
338   gtk_box_pack_start (GTK_BOX (fontsel), GTK_WIDGET(alignment), FALSE, TRUE, 0);
339
340   priv->size = 12 * PANGO_SCALE;
341   priv->face = NULL;
342   priv->family = NULL;
343
344   gtk_widget_show_all (GTK_WIDGET (fontsel));
345   gtk_widget_hide (GTK_WIDGET (fontsel));
346
347   gtk_font_selection_bootstrap_fontlist (GTK_TREE_VIEW (priv->family_face_list));
348
349   gtk_widget_pop_composite_child();
350 }
351
352 /**
353  * gtk_font_selection_new:
354  *
355  * Creates a new #GtkFontSelection.
356  *
357  * Return value: a n ew #GtkFontSelection
358  */
359 GtkWidget *
360 gtk_font_selection_new (void)
361 {
362   GtkFontSelection *fontsel;
363   
364   fontsel = g_object_new (GTK_TYPE_FONT_SELECTION, NULL);
365   
366   return GTK_WIDGET (fontsel);
367 }
368
369 static int
370 cmp_families (const void *a, const void *b)
371 {
372   const char *a_name = pango_font_family_get_name (*(PangoFontFamily **)a);
373   const char *b_name = pango_font_family_get_name (*(PangoFontFamily **)b);
374
375   return g_utf8_collate (a_name, b_name);
376 }
377
378 static void
379 set_cursor_to_iter (GtkTreeView *view,
380                     GtkTreeIter *iter)
381 {
382   GtkTreeModel *model = gtk_tree_view_get_model (view);
383   GtkTreePath *path = gtk_tree_model_get_path (model, iter);
384
385   gtk_tree_view_set_cursor (view, path, NULL, FALSE);
386
387   gtk_tree_path_free (path);
388 }
389
390 static void 
391 gtk_font_selection_populate_list (GtkTreeView *treeview)
392 {
393   GtkListStore *model;
394   PangoFontFamily *match_family;
395   PangoFontFamily **families;
396   gint n_families, i;
397   GtkTreeIter match_row;
398   GString *tmp = g_string_new (NULL);
399   const gchar* row_format = ROW_FORMAT_STRING;
400   
401   model = GTK_LIST_STORE (gtk_tree_view_get_model (treeview));
402
403   pango_context_list_families (gtk_widget_get_pango_context (GTK_WIDGET (treeview)),
404                                &families,
405                                &n_families);
406
407   qsort (families, n_families, sizeof (PangoFontFamily *), cmp_families);
408
409   gtk_list_store_clear (model);
410   
411   /* FIXME: Get theme color here */
412
413   for (i=0; i<n_families; i++)
414     {
415       GtkTreeIter     iter;
416       PangoFontFace **faces;
417       int             j, n_faces;
418       const gchar    *fam_name = pango_font_family_get_name (families[i]);
419
420       pango_font_family_list_faces (families[i], &faces, &n_faces);
421       
422       for (j=0; j<n_faces; j++)
423         {
424           PangoFontDescription *pango_desc = pango_font_face_describe (faces[j]);
425           const gchar *face_name = pango_font_face_get_face_name (faces[j]);
426           gchar       *font_desc = pango_font_description_to_string (pango_desc);
427           
428           /* foreground_color, family_name, face_name, desc, sample string */
429           g_string_printf (tmp, ROW_FORMAT_STRING,
430                                 "darkgrey", /* FIXME: This has to be a theme color */
431                                 fam_name,
432                                 face_name,
433                                 font_desc,
434                                 PREVIEW_TEXT);
435
436
437           gtk_list_store_append (model, &iter);
438           gtk_list_store_set (model, &iter,
439                               FAMILY_COLUMN, families[i],
440                               FACE_COLUMN, faces[j],
441                               FAMILY_NAME_COLUMN, fam_name,
442                               TEXT_COLUMN, tmp->str,
443                               -1);
444
445           if ((i == 0 && j == 0) ||
446               (!g_ascii_strcasecmp (face_name, "sans") && j == 0))
447             {
448               match_family = families[i];
449               match_row = iter;
450             }
451
452           pango_font_description_free(pango_desc);
453           g_free (font_desc);
454         }
455
456       g_free (faces);
457     }
458
459   set_cursor_to_iter (treeview, &match_row);
460
461   g_string_free (tmp, TRUE);
462   g_free (families);
463 }
464
465 static void
466 gtk_font_selection_bootstrap_fontlist (GtkTreeView* treeview)
467 {
468   GtkTreeViewColumn *col;
469   GtkListStore      *fonts_model;
470
471   fonts_model = gtk_list_store_new (4,
472                                     PANGO_TYPE_FONT_FAMILY,
473                                     PANGO_TYPE_FONT_FACE,
474                                     G_TYPE_STRING,
475                                     G_TYPE_STRING);
476   gtk_tree_view_set_model (treeview, GTK_TREE_MODEL (fonts_model));
477   
478   gtk_tree_view_set_rules_hint      (treeview, TRUE);
479   gtk_tree_view_set_headers_visible (treeview, FALSE);
480
481   col = gtk_tree_view_column_new_with_attributes ("Family",
482                                                    gtk_cell_renderer_text_new (),
483                                                    "markup", TEXT_COLUMN,
484                                                    NULL);
485   gtk_tree_view_append_column (treeview, col);
486
487   gtk_font_selection_populate_list (treeview);  
488 }
489
490
491 static void
492 gtk_font_selection_finalize (GObject *object)
493 {
494   GtkFontSelection *fontsel = GTK_FONT_SELECTION (object);
495
496   gtk_font_selection_ref_family (fontsel, NULL);
497   gtk_font_selection_ref_face (fontsel, NULL);
498
499   G_OBJECT_CLASS (gtk_font_selection_parent_class)->finalize (object);
500 }
501
502 static void
503 gtk_font_selection_screen_changed (GtkWidget *widget,
504                                   GdkScreen *previous_screen)
505 {
506   return;
507 }
508
509 static void
510 gtk_font_selection_style_updated (GtkWidget *widget)
511 {
512   GTK_WIDGET_CLASS (gtk_font_selection_parent_class)->style_updated (widget);
513
514   return;
515 }
516
517 static void
518 gtk_font_selection_ref_family (GtkFontSelection *fontsel,
519                                PangoFontFamily  *family)
520 {
521   GtkFontSelectionPrivate *priv = fontsel->priv;
522
523   if (family)
524     family = g_object_ref (family);
525   if (priv->family)
526     g_object_unref (priv->family);
527   priv->family = family;
528 }
529
530 static void
531 gtk_font_selection_ref_face (GtkFontSelection *fontsel,
532                              PangoFontFace    *face)
533 {
534   GtkFontSelectionPrivate *priv = fontsel->priv;
535
536   if (face)
537     face = g_object_ref (face);
538   if (priv->face)
539     g_object_unref (priv->face);
540   priv->face = face;
541 }
542
543 /*****************************************************************************
544  * These functions are the main public interface for getting/setting the font.
545  *****************************************************************************/
546
547 /**
548  * gtk_font_selection_get_family_list:
549  * @fontsel: a #GtkFontSelection
550  *
551  * This returns the #GtkTreeView that lists font families, for
552  * example, 'Sans', 'Serif', etc.
553  *
554  * Return value: (transfer none): A #GtkWidget that is part of @fontsel
555  *
556  * Deprecated: 3.2
557  */
558 GtkWidget *
559 gtk_font_selection_get_family_list (GtkFontSelection *fontsel)
560 {
561   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
562
563   return NULL;
564 }
565
566 /**
567  * gtk_font_selection_get_face_list:
568  * @fontsel: a #GtkFontSelection
569  *
570  * This returns the #GtkTreeView which lists all styles available for
571  * the selected font. For example, 'Regular', 'Bold', etc.
572  * 
573  * Return value: (transfer none): A #GtkWidget that is part of @fontsel
574  *
575  * Deprecated: 3.2
576  */
577 GtkWidget *
578 gtk_font_selection_get_face_list (GtkFontSelection *fontsel)
579 {
580   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
581
582   return NULL;
583 }
584
585 /**
586  * gtk_font_selection_get_size_entry:
587  * @fontsel: a #GtkFontSelection
588  *
589  * This returns the #GtkEntry used to allow the user to edit the font
590  * number manually instead of selecting it from the list of font sizes.
591  *
592  * Return value: (transfer none): A #GtkWidget that is part of @fontsel
593  *
594  * Deprecated: 3.2
595  */
596 GtkWidget *
597 gtk_font_selection_get_size_entry (GtkFontSelection *fontsel)
598 {
599   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
600
601   return NULL;
602 }
603
604 /**
605  * gtk_font_selection_get_size_list:
606  * @fontsel: a #GtkFontSelection
607  *
608  * This returns the #GtkTreeeView used to list font sizes.
609  *
610  * Return value: (transfer none): A #GtkWidget that is part of @fontsel
611  *
612  * Deprecated: 3.2
613  */
614 GtkWidget *
615 gtk_font_selection_get_size_list (GtkFontSelection *fontsel)
616 {
617   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
618
619   return NULL;
620 }
621
622 /**
623  * gtk_font_selection_get_preview_entry:
624  * @fontsel: a #GtkFontSelection
625  *
626  * This returns the #GtkEntry used to display the font as a preview.
627  *
628  * Return value: (transfer none): A #GtkWidget that is part of @fontsel
629  *
630  * Deprecated: 3.2
631  */
632 GtkWidget *
633 gtk_font_selection_get_preview_entry (GtkFontSelection *fontsel)
634 {
635   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
636
637   return NULL;
638 }
639
640 /**
641  * gtk_font_selection_get_family:
642  * @fontsel: a #GtkFontSelection
643  *
644  * Gets the #PangoFontFamily representing the selected font family.
645  *
646  * Return value: (transfer none): A #PangoFontFamily representing the
647  *     selected font family. Font families are a collection of font
648  *     faces. The returned object is owned by @fontsel and must not
649  *     be modified or freed.
650  *
651  * Since: 2.14
652  */
653 PangoFontFamily *
654 gtk_font_selection_get_family (GtkFontSelection *fontsel)
655 {
656   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
657
658   return NULL;
659 }
660
661 /**
662  * gtk_font_selection_get_face:
663  * @fontsel: a #GtkFontSelection
664  *
665  * Gets the #PangoFontFace representing the selected font group
666  * details (i.e. family, slant, weight, width, etc).
667  *
668  * Return value: (transfer none): A #PangoFontFace representing the
669  *     selected font group details. The returned object is owned by
670  *     @fontsel and must not be modified or freed.
671  *
672  * Since: 2.14
673  */
674 PangoFontFace *
675 gtk_font_selection_get_face (GtkFontSelection *fontsel)
676 {
677   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
678
679   return NULL;
680 }
681
682 /**
683  * gtk_font_selection_get_size:
684  * @fontsel: a #GtkFontSelection
685  *
686  * The selected font size.
687  *
688  * Return value: A n integer representing the selected font size,
689  *     or -1 if no font size is selected.
690  *
691  * Since: 2.14
692  **/
693 gint
694 gtk_font_selection_get_size (GtkFontSelection *fontsel)
695 {
696   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), -1);
697
698   return NULL;
699 }
700
701 /**
702  * gtk_font_selection_get_font_name:
703  * @fontsel: a #GtkFontSelection
704  * 
705  * Gets the currently-selected font name. 
706  *
707  * Note that this can be a different string than what you set with 
708  * gtk_font_selection_set_font_name(), as the font selection widget may 
709  * normalize font names and thus return a string with a different structure. 
710  * For example, "Helvetica Italic Bold 12" could be normalized to 
711  * "Helvetica Bold Italic 12". Use pango_font_description_equal()
712  * if you want to compare two font descriptions.
713  * 
714  * Return value: A string with the name of the current font, or %NULL if 
715  *     no font is selected. You must free this string with g_free().
716  */
717 gchar *
718 gtk_font_selection_get_font_name (GtkFontSelection *fontsel)
719 {
720   return NULL;
721 }
722
723 /* This sets the current font, then selecting the appropriate list rows. */
724
725 /**
726  * gtk_font_selection_set_font_name:
727  * @fontsel: a #GtkFontSelection
728  * @fontname: a font name like "Helvetica 12" or "Times Bold 18"
729  * 
730  * Sets the currently-selected font. 
731  *
732  * Note that the @fontsel needs to know the screen in which it will appear 
733  * for this to work; this can be guaranteed by simply making sure that the 
734  * @fontsel is inserted in a toplevel window before you call this function.
735  * 
736  * Return value: %TRUE if the font could be set successfully; %FALSE if no 
737  *     such font exists or if the @fontsel doesn't belong to a particular 
738  *     screen yet.
739  */
740 gboolean
741 gtk_font_selection_set_font_name (GtkFontSelection *fontsel,
742                                   const gchar      *fontname)
743 {
744   PangoFontFamily *family = NULL;
745   PangoFontFace *face = NULL;
746   PangoFontDescription *new_desc;
747   
748   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), FALSE);
749
750   return TRUE;
751 }
752
753 /**
754  * gtk_font_selection_get_preview_text:
755  * @fontsel: a #GtkFontSelection
756  *
757  * Gets the text displayed in the preview area.
758  * 
759  * Return value: the text displayed in the preview area. 
760  *     This string is owned by the widget and should not be 
761  *     modified or freed 
762  */
763 G_CONST_RETURN gchar*
764 gtk_font_selection_get_preview_text (GtkFontSelection *fontsel)
765 {
766   return NULL;
767 }
768
769
770 /**
771  * gtk_font_selection_set_preview_text:
772  * @fontsel: a #GtkFontSelection
773  * @text: the text to display in the preview area 
774  *
775  * Sets the text displayed in the preview area.
776  * The @text is used to show how the selected font looks.
777  */
778 void
779 gtk_font_selection_set_preview_text  (GtkFontSelection *fontsel,
780                                       const gchar      *text)
781 {
782   GtkFontSelectionPrivate *priv;
783
784   g_return_if_fail (GTK_IS_FONT_SELECTION (fontsel));
785   g_return_if_fail (text != NULL);
786
787   priv = fontsel->priv;
788 }
789
790
791 /**
792  * SECTION:gtkfontseldlg
793  * @Short_description: A dialog box for selecting fonts
794  * @Title: GtkFontSelectionDialog
795  * @See_also: #GtkFontSelection, #GtkDialog
796  *
797  * The #GtkFontSelectionDialog widget is a dialog box for selecting a font.
798  *
799  * To set the font which is initially selected, use
800  * gtk_font_selection_dialog_set_font_name().
801  *
802  * To get the selected font use gtk_font_selection_dialog_get_font_name().
803  *
804  * To change the text which is shown in the preview area, use
805  * gtk_font_selection_dialog_set_preview_text().
806  *
807  * <refsect2 id="GtkFontSelectionDialog-BUILDER-UI">
808  * <title>GtkFontSelectionDialog as GtkBuildable</title>
809  * The GtkFontSelectionDialog implementation of the GtkBuildable interface
810  * exposes the embedded #GtkFontSelection as internal child with the
811  * name "font_selection". It also exposes the buttons with the names
812  * "ok_button", "cancel_button" and "apply_button".
813  * </refsect2>
814  */
815
816 static void gtk_font_selection_dialog_buildable_interface_init     (GtkBuildableIface *iface);
817 static GObject * gtk_font_selection_dialog_buildable_get_internal_child (GtkBuildable *buildable,
818                                                                           GtkBuilder   *builder,
819                                                                           const gchar  *childname);
820
821 G_DEFINE_TYPE_WITH_CODE (GtkFontSelectionDialog, gtk_font_selection_dialog,
822                          GTK_TYPE_DIALOG,
823                          G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
824                                                 gtk_font_selection_dialog_buildable_interface_init))
825
826 static GtkBuildableIface *parent_buildable_iface;
827
828 static void
829 gtk_font_selection_dialog_class_init (GtkFontSelectionDialogClass *klass)
830 {
831   g_type_class_add_private (klass, sizeof (GtkFontSelectionDialogPrivate));
832 }
833
834 static void
835 gtk_font_selection_dialog_init (GtkFontSelectionDialog *fontseldiag)
836 {
837   GtkFontSelectionDialogPrivate *priv;
838   GtkDialog *dialog = GTK_DIALOG (fontseldiag);
839   GtkWidget *action_area, *content_area;
840
841   fontseldiag->priv = G_TYPE_INSTANCE_GET_PRIVATE (fontseldiag,
842                                                    GTK_TYPE_FONT_SELECTION_DIALOG,
843                                                    GtkFontSelectionDialogPrivate);
844   priv = fontseldiag->priv;
845
846   content_area = gtk_dialog_get_content_area (dialog);
847   action_area = gtk_dialog_get_action_area (dialog);
848
849   gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
850   gtk_box_set_spacing (GTK_BOX (content_area), 2); /* 2 * 5 + 2 = 12 */
851   gtk_container_set_border_width (GTK_CONTAINER (action_area), 5);
852   gtk_box_set_spacing (GTK_BOX (action_area), 6);
853
854   gtk_widget_push_composite_child ();
855
856   gtk_window_set_resizable (GTK_WINDOW (fontseldiag), TRUE);
857
858   /* Create the content area */
859   priv->fontsel = gtk_font_selection_new ();
860   gtk_container_set_border_width (GTK_CONTAINER (priv->fontsel), 5);
861   gtk_widget_show (priv->fontsel);
862   gtk_box_pack_start (GTK_BOX (content_area),
863                       priv->fontsel, TRUE, TRUE, 0);
864
865   /* Create the action area */
866   priv->cancel_button = gtk_dialog_add_button (dialog,
867                                                GTK_STOCK_CANCEL,
868                                                GTK_RESPONSE_CANCEL);
869
870   priv->apply_button = gtk_dialog_add_button (dialog,
871                                               GTK_STOCK_APPLY,
872                                               GTK_RESPONSE_APPLY);
873   gtk_widget_hide (priv->apply_button);
874
875   priv->ok_button = gtk_dialog_add_button (dialog,
876                                            GTK_STOCK_OK,
877                                            GTK_RESPONSE_OK);
878   gtk_widget_grab_default (priv->ok_button);
879
880   gtk_dialog_set_alternative_button_order (GTK_DIALOG (fontseldiag),
881                                            GTK_RESPONSE_OK,
882                                            GTK_RESPONSE_APPLY,
883                                            GTK_RESPONSE_CANCEL,
884                                            -1);
885
886   gtk_window_set_title (GTK_WINDOW (fontseldiag),
887                         _("Font Selection"));
888
889   gtk_widget_pop_composite_child ();
890 }
891
892 /**
893  * gtk_font_selection_dialog_new:
894  * @title: the title of the dialog window 
895  *
896  * Creates a new #GtkFontSelectionDialog.
897  *
898  * Return value: a new #GtkFontSelectionDialog
899  */
900 GtkWidget*
901 gtk_font_selection_dialog_new (const gchar *title)
902 {
903   GtkFontSelectionDialog *fontseldiag;
904   
905   fontseldiag = g_object_new (GTK_TYPE_FONT_SELECTION_DIALOG, NULL);
906
907   if (title)
908     gtk_window_set_title (GTK_WINDOW (fontseldiag), title);
909   
910   return GTK_WIDGET (fontseldiag);
911 }
912
913 /**
914  * gtk_font_selection_dialog_get_font_selection:
915  * @fsd: a #GtkFontSelectionDialog
916  *
917  * Retrieves the #GtkFontSelection widget embedded in the dialog.
918  *
919  * Returns: (transfer none): the embedded #GtkFontSelection
920  *
921  * Since: 2.22
922  **/
923 GtkWidget*
924 gtk_font_selection_dialog_get_font_selection (GtkFontSelectionDialog *fsd)
925 {
926   g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
927
928   return fsd->priv->fontsel;
929 }
930
931
932 /**
933  * gtk_font_selection_dialog_get_ok_button:
934  * @fsd: a #GtkFontSelectionDialog
935  *
936  * Gets the 'OK' button.
937  *
938  * Return value: (transfer none): the #GtkWidget used in the dialog
939  *     for the 'OK' button.
940  *
941  * Since: 2.14
942  */
943 GtkWidget *
944 gtk_font_selection_dialog_get_ok_button (GtkFontSelectionDialog *fsd)
945 {
946   g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
947
948   return fsd->priv->ok_button;
949 }
950
951 /**
952  * gtk_font_selection_dialog_get_cancel_button:
953  * @fsd: a #GtkFontSelectionDialog
954  *
955  * Gets the 'Cancel' button.
956  *
957  * Return value: (transfer none): the #GtkWidget used in the dialog
958  *     for the 'Cancel' button.
959  *
960  * Since: 2.14
961  */
962 GtkWidget *
963 gtk_font_selection_dialog_get_cancel_button (GtkFontSelectionDialog *fsd)
964 {
965   g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
966
967   return fsd->priv->cancel_button;
968 }
969
970 static void
971 gtk_font_selection_dialog_buildable_interface_init (GtkBuildableIface *iface)
972 {
973   parent_buildable_iface = g_type_interface_peek_parent (iface);
974   iface->get_internal_child = gtk_font_selection_dialog_buildable_get_internal_child;
975 }
976
977 static GObject *
978 gtk_font_selection_dialog_buildable_get_internal_child (GtkBuildable *buildable,
979                                                         GtkBuilder   *builder,
980                                                         const gchar  *childname)
981 {
982   GtkFontSelectionDialogPrivate *priv;
983
984   priv = GTK_FONT_SELECTION_DIALOG (buildable)->priv;
985
986   if (g_strcmp0 (childname, "ok_button") == 0)
987     return G_OBJECT (priv->ok_button);
988   else if (g_strcmp0 (childname, "cancel_button") == 0)
989     return G_OBJECT (priv->cancel_button);
990   else if (g_strcmp0 (childname, "apply_button") == 0)
991     return G_OBJECT (priv->apply_button);
992   else if (g_strcmp0 (childname, "font_selection") == 0)
993     return G_OBJECT (priv->fontsel);
994
995   return parent_buildable_iface->get_internal_child (buildable, builder, childname);
996 }
997
998 /**
999  * gtk_font_selection_dialog_get_font_name:
1000  * @fsd: a #GtkFontSelectionDialog
1001  * 
1002  * Gets the currently-selected font name.
1003  *
1004  * Note that this can be a different string than what you set with 
1005  * gtk_font_selection_dialog_set_font_name(), as the font selection widget
1006  * may normalize font names and thus return a string with a different 
1007  * structure. For example, "Helvetica Italic Bold 12" could be normalized 
1008  * to "Helvetica Bold Italic 12".  Use pango_font_description_equal()
1009  * if you want to compare two font descriptions.
1010  * 
1011  * Return value: A string with the name of the current font, or %NULL if no 
1012  *     font is selected. You must free this string with g_free().
1013  */
1014 gchar*
1015 gtk_font_selection_dialog_get_font_name (GtkFontSelectionDialog *fsd)
1016 {
1017   GtkFontSelectionDialogPrivate *priv;
1018
1019   g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1020
1021   priv = fsd->priv;
1022
1023   return gtk_font_selection_get_font_name (GTK_FONT_SELECTION (priv->fontsel));
1024 }
1025
1026 /**
1027  * gtk_font_selection_dialog_set_font_name:
1028  * @fsd: a #GtkFontSelectionDialog
1029  * @fontname: a font name like "Helvetica 12" or "Times Bold 18"
1030  *
1031  * Sets the currently selected font. 
1032  * 
1033  * Return value: %TRUE if the font selected in @fsd is now the
1034  *     @fontname specified, %FALSE otherwise. 
1035  */
1036 gboolean
1037 gtk_font_selection_dialog_set_font_name (GtkFontSelectionDialog *fsd,
1038                                          const gchar            *fontname)
1039 {
1040   GtkFontSelectionDialogPrivate *priv;
1041
1042   g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), FALSE);
1043   g_return_val_if_fail (fontname, FALSE);
1044
1045   priv = fsd->priv;
1046
1047   return gtk_font_selection_set_font_name (GTK_FONT_SELECTION (priv->fontsel), fontname);
1048 }
1049
1050 /**
1051  * gtk_font_selection_dialog_get_preview_text:
1052  * @fsd: a #GtkFontSelectionDialog
1053  *
1054  * Gets the text displayed in the preview area.
1055  * 
1056  * Return value: the text displayed in the preview area. 
1057  *     This string is owned by the widget and should not be 
1058  *     modified or freed 
1059  */
1060 G_CONST_RETURN gchar*
1061 gtk_font_selection_dialog_get_preview_text (GtkFontSelectionDialog *fsd)
1062 {
1063   GtkFontSelectionDialogPrivate *priv;
1064
1065   g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1066
1067   priv = fsd->priv;
1068
1069   return gtk_font_selection_get_preview_text (GTK_FONT_SELECTION (priv->fontsel));
1070 }
1071
1072 /**
1073  * gtk_font_selection_dialog_set_preview_text:
1074  * @fsd: a #GtkFontSelectionDialog
1075  * @text: the text to display in the preview area
1076  *
1077  * Sets the text displayed in the preview area. 
1078  */
1079 void
1080 gtk_font_selection_dialog_set_preview_text (GtkFontSelectionDialog *fsd,
1081                                             const gchar            *text)
1082 {
1083   GtkFontSelectionDialogPrivate *priv;
1084
1085   g_return_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd));
1086   g_return_if_fail (text != NULL);
1087
1088   priv = fsd->priv;
1089
1090   gtk_font_selection_set_preview_text (GTK_FONT_SELECTION (priv->fontsel), text);
1091 }