gtkfontsel.c 56.8 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
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"
33
#include <stdlib.h>
34
#include <glib/gprintf.h>
35 36
#include <string.h>

37 38
#include <atk/atk.h>

39
#include "gdk/gdk.h"
40 41
#include "gdk/gdkkeysyms.h"

42 43
#include "gtkfontsel.h"

44
#include "gtkbutton.h"
45
#include "gtkcellrenderertext.h"
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"
54
#include "gtktable.h"
55 56
#include "gtktreeselection.h"
#include "gtktreeview.h"
57
#include "gtkvbox.h"
58
#include "gtkscrolledwindow.h"
59
#include "gtkintl.h"
60
#include "gtkaccessible.h"
61
#include "gtkprivate.h"
62
#include "gtkbuildable.h"
63

64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
struct _GtkFontSelectionPriv
{
  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;
};

82 83 84 85 86 87 88 89 90 91 92

struct _GtkFontSelectionDialogPriv
{
  GtkWidget *fontsel;

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


93 94 95 96 97 98 99 100
/* 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

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

Matthias Clasen's avatar
Matthias Clasen committed
105 106
#define DEFAULT_FONT_NAME "Sans 10"

107 108 109 110 111
/* 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

112
/* These are the sizes of the font, style & size lists. */
113
#define FONT_LIST_HEIGHT	136
Damon Chaplin's avatar
Damon Chaplin committed
114 115
#define FONT_LIST_WIDTH		190
#define FONT_STYLE_LIST_WIDTH	170
116 117
#define FONT_SIZE_LIST_WIDTH	60

118
/* These are what we use as the standard font sizes, for the size list.
119 120
 */
static const guint16 font_sizes[] = {
121
  6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 22, 24, 26, 28,
122
  32, 36, 40, 48, 56, 64, 72
123 124
};

125 126 127 128 129 130
enum {
   PROP_0,
   PROP_FONT_NAME,
   PROP_PREVIEW_TEXT
};

131 132 133 134 135 136 137 138 139 140 141 142 143 144 145

enum {
  FAMILY_COLUMN,
  FAMILY_NAME_COLUMN
};

enum {
  FACE_COLUMN,
  FACE_NAME_COLUMN
};

enum {
  SIZE_COLUMN
};

146 147 148 149 150 151 152 153
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);
154 155 156 157 158
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);
159 160

/* These are the callbacks & related functions. */
161
static void     gtk_font_selection_select_font           (GtkTreeSelection *selection,
162 163 164 165 166 167
							  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);
168
static void     gtk_font_selection_select_style          (GtkTreeSelection *selection,
169 170 171
							  gpointer          data);

static void     gtk_font_selection_select_best_size      (GtkFontSelection *fs);
172 173
static void     gtk_font_selection_show_available_sizes  (GtkFontSelection *fs,
							  gboolean          first_time);
174
static void     gtk_font_selection_size_activate         (GtkWidget        *w,
175
							  gpointer          data);
176 177 178
static gboolean gtk_font_selection_size_focus_out        (GtkWidget        *w,
							  GdkEventFocus    *event,
							  gpointer          data);
179
static void     gtk_font_selection_select_size           (GtkTreeSelection *selection,
180 181
							  gpointer          data);

182
static void     gtk_font_selection_scroll_on_map         (GtkWidget        *w,
183 184
							  gpointer          data);

185 186
static void     gtk_font_selection_preview_changed       (GtkWidget        *entry,
							  GtkFontSelection *fontsel);
187 188
static void     gtk_font_selection_scroll_to_selection   (GtkFontSelection *fontsel);

189 190

/* Misc. utility functions. */
Manish Singh's avatar
Manish Singh committed
191
static void    gtk_font_selection_load_font          (GtkFontSelection *fs);
192 193
static void    gtk_font_selection_update_preview     (GtkFontSelection *fs);

194 195 196 197 198 199 200 201 202 203
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);
204

Matthias Clasen's avatar
Matthias Clasen committed
205
G_DEFINE_TYPE (GtkFontSelection, gtk_font_selection, GTK_TYPE_VBOX)
206 207

