gtkfontsel.c 55.1 KB
Newer Older
Cody Russell's avatar
Cody Russell committed
1
/* GTK - The GIMP Toolkit
Owen Taylor's avatar
Owen Taylor committed
2 3
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
 *
4
 * Massively updated for Pango by Owen Taylor, May 2000
Owen Taylor's avatar
Owen Taylor committed
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
Owen Taylor's avatar
Owen Taylor committed
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.
Owen Taylor's avatar
Owen Taylor committed
18
 *
19
 * You should have received a copy of the GNU Lesser General Public
Owen Taylor's avatar
Owen Taylor committed
20 21 22 23 24
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

25
/*
26
 * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
27 28 29 30 31
 * 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/. 
 */

32
#include "config.h"
Owen Taylor's avatar
Owen Taylor committed
33
#include <stdlib.h>
34
#include <glib/gprintf.h>
Owen Taylor's avatar
Owen Taylor committed
35 36
#include <string.h>

37 38
#include <atk/atk.h>

39
#include "gdk/gdk.h"
Owen Taylor's avatar
Owen Taylor committed
40 41
#include "gdk/gdkkeysyms.h"

42 43
#include "gtkfontsel.h"

Owen Taylor's avatar
Owen Taylor committed
44
#include "gtkbutton.h"
45
#include "gtkcellrenderertext.h"
Owen Taylor's avatar
Owen Taylor committed
46 47 48 49 50
#include "gtkentry.h"
#include "gtkframe.h"
#include "gtkhbbox.h"
#include "gtkhbox.h"
#include "gtklabel.h"
51
#include "gtkliststore.h"
52
#include "gtkrc.h"
53
#include "gtkstock.h"
Owen Taylor's avatar
Owen Taylor committed
54
#include "gtktable.h"
55 56
#include "gtktreeselection.h"
#include "gtktreeview.h"
Owen Taylor's avatar
Owen Taylor committed
57
#include "gtkvbox.h"
58
#include "gtkscrolledwindow.h"
59
#include "gtkintl.h"
60
#include "gtkaccessible.h"
61
#include "gtkprivate.h"
Johan Dahlin's avatar
Johan Dahlin committed
62
#include "gtkbuildable.h"
Owen Taylor's avatar
Owen Taylor committed
63

64 65 66 67 68 69 70 71
/* 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

Owen Taylor's avatar
Owen Taylor committed
72 73
/* This is the default text shown in the preview entry, though the user
   can set it. Remember that some fonts only have capital letters. */
74
#define PREVIEW_TEXT N_("abcdefghijk ABCDEFGHIJK")
Owen Taylor's avatar
Owen Taylor committed
75

Matthias Clasen's avatar
Matthias Clasen committed
76 77
#define DEFAULT_FONT_NAME "Sans 10"

Owen Taylor's avatar
Owen Taylor committed
78 79 80 81 82
/* 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

83
/* These are the sizes of the font, style & size lists. */
Owen Taylor's avatar
Owen Taylor committed
84
#define FONT_LIST_HEIGHT	136
Damon Chaplin's avatar
""  
Damon Chaplin committed
85 86
#define FONT_LIST_WIDTH		190
#define FONT_STYLE_LIST_WIDTH	170
Owen Taylor's avatar
Owen Taylor committed
87 88
#define FONT_SIZE_LIST_WIDTH	60

89
/* These are what we use as the standard font sizes, for the size list.
90 91
 */
static const guint16 font_sizes[] = {
Matthias Clasen's avatar
Matthias Clasen committed
92
  6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 22, 24, 26, 28,
93
  32, 36, 40, 48, 56, 64, 72
Owen Taylor's avatar
Owen Taylor committed
94 95
};

96 97 98 99 100 101
enum {
   PROP_0,
   PROP_FONT_NAME,
   PROP_PREVIEW_TEXT
};

102 103 104 105 106 107 108 109 110 111 112 113 114 115 116

enum {
  FAMILY_COLUMN,
  FAMILY_NAME_COLUMN
};

enum {
  FACE_COLUMN,
  FACE_NAME_COLUMN
};

enum {
  SIZE_COLUMN
};

117 118 119 120 121 122 123 124
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);
125 126 127 128 129
static void    gtk_font_selection_finalize	     (GObject         *object);
static void    gtk_font_selection_screen_changed     (GtkWidget	      *widget,
						      GdkScreen       *previous_screen);
static void    gtk_font_selection_style_set          (GtkWidget      *widget,
						      GtkStyle       *prev_style);
Owen Taylor's avatar
Owen Taylor committed
130 131

/* These are the callbacks & related functions. */
132
static void     gtk_font_selection_select_font           (GtkTreeSelection *selection,
133 134 135 136 137 138
							  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);
139
static void     gtk_font_selection_select_style          (GtkTreeSelection *selection,
140 141 142
							  gpointer          data);

static void     gtk_font_selection_select_best_size      (GtkFontSelection *fs);
143 144
static void     gtk_font_selection_show_available_sizes  (GtkFontSelection *fs,
							  gboolean          first_time);
