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