static void
208
gtk_font_selection_class_init (GtkFontSelectionClass *klass)
209
{
210
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
211
  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
212 213

  gobject_class->finalize = gtk_font_selection_finalize;
214 215
  gobject_class->set_property = gtk_font_selection_set_property;
  gobject_class->get_property = gtk_font_selection_get_property;
216

217
  widget_class->screen_changed = gtk_font_selection_screen_changed;
218
  widget_class->style_set = gtk_font_selection_style_set;
219 220 221
   
  g_object_class_install_property (gobject_class,
                                   PROP_FONT_NAME,
222
                                   g_param_spec_string ("font-name",
223
                                                        P_("Font name"),
Matthias Clasen's avatar
Matthias Clasen committed
224 225
                                                        P_("The string that represents this font"),
                                                        DEFAULT_FONT_NAME,
226
                                                        GTK_PARAM_READWRITE));
227 228
  g_object_class_install_property (gobject_class,
                                   PROP_PREVIEW_TEXT,
229
                                   g_param_spec_string ("preview-text",
230 231
                                                        P_("Preview text"),
                                                        P_("The text to display in order to demonstrate the selected font"),
Matthias Clasen's avatar
Matthias Clasen committed
232
                                                        _(PREVIEW_TEXT),
233
                                                        GTK_PARAM_READWRITE));
234 235

  g_type_class_add_private (klass, sizeof (GtkFontSelectionPriv));
236 237
}

238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273
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:
274
      g_value_take_string (value, gtk_font_selection_get_font_name (fontsel));
275 276 277 278 279 280 281 282 283 284
      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;
    }
}

285 286 287 288 289 290
/* 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)
{
291
  GtkWidget *default_widget, *focus_widget;
292 293 294
  GtkWindow *window;
  
  window = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (widget)));
295
  if (!gtk_widget_is_toplevel (GTK_WIDGET (window)))
296
    window = NULL;
297 298

  if (window)
299
    {
300 301 302 303 304 305
      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);
306
    }
307

308 309
  return TRUE;
}
310

311
static void
312
gtk_font_selection_init (GtkFontSelection *fontsel)
313
{
314
  GtkFontSelectionPriv *priv;
315
  GtkWidget *scrolled_win;
316 317
  GtkWidget *text_box;
  GtkWidget *table, *label;
318
  GtkWidget *font_label, *style_label;
319
  GtkWidget *vbox;
320 321 322
  GtkListStore *model;
  GtkTreeViewColumn *column;
  GList *focus_chain = NULL;
323
  AtkObject *atk_obj;
324

325 326 327 328 329
  fontsel->priv = G_TYPE_INSTANCE_GET_PRIVATE (fontsel,
                                               GTK_TYPE_FONT_SELECTION,
                                               GtkFontSelectionPriv);
  priv = fontsel->priv;

330 331
  gtk_widget_push_composite_child ();

332
  gtk_box_set_spacing (GTK_BOX (fontsel), 12);
333
  priv->size = 12 * PANGO_SCALE;
334
  
335 336 337
  /* Create the table of font, style & size. */
  table = gtk_table_new (3, 3, FALSE);
  gtk_widget_show (table);
338 339
  gtk_table_set_row_spacings (GTK_TABLE (table), 6);
  gtk_table_set_col_spacings (GTK_TABLE (table), 12);
340
  gtk_box_pack_start (GTK_BOX (fontsel), table, TRUE, TRUE, 0);
341

Manish Singh's avatar
Manish Singh committed
342
#ifdef INCLUDE_FONT_ENTRIES
343 344 345 346 347
  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,
348
		    GTK_FILL, 0, 0, 0);
349
  
350 351 352 353 354
  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,
355
		    GTK_FILL, 0, 0, 0);
356
#endif /* INCLUDE_FONT_ENTRIES */
357
  
358 359 360 361
  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,
362
		    GTK_FILL, 0, 0, 0);
363
  g_signal_connect (priv->size_entry, "activate",
Manish Singh's avatar
Manish Singh committed
364 365
		    G_CALLBACK (gtk_font_selection_size_activate),
		    fontsel);
