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