145
static void     gtk_font_selection_size_activate         (GtkWidget        *w,
146
							  gpointer          data);
147 148 149
static gboolean gtk_font_selection_size_focus_out        (GtkWidget        *w,
							  GdkEventFocus    *event,
							  gpointer          data);
150
static void     gtk_font_selection_select_size           (GtkTreeSelection *selection,
151 152
							  gpointer          data);

153
static void     gtk_font_selection_scroll_on_map         (GtkWidget        *w,
154 155
							  gpointer          data);

156 157
static void     gtk_font_selection_preview_changed       (GtkWidget        *entry,
							  GtkFontSelection *fontsel);
158 159
static void     gtk_font_selection_scroll_to_selection   (GtkFontSelection *fontsel);

Owen Taylor's avatar
Owen Taylor committed
160 161

/* Misc. utility functions. */
Manish Singh's avatar
Manish Singh committed
162
static void    gtk_font_selection_load_font          (GtkFontSelection *fs);
Owen Taylor's avatar
Owen Taylor committed
163 164
static void    gtk_font_selection_update_preview     (GtkFontSelection *fs);

165 166 167 168 169 170 171 172 173 174
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);
175

Matthias Clasen's avatar
Matthias Clasen committed
176
G_DEFINE_TYPE (GtkFontSelection, gtk_font_selection, GTK_TYPE_VBOX)
Owen Taylor's avatar
Owen Taylor committed
177 178

static void
179
gtk_font_selection_class_init (GtkFontSelectionClass *klass)
Owen Taylor's avatar
Owen Taylor committed
180
{
181
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
182
  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
183
  
184 185
  gobject_class->set_property = gtk_font_selection_set_property;
  gobject_class->get_property = gtk_font_selection_get_property;
186

Owen Taylor's avatar
Owen Taylor committed
187
  widget_class->screen_changed = gtk_font_selection_screen_changed;
188
  widget_class->style_set = gtk_font_selection_style_set;
189 190 191
   
  g_object_class_install_property (gobject_class,
                                   PROP_FONT_NAME,
192
                                   g_param_spec_string ("font-name",
193
                                                        P_("Font name"),
Matthias Clasen's avatar
Matthias Clasen committed
194 195
                                                        P_("The string that represents this font"),
                                                        DEFAULT_FONT_NAME,
196
                                                        GTK_PARAM_READWRITE));
197 198
  g_object_class_install_property (gobject_class,
                                   PROP_PREVIEW_TEXT,
199
                                   g_param_spec_string ("preview-text",
200 201
                                                        P_("Preview text"),
                                                        P_("The text to display in order to demonstrate the selected font"),
Matthias Clasen's avatar
Matthias Clasen committed
202
                                                        _(PREVIEW_TEXT),
203
                                                        GTK_PARAM_READWRITE));
204
  gobject_class->finalize = gtk_font_selection_finalize;
Owen Taylor's avatar
Owen Taylor committed
205 206
}

207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
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:
243
      g_value_take_string (value, gtk_font_selection_get_font_name (fontsel));
244 245 246 247 248 249 250 251 252 253
      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;
    }
}

254 255 256 257 258 259 260 261 262
/* 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)
{
  GtkWindow *window;
  
  window = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (widget)));
263
  if (!gtk_widget_is_toplevel (GTK_WIDGET (window)))
264 265 266 267 268
    window = NULL;
  
  if (window
      && widget != window->default_widget
      && !(widget == window->focus_widget &&
269
	   (!window->default_widget || !gtk_widget_get_sensitive (window->default_widget))))
270 271 272 273 274 275
    {
      gtk_window_activate_default (window);
    }
  
  return TRUE;
}
276

Owen Taylor's avatar
Owen Taylor committed
277
static void
278
gtk_font_selection_init (GtkFontSelection *fontsel)
Owen Taylor's avatar
Owen Taylor committed
279
{
280
  GtkWidget *scrolled_win;
281 282
  GtkWidget *text_box;
  GtkWidget *table, *label;
283
  GtkWidget *font_label, *style_label;
284
  GtkWidget *vbox;
285 286 287
  GtkListStore *model;
  GtkTreeViewColumn *column;
  GList *focus_chain = NULL;
288
  AtkObject *atk_obj;
289

290 291
  gtk_widget_push_composite_child ();

292
  gtk_box_set_spacing (GTK_BOX (fontsel), 12);
293
  fontsel->size = 12 * PANGO_SCALE;
294
  
Owen Taylor's avatar
Owen Taylor committed
295 296 297
  /* Create the table of font, style & size. */
  table = gtk_table_new (3, 3, FALSE);
  gtk_widget_show (table);
298 299
  gtk_table_set_row_spacings (GTK_TABLE (table), 6);
  gtk_table_set_col_spacings (GTK_TABLE (table), 12);
300
  gtk_box_pack_start (GTK_BOX (fontsel), table, TRUE, TRUE, 0);
301

Manish Singh's avatar
Manish Singh committed
302
#ifdef INCLUDE_FONT_ENTRIES
303
  fontsel->font_entry = gtk_entry_new ();
