gtkfontsel.c 40.4 KB
Newer Older
1 2 3
/* GTK - The GIMP Toolkit
 * 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 33 34 35
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

36
#include "gdk/gdk.h"
37 38
#include "gdk/gdkkeysyms.h"

39 40
#include "gtkfontsel.h"

41
#include "gtkbutton.h"
42
#include "gtkcellrenderertext.h"
43 44 45 46 47
#include "gtkentry.h"
#include "gtkframe.h"
#include "gtkhbbox.h"
#include "gtkhbox.h"
#include "gtklabel.h"
48
#include "gtkliststore.h"
49
#include "gtkrc.h"
50
#include "gtksignal.h"
51
#include "gtkstock.h"
52
#include "gtktable.h"
53 54
#include "gtktreeselection.h"
#include "gtktreeview.h"
55
#include "gtkvbox.h"
56
#include "gtkscrolledwindow.h"
57
#include "gtkintl.h"
58 59 60 61 62 63 64 65 66 67

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

/* 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

68
/* These are the sizes of the font, style & size lists. */
69
#define FONT_LIST_HEIGHT	136
Damon Chaplin's avatar
Damon Chaplin committed
70 71
#define FONT_LIST_WIDTH		190
#define FONT_STYLE_LIST_WIDTH	170
72 73
#define FONT_SIZE_LIST_WIDTH	60

74
/* These are what we use as the standard font sizes, for the size list.
75 76 77 78
 */
static const guint16 font_sizes[] = {
  8, 9, 10, 11, 12, 13, 14, 16, 18, 20, 22, 24, 26, 28,
  32, 36, 40, 48, 56, 64, 72
79 80
};

81 82 83 84 85 86 87
enum {
   PROP_0,
   PROP_FONT_NAME,
   PROP_FONT,
   PROP_PREVIEW_TEXT
};

88 89 90 91 92 93 94 95 96 97 98 99 100 101 102

enum {
  FAMILY_COLUMN,
  FAMILY_NAME_COLUMN
};

enum {
  FACE_COLUMN,
  FACE_NAME_COLUMN
};

enum {
  SIZE_COLUMN
};

103
static void    gtk_font_selection_class_init	     (GtkFontSelectionClass *klass);
104 105 106 107 108 109 110 111
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);
112 113
static void    gtk_font_selection_init		     (GtkFontSelection      *fontsel);
static void    gtk_font_selection_finalize	     (GObject               *object);
114 115

/* These are the callbacks & related functions. */
116
static void     gtk_font_selection_select_font           (GtkTreeSelection *selection,
117 118 119 120 121 122
							  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);
123
static void     gtk_font_selection_select_style          (GtkTreeSelection *selection,
124 125 126
							  gpointer          data);

static void     gtk_font_selection_select_best_size      (GtkFontSelection *fs);
127 128
static void     gtk_font_selection_show_available_sizes  (GtkFontSelection *fs,
							  gboolean          first_time);
129
static void     gtk_font_selection_size_activate         (GtkWidget        *w,
130
							  gpointer          data);
131
static void     gtk_font_selection_select_size           (GtkTreeSelection *selection,
132 133
							  gpointer          data);

134
static void     gtk_font_selection_scroll_on_map         (GtkWidget        *w,
135 136
							  gpointer          data);

137 138
static void     gtk_font_selection_preview_changed       (GtkWidget        *entry,
							  GtkFontSelection *fontsel);
139 140

/* Misc. utility functions. */
141
static void     gtk_font_selection_load_font         (GtkFontSelection *fs);
142 143 144 145 146 147
static void    gtk_font_selection_update_preview     (GtkFontSelection *fs);

/* FontSelectionDialog */
static void    gtk_font_selection_dialog_class_init  (GtkFontSelectionDialogClass *klass);
static void    gtk_font_selection_dialog_init	     (GtkFontSelectionDialog *fontseldiag);

148 149 150
static gint    gtk_font_selection_dialog_on_configure (GtkWidget      *widget,
						       GdkEventConfigure *event,
						       GtkFontSelectionDialog *fsd);
151 152

static GtkWindowClass *font_selection_parent_class = NULL;
153
static GtkVBoxClass *font_selection_dialog_parent_class = NULL;
154

155
GtkType
156
gtk_font_selection_get_type ()
157
{
158
  static GtkType font_selection_type = 0;
159
  
160
  if (!font_selection_type)
161
    {
162
      static const GtkTypeInfo fontsel_type_info =
163 164
      {
	"GtkFontSelection",
165 166
	sizeof (GtkFontSelection),
	sizeof (GtkFontSelectionClass),
167 168
	(GtkClassInitFunc) gtk_font_selection_class_init,
	(GtkObjectInitFunc) gtk_font_selection_init,
169 170
	/* reserved_1 */ NULL,
	/* reserved_2 */ NULL,
171
        (GtkClassInitFunc) NULL,
172
      };
173
      
174
      font_selection_type = gtk_type_unique (GTK_TYPE_VBOX,
175
					     &fontsel_type_info);
176
    }
177
  
178 179 180 181
  return font_selection_type;
}

