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