366
  g_signal_connect_after (priv->size_entry, "focus-out-event",
Manish Singh's avatar
Manish Singh committed
367 368
			  G_CALLBACK (gtk_font_selection_size_focus_out),
			  fontsel);
369
  
370 371 372 373
  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,
374
		    GTK_FILL, 0, 0, 0);  
375 376 377 378 379

  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,
380
		    GTK_FILL, 0, 0, 0);
381
  
382 383
  label = gtk_label_new_with_mnemonic (_("Si_ze:"));
  gtk_label_set_mnemonic_widget (GTK_LABEL (label),
384
                                 priv->size_entry);
385 386 387 388 389 390
  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);
  
  
391 392 393 394 395
  /* Create the lists  */

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

399
  g_signal_connect (priv->family_list, "row-activated",
400 401
		    G_CALLBACK (list_row_activated), fontsel);

402 403 404 405 406
  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);
407
  gtk_tree_view_append_column (GTK_TREE_VIEW (priv->family_list), column);
408

409 410
  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)),
411 412
			       GTK_SELECTION_BROWSE);
  
413
  gtk_label_set_mnemonic_widget (GTK_LABEL (font_label), priv->family_list);
414

415
  scrolled_win = gtk_scrolled_window_new (NULL, NULL);
416
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), GTK_SHADOW_IN);
Manish Singh's avatar
Manish Singh committed
417 418
  gtk_widget_set_size_request (scrolled_win,
			       FONT_LIST_WIDTH, FONT_LIST_HEIGHT);
419
  gtk_container_add (GTK_CONTAINER (scrolled_win), priv->family_list);
420 421
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
				  GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
422
  gtk_widget_show (priv->family_list);
423
  gtk_widget_show (scrolled_win);
424

425
  gtk_table_attach (GTK_TABLE (table), scrolled_win, 0, 1, 1, 3,
426 427
		    GTK_EXPAND | GTK_FILL,
		    GTK_EXPAND | GTK_FILL, 0, 0);
428 429 430 431 432
  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 */
433
  priv->face_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
434
  g_object_unref (model);
435
  g_signal_connect (priv->face_list, "row-activated",
436
		    G_CALLBACK (list_row_activated), fontsel);
437

438
  gtk_label_set_mnemonic_widget (GTK_LABEL (style_label), priv->face_list);
439 440 441 442 443 444

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

447 448
  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)),
449
			       GTK_SELECTION_BROWSE);
450
  
451
  scrolled_win = gtk_scrolled_window_new (NULL, NULL);
452
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), GTK_SHADOW_IN);
Manish Singh's avatar
Manish Singh committed
453 454
  gtk_widget_set_size_request (scrolled_win,
			       FONT_STYLE_LIST_WIDTH, FONT_LIST_HEIGHT);
455
  gtk_container_add (GTK_CONTAINER (scrolled_win), priv->face_list);
456 457
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
				  GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
458
  gtk_widget_show (priv->face_list);
459
  gtk_widget_show (scrolled_win);
460
  gtk_table_attach (GTK_TABLE (table), scrolled_win, 1, 2, 1, 3,
461 462
		    GTK_EXPAND | GTK_FILL,
		    GTK_EXPAND | GTK_FILL, 0, 0);
463 464
  focus_chain = g_list_append (focus_chain, scrolled_win);
  
465
  focus_chain = g_list_append (focus_chain, priv->size_entry);
466 467

  model = gtk_list_store_new (1, G_TYPE_INT);
468
  priv->size_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
469
  g_object_unref (model);
470
  g_signal_connect (priv->size_list, "row-activated",
471
		    G_CALLBACK (list_row_activated), fontsel);
472 473 474 475 476 477

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

480 481
  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)),
482
			       GTK_SELECTION_BROWSE);
483
  
484
  scrolled_win = gtk_scrolled_window_new (NULL, NULL);
485
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), GTK_SHADOW_IN);
486
  gtk_container_add (GTK_CONTAINER (scrolled_win), priv->size_list);
Manish Singh's avatar
Manish Singh committed
487
  gtk_widget_set_size_request (scrolled_win, -1, FONT_LIST_HEIGHT);
488
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
489
				  GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
490
  gtk_widget_show (priv->size_list);