static void
182
gtk_font_selection_class_init (GtkFontSelectionClass *klass)
183
{
184
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
185
  
186
  font_selection_parent_class = gtk_type_class (GTK_TYPE_VBOX);
187
  
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
  gobject_class->set_property = gtk_font_selection_set_property;
  gobject_class->get_property = gtk_font_selection_get_property;
   
  g_object_class_install_property (gobject_class,
                                   PROP_FONT_NAME,
                                   g_param_spec_string ("font_name",
                                                        _("Font name"),
                                                        _("The X string that represents this font."),
                                                        NULL,
                                                        G_PARAM_READWRITE));
  g_object_class_install_property (gobject_class,
				   PROP_FONT,
				   g_param_spec_boxed ("font",
						       _("Font"),
						       _("The GdkFont that is currently selected."),
						       GDK_TYPE_FONT,
						       G_PARAM_READABLE));
  g_object_class_install_property (gobject_class,
                                   PROP_PREVIEW_TEXT,
                                   g_param_spec_string ("preview_text",
                                                        _("Preview text"),
                                                        _("The text to display in order to demonstrate the selected font."),
                                                        PREVIEW_TEXT,
                                                        G_PARAM_READWRITE));
212
  gobject_class->finalize = gtk_font_selection_finalize;
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 243 244 245 246 247 248 249 250 251 252 253
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:
      g_value_set_string (value, gtk_font_selection_get_font_name (fontsel));
      break;
    case PROP_FONT:
254
      g_value_set_object (value, gtk_font_selection_get_font (fontsel));
255 256 257 258 259 260 261 262 263 264 265
      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;
    }
}


266
static void
267
gtk_font_selection_init (GtkFontSelection *fontsel)
268
{
269
  GtkWidget *scrolled_win;
270
  GtkWidget *text_frame;
271 272
  GtkWidget *text_box;
  GtkWidget *table, *label;
273 274 275 276
  GtkWidget *font_label, *style_label;
  GtkListStore *model;
  GtkTreeViewColumn *column;
  GList *focus_chain = NULL;
277

278 279
  gtk_widget_push_composite_child ();

280
  fontsel->size = 12 * PANGO_SCALE;
281
  
282 283 284
  /* Create the table of font, style & size. */
  table = gtk_table_new (3, 3, FALSE);
  gtk_widget_show (table);
285
  gtk_table_set_col_spacings (GTK_TABLE (table), 8);
286
  gtk_box_pack_start (GTK_BOX (fontsel), table, TRUE, TRUE, 0);
287

288
  fontsel->font_entry = gtk_entry_new ();
289
  gtk_entry_set_editable (GTK_ENTRY (fontsel->font_entry), FALSE);
290
  gtk_widget_set_usize (fontsel->font_entry, 20, -1);
291
  /*  gtk_widget_show (fontsel->font_entry); */
292 293
  gtk_table_attach (GTK_TABLE (table), fontsel->font_entry, 0, 1, 1, 2,
		    GTK_FILL, 0, 0, 0);
294 295
  
  fontsel->font_style_entry = gtk_entry_new ();
296
  gtk_entry_set_editable (GTK_ENTRY (fontsel->font_style_entry), FALSE);
297
  gtk_widget_set_usize (fontsel->font_style_entry, 20, -1);
298
  /* gtk_widget_show (fontsel->font_style_entry); */
299 300
  gtk_table_attach (GTK_TABLE (table), fontsel->font_style_entry, 1, 2, 1, 2,
		    GTK_FILL, 0, 0, 0);
301 302
  
  fontsel->size_entry = gtk_entry_new ();
303 304 305 306
  gtk_widget_set_usize (fontsel->size_entry, 20, -1);
  gtk_widget_show (fontsel->size_entry);
  gtk_table_attach (GTK_TABLE (table), fontsel->size_entry, 2, 3, 1, 2,
		    GTK_FILL, 0, 0, 0);
307 308
  gtk_signal_connect (GTK_OBJECT (fontsel->size_entry), "activate",
		      (GtkSignalFunc) gtk_font_selection_size_activate,
309
		      fontsel);
310
  
311 312 313 314
  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,
315
		    GTK_FILL, 0, 0, 0);  
316 317 318 319 320

  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,
321
		    GTK_FILL, 0, 0, 0);
322
  
323 324 325 326 327 328 329 330 331
  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);
  
  
