gtkfontsel.c 58.7 KB
Newer Older
Cody Russell's avatar
Cody Russell committed
1
/* GTK - The GIMP Toolkit
2 3
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
 *
4
 * Massively updated for Pango by Owen Taylor, May 2000
5 6 7 8 9
 * GtkFontSelection widget for Gtk+, by Damon Chaplin, May 1998.
 * Based on the GnomeFontSelector widget, by Elliot Lee, but major changes.
 * The GnomeFontSelector was derived from app/text_tool.c in the GIMP.
 *
 * This library is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU Lesser General Public
11 12 13 14 15 16
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * 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
Javier Jardón's avatar
Javier Jardón committed
20
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
21 22
 */

23
/*
24
 * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
25 26 27 28 29
 * file for a list of people on the GTK+ Team.  See the ChangeLog
 * files for a list of changes.  These files are distributed with
 * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
 */

30
#include "config.h"
31

32 33
#define GDK_DISABLE_DEPRECATION_WARNINGS

34
#include <stdlib.h>
35
#include <glib/gprintf.h>
36 37
#include <string.h>

38 39
#include <atk/atk.h>

40
#include "gtkbutton.h"
41
#include "gtkcellrenderertext.h"
42 43 44
#include "gtkentry.h"
#include "gtkframe.h"
#include "gtklabel.h"
45
#include "gtkliststore.h"
46
#include "gtkstock.h"
47
#include "gtktable.h"
48 49
#include "gtktreeselection.h"
#include "gtktreeview.h"
50
#include "gtkscrolledwindow.h"
51
#include "gtkintl.h"
52
#include "gtkaccessible.h"
53
#include "gtkbuildable.h"
54
#include "gtkorientable.h"
55
#include "gtkprivate.h"
56
#include "gtkfontsel.h"
57 58 59

/**
 * SECTION:gtkfontsel
60
 * @Short_description: Deprecated widget for selecting fonts
61
 * @Title: GtkFontSelection
62
 * @See_also: #GtkFontSelectionDialog, #GtkFontChooser
63 64 65 66 67 68 69 70 71 72 73 74 75
 *
 * The #GtkFontSelection widget lists the available fonts, styles and sizes,
 * allowing the user to select a font.
 * It is used in the #GtkFontSelectionDialog widget to provide a dialog box for
 * selecting fonts.
 *
 * To set the font which is initially selected, use
 * gtk_font_selection_set_font_name().
 *
 * To get the selected font use gtk_font_selection_get_font_name().
 *
 * To change the text which is shown in the preview area, use
 * gtk_font_selection_set_preview_text().
76 77 78
 *
 * In GTK+ 3.2, #GtkFontSelection has been deprecated in favor of
 * #GtkFontChooser.
79 80 81
 */


82
struct _GtkFontSelectionPrivate
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
{
  GtkWidget *font_entry;        /* Used _get_family_entry() for consistency, -mr */
  GtkWidget *font_style_entry;  /* Used _get_face_entry() for consistency, -mr */

  GtkWidget *size_entry;
  GtkWidget *preview_entry;

  GtkWidget *family_list;
  GtkWidget *face_list;
  GtkWidget *size_list;

  PangoFontFamily *family;      /* Current family */
  PangoFontFace *face;          /* Current face */

  gint size;
};

100

101
struct _GtkFontSelectionDialogPrivate
102 103 104 105 106 107 108 109 110
{
  GtkWidget *fontsel;

  GtkWidget *ok_button;
  GtkWidget *apply_button;
  GtkWidget *cancel_button;
};


111 112 113 114 115 116 117 118
/* We don't enable the font and style entries because they don't add
 * much in terms of visible effect and have a weird effect on keynav.
 * the Windows font selector has entries similarly positioned but they
 * act in conjunction with the associated lists to form a single focus
 * location.
 */
#undef INCLUDE_FONT_ENTRIES

119 120
/* This is the default text shown in the preview entry, though the user
   can set it. Remember that some fonts only have capital letters. */
121
#define PREVIEW_TEXT N_("abcdefghijk ABCDEFGHIJK")
122

Matthias Clasen's avatar
Matthias Clasen committed
123 124
#define DEFAULT_FONT_NAME "Sans 10"

125 126 127 128 129
/* This is the initial and maximum height of the preview entry (it expands
   when large font sizes are selected). Initial height is also the minimum. */
#define INITIAL_PREVIEW_HEIGHT 44
#define MAX_PREVIEW_HEIGHT 300

130
/* These are the sizes of the font, style & size lists. */
131
#define FONT_LIST_HEIGHT	136
Damon Chaplin's avatar
Damon Chaplin committed
132 133
#define FONT_LIST_WIDTH		190
#define FONT_STYLE_LIST_WIDTH	170
134 135
#define FONT_SIZE_LIST_WIDTH	60

136
/* These are what we use as the standard font sizes, for the size list.
137 138
 */
static const guint16 font_sizes[] = {
139
  6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 22, 24, 26, 28,
140
  32, 36, 40, 48, 56, 64, 72
141 142
};

143 144 145 146 147 148
enum {
   PROP_0,
   PROP_FONT_NAME,
   PROP_PREVIEW_TEXT
};

149 150 151 152 153 154 155 156 157 158 159 160 161 162 163

enum {
  FAMILY_COLUMN,
  FAMILY_NAME_COLUMN
};

enum {
  FACE_COLUMN,
  FACE_NAME_COLUMN
};

enum {
  SIZE_COLUMN
};

164 165 166 167 168 169 170 171
static void    gtk_font_selection_set_property       (GObject         *object,
						      guint            prop_id,
						      const GValue    *value,
						      GParamSpec      *pspec);
static void    gtk_font_selection_get_property       (GObject         *object,
						      guint            prop_id,
						      GValue          *value,
						      GParamSpec      *pspec);