Manish Singh's avatar
Manish Singh committed
304 305
  gtk_editable_set_editable (GTK_EDITABLE (fontsel->font_entry), FALSE);
  gtk_widget_set_size_request (fontsel->font_entry, 20, -1);
306
  gtk_widget_show (fontsel->font_entry);
Owen Taylor's avatar
Owen Taylor committed
307 308
  gtk_table_attach (GTK_TABLE (table), fontsel->font_entry, 0, 1, 1, 2,
		    GTK_FILL, 0, 0, 0);
309 310
  
  fontsel->font_style_entry = gtk_entry_new ();
Manish Singh's avatar
Manish Singh committed
311 312
  gtk_editable_set_editable (GTK_EDITABLE (fontsel->font_style_entry), FALSE);
  gtk_widget_set_size_request (fontsel->font_style_entry, 20, -1);
313
  gtk_widget_show (fontsel->font_style_entry);
Owen Taylor's avatar
Owen Taylor committed
314 315
  gtk_table_attach (GTK_TABLE (table), fontsel->font_style_entry, 1, 2, 1, 2,
		    GTK_FILL, 0, 0, 0);
316
#endif /* INCLUDE_FONT_ENTRIES */
317 318
  
  fontsel->size_entry = gtk_entry_new ();
Manish Singh's avatar
Manish Singh committed
319
  gtk_widget_set_size_request (fontsel->size_entry, 20, -1);
Owen Taylor's avatar
Owen Taylor committed
320 321 322
  gtk_widget_show (fontsel->size_entry);
  gtk_table_attach (GTK_TABLE (table), fontsel->size_entry, 2, 3, 1, 2,
		    GTK_FILL, 0, 0, 0);
Manish Singh's avatar
Manish Singh committed
323 324 325
  g_signal_connect (fontsel->size_entry, "activate",
		    G_CALLBACK (gtk_font_selection_size_activate),
		    fontsel);
326
  g_signal_connect_after (fontsel->size_entry, "focus-out-event",
Manish Singh's avatar
Manish Singh committed
327 328
			  G_CALLBACK (gtk_font_selection_size_focus_out),
			  fontsel);
329
  
330 331 332 333
  font_label = gtk_label_new_with_mnemonic (_("_Family:"));
  gtk_misc_set_alignment (GTK_MISC (font_label), 0.0, 0.5);
  gtk_widget_show (font_label);
  gtk_table_attach (GTK_TABLE (table), font_label, 0, 1, 0, 1,
334
		    GTK_FILL, 0, 0, 0);  
335 336 337 338 339

  style_label = gtk_label_new_with_mnemonic (_("_Style:"));
  gtk_misc_set_alignment (GTK_MISC (style_label), 0.0, 0.5);
  gtk_widget_show (style_label);
  gtk_table_attach (GTK_TABLE (table), style_label, 1, 2, 0, 1,
340
		    GTK_FILL, 0, 0, 0);
341
  
342 343 344 345 346 347 348 349 350
  label = gtk_label_new_with_mnemonic (_("Si_ze:"));
  gtk_label_set_mnemonic_widget (GTK_LABEL (label),
                                 fontsel->size_entry);
  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  gtk_widget_show (label);
  gtk_table_attach (GTK_TABLE (table), label, 2, 3, 0, 1,
		    GTK_FILL, 0, 0, 0);
  
  
351 352 353 354 355 356 357 358
  /* Create the lists  */

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

359
  g_signal_connect (fontsel->family_list, "row-activated",
360 361
		    G_CALLBACK (list_row_activated), fontsel);

362 363 364 365 366 367 368 369 370 371 372 373 374
  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);
  gtk_tree_view_append_column (GTK_TREE_VIEW (fontsel->family_list), column);

  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (fontsel->family_list), FALSE);
  gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (fontsel->family_list)),
			       GTK_SELECTION_BROWSE);
  
  gtk_label_set_mnemonic_widget (GTK_LABEL (font_label), fontsel->family_list);

375
  scrolled_win = gtk_scrolled_window_new (NULL, NULL);
376
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), GTK_SHADOW_IN);
Manish Singh's avatar
Manish Singh committed
377 378
  gtk_widget_set_size_request (scrolled_win,
			       FONT_LIST_WIDTH, FONT_LIST_HEIGHT);
379
  gtk_container_add (GTK_CONTAINER (scrolled_win), fontsel->family_list);
380 381
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
				  GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
382
  gtk_widget_show (fontsel->family_list);
383
  gtk_widget_show (scrolled_win);
384

385
  gtk_table_attach (GTK_TABLE (table), scrolled_win, 0, 1, 1, 3,
Owen Taylor's avatar
Owen Taylor committed
386 387
		    GTK_EXPAND | GTK_FILL,
		    GTK_EXPAND | GTK_FILL, 0, 0);
388 389 390 391 392 393 394
  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 */
  fontsel->face_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
  g_object_unref (model);