332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352
  /* 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);

  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);

353
  scrolled_win = gtk_scrolled_window_new (NULL, NULL);
354
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), GTK_SHADOW_IN);
Damon Chaplin's avatar
Damon Chaplin committed
355
  gtk_widget_set_usize (scrolled_win, FONT_LIST_WIDTH, FONT_LIST_HEIGHT);
356
  gtk_container_add (GTK_CONTAINER (scrolled_win), fontsel->family_list);
357 358
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
				  GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
359
  gtk_widget_show (fontsel->family_list);
360
  gtk_widget_show (scrolled_win);
361

362
  gtk_table_attach (GTK_TABLE (table), scrolled_win, 0, 1, 1, 3,
363 364
		    GTK_EXPAND | GTK_FILL,
		    GTK_EXPAND | GTK_FILL, 0, 0);
365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384
  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);

  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);
385
  
386
  scrolled_win = gtk_scrolled_window_new (NULL, NULL);
387 388 389
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), GTK_SHADOW_IN);
  gtk_widget_set_usize (scrolled_win, FONT_STYLE_LIST_WIDTH, FONT_LIST_HEIGHT);
  gtk_container_add (GTK_CONTAINER (scrolled_win), fontsel->face_list);
390 391
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
				  GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
392
  gtk_widget_show (fontsel->face_list);
393
  gtk_widget_show (scrolled_win);
394
  gtk_table_attach (GTK_TABLE (table), scrolled_win, 1, 2, 1, 3,
395 396
		    GTK_EXPAND | GTK_FILL,
		    GTK_EXPAND | GTK_FILL, 0, 0);
397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414
  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);

  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);
415
  
416
  scrolled_win = gtk_scrolled_window_new (NULL, NULL);
417 418 419
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), GTK_SHADOW_IN);
  gtk_container_add (GTK_CONTAINER (scrolled_win), fontsel->size_list);
  gtk_widget_set_usize (scrolled_win, -1, FONT_LIST_HEIGHT);
420
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
421 422
				  GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
  gtk_widget_show (fontsel->size_list);
423
  gtk_widget_show (scrolled_win);
424
  gtk_table_attach (GTK_TABLE (table), scrolled_win, 2, 3, 2, 3,
425 426 427 428 429
		    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);
430
  
431
  /* Insert the fonts. */
432
  gtk_font_selection_show_available_fonts (fontsel);
433
  
434 435
  g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (fontsel->family_list)), "changed",
		    G_CALLBACK (gtk_font_selection_select_font), fontsel);
436

437
  gtk_signal_connect_after (GTK_OBJECT (fontsel->family_list), "map",
438
			    GTK_SIGNAL_FUNC (gtk_font_selection_scroll_on_map),
439
			    fontsel);
440
  
441 442
  gtk_font_selection_show_available_styles (fontsel);
  
443 444
  g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (fontsel->face_list)), "changed",
		    G_CALLBACK (gtk_font_selection_select_style), fontsel);
445

446
  gtk_font_selection_show_available_sizes (fontsel, TRUE);
447
  
448 449 450
  g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (fontsel->size_list)), "changed",
		    G_CALLBACK (gtk_font_selection_select_size), fontsel);

451
  /* create the text entry widget */
452 453 454 455 456 457
  label = gtk_label_new_with_mnemonic (_("_Preview:"));
  gtk_widget_show (label);
  
  text_frame = gtk_frame_new (NULL);
  gtk_frame_set_label_widget (GTK_FRAME (text_frame), label);
  
458
  gtk_widget_show (text_frame);
459
  gtk_frame_set_shadow_type (GTK_FRAME (text_frame), GTK_SHADOW_ETCHED_IN);
460
  gtk_box_pack_start (GTK_BOX (fontsel), text_frame,
461
		      FALSE, TRUE, 0);
462
  
463 464 465 466
  /* This is just used to get a 4-pixel space around the preview entry. */
  text_box = gtk_hbox_new (FALSE, 0);
  gtk_widget_show (text_box);
  gtk_container_add (GTK_CONTAINER (text_frame), text_box);
467
  gtk_container_set_border_width (GTK_CONTAINER (text_box), 4);
468
  
469
  fontsel->preview_entry = gtk_entry_new ();
470 471
  gtk_label_set_mnemonic_widget (GTK_LABEL (label), fontsel->preview_entry);
  
472
  gtk_widget_show (fontsel->preview_entry);
473 474 475
  gtk_signal_connect (GTK_OBJECT (fontsel->preview_entry), "changed",
		      (GtkSignalFunc) gtk_font_selection_preview_changed,
		      fontsel);
476 477 478
  gtk_widget_set_usize (fontsel->preview_entry, -1, INITIAL_PREVIEW_HEIGHT);
  gtk_box_pack_start (GTK_BOX (text_box), fontsel->preview_entry,
		      TRUE, TRUE, 0);
479

480
  gtk_font_selection_update_preview (fontsel);
481 482

  gtk_widget_pop_composite_child();
483 484 485
}

GtkWidget *
486
gtk_font_selection_new ()
487 488
{
  GtkFontSelection *fontsel;
489
  
490
  fontsel = gtk_type_new (GTK_TYPE_FONT_SELECTION);
491
  
492 493 494 495
  return GTK_WIDGET (fontsel);
}

static void
496
gtk_font_selection_finalize (GObject *object)
497 498
{
  GtkFontSelection *fontsel;
499
  
500
  g_return_if_fail (GTK_IS_FONT_SELECTION (object));
501
  
502
  fontsel = GTK_FONT_SELECTION (object);
503

504 505
  if (fontsel->font)
    gdk_font_unref (fontsel->font);
506
  
507 508
  if (G_OBJECT_CLASS (font_selection_parent_class)->finalize)
    (* G_OBJECT_CLASS (font_selection_parent_class)->finalize) (object);
509 510
}

