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 "gtkprivate.h"
64 struct _GtkFontSelectionPrivate
66 GtkWidget *font_entry; /* Used _get_family_entry() for consistency, -mr */
67 GtkWidget *font_style_entry; /* Used _get_face_entry() for consistency, -mr */
69 GtkWidget *size_entry;
70 GtkWidget *preview_entry;
72 GtkWidget *family_list;
76 PangoFontFamily *family; /* Current family */
77 PangoFontFace *face; /* Current face */
83 struct _GtkFontSelectionDialogPrivate
88 GtkWidget *apply_button;
89 GtkWidget *cancel_button;
93 /* We don't enable the font and style entries because they don't add
94 * much in terms of visible effect and have a weird effect on keynav.
95 * the Windows font selector has entries similarly positioned but they
96 * act in conjunction with the associated lists to form a single focus
99 #undef INCLUDE_FONT_ENTRIES
101 /* This is the default text shown in the preview entry, though the user
102 can set it. Remember that some fonts only have capital letters. */
103 #define PREVIEW_TEXT N_("abcdefghijk ABCDEFGHIJK")
105 #define DEFAULT_FONT_NAME "Sans 10"
107 /* This is the initial and maximum height of the preview entry (it expands
108 when large font sizes are selected). Initial height is also the minimum. */
109 #define INITIAL_PREVIEW_HEIGHT 44
110 #define MAX_PREVIEW_HEIGHT 300
112 /* These are the sizes of the font, style & size lists. */
113 #define FONT_LIST_HEIGHT 136
114 #define FONT_LIST_WIDTH 190
115 #define FONT_STYLE_LIST_WIDTH 170
116 #define FONT_SIZE_LIST_WIDTH 60
118 /* These are what we use as the standard font sizes, for the size list.
120 static const guint16 font_sizes[] = {
121 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 22, 24, 26, 28,
122 32, 36, 40, 48, 56, 64, 72
146 static void gtk_font_selection_set_property (GObject *object,
150 static void gtk_font_selection_get_property (GObject *object,
154 static void gtk_font_selection_finalize (GObject *object);
155 static void gtk_font_selection_screen_changed (GtkWidget *widget,
156 GdkScreen *previous_screen);
157 static void gtk_font_selection_style_set (GtkWidget *widget,
158 GtkStyle *prev_style);
160 /* These are the callbacks & related functions. */
161 static void gtk_font_selection_select_font (GtkTreeSelection *selection,
163 static void gtk_font_selection_show_available_fonts (GtkFontSelection *fs);
165 static void gtk_font_selection_show_available_styles (GtkFontSelection *fs);
166 static void gtk_font_selection_select_best_style (GtkFontSelection *fs,
168 static void gtk_font_selection_select_style (GtkTreeSelection *selection,
171 static void gtk_font_selection_select_best_size (GtkFontSelection *fs);
172 static void gtk_font_selection_show_available_sizes (GtkFontSelection *fs,
173 gboolean first_time);
174 static void gtk_font_selection_size_activate (GtkWidget *w,
176 static gboolean gtk_font_selection_size_focus_out (GtkWidget *w,
177 GdkEventFocus *event,
179 static void gtk_font_selection_select_size (GtkTreeSelection *selection,
182 static void gtk_font_selection_scroll_on_map (GtkWidget *w,
185 static void gtk_font_selection_preview_changed (GtkWidget *entry,
186 GtkFontSelection *fontsel);
187 static void gtk_font_selection_scroll_to_selection (GtkFontSelection *fontsel);
190 /* Misc. utility functions. */
191 static void gtk_font_selection_load_font (GtkFontSelection *fs);
192 static void gtk_font_selection_update_preview (GtkFontSelection *fs);
194 static PangoFontDescription *gtk_font_selection_get_font_description (GtkFontSelection *fontsel);
195 static gboolean gtk_font_selection_select_font_desc (GtkFontSelection *fontsel,
196 PangoFontDescription *new_desc,
197 PangoFontFamily **pfamily,
198 PangoFontFace **pface);
199 static void gtk_font_selection_reload_fonts (GtkFontSelection *fontsel);
200 static void gtk_font_selection_ref_family (GtkFontSelection *fontsel,
201 PangoFontFamily *family);
202 static void gtk_font_selection_ref_face (GtkFontSelection *fontsel,
203 PangoFontFace *face);
205 G_DEFINE_TYPE (GtkFontSelection, gtk_font_selection, GTK_TYPE_VBOX)
208 gtk_font_selection_class_init (GtkFontSelectionClass *klass)
210 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
211 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
213 gobject_class->finalize = gtk_font_selection_finalize;
214 gobject_class->set_property = gtk_font_selection_set_property;
215 gobject_class->get_property = gtk_font_selection_get_property;
217 widget_class->screen_changed = gtk_font_selection_screen_changed;
218 widget_class->style_set = gtk_font_selection_style_set;
220 g_object_class_install_property (gobject_class,
222 g_param_spec_string ("font-name",
224 P_("The string that represents this font"),
226 GTK_PARAM_READWRITE));
227 g_object_class_install_property (gobject_class,
229 g_param_spec_string ("preview-text",
231 P_("The text to display in order to demonstrate the selected font"),
233 GTK_PARAM_READWRITE));
235 g_type_class_add_private (klass, sizeof (GtkFontSelectionPrivate));
239 gtk_font_selection_set_property (GObject *object,
244 GtkFontSelection *fontsel;
246 fontsel = GTK_FONT_SELECTION (object);
251 gtk_font_selection_set_font_name (fontsel, g_value_get_string (value));
253 case PROP_PREVIEW_TEXT:
254 gtk_font_selection_set_preview_text (fontsel, g_value_get_string (value));
257 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
262 static void gtk_font_selection_get_property (GObject *object,
267 GtkFontSelection *fontsel;
269 fontsel = GTK_FONT_SELECTION (object);
274 g_value_take_string (value, gtk_font_selection_get_font_name (fontsel));
276 case PROP_PREVIEW_TEXT:
277 g_value_set_string (value, gtk_font_selection_get_preview_text (fontsel));
280 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
285 /* Handles key press events on the lists, so that we can trap Enter to
286 * activate the default button on our own.
289 list_row_activated (GtkWidget *widget)
291 GtkWidget *default_widget, *focus_widget;
294 window = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (widget)));
295 if (!gtk_widget_is_toplevel (GTK_WIDGET (window)))
300 default_widget = gtk_window_get_default_widget (window);
301 focus_widget = gtk_window_get_focus (window);
303 if (widget != default_widget &&
304 !(widget == focus_widget && (!default_widget || !gtk_widget_get_sensitive (default_widget))))
305 gtk_window_activate_default (window);
312 gtk_font_selection_init (GtkFontSelection *fontsel)
314 GtkFontSelectionPrivate *priv;
315 GtkWidget *scrolled_win;
317 GtkWidget *table, *label;
318 GtkWidget *font_label, *style_label;
321 GtkTreeViewColumn *column;
322 GList *focus_chain = NULL;
325 fontsel->priv = G_TYPE_INSTANCE_GET_PRIVATE (fontsel,
326 GTK_TYPE_FONT_SELECTION,
327 GtkFontSelectionPrivate);
328 priv = fontsel->priv;
330 gtk_widget_push_composite_child ();
332 gtk_box_set_spacing (GTK_BOX (fontsel), 12);
333 priv->size = 12 * PANGO_SCALE;
335 /* Create the table of font, style & size. */
336 table = gtk_table_new (3, 3, FALSE);
337 gtk_widget_show (table);
338 gtk_table_set_row_spacings (GTK_TABLE (table), 6);
339 gtk_table_set_col_spacings (GTK_TABLE (table), 12);
340 gtk_box_pack_start (GTK_BOX (fontsel), table, TRUE, TRUE, 0);
342 #ifdef INCLUDE_FONT_ENTRIES
343 priv->font_entry = gtk_entry_new ();
344 gtk_editable_set_editable (GTK_EDITABLE (priv->font_entry), FALSE);
345 gtk_widget_set_size_request (priv->font_entry, 20, -1);
346 gtk_widget_show (priv->font_entry);
347 gtk_table_attach (GTK_TABLE (table), priv->font_entry, 0, 1, 1, 2,
350 priv->font_style_entry = gtk_entry_new ();
351 gtk_editable_set_editable (GTK_EDITABLE (priv->font_style_entry), FALSE);
352 gtk_widget_set_size_request (priv->font_style_entry, 20, -1);
353 gtk_widget_show (priv->font_style_entry);
354 gtk_table_attach (GTK_TABLE (table), priv->font_style_entry, 1, 2, 1, 2,
356 #endif /* INCLUDE_FONT_ENTRIES */
358 priv->size_entry = gtk_entry_new ();
359 gtk_widget_set_size_request (priv->size_entry, 20, -1);
360 gtk_widget_show (priv->size_entry);
361 gtk_table_attach (GTK_TABLE (table), priv->size_entry, 2, 3, 1, 2,
363 g_signal_connect (priv->size_entry, "activate",
364 G_CALLBACK (gtk_font_selection_size_activate),
366 g_signal_connect_after (priv->size_entry, "focus-out-event",
367 G_CALLBACK (gtk_font_selection_size_focus_out),
370 font_label = gtk_label_new_with_mnemonic (_("_Family:"));
371 gtk_misc_set_alignment (GTK_MISC (font_label), 0.0, 0.5);
372 gtk_widget_show (font_label);
373 gtk_table_attach (GTK_TABLE (table), font_label, 0, 1, 0, 1,
376 style_label = gtk_label_new_with_mnemonic (_("_Style:"));
377 gtk_misc_set_alignment (GTK_MISC (style_label), 0.0, 0.5);
378 gtk_widget_show (style_label);
379 gtk_table_attach (GTK_TABLE (table), style_label, 1, 2, 0, 1,
382 label = gtk_label_new_with_mnemonic (_("Si_ze:"));
383 gtk_label_set_mnemonic_widget (GTK_LABEL (label),
385 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
386 gtk_widget_show (label);
387 gtk_table_attach (GTK_TABLE (table), label, 2, 3, 0, 1,
391 /* Create the lists */
393 model = gtk_list_store_new (2,
394 G_TYPE_OBJECT, /* FAMILY_COLUMN */
395 G_TYPE_STRING); /* FAMILY_NAME_COLUMN */
396 priv->family_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
397 g_object_unref (model);
399 g_signal_connect (priv->family_list, "row-activated",
400 G_CALLBACK (list_row_activated), fontsel);
402 column = gtk_tree_view_column_new_with_attributes ("Family",
403 gtk_cell_renderer_text_new (),
404 "text", FAMILY_NAME_COLUMN,
406 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
407 gtk_tree_view_append_column (GTK_TREE_VIEW (priv->family_list), column);
409 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->family_list), FALSE);
410 gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->family_list)),
411 GTK_SELECTION_BROWSE);
413 gtk_label_set_mnemonic_widget (GTK_LABEL (font_label), priv->family_list);
415 scrolled_win = gtk_scrolled_window_new (NULL, NULL);
416 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), GTK_SHADOW_IN);
417 gtk_widget_set_size_request (scrolled_win,
418 FONT_LIST_WIDTH, FONT_LIST_HEIGHT);
419 gtk_container_add (GTK_CONTAINER (scrolled_win), priv->family_list);
420 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
421 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
422 gtk_widget_show (priv->family_list);
423 gtk_widget_show (scrolled_win);
425 gtk_table_attach (GTK_TABLE (table), scrolled_win, 0, 1, 1, 3,
426 GTK_EXPAND | GTK_FILL,
427 GTK_EXPAND | GTK_FILL, 0, 0);
428 focus_chain = g_list_append (focus_chain, scrolled_win);
430 model = gtk_list_store_new (2,
431 G_TYPE_OBJECT, /* FACE_COLUMN */
432 G_TYPE_STRING); /* FACE_NAME_COLUMN */
433 priv->face_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
434 g_object_unref (model);
435 g_signal_connect (priv->face_list, "row-activated",
436 G_CALLBACK (list_row_activated), fontsel);
438 gtk_label_set_mnemonic_widget (GTK_LABEL (style_label), priv->face_list);
440 column = gtk_tree_view_column_new_with_attributes ("Face",
441 gtk_cell_renderer_text_new (),
442 "text", FACE_NAME_COLUMN,
444 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
445 gtk_tree_view_append_column (GTK_TREE_VIEW (priv->face_list), column);
447 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->face_list), FALSE);
448 gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->face_list)),
449 GTK_SELECTION_BROWSE);
451 scrolled_win = gtk_scrolled_window_new (NULL, NULL);
452 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), GTK_SHADOW_IN);
453 gtk_widget_set_size_request (scrolled_win,
454 FONT_STYLE_LIST_WIDTH, FONT_LIST_HEIGHT);
455 gtk_container_add (GTK_CONTAINER (scrolled_win), priv->face_list);
456 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
457 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
458 gtk_widget_show (priv->face_list);
459 gtk_widget_show (scrolled_win);
460 gtk_table_attach (GTK_TABLE (table), scrolled_win, 1, 2, 1, 3,
461 GTK_EXPAND | GTK_FILL,
462 GTK_EXPAND | GTK_FILL, 0, 0);
463 focus_chain = g_list_append (focus_chain, scrolled_win);
465 focus_chain = g_list_append (focus_chain, priv->size_entry);
467 model = gtk_list_store_new (1, G_TYPE_INT);
468 priv->size_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
469 g_object_unref (model);
470 g_signal_connect (priv->size_list, "row-activated",
471 G_CALLBACK (list_row_activated), fontsel);
473 column = gtk_tree_view_column_new_with_attributes ("Size",
474 gtk_cell_renderer_text_new (),
477 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
478 gtk_tree_view_append_column (GTK_TREE_VIEW (priv->size_list), column);
480 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->size_list), FALSE);
481 gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->size_list)),
482 GTK_SELECTION_BROWSE);
484 scrolled_win = gtk_scrolled_window_new (NULL, NULL);
485 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), GTK_SHADOW_IN);
486 gtk_container_add (GTK_CONTAINER (scrolled_win), priv->size_list);
487 gtk_widget_set_size_request (scrolled_win, -1, FONT_LIST_HEIGHT);
488 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
489 GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
490 gtk_widget_show (priv->size_list);
491 gtk_widget_show (scrolled_win);
492 gtk_table_attach (GTK_TABLE (table), scrolled_win, 2, 3, 2, 3,
493 GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
494 focus_chain = g_list_append (focus_chain, scrolled_win);
496 gtk_container_set_focus_chain (GTK_CONTAINER (table), focus_chain);
497 g_list_free (focus_chain);
499 /* Insert the fonts. */
500 g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->family_list)), "changed",
501 G_CALLBACK (gtk_font_selection_select_font), fontsel);
503 g_signal_connect_after (priv->family_list, "map",
504 G_CALLBACK (gtk_font_selection_scroll_on_map),
507 g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->face_list)), "changed",
508 G_CALLBACK (gtk_font_selection_select_style), fontsel);
510 g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->size_list)), "changed",
511 G_CALLBACK (gtk_font_selection_select_size), fontsel);
512 atk_obj = gtk_widget_get_accessible (priv->size_list);
513 if (GTK_IS_ACCESSIBLE (atk_obj))
515 /* Accessibility support is enabled.
516 * Make the label ATK_RELATON_LABEL_FOR for the size list as well.
518 AtkObject *atk_label;
519 AtkRelationSet *relation_set;
520 AtkRelation *relation;
521 AtkObject *obj_array[1];
523 atk_label = gtk_widget_get_accessible (label);
524 relation_set = atk_object_ref_relation_set (atk_obj);
525 relation = atk_relation_set_get_relation_by_type (relation_set, ATK_RELATION_LABELLED_BY);
528 atk_relation_add_target (relation, atk_label);
532 obj_array[0] = atk_label;
533 relation = atk_relation_new (obj_array, 1, ATK_RELATION_LABELLED_BY);
534 atk_relation_set_add (relation_set, relation);
536 g_object_unref (relation_set);
538 relation_set = atk_object_ref_relation_set (atk_label);
539 relation = atk_relation_set_get_relation_by_type (relation_set, ATK_RELATION_LABEL_FOR);
542 atk_relation_add_target (relation, atk_obj);
546 obj_array[0] = atk_obj;
547 relation = atk_relation_new (obj_array, 1, ATK_RELATION_LABEL_FOR);
548 atk_relation_set_add (relation_set, relation);
550 g_object_unref (relation_set);
553 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
554 gtk_widget_show (vbox);
555 gtk_box_pack_start (GTK_BOX (fontsel), vbox, FALSE, TRUE, 0);
557 /* create the text entry widget */
558 label = gtk_label_new_with_mnemonic (_("_Preview:"));
559 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
560 gtk_widget_show (label);
561 gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 0);
563 text_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
564 gtk_widget_show (text_box);
565 gtk_box_pack_start (GTK_BOX (vbox), text_box, FALSE, TRUE, 0);
567 priv->preview_entry = gtk_entry_new ();
568 gtk_label_set_mnemonic_widget (GTK_LABEL (label), priv->preview_entry);
569 gtk_entry_set_text (GTK_ENTRY (priv->preview_entry), _(PREVIEW_TEXT));
571 gtk_widget_show (priv->preview_entry);
572 g_signal_connect (priv->preview_entry, "changed",
573 G_CALLBACK (gtk_font_selection_preview_changed), fontsel);
574 gtk_widget_set_size_request (priv->preview_entry,
575 -1, INITIAL_PREVIEW_HEIGHT);
576 gtk_box_pack_start (GTK_BOX (text_box), priv->preview_entry,
578 gtk_widget_pop_composite_child();
582 * gtk_font_selection_new:
584 * Creates a new #GtkFontSelection.
586 * Return value: a n ew #GtkFontSelection
589 gtk_font_selection_new (void)
591 GtkFontSelection *fontsel;
593 fontsel = g_object_new (GTK_TYPE_FONT_SELECTION, NULL);
595 return GTK_WIDGET (fontsel);
599 gtk_font_selection_finalize (GObject *object)
601 GtkFontSelection *fontsel = GTK_FONT_SELECTION (object);
603 gtk_font_selection_ref_family (fontsel, NULL);
604 gtk_font_selection_ref_face (fontsel, NULL);
606 G_OBJECT_CLASS (gtk_font_selection_parent_class)->finalize (object);
610 gtk_font_selection_ref_family (GtkFontSelection *fontsel,
611 PangoFontFamily *family)
613 GtkFontSelectionPrivate *priv = fontsel->priv;
616 family = g_object_ref (family);
618 g_object_unref (priv->family);
619 priv->family = family;
622 static void gtk_font_selection_ref_face (GtkFontSelection *fontsel,
625 GtkFontSelectionPrivate *priv = fontsel->priv;
628 face = g_object_ref (face);
630 g_object_unref (priv->face);
635 gtk_font_selection_reload_fonts (GtkFontSelection *fontsel)
637 if (gtk_widget_has_screen (GTK_WIDGET (fontsel)))
639 PangoFontDescription *desc;
640 desc = gtk_font_selection_get_font_description (fontsel);
642 gtk_font_selection_show_available_fonts (fontsel);
643 gtk_font_selection_show_available_sizes (fontsel, TRUE);
644 gtk_font_selection_show_available_styles (fontsel);
646 gtk_font_selection_select_font_desc (fontsel, desc, NULL, NULL);
647 gtk_font_selection_scroll_to_selection (fontsel);
649 pango_font_description_free (desc);
654 gtk_font_selection_screen_changed (GtkWidget *widget,
655 GdkScreen *previous_screen)
657 gtk_font_selection_reload_fonts (GTK_FONT_SELECTION (widget));
661 gtk_font_selection_style_set (GtkWidget *widget,
662 GtkStyle *prev_style)
664 /* Maybe fonts where installed or removed... */
665 gtk_font_selection_reload_fonts (GTK_FONT_SELECTION (widget));
669 gtk_font_selection_preview_changed (GtkWidget *entry,
670 GtkFontSelection *fontsel)
672 g_object_notify (G_OBJECT (fontsel), "preview-text");
676 scroll_to_selection (GtkTreeView *tree_view)
678 GtkTreeSelection *selection = gtk_tree_view_get_selection (tree_view);
682 if (gtk_tree_selection_get_selected (selection, &model, &iter))
684 GtkTreePath *path = gtk_tree_model_get_path (model, &iter);
685 gtk_tree_view_scroll_to_cell (tree_view, path, NULL, TRUE, 0.5, 0.5);
686 gtk_tree_path_free (path);
691 set_cursor_to_iter (GtkTreeView *view,
694 GtkTreeModel *model = gtk_tree_view_get_model (view);
695 GtkTreePath *path = gtk_tree_model_get_path (model, iter);
697 gtk_tree_view_set_cursor (view, path, NULL, FALSE);
699 gtk_tree_path_free (path);
703 gtk_font_selection_scroll_to_selection (GtkFontSelection *fontsel)
705 GtkFontSelectionPrivate *priv = fontsel->priv;
707 /* Try to scroll the font family list to the selected item */
708 scroll_to_selection (GTK_TREE_VIEW (priv->family_list));
710 /* Try to scroll the font family list to the selected item */
711 scroll_to_selection (GTK_TREE_VIEW (priv->face_list));
713 /* Try to scroll the font family list to the selected item */
714 scroll_to_selection (GTK_TREE_VIEW (priv->size_list));
715 /* This is called when the list is mapped. Here we scroll to the current
716 font if necessary. */
720 gtk_font_selection_scroll_on_map (GtkWidget *widget,
723 gtk_font_selection_scroll_to_selection (GTK_FONT_SELECTION (data));
726 /* This is called when a family is selected in the list. */
728 gtk_font_selection_select_font (GtkTreeSelection *selection,
731 GtkFontSelection *fontsel;
732 GtkFontSelectionPrivate *priv;
735 #ifdef INCLUDE_FONT_ENTRIES
736 const gchar *family_name;
739 fontsel = GTK_FONT_SELECTION (data);
740 priv = fontsel->priv;
742 if (gtk_tree_selection_get_selected (selection, &model, &iter))
744 PangoFontFamily *family;
746 gtk_tree_model_get (model, &iter, FAMILY_COLUMN, &family, -1);
747 if (priv->family != family)
749 gtk_font_selection_ref_family (fontsel, family);
751 #ifdef INCLUDE_FONT_ENTRIES
752 family_name = pango_font_family_get_name (priv->family);
753 gtk_entry_set_text (GTK_ENTRY (priv->font_entry), family_name);
756 gtk_font_selection_show_available_styles (fontsel);
757 gtk_font_selection_select_best_style (fontsel, TRUE);
760 g_object_unref (family);
765 cmp_families (const void *a, const void *b)
767 const char *a_name = pango_font_family_get_name (*(PangoFontFamily **)a);
768 const char *b_name = pango_font_family_get_name (*(PangoFontFamily **)b);
770 return g_utf8_collate (a_name, b_name);
774 gtk_font_selection_show_available_fonts (GtkFontSelection *fontsel)
776 GtkFontSelectionPrivate *priv = fontsel->priv;
778 PangoFontFamily **families;
779 PangoFontFamily *match_family = NULL;
781 GtkTreeIter match_row;
783 model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (priv->family_list)));
785 pango_context_list_families (gtk_widget_get_pango_context (GTK_WIDGET (fontsel)),
786 &families, &n_families);
787 qsort (families, n_families, sizeof (PangoFontFamily *), cmp_families);
789 gtk_list_store_clear (model);
791 for (i=0; i<n_families; i++)
793 const gchar *name = pango_font_family_get_name (families[i]);
796 gtk_list_store_append (model, &iter);
797 gtk_list_store_set (model, &iter,
798 FAMILY_COLUMN, families[i],
799 FAMILY_NAME_COLUMN, name,
802 if (i == 0 || !g_ascii_strcasecmp (name, "sans"))
804 match_family = families[i];
809 gtk_font_selection_ref_family (fontsel, match_family);
812 set_cursor_to_iter (GTK_TREE_VIEW (priv->family_list), &match_row);
813 #ifdef INCLUDE_FONT_ENTRIES
814 gtk_entry_set_text (GTK_ENTRY (priv->font_entry),
815 pango_font_family_get_name (match_family));
816 #endif /* INCLUDE_FONT_ENTRIES */
823 compare_font_descriptions (const PangoFontDescription *a, const PangoFontDescription *b)
825 int val = strcmp (pango_font_description_get_family (a), pango_font_description_get_family (b));
829 if (pango_font_description_get_weight (a) != pango_font_description_get_weight (b))
830 return pango_font_description_get_weight (a) - pango_font_description_get_weight (b);
832 if (pango_font_description_get_style (a) != pango_font_description_get_style (b))
833 return pango_font_description_get_style (a) - pango_font_description_get_style (b);
835 if (pango_font_description_get_stretch (a) != pango_font_description_get_stretch (b))
836 return pango_font_description_get_stretch (a) - pango_font_description_get_stretch (b);
838 if (pango_font_description_get_variant (a) != pango_font_description_get_variant (b))
839 return pango_font_description_get_variant (a) - pango_font_description_get_variant (b);
845 faces_sort_func (const void *a, const void *b)
847 PangoFontDescription *desc_a = pango_font_face_describe (*(PangoFontFace **)a);
848 PangoFontDescription *desc_b = pango_font_face_describe (*(PangoFontFace **)b);
850 int ord = compare_font_descriptions (desc_a, desc_b);
852 pango_font_description_free (desc_a);
853 pango_font_description_free (desc_b);
859 font_description_style_equal (const PangoFontDescription *a,
860 const PangoFontDescription *b)
862 return (pango_font_description_get_weight (a) == pango_font_description_get_weight (b) &&
863 pango_font_description_get_style (a) == pango_font_description_get_style (b) &&
864 pango_font_description_get_stretch (a) == pango_font_description_get_stretch (b) &&
865 pango_font_description_get_variant (a) == pango_font_description_get_variant (b));
868 /* This fills the font style list with all the possible style combinations
869 for the current font family. */
871 gtk_font_selection_show_available_styles (GtkFontSelection *fontsel)
873 GtkFontSelectionPrivate *priv = fontsel->priv;
875 PangoFontFace **faces;
876 PangoFontDescription *old_desc;
878 GtkTreeIter match_row;
879 PangoFontFace *match_face = NULL;
881 model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (priv->face_list)));
884 old_desc = pango_font_face_describe (priv->face);
888 pango_font_family_list_faces (priv->family, &faces, &n_faces);
889 qsort (faces, n_faces, sizeof (PangoFontFace *), faces_sort_func);
891 gtk_list_store_clear (model);
893 for (i=0; i < n_faces; i++)
896 const gchar *str = pango_font_face_get_face_name (faces[i]);
898 gtk_list_store_append (model, &iter);
899 gtk_list_store_set (model, &iter,
900 FACE_COLUMN, faces[i],
901 FACE_NAME_COLUMN, str,
907 match_face = faces[i];
911 PangoFontDescription *tmp_desc = pango_font_face_describe (faces[i]);
913 if (font_description_style_equal (tmp_desc, old_desc))
916 match_face = faces[i];
919 pango_font_description_free (tmp_desc);
924 pango_font_description_free (old_desc);
926 gtk_font_selection_ref_face (fontsel, match_face);
929 #ifdef INCLUDE_FONT_ENTRIES
930 const gchar *str = pango_font_face_get_face_name (priv->face);
932 gtk_entry_set_text (GTK_ENTRY (priv->font_style_entry), str);
934 set_cursor_to_iter (GTK_TREE_VIEW (priv->face_list), &match_row);
940 /* This selects a style when the user selects a font. It just uses the first
941 available style at present. I was thinking of trying to maintain the
942 selected style, e.g. bold italic, when the user selects different fonts.
943 However, the interface is so easy to use now I'm not sure it's worth it.
944 Note: This will load a font. */
946 gtk_font_selection_select_best_style (GtkFontSelection *fontsel,
949 GtkFontSelectionPrivate *priv = fontsel->priv;
953 model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->face_list));
955 if (gtk_tree_model_get_iter_first (model, &iter))
957 set_cursor_to_iter (GTK_TREE_VIEW (priv->face_list), &iter);
958 scroll_to_selection (GTK_TREE_VIEW (priv->face_list));
961 gtk_font_selection_show_available_sizes (fontsel, FALSE);
962 gtk_font_selection_select_best_size (fontsel);
966 /* This is called when a style is selected in the list. */
968 gtk_font_selection_select_style (GtkTreeSelection *selection,
971 GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
975 if (gtk_tree_selection_get_selected (selection, &model, &iter))
979 gtk_tree_model_get (model, &iter, FACE_COLUMN, &face, -1);
980 gtk_font_selection_ref_face (fontsel, face);
981 g_object_unref (face);
984 gtk_font_selection_show_available_sizes (fontsel, FALSE);
985 gtk_font_selection_select_best_size (fontsel);
989 gtk_font_selection_show_available_sizes (GtkFontSelection *fontsel,
992 GtkFontSelectionPrivate *priv = fontsel->priv;
998 model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (priv->size_list)));
1000 /* Insert the standard font sizes */
1003 gtk_list_store_clear (model);
1005 for (i = 0; i < G_N_ELEMENTS (font_sizes); i++)
1009 gtk_list_store_append (model, &iter);
1010 gtk_list_store_set (model, &iter, SIZE_COLUMN, font_sizes[i], -1);
1012 if (font_sizes[i] * PANGO_SCALE == priv->size)
1013 set_cursor_to_iter (GTK_TREE_VIEW (priv->size_list), &iter);
1019 gboolean found = FALSE;
1021 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &iter);
1022 for (i = 0; i < G_N_ELEMENTS (font_sizes) && !found; i++)
1024 if (font_sizes[i] * PANGO_SCALE == priv->size)
1026 set_cursor_to_iter (GTK_TREE_VIEW (priv->size_list), &iter);
1030 gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &iter);
1035 GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->size_list));
1036 gtk_tree_selection_unselect_all (selection);
1040 /* Set the entry to the new size, rounding to 1 digit,
1041 * trimming of trailing 0's and a trailing period
1043 g_snprintf (buffer, sizeof (buffer), "%.1f", priv->size / (1.0 * PANGO_SCALE));
1044 if (strchr (buffer, '.'))
1046 p = buffer + strlen (buffer) - 1;
1054 /* Compare, to avoid moving the cursor unecessarily */
1055 if (strcmp (gtk_entry_get_text (GTK_ENTRY (priv->size_entry)), buffer) != 0)
1056 gtk_entry_set_text (GTK_ENTRY (priv->size_entry), buffer);
1060 gtk_font_selection_select_best_size (GtkFontSelection *fontsel)
1062 gtk_font_selection_load_font (fontsel);
1066 gtk_font_selection_set_size (GtkFontSelection *fontsel,
1069 GtkFontSelectionPrivate *priv = fontsel->priv;
1071 if (priv->size != new_size)
1073 priv->size = new_size;
1075 gtk_font_selection_show_available_sizes (fontsel, FALSE);
1076 gtk_font_selection_load_font (fontsel);
1080 /* If the user hits return in the font size entry, we change to the new font
1083 gtk_font_selection_size_activate (GtkWidget *w,
1086 GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
1087 GtkFontSelectionPrivate *priv = fontsel->priv;
1091 text = gtk_entry_get_text (GTK_ENTRY (priv->size_entry));
1092 new_size = MAX (0.1, atof (text) * PANGO_SCALE + 0.5);
1094 if (priv->size != new_size)
1095 gtk_font_selection_set_size (fontsel, new_size);
1097 list_row_activated (w);
1101 gtk_font_selection_size_focus_out (GtkWidget *w,
1102 GdkEventFocus *event,
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 gtk_font_selection_set_size (fontsel, new_size);
1118 /* This is called when a size is selected in the list. */
1120 gtk_font_selection_select_size (GtkTreeSelection *selection,
1123 GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
1124 GtkTreeModel *model;
1128 if (gtk_tree_selection_get_selected (selection, &model, &iter))
1130 gtk_tree_model_get (model, &iter, SIZE_COLUMN, &new_size, -1);
1131 gtk_font_selection_set_size (fontsel, new_size * PANGO_SCALE);
1136 gtk_font_selection_load_font (GtkFontSelection *fontsel)
1138 gtk_font_selection_update_preview (fontsel);
1141 static PangoFontDescription *
1142 gtk_font_selection_get_font_description (GtkFontSelection *fontsel)
1144 GtkFontSelectionPrivate *priv = fontsel->priv;
1145 PangoFontDescription *font_desc;
1149 font_desc = pango_font_face_describe (priv->face);
1150 pango_font_description_set_size (font_desc, priv->size);
1153 font_desc = pango_font_description_from_string (DEFAULT_FONT_NAME);
1158 /* This sets the font in the preview entry to the selected font, and tries to
1159 make sure that the preview entry is a reasonable size, i.e. so that the
1160 text can be seen with a bit of space to spare. But it tries to avoid
1161 resizing the entry every time the font changes.
1162 This also used to shrink the preview if the font size was decreased, but
1163 that made it awkward if the user wanted to resize the window themself. */
1165 gtk_font_selection_update_preview (GtkFontSelection *fontsel)
1167 GtkFontSelectionPrivate *priv = fontsel->priv;
1168 GtkRcStyle *rc_style;
1170 GtkRequisition old_requisition, new_requisition;
1171 GtkWidget *preview_entry = priv->preview_entry;
1174 gtk_widget_get_preferred_size (preview_entry, &old_requisition, NULL);
1176 rc_style = gtk_rc_style_new ();
1177 rc_style->font_desc = gtk_font_selection_get_font_description (fontsel);
1179 gtk_widget_modify_style (preview_entry, rc_style);
1180 g_object_unref (rc_style);
1182 gtk_widget_get_preferred_size (preview_entry, &new_requisition, NULL);
1184 /* We don't ever want to be over MAX_PREVIEW_HEIGHT pixels high. */
1185 new_height = CLAMP (new_requisition.height, INITIAL_PREVIEW_HEIGHT, MAX_PREVIEW_HEIGHT);
1187 if (new_height > old_requisition.height || new_height < old_requisition.height - 30)
1188 gtk_widget_set_size_request (preview_entry, -1, new_height);
1190 /* This sets the preview text, if it hasn't been set already. */
1191 text = gtk_entry_get_text (GTK_ENTRY (preview_entry));
1192 if (strlen (text) == 0)
1193 gtk_entry_set_text (GTK_ENTRY (preview_entry), _(PREVIEW_TEXT));
1194 gtk_editable_set_position (GTK_EDITABLE (preview_entry), 0);
1198 /*****************************************************************************
1199 * These functions are the main public interface for getting/setting the font.
1200 *****************************************************************************/
1203 * gtk_font_selection_get_family_list:
1204 * @fontsel: a #GtkFontSelection
1206 * This returns the #GtkTreeView that lists font families, for
1207 * example, 'Sans', 'Serif', etc.
1209 * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1214 gtk_font_selection_get_family_list (GtkFontSelection *fontsel)
1216 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1218 return fontsel->priv->family_list;
1222 * gtk_font_selection_get_face_list:
1223 * @fontsel: a #GtkFontSelection
1225 * This returns the #GtkTreeView which lists all styles available for
1226 * the selected font. For example, 'Regular', 'Bold', etc.
1228 * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1233 gtk_font_selection_get_face_list (GtkFontSelection *fontsel)
1235 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1237 return fontsel->priv->face_list;
1241 * gtk_font_selection_get_size_entry:
1242 * @fontsel: a #GtkFontSelection
1244 * This returns the #GtkEntry used to allow the user to edit the font
1245 * number manually instead of selecting it from the list of font sizes.
1247 * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1252 gtk_font_selection_get_size_entry (GtkFontSelection *fontsel)
1254 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1256 return fontsel->priv->size_entry;
1260 * gtk_font_selection_get_size_list:
1261 * @fontsel: a #GtkFontSelection
1263 * This returns the #GtkTreeeView used to list font sizes.
1265 * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1270 gtk_font_selection_get_size_list (GtkFontSelection *fontsel)
1272 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1274 return fontsel->priv->size_list;
1278 * gtk_font_selection_get_preview_entry:
1279 * @fontsel: a #GtkFontSelection
1281 * This returns the #GtkEntry used to display the font as a preview.
1283 * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1288 gtk_font_selection_get_preview_entry (GtkFontSelection *fontsel)
1290 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1292 return fontsel->priv->preview_entry;
1296 * gtk_font_selection_get_family:
1297 * @fontsel: a #GtkFontSelection
1299 * Gets the #PangoFontFamily representing the selected font family.
1301 * Return value: (transfer none): A #PangoFontFamily representing the
1302 * selected font family. Font families are a collection of font
1303 * faces. The returned object is owned by @fontsel and must not
1304 * be modified or freed.
1309 gtk_font_selection_get_family (GtkFontSelection *fontsel)
1311 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1313 return fontsel->priv->family;
1317 * gtk_font_selection_get_face:
1318 * @fontsel: a #GtkFontSelection
1320 * Gets the #PangoFontFace representing the selected font group
1321 * details (i.e. family, slant, weight, width, etc).
1323 * Return value: (transfer none): A #PangoFontFace representing the
1324 * selected font group details. The returned object is owned by
1325 * @fontsel and must not be modified or freed.
1330 gtk_font_selection_get_face (GtkFontSelection *fontsel)
1332 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1334 return fontsel->priv->face;
1338 * gtk_font_selection_get_size:
1339 * @fontsel: a #GtkFontSelection
1341 * The selected font size.
1343 * Return value: A n integer representing the selected font size,
1344 * or -1 if no font size is selected.
1349 gtk_font_selection_get_size (GtkFontSelection *fontsel)
1351 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), -1);
1353 return fontsel->priv->size;
1357 * gtk_font_selection_get_font_name:
1358 * @fontsel: a #GtkFontSelection
1360 * Gets the currently-selected font name.
1362 * Note that this can be a different string than what you set with
1363 * gtk_font_selection_set_font_name(), as the font selection widget may
1364 * normalize font names and thus return a string with a different structure.
1365 * For example, "Helvetica Italic Bold 12" could be normalized to
1366 * "Helvetica Bold Italic 12". Use pango_font_description_equal()
1367 * if you want to compare two font descriptions.
1369 * Return value: A string with the name of the current font, or %NULL if
1370 * no font is selected. You must free this string with g_free().
1373 gtk_font_selection_get_font_name (GtkFontSelection *fontsel)
1377 PangoFontDescription *font_desc = gtk_font_selection_get_font_description (fontsel);
1378 result = pango_font_description_to_string (font_desc);
1379 pango_font_description_free (font_desc);
1384 /* This selects the appropriate list rows.
1385 First we check the fontname is valid and try to find the font family
1386 - i.e. the name in the main list. If we can't find that, then just return.
1387 Next we try to set each of the properties according to the fontname.
1388 Finally we select the font family & style in the lists. */
1390 gtk_font_selection_select_font_desc (GtkFontSelection *fontsel,
1391 PangoFontDescription *new_desc,
1392 PangoFontFamily **pfamily,
1393 PangoFontFace **pface)
1395 GtkFontSelectionPrivate *priv = fontsel->priv;
1396 PangoFontFamily *new_family = NULL;
1397 PangoFontFace *new_face = NULL;
1398 PangoFontFace *fallback_face = NULL;
1399 GtkTreeModel *model;
1401 GtkTreeIter match_iter;
1403 const gchar *new_family_name;
1405 new_family_name = pango_font_description_get_family (new_desc);
1407 if (!new_family_name)
1410 /* Check to make sure that this is in the list of allowed fonts
1412 model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->family_list));
1413 for (valid = gtk_tree_model_get_iter_first (model, &iter);
1415 valid = gtk_tree_model_iter_next (model, &iter))
1417 PangoFontFamily *family;
1419 gtk_tree_model_get (model, &iter, FAMILY_COLUMN, &family, -1);
1421 if (g_ascii_strcasecmp (pango_font_family_get_name (family),
1422 new_family_name) == 0)
1423 new_family = g_object_ref (family);
1425 g_object_unref (family);
1435 *pfamily = new_family;
1437 g_object_unref (new_family);
1438 set_cursor_to_iter (GTK_TREE_VIEW (priv->family_list), &iter);
1439 gtk_font_selection_show_available_styles (fontsel);
1441 model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->face_list));
1442 for (valid = gtk_tree_model_get_iter_first (model, &iter);
1444 valid = gtk_tree_model_iter_next (model, &iter))
1446 PangoFontFace *face;
1447 PangoFontDescription *tmp_desc;
1449 gtk_tree_model_get (model, &iter, FACE_COLUMN, &face, -1);
1450 tmp_desc = pango_font_face_describe (face);
1452 if (font_description_style_equal (tmp_desc, new_desc))
1453 new_face = g_object_ref (face);
1457 fallback_face = g_object_ref (face);
1461 pango_font_description_free (tmp_desc);
1462 g_object_unref (face);
1472 new_face = fallback_face;
1473 else if (fallback_face)
1474 g_object_unref (fallback_face);
1479 g_object_unref (new_face);
1480 set_cursor_to_iter (GTK_TREE_VIEW (priv->face_list), &match_iter);
1482 gtk_font_selection_set_size (fontsel, pango_font_description_get_size (new_desc));
1488 /* This sets the current font, then selecting the appropriate list rows. */
1491 * gtk_font_selection_set_font_name:
1492 * @fontsel: a #GtkFontSelection
1493 * @fontname: a font name like "Helvetica 12" or "Times Bold 18"
1495 * Sets the currently-selected font.
1497 * Note that the @fontsel needs to know the screen in which it will appear
1498 * for this to work; this can be guaranteed by simply making sure that the
1499 * @fontsel is inserted in a toplevel window before you call this function.
1501 * Return value: %TRUE if the font could be set successfully; %FALSE if no
1502 * such font exists or if the @fontsel doesn't belong to a particular
1506 gtk_font_selection_set_font_name (GtkFontSelection *fontsel,
1507 const gchar *fontname)
1509 PangoFontFamily *family = NULL;
1510 PangoFontFace *face = NULL;
1511 PangoFontDescription *new_desc;
1513 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), FALSE);
1515 if (!gtk_widget_has_screen (GTK_WIDGET (fontsel)))
1518 new_desc = pango_font_description_from_string (fontname);
1520 if (gtk_font_selection_select_font_desc (fontsel, new_desc, &family, &face))
1522 gtk_font_selection_ref_family (fontsel, family);
1524 g_object_unref (family);
1526 gtk_font_selection_ref_face (fontsel, face);
1528 g_object_unref (face);
1531 pango_font_description_free (new_desc);
1533 g_object_notify (G_OBJECT (fontsel), "font-name");
1539 * gtk_font_selection_get_preview_text:
1540 * @fontsel: a #GtkFontSelection
1542 * Gets the text displayed in the preview area.
1544 * Return value: the text displayed in the preview area.
1545 * This string is owned by the widget and should not be
1548 G_CONST_RETURN gchar*
1549 gtk_font_selection_get_preview_text (GtkFontSelection *fontsel)
1551 GtkFontSelectionPrivate *priv;
1553 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1555 priv = fontsel->priv;
1557 return gtk_entry_get_text (GTK_ENTRY (priv->preview_entry));
1562 * gtk_font_selection_set_preview_text:
1563 * @fontsel: a #GtkFontSelection
1564 * @text: the text to display in the preview area
1566 * Sets the text displayed in the preview area.
1567 * The @text is used to show how the selected font looks.
1570 gtk_font_selection_set_preview_text (GtkFontSelection *fontsel,
1573 GtkFontSelectionPrivate *priv;
1575 g_return_if_fail (GTK_IS_FONT_SELECTION (fontsel));
1576 g_return_if_fail (text != NULL);
1578 priv = fontsel->priv;
1580 gtk_entry_set_text (GTK_ENTRY (priv->preview_entry), text);
1583 /*****************************************************************************
1584 * GtkFontSelectionDialog
1585 *****************************************************************************/
1587 static void gtk_font_selection_dialog_buildable_interface_init (GtkBuildableIface *iface);
1588 static GObject * gtk_font_selection_dialog_buildable_get_internal_child (GtkBuildable *buildable,
1589 GtkBuilder *builder,
1590 const gchar *childname);
1592 G_DEFINE_TYPE_WITH_CODE (GtkFontSelectionDialog, gtk_font_selection_dialog,
1594 G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
1595 gtk_font_selection_dialog_buildable_interface_init))
1597 static GtkBuildableIface *parent_buildable_iface;
1600 gtk_font_selection_dialog_class_init (GtkFontSelectionDialogClass *klass)
1602 g_type_class_add_private (klass, sizeof (GtkFontSelectionDialogPrivate));
1606 gtk_font_selection_dialog_init (GtkFontSelectionDialog *fontseldiag)
1608 GtkFontSelectionDialogPrivate *priv;
1609 GtkDialog *dialog = GTK_DIALOG (fontseldiag);
1610 GtkWidget *action_area, *content_area;
1612 fontseldiag->priv = G_TYPE_INSTANCE_GET_PRIVATE (fontseldiag,
1613 GTK_TYPE_FONT_SELECTION_DIALOG,
1614 GtkFontSelectionDialogPrivate);
1615 priv = fontseldiag->priv;
1617 content_area = gtk_dialog_get_content_area (dialog);
1618 action_area = gtk_dialog_get_action_area (dialog);
1620 gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
1621 gtk_box_set_spacing (GTK_BOX (content_area), 2); /* 2 * 5 + 2 = 12 */
1622 gtk_container_set_border_width (GTK_CONTAINER (action_area), 5);
1623 gtk_box_set_spacing (GTK_BOX (action_area), 6);
1625 gtk_widget_push_composite_child ();
1627 gtk_window_set_resizable (GTK_WINDOW (fontseldiag), TRUE);
1629 /* Create the content area */
1630 priv->fontsel = gtk_font_selection_new ();
1631 gtk_container_set_border_width (GTK_CONTAINER (priv->fontsel), 5);
1632 gtk_widget_show (priv->fontsel);
1633 gtk_box_pack_start (GTK_BOX (content_area),
1634 priv->fontsel, TRUE, TRUE, 0);
1636 /* Create the action area */
1637 priv->cancel_button = gtk_dialog_add_button (dialog,
1639 GTK_RESPONSE_CANCEL);
1641 priv->apply_button = gtk_dialog_add_button (dialog,
1643 GTK_RESPONSE_APPLY);
1644 gtk_widget_hide (priv->apply_button);
1646 priv->ok_button = gtk_dialog_add_button (dialog,
1649 gtk_widget_grab_default (priv->ok_button);
1651 gtk_dialog_set_alternative_button_order (GTK_DIALOG (fontseldiag),
1654 GTK_RESPONSE_CANCEL,
1657 gtk_window_set_title (GTK_WINDOW (fontseldiag),
1658 _("Font Selection"));
1660 gtk_widget_pop_composite_child ();
1664 * gtk_font_selection_dialog_new:
1665 * @title: the title of the dialog window
1667 * Creates a new #GtkFontSelectionDialog.
1669 * Return value: a new #GtkFontSelectionDialog
1672 gtk_font_selection_dialog_new (const gchar *title)
1674 GtkFontSelectionDialog *fontseldiag;
1676 fontseldiag = g_object_new (GTK_TYPE_FONT_SELECTION_DIALOG, NULL);
1679 gtk_window_set_title (GTK_WINDOW (fontseldiag), title);
1681 return GTK_WIDGET (fontseldiag);
1685 * gtk_font_selection_dialog_get_font_selection:
1686 * @fsd: a #GtkFontSelectionDialog
1688 * Retrieves the #GtkFontSelection widget embedded in the dialog.
1690 * Returns: (transfer none): the embedded #GtkFontSelection
1695 gtk_font_selection_dialog_get_font_selection (GtkFontSelectionDialog *fsd)
1697 g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1699 return fsd->priv->fontsel;
1704 * gtk_font_selection_dialog_get_ok_button:
1705 * @fsd: a #GtkFontSelectionDialog
1707 * Gets the 'OK' button.
1709 * Return value: (transfer none): the #GtkWidget used in the dialog
1710 * for the 'OK' button.
1715 gtk_font_selection_dialog_get_ok_button (GtkFontSelectionDialog *fsd)
1717 g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1719 return fsd->priv->ok_button;
1723 * gtk_font_selection_dialog_get_cancel_button:
1724 * @fsd: a #GtkFontSelectionDialog
1726 * Gets the 'Cancel' button.
1728 * Return value: (transfer none): the #GtkWidget used in the dialog
1729 * for the 'Cancel' button.
1734 gtk_font_selection_dialog_get_cancel_button (GtkFontSelectionDialog *fsd)
1736 g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1738 return fsd->priv->cancel_button;
1742 gtk_font_selection_dialog_buildable_interface_init (GtkBuildableIface *iface)
1744 parent_buildable_iface = g_type_interface_peek_parent (iface);
1745 iface->get_internal_child = gtk_font_selection_dialog_buildable_get_internal_child;
1749 gtk_font_selection_dialog_buildable_get_internal_child (GtkBuildable *buildable,
1750 GtkBuilder *builder,
1751 const gchar *childname)
1753 GtkFontSelectionDialogPrivate *priv;
1755 priv = GTK_FONT_SELECTION_DIALOG (buildable)->priv;
1757 if (g_strcmp0 (childname, "ok_button") == 0)
1758 return G_OBJECT (priv->ok_button);
1759 else if (g_strcmp0 (childname, "cancel_button") == 0)
1760 return G_OBJECT (priv->cancel_button);
1761 else if (g_strcmp0 (childname, "apply_button") == 0)
1762 return G_OBJECT (priv->apply_button);
1763 else if (g_strcmp0 (childname, "font_selection") == 0)
1764 return G_OBJECT (priv->fontsel);
1766 return parent_buildable_iface->get_internal_child (buildable, builder, childname);
1770 * gtk_font_selection_dialog_get_font_name:
1771 * @fsd: a #GtkFontSelectionDialog
1773 * Gets the currently-selected font name.
1775 * Note that this can be a different string than what you set with
1776 * gtk_font_selection_dialog_set_font_name(), as the font selection widget
1777 * may normalize font names and thus return a string with a different
1778 * structure. For example, "Helvetica Italic Bold 12" could be normalized
1779 * to "Helvetica Bold Italic 12". Use pango_font_description_equal()
1780 * if you want to compare two font descriptions.
1782 * Return value: A string with the name of the current font, or %NULL if no
1783 * font is selected. You must free this string with g_free().
1786 gtk_font_selection_dialog_get_font_name (GtkFontSelectionDialog *fsd)
1788 GtkFontSelectionDialogPrivate *priv;
1790 g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1794 return gtk_font_selection_get_font_name (GTK_FONT_SELECTION (priv->fontsel));
1798 * gtk_font_selection_dialog_set_font_name:
1799 * @fsd: a #GtkFontSelectionDialog
1800 * @fontname: a font name like "Helvetica 12" or "Times Bold 18"
1802 * Sets the currently selected font.
1804 * Return value: %TRUE if the font selected in @fsd is now the
1805 * @fontname specified, %FALSE otherwise.
1808 gtk_font_selection_dialog_set_font_name (GtkFontSelectionDialog *fsd,
1809 const gchar *fontname)
1811 GtkFontSelectionDialogPrivate *priv;
1813 g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), FALSE);
1814 g_return_val_if_fail (fontname, FALSE);
1818 return gtk_font_selection_set_font_name (GTK_FONT_SELECTION (priv->fontsel), fontname);
1822 * gtk_font_selection_dialog_get_preview_text:
1823 * @fsd: a #GtkFontSelectionDialog
1825 * Gets the text displayed in the preview area.
1827 * Return value: the text displayed in the preview area.
1828 * This string is owned by the widget and should not be
1831 G_CONST_RETURN gchar*
1832 gtk_font_selection_dialog_get_preview_text (GtkFontSelectionDialog *fsd)
1834 GtkFontSelectionDialogPrivate *priv;
1836 g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1840 return gtk_font_selection_get_preview_text (GTK_FONT_SELECTION (priv->fontsel));
1844 * gtk_font_selection_dialog_set_preview_text:
1845 * @fsd: a #GtkFontSelectionDialog
1846 * @text: the text to display in the preview area
1848 * Sets the text displayed in the preview area.
1851 gtk_font_selection_dialog_set_preview_text (GtkFontSelectionDialog *fsd,
1854 GtkFontSelectionDialogPrivate *priv;
1856 g_return_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd));
1857 g_return_if_fail (text != NULL);
1861 gtk_font_selection_set_preview_text (GTK_FONT_SELECTION (priv->fontsel), text);