gtkfontsel.c 120 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
/* 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.
 */

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

Owen Taylor's avatar
Owen Taylor committed
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
/*
 * 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
55
 *		   first, then bold, bold italic etc.
Owen Taylor's avatar
Owen Taylor committed
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
 *
 *  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>

72
#include "gdk/gdk.h"
73
/* Protect against the CHARSET struct in Win32 */
74
#ifdef GDK_WINDOWING_WIN32
75 76
# define CHARSET CHARSETstruct
#endif
77
#include "gdkx.h"
78
#ifdef GDK_WINDOWING_WIN32
79 80
# undef CHARSET
#endif
Owen Taylor's avatar
Owen Taylor committed
81 82 83
#include "gdk/gdkkeysyms.h"

#include "gtkbutton.h"
84
#include "gtkcheckbutton.h"
Owen Taylor's avatar
Owen Taylor committed
85 86 87 88 89 90 91 92 93 94 95 96
#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"
97
#include "gtkscrolledwindow.h"
98
#include "gtkintl.h"
Owen Taylor's avatar
Owen Taylor committed
99 100 101 102 103 104 105 106 107 108 109

/* 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). */
110
static const guint16 font_sizes[] = {
Owen Taylor's avatar
Owen Taylor committed
111 112 113 114 115 116
  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. */
117
#define INITIAL_METRIC		  GTK_FONT_METRIC_POINTS
Owen Taylor's avatar
Owen Taylor committed
118 119 120 121 122 123 124 125 126 127 128 129 130
#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
131 132
#define FONT_LIST_WIDTH		190
#define FONT_STYLE_LIST_WIDTH	170
Owen Taylor's avatar
Owen Taylor committed
133 134 135 136 137 138
#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

139 140 141 142 143 144 145 146 147 148 149 150 151 152
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;
};
153

154 155
/* 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
156 157 158 159 160
   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)
161 162 163 164 165 166 167 168 169 170 171
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 {
172
  
173 174 175
  /* This is a table with each FontInfo representing one font family+foundry */
  FontInfo *font_info;
  gint nfonts;
176
  
177 178 179 180
  /* 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;
181
  
182 183 184 185
  /* This stores all the font sizes available for every style.
     Each style holds an index into these arrays. */
  guint16 *pixel_sizes;
  guint16 *point_sizes;
186
  
187 188 189
  /* 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. */
190 191 192 193 194
  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
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
/* 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. */
215
static const gchar* xlfd_field_names[GTK_XLFD_NUM_FIELDS] = {
216 217 218 219 220 221 222 223 224 225 226 227 228
  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
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244
};