511 512 513 514 515 516
static void
gtk_font_selection_preview_changed (GtkWidget        *entry,
				    GtkFontSelection *fontsel)
{
  g_object_notify (G_OBJECT (fontsel), "preview_text");
}
517

518 519 520 521 522 523 524 525 526 527 528 529 530 531 532
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);
    }
}

533 534 535 536 537 538 539 540 541 542 543 544
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);
  
  gtk_tree_view_set_cursor (view, path, 0, FALSE);

  gtk_tree_path_free (path);
}

545
/* This is called when the list is mapped. Here we scroll to the current
546 547
   font if necessary. */
static void
548 549
gtk_font_selection_scroll_on_map (GtkWidget		*widget,
                                  gpointer		 data)
550 551
{
  GtkFontSelection *fontsel;
552
  
553
#ifdef FONTSEL_DEBUG
554
  g_message ("In expose_list\n");
555
#endif
556
  fontsel = GTK_FONT_SELECTION (data);
557
  
558 559
  /* Try to scroll the font family list to the selected item */
  scroll_to_selection (GTK_TREE_VIEW (fontsel->family_list));
560
      
561 562
  /* Try to scroll the font family list to the selected item */
  scroll_to_selection (GTK_TREE_VIEW (fontsel->face_list));
563
      
564 565
  /* Try to scroll the font family list to the selected item */
  scroll_to_selection (GTK_TREE_VIEW (fontsel->size_list));
566 567
}

568
/* This is called when a family is selected in the list. */
Damon Chaplin's avatar
Damon Chaplin committed
569
static void
570 571
gtk_font_selection_select_font (GtkTreeSelection *selection,
				gpointer          data)
Damon Chaplin's avatar
Damon Chaplin committed
572 573
{
  GtkFontSelection *fontsel;
574 575
  GtkTreeModel *model;
  GtkTreeIter iter;
576
  const gchar *family_name;
577
  
Damon Chaplin's avatar
Damon Chaplin committed
578 579
  fontsel = GTK_FONT_SELECTION (data);

580
  if (gtk_tree_selection_get_selected (selection, &model, &iter))
Damon Chaplin's avatar
Damon Chaplin committed
581
    {
582 583 584 585
      PangoFontFamily *family;
      
      gtk_tree_model_get (model, &iter, FAMILY_COLUMN, &family, -1);
      if (fontsel->family != family)
Damon Chaplin's avatar
Damon Chaplin committed
586
	{
587
	  fontsel->family = family;
588 589 590
	  
	  family_name = pango_font_family_get_name (fontsel->family);
	  
Havoc Pennington's avatar
Havoc Pennington committed
591
	  gtk_entry_set_text (GTK_ENTRY (fontsel->font_entry), family_name);
592 593 594
	  
	  gtk_font_selection_show_available_styles (fontsel);
	  gtk_font_selection_select_best_style (fontsel, TRUE);
Damon Chaplin's avatar
Damon Chaplin committed
595
	}
596 597

      g_object_unref (family);
Damon Chaplin's avatar
Damon Chaplin committed
598 599 600
    }
}

601
static int
602
cmp_families (const void *a, const void *b)
603
{
604 605 606 607
  const char *a_name = pango_font_family_get_name (*(PangoFontFamily **)a);
  const char *b_name = pango_font_family_get_name (*(PangoFontFamily **)b);
  
  return strcmp (a_name, b_name);
608
}
Damon Chaplin's avatar
Damon Chaplin committed
609

610
static void
611
gtk_font_selection_show_available_fonts (GtkFontSelection *fontsel)
612
{
613 614 615
  GtkListStore *model;
  PangoFontFamily **families;
  PangoFontFamily *match_family = NULL;
616
  gint n_families, i;
617 618 619 620
  GtkTreeIter match_row;
  
  model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (fontsel->family_list)));
  
621
  pango_context_list_families (gtk_widget_get_pango_context (GTK_WIDGET (fontsel)),
622 623
			       &families, &n_families);
  qsort (families, n_families, sizeof (PangoFontFamily *), cmp_families);
624

625
  gtk_list_store_clear (model);
626 627 628

  for (i=0; i<n_families; i++)
    {
629 630 631 632 633 634 635 636
      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);
637
      
638 639 640 641 642
      if (i == 0 || !g_strcasecmp (name, "sans"))
	{
	  match_family = families[i];
	  match_row = iter;
	}
643
    }
644

645 646 647
  fontsel->family = match_family;
  if (match_family)
    {
648
      set_cursor_to_iter (GTK_TREE_VIEW (fontsel->family_list), &match_row);
649 650 651
      gtk_entry_set_text (GTK_ENTRY (fontsel->font_entry), 
			  pango_font_family_get_name (match_family));
    }
652

653
  g_free (families);
