gtkfontsel.c 113 KB
Newer Older
Owen Taylor's avatar
Owen Taylor committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
/* GTK - The GIMP Toolkit
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * 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
 * modify it under the terms of the GNU Library General Public
 * 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/*
 * Limits:
 *
 *  Fontnames	 - A maximum of MAX_FONTS (32767) fontnames will be retrieved
 *		   from X Windows with XListFonts(). Any more are ignored.
 *		   I think this limit may have been set because of a limit in
 *		   GtkList. It could possibly be increased since we are using
 *		   GtkClists now, but I'd be surprised if it was reached.
 *  Field length - XLFD_MAX_FIELD_LEN is the maximum length that any field of a
 *		   fontname can be for it to be considered valid. Others are
 *		   ignored.
 *  Properties   - Maximum of 65535 choices for each font property - guint16's
 *		   are used as indices, e.g. in the FontInfo struct.
 *  Combinations - Maximum of 65535 combinations of properties for each font
 *		   family - a guint16 is used in the FontInfo struct.
 *  Font size    - Minimum font size of 2 pixels/points, since trying to load
 *		   some fonts with a size of 1 can cause X to hang.
 *		   (e.g. the Misc Fixed fonts).
 */

/*
 * Possible Improvements:
 *
 *  Font Styles  - could sort the styles into a reasonable order - regular
48
 *		   first, then bold, bold italic etc.
Owen Taylor's avatar
Owen Taylor committed
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
 *
 *  I18N	 - the default preview text is not useful for international
 *		   fonts. Maybe the first few characters of the font could be
 *		   displayed instead.
 *		 - fontsets? should these be handled by the font dialog?
 */

/*
 * Debugging: compile with -DFONTSEL_DEBUG for lots of debugging output.
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <X11/Xlib.h>

#include "gdk/gdkx.h"
#include "gdk/gdkkeysyms.h"

#include "gtkbutton.h"
71
#include "gtkcheckbutton.h"
Owen Taylor's avatar
Owen Taylor committed
72 73 74 75 76 77 78 79 80 81 82 83
#include "gtkclist.h"
#include "gtkentry.h"
#include "gtkfontsel.h"
#include "gtkframe.h"
#include "gtkhbbox.h"
#include "gtkhbox.h"
#include "gtklabel.h"
#include "gtknotebook.h"
#include "gtkradiobutton.h"
#include "gtksignal.h"
#include "gtktable.h"
#include "gtkvbox.h"
84
#include "gtkscrolledwindow.h"
85
#include "gtkintl.h"
Owen Taylor's avatar
Owen Taylor committed
86 87 88 89 90 91 92 93 94 95 96

/* The maximum number of fontnames requested with XListFonts(). */
#define MAX_FONTS 32767

/* This is the largest field length we will accept. If a fontname has a field
   larger than this we will skip it. */
#define XLFD_MAX_FIELD_LEN 64

/* These are what we use as the standard font sizes, for the size clist.
   Note that when using points we still show these integer point values but
   we work internally in decipoints (and decipoint values can be typed in). */
97
static const guint16 font_sizes[] = {
Owen Taylor's avatar
Owen Taylor committed
98 99 100 101 102 103
  8, 9, 10, 11, 12, 13, 14, 16, 18, 20, 22, 24, 26, 28,
  32, 36, 40, 48, 56, 64, 72
};

/* Initial font metric & size (Remember point sizes are in decipoints).
   The font size should match one of those in the font_sizes array. */
104
#define INITIAL_METRIC		  GTK_FONT_METRIC_POINTS
Owen Taylor's avatar
Owen Taylor committed
105 106 107 108 109 110 111 112 113 114 115 116 117
#define INITIAL_FONT_SIZE	  140

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

/* These are the sizes of the font, style & size clists. */
#define FONT_LIST_HEIGHT	136
Damon Chaplin's avatar
""  
Damon Chaplin committed
118 119
#define FONT_LIST_WIDTH		190
#define FONT_STYLE_LIST_WIDTH	170
Owen Taylor's avatar
Owen Taylor committed
120 121 122 123 124 125
#define FONT_SIZE_LIST_WIDTH	60

/* This is the number of fields in an X Logical Font Description font name.
   Note that we count the registry & encoding as 1. */
#define GTK_XLFD_NUM_FIELDS 13

126 127 128 129 130 131 132 133 134 135 136 137 138 139
typedef struct _GtkFontSelInfo GtkFontSelInfo;
typedef struct _FontInfo FontInfo;
typedef struct _FontStyle FontStyle;

/* This struct represents one family of fonts (with one foundry), e.g. adobe
   courier or sony fixed. It stores the family name, the index of the foundry
   name, and the index of and number of available styles. */
struct _FontInfo
{
  gchar   *family;
  guint16  foundry;
  gint	   style_index;
  guint16  nstyles;
};
140

141 142
/* This represents one style, as displayed in the Font Style clist. It can
   have a number of available pixel sizes and point sizes. The indexes point
143 144 145 146 147
   into the two big fontsel_info->pixel_sizes & fontsel_info->point_sizes
   arrays. The displayed flag is used when displaying styles to remember which
   styles have already been displayed. Note that it is combined with the
   GtkFontType in the flags field. */
#define  GTK_FONT_DISPLAYED	(1 << 7)
148 149 150 151 152 153 154 155 156 157 158
struct _FontStyle
{
  guint16  properties[GTK_NUM_STYLE_PROPERTIES];
  gint	   pixel_sizes_index;
  guint16  npixel_sizes;
  gint	   point_sizes_index;
  guint16  npoint_sizes;
  guint8   flags;
};

struct _GtkFontSelInfo {
159
  
160 161 162
  /* This is a table with each FontInfo representing one font family+foundry */
  FontInfo *font_info;
  gint nfonts;
163
  
164 165 166 167
  /* This stores all the valid combinations of properties for every family.
     Each FontInfo holds an index into its own space in this one big array. */
  FontStyle *font_styles;
  gint nstyles;
168
  
169 170 171 172
  /* This stores all the font sizes available for every style.
     Each style holds an index into these arrays. */
  guint16 *pixel_sizes;
  guint16 *point_sizes;
173
  
174 175 176
  /* These are the arrays of strings of all possible weights, slants, 
     set widths, spacings, charsets & foundries, and the amount of space
     allocated for each array. */
177 178 179 180 181
  gchar **properties[GTK_NUM_FONT_PROPERTIES];
  guint16 nproperties[GTK_NUM_FONT_PROPERTIES];
  guint16 space_allocated[GTK_NUM_FONT_PROPERTIES];
};

Owen Taylor's avatar
Owen Taylor committed
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
/* These are the field numbers in the X Logical Font Description fontnames,
   e.g. -adobe-courier-bold-o-normal--25-180-100-100-m-150-iso8859-1 */
typedef enum
{
  XLFD_FOUNDRY		= 0,
  XLFD_FAMILY		= 1,
  XLFD_WEIGHT		= 2,
  XLFD_SLANT		= 3,
  XLFD_SET_WIDTH	= 4,
  XLFD_ADD_STYLE	= 5,
  XLFD_PIXELS		= 6,
  XLFD_POINTS		= 7,
  XLFD_RESOLUTION_X	= 8,
  XLFD_RESOLUTION_Y	= 9,
  XLFD_SPACING		= 10,
  XLFD_AVERAGE_WIDTH	= 11,
  XLFD_CHARSET		= 12
} FontField;