395 396
  g_signal_connect (fontsel->face_list, "row-activated",
		    G_CALLBACK (list_row_activated), fontsel);
397 398 399 400 401 402 403 404 405 406 407 408 409

  gtk_label_set_mnemonic_widget (GTK_LABEL (style_label), fontsel->face_list);

  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);
  gtk_tree_view_append_column (GTK_TREE_VIEW (fontsel->face_list), column);

  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (fontsel->face_list), FALSE);
  gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (fontsel->face_list)),
			       GTK_SELECTION_BROWSE);
410
  
411
  scrolled_win = gtk_scrolled_window_new (NULL, NULL);
412
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), GTK_SHADOW_IN);
Manish Singh's avatar
Manish Singh committed
413 414
  gtk_widget_set_size_request (scrolled_win,
			       FONT_STYLE_LIST_WIDTH, FONT_LIST_HEIGHT);
415
  gtk_container_add (GTK_CONTAINER (scrolled_win), fontsel->face_list);
416 417
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
				  GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
418
  gtk_widget_show (fontsel->face_list);
419
  gtk_widget_show (scrolled_win);
420
  gtk_table_attach (GTK_TABLE (table), scrolled_win, 1, 2, 1, 3,
Owen Taylor's avatar
Owen Taylor committed
421 422
		    GTK_EXPAND | GTK_FILL,
		    GTK_EXPAND | GTK_FILL, 0, 0);
423 424 425 426 427 428 429
  focus_chain = g_list_append (focus_chain, scrolled_win);
  
  focus_chain = g_list_append (focus_chain, fontsel->size_entry);

  model = gtk_list_store_new (1, G_TYPE_INT);
  fontsel->size_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
  g_object_unref (model);
430 431
  g_signal_connect (fontsel->size_list, "row-activated",
		    G_CALLBACK (list_row_activated), fontsel);
432 433 434 435 436 437 438 439 440 441 442

  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);
  gtk_tree_view_append_column (GTK_TREE_VIEW (fontsel->size_list), column);

  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (fontsel->size_list), FALSE);
  gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (fontsel->size_list)),
			       GTK_SELECTION_BROWSE);
443
  
444
  scrolled_win = gtk_scrolled_window_new (NULL, NULL);
445 446
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), GTK_SHADOW_IN);
  gtk_container_add (GTK_CONTAINER (scrolled_win), fontsel->size_list);
Manish Singh's avatar
Manish Singh committed
447
  gtk_widget_set_size_request (scrolled_win, -1, FONT_LIST_HEIGHT);
448
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
449 450
				  GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
  gtk_widget_show (fontsel->size_list);
451
  gtk_widget_show (scrolled_win);
452
  gtk_table_attach (GTK_TABLE (table), scrolled_win, 2, 3, 2, 3,
453 454 455 456 457
		    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);
458
  
459 460 461
  /* Insert the fonts. */
  g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (fontsel->family_list)), "changed",
		    G_CALLBACK (gtk_font_selection_select_font), fontsel);
462

Manish Singh's avatar
Manish Singh committed
463 464 465
  g_signal_connect_after (fontsel->family_list, "map",
			  G_CALLBACK (gtk_font_selection_scroll_on_map),
			  fontsel);
466
  
467 468
  g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (fontsel->face_list)), "changed",
		    G_CALLBACK (gtk_font_selection_select_style), fontsel);
469

470 471
  g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (fontsel->size_list)), "changed",
		    G_CALLBACK (gtk_font_selection_select_size), fontsel);
472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487
  atk_obj = gtk_widget_get_accessible (fontsel->size_list);
  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)
        {
488
          atk_relation_add_target (relation, atk_label);
489 490 491 492 493 494 495 496 497 498 499 500 501
        }
      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)
        {
502
          atk_relation_add_target (relation, atk_obj);
503 504 505 506 507 508 509 510 511 512
        }
      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);
    }    
      
513

514 515 516 517
  vbox = gtk_vbox_new (FALSE, 6);
  gtk_widget_show (vbox);
  gtk_box_pack_start (GTK_BOX (fontsel), vbox, FALSE, TRUE, 0);
  
Owen Taylor's avatar
Owen Taylor committed
518
  /* create the text entry widget */
519
  label = gtk_label_new_with_mnemonic (_("_Preview:"));
520
  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
521
  gtk_widget_show (label);
522
  gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 0);
523
  
Owen Taylor's avatar
Owen Taylor committed
524 525
  text_box = gtk_hbox_new (FALSE, 0);
  gtk_widget_show (text_box);
526
  gtk_box_pack_start (GTK_BOX (vbox), text_box, FALSE, TRUE, 0);
527
  
Owen Taylor's avatar
Owen Taylor committed
528
  fontsel->preview_entry = gtk_entry_new ();
529
  gtk_label_set_mnemonic_widget (GTK_LABEL (label), fontsel->preview_entry);
Matthias Clasen's avatar
Matthias Clasen committed
530
  gtk_entry_set_text (GTK_ENTRY (fontsel->preview_entry), _(PREVIEW_TEXT));
531
  