654
}
655

656 657 658
static int
compare_font_descriptions (const PangoFontDescription *a, const PangoFontDescription *b)
{
659
  int val = strcmp (pango_font_description_get_family (a), pango_font_description_get_family (b));
660 661 662
  if (val != 0)
    return val;

663 664
  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);
665

666 667
  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);
668
  
669 670
  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);
671

672 673
  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);
674 675 676 677 678

  return 0;
}

static int
679
faces_sort_func (const void *a, const void *b)
680
{
681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699
  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));
700
}
701

702
/* This fills the font style list with all the possible style combinations
703 704 705 706
   for the current font family. */
static void
gtk_font_selection_show_available_styles (GtkFontSelection *fontsel)
{
707
  gint n_faces, i;
708
  PangoFontFace **faces;
709
  PangoFontDescription *old_desc;
710 711 712 713 714 715
  GtkListStore *model;
  GtkTreeIter match_row;
  PangoFontFace *match_face = NULL;
  
  model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (fontsel->face_list)));
  
716 717 718 719 720
  if (fontsel->face)
    old_desc = pango_font_face_describe (fontsel->face);
  else
    old_desc= NULL;

721 722
  pango_font_family_list_faces (fontsel->family, &faces, &n_faces);
  qsort (faces, n_faces, sizeof (PangoFontFace *), faces_sort_func);
723

724
  gtk_list_store_clear (model);
725

726
  for (i=0; i < n_faces; i++)
727
    {
728 729
      GtkTreeIter iter;
      const gchar *str = pango_font_face_get_face_name (faces[i]);
730

731 732 733 734 735 736 737
      gtk_list_store_append (model, &iter);
      gtk_list_store_set (model, &iter,
			  FACE_COLUMN, faces[i],
			  FACE_NAME_COLUMN, str,
			  -1);

      if (i == 0)
738
	{
739 740 741 742 743 744
	  match_row = iter;
	  match_face = faces[i];
	}
      else if (old_desc)
	{
	  PangoFontDescription *tmp_desc = pango_font_face_describe (faces[i]);
745 746
	  
	  if (font_description_style_equal (tmp_desc, old_desc))
747 748 749 750
	    {
	      match_row = iter;
	      match_face = faces[i];
	    }
751
      
752 753
	  pango_font_description_free (tmp_desc);
	}
754
    }
755

756 757 758
  if (old_desc)
    pango_font_description_free (old_desc);

759 760
  fontsel->face = match_face;
  if (match_face)
761
    {
762 763
      const gchar *str = pango_font_face_get_face_name (fontsel->face);

764 765
      gtk_entry_set_text (GTK_ENTRY (fontsel->font_style_entry), str);
      set_cursor_to_iter (GTK_TREE_VIEW (fontsel->face_list), &match_row);
766
    }
767 768

  g_free (faces);
769 770 771 772 773 774 775 776
}

/* 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
777 778
gtk_font_selection_select_best_style (GtkFontSelection *fontsel,
				      gboolean	        use_first)
779
{
780 781 782 783 784 785 786
  GtkTreeIter iter;
  GtkTreeModel *model;

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

  if (gtk_tree_model_get_iter_root (model, &iter))
    {
787
      set_cursor_to_iter (GTK_TREE_VIEW (fontsel->face_list), &iter);
788 789 790 791
      scroll_to_selection (GTK_TREE_VIEW (fontsel->face_list));
    }

  gtk_font_selection_show_available_sizes (fontsel, FALSE);
792 793 794 795 796 797
  gtk_font_selection_select_best_size (fontsel);
}


/* This is called when a style is selected in the list. */
static void
798 799
gtk_font_selection_select_style (GtkTreeSelection *selection,
				 gpointer          data)
800
{
801
  GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
802 803
  GtkTreeModel *model;
  GtkTreeIter iter;
804
  
805
  if (gtk_tree_selection_get_selected (selection, &model, &iter))
806
    {
807 808 809 810 811 812
      PangoFontFace *face;
      
      gtk_tree_model_get (model, &iter, FACE_COLUMN, &face, -1);
      fontsel->face = face;

      g_object_unref (face);
813 814
    }

815
  gtk_font_selection_show_available_sizes (fontsel, FALSE);
816
  gtk_font_selection_select_best_size (fontsel);
817 818
}

819
static void
820 821
gtk_font_selection_show_available_sizes (GtkFontSelection *fontsel,
					 gboolean          first_time)
822
{
823
  gint i;
824 825
  GtkListStore *model;
  GtkTreeSelection *selection;
826
  gchar buffer[128];
827 828 829

  model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (fontsel->size_list)));
  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (fontsel->size_list));
830

831
  /* Insert the standard font sizes */
832 833 834
  if (first_time)
    {
      gtk_list_store_clear (model);
835

836 837 838 839 840 841 842 843
      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)
844
	    set_cursor_to_iter (GTK_TREE_VIEW (fontsel->size_list), &iter);
845 846 847
	}
    }
  else