172 173 174
static void    gtk_font_selection_finalize	     (GObject         *object);
static void    gtk_font_selection_screen_changed     (GtkWidget	      *widget,
						      GdkScreen       *previous_screen);
175
static void    gtk_font_selection_style_updated      (GtkWidget      *widget);
176 177

/* These are the callbacks & related functions. */
178
static void     gtk_font_selection_select_font           (GtkTreeSelection *selection,
179 180 181 182 183 184
							  gpointer          data);
static void     gtk_font_selection_show_available_fonts  (GtkFontSelection *fs);

static void     gtk_font_selection_show_available_styles (GtkFontSelection *fs);
static void     gtk_font_selection_select_best_style     (GtkFontSelection *fs,
							  gboolean          use_first);
185
static void     gtk_font_selection_select_style          (GtkTreeSelection *selection,
186 187 188
							  gpointer          data);

static void     gtk_font_selection_select_best_size      (GtkFontSelection *fs);
189 190
static void     gtk_font_selection_show_available_sizes  (GtkFontSelection *fs,
							  gboolean          first_time);
191
static void     gtk_font_selection_size_activate         (GtkWidget        *w,
192
							  gpointer          data);
193 194 195
static gboolean gtk_font_selection_size_focus_out        (GtkWidget        *w,
							  GdkEventFocus    *event,
							  gpointer          data);
196
static void     gtk_font_selection_select_size           (GtkTreeSelection *selection,
197 198
							  gpointer          data);

199
static void     gtk_font_selection_scroll_on_map         (GtkWidget        *w,
200 201
							  gpointer          data);

202 203
static void     gtk_font_selection_preview_changed       (GtkWidget        *entry,
							  GtkFontSelection *fontsel);
204 205
static void     gtk_font_selection_scroll_to_selection   (GtkFontSelection *fontsel);

206 207

/* Misc. utility functions. */
Manish Singh's avatar
Manish Singh committed
208
static void    gtk_font_selection_load_font          (GtkFontSelection *fs);
209 210
static void    gtk_font_selection_update_preview     (GtkFontSelection *fs);

211 212 213 214 215 216 217 218 219 220
static PangoFontDescription *gtk_font_selection_get_font_description (GtkFontSelection *fontsel);
static gboolean gtk_font_selection_select_font_desc  (GtkFontSelection      *fontsel,
						      PangoFontDescription  *new_desc,
						      PangoFontFamily      **pfamily,
						      PangoFontFace        **pface);
static void     gtk_font_selection_reload_fonts          (GtkFontSelection *fontsel);
static void     gtk_font_selection_ref_family            (GtkFontSelection *fontsel,
							  PangoFontFamily  *family);
static void     gtk_font_selection_ref_face              (GtkFontSelection *fontsel,
							  PangoFontFace    *face);
221

222
G_DEFINE_TYPE_WITH_PRIVATE (GtkFontSelection, gtk_font_selection, GTK_TYPE_BOX)
223 224

static void
225
gtk_font_selection_class_init (GtkFontSelectionClass *klass)
226
{
227
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
228
  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
229 230

  gobject_class->finalize = gtk_font_selection_finalize;
231 232
  gobject_class->set_property = gtk_font_selection_set_property;
  gobject_class->get_property = gtk_font_selection_get_property;
233

234
  widget_class->screen_changed = gtk_font_selection_screen_changed;
235
  widget_class->style_updated = gtk_font_selection_style_updated;
236 237 238
   
  g_object_class_install_property (gobject_class,
                                   PROP_FONT_NAME,
239
                                   g_param_spec_string ("font-name",
240
                                                        P_("Font name"),
Matthias Clasen's avatar
Matthias Clasen committed
241 242
                                                        P_("The string that represents this font"),
                                                        DEFAULT_FONT_NAME,
243
                                                        GTK_PARAM_READWRITE));
244 245
  g_object_class_install_property (gobject_class,
                                   PROP_PREVIEW_TEXT,
246
                                   g_param_spec_string ("preview-text",
247 248
                                                        P_("Preview text"),
                                                        P_("The text to display in order to demonstrate the selected font"),
Matthias Clasen's avatar
Matthias Clasen committed
249
                                                        _(PREVIEW_TEXT),
250
                                                        GTK_PARAM_READWRITE));
251 252
}

