1 /*
2 * GTK - The GIMP Toolkit
3 * Copyright (C) 1998 David Abilleira Freijeiro <odaf@nexo.es>
4 * All rights reserved.
5 *
6 * Based on gnome-color-picker by Federico Mena <federico@nuclecu.unam.mx>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
20 */
21 /*
22 * Modified by the GTK+ Team and others 2003. See the AUTHORS
23 * file for a list of people on the GTK+ Team. See the ChangeLog
24 * files for a list of changes. These files are distributed with
25 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
26 */
27
28 #include "config.h"
29
30 #include "gtkfontbutton.h"
31
32 #include "gtkmain.h"
33 #include "gtkbox.h"
34 #include "gtklabel.h"
35 #include "gtkfontchooser.h"
36 #include "gtkfontchooserdialog.h"
37 #include "gtkimage.h"
38 #include "gtkmarshalers.h"
39 #include "gtkseparator.h"
40 #include "gtkprivate.h"
41 #include "gtkintl.h"
42 #include "gtkcssprovider.h"
43
44 #include <string.h>
45 #include <stdio.h>
46 #include "gtkfontchooserutils.h"
47
48
49 /**
50 * SECTION:gtkfontbutton
51 * @Short_description: A button to launch a font chooser dialog
52 * @Title: GtkFontButton
53 * @See_also: #GtkFontChooserDialog, #GtkColorButton.
54 *
55 * The #GtkFontButton is a button which displays the currently selected
56 * font an allows to open a font chooser dialog to change the font.
57 * It is suitable widget for selecting a font in a preference dialog.
58 *
59 * # CSS nodes
60 *
61 * GtkFontButton has a single CSS node with name button and style class .font.
62 */
63
64
65 struct _GtkFontButtonPrivate
66 {
67 gchar *title;
68
69 gchar *fontname;
70
71 guint use_font : 1;
72 guint use_size : 1;
73 guint show_style : 1;
74 guint show_size : 1;
75 guint show_preview_entry : 1;
76
77 GtkWidget *font_dialog;
78 GtkWidget *font_label;
79 GtkWidget *size_label;
80 GtkWidget *font_size_box;
81
82 PangoFontDescription *font_desc;
83 PangoFontFamily *font_family;
84 PangoFontFace *font_face;
85 PangoFontMap *font_map;
86 gint font_size;
87 char *font_features;
88 PangoLanguage *language;
89 gchar *preview_text;
90 GtkFontFilterFunc font_filter;
91 gpointer font_filter_data;
92 GDestroyNotify font_filter_data_destroy;
93 GtkCssProvider *provider;
94
95 GtkFontChooserLevel level;
96 };
97
98 /* Signals */
99 enum
100 {
101 FONT_SET,
102 LAST_SIGNAL
103 };
104
105 enum
106 {
107 PROP_0,
108 PROP_TITLE,
109 PROP_FONT_NAME,
110 PROP_USE_FONT,
111 PROP_USE_SIZE,
112 PROP_SHOW_STYLE,
113 PROP_SHOW_SIZE
114 };
115
116 /* Prototypes */
117 static void gtk_font_button_finalize (GObject *object);
118 static void gtk_font_button_get_property (GObject *object,
119 guint param_id,
120 GValue *value,
121 GParamSpec *pspec);
122 static void gtk_font_button_set_property (GObject *object,
123 guint param_id,
124 const GValue *value,
125 GParamSpec *pspec);
126
127 static void gtk_font_button_clicked (GtkButton *button);
128
129 /* Dialog response functions */
130 static void response_cb (GtkDialog *dialog,
131 gint response_id,
132 gpointer data);
133 static void dialog_destroy (GtkWidget *widget,
134 gpointer data);
135
136 /* Auxiliary functions */
137 static void gtk_font_button_label_use_font (GtkFontButton *gfs);
138 static void gtk_font_button_update_font_info (GtkFontButton *gfs);
139
140 static void font_button_set_font_name (GtkFontButton *button,
141 const char *fontname);
142 static void gtk_font_button_set_level (GtkFontButton *font_button,
143 GtkFontChooserLevel level);
144 static void gtk_font_button_set_language (GtkFontButton *button,
145 const char *language);
146
147 static guint font_button_signals[LAST_SIGNAL] = { 0 };
148
149 static void
clear_font_data(GtkFontButton * font_button)150 clear_font_data (GtkFontButton *font_button)
151 {
152 GtkFontButtonPrivate *priv = font_button->priv;
153
154 if (priv->font_family)
155 g_object_unref (priv->font_family);
156 priv->font_family = NULL;
157
158 if (priv->font_face)
159 g_object_unref (priv->font_face);
160 priv->font_face = NULL;
161
162 if (priv->font_desc)
163 pango_font_description_free (priv->font_desc);
164 priv->font_desc = NULL;
165
166 g_free (priv->fontname);
167 priv->fontname = NULL;
168
169 g_free (priv->font_features);
170 priv->font_features = NULL;
171 }
172
173 static void
clear_font_filter_data(GtkFontButton * font_button)174 clear_font_filter_data (GtkFontButton *font_button)
175 {
176 GtkFontButtonPrivate *priv = font_button->priv;
177
178 if (priv->font_filter_data_destroy)
179 priv->font_filter_data_destroy (priv->font_filter_data);
180 priv->font_filter = NULL;
181 priv->font_filter_data = NULL;
182 priv->font_filter_data_destroy = NULL;
183 }
184
185 static gboolean
font_description_style_equal(const PangoFontDescription * a,const PangoFontDescription * b)186 font_description_style_equal (const PangoFontDescription *a,
187 const PangoFontDescription *b)
188 {
189 return (pango_font_description_get_weight (a) == pango_font_description_get_weight (b) &&
190 pango_font_description_get_style (a) == pango_font_description_get_style (b) &&
191 pango_font_description_get_stretch (a) == pango_font_description_get_stretch (b) &&
192 pango_font_description_get_variant (a) == pango_font_description_get_variant (b));
193 }
194
195 static void
gtk_font_button_update_font_data(GtkFontButton * font_button)196 gtk_font_button_update_font_data (GtkFontButton *font_button)
197 {
198 GtkFontButtonPrivate *priv = font_button->priv;
199 PangoFontFamily **families;
200 PangoFontFace **faces;
201 gint n_families, n_faces, i;
202 const gchar *family;
203
204 g_assert (priv->font_desc != NULL);
205
206 priv->fontname = pango_font_description_to_string (priv->font_desc);
207
208 family = pango_font_description_get_family (priv->font_desc);
209 if (family == NULL)
210 return;
211
212 n_families = 0;
213 families = NULL;
214 pango_context_list_families (gtk_widget_get_pango_context (GTK_WIDGET (font_button)),
215 &families, &n_families);
216 n_faces = 0;
217 faces = NULL;
218 for (i = 0; i < n_families; i++)
219 {
220 const gchar *name = pango_font_family_get_name (families[i]);
221
222 if (!g_ascii_strcasecmp (name, family))
223 {
224 priv->font_family = g_object_ref (families[i]);
225
226 pango_font_family_list_faces (families[i], &faces, &n_faces);
227 break;
228 }
229 }
230 g_free (families);
231
232 for (i = 0; i < n_faces; i++)
233 {
234 PangoFontDescription *tmp_desc = pango_font_face_describe (faces[i]);
235
236 if (font_description_style_equal (tmp_desc, priv->font_desc))
237 {
238 priv->font_face = g_object_ref (faces[i]);
239
240 pango_font_description_free (tmp_desc);
241 break;
242 }
243 else
244 pango_font_description_free (tmp_desc);
245 }
246
247 g_free (faces);
248 }
249
250 static gchar *
gtk_font_button_get_preview_text(GtkFontButton * font_button)251 gtk_font_button_get_preview_text (GtkFontButton *font_button)
252 {
253 GtkFontButtonPrivate *priv = font_button->priv;
254
255 if (priv->font_dialog)
256 return gtk_font_chooser_get_preview_text (GTK_FONT_CHOOSER (priv->font_dialog));
257
258 return g_strdup (priv->preview_text);
259 }
260
261 static void
gtk_font_button_set_preview_text(GtkFontButton * font_button,const gchar * preview_text)262 gtk_font_button_set_preview_text (GtkFontButton *font_button,
263 const gchar *preview_text)
264 {
265 GtkFontButtonPrivate *priv = font_button->priv;
266
267 if (priv->font_dialog)
268 {
269 gtk_font_chooser_set_preview_text (GTK_FONT_CHOOSER (priv->font_dialog),
270 preview_text);
271 return;
272 }
273
274 g_free (priv->preview_text);
275 priv->preview_text = g_strdup (preview_text);
276 }
277
278
279 static gboolean
gtk_font_button_get_show_preview_entry(GtkFontButton * font_button)280 gtk_font_button_get_show_preview_entry (GtkFontButton *font_button)
281 {
282 GtkFontButtonPrivate *priv = font_button->priv;
283
284 if (priv->font_dialog)
285 return gtk_font_chooser_get_show_preview_entry (GTK_FONT_CHOOSER (priv->font_dialog));
286
287 return priv->show_preview_entry;
288 }
289
290 static void
gtk_font_button_set_show_preview_entry(GtkFontButton * font_button,gboolean show)291 gtk_font_button_set_show_preview_entry (GtkFontButton *font_button,
292 gboolean show)
293 {
294 GtkFontButtonPrivate *priv = font_button->priv;
295
296 show = show != FALSE;
297
298 if (priv->show_preview_entry != show)
299 {
300 priv->show_preview_entry = show;
301 if (priv->font_dialog)
302 gtk_font_chooser_set_show_preview_entry (GTK_FONT_CHOOSER (priv->font_dialog), show);
303 g_object_notify (G_OBJECT (font_button), "show-preview-entry");
304 }
305 }
306
307 static PangoFontFamily *
gtk_font_button_font_chooser_get_font_family(GtkFontChooser * chooser)308 gtk_font_button_font_chooser_get_font_family (GtkFontChooser *chooser)
309 {
310 GtkFontButton *font_button = GTK_FONT_BUTTON (chooser);
311 GtkFontButtonPrivate *priv = font_button->priv;
312
313 return priv->font_family;
314 }
315
316 static PangoFontFace *
gtk_font_button_font_chooser_get_font_face(GtkFontChooser * chooser)317 gtk_font_button_font_chooser_get_font_face (GtkFontChooser *chooser)
318 {
319 GtkFontButton *font_button = GTK_FONT_BUTTON (chooser);
320 GtkFontButtonPrivate *priv = font_button->priv;
321
322 return priv->font_face;
323 }
324
325 static int
gtk_font_button_font_chooser_get_font_size(GtkFontChooser * chooser)326 gtk_font_button_font_chooser_get_font_size (GtkFontChooser *chooser)
327 {
328 GtkFontButton *font_button = GTK_FONT_BUTTON (chooser);
329 GtkFontButtonPrivate *priv = font_button->priv;
330
331 return priv->font_size;
332 }
333
334 static void
gtk_font_button_font_chooser_set_filter_func(GtkFontChooser * chooser,GtkFontFilterFunc filter_func,gpointer filter_data,GDestroyNotify data_destroy)335 gtk_font_button_font_chooser_set_filter_func (GtkFontChooser *chooser,
336 GtkFontFilterFunc filter_func,
337 gpointer filter_data,
338 GDestroyNotify data_destroy)
339 {
340 GtkFontButton *font_button = GTK_FONT_BUTTON (chooser);
341 GtkFontButtonPrivate *priv = font_button->priv;
342
343 if (priv->font_dialog)
344 {
345 gtk_font_chooser_set_filter_func (GTK_FONT_CHOOSER (priv->font_dialog),
346 filter_func,
347 filter_data,
348 data_destroy);
349 return;
350 }
351
352 clear_font_filter_data (font_button);
353 priv->font_filter = filter_func;
354 priv->font_filter_data = filter_data;
355 priv->font_filter_data_destroy = data_destroy;
356 }
357
358 static void
gtk_font_button_take_font_desc(GtkFontButton * font_button,PangoFontDescription * font_desc)359 gtk_font_button_take_font_desc (GtkFontButton *font_button,
360 PangoFontDescription *font_desc)
361 {
362 GtkFontButtonPrivate *priv = font_button->priv;
363 GObject *object = G_OBJECT (font_button);
364
365 if (priv->font_desc && font_desc &&
366 pango_font_description_equal (priv->font_desc, font_desc))
367 {
368 pango_font_description_free (font_desc);
369 return;
370 }
371
372 g_object_freeze_notify (object);
373
374 clear_font_data (font_button);
375
376 if (font_desc)
377 priv->font_desc = font_desc; /* adopted */
378 else
379 priv->font_desc = pango_font_description_from_string (_("Sans 12"));
380
381 if (pango_font_description_get_size_is_absolute (priv->font_desc))
382 priv->font_size = pango_font_description_get_size (priv->font_desc);
383 else
384 priv->font_size = pango_font_description_get_size (priv->font_desc) / PANGO_SCALE;
385
386 gtk_font_button_update_font_data (font_button);
387 gtk_font_button_update_font_info (font_button);
388
389 if (priv->font_dialog)
390 gtk_font_chooser_set_font_desc (GTK_FONT_CHOOSER (priv->font_dialog),
391 priv->font_desc);
392
393 g_object_notify (G_OBJECT (font_button), "font");
394 g_object_notify (G_OBJECT (font_button), "font-desc");
395 g_object_notify (G_OBJECT (font_button), "font-name");
396
397 g_object_thaw_notify (object);
398 }
399
400 static const PangoFontDescription *
gtk_font_button_get_font_desc(GtkFontButton * font_button)401 gtk_font_button_get_font_desc (GtkFontButton *font_button)
402 {
403 return font_button->priv->font_desc;
404 }
405
406 static void
gtk_font_button_font_chooser_set_font_map(GtkFontChooser * chooser,PangoFontMap * font_map)407 gtk_font_button_font_chooser_set_font_map (GtkFontChooser *chooser,
408 PangoFontMap *font_map)
409 {
410 GtkFontButton *font_button = GTK_FONT_BUTTON (chooser);
411
412 if (g_set_object (&font_button->priv->font_map, font_map))
413 {
414 PangoContext *context;
415
416 if (!font_map)
417 font_map = pango_cairo_font_map_get_default ();
418
419 context = gtk_widget_get_pango_context (font_button->priv->font_label);
420 pango_context_set_font_map (context, font_map);
421 }
422 }
423
424 static PangoFontMap *
gtk_font_button_font_chooser_get_font_map(GtkFontChooser * chooser)425 gtk_font_button_font_chooser_get_font_map (GtkFontChooser *chooser)
426 {
427 GtkFontButton *font_button = GTK_FONT_BUTTON (chooser);
428
429 return font_button->priv->font_map;
430 }
431
432 static void
gtk_font_button_font_chooser_notify(GObject * object,GParamSpec * pspec,gpointer user_data)433 gtk_font_button_font_chooser_notify (GObject *object,
434 GParamSpec *pspec,
435 gpointer user_data)
436 {
437 /* We do not forward the notification of the "font" property to the dialog! */
438 if (pspec->name == I_("preview-text") ||
439 pspec->name == I_("show-preview-entry"))
440 g_object_notify_by_pspec (user_data, pspec);
441 }
442
443 static void
gtk_font_button_font_chooser_iface_init(GtkFontChooserIface * iface)444 gtk_font_button_font_chooser_iface_init (GtkFontChooserIface *iface)
445 {
446 iface->get_font_family = gtk_font_button_font_chooser_get_font_family;
447 iface->get_font_face = gtk_font_button_font_chooser_get_font_face;
448 iface->get_font_size = gtk_font_button_font_chooser_get_font_size;
449 iface->set_filter_func = gtk_font_button_font_chooser_set_filter_func;
450 iface->set_font_map = gtk_font_button_font_chooser_set_font_map;
451 iface->get_font_map = gtk_font_button_font_chooser_get_font_map;
452 }
453
G_DEFINE_TYPE_WITH_CODE(GtkFontButton,gtk_font_button,GTK_TYPE_BUTTON,G_ADD_PRIVATE (GtkFontButton)G_IMPLEMENT_INTERFACE (GTK_TYPE_FONT_CHOOSER,gtk_font_button_font_chooser_iface_init))454 G_DEFINE_TYPE_WITH_CODE (GtkFontButton, gtk_font_button, GTK_TYPE_BUTTON,
455 G_ADD_PRIVATE (GtkFontButton)
456 G_IMPLEMENT_INTERFACE (GTK_TYPE_FONT_CHOOSER,
457 gtk_font_button_font_chooser_iface_init))
458
459 static void
460 gtk_font_button_class_init (GtkFontButtonClass *klass)
461 {
462 GObjectClass *gobject_class;
463 GtkWidgetClass *widget_class;
464 GtkButtonClass *button_class;
465
466 gobject_class = (GObjectClass *) klass;
467 widget_class = (GtkWidgetClass *) klass;
468 button_class = (GtkButtonClass *) klass;
469
470 gobject_class->finalize = gtk_font_button_finalize;
471 gobject_class->set_property = gtk_font_button_set_property;
472 gobject_class->get_property = gtk_font_button_get_property;
473
474 button_class->clicked = gtk_font_button_clicked;
475
476 klass->font_set = NULL;
477
478 _gtk_font_chooser_install_properties (gobject_class);
479
480 /**
481 * GtkFontButton:title:
482 *
483 * The title of the font chooser dialog.
484 *
485 * Since: 2.4
486 */
487 g_object_class_install_property (gobject_class,
488 PROP_TITLE,
489 g_param_spec_string ("title",
490 P_("Title"),
491 P_("The title of the font chooser dialog"),
492 _("Pick a Font"),
493 GTK_PARAM_READWRITE));
494
495 /**
496 * GtkFontButton:font-name:
497 *
498 * The name of the currently selected font.
499 *
500 * Since: 2.4
501 *
502 * Deprecated: 3.22: Use the #GtkFontChooser::font property instead
503 */
504 g_object_class_install_property (gobject_class,
505 PROP_FONT_NAME,
506 g_param_spec_string ("font-name",
507 P_("Font name"),
508 P_("The name of the selected font"),
509 _("Sans 12"),
510 GTK_PARAM_READWRITE | G_PARAM_DEPRECATED));
511
512 /**
513 * GtkFontButton:use-font:
514 *
515 * If this property is set to %TRUE, the label will be drawn
516 * in the selected font.
517 *
518 * Since: 2.4
519 */
520 g_object_class_install_property (gobject_class,
521 PROP_USE_FONT,
522 g_param_spec_boolean ("use-font",
523 P_("Use font in label"),
524 P_("Whether the label is drawn in the selected font"),
525 FALSE,
526 GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
527
528 /**
529 * GtkFontButton:use-size:
530 *
531 * If this property is set to %TRUE, the label will be drawn
532 * with the selected font size.
533 *
534 * Since: 2.4
535 */
536 g_object_class_install_property (gobject_class,
537 PROP_USE_SIZE,
538 g_param_spec_boolean ("use-size",
539 P_("Use size in label"),
540 P_("Whether the label is drawn with the selected font size"),
541 FALSE,
542 GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
543
544 /**
545 * GtkFontButton:show-style:
546 *
547 * If this property is set to %TRUE, the name of the selected font style
548 * will be shown in the label. For a more WYSIWYG way to show the selected
549 * style, see the ::use-font property.
550 *
551 * Since: 2.4
552 */
553 g_object_class_install_property (gobject_class,
554 PROP_SHOW_STYLE,
555 g_param_spec_boolean ("show-style",
556 P_("Show style"),
557 P_("Whether the selected font style is shown in the label"),
558 TRUE,
559 GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
560 /**
561 * GtkFontButton:show-size:
562 *
563 * If this property is set to %TRUE, the selected font size will be shown
564 * in the label. For a more WYSIWYG way to show the selected size, see the
565 * ::use-size property.
566 *
567 * Since: 2.4
568 */
569 g_object_class_install_property (gobject_class,
570 PROP_SHOW_SIZE,
571 g_param_spec_boolean ("show-size",
572 P_("Show size"),
573 P_("Whether selected font size is shown in the label"),
574 TRUE,
575 GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
576
577 /**
578 * GtkFontButton::font-set:
579 * @widget: the object which received the signal.
580 *
581 * The ::font-set signal is emitted when the user selects a font.
582 * When handling this signal, use gtk_font_chooser_get_font()
583 * to find out which font was just selected.
584 *
585 * Note that this signal is only emitted when the user
586 * changes the font. If you need to react to programmatic font changes
587 * as well, use the notify::font signal.
588 *
589 * Since: 2.4
590 */
591 font_button_signals[FONT_SET] = g_signal_new (I_("font-set"),
592 G_TYPE_FROM_CLASS (gobject_class),
593 G_SIGNAL_RUN_FIRST,
594 G_STRUCT_OFFSET (GtkFontButtonClass, font_set),
595 NULL, NULL,
596 NULL,
597 G_TYPE_NONE, 0);
598
599 /* Bind class to template
600 */
601 gtk_widget_class_set_template_from_resource (widget_class, "/org/gtk/libgtk/ui/gtkfontbutton.ui");
602 gtk_widget_class_bind_template_child_private (widget_class, GtkFontButton, font_label);
603 gtk_widget_class_bind_template_child_private (widget_class, GtkFontButton, size_label);
604 gtk_widget_class_bind_template_child_private (widget_class, GtkFontButton, font_size_box);
605
606 gtk_widget_class_set_css_name (widget_class, "button");
607 }
608
609 static void
gtk_font_button_init(GtkFontButton * font_button)610 gtk_font_button_init (GtkFontButton *font_button)
611 {
612 GtkStyleContext *context;
613
614 font_button->priv = gtk_font_button_get_instance_private (font_button);
615
616 /* Initialize fields */
617 font_button->priv->use_font = FALSE;
618 font_button->priv->use_size = FALSE;
619 font_button->priv->show_style = TRUE;
620 font_button->priv->show_size = TRUE;
621 font_button->priv->show_preview_entry = TRUE;
622 font_button->priv->font_dialog = NULL;
623 font_button->priv->font_family = NULL;
624 font_button->priv->font_face = NULL;
625 font_button->priv->font_size = -1;
626 font_button->priv->title = g_strdup (_("Pick a Font"));
627 font_button->priv->level = GTK_FONT_CHOOSER_LEVEL_FAMILY |
628 GTK_FONT_CHOOSER_LEVEL_STYLE |
629 GTK_FONT_CHOOSER_LEVEL_SIZE;
630 font_button->priv->language = pango_language_get_default ();
631
632 gtk_widget_init_template (GTK_WIDGET (font_button));
633
634 gtk_font_button_take_font_desc (font_button, NULL);
635
636 context = gtk_widget_get_style_context (GTK_WIDGET (font_button));
637 gtk_style_context_add_class (context, "font");
638 }
639
640 static void
gtk_font_button_finalize(GObject * object)641 gtk_font_button_finalize (GObject *object)
642 {
643 GtkFontButton *font_button = GTK_FONT_BUTTON (object);
644 GtkFontButtonPrivate *priv = font_button->priv;
645
646 if (priv->font_dialog != NULL)
647 gtk_widget_destroy (priv->font_dialog);
648
649 g_free (priv->title);
650
651 clear_font_data (font_button);
652 clear_font_filter_data (font_button);
653
654 g_free (priv->preview_text);
655
656 g_clear_object (&priv->provider);
657
658 G_OBJECT_CLASS (gtk_font_button_parent_class)->finalize (object);
659 }
660
661 static void
gtk_font_button_set_property(GObject * object,guint param_id,const GValue * value,GParamSpec * pspec)662 gtk_font_button_set_property (GObject *object,
663 guint param_id,
664 const GValue *value,
665 GParamSpec *pspec)
666 {
667 GtkFontButton *font_button = GTK_FONT_BUTTON (object);
668
669 switch (param_id)
670 {
671 case GTK_FONT_CHOOSER_PROP_PREVIEW_TEXT:
672 gtk_font_button_set_preview_text (font_button, g_value_get_string (value));
673 break;
674 case GTK_FONT_CHOOSER_PROP_SHOW_PREVIEW_ENTRY:
675 gtk_font_button_set_show_preview_entry (font_button, g_value_get_boolean (value));
676 break;
677 case PROP_TITLE:
678 gtk_font_button_set_title (font_button, g_value_get_string (value));
679 break;
680 case GTK_FONT_CHOOSER_PROP_FONT_DESC:
681 gtk_font_button_take_font_desc (font_button, g_value_dup_boxed (value));
682 break;
683 case GTK_FONT_CHOOSER_PROP_LANGUAGE:
684 gtk_font_button_set_language (font_button, g_value_get_string (value));
685 break;
686 case GTK_FONT_CHOOSER_PROP_LEVEL:
687 gtk_font_button_set_level (font_button, g_value_get_flags (value));
688 break;
689 case GTK_FONT_CHOOSER_PROP_FONT:
690 case PROP_FONT_NAME:
691 font_button_set_font_name (font_button, g_value_get_string (value));
692 break;
693 case PROP_USE_FONT:
694 gtk_font_button_set_use_font (font_button, g_value_get_boolean (value));
695 break;
696 case PROP_USE_SIZE:
697 gtk_font_button_set_use_size (font_button, g_value_get_boolean (value));
698 break;
699 case PROP_SHOW_STYLE:
700 gtk_font_button_set_show_style (font_button, g_value_get_boolean (value));
701 break;
702 case PROP_SHOW_SIZE:
703 gtk_font_button_set_show_size (font_button, g_value_get_boolean (value));
704 break;
705 default:
706 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
707 break;
708 }
709 }
710
711 static void
gtk_font_button_get_property(GObject * object,guint param_id,GValue * value,GParamSpec * pspec)712 gtk_font_button_get_property (GObject *object,
713 guint param_id,
714 GValue *value,
715 GParamSpec *pspec)
716 {
717 GtkFontButton *font_button = GTK_FONT_BUTTON (object);
718 GtkFontButtonPrivate *priv = font_button->priv;
719
720 switch (param_id)
721 {
722 case GTK_FONT_CHOOSER_PROP_PREVIEW_TEXT:
723 g_value_set_string (value, gtk_font_button_get_preview_text (font_button));
724 break;
725 case GTK_FONT_CHOOSER_PROP_SHOW_PREVIEW_ENTRY:
726 g_value_set_boolean (value, gtk_font_button_get_show_preview_entry (font_button));
727 break;
728 case PROP_TITLE:
729 g_value_set_string (value, gtk_font_button_get_title (font_button));
730 break;
731 case GTK_FONT_CHOOSER_PROP_FONT_DESC:
732 g_value_set_boxed (value, gtk_font_button_get_font_desc (font_button));
733 break;
734 case GTK_FONT_CHOOSER_PROP_FONT_FEATURES:
735 g_value_set_string (value, priv->font_features);
736 break;
737 case GTK_FONT_CHOOSER_PROP_LANGUAGE:
738 g_value_set_string (value, pango_language_to_string (priv->language));
739 break;
740 case GTK_FONT_CHOOSER_PROP_LEVEL:
741 g_value_set_flags (value, priv->level);
742 break;
743 case GTK_FONT_CHOOSER_PROP_FONT:
744 case PROP_FONT_NAME:
745 g_value_set_string (value, font_button->priv->fontname);
746 break;
747 case PROP_USE_FONT:
748 g_value_set_boolean (value, gtk_font_button_get_use_font (font_button));
749 break;
750 case PROP_USE_SIZE:
751 g_value_set_boolean (value, gtk_font_button_get_use_size (font_button));
752 break;
753 case PROP_SHOW_STYLE:
754 g_value_set_boolean (value, gtk_font_button_get_show_style (font_button));
755 break;
756 case PROP_SHOW_SIZE:
757 g_value_set_boolean (value, gtk_font_button_get_show_size (font_button));
758 break;
759 default:
760 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
761 break;
762 }
763 }
764
765
766 /**
767 * gtk_font_button_new:
768 *
769 * Creates a new font picker widget.
770 *
771 * Returns: a new font picker widget.
772 *
773 * Since: 2.4
774 */
775 GtkWidget *
gtk_font_button_new(void)776 gtk_font_button_new (void)
777 {
778 return g_object_new (GTK_TYPE_FONT_BUTTON, NULL);
779 }
780
781 /**
782 * gtk_font_button_new_with_font:
783 * @fontname: Name of font to display in font chooser dialog
784 *
785 * Creates a new font picker widget.
786 *
787 * Returns: a new font picker widget.
788 *
789 * Since: 2.4
790 */
791 GtkWidget *
gtk_font_button_new_with_font(const gchar * fontname)792 gtk_font_button_new_with_font (const gchar *fontname)
793 {
794 return g_object_new (GTK_TYPE_FONT_BUTTON, "font", fontname, NULL);
795 }
796
797 /**
798 * gtk_font_button_set_title:
799 * @font_button: a #GtkFontButton
800 * @title: a string containing the font chooser dialog title
801 *
802 * Sets the title for the font chooser dialog.
803 *
804 * Since: 2.4
805 */
806 void
gtk_font_button_set_title(GtkFontButton * font_button,const gchar * title)807 gtk_font_button_set_title (GtkFontButton *font_button,
808 const gchar *title)
809 {
810 gchar *old_title;
811 g_return_if_fail (GTK_IS_FONT_BUTTON (font_button));
812
813 old_title = font_button->priv->title;
814 font_button->priv->title = g_strdup (title);
815 g_free (old_title);
816
817 if (font_button->priv->font_dialog)
818 gtk_window_set_title (GTK_WINDOW (font_button->priv->font_dialog),
819 font_button->priv->title);
820
821 g_object_notify (G_OBJECT (font_button), "title");
822 }
823
824 /**
825 * gtk_font_button_get_title:
826 * @font_button: a #GtkFontButton
827 *
828 * Retrieves the title of the font chooser dialog.
829 *
830 * Returns: an internal copy of the title string which must not be freed.
831 *
832 * Since: 2.4
833 */
834 const gchar*
gtk_font_button_get_title(GtkFontButton * font_button)835 gtk_font_button_get_title (GtkFontButton *font_button)
836 {
837 g_return_val_if_fail (GTK_IS_FONT_BUTTON (font_button), NULL);
838
839 return font_button->priv->title;
840 }
841
842 /**
843 * gtk_font_button_get_use_font:
844 * @font_button: a #GtkFontButton
845 *
846 * Returns whether the selected font is used in the label.
847 *
848 * Returns: whether the selected font is used in the label.
849 *
850 * Since: 2.4
851 */
852 gboolean
gtk_font_button_get_use_font(GtkFontButton * font_button)853 gtk_font_button_get_use_font (GtkFontButton *font_button)
854 {
855 g_return_val_if_fail (GTK_IS_FONT_BUTTON (font_button), FALSE);
856
857 return font_button->priv->use_font;
858 }
859
860 /**
861 * gtk_font_button_set_use_font:
862 * @font_button: a #GtkFontButton
863 * @use_font: If %TRUE, font name will be written using font chosen.
864 *
865 * If @use_font is %TRUE, the font name will be written using the selected font.
866 *
867 * Since: 2.4
868 */
869 void
gtk_font_button_set_use_font(GtkFontButton * font_button,gboolean use_font)870 gtk_font_button_set_use_font (GtkFontButton *font_button,
871 gboolean use_font)
872 {
873 g_return_if_fail (GTK_IS_FONT_BUTTON (font_button));
874
875 use_font = (use_font != FALSE);
876
877 if (font_button->priv->use_font != use_font)
878 {
879 font_button->priv->use_font = use_font;
880
881 gtk_font_button_label_use_font (font_button);
882
883 g_object_notify (G_OBJECT (font_button), "use-font");
884 }
885 }
886
887
888 /**
889 * gtk_font_button_get_use_size:
890 * @font_button: a #GtkFontButton
891 *
892 * Returns whether the selected size is used in the label.
893 *
894 * Returns: whether the selected size is used in the label.
895 *
896 * Since: 2.4
897 */
898 gboolean
gtk_font_button_get_use_size(GtkFontButton * font_button)899 gtk_font_button_get_use_size (GtkFontButton *font_button)
900 {
901 g_return_val_if_fail (GTK_IS_FONT_BUTTON (font_button), FALSE);
902
903 return font_button->priv->use_size;
904 }
905
906 /**
907 * gtk_font_button_set_use_size:
908 * @font_button: a #GtkFontButton
909 * @use_size: If %TRUE, font name will be written using the selected size.
910 *
911 * If @use_size is %TRUE, the font name will be written using the selected size.
912 *
913 * Since: 2.4
914 */
915 void
gtk_font_button_set_use_size(GtkFontButton * font_button,gboolean use_size)916 gtk_font_button_set_use_size (GtkFontButton *font_button,
917 gboolean use_size)
918 {
919 g_return_if_fail (GTK_IS_FONT_BUTTON (font_button));
920
921 use_size = (use_size != FALSE);
922 if (font_button->priv->use_size != use_size)
923 {
924 font_button->priv->use_size = use_size;
925
926 gtk_font_button_label_use_font (font_button);
927
928 g_object_notify (G_OBJECT (font_button), "use-size");
929 }
930 }
931
932 /**
933 * gtk_font_button_get_show_style:
934 * @font_button: a #GtkFontButton
935 *
936 * Returns whether the name of the font style will be shown in the label.
937 *
938 * Returns: whether the font style will be shown in the label.
939 *
940 * Since: 2.4
941 **/
942 gboolean
gtk_font_button_get_show_style(GtkFontButton * font_button)943 gtk_font_button_get_show_style (GtkFontButton *font_button)
944 {
945 g_return_val_if_fail (GTK_IS_FONT_BUTTON (font_button), FALSE);
946
947 return font_button->priv->show_style;
948 }
949
950 /**
951 * gtk_font_button_set_show_style:
952 * @font_button: a #GtkFontButton
953 * @show_style: %TRUE if font style should be displayed in label.
954 *
955 * If @show_style is %TRUE, the font style will be displayed along with name of the selected font.
956 *
957 * Since: 2.4
958 */
959 void
gtk_font_button_set_show_style(GtkFontButton * font_button,gboolean show_style)960 gtk_font_button_set_show_style (GtkFontButton *font_button,
961 gboolean show_style)
962 {
963 g_return_if_fail (GTK_IS_FONT_BUTTON (font_button));
964
965 show_style = (show_style != FALSE);
966 if (font_button->priv->show_style != show_style)
967 {
968 font_button->priv->show_style = show_style;
969
970 gtk_font_button_update_font_info (font_button);
971
972 g_object_notify (G_OBJECT (font_button), "show-style");
973 }
974 }
975
976
977 /**
978 * gtk_font_button_get_show_size:
979 * @font_button: a #GtkFontButton
980 *
981 * Returns whether the font size will be shown in the label.
982 *
983 * Returns: whether the font size will be shown in the label.
984 *
985 * Since: 2.4
986 **/
987 gboolean
gtk_font_button_get_show_size(GtkFontButton * font_button)988 gtk_font_button_get_show_size (GtkFontButton *font_button)
989 {
990 g_return_val_if_fail (GTK_IS_FONT_BUTTON (font_button), FALSE);
991
992 return font_button->priv->show_size;
993 }
994
995 /**
996 * gtk_font_button_set_show_size:
997 * @font_button: a #GtkFontButton
998 * @show_size: %TRUE if font size should be displayed in dialog.
999 *
1000 * If @show_size is %TRUE, the font size will be displayed along with the name of the selected font.
1001 *
1002 * Since: 2.4
1003 */
1004 void
gtk_font_button_set_show_size(GtkFontButton * font_button,gboolean show_size)1005 gtk_font_button_set_show_size (GtkFontButton *font_button,
1006 gboolean show_size)
1007 {
1008 g_return_if_fail (GTK_IS_FONT_BUTTON (font_button));
1009
1010 show_size = (show_size != FALSE);
1011
1012 if (font_button->priv->show_size != show_size)
1013 {
1014 font_button->priv->show_size = show_size;
1015
1016 if (font_button->priv->show_size)
1017 gtk_widget_show (font_button->priv->font_size_box);
1018 else
1019 gtk_widget_hide (font_button->priv->font_size_box);
1020
1021 gtk_font_button_update_font_info (font_button);
1022
1023 g_object_notify (G_OBJECT (font_button), "show-size");
1024 }
1025 }
1026
1027
1028 /**
1029 * gtk_font_button_get_font_name:
1030 * @font_button: a #GtkFontButton
1031 *
1032 * Retrieves the name of the currently selected font. This name includes
1033 * style and size information as well. If you want to render something
1034 * with the font, use this string with pango_font_description_from_string() .
1035 * If you’re interested in peeking certain values (family name,
1036 * style, size, weight) just query these properties from the
1037 * #PangoFontDescription object.
1038 *
1039 * Returns: an internal copy of the font name which must not be freed.
1040 *
1041 * Since: 2.4
1042 * Deprecated: 3.22: Use gtk_font_chooser_get_font() instead
1043 */
1044 const gchar *
gtk_font_button_get_font_name(GtkFontButton * font_button)1045 gtk_font_button_get_font_name (GtkFontButton *font_button)
1046 {
1047 g_return_val_if_fail (GTK_IS_FONT_BUTTON (font_button), NULL);
1048
1049 return font_button->priv->fontname;
1050 }
1051
1052 static void
font_button_set_font_name(GtkFontButton * font_button,const char * fontname)1053 font_button_set_font_name (GtkFontButton *font_button,
1054 const char *fontname)
1055 {
1056 PangoFontDescription *font_desc;
1057
1058 font_desc = pango_font_description_from_string (fontname);
1059 gtk_font_button_take_font_desc (font_button, font_desc);
1060 }
1061
1062 /**
1063 * gtk_font_button_set_font_name:
1064 * @font_button: a #GtkFontButton
1065 * @fontname: Name of font to display in font chooser dialog
1066 *
1067 * Sets or updates the currently-displayed font in font picker dialog.
1068 *
1069 * Returns: %TRUE
1070 *
1071 * Since: 2.4
1072 * Deprecated: 3.22: Use gtk_font_chooser_set_font() instead
1073 */
1074 gboolean
gtk_font_button_set_font_name(GtkFontButton * font_button,const gchar * fontname)1075 gtk_font_button_set_font_name (GtkFontButton *font_button,
1076 const gchar *fontname)
1077 {
1078 g_return_val_if_fail (GTK_IS_FONT_BUTTON (font_button), FALSE);
1079 g_return_val_if_fail (fontname != NULL, FALSE);
1080
1081 font_button_set_font_name (font_button, fontname);
1082
1083 return TRUE;
1084 }
1085
1086 static void
gtk_font_button_clicked(GtkButton * button)1087 gtk_font_button_clicked (GtkButton *button)
1088 {
1089 GtkFontChooser *font_dialog;
1090 GtkFontButton *font_button = GTK_FONT_BUTTON (button);
1091 GtkFontButtonPrivate *priv = font_button->priv;
1092
1093 if (!font_button->priv->font_dialog)
1094 {
1095 GtkWidget *parent;
1096
1097 parent = gtk_widget_get_toplevel (GTK_WIDGET (font_button));
1098
1099 priv->font_dialog = gtk_font_chooser_dialog_new (priv->title, NULL);
1100 font_dialog = GTK_FONT_CHOOSER (font_button->priv->font_dialog);
1101
1102 if (priv->font_map)
1103 gtk_font_chooser_set_font_map (font_dialog, priv->font_map);
1104 gtk_font_chooser_set_show_preview_entry (font_dialog, priv->show_preview_entry);
1105 gtk_font_chooser_set_level (GTK_FONT_CHOOSER (font_dialog), priv->level);
1106 gtk_font_chooser_set_language (GTK_FONT_CHOOSER (font_dialog), pango_language_to_string
1107 (priv->language));
1108
1109 if (priv->preview_text)
1110 {
1111 gtk_font_chooser_set_preview_text (font_dialog, priv->preview_text);
1112 g_free (priv->preview_text);
1113 priv->preview_text = NULL;
1114 }
1115
1116 if (priv->font_filter)
1117 {
1118 gtk_font_chooser_set_filter_func (font_dialog,
1119 priv->font_filter,
1120 priv->font_filter_data,
1121 priv->font_filter_data_destroy);
1122 priv->font_filter = NULL;
1123 priv->font_filter_data = NULL;
1124 priv->font_filter_data_destroy = NULL;
1125 }
1126
1127 if (gtk_widget_is_toplevel (parent) && GTK_IS_WINDOW (parent))
1128 {
1129 if (GTK_WINDOW (parent) != gtk_window_get_transient_for (GTK_WINDOW (font_dialog)))
1130 gtk_window_set_transient_for (GTK_WINDOW (font_dialog), GTK_WINDOW (parent));
1131
1132 gtk_window_set_modal (GTK_WINDOW (font_dialog),
1133 gtk_window_get_modal (GTK_WINDOW (parent)));
1134 }
1135
1136 g_signal_connect (font_dialog, "notify",
1137 G_CALLBACK (gtk_font_button_font_chooser_notify), button);
1138
1139 g_signal_connect (font_dialog, "response",
1140 G_CALLBACK (response_cb), font_button);
1141
1142 g_signal_connect (font_dialog, "destroy",
1143 G_CALLBACK (dialog_destroy), font_button);
1144
1145 g_signal_connect (font_dialog, "delete-event",
1146 G_CALLBACK (gtk_widget_hide_on_delete), NULL);
1147 }
1148
1149 if (!gtk_widget_get_visible (font_button->priv->font_dialog))
1150 {
1151 font_dialog = GTK_FONT_CHOOSER (font_button->priv->font_dialog);
1152 gtk_font_chooser_set_font_desc (font_dialog, font_button->priv->font_desc);
1153 }
1154
1155 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
1156 gtk_window_present (GTK_WINDOW (font_button->priv->font_dialog));
1157 G_GNUC_END_IGNORE_DEPRECATIONS
1158 }
1159
1160
1161 static void
response_cb(GtkDialog * dialog,gint response_id,gpointer data)1162 response_cb (GtkDialog *dialog,
1163 gint response_id,
1164 gpointer data)
1165 {
1166 GtkFontButton *font_button = GTK_FONT_BUTTON (data);
1167 GtkFontButtonPrivate *priv = font_button->priv;
1168 GtkFontChooser *font_chooser;
1169 GObject *object;
1170
1171 gtk_widget_hide (font_button->priv->font_dialog);
1172
1173 if (response_id != GTK_RESPONSE_OK)
1174 return;
1175
1176 font_chooser = GTK_FONT_CHOOSER (priv->font_dialog);
1177 object = G_OBJECT (font_chooser);
1178
1179 g_object_freeze_notify (object);
1180
1181 clear_font_data (font_button);
1182
1183 priv->font_desc = gtk_font_chooser_get_font_desc (font_chooser);
1184 if (priv->font_desc)
1185 priv->fontname = pango_font_description_to_string (priv->font_desc);
1186 priv->font_family = gtk_font_chooser_get_font_family (font_chooser);
1187 if (priv->font_family)
1188 g_object_ref (priv->font_family);
1189 priv->font_face = gtk_font_chooser_get_font_face (font_chooser);
1190 if (priv->font_face)
1191 g_object_ref (priv->font_face);
1192 priv->font_size = gtk_font_chooser_get_font_size (font_chooser);
1193 g_free (priv->font_features);
1194 priv->font_features = gtk_font_chooser_get_font_features (font_chooser);
1195 priv->language = pango_language_from_string (gtk_font_chooser_get_language (font_chooser));
1196
1197 /* Set label font */
1198 gtk_font_button_update_font_info (font_button);
1199
1200 g_object_notify (G_OBJECT (font_button), "font");
1201 g_object_notify (G_OBJECT (font_button), "font-desc");
1202 g_object_notify (G_OBJECT (font_button), "font-name");
1203 g_object_notify (G_OBJECT (font_button), "font-features");
1204
1205 g_object_thaw_notify (object);
1206
1207 /* Emit font_set signal */
1208 g_signal_emit (font_button, font_button_signals[FONT_SET], 0);
1209 }
1210
1211 static void
dialog_destroy(GtkWidget * widget,gpointer data)1212 dialog_destroy (GtkWidget *widget,
1213 gpointer data)
1214 {
1215 GtkFontButton *font_button = GTK_FONT_BUTTON (data);
1216
1217 /* Dialog will get destroyed so reference is not valid now */
1218 font_button->priv->font_dialog = NULL;
1219 }
1220
1221 static gchar *
pango_font_description_to_css(PangoFontDescription * desc)1222 pango_font_description_to_css (PangoFontDescription *desc)
1223 {
1224 GString *s;
1225 PangoFontMask set;
1226
1227 s = g_string_new ("* { ");
1228
1229 set = pango_font_description_get_set_fields (desc);
1230 if (set & PANGO_FONT_MASK_FAMILY)
1231 {
1232 g_string_append (s, "font-family: ");
1233 g_string_append (s, pango_font_description_get_family (desc));
1234 g_string_append (s, "; ");
1235 }
1236 if (set & PANGO_FONT_MASK_STYLE)
1237 {
1238 switch (pango_font_description_get_style (desc))
1239 {
1240 case PANGO_STYLE_NORMAL:
1241 g_string_append (s, "font-style: normal; ");
1242 break;
1243 case PANGO_STYLE_OBLIQUE:
1244 g_string_append (s, "font-style: oblique; ");
1245 break;
1246 case PANGO_STYLE_ITALIC:
1247 g_string_append (s, "font-style: italic; ");
1248 break;
1249 }
1250 }
1251 if (set & PANGO_FONT_MASK_VARIANT)
1252 {
1253 switch (pango_font_description_get_variant (desc))
1254 {
1255 case PANGO_VARIANT_NORMAL:
1256 g_string_append (s, "font-variant: normal; ");
1257 break;
1258 case PANGO_VARIANT_SMALL_CAPS:
1259 g_string_append (s, "font-variant: small-caps; ");
1260 break;
1261 }
1262 }
1263 if (set & PANGO_FONT_MASK_WEIGHT)
1264 {
1265 switch (pango_font_description_get_weight (desc))
1266 {
1267 case PANGO_WEIGHT_THIN:
1268 g_string_append (s, "font-weight: 100; ");
1269 break;
1270 case PANGO_WEIGHT_ULTRALIGHT:
1271 g_string_append (s, "font-weight: 200; ");
1272 break;
1273 case PANGO_WEIGHT_LIGHT:
1274 case PANGO_WEIGHT_SEMILIGHT:
1275 g_string_append (s, "font-weight: 300; ");
1276 break;
1277 case PANGO_WEIGHT_BOOK:
1278 case PANGO_WEIGHT_NORMAL:
1279 g_string_append (s, "font-weight: 400; ");
1280 break;
1281 case PANGO_WEIGHT_MEDIUM:
1282 g_string_append (s, "font-weight: 500; ");
1283 break;
1284 case PANGO_WEIGHT_SEMIBOLD:
1285 g_string_append (s, "font-weight: 600; ");
1286 break;
1287 case PANGO_WEIGHT_BOLD:
1288 g_string_append (s, "font-weight: 700; ");
1289 break;
1290 case PANGO_WEIGHT_ULTRABOLD:
1291 g_string_append (s, "font-weight: 800; ");
1292 break;
1293 case PANGO_WEIGHT_HEAVY:
1294 case PANGO_WEIGHT_ULTRAHEAVY:
1295 g_string_append (s, "font-weight: 900; ");
1296 break;
1297 }
1298 }
1299 if (set & PANGO_FONT_MASK_STRETCH)
1300 {
1301 switch (pango_font_description_get_stretch (desc))
1302 {
1303 case PANGO_STRETCH_ULTRA_CONDENSED:
1304 g_string_append (s, "font-stretch: ultra-condensed; ");
1305 break;
1306 case PANGO_STRETCH_EXTRA_CONDENSED:
1307 g_string_append (s, "font-stretch: extra-condensed; ");
1308 break;
1309 case PANGO_STRETCH_CONDENSED:
1310 g_string_append (s, "font-stretch: condensed; ");
1311 break;
1312 case PANGO_STRETCH_SEMI_CONDENSED:
1313 g_string_append (s, "font-stretch: semi-condensed; ");
1314 break;
1315 case PANGO_STRETCH_NORMAL:
1316 g_string_append (s, "font-stretch: normal; ");
1317 break;
1318 case PANGO_STRETCH_SEMI_EXPANDED:
1319 g_string_append (s, "font-stretch: semi-expanded; ");
1320 break;
1321 case PANGO_STRETCH_EXPANDED:
1322 g_string_append (s, "font-stretch: expanded; ");
1323 break;
1324 case PANGO_STRETCH_EXTRA_EXPANDED:
1325 g_string_append (s, "font-stretch: extra-expanded; ");
1326 break;
1327 case PANGO_STRETCH_ULTRA_EXPANDED:
1328 g_string_append (s, "font-stretch: ultra-expanded; ");
1329 break;
1330 }
1331 }
1332 if (set & PANGO_FONT_MASK_SIZE)
1333 {
1334 g_string_append_printf (s, "font-size: %dpt", pango_font_description_get_size (desc) / PANGO_SCALE);
1335 }
1336
1337 g_string_append (s, "}");
1338
1339 return g_string_free (s, FALSE);
1340 }
1341
1342 static void
gtk_font_button_label_use_font(GtkFontButton * font_button)1343 gtk_font_button_label_use_font (GtkFontButton *font_button)
1344 {
1345 GtkFontButtonPrivate *priv = font_button->priv;
1346 GtkStyleContext *context;
1347
1348 context = gtk_widget_get_style_context (priv->font_label);
1349
1350 if (!priv->use_font)
1351 {
1352 if (priv->provider)
1353 {
1354 gtk_style_context_remove_provider (context, GTK_STYLE_PROVIDER (priv->provider));
1355 g_clear_object (&priv->provider);
1356 }
1357 }
1358 else
1359 {
1360 PangoFontDescription *desc;
1361 gchar *data;
1362
1363 if (!priv->provider)
1364 {
1365 priv->provider = gtk_css_provider_new ();
1366 gtk_style_context_add_provider (context,
1367 GTK_STYLE_PROVIDER (priv->provider),
1368 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1369 }
1370
1371 desc = pango_font_description_copy (priv->font_desc);
1372
1373 if (!priv->use_size)
1374 pango_font_description_unset_fields (desc, PANGO_FONT_MASK_SIZE);
1375
1376 data = pango_font_description_to_css (desc);
1377 gtk_css_provider_load_from_data (priv->provider, data, -1, NULL);
1378
1379 g_free (data);
1380 pango_font_description_free (desc);
1381 }
1382 }
1383
1384 static void
gtk_font_button_update_font_info(GtkFontButton * font_button)1385 gtk_font_button_update_font_info (GtkFontButton *font_button)
1386 {
1387 GtkFontButtonPrivate *priv = font_button->priv;
1388 const gchar *fam_name;
1389 const gchar *face_name;
1390 gchar *family_style;
1391
1392 if (priv->font_family)
1393 fam_name = pango_font_family_get_name (priv->font_family);
1394 else
1395 fam_name = C_("font", "None");
1396 if (priv->font_face)
1397 face_name = pango_font_face_get_face_name (priv->font_face);
1398 else
1399 face_name = "";
1400
1401 if (priv->show_style)
1402 family_style = g_strconcat (fam_name, " ", face_name, NULL);
1403 else
1404 family_style = g_strdup (fam_name);
1405
1406 gtk_label_set_text (GTK_LABEL (font_button->priv->font_label), family_style);
1407 g_free (family_style);
1408
1409 if (font_button->priv->show_size)
1410 {
1411 /* mirror Pango, which doesn't translate this either */
1412 gchar *size = g_strdup_printf ("%2.4g%s",
1413 pango_font_description_get_size (priv->font_desc) / (double)PANGO_SCALE,
1414 pango_font_description_get_size_is_absolute (priv->font_desc) ? "px" : "");
1415
1416 gtk_label_set_text (GTK_LABEL (font_button->priv->size_label), size);
1417
1418 g_free (size);
1419 }
1420
1421 gtk_font_button_label_use_font (font_button);
1422 }
1423
1424 static void
gtk_font_button_set_level(GtkFontButton * button,GtkFontChooserLevel level)1425 gtk_font_button_set_level (GtkFontButton *button,
1426 GtkFontChooserLevel level)
1427 {
1428 GtkFontButtonPrivate *priv = button->priv;
1429
1430 if (priv->level == level)
1431 return;
1432
1433 priv->level = level;
1434
1435 if (priv->font_dialog)
1436 g_object_set (priv->font_dialog, "level", level, NULL);
1437
1438 g_object_set (button,
1439 "show-size", (level & GTK_FONT_CHOOSER_LEVEL_SIZE) != 0,
1440 "show-style", (level & GTK_FONT_CHOOSER_LEVEL_STYLE) != 0,
1441 NULL);
1442
1443 g_object_notify (G_OBJECT (button), "level");
1444 }
1445
1446 static void
gtk_font_button_set_language(GtkFontButton * button,const char * language)1447 gtk_font_button_set_language (GtkFontButton *button,
1448 const char *language)
1449 {
1450 GtkFontButtonPrivate *priv = button->priv;
1451
1452 priv->language = pango_language_from_string (language);
1453
1454 if (priv->font_dialog)
1455 gtk_font_chooser_set_language (GTK_FONT_CHOOSER (priv->font_dialog), language);
1456
1457 g_object_notify (G_OBJECT (button), "language");
1458 }
1459