/* These are the names of the fields, used on the info & filter page. */
202
static const gchar* xlfd_field_names[GTK_XLFD_NUM_FIELDS] = {
203 204 205 206 207 208 209 210 211 212 213 214 215
  N_("Foundry:"),
  N_("Family:"),
  N_("Weight:"),
  N_("Slant:"),
  N_("Set Width:"),
  N_("Add Style:"),
  N_("Pixel Size:"),
  N_("Point Size:"),
  N_("Resolution X:"),
  N_("Resolution Y:"),
  N_("Spacing:"),
  N_("Average Width:"),
  N_("Charset:"),
Owen Taylor's avatar
Owen Taylor committed
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
};

/* These are the array indices of the font properties used in several arrays,
   and should match the xlfd_index array below. */
typedef enum
{
  WEIGHT	= 0,
  SLANT		= 1,
  SET_WIDTH	= 2,
  SPACING	= 3,
  CHARSET	= 4,
  FOUNDRY	= 5
} PropertyIndexType;

/* This is used to look up a field in a fontname given one of the above
   property indices. */
232
static const FontField xlfd_index[GTK_NUM_FONT_PROPERTIES] = {
Owen Taylor's avatar
Owen Taylor committed
233 234 235 236 237 238 239 240 241
  XLFD_WEIGHT,
  XLFD_SLANT,
  XLFD_SET_WIDTH,
  XLFD_SPACING,
  XLFD_CHARSET,
  XLFD_FOUNDRY
};

/* These are the positions of the properties in the filter table - x, y. */
242
static const gint filter_positions[GTK_NUM_FONT_PROPERTIES][2] = {
Owen Taylor's avatar
Owen Taylor committed
243 244
  { 1, 0 }, { 0, 2 }, { 1, 2 }, { 2, 2 }, { 2, 0 }, { 0, 0 }
};
245
static const gint filter_heights[GTK_NUM_FONT_PROPERTIES] = {
246
  100, 70, 70, 40, 100, 100
Owen Taylor's avatar
Owen Taylor committed
247 248
};

249 250 251 252 253 254 255 256 257 258 259
/* This is returned by gtk_font_selection_filter_state to describe if a
   property value is filtered. e.g. if 'bold' has been selected on the filter
   page, then that will return 'FILTERED' and 'black' will be 'NOT_FILTERED'.
   If none of the weight values are selected, they all return 'NOT_SET'. */
typedef enum
{
  FILTERED,
  NOT_FILTERED,
  NOT_SET
} GtkFontPropertyFilterState;

260 261
static GtkFontSelInfo *fontsel_info = NULL;

Owen Taylor's avatar
Owen Taylor committed
262 263 264 265 266 267 268 269
/* The initial size and increment of each of the arrays of property values. */
#define PROPERTY_ARRAY_INCREMENT	16

static void    gtk_font_selection_class_init	     (GtkFontSelectionClass *klass);
static void    gtk_font_selection_init		     (GtkFontSelection *fontsel);
static void    gtk_font_selection_destroy	     (GtkObject      *object);

/* These are all used for class initialization - loading in the fonts etc. */
270 271
static void    gtk_font_selection_get_fonts          (void);
static void    gtk_font_selection_insert_font        (GSList         *fontnames[],
Owen Taylor's avatar
Owen Taylor committed
272 273
						      gint           *ntable,
						      gchar          *fontname);
274
static gint    gtk_font_selection_insert_field       (gchar          *fontname,
Owen Taylor's avatar
Owen Taylor committed
275 276 277 278 279 280 281 282 283 284 285 286 287 288 289
						      gint            prop);

/* These are the callbacks & related functions. */
static void    gtk_font_selection_select_font	     (GtkWidget      *w,
						      gint	      row,
						      gint	      column,
						      GdkEventButton *bevent,
						      gpointer        data);
static gint    gtk_font_selection_on_clist_key_press (GtkWidget      *clist,
						      GdkEventKey    *event,
						      GtkFontSelection *fs);
static gboolean gtk_font_selection_select_next	     (GtkFontSelection *fs,
						      GtkWidget        *clist,
						      gint		step);
static void    gtk_font_selection_show_available_styles
290
(GtkFontSelection *fs);
291 292
static void    gtk_font_selection_select_best_style  (GtkFontSelection *fs,
						      gboolean	       use_first);
Owen Taylor's avatar
Owen Taylor committed
293 294 295 296 297 298 299

static void    gtk_font_selection_select_style	     (GtkWidget      *w,
						      gint	      row,
						      gint	      column,
						      GdkEventButton *bevent,
						      gpointer        data);
static void    gtk_font_selection_show_available_sizes
300
(GtkFontSelection *fs);
Owen Taylor's avatar
Owen Taylor committed
301 302 303 304 305 306 307 308 309 310 311 312 313 314 315
static gint    gtk_font_selection_size_key_press     (GtkWidget      *w,
						      GdkEventKey    *event,
						      gpointer        data);
static void    gtk_font_selection_select_best_size   (GtkFontSelection *fs);
static void    gtk_font_selection_select_size	     (GtkWidget      *w,
						      gint	      row,
						      gint	      column,
						      GdkEventButton *bevent,
						      gpointer        data);

static void    gtk_font_selection_metric_callback    (GtkWidget      *w,
						      gpointer        data);
static void    gtk_font_selection_expose_list	     (GtkWidget	     *w,
						      GdkEventExpose *event,
						      gpointer        data);
Damon Chaplin's avatar
""  
Damon Chaplin committed
316 317
static void    gtk_font_selection_realize_list	     (GtkWidget	     *widget,
						      gpointer	      data);
Owen Taylor's avatar
Owen Taylor committed
318 319 320 321 322 323 324 325 326 327 328

static void    gtk_font_selection_switch_page	     (GtkWidget      *w,
						      GtkNotebookPage *page,
						      gint             page_num,
						      gpointer         data);
static void    gtk_font_selection_show_font_info     (GtkFontSelection *fs);

static void    gtk_font_selection_select_filter	     (GtkWidget      *w,
						      gint	      row,
						      gint	      column,
						      GdkEventButton *bevent,
329
						      GtkFontSelection *fs);
Owen Taylor's avatar
Owen Taylor committed
330 331 332 333
static void    gtk_font_selection_unselect_filter    (GtkWidget      *w,
						      gint	      row,
						      gint	      column,
						      GdkEventButton *bevent,
334 335
						      GtkFontSelection *fs);
static void    gtk_font_selection_update_filter	     (GtkFontSelection *fs);
Owen Taylor's avatar
Owen Taylor committed
336 337 338 339
static gboolean gtk_font_selection_style_visible     (GtkFontSelection *fs,
						      FontInfo       *font,
						      gint	      style);
static void    gtk_font_selection_reset_filter	     (GtkWidget      *w,
340
						      GtkFontSelection *fs);
341
static void    gtk_font_selection_on_clear_filter    (GtkWidget      *w,
342 343 344
						      GtkFontSelection *fs);
static void    gtk_font_selection_show_available_fonts
						     (GtkFontSelection *fs);
Owen Taylor's avatar
Owen Taylor committed
345
static void    gtk_font_selection_clear_filter       (GtkFontSelection *fs);
346 347 348 349 350 351
static void    gtk_font_selection_update_filter_lists(GtkFontSelection *fs);
static GtkFontPropertyFilterState gtk_font_selection_filter_state
						     (GtkFontSelection *fs,
						      GtkFontFilterType filter_type,
						      gint		property,
						      gint		index);
