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);
554 vbox = gtk_vbox_new (FALSE, 6);
555 gtk_widget_show (vbox);
556 gtk_box_pack_start (GTK_BOX (fontsel), vbox, FALSE, TRUE, 0);
558 /* create the text entry widget */
559 label = gtk_label_new_with_mnemonic (_("_Preview:"));
560 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
561 gtk_widget_show (label);
562 gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 0);
564 text_box = gtk_hbox_new (FALSE, 0);
565 gtk_widget_show (text_box);
566 gtk_box_pack_start (GTK_BOX (vbox), text_box, FALSE, TRUE, 0);
568 priv->preview_entry = gtk_entry_new ();
569 gtk_label_set_mnemonic_widget (GTK_LABEL (label), priv->preview_entry);
570 gtk_entry_set_text (GTK_ENTRY (priv->preview_entry), _(PREVIEW_TEXT));
572 gtk_widget_show (priv->preview_entry);
573 g_signal_connect (priv->preview_entry, "changed",
574 G_CALLBACK (gtk_font_selection_preview_changed), fontsel);
575 gtk_widget_set_size_request (priv->preview_entry,
576 -1, INITIAL_PREVIEW_HEIGHT);
577 gtk_box_pack_start (GTK_BOX (text_box), priv->preview_entry,
579 gtk_widget_pop_composite_child();
583 * gtk_font_selection_new:
585 * Creates a new #GtkFontSelection.
587 * Return value: a n ew #GtkFontSelection
590 gtk_font_selection_new (void)
592 GtkFontSelection *fontsel;
594 fontsel = g_object_new (GTK_TYPE_FONT_SELECTION, NULL);
596 return GTK_WIDGET (fontsel);
600 gtk_font_selection_finalize (GObject *object)
602 GtkFontSelection *fontsel = GTK_FONT_SELECTION (object);
604 gtk_font_selection_ref_family (fontsel, NULL);
605 gtk_font_selection_ref_face (fontsel, NULL);
607 G_OBJECT_CLASS (gtk_font_selection_parent_class)->finalize (object);
611 gtk_font_selection_ref_family (GtkFontSelection *fontsel,
612 PangoFontFamily *family)
614 GtkFontSelectionPrivate *priv = fontsel->priv;
617 family = g_object_ref (family);
619 g_object_unref (priv->family);
620 priv->family = family;
623 static void gtk_font_selection_ref_face (GtkFontSelection *fontsel,
626 GtkFontSelectionPrivate *priv = fontsel->priv;
629 face = g_object_ref (face);
631 g_object_unref (priv->face);
636 gtk_font_selection_reload_fonts (GtkFontSelection *fontsel)
638 if (gtk_widget_has_screen (GTK_WIDGET (fontsel)))
640 PangoFontDescription *desc;
641 desc = gtk_font_selection_get_font_description (fontsel);
643 gtk_font_selection_show_available_fonts (fontsel);
644 gtk_font_selection_show_available_sizes (fontsel, TRUE);
645 gtk_font_selection_show_available_styles (fontsel);
647 gtk_font_selection_select_font_desc (fontsel, desc, NULL, NULL);
648 gtk_font_selection_scroll_to_selection (fontsel);
650 pango_font_description_free (desc);
655 gtk_font_selection_screen_changed (GtkWidget *widget,
656 GdkScreen *previous_screen)
658 gtk_font_selection_reload_fonts (GTK_FONT_SELECTION (widget));
662 gtk_font_selection_style_set (GtkWidget *widget,
663 GtkStyle *prev_style)
665 /* Maybe fonts where installed or removed... */
666 gtk_font_selection_reload_fonts (GTK_FONT_SELECTION (widget));
670 gtk_font_selection_preview_changed (GtkWidget *entry,
671 GtkFontSelection *fontsel)
673 g_object_notify (G_OBJECT (fontsel), "preview-text");
677 scroll_to_selection (GtkTreeView *tree_view)
679 GtkTreeSelection *selection = gtk_tree_view_get_selection (tree_view);
683 if (gtk_tree_selection_get_selected (selection, &model, &iter))
685 GtkTreePath *path = gtk_tree_model_get_path (model, &iter);
686 gtk_tree_view_scroll_to_cell (tree_view, path, NULL, TRUE, 0.5, 0.5);
687 gtk_tree_path_free (path);
692 set_cursor_to_iter (GtkTreeView *view,
695 GtkTreeModel *model = gtk_tree_view_get_model (view);
696 GtkTreePath *path = gtk_tree_model_get_path (model, iter);
698 gtk_tree_view_set_cursor (view, path, NULL, FALSE);
700 gtk_tree_path_free (path);
704 gtk_font_selection_scroll_to_selection (GtkFontSelection *fontsel)
706 GtkFontSelectionPrivate *priv = fontsel->priv;
708 /* Try to scroll the font family list to the selected item */
709 scroll_to_selection (GTK_TREE_VIEW (priv->family_list));
711 /* Try to scroll the font family list to the selected item */
712 scroll_to_selection (GTK_TREE_VIEW (priv->face_list));
714 /* Try to scroll the font family list to the selected item */
715 scroll_to_selection (GTK_TREE_VIEW (priv->size_list));
716 /* This is called when the list is mapped. Here we scroll to the current
717 font if necessary. */
721 gtk_font_selection_scroll_on_map (GtkWidget *widget,
724 gtk_font_selection_scroll_to_selection (GTK_FONT_SELECTION (data));
727 /* This is called when a family is selected in the list. */
729 gtk_font_selection_select_font (GtkTreeSelection *selection,
732 GtkFontSelection *fontsel;
733 GtkFontSelectionPrivate *priv;
736 #ifdef INCLUDE_FONT_ENTRIES
737 const gchar *family_name;
740 fontsel = GTK_FONT_SELECTION (data);
741 priv = fontsel->priv;
743 if (gtk_tree_selection_get_selected (selection, &model, &iter))
745 PangoFontFamily *family;
747 gtk_tree_model_get (model, &iter, FAMILY_COLUMN, &family, -1);
748 if (priv->family != family)
750 gtk_font_selection_ref_family (fontsel, family);
752 #ifdef INCLUDE_FONT_ENTRIES
753 family_name = pango_font_family_get_name (priv->family);
754 gtk_entry_set_text (GTK_ENTRY (priv->font_entry), family_name);
757 gtk_font_selection_show_available_styles (fontsel);
758 gtk_font_selection_select_best_style (fontsel, TRUE);
761 g_object_unref (family);
766 cmp_families (const void *a, const void *b)
768 const char *a_name = pango_font_family_get_name (*(PangoFontFamily **)a);
769 const char *b_name = pango_font_family_get_name (*(PangoFontFamily **)b);
771 return g_utf8_collate (a_name, b_name);
775 gtk_font_selection_show_available_fonts (GtkFontSelection *fontsel)
777 GtkFontSelectionPrivate *priv = fontsel->priv;
779 PangoFontFamily **families;
780 PangoFontFamily *match_family = NULL;
782 GtkTreeIter match_row;
784 model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (priv->family_list)));
786 pango_context_list_families (gtk_widget_get_pango_context (GTK_WIDGET (fontsel)),
787 &families, &n_families);
788 qsort (families, n_families, sizeof (PangoFontFamily *), cmp_families);
790 gtk_list_store_clear (model);
792 for (i=0; i<n_families; i++)
794 const gchar *name = pango_font_family_get_name (families[i]);
797 gtk_list_store_append (model, &iter);
798 gtk_list_store_set (model, &iter,
799 FAMILY_COLUMN, families[i],
800 FAMILY_NAME_COLUMN, name,
803 if (i == 0 || !g_ascii_strcasecmp (name, "sans"))
805 match_family = families[i];
810 gtk_font_selection_ref_family (fontsel, match_family);
813 set_cursor_to_iter (GTK_TREE_VIEW (priv->family_list), &match_row);
814 #ifdef INCLUDE_FONT_ENTRIES
815 gtk_entry_set_text (GTK_ENTRY (priv->font_entry),
816 pango_font_family_get_name (match_family));
817 #endif /* INCLUDE_FONT_ENTRIES */
824 compare_font_descriptions (const PangoFontDescription *a, const PangoFontDescription *b)
826 int val = strcmp (pango_font_description_get_family (a), pango_font_description_get_family (b));
830 if (pango_font_description_get_weight (a) != pango_font_description_get_weight (b))
831 return pango_font_description_get_weight (a) - pango_font_description_get_weight (b);
833 if (pango_font_description_get_style (a) != pango_font_description_get_style (b))
834 return pango_font_description_get_style (a) - pango_font_description_get_style (b);
836 if (pango_font_description_get_stretch (a) != pango_font_description_get_stretch (b))
837 return pango_font_description_get_stretch (a) - pango_font_description_get_stretch (b);
839 if (pango_font_description_get_variant (a) != pango_font_description_get_variant (b))
840 return pango_font_description_get_variant (a) - pango_font_description_get_variant (b);
846 faces_sort_func (const void *a, const void *b)
848 PangoFontDescription *desc_a = pango_font_face_describe (*(PangoFontFace **)a);
849 PangoFontDescription *desc_b = pango_font_face_describe (*(PangoFontFace **)b);
851 int ord = compare_font_descriptions (desc_a, desc_b);
853 pango_font_description_free (desc_a);
854 pango_font_description_free (desc_b);
860 font_description_style_equal (const PangoFontDescription *a,
861 const PangoFontDescription *b)
863 return (pango_font_description_get_weight (a) == pango_font_description_get_weight (b) &&
864 pango_font_description_get_style (a) == pango_font_description_get_style (b) &&
865 pango_font_description_get_stretch (a) == pango_font_description_get_stretch (b) &&
866 pango_font_description_get_variant (a) == pango_font_description_get_variant (b));
869 /* This fills the font style list with all the possible style combinations
870 for the current font family. */
872 gtk_font_selection_show_available_styles (GtkFontSelection *fontsel)
874 GtkFontSelectionPrivate *priv = fontsel->priv;
876 PangoFontFace **faces;
877 PangoFontDescription *old_desc;
879 GtkTreeIter match_row;
880 PangoFontFace *match_face = NULL;
882 model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (priv->face_list)));
885 old_desc = pango_font_face_describe (priv->face);
889 pango_font_family_list_faces (priv->family, &faces, &n_faces);
890 qsort (faces, n_faces, sizeof (PangoFontFace *), faces_sort_func);
892 gtk_list_store_clear (model);
894 for (i=0; i < n_faces; i++)
897 const gchar *str = pango_font_face_get_face_name (faces[i]);
899 gtk_list_store_append (model, &iter);
900 gtk_list_store_set (model, &iter,
901 FACE_COLUMN, faces[i],
902 FACE_NAME_COLUMN, str,
908 match_face = faces[i];
912 PangoFontDescription *tmp_desc = pango_font_face_describe (faces[i]);
914 if (font_description_style_equal (tmp_desc, old_desc))
917 match_face = faces[i];
920 pango_font_description_free (tmp_desc);
925 pango_font_description_free (old_desc);
927 gtk_font_selection_ref_face (fontsel, match_face);
930 #ifdef INCLUDE_FONT_ENTRIES
931 const gchar *str = pango_font_face_get_face_name (priv->face);
933 gtk_entry_set_text (GTK_ENTRY (priv->font_style_entry), str);
935 set_cursor_to_iter (GTK_TREE_VIEW (priv->face_list), &match_row);
941 /* This selects a style when the user selects a font. It just uses the first
942 available style at present. I was thinking of trying to maintain the
943 selected style, e.g. bold italic, when the user selects different fonts.
944 However, the interface is so easy to use now I'm not sure it's worth it.
945 Note: This will load a font. */
947 gtk_font_selection_select_best_style (GtkFontSelection *fontsel,
950 GtkFontSelectionPrivate *priv = fontsel->priv;
954 model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->face_list));
956 if (gtk_tree_model_get_iter_first (model, &iter))
958 set_cursor_to_iter (GTK_TREE_VIEW (priv->face_list), &iter);
959 scroll_to_selection (GTK_TREE_VIEW (priv->face_list));
962 gtk_font_selection_show_available_sizes (fontsel, FALSE);
963 gtk_font_selection_select_best_size (fontsel);
967 /* This is called when a style is selected in the list. */
969 gtk_font_selection_select_style (GtkTreeSelection *selection,
972 GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
976 if (gtk_tree_selection_get_selected (selection, &model, &iter))
980 gtk_tree_model_get (model, &iter, FACE_COLUMN, &face, -1);
981 gtk_font_selection_ref_face (fontsel, face);
982 g_object_unref (face);
985 gtk_font_selection_show_available_sizes (fontsel, FALSE);
986 gtk_font_selection_select_best_size (fontsel);
990 gtk_font_selection_show_available_sizes (GtkFontSelection *fontsel,
993 GtkFontSelectionPrivate *priv = fontsel->priv;
999 model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (priv->size_list)));
1001 /* Insert the standard font sizes */
1004 gtk_list_store_clear (model);
1006 for (i = 0; i < G_N_ELEMENTS (font_sizes); i++)
1010 gtk_list_store_append (model, &iter);
1011 gtk_list_store_set (model, &iter, SIZE_COLUMN, font_sizes[i], -1);
1013 if (font_sizes[i] * PANGO_SCALE == priv->size)
1014 set_cursor_to_iter (GTK_TREE_VIEW (priv->size_list), &iter);
1020 gboolean found = FALSE;
1022 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &iter);
1023 for (i = 0; i < G_N_ELEMENTS (font_sizes) && !found; i++)
1025 if (font_sizes[i] * PANGO_SCALE == priv->size)
1027 set_cursor_to_iter (GTK_TREE_VIEW (priv->size_list), &iter);
1031 gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &iter);
1036 GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->size_list));
1037 gtk_tree_selection_unselect_all (selection);
1041 /* Set the entry to the new size, rounding to 1 digit,
1042 * trimming of trailing 0's and a trailing period
1044 g_snprintf (buffer, sizeof (buffer), "%.1f", priv->size / (1.0 * PANGO_SCALE));
1045 if (strchr (buffer, '.'))
1047 p = buffer + strlen (buffer) - 1;
1055 /* Compare, to avoid moving the cursor unecessarily */
1056 if (strcmp (gtk_entry_get_text (GTK_ENTRY (priv->size_entry)), buffer) != 0)
1057 gtk_entry_set_text (GTK_ENTRY (priv->size_entry), buffer);
1061 gtk_font_selection_select_best_size (GtkFontSelection *fontsel)
1063 gtk_font_selection_load_font (fontsel);
1067 gtk_font_selection_set_size (GtkFontSelection *fontsel,
1070 GtkFontSelectionPrivate *priv = fontsel->priv;
1072 if (priv->size != new_size)
1074 priv->size = new_size;
1076 gtk_font_selection_show_available_sizes (fontsel, FALSE);
1077 gtk_font_selection_load_font (fontsel);
1081 /* If the user hits return in the font size entry, we change to the new font
1084 gtk_font_selection_size_activate (GtkWidget *w,
1087 GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
1088 GtkFontSelectionPrivate *priv = fontsel->priv;
1092 text = gtk_entry_get_text (GTK_ENTRY (priv->size_entry));
1093 new_size = MAX (0.1, atof (text) * PANGO_SCALE + 0.5);
1095 if (priv->size != new_size)
1096 gtk_font_selection_set_size (fontsel, new_size);
1098 list_row_activated (w);
1102 gtk_font_selection_size_focus_out (GtkWidget *w,
1103 GdkEventFocus *event,
1106 GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
1107 GtkFontSelectionPrivate *priv = fontsel->priv;
1111 text = gtk_entry_get_text (GTK_ENTRY (priv->size_entry));
1112 new_size = MAX (0.1, atof (text) * PANGO_SCALE + 0.5);
1114 gtk_font_selection_set_size (fontsel, new_size);
1119 /* This is called when a size is selected in the list. */
1121 gtk_font_selection_select_size (GtkTreeSelection *selection,
1124 GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
1125 GtkTreeModel *model;
1129 if (gtk_tree_selection_get_selected (selection, &model, &iter))
1131 gtk_tree_model_get (model, &iter, SIZE_COLUMN, &new_size, -1);
1132 gtk_font_selection_set_size (fontsel, new_size * PANGO_SCALE);
1137 gtk_font_selection_load_font (GtkFontSelection *fontsel)
1139 gtk_font_selection_update_preview (fontsel);
1142 static PangoFontDescription *
1143 gtk_font_selection_get_font_description (GtkFontSelection *fontsel)
1145 GtkFontSelectionPrivate *priv = fontsel->priv;
1146 PangoFontDescription *font_desc;
1150 font_desc = pango_font_face_describe (priv->face);
1151 pango_font_description_set_size (font_desc, priv->size);
1154 font_desc = pango_font_description_from_string (DEFAULT_FONT_NAME);
1159 /* This sets the font in the preview entry to the selected font, and tries to
1160 make sure that the preview entry is a reasonable size, i.e. so that the
1161 text can be seen with a bit of space to spare. But it tries to avoid
1162 resizing the entry every time the font changes.
1163 This also used to shrink the preview if the font size was decreased, but
1164 that made it awkward if the user wanted to resize the window themself. */
1166 gtk_font_selection_update_preview (GtkFontSelection *fontsel)
1168 GtkFontSelectionPrivate *priv = fontsel->priv;
1169 GtkRcStyle *rc_style;
1171 GtkRequisition old_requisition, new_requisition;
1172 GtkWidget *preview_entry = priv->preview_entry;
1175 gtk_widget_get_preferred_size (preview_entry, &old_requisition, NULL);
1177 rc_style = gtk_rc_style_new ();
1178 rc_style->font_desc = gtk_font_selection_get_font_description (fontsel);
1180 gtk_widget_modify_style (preview_entry, rc_style);
1181 g_object_unref (rc_style);
1183 gtk_widget_get_preferred_size (preview_entry, &new_requisition, NULL);
1185 /* We don't ever want to be over MAX_PREVIEW_HEIGHT pixels high. */
1186 new_height = CLAMP (new_requisition.height, INITIAL_PREVIEW_HEIGHT, MAX_PREVIEW_HEIGHT);
1188 if (new_height > old_requisition.height || new_height < old_requisition.height - 30)
1189 gtk_widget_set_size_request (preview_entry, -1, new_height);
1191 /* This sets the preview text, if it hasn't been set already. */
1192 text = gtk_entry_get_text (GTK_ENTRY (preview_entry));
1193 if (strlen (text) == 0)
1194 gtk_entry_set_text (GTK_ENTRY (preview_entry), _(PREVIEW_TEXT));
1195 gtk_editable_set_position (GTK_EDITABLE (preview_entry), 0);
1199 /*****************************************************************************
1200 * These functions are the main public interface for getting/setting the font.
1201 *****************************************************************************/
1204 * gtk_font_selection_get_family_list:
1205 * @fontsel: a #GtkFontSelection
1207 * This returns the #GtkTreeView that lists font families, for
1208 * example, 'Sans', 'Serif', etc.
1210 * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1215 gtk_font_selection_get_family_list (GtkFontSelection *fontsel)
1217 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1219 return fontsel->priv->family_list;
1223 * gtk_font_selection_get_face_list:
1224 * @fontsel: a #GtkFontSelection
1226 * This returns the #GtkTreeView which lists all styles available for
1227 * the selected font. For example, 'Regular', 'Bold', etc.
1229 * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1234 gtk_font_selection_get_face_list (GtkFontSelection *fontsel)
1236 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1238 return fontsel->priv->face_list;
1242 * gtk_font_selection_get_size_entry:
1243 * @fontsel: a #GtkFontSelection
1245 * This returns the #GtkEntry used to allow the user to edit the font
1246 * number manually instead of selecting it from the list of font sizes.
1248 * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1253 gtk_font_selection_get_size_entry (GtkFontSelection *fontsel)
1255 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1257 return fontsel->priv->size_entry;
1261 * gtk_font_selection_get_size_list:
1262 * @fontsel: a #GtkFontSelection
1264 * This returns the #GtkTreeeView used to list font sizes.
1266 * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1271 gtk_font_selection_get_size_list (GtkFontSelection *fontsel)
1273 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1275 return fontsel->priv->size_list;
1279 * gtk_font_selection_get_preview_entry:
1280 * @fontsel: a #GtkFontSelection
1282 * This returns the #GtkEntry used to display the font as a preview.
1284 * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1289 gtk_font_selection_get_preview_entry (GtkFontSelection *fontsel)
1291 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1293 return fontsel->priv->preview_entry;
1297 * gtk_font_selection_get_family:
1298 * @fontsel: a #GtkFontSelection
1300 * Gets the #PangoFontFamily representing the selected font family.
1302 * Return value: (transfer none): A #PangoFontFamily representing the
1303 * selected font family. Font families are a collection of font
1304 * faces. The returned object is owned by @fontsel and must not
1305 * be modified or freed.
1310 gtk_font_selection_get_family (GtkFontSelection *fontsel)
1312 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1314 return fontsel->priv->family;
1318 * gtk_font_selection_get_face:
1319 * @fontsel: a #GtkFontSelection
1321 * Gets the #PangoFontFace representing the selected font group
1322 * details (i.e. family, slant, weight, width, etc).
1324 * Return value: (transfer none): A #PangoFontFace representing the
1325 * selected font group details. The returned object is owned by
1326 * @fontsel and must not be modified or freed.
1331 gtk_font_selection_get_face (GtkFontSelection *fontsel)
1333 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1335 return fontsel->priv->face;
1339 * gtk_font_selection_get_size:
1340 * @fontsel: a #GtkFontSelection
1342 * The selected font size.
1344 * Return value: A n integer representing the selected font size,
1345 * or -1 if no font size is selected.
1350 gtk_font_selection_get_size (GtkFontSelection *fontsel)
1352 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), -1);
1354 return fontsel->priv->size;
1358 * gtk_font_selection_get_font_name:
1359 * @fontsel: a #GtkFontSelection
1361 * Gets the currently-selected font name.
1363 * Note that this can be a different string than what you set with
1364 * gtk_font_selection_set_font_name(), as the font selection widget may
1365 * normalize font names and thus return a string with a different structure.
1366 * For example, "Helvetica Italic Bold 12" could be normalized to
1367 * "Helvetica Bold Italic 12". Use pango_font_description_equal()
1368 * if you want to compare two font descriptions.
1370 * Return value: A string with the name of the current font, or %NULL if
1371 * no font is selected. You must free this string with g_free().
1374 gtk_font_selection_get_font_name (GtkFontSelection *fontsel)
1378 PangoFontDescription *font_desc = gtk_font_selection_get_font_description (fontsel);
1379 result = pango_font_description_to_string (font_desc);
1380 pango_font_description_free (font_desc);
1385 /* This selects the appropriate list rows.
1386 First we check the fontname is valid and try to find the font family
1387 - i.e. the name in the main list. If we can't find that, then just return.
1388 Next we try to set each of the properties according to the fontname.
1389 Finally we select the font family & style in the lists. */
1391 gtk_font_selection_select_font_desc (GtkFontSelection *fontsel,
1392 PangoFontDescription *new_desc,
1393 PangoFontFamily **pfamily,
1394 PangoFontFace **pface)
1396 GtkFontSelectionPrivate *priv = fontsel->priv;
1397 PangoFontFamily *new_family = NULL;
1398 PangoFontFace *new_face = NULL;
1399 PangoFontFace *fallback_face = NULL;
1400 GtkTreeModel *model;
1402 GtkTreeIter match_iter;
1404 const gchar *new_family_name;
1406 new_family_name = pango_font_description_get_family (new_desc);
1408 if (!new_family_name)
1411 /* Check to make sure that this is in the list of allowed fonts
1413 model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->family_list));
1414 for (valid = gtk_tree_model_get_iter_first (model, &iter);
1416 valid = gtk_tree_model_iter_next (model, &iter))
1418 PangoFontFamily *family;
1420 gtk_tree_model_get (model, &iter, FAMILY_COLUMN, &family, -1);
1422 if (g_ascii_strcasecmp (pango_font_family_get_name (family),
1423 new_family_name) == 0)
1424 new_family = g_object_ref (family);
1426 g_object_unref (family);
1436 *pfamily = new_family;
1438 g_object_unref (new_family);
1439 set_cursor_to_iter (GTK_TREE_VIEW (priv->family_list), &iter);
1440 gtk_font_selection_show_available_styles (fontsel);
1442 model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->face_list));
1443 for (valid = gtk_tree_model_get_iter_first (model, &iter);
1445 valid = gtk_tree_model_iter_next (model, &iter))
1447 PangoFontFace *face;
1448 PangoFontDescription *tmp_desc;
1450 gtk_tree_model_get (model, &iter, FACE_COLUMN, &face, -1);
1451 tmp_desc = pango_font_face_describe (face);
1453 if (font_description_style_equal (tmp_desc, new_desc))
1454 new_face = g_object_ref (face);
1458 fallback_face = g_object_ref (face);
1462 pango_font_description_free (tmp_desc);
1463 g_object_unref (face);
1473 new_face = fallback_face;
1474 else if (fallback_face)
1475 g_object_unref (fallback_face);
1480 g_object_unref (new_face);
1481 set_cursor_to_iter (GTK_TREE_VIEW (priv->face_list), &match_iter);
1483 gtk_font_selection_set_size (fontsel, pango_font_description_get_size (new_desc));
1489 /* This sets the current font, then selecting the appropriate list rows. */
1492 * gtk_font_selection_set_font_name:
1493 * @fontsel: a #GtkFontSelection
1494 * @fontname: a font name like "Helvetica 12" or "Times Bold 18"
1496 * Sets the currently-selected font.
1498 * Note that the @fontsel needs to know the screen in which it will appear
1499 * for this to work; this can be guaranteed by simply making sure that the
1500 * @fontsel is inserted in a toplevel window before you call this function.
1502 * Return value: %TRUE if the font could be set successfully; %FALSE if no
1503 * such font exists or if the @fontsel doesn't belong to a particular
1507 gtk_font_selection_set_font_name (GtkFontSelection *fontsel,
1508 const gchar *fontname)
1510 PangoFontFamily *family = NULL;
1511 PangoFontFace *face = NULL;
1512 PangoFontDescription *new_desc;
1514 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), FALSE);
1516 if (!gtk_widget_has_screen (GTK_WIDGET (fontsel)))
1519 new_desc = pango_font_description_from_string (fontname);
1521 if (gtk_font_selection_select_font_desc (fontsel, new_desc, &family, &face))
1523 gtk_font_selection_ref_family (fontsel, family);
1525 g_object_unref (family);
1527 gtk_font_selection_ref_face (fontsel, face);
1529 g_object_unref (face);
1532 pango_font_description_free (new_desc);
1534 g_object_notify (G_OBJECT (fontsel), "font-name");
1540 * gtk_font_selection_get_preview_text:
1541 * @fontsel: a #GtkFontSelection
1543 * Gets the text displayed in the preview area.
1545 * Return value: the text displayed in the preview area.
1546 * This string is owned by the widget and should not be
1549 G_CONST_RETURN gchar*
1550 gtk_font_selection_get_preview_text (GtkFontSelection *fontsel)
1552 GtkFontSelectionPrivate *priv;
1554 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1556 priv = fontsel->priv;
1558 return gtk_entry_get_text (GTK_ENTRY (priv->preview_entry));
1563 * gtk_font_selection_set_preview_text:
1564 * @fontsel: a #GtkFontSelection
1565 * @text: the text to display in the preview area
1567 * Sets the text displayed in the preview area.
1568 * The @text is used to show how the selected font looks.
1571 gtk_font_selection_set_preview_text (GtkFontSelection *fontsel,
1574 GtkFontSelectionPrivate *priv;
1576 g_return_if_fail (GTK_IS_FONT_SELECTION (fontsel));
1577 g_return_if_fail (text != NULL);
1579 priv = fontsel->priv;
1581 gtk_entry_set_text (GTK_ENTRY (priv->preview_entry), text);
1584 /*****************************************************************************
1585 * GtkFontSelectionDialog
1586 *****************************************************************************/
1588 static void gtk_font_selection_dialog_buildable_interface_init (GtkBuildableIface *iface);
1589 static GObject * gtk_font_selection_dialog_buildable_get_internal_child (GtkBuildable *buildable,
1590 GtkBuilder *builder,
1591 const gchar *childname);
1593 G_DEFINE_TYPE_WITH_CODE (GtkFontSelectionDialog, gtk_font_selection_dialog,
1595 G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
1596 gtk_font_selection_dialog_buildable_interface_init))
1598 static GtkBuildableIface *parent_buildable_iface;
1601 gtk_font_selection_dialog_class_init (GtkFontSelectionDialogClass *klass)
1603 g_type_class_add_private (klass, sizeof (GtkFontSelectionDialogPrivate));
1607 gtk_font_selection_dialog_init (GtkFontSelectionDialog *fontseldiag)
1609 GtkFontSelectionDialogPrivate *priv;
1610 GtkDialog *dialog = GTK_DIALOG (fontseldiag);
1611 GtkWidget *action_area, *content_area;
1613 fontseldiag->priv = G_TYPE_INSTANCE_GET_PRIVATE (fontseldiag,
1614 GTK_TYPE_FONT_SELECTION_DIALOG,
1615 GtkFontSelectionDialogPrivate);
1616 priv = fontseldiag->priv;
1618 content_area = gtk_dialog_get_content_area (dialog);
1619 action_area = gtk_dialog_get_action_area (dialog);
1621 gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
1622 gtk_box_set_spacing (GTK_BOX (content_area), 2); /* 2 * 5 + 2 = 12 */
1623 gtk_container_set_border_width (GTK_CONTAINER (action_area), 5);
1624 gtk_box_set_spacing (GTK_BOX (action_area), 6);
1626 gtk_widget_push_composite_child ();
1628 gtk_window_set_resizable (GTK_WINDOW (fontseldiag), TRUE);
1630 /* Create the content area */
1631 priv->fontsel = gtk_font_selection_new ();
1632 gtk_container_set_border_width (GTK_CONTAINER (priv->fontsel), 5);
1633 gtk_widget_show (priv->fontsel);
1634 gtk_box_pack_start (GTK_BOX (content_area),
1635 priv->fontsel, TRUE, TRUE, 0);
1637 /* Create the action area */
1638 priv->cancel_button = gtk_dialog_add_button (dialog,
1640 GTK_RESPONSE_CANCEL);
1642 priv->apply_button = gtk_dialog_add_button (dialog,
1644 GTK_RESPONSE_APPLY);
1645 gtk_widget_hide (priv->apply_button);
1647 priv->ok_button = gtk_dialog_add_button (dialog,
1650 gtk_widget_grab_default (priv->ok_button);
1652 gtk_dialog_set_alternative_button_order (GTK_DIALOG (fontseldiag),
1655 GTK_RESPONSE_CANCEL,
1658 gtk_window_set_title (GTK_WINDOW (fontseldiag),
1659 _("Font Selection"));
1661 gtk_widget_pop_composite_child ();
1665 * gtk_font_selection_dialog_new:
1666 * @title: the title of the dialog window
1668 * Creates a new #GtkFontSelectionDialog.
1670 * Return value: a new #GtkFontSelectionDialog
1673 gtk_font_selection_dialog_new (const gchar *title)
1675 GtkFontSelectionDialog *fontseldiag;
1677 fontseldiag = g_object_new (GTK_TYPE_FONT_SELECTION_DIALOG, NULL);
1680 gtk_window_set_title (GTK_WINDOW (fontseldiag), title);
1682 return GTK_WIDGET (fontseldiag);
1686 * gtk_font_selection_dialog_get_font_selection:
1687 * @fsd: a #GtkFontSelectionDialog
1689 * Retrieves the #GtkFontSelection widget embedded in the dialog.
1691 * Returns: (transfer none): the embedded #GtkFontSelection
1696 gtk_font_selection_dialog_get_font_selection (GtkFontSelectionDialog *fsd)
1698 g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1700 return fsd->priv->fontsel;
1705 * gtk_font_selection_dialog_get_ok_button:
1706 * @fsd: a #GtkFontSelectionDialog
1708 * Gets the 'OK' button.
1710 * Return value: (transfer none): the #GtkWidget used in the dialog
1711 * for the 'OK' button.
1716 gtk_font_selection_dialog_get_ok_button (GtkFontSelectionDialog *fsd)
1718 g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1720 return fsd->priv->ok_button;
1724 * gtk_font_selection_dialog_get_cancel_button:
1725 * @fsd: a #GtkFontSelectionDialog
1727 * Gets the 'Cancel' button.
1729 * Return value: (transfer none): the #GtkWidget used in the dialog
1730 * for the 'Cancel' button.
1735 gtk_font_selection_dialog_get_cancel_button (GtkFontSelectionDialog *fsd)
1737 g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1739 return fsd->priv->cancel_button;
1743 gtk_font_selection_dialog_buildable_interface_init (GtkBuildableIface *iface)
1745 parent_buildable_iface = g_type_interface_peek_parent (iface);
1746 iface->get_internal_child = gtk_font_selection_dialog_buildable_get_internal_child;
1750 gtk_font_selection_dialog_buildable_get_internal_child (GtkBuildable *buildable,
1751 GtkBuilder *builder,
1752 const gchar *childname)
1754 GtkFontSelectionDialogPrivate *priv;
1756 priv = GTK_FONT_SELECTION_DIALOG (buildable)->priv;
1758 if (g_strcmp0 (childname, "ok_button") == 0)
1759 return G_OBJECT (priv->ok_button);
1760 else if (g_strcmp0 (childname, "cancel_button") == 0)
1761 return G_OBJECT (priv->cancel_button);
1762 else if (g_strcmp0 (childname, "apply_button") == 0)
1763 return G_OBJECT (priv->apply_button);
1764 else if (g_strcmp0 (childname, "font_selection") == 0)
1765 return G_OBJECT (priv->fontsel);
1767 return parent_buildable_iface->get_internal_child (buildable, builder, childname);
1771 * gtk_font_selection_dialog_get_font_name:
1772 * @fsd: a #GtkFontSelectionDialog
1774 * Gets the currently-selected font name.
1776 * Note that this can be a different string than what you set with
1777 * gtk_font_selection_dialog_set_font_name(), as the font selection widget
1778 * may normalize font names and thus return a string with a different
1779 * structure. For example, "Helvetica Italic Bold 12" could be normalized
1780 * to "Helvetica Bold Italic 12". Use pango_font_description_equal()
1781 * if you want to compare two font descriptions.
1783 * Return value: A string with the name of the current font, or %NULL if no
1784 * font is selected. You must free this string with g_free().
1787 gtk_font_selection_dialog_get_font_name (GtkFontSelectionDialog *fsd)
1789 GtkFontSelectionDialogPrivate *priv;
1791 g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1795 return gtk_font_selection_get_font_name (GTK_FONT_SELECTION (priv->fontsel));
1799 * gtk_font_selection_dialog_set_font_name:
1800 * @fsd: a #GtkFontSelectionDialog
1801 * @fontname: a font name like "Helvetica 12" or "Times Bold 18"
1803 * Sets the currently selected font.
1805 * Return value: %TRUE if the font selected in @fsd is now the
1806 * @fontname specified, %FALSE otherwise.
1809 gtk_font_selection_dialog_set_font_name (GtkFontSelectionDialog *fsd,
1810 const gchar *fontname)
1812 GtkFontSelectionDialogPrivate *priv;
1814 g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), FALSE);
1815 g_return_val_if_fail (fontname, FALSE);
1819 return gtk_font_selection_set_font_name (GTK_FONT_SELECTION (priv->fontsel), fontname);
1823 * gtk_font_selection_dialog_get_preview_text:
1824 * @fsd: a #GtkFontSelectionDialog
1826 * Gets the text displayed in the preview area.
1828 * Return value: the text displayed in the preview area.
1829 * This string is owned by the widget and should not be
1832 G_CONST_RETURN gchar*
1833 gtk_font_selection_dialog_get_preview_text (GtkFontSelectionDialog *fsd)
1835 GtkFontSelectionDialogPrivate *priv;
1837 g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1841 return gtk_font_selection_get_preview_text (GTK_FONT_SELECTION (priv->fontsel));
1845 * gtk_font_selection_dialog_set_preview_text:
1846 * @fsd: a #GtkFontSelectionDialog
1847 * @text: the text to display in the preview area
1849 * Sets the text displayed in the preview area.
1852 gtk_font_selection_dialog_set_preview_text (GtkFontSelectionDialog *fsd,
1855 GtkFontSelectionDialogPrivate *priv;
1857 g_return_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd));
1858 g_return_if_fail (text != NULL);
1862 gtk_font_selection_set_preview_text (GTK_FONT_SELECTION (priv->fontsel), text);