/* 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. */
245
static const FontField xlfd_index[GTK_NUM_FONT_PROPERTIES] = {
Owen Taylor's avatar
Owen Taylor committed
246 247 248 249 250 251 252 253 254
  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. */
255
static const gint filter_positions[GTK_NUM_FONT_PROPERTIES][2] = {
Owen Taylor's avatar
Owen Taylor committed
256 257
  { 1, 0 }, { 0, 2 }, { 1, 2 }, { 2, 2 }, { 2, 0 }, { 0, 0 }
};
258
static const gint filter_heights[GTK_NUM_FONT_PROPERTIES] = {
259
  100, 70, 70, 40, 100, 100
Owen Taylor's avatar
Owen Taylor committed
260 261
};

262 263 264 265 266 267 268 269 270 271 272
/* 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;

273 274
static GtkFontSelInfo *fontsel_info = NULL;

Owen Taylor's avatar
Owen Taylor committed
275 276 277 278 279 280 281 282
/* 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. */
283 284
static void    gtk_font_selection_get_fonts          (void);
static void    gtk_font_selection_insert_font        (GSList         *fontnames[],
Owen Taylor's avatar
Owen Taylor committed
285 286
						      gint           *ntable,
						      gchar          *fontname);
287
static gint    gtk_font_selection_insert_field       (gchar          *fontname,
Owen Taylor's avatar
Owen Taylor committed
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302
						      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
303
(GtkFontSelection *fs);
304 305
static void    gtk_font_selection_select_best_style  (GtkFontSelection *fs,
						      gboolean	       use_first);
Owen Taylor's avatar
Owen Taylor committed
306 307 308 309 310 311 312

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
313
(GtkFontSelection *fs);
Owen Taylor's avatar
Owen Taylor committed
314 315 316 317 318 319 320 321 322 323 324 325 326 327 328
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
329 330
static void    gtk_font_selection_realize_list	     (GtkWidget	     *widget,
						      gpointer	      data);
Owen Taylor's avatar
Owen Taylor committed
331 332 333 334 335 336 337 338 339 340 341

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,
342
						      GtkFontSelection *fs);
Owen Taylor's avatar
Owen Taylor committed
343 344 345 346
static void    gtk_font_selection_unselect_filter    (GtkWidget      *w,
						      gint	      row,
						      gint	      column,
						      GdkEventButton *bevent,
347 348
						      GtkFontSelection *fs);
static void    gtk_font_selection_update_filter	     (GtkFontSelection *fs);
Owen Taylor's avatar
Owen Taylor committed
349 350 351 352
static gboolean gtk_font_selection_style_visible     (GtkFontSelection *fs,
						      FontInfo       *font,
						      gint	      style);
static void    gtk_font_selection_reset_filter	     (GtkWidget      *w,
353
						      GtkFontSelection *fs);
354
static void    gtk_font_selection_on_clear_filter    (GtkWidget      *w,
355 356 357
						      GtkFontSelection *fs);
static void    gtk_font_selection_show_available_fonts
						     (GtkFontSelection *fs);
Owen Taylor's avatar
Owen Taylor committed
358
static void    gtk_font_selection_clear_filter       (GtkFontSelection *fs);
359 360 361 362 363 364
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
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 394 395 396 397 398 399 400 401 402 403

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

404
#ifdef GDK_WINDOWING_WIN32
405 406 407 408 409 410
static char *logfont_to_xlfd (const LOGFONT *lfp,
			      int size,
			      int res,
			      int avg_width);
#endif

Owen Taylor's avatar
Owen Taylor committed
411 412 413
static GtkWindowClass *font_selection_parent_class = NULL;
static GtkNotebookClass *font_selection_dialog_parent_class = NULL;

Tim Janik's avatar
Tim Janik committed
414
GtkType
Owen Taylor's avatar
Owen Taylor committed
415 416
gtk_font_selection_get_type()
{
Tim Janik's avatar
Tim Janik committed
417
  static GtkType font_selection_type = 0;
418
  
Owen Taylor's avatar
Owen Taylor committed
419 420
  if(!font_selection_type)
    {
421
      static const GtkTypeInfo fontsel_type_info =
Owen Taylor's avatar
Owen Taylor committed
422 423
      {
	"GtkFontSelection",
Tim Janik's avatar
Tim Janik committed
424 425
	sizeof (GtkFontSelection),
	sizeof (GtkFontSelectionClass),
Owen Taylor's avatar
Owen Taylor committed
426 427
	(GtkClassInitFunc) gtk_font_selection_class_init,
	(GtkObjectInitFunc) gtk_font_selection_init,
428 429
	/* reserved_1 */ NULL,
	/* reserved_2 */ NULL,
430
        (GtkClassInitFunc) NULL,
Owen Taylor's avatar
Owen Taylor committed
431
      };
432
      
Tim Janik's avatar
Tim Janik committed
433 434
      font_selection_type = gtk_type_unique (GTK_TYPE_NOTEBOOK,
					     &fontsel_type_info);
Owen Taylor's avatar
Owen Taylor committed
435
    }
436
  
Owen Taylor's avatar
Owen Taylor committed
437 438 439 440 441 442 443
  return font_selection_type;
}

static void
gtk_font_selection_class_init(GtkFontSelectionClass *klass)
{
  GtkObjectClass *object_class;
444
  
Owen Taylor's avatar
Owen Taylor committed
445
  object_class = (GtkObjectClass *) klass;
446
  
Tim Janik's avatar
Tim Janik committed
447
  font_selection_parent_class = gtk_type_class (GTK_TYPE_NOTEBOOK);
448
  
Owen Taylor's avatar
Owen Taylor committed
449
  object_class->destroy = gtk_font_selection_destroy;
450
  
451
  gtk_font_selection_get_fonts ();
Owen Taylor's avatar
Owen Taylor committed
452 453 454 455 456
}

static void
gtk_font_selection_init(GtkFontSelection *fontsel)
{
457
  GtkWidget *scrolled_win;
Owen Taylor's avatar
Owen Taylor committed
458
  GtkWidget *text_frame;
459
  GtkWidget *text_box, *frame;
Owen Taylor's avatar
Owen Taylor committed
460 461
  GtkWidget *table, *label, *hbox, *hbox2, *clist, *button, *vbox, *alignment;
  gint i, prop, row;
Jeff Garzik's avatar
Jeff Garzik committed
462
  gchar *titles[] = { NULL, NULL, NULL };
Owen Taylor's avatar
Owen Taylor committed
463 464 465
  gchar buffer[128];
  gchar *size;
  gint size_to_match;
466
  gchar *row_text[3];
Owen Taylor's avatar
Owen Taylor committed
467 468
  gchar *property, *text;
  gboolean inserted;
469
  
Jeff Garzik's avatar
Jeff Garzik committed
470 471 472 473 474 475
  /* Number of internationalized titles here must match number
     of NULL initializers above */
  titles[0] = _("Font Property");
  titles[1] = _("Requested Value");
  titles[2] = _("Actual Value");

Owen Taylor's avatar
Owen Taylor committed
476 477 478 479 480 481 482 483
  /* 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;
484 485 486 487 488

  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;

489
  
Owen Taylor's avatar
Owen Taylor committed
490 491
  for (prop = 0; prop < GTK_NUM_FONT_PROPERTIES; prop++)
    {
492 493 494 495
      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
496
    }
497
  
Owen Taylor's avatar
Owen Taylor committed
498
  for (prop = 0; prop < GTK_NUM_STYLE_PROPERTIES; prop++)
499 500
    fontsel->property_values[prop] = 0;
  
501
  /* Create the main notebook page. */
Damon Chaplin's avatar
""  
Damon Chaplin committed
502 503
  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
504 505
  fontsel->main_vbox = gtk_vbox_new (FALSE, 4);
  gtk_widget_show (fontsel->main_vbox);
506
  gtk_container_set_border_width (GTK_CONTAINER (fontsel->main_vbox), 6);
507
  label = gtk_label_new(_("Font"));
Owen Taylor's avatar
Owen Taylor committed
508 509
  gtk_notebook_append_page (GTK_NOTEBOOK (fontsel),
			    fontsel->main_vbox, label);
510
  
Owen Taylor's avatar
Owen Taylor committed
511 512 513 514 515
  /* 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);
516
  
517
  fontsel->font_label = gtk_label_new(_("Font:"));
Owen Taylor's avatar
Owen Taylor committed
518 519 520 521
  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);
522
  label = gtk_label_new(_("Font Style:"));
Owen Taylor's avatar
Owen Taylor committed
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, 1, 2, 0, 1,
		    GTK_FILL, 0, 0, 0);
527
  label = gtk_label_new(_("Size:"));
Owen Taylor's avatar
Owen Taylor committed
528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552
  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);
553
  
Owen Taylor's avatar
Owen Taylor committed
554 555 556
  /* 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
557
  gtk_clist_set_column_auto_resize (GTK_CLIST (fontsel->font_clist), 0, TRUE);
558
  scrolled_win = gtk_scrolled_window_new (NULL, NULL);
Damon Chaplin's avatar
""  
Damon Chaplin committed
559
  gtk_widget_set_usize (scrolled_win, FONT_LIST_WIDTH, FONT_LIST_HEIGHT);
560 561 562
  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
563
  gtk_widget_show(fontsel->font_clist);
564 565 566
  gtk_widget_show(scrolled_win);

  gtk_table_attach (GTK_TABLE (table), scrolled_win, 0, 1, 2, 3,
Owen Taylor's avatar
Owen Taylor committed
567 568
		    GTK_EXPAND | GTK_FILL,
		    GTK_EXPAND | GTK_FILL, 0, 0);
569
  
Owen Taylor's avatar
Owen Taylor committed
570 571
  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
572 573
  gtk_clist_set_column_auto_resize (GTK_CLIST (fontsel->font_style_clist),
				    0, TRUE);
574
  scrolled_win = gtk_scrolled_window_new (NULL, NULL);
Damon Chaplin's avatar
""  
Damon Chaplin committed
575
  gtk_widget_set_usize (scrolled_win, FONT_STYLE_LIST_WIDTH, -1);
576 577 578
  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
579
  gtk_widget_show(fontsel->font_style_clist);
580 581
  gtk_widget_show(scrolled_win);
  gtk_table_attach (GTK_TABLE (table), scrolled_win, 1, 2, 2, 3,
Owen Taylor's avatar
Owen Taylor committed
582 583
		    GTK_EXPAND | GTK_FILL,
		    GTK_EXPAND | GTK_FILL, 0, 0);
584
  
Owen Taylor's avatar
Owen Taylor committed
585 586
  fontsel->size_clist = gtk_clist_new(1);
  gtk_clist_column_titles_hide (GTK_CLIST(fontsel->size_clist));
Damon Chaplin's avatar
""  
Damon Chaplin committed
587
  gtk_clist_set_column_width (GTK_CLIST(fontsel->size_clist), 0, 20);
588
  scrolled_win = gtk_scrolled_window_new (NULL, NULL);
Damon Chaplin's avatar
""  
Damon Chaplin committed
589
  gtk_widget_set_usize (scrolled_win, FONT_SIZE_LIST_WIDTH, -1);
590 591 592
  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
593
  gtk_widget_show(fontsel->size_clist);
594 595
  gtk_widget_show(scrolled_win);
  gtk_table_attach (GTK_TABLE (table), scrolled_win, 2, 3, 2, 3,
Owen Taylor's avatar
Owen Taylor committed
596
		    GTK_FILL, GTK_FILL, 0, 0);
597 598
  
  
Owen Taylor's avatar
Owen Taylor committed
599 600
  /* Insert the fonts. If there exist fonts with the same family but
     different foundries, then the foundry name is appended in brackets. */
601
  gtk_font_selection_show_available_fonts(fontsel);
602
  
Owen Taylor's avatar
Owen Taylor committed
603 604 605 606 607 608 609 610 611 612
  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);
613
  
Owen Taylor's avatar
Owen Taylor committed
614 615 616 617 618 619 620 621
  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
622 623 624 625
  gtk_signal_connect_after (GTK_OBJECT (fontsel->font_style_clist),
			    "realize",
			    GTK_SIGNAL_FUNC(gtk_font_selection_realize_list),
			    fontsel);
626
  
Owen Taylor's avatar
Owen Taylor committed
627 628 629
  /* Insert the standard font sizes */
  gtk_clist_freeze (GTK_CLIST(fontsel->size_clist));
  size_to_match = INITIAL_FONT_SIZE;
630
  if (INITIAL_METRIC == GTK_FONT_METRIC_POINTS)
Owen Taylor's avatar
Owen Taylor committed
631 632 633 634 635 636 637 638 639 640 641 642 643
    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));
