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