]> Pileus Git - ~andy/gtk/blob - gtk/gtkfontsel.c
Fixes #136082 and #135265, patch by Morten Welinder.
[~andy/gtk] / gtk / gtkfontsel.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 #include <stdlib.h>
34 #include <glib/gprintf.h>
35 #include <string.h>
36
37 #include "gdk/gdk.h"
38 #include "gdk/gdkkeysyms.h"
39
40 #include "gtkfontsel.h"
41
42 #include "gtkbutton.h"
43 #include "gtkcellrenderertext.h"
44 #include "gtkentry.h"
45 #include "gtkframe.h"
46 #include "gtkhbbox.h"
47 #include "gtkhbox.h"
48 #include "gtklabel.h"
49 #include "gtkliststore.h"
50 #include "gtkrc.h"
51 #include "gtkstock.h"
52 #include "gtktable.h"
53 #include "gtktreeselection.h"
54 #include "gtktreeview.h"
55 #include "gtkvbox.h"
56 #include "gtkscrolledwindow.h"
57 #include "gtkintl.h"
58
59 /* We don't enable the font and style entries because they don't add
60  * much in terms of visible effect and have a weird effect on keynav.
61  * the Windows font selector has entries similarly positioned but they
62  * act in conjunction with the associated lists to form a single focus
63  * location.
64  */
65 #undef INCLUDE_FONT_ENTRIES
66
67 /* This is the default text shown in the preview entry, though the user
68    can set it. Remember that some fonts only have capital letters. */
69 #define PREVIEW_TEXT N_("abcdefghijk ABCDEFGHIJK")
70
71 /* This is the initial and maximum height of the preview entry (it expands
72    when large font sizes are selected). Initial height is also the minimum. */
73 #define INITIAL_PREVIEW_HEIGHT 44
74 #define MAX_PREVIEW_HEIGHT 300
75
76 /* These are the sizes of the font, style & size lists. */
77 #define FONT_LIST_HEIGHT        136
78 #define FONT_LIST_WIDTH         190
79 #define FONT_STYLE_LIST_WIDTH   170
80 #define FONT_SIZE_LIST_WIDTH    60
81
82 /* These are what we use as the standard font sizes, for the size list.
83  */
84 static const guint16 font_sizes[] = {
85   8, 9, 10, 11, 12, 13, 14, 16, 18, 20, 22, 24, 26, 28,
86   32, 36, 40, 48, 56, 64, 72
87 };
88
89 enum {
90    PROP_0,
91    PROP_FONT_NAME,
92    PROP_FONT,
93    PROP_PREVIEW_TEXT
94 };
95
96
97 enum {
98   FAMILY_COLUMN,
99   FAMILY_NAME_COLUMN
100 };
101
102 enum {
103   FACE_COLUMN,
104   FACE_NAME_COLUMN
105 };
106
107 enum {
108   SIZE_COLUMN
109 };
110
111 static void    gtk_font_selection_class_init         (GtkFontSelectionClass *klass);
112 static void    gtk_font_selection_set_property       (GObject         *object,
113                                                       guint            prop_id,
114                                                       const GValue    *value,
115                                                       GParamSpec      *pspec);
116 static void    gtk_font_selection_get_property       (GObject         *object,
117                                                       guint            prop_id,
118                                                       GValue          *value,
119                                                       GParamSpec      *pspec);
120 static void    gtk_font_selection_init               (GtkFontSelection      *fontsel);
121 static void    gtk_font_selection_finalize           (GObject               *object);
122 static void    gtk_font_selection_screen_changed     (GtkWidget             *widget,
123                                                       GdkScreen             *previous_screen);
124
125 /* These are the callbacks & related functions. */
126 static void     gtk_font_selection_select_font           (GtkTreeSelection *selection,
127                                                           gpointer          data);
128 static void     gtk_font_selection_show_available_fonts  (GtkFontSelection *fs);
129
130 static void     gtk_font_selection_show_available_styles (GtkFontSelection *fs);
131 static void     gtk_font_selection_select_best_style     (GtkFontSelection *fs,
132                                                           gboolean          use_first);
133 static void     gtk_font_selection_select_style          (GtkTreeSelection *selection,
134                                                           gpointer          data);
135
136 static void     gtk_font_selection_select_best_size      (GtkFontSelection *fs);
137 static void     gtk_font_selection_show_available_sizes  (GtkFontSelection *fs,
138                                                           gboolean          first_time);
139 static void     gtk_font_selection_size_activate         (GtkWidget        *w,
140                                                           gpointer          data);
141 static gboolean gtk_font_selection_size_focus_out        (GtkWidget        *w,
142                                                           GdkEventFocus    *event,
143                                                           gpointer          data);
144 static void     gtk_font_selection_select_size           (GtkTreeSelection *selection,
145                                                           gpointer          data);
146
147 static void     gtk_font_selection_scroll_on_map         (GtkWidget        *w,
148                                                           gpointer          data);
149
150 static void     gtk_font_selection_preview_changed       (GtkWidget        *entry,
151                                                           GtkFontSelection *fontsel);
152
153 /* Misc. utility functions. */
154 static void    gtk_font_selection_load_font          (GtkFontSelection *fs);
155 static void    gtk_font_selection_update_preview     (GtkFontSelection *fs);
156
157 static GdkFont* gtk_font_selection_get_font_internal (GtkFontSelection *fontsel);
158
159 /* FontSelectionDialog */
160 static void    gtk_font_selection_dialog_class_init  (GtkFontSelectionDialogClass *klass);
161 static void    gtk_font_selection_dialog_init        (GtkFontSelectionDialog *fontseldiag);
162
163 static GtkVBoxClass *font_selection_parent_class = NULL;
164 static GtkWindowClass *font_selection_dialog_parent_class = NULL;
165
166
167 GType
168 gtk_font_selection_get_type (void)
169 {
170   static GType font_selection_type = 0;
171   
172   if (!font_selection_type)
173     {
174       static const GTypeInfo fontsel_type_info =
175       {
176         sizeof (GtkFontSelectionClass),
177         NULL,           /* base_init */
178         NULL,           /* base_finalize */
179         (GClassInitFunc) gtk_font_selection_class_init,
180         NULL,           /* class_finalize */
181         NULL,           /* class_data */
182         sizeof (GtkFontSelection),
183         0,              /* n_preallocs */
184         (GInstanceInitFunc) gtk_font_selection_init,
185       };
186       
187       font_selection_type =
188         g_type_register_static (GTK_TYPE_VBOX, "GtkFontSelection",
189                                 &fontsel_type_info, 0);
190     }
191   
192   return font_selection_type;
193 }
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   font_selection_parent_class = g_type_class_peek_parent (klass);
202   
203   gobject_class->set_property = gtk_font_selection_set_property;
204   gobject_class->get_property = gtk_font_selection_get_property;
205
206   widget_class->screen_changed = gtk_font_selection_screen_changed;
207    
208   g_object_class_install_property (gobject_class,
209                                    PROP_FONT_NAME,
210                                    g_param_spec_string ("font_name",
211                                                         P_("Font name"),
212                                                         P_("The X string that represents this font"),
213                                                         NULL,
214                                                         G_PARAM_READWRITE));
215   g_object_class_install_property (gobject_class,
216                                    PROP_FONT,
217                                    g_param_spec_boxed ("font",
218                                                        P_("Font"),
219                                                        P_("The GdkFont that is currently selected"),
220                                                        GDK_TYPE_FONT,
221                                                        G_PARAM_READABLE));
222   g_object_class_install_property (gobject_class,
223                                    PROP_PREVIEW_TEXT,
224                                    g_param_spec_string ("preview_text",
225                                                         P_("Preview text"),
226                                                         P_("The text to display in order to demonstrate the selected font"),
227                                                         PREVIEW_TEXT,
228                                                         G_PARAM_READWRITE));
229   gobject_class->finalize = gtk_font_selection_finalize;
230 }
231
232 static void 
233 gtk_font_selection_set_property (GObject         *object,
234                                  guint            prop_id,
235                                  const GValue    *value,
236                                  GParamSpec      *pspec)
237 {
238   GtkFontSelection *fontsel;
239
240   fontsel = GTK_FONT_SELECTION (object);
241
242   switch (prop_id)
243     {
244     case PROP_FONT_NAME:
245       gtk_font_selection_set_font_name (fontsel, g_value_get_string (value));
246       break;
247     case PROP_PREVIEW_TEXT:
248       gtk_font_selection_set_preview_text (fontsel, g_value_get_string (value));
249       break;
250     default:
251       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
252       break;
253     }
254 }
255
256 static void gtk_font_selection_get_property (GObject         *object,
257                                              guint            prop_id,
258                                              GValue          *value,
259                                              GParamSpec      *pspec)
260 {
261   GtkFontSelection *fontsel;
262
263   fontsel = GTK_FONT_SELECTION (object);
264
265   switch (prop_id)
266     {
267     case PROP_FONT_NAME:
268       g_value_set_string (value, gtk_font_selection_get_font_name (fontsel));
269       break;
270     case PROP_FONT:
271       g_value_set_object (value, gtk_font_selection_get_font_internal (fontsel));
272       break;
273     case PROP_PREVIEW_TEXT:
274       g_value_set_string (value, gtk_font_selection_get_preview_text (fontsel));
275       break;
276     default:
277       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
278       break;
279     }
280 }
281
282
283 static void
284 gtk_font_selection_init (GtkFontSelection *fontsel)
285 {
286   GtkWidget *scrolled_win;
287   GtkWidget *text_frame;
288   GtkWidget *text_box;
289   GtkWidget *table, *label;
290   GtkWidget *font_label, *style_label;
291   GtkListStore *model;
292   GtkTreeViewColumn *column;
293   GList *focus_chain = NULL;
294
295   gtk_widget_push_composite_child ();
296
297   fontsel->size = 12 * PANGO_SCALE;
298   
299   /* Create the table of font, style & size. */
300   table = gtk_table_new (3, 3, FALSE);
301   gtk_widget_show (table);
302   gtk_table_set_col_spacings (GTK_TABLE (table), 8);
303   gtk_box_pack_start (GTK_BOX (fontsel), table, TRUE, TRUE, 0);
304
305 #ifdef INCLUDE_FONT_ENTRIES
306   fontsel->font_entry = gtk_entry_new ();
307   gtk_editable_set_editable (GTK_EDITABLE (fontsel->font_entry), FALSE);
308   gtk_widget_set_size_request (fontsel->font_entry, 20, -1);
309   gtk_widget_show (fontsel->font_entry);
310   gtk_table_attach (GTK_TABLE (table), fontsel->font_entry, 0, 1, 1, 2,
311                     GTK_FILL, 0, 0, 0);
312   
313   fontsel->font_style_entry = gtk_entry_new ();
314   gtk_editable_set_editable (GTK_EDITABLE (fontsel->font_style_entry), FALSE);
315   gtk_widget_set_size_request (fontsel->font_style_entry, 20, -1);
316   gtk_widget_show (fontsel->font_style_entry);
317   gtk_table_attach (GTK_TABLE (table), fontsel->font_style_entry, 1, 2, 1, 2,
318                     GTK_FILL, 0, 0, 0);
319 #endif /* INCLUDE_FONT_ENTRIES */
320   
321   fontsel->size_entry = gtk_entry_new ();
322   gtk_widget_set_size_request (fontsel->size_entry, 20, -1);
323   gtk_widget_show (fontsel->size_entry);
324   gtk_table_attach (GTK_TABLE (table), fontsel->size_entry, 2, 3, 1, 2,
325                     GTK_FILL, 0, 0, 0);
326   g_signal_connect (fontsel->size_entry, "activate",
327                     G_CALLBACK (gtk_font_selection_size_activate),
328                     fontsel);
329   g_signal_connect_after (fontsel->size_entry, "focus_out_event",
330                           G_CALLBACK (gtk_font_selection_size_focus_out),
331                           fontsel);
332   
333   font_label = gtk_label_new_with_mnemonic (_("_Family:"));
334   gtk_misc_set_alignment (GTK_MISC (font_label), 0.0, 0.5);
335   gtk_widget_show (font_label);
336   gtk_table_attach (GTK_TABLE (table), font_label, 0, 1, 0, 1,
337                     GTK_FILL, 0, 0, 0);  
338
339   style_label = gtk_label_new_with_mnemonic (_("_Style:"));
340   gtk_misc_set_alignment (GTK_MISC (style_label), 0.0, 0.5);
341   gtk_widget_show (style_label);
342   gtk_table_attach (GTK_TABLE (table), style_label, 1, 2, 0, 1,
343                     GTK_FILL, 0, 0, 0);
344   
345   label = gtk_label_new_with_mnemonic (_("Si_ze:"));
346   gtk_label_set_mnemonic_widget (GTK_LABEL (label),
347                                  fontsel->size_entry);
348   gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
349   gtk_widget_show (label);
350   gtk_table_attach (GTK_TABLE (table), label, 2, 3, 0, 1,
351                     GTK_FILL, 0, 0, 0);
352   
353   
354   /* Create the lists  */
355
356   model = gtk_list_store_new (2,
357                               G_TYPE_OBJECT,  /* FAMILY_COLUMN */
358                               G_TYPE_STRING); /* FAMILY_NAME_COLUMN */
359   fontsel->family_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
360   g_object_unref (model);
361
362   column = gtk_tree_view_column_new_with_attributes ("Family",
363                                                      gtk_cell_renderer_text_new (),
364                                                      "text", FAMILY_NAME_COLUMN,
365                                                      NULL);
366   gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
367   gtk_tree_view_append_column (GTK_TREE_VIEW (fontsel->family_list), column);
368
369   gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (fontsel->family_list), FALSE);
370   gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (fontsel->family_list)),
371                                GTK_SELECTION_BROWSE);
372   
373   gtk_label_set_mnemonic_widget (GTK_LABEL (font_label), fontsel->family_list);
374
375   scrolled_win = gtk_scrolled_window_new (NULL, NULL);
376   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), GTK_SHADOW_IN);
377   gtk_widget_set_size_request (scrolled_win,
378                                FONT_LIST_WIDTH, FONT_LIST_HEIGHT);
379   gtk_container_add (GTK_CONTAINER (scrolled_win), fontsel->family_list);
380   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
381                                   GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
382   gtk_widget_show (fontsel->family_list);
383   gtk_widget_show (scrolled_win);
384
385   gtk_table_attach (GTK_TABLE (table), scrolled_win, 0, 1, 1, 3,
386                     GTK_EXPAND | GTK_FILL,
387                     GTK_EXPAND | GTK_FILL, 0, 0);
388   focus_chain = g_list_append (focus_chain, scrolled_win);
389   
390   model = gtk_list_store_new (2,
391                               G_TYPE_OBJECT,  /* FACE_COLUMN */
392                               G_TYPE_STRING); /* FACE_NAME_COLUMN */
393   fontsel->face_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
394   g_object_unref (model);
395
396   gtk_label_set_mnemonic_widget (GTK_LABEL (style_label), fontsel->face_list);
397
398   column = gtk_tree_view_column_new_with_attributes ("Face",
399                                                      gtk_cell_renderer_text_new (),
400                                                      "text", FACE_NAME_COLUMN,
401                                                      NULL);
402   gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
403   gtk_tree_view_append_column (GTK_TREE_VIEW (fontsel->face_list), column);
404
405   gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (fontsel->face_list), FALSE);
406   gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (fontsel->face_list)),
407                                GTK_SELECTION_BROWSE);
408   
409   scrolled_win = gtk_scrolled_window_new (NULL, NULL);
410   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), GTK_SHADOW_IN);
411   gtk_widget_set_size_request (scrolled_win,
412                                FONT_STYLE_LIST_WIDTH, FONT_LIST_HEIGHT);
413   gtk_container_add (GTK_CONTAINER (scrolled_win), fontsel->face_list);
414   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
415                                   GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
416   gtk_widget_show (fontsel->face_list);
417   gtk_widget_show (scrolled_win);
418   gtk_table_attach (GTK_TABLE (table), scrolled_win, 1, 2, 1, 3,
419                     GTK_EXPAND | GTK_FILL,
420                     GTK_EXPAND | GTK_FILL, 0, 0);
421   focus_chain = g_list_append (focus_chain, scrolled_win);
422   
423   focus_chain = g_list_append (focus_chain, fontsel->size_entry);
424
425   model = gtk_list_store_new (1, G_TYPE_INT);
426   fontsel->size_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
427   g_object_unref (model);
428
429   column = gtk_tree_view_column_new_with_attributes ("Size",
430                                                      gtk_cell_renderer_text_new (),
431                                                      "text", SIZE_COLUMN,
432                                                      NULL);
433   gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
434   gtk_tree_view_append_column (GTK_TREE_VIEW (fontsel->size_list), column);
435
436   gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (fontsel->size_list), FALSE);
437   gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (fontsel->size_list)),
438                                GTK_SELECTION_BROWSE);
439   
440   scrolled_win = gtk_scrolled_window_new (NULL, NULL);
441   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), GTK_SHADOW_IN);
442   gtk_container_add (GTK_CONTAINER (scrolled_win), fontsel->size_list);
443   gtk_widget_set_size_request (scrolled_win, -1, FONT_LIST_HEIGHT);
444   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
445                                   GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
446   gtk_widget_show (fontsel->size_list);
447   gtk_widget_show (scrolled_win);
448   gtk_table_attach (GTK_TABLE (table), scrolled_win, 2, 3, 2, 3,
449                     GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
450   focus_chain = g_list_append (focus_chain, scrolled_win);
451
452   gtk_container_set_focus_chain (GTK_CONTAINER (table), focus_chain);
453   g_list_free (focus_chain);
454   
455   /* Insert the fonts. */
456   g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (fontsel->family_list)), "changed",
457                     G_CALLBACK (gtk_font_selection_select_font), fontsel);
458
459   g_signal_connect_after (fontsel->family_list, "map",
460                           G_CALLBACK (gtk_font_selection_scroll_on_map),
461                           fontsel);
462   
463   g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (fontsel->face_list)), "changed",
464                     G_CALLBACK (gtk_font_selection_select_style), fontsel);
465
466   g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (fontsel->size_list)), "changed",
467                     G_CALLBACK (gtk_font_selection_select_size), fontsel);
468
469   /* create the text entry widget */
470   label = gtk_label_new_with_mnemonic (_("_Preview:"));
471   gtk_widget_show (label);
472   
473   text_frame = gtk_frame_new (NULL);
474   gtk_frame_set_label_widget (GTK_FRAME (text_frame), label);
475   
476   gtk_widget_show (text_frame);
477   gtk_frame_set_shadow_type (GTK_FRAME (text_frame), GTK_SHADOW_ETCHED_IN);
478   gtk_box_pack_start (GTK_BOX (fontsel), text_frame,
479                       FALSE, TRUE, 0);
480   
481   /* This is just used to get a 4-pixel space around the preview entry. */
482   text_box = gtk_hbox_new (FALSE, 0);
483   gtk_widget_show (text_box);
484   gtk_container_add (GTK_CONTAINER (text_frame), text_box);
485   gtk_container_set_border_width (GTK_CONTAINER (text_box), 4);
486   
487   fontsel->preview_entry = gtk_entry_new ();
488   gtk_label_set_mnemonic_widget (GTK_LABEL (label), fontsel->preview_entry);
489   
490   gtk_widget_show (fontsel->preview_entry);
491   g_signal_connect (fontsel->preview_entry, "changed",
492                     G_CALLBACK (gtk_font_selection_preview_changed), fontsel);
493   gtk_widget_set_size_request (fontsel->preview_entry,
494                                -1, INITIAL_PREVIEW_HEIGHT);
495   gtk_box_pack_start (GTK_BOX (text_box), fontsel->preview_entry,
496                       TRUE, TRUE, 0);
497
498   gtk_widget_pop_composite_child();
499 }
500
501 GtkWidget *
502 gtk_font_selection_new ()
503 {
504   GtkFontSelection *fontsel;
505   
506   fontsel = g_object_new (GTK_TYPE_FONT_SELECTION, NULL);
507   
508   return GTK_WIDGET (fontsel);
509 }
510
511 static void
512 gtk_font_selection_finalize (GObject *object)
513 {
514   GtkFontSelection *fontsel;
515   
516   g_return_if_fail (GTK_IS_FONT_SELECTION (object));
517   
518   fontsel = GTK_FONT_SELECTION (object);
519
520   if (fontsel->font)
521     gdk_font_unref (fontsel->font);
522   
523   if (G_OBJECT_CLASS (font_selection_parent_class)->finalize)
524     (* G_OBJECT_CLASS (font_selection_parent_class)->finalize) (object);
525 }
526
527 static void
528 gtk_font_selection_screen_changed (GtkWidget *widget,
529                                    GdkScreen *previous_screen)
530 {
531   GtkFontSelection *fontsel = GTK_FONT_SELECTION (widget);
532
533   if (gtk_widget_has_screen (GTK_WIDGET (fontsel)))
534     {
535       gtk_font_selection_show_available_fonts (fontsel);
536       gtk_font_selection_show_available_sizes (fontsel, TRUE);
537       gtk_font_selection_show_available_styles (fontsel);
538     }
539 }
540
541 static void
542 gtk_font_selection_preview_changed (GtkWidget        *entry,
543                                     GtkFontSelection *fontsel)
544 {
545   g_object_notify (G_OBJECT (fontsel), "preview_text");
546 }
547
548 static void
549 scroll_to_selection (GtkTreeView *tree_view)
550 {
551   GtkTreeSelection *selection = gtk_tree_view_get_selection (tree_view);
552   GtkTreeModel *model;
553   GtkTreeIter iter;
554
555   if (gtk_tree_selection_get_selected (selection, &model, &iter))
556     {
557       GtkTreePath *path = gtk_tree_model_get_path (model, &iter);
558       gtk_tree_view_scroll_to_cell (tree_view, path, NULL, TRUE, 0.5, 0.5);
559       gtk_tree_path_free (path);
560     }
561 }
562
563 static void
564 set_cursor_to_iter (GtkTreeView *view,
565                     GtkTreeIter *iter)
566 {
567   GtkTreeModel *model = gtk_tree_view_get_model (view);
568   GtkTreePath *path = gtk_tree_model_get_path (model, iter);
569   
570   gtk_tree_view_set_cursor (view, path, 0, FALSE);
571
572   gtk_tree_path_free (path);
573 }
574
575 /* This is called when the list is mapped. Here we scroll to the current
576    font if necessary. */
577 static void
578 gtk_font_selection_scroll_on_map (GtkWidget             *widget,
579                                   gpointer               data)
580 {
581   GtkFontSelection *fontsel;
582   
583 #ifdef FONTSEL_DEBUG
584   g_message ("In expose_list\n");
585 #endif
586   fontsel = GTK_FONT_SELECTION (data);
587   
588   /* Try to scroll the font family list to the selected item */
589   scroll_to_selection (GTK_TREE_VIEW (fontsel->family_list));
590       
591   /* Try to scroll the font family list to the selected item */
592   scroll_to_selection (GTK_TREE_VIEW (fontsel->face_list));
593       
594   /* Try to scroll the font family list to the selected item */
595   scroll_to_selection (GTK_TREE_VIEW (fontsel->size_list));
596 }
597
598 /* This is called when a family is selected in the list. */
599 static void
600 gtk_font_selection_select_font (GtkTreeSelection *selection,
601                                 gpointer          data)
602 {
603   GtkFontSelection *fontsel;
604   GtkTreeModel *model;
605   GtkTreeIter iter;
606   const gchar *family_name;
607   
608   fontsel = GTK_FONT_SELECTION (data);
609
610   if (gtk_tree_selection_get_selected (selection, &model, &iter))
611     {
612       PangoFontFamily *family;
613       
614       gtk_tree_model_get (model, &iter, FAMILY_COLUMN, &family, -1);
615       if (fontsel->family != family)
616         {
617           fontsel->family = family;
618           
619           family_name = pango_font_family_get_name (fontsel->family);
620           
621 #ifdef INCLUDE_FONT_ENTRIES
622           gtk_entry_set_text (GTK_ENTRY (fontsel->font_entry), family_name);
623 #endif
624           
625           gtk_font_selection_show_available_styles (fontsel);
626           gtk_font_selection_select_best_style (fontsel, TRUE);
627         }
628
629       g_object_unref (family);
630     }
631 }
632
633 static int
634 cmp_families (const void *a, const void *b)
635 {
636   const char *a_name = pango_font_family_get_name (*(PangoFontFamily **)a);
637   const char *b_name = pango_font_family_get_name (*(PangoFontFamily **)b);
638   
639   return g_utf8_collate (a_name, b_name);
640 }
641
642 static void
643 gtk_font_selection_show_available_fonts (GtkFontSelection *fontsel)
644 {
645   GtkListStore *model;
646   PangoFontFamily **families;
647   PangoFontFamily *match_family = NULL;
648   gint n_families, i;
649   GtkTreeIter match_row;
650   
651   model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (fontsel->family_list)));
652   
653   pango_context_list_families (gtk_widget_get_pango_context (GTK_WIDGET (fontsel)),
654                                &families, &n_families);
655   qsort (families, n_families, sizeof (PangoFontFamily *), cmp_families);
656
657   gtk_list_store_clear (model);
658
659   for (i=0; i<n_families; i++)
660     {
661       const gchar *name = pango_font_family_get_name (families[i]);
662       GtkTreeIter iter;
663
664       gtk_list_store_append (model, &iter);
665       gtk_list_store_set (model, &iter,
666                           FAMILY_COLUMN, families[i],
667                           FAMILY_NAME_COLUMN, name,
668                           -1);
669       
670       if (i == 0 || !g_ascii_strcasecmp (name, "sans"))
671         {
672           match_family = families[i];
673           match_row = iter;
674         }
675     }
676
677   fontsel->family = match_family;
678   if (match_family)
679     {
680       set_cursor_to_iter (GTK_TREE_VIEW (fontsel->family_list), &match_row);
681 #ifdef INCLUDE_FONT_ENTRIES
682       gtk_entry_set_text (GTK_ENTRY (fontsel->font_entry), 
683                           pango_font_family_get_name (match_family));
684 #endif /* INCLUDE_FONT_ENTRIES */
685     }
686
687   g_free (families);
688 }
689
690 static int
691 compare_font_descriptions (const PangoFontDescription *a, const PangoFontDescription *b)
692 {
693   int val = strcmp (pango_font_description_get_family (a), pango_font_description_get_family (b));
694   if (val != 0)
695     return val;
696
697   if (pango_font_description_get_weight (a) != pango_font_description_get_weight (b))
698     return pango_font_description_get_weight (a) - pango_font_description_get_weight (b);
699
700   if (pango_font_description_get_style (a) != pango_font_description_get_style (b))
701     return pango_font_description_get_style (a) - pango_font_description_get_style (b);
702   
703   if (pango_font_description_get_stretch (a) != pango_font_description_get_stretch (b))
704     return pango_font_description_get_stretch (a) - pango_font_description_get_stretch (b);
705
706   if (pango_font_description_get_variant (a) != pango_font_description_get_variant (b))
707     return pango_font_description_get_variant (a) - pango_font_description_get_variant (b);
708
709   return 0;
710 }
711
712 static int
713 faces_sort_func (const void *a, const void *b)
714 {
715   PangoFontDescription *desc_a = pango_font_face_describe (*(PangoFontFace **)a);
716   PangoFontDescription *desc_b = pango_font_face_describe (*(PangoFontFace **)b);
717   
718   int ord = compare_font_descriptions (desc_a, desc_b);
719
720   pango_font_description_free (desc_a);
721   pango_font_description_free (desc_b);
722
723   return ord;
724 }
725
726 static gboolean
727 font_description_style_equal (const PangoFontDescription *a,
728                               const PangoFontDescription *b)
729 {
730   return (pango_font_description_get_weight (a) == pango_font_description_get_weight (b) &&
731           pango_font_description_get_style (a) == pango_font_description_get_style (b) &&
732           pango_font_description_get_stretch (a) == pango_font_description_get_stretch (b) &&
733           pango_font_description_get_variant (a) == pango_font_description_get_variant (b));
734 }
735
736 /* This fills the font style list with all the possible style combinations
737    for the current font family. */
738 static void
739 gtk_font_selection_show_available_styles (GtkFontSelection *fontsel)
740 {
741   gint n_faces, i;
742   PangoFontFace **faces;
743   PangoFontDescription *old_desc;
744   GtkListStore *model;
745   GtkTreeIter match_row;
746   PangoFontFace *match_face = NULL;
747   
748   model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (fontsel->face_list)));
749   
750   if (fontsel->face)
751     old_desc = pango_font_face_describe (fontsel->face);
752   else
753     old_desc= NULL;
754
755   pango_font_family_list_faces (fontsel->family, &faces, &n_faces);
756   qsort (faces, n_faces, sizeof (PangoFontFace *), faces_sort_func);
757
758   gtk_list_store_clear (model);
759
760   for (i=0; i < n_faces; i++)
761     {
762       GtkTreeIter iter;
763       const gchar *str = pango_font_face_get_face_name (faces[i]);
764
765       gtk_list_store_append (model, &iter);
766       gtk_list_store_set (model, &iter,
767                           FACE_COLUMN, faces[i],
768                           FACE_NAME_COLUMN, str,
769                           -1);
770
771       if (i == 0)
772         {
773           match_row = iter;
774           match_face = faces[i];
775         }
776       else if (old_desc)
777         {
778           PangoFontDescription *tmp_desc = pango_font_face_describe (faces[i]);
779           
780           if (font_description_style_equal (tmp_desc, old_desc))
781             {
782               match_row = iter;
783               match_face = faces[i];
784             }
785       
786           pango_font_description_free (tmp_desc);
787         }
788     }
789
790   if (old_desc)
791     pango_font_description_free (old_desc);
792
793   fontsel->face = match_face;
794   if (match_face)
795     {
796 #ifdef INCLUDE_FONT_ENTRIES
797       const gchar *str = pango_font_face_get_face_name (fontsel->face);
798
799       gtk_entry_set_text (GTK_ENTRY (fontsel->font_style_entry), str);
800 #endif      
801       set_cursor_to_iter (GTK_TREE_VIEW (fontsel->face_list), &match_row);
802     }
803
804   g_free (faces);
805 }
806
807 /* This selects a style when the user selects a font. It just uses the first
808    available style at present. I was thinking of trying to maintain the
809    selected style, e.g. bold italic, when the user selects different fonts.
810    However, the interface is so easy to use now I'm not sure it's worth it.
811    Note: This will load a font. */
812 static void
813 gtk_font_selection_select_best_style (GtkFontSelection *fontsel,
814                                       gboolean          use_first)
815 {
816   GtkTreeIter iter;
817   GtkTreeModel *model;
818
819   model = gtk_tree_view_get_model (GTK_TREE_VIEW (fontsel->face_list));
820
821   if (gtk_tree_model_get_iter_first (model, &iter))
822     {
823       set_cursor_to_iter (GTK_TREE_VIEW (fontsel->face_list), &iter);
824       scroll_to_selection (GTK_TREE_VIEW (fontsel->face_list));
825     }
826
827   gtk_font_selection_show_available_sizes (fontsel, FALSE);
828   gtk_font_selection_select_best_size (fontsel);
829 }
830
831
832 /* This is called when a style is selected in the list. */
833 static void
834 gtk_font_selection_select_style (GtkTreeSelection *selection,
835                                  gpointer          data)
836 {
837   GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
838   GtkTreeModel *model;
839   GtkTreeIter iter;
840   
841   if (gtk_tree_selection_get_selected (selection, &model, &iter))
842     {
843       PangoFontFace *face;
844       
845       gtk_tree_model_get (model, &iter, FACE_COLUMN, &face, -1);
846       fontsel->face = face;
847
848       g_object_unref (face);
849     }
850
851   gtk_font_selection_show_available_sizes (fontsel, FALSE);
852   gtk_font_selection_select_best_size (fontsel);
853 }
854
855 static void
856 gtk_font_selection_show_available_sizes (GtkFontSelection *fontsel,
857                                          gboolean          first_time)
858 {
859   gint i;
860   GtkListStore *model;
861   GtkTreeSelection *selection;
862   gchar buffer[128];
863   gchar *p;
864       
865   model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (fontsel->size_list)));
866   selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (fontsel->size_list));
867
868   /* Insert the standard font sizes */
869   if (first_time)
870     {
871       gtk_list_store_clear (model);
872
873       for (i = 0; i < G_N_ELEMENTS (font_sizes); i++)
874         {
875           GtkTreeIter iter;
876           
877           gtk_list_store_append (model, &iter);
878           gtk_list_store_set (model, &iter, SIZE_COLUMN, font_sizes[i], -1);
879           
880           if (font_sizes[i] * PANGO_SCALE == fontsel->size)
881             set_cursor_to_iter (GTK_TREE_VIEW (fontsel->size_list), &iter);
882         }
883     }
884   else
885     {
886       GtkTreeIter iter;
887       gboolean found = FALSE;
888       
889       gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &iter);
890       for (i = 0; i < G_N_ELEMENTS (font_sizes) && !found; i++)
891         {
892           if (font_sizes[i] * PANGO_SCALE == fontsel->size)
893             {
894               set_cursor_to_iter (GTK_TREE_VIEW (fontsel->size_list), &iter);
895               found = TRUE;
896             }
897
898           gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &iter);
899         }
900
901       if (!found)
902         {
903           GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (fontsel->size_list));
904           gtk_tree_selection_unselect_all (selection);
905         }
906     }
907
908   /* Set the entry to the new size, rounding to 1 digit,
909    * trimming of trailing 0's and a trailing period
910    */
911   g_snprintf (buffer, sizeof (buffer), "%.1f", fontsel->size / (1.0 * PANGO_SCALE));
912   if (strchr (buffer, '.'))
913     {
914       p = buffer + strlen (buffer) - 1;
915       while (*p == '0')
916         p--;
917       if (*p == '.')
918         p--;
919       p[1] = '\0';
920     }
921
922   /* Compare, to avoid moving the cursor unecessarily */
923   if (strcmp (gtk_entry_get_text (GTK_ENTRY (fontsel->size_entry)), buffer) != 0)
924     gtk_entry_set_text (GTK_ENTRY (fontsel->size_entry), buffer);
925 }
926
927 static void
928 gtk_font_selection_select_best_size (GtkFontSelection *fontsel)
929 {
930   gtk_font_selection_load_font (fontsel);  
931 }
932
933 static void
934 gtk_font_selection_set_size (GtkFontSelection *fontsel,
935                              gint              new_size)
936 {
937   if (fontsel->size != new_size)
938     {
939       fontsel->size = new_size;
940
941       gtk_font_selection_show_available_sizes (fontsel, FALSE);      
942       gtk_font_selection_load_font (fontsel);
943     }
944 }
945
946 /* If the user hits return in the font size entry, we change to the new font
947    size. */
948 static void
949 gtk_font_selection_size_activate (GtkWidget   *w,
950                                   gpointer     data)
951 {
952   GtkFontSelection *fontsel;
953   gint new_size;
954   const gchar *text;
955   
956   fontsel = GTK_FONT_SELECTION (data);
957
958   text = gtk_entry_get_text (GTK_ENTRY (fontsel->size_entry));
959   new_size = MAX (0.1, atof (text) * PANGO_SCALE + 0.5);
960
961   gtk_font_selection_set_size (fontsel, new_size);
962 }
963
964 static gboolean
965 gtk_font_selection_size_focus_out (GtkWidget     *w,
966                                    GdkEventFocus *event,
967                                    gpointer       data)
968 {
969   gtk_font_selection_size_activate (w, data);
970   
971   return TRUE;
972 }
973
974 /* This is called when a size is selected in the list. */
975 static void
976 gtk_font_selection_select_size (GtkTreeSelection *selection,
977                                 gpointer          data)
978 {
979   GtkFontSelection *fontsel;
980   GtkTreeModel *model;
981   GtkTreeIter iter;
982   gint new_size;
983   
984   fontsel = GTK_FONT_SELECTION (data);
985   
986   if (gtk_tree_selection_get_selected (selection, &model, &iter))
987     {
988       gtk_tree_model_get (model, &iter, SIZE_COLUMN, &new_size, -1);
989       gtk_font_selection_set_size (fontsel, new_size * PANGO_SCALE);
990     }
991 }
992
993 static void
994 gtk_font_selection_load_font (GtkFontSelection *fontsel)
995 {
996   if (fontsel->font)
997     gdk_font_unref (fontsel->font);
998   fontsel->font = NULL;
999
1000   gtk_font_selection_update_preview (fontsel);
1001 }
1002
1003 static PangoFontDescription *
1004 gtk_font_selection_get_font_description (GtkFontSelection *fontsel)
1005 {
1006   PangoFontDescription *font_desc;
1007
1008   if (fontsel->face)
1009     {
1010       font_desc = pango_font_face_describe (fontsel->face);
1011       pango_font_description_set_size (font_desc, fontsel->size);
1012     }
1013   else
1014     font_desc = pango_font_description_from_string ("Sans 10");
1015
1016   return font_desc;
1017 }
1018
1019 /* This sets the font in the preview entry to the selected font, and tries to
1020    make sure that the preview entry is a reasonable size, i.e. so that the
1021    text can be seen with a bit of space to spare. But it tries to avoid
1022    resizing the entry every time the font changes.
1023    This also used to shrink the preview if the font size was decreased, but
1024    that made it awkward if the user wanted to resize the window themself. */
1025 static void
1026 gtk_font_selection_update_preview (GtkFontSelection *fontsel)
1027 {
1028   GtkRcStyle *rc_style;
1029   gint new_height;
1030   GtkRequisition old_requisition;
1031   GtkWidget *preview_entry = fontsel->preview_entry;
1032   const gchar *text;
1033
1034   gtk_widget_get_child_requisition (preview_entry, &old_requisition);
1035   
1036   rc_style = gtk_rc_style_new ();
1037   rc_style->font_desc = gtk_font_selection_get_font_description (fontsel);
1038   
1039   gtk_widget_modify_style (preview_entry, rc_style);
1040   gtk_rc_style_unref (rc_style);
1041
1042   gtk_widget_size_request (preview_entry, NULL);
1043   
1044   /* We don't ever want to be over MAX_PREVIEW_HEIGHT pixels high. */
1045   new_height = CLAMP (preview_entry->requisition.height, INITIAL_PREVIEW_HEIGHT, MAX_PREVIEW_HEIGHT);
1046
1047   if (new_height > old_requisition.height || new_height < old_requisition.height - 30)
1048     gtk_widget_set_size_request (preview_entry, -1, new_height);
1049   
1050   /* This sets the preview text, if it hasn't been set already. */
1051   text = gtk_entry_get_text (GTK_ENTRY (preview_entry));
1052   if (strlen (text) == 0)
1053     gtk_entry_set_text (GTK_ENTRY (preview_entry), _(PREVIEW_TEXT));
1054   gtk_editable_set_position (GTK_EDITABLE (preview_entry), 0);
1055 }
1056
1057 static GdkFont*
1058 gtk_font_selection_get_font_internal (GtkFontSelection *fontsel)
1059 {
1060   if (!fontsel->font)
1061     {
1062       PangoFontDescription *font_desc = gtk_font_selection_get_font_description (fontsel);
1063       fontsel->font = gdk_font_from_description_for_display (gtk_widget_get_display (GTK_WIDGET (fontsel)), font_desc);
1064       pango_font_description_free (font_desc);
1065     }
1066   
1067   return fontsel->font;
1068 }
1069
1070
1071 /*****************************************************************************
1072  * These functions are the main public interface for getting/setting the font.
1073  *****************************************************************************/
1074
1075 GdkFont*
1076 gtk_font_selection_get_font (GtkFontSelection *fontsel)
1077 {
1078   return gtk_font_selection_get_font_internal (fontsel);
1079 }
1080
1081 gchar *
1082 gtk_font_selection_get_font_name (GtkFontSelection *fontsel)
1083 {
1084   gchar *result;
1085   
1086   PangoFontDescription *font_desc = gtk_font_selection_get_font_description (fontsel);
1087   result = pango_font_description_to_string (font_desc);
1088   pango_font_description_free (font_desc);
1089
1090   return result;
1091 }
1092
1093
1094 /* This sets the current font, selecting the appropriate list rows.
1095    First we check the fontname is valid and try to find the font family
1096    - i.e. the name in the main list. If we can't find that, then just return.
1097    Next we try to set each of the properties according to the fontname.
1098    Finally we select the font family & style in the lists. */
1099 gboolean
1100 gtk_font_selection_set_font_name (GtkFontSelection *fontsel,
1101                                   const gchar      *fontname)
1102 {
1103   PangoFontFamily *new_family = NULL;
1104   PangoFontFace *new_face = NULL;
1105   PangoFontFace *fallback_face = NULL;
1106   PangoFontDescription *new_desc;
1107   GtkTreeModel *model;
1108   GtkTreeIter iter;
1109   GtkTreeIter match_iter;
1110   gboolean valid;
1111   
1112   g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), FALSE);
1113   
1114   new_desc = pango_font_description_from_string (fontname);
1115
1116   /* Check to make sure that this is in the list of allowed fonts */
1117
1118   model = gtk_tree_view_get_model (GTK_TREE_VIEW (fontsel->family_list));
1119   for (valid = gtk_tree_model_get_iter_first (model, &iter);
1120        valid;
1121        valid = gtk_tree_model_iter_next (model, &iter))
1122     {
1123       PangoFontFamily *family;
1124       
1125       gtk_tree_model_get (model, &iter, FAMILY_COLUMN, &family, -1);
1126       
1127       if (g_ascii_strcasecmp (pango_font_family_get_name (family),
1128                               pango_font_description_get_family (new_desc)) == 0)
1129         new_family = family;
1130       
1131       g_object_unref (family);
1132       
1133       if (new_family)
1134         break;
1135     }
1136
1137   if (!new_family)
1138     return FALSE;
1139
1140   fontsel->family = new_family;
1141   set_cursor_to_iter (GTK_TREE_VIEW (fontsel->family_list), &iter);
1142   gtk_font_selection_show_available_styles (fontsel);
1143
1144   model = gtk_tree_view_get_model (GTK_TREE_VIEW (fontsel->face_list));
1145   for (valid = gtk_tree_model_get_iter_first (model, &iter);
1146        valid;
1147        valid = gtk_tree_model_iter_next (model, &iter))
1148     {
1149       PangoFontFace *face;
1150       PangoFontDescription *tmp_desc;
1151       
1152       gtk_tree_model_get (model, &iter, FACE_COLUMN, &face, -1);
1153       tmp_desc = pango_font_face_describe (face);
1154       
1155       if (font_description_style_equal (tmp_desc, new_desc))
1156         new_face = face;
1157       
1158       if (!fallback_face)
1159         {
1160           fallback_face = face;
1161           match_iter = iter;
1162         }
1163       
1164       pango_font_description_free (tmp_desc);
1165       g_object_unref (face);
1166       
1167       if (new_face)
1168         {
1169           match_iter = iter;
1170           break;
1171         }
1172     }
1173
1174   if (!new_face)
1175     new_face = fallback_face;
1176
1177   fontsel->face = new_face;
1178   set_cursor_to_iter (GTK_TREE_VIEW (fontsel->face_list), &match_iter);  
1179
1180   gtk_font_selection_set_size (fontsel, pango_font_description_get_size (new_desc));
1181   
1182   g_object_freeze_notify (G_OBJECT (fontsel));
1183   g_object_notify (G_OBJECT (fontsel), "font_name");
1184   g_object_notify (G_OBJECT (fontsel), "font");
1185   g_object_thaw_notify (G_OBJECT (fontsel));
1186
1187   pango_font_description_free (new_desc);
1188
1189   return TRUE;
1190 }
1191
1192
1193 /* This returns the text in the preview entry. You should copy the returned
1194    text if you need it. */
1195 G_CONST_RETURN gchar*
1196 gtk_font_selection_get_preview_text  (GtkFontSelection *fontsel)
1197 {
1198   return gtk_entry_get_text (GTK_ENTRY (fontsel->preview_entry));
1199 }
1200
1201
1202 /* This sets the text in the preview entry. */
1203 void
1204 gtk_font_selection_set_preview_text  (GtkFontSelection *fontsel,
1205                                       const gchar         *text)
1206 {
1207   gtk_entry_set_text (GTK_ENTRY (fontsel->preview_entry), text);
1208 }
1209
1210 /*****************************************************************************
1211  * GtkFontSelectionDialog
1212  *****************************************************************************/
1213
1214 GType
1215 gtk_font_selection_dialog_get_type (void)
1216 {
1217   static GType font_selection_dialog_type = 0;
1218   
1219   if (!font_selection_dialog_type)
1220     {
1221       static const GTypeInfo fontsel_diag_info =
1222       {
1223         sizeof (GtkFontSelectionDialogClass),
1224         NULL,           /* base_init */
1225         NULL,           /* base_finalize */
1226         (GClassInitFunc) gtk_font_selection_dialog_class_init,
1227         NULL,           /* class_finalize */
1228         NULL,           /* class_data */
1229         sizeof (GtkFontSelectionDialog),
1230         0,              /* n_preallocs */
1231         (GInstanceInitFunc) gtk_font_selection_dialog_init,
1232       };
1233       
1234       font_selection_dialog_type =
1235         g_type_register_static (GTK_TYPE_DIALOG, "GtkFontSelectionDialog",
1236                                 &fontsel_diag_info, 0);
1237     }
1238   
1239   return font_selection_dialog_type;
1240 }
1241
1242 static void
1243 gtk_font_selection_dialog_class_init (GtkFontSelectionDialogClass *klass)
1244 {
1245   font_selection_dialog_parent_class = g_type_class_peek_parent (klass);
1246 }
1247
1248 static void
1249 gtk_font_selection_dialog_init (GtkFontSelectionDialog *fontseldiag)
1250 {
1251   GtkDialog *dialog;
1252
1253   gtk_widget_push_composite_child ();
1254
1255   dialog = GTK_DIALOG (fontseldiag);
1256   
1257   gtk_container_set_border_width (GTK_CONTAINER (fontseldiag), 4);
1258   gtk_window_set_resizable (GTK_WINDOW (fontseldiag), TRUE);
1259   
1260   fontseldiag->main_vbox = dialog->vbox;
1261   
1262   fontseldiag->fontsel = gtk_font_selection_new ();
1263   gtk_container_set_border_width (GTK_CONTAINER (fontseldiag->fontsel), 4);
1264   gtk_widget_show (fontseldiag->fontsel);
1265   gtk_box_pack_start (GTK_BOX (fontseldiag->main_vbox),
1266                       fontseldiag->fontsel, TRUE, TRUE, 0);
1267   
1268   /* Create the action area */
1269   fontseldiag->action_area = dialog->action_area;
1270
1271   fontseldiag->cancel_button = gtk_dialog_add_button (dialog,
1272                                                       GTK_STOCK_CANCEL,
1273                                                       GTK_RESPONSE_CANCEL);
1274
1275   fontseldiag->apply_button = gtk_dialog_add_button (dialog,
1276                                                      GTK_STOCK_APPLY,
1277                                                      GTK_RESPONSE_APPLY);
1278   gtk_widget_hide (fontseldiag->apply_button);
1279
1280   fontseldiag->ok_button = gtk_dialog_add_button (dialog,
1281                                                   GTK_STOCK_OK,
1282                                                   GTK_RESPONSE_OK);
1283   gtk_widget_grab_default (fontseldiag->ok_button);
1284   
1285   gtk_window_set_title (GTK_WINDOW (fontseldiag),
1286                         _("Font Selection"));
1287
1288   gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
1289   
1290   gtk_widget_pop_composite_child ();
1291 }
1292
1293 GtkWidget*
1294 gtk_font_selection_dialog_new (const gchar *title)
1295 {
1296   GtkFontSelectionDialog *fontseldiag;
1297   
1298   fontseldiag = g_object_new (GTK_TYPE_FONT_SELECTION_DIALOG, NULL);
1299
1300   if (title)
1301     gtk_window_set_title (GTK_WINDOW (fontseldiag), title);
1302   
1303   return GTK_WIDGET (fontseldiag);
1304 }
1305
1306 gchar*
1307 gtk_font_selection_dialog_get_font_name (GtkFontSelectionDialog *fsd)
1308 {
1309   return gtk_font_selection_get_font_name (GTK_FONT_SELECTION (fsd->fontsel));
1310 }
1311
1312 GdkFont*
1313 gtk_font_selection_dialog_get_font (GtkFontSelectionDialog *fsd)
1314 {
1315   return gtk_font_selection_get_font (GTK_FONT_SELECTION (fsd->fontsel));
1316 }
1317
1318 gboolean
1319 gtk_font_selection_dialog_set_font_name (GtkFontSelectionDialog *fsd,
1320                                          const gchar      *fontname)
1321 {
1322   return gtk_font_selection_set_font_name (GTK_FONT_SELECTION (fsd->fontsel), fontname);
1323 }
1324
1325 G_CONST_RETURN gchar*
1326 gtk_font_selection_dialog_get_preview_text (GtkFontSelectionDialog *fsd)
1327 {
1328   return gtk_font_selection_get_preview_text (GTK_FONT_SELECTION (fsd->fontsel));
1329 }
1330
1331 void
1332 gtk_font_selection_dialog_set_preview_text (GtkFontSelectionDialog *fsd,
1333                                             const gchar            *text)
1334 {
1335   gtk_font_selection_set_preview_text (GTK_FONT_SELECTION (fsd->fontsel), text);
1336 }