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