491
  gtk_widget_show (scrolled_win);
492
  gtk_table_attach (GTK_TABLE (table), scrolled_win, 2, 3, 2, 3,
493 494 495 496 497
		    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);
498
  
499
  /* Insert the fonts. */
500
  g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->family_list)), "changed",
501
		    G_CALLBACK (gtk_font_selection_select_font), fontsel);
502

503
  g_signal_connect_after (priv->family_list, "map",
Manish Singh's avatar
Manish Singh committed
504 505
			  G_CALLBACK (gtk_font_selection_scroll_on_map),
			  fontsel);
506
  
507
  g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->face_list)), "changed",
508
		    G_CALLBACK (gtk_font_selection_select_style), fontsel);
509

510
  g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->size_list)), "changed",
511
		    G_CALLBACK (gtk_font_selection_select_size), fontsel);
512
  atk_obj = gtk_widget_get_accessible (priv->size_list);
513 514 515 516 517 518 519 520 521 522 523 524 525 526 527
  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)
        {
528
          atk_relation_add_target (relation, atk_label);
529 530 531 532 533 534 535 536 537 538 539 540 541
        }
      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)
        {
542
          atk_relation_add_target (relation, atk_obj);
543 544 545 546 547 548 549 550 551 552
        }
      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);
    }    
      
553

554 555 556 557
  vbox = gtk_vbox_new (FALSE, 6);
  gtk_widget_show (vbox);
  gtk_box_pack_start (GTK_BOX (fontsel), vbox, FALSE, TRUE, 0);
  
558
  /* create the text entry widget */
559
  label = gtk_label_new_with_mnemonic (_("_Preview:"));
560
  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
561
  gtk_widget_show (label);
562
  gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 0);
563
  
564 565
  text_box = gtk_hbox_new (FALSE, 0);
  gtk_widget_show (text_box);
566
  gtk_box_pack_start (GTK_BOX (vbox), text_box, FALSE, TRUE, 0);
567
  
568 569 570
  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));
571
  
572 573
  gtk_widget_show (priv->preview_entry);
  g_signal_connect (priv->preview_entry, "changed",
Manish Singh's avatar
Manish Singh committed
574
		    G_CALLBACK (gtk_font_selection_preview_changed), fontsel);
575
  gtk_widget_set_size_request (priv->preview_entry,
Manish Singh's avatar
Manish Singh committed
576
			       -1, INITIAL_PREVIEW_HEIGHT);
577
  gtk_box_pack_start (GTK_BOX (text_box), priv->preview_entry,
578
		      TRUE, TRUE, 0);
579
  gtk_widget_pop_composite_child();
580 581
}

Matthias Clasen's avatar
Matthias Clasen committed
582 583 584 585 586 587 588
/**
 * gtk_font_selection_new:
 *
 * Creates a new #GtkFontSelection.
 *
 * Return value: a n ew #GtkFontSelection
 */
589
GtkWidget *
590
gtk_font_selection_new (void)
591 592
{
  GtkFontSelection *fontsel;
593
  
Manish Singh's avatar
Manish Singh committed
594
  fontsel = g_object_new (GTK_TYPE_FONT_SELECTION, NULL);
595
  
596 597 598 599
  return GTK_WIDGET (fontsel);
}

static void
600
gtk_font_selection_finalize (GObject *object)
601
{
602
  GtkFontSelection *fontsel = GTK_FONT_SELECTION (object);
603

604 605 606
  gtk_font_selection_ref_family (fontsel, NULL);
  gtk_font_selection_ref_face (fontsel, NULL);

607
  G_OBJECT_CLASS (gtk_font_selection_parent_class)->finalize (object);
608 609
}

610
static void
611 612
gtk_font_selection_ref_family (GtkFontSelection *fontsel,
			       PangoFontFamily  *family)
613
{
614 615
  GtkFontSelectionPriv *priv = fontsel->priv;

616 617
  if (family)
    family = g_object_ref (family);
618 619 620
  if (priv->family)
    g_object_unref (priv->family);
  priv->family = family;
621
}
622