848
    {
849 850 851 852 853 854
      GtkTreeIter iter;
      
      gtk_tree_model_get_iter_root (GTK_TREE_MODEL (model), &iter);
      for (i = 0; i < G_N_ELEMENTS (font_sizes); i++)
	{
	  if (font_sizes[i] * PANGO_SCALE == fontsel->size)
855
	    set_cursor_to_iter (GTK_TREE_VIEW (fontsel->size_list), &iter);
856 857 858 859

	  gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &iter);
	}
      
860 861
    }

862
  sprintf (buffer, "%i", fontsel->size / PANGO_SCALE);
863
  gtk_entry_set_text (GTK_ENTRY (fontsel->size_entry), buffer);
864 865
}

866
static void
867
gtk_font_selection_select_best_size (GtkFontSelection *fontsel)
868
{
869 870
  gtk_font_selection_load_font (fontsel);  
}
871

872 873
/* If the user hits return in the font size entry, we change to the new font
   size. */
874 875 876
static void
gtk_font_selection_size_activate (GtkWidget   *w,
                                  gpointer     data)
877 878 879
{
  GtkFontSelection *fontsel;
  gint new_size;
880
  const gchar *text;
881
  
882
  fontsel = GTK_FONT_SELECTION (data);
883 884 885

  text = gtk_entry_get_text (GTK_ENTRY (fontsel->size_entry));
  new_size = atoi (text) * PANGO_SCALE;
886
  
887
  if (fontsel->size != new_size)
888
    {
889
      fontsel->size = new_size;
890
      gtk_font_selection_load_font (fontsel);
891 892 893
    }
}

894
/* This is called when a size is selected in the list. */
895
static void
896 897
gtk_font_selection_select_size (GtkTreeSelection *selection,
				gpointer          data)
898
{
899
  GtkFontSelection *fontsel;
900 901
  GtkTreeModel *model;
  GtkTreeIter iter;
902
  gint new_size;
903
  gchar buffer[128];
904 905
  
  fontsel = GTK_FONT_SELECTION (data);
906
  
907
  if (gtk_tree_selection_get_selected (selection, &model, &iter))
908
    {
909 910 911 912 913 914 915
      gtk_tree_model_get (model, &iter, SIZE_COLUMN, &new_size, -1);
      new_size *= PANGO_SCALE;
  
      if (fontsel->size != new_size)
	{
	  /* If the size was selected by the user we set the selected_size. */
	  fontsel->size = new_size;
916 917 918 919

	  sprintf (buffer, "%i", fontsel->size / PANGO_SCALE);
	  gtk_entry_set_text (GTK_ENTRY (fontsel->size_entry), buffer);

920 921
	  gtk_font_selection_load_font (fontsel);
	}
922 923 924
    }
}

925 926 927 928 929 930 931 932 933
static void
gtk_font_selection_load_font (GtkFontSelection *fontsel)
{
  if (fontsel->font)
    gdk_font_unref (fontsel->font);
  fontsel->font = NULL;

  gtk_font_selection_update_preview (fontsel);
}
934

935 936 937 938 939 940 941 942 943
static PangoFontDescription *
gtk_font_selection_get_font_description (GtkFontSelection *fontsel)
{
  PangoFontDescription *font_desc = pango_font_face_describe (fontsel->face);
  pango_font_description_set_size (font_desc, fontsel->size);

  return font_desc;
}

944 945 946 947 948 949 950 951
/* 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)
952
{
953 954 955 956
  GtkRcStyle *rc_style;
  gint new_height;
  GtkRequisition old_requisition;
  GtkWidget *preview_entry = fontsel->preview_entry;
957
  const gchar *text;
958 959

  gtk_widget_get_child_requisition (preview_entry, &old_requisition);
960
  
961
  rc_style = gtk_rc_style_new ();
962 963
  rc_style->font_desc = gtk_font_selection_get_font_description (fontsel);
  
964 965 966 967 968 969 970
  gtk_widget_modify_style (preview_entry, rc_style);
  gtk_rc_style_unref (rc_style);

  gtk_widget_size_request (preview_entry, NULL);
  
  /* We don't ever want to be over MAX_PREVIEW_HEIGHT pixels high. */
  new_height = CLAMP (preview_entry->requisition.height, INITIAL_PREVIEW_HEIGHT, MAX_PREVIEW_HEIGHT);
971

972
  if (new_height > old_requisition.height || new_height < old_requisition.height - 30)
973
    gtk_widget_set_usize (preview_entry, -1, new_height);
974 975
  
  /* This sets the preview text, if it hasn't been set already. */
976 977 978 979
  text = gtk_entry_get_text (GTK_ENTRY (preview_entry));
  if (strlen (text) == 0)
    gtk_entry_set_text (GTK_ENTRY (preview_entry), PREVIEW_TEXT);
  gtk_entry_set_position (GTK_ENTRY (preview_entry), 0);
980
}
981 982 983 984 985 986 987 988

/*****************************************************************************
 * These functions are the main public interface for getting/setting the font.
 *****************************************************************************/