Owen Taylor's avatar
Owen Taylor committed
532
  gtk_widget_show (fontsel->preview_entry);
Manish Singh's avatar
Manish Singh committed
533 534 535 536
  g_signal_connect (fontsel->preview_entry, "changed",
		    G_CALLBACK (gtk_font_selection_preview_changed), fontsel);
  gtk_widget_set_size_request (fontsel->preview_entry,
			       -1, INITIAL_PREVIEW_HEIGHT);
Owen Taylor's avatar
Owen Taylor committed
537 538
  gtk_box_pack_start (GTK_BOX (text_box), fontsel->preview_entry,
		      TRUE, TRUE, 0);
539
  gtk_widget_pop_composite_child();
Owen Taylor's avatar
Owen Taylor committed
540 541
}

Matthias Clasen's avatar
Matthias Clasen committed
542 543 544 545 546 547 548
/**
 * gtk_font_selection_new:
 *
 * Creates a new #GtkFontSelection.
 *
 * Return value: a n ew #GtkFontSelection
 */
Owen Taylor's avatar
Owen Taylor committed
549
GtkWidget *
Matthias Clasen's avatar
Matthias Clasen committed
550
gtk_font_selection_new (void)
Owen Taylor's avatar
Owen Taylor committed
551 552
{
  GtkFontSelection *fontsel;
553
  
Manish Singh's avatar
Manish Singh committed
554
  fontsel = g_object_new (GTK_TYPE_FONT_SELECTION, NULL);
555
  
Owen Taylor's avatar
Owen Taylor committed
556 557 558 559
  return GTK_WIDGET (fontsel);
}

static void
560
gtk_font_selection_finalize (GObject *object)
Owen Taylor's avatar
Owen Taylor committed
561 562
{
  GtkFontSelection *fontsel;
563
  
Owen Taylor's avatar
Owen Taylor committed
564
  g_return_if_fail (GTK_IS_FONT_SELECTION (object));
565
  
Owen Taylor's avatar
Owen Taylor committed
566
  fontsel = GTK_FONT_SELECTION (object);
567

568 569 570
  gtk_font_selection_ref_family (fontsel, NULL);
  gtk_font_selection_ref_face (fontsel, NULL);

571
  G_OBJECT_CLASS (gtk_font_selection_parent_class)->finalize (object);
Owen Taylor's avatar
Owen Taylor committed
572 573
}

574
static void
575 576
gtk_font_selection_ref_family (GtkFontSelection *fontsel,
			       PangoFontFamily  *family)
577
{
578 579 580 581 582 583
  if (family)
    family = g_object_ref (family);
  if (fontsel->family)
    g_object_unref (fontsel->family);
  fontsel->family = family;
}
584

585 586 587 588 589 590 591 592 593 594 595 596 597
static void gtk_font_selection_ref_face (GtkFontSelection *fontsel,
					 PangoFontFace    *face)
{
  if (face)
    face = g_object_ref (face);
  if (fontsel->face)
    g_object_unref (fontsel->face);
  fontsel->face = face;
}

static void
gtk_font_selection_reload_fonts (GtkFontSelection *fontsel)
{
598 599
  if (gtk_widget_has_screen (GTK_WIDGET (fontsel)))
    {
600 601 602
      PangoFontDescription *desc;
      desc = gtk_font_selection_get_font_description (fontsel);

603 604 605
      gtk_font_selection_show_available_fonts (fontsel);
      gtk_font_selection_show_available_sizes (fontsel, TRUE);
      gtk_font_selection_show_available_styles (fontsel);
606 607 608 609 610

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

      pango_font_description_free (desc);
611 612 613
    }
}

614 615 616 617 618 619 620 621 622 623 624 625 626 627 628
static void
gtk_font_selection_screen_changed (GtkWidget *widget,
				   GdkScreen *previous_screen)
{
  gtk_font_selection_reload_fonts (GTK_FONT_SELECTION (widget));
}

static void
gtk_font_selection_style_set (GtkWidget *widget,
			      GtkStyle  *prev_style)
{
  /* Maybe fonts where installed or removed... */
  gtk_font_selection_reload_fonts (GTK_FONT_SELECTION (widget));
}

629 630 631 632
static void
gtk_font_selection_preview_changed (GtkWidget        *entry,
				    GtkFontSelection *fontsel)
{
633
  g_object_notify (G_OBJECT (fontsel), "preview-text");
634
}
Owen Taylor's avatar
Owen Taylor committed
635

636 637 638 639 640 641 642 643 644 645 646 647 648 649 650
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);
    }
}

651 652 653 654 655 656 657
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);
  
Matthias Clasen's avatar
Matthias Clasen committed
658
  gtk_tree_view_set_cursor (view, path, NULL, FALSE);
659 660 661 662

  gtk_tree_path_free (path);
}