623 624 625
static void gtk_font_selection_ref_face (GtkFontSelection *fontsel,
					 PangoFontFace    *face)
{
626 627
  GtkFontSelectionPriv *priv = fontsel->priv;

628 629
  if (face)
    face = g_object_ref (face);
630 631 632
  if (priv->face)
    g_object_unref (priv->face);
  priv->face = face;
633 634 635 636 637
}

static void
gtk_font_selection_reload_fonts (GtkFontSelection *fontsel)
{
638 639
  if (gtk_widget_has_screen (GTK_WIDGET (fontsel)))
    {
640 641 642
      PangoFontDescription *desc;
      desc = gtk_font_selection_get_font_description (fontsel);

643 644 645
      gtk_font_selection_show_available_fonts (fontsel);
      gtk_font_selection_show_available_sizes (fontsel, TRUE);
      gtk_font_selection_show_available_styles (fontsel);
646 647 648 649 650

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

      pango_font_description_free (desc);
651 652 653
    }
}

654 655 656 657 658 659 660 661 662 663 664 665 666 667 668
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));
}

669 670 671 672
static void
gtk_font_selection_preview_changed (GtkWidget        *entry,
				    GtkFontSelection *fontsel)
{
673
  g_object_notify (G_OBJECT (fontsel), "preview-text");
674
}
675

676 677 678 679 680 681 682 683 684 685 686 687 688 689 690
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);
    }
}

691 692 693 694 695 696 697
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);
  
698
  gtk_tree_view_set_cursor (view, path, NULL, FALSE);
699 700 701 702

  gtk_tree_path_free (path);
}

703
static void
704
gtk_font_selection_scroll_to_selection (GtkFontSelection *fontsel)
705
{
706 707
  GtkFontSelectionPriv *priv = fontsel->priv;

708
  /* Try to scroll the font family list to the selected item */
709 710
  scroll_to_selection (GTK_TREE_VIEW (priv->family_list));

711
  /* Try to scroll the font family list to the selected item */
712 713
  scroll_to_selection (GTK_TREE_VIEW (priv->face_list));

714
  /* Try to scroll the font family list to the selected item */
715
  scroll_to_selection (GTK_TREE_VIEW (priv->size_list));
716 717 718 719 720 721 722 723 724
/* 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));
725 726
}

727
/* This is called when a family is selected in the list. */
Damon Chaplin's avatar
Damon Chaplin committed
728
static void
729 730
gtk_font_selection_select_font (GtkTreeSelection *selection,
				gpointer          data)
Damon Chaplin's avatar
Damon Chaplin committed
731 732
{
  GtkFontSelection *fontsel;
733
  GtkFontSelectionPriv *priv;
734 735
  GtkTreeModel *model;
  GtkTreeIter iter;
736
#ifdef INCLUDE_FONT_ENTRIES
737
  const gchar *family_name;
738 739
#endif

Damon Chaplin's avatar
Damon Chaplin committed
740
  fontsel = GTK_FONT_SELECTION (data);
741
  priv = fontsel->priv;
Damon Chaplin's avatar
Damon Chaplin committed
742

743
  if (gtk_tree_selection_get_selected (selection, &model, &iter))
Damon Chaplin's avatar
Damon Chaplin committed
744
    {
745
      PangoFontFamily *family;
746

747
      gtk_tree_model_get (model, &iter, FAMILY_COLUMN, &family, -1);
748
      if (priv->family != family)
Damon Chaplin's avatar
Damon Chaplin committed
749
	{
750
	  gtk_font_selection_ref_family (fontsel, family);
751

752
#ifdef INCLUDE_FONT_ENTRIES
753 754
	  family_name = pango_font_family_get_name (priv->family);
	  gtk_entry_set_text (GTK_ENTRY (priv->font_entry), family_name);
755
#endif
756

757 758
	  gtk_font_selection_show_available_styles (fontsel);
	  gtk_font_selection_select_best_style (fontsel, TRUE);
Damon Chaplin's avatar
Damon Chaplin committed
759
	}
760 761

      g_object_unref (family);
Damon Chaplin's avatar
Damon Chaplin committed
762 763 764
    }
}

765
static int
766
cmp_families (const void *a, const void *b)
767
{
768 769 770
  const char *a_name = pango_font_family_get_name (*(PangoFontFamily **)a);
  const char *b_name = pango_font_family_get_name (*(PangoFontFamily **)b);
  
771
  return g_utf8_collate (a_name, b_name);
772
}
Damon Chaplin's avatar
Damon Chaplin committed
773

774
static void
775
gtk_font_selection_show_available_fonts (GtkFontSelection *fontsel)
776
{
777
  GtkFontSelectionPriv *priv = fontsel->priv;
778 779 780
  GtkListStore *model;
  PangoFontFamily **families;
  PangoFontFamily *match_family = NULL;
781
  gint n_families, i;
782
  GtkTreeIter match_row;
783 784 785

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

786
  pango_context_list_families (gtk_widget_get_pango_context (GTK_WIDGET (fontsel)),
787 788
			       &families, &n_families);
  qsort (families, n_families, sizeof (PangoFontFamily *), cmp_families);
789

790
  gtk_list_store_clear (model);
791 792 793

  for (i=0; i<n_families; i++)
    {
794 795 796 797 798 799 800 801
      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);
802
      
803
      if (i == 0 || !g_ascii_strcasecmp (name, "sans"))
804 805 806 807
	{
	  match_family = families[i];
	  match_row = iter;
	}
808
    }
809

810
  gtk_font_selection_ref_family (fontsel, match_family);
811 812
  if (match_family)
    {
813
      set_cursor_to_iter (GTK_TREE_VIEW (priv->family_list), &match_row);
Manish Singh's avatar
Manish Singh committed
814
#ifdef INCLUDE_FONT_ENTRIES
815
      gtk_entry_set_text (GTK_ENTRY (priv->font_entry), 
816
			  pango_font_family_get_name (match_family));
817
#endif /* INCLUDE_FONT_ENTRIES */
818
    }
819

820
  g_free (families);
821
}
822