GdkFont*
gtk_font_selection_get_font (GtkFontSelection *fontsel)
{
989
  if (!fontsel->font)
990 991 992 993 994
    {
      PangoFontDescription *font_desc = gtk_font_selection_get_font_description (fontsel);
      fontsel->font = gdk_font_from_description (font_desc);
      pango_font_description_free (font_desc);
    }
995
  
996 997 998 999 1000 1001 1002
  return fontsel->font;
}


gchar *
gtk_font_selection_get_font_name (GtkFontSelection *fontsel)
{
1003 1004 1005 1006 1007 1008 1009
  gchar *result;
  
  PangoFontDescription *font_desc = gtk_font_selection_get_font_description (fontsel);
  result = pango_font_description_to_string (font_desc);
  pango_font_description_free (font_desc);

  return result;
1010 1011 1012
}


1013
/* This sets the current font, selecting the appropriate list rows.
1014 1015 1016
   First we check the fontname is valid and try to find the font family
   - i.e. the name in the main list. If we can't find that, then just return.
   Next we try to set each of the properties according to the fontname.
1017
   Finally we select the font family & style in the lists. */
1018 1019 1020 1021
gboolean
gtk_font_selection_set_font_name (GtkFontSelection *fontsel,
				  const gchar      *fontname)
{
1022 1023
  PangoFontFamily *new_family = NULL;
  PangoFontFace *new_face = NULL;
1024
  PangoFontFace *fallback_face = NULL;
1025
  PangoFontDescription *new_desc;
1026 1027 1028
  GtkTreeModel *model;
  GtkTreeIter iter;
  gboolean valid;
1029
  
1030
  g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), FALSE);
1031
  
1032
  new_desc = pango_font_description_from_string (fontname);
1033

1034
  /* Check to make sure that this is in the list of allowed fonts */
1035

1036 1037 1038 1039
  model = gtk_tree_view_get_model (GTK_TREE_VIEW (fontsel->family_list));
  for (valid = gtk_tree_model_get_iter_root (model, &iter);
       valid;
       valid = gtk_tree_model_iter_next (model, &iter))
1040
    {
1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052
      PangoFontFamily *family;
      
      gtk_tree_model_get (model, &iter, FAMILY_COLUMN, &family, -1);
      
      if (g_ascii_strcasecmp (pango_font_family_get_name (family),
			      pango_font_description_get_family (new_desc)) == 0)
	new_family = family;
      
      g_object_unref (family);
      
      if (new_family)
	break;
1053
    }
1054

1055
  if (!new_family)
1056 1057
    return FALSE;

1058 1059 1060
  fontsel->family = new_family;
  gtk_font_selection_show_available_styles (fontsel);

1061 1062 1063 1064
  model = gtk_tree_view_get_model (GTK_TREE_VIEW (fontsel->face_list));
  for (valid = gtk_tree_model_get_iter_root (model, &iter);
       valid;
       valid = gtk_tree_model_iter_next (model, &iter))
1065
    {
1066 1067 1068 1069 1070
      PangoFontFace *face;
      PangoFontDescription *tmp_desc;
      
      gtk_tree_model_get (model, &iter, FACE_COLUMN, &face, -1);
      tmp_desc = pango_font_face_describe (face);
1071 1072
      
      if (font_description_style_equal (tmp_desc, new_desc))
1073 1074 1075 1076 1077
	new_face = face;
      
      if (!fallback_face)
	fallback_face = face;
      
1078
      pango_font_description_free (tmp_desc);
1079 1080
      g_object_unref (face);
      
1081 1082 1083 1084 1085
      if (new_face)
	break;
    }

  if (!new_face)
1086
    new_face = fallback_face;
1087 1088 1089

  fontsel->face = new_face;
  gtk_font_selection_select_best_size (fontsel);
1090

1091
  g_object_freeze_notify (G_OBJECT (fontsel));
1092 1093
  g_object_notify (G_OBJECT (fontsel), "font_name");
  g_object_notify (G_OBJECT (fontsel), "font");
1094
  g_object_thaw_notify (G_OBJECT (fontsel));
1095

1096
  return TRUE;
1097 1098 1099 1100 1101
}


/* This returns the text in the preview entry. You should copy the returned
   text if you need it. */
1102
G_CONST_RETURN gchar*
1103 1104
gtk_font_selection_get_preview_text  (GtkFontSelection *fontsel)
{
1105
  return gtk_entry_get_text (GTK_ENTRY (fontsel->preview_entry));
1106 1107 1108 1109 1110 1111 1112 1113
}


/* This sets the text in the preview entry. */
void
gtk_font_selection_set_preview_text  (GtkFontSelection *fontsel,
				      const gchar	  *text)
{
1114
  gtk_entry_set_text (GTK_ENTRY (fontsel->preview_entry), text);
1115 1116 1117 1118 1119 1120
}

/*****************************************************************************
 * GtkFontSelectionDialog
 *****************************************************************************/