Owen Taylor's avatar
Owen Taylor committed
352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393

/* Misc. utility functions. */
static gboolean gtk_font_selection_load_font         (GtkFontSelection *fs);
static void    gtk_font_selection_update_preview     (GtkFontSelection *fs);

static gint    gtk_font_selection_find_font	     (GtkFontSelection *fs,
						      gchar          *family,
						      guint16	      foundry);
static guint16 gtk_font_selection_field_to_index     (gchar         **table,
						      gint            ntable,
						      gchar          *field);

static gchar*  gtk_font_selection_expand_slant_code  (gchar          *slant);
static gchar*  gtk_font_selection_expand_spacing_code(gchar          *spacing);

/* Functions for handling X Logical Font Description fontnames. */
static gboolean gtk_font_selection_is_xlfd_font_name (const gchar    *fontname);
static char*   gtk_font_selection_get_xlfd_field     (const gchar    *fontname,
						      FontField       field_num,
						      gchar          *buffer);
static gchar * gtk_font_selection_create_xlfd        (gint            size,
						      GtkFontMetricType metric,
						      gchar          *foundry,
						      gchar          *family,
						      gchar          *weight,
						      gchar          *slant,
						      gchar          *set_width,
						      gchar          *spacing,
						      gchar	     *charset);


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

static gint    gtk_font_selection_dialog_on_configure(GtkWidget      *widget,
						      GdkEventConfigure *event,
						      GtkFontSelectionDialog *fsd);

static GtkWindowClass *font_selection_parent_class = NULL;
static GtkNotebookClass *font_selection_dialog_parent_class = NULL;

Tim Janik's avatar
Tim Janik committed
394
GtkType
Owen Taylor's avatar
Owen Taylor committed
395 396
gtk_font_selection_get_type()
{
Tim Janik's avatar
Tim Janik committed
397
  static GtkType font_selection_type = 0;
398
  
Owen Taylor's avatar
Owen Taylor committed
399 400
  if(!font_selection_type)
    {
401
      static const GtkTypeInfo fontsel_type_info =
Owen Taylor's avatar
Owen Taylor committed
402 403
      {
	"GtkFontSelection",
Tim Janik's avatar
Tim Janik committed
404 405
	sizeof (GtkFontSelection),
	sizeof (GtkFontSelectionClass),
Owen Taylor's avatar
Owen Taylor committed
406 407
	(GtkClassInitFunc) gtk_font_selection_class_init,
	(GtkObjectInitFunc) gtk_font_selection_init,
408 409
	/* reserved_1 */ NULL,
	/* reserved_2 */ NULL,
410
        (GtkClassInitFunc) NULL,
Owen Taylor's avatar
Owen Taylor committed
411
      };
412
      
Tim Janik's avatar
Tim Janik committed
413 414
      font_selection_type = gtk_type_unique (GTK_TYPE_NOTEBOOK,
					     &fontsel_type_info);
Owen Taylor's avatar
Owen Taylor committed
415
    }
416
  
Owen Taylor's avatar
Owen Taylor committed
417 418 419 420 421 422 423
  return font_selection_type;
}

static void
gtk_font_selection_class_init(GtkFontSelectionClass *klass)
{
  GtkObjectClass *object_class;
424
  
Owen Taylor's avatar
Owen Taylor committed
425
  object_class = (GtkObjectClass *) klass;
426
  
Tim Janik's avatar
Tim Janik committed
427
  font_selection_parent_class = gtk_type_class (GTK_TYPE_NOTEBOOK);
428
  
Owen Taylor's avatar
Owen Taylor committed
429
  object_class->destroy = gtk_font_selection_destroy;
430
  
431
  gtk_font_selection_get_fonts ();
Owen Taylor's avatar
Owen Taylor committed
432 433 434 435 436
}

static void
gtk_font_selection_init(GtkFontSelection *fontsel)
{
437
  GtkWidget *scrolled_win;
Owen Taylor's avatar
Owen Taylor committed
438
  GtkWidget *text_frame;
439
  GtkWidget *text_box, *frame;
Owen Taylor's avatar
Owen Taylor committed
440 441
  GtkWidget *table, *label, *hbox, *hbox2, *clist, *button, *vbox, *alignment;
  gint i, prop, row;
442
  gchar *titles[] = { _("Font Property"), _("Requested Value"), _("Actual Value") };
Owen Taylor's avatar
Owen Taylor committed
443 444 445
  gchar buffer[128];
  gchar *size;
  gint size_to_match;
446
  gchar *row_text[3];
Owen Taylor's avatar
Owen Taylor committed
447 448
  gchar *property, *text;
  gboolean inserted;
449
  
Owen Taylor's avatar
Owen Taylor committed
450 451 452 453 454 455 456 457
  /* Initialize the GtkFontSelection struct. We do this here in case any
     callbacks are triggered while creating the interface. */
  fontsel->font = NULL;
  fontsel->font_index = -1;
  fontsel->style = -1;
  fontsel->metric = INITIAL_METRIC;
  fontsel->size = INITIAL_FONT_SIZE;
  fontsel->selected_size = INITIAL_FONT_SIZE;
458 459 460 461 462

  fontsel->filters[GTK_FONT_FILTER_BASE].font_type = GTK_FONT_ALL;
  fontsel->filters[GTK_FONT_FILTER_USER].font_type = GTK_FONT_BITMAP
    | GTK_FONT_SCALABLE;

463
  
Owen Taylor's avatar
Owen Taylor committed
464 465
  for (prop = 0; prop < GTK_NUM_FONT_PROPERTIES; prop++)
    {
466 467 468 469
      fontsel->filters[GTK_FONT_FILTER_BASE].property_filters[prop] = NULL;
      fontsel->filters[GTK_FONT_FILTER_BASE].property_nfilters[prop] = 0;
      fontsel->filters[GTK_FONT_FILTER_USER].property_filters[prop] = NULL;
      fontsel->filters[GTK_FONT_FILTER_USER].property_nfilters[prop] = 0;
Owen Taylor's avatar
Owen Taylor committed
470
    }
471
  
Owen Taylor's avatar
Owen Taylor committed
472
  for (prop = 0; prop < GTK_NUM_STYLE_PROPERTIES; prop++)
473 474
    fontsel->property_values[prop] = 0;
  
475
  /* Create the main notebook page. */
Damon Chaplin's avatar
""  
Damon Chaplin committed
476 477
  gtk_notebook_set_homogeneous_tabs (GTK_NOTEBOOK (fontsel), TRUE);
  gtk_notebook_set_tab_hborder (GTK_NOTEBOOK (fontsel), 8);
Owen Taylor's avatar
Owen Taylor committed
478 479
  fontsel->main_vbox = gtk_vbox_new (FALSE, 4);
  gtk_widget_show (fontsel->main_vbox);
480
  gtk_container_set_border_width (GTK_CONTAINER (fontsel->main_vbox), 6);
481
  label = gtk_label_new(_("Font"));
Owen Taylor's avatar
Owen Taylor committed
482 483
  gtk_notebook_append_page (GTK_NOTEBOOK (fontsel),
			    fontsel->main_vbox, label);
484
  
Owen Taylor's avatar
Owen Taylor committed
485 486 487 488 489
  /* Create the table of font, style & size. */
  table = gtk_table_new (3, 3, FALSE);
  gtk_widget_show (table);
  gtk_table_set_col_spacings(GTK_TABLE(table), 8);
  gtk_box_pack_start (GTK_BOX (fontsel->main_vbox), table, TRUE, TRUE, 0);
490
  
491
  fontsel->font_label = gtk_label_new(_("Font:"));
Owen Taylor's avatar
Owen Taylor committed
492 493 494 495
  gtk_misc_set_alignment (GTK_MISC (fontsel->font_label), 0.0, 0.5);
  gtk_widget_show (fontsel->font_label);
  gtk_table_attach (GTK_TABLE (table), fontsel->font_label, 0, 1, 0, 1,
		    GTK_FILL, 0, 0, 0);
496
  label = gtk_label_new(_("Font Style:"));
Owen Taylor's avatar
Owen Taylor committed
497 498 499 500
  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  gtk_widget_show (label);
  gtk_table_attach (GTK_TABLE (table), label, 1, 2, 0, 1,
		    GTK_FILL, 0, 0, 0);
501
  label = gtk_label_new(_("Size:"));
Owen Taylor's avatar
Owen Taylor committed
502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526
  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);
  
  fontsel->font_entry = gtk_entry_new();
  gtk_entry_set_editable(GTK_ENTRY(fontsel->font_entry), FALSE);
  gtk_widget_set_usize (fontsel->font_entry, 20, -1);
  gtk_widget_show (fontsel->font_entry);
  gtk_table_attach (GTK_TABLE (table), fontsel->font_entry, 0, 1, 1, 2,
		    GTK_FILL, 0, 0, 0);
  fontsel->font_style_entry = gtk_entry_new();
  gtk_entry_set_editable(GTK_ENTRY(fontsel->font_style_entry), FALSE);
  gtk_widget_set_usize (fontsel->font_style_entry, 20, -1);
  gtk_widget_show (fontsel->font_style_entry);
  gtk_table_attach (GTK_TABLE (table), fontsel->font_style_entry, 1, 2, 1, 2,
		    GTK_FILL, 0, 0, 0);
  fontsel->size_entry = gtk_entry_new();
  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);
  gtk_signal_connect (GTK_OBJECT (fontsel->size_entry), "key_press_event",
		      (GtkSignalFunc) gtk_font_selection_size_key_press,
		      fontsel);