253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288
static void 
gtk_font_selection_set_property (GObject         *object,
				 guint            prop_id,
				 const GValue    *value,
				 GParamSpec      *pspec)
{
  GtkFontSelection *fontsel;

  fontsel = GTK_FONT_SELECTION (object);

  switch (prop_id)
    {
    case PROP_FONT_NAME:
      gtk_font_selection_set_font_name (fontsel, g_value_get_string (value));
      break;
    case PROP_PREVIEW_TEXT:
      gtk_font_selection_set_preview_text (fontsel, g_value_get_string (value));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static void gtk_font_selection_get_property (GObject         *object,
					     guint            prop_id,
					     GValue          *value,
					     GParamSpec      *pspec)
{
  GtkFontSelection *fontsel;

  fontsel = GTK_FONT_SELECTION (object);

  switch (prop_id)
    {
    case PROP_FONT_NAME:
289
      g_value_take_string (value, gtk_font_selection_get_font_name (fontsel));
290 291 292 293 294 295 296 297 298 299
      break;
    case PROP_PREVIEW_TEXT:
      g_value_set_string (value, gtk_font_selection_get_preview_text (fontsel));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

300 301 302 303 304 305
/* Handles key press events on the lists, so that we can trap Enter to
 * activate the default button on our own.
 */
static gboolean
list_row_activated (GtkWidget *widget)
{
306
  GtkWidget *default_widget, *focus_widget;
307 308 309
  GtkWindow *window;
  
  window = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (widget)));
310
  if (!gtk_widget_is_toplevel (GTK_WIDGET (window)))
311
    window = NULL;
312 313

  if (window)
314
    {
315 316 317 318 319 320
      default_widget = gtk_window_get_default_widget (window);
      focus_widget = gtk_window_get_focus (window);

      if (widget != default_widget &&
          !(widget == focus_widget && (!default_widget || !gtk_widget_get_sensitive (default_widget))))
        gtk_window_activate_default (window);
321
    }
322

323 324
  return TRUE;
}
325

326
static void
327
gtk_font_selection_init (GtkFontSelection *fontsel)
328
{
329
  GtkFontSelectionPrivate *priv;
330
  GtkWidget *scrolled_win;
331 332
  GtkWidget *text_box;
  GtkWidget *table, *label;
333
  GtkWidget *font_label, *style_label;
334
  GtkWidget *vbox;
335 336 337
  GtkListStore *model;
  GtkTreeViewColumn *column;
  GList *focus_chain = NULL;
338
  AtkObject *atk_obj;
339

340
  fontsel->priv = gtk_font_selection_get_instance_private (fontsel);
341 342
  priv = fontsel->priv;

343 344 345
  gtk_orientable_set_orientation (GTK_ORIENTABLE (fontsel),
                                  GTK_ORIENTATION_VERTICAL);

346 347
  gtk_widget_push_composite_child ();

348
  gtk_box_set_spacing (GTK_BOX (fontsel), 12);
349
  priv->size = 12 * PANGO_SCALE;
350
  
351 352 353
  /* Create the table of font, style & size. */
  table = gtk_table_new (3, 3, FALSE);
  gtk_widget_show (table);
354 355
  gtk_table_set_row_spacings (GTK_TABLE (table), 6);
  gtk_table_set_col_spacings (GTK_TABLE (table), 12);
356
  gtk_box_pack_start (GTK_BOX (fontsel), table, TRUE, TRUE, 0);
357

Manish Singh's avatar
Manish Singh committed
358
#ifdef INCLUDE_FONT_ENTRIES
359 360 361 362 363
  priv->font_entry = gtk_entry_new ();
  gtk_editable_set_editable (GTK_EDITABLE (priv->font_entry), FALSE);
  gtk_widget_set_size_request (priv->font_entry, 20, -1);
  gtk_widget_show (priv->font_entry);
  gtk_table_attach (GTK_TABLE (table), priv->font_entry, 0, 1, 1, 2,
364
		    GTK_FILL, 0, 0, 0);
365
  
366 367 368 369 370
  priv->font_style_entry = gtk_entry_new ();
  gtk_editable_set_editable (GTK_EDITABLE (priv->font_style_entry), FALSE);
  gtk_widget_set_size_request (priv->font_style_entry, 20, -1);
  gtk_widget_show (priv->font_style_entry);
  gtk_table_attach (GTK_TABLE (table), priv->font_style_entry, 1, 2, 1, 2,
371
		    GTK_FILL, 0, 0, 0);
372
#endif /* INCLUDE_FONT_ENTRIES */
373
  
374 375 376 377
  priv->size_entry = gtk_entry_new ();
  gtk_widget_set_size_request (priv->size_entry, 20, -1);
  gtk_widget_show (priv->size_entry);
  gtk_table_attach (GTK_TABLE (table), priv->size_entry, 2, 3, 1, 2,
378
		    GTK_FILL, 0, 0, 0);
379
  g_signal_connect (priv->size_entry, "activate",
Manish Singh's avatar
Manish Singh committed
380 381
		    G_CALLBACK (gtk_font_selection_size_activate),
		    fontsel);
382
  g_signal_connect_after (priv->size_entry, "focus-out-event",
Manish Singh's avatar
Manish Singh committed
383 384
			  G_CALLBACK (gtk_font_selection_size_focus_out),
			  fontsel);
385
  
386
  font_label = gtk_label_new_with_mnemonic (_("_Family:"));
387 388
  gtk_widget_set_halign (font_label, GTK_ALIGN_START);
  gtk_widget_set_valign (font_label, GTK_ALIGN_CENTER);
389 390
  gtk_widget_show (font_label);
  gtk_table_attach (GTK_TABLE (table), font_label, 0, 1, 0, 1,
391
		    GTK_FILL, 0, 0, 0);  
392 393

  style_label = gtk_label_new_with_mnemonic (_("_Style:"));
394 395
  gtk_widget_set_halign (style_label, GTK_ALIGN_START);
  gtk_widget_set_valign (style_label, GTK_ALIGN_CENTER);
396 397
  gtk_widget_show (style_label);
  gtk_table_attach (GTK_TABLE (table), style_label, 1, 2, 0, 1,
398
		    GTK_FILL, 0, 0, 0);
399
  
400 401
  label = gtk_label_new_with_mnemonic (_("Si_ze:"));
  gtk_label_set_mnemonic_widget (GTK_LABEL (label),
402
                                 priv->size_entry);
403 404
  gtk_widget_set_halign (label, GTK_ALIGN_START);
  gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
405 406 407 408 409
  gtk_widget_show (label);
  gtk_table_attach (GTK_TABLE (table), label, 2, 3, 0, 1,
		    GTK_FILL, 0, 0, 0);
  
  
410 411 412 413 414
  /* Create the lists  */

  model = gtk_list_store_new (2,
			      G_TYPE_OBJECT,  /* FAMILY_COLUMN */
			      G_TYPE_STRING); /* FAMILY_NAME_COLUMN */
415
  priv->family_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
416 417
  g_object_unref (model);

418
  g_signal_connect (priv->family_list, "row-activated",
419 420
		    G_CALLBACK (list_row_activated), fontsel);

421 422 423 424 425
  column = gtk_tree_view_column_new_with_attributes ("Family",
						     gtk_cell_renderer_text_new (),
						     "text", FAMILY_NAME_COLUMN,
						     NULL);
  gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
426
  gtk_tree_view_append_column (GTK_TREE_VIEW (priv->family_list), column);
427

428 429
  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->family_list), FALSE);
  gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->family_list)),
