1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 2011 Alberto Ruiz <aruiz@gnome.org>
3 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
5 * Massively updated to rework the user interface by Alberto Ruiz, 2011
6 * Massively updated for Pango by Owen Taylor, May 2000
7 * GtkFontChooser widget for Gtk+, by Damon Chaplin, May 1998.
8 * Based on the GnomeFontSelector widget, by Elliot Lee, but major changes.
9 * The GnomeFontSelector was derived from app/text_tool.c in the GIMP.
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2 of the License, or (at your option) any later version.
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the
23 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24 * Boston, MA 02111-1307, USA.
30 #include <glib/gprintf.h>
35 #include "gtkfontchooser.h"
36 #include "gtkbutton.h"
37 #include "gtkcellrenderertext.h"
43 #include "gtkliststore.h"
47 #include "gtktreeselection.h"
48 #include "gtktreeview.h"
50 #include "gtkscrolledwindow.h"
52 #include "gtkaccessible.h"
53 #include "gtkbuildable.h"
54 #include "gtkprivate.h"
55 #include "gtkalignment.h"
58 #include "gtkspinbutton.h"
59 #include "gtkwidget.h"
62 * SECTION:gtkfontchooser
63 * @Short_description: A widget for selecting fonts
64 * @Title: GtkFontChooser
65 * @See_also: #GtkFontChooserDialog
67 * The #GtkFontChooser widget lists the available fonts, styles and sizes,
68 * allowing the user to select a font.
69 * It is used in the #GtkFontChooserDialog widget to provide a dialog box for
72 * To set the font which is initially selected, use
73 * gtk_font_chooser_set_font_name().
75 * To get the selected font use gtk_font_chooser_get_font_name().
77 * To change the text which is shown in the preview area, use
78 * gtk_font_chooser_set_preview_text().
82 struct _GtkFontChooserPrivate
84 GtkWidget *search_entry;
85 GtkWidget *family_face_list;
90 GtkWidget *preview_scrolled_window;
92 gboolean show_preview_entry;
95 GtkWidget *size_slider;
96 gboolean ignore_slider;
100 PangoFontFamily *family;
103 GtkWidget *size_list;
104 GtkWidget *font_list;
105 GtkWidget *face_list;
107 GtkListStore *_size_model;
108 GtkListStore *_font_model;
109 GtkListStore *_face_model;
111 gboolean ignore_size;
112 gboolean ignore_face;
113 gboolean ignore_font;
117 struct _GtkFontChooserDialogPrivate
119 GtkWidget *fontchooser;
121 GtkWidget *select_button;
122 GtkWidget *cancel_button;
125 GtkWidget *apply_button;
129 #define DEFAULT_FONT_NAME "Sans 10"
130 #define MAX_FONT_SIZE 999
132 /* This is the initial fixed height and the top padding of the preview entry */
133 #define PREVIEW_HEIGHT 72
134 #define PREVIEW_TOP_PADDING 6
136 /* Widget default geometry */
137 #define FONT_CHOOSER_WIDTH 540
138 #define FONT_CHOOSER_HEIGHT 408
140 /* These are the sizes of the font, style & size lists. */
141 #define FONT_LIST_HEIGHT 136
142 #define FONT_LIST_WIDTH 190
143 #define FONT_STYLE_LIST_WIDTH 170
144 #define FONT_SIZE_LIST_WIDTH 60
146 #define ROW_FORMAT_STRING "<span weight=\"bold\" size=\"small\" foreground=\"%s\">%s</span>\n<span size=\"x-large\" font_desc=\"%s\">%s</span>"
148 /* These are what we use as the standard font sizes, for the size list.
150 #define FONT_SIZES_LENGTH 14
151 static const gint font_sizes[] = {
152 6, 8, 9, 10, 11, 12, 13, 14, 16, 20, 24, 36, 48, 72
159 PROP_SHOW_PREVIEW_ENTRY
170 static void gtk_font_chooser_set_property (GObject *object,
174 static void gtk_font_chooser_get_property (GObject *object,
178 static void gtk_font_chooser_finalize (GObject *object);
180 static void gtk_font_chooser_screen_changed (GtkWidget *widget,
181 GdkScreen *previous_screen);
182 static void gtk_font_chooser_style_updated (GtkWidget *widget);
184 static void gtk_font_chooser_ref_family (GtkFontChooser *fontchooser,
185 PangoFontFamily *family);
186 static void gtk_font_chooser_ref_face (GtkFontChooser *fontchooser,
187 PangoFontFace *face);
189 static void gtk_font_chooser_bootstrap_fontlist (GtkFontChooser *fontchooser);
192 static void update_font_list_selection (GtkFontChooser *fontchooser);
193 static void update_size_list_selection (GtkFontChooser *fontchooser);
194 static void update_face_model (GtkFontChooser *fontchooser,
197 G_DEFINE_TYPE (GtkFontChooser, gtk_font_chooser, GTK_TYPE_VBOX)
200 gtk_font_chooser_class_init (GtkFontChooserClass *klass)
202 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
203 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
205 widget_class->screen_changed = gtk_font_chooser_screen_changed;
206 widget_class->style_updated = gtk_font_chooser_style_updated;
208 gobject_class->finalize = gtk_font_chooser_finalize;
209 gobject_class->set_property = gtk_font_chooser_set_property;
210 gobject_class->get_property = gtk_font_chooser_get_property;
212 g_object_class_install_property (gobject_class,
214 g_param_spec_string ("font-name",
216 P_("The string that represents this font"),
218 GTK_PARAM_READWRITE));
219 g_object_class_install_property (gobject_class,
221 g_param_spec_string ("preview-text",
223 P_("The text to display in order to demonstrate the selected font"),
224 pango_language_get_sample_string (NULL),
225 GTK_PARAM_READWRITE));
227 g_object_class_install_property (gobject_class,
228 PROP_SHOW_PREVIEW_ENTRY,
229 g_param_spec_boolean ("show-preview-entry",
230 P_("Show preview text entry"),
231 P_("Whether the preview text entry is shown or not"),
233 GTK_PARAM_READWRITE));
235 g_type_class_add_private (klass, sizeof (GtkFontChooserPrivate));
239 gtk_font_chooser_set_property (GObject *object,
244 GtkFontChooser *fontchooser;
246 fontchooser = GTK_FONT_CHOOSER (object);
251 gtk_font_chooser_set_font_name (fontchooser, g_value_get_string (value));
253 case PROP_PREVIEW_TEXT:
254 gtk_font_chooser_set_preview_text (fontchooser, g_value_get_string (value));
256 case PROP_SHOW_PREVIEW_ENTRY:
257 gtk_font_chooser_set_show_preview_entry (fontchooser, g_value_get_boolean (value));
259 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
265 gtk_font_chooser_get_property (GObject *object,
270 GtkFontChooser *fontchooser;
272 fontchooser = GTK_FONT_CHOOSER (object);
277 g_value_take_string (value, gtk_font_chooser_get_font_name (fontchooser));
279 case PROP_PREVIEW_TEXT:
280 g_value_set_string (value, gtk_font_chooser_get_preview_text (fontchooser));
282 case PROP_SHOW_PREVIEW_ENTRY:
283 g_value_set_boolean (value, gtk_font_chooser_get_show_preview_entry (fontchooser));
285 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
291 refilter_and_focus (GtkFontChooserPrivate *priv)
294 GtkTreeView *treeview = GTK_TREE_VIEW (priv->family_face_list);
295 GtkTreePath *path = gtk_tree_path_new ();
297 gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (priv->filter));
302 gtk_tree_view_get_cursor (treeview, &path, NULL);
304 if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->filter), &iter, path))
306 gtk_tree_path_free (path);
310 gtk_tree_view_scroll_to_cell (treeview, path, NULL, TRUE, 0.5, 0.5);
311 gtk_tree_path_free (path);
315 deleted_text_cb (GtkEntryBuffer *buffer,
320 GtkFontChooserPrivate *priv = (GtkFontChooserPrivate*)user_data;
321 GtkWidget *entry = priv->search_entry;
323 if (gtk_entry_buffer_get_length (buffer) == 0)
325 gtk_entry_set_icon_from_stock (GTK_ENTRY (entry),
326 GTK_ENTRY_ICON_SECONDARY,
330 gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (priv->filter));
334 inserted_text_cb (GtkEntryBuffer *buffer,
340 GtkFontChooserPrivate *priv = (GtkFontChooserPrivate*)user_data;
341 GtkWidget *entry = priv->search_entry;
343 if (g_strcmp0 (gtk_entry_get_icon_stock (GTK_ENTRY (entry), GTK_ENTRY_ICON_SECONDARY),
345 gtk_entry_set_icon_from_stock (GTK_ENTRY (entry),
346 GTK_ENTRY_ICON_SECONDARY,
350 gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (priv->filter));
354 icon_press_cb (GtkEntry *entry,
355 GtkEntryIconPosition pos,
359 gtk_entry_buffer_delete_text (gtk_entry_get_buffer (entry), 0, -1);
363 slider_change_cb (GtkAdjustment *adjustment, gpointer data)
365 GtkFontChooserPrivate *priv = (GtkFontChooserPrivate*)data;
367 /* If we set the silder value manually, we ignore this callback */
368 if (priv->ignore_slider)
370 priv->ignore_slider = FALSE;
374 gtk_adjustment_set_value (gtk_spin_button_get_adjustment( GTK_SPIN_BUTTON(priv->size_spin)),
375 gtk_adjustment_get_value (adjustment));
379 spin_change_cb (GtkAdjustment *adjustment, gpointer data)
381 PangoFontDescription *desc;
382 GtkFontChooser *fontchooser = (GtkFontChooser*)data;
383 GtkFontChooserPrivate *priv = fontchooser->priv;
385 gdouble size = gtk_adjustment_get_value (adjustment);
387 GtkAdjustment *slider_adj = gtk_range_get_adjustment (GTK_RANGE (priv->size_slider));
389 /* We ignore the slider value change callback for both of this set_value call */
390 priv->ignore_slider = TRUE;
391 if (size < gtk_adjustment_get_lower (slider_adj))
392 gtk_adjustment_set_value (slider_adj, gtk_adjustment_get_lower (slider_adj));
393 else if (size > gtk_adjustment_get_upper (slider_adj))
394 gtk_adjustment_set_value (slider_adj, gtk_adjustment_get_upper (slider_adj));
396 gtk_adjustment_set_value (slider_adj, size);
398 priv->size = ((gint)gtk_adjustment_get_value (adjustment)) * PANGO_SCALE;
400 desc = pango_context_get_font_description (gtk_widget_get_pango_context (priv->preview));
401 pango_font_description_set_size (desc, priv->size);
402 gtk_widget_override_font (priv->preview, desc);
408 priv->ignore_size = TRUE;
409 update_size_list_selection (fontchooser);
412 g_object_notify (G_OBJECT (fontchooser), "font-name");
414 gtk_widget_queue_draw (priv->preview);
418 set_range_marks (GtkFontChooserPrivate *priv,
419 GtkWidget* size_slider,
429 sizes = (gint*)font_sizes;
430 length = FONT_SIZES_LENGTH;
433 gtk_scale_clear_marks (GTK_SCALE (size_slider));
435 adj = gtk_range_get_adjustment(GTK_RANGE (size_slider));
437 gtk_adjustment_set_lower (adj, (gdouble) sizes[0]);
438 gtk_adjustment_set_upper (adj, (gdouble) sizes[length-1]);
440 value = gtk_adjustment_get_value (adj);
441 if (value > (gdouble) sizes[length-1])
443 gtk_adjustment_set_value (adj, (gdouble) sizes[length-1]);
444 priv->ignore_slider = TRUE;
446 else if (value < (gdouble) sizes[0])
448 gtk_adjustment_set_value (adj, (gdouble) sizes[0]);
449 priv->ignore_slider = TRUE;
452 /* Deprecated: just populate the marks in the scale after removal */
453 if (!priv->_size_model)
455 for (i=0; i<length; i++)
456 gtk_scale_add_mark (GTK_SCALE (size_slider),
458 GTK_POS_BOTTOM, NULL);
462 GString *size_str = g_string_new (NULL);
463 gtk_list_store_clear (priv->_size_model);
465 for (i=0; i<length; i++)
469 g_string_printf (size_str, "%d", sizes[i]);
471 gtk_scale_add_mark (GTK_SCALE (size_slider),
473 GTK_POS_BOTTOM, NULL);
475 gtk_list_store_append (priv->_size_model, &iter);
476 gtk_list_store_set (priv->_size_model, &iter,
481 g_string_free (size_str, TRUE);
486 cursor_changed_cb (GtkTreeView *treeview, gpointer data)
488 PangoFontFamily *family;
490 PangoFontDescription *desc;
496 GtkTreePath *path = gtk_tree_path_new ();
498 GtkFontChooser *fontchooser = (GtkFontChooser*)data;
500 gtk_tree_view_get_cursor (treeview, &path, NULL);
505 if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (fontchooser->priv->filter), &iter, path))
507 gtk_tree_path_free (path);
512 gtk_tree_model_get (GTK_TREE_MODEL (fontchooser->priv->filter), &iter,
514 FAMILY_COLUMN, &family,
517 gtk_tree_view_scroll_to_cell (treeview, path, NULL, TRUE, 0.5, 0.5);
519 gtk_tree_path_free (path);
522 if (!face || !family)
524 g_object_unref (face);
525 g_object_unref (family);
529 desc = pango_font_face_describe (face);
530 pango_font_description_set_size (desc, fontchooser->priv->size);
531 gtk_widget_override_font (fontchooser->priv->preview, desc);
533 pango_font_face_list_sizes (face, &sizes, &n_sizes);
534 /* It seems not many fonts actually have a sane set of sizes */
535 for (i=0; i<n_sizes; i++)
536 sizes[i] = sizes[i] / PANGO_SCALE;
538 set_range_marks (fontchooser->priv, fontchooser->priv->size_slider, sizes, n_sizes);
540 gtk_font_chooser_ref_family (fontchooser, family);
541 gtk_font_chooser_ref_face (fontchooser, face);
543 /* Deprecated: Remove if clause after removal */
544 if (fontchooser->priv->_font_model)
545 update_font_list_selection (fontchooser);
548 g_object_unref ((gpointer)family);
549 g_object_unref ((gpointer)face);
550 pango_font_description_free(desc);
552 g_object_notify (G_OBJECT (fontchooser), "font-name");
556 zoom_preview_cb (GtkWidget *scrolled_window, GdkEventScroll *event, gpointer data)
558 GtkFontChooserPrivate *priv = (GtkFontChooserPrivate*)data;
560 GtkAdjustment *adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->size_spin));
562 if (event->direction == GDK_SCROLL_UP || event->direction == GDK_SCROLL_RIGHT)
563 gtk_adjustment_set_value (adj,
564 gtk_adjustment_get_value (adj) +
565 gtk_adjustment_get_step_increment (adj));
566 else if (event->direction == GDK_SCROLL_DOWN || event->direction == GDK_SCROLL_LEFT)
567 gtk_adjustment_set_value (adj,
568 gtk_adjustment_get_value (adj) -
569 gtk_adjustment_get_step_increment (adj));
574 gtk_font_chooser_init (GtkFontChooser *fontchooser)
576 GtkFontChooserPrivate *priv;
577 PangoFontDescription *font_desc;
578 GtkWidget *scrolled_win;
579 GtkWidget *preview_and_size;
580 GtkWidget *size_controls;
582 fontchooser->priv = G_TYPE_INSTANCE_GET_PRIVATE (fontchooser,
583 GTK_TYPE_FONT_CHOOSER,
584 GtkFontChooserPrivate);
586 priv = fontchooser->priv;
588 /* Deprecated: These members will not exist after removal */
589 priv->size_list = NULL;
590 priv->font_list = NULL;
591 priv->face_list = NULL;
593 priv->_size_model = NULL;
594 priv->_font_model = NULL;
595 priv->_face_model = NULL;
597 priv->ignore_size = FALSE;
598 priv->ignore_face = FALSE;
599 priv->ignore_font = FALSE;
601 /* Default preview string */
602 priv->preview_text = g_strdup (pango_language_get_sample_string (NULL));
603 priv->show_preview_entry = TRUE;
605 /* Getting the default size */
606 font_desc = pango_context_get_font_description (gtk_widget_get_pango_context (GTK_WIDGET (fontchooser)));
607 priv->size = pango_font_description_get_size (font_desc);
611 gtk_widget_push_composite_child ();
613 /* Creating fundamental widgets for the private struct */
614 priv->search_entry = gtk_entry_new ();
615 priv->family_face_list = gtk_tree_view_new ();
616 priv->preview = gtk_entry_new ();
617 priv->size_slider = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL,
618 (gdouble) font_sizes[0],
619 (gdouble) font_sizes[FONT_SIZES_LENGTH - 1],
622 priv->size_spin = gtk_spin_button_new_with_range (0.0, (gdouble)(G_MAXINT / PANGO_SCALE), 1.0);
624 /** Bootstrapping widget layout **/
625 gtk_box_set_spacing (GTK_BOX (fontchooser), 6);
626 gtk_box_pack_start (GTK_BOX (fontchooser), priv->search_entry, FALSE, TRUE, 0);
628 /* Main font family/face view */
629 scrolled_win = gtk_scrolled_window_new (NULL, NULL);
630 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
631 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
632 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win),
633 GTK_SHADOW_ETCHED_IN);
634 gtk_container_add (GTK_CONTAINER (scrolled_win), priv->family_face_list);
636 /* Alignment for the preview and size controls */
637 gtk_box_pack_start (GTK_BOX (fontchooser), scrolled_win, TRUE, TRUE, 0);
639 preview_and_size = gtk_vbox_new (TRUE, 0);
640 gtk_box_set_homogeneous (GTK_BOX (preview_and_size), FALSE);
641 gtk_box_set_spacing (GTK_BOX (preview_and_size), 6);
643 /* The preview entry needs a scrolled window to make sure we have a */
644 scrolled_win = gtk_scrolled_window_new (NULL, NULL);
645 priv->preview_scrolled_window = scrolled_win;
646 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
647 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
648 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win),
649 GTK_SHADOW_ETCHED_IN);
650 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_win),
652 gtk_box_pack_start (GTK_BOX (preview_and_size), scrolled_win, FALSE, FALSE, 0);
654 /* Setting the size requests for various widgets */
655 gtk_widget_set_size_request (GTK_WIDGET (fontchooser), FONT_CHOOSER_WIDTH, FONT_CHOOSER_HEIGHT);
656 gtk_widget_set_size_request (scrolled_win, -1, PREVIEW_HEIGHT);
657 gtk_widget_set_size_request (priv->preview, -1, PREVIEW_HEIGHT - 6);
659 /* Unset the frame on the preview entry */
660 gtk_entry_set_has_frame (GTK_ENTRY (priv->preview), FALSE);
662 /* Packing the slider and the spin in a hbox */
663 size_controls = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
664 gtk_scale_set_draw_value (GTK_SCALE (priv->size_slider), FALSE);
665 gtk_box_set_spacing (GTK_BOX (size_controls), 6);
666 gtk_box_pack_start (GTK_BOX (size_controls), priv->size_slider, TRUE, TRUE, 0);
667 gtk_box_pack_start (GTK_BOX (size_controls), priv->size_spin, FALSE, TRUE, 0);
669 gtk_widget_set_valign (priv->size_spin, GTK_ALIGN_START);
671 gtk_box_pack_start (GTK_BOX (preview_and_size), size_controls, FALSE, FALSE, 0);
673 gtk_box_pack_start (GTK_BOX (fontchooser), GTK_WIDGET(preview_and_size), FALSE, TRUE, 0);
675 gtk_adjustment_set_value (gtk_range_get_adjustment (GTK_RANGE (priv->size_slider)),
676 (gdouble)(priv->size / PANGO_SCALE));
677 gtk_adjustment_set_value (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->size_spin)),
678 (gdouble)(priv->size / PANGO_SCALE));
680 gtk_widget_show_all (GTK_WIDGET (fontchooser));
681 gtk_widget_hide (GTK_WIDGET (fontchooser));
683 /* Treeview column and model bootstrapping */
684 gtk_font_chooser_bootstrap_fontlist (fontchooser);
686 /* Set default preview text */
687 gtk_entry_set_text (GTK_ENTRY (priv->preview),
688 pango_language_get_sample_string (NULL));
690 /* Set search icon and place holder text */
691 gtk_entry_set_icon_from_stock (GTK_ENTRY (priv->search_entry),
692 GTK_ENTRY_ICON_SECONDARY,
694 gtk_entry_set_placeholder_text (GTK_ENTRY (priv->search_entry), _("Search font name"));
696 /** Callback connections **/
697 /* Connect to callback for the live search text entry */
698 g_signal_connect (G_OBJECT (gtk_entry_get_buffer (GTK_ENTRY (priv->search_entry))),
699 "deleted-text", G_CALLBACK (deleted_text_cb), priv);
700 g_signal_connect (G_OBJECT (gtk_entry_get_buffer (GTK_ENTRY (priv->search_entry))),
701 "inserted-text", G_CALLBACK (inserted_text_cb), priv);
702 g_signal_connect (G_OBJECT (priv->search_entry),
703 "icon-press", G_CALLBACK (icon_press_cb), priv);
705 /* Size controls callbacks */
706 g_signal_connect (G_OBJECT (gtk_range_get_adjustment (GTK_RANGE (priv->size_slider))),
707 "value-changed", G_CALLBACK (slider_change_cb), priv);
708 g_signal_connect (G_OBJECT (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->size_spin))),
709 "value-changed", G_CALLBACK (spin_change_cb), fontchooser);
710 priv->ignore_slider = FALSE;
712 /* Font selection callback */
713 g_signal_connect (G_OBJECT (priv->family_face_list), "cursor-changed",
714 G_CALLBACK (cursor_changed_cb), fontchooser);
716 /* Zoom on preview scroll*/
717 g_signal_connect (G_OBJECT (scrolled_win), "scroll-event",
718 G_CALLBACK (zoom_preview_cb), priv);
720 g_signal_connect (G_OBJECT (priv->size_slider), "scroll-event",
721 G_CALLBACK (zoom_preview_cb), priv);
723 set_range_marks (priv, priv->size_slider, (gint*)font_sizes, FONT_SIZES_LENGTH);
725 /* Set default focus */
726 gtk_widget_pop_composite_child();
730 * gtk_font_chooser_new:
732 * Creates a new #GtkFontChooser.
734 * Return value: a new #GtkFontChooser
737 gtk_font_chooser_new (void)
739 GtkFontChooser *fontchooser;
741 fontchooser = g_object_new (GTK_TYPE_FONT_CHOOSER, NULL);
743 return GTK_WIDGET (fontchooser);
747 cmp_families (const void *a, const void *b)
749 const char *a_name = pango_font_family_get_name (*(PangoFontFamily **)a);
750 const char *b_name = pango_font_family_get_name (*(PangoFontFamily **)b);
752 return g_utf8_collate (a_name, b_name);
756 populate_list (GtkFontChooser *fontchooser, GtkTreeView* treeview, GtkListStore* model)
758 GtkStyleContext *style_context;
762 PangoFontDescription *default_font;
764 GtkTreeIter match_row;
768 PangoFontFamily **families;
770 GString *tmp = g_string_new (NULL);
771 GString *family_and_face = g_string_new (NULL);
773 pango_context_list_families (gtk_widget_get_pango_context (GTK_WIDGET (treeview)),
777 qsort (families, n_families, sizeof (PangoFontFamily *), cmp_families);
779 gtk_list_store_clear (model);
781 /* Get row header font color */
782 style_context = gtk_widget_get_style_context (GTK_WIDGET (treeview));
783 gtk_style_context_get_color (style_context,
784 GTK_STATE_FLAG_NORMAL | GTK_STATE_FLAG_INSENSITIVE,
787 p_color.red = (guint16)((gdouble)G_MAXUINT16 * g_color.red);
788 p_color.green = (guint16)((gdouble)G_MAXUINT16 * g_color.green);
789 p_color.blue = (guint16)((gdouble)G_MAXUINT16 * g_color.blue);
790 color_string = pango_color_to_string (&p_color);
793 default_font = (PangoFontDescription*) gtk_style_context_get_font (style_context,
796 /* Iterate over families and faces */
797 for (i=0; i<n_families; i++)
800 PangoFontFace **faces;
803 const gchar *fam_name = pango_font_family_get_name (families[i]);
805 pango_font_family_list_faces (families[i], &faces, &n_faces);
807 for (j=0; j<n_faces; j++)
809 PangoFontDescription *pango_desc = pango_font_face_describe (faces[j]);
810 const gchar *face_name = pango_font_face_get_face_name (faces[j]);
811 gchar *font_desc = pango_font_description_to_string (pango_desc);
813 /* foreground_color, family_name, face_name, desc, sample string */
814 g_string_printf (family_and_face, "%s %s",
818 g_string_printf (tmp, ROW_FORMAT_STRING,
820 family_and_face->str,
822 fontchooser->priv->preview_text);
824 gtk_list_store_append (model, &iter);
825 gtk_list_store_set (model, &iter,
826 FAMILY_COLUMN, families[i],
827 FACE_COLUMN, faces[j],
828 PREVIEW_TITLE_COLUMN, family_and_face->str,
829 PREVIEW_TEXT_COLUMN, tmp->str,
832 /* Select the first font or the default font/face from the style context */
833 if ((i == 0 && j == 0) ||
834 (!strcmp (fam_name, pango_font_description_get_family (default_font)) && j == 0))
837 pango_font_description_free(pango_desc);
844 path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &match_row);
848 gtk_tree_view_set_cursor (treeview, path, NULL, FALSE);
849 gtk_tree_view_scroll_to_cell (treeview, path, NULL, TRUE, 0.5, 0.5);
850 gtk_tree_path_free(path);
853 g_string_free (family_and_face, TRUE);
854 g_string_free (tmp, TRUE);
855 g_free (color_string);
860 visible_func (GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
862 gboolean result = FALSE;
863 GtkFontChooserPrivate *priv = (GtkFontChooserPrivate*) data;
865 const gchar *search_text = (const gchar*)gtk_entry_get_text (GTK_ENTRY (priv->search_entry));
867 gchar *font_name_casefold;
868 gchar *search_text_casefold;
870 gtk_tree_model_get (model, iter,
871 PREVIEW_TITLE_COLUMN, &font_name,
874 /* Covering some corner cases to speed up the result */
875 if (font_name == NULL ||
876 strlen (search_text) > strlen (font_name))
881 if (strlen (search_text) == 0)
887 font_name_casefold = g_utf8_casefold (font_name, -1);
888 search_text_casefold = g_utf8_casefold (search_text, -1);
890 if (g_strrstr (font_name_casefold, search_text_casefold))
893 g_free (search_text_casefold);
894 g_free (font_name_casefold);
900 gtk_font_chooser_bootstrap_fontlist (GtkFontChooser* fontchooser)
902 GtkTreeView *treeview = GTK_TREE_VIEW (fontchooser->priv->family_face_list);
903 GtkCellRenderer *cell;
904 GtkTreeViewColumn *col;
906 fontchooser->priv->model = gtk_list_store_new (4,
907 PANGO_TYPE_FONT_FAMILY,
908 PANGO_TYPE_FONT_FACE,
912 fontchooser->priv->filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fontchooser->priv->model),
914 g_object_unref (fontchooser->priv->model);
916 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (fontchooser->priv->filter),
918 (gpointer)fontchooser->priv,
921 gtk_tree_view_set_model (treeview, GTK_TREE_MODEL (fontchooser->priv->filter));
922 g_object_unref (fontchooser->priv->filter);
924 gtk_tree_view_set_rules_hint (treeview, TRUE);
925 gtk_tree_view_set_headers_visible (treeview, FALSE);
927 cell = gtk_cell_renderer_text_new ();
928 col = gtk_tree_view_column_new_with_attributes ("Family",
930 "markup", PREVIEW_TEXT_COLUMN,
933 g_object_set (cell, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
935 gtk_tree_view_append_column (treeview, col);
937 populate_list (fontchooser, treeview, fontchooser->priv->model);
942 gtk_font_chooser_finalize (GObject *object)
944 GtkFontChooser *fontchooser = GTK_FONT_CHOOSER (object);
946 gtk_font_chooser_ref_family (fontchooser, NULL);
947 gtk_font_chooser_ref_face (fontchooser, NULL);
949 /* Deprecated: Remove if clause after removal */
950 if (fontchooser->priv->size_list)
952 g_object_unref (fontchooser->priv->size_list);
953 g_object_unref (fontchooser->priv->font_list);
954 g_object_unref (fontchooser->priv->face_list);
957 G_OBJECT_CLASS (gtk_font_chooser_parent_class)->finalize (object);
962 gtk_font_chooser_screen_changed (GtkWidget *widget,
963 GdkScreen *previous_screen)
965 GtkFontChooser *fontchooser = GTK_FONT_CHOOSER (widget);
967 populate_list (fontchooser,
968 GTK_TREE_VIEW (fontchooser->priv->family_face_list),
969 fontchooser->priv->model);
974 gtk_font_chooser_style_updated (GtkWidget *widget)
976 GtkFontChooser *fontchooser = GTK_FONT_CHOOSER (widget);
978 GTK_WIDGET_CLASS (gtk_font_chooser_parent_class)->style_updated (widget);
980 populate_list (fontchooser,
981 GTK_TREE_VIEW (fontchooser->priv->family_face_list),
982 fontchooser->priv->model);
987 gtk_font_chooser_ref_family (GtkFontChooser *fontchooser,
988 PangoFontFamily *family)
990 GtkFontChooserPrivate *priv = fontchooser->priv;
993 family = g_object_ref (family);
995 g_object_unref (priv->family);
996 priv->family = family;
1000 gtk_font_chooser_ref_face (GtkFontChooser *fontchooser,
1001 PangoFontFace *face)
1003 GtkFontChooserPrivate *priv = fontchooser->priv;
1006 face = g_object_ref (face);
1008 g_object_unref (priv->face);
1012 /* Deprecated: All these functions aid deprecated functionality */
1014 populate_font_model (GtkFontChooser *fontchooser)
1017 PangoFontFamily **families;
1018 GtkFontChooserPrivate *priv = fontchooser->priv;
1021 pango_context_list_families (gtk_widget_get_pango_context (GTK_WIDGET (fontchooser)),
1025 qsort (families, n_families, sizeof (PangoFontFamily *), cmp_families);
1027 gtk_list_store_clear (priv->_font_model);
1029 for (i=0; i<n_families; i++)
1033 gtk_list_store_append (priv->_font_model, &iter);
1034 gtk_list_store_set (priv->_font_model, &iter,
1036 1, pango_font_family_get_name (families[i]),
1039 !strcmp (pango_font_family_get_name (families[i]),
1040 pango_font_family_get_name (priv->family)))
1042 path = gtk_tree_model_get_path (GTK_TREE_MODEL (priv->_face_model),
1046 GtkWidget *tv = gtk_bin_get_child (GTK_BIN (priv->font_list));
1047 gtk_tree_view_set_cursor (GTK_TREE_VIEW (tv),
1051 gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (tv),
1052 path, NULL, TRUE, 0.5, 0.5);
1053 gtk_tree_path_free (path);
1062 update_font_list_selection (GtkFontChooser *fontchooser)
1066 GtkFontChooserPrivate *priv = fontchooser->priv;
1069 valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->_font_model), &iter);
1074 gtk_tree_model_get (GTK_TREE_MODEL (priv->_font_model), &iter,
1077 if (strcmp (family_name, pango_font_family_get_name (priv->family)))
1079 gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->_font_model), &iter);
1080 g_free (family_name);
1083 path = gtk_tree_model_get_path (GTK_TREE_MODEL (priv->_font_model), &iter);
1087 g_free (family_name);
1091 tv = gtk_bin_get_child (GTK_BIN (priv->font_list));
1093 priv->ignore_font = TRUE;
1094 gtk_tree_view_set_cursor (GTK_TREE_VIEW (tv), path, NULL, FALSE);
1095 gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (tv), path, NULL, TRUE, 0.5, 0.5);
1097 /* Free resources */
1098 gtk_tree_path_free (path);
1099 g_free (family_name);
1103 update_face_model (fontchooser, FALSE);
1107 update_face_model (GtkFontChooser *fontchooser, gboolean first)
1109 GtkFontChooserPrivate *priv = fontchooser->priv;
1110 PangoFontFace **faces;
1113 pango_font_family_list_faces (priv->family, &faces, &n_faces);
1115 gtk_list_store_clear (priv->_face_model);
1117 for (i=0; i<n_faces; i++)
1121 gtk_list_store_append (priv->_face_model, &iter);
1122 gtk_list_store_set (priv->_face_model, &iter,
1124 1, pango_font_face_get_face_name (faces[i]),
1127 if ((!first && faces[i] == priv->face) ||
1133 path = gtk_tree_model_get_path (GTK_TREE_MODEL (priv->_face_model), &iter);
1137 tv = gtk_bin_get_child (GTK_BIN (priv->face_list));
1140 priv->ignore_face = TRUE;
1142 gtk_tree_view_set_cursor (GTK_TREE_VIEW (tv), path, NULL, FALSE);
1144 gtk_tree_path_free (path);
1147 gtk_font_chooser_ref_face (fontchooser, faces[i]);
1151 update_size_list_selection (fontchooser);
1153 g_object_notify (G_OBJECT (fontchooser), "font-name");
1157 update_size_list_selection (GtkFontChooser *fontchooser)
1161 GtkFontChooserPrivate *priv = fontchooser->priv;
1162 GtkWidget *tv = gtk_bin_get_child (GTK_BIN (priv->size_list));
1164 gtk_tree_selection_unselect_all (gtk_tree_view_get_selection (GTK_TREE_VIEW (tv)));
1166 valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->_size_model), &iter);
1170 gtk_tree_model_get (GTK_TREE_MODEL (priv->_size_model), &iter,
1174 if (size * PANGO_SCALE == priv->size)
1179 path = gtk_tree_model_get_path (GTK_TREE_MODEL (priv->_size_model), &iter);
1184 priv->ignore_size = TRUE;
1185 gtk_tree_view_set_cursor (GTK_TREE_VIEW (tv), path, NULL, FALSE);
1187 gtk_tree_path_free (path);
1190 valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->_size_model), &iter);
1196 select_family_and_face (GtkFontChooser *fontchooser)
1200 GtkFontChooserPrivate *priv = fontchooser->priv;
1201 PangoFontFace *face;
1202 PangoFontFamily *family;
1204 gtk_entry_set_text (GTK_ENTRY (priv->search_entry), "");
1206 valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->filter), &iter);
1209 gtk_tree_model_get (GTK_TREE_MODEL (priv->filter), &iter,
1211 FAMILY_COLUMN, &family,
1214 if (face == priv->face && family == priv->family)
1218 path = gtk_tree_model_get_path (GTK_TREE_MODEL (priv->filter), &iter);
1221 g_object_unref (face);
1222 g_object_unref (family);
1226 priv->ignore_size = TRUE;
1227 gtk_tree_view_set_cursor (GTK_TREE_VIEW (priv->family_face_list), path, NULL, FALSE);
1229 gtk_tree_path_free (path);
1230 g_object_unref (face);
1231 g_object_unref (family);
1235 g_object_unref (face);
1236 g_object_unref (family);
1237 valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->filter), &iter);
1243 family_list_cursor_changed_cb (GtkTreeView *treeview, gpointer data)
1248 GtkFontChooser *fontchooser = (GtkFontChooser*)data;
1249 PangoFontFamily *font;
1251 if (fontchooser->priv->ignore_font)
1253 fontchooser->priv->ignore_font = FALSE;
1257 tv = gtk_bin_get_child (GTK_BIN (fontchooser->priv->font_list));
1258 gtk_tree_view_get_cursor (GTK_TREE_VIEW (tv), &path, NULL);
1263 gtk_tree_model_get_iter (GTK_TREE_MODEL (fontchooser->priv->_font_model),
1267 gtk_tree_model_get (GTK_TREE_MODEL (fontchooser->priv->_font_model), &iter,
1271 gtk_font_chooser_ref_family (fontchooser, font);
1272 update_face_model (fontchooser, TRUE);
1274 fontchooser->priv->ignore_font = TRUE;
1275 select_family_and_face (fontchooser);
1277 gtk_tree_path_free (path);
1278 g_object_unref (font);
1282 face_list_cursor_changed_cb (GtkTreeView *treeview, gpointer data)
1287 GtkFontChooser *fontchooser = (GtkFontChooser*)data;
1288 PangoFontFace *face;
1290 if (fontchooser->priv->ignore_face)
1292 fontchooser->priv->ignore_face = FALSE;
1296 tv = gtk_bin_get_child (GTK_BIN (fontchooser->priv->face_list));
1297 gtk_tree_view_get_cursor (GTK_TREE_VIEW (tv), &path, NULL);
1302 gtk_tree_model_get_iter (GTK_TREE_MODEL (fontchooser->priv->_face_model),
1306 gtk_tree_model_get (GTK_TREE_MODEL (fontchooser->priv->_face_model), &iter,
1310 gtk_font_chooser_ref_face (fontchooser, face);
1312 fontchooser->priv->ignore_face = TRUE;
1313 select_family_and_face (fontchooser);
1315 gtk_tree_path_free (path);
1316 g_object_unref (face);
1320 size_list_cursor_changed_cb (GtkTreeView *treeview, gpointer data)
1325 GtkFontChooser *fontchooser = (GtkFontChooser*)data;
1328 if (fontchooser->priv->ignore_size)
1330 fontchooser->priv->ignore_size = FALSE;
1334 tv = gtk_bin_get_child (GTK_BIN (fontchooser->priv->size_list));
1335 gtk_tree_view_get_cursor (GTK_TREE_VIEW (tv), &path, NULL);
1340 gtk_tree_model_get_iter (GTK_TREE_MODEL (fontchooser->priv->_size_model),
1344 gtk_tree_model_get (GTK_TREE_MODEL (fontchooser->priv->_size_model), &iter,
1348 gtk_spin_button_set_value (GTK_SPIN_BUTTON (fontchooser->priv->size_spin), value);
1349 gtk_tree_path_free (path);
1353 initialize_deprecated_widgets (GtkFontChooser *fontchooser)
1355 GtkTreeViewColumn *col;
1356 GtkFontChooserPrivate *priv = fontchooser->priv;
1358 GtkWidget *size_list;
1359 GtkWidget *font_list;
1360 GtkWidget *face_list;
1362 priv->_size_model = gtk_list_store_new (2, G_TYPE_INT, G_TYPE_STRING);
1363 priv->_font_model = gtk_list_store_new (2, PANGO_TYPE_FONT_FAMILY, G_TYPE_STRING);
1364 priv->_face_model = gtk_list_store_new (2, PANGO_TYPE_FONT_FACE, G_TYPE_STRING);
1366 size_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (priv->_size_model));
1367 font_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (priv->_font_model));
1368 face_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (priv->_face_model));
1370 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (size_list), FALSE);
1371 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (font_list), FALSE);
1372 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (face_list), FALSE);
1374 g_object_unref (priv->_size_model);
1375 g_object_unref (priv->_font_model);
1376 g_object_unref (priv->_face_model);
1378 col = gtk_tree_view_column_new_with_attributes ("Size",
1379 gtk_cell_renderer_text_new (),
1382 gtk_tree_view_append_column (GTK_TREE_VIEW (size_list), col);
1384 col = gtk_tree_view_column_new_with_attributes ("Family",
1385 gtk_cell_renderer_text_new (),
1388 gtk_tree_view_append_column (GTK_TREE_VIEW (font_list), col);
1390 col = gtk_tree_view_column_new_with_attributes ("Face",
1391 gtk_cell_renderer_text_new (),
1394 gtk_tree_view_append_column (GTK_TREE_VIEW (face_list), col);
1397 priv->font_list = gtk_scrolled_window_new (NULL, NULL);
1398 priv->face_list = gtk_scrolled_window_new (NULL, NULL);
1399 priv->size_list = gtk_scrolled_window_new (NULL, NULL);
1401 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->font_list),
1402 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1403 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->face_list),
1404 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1405 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->size_list),
1406 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1408 gtk_container_add (GTK_CONTAINER (priv->font_list), font_list);
1409 gtk_container_add (GTK_CONTAINER (priv->face_list), face_list);
1410 gtk_container_add (GTK_CONTAINER (priv->size_list), size_list);
1412 g_signal_connect (G_OBJECT (font_list), "cursor-changed",
1413 G_CALLBACK (family_list_cursor_changed_cb), fontchooser);
1415 g_signal_connect (G_OBJECT (face_list), "cursor-changed",
1416 G_CALLBACK (face_list_cursor_changed_cb), fontchooser);
1418 g_signal_connect (G_OBJECT (size_list), "cursor-changed",
1419 G_CALLBACK (size_list_cursor_changed_cb), fontchooser);
1421 populate_font_model (fontchooser);
1422 cursor_changed_cb (GTK_TREE_VIEW (priv->family_face_list), fontchooser);
1425 /*****************************************************************************
1426 * These functions are the main public interface for getting/setting the font.
1427 *****************************************************************************/
1430 * gtk_font_chooser_get_family:
1431 * @fontchooser: a #GtkFontChooser
1433 * Gets the #PangoFontFamily representing the selected font family.
1435 * Return value: (transfer none): A #PangoFontFamily representing the
1436 * selected font family. Font families are a collection of font
1437 * faces. The returned object is owned by @fontchooser and must not
1438 * be modified or freed.
1443 gtk_font_chooser_get_family (GtkFontChooser *fontchooser)
1445 g_return_val_if_fail (GTK_IS_FONT_CHOOSER (fontchooser), NULL);
1447 return fontchooser->priv->family;
1451 * gtk_font_chooser_get_face:
1452 * @fontchooser: a #GtkFontChooser
1454 * Gets the #PangoFontFace representing the selected font group
1455 * details (i.e. family, slant, weight, width, etc).
1457 * Return value: (transfer none): A #PangoFontFace representing the
1458 * selected font group details. The returned object is owned by
1459 * @fontchooser and must not be modified or freed.
1464 gtk_font_chooser_get_face (GtkFontChooser *fontchooser)
1466 g_return_val_if_fail (GTK_IS_FONT_CHOOSER (fontchooser), NULL);
1468 return fontchooser->priv->face;
1472 * gtk_font_chooser_get_size:
1473 * @fontchooser: a #GtkFontChooser
1475 * The selected font size.
1477 * Return value: A n integer representing the selected font size,
1478 * or -1 if no font size is selected.
1483 gtk_font_chooser_get_size (GtkFontChooser *fontchooser)
1485 g_return_val_if_fail (GTK_IS_FONT_CHOOSER (fontchooser), -1);
1487 return fontchooser->priv->size;
1491 * gtk_font_chooser_get_font_name:
1492 * @fontchooser: a #GtkFontChooser
1494 * Gets the currently-selected font name.
1496 * Note that this can be a different string than what you set with
1497 * gtk_font_chooser_set_font_name(), as the font selection widget may
1498 * normalize font names and thus return a string with a different structure.
1499 * For example, "Helvetica Italic Bold 12" could be normalized to
1500 * "Helvetica Bold Italic 12". Use pango_font_description_equal()
1501 * if you want to compare two font descriptions.
1503 * Return value: (transfer full) (allow-none): A string with the name of the
1504 * current font, or %NULL if no font is selected. You must free this
1505 * string with g_free().
1508 gtk_font_chooser_get_font_name (GtkFontChooser *fontchooser)
1511 PangoFontDescription *desc;
1513 if (!fontchooser->priv->face)
1516 desc = pango_font_face_describe (fontchooser->priv->face);
1517 font_name = pango_font_description_to_string (desc);
1518 pango_font_description_free (desc);
1522 /* This sets the current font, then selecting the appropriate list rows. */
1525 * gtk_font_chooser_set_font_name:
1526 * @fontchooser: a #GtkFontChooser
1527 * @fontname: a font name like "Helvetica 12" or "Times Bold 18"
1529 * Sets the currently-selected font.
1531 * Note that the @fontchooser needs to know the screen in which it will appear
1532 * for this to work; this can be guaranteed by simply making sure that the
1533 * @fontchooser is inserted in a toplevel window before you call this function.
1535 * Return value: %TRUE if the font could be set successfully; %FALSE if no
1536 * such font exists or if the @fontchooser doesn't belong to a particular
1540 gtk_font_chooser_set_font_name (GtkFontChooser *fontchooser,
1541 const gchar *fontname)
1543 GtkFontChooserPrivate *priv = fontchooser->priv;
1547 PangoFontDescription *desc;
1548 gboolean found = FALSE;
1550 g_return_val_if_fail (GTK_IS_FONT_CHOOSER (fontchooser), FALSE);
1551 g_return_val_if_fail (fontname != NULL, FALSE);
1553 if (!gtk_widget_has_screen (GTK_WIDGET (fontchooser)))
1556 desc = pango_font_description_from_string (fontname);
1557 family_name = (gchar*)pango_font_description_get_family (desc);
1561 pango_font_description_free (desc);
1565 /* We make sure the filter is clear */
1566 gtk_entry_set_text (GTK_ENTRY (priv->search_entry), "");
1568 /* We find the matching family/face */
1569 for (valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->filter), &iter);
1571 valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->filter), &iter))
1573 PangoFontFace *face;
1574 PangoFontDescription *tmp_desc;
1576 gtk_tree_model_get (GTK_TREE_MODEL (priv->filter), &iter,
1580 tmp_desc = pango_font_face_describe (face);
1581 if (pango_font_description_get_size_is_absolute (desc))
1582 pango_font_description_set_absolute_size (tmp_desc,
1583 pango_font_description_get_size (desc));
1585 pango_font_description_set_size (tmp_desc,
1586 pango_font_description_get_size (desc));
1589 if (pango_font_description_equal (desc, tmp_desc))
1592 gint size = pango_font_description_get_size (desc);
1596 if (pango_font_description_get_size_is_absolute (desc))
1597 size = size * PANGO_SCALE;
1598 gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->size_spin),
1599 size / PANGO_SCALE);
1602 path = gtk_tree_model_get_path (GTK_TREE_MODEL (priv->filter),
1607 gtk_tree_view_set_cursor (GTK_TREE_VIEW (priv->family_face_list),
1611 gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (priv->family_face_list),
1617 gtk_tree_path_free (path);
1623 g_object_unref (face);
1624 pango_font_description_free (tmp_desc);
1630 pango_font_description_free (desc);
1631 g_object_notify (G_OBJECT (fontchooser), "font-name");
1637 * gtk_font_chooser_get_preview_text:
1638 * @fontchooser: a #GtkFontChooser
1640 * Gets the text displayed in the preview area.
1642 * Return value: (transfer none): the text displayed in the
1643 * preview area. This string is owned by the widget and
1644 * should not be modified or freed
1646 G_CONST_RETURN gchar*
1647 gtk_font_chooser_get_preview_text (GtkFontChooser *fontchooser)
1649 g_return_val_if_fail (GTK_IS_FONT_CHOOSER (fontchooser), NULL);
1650 return (const gchar*)fontchooser->priv->preview_text;
1655 * gtk_font_chooser_set_preview_text:
1656 * @fontchooser: a #GtkFontChooser
1657 * @text: (transfer none): the text to display in the preview area
1659 * Sets the text displayed in the preview area.
1660 * The @text is used to show how the selected font looks.
1663 gtk_font_chooser_set_preview_text (GtkFontChooser *fontchooser,
1666 g_return_if_fail (GTK_IS_FONT_CHOOSER (fontchooser));
1667 g_return_if_fail (text != NULL);
1669 g_free (fontchooser->priv->preview_text);
1670 fontchooser->priv->preview_text = g_strdup (text);
1672 populate_list (fontchooser,
1673 GTK_TREE_VIEW (fontchooser->priv->family_face_list),
1674 fontchooser->priv->model);
1676 gtk_entry_set_text (GTK_ENTRY (fontchooser->priv->preview), text);
1678 g_object_notify (G_OBJECT (fontchooser), "preview-text");
1682 * gtk_font_chooser_get_show_preview_entry:
1683 * @fontchooser: a #GtkFontChooser
1685 * Return value: %TRUE if the preview entry is shown or %FALSE if
1690 gtk_font_chooser_get_show_preview_entry (GtkFontChooser *fontchooser)
1692 g_return_val_if_fail (GTK_IS_FONT_CHOOSER (fontchooser), FALSE);
1694 return fontchooser->priv->show_preview_entry;
1698 * gtk_font_chooser_set_show_preview_entry:
1699 * @fontchooser: a #GtkFontChooser
1700 * @show_preview_entry: whether to show the editable preview entry or not
1702 * Shows or hides the editable preview entry.
1706 gtk_font_chooser_set_show_preview_entry (GtkFontChooser *fontchooser,
1707 gboolean show_preview_entry)
1709 g_return_if_fail (GTK_IS_FONT_CHOOSER (fontchooser));
1711 if (show_preview_entry)
1712 gtk_widget_show (fontchooser->priv->preview_scrolled_window);
1714 gtk_widget_hide (fontchooser->priv->preview_scrolled_window);
1716 fontchooser->priv->show_preview_entry = show_preview_entry;
1717 g_object_notify (G_OBJECT (fontchooser), "show-preview-entry");
1721 * gtk_font_chooser_get_family_list:
1722 * @fontchooser: a #GtkFontChooser
1724 * This returns the #GtkTreeView that lists font families, for
1725 * example, 'Sans', 'Serif', etc.
1727 * Return value: (transfer none): A #GtkWidget that is part of @fontchooser
1732 gtk_font_chooser_get_family_list (GtkFontChooser *fontchooser)
1734 GtkFontChooserPrivate *priv = fontchooser->priv;
1735 g_return_val_if_fail (GTK_IS_FONT_CHOOSER (fontchooser), NULL);
1736 if (!priv->font_list)
1737 initialize_deprecated_widgets (fontchooser);
1739 return priv->font_list;
1743 * gtk_font_chooser_get_face_list:
1744 * @fontchooser: a #GtkFontChooser
1746 * This returns the #GtkTreeView which lists all styles available for
1747 * the selected font. For example, 'Regular', 'Bold', etc.
1749 * Return value: (transfer none): A #GtkWidget that is part of @fontchooser
1754 gtk_font_chooser_get_face_list (GtkFontChooser *fontchooser)
1756 GtkFontChooserPrivate *priv = fontchooser->priv;
1757 g_return_val_if_fail (GTK_IS_FONT_CHOOSER (fontchooser), NULL);
1758 if (!priv->face_list)
1759 initialize_deprecated_widgets (fontchooser);
1761 return priv->face_list;
1765 * gtk_font_chooser_get_size_entry:
1766 * @fontchooser: a #GtkFontChooser
1768 * This returns the #GtkEntry used to allow the user to edit the font
1769 * number manually instead of selecting it from the list of font sizes.
1771 * Return value: (transfer none): A #GtkWidget that is part of @fontchooser
1776 gtk_font_chooser_get_size_entry (GtkFontChooser *fontchooser)
1778 GtkFontChooserPrivate *priv = fontchooser->priv;
1779 g_return_val_if_fail (GTK_IS_FONT_CHOOSER (fontchooser), NULL);
1781 return priv->size_spin;
1785 * gtk_font_chooser_get_size_list:
1786 * @fontchooser: a #GtkFontChooser
1788 * This returns the #GtkTreeeView used to list font sizes.
1790 * Return value: (transfer none): A #GtkWidget that is part of @fontchooser
1795 gtk_font_chooser_get_size_list (GtkFontChooser *fontchooser)
1797 GtkFontChooserPrivate *priv = fontchooser->priv;
1798 g_return_val_if_fail (GTK_IS_FONT_CHOOSER (fontchooser), NULL);
1799 if (!priv->size_list)
1800 initialize_deprecated_widgets (fontchooser);
1802 return priv->size_list;
1806 * gtk_font_chooser_get_preview_entry:
1807 * @fontchooser: a #GtkFontChooser
1809 * This returns the #GtkEntry used to display the font as a preview.
1811 * Return value: (transfer none): A #GtkWidget that is part of @fontchooser
1816 gtk_font_chooser_get_preview_entry (GtkFontChooser *fontchooser)
1818 GtkFontChooserPrivate *priv = fontchooser->priv;
1819 g_return_val_if_fail (GTK_IS_FONT_CHOOSER (fontchooser), NULL);
1821 return priv->preview;
1825 * SECTION:gtkfontchooserdlg
1826 * @Short_description: A dialog box for selecting fonts
1827 * @Title: GtkFontChooserDialog
1828 * @See_also: #GtkFontChooser, #GtkDialog
1830 * The #GtkFontChooserDialog widget is a dialog box for selecting a font.
1832 * To set the font which is initially selected, use
1833 * gtk_font_chooser_dialog_set_font_name().
1835 * To get the selected font use gtk_font_chooser_dialog_get_font_name().
1837 * To change the text which is shown in the preview area, use
1838 * gtk_font_chooser_dialog_set_preview_text().
1840 * <refsect2 id="GtkFontChooserDialog-BUILDER-UI">
1841 * <title>GtkFontChooserDialog as GtkBuildable</title>
1842 * The GtkFontChooserDialog implementation of the GtkBuildable interface
1843 * exposes the embedded #GtkFontChooser as internal child with the
1844 * name "font_selection". It also exposes the buttons with the names
1845 * "select_button" and "cancel_button. The buttons with the names
1846 * "ok_button" and "apply_button" are exposed but deprecated.
1850 static void gtk_font_chooser_dialog_buildable_interface_init (GtkBuildableIface *iface);
1851 static GObject * gtk_font_chooser_dialog_buildable_get_internal_child (GtkBuildable *buildable,
1852 GtkBuilder *builder,
1853 const gchar *childname);
1855 G_DEFINE_TYPE_WITH_CODE (GtkFontChooserDialog, gtk_font_chooser_dialog,
1857 G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
1858 gtk_font_chooser_dialog_buildable_interface_init))
1860 static GtkBuildableIface *parent_buildable_iface;
1863 gtk_font_chooser_dialog_class_init (GtkFontChooserDialogClass *klass)
1865 g_type_class_add_private (klass, sizeof (GtkFontChooserDialogPrivate));
1869 gtk_font_chooser_dialog_init (GtkFontChooserDialog *fontchooserdiag)
1871 GtkFontChooserDialogPrivate *priv;
1872 GtkDialog *dialog = GTK_DIALOG (fontchooserdiag);
1873 GtkWidget *action_area, *content_area;
1875 fontchooserdiag->priv = G_TYPE_INSTANCE_GET_PRIVATE (fontchooserdiag,
1876 GTK_TYPE_FONT_CHOOSER_DIALOG,
1877 GtkFontChooserDialogPrivate);
1878 priv = fontchooserdiag->priv;
1880 content_area = gtk_dialog_get_content_area (dialog);
1881 action_area = gtk_dialog_get_action_area (dialog);
1883 gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
1884 gtk_box_set_spacing (GTK_BOX (content_area), 2); /* 2 * 5 + 2 = 12 */
1885 gtk_container_set_border_width (GTK_CONTAINER (action_area), 5);
1886 gtk_box_set_spacing (GTK_BOX (action_area), 6);
1888 gtk_widget_push_composite_child ();
1890 gtk_window_set_resizable (GTK_WINDOW (fontchooserdiag), TRUE);
1892 /* Create the content area */
1893 priv->fontchooser = gtk_font_chooser_new ();
1894 gtk_container_set_border_width (GTK_CONTAINER (priv->fontchooser), 5);
1895 gtk_widget_show (priv->fontchooser);
1896 gtk_box_pack_start (GTK_BOX (content_area),
1897 priv->fontchooser, TRUE, TRUE, 0);
1899 /* Create the action area */
1900 priv->cancel_button = gtk_dialog_add_button (dialog,
1902 GTK_RESPONSE_CANCEL);
1903 /* Deprecated: Apply button is not used anymore */
1904 priv->apply_button = gtk_dialog_add_button (dialog,
1906 GTK_RESPONSE_APPLY);
1907 gtk_widget_hide (priv->apply_button);
1909 priv->select_button = gtk_dialog_add_button (dialog,
1912 gtk_widget_grab_default (priv->select_button);
1914 gtk_dialog_set_alternative_button_order (GTK_DIALOG (fontchooserdiag),
1916 GTK_RESPONSE_APPLY, /* Deprecated */
1917 GTK_RESPONSE_CANCEL,
1920 gtk_window_set_title (GTK_WINDOW (fontchooserdiag),
1921 _("Font Selection"));
1923 gtk_widget_pop_composite_child ();
1927 * gtk_font_chooser_dialog_new:
1928 * @title: (allow-none): the title of the dialog window
1930 * Creates a new #GtkFontChooserDialog.
1932 * Return value: a new #GtkFontChooserDialog
1935 gtk_font_chooser_dialog_new (const gchar *title)
1937 GtkFontChooserDialog *fontchooserdiag;
1939 fontchooserdiag = g_object_new (GTK_TYPE_FONT_CHOOSER_DIALOG, NULL);
1942 gtk_window_set_title (GTK_WINDOW (fontchooserdiag), title);
1944 return GTK_WIDGET (fontchooserdiag);
1948 * gtk_font_chooser_dialog_get_font_selection:
1949 * @fsd: a #GtkFontChooserDialog
1951 * Retrieves the #GtkFontChooser widget embedded in the dialog.
1953 * Returns: (transfer none): the embedded #GtkFontChooser
1958 gtk_font_chooser_dialog_get_font_selection (GtkFontChooserDialog *fsd)
1960 g_return_val_if_fail (GTK_IS_FONT_CHOOSER_DIALOG (fsd), NULL);
1962 return fsd->priv->fontchooser;
1966 gtk_font_chooser_dialog_buildable_interface_init (GtkBuildableIface *iface)
1968 parent_buildable_iface = g_type_interface_peek_parent (iface);
1969 iface->get_internal_child = gtk_font_chooser_dialog_buildable_get_internal_child;
1973 gtk_font_chooser_dialog_buildable_get_internal_child (GtkBuildable *buildable,
1974 GtkBuilder *builder,
1975 const gchar *childname)
1977 GtkFontChooserDialogPrivate *priv;
1979 priv = GTK_FONT_CHOOSER_DIALOG (buildable)->priv;
1981 if (g_strcmp0 (childname, "select_button") == 0)
1982 return G_OBJECT (priv->select_button);
1983 else if (g_strcmp0 (childname, "cancel_button") == 0)
1984 return G_OBJECT (priv->cancel_button);
1985 else if (g_strcmp0 (childname, "font_selection") == 0)
1986 return G_OBJECT (priv->fontchooser);
1989 else if (g_strcmp0 (childname, "ok_button") == 0)
1990 return G_OBJECT (priv->select_button);
1991 else if (g_strcmp0 (childname, "apply_button") == 0)
1992 return G_OBJECT (priv->apply_button);
1994 return parent_buildable_iface->get_internal_child (buildable, builder, childname);
1998 * gtk_font_chooser_dialog_get_font_name:
1999 * @fsd: a #GtkFontChooserDialog
2001 * Gets the currently-selected font name.
2003 * Note that this can be a different string than what you set with
2004 * gtk_font_chooser_dialog_set_font_name(), as the font selection widget
2005 * may normalize font names and thus return a string with a different
2006 * structure. For example, "Helvetica Italic Bold 12" could be normalized
2007 * to "Helvetica Bold Italic 12". Use pango_font_description_equal()
2008 * if you want to compare two font descriptions.
2010 * Return value: A string with the name of the current font, or %NULL if no
2011 * font is selected. You must free this string with g_free().
2014 gtk_font_chooser_dialog_get_font_name (GtkFontChooserDialog *fsd)
2016 GtkFontChooserDialogPrivate *priv;
2018 g_return_val_if_fail (GTK_IS_FONT_CHOOSER_DIALOG (fsd), NULL);
2022 return gtk_font_chooser_get_font_name (GTK_FONT_CHOOSER (priv->fontchooser));
2026 * gtk_font_chooser_dialog_set_font_name:
2027 * @fsd: a #GtkFontChooserDialog
2028 * @fontname: a font name like "Helvetica 12" or "Times Bold 18"
2030 * Sets the currently selected font.
2032 * Return value: %TRUE if the font selected in @fsd is now the
2033 * @fontname specified, %FALSE otherwise.
2036 gtk_font_chooser_dialog_set_font_name (GtkFontChooserDialog *fsd,
2037 const gchar *fontname)
2039 GtkFontChooserDialogPrivate *priv;
2041 g_return_val_if_fail (GTK_IS_FONT_CHOOSER_DIALOG (fsd), FALSE);
2042 g_return_val_if_fail (fontname, FALSE);
2046 return gtk_font_chooser_set_font_name (GTK_FONT_CHOOSER (priv->fontchooser), fontname);
2050 * gtk_font_chooser_dialog_get_preview_text:
2051 * @fsd: a #GtkFontChooserDialog
2053 * Gets the text displayed in the preview area.
2055 * Return value: the text displayed in the preview area.
2056 * This string is owned by the widget and should not be
2059 G_CONST_RETURN gchar*
2060 gtk_font_chooser_dialog_get_preview_text (GtkFontChooserDialog *fsd)
2062 GtkFontChooserDialogPrivate *priv;
2064 g_return_val_if_fail (GTK_IS_FONT_CHOOSER_DIALOG (fsd), NULL);
2068 return gtk_font_chooser_get_preview_text (GTK_FONT_CHOOSER (priv->fontchooser));
2072 * gtk_font_chooser_dialog_set_preview_text:
2073 * @fsd: a #GtkFontChooserDialog
2074 * @text: the text to display in the preview area
2076 * Sets the text displayed in the preview area.
2079 gtk_font_chooser_dialog_set_preview_text (GtkFontChooserDialog *fsd,
2082 GtkFontChooserDialogPrivate *priv;
2084 g_return_if_fail (GTK_IS_FONT_CHOOSER_DIALOG (fsd));
2085 g_return_if_fail (text != NULL);
2089 gtk_font_chooser_set_preview_text (GTK_FONT_CHOOSER (priv->fontchooser), text);
2093 * gtk_font_chooser_dialog_get_ok_button:
2094 * @fsd: a #GtkFontChooserDialog
2096 * Gets the 'OK' button.
2098 * Return value: (transfer none): the #GtkWidget used in the dialog
2099 * for the 'OK' button.
2104 gtk_font_chooser_dialog_get_ok_button (GtkFontChooserDialog *fsd)
2106 g_return_val_if_fail (GTK_IS_FONT_CHOOSER_DIALOG (fsd), NULL);
2108 return fsd->priv->select_button;
2112 * gtk_font_chooser_dialog_get_cancel_button:
2113 * @fsd: a #GtkFontChooserDialog
2115 * Gets the 'Cancel' button.
2117 * Return value: (transfer none): the #GtkWidget used in the dialog
2118 * for the 'Cancel' button.
2123 gtk_font_chooser_dialog_get_cancel_button (GtkFontChooserDialog *fsd)
2125 g_return_val_if_fail (GTK_IS_FONT_CHOOSER_DIALOG (fsd), NULL);
2127 return fsd->priv->cancel_button;