527
  
Owen Taylor's avatar
Owen Taylor committed
528 529 530
  /* Create the clists  */
  fontsel->font_clist = gtk_clist_new(1);
  gtk_clist_column_titles_hide (GTK_CLIST(fontsel->font_clist));
Damon Chaplin's avatar
""  
Damon Chaplin committed
531
  gtk_clist_set_column_auto_resize (GTK_CLIST (fontsel->font_clist), 0, TRUE);
532
  scrolled_win = gtk_scrolled_window_new (NULL, NULL);
Damon Chaplin's avatar
""  
Damon Chaplin committed
533
  gtk_widget_set_usize (scrolled_win, FONT_LIST_WIDTH, FONT_LIST_HEIGHT);
534 535 536
  gtk_container_add (GTK_CONTAINER (scrolled_win), fontsel->font_clist);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
				  GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
Owen Taylor's avatar
Owen Taylor committed
537
  gtk_widget_show(fontsel->font_clist);
538 539 540
  gtk_widget_show(scrolled_win);

  gtk_table_attach (GTK_TABLE (table), scrolled_win, 0, 1, 2, 3,
Owen Taylor's avatar
Owen Taylor committed
541 542
		    GTK_EXPAND | GTK_FILL,
		    GTK_EXPAND | GTK_FILL, 0, 0);
543
  
Owen Taylor's avatar
Owen Taylor committed
544 545
  fontsel->font_style_clist = gtk_clist_new(1);
  gtk_clist_column_titles_hide (GTK_CLIST(fontsel->font_style_clist));
Damon Chaplin's avatar
""  
Damon Chaplin committed
546 547
  gtk_clist_set_column_auto_resize (GTK_CLIST (fontsel->font_style_clist),
				    0, TRUE);
548
  scrolled_win = gtk_scrolled_window_new (NULL, NULL);
Damon Chaplin's avatar
""  
Damon Chaplin committed
549
  gtk_widget_set_usize (scrolled_win, FONT_STYLE_LIST_WIDTH, -1);
550 551 552
  gtk_container_add (GTK_CONTAINER (scrolled_win), fontsel->font_style_clist);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
				  GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
Owen Taylor's avatar
Owen Taylor committed
553
  gtk_widget_show(fontsel->font_style_clist);
554 555
  gtk_widget_show(scrolled_win);
  gtk_table_attach (GTK_TABLE (table), scrolled_win, 1, 2, 2, 3,
Owen Taylor's avatar
Owen Taylor committed
556 557
		    GTK_EXPAND | GTK_FILL,
		    GTK_EXPAND | GTK_FILL, 0, 0);
558
  
Owen Taylor's avatar
Owen Taylor committed
559 560
  fontsel->size_clist = gtk_clist_new(1);
  gtk_clist_column_titles_hide (GTK_CLIST(fontsel->size_clist));
Damon Chaplin's avatar
""  
Damon Chaplin committed
561
  gtk_clist_set_column_width (GTK_CLIST(fontsel->size_clist), 0, 20);
562
  scrolled_win = gtk_scrolled_window_new (NULL, NULL);
Damon Chaplin's avatar
""  
Damon Chaplin committed
563
  gtk_widget_set_usize (scrolled_win, FONT_SIZE_LIST_WIDTH, -1);
564 565 566
  gtk_container_add (GTK_CONTAINER (scrolled_win), fontsel->size_clist);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
				  GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
Owen Taylor's avatar
Owen Taylor committed
567
  gtk_widget_show(fontsel->size_clist);
568 569
  gtk_widget_show(scrolled_win);
  gtk_table_attach (GTK_TABLE (table), scrolled_win, 2, 3, 2, 3,
Owen Taylor's avatar
Owen Taylor committed
570
		    GTK_FILL, GTK_FILL, 0, 0);
571 572
  
  
Owen Taylor's avatar
Owen Taylor committed
573 574
  /* Insert the fonts. If there exist fonts with the same family but
     different foundries, then the foundry name is appended in brackets. */
575
  gtk_font_selection_show_available_fonts(fontsel);
576
  
Owen Taylor's avatar
Owen Taylor committed
577 578 579 580 581 582 583 584 585 586
  gtk_signal_connect (GTK_OBJECT (fontsel->font_clist), "select_row",
		      GTK_SIGNAL_FUNC(gtk_font_selection_select_font),
		      fontsel);
  GTK_WIDGET_SET_FLAGS (fontsel->font_clist, GTK_CAN_FOCUS);
  gtk_signal_connect (GTK_OBJECT (fontsel->font_clist), "key_press_event",
		      GTK_SIGNAL_FUNC(gtk_font_selection_on_clist_key_press),
		      fontsel);
  gtk_signal_connect_after (GTK_OBJECT (fontsel->font_clist), "expose_event",
			    GTK_SIGNAL_FUNC(gtk_font_selection_expose_list),
			    fontsel);
587
  