430 431
			       GTK_SELECTION_BROWSE);
  
432
  gtk_label_set_mnemonic_widget (GTK_LABEL (font_label), priv->family_list);
433

434
  scrolled_win = gtk_scrolled_window_new (NULL, NULL);
435
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), GTK_SHADOW_IN);
Manish Singh's avatar
Manish Singh committed
436 437
  gtk_widget_set_size_request (scrolled_win,
			       FONT_LIST_WIDTH, FONT_LIST_HEIGHT);
438
  gtk_container_add (GTK_CONTAINER (scrolled_win), priv->family_list);
439 440
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
				  GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
441
  gtk_widget_show (priv->family_list);
442
  gtk_widget_show (scrolled_win);
443

444
  gtk_table_attach (GTK_TABLE (table), scrolled_win, 0, 1, 1, 3,
445 446
		    GTK_EXPAND | GTK_FILL,
		    GTK_EXPAND | GTK_FILL, 0, 0);
447 448 449 450 451
  focus_chain = g_list_append (focus_chain, scrolled_win);
  
  model = gtk_list_store_new (2,
			      G_TYPE_OBJECT,  /* FACE_COLUMN */
			      G_TYPE_STRING); /* FACE_NAME_COLUMN */
452
  priv->face_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
453
  g_object_unref (model);
454
  g_signal_connect (priv->face_list, "row-activated",
455
		    G_CALLBACK (list_row_activated), fontsel);
456

457
  gtk_label_set_mnemonic_widget (GTK_LABEL (style_label), priv->face_list);
458 459 460 461 462 463

  column = gtk_tree_view_column_new_with_attributes ("Face",
						     gtk_cell_renderer_text_new (),
						     "text", FACE_NAME_COLUMN,
						     NULL);
  gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
464
  gtk_tree_view_append_column (GTK_TREE_VIEW (priv->face_list), column);
465

466 467
  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->face_list), FALSE);
  gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->face_list)),
468
			       GTK_SELECTION_BROWSE);
469
  
470
  scrolled_win = gtk_scrolled_window_new (NULL, NULL);
471
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), GTK_SHADOW_IN);
Manish Singh's avatar
Manish Singh committed
472 473
  gtk_widget_set_size_request (scrolled_win,
			       FONT_STYLE_LIST_WIDTH, FONT_LIST_HEIGHT);
474
  gtk_container_add (GTK_CONTAINER (scrolled_win), priv->face_list);
475 476
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
				  GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
477
  gtk_widget_show (priv->face_list);
478
  gtk_widget_show (scrolled_win);
479
  gtk_table_attach (GTK_TABLE (table), scrolled_win, 1, 2, 1, 3,
480 481
		    GTK_EXPAND | GTK_FILL,
		    GTK_EXPAND | GTK_FILL, 0, 0);
482 483
  focus_chain = g_list_append (focus_chain, scrolled_win);
  
484
  focus_chain = g_list_append (focus_chain, priv->size_entry);
485 486

  model = gtk_list_store_new (1, G_TYPE_INT);
487
  priv->size_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
488
  g_object_unref (model);
489
  g_signal_connect (priv->size_list, "row-activated",
490
		    G_CALLBACK (list_row_activated), fontsel);
491 492 493 494 495 496

  column = gtk_tree_view_column_new_with_attributes ("Size",
						     gtk_cell_renderer_text_new (),
						     "text", SIZE_COLUMN,
						     NULL);
  gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
497
  gtk_tree_view_append_column (GTK_TREE_VIEW (priv->size_list), column);
498

499 500
  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->size_list), FALSE);
  gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->size_list)),
501
			       GTK_SELECTION_BROWSE);
502
  
503
  scrolled_win = gtk_scrolled_window_new (NULL, NULL);
504
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), GTK_SHADOW_IN);
505
  gtk_container_add (GTK_CONTAINER (scrolled_win), priv->size_list);
Manish Singh's avatar
Manish Singh committed
506
  gtk_widget_set_size_request (scrolled_win, -1, FONT_LIST_HEIGHT);
507
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
508
				  GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
509
  gtk_widget_show (priv->size_list);
510
  gtk_widget_show (scrolled_win);
511
  gtk_table_attach (GTK_TABLE (table), scrolled_win, 2, 3, 2, 3,
512 513 514 515 516
		    GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
  focus_chain = g_list_append (focus_chain, scrolled_win);

  gtk_container_set_focus_chain (GTK_CONTAINER (table), focus_chain);
  g_list_free (focus_chain);
517
  
518
  /* Insert the fonts. */
519
  g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->family_list)), "changed",
520
		    G_CALLBACK (gtk_font_selection_select_font), fontsel);
521

522
  g_signal_connect_after (priv->family_list, "map",
Manish Singh's avatar
Manish Singh committed
523 524
			  G_CALLBACK (gtk_font_selection_scroll_on_map),
			  fontsel);
525
  
526
  g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->face_list)), "changed",
527
		    G_CALLBACK (gtk_font_selection_select_style), fontsel);
528

529
  g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->size_list)), "changed",
530
		    G_CALLBACK (gtk_font_selection_select_size), fontsel);
531
  atk_obj = gtk_widget_get_accessible (priv->size_list);