644
  
Owen Taylor's avatar
Owen Taylor committed
645 646 647 648 649 650 651
  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);
652 653
  
  
654
  /* create the Reset Filter & Metric buttons */
Owen Taylor's avatar
Owen Taylor committed
655 656 657
  hbox = gtk_hbox_new(FALSE, 8);
  gtk_widget_show (hbox);
  gtk_box_pack_start (GTK_BOX (fontsel->main_vbox), hbox, FALSE, TRUE, 0);
658
  
659
  fontsel->filter_button = gtk_button_new_with_label(_("Reset Filter"));
Damon Chaplin's avatar
""  
Damon Chaplin committed
660 661
  gtk_misc_set_padding (GTK_MISC (GTK_BIN (fontsel->filter_button)->child),
			16, 0);
Owen Taylor's avatar
Owen Taylor committed
662 663 664 665
  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",
666
		      GTK_SIGNAL_FUNC(gtk_font_selection_on_clear_filter),
Owen Taylor's avatar
Owen Taylor committed
667
		      fontsel);
668
  
Owen Taylor's avatar
Owen Taylor committed
669 670 671 672
  hbox2 = gtk_hbox_new(FALSE, 0);
  gtk_widget_show (hbox2);
  gtk_box_pack_end (GTK_BOX (hbox), hbox2, FALSE, FALSE, 0);
  