Owen Taylor's avatar
Owen Taylor committed
588 589 590 591 592 593 594 595
  gtk_signal_connect (GTK_OBJECT (fontsel->font_style_clist), "select_row",
		      GTK_SIGNAL_FUNC(gtk_font_selection_select_style),
		      fontsel);
  GTK_WIDGET_SET_FLAGS (fontsel->font_style_clist, GTK_CAN_FOCUS);
  gtk_signal_connect (GTK_OBJECT (fontsel->font_style_clist),
		      "key_press_event",
		      GTK_SIGNAL_FUNC(gtk_font_selection_on_clist_key_press),
		      fontsel);
Damon Chaplin's avatar
""  
Damon Chaplin committed
596 597 598 599
  gtk_signal_connect_after (GTK_OBJECT (fontsel->font_style_clist),
			    "realize",
			    GTK_SIGNAL_FUNC(gtk_font_selection_realize_list),
			    fontsel);
600
  
Owen Taylor's avatar
Owen Taylor committed
601 602 603
  /* Insert the standard font sizes */
  gtk_clist_freeze (GTK_CLIST(fontsel->size_clist));
  size_to_match = INITIAL_FONT_SIZE;
604
  if (INITIAL_METRIC == GTK_FONT_METRIC_POINTS)
Owen Taylor's avatar
Owen Taylor committed
605 606 607 608 609 610 611 612 613 614 615 616 617
    size_to_match = size_to_match / 10;
  for (i = 0; i < sizeof(font_sizes) / sizeof(font_sizes[0]); i++)
    {
      sprintf(buffer, "%i", font_sizes[i]);
      size = buffer;
      gtk_clist_append(GTK_CLIST(fontsel->size_clist), &size);
      if (font_sizes[i] == size_to_match)
	{
	  gtk_clist_select_row(GTK_CLIST(fontsel->size_clist), i, 0);
	  gtk_entry_set_text(GTK_ENTRY(fontsel->size_entry), buffer);
	}
    }
  gtk_clist_thaw (GTK_CLIST(fontsel->size_clist));
618
  
Owen Taylor's avatar
Owen Taylor committed
619 620 621 622 623 624 625
  gtk_signal_connect (GTK_OBJECT (fontsel->size_clist), "select_row",
		      GTK_SIGNAL_FUNC(gtk_font_selection_select_size),
		      fontsel);
  GTK_WIDGET_SET_FLAGS (fontsel->size_clist, GTK_CAN_FOCUS);
  gtk_signal_connect (GTK_OBJECT (fontsel->size_clist), "key_press_event",
		      GTK_SIGNAL_FUNC(gtk_font_selection_on_clist_key_press),
		      fontsel);
626 627
  
  
628
  /* create the Reset Filter & Metric buttons */
Owen Taylor's avatar
Owen Taylor committed
629 630 631
  hbox = gtk_hbox_new(FALSE, 8);
  gtk_widget_show (hbox);
  gtk_box_pack_start (GTK_BOX (fontsel->main_vbox), hbox, FALSE, TRUE, 0);
632
  
633
  fontsel->filter_button = gtk_button_new_with_label(_("Reset Filter"));
Damon Chaplin's avatar
""  
Damon Chaplin committed
634 635
  gtk_misc_set_padding (GTK_MISC (GTK_BIN (fontsel->filter_button)->child),
			16, 0);
Owen Taylor's avatar
Owen Taylor committed
636 637 638 639
  gtk_widget_show(fontsel->filter_button);
  gtk_box_pack_start (GTK_BOX (hbox), fontsel->filter_button, FALSE, FALSE, 0);
  gtk_widget_set_sensitive (fontsel->filter_button, FALSE);
  gtk_signal_connect (GTK_OBJECT (fontsel->filter_button), "clicked",
640
		      GTK_SIGNAL_FUNC(gtk_font_selection_on_clear_filter),
Owen Taylor's avatar
Owen Taylor committed
641
		      fontsel);
642
  
Owen Taylor's avatar
Owen Taylor committed
643 644 645 646
  hbox2 = gtk_hbox_new(FALSE, 0);
  gtk_widget_show (hbox2);
  gtk_box_pack_end (GTK_BOX (hbox), hbox2, FALSE, FALSE, 0);
  
647
  label = gtk_label_new(_("Metric:"));
Owen Taylor's avatar
Owen Taylor committed
648 649
  gtk_widget_show (label);
  gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 8);
650
  
651
  fontsel->points_button = gtk_radio_button_new_with_label(NULL, _("Points"));
Owen Taylor's avatar
Owen Taylor committed
652 653
  gtk_widget_show (fontsel->points_button);
  gtk_box_pack_start (GTK_BOX (hbox2), fontsel->points_button, FALSE, TRUE, 0);
654
  if (INITIAL_METRIC == GTK_FONT_METRIC_POINTS)
Owen Taylor's avatar
Owen Taylor committed
655 656
    gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(fontsel->points_button),
				TRUE);
657
  
658
  fontsel->pixels_button = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(fontsel->points_button), _("Pixels"));
Owen Taylor's avatar
Owen Taylor committed
659 660
  gtk_widget_show (fontsel->pixels_button);
  gtk_box_pack_start (GTK_BOX (hbox2), fontsel->pixels_button, FALSE, TRUE, 0);
661
  if (INITIAL_METRIC == GTK_FONT_METRIC_PIXELS)
Owen Taylor's avatar
Owen Taylor committed
662 663
    gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(fontsel->pixels_button),
				TRUE);
664
  
Owen Taylor's avatar
Owen Taylor committed
665 666 667 668 669 670
  gtk_signal_connect(GTK_OBJECT(fontsel->points_button), "toggled",
		     (GtkSignalFunc) gtk_font_selection_metric_callback,
		     fontsel);
  gtk_signal_connect(GTK_OBJECT(fontsel->pixels_button), "toggled",
		     (GtkSignalFunc) gtk_font_selection_metric_callback,
		     fontsel);
671 672
  
  
Owen Taylor's avatar
Owen Taylor committed
673
  /* create the text entry widget */
674
  text_frame = gtk_frame_new (_("Preview:"));
Owen Taylor's avatar
Owen Taylor committed
675 676 677 678
  gtk_widget_show (text_frame);
  gtk_frame_set_shadow_type(GTK_FRAME(text_frame), GTK_SHADOW_ETCHED_IN);
  gtk_box_pack_start (GTK_BOX (fontsel->main_vbox), text_frame,
		      FALSE, TRUE, 0);
679
  
Owen Taylor's avatar
Owen Taylor committed
680 681 682 683
  /* 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);
684
  gtk_container_set_border_width (GTK_CONTAINER (text_box), 4);
685
  
Owen Taylor's avatar
Owen Taylor committed
686 687 688 689 690
  fontsel->preview_entry = gtk_entry_new ();
  gtk_widget_show (fontsel->preview_entry);
  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);
691
  
Owen Taylor's avatar
Owen Taylor committed
692 693 694 695 696
  /* Create the message area */
  fontsel->message_label = gtk_label_new("");
  gtk_widget_show (fontsel->message_label);
  gtk_box_pack_start (GTK_BOX (fontsel->main_vbox), fontsel->message_label, 
		      FALSE, FALSE, 0);
697 698
  
  
Owen Taylor's avatar
Owen Taylor committed
699 700 701
  /* Create the font info page */
  fontsel->info_vbox = gtk_vbox_new (FALSE, 4);
  gtk_widget_show (fontsel->info_vbox);
702
  gtk_container_set_border_width (GTK_CONTAINER (fontsel->info_vbox), 2);