532 533 534 535 536 537 538 539 540 541 542 543 544 545 546
  if (GTK_IS_ACCESSIBLE (atk_obj))
    {
      /* Accessibility support is enabled.
       * Make the label ATK_RELATON_LABEL_FOR for the size list as well.
       */
      AtkObject *atk_label;
      AtkRelationSet *relation_set;
      AtkRelation *relation;
      AtkObject *obj_array[1];

      atk_label = gtk_widget_get_accessible (label);
      relation_set = atk_object_ref_relation_set (atk_obj);
      relation = atk_relation_set_get_relation_by_type (relation_set, ATK_RELATION_LABELLED_BY);
      if (relation)
        {
547
          atk_relation_add_target (relation, atk_label);
548 549 550 551 552 553 554 555 556 557 558 559 560
        }
      else 
        {
          obj_array[0] = atk_label;
          relation = atk_relation_new (obj_array, 1, ATK_RELATION_LABELLED_BY);
          atk_relation_set_add (relation_set, relation);
        }
      g_object_unref (relation_set);

      relation_set = atk_object_ref_relation_set (atk_label);
      relation = atk_relation_set_get_relation_by_type (relation_set, ATK_RELATION_LABEL_FOR);
      if (relation)
        {
561
          atk_relation_add_target (relation, atk_obj);
562 563 564 565 566 567 568 569
        }
      else 
        {
          obj_array[0] = atk_obj;
          relation = atk_relation_new (obj_array, 1, ATK_RELATION_LABEL_FOR);
          atk_relation_set_add (relation_set, relation);
        }
      g_object_unref (relation_set);
570
    }
571

572
  vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
573 574 575
  gtk_widget_show (vbox);
  gtk_box_pack_start (GTK_BOX (fontsel), vbox, FALSE, TRUE, 0);
  
576
  /* create the text entry widget */
577
  label = gtk_label_new_with_mnemonic (_("_Preview:"));
578 579
  gtk_widget_set_halign (label, GTK_ALIGN_START);
  gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
580
  gtk_widget_show (label);
581
  gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 0);
582 583

  text_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
584
  gtk_widget_show (text_box);
585
  gtk_box_pack_start (GTK_BOX (vbox), text_box, FALSE, TRUE, 0);
586
  
587 588 589
  priv->preview_entry = gtk_entry_new ();
  gtk_label_set_mnemonic_widget (GTK_LABEL (label), priv->preview_entry);
  gtk_entry_set_text (GTK_ENTRY (priv->preview_entry), _(PREVIEW_TEXT));
590
  
591 592
  gtk_widget_show (priv->preview_entry);
  g_signal_connect (priv->preview_entry, "changed",
Manish Singh's avatar
Manish Singh committed
593
		    G_CALLBACK (gtk_font_selection_preview_changed), fontsel);
594
  gtk_widget_set_size_request (priv->preview_entry,
Manish Singh's avatar
Manish Singh committed
595
			       -1, INITIAL_PREVIEW_HEIGHT);
596
  gtk_box_pack_start (GTK_BOX (text_box), priv->preview_entry,
597
		      TRUE, TRUE, 0);
598
  gtk_widget_pop_composite_child();
599 600
}

Matthias Clasen's avatar
Matthias Clasen committed
601 602 603 604 605
/**
 * gtk_font_selection_new:
 *
 * Creates a new #GtkFontSelection.
 *
606 607 608
 * Return value: a new #GtkFontSelection
 *
 * Deprecated: 3.2: Use #GtkFontChooserWidget instead
Matthias Clasen's avatar
Matthias Clasen committed
609
 */
610
GtkWidget *
611
gtk_font_selection_new (void)
612 613
{
  GtkFontSelection *fontsel;
614
  
Manish Singh's avatar
Manish Singh committed
615
  fontsel = g_object_new (GTK_TYPE_FONT_SELECTION, NULL);
616
  
617 618 619 620
  return GTK_WIDGET (fontsel);
}

static void
621
gtk_font_selection_finalize (GObject *object)
622
{
623
  GtkFontSelection *fontsel = GTK_FONT_SELECTION (object);
624

625 626 627
  gtk_font_selection_ref_family (fontsel, NULL);
  gtk_font_selection_ref_face (fontsel, NULL);

628
  G_OBJECT_CLASS (gtk_font_selection_parent_class)->finalize (object);
629 630
}

631
static void
632 633
gtk_font_selection_ref_family (GtkFontSelection *fontsel,
			       PangoFontFamily  *family)
634
{
635
  GtkFontSelectionPrivate *priv = fontsel->priv;
636

637 638
  if (family)
    family = g_object_ref (family);
639 640 641
  if (priv->family)
    g_object_unref (priv->family);
  priv->family = family;
642
}
643

644 645 646
static void gtk_font_selection_ref_face (GtkFontSelection *fontsel,
					 PangoFontFace    *face)
{
647
  GtkFontSelectionPrivate *priv = fontsel->priv;
648

649 650
  if (face)
    face = g_object_ref (face);
651 652 653
  if (priv->face)
    g_object_unref (priv->face);
  priv->face = face;
654 655 656 657 658
}

static void
gtk_font_selection_reload_fonts (GtkFontSelection *fontsel)
{
659 660
  if (gtk_widget_has_screen (GTK_WIDGET (fontsel)))
    {
661 662 663
      PangoFontDescription *desc;
      desc = gtk_font_selection_get_font_description (fontsel);

664 665 666
      gtk_font_selection_show_available_fonts (fontsel);
      gtk_font_selection_show_available_sizes (fontsel, TRUE);
      gtk_font_selection_show_available_styles (fontsel);
667 668 669 670 671

      gtk_font_selection_select_font_desc (fontsel, desc, NULL, NULL);
      gtk_font_selection_scroll_to_selection (fontsel);

      pango_font_description_free (desc);
672 673 674
    }
}

675 676 677 678 679 680 681 682
static void
gtk_font_selection_screen_changed (GtkWidget *widget,
				   GdkScreen *previous_screen)
{
  gtk_font_selection_reload_fonts (GTK_FONT_SELECTION (widget));
}

static void
683
gtk_font_selection_style_updated (GtkWidget *widget)
684
{
685 686
  GTK_WIDGET_CLASS (gtk_font_selection_parent_class)->style_updated (widget);

687 688 689 690
  /* Maybe fonts where installed or removed... */
  gtk_font_selection_reload_fonts (GTK_FONT_SELECTION (widget));
}