1121
GtkType
1122
gtk_font_selection_dialog_get_type (void)
1123
{
1124
  static GtkType font_selection_dialog_type = 0;
1125
  
1126 1127 1128 1129 1130 1131 1132 1133 1134
  if (!font_selection_dialog_type)
    {
      GtkTypeInfo fontsel_diag_info =
      {
	"GtkFontSelectionDialog",
	sizeof (GtkFontSelectionDialog),
	sizeof (GtkFontSelectionDialogClass),
	(GtkClassInitFunc) gtk_font_selection_dialog_class_init,
	(GtkObjectInitFunc) gtk_font_selection_dialog_init,
1135 1136
	/* reserved_1 */ NULL,
	/* reserved_2 */ NULL,
1137
        (GtkClassInitFunc) NULL,
1138
      };
1139
      
1140 1141
      font_selection_dialog_type = gtk_type_unique (GTK_TYPE_DIALOG,
                                                    &fontsel_diag_info);
1142
    }
1143
  
1144 1145 1146 1147 1148 1149 1150
  return font_selection_dialog_type;
}

static void
gtk_font_selection_dialog_class_init (GtkFontSelectionDialogClass *klass)
{
  GtkObjectClass *object_class;
1151
  
1152
  object_class = (GtkObjectClass*) klass;
1153
  
1154
  font_selection_dialog_parent_class = gtk_type_class (GTK_TYPE_DIALOG);
1155 1156 1157 1158 1159
}

static void
gtk_font_selection_dialog_init (GtkFontSelectionDialog *fontseldiag)
{
1160 1161
  GtkDialog *dialog;

1162 1163
  gtk_widget_push_composite_child ();

1164 1165
  dialog = GTK_DIALOG (fontseldiag);
  
1166 1167
  fontseldiag->dialog_width = -1;
  fontseldiag->auto_resize = TRUE;
1168
  
1169
  gtk_widget_set_events (GTK_WIDGET (fontseldiag), GDK_STRUCTURE_MASK);
1170 1171 1172
  gtk_signal_connect (GTK_OBJECT (fontseldiag), "configure_event",
		      (GtkSignalFunc) gtk_font_selection_dialog_on_configure,
		      fontseldiag);
1173
  
1174
  gtk_container_set_border_width (GTK_CONTAINER (fontseldiag), 4);
1175
  gtk_window_set_policy (GTK_WINDOW (fontseldiag), FALSE, TRUE, TRUE);
1176
  
1177
  fontseldiag->main_vbox = dialog->vbox;
1178
  
1179
  fontseldiag->fontsel = gtk_font_selection_new ();
1180
  gtk_container_set_border_width (GTK_CONTAINER (fontseldiag->fontsel), 4);
1181 1182 1183
  gtk_widget_show (fontseldiag->fontsel);
  gtk_box_pack_start (GTK_BOX (fontseldiag->main_vbox),
		      fontseldiag->fontsel, TRUE, TRUE, 0);
1184
  
1185
  /* Create the action area */
1186
  fontseldiag->action_area = dialog->action_area;
1187 1188 1189 1190 1191

  fontseldiag->cancel_button = gtk_dialog_add_button (dialog,
                                                      GTK_STOCK_CANCEL,
                                                      GTK_RESPONSE_CANCEL);

1192
  fontseldiag->apply_button = gtk_dialog_add_button (dialog,
1193
                                                     GTK_STOCK_APPLY,
1194 1195 1196
                                                     GTK_RESPONSE_APPLY);
  gtk_widget_hide (fontseldiag->apply_button);

1197 1198 1199 1200
  fontseldiag->ok_button = gtk_dialog_add_button (dialog,
                                                  GTK_STOCK_OK,
                                                  GTK_RESPONSE_OK);
  gtk_widget_grab_default (fontseldiag->ok_button);
1201
  
1202 1203 1204
  gtk_window_set_title (GTK_WINDOW (fontseldiag),
                        _("Font Selection"));

1205 1206
  gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
  
1207
  gtk_widget_pop_composite_child ();
1208 1209 1210
}

GtkWidget*
1211
gtk_font_selection_dialog_new (const gchar *title)
1212 1213
{
  GtkFontSelectionDialog *fontseldiag;
1214
  
1215
  fontseldiag = gtk_type_new (GTK_TYPE_FONT_SELECTION_DIALOG);
1216 1217 1218

  if (title)
    gtk_window_set_title (GTK_WINDOW (fontseldiag), title);
1219
  
1220 1221 1222 1223
  return GTK_WIDGET (fontseldiag);
}

gchar*
1224
gtk_font_selection_dialog_get_font_name (GtkFontSelectionDialog *fsd)
1225
{
1226
  return gtk_font_selection_get_font_name (GTK_FONT_SELECTION (fsd->fontsel));
1227 1228 1229
}

GdkFont*
1230
gtk_font_selection_dialog_get_font (GtkFontSelectionDialog *fsd)
1231
{
1232
  return gtk_font_selection_get_font (GTK_FONT_SELECTION (fsd->fontsel));
1233 1234 1235
}

gboolean
Owen Taylor's avatar