703
  label = gtk_label_new(_("Font Information"));
Owen Taylor's avatar
Owen Taylor committed
704 705
  gtk_notebook_append_page (GTK_NOTEBOOK (fontsel),
			    fontsel->info_vbox, label);
706
  
707
  fontsel->info_clist = gtk_clist_new_with_titles (3, titles);
Owen Taylor's avatar
Owen Taylor committed
708 709 710 711 712
  gtk_widget_set_usize (fontsel->info_clist, 390, 150);
  gtk_clist_set_column_width(GTK_CLIST(fontsel->info_clist), 0, 130);
  gtk_clist_set_column_width(GTK_CLIST(fontsel->info_clist), 1, 130);
  gtk_clist_set_column_width(GTK_CLIST(fontsel->info_clist), 2, 130);
  gtk_clist_column_titles_passive(GTK_CLIST(fontsel->info_clist));
713 714 715 716
  scrolled_win = gtk_scrolled_window_new (NULL, NULL);
  gtk_container_add (GTK_CONTAINER (scrolled_win), fontsel->info_clist);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
				  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
Owen Taylor's avatar
Owen Taylor committed
717
  gtk_widget_show(fontsel->info_clist);
718 719
  gtk_widget_show(scrolled_win);
  gtk_box_pack_start (GTK_BOX (fontsel->info_vbox), scrolled_win,
Owen Taylor's avatar
Owen Taylor committed
720
		      TRUE, TRUE, 0);
721
  
Owen Taylor's avatar
Owen Taylor committed
722 723 724 725 726 727
  /* Insert the property names */
  gtk_clist_freeze (GTK_CLIST(fontsel->info_clist));
  row_text[1] = "";
  row_text[2] = "";
  for (i = 0; i < GTK_XLFD_NUM_FIELDS; i++)
    {
728
      row_text[0] = gettext(xlfd_field_names[i]);
Owen Taylor's avatar
Owen Taylor committed
729 730 731 732 733 734
      gtk_clist_append(GTK_CLIST(fontsel->info_clist), row_text);
      gtk_clist_set_shift(GTK_CLIST(fontsel->info_clist), i, 0, 0, 4);
      gtk_clist_set_shift(GTK_CLIST(fontsel->info_clist), i, 1, 0, 4);
      gtk_clist_set_shift(GTK_CLIST(fontsel->info_clist), i, 2, 0, 4);
    }
  gtk_clist_thaw (GTK_CLIST(fontsel->info_clist));
735
  
736
  label = gtk_label_new(_("Requested Font Name:"));
Owen Taylor's avatar
Owen Taylor committed
737 738 739
  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  gtk_widget_show (label);
  gtk_box_pack_start (GTK_BOX (fontsel->info_vbox), label, FALSE, TRUE, 0);
740
  
Owen Taylor's avatar
Owen Taylor committed
741 742 743 744 745
  fontsel->requested_font_name = gtk_entry_new();
  gtk_entry_set_editable(GTK_ENTRY(fontsel->requested_font_name), FALSE);
  gtk_widget_show (fontsel->requested_font_name);
  gtk_box_pack_start (GTK_BOX (fontsel->info_vbox),
		      fontsel->requested_font_name, FALSE, TRUE, 0);
746
  
747
  label = gtk_label_new(_("Actual Font Name:"));
Owen Taylor's avatar
Owen Taylor committed
748 749 750 751 752 753 754 755 756
  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  gtk_widget_show (label);
  gtk_box_pack_start (GTK_BOX (fontsel->info_vbox), label, FALSE, TRUE, 0);
  
  fontsel->actual_font_name = gtk_entry_new();
  gtk_entry_set_editable(GTK_ENTRY(fontsel->actual_font_name), FALSE);
  gtk_widget_show (fontsel->actual_font_name);
  gtk_box_pack_start (GTK_BOX (fontsel->info_vbox),
		      fontsel->actual_font_name, FALSE, TRUE, 0);
757
  
758
  sprintf(buffer, _("%i fonts available with a total of %i styles."),
759
	  fontsel_info->nfonts, fontsel_info->nstyles);
Owen Taylor's avatar
Owen Taylor committed
760 761 762
  label = gtk_label_new(buffer);
  gtk_widget_show (label);
  gtk_box_pack_start (GTK_BOX (fontsel->info_vbox), label, FALSE, FALSE, 0);
763
  
Owen Taylor's avatar
Owen Taylor committed
764 765 766
  gtk_signal_connect (GTK_OBJECT (fontsel), "switch_page",
		      GTK_SIGNAL_FUNC(gtk_font_selection_switch_page),
		      fontsel);
767 768
  
  
Owen Taylor's avatar
Owen Taylor committed
769 770 771
  /* Create the Filter page. */
  fontsel->filter_vbox = gtk_vbox_new (FALSE, 4);
  gtk_widget_show (fontsel->filter_vbox);
772
  gtk_container_set_border_width (GTK_CONTAINER (fontsel->filter_vbox), 2);
773
  label = gtk_label_new(_("Filter"));
Owen Taylor's avatar
Owen Taylor committed
774 775
  gtk_notebook_append_page (GTK_NOTEBOOK (fontsel),
			    fontsel->filter_vbox, label);
776
  
777 778 779 780 781 782 783 784 785
  /* Create the font type checkbuttons. */
  frame = gtk_frame_new (NULL);
  gtk_widget_show (frame);
  gtk_box_pack_start (GTK_BOX (fontsel->filter_vbox), frame, FALSE, TRUE, 0);

  hbox = gtk_hbox_new (FALSE, 20);
  gtk_widget_show (hbox);
  gtk_container_add (GTK_CONTAINER (frame), hbox);

786
  label = gtk_label_new(_("Font Types:"));
787 788 789 790 791 792 793
  gtk_widget_show (label);
  gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 10);

  hbox2 = gtk_hbox_new (TRUE, 0);
  gtk_widget_show (hbox2);
  gtk_box_pack_start (GTK_BOX (hbox), hbox2, FALSE, TRUE, 0);

794
  fontsel->type_bitmaps_button = gtk_check_button_new_with_label (_("Bitmap"));
795 796 797 798 799
  gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (fontsel->type_bitmaps_button), TRUE);
  gtk_widget_show (fontsel->type_bitmaps_button);
  gtk_box_pack_start (GTK_BOX (hbox2), fontsel->type_bitmaps_button,
		      FALSE, TRUE, 0);

800
  fontsel->type_scalable_button = gtk_check_button_new_with_label (_("Scalable"));
801 802 803 804 805
  gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (fontsel->type_scalable_button), TRUE);
  gtk_widget_show (fontsel->type_scalable_button);
  gtk_box_pack_start (GTK_BOX (hbox2), fontsel->type_scalable_button,
		      FALSE, TRUE, 0);

806
  fontsel->type_scaled_bitmaps_button = gtk_check_button_new_with_label (_("Scaled Bitmap"));
807 808 809 810
  gtk_widget_show (fontsel->type_scaled_bitmaps_button);
  gtk_box_pack_start (GTK_BOX (hbox2), fontsel->type_scaled_bitmaps_button,
		      FALSE, TRUE, 0);

Owen Taylor's avatar
Owen Taylor committed
811 812 813 814
  table = gtk_table_new (4, 3, FALSE);
  gtk_table_set_col_spacings(GTK_TABLE(table), 2);
  gtk_widget_show (table);
  gtk_box_pack_start (GTK_BOX (fontsel->filter_vbox), table, TRUE, TRUE, 0);