823 824 825
static int
compare_font_descriptions (const PangoFontDescription *a, const PangoFontDescription *b)
{
826
  int val = strcmp (pango_font_description_get_family (a), pango_font_description_get_family (b));
827 828 829
  if (val != 0)
    return val;

830 831
  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);
832

833 834
  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);
835
  
836 837
  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);
838

839 840
  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);
841 842 843 844 845

  return 0;
}

static int
846
faces_sort_func (const void *a, const void *b)
847
{
848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866
  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));
867
}
868

869
/* This fills the font style list with all the possible style combinations
870 871 872 873
   for the current font family. */
static void
gtk_font_selection_show_available_styles (GtkFontSelection *fontsel)
{
874
  GtkFontSelectionPriv *priv = fontsel->priv;
875
  gint n_faces, i;
876
  PangoFontFace **faces;
877
  PangoFontDescription *old_desc;
878 879 880
  GtkListStore *model;
  GtkTreeIter match_row;
  PangoFontFace *match_face = NULL;
881 882 883 884 885

  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);
886 887 888
  else
    old_desc= NULL;

889
  pango_font_family_list_faces (priv->family, &faces, &n_faces);
890
  qsort (faces, n_faces, sizeof (PangoFontFace *), faces_sort_func);
891

892
  gtk_list_store_clear (model);
893

894
  for (i=0; i < n_faces; i++)
895
    {
896 897
      GtkTreeIter iter;
      const gchar *str = pango_font_face_get_face_name (faces[i]);
898

899 900 901 902 903 904 905
      gtk_list_store_append (model, &iter);
      gtk_list_store_set (model, &iter,
			  FACE_COLUMN, faces[i],
			  FACE_NAME_COLUMN, str,
			  -1);

      if (i == 0)
906
	{
907 908 909 910 911 912
	  match_row = iter;
	  match_face = faces[i];
	}
      else if (old_desc)
	{
	  PangoFontDescription *tmp_desc = pango_font_face_describe (faces[i]);
913 914
	  
	  if (font_description_style_equal (tmp_desc, old_desc))
915 916 917 918
	    {
	      match_row = iter;
	      match_face = faces[i];
	    }
919
      
920 921
	  pango_font_description_free (tmp_desc);
	}
922
    }