673
  label = gtk_label_new(_("Metric:"));
Owen Taylor's avatar
Owen Taylor committed
674 675
  gtk_widget_show (label);
  gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, TRUE, 8);
676
  
677
  fontsel->points_button = gtk_radio_button_new_with_label(NULL, _("Points"));
Owen Taylor's avatar
Owen Taylor committed
678 679
  gtk_widget_show (fontsel->points_button);
  gtk_box_pack_start (GTK_BOX (hbox2), fontsel->points_button, FALSE, TRUE, 0);
680
  if (INITIAL_METRIC == GTK_FONT_METRIC_POINTS)
681
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fontsel->points_button),
Owen Taylor's avatar
Owen Taylor committed
682
				TRUE);
683
  
684
  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
685 686
  gtk_widget_show (fontsel->pixels_button);
  gtk_box_pack_start (GTK_BOX (hbox2), fontsel->pixels_button, FALSE, TRUE, 0);
687
  if (INITIAL_METRIC == GTK_FONT_METRIC_PIXELS)
688
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fontsel->pixels_button),
Owen Taylor's avatar
Owen Taylor committed
689
				TRUE);
690
  
Owen Taylor's avatar
Owen Taylor committed
691 692 693 694 695 696
  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);
697 698
  
  
Owen Taylor's avatar
Owen Taylor committed
699
  /* create the text entry widget */