691 692 693 694
static void
gtk_font_selection_preview_changed (GtkWidget        *entry,
				    GtkFontSelection *fontsel)
{
695
  g_object_notify (G_OBJECT (fontsel), "preview-text");
696
}
697

698 699 700 701 702 703 704 705 706 707 708 709 710 711 712
static void
scroll_to_selection (GtkTreeView *tree_view)
{
  GtkTreeSelection *selection = gtk_tree_view_get_selection (tree_view);
  GtkTreeModel *model;
  GtkTreeIter iter;

  if (gtk_tree_selection_get_selected (selection, &model, &iter))
    {
      GtkTreePath *path = gtk_tree_model_get_path (model, &iter);
      gtk_tree_view_scroll_to_cell (tree_view, path, NULL, TRUE, 0.5, 0.5);
      gtk_tree_path_free (path);
    }
}

713 714 715 716 717 718 719
static void
set_cursor_to_iter (GtkTreeView *view,
		    GtkTreeIter *iter)
{
  GtkTreeModel *model = gtk_tree_view_get_model (view);
  GtkTreePath *path = gtk_tree_model_get_path (model, iter);
  
720
  gtk_tree_view_set_cursor (view, path, NULL, FALSE);
721 722 723 724

  gtk_tree_path_free (path);
}

725
static void
726
gtk_font_selection_scroll_to_selection (GtkFontSelection *fontsel)
727
{
728
  GtkFontSelectionPrivate *priv = fontsel->priv;
729

730
  /* Try to scroll the font family list to the selected item */
731 732
  scroll_to_selection (GTK_TREE_VIEW (priv->family_list));

733
  /* Try to scroll the font family list to the selected item */
734 735
  scroll_to_selection (GTK_TREE_VIEW (priv->face_list));

736
  /* Try to scroll the font family list to the selected item */
737
  scroll_to_selection (GTK_TREE_VIEW (priv->size_list));
738 739 740 741 742 743 744 745 746
/* This is called when the list is mapped. Here we scroll to the current
   font if necessary. */
}

static void
gtk_font_selection_scroll_on_map (GtkWidget		*widget,
                                  gpointer		 data)
{
  gtk_font_selection_scroll_to_selection (GTK_FONT_SELECTION (data));
747 748
}

749
/* This is called when a family is selected in the list. */
Damon Chaplin's avatar
Damon Chaplin committed
750
static void
751 752
gtk_font_selection_select_font (GtkTreeSelection *selection,
				gpointer          data)
Damon Chaplin's avatar
Damon Chaplin committed
753 754
{
  GtkFontSelection *fontsel;
755
  GtkFontSelectionPrivate *priv;
756 757
  GtkTreeModel *model;
  GtkTreeIter iter;
758
#ifdef INCLUDE_FONT_ENTRIES
759
  const gchar *family_name;
760 761
#endif

Damon Chaplin's avatar
Damon Chaplin committed
762
  fontsel = GTK_FONT_SELECTION (data);
763
  priv = fontsel->priv;
Damon Chaplin's avatar
Damon Chaplin committed
764

765
  if (gtk_tree_selection_get_selected (selection, &model, &iter))
Damon Chaplin's avatar
Damon Chaplin committed
766
    {
767
      PangoFontFamily *family;
768

769
      gtk_tree_model_get (model, &iter, FAMILY_COLUMN, &family, -1);
770
      if (priv->family != family)
Damon Chaplin's avatar
Damon Chaplin committed
771
	{
772
	  gtk_font_selection_ref_family (fontsel, family);
773

774
#ifdef INCLUDE_FONT_ENTRIES
775 776
	  family_name = pango_font_family_get_name (priv->family);
	  gtk_entry_set_text (GTK_ENTRY (priv->font_entry), family_name);
777
#endif
778

779 780
	  gtk_font_selection_show_available_styles (fontsel);
	  gtk_font_selection_select_best_style (fontsel, TRUE);
Damon Chaplin's avatar
Damon Chaplin committed
781
	}
782 783

      g_object_unref (family);
Damon Chaplin's avatar
Damon Chaplin committed
784 785 786
    }
}

787
static int
788
cmp_families (const void *a, const void *b)
789
{
790 791 792
  const char *a_name = pango_font_family_get_name (*(PangoFontFamily **)a);
  const char *b_name = pango_font_family_get_name (*(PangoFontFamily **)b);
  
793
  return g_utf8_collate (a_name, b_name);
794
}
Damon Chaplin's avatar
Damon Chaplin committed
795

796
static void
797
gtk_font_selection_show_available_fonts (GtkFontSelection *fontsel)
798
{
799
  GtkFontSelectionPrivate *priv = fontsel->priv;
800 801 802
  GtkListStore *model;
  PangoFontFamily **families;
  PangoFontFamily *match_family = NULL;
803
  gint n_families, i;
804
  GtkTreeIter match_row;
805 806 807

  model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (priv->family_list)));

808
  pango_context_list_families (gtk_widget_get_pango_context (GTK_WIDGET (fontsel)),
809 810
			       &families, &n_families);
  qsort (families, n_families, sizeof (PangoFontFamily *), cmp_families);
811

812
  gtk_list_store_clear (model);
813 814 815

  for (i=0; i<n_families; i++)
    {
816 817 818
      const gchar *name = pango_font_family_get_name (families[i]);
      GtkTreeIter iter;

819 820 821 822 823
      gtk_list_store_insert_with_values (model, &iter, -1,
                                         FAMILY_COLUMN, families[i],
                                         FAMILY_NAME_COLUMN, name,
                                         -1);

824
      if (i == 0 || !g_ascii_strcasecmp (name, "sans"))
825 826 827 828
	{
	  match_family = families[i];
	  match_row = iter;
	}
829
    }