815
  
Owen Taylor's avatar
Owen Taylor committed
816 817 818 819
  for (prop = 0; prop < GTK_NUM_FONT_PROPERTIES; prop++)
    {
      gint left = filter_positions[prop][0];
      gint top = filter_positions[prop][1];
820
      
821
      label = gtk_label_new(gettext(xlfd_field_names[xlfd_index[prop]]));
Owen Taylor's avatar
Owen Taylor committed
822 823 824 825 826
      gtk_misc_set_alignment (GTK_MISC (label), 0.0, 1.0);
      gtk_misc_set_padding (GTK_MISC (label), 0, 2);
      gtk_widget_show(label);
      gtk_table_attach (GTK_TABLE (table), label, left, left + 1,
			top, top + 1, GTK_FILL, GTK_FILL, 0, 0);
827
      
Owen Taylor's avatar
Owen Taylor committed
828 829 830 831
      clist = gtk_clist_new(1);
      gtk_widget_set_usize (clist, 100, filter_heights[prop]);
      gtk_clist_set_selection_mode(GTK_CLIST(clist), GTK_SELECTION_MULTIPLE);
      gtk_clist_column_titles_hide(GTK_CLIST(clist));
Damon Chaplin's avatar
""  
Damon Chaplin committed
832
      gtk_clist_set_column_auto_resize (GTK_CLIST (clist), 0, TRUE);
833 834 835 836 837
      scrolled_win = gtk_scrolled_window_new (NULL, NULL);
      gtk_container_add (GTK_CONTAINER (scrolled_win), clist);
      gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
				      GTK_POLICY_AUTOMATIC,
				      GTK_POLICY_AUTOMATIC);
Owen Taylor's avatar
Owen Taylor committed
838
      gtk_widget_show(clist);
839
      gtk_widget_show(scrolled_win);
840
      
841
      /* For the bottom-right cell we add the 'Reset Filter' button. */
Owen Taylor's avatar
Owen Taylor committed
842 843 844 845 846 847
      if (top == 2 && left == 2)
	{
	  vbox = gtk_vbox_new(FALSE, 0);
	  gtk_widget_show(vbox);
	  gtk_table_attach (GTK_TABLE (table), vbox, left, left + 1,
			    top + 1, top + 2, GTK_FILL, GTK_FILL, 0, 0);
848
	  
849
	  gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
850
	  
Owen Taylor's avatar
Owen Taylor committed
851 852 853
	  alignment = gtk_alignment_new(0.5, 0.0, 0.8, 0.0);
	  gtk_widget_show(alignment);
	  gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, TRUE, 4);
854
	  
855
	  button = gtk_button_new_with_label(_("Reset Filter"));
Owen Taylor's avatar
Owen Taylor committed
856 857 858 859 860 861 862
	  gtk_widget_show(button);
	  gtk_container_add(GTK_CONTAINER(alignment), button);
	  gtk_signal_connect (GTK_OBJECT (button), "clicked",
			      GTK_SIGNAL_FUNC(gtk_font_selection_reset_filter),
			      fontsel);
	}
      else
863
	gtk_table_attach (GTK_TABLE (table), scrolled_win,
Owen Taylor's avatar
Owen Taylor committed
864 865
			  left, left + 1, top + 1, top + 2,
			  GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
866
      
Owen Taylor's avatar
Owen Taylor committed
867 868 869 870 871 872
      gtk_signal_connect (GTK_OBJECT (clist), "select_row",
			  GTK_SIGNAL_FUNC(gtk_font_selection_select_filter),
			  fontsel);
      gtk_signal_connect (GTK_OBJECT (clist), "unselect_row",
			  GTK_SIGNAL_FUNC(gtk_font_selection_unselect_filter),
			  fontsel);
873
      
Owen Taylor's avatar
Owen Taylor committed
874 875 876 877 878
      /* Insert the property names, expanded, and in sorted order.
	 But we make sure that the wildcard '*' is first. */
      gtk_clist_freeze (GTK_CLIST(clist));
      property = "*";
      gtk_clist_append(GTK_CLIST(clist), &property);
879
      
880 881
      for (i = 1; i < fontsel_info->nproperties[prop]; i++) {
	property = fontsel_info->properties[prop][i];
Owen Taylor's avatar
Owen Taylor committed
882 883 884 885
	if (prop == SLANT)
	  property = gtk_font_selection_expand_slant_code(property);
	else if (prop == SPACING)
	  property = gtk_font_selection_expand_spacing_code(property);
886
	
Owen Taylor's avatar
Owen Taylor committed
887 888 889 890 891 892 893 894 895 896 897 898 899
	inserted = FALSE;
	for (row = 1; row < GTK_CLIST(clist)->rows; row++)
	  {
	    gtk_clist_get_text(GTK_CLIST(clist), row, 0, &text);
	    if (strcmp(property, text) < 0)
	      {
		inserted = TRUE;
		gtk_clist_insert(GTK_CLIST(clist), row, &property);
		break;
	      }
	  }
	if (!inserted)
	  row = gtk_clist_append(GTK_CLIST(clist), &property);
900
	gtk_clist_set_row_data(GTK_CLIST(clist), row, GINT_TO_POINTER (i));
Owen Taylor's avatar
Owen Taylor committed
901 902 903 904 905 906 907 908 909 910 911
      }
      gtk_clist_select_row(GTK_CLIST(clist), 0, 0);
      gtk_clist_thaw (GTK_CLIST(clist));
      fontsel->filter_clists[prop] = clist;
    }
}

GtkWidget *
gtk_font_selection_new()
{
  GtkFontSelection *fontsel;
912
  
Tim Janik's avatar
Tim Janik committed
913
  fontsel = gtk_type_new (GTK_TYPE_FONT_SELECTION);
914
  
Owen Taylor's avatar
Owen Taylor committed
915 916 917 918 919 920 921
  return GTK_WIDGET (fontsel);
}

static void
gtk_font_selection_destroy (GtkObject *object)
{
  GtkFontSelection *fontsel;
922
  
Owen Taylor's avatar
Owen Taylor committed
923 924
  g_return_if_fail (object != NULL);
  g_return_if_fail (GTK_IS_FONT_SELECTION (object));
925
  
Owen Taylor's avatar
Owen Taylor committed
926
  fontsel = GTK_FONT_SELECTION (object);
927
  
Owen Taylor's avatar
Owen Taylor committed
928 929 930
  /* All we have to do is unref the font, if we have one. */
  if (fontsel->font)
    gdk_font_unref (fontsel->font);
931
  
Owen Taylor's avatar
Owen Taylor committed
932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947
  if (GTK_OBJECT_CLASS (font_selection_parent_class)->destroy)
    (* GTK_OBJECT_CLASS (font_selection_parent_class)->destroy) (object);
}


/* This is called when the clist is exposed. Here we scroll to the current
   font if necessary. */