700
  text_frame = gtk_frame_new (_("Preview:"));
Owen Taylor's avatar
Owen Taylor committed
701 702 703 704
  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);
705
  
Owen Taylor's avatar
Owen Taylor committed
706 707 708 709
  /* 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);
710
  gtk_container_set_border_width (GTK_CONTAINER (text_box), 4);
711
  
Owen Taylor's avatar
Owen Taylor committed
712 713 714 715 716
  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);
717
  
Owen Taylor's avatar
Owen Taylor committed
718 719 720 721 722
  /* 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);
723 724
  
  
Owen Taylor's avatar
Owen Taylor committed
725 726 727
  /* Create the font info page */
  fontsel->info_vbox = gtk_vbox_new (FALSE, 4);
  gtk_widget_show (fontsel->info_vbox);
728
  gtk_container_set_border_width (GTK_CONTAINER (fontsel->info_vbox), 2);
729
  label = gtk_label_new(_("Font Information"));
Owen Taylor's avatar
Owen Taylor committed
730 731
  gtk_notebook_append_page (GTK_NOTEBOOK (fontsel),
			    fontsel->info_vbox, label);
732
  
733
  fontsel->info_clist = gtk_clist_new_with_titles (3, titles);
Owen Taylor's avatar
Owen Taylor committed
734 735 736 737 738
  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));
739 740 741 742
  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
743
  gtk_widget_show(fontsel->info_clist);
744 745
  gtk_widget_show(scrolled_win);
  gtk_box_pack_start (GTK_BOX (fontsel->info_vbox), scrolled_win,
Owen Taylor's avatar
Owen Taylor committed
746
		      TRUE, TRUE, 0);
747
  
Owen Taylor's avatar
Owen Taylor committed
748 749 750 751 752 753
  /* 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++)
    {
754
      row_text[0] = _(xlfd_field_names[i]);
Owen Taylor's avatar
Owen Taylor committed
755 756 757 758 759 760
      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));
761
  
762
  label = gtk_label_new(_("Requested Font Name:"));
Owen Taylor's avatar
Owen Taylor committed
763 764 765
  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);
766
  
Owen Taylor's avatar
Owen Taylor committed
767 768 769 770 771
  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);
772
  
773
  label = gtk_label_new(_("Actual Font Name:"));
Owen Taylor's avatar
Owen Taylor committed
774 775 776 777 778 779 780 781 782
  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);
783
  
784
  sprintf(buffer, _("%i fonts available with a total of %i styles."),
785
	  fontsel_info->nfonts, fontsel_info->nstyles);
Owen Taylor's avatar
Owen Taylor committed
786 787 788
  label = gtk_label_new(buffer);
  gtk_widget_show (label);
  gtk_box_pack_start (GTK_BOX (fontsel->info_vbox), label, FALSE, FALSE, 0);
789
  
Owen Taylor's avatar
Owen Taylor committed
790 791 792
  gtk_signal_connect (GTK_OBJECT (fontsel), "switch_page",
		      GTK_SIGNAL_FUNC(gtk_font_selection_switch_page),
		      fontsel);
793 794
  
  
Owen Taylor's avatar
Owen Taylor committed
795 796 797
  /* Create the Filter page. */
  fontsel->filter_vbox = gtk_vbox_new (FALSE, 4);
  gtk_widget_show (fontsel->filter_vbox);