923

924 925 926
  if (old_desc)
    pango_font_description_free (old_desc);

927
  gtk_font_selection_ref_face (fontsel, match_face);
928
  if (match_face)
929
    {
Manish Singh's avatar
Manish Singh committed
930
#ifdef INCLUDE_FONT_ENTRIES
931
      const gchar *str = pango_font_face_get_face_name (priv->face);
932

933 934 935
      gtk_entry_set_text (GTK_ENTRY (priv->font_style_entry), str);
#endif
      set_cursor_to_iter (GTK_TREE_VIEW (priv->face_list), &match_row);
936
    }
937 938

  g_free (faces);
939 940 941 942 943 944 945 946
}

/* 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
947 948
gtk_font_selection_select_best_style (GtkFontSelection *fontsel,
				      gboolean	        use_first)
949
{
950
  GtkFontSelectionPriv *priv = fontsel->priv;
951 952 953
  GtkTreeIter iter;
  GtkTreeModel *model;

954
  model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->face_list));
955

956
  if (gtk_tree_model_get_iter_first (model, &iter))
957
    {
958 959
      set_cursor_to_iter (GTK_TREE_VIEW (priv->face_list), &iter);
      scroll_to_selection (GTK_TREE_VIEW (priv->face_list));
960 961 962
    }

  gtk_font_selection_show_available_sizes (fontsel, FALSE);
963 964 965 966 967 968
  gtk_font_selection_select_best_size (fontsel);
}


/* This is called when a style is selected in the list. */
static void
969 970
gtk_font_selection_select_style (GtkTreeSelection *selection,
				 gpointer          data)
971
{
972
  GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
973 974
  GtkTreeModel *model;
  GtkTreeIter iter;
975

976
  if (gtk_tree_selection_get_selected (selection, &model, &iter))
977
    {
978 979 980
      PangoFontFace *face;
      
      gtk_tree_model_get (model, &iter, FACE_COLUMN, &face, -1);
981
      gtk_font_selection_ref_face (fontsel, face);
982
      g_object_unref (face);
983 984
    }

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

989
static void
990 991
gtk_font_selection_show_available_sizes (GtkFontSelection *fontsel,
					 gboolean          first_time)
992
{
993
  GtkFontSelectionPriv *priv = fontsel->priv;
994
  gint i;
995
  GtkListStore *model;
996
  gchar buffer[128];
997
  gchar *p;
998 999

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

1001
  /* Insert the standard font sizes */
1002 1003 1004
  if (first_time)
    {
      gtk_list_store_clear (model);
1005

1006 1007 1008
      for (i = 0; i < G_N_ELEMENTS (font_sizes); i++)
	{
	  GtkTreeIter iter;
1009

1010 1011
	  gtk_list_store_append (model, &iter);
	  gtk_list_store_set (model, &iter, SIZE_COLUMN, font_sizes[i], -1);
1012 1013 1014

	  if (font_sizes[i] * PANGO_SCALE == priv->size)
	    set_cursor_to_iter (GTK_TREE_VIEW (priv->size_list), &iter);
1015 1016 1017
	}
    }
  else
1018
    {
1019
      GtkTreeIter iter;
1020
      gboolean found = FALSE;
1021

1022
      gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &iter);
1023
      for (i = 0; i < G_N_ELEMENTS (font_sizes) && !found; i++)
1024
	{
1025
	  if (font_sizes[i] * PANGO_SCALE == priv->size)
1026
	    {
1027
	      set_cursor_to_iter (GTK_TREE_VIEW (priv->size_list), &iter);
1028 1029
	      found = TRUE;
	    }
1030 1031 1032

	  gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &iter);
	}
1033 1034 1035

      if (!found)
	{
1036
	  GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->size_list));
1037 1038 1039 1040 1041 1042 1043
	  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
   */
1044
  g_snprintf (buffer, sizeof (buffer), "%.1f", priv->size / (1.0 * PANGO_SCALE));
1045 1046 1047 1048 1049 1050 1051 1052
  if (strchr (buffer, '.'))
    {
      p = buffer + strlen (buffer) - 1;
      while (*p == '0')
	p--;
      if (*p == '.')
	p--;
      p[1] = '\0';
1053 1054
    }

