1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * Massively updated for Pango by Owen Taylor, May 2000
5 * GtkFontSelection widget for Gtk+, by Damon Chaplin, May 1998.
6 * Based on the GnomeFontSelector widget, by Elliot Lee, but major changes.
7 * The GnomeFontSelector was derived from app/text_tool.c in the GIMP.
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 * Boston, MA 02111-1307, USA.
26 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
27 * file for a list of people on the GTK+ Team. See the ChangeLog
28 * files for a list of changes. These files are distributed with
29 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
35 #include <glib/gprintf.h>
40 #include "gtkfontsel.h"
41 #include "gtkbutton.h"
42 #include "gtkcellrenderertext.h"
48 #include "gtkliststore.h"
52 #include "gtktreeselection.h"
53 #include "gtktreeview.h"
55 #include "gtkscrolledwindow.h"
57 #include "gtkaccessible.h"
58 #include "gtkbuildable.h"
59 #include "gtkprivate.h"
64 * @Short_description: A widget for selecting fonts
65 * @Title: GtkFontSelection
66 * @See_also: #GtkFontSelectionDialog
68 * The #GtkFontSelection widget lists the available fonts, styles and sizes,
69 * allowing the user to select a font.
70 * It is used in the #GtkFontSelectionDialog widget to provide a dialog box for
73 * To set the font which is initially selected, use
74 * gtk_font_selection_set_font_name().
76 * To get the selected font use gtk_font_selection_get_font_name().
78 * To change the text which is shown in the preview area, use
79 * gtk_font_selection_set_preview_text().
83 struct _GtkFontSelectionPrivate
85 GtkWidget *font_entry; /* Used _get_family_entry() for consistency, -mr */
86 GtkWidget *font_style_entry; /* Used _get_face_entry() for consistency, -mr */
88 GtkWidget *size_entry;
89 GtkWidget *preview_entry;
91 GtkWidget *family_list;
95 PangoFontFamily *family; /* Current family */
96 PangoFontFace *face; /* Current face */
102 struct _GtkFontSelectionDialogPrivate
106 GtkWidget *ok_button;
107 GtkWidget *apply_button;
108 GtkWidget *cancel_button;
112 /* We don't enable the font and style entries because they don't add
113 * much in terms of visible effect and have a weird effect on keynav.
114 * the Windows font selector has entries similarly positioned but they
115 * act in conjunction with the associated lists to form a single focus
118 #undef INCLUDE_FONT_ENTRIES
120 /* This is the default text shown in the preview entry, though the user
121 can set it. Remember that some fonts only have capital letters. */
122 #define PREVIEW_TEXT N_("abcdefghijk ABCDEFGHIJK")
124 #define DEFAULT_FONT_NAME "Sans 10"
126 /* This is the initial and maximum height of the preview entry (it expands
127 when large font sizes are selected). Initial height is also the minimum. */
128 #define INITIAL_PREVIEW_HEIGHT 44
129 #define MAX_PREVIEW_HEIGHT 300
131 /* These are the sizes of the font, style & size lists. */
132 #define FONT_LIST_HEIGHT 136
133 #define FONT_LIST_WIDTH 190
134 #define FONT_STYLE_LIST_WIDTH 170
135 #define FONT_SIZE_LIST_WIDTH 60
137 /* These are what we use as the standard font sizes, for the size list.
139 static const guint16 font_sizes[] = {
140 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 22, 24, 26, 28,
141 32, 36, 40, 48, 56, 64, 72
165 static void gtk_font_selection_set_property (GObject *object,
169 static void gtk_font_selection_get_property (GObject *object,
173 static void gtk_font_selection_finalize (GObject *object);
174 static void gtk_font_selection_screen_changed (GtkWidget *widget,
175 GdkScreen *previous_screen);
176 static void gtk_font_selection_style_updated (GtkWidget *widget);
178 /* These are the callbacks & related functions. */
179 static void gtk_font_selection_select_font (GtkTreeSelection *selection,
181 static void gtk_font_selection_show_available_fonts (GtkFontSelection *fs);
183 static void gtk_font_selection_show_available_styles (GtkFontSelection *fs);
184 static void gtk_font_selection_select_best_style (GtkFontSelection *fs,
186 static void gtk_font_selection_select_style (GtkTreeSelection *selection,
189 static void gtk_font_selection_select_best_size (GtkFontSelection *fs);
190 static void gtk_font_selection_show_available_sizes (GtkFontSelection *fs,
191 gboolean first_time);
192 static void gtk_font_selection_size_activate (GtkWidget *w,
194 static gboolean gtk_font_selection_size_focus_out (GtkWidget *w,
195 GdkEventFocus *event,
197 static void gtk_font_selection_select_size (GtkTreeSelection *selection,
200 static void gtk_font_selection_scroll_on_map (GtkWidget *w,
203 static void gtk_font_selection_preview_changed (GtkWidget *entry,
204 GtkFontSelection *fontsel);
205 static void gtk_font_selection_scroll_to_selection (GtkFontSelection *fontsel);
208 /* Misc. utility functions. */
209 static void gtk_font_selection_load_font (GtkFontSelection *fs);
210 static void gtk_font_selection_update_preview (GtkFontSelection *fs);
212 static PangoFontDescription *gtk_font_selection_get_font_description (GtkFontSelection *fontsel);
213 static gboolean gtk_font_selection_select_font_desc (GtkFontSelection *fontsel,
214 PangoFontDescription *new_desc,
215 PangoFontFamily **pfamily,
216 PangoFontFace **pface);
217 static void gtk_font_selection_reload_fonts (GtkFontSelection *fontsel);
218 static void gtk_font_selection_ref_family (GtkFontSelection *fontsel,
219 PangoFontFamily *family);
220 static void gtk_font_selection_ref_face (GtkFontSelection *fontsel,
221 PangoFontFace *face);
223 G_DEFINE_TYPE (GtkFontSelection, gtk_font_selection, GTK_TYPE_VBOX)
226 gtk_font_selection_class_init (GtkFontSelectionClass *klass)
228 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
229 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
231 gobject_class->finalize = gtk_font_selection_finalize;
232 gobject_class->set_property = gtk_font_selection_set_property;
233 gobject_class->get_property = gtk_font_selection_get_property;
235 widget_class->screen_changed = gtk_font_selection_screen_changed;
236 widget_class->style_updated = gtk_font_selection_style_updated;
238 g_object_class_install_property (gobject_class,
240 g_param_spec_string ("font-name",
242 P_("The string that represents this font"),
244 GTK_PARAM_READWRITE));
245 g_object_class_install_property (gobject_class,
247 g_param_spec_string ("preview-text",
249 P_("The text to display in order to demonstrate the selected font"),
251 GTK_PARAM_READWRITE));
253 g_type_class_add_private (klass, sizeof (GtkFontSelectionPrivate));
257 gtk_font_selection_set_property (GObject *object,
262 GtkFontSelection *fontsel;
264 fontsel = GTK_FONT_SELECTION (object);
269 gtk_font_selection_set_font_name (fontsel, g_value_get_string (value));
271 case PROP_PREVIEW_TEXT:
272 gtk_font_selection_set_preview_text (fontsel, g_value_get_string (value));
275 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
280 static void gtk_font_selection_get_property (GObject *object,
285 GtkFontSelection *fontsel;
287 fontsel = GTK_FONT_SELECTION (object);
292 g_value_take_string (value, gtk_font_selection_get_font_name (fontsel));
294 case PROP_PREVIEW_TEXT:
295 g_value_set_string (value, gtk_font_selection_get_preview_text (fontsel));
298 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
303 /* Handles key press events on the lists, so that we can trap Enter to
304 * activate the default button on our own.
307 list_row_activated (GtkWidget *widget)
309 GtkWidget *default_widget, *focus_widget;
312 window = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (widget)));
313 if (!gtk_widget_is_toplevel (GTK_WIDGET (window)))
318 default_widget = gtk_window_get_default_widget (window);
319 focus_widget = gtk_window_get_focus (window);
321 if (widget != default_widget &&
322 !(widget == focus_widget && (!default_widget || !gtk_widget_get_sensitive (default_widget))))
323 gtk_window_activate_default (window);
330 gtk_font_selection_init (GtkFontSelection *fontsel)
332 GtkFontSelectionPrivate *priv;
333 GtkWidget *scrolled_win;
335 GtkWidget *table, *label;
336 GtkWidget *font_label, *style_label;
339 GtkTreeViewColumn *column;
340 GList *focus_chain = NULL;
343 fontsel->priv = G_TYPE_INSTANCE_GET_PRIVATE (fontsel,
344 GTK_TYPE_FONT_SELECTION,
345 GtkFontSelectionPrivate);
346 priv = fontsel->priv;
348 gtk_widget_push_composite_child ();
350 gtk_box_set_spacing (GTK_BOX (fontsel), 12);
351 priv->size = 12 * PANGO_SCALE;
353 /* Create the table of font, style & size. */
354 table = gtk_table_new (3, 3, FALSE);
355 gtk_widget_show (table);
356 gtk_table_set_row_spacings (GTK_TABLE (table), 6);
357 gtk_table_set_col_spacings (GTK_TABLE (table), 12);
358 gtk_box_pack_start (GTK_BOX (fontsel), table, TRUE, TRUE, 0);
360 #ifdef INCLUDE_FONT_ENTRIES
361 priv->font_entry = gtk_entry_new ();
362 gtk_editable_set_editable (GTK_EDITABLE (priv->font_entry), FALSE);
363 gtk_widget_set_size_request (priv->font_entry, 20, -1);
364 gtk_widget_show (priv->font_entry);
365 gtk_table_attach (GTK_TABLE (table), priv->font_entry, 0, 1, 1, 2,
368 priv->font_style_entry = gtk_entry_new ();
369 gtk_editable_set_editable (GTK_EDITABLE (priv->font_style_entry), FALSE);
370 gtk_widget_set_size_request (priv->font_style_entry, 20, -1);
371 gtk_widget_show (priv->font_style_entry);
372 gtk_table_attach (GTK_TABLE (table), priv->font_style_entry, 1, 2, 1, 2,
374 #endif /* INCLUDE_FONT_ENTRIES */
376 priv->size_entry = gtk_entry_new ();
377 gtk_widget_set_size_request (priv->size_entry, 20, -1);
378 gtk_widget_show (priv->size_entry);
379 gtk_table_attach (GTK_TABLE (table), priv->size_entry, 2, 3, 1, 2,
381 g_signal_connect (priv->size_entry, "activate",
382 G_CALLBACK (gtk_font_selection_size_activate),
384 g_signal_connect_after (priv->size_entry, "focus-out-event",
385 G_CALLBACK (gtk_font_selection_size_focus_out),
388 font_label = gtk_label_new_with_mnemonic (_("_Family:"));
389 gtk_misc_set_alignment (GTK_MISC (font_label), 0.0, 0.5);
390 gtk_widget_show (font_label);
391 gtk_table_attach (GTK_TABLE (table), font_label, 0, 1, 0, 1,
394 style_label = gtk_label_new_with_mnemonic (_("_Style:"));
395 gtk_misc_set_alignment (GTK_MISC (style_label), 0.0, 0.5);
396 gtk_widget_show (style_label);
397 gtk_table_attach (GTK_TABLE (table), style_label, 1, 2, 0, 1,
400 label = gtk_label_new_with_mnemonic (_("Si_ze:"));
401 gtk_label_set_mnemonic_widget (GTK_LABEL (label),
403 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
404 gtk_widget_show (label);
405 gtk_table_attach (GTK_TABLE (table), label, 2, 3, 0, 1,
409 /* Create the lists */
411 model = gtk_list_store_new (2,
412 G_TYPE_OBJECT, /* FAMILY_COLUMN */
413 G_TYPE_STRING); /* FAMILY_NAME_COLUMN */
414 priv->family_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
415 g_object_unref (model);
417 g_signal_connect (priv->family_list, "row-activated",
418 G_CALLBACK (list_row_activated), fontsel);
420 column = gtk_tree_view_column_new_with_attributes ("Family",
421 gtk_cell_renderer_text_new (),
422 "text", FAMILY_NAME_COLUMN,
424 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
425 gtk_tree_view_append_column (GTK_TREE_VIEW (priv->family_list), column);
427 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->family_list), FALSE);
428 gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->family_list)),
429 GTK_SELECTION_BROWSE);
431 gtk_label_set_mnemonic_widget (GTK_LABEL (font_label), priv->family_list);
433 scrolled_win = gtk_scrolled_window_new (NULL, NULL);
434 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), GTK_SHADOW_IN);
435 gtk_widget_set_size_request (scrolled_win,
436 FONT_LIST_WIDTH, FONT_LIST_HEIGHT);
437 gtk_container_add (GTK_CONTAINER (scrolled_win), priv->family_list);
438 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
439 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
440 gtk_widget_show (priv->family_list);
441 gtk_widget_show (scrolled_win);
443 gtk_table_attach (GTK_TABLE (table), scrolled_win, 0, 1, 1, 3,
444 GTK_EXPAND | GTK_FILL,
445 GTK_EXPAND | GTK_FILL, 0, 0);
446 focus_chain = g_list_append (focus_chain, scrolled_win);
448 model = gtk_list_store_new (2,
449 G_TYPE_OBJECT, /* FACE_COLUMN */
450 G_TYPE_STRING); /* FACE_NAME_COLUMN */
451 priv->face_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
452 g_object_unref (model);
453 g_signal_connect (priv->face_list, "row-activated",
454 G_CALLBACK (list_row_activated), fontsel);
456 gtk_label_set_mnemonic_widget (GTK_LABEL (style_label), priv->face_list);
458 column = gtk_tree_view_column_new_with_attributes ("Face",
459 gtk_cell_renderer_text_new (),
460 "text", FACE_NAME_COLUMN,
462 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
463 gtk_tree_view_append_column (GTK_TREE_VIEW (priv->face_list), column);
465 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->face_list), FALSE);
466 gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->face_list)),
467 GTK_SELECTION_BROWSE);
469 scrolled_win = gtk_scrolled_window_new (NULL, NULL);
470 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), GTK_SHADOW_IN);
471 gtk_widget_set_size_request (scrolled_win,
472 FONT_STYLE_LIST_WIDTH, FONT_LIST_HEIGHT);
473 gtk_container_add (GTK_CONTAINER (scrolled_win), priv->face_list);
474 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
475 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
476 gtk_widget_show (priv->face_list);
477 gtk_widget_show (scrolled_win);
478 gtk_table_attach (GTK_TABLE (table), scrolled_win, 1, 2, 1, 3,
479 GTK_EXPAND | GTK_FILL,
480 GTK_EXPAND | GTK_FILL, 0, 0);
481 focus_chain = g_list_append (focus_chain, scrolled_win);
483 focus_chain = g_list_append (focus_chain, priv->size_entry);
485 model = gtk_list_store_new (1, G_TYPE_INT);
486 priv->size_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
487 g_object_unref (model);
488 g_signal_connect (priv->size_list, "row-activated",
489 G_CALLBACK (list_row_activated), fontsel);
491 column = gtk_tree_view_column_new_with_attributes ("Size",
492 gtk_cell_renderer_text_new (),
495 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
496 gtk_tree_view_append_column (GTK_TREE_VIEW (priv->size_list), column);
498 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->size_list), FALSE);
499 gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->size_list)),
500 GTK_SELECTION_BROWSE);
502 scrolled_win = gtk_scrolled_window_new (NULL, NULL);
503 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), GTK_SHADOW_IN);
504 gtk_container_add (GTK_CONTAINER (scrolled_win), priv->size_list);
505 gtk_widget_set_size_request (scrolled_win, -1, FONT_LIST_HEIGHT);
506 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
507 GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
508 gtk_widget_show (priv->size_list);
509 gtk_widget_show (scrolled_win);
510 gtk_table_attach (GTK_TABLE (table), scrolled_win, 2, 3, 2, 3,
511 GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
512 focus_chain = g_list_append (focus_chain, scrolled_win);
514 gtk_container_set_focus_chain (GTK_CONTAINER (table), focus_chain);
515 g_list_free (focus_chain);
517 /* Insert the fonts. */
518 g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->family_list)), "changed",
519 G_CALLBACK (gtk_font_selection_select_font), fontsel);
521 g_signal_connect_after (priv->family_list, "map",
522 G_CALLBACK (gtk_font_selection_scroll_on_map),
525 g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->face_list)), "changed",
526 G_CALLBACK (gtk_font_selection_select_style), fontsel);
528 g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->size_list)), "changed",
529 G_CALLBACK (gtk_font_selection_select_size), fontsel);
530 atk_obj = gtk_widget_get_accessible (priv->size_list);
531 if (GTK_IS_ACCESSIBLE (atk_obj))
533 /* Accessibility support is enabled.
534 * Make the label ATK_RELATON_LABEL_FOR for the size list as well.
536 AtkObject *atk_label;
537 AtkRelationSet *relation_set;
538 AtkRelation *relation;
539 AtkObject *obj_array[1];
541 atk_label = gtk_widget_get_accessible (label);
542 relation_set = atk_object_ref_relation_set (atk_obj);
543 relation = atk_relation_set_get_relation_by_type (relation_set, ATK_RELATION_LABELLED_BY);
546 atk_relation_add_target (relation, atk_label);
550 obj_array[0] = atk_label;
551 relation = atk_relation_new (obj_array, 1, ATK_RELATION_LABELLED_BY);
552 atk_relation_set_add (relation_set, relation);
554 g_object_unref (relation_set);
556 relation_set = atk_object_ref_relation_set (atk_label);
557 relation = atk_relation_set_get_relation_by_type (relation_set, ATK_RELATION_LABEL_FOR);
560 atk_relation_add_target (relation, atk_obj);
564 obj_array[0] = atk_obj;
565 relation = atk_relation_new (obj_array, 1, ATK_RELATION_LABEL_FOR);
566 atk_relation_set_add (relation_set, relation);
568 g_object_unref (relation_set);
571 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
572 gtk_widget_show (vbox);
573 gtk_box_pack_start (GTK_BOX (fontsel), vbox, FALSE, TRUE, 0);
575 /* create the text entry widget */
576 label = gtk_label_new_with_mnemonic (_("_Preview:"));
577 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
578 gtk_widget_show (label);
579 gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 0);
581 text_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
582 gtk_widget_show (text_box);
583 gtk_box_pack_start (GTK_BOX (vbox), text_box, FALSE, TRUE, 0);
585 priv->preview_entry = gtk_entry_new ();
586 gtk_label_set_mnemonic_widget (GTK_LABEL (label), priv->preview_entry);
587 gtk_entry_set_text (GTK_ENTRY (priv->preview_entry), _(PREVIEW_TEXT));
589 gtk_widget_show (priv->preview_entry);
590 g_signal_connect (priv->preview_entry, "changed",
591 G_CALLBACK (gtk_font_selection_preview_changed), fontsel);
592 gtk_widget_set_size_request (priv->preview_entry,
593 -1, INITIAL_PREVIEW_HEIGHT);
594 gtk_box_pack_start (GTK_BOX (text_box), priv->preview_entry,
596 gtk_widget_pop_composite_child();
600 * gtk_font_selection_new:
602 * Creates a new #GtkFontSelection.
604 * Return value: a n ew #GtkFontSelection
607 gtk_font_selection_new (void)
609 GtkFontSelection *fontsel;
611 fontsel = g_object_new (GTK_TYPE_FONT_SELECTION, NULL);
613 return GTK_WIDGET (fontsel);
617 gtk_font_selection_finalize (GObject *object)
619 GtkFontSelection *fontsel = GTK_FONT_SELECTION (object);
621 gtk_font_selection_ref_family (fontsel, NULL);
622 gtk_font_selection_ref_face (fontsel, NULL);
624 G_OBJECT_CLASS (gtk_font_selection_parent_class)->finalize (object);
628 gtk_font_selection_ref_family (GtkFontSelection *fontsel,
629 PangoFontFamily *family)
631 GtkFontSelectionPrivate *priv = fontsel->priv;
634 family = g_object_ref (family);
636 g_object_unref (priv->family);
637 priv->family = family;
640 static void gtk_font_selection_ref_face (GtkFontSelection *fontsel,
643 GtkFontSelectionPrivate *priv = fontsel->priv;
646 face = g_object_ref (face);
648 g_object_unref (priv->face);
653 gtk_font_selection_reload_fonts (GtkFontSelection *fontsel)
655 if (gtk_widget_has_screen (GTK_WIDGET (fontsel)))
657 PangoFontDescription *desc;
658 desc = gtk_font_selection_get_font_description (fontsel);
660 gtk_font_selection_show_available_fonts (fontsel);
661 gtk_font_selection_show_available_sizes (fontsel, TRUE);
662 gtk_font_selection_show_available_styles (fontsel);
664 gtk_font_selection_select_font_desc (fontsel, desc, NULL, NULL);
665 gtk_font_selection_scroll_to_selection (fontsel);
667 pango_font_description_free (desc);
672 gtk_font_selection_screen_changed (GtkWidget *widget,
673 GdkScreen *previous_screen)
675 gtk_font_selection_reload_fonts (GTK_FONT_SELECTION (widget));
679 gtk_font_selection_style_updated (GtkWidget *widget)
681 GTK_WIDGET_CLASS (gtk_font_selection_parent_class)->style_updated (widget);
683 /* Maybe fonts where installed or removed... */
684 gtk_font_selection_reload_fonts (GTK_FONT_SELECTION (widget));
688 gtk_font_selection_preview_changed (GtkWidget *entry,
689 GtkFontSelection *fontsel)
691 g_object_notify (G_OBJECT (fontsel), "preview-text");
695 scroll_to_selection (GtkTreeView *tree_view)
697 GtkTreeSelection *selection = gtk_tree_view_get_selection (tree_view);
701 if (gtk_tree_selection_get_selected (selection, &model, &iter))
703 GtkTreePath *path = gtk_tree_model_get_path (model, &iter);
704 gtk_tree_view_scroll_to_cell (tree_view, path, NULL, TRUE, 0.5, 0.5);
705 gtk_tree_path_free (path);
710 set_cursor_to_iter (GtkTreeView *view,
713 GtkTreeModel *model = gtk_tree_view_get_model (view);
714 GtkTreePath *path = gtk_tree_model_get_path (model, iter);
716 gtk_tree_view_set_cursor (view, path, NULL, FALSE);
718 gtk_tree_path_free (path);
722 gtk_font_selection_scroll_to_selection (GtkFontSelection *fontsel)
724 GtkFontSelectionPrivate *priv = fontsel->priv;
726 /* Try to scroll the font family list to the selected item */
727 scroll_to_selection (GTK_TREE_VIEW (priv->family_list));
729 /* Try to scroll the font family list to the selected item */
730 scroll_to_selection (GTK_TREE_VIEW (priv->face_list));
732 /* Try to scroll the font family list to the selected item */
733 scroll_to_selection (GTK_TREE_VIEW (priv->size_list));
734 /* This is called when the list is mapped. Here we scroll to the current
735 font if necessary. */
739 gtk_font_selection_scroll_on_map (GtkWidget *widget,
742 gtk_font_selection_scroll_to_selection (GTK_FONT_SELECTION (data));
745 /* This is called when a family is selected in the list. */
747 gtk_font_selection_select_font (GtkTreeSelection *selection,
750 GtkFontSelection *fontsel;
751 GtkFontSelectionPrivate *priv;
754 #ifdef INCLUDE_FONT_ENTRIES
755 const gchar *family_name;
758 fontsel = GTK_FONT_SELECTION (data);
759 priv = fontsel->priv;
761 if (gtk_tree_selection_get_selected (selection, &model, &iter))
763 PangoFontFamily *family;
765 gtk_tree_model_get (model, &iter, FAMILY_COLUMN, &family, -1);
766 if (priv->family != family)
768 gtk_font_selection_ref_family (fontsel, family);
770 #ifdef INCLUDE_FONT_ENTRIES
771 family_name = pango_font_family_get_name (priv->family);
772 gtk_entry_set_text (GTK_ENTRY (priv->font_entry), family_name);
775 gtk_font_selection_show_available_styles (fontsel);
776 gtk_font_selection_select_best_style (fontsel, TRUE);
779 g_object_unref (family);
784 cmp_families (const void *a, const void *b)
786 const char *a_name = pango_font_family_get_name (*(PangoFontFamily **)a);
787 const char *b_name = pango_font_family_get_name (*(PangoFontFamily **)b);
789 return g_utf8_collate (a_name, b_name);
793 gtk_font_selection_show_available_fonts (GtkFontSelection *fontsel)
795 GtkFontSelectionPrivate *priv = fontsel->priv;
797 PangoFontFamily **families;
798 PangoFontFamily *match_family = NULL;
800 GtkTreeIter match_row;
802 model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (priv->family_list)));
804 pango_context_list_families (gtk_widget_get_pango_context (GTK_WIDGET (fontsel)),
805 &families, &n_families);
806 qsort (families, n_families, sizeof (PangoFontFamily *), cmp_families);
808 gtk_list_store_clear (model);
810 for (i=0; i<n_families; i++)
812 const gchar *name = pango_font_family_get_name (families[i]);
815 gtk_list_store_append (model, &iter);
816 gtk_list_store_set (model, &iter,
817 FAMILY_COLUMN, families[i],
818 FAMILY_NAME_COLUMN, name,
821 if (i == 0 || !g_ascii_strcasecmp (name, "sans"))
823 match_family = families[i];
828 gtk_font_selection_ref_family (fontsel, match_family);
831 set_cursor_to_iter (GTK_TREE_VIEW (priv->family_list), &match_row);
832 #ifdef INCLUDE_FONT_ENTRIES
833 gtk_entry_set_text (GTK_ENTRY (priv->font_entry),
834 pango_font_family_get_name (match_family));
835 #endif /* INCLUDE_FONT_ENTRIES */
842 compare_font_descriptions (const PangoFontDescription *a, const PangoFontDescription *b)
844 int val = strcmp (pango_font_description_get_family (a), pango_font_description_get_family (b));
848 if (pango_font_description_get_weight (a) != pango_font_description_get_weight (b))
849 return pango_font_description_get_weight (a) - pango_font_description_get_weight (b);
851 if (pango_font_description_get_style (a) != pango_font_description_get_style (b))
852 return pango_font_description_get_style (a) - pango_font_description_get_style (b);
854 if (pango_font_description_get_stretch (a) != pango_font_description_get_stretch (b))
855 return pango_font_description_get_stretch (a) - pango_font_description_get_stretch (b);
857 if (pango_font_description_get_variant (a) != pango_font_description_get_variant (b))
858 return pango_font_description_get_variant (a) - pango_font_description_get_variant (b);
864 faces_sort_func (const void *a, const void *b)
866 PangoFontDescription *desc_a = pango_font_face_describe (*(PangoFontFace **)a);
867 PangoFontDescription *desc_b = pango_font_face_describe (*(PangoFontFace **)b);
869 int ord = compare_font_descriptions (desc_a, desc_b);
871 pango_font_description_free (desc_a);
872 pango_font_description_free (desc_b);
878 font_description_style_equal (const PangoFontDescription *a,
879 const PangoFontDescription *b)
881 return (pango_font_description_get_weight (a) == pango_font_description_get_weight (b) &&
882 pango_font_description_get_style (a) == pango_font_description_get_style (b) &&
883 pango_font_description_get_stretch (a) == pango_font_description_get_stretch (b) &&
884 pango_font_description_get_variant (a) == pango_font_description_get_variant (b));
887 /* This fills the font style list with all the possible style combinations
888 for the current font family. */
890 gtk_font_selection_show_available_styles (GtkFontSelection *fontsel)
892 GtkFontSelectionPrivate *priv = fontsel->priv;
894 PangoFontFace **faces;
895 PangoFontDescription *old_desc;
897 GtkTreeIter match_row;
898 PangoFontFace *match_face = NULL;
900 model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (priv->face_list)));
903 old_desc = pango_font_face_describe (priv->face);
907 pango_font_family_list_faces (priv->family, &faces, &n_faces);
908 qsort (faces, n_faces, sizeof (PangoFontFace *), faces_sort_func);
910 gtk_list_store_clear (model);
912 for (i=0; i < n_faces; i++)
915 const gchar *str = pango_font_face_get_face_name (faces[i]);
917 gtk_list_store_append (model, &iter);
918 gtk_list_store_set (model, &iter,
919 FACE_COLUMN, faces[i],
920 FACE_NAME_COLUMN, str,
926 match_face = faces[i];
930 PangoFontDescription *tmp_desc = pango_font_face_describe (faces[i]);
932 if (font_description_style_equal (tmp_desc, old_desc))
935 match_face = faces[i];
938 pango_font_description_free (tmp_desc);
943 pango_font_description_free (old_desc);
945 gtk_font_selection_ref_face (fontsel, match_face);
948 #ifdef INCLUDE_FONT_ENTRIES
949 const gchar *str = pango_font_face_get_face_name (priv->face);
951 gtk_entry_set_text (GTK_ENTRY (priv->font_style_entry), str);
953 set_cursor_to_iter (GTK_TREE_VIEW (priv->face_list), &match_row);
959 /* This selects a style when the user selects a font. It just uses the first
960 available style at present. I was thinking of trying to maintain the
961 selected style, e.g. bold italic, when the user selects different fonts.
962 However, the interface is so easy to use now I'm not sure it's worth it.
963 Note: This will load a font. */
965 gtk_font_selection_select_best_style (GtkFontSelection *fontsel,
968 GtkFontSelectionPrivate *priv = fontsel->priv;
972 model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->face_list));
974 if (gtk_tree_model_get_iter_first (model, &iter))
976 set_cursor_to_iter (GTK_TREE_VIEW (priv->face_list), &iter);
977 scroll_to_selection (GTK_TREE_VIEW (priv->face_list));
980 gtk_font_selection_show_available_sizes (fontsel, FALSE);
981 gtk_font_selection_select_best_size (fontsel);
985 /* This is called when a style is selected in the list. */
987 gtk_font_selection_select_style (GtkTreeSelection *selection,
990 GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
994 if (gtk_tree_selection_get_selected (selection, &model, &iter))
998 gtk_tree_model_get (model, &iter, FACE_COLUMN, &face, -1);
999 gtk_font_selection_ref_face (fontsel, face);
1000 g_object_unref (face);
1003 gtk_font_selection_show_available_sizes (fontsel, FALSE);
1004 gtk_font_selection_select_best_size (fontsel);
1008 gtk_font_selection_show_available_sizes (GtkFontSelection *fontsel,
1009 gboolean first_time)
1011 GtkFontSelectionPrivate *priv = fontsel->priv;
1013 GtkListStore *model;
1017 model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (priv->size_list)));
1019 /* Insert the standard font sizes */
1022 gtk_list_store_clear (model);
1024 for (i = 0; i < G_N_ELEMENTS (font_sizes); i++)
1028 gtk_list_store_append (model, &iter);
1029 gtk_list_store_set (model, &iter, SIZE_COLUMN, font_sizes[i], -1);
1031 if (font_sizes[i] * PANGO_SCALE == priv->size)
1032 set_cursor_to_iter (GTK_TREE_VIEW (priv->size_list), &iter);
1038 gboolean found = FALSE;
1040 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &iter);
1041 for (i = 0; i < G_N_ELEMENTS (font_sizes) && !found; i++)
1043 if (font_sizes[i] * PANGO_SCALE == priv->size)
1045 set_cursor_to_iter (GTK_TREE_VIEW (priv->size_list), &iter);
1049 gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &iter);
1054 GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->size_list));
1055 gtk_tree_selection_unselect_all (selection);
1059 /* Set the entry to the new size, rounding to 1 digit,
1060 * trimming of trailing 0's and a trailing period
1062 g_snprintf (buffer, sizeof (buffer), "%.1f", priv->size / (1.0 * PANGO_SCALE));
1063 if (strchr (buffer, '.'))
1065 p = buffer + strlen (buffer) - 1;
1073 /* Compare, to avoid moving the cursor unecessarily */
1074 if (strcmp (gtk_entry_get_text (GTK_ENTRY (priv->size_entry)), buffer) != 0)
1075 gtk_entry_set_text (GTK_ENTRY (priv->size_entry), buffer);
1079 gtk_font_selection_select_best_size (GtkFontSelection *fontsel)
1081 gtk_font_selection_load_font (fontsel);
1085 gtk_font_selection_set_size (GtkFontSelection *fontsel,
1088 GtkFontSelectionPrivate *priv = fontsel->priv;
1090 if (priv->size != new_size)
1092 priv->size = new_size;
1094 gtk_font_selection_show_available_sizes (fontsel, FALSE);
1095 gtk_font_selection_load_font (fontsel);
1099 /* If the user hits return in the font size entry, we change to the new font
1102 gtk_font_selection_size_activate (GtkWidget *w,
1105 GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
1106 GtkFontSelectionPrivate *priv = fontsel->priv;
1110 text = gtk_entry_get_text (GTK_ENTRY (priv->size_entry));
1111 new_size = MAX (0.1, atof (text) * PANGO_SCALE + 0.5);
1113 if (priv->size != new_size)
1114 gtk_font_selection_set_size (fontsel, new_size);
1116 list_row_activated (w);
1120 gtk_font_selection_size_focus_out (GtkWidget *w,
1121 GdkEventFocus *event,
1124 GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
1125 GtkFontSelectionPrivate *priv = fontsel->priv;
1129 text = gtk_entry_get_text (GTK_ENTRY (priv->size_entry));
1130 new_size = MAX (0.1, atof (text) * PANGO_SCALE + 0.5);
1132 gtk_font_selection_set_size (fontsel, new_size);
1137 /* This is called when a size is selected in the list. */
1139 gtk_font_selection_select_size (GtkTreeSelection *selection,
1142 GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
1143 GtkTreeModel *model;
1147 if (gtk_tree_selection_get_selected (selection, &model, &iter))
1149 gtk_tree_model_get (model, &iter, SIZE_COLUMN, &new_size, -1);
1150 gtk_font_selection_set_size (fontsel, new_size * PANGO_SCALE);
1155 gtk_font_selection_load_font (GtkFontSelection *fontsel)
1157 gtk_font_selection_update_preview (fontsel);
1160 static PangoFontDescription *
1161 gtk_font_selection_get_font_description (GtkFontSelection *fontsel)
1163 GtkFontSelectionPrivate *priv = fontsel->priv;
1164 PangoFontDescription *font_desc;
1168 font_desc = pango_font_face_describe (priv->face);
1169 pango_font_description_set_size (font_desc, priv->size);
1172 font_desc = pango_font_description_from_string (DEFAULT_FONT_NAME);
1177 /* This sets the font in the preview entry to the selected font,
1178 * and tries to make sure that the preview entry is a reasonable
1179 * size, i.e. so that the text can be seen with a bit of space to
1180 * spare. But it tries to avoid resizing the entry every time the
1181 * font changes. This also used to shrink the preview if the font
1182 * size was decreased, but that made it awkward if the user wanted
1183 * to resize the window themself.
1186 gtk_font_selection_update_preview (GtkFontSelection *fontsel)
1188 GtkFontSelectionPrivate *priv = fontsel->priv;
1190 GtkRequisition old_requisition, new_requisition;
1191 GtkWidget *preview_entry = priv->preview_entry;
1194 gtk_widget_get_preferred_size (preview_entry, &old_requisition, NULL);
1196 gtk_widget_override_font (preview_entry,
1197 gtk_font_selection_get_font_description (fontsel));
1199 gtk_widget_get_preferred_size (preview_entry, &new_requisition, NULL);
1201 /* We don't ever want to be over MAX_PREVIEW_HEIGHT pixels high. */
1202 new_height = CLAMP (new_requisition.height, INITIAL_PREVIEW_HEIGHT, MAX_PREVIEW_HEIGHT);
1204 if (new_height > old_requisition.height || new_height < old_requisition.height - 30)
1205 gtk_widget_set_size_request (preview_entry, -1, new_height);
1207 /* This sets the preview text, if it hasn't been set already. */
1208 text = gtk_entry_get_text (GTK_ENTRY (preview_entry));
1209 if (strlen (text) == 0)
1210 gtk_entry_set_text (GTK_ENTRY (preview_entry), _(PREVIEW_TEXT));
1211 gtk_editable_set_position (GTK_EDITABLE (preview_entry), 0);
1215 /*****************************************************************************
1216 * These functions are the main public interface for getting/setting the font.
1217 *****************************************************************************/
1220 * gtk_font_selection_get_family_list:
1221 * @fontsel: a #GtkFontSelection
1223 * This returns the #GtkTreeView that lists font families, for
1224 * example, 'Sans', 'Serif', etc.
1226 * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1231 gtk_font_selection_get_family_list (GtkFontSelection *fontsel)
1233 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1235 return fontsel->priv->family_list;
1239 * gtk_font_selection_get_face_list:
1240 * @fontsel: a #GtkFontSelection
1242 * This returns the #GtkTreeView which lists all styles available for
1243 * the selected font. For example, 'Regular', 'Bold', etc.
1245 * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1250 gtk_font_selection_get_face_list (GtkFontSelection *fontsel)
1252 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1254 return fontsel->priv->face_list;
1258 * gtk_font_selection_get_size_entry:
1259 * @fontsel: a #GtkFontSelection
1261 * This returns the #GtkEntry used to allow the user to edit the font
1262 * number manually instead of selecting it from the list of font sizes.
1264 * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1269 gtk_font_selection_get_size_entry (GtkFontSelection *fontsel)
1271 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1273 return fontsel->priv->size_entry;
1277 * gtk_font_selection_get_size_list:
1278 * @fontsel: a #GtkFontSelection
1280 * This returns the #GtkTreeeView used to list font sizes.
1282 * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1287 gtk_font_selection_get_size_list (GtkFontSelection *fontsel)
1289 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1291 return fontsel->priv->size_list;
1295 * gtk_font_selection_get_preview_entry:
1296 * @fontsel: a #GtkFontSelection
1298 * This returns the #GtkEntry used to display the font as a preview.
1300 * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1305 gtk_font_selection_get_preview_entry (GtkFontSelection *fontsel)
1307 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1309 return fontsel->priv->preview_entry;
1313 * gtk_font_selection_get_family:
1314 * @fontsel: a #GtkFontSelection
1316 * Gets the #PangoFontFamily representing the selected font family.
1318 * Return value: (transfer none): A #PangoFontFamily representing the
1319 * selected font family. Font families are a collection of font
1320 * faces. The returned object is owned by @fontsel and must not
1321 * be modified or freed.
1326 gtk_font_selection_get_family (GtkFontSelection *fontsel)
1328 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1330 return fontsel->priv->family;
1334 * gtk_font_selection_get_face:
1335 * @fontsel: a #GtkFontSelection
1337 * Gets the #PangoFontFace representing the selected font group
1338 * details (i.e. family, slant, weight, width, etc).
1340 * Return value: (transfer none): A #PangoFontFace representing the
1341 * selected font group details. The returned object is owned by
1342 * @fontsel and must not be modified or freed.
1347 gtk_font_selection_get_face (GtkFontSelection *fontsel)
1349 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1351 return fontsel->priv->face;
1355 * gtk_font_selection_get_size:
1356 * @fontsel: a #GtkFontSelection
1358 * The selected font size.
1360 * Return value: A n integer representing the selected font size,
1361 * or -1 if no font size is selected.
1366 gtk_font_selection_get_size (GtkFontSelection *fontsel)
1368 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), -1);
1370 return fontsel->priv->size;
1374 * gtk_font_selection_get_font_name:
1375 * @fontsel: a #GtkFontSelection
1377 * Gets the currently-selected font name.
1379 * Note that this can be a different string than what you set with
1380 * gtk_font_selection_set_font_name(), as the font selection widget may
1381 * normalize font names and thus return a string with a different structure.
1382 * For example, "Helvetica Italic Bold 12" could be normalized to
1383 * "Helvetica Bold Italic 12". Use pango_font_description_equal()
1384 * if you want to compare two font descriptions.
1386 * Return value: A string with the name of the current font, or %NULL if
1387 * no font is selected. You must free this string with g_free().
1390 gtk_font_selection_get_font_name (GtkFontSelection *fontsel)
1394 PangoFontDescription *font_desc = gtk_font_selection_get_font_description (fontsel);
1395 result = pango_font_description_to_string (font_desc);
1396 pango_font_description_free (font_desc);
1401 /* This selects the appropriate list rows.
1402 First we check the fontname is valid and try to find the font family
1403 - i.e. the name in the main list. If we can't find that, then just return.
1404 Next we try to set each of the properties according to the fontname.
1405 Finally we select the font family & style in the lists. */
1407 gtk_font_selection_select_font_desc (GtkFontSelection *fontsel,
1408 PangoFontDescription *new_desc,
1409 PangoFontFamily **pfamily,
1410 PangoFontFace **pface)
1412 GtkFontSelectionPrivate *priv = fontsel->priv;
1413 PangoFontFamily *new_family = NULL;
1414 PangoFontFace *new_face = NULL;
1415 PangoFontFace *fallback_face = NULL;
1416 GtkTreeModel *model;
1418 GtkTreeIter match_iter;
1420 const gchar *new_family_name;
1422 new_family_name = pango_font_description_get_family (new_desc);
1424 if (!new_family_name)
1427 /* Check to make sure that this is in the list of allowed fonts
1429 model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->family_list));
1430 for (valid = gtk_tree_model_get_iter_first (model, &iter);
1432 valid = gtk_tree_model_iter_next (model, &iter))
1434 PangoFontFamily *family;
1436 gtk_tree_model_get (model, &iter, FAMILY_COLUMN, &family, -1);
1438 if (g_ascii_strcasecmp (pango_font_family_get_name (family),
1439 new_family_name) == 0)
1440 new_family = g_object_ref (family);
1442 g_object_unref (family);
1452 *pfamily = new_family;
1454 g_object_unref (new_family);
1455 set_cursor_to_iter (GTK_TREE_VIEW (priv->family_list), &iter);
1456 gtk_font_selection_show_available_styles (fontsel);
1458 model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->face_list));
1459 for (valid = gtk_tree_model_get_iter_first (model, &iter);
1461 valid = gtk_tree_model_iter_next (model, &iter))
1463 PangoFontFace *face;
1464 PangoFontDescription *tmp_desc;
1466 gtk_tree_model_get (model, &iter, FACE_COLUMN, &face, -1);
1467 tmp_desc = pango_font_face_describe (face);
1469 if (font_description_style_equal (tmp_desc, new_desc))
1470 new_face = g_object_ref (face);
1474 fallback_face = g_object_ref (face);
1478 pango_font_description_free (tmp_desc);
1479 g_object_unref (face);
1489 new_face = fallback_face;
1490 else if (fallback_face)
1491 g_object_unref (fallback_face);
1496 g_object_unref (new_face);
1497 set_cursor_to_iter (GTK_TREE_VIEW (priv->face_list), &match_iter);
1499 gtk_font_selection_set_size (fontsel, pango_font_description_get_size (new_desc));
1505 /* This sets the current font, then selecting the appropriate list rows. */
1508 * gtk_font_selection_set_font_name:
1509 * @fontsel: a #GtkFontSelection
1510 * @fontname: a font name like "Helvetica 12" or "Times Bold 18"
1512 * Sets the currently-selected font.
1514 * Note that the @fontsel needs to know the screen in which it will appear
1515 * for this to work; this can be guaranteed by simply making sure that the
1516 * @fontsel is inserted in a toplevel window before you call this function.
1518 * Return value: %TRUE if the font could be set successfully; %FALSE if no
1519 * such font exists or if the @fontsel doesn't belong to a particular
1523 gtk_font_selection_set_font_name (GtkFontSelection *fontsel,
1524 const gchar *fontname)
1526 PangoFontFamily *family = NULL;
1527 PangoFontFace *face = NULL;
1528 PangoFontDescription *new_desc;
1530 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), FALSE);
1532 if (!gtk_widget_has_screen (GTK_WIDGET (fontsel)))
1535 new_desc = pango_font_description_from_string (fontname);
1537 if (gtk_font_selection_select_font_desc (fontsel, new_desc, &family, &face))
1539 gtk_font_selection_ref_family (fontsel, family);
1541 g_object_unref (family);
1543 gtk_font_selection_ref_face (fontsel, face);
1545 g_object_unref (face);
1548 pango_font_description_free (new_desc);
1550 g_object_notify (G_OBJECT (fontsel), "font-name");
1556 * gtk_font_selection_get_preview_text:
1557 * @fontsel: a #GtkFontSelection
1559 * Gets the text displayed in the preview area.
1561 * Return value: the text displayed in the preview area.
1562 * This string is owned by the widget and should not be
1565 G_CONST_RETURN gchar*
1566 gtk_font_selection_get_preview_text (GtkFontSelection *fontsel)
1568 GtkFontSelectionPrivate *priv;
1570 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1572 priv = fontsel->priv;
1574 return gtk_entry_get_text (GTK_ENTRY (priv->preview_entry));
1579 * gtk_font_selection_set_preview_text:
1580 * @fontsel: a #GtkFontSelection
1581 * @text: the text to display in the preview area
1583 * Sets the text displayed in the preview area.
1584 * The @text is used to show how the selected font looks.
1587 gtk_font_selection_set_preview_text (GtkFontSelection *fontsel,
1590 GtkFontSelectionPrivate *priv;
1592 g_return_if_fail (GTK_IS_FONT_SELECTION (fontsel));
1593 g_return_if_fail (text != NULL);
1595 priv = fontsel->priv;
1597 gtk_entry_set_text (GTK_ENTRY (priv->preview_entry), text);
1602 * SECTION:gtkfontseldlg
1603 * @Short_description: A dialog box for selecting fonts
1604 * @Title: GtkFontSelectionDialog
1605 * @See_also: #GtkFontSelection, #GtkDialog
1607 * The #GtkFontSelectionDialog widget is a dialog box for selecting a font.
1609 * To set the font which is initially selected, use
1610 * gtk_font_selection_dialog_set_font_name().
1612 * To get the selected font use gtk_font_selection_dialog_get_font_name().
1614 * To change the text which is shown in the preview area, use
1615 * gtk_font_selection_dialog_set_preview_text().
1617 * <refsect2 id="GtkFontSelectionDialog-BUILDER-UI">
1618 * <title>GtkFontSelectionDialog as GtkBuildable</title>
1619 * The GtkFontSelectionDialog implementation of the GtkBuildable interface
1620 * exposes the embedded #GtkFontSelection as internal child with the
1621 * name "font_selection". It also exposes the buttons with the names
1622 * "ok_button", "cancel_button" and "apply_button".
1626 static void gtk_font_selection_dialog_buildable_interface_init (GtkBuildableIface *iface);
1627 static GObject * gtk_font_selection_dialog_buildable_get_internal_child (GtkBuildable *buildable,
1628 GtkBuilder *builder,
1629 const gchar *childname);
1631 G_DEFINE_TYPE_WITH_CODE (GtkFontSelectionDialog, gtk_font_selection_dialog,
1633 G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
1634 gtk_font_selection_dialog_buildable_interface_init))
1636 static GtkBuildableIface *parent_buildable_iface;
1639 gtk_font_selection_dialog_class_init (GtkFontSelectionDialogClass *klass)
1641 g_type_class_add_private (klass, sizeof (GtkFontSelectionDialogPrivate));
1645 gtk_font_selection_dialog_init (GtkFontSelectionDialog *fontseldiag)
1647 GtkFontSelectionDialogPrivate *priv;
1648 GtkDialog *dialog = GTK_DIALOG (fontseldiag);
1649 GtkWidget *action_area, *content_area;
1651 fontseldiag->priv = G_TYPE_INSTANCE_GET_PRIVATE (fontseldiag,
1652 GTK_TYPE_FONT_SELECTION_DIALOG,
1653 GtkFontSelectionDialogPrivate);
1654 priv = fontseldiag->priv;
1656 content_area = gtk_dialog_get_content_area (dialog);
1657 action_area = gtk_dialog_get_action_area (dialog);
1659 gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
1660 gtk_box_set_spacing (GTK_BOX (content_area), 2); /* 2 * 5 + 2 = 12 */
1661 gtk_container_set_border_width (GTK_CONTAINER (action_area), 5);
1662 gtk_box_set_spacing (GTK_BOX (action_area), 6);
1664 gtk_widget_push_composite_child ();
1666 gtk_window_set_resizable (GTK_WINDOW (fontseldiag), TRUE);
1668 /* Create the content area */
1669 priv->fontsel = gtk_font_selection_new ();
1670 gtk_container_set_border_width (GTK_CONTAINER (priv->fontsel), 5);
1671 gtk_widget_show (priv->fontsel);
1672 gtk_box_pack_start (GTK_BOX (content_area),
1673 priv->fontsel, TRUE, TRUE, 0);
1675 /* Create the action area */
1676 priv->cancel_button = gtk_dialog_add_button (dialog,
1678 GTK_RESPONSE_CANCEL);
1680 priv->apply_button = gtk_dialog_add_button (dialog,
1682 GTK_RESPONSE_APPLY);
1683 gtk_widget_hide (priv->apply_button);
1685 priv->ok_button = gtk_dialog_add_button (dialog,
1688 gtk_widget_grab_default (priv->ok_button);
1690 gtk_dialog_set_alternative_button_order (GTK_DIALOG (fontseldiag),
1693 GTK_RESPONSE_CANCEL,
1696 gtk_window_set_title (GTK_WINDOW (fontseldiag),
1697 _("Font Selection"));
1699 gtk_widget_pop_composite_child ();
1703 * gtk_font_selection_dialog_new:
1704 * @title: the title of the dialog window
1706 * Creates a new #GtkFontSelectionDialog.
1708 * Return value: a new #GtkFontSelectionDialog
1711 gtk_font_selection_dialog_new (const gchar *title)
1713 GtkFontSelectionDialog *fontseldiag;
1715 fontseldiag = g_object_new (GTK_TYPE_FONT_SELECTION_DIALOG, NULL);
1718 gtk_window_set_title (GTK_WINDOW (fontseldiag), title);
1720 return GTK_WIDGET (fontseldiag);
1724 * gtk_font_selection_dialog_get_font_selection:
1725 * @fsd: a #GtkFontSelectionDialog
1727 * Retrieves the #GtkFontSelection widget embedded in the dialog.
1729 * Returns: (transfer none): the embedded #GtkFontSelection
1734 gtk_font_selection_dialog_get_font_selection (GtkFontSelectionDialog *fsd)
1736 g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1738 return fsd->priv->fontsel;
1743 * gtk_font_selection_dialog_get_ok_button:
1744 * @fsd: a #GtkFontSelectionDialog
1746 * Gets the 'OK' button.
1748 * Return value: (transfer none): the #GtkWidget used in the dialog
1749 * for the 'OK' button.
1754 gtk_font_selection_dialog_get_ok_button (GtkFontSelectionDialog *fsd)
1756 g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1758 return fsd->priv->ok_button;
1762 * gtk_font_selection_dialog_get_cancel_button:
1763 * @fsd: a #GtkFontSelectionDialog
1765 * Gets the 'Cancel' button.
1767 * Return value: (transfer none): the #GtkWidget used in the dialog
1768 * for the 'Cancel' button.
1773 gtk_font_selection_dialog_get_cancel_button (GtkFontSelectionDialog *fsd)
1775 g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1777 return fsd->priv->cancel_button;
1781 gtk_font_selection_dialog_buildable_interface_init (GtkBuildableIface *iface)
1783 parent_buildable_iface = g_type_interface_peek_parent (iface);
1784 iface->get_internal_child = gtk_font_selection_dialog_buildable_get_internal_child;
1788 gtk_font_selection_dialog_buildable_get_internal_child (GtkBuildable *buildable,
1789 GtkBuilder *builder,
1790 const gchar *childname)
1792 GtkFontSelectionDialogPrivate *priv;
1794 priv = GTK_FONT_SELECTION_DIALOG (buildable)->priv;
1796 if (g_strcmp0 (childname, "ok_button") == 0)
1797 return G_OBJECT (priv->ok_button);
1798 else if (g_strcmp0 (childname, "cancel_button") == 0)
1799 return G_OBJECT (priv->cancel_button);
1800 else if (g_strcmp0 (childname, "apply_button") == 0)
1801 return G_OBJECT (priv->apply_button);
1802 else if (g_strcmp0 (childname, "font_selection") == 0)
1803 return G_OBJECT (priv->fontsel);
1805 return parent_buildable_iface->get_internal_child (buildable, builder, childname);
1809 * gtk_font_selection_dialog_get_font_name:
1810 * @fsd: a #GtkFontSelectionDialog
1812 * Gets the currently-selected font name.
1814 * Note that this can be a different string than what you set with
1815 * gtk_font_selection_dialog_set_font_name(), as the font selection widget
1816 * may normalize font names and thus return a string with a different
1817 * structure. For example, "Helvetica Italic Bold 12" could be normalized
1818 * to "Helvetica Bold Italic 12". Use pango_font_description_equal()
1819 * if you want to compare two font descriptions.
1821 * Return value: A string with the name of the current font, or %NULL if no
1822 * font is selected. You must free this string with g_free().
1825 gtk_font_selection_dialog_get_font_name (GtkFontSelectionDialog *fsd)
1827 GtkFontSelectionDialogPrivate *priv;
1829 g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1833 return gtk_font_selection_get_font_name (GTK_FONT_SELECTION (priv->fontsel));
1837 * gtk_font_selection_dialog_set_font_name:
1838 * @fsd: a #GtkFontSelectionDialog
1839 * @fontname: a font name like "Helvetica 12" or "Times Bold 18"
1841 * Sets the currently selected font.
1843 * Return value: %TRUE if the font selected in @fsd is now the
1844 * @fontname specified, %FALSE otherwise.
1847 gtk_font_selection_dialog_set_font_name (GtkFontSelectionDialog *fsd,
1848 const gchar *fontname)
1850 GtkFontSelectionDialogPrivate *priv;
1852 g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), FALSE);
1853 g_return_val_if_fail (fontname, FALSE);
1857 return gtk_font_selection_set_font_name (GTK_FONT_SELECTION (priv->fontsel), fontname);
1861 * gtk_font_selection_dialog_get_preview_text:
1862 * @fsd: a #GtkFontSelectionDialog
1864 * Gets the text displayed in the preview area.
1866 * Return value: the text displayed in the preview area.
1867 * This string is owned by the widget and should not be
1870 G_CONST_RETURN gchar*
1871 gtk_font_selection_dialog_get_preview_text (GtkFontSelectionDialog *fsd)
1873 GtkFontSelectionDialogPrivate *priv;
1875 g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1879 return gtk_font_selection_get_preview_text (GTK_FONT_SELECTION (priv->fontsel));
1883 * gtk_font_selection_dialog_set_preview_text:
1884 * @fsd: a #GtkFontSelectionDialog
1885 * @text: the text to display in the preview area
1887 * Sets the text displayed in the preview area.
1890 gtk_font_selection_dialog_set_preview_text (GtkFontSelectionDialog *fsd,
1893 GtkFontSelectionDialogPrivate *priv;
1895 g_return_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd));
1896 g_return_if_fail (text != NULL);
1900 gtk_font_selection_set_preview_text (GTK_FONT_SELECTION (priv->fontsel), text);