Owen Taylor's avatar
Owen Taylor committed
663
static void
664
gtk_font_selection_scroll_to_selection (GtkFontSelection *fontsel)
Owen Taylor's avatar
Owen Taylor committed
665
{
666 667
  /* Try to scroll the font family list to the selected item */
  scroll_to_selection (GTK_TREE_VIEW (fontsel->family_list));
668
      
669 670
  /* Try to scroll the font family list to the selected item */
  scroll_to_selection (GTK_TREE_VIEW (fontsel->face_list));
671
      
672 673
  /* Try to scroll the font family list to the selected item */
  scroll_to_selection (GTK_TREE_VIEW (fontsel->size_list));
674 675 676 677 678 679 680 681 682
/* 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));
Owen Taylor's avatar
Owen Taylor committed
683 684
}

685
/* This is called when a family is selected in the list. */
Damon Chaplin's avatar
""  
Damon Chaplin committed
686
static void
687 688
gtk_font_selection_select_font (GtkTreeSelection *selection,
				gpointer          data)
Damon Chaplin's avatar
""  
Damon Chaplin committed
689 690
{
  GtkFontSelection *fontsel;
691 692
  GtkTreeModel *model;
  GtkTreeIter iter;
693
#ifdef INCLUDE_FONT_ENTRIES
694
  const gchar *family_name;
695 696
#endif

Damon Chaplin's avatar
""  
Damon Chaplin committed
697 698
  fontsel = GTK_FONT_SELECTION (data);

699
  if (gtk_tree_selection_get_selected (selection, &model, &iter))
Damon Chaplin's avatar
""  
Damon Chaplin committed
700
    {
701 702 703 704
      PangoFontFamily *family;
      
      gtk_tree_model_get (model, &iter, FAMILY_COLUMN, &family, -1);
      if (fontsel->family != family)
Damon Chaplin's avatar
""  
Damon Chaplin committed
705
	{
706
	  gtk_font_selection_ref_family (fontsel, family);
707
	  
708
#ifdef INCLUDE_FONT_ENTRIES
709
	  family_name = pango_font_family_get_name (fontsel->family);
Havoc Pennington's avatar
Havoc Pennington committed
710
	  gtk_entry_set_text (GTK_ENTRY (fontsel->font_entry), family_name);
711
#endif
712 713 714
	  
	  gtk_font_selection_show_available_styles (fontsel);
	  gtk_font_selection_select_best_style (fontsel, TRUE);
Damon Chaplin's avatar
""  
Damon Chaplin committed
715
	}
716 717

      g_object_unref (family);
Damon Chaplin's avatar
""  
Damon Chaplin committed
718 719 720
    }
}

721
static int
722
cmp_families (const void *a, const void *b)
723
{
724 725 726
  const char *a_name = pango_font_family_get_name (*(PangoFontFamily **)a);
  const char *b_name = pango_font_family_get_name (*(PangoFontFamily **)b);
  
727
  return g_utf8_collate (a_name, b_name);
728
}
Damon Chaplin's avatar
""  
Damon Chaplin committed
729

Owen Taylor's avatar
Owen Taylor committed
730
static void
731
gtk_font_selection_show_available_fonts (GtkFontSelection *fontsel)
Owen Taylor's avatar
Owen Taylor committed
732
{
733 734 735
  GtkListStore *model;
  PangoFontFamily **families;
  PangoFontFamily *match_family = NULL;
736
  gint n_families, i;
737 738 739 740
  GtkTreeIter match_row;
  
  model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (fontsel->family_list)));
  
741
  pango_context_list_families (gtk_widget_get_pango_context (GTK_WIDGET (fontsel)),
742 743
			       &families, &n_families);
  qsort (families, n_families, sizeof (PangoFontFamily *), cmp_families);
744

745
  gtk_list_store_clear (model);
746 747 748

  for (i=0; i<n_families; i++)
    {
749 750 751 752 753 754 755 756
      const gchar *name = pango_font_family_get_name (families[i]);
      GtkTreeIter iter;

      gtk_list_store_append (model, &iter);
      gtk_list_store_set (model, &iter,
			  FAMILY_COLUMN, families[i],
			  FAMILY_NAME_COLUMN, name,
			  -1);
757
      
758
      if (i == 0 || !g_ascii_strcasecmp (name, "sans"))
759 760 761 762
	{
	  match_family = families[i];
	  match_row = iter;
	}
763
    }
764

765
  gtk_font_selection_ref_family (fontsel, match_family);
766 767
  if (match_family)
    {
768
      set_cursor_to_iter (GTK_TREE_VIEW (fontsel->family_list), &match_row);
Manish Singh's avatar
Manish Singh committed
769
#ifdef INCLUDE_FONT_ENTRIES
770 771
      gtk_entry_set_text (GTK_ENTRY (fontsel->font_entry), 
			  pango_font_family_get_name (match_family));
772
#endif /* INCLUDE_FONT_ENTRIES */
773
    }
774

775
  g_free (families);
776
}
Owen Taylor's avatar
Owen Taylor committed
777

778 779 780
static int
compare_font_descriptions (const PangoFontDescription *a, const PangoFontDescription *b)
{
781
  int val = strcmp (pango_font_description_get_family (a), pango_font_description_get_family (b));
782 783 784
  if (val != 0)
    return val;

785 786
  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);