798
  gtk_container_set_border_width (GTK_CONTAINER (fontsel->filter_vbox), 2);
799
  label = gtk_label_new(_("Filter"));
Owen Taylor's avatar
Owen Taylor committed
800 801
  gtk_notebook_append_page (GTK_NOTEBOOK (fontsel),
			    fontsel->filter_vbox, label);
802
  
803 804 805 806 807 808 809 810 811
  /* 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);

812
  label = gtk_label_new(_("Font Types:"));
813 814 815 816 817 818 819
  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);

820
  fontsel->type_bitmaps_button = gtk_check_button_new_with_label (_("Bitmap"));
821
  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fontsel->type_bitmaps_button), TRUE);
822 823 824 825
  gtk_widget_show (fontsel->type_bitmaps_button);
  gtk_box_pack_start (GTK_BOX (hbox2), fontsel->type_bitmaps_button,
		      FALSE, TRUE, 0);

826
  fontsel->type_scalable_button = gtk_check_button_new_with_label (_("Scalable"));
827
  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fontsel->type_scalable_button), TRUE);
828 829 830 831
  gtk_widget_show (fontsel->type_scalable_button);
  gtk_box_pack_start (GTK_BOX (hbox2), fontsel->type_scalable_button,
		      FALSE, TRUE, 0);

832
  fontsel->type_scaled_bitmaps_button = gtk_check_button_new_with_label (_("Scaled Bitmap"));
833 834 835 836
  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
837 838 839 840
  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);
841
  
Owen Taylor's avatar
Owen Taylor committed
842 843 844 845
  for (prop = 0; prop < GTK_NUM_FONT_PROPERTIES; prop++)
    {
      gint left = filter_positions[prop][0];
      gint top = filter_positions[prop][1];
846
      
847
      label = gtk_label_new(_(xlfd_field_names[xlfd_index[prop]]));
Owen Taylor's avatar
Owen Taylor committed
848 849 850 851 852
      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);
853
      
Owen Taylor's avatar
Owen Taylor committed
854 855 856 857
      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
858
      gtk_clist_set_column_auto_resize (GTK_CLIST (clist), 0, TRUE);
859 860 861 862 863
      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
864
      gtk_widget_show(clist);
865
      gtk_widget_show(scrolled_win);
866
      
867
      /* For the bottom-right cell we add the 'Reset Filter' button. */
Owen Taylor's avatar
Owen Taylor committed
868 869 870 871 872 873
      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);
874
	  
875
	  gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
876
	  
Owen Taylor's avatar
Owen Taylor committed
877 878 879
	  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);
880
	  
881
	  button = gtk_button_new_with_label(_("Reset Filter"));
Owen Taylor's avatar
Owen Taylor committed
882 883 884 885 886 887 888
	  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
889
	gtk_table_attach (GTK_TABLE (table), scrolled_win,
Owen Taylor's avatar
Owen Taylor committed
890 891
			  left, left + 1, top + 1, top + 2,
			  GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
892
      
Owen Taylor's avatar
Owen Taylor committed
893 894 895 896 897 898
      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);
899
      
Owen Taylor's avatar
Owen Taylor committed
900 901 902
      /* Insert the property names, expanded, and in sorted order.
	 But we make sure that the wildcard '*' is first. */
      gtk_clist_freeze (GTK_CLIST(clist));
903
      property = N_("*");
Owen Taylor's avatar
Owen Taylor committed
904
      gtk_clist_append(GTK_CLIST(clist), &property);
905
      
906
      for (i = 1; i < fontsel_info->nproperties[prop]; i++) {
907
	property = _(fontsel_info->properties[prop][i]);
Owen Taylor's avatar
Owen Taylor committed
908 909 910 911
	if (prop == SLANT)
	  property = gtk_font_selection_expand_slant_code(property);
	else if (prop == SPACING)
	  property = gtk_font_selection_expand_spacing_code(property);
912

Owen Taylor's avatar
Owen Taylor committed
913 914 915 916 917 918 919 920 921 922 923 924 925
	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);
926
	gtk_clist_set_row_data(GTK_CLIST(clist), row, GINT_TO_POINTER (i));
Owen Taylor's avatar
Owen Taylor committed
927 928 929 930 931 932 933 934 935 936 937
      }
      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;