830

831
  gtk_font_selection_ref_family (fontsel, match_family);
832 833
  if (match_family)
    {
834
      set_cursor_to_iter (GTK_TREE_VIEW (priv->family_list), &match_row);
Manish Singh's avatar
Manish Singh committed
835
#ifdef INCLUDE_FONT_ENTRIES
836
      gtk_entry_set_text (GTK_ENTRY (priv->font_entry), 
837
			  pango_font_family_get_name (match_family));
838
#endif /* INCLUDE_FONT_ENTRIES */
839
    }
840

841
  g_free (families);
842
}
843

844 845 846
static int
compare_font_descriptions (const PangoFontDescription *a, const PangoFontDescription *b)
{
847
  int val = strcmp (pango_font_description_get_family (a), pango_font_description_get_family (b));
848 849 850
  if (val != 0)
    return val;

851 852
  if (pango_font_description_get_weight (a) != pango_font_description_get_weight (b))
    return pango_font_description_get_weight (a) - pango_font_description_get_weight (b);
853

854 855
  if (pango_font_description_get_style (a) != pango_font_description_get_style (b))
    return pango_font_description_get_style (a) - pango_font_description_get_style (b);
856
  
857 858
  if (pango_font_description_get_stretch (a) != pango_font_description_get_stretch (b))
    return pango_font_description_get_stretch (a) - pango_font_description_get_stretch (b);
859

860 861
  if (pango_font_description_get_variant (a) != pango_font_description_get_variant (b))
    return pango_font_description_get_variant (a) - pango_font_description_get_variant (b);
862 863 864 865 866

  return 0;
}

static int
867
faces_sort_func (const void *a, const void *b)
868
{
869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887
  PangoFontDescription *desc_a = pango_font_face_describe (*(PangoFontFace **)a);
  PangoFontDescription *desc_b = pango_font_face_describe (*(PangoFontFace **)b);
  
  int ord = compare_font_descriptions (desc_a, desc_b);

  pango_font_description_free (desc_a);
  pango_font_description_free (desc_b);

  return ord;
}

static gboolean
font_description_style_equal (const PangoFontDescription *a,
			      const PangoFontDescription *b)
{
  return (pango_font_description_get_weight (a) == pango_font_description_get_weight (b) &&
	  pango_font_description_get_style (a) == pango_font_description_get_style (b) &&
	  pango_font_description_get_stretch (a) == pango_font_description_get_stretch (b) &&
	  pango_font_description_get_variant (a) == pango_font_description_get_variant (b));
888
}
889

890
/* This fills the font style list with all the possible style combinations
891 892 893 894
   for the current font family. */
static void
gtk_font_selection_show_available_styles (GtkFontSelection *fontsel)
{
895
  GtkFontSelectionPrivate *priv = fontsel->priv;
896
  gint n_faces, i;
897
  PangoFontFace **faces;
898
  PangoFontDescription *old_desc;
899 900 901
  GtkListStore *model;
  GtkTreeIter match_row;
  PangoFontFace *match_face = NULL;
902 903 904 905 906

  model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (priv->face_list)));

  if (priv->face)
    old_desc = pango_font_face_describe (priv->face);
907 908 909
  else
    old_desc= NULL;

910
  pango_font_family_list_faces (priv->family, &faces, &n_faces);
911
  qsort (faces, n_faces, sizeof (PangoFontFace *), faces_sort_func);
912

913
  gtk_list_store_clear (model);
914

915
  for (i=0; i < n_faces; i++)
916
    {
917 918
      GtkTreeIter iter;
      const gchar *str = pango_font_face_get_face_name (faces[i]);
919

920 921 922 923
      gtk_list_store_insert_with_values (model, &iter, -1,
                                         FACE_COLUMN, faces[i],
                                         FACE_NAME_COLUMN, str,
                                         -1);
924 925

      if (i == 0)
926
	{
927 928 929 930 931 932
	  match_row = iter;
	  match_face = faces[i];
	}
      else if (old_desc)
	{
	  PangoFontDescription *tmp_desc = pango_font_face_describe (faces[i]);
933 934
	  
	  if (font_description_style_equal (tmp_desc, old_desc))
935 936 937 938
	    {
	      match_row = iter;
	      match_face = faces[i];
	    }
939
      
940 941
	  pango_font_description_free (tmp_desc);
	}
942
    }
943

944 945 946
  if (old_desc)
    pango_font_description_free (old_desc);

947
  gtk_font_selection_ref_face (fontsel, match_face);
948
  if (match_face)
949
    {
Manish Singh's avatar
Manish Singh committed
950
#ifdef INCLUDE_FONT_ENTRIES
951
      const gchar *str = pango_font_face_get_face_name (priv->face);
952

953 954 955
      gtk_entry_set_text (GTK_ENTRY (priv->font_style_entry), str);
#endif
      set_cursor_to_iter (GTK_TREE_VIEW (priv->face_list), &match_row);
956
    }
957 958

  g_free (faces);
959 960 961 962 963 964 965 966
}

/* This selects a style when the user selects a font. It just uses the first
   available style at present. I was thinking of trying to maintain the
   selected style, e.g. bold italic, when the user selects different fonts.
   However, the interface is so easy to use now I'm not sure it's worth it.
   Note: This will load a font. */
static void
967 968
gtk_font_selection_select_best_style (GtkFontSelection *fontsel,
				      gboolean	        use_first)
969
{
970
  GtkFontSelectionPrivate *priv = fontsel->priv;
971 972 973
  GtkTreeIter iter;
  GtkTreeModel *model;

974
  model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->face_list));
975

976
  if (gtk_tree_model_get_iter_first (model, &iter))
977
    {
978 979
      set_cursor_to_iter (GTK_TREE_VIEW (priv->face_list), &iter);
      scroll_to_selection (GTK_TREE_VIEW (priv->face_list));
980 981 982
    }

  gtk_font_selection_show_available_sizes (fontsel, FALSE);