static void
gtk_font_selection_expose_list (GtkWidget		*widget,
				GdkEventExpose		*event,
				gpointer		 data)
{
  GtkFontSelection *fontsel;
  FontInfo *font_info;
  GList *selection;
  gint index;
948
  
Owen Taylor's avatar
Owen Taylor committed
949
#ifdef FONTSEL_DEBUG
950
  g_message("In expose_list\n");
Owen Taylor's avatar
Owen Taylor committed
951 952
#endif
  fontsel = GTK_FONT_SELECTION(data);
953
  
954
  font_info = fontsel_info->font_info;
955
      
956 957 958 959 960 961 962 963 964
  /* Try to scroll the font family clist to the selected item */
  selection = GTK_CLIST(fontsel->font_clist)->selection;
  if (selection)
    {
      index = GPOINTER_TO_INT (selection->data);
      if (gtk_clist_row_is_visible(GTK_CLIST(fontsel->font_clist), index)
	  != GTK_VISIBILITY_FULL)
	gtk_clist_moveto(GTK_CLIST(fontsel->font_clist), index, -1, 0.5, 0);
    }
965
      
966 967 968 969 970 971 972 973 974 975
  /* Try to scroll the font style clist to the selected item */
  selection = GTK_CLIST(fontsel->font_style_clist)->selection;
  if (selection)
    {
      index = GPOINTER_TO_INT (selection->data);
      if (gtk_clist_row_is_visible(GTK_CLIST(fontsel->font_style_clist), index)
	  != GTK_VISIBILITY_FULL)
	gtk_clist_moveto(GTK_CLIST(fontsel->font_style_clist), index, -1,
			 0.5, 0);
    }
976
      
977 978 979 980 981 982 983 984
  /* Try to scroll the font size clist to the selected item */
  selection = GTK_CLIST(fontsel->size_clist)->selection;
  if (selection)
    {
      index = GPOINTER_TO_INT (selection->data);
      if (gtk_clist_row_is_visible(GTK_CLIST(fontsel->size_clist), index)
	  != GTK_VISIBILITY_FULL)
      gtk_clist_moveto(GTK_CLIST(fontsel->size_clist), index, -1, 0.5, 0);
Owen Taylor's avatar
Owen Taylor committed
985 986 987 988
    }
}


Damon Chaplin's avatar
""  
Damon Chaplin committed
989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020
/* This is called when the style clist is realized. We need to set any
   charset rows to insensitive colours. */
static void
gtk_font_selection_realize_list (GtkWidget		*widget,
				 gpointer		 data)
{
  GtkFontSelection *fontsel;
  gint row;
  GdkColor *inactive_fg, *inactive_bg;

#ifdef FONTSEL_DEBUG
  g_message("In realize_list\n");
#endif
  fontsel = GTK_FONT_SELECTION (data);

  /* Set the colours for any charset rows to insensitive. */
  inactive_fg = &fontsel->font_style_clist->style->fg[GTK_STATE_INSENSITIVE];
  inactive_bg = &fontsel->font_style_clist->style->bg[GTK_STATE_INSENSITIVE];

  for (row = 0; row < GTK_CLIST (fontsel->font_style_clist)->rows; row++)
    {
      if (GPOINTER_TO_INT (gtk_clist_get_row_data (GTK_CLIST (fontsel->font_style_clist), row)) == -1)
	{
	  gtk_clist_set_foreground (GTK_CLIST (fontsel->font_style_clist),
				    row, inactive_fg);
	  gtk_clist_set_background (GTK_CLIST (fontsel->font_style_clist),
				    row, inactive_bg);
	}
    }
}


Owen Taylor's avatar
Owen Taylor committed
1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031
/* This is called when a family is selected in the list. */
static void
gtk_font_selection_select_font (GtkWidget      *w,
				gint	        row,
				gint	        column,
				GdkEventButton *bevent,
				gpointer        data)
{
  GtkFontSelection *fontsel;
  FontInfo *font_info;
  FontInfo *font;
1032
  
Owen Taylor's avatar
Owen Taylor committed
1033
#ifdef FONTSEL_DEBUG
1034
  g_message("In select_font\n");
Owen Taylor's avatar
Owen Taylor committed
1035 1036
#endif
  fontsel = GTK_FONT_SELECTION(data);
1037
  font_info = fontsel_info->font_info;
1038
  
Owen Taylor's avatar
Owen Taylor committed
1039 1040
  if (bevent && !GTK_WIDGET_HAS_FOCUS (w))
    gtk_widget_grab_focus (w);
1041
  
1042
  row = GPOINTER_TO_INT (gtk_clist_get_row_data (GTK_CLIST (fontsel->font_clist), row));
Owen Taylor's avatar
Owen Taylor committed
1043 1044
  font = &font_info[row];
  gtk_entry_set_text(GTK_ENTRY(fontsel->font_entry), font->family);
1045
  
Owen Taylor's avatar
Owen Taylor committed
1046 1047 1048
  /* If it is already the current font, just return. */
  if (fontsel->font_index == row)
    return;
1049
  
Owen Taylor's avatar
Owen Taylor committed
1050 1051
  fontsel->font_index = row;
  gtk_font_selection_show_available_styles (fontsel);
1052
  gtk_font_selection_select_best_style (fontsel, TRUE);
Owen Taylor's avatar
Owen Taylor committed
1053 1054 1055 1056 1057 1058 1059 1060 1061
}


static gint
gtk_font_selection_on_clist_key_press (GtkWidget        *clist,
				       GdkEventKey      *event,
				       GtkFontSelection *fontsel)
{
#ifdef FONTSEL_DEBUG
1062
  g_message("In on_clist_key_press\n");
Owen Taylor's avatar
Owen Taylor committed
1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079
#endif
  if (event->keyval == GDK_Up)
    return gtk_font_selection_select_next (fontsel, clist, -1);
  else if (event->keyval == GDK_Down)
    return gtk_font_selection_select_next (fontsel, clist, 1);
  else
    return FALSE;
}


static gboolean
gtk_font_selection_select_next (GtkFontSelection *fontsel,
				GtkWidget        *clist,
				gint		  step)
{
  GList *selection;
  gint current_row, row;
1080
  
Owen Taylor's avatar
Owen Taylor committed
1081 1082 1083
  selection = GTK_CLIST(clist)->selection;
  if (!selection)
    return FALSE;
1084
  current_row = GPOINTER_TO_INT (selection->data);
1085
  
1086 1087 1088
  /* Stop the normal clist key handler from being run. */
  gtk_signal_emit_stop_by_name (GTK_OBJECT (clist), "key_press_event");

Owen Taylor's avatar
Owen Taylor committed
1089 1090 1091 1092 1093 1094 1095
  for (row = current_row + step;
       row >= 0 && row < GTK_CLIST(clist)->rows;
       row += step)
    {
      /* If this is the style clist, make sure that the item is not a charset
	 entry. */
      if (clist == fontsel->font_style_clist)
1096
	if (GPOINTER_TO_INT (gtk_clist_get_row_data(GTK_CLIST(clist), row)) == -1)
Owen Taylor's avatar
Owen Taylor committed
1097
	  continue;
1098
      
Owen Taylor's avatar
Owen Taylor committed
1099 1100 1101 1102 1103
      /* Now we've found the row to select. */
      if (gtk_clist_row_is_visible(GTK_CLIST(clist), row)
	  != GTK_VISIBILITY_FULL)
	gtk_clist_moveto(GTK_CLIST(clist), row, -1, (step < 0) ? 0 : 1, 0);
      gtk_clist_select_row(GTK_CLIST(clist), row, 0);
1104
      break;
Owen Taylor's avatar
Owen Taylor committed
1105
    }
1106
  return TRUE;
Owen Taylor's avatar
Owen Taylor committed
1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119