938
  
Tim Janik's avatar
Tim Janik committed
939
  fontsel = gtk_type_new (GTK_TYPE_FONT_SELECTION);
940
  
Owen Taylor's avatar
Owen Taylor committed
941 942 943 944 945 946 947
  return GTK_WIDGET (fontsel);
}

static void
gtk_font_selection_destroy (GtkObject *object)
{
  GtkFontSelection *fontsel;
948
  
Owen Taylor's avatar
Owen Taylor committed
949 950
  g_return_if_fail (object != NULL);
  g_return_if_fail (GTK_IS_FONT_SELECTION (object));
951
  
Owen Taylor's avatar
Owen Taylor committed
952
  fontsel = GTK_FONT_SELECTION (object);
953
  
Owen Taylor's avatar
Owen Taylor committed
954 955 956
  /* All we have to do is unref the font, if we have one. */
  if (fontsel->font)
    gdk_font_unref (fontsel->font);
957
  
Owen Taylor's avatar
Owen Taylor committed
958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973
  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;
974
  
Owen Taylor's avatar
Owen Taylor committed
975
#ifdef FONTSEL_DEBUG
976
  g_message("In expose_list\n");
Owen Taylor's avatar
Owen Taylor committed
977 978
#endif
  fontsel = GTK_FONT_SELECTION(data);
979
  
980
  font_info = fontsel_info->font_info;
981
      
982 983 984 985 986 987 988 989 990
  /* 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);
    }
991
      
992 993 994 995 996 997 998 999 1000 1001
  /* 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);
    }
1002
      
1003 1004 1005 1006 1007 1008 1009 1010
  /* 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
1011 1012 1013 1014
    }
}


Damon Chaplin's avatar
""  
Damon Chaplin committed
1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046
/* 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
1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057
/* 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;
1058
  
Owen Taylor's avatar
Owen Taylor committed
1059
#ifdef FONTSEL_DEBUG
1060
  g_message("In select_font\n");
Owen Taylor's avatar
Owen Taylor committed
1061 1062
#endif
  fontsel = GTK_FONT_SELECTION(data);
1063
  font_info = fontsel_info->font_info;
1064
  
Owen Taylor's avatar
Owen Taylor committed
1065 1066
  if (bevent && !GTK_WIDGET_HAS_FOCUS (w))
    gtk_widget_grab_focus (w);
1067
  
1068
  row = GPOINTER_TO_INT (gtk_clist_get_row_data (GTK_CLIST (fontsel->font_clist), row));
Owen Taylor's avatar
Owen Taylor committed
1069 1070
  font = &font_info[row];
  gtk_entry_set_text(GTK_ENTRY(fontsel->font_entry), font->family);
1071
  
Owen Taylor's avatar
Owen Taylor committed
1072 1073 1074
  /* If it is already the current font, just return. */
  if (fontsel->font_index == row)
    return;
1075
  
Owen Taylor's avatar
Owen Taylor committed
1076 1077
  fontsel->font_index = row;
  gtk_font_selection_show_available_styles (fontsel);
1078
  gtk_font_selection_select_best_style (fontsel, TRUE);
Owen Taylor's avatar
Owen Taylor committed
1079 1080 1081 1082 1083 1084 1085 1086 1087
}


static gint
gtk_font_selection_on_clist_key_press (GtkWidget        *clist,
				       GdkEventKey      *event,
				       GtkFontSelection *fontsel)
{
#ifdef FONTSEL_DEBUG
1088
  g_message("In on_clist_key_press\n");
Owen Taylor's avatar
Owen Taylor committed
1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105
#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;
1106
  
Owen Taylor's avatar
Owen Taylor committed
1107 1108 1109
  selection = GTK_CLIST(clist)->selection;
  if (!selection)
    return FALSE;
1110
  current_row = GPOINTER_TO_INT (selection->data);
1111
  
1112 1113 1114
  /* 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
1115 1116 1117 1118 1119 1120 1121
  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)
1122
	if (GPOINTER_TO_INT (gtk_clist_get_row_data(GTK_CLIST(clist), row)) == -1)
Owen Taylor's avatar
Owen Taylor committed
1123
	  continue;
1124
      
Owen Taylor's avatar
Owen Taylor committed
1125 1126 1127 1128 1129
      /* 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);
1130
      break;