787

788 789
  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);
790
  
791 792
  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);
793

794 795
  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);
796 797 798 799 800

  return 0;
}

static int
801
faces_sort_func (const void *a, const void *b)
802
{
803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821
  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));
822
}
Owen Taylor's avatar
Owen Taylor committed
823

824
/* This fills the font style list with all the possible style combinations
Owen Taylor's avatar
Owen Taylor committed
825 826 827 828
   for the current font family. */
static void
gtk_font_selection_show_available_styles (GtkFontSelection *fontsel)
{
829
  gint n_faces, i;
830
  PangoFontFace **faces;
831
  PangoFontDescription *old_desc;
832 833 834 835 836 837
  GtkListStore *model;
  GtkTreeIter match_row;
  PangoFontFace *match_face = NULL;
  
  model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (fontsel->face_list)));
  
838 839 840 841 842
  if (fontsel->face)
    old_desc = pango_font_face_describe (fontsel->face);
  else
    old_desc= NULL;

843 844
  pango_font_family_list_faces (fontsel->family, &faces, &n_faces);
  qsort (faces, n_faces, sizeof (PangoFontFace *), faces_sort_func);
845

846
  gtk_list_store_clear (model);
847

848
  for (i=0; i < n_faces; i++)
Owen Taylor's avatar
Owen Taylor committed
849
    {
850 851
      GtkTreeIter iter;
      const gchar *str = pango_font_face_get_face_name (faces[i]);
852

853 854 855 856 857 858 859
      gtk_list_store_append (model, &iter);
      gtk_list_store_set (model, &iter,
			  FACE_COLUMN, faces[i],
			  FACE_NAME_COLUMN, str,
			  -1);

      if (i == 0)
860
	{
861 862 863 864 865 866
	  match_row = iter;
	  match_face = faces[i];
	}
      else if (old_desc)
	{
	  PangoFontDescription *tmp_desc = pango_font_face_describe (faces[i]);
867 868
	  
	  if (font_description_style_equal (tmp_desc, old_desc))
869 870 871 872
	    {
	      match_row = iter;
	      match_face = faces[i];
	    }
873
      
874 875
	  pango_font_description_free (tmp_desc);
	}
Owen Taylor's avatar
Owen Taylor committed
876
    }
877

878 879 880
  if (old_desc)
    pango_font_description_free (old_desc);

881
  gtk_font_selection_ref_face (fontsel, match_face);
882
  if (match_face)
883
    {
Manish Singh's avatar
Manish Singh committed
884
#ifdef INCLUDE_FONT_ENTRIES
885 886
      const gchar *str = pango_font_face_get_face_name (fontsel->face);

887
      gtk_entry_set_text (GTK_ENTRY (fontsel->font_style_entry), str);
888
#endif      
889
      set_cursor_to_iter (GTK_TREE_VIEW (fontsel->face_list), &match_row);
890
    }
891 892

  g_free (faces);
Owen Taylor's avatar
Owen Taylor committed
893 894 895 896 897 898 899 900
}

/* 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
901 902
gtk_font_selection_select_best_style (GtkFontSelection *fontsel,
				      gboolean	        use_first)
Owen Taylor's avatar
Owen Taylor committed
903
{
904 905 906 907 908
  GtkTreeIter iter;
  GtkTreeModel *model;

  model = gtk_tree_view_get_model (GTK_TREE_VIEW (fontsel->face_list));

909
  if (gtk_tree_model_get_iter_first (model, &iter))
910
    {
911
      set_cursor_to_iter (GTK_TREE_VIEW (fontsel->face_list), &iter);
912 913 914 915
      scroll_to_selection (GTK_TREE_VIEW (fontsel->face_list));
    }

  gtk_font_selection_show_available_sizes (fontsel, FALSE);
Owen Taylor's avatar
Owen Taylor committed
916 917 918 919 920 921
  gtk_font_selection_select_best_size (fontsel);
}


/* This is called when a style is selected in the list. */
static void
922 923
gtk_font_selection_select_style (GtkTreeSelection *selection,
				 gpointer          data)
Owen Taylor's avatar
Owen Taylor committed
924
{
925
  GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
926 927
  GtkTreeModel *model;
  GtkTreeIter iter;
928
  
929
  if (gtk_tree_selection_get_selected (selection, &model, &iter))
930
    {
931 932 933
      PangoFontFace *face;
      
      gtk_tree_model_get (model, &iter, FACE_COLUMN, &face, -1);
934
      gtk_font_selection_ref_face (fontsel, face);
935
      g_object_unref (face);
936 937
    }

938
  gtk_font_selection_show_available_sizes (fontsel, FALSE);
939
  gtk_font_selection_select_best_size (fontsel);
940 941
}

942
static void
943 944
gtk_font_selection_show_available_sizes (GtkFontSelection *fontsel,
					 gboolean          first_time)
945
{
946
  gint i;
947
  GtkListStore *model;
948
  gchar buffer[128];
949 950
  gchar *p;
      
951
  model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (fontsel->size_list)));