983 984 985 986 987 988
  gtk_font_selection_select_best_size (fontsel);
}


/* This is called when a style is selected in the list. */
static void
989 990
gtk_font_selection_select_style (GtkTreeSelection *selection,
				 gpointer          data)
991
{
992
  GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
993 994
  GtkTreeModel *model;
  GtkTreeIter iter;
995

996
  if (gtk_tree_selection_get_selected (selection, &model, &iter))
997
    {
998 999 1000
      PangoFontFace *face;
      
      gtk_tree_model_get (model, &iter, FACE_COLUMN, &face, -1);
1001
      gtk_font_selection_ref_face (fontsel, face);
1002
      g_object_unref (face);
1003 1004
    }

1005
  gtk_font_selection_show_available_sizes (fontsel, FALSE);
1006
  gtk_font_selection_select_best_size (fontsel);
1007 1008
}

1009
static void
1010 1011
gtk_font_selection_show_available_sizes (GtkFontSelection *fontsel,
					 gboolean          first_time)
1012
{
1013
  GtkFontSelectionPrivate *priv = fontsel->priv;
1014
  gint i;
1015
  GtkListStore *model;
1016
  gchar buffer[128];
1017
  gchar *p;
1018 1019

  model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (priv->size_list)));
1020

1021
  /* Insert the standard font sizes */
1022 1023 1024
  if (first_time)
    {
      gtk_list_store_clear (model);
1025

1026 1027 1028
      for (i = 0; i < G_N_ELEMENTS (font_sizes); i++)
	{
	  GtkTreeIter iter;
1029

1030 1031
	  gtk_list_store_insert_with_values (model, &iter, -1,
	                                     SIZE_COLUMN, font_sizes[i], -1);
1032 1033 1034

	  if (font_sizes[i] * PANGO_SCALE == priv->size)
	    set_cursor_to_iter (GTK_TREE_VIEW (priv->size_list), &iter);
1035 1036 1037
	}
    }
  else
1038
    {
1039
      GtkTreeIter iter;
1040
      gboolean found = FALSE;
1041

1042
      gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &iter);
1043
      for (i = 0; i < G_N_ELEMENTS (font_sizes) && !found; i++)
1044
	{
1045
	  if (font_sizes[i] * PANGO_SCALE == priv->size)
1046
	    {
1047
	      set_cursor_to_iter (GTK_TREE_VIEW (priv->size_list), &iter);
1048 1049
	      found = TRUE;
	    }
1050

1051 1052
          if (!gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &iter))
            break;
1053
	}
1054 1055 1056

      if (!found)
	{
1057
	  GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->size_list));
1058 1059 1060 1061 1062 1063 1064
	  gtk_tree_selection_unselect_all (selection);
	}
    }

  /* Set the entry to the new size, rounding to 1 digit,
   * trimming of trailing 0's and a trailing period
   */
1065
  g_snprintf (buffer, sizeof (buffer), "%.1f", priv->size / (1.0 * PANGO_SCALE));
1066 1067 1068 1069 1070 1071 1072 1073
  if (strchr (buffer, '.'))
    {
      p = buffer + strlen (buffer) - 1;
      while (*p == '0')
	p--;
      if (*p == '.')
	p--;
      p[1] = '\0';
1074 1075
    }

1076
  /* Compare, to avoid moving the cursor unecessarily */
1077 1078
  if (strcmp (gtk_entry_get_text (GTK_ENTRY (priv->size_entry)), buffer) != 0)
    gtk_entry_set_text (GTK_ENTRY (priv->size_entry), buffer);
1079 1080
}

1081
static void
1082
gtk_font_selection_select_best_size (GtkFontSelection *fontsel)
1083
{
1084 1085
  gtk_font_selection_load_font (fontsel);  
}
1086

1087 1088 1089 1090
static void
gtk_font_selection_set_size (GtkFontSelection *fontsel,
			     gint              new_size)
{
1091
  GtkFontSelectionPrivate *priv = fontsel->priv;
1092 1093

  if (priv->size != new_size)
1094
    {
1095
      priv->size = new_size;
1096 1097 1098 1099 1100 1101

      gtk_font_selection_show_available_sizes (fontsel, FALSE);      
      gtk_font_selection_load_font (fontsel);
    }
}

1102 1103
/* If the user hits return in the font size entry, we change to the new font
   size. */
1104 1105 1106
static void
gtk_font_selection_size_activate (GtkWidget   *w,
                                  gpointer     data)
1107
{
1108
  GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
1109
  GtkFontSelectionPrivate *priv = fontsel->priv;
1110
  gint new_size;
1111
  const gchar *text;
1112

1113
  text = gtk_entry_get_text (GTK_ENTRY (priv->size_entry));
1114 1115
  new_size = MAX (0.1, atof (text) * PANGO_SCALE + 0.5);

1116
  if (priv->size != new_size)
1117 1118 1119
    gtk_font_selection_set_size (fontsel, new_size);
  else 
    list_row_activated (w);
1120 1121
}

1122 1123 1124 1125 1126
static gboolean
gtk_font_selection_size_focus_out (GtkWidget     *w,
				   GdkEventFocus *event,
				   gpointer       data)
{
1127
  GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
1128
  GtkFontSelectionPrivate *priv = fontsel->priv;
1129 1130 1131
  gint new_size;
  const gchar *text;

1132
  text = gtk_entry_get_text (GTK_ENTRY (priv->size_entry));
1133 1134 1135
  new_size = MAX (0.1, atof (text) * PANGO_SCALE + 0.5);

  gtk_font_selection_set_size (fontsel, new_size);
1136

1137 1138 1139
  return TRUE;
}

1140
/* This is called when a size is selected in the list. */
1141
static void
Owen Taylor's avatar