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/.
34 #include <glib/gprintf.h>
40 #include "gdk/gdkkeysyms.h"
42 #include "gtkfontsel.h"
44 #include "gtkbutton.h"
45 #include "gtkcellrenderertext.h"
51 #include "gtkliststore.h"
55 #include "gtktreeselection.h"
56 #include "gtktreeview.h"
58 #include "gtkscrolledwindow.h"
60 #include "gtkaccessible.h"
61 #include "gtkbuildable.h"
62 #include "gtksizerequest.h"
63 #include "gtkprivate.h"
65 struct _GtkFontSelectionPrivate
67 GtkWidget *font_entry; /* Used _get_family_entry() for consistency, -mr */
68 GtkWidget *font_style_entry; /* Used _get_face_entry() for consistency, -mr */
70 GtkWidget *size_entry;
71 GtkWidget *preview_entry;
73 GtkWidget *family_list;
77 PangoFontFamily *family; /* Current family */
78 PangoFontFace *face; /* Current face */
84 struct _GtkFontSelectionDialogPrivate
89 GtkWidget *apply_button;
90 GtkWidget *cancel_button;
94 /* We don't enable the font and style entries because they don't add
95 * much in terms of visible effect and have a weird effect on keynav.
96 * the Windows font selector has entries similarly positioned but they
97 * act in conjunction with the associated lists to form a single focus
100 #undef INCLUDE_FONT_ENTRIES
102 /* This is the default text shown in the preview entry, though the user
103 can set it. Remember that some fonts only have capital letters. */
104 #define PREVIEW_TEXT N_("abcdefghijk ABCDEFGHIJK")
106 #define DEFAULT_FONT_NAME "Sans 10"
108 /* This is the initial and maximum height of the preview entry (it expands
109 when large font sizes are selected). Initial height is also the minimum. */
110 #define INITIAL_PREVIEW_HEIGHT 44
111 #define MAX_PREVIEW_HEIGHT 300
113 /* These are the sizes of the font, style & size lists. */
114 #define FONT_LIST_HEIGHT 136
115 #define FONT_LIST_WIDTH 190
116 #define FONT_STYLE_LIST_WIDTH 170
117 #define FONT_SIZE_LIST_WIDTH 60
119 /* These are what we use as the standard font sizes, for the size list.
121 static const guint16 font_sizes[] = {
122 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 22, 24, 26, 28,
123 32, 36, 40, 48, 56, 64, 72
147 static void gtk_font_selection_set_property (GObject *object,
151 static void gtk_font_selection_get_property (GObject *object,
155 static void gtk_font_selection_finalize (GObject *object);
156 static void gtk_font_selection_screen_changed (GtkWidget *widget,
157 GdkScreen *previous_screen);
158 static void gtk_font_selection_style_set (GtkWidget *widget,
159 GtkStyle *prev_style);
161 /* These are the callbacks & related functions. */
162 static void gtk_font_selection_select_font (GtkTreeSelection *selection,
164 static void gtk_font_selection_show_available_fonts (GtkFontSelection *fs);
166 static void gtk_font_selection_show_available_styles (GtkFontSelection *fs);
167 static void gtk_font_selection_select_best_style (GtkFontSelection *fs,
169 static void gtk_font_selection_select_style (GtkTreeSelection *selection,
172 static void gtk_font_selection_select_best_size (GtkFontSelection *fs);
173 static void gtk_font_selection_show_available_sizes (GtkFontSelection *fs,
174 gboolean first_time);
175 static void gtk_font_selection_size_activate (GtkWidget *w,
177 static gboolean gtk_font_selection_size_focus_out (GtkWidget *w,
178 GdkEventFocus *event,
180 static void gtk_font_selection_select_size (GtkTreeSelection *selection,
183 static void gtk_font_selection_scroll_on_map (GtkWidget *w,
186 static void gtk_font_selection_preview_changed (GtkWidget *entry,
187 GtkFontSelection *fontsel);
188 static void gtk_font_selection_scroll_to_selection (GtkFontSelection *fontsel);
191 /* Misc. utility functions. */
192 static void gtk_font_selection_load_font (GtkFontSelection *fs);
193 static void gtk_font_selection_update_preview (GtkFontSelection *fs);
195 static PangoFontDescription *gtk_font_selection_get_font_description (GtkFontSelection *fontsel);
196 static gboolean gtk_font_selection_select_font_desc (GtkFontSelection *fontsel,
197 PangoFontDescription *new_desc,
198 PangoFontFamily **pfamily,
199 PangoFontFace **pface);
200 static void gtk_font_selection_reload_fonts (GtkFontSelection *fontsel);
201 static void gtk_font_selection_ref_family (GtkFontSelection *fontsel,
202 PangoFontFamily *family);
203 static void gtk_font_selection_ref_face (GtkFontSelection *fontsel,
204 PangoFontFace *face);
206 G_DEFINE_TYPE (GtkFontSelection, gtk_font_selection, GTK_TYPE_VBOX)
209 gtk_font_selection_class_init (GtkFontSelectionClass *klass)
211 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
212 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
214 gobject_class->finalize = gtk_font_selection_finalize;
215 gobject_class->set_property = gtk_font_selection_set_property;
216 gobject_class->get_property = gtk_font_selection_get_property;
218 widget_class->screen_changed = gtk_font_selection_screen_changed;
219 widget_class->style_set = gtk_font_selection_style_set;
221 g_object_class_install_property (gobject_class,
223 g_param_spec_string ("font-name",
225 P_("The string that represents this font"),
227 GTK_PARAM_READWRITE));
228 g_object_class_install_property (gobject_class,
230 g_param_spec_string ("preview-text",
232 P_("The text to display in order to demonstrate the selected font"),
234 GTK_PARAM_READWRITE));
236 g_type_class_add_private (klass, sizeof (GtkFontSelectionPrivate));
240 gtk_font_selection_set_property (GObject *object,
245 GtkFontSelection *fontsel;
247 fontsel = GTK_FONT_SELECTION (object);
252 gtk_font_selection_set_font_name (fontsel, g_value_get_string (value));
254 case PROP_PREVIEW_TEXT:
255 gtk_font_selection_set_preview_text (fontsel, g_value_get_string (value));
258 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
263 static void gtk_font_selection_get_property (GObject *object,
268 GtkFontSelection *fontsel;
270 fontsel = GTK_FONT_SELECTION (object);
275 g_value_take_string (value, gtk_font_selection_get_font_name (fontsel));
277 case PROP_PREVIEW_TEXT:
278 g_value_set_string (value, gtk_font_selection_get_preview_text (fontsel));
281 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
286 /* Handles key press events on the lists, so that we can trap Enter to
287 * activate the default button on our own.
290 list_row_activated (GtkWidget *widget)
292 GtkWidget *default_widget, *focus_widget;
295 window = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (widget)));
296 if (!gtk_widget_is_toplevel (GTK_WIDGET (window)))
301 default_widget = gtk_window_get_default_widget (window);
302 focus_widget = gtk_window_get_focus (window);
304 if (widget != default_widget &&
305 !(widget == focus_widget && (!default_widget || !gtk_widget_get_sensitive (default_widget))))
306 gtk_window_activate_default (window);
313 gtk_font_selection_init (GtkFontSelection *fontsel)
315 GtkFontSelectionPrivate *priv;
316 GtkWidget *scrolled_win;
318 GtkWidget *table, *label;
319 GtkWidget *font_label, *style_label;
322 GtkTreeViewColumn *column;
323 GList *focus_chain = NULL;
326 fontsel->priv = G_TYPE_INSTANCE_GET_PRIVATE (fontsel,
327 GTK_TYPE_FONT_SELECTION,
328 GtkFontSelectionPrivate);
329 priv = fontsel->priv;
331 gtk_widget_push_composite_child ();
333 gtk_box_set_spacing (GTK_BOX (fontsel), 12);
334 priv->size = 12 * PANGO_SCALE;
336 /* Create the table of font, style & size. */
337 table = gtk_table_new (3, 3, FALSE);
338 gtk_widget_show (table);
339 gtk_table_set_row_spacings (GTK_TABLE (table), 6);
340 gtk_table_set_col_spacings (GTK_TABLE (table), 12);
341 gtk_box_pack_start (GTK_BOX (fontsel), table, TRUE, TRUE, 0);
343 #ifdef INCLUDE_FONT_ENTRIES
344 priv->font_entry = gtk_entry_new ();
345 gtk_editable_set_editable (GTK_EDITABLE (priv->font_entry), FALSE);
346 gtk_widget_set_size_request (priv->font_entry, 20, -1);
347 gtk_widget_show (priv->font_entry);
348 gtk_table_attach (GTK_TABLE (table), priv->font_entry, 0, 1, 1, 2,
351 priv->font_style_entry = gtk_entry_new ();
352 gtk_editable_set_editable (GTK_EDITABLE (priv->font_style_entry), FALSE);
353 gtk_widget_set_size_request (priv->font_style_entry, 20, -1);
354 gtk_widget_show (priv->font_style_entry);
355 gtk_table_attach (GTK_TABLE (table), priv->font_style_entry, 1, 2, 1, 2,
357 #endif /* INCLUDE_FONT_ENTRIES */
359 priv->size_entry = gtk_entry_new ();
360 gtk_widget_set_size_request (priv->size_entry, 20, -1);
361 gtk_widget_show (priv->size_entry);
362 gtk_table_attach (GTK_TABLE (table), priv->size_entry, 2, 3, 1, 2,
364 g_signal_connect (priv->size_entry, "activate",
365 G_CALLBACK (gtk_font_selection_size_activate),
367 g_signal_connect_after (priv->size_entry, "focus-out-event",
368 G_CALLBACK (gtk_font_selection_size_focus_out),
371 font_label = gtk_label_new_with_mnemonic (_("_Family:"));
372 gtk_misc_set_alignment (GTK_MISC (font_label), 0.0, 0.5);
373 gtk_widget_show (font_label);
374 gtk_table_attach (GTK_TABLE (table), font_label, 0, 1, 0, 1,
377 style_label = gtk_label_new_with_mnemonic (_("_Style:"));
378 gtk_misc_set_alignment (GTK_MISC (style_label), 0.0, 0.5);
379 gtk_widget_show (style_label);
380 gtk_table_attach (GTK_TABLE (table), style_label, 1, 2, 0, 1,
383 label = gtk_label_new_with_mnemonic (_("Si_ze:"));
384 gtk_label_set_mnemonic_widget (GTK_LABEL (label),
386 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
387 gtk_widget_show (label);
388 gtk_table_attach (GTK_TABLE (table), label, 2, 3, 0, 1,
392 /* Create the lists */
394 model = gtk_list_store_new (2,
395 G_TYPE_OBJECT, /* FAMILY_COLUMN */
396 G_TYPE_STRING); /* FAMILY_NAME_COLUMN */
397 priv->family_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
398 g_object_unref (model);
400 g_signal_connect (priv->family_list, "row-activated",
401 G_CALLBACK (list_row_activated), fontsel);
403 column = gtk_tree_view_column_new_with_attributes ("Family",
404 gtk_cell_renderer_text_new (),
405 "text", FAMILY_NAME_COLUMN,
407 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
408 gtk_tree_view_append_column (GTK_TREE_VIEW (priv->family_list), column);
410 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->family_list), FALSE);
411 gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->family_list)),
412 GTK_SELECTION_BROWSE);
414 gtk_label_set_mnemonic_widget (GTK_LABEL (font_label), priv->family_list);
416 scrolled_win = gtk_scrolled_window_new (NULL, NULL);
417 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), GTK_SHADOW_IN);
418 gtk_widget_set_size_request (scrolled_win,
419 FONT_LIST_WIDTH, FONT_LIST_HEIGHT);
420 gtk_container_add (GTK_CONTAINER (scrolled_win), priv->family_list);
421 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
422 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
423 gtk_widget_show (priv->family_list);
424 gtk_widget_show (scrolled_win);
426 gtk_table_attach (GTK_TABLE (table), scrolled_win, 0, 1, 1, 3,
427 GTK_EXPAND | GTK_FILL,
428 GTK_EXPAND | GTK_FILL, 0, 0);
429 focus_chain = g_list_append (focus_chain, scrolled_win);
431 model = gtk_list_store_new (2,
432 G_TYPE_OBJECT, /* FACE_COLUMN */
433 G_TYPE_STRING); /* FACE_NAME_COLUMN */
434 priv->face_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
435 g_object_unref (model);
436 g_signal_connect (priv->face_list, "row-activated",
437 G_CALLBACK (list_row_activated), fontsel);
439 gtk_label_set_mnemonic_widget (GTK_LABEL (style_label), priv->face_list);
441 column = gtk_tree_view_column_new_with_attributes ("Face",
442 gtk_cell_renderer_text_new (),
443 "text", FACE_NAME_COLUMN,
445 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
446 gtk_tree_view_append_column (GTK_TREE_VIEW (priv->face_list), column);
448 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->face_list), FALSE);
449 gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->face_list)),
450 GTK_SELECTION_BROWSE);
452 scrolled_win = gtk_scrolled_window_new (NULL, NULL);
453 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), GTK_SHADOW_IN);
454 gtk_widget_set_size_request (scrolled_win,
455 FONT_STYLE_LIST_WIDTH, FONT_LIST_HEIGHT);
456 gtk_container_add (GTK_CONTAINER (scrolled_win), priv->face_list);
457 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
458 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
459 gtk_widget_show (priv->face_list);
460 gtk_widget_show (scrolled_win);
461 gtk_table_attach (GTK_TABLE (table), scrolled_win, 1, 2, 1, 3,
462 GTK_EXPAND | GTK_FILL,
463 GTK_EXPAND | GTK_FILL, 0, 0);
464 focus_chain = g_list_append (focus_chain, scrolled_win);
466 focus_chain = g_list_append (focus_chain, priv->size_entry);
468 model = gtk_list_store_new (1, G_TYPE_INT);
469 priv->size_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
470 g_object_unref (model);
471 g_signal_connect (priv->size_list, "row-activated",
472 G_CALLBACK (list_row_activated), fontsel);
474 column = gtk_tree_view_column_new_with_attributes ("Size",
475 gtk_cell_renderer_text_new (),
478 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
479 gtk_tree_view_append_column (GTK_TREE_VIEW (priv->size_list), column);
481 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->size_list), FALSE);
482 gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->size_list)),
483 GTK_SELECTION_BROWSE);
485 scrolled_win = gtk_scrolled_window_new (NULL, NULL);
486 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), GTK_SHADOW_IN);
487 gtk_container_add (GTK_CONTAINER (scrolled_win), priv->size_list);
488 gtk_widget_set_size_request (scrolled_win, -1, FONT_LIST_HEIGHT);
489 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
490 GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
491 gtk_widget_show (priv->size_list);
492 gtk_widget_show (scrolled_win);
493 gtk_table_attach (GTK_TABLE (table), scrolled_win, 2, 3, 2, 3,
494 GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
495 focus_chain = g_list_append (focus_chain, scrolled_win);
497 gtk_container_set_focus_chain (GTK_CONTAINER (table), focus_chain);
498 g_list_free (focus_chain);
500 /* Insert the fonts. */
501 g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->family_list)), "changed",
502 G_CALLBACK (gtk_font_selection_select_font), fontsel);
504 g_signal_connect_after (priv->family_list, "map",
505 G_CALLBACK (gtk_font_selection_scroll_on_map),
508 g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->face_list)), "changed",
509 G_CALLBACK (gtk_font_selection_select_style), fontsel);
511 g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->size_list)), "changed",
512 G_CALLBACK (gtk_font_selection_select_size), fontsel);
513 atk_obj = gtk_widget_get_accessible (priv->size_list);
514 if (GTK_IS_ACCESSIBLE (atk_obj))
516 /* Accessibility support is enabled.
517 * Make the label ATK_RELATON_LABEL_FOR for the size list as well.
519 AtkObject *atk_label;
520 AtkRelationSet *relation_set;
521 AtkRelation *relation;
522 AtkObject *obj_array[1];
524 atk_label = gtk_widget_get_accessible (label);
525 relation_set = atk_object_ref_relation_set (atk_obj);
526 relation = atk_relation_set_get_relation_by_type (relation_set, ATK_RELATION_LABELLED_BY);
529 atk_relation_add_target (relation, atk_label);
533 obj_array[0] = atk_label;
534 relation = atk_relation_new (obj_array, 1, ATK_RELATION_LABELLED_BY);
535 atk_relation_set_add (relation_set, relation);
537 g_object_unref (relation_set);
539 relation_set = atk_object_ref_relation_set (atk_label);
540 relation = atk_relation_set_get_relation_by_type (relation_set, ATK_RELATION_LABEL_FOR);
543 atk_relation_add_target (relation, atk_obj);
547 obj_array[0] = atk_obj;
548 relation = atk_relation_new (obj_array, 1, ATK_RELATION_LABEL_FOR);
549 atk_relation_set_add (relation_set, relation);
551 g_object_unref (relation_set);
555 vbox = gtk_vbox_new (FALSE, 6);
556 gtk_widget_show (vbox);
557 gtk_box_pack_start (GTK_BOX (fontsel), vbox, FALSE, TRUE, 0);
559 /* create the text entry widget */
560 label = gtk_label_new_with_mnemonic (_("_Preview:"));
561 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
562 gtk_widget_show (label);
563 gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 0);
565 text_box = gtk_hbox_new (FALSE, 0);
566 gtk_widget_show (text_box);
567 gtk_box_pack_start (GTK_BOX (vbox), text_box, FALSE, TRUE, 0);
569 priv->preview_entry = gtk_entry_new ();
570 gtk_label_set_mnemonic_widget (GTK_LABEL (label), priv->preview_entry);
571 gtk_entry_set_text (GTK_ENTRY (priv->preview_entry), _(PREVIEW_TEXT));
573 gtk_widget_show (priv->preview_entry);
574 g_signal_connect (priv->preview_entry, "changed",
575 G_CALLBACK (gtk_font_selection_preview_changed), fontsel);
576 gtk_widget_set_size_request (priv->preview_entry,
577 -1, INITIAL_PREVIEW_HEIGHT);
578 gtk_box_pack_start (GTK_BOX (text_box), priv->preview_entry,
580 gtk_widget_pop_composite_child();
584 * gtk_font_selection_new:
586 * Creates a new #GtkFontSelection.
588 * Return value: a n ew #GtkFontSelection
591 gtk_font_selection_new (void)
593 GtkFontSelection *fontsel;
595 fontsel = g_object_new (GTK_TYPE_FONT_SELECTION, NULL);
597 return GTK_WIDGET (fontsel);
601 gtk_font_selection_finalize (GObject *object)
603 GtkFontSelection *fontsel = GTK_FONT_SELECTION (object);
605 gtk_font_selection_ref_family (fontsel, NULL);
606 gtk_font_selection_ref_face (fontsel, NULL);
608 G_OBJECT_CLASS (gtk_font_selection_parent_class)->finalize (object);
612 gtk_font_selection_ref_family (GtkFontSelection *fontsel,
613 PangoFontFamily *family)
615 GtkFontSelectionPrivate *priv = fontsel->priv;
618 family = g_object_ref (family);
620 g_object_unref (priv->family);
621 priv->family = family;
624 static void gtk_font_selection_ref_face (GtkFontSelection *fontsel,
627 GtkFontSelectionPrivate *priv = fontsel->priv;
630 face = g_object_ref (face);
632 g_object_unref (priv->face);
637 gtk_font_selection_reload_fonts (GtkFontSelection *fontsel)
639 if (gtk_widget_has_screen (GTK_WIDGET (fontsel)))
641 PangoFontDescription *desc;
642 desc = gtk_font_selection_get_font_description (fontsel);
644 gtk_font_selection_show_available_fonts (fontsel);
645 gtk_font_selection_show_available_sizes (fontsel, TRUE);
646 gtk_font_selection_show_available_styles (fontsel);
648 gtk_font_selection_select_font_desc (fontsel, desc, NULL, NULL);
649 gtk_font_selection_scroll_to_selection (fontsel);
651 pango_font_description_free (desc);
656 gtk_font_selection_screen_changed (GtkWidget *widget,
657 GdkScreen *previous_screen)
659 gtk_font_selection_reload_fonts (GTK_FONT_SELECTION (widget));
663 gtk_font_selection_style_set (GtkWidget *widget,
664 GtkStyle *prev_style)
666 /* Maybe fonts where installed or removed... */
667 gtk_font_selection_reload_fonts (GTK_FONT_SELECTION (widget));
671 gtk_font_selection_preview_changed (GtkWidget *entry,
672 GtkFontSelection *fontsel)
674 g_object_notify (G_OBJECT (fontsel), "preview-text");
678 scroll_to_selection (GtkTreeView *tree_view)
680 GtkTreeSelection *selection = gtk_tree_view_get_selection (tree_view);
684 if (gtk_tree_selection_get_selected (selection, &model, &iter))
686 GtkTreePath *path = gtk_tree_model_get_path (model, &iter);
687 gtk_tree_view_scroll_to_cell (tree_view, path, NULL, TRUE, 0.5, 0.5);
688 gtk_tree_path_free (path);
693 set_cursor_to_iter (GtkTreeView *view,
696 GtkTreeModel *model = gtk_tree_view_get_model (view);
697 GtkTreePath *path = gtk_tree_model_get_path (model, iter);
699 gtk_tree_view_set_cursor (view, path, NULL, FALSE);
701 gtk_tree_path_free (path);
705 gtk_font_selection_scroll_to_selection (GtkFontSelection *fontsel)
707 GtkFontSelectionPrivate *priv = fontsel->priv;
709 /* Try to scroll the font family list to the selected item */
710 scroll_to_selection (GTK_TREE_VIEW (priv->family_list));
712 /* Try to scroll the font family list to the selected item */
713 scroll_to_selection (GTK_TREE_VIEW (priv->face_list));
715 /* Try to scroll the font family list to the selected item */
716 scroll_to_selection (GTK_TREE_VIEW (priv->size_list));
717 /* This is called when the list is mapped. Here we scroll to the current
718 font if necessary. */
722 gtk_font_selection_scroll_on_map (GtkWidget *widget,
725 gtk_font_selection_scroll_to_selection (GTK_FONT_SELECTION (data));
728 /* This is called when a family is selected in the list. */
730 gtk_font_selection_select_font (GtkTreeSelection *selection,
733 GtkFontSelection *fontsel;
734 GtkFontSelectionPrivate *priv;
737 #ifdef INCLUDE_FONT_ENTRIES
738 const gchar *family_name;
741 fontsel = GTK_FONT_SELECTION (data);
742 priv = fontsel->priv;
744 if (gtk_tree_selection_get_selected (selection, &model, &iter))
746 PangoFontFamily *family;
748 gtk_tree_model_get (model, &iter, FAMILY_COLUMN, &family, -1);
749 if (priv->family != family)
751 gtk_font_selection_ref_family (fontsel, family);
753 #ifdef INCLUDE_FONT_ENTRIES
754 family_name = pango_font_family_get_name (priv->family);
755 gtk_entry_set_text (GTK_ENTRY (priv->font_entry), family_name);
758 gtk_font_selection_show_available_styles (fontsel);
759 gtk_font_selection_select_best_style (fontsel, TRUE);
762 g_object_unref (family);
767 cmp_families (const void *a, const void *b)
769 const char *a_name = pango_font_family_get_name (*(PangoFontFamily **)a);
770 const char *b_name = pango_font_family_get_name (*(PangoFontFamily **)b);
772 return g_utf8_collate (a_name, b_name);
776 gtk_font_selection_show_available_fonts (GtkFontSelection *fontsel)
778 GtkFontSelectionPrivate *priv = fontsel->priv;
780 PangoFontFamily **families;
781 PangoFontFamily *match_family = NULL;
783 GtkTreeIter match_row;
785 model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (priv->family_list)));
787 pango_context_list_families (gtk_widget_get_pango_context (GTK_WIDGET (fontsel)),
788 &families, &n_families);
789 qsort (families, n_families, sizeof (PangoFontFamily *), cmp_families);
791 gtk_list_store_clear (model);
793 for (i=0; i<n_families; i++)
795 const gchar *name = pango_font_family_get_name (families[i]);
798 gtk_list_store_append (model, &iter);
799 gtk_list_store_set (model, &iter,
800 FAMILY_COLUMN, families[i],
801 FAMILY_NAME_COLUMN, name,
804 if (i == 0 || !g_ascii_strcasecmp (name, "sans"))
806 match_family = families[i];
811 gtk_font_selection_ref_family (fontsel, match_family);
814 set_cursor_to_iter (GTK_TREE_VIEW (priv->family_list), &match_row);
815 #ifdef INCLUDE_FONT_ENTRIES
816 gtk_entry_set_text (GTK_ENTRY (priv->font_entry),
817 pango_font_family_get_name (match_family));
818 #endif /* INCLUDE_FONT_ENTRIES */
825 compare_font_descriptions (const PangoFontDescription *a, const PangoFontDescription *b)
827 int val = strcmp (pango_font_description_get_family (a), pango_font_description_get_family (b));
831 if (pango_font_description_get_weight (a) != pango_font_description_get_weight (b))
832 return pango_font_description_get_weight (a) - pango_font_description_get_weight (b);
834 if (pango_font_description_get_style (a) != pango_font_description_get_style (b))
835 return pango_font_description_get_style (a) - pango_font_description_get_style (b);
837 if (pango_font_description_get_stretch (a) != pango_font_description_get_stretch (b))
838 return pango_font_description_get_stretch (a) - pango_font_description_get_stretch (b);
840 if (pango_font_description_get_variant (a) != pango_font_description_get_variant (b))
841 return pango_font_description_get_variant (a) - pango_font_description_get_variant (b);
847 faces_sort_func (const void *a, const void *b)
849 PangoFontDescription *desc_a = pango_font_face_describe (*(PangoFontFace **)a);
850 PangoFontDescription *desc_b = pango_font_face_describe (*(PangoFontFace **)b);
852 int ord = compare_font_descriptions (desc_a, desc_b);
854 pango_font_description_free (desc_a);
855 pango_font_description_free (desc_b);
861 font_description_style_equal (const PangoFontDescription *a,
862 const PangoFontDescription *b)
864 return (pango_font_description_get_weight (a) == pango_font_description_get_weight (b) &&
865 pango_font_description_get_style (a) == pango_font_description_get_style (b) &&
866 pango_font_description_get_stretch (a) == pango_font_description_get_stretch (b) &&
867 pango_font_description_get_variant (a) == pango_font_description_get_variant (b));
870 /* This fills the font style list with all the possible style combinations
871 for the current font family. */
873 gtk_font_selection_show_available_styles (GtkFontSelection *fontsel)
875 GtkFontSelectionPrivate *priv = fontsel->priv;
877 PangoFontFace **faces;
878 PangoFontDescription *old_desc;
880 GtkTreeIter match_row;
881 PangoFontFace *match_face = NULL;
883 model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (priv->face_list)));
886 old_desc = pango_font_face_describe (priv->face);
890 pango_font_family_list_faces (priv->family, &faces, &n_faces);
891 qsort (faces, n_faces, sizeof (PangoFontFace *), faces_sort_func);
893 gtk_list_store_clear (model);
895 for (i=0; i < n_faces; i++)
898 const gchar *str = pango_font_face_get_face_name (faces[i]);
900 gtk_list_store_append (model, &iter);
901 gtk_list_store_set (model, &iter,
902 FACE_COLUMN, faces[i],
903 FACE_NAME_COLUMN, str,
909 match_face = faces[i];
913 PangoFontDescription *tmp_desc = pango_font_face_describe (faces[i]);
915 if (font_description_style_equal (tmp_desc, old_desc))
918 match_face = faces[i];
921 pango_font_description_free (tmp_desc);
926 pango_font_description_free (old_desc);
928 gtk_font_selection_ref_face (fontsel, match_face);
931 #ifdef INCLUDE_FONT_ENTRIES
932 const gchar *str = pango_font_face_get_face_name (priv->face);
934 gtk_entry_set_text (GTK_ENTRY (priv->font_style_entry), str);
936 set_cursor_to_iter (GTK_TREE_VIEW (priv->face_list), &match_row);
942 /* This selects a style when the user selects a font. It just uses the first
943 available style at present. I was thinking of trying to maintain the
944 selected style, e.g. bold italic, when the user selects different fonts.
945 However, the interface is so easy to use now I'm not sure it's worth it.
946 Note: This will load a font. */
948 gtk_font_selection_select_best_style (GtkFontSelection *fontsel,
951 GtkFontSelectionPrivate *priv = fontsel->priv;
955 model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->face_list));
957 if (gtk_tree_model_get_iter_first (model, &iter))
959 set_cursor_to_iter (GTK_TREE_VIEW (priv->face_list), &iter);
960 scroll_to_selection (GTK_TREE_VIEW (priv->face_list));
963 gtk_font_selection_show_available_sizes (fontsel, FALSE);
964 gtk_font_selection_select_best_size (fontsel);
968 /* This is called when a style is selected in the list. */
970 gtk_font_selection_select_style (GtkTreeSelection *selection,
973 GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
977 if (gtk_tree_selection_get_selected (selection, &model, &iter))
981 gtk_tree_model_get (model, &iter, FACE_COLUMN, &face, -1);
982 gtk_font_selection_ref_face (fontsel, face);
983 g_object_unref (face);
986 gtk_font_selection_show_available_sizes (fontsel, FALSE);
987 gtk_font_selection_select_best_size (fontsel);
991 gtk_font_selection_show_available_sizes (GtkFontSelection *fontsel,
994 GtkFontSelectionPrivate *priv = fontsel->priv;
1000 model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (priv->size_list)));
1002 /* Insert the standard font sizes */
1005 gtk_list_store_clear (model);
1007 for (i = 0; i < G_N_ELEMENTS (font_sizes); i++)
1011 gtk_list_store_append (model, &iter);
1012 gtk_list_store_set (model, &iter, SIZE_COLUMN, font_sizes[i], -1);
1014 if (font_sizes[i] * PANGO_SCALE == priv->size)
1015 set_cursor_to_iter (GTK_TREE_VIEW (priv->size_list), &iter);
1021 gboolean found = FALSE;
1023 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &iter);
1024 for (i = 0; i < G_N_ELEMENTS (font_sizes) && !found; i++)
1026 if (font_sizes[i] * PANGO_SCALE == priv->size)
1028 set_cursor_to_iter (GTK_TREE_VIEW (priv->size_list), &iter);
1032 gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &iter);
1037 GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->size_list));
1038 gtk_tree_selection_unselect_all (selection);
1042 /* Set the entry to the new size, rounding to 1 digit,
1043 * trimming of trailing 0's and a trailing period
1045 g_snprintf (buffer, sizeof (buffer), "%.1f", priv->size / (1.0 * PANGO_SCALE));
1046 if (strchr (buffer, '.'))
1048 p = buffer + strlen (buffer) - 1;
1056 /* Compare, to avoid moving the cursor unecessarily */
1057 if (strcmp (gtk_entry_get_text (GTK_ENTRY (priv->size_entry)), buffer) != 0)
1058 gtk_entry_set_text (GTK_ENTRY (priv->size_entry), buffer);
1062 gtk_font_selection_select_best_size (GtkFontSelection *fontsel)
1064 gtk_font_selection_load_font (fontsel);
1068 gtk_font_selection_set_size (GtkFontSelection *fontsel,
1071 GtkFontSelectionPrivate *priv = fontsel->priv;
1073 if (priv->size != new_size)
1075 priv->size = new_size;
1077 gtk_font_selection_show_available_sizes (fontsel, FALSE);
1078 gtk_font_selection_load_font (fontsel);
1082 /* If the user hits return in the font size entry, we change to the new font
1085 gtk_font_selection_size_activate (GtkWidget *w,
1088 GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
1089 GtkFontSelectionPrivate *priv = fontsel->priv;
1093 text = gtk_entry_get_text (GTK_ENTRY (priv->size_entry));
1094 new_size = MAX (0.1, atof (text) * PANGO_SCALE + 0.5);
1096 if (priv->size != new_size)
1097 gtk_font_selection_set_size (fontsel, new_size);
1099 list_row_activated (w);
1103 gtk_font_selection_size_focus_out (GtkWidget *w,
1104 GdkEventFocus *event,
1107 GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
1108 GtkFontSelectionPrivate *priv = fontsel->priv;
1112 text = gtk_entry_get_text (GTK_ENTRY (priv->size_entry));
1113 new_size = MAX (0.1, atof (text) * PANGO_SCALE + 0.5);
1115 gtk_font_selection_set_size (fontsel, new_size);
1120 /* This is called when a size is selected in the list. */
1122 gtk_font_selection_select_size (GtkTreeSelection *selection,
1125 GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
1126 GtkTreeModel *model;
1130 if (gtk_tree_selection_get_selected (selection, &model, &iter))
1132 gtk_tree_model_get (model, &iter, SIZE_COLUMN, &new_size, -1);
1133 gtk_font_selection_set_size (fontsel, new_size * PANGO_SCALE);
1138 gtk_font_selection_load_font (GtkFontSelection *fontsel)
1140 gtk_font_selection_update_preview (fontsel);
1143 static PangoFontDescription *
1144 gtk_font_selection_get_font_description (GtkFontSelection *fontsel)
1146 GtkFontSelectionPrivate *priv = fontsel->priv;
1147 PangoFontDescription *font_desc;
1151 font_desc = pango_font_face_describe (priv->face);
1152 pango_font_description_set_size (font_desc, priv->size);
1155 font_desc = pango_font_description_from_string (DEFAULT_FONT_NAME);
1160 /* This sets the font in the preview entry to the selected font, and tries to
1161 make sure that the preview entry is a reasonable size, i.e. so that the
1162 text can be seen with a bit of space to spare. But it tries to avoid
1163 resizing the entry every time the font changes.
1164 This also used to shrink the preview if the font size was decreased, but
1165 that made it awkward if the user wanted to resize the window themself. */
1167 gtk_font_selection_update_preview (GtkFontSelection *fontsel)
1169 GtkFontSelectionPrivate *priv = fontsel->priv;
1170 GtkRcStyle *rc_style;
1172 GtkRequisition old_requisition, new_requisition;
1173 GtkWidget *preview_entry = priv->preview_entry;
1176 gtk_size_request_get_size (GTK_SIZE_REQUEST (preview_entry),
1177 &old_requisition, NULL);
1179 rc_style = gtk_rc_style_new ();
1180 rc_style->font_desc = gtk_font_selection_get_font_description (fontsel);
1182 gtk_widget_modify_style (preview_entry, rc_style);
1183 g_object_unref (rc_style);
1185 gtk_size_request_get_size (GTK_SIZE_REQUEST (preview_entry), &new_requisition, NULL);
1187 /* We don't ever want to be over MAX_PREVIEW_HEIGHT pixels high. */
1188 new_height = CLAMP (new_requisition.height, INITIAL_PREVIEW_HEIGHT, MAX_PREVIEW_HEIGHT);
1190 if (new_height > old_requisition.height || new_height < old_requisition.height - 30)
1191 gtk_widget_set_size_request (preview_entry, -1, new_height);
1193 /* This sets the preview text, if it hasn't been set already. */
1194 text = gtk_entry_get_text (GTK_ENTRY (preview_entry));
1195 if (strlen (text) == 0)
1196 gtk_entry_set_text (GTK_ENTRY (preview_entry), _(PREVIEW_TEXT));
1197 gtk_editable_set_position (GTK_EDITABLE (preview_entry), 0);
1201 /*****************************************************************************
1202 * These functions are the main public interface for getting/setting the font.
1203 *****************************************************************************/
1206 * gtk_font_selection_get_family_list:
1207 * @fontsel: a #GtkFontSelection
1209 * This returns the #GtkTreeView that lists font families, for
1210 * example, 'Sans', 'Serif', etc.
1212 * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1217 gtk_font_selection_get_family_list (GtkFontSelection *fontsel)
1219 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1221 return fontsel->priv->family_list;
1225 * gtk_font_selection_get_face_list:
1226 * @fontsel: a #GtkFontSelection
1228 * This returns the #GtkTreeView which lists all styles available for
1229 * the selected font. For example, 'Regular', 'Bold', etc.
1231 * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1236 gtk_font_selection_get_face_list (GtkFontSelection *fontsel)
1238 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1240 return fontsel->priv->face_list;
1244 * gtk_font_selection_get_size_entry:
1245 * @fontsel: a #GtkFontSelection
1247 * This returns the #GtkEntry used to allow the user to edit the font
1248 * number manually instead of selecting it from the list of font sizes.
1250 * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1255 gtk_font_selection_get_size_entry (GtkFontSelection *fontsel)
1257 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1259 return fontsel->priv->size_entry;
1263 * gtk_font_selection_get_size_list:
1264 * @fontsel: a #GtkFontSelection
1266 * This returns the #GtkTreeeView used to list font sizes.
1268 * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1273 gtk_font_selection_get_size_list (GtkFontSelection *fontsel)
1275 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1277 return fontsel->priv->size_list;
1281 * gtk_font_selection_get_preview_entry:
1282 * @fontsel: a #GtkFontSelection
1284 * This returns the #GtkEntry used to display the font as a preview.
1286 * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1291 gtk_font_selection_get_preview_entry (GtkFontSelection *fontsel)
1293 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1295 return fontsel->priv->preview_entry;
1299 * gtk_font_selection_get_family:
1300 * @fontsel: a #GtkFontSelection
1302 * Gets the #PangoFontFamily representing the selected font family.
1304 * Return value: (transfer none): A #PangoFontFamily representing the
1305 * selected font family. Font families are a collection of font
1306 * faces. The returned object is owned by @fontsel and must not
1307 * be modified or freed.
1312 gtk_font_selection_get_family (GtkFontSelection *fontsel)
1314 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1316 return fontsel->priv->family;
1320 * gtk_font_selection_get_face:
1321 * @fontsel: a #GtkFontSelection
1323 * Gets the #PangoFontFace representing the selected font group
1324 * details (i.e. family, slant, weight, width, etc).
1326 * Return value: (transfer none): A #PangoFontFace representing the
1327 * selected font group details. The returned object is owned by
1328 * @fontsel and must not be modified or freed.
1333 gtk_font_selection_get_face (GtkFontSelection *fontsel)
1335 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1337 return fontsel->priv->face;
1341 * gtk_font_selection_get_size:
1342 * @fontsel: a #GtkFontSelection
1344 * The selected font size.
1346 * Return value: A n integer representing the selected font size,
1347 * or -1 if no font size is selected.
1352 gtk_font_selection_get_size (GtkFontSelection *fontsel)
1354 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), -1);
1356 return fontsel->priv->size;
1360 * gtk_font_selection_get_font_name:
1361 * @fontsel: a #GtkFontSelection
1363 * Gets the currently-selected font name.
1365 * Note that this can be a different string than what you set with
1366 * gtk_font_selection_set_font_name(), as the font selection widget may
1367 * normalize font names and thus return a string with a different structure.
1368 * For example, "Helvetica Italic Bold 12" could be normalized to
1369 * "Helvetica Bold Italic 12". Use pango_font_description_equal()
1370 * if you want to compare two font descriptions.
1372 * Return value: A string with the name of the current font, or %NULL if
1373 * no font is selected. You must free this string with g_free().
1376 gtk_font_selection_get_font_name (GtkFontSelection *fontsel)
1380 PangoFontDescription *font_desc = gtk_font_selection_get_font_description (fontsel);
1381 result = pango_font_description_to_string (font_desc);
1382 pango_font_description_free (font_desc);
1387 /* This selects the appropriate list rows.
1388 First we check the fontname is valid and try to find the font family
1389 - i.e. the name in the main list. If we can't find that, then just return.
1390 Next we try to set each of the properties according to the fontname.
1391 Finally we select the font family & style in the lists. */
1393 gtk_font_selection_select_font_desc (GtkFontSelection *fontsel,
1394 PangoFontDescription *new_desc,
1395 PangoFontFamily **pfamily,
1396 PangoFontFace **pface)
1398 GtkFontSelectionPrivate *priv = fontsel->priv;
1399 PangoFontFamily *new_family = NULL;
1400 PangoFontFace *new_face = NULL;
1401 PangoFontFace *fallback_face = NULL;
1402 GtkTreeModel *model;
1404 GtkTreeIter match_iter;
1406 const gchar *new_family_name;
1408 new_family_name = pango_font_description_get_family (new_desc);
1410 if (!new_family_name)
1413 /* Check to make sure that this is in the list of allowed fonts
1415 model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->family_list));
1416 for (valid = gtk_tree_model_get_iter_first (model, &iter);
1418 valid = gtk_tree_model_iter_next (model, &iter))
1420 PangoFontFamily *family;
1422 gtk_tree_model_get (model, &iter, FAMILY_COLUMN, &family, -1);
1424 if (g_ascii_strcasecmp (pango_font_family_get_name (family),
1425 new_family_name) == 0)
1426 new_family = g_object_ref (family);
1428 g_object_unref (family);
1438 *pfamily = new_family;
1440 g_object_unref (new_family);
1441 set_cursor_to_iter (GTK_TREE_VIEW (priv->family_list), &iter);
1442 gtk_font_selection_show_available_styles (fontsel);
1444 model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->face_list));
1445 for (valid = gtk_tree_model_get_iter_first (model, &iter);
1447 valid = gtk_tree_model_iter_next (model, &iter))
1449 PangoFontFace *face;
1450 PangoFontDescription *tmp_desc;
1452 gtk_tree_model_get (model, &iter, FACE_COLUMN, &face, -1);
1453 tmp_desc = pango_font_face_describe (face);
1455 if (font_description_style_equal (tmp_desc, new_desc))
1456 new_face = g_object_ref (face);
1460 fallback_face = g_object_ref (face);
1464 pango_font_description_free (tmp_desc);
1465 g_object_unref (face);
1475 new_face = fallback_face;
1476 else if (fallback_face)
1477 g_object_unref (fallback_face);
1482 g_object_unref (new_face);
1483 set_cursor_to_iter (GTK_TREE_VIEW (priv->face_list), &match_iter);
1485 gtk_font_selection_set_size (fontsel, pango_font_description_get_size (new_desc));
1491 /* This sets the current font, then selecting the appropriate list rows. */
1494 * gtk_font_selection_set_font_name:
1495 * @fontsel: a #GtkFontSelection
1496 * @fontname: a font name like "Helvetica 12" or "Times Bold 18"
1498 * Sets the currently-selected font.
1500 * Note that the @fontsel needs to know the screen in which it will appear
1501 * for this to work; this can be guaranteed by simply making sure that the
1502 * @fontsel is inserted in a toplevel window before you call this function.
1504 * Return value: %TRUE if the font could be set successfully; %FALSE if no
1505 * such font exists or if the @fontsel doesn't belong to a particular
1509 gtk_font_selection_set_font_name (GtkFontSelection *fontsel,
1510 const gchar *fontname)
1512 PangoFontFamily *family = NULL;
1513 PangoFontFace *face = NULL;
1514 PangoFontDescription *new_desc;
1516 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), FALSE);
1518 if (!gtk_widget_has_screen (GTK_WIDGET (fontsel)))
1521 new_desc = pango_font_description_from_string (fontname);
1523 if (gtk_font_selection_select_font_desc (fontsel, new_desc, &family, &face))
1525 gtk_font_selection_ref_family (fontsel, family);
1527 g_object_unref (family);
1529 gtk_font_selection_ref_face (fontsel, face);
1531 g_object_unref (face);
1534 pango_font_description_free (new_desc);
1536 g_object_notify (G_OBJECT (fontsel), "font-name");
1542 * gtk_font_selection_get_preview_text:
1543 * @fontsel: a #GtkFontSelection
1545 * Gets the text displayed in the preview area.
1547 * Return value: the text displayed in the preview area.
1548 * This string is owned by the widget and should not be
1551 G_CONST_RETURN gchar*
1552 gtk_font_selection_get_preview_text (GtkFontSelection *fontsel)
1554 GtkFontSelectionPrivate *priv;
1556 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1558 priv = fontsel->priv;
1560 return gtk_entry_get_text (GTK_ENTRY (priv->preview_entry));
1565 * gtk_font_selection_set_preview_text:
1566 * @fontsel: a #GtkFontSelection
1567 * @text: the text to display in the preview area
1569 * Sets the text displayed in the preview area.
1570 * The @text is used to show how the selected font looks.
1573 gtk_font_selection_set_preview_text (GtkFontSelection *fontsel,
1576 GtkFontSelectionPrivate *priv;
1578 g_return_if_fail (GTK_IS_FONT_SELECTION (fontsel));
1579 g_return_if_fail (text != NULL);
1581 priv = fontsel->priv;
1583 gtk_entry_set_text (GTK_ENTRY (priv->preview_entry), text);
1586 /*****************************************************************************
1587 * GtkFontSelectionDialog
1588 *****************************************************************************/
1590 static void gtk_font_selection_dialog_buildable_interface_init (GtkBuildableIface *iface);
1591 static GObject * gtk_font_selection_dialog_buildable_get_internal_child (GtkBuildable *buildable,
1592 GtkBuilder *builder,
1593 const gchar *childname);
1595 G_DEFINE_TYPE_WITH_CODE (GtkFontSelectionDialog, gtk_font_selection_dialog,
1597 G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
1598 gtk_font_selection_dialog_buildable_interface_init))
1600 static GtkBuildableIface *parent_buildable_iface;
1603 gtk_font_selection_dialog_class_init (GtkFontSelectionDialogClass *klass)
1605 g_type_class_add_private (klass, sizeof (GtkFontSelectionDialogPrivate));
1609 gtk_font_selection_dialog_init (GtkFontSelectionDialog *fontseldiag)
1611 GtkFontSelectionDialogPrivate *priv;
1612 GtkDialog *dialog = GTK_DIALOG (fontseldiag);
1613 GtkWidget *action_area, *content_area;
1615 fontseldiag->priv = G_TYPE_INSTANCE_GET_PRIVATE (fontseldiag,
1616 GTK_TYPE_FONT_SELECTION_DIALOG,
1617 GtkFontSelectionDialogPrivate);
1618 priv = fontseldiag->priv;
1620 content_area = gtk_dialog_get_content_area (dialog);
1621 action_area = gtk_dialog_get_action_area (dialog);
1623 gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
1624 gtk_box_set_spacing (GTK_BOX (content_area), 2); /* 2 * 5 + 2 = 12 */
1625 gtk_container_set_border_width (GTK_CONTAINER (action_area), 5);
1626 gtk_box_set_spacing (GTK_BOX (action_area), 6);
1628 gtk_widget_push_composite_child ();
1630 gtk_window_set_resizable (GTK_WINDOW (fontseldiag), TRUE);
1632 /* Create the content area */
1633 priv->fontsel = gtk_font_selection_new ();
1634 gtk_container_set_border_width (GTK_CONTAINER (priv->fontsel), 5);
1635 gtk_widget_show (priv->fontsel);
1636 gtk_box_pack_start (GTK_BOX (content_area),
1637 priv->fontsel, TRUE, TRUE, 0);
1639 /* Create the action area */
1640 priv->cancel_button = gtk_dialog_add_button (dialog,
1642 GTK_RESPONSE_CANCEL);
1644 priv->apply_button = gtk_dialog_add_button (dialog,
1646 GTK_RESPONSE_APPLY);
1647 gtk_widget_hide (priv->apply_button);
1649 priv->ok_button = gtk_dialog_add_button (dialog,
1652 gtk_widget_grab_default (priv->ok_button);
1654 gtk_dialog_set_alternative_button_order (GTK_DIALOG (fontseldiag),
1657 GTK_RESPONSE_CANCEL,
1660 gtk_window_set_title (GTK_WINDOW (fontseldiag),
1661 _("Font Selection"));
1663 gtk_widget_pop_composite_child ();
1667 * gtk_font_selection_dialog_new:
1668 * @title: the title of the dialog window
1670 * Creates a new #GtkFontSelectionDialog.
1672 * Return value: a new #GtkFontSelectionDialog
1675 gtk_font_selection_dialog_new (const gchar *title)
1677 GtkFontSelectionDialog *fontseldiag;
1679 fontseldiag = g_object_new (GTK_TYPE_FONT_SELECTION_DIALOG, NULL);
1682 gtk_window_set_title (GTK_WINDOW (fontseldiag), title);
1684 return GTK_WIDGET (fontseldiag);
1688 * gtk_font_selection_dialog_get_font_selection:
1689 * @fsd: a #GtkFontSelectionDialog
1691 * Retrieves the #GtkFontSelection widget embedded in the dialog.
1693 * Returns: (transfer none): the embedded #GtkFontSelection
1698 gtk_font_selection_dialog_get_font_selection (GtkFontSelectionDialog *fsd)
1700 g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1702 return fsd->priv->fontsel;
1707 * gtk_font_selection_dialog_get_ok_button:
1708 * @fsd: a #GtkFontSelectionDialog
1710 * Gets the 'OK' button.
1712 * Return value: (transfer none): the #GtkWidget used in the dialog
1713 * for the 'OK' button.
1718 gtk_font_selection_dialog_get_ok_button (GtkFontSelectionDialog *fsd)
1720 g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1722 return fsd->priv->ok_button;
1726 * gtk_font_selection_dialog_get_cancel_button:
1727 * @fsd: a #GtkFontSelectionDialog
1729 * Gets the 'Cancel' button.
1731 * Return value: (transfer none): the #GtkWidget used in the dialog
1732 * for the 'Cancel' button.
1737 gtk_font_selection_dialog_get_cancel_button (GtkFontSelectionDialog *fsd)
1739 g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1741 return fsd->priv->cancel_button;
1745 gtk_font_selection_dialog_buildable_interface_init (GtkBuildableIface *iface)
1747 parent_buildable_iface = g_type_interface_peek_parent (iface);
1748 iface->get_internal_child = gtk_font_selection_dialog_buildable_get_internal_child;
1752 gtk_font_selection_dialog_buildable_get_internal_child (GtkBuildable *buildable,
1753 GtkBuilder *builder,
1754 const gchar *childname)
1756 GtkFontSelectionDialogPrivate *priv;
1758 priv = GTK_FONT_SELECTION_DIALOG (buildable)->priv;
1760 if (g_strcmp0 (childname, "ok_button") == 0)
1761 return G_OBJECT (priv->ok_button);
1762 else if (g_strcmp0 (childname, "cancel_button") == 0)
1763 return G_OBJECT (priv->cancel_button);
1764 else if (g_strcmp0 (childname, "apply_button") == 0)
1765 return G_OBJECT (priv->apply_button);
1766 else if (g_strcmp0 (childname, "font_selection") == 0)
1767 return G_OBJECT (priv->fontsel);
1769 return parent_buildable_iface->get_internal_child (buildable, builder, childname);
1773 * gtk_font_selection_dialog_get_font_name:
1774 * @fsd: a #GtkFontSelectionDialog
1776 * Gets the currently-selected font name.
1778 * Note that this can be a different string than what you set with
1779 * gtk_font_selection_dialog_set_font_name(), as the font selection widget
1780 * may normalize font names and thus return a string with a different
1781 * structure. For example, "Helvetica Italic Bold 12" could be normalized
1782 * to "Helvetica Bold Italic 12". Use pango_font_description_equal()
1783 * if you want to compare two font descriptions.
1785 * Return value: A string with the name of the current font, or %NULL if no
1786 * font is selected. You must free this string with g_free().
1789 gtk_font_selection_dialog_get_font_name (GtkFontSelectionDialog *fsd)
1791 GtkFontSelectionDialogPrivate *priv;
1793 g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1797 return gtk_font_selection_get_font_name (GTK_FONT_SELECTION (priv->fontsel));
1801 * gtk_font_selection_dialog_set_font_name:
1802 * @fsd: a #GtkFontSelectionDialog
1803 * @fontname: a font name like "Helvetica 12" or "Times Bold 18"
1805 * Sets the currently selected font.
1807 * Return value: %TRUE if the font selected in @fsd is now the
1808 * @fontname specified, %FALSE otherwise.
1811 gtk_font_selection_dialog_set_font_name (GtkFontSelectionDialog *fsd,
1812 const gchar *fontname)
1814 GtkFontSelectionDialogPrivate *priv;
1816 g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), FALSE);
1817 g_return_val_if_fail (fontname, FALSE);
1821 return gtk_font_selection_set_font_name (GTK_FONT_SELECTION (priv->fontsel), fontname);
1825 * gtk_font_selection_dialog_get_preview_text:
1826 * @fsd: a #GtkFontSelectionDialog
1828 * Gets the text displayed in the preview area.
1830 * Return value: the text displayed in the preview area.
1831 * This string is owned by the widget and should not be
1834 G_CONST_RETURN gchar*
1835 gtk_font_selection_dialog_get_preview_text (GtkFontSelectionDialog *fsd)
1837 GtkFontSelectionDialogPrivate *priv;
1839 g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1843 return gtk_font_selection_get_preview_text (GTK_FONT_SELECTION (priv->fontsel));
1847 * gtk_font_selection_dialog_set_preview_text:
1848 * @fsd: a #GtkFontSelectionDialog
1849 * @text: the text to display in the preview area
1851 * Sets the text displayed in the preview area.
1854 gtk_font_selection_dialog_set_preview_text (GtkFontSelectionDialog *fsd,
1857 GtkFontSelectionDialogPrivate *priv;
1859 g_return_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd));
1860 g_return_if_fail (text != NULL);
1864 gtk_font_selection_set_preview_text (GTK_FONT_SELECTION (priv->fontsel), text);