952

953
  /* Insert the standard font sizes */
954 955 956
  if (first_time)
    {
      gtk_list_store_clear (model);
957

958 959 960 961 962 963 964 965
      for (i = 0; i < G_N_ELEMENTS (font_sizes); i++)
	{
	  GtkTreeIter iter;
	  
	  gtk_list_store_append (model, &iter);
	  gtk_list_store_set (model, &iter, SIZE_COLUMN, font_sizes[i], -1);
	  
	  if (font_sizes[i] * PANGO_SCALE == fontsel->size)
966
	    set_cursor_to_iter (GTK_TREE_VIEW (fontsel->size_list), &iter);
967 968 969
	}
    }
  else
970
    {
971
      GtkTreeIter iter;
972
      gboolean found = FALSE;
973
      
974
      gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &iter);
975
      for (i = 0; i < G_N_ELEMENTS (font_sizes) && !found; i++)
976 977
	{
	  if (font_sizes[i] * PANGO_SCALE == fontsel->size)
978 979 980 981
	    {
	      set_cursor_to_iter (GTK_TREE_VIEW (fontsel->size_list), &iter);
	      found = TRUE;
	    }
982 983 984

	  gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &iter);
	}
985 986 987 988 989 990 991 992 993 994 995

      if (!found)
	{
	  GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (fontsel->size_list));
	  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
   */
996
  g_snprintf (buffer, sizeof (buffer), "%.1f", fontsel->size / (1.0 * PANGO_SCALE));
997 998 999 1000 1001 1002 1003 1004
  if (strchr (buffer, '.'))
    {
      p = buffer + strlen (buffer) - 1;
      while (*p == '0')
	p--;
      if (*p == '.')
	p--;
      p[1] = '\0';
1005 1006
    }

1007 1008 1009
  /* Compare, to avoid moving the cursor unecessarily */
  if (strcmp (gtk_entry_get_text (GTK_ENTRY (fontsel->size_entry)), buffer) != 0)
    gtk_entry_set_text (GTK_ENTRY (fontsel->size_entry), buffer);
1010 1011
}

Owen Taylor's avatar
Owen Taylor committed
1012
static void
1013
gtk_font_selection_select_best_size (GtkFontSelection *fontsel)
Owen Taylor's avatar
Owen Taylor committed
1014
{
1015 1016
  gtk_font_selection_load_font (fontsel);  
}
1017

1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030
static void
gtk_font_selection_set_size (GtkFontSelection *fontsel,
			     gint              new_size)
{
  if (fontsel->size != new_size)
    {
      fontsel->size = new_size;

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

1031 1032
/* If the user hits return in the font size entry, we change to the new font
   size. */
1033 1034 1035
static void
gtk_font_selection_size_activate (GtkWidget   *w,
                                  gpointer     data)
1036 1037 1038
{
  GtkFontSelection *fontsel;
  gint new_size;
1039
  const gchar *text;
1040
  
1041
  fontsel = GTK_FONT_SELECTION (data);
1042 1043

  text = gtk_entry_get_text (GTK_ENTRY (fontsel->size_entry));
1044 1045
  new_size = MAX (0.1, atof (text) * PANGO_SCALE + 0.5);

1046 1047 1048 1049
  if (fontsel->size != new_size)
    gtk_font_selection_set_size (fontsel, new_size);
  else 
    list_row_activated (w);
Owen Taylor's avatar
Owen Taylor committed
1050 1051
}

1052 1053 1054 1055 1056
static gboolean
gtk_font_selection_size_focus_out (GtkWidget     *w,
				   GdkEventFocus *event,
				   gpointer       data)
{
1057 1058 1059 1060 1061 1062 1063 1064 1065 1066
  GtkFontSelection *fontsel;
  gint new_size;
  const gchar *text;
  
  fontsel = GTK_FONT_SELECTION (data);

  text = gtk_entry_get_text (GTK_ENTRY (fontsel->size_entry));
  new_size = MAX (0.1, atof (text) * PANGO_SCALE + 0.5);

  gtk_font_selection_set_size (fontsel, new_size);
1067 1068 1069 1070
  
  return TRUE;
}

1071
/* This is called when a size is selected in the list. */
Owen Taylor's avatar
Owen Taylor committed
1072
static void
1073 1074
gtk_font_selection_select_size (GtkTreeSelection *selection,
				gpointer          data)
Owen Taylor's avatar
Owen Taylor committed
1075
{
1076
  GtkFontSelection *fontsel;
1077 1078
  GtkTreeModel *model;
  GtkTreeIter iter;
1079 1080 1081
  gint new_size;
  
  fontsel = GTK_FONT_SELECTION (data);
1082
  
1083
  if (gtk_tree_selection_get_selected (selection, &model, &iter))
Owen Taylor's avatar
Owen Taylor committed
1084
    {
1085
      gtk_tree_model_get (model, &iter, SIZE_COLUMN, &new_size, -1);
1086
      gtk_font_selection_set_size (fontsel, new_size * PANGO_SCALE);