1055
  /* Compare, to avoid moving the cursor unecessarily */
1056 1057
  if (strcmp (gtk_entry_get_text (GTK_ENTRY (priv->size_entry)), buffer) != 0)
    gtk_entry_set_text (GTK_ENTRY (priv->size_entry), buffer);
1058 1059
}

1060
static void
1061
gtk_font_selection_select_best_size (GtkFontSelection *fontsel)
1062
{
1063 1064
  gtk_font_selection_load_font (fontsel);  
}
1065

1066 1067 1068 1069
static void
gtk_font_selection_set_size (GtkFontSelection *fontsel,
			     gint              new_size)
{
1070 1071 1072
  GtkFontSelectionPriv *priv = fontsel->priv;

  if (priv->size != new_size)
1073
    {
1074
      priv->size = new_size;
1075 1076 1077 1078 1079 1080

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

1081 1082
/* If the user hits return in the font size entry, we change to the new font
   size. */
1083 1084 1085
static void
gtk_font_selection_size_activate (GtkWidget   *w,
                                  gpointer     data)
1086
{
1087 1088
  GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
  GtkFontSelectionPriv *priv = fontsel->priv;
1089
  gint new_size;
1090
  const gchar *text;
1091

1092
  text = gtk_entry_get_text (GTK_ENTRY (priv->size_entry));
1093 1094
  new_size = MAX (0.1, atof (text) * PANGO_SCALE + 0.5);

1095
  if (priv->size != new_size)
1096 1097 1098
    gtk_font_selection_set_size (fontsel, new_size);
  else 
    list_row_activated (w);
1099 1100
}

1101 1102 1103 1104 1105
static gboolean
gtk_font_selection_size_focus_out (GtkWidget     *w,
				   GdkEventFocus *event,
				   gpointer       data)
{
1106 1107
  GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
  GtkFontSelectionPriv *priv = fontsel->priv;
1108 1109 1110
  gint new_size;
  const gchar *text;

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

  gtk_font_selection_set_size (fontsel, new_size);
1115

1116 1117 1118
  return TRUE;
}

1119
/* This is called when a size is selected in the list. */
1120
static void
1121 1122
gtk_font_selection_select_size (GtkTreeSelection *selection,
				gpointer          data)
1123
{
1124
  GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
1125 1126
  GtkTreeModel *model;
  GtkTreeIter iter;
1127
  gint new_size;
1128

1129
  if (gtk_tree_selection_get_selected (selection, &model, &iter))
1130
    {
1131
      gtk_tree_model_get (model, &iter, SIZE_COLUMN, &new_size, -1);
1132
      gtk_font_selection_set_size (fontsel, new_size * PANGO_SCALE);
1133 1134 1135
    }
}

1136 1137 1138 1139 1140
static void
gtk_font_selection_load_font (GtkFontSelection *fontsel)
{
  gtk_font_selection_update_preview (fontsel);
}
1141

1142 1143 1144
static PangoFontDescription *
gtk_font_selection_get_font_description (GtkFontSelection *fontsel)
{
1145
  GtkFontSelectionPriv *priv = fontsel->priv;
1146 1147
  PangoFontDescription *font_desc;

1148
  if (priv->face)
1149
    {
1150 1151
      font_desc = pango_font_face_describe (priv->face);
      pango_font_description_set_size (font_desc, priv->size);
1152 1153
    }
  else
Matthias Clasen's avatar
Matthias Clasen committed
1154
    font_desc = pango_font_description_from_string (DEFAULT_FONT_NAME);
1155 1156 1157 1158

  return font_desc;
}

1159 1160 1161 1162 1163 1164 1165 1166
/* This sets the font in the preview entry to the selected font, and tries to
   make sure that the preview entry is a reasonable size, i.e. so that the
   text can be seen with a bit of space to spare. But it tries to avoid
   resizing the entry every time the font changes.
   This also used to shrink the preview if the font size was decreased, but
   that made it awkward if the user wanted to resize the window themself. */
static void
gtk_font_selection_update_preview (GtkFontSelection *fontsel)
1167
{