2 * This file is part of hildon-libs
4 * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
6 * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; version 2.1 of
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
26 * SECTION:hildon-font-selection-dialog
27 * @short_description: A widget used to allow users to select a font
28 * with certain properties
30 * Font selection can be made using this widget. Users can select font name,
31 * size, style, etc. Users can also preview text in the selected font.
37 #include <gtk/gtkstock.h>
38 #include <gtk/gtkcombobox.h>
39 #include <gtk/gtktogglebutton.h>
40 #include <gtk/gtkcheckbutton.h>
41 #include <gtk/gtklabel.h>
42 #include <gtk/gtkvbox.h>
43 #include <gtk/gtkliststore.h>
44 #include <gtk/gtknotebook.h>
47 #include <gdk/gdkkeysyms.h>
48 #include "hildon-font-selection-dialog.h"
49 #include "hildon-caption.h"
50 #include "hildon-color-selector.h"
51 #include "hildon-color-button.h"
54 #define _(String) dgettext(PACKAGE, String)
56 #define SUPERSCRIPT_RISE 3333
57 #define SUBSCRIPT_LOW -3333
62 * These are what we use as the standard font sizes, for the size list.
64 static const guint16 font_sizes[] =
66 6, 8, 10, 12, 16, 24, 32
69 #define HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(obj) \
70 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
71 HILDON_TYPE_FONT_SELECTION_DIALOG, \
72 HildonFontSelectionDialogPrivate))
74 /*None of designed api function works, so now it all comes down to
75 *use properties to achieve what we are supposed to achieve*/
91 PROP_STRIKETHROUGH_SET,
99 _HildonFontSelectionDialogPrivate HildonFontSelectionDialogPrivate;
101 struct _HildonFontSelectionDialogPrivate
103 GtkNotebook *notebook;
108 GtkWidget *cbx_font_type;
109 GtkWidget *cbx_font_size;
110 GtkWidget *font_color_button;
114 GtkWidget *chk_italic;
115 GtkWidget *chk_underline;
118 GtkWidget *chk_strikethrough;
119 GtkWidget *cbx_positioning;
122 PangoFontFamily **families;
125 /*color_set is used to show whether the color is inconsistent
126 * The handler id is used to block the signal emission
127 * when we change the color setting*/
131 /* font_scaling is the scaling factor applied to font
132 * scale in the preview dialog */
134 gdouble font_scaling;
135 gulong color_modified_signal_handler;
138 /*combo box active row indicator -2--inconsistent, -1--undefined
139 * please make sure that you use settings_init settings_apply
140 * and settings_destroy, dont even try to touch this structure
141 * without using the three above interface functions, of course
142 * if you know what you are doing, do as you please ;-)*/
145 HildonFontSelectionDialog
146 *fsd; /*pointer to our font selection dialog*/
148 gint family; /*combo box indicator*/
149 gint size; /*combo box indicator*/
150 GdkColor *color; /*free after read the setting*/
151 gboolean color_inconsist;
152 gint weight; /*bit mask*/
153 gint style; /*bit mask*/
154 gint underline; /*bit mask*/
155 gint strikethrough; /*bit mask*/
156 gint position; /*combo box indicator*/
158 }HildonFontSelectionDialogSettings;
161 hildon_font_selection_dialog_preview_key_press
166 /*Some tools from gtk_font_selection*/
167 static int cmp_families (const void *a, const void *b);
169 static void hildon_font_selection_dialog_show_preview
170 (HildonFontSelectionDialog
173 static PangoAttrList*
174 hildon_font_selection_dialog_create_attrlist
175 (HildonFontSelectionDialog
176 *fontsel, guint start_index,
179 static void hildon_font_selection_dialog_show_available_positionings
180 (HildonFontSelectionDialogPrivate
183 static void hildon_font_selection_dialog_show_available_fonts
184 (HildonFontSelectionDialog
187 static void hildon_font_selection_dialog_show_available_sizes
188 (HildonFontSelectionDialogPrivate
191 static void hildon_font_selection_dialog_class_init
192 (HildonFontSelectionDialogClass
195 static void hildon_font_selection_dialog_init
196 (HildonFontSelectionDialog
199 static void hildon_font_selection_dialog_finalize
202 static void hildon_font_selection_dialog_construct_notebook
203 (HildonFontSelectionDialog
206 static void color_modified_cb (HildonColorButton *button,
210 static void add_preview_text_attr (PangoAttrList *list,
211 PangoAttribute *attr,
215 static void toggle_clicked (GtkButton *button,
220 static GtkDialogClass *font_selection_dialog_parent_class = NULL;
222 GType hildon_font_selection_dialog_get_type(void)
224 static GType font_selection_dialog_type = 0;
226 if (!font_selection_dialog_type) {
227 static const GTypeInfo fontsel_diag_info = {
228 sizeof(HildonFontSelectionDialogClass),
229 NULL, /* base_init */
230 NULL, /* base_finalize */
231 (GClassInitFunc) hildon_font_selection_dialog_class_init,
232 NULL, /* class_finalize */
233 NULL, /* class_data */
234 sizeof(HildonFontSelectionDialog),
236 (GInstanceInitFunc) hildon_font_selection_dialog_init,
239 font_selection_dialog_type =
240 g_type_register_static(GTK_TYPE_DIALOG,
241 "HildonFontSelectionDialog",
242 &fontsel_diag_info, 0);
245 return font_selection_dialog_type;
249 hildon_font_selection_dialog_get_property (GObject *object,
255 GdkColor *color = NULL;
257 HildonFontSelectionDialogPrivate *priv =
258 HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(
259 HILDON_FONT_SELECTION_DIALOG(object));
265 i = gtk_combo_box_get_active(GTK_COMBO_BOX(priv->cbx_font_type));
266 if(i >= 0 && i < priv->n_families)
267 g_value_set_string(value,
268 pango_font_family_get_name(priv->families[i]));
270 g_value_set_string(value, "Sans");
273 case PROP_FAMILY_SET:
274 i = gtk_combo_box_get_active(GTK_COMBO_BOX(priv->cbx_font_type));
275 if(i >= 0 && i < priv->n_families)
276 g_value_set_boolean(value, TRUE);
278 g_value_set_boolean(value, FALSE);
282 i = gtk_combo_box_get_active(GTK_COMBO_BOX(priv->cbx_font_size));
283 if(i >= 0 && i < G_N_ELEMENTS(font_sizes))
284 g_value_set_int(value, font_sizes[i]);
286 g_value_set_int(value, 16);
290 i = gtk_combo_box_get_active(GTK_COMBO_BOX(priv->cbx_font_size));
291 if(i >= 0 && i < G_N_ELEMENTS(font_sizes))
292 g_value_set_boolean(value, TRUE);
294 g_value_set_boolean(value, FALSE);
298 color = hildon_color_button_get_color
299 (HILDON_COLOR_BUTTON(priv->font_color_button));
300 g_value_set_boxed(value, (gconstpointer) color);
302 gdk_color_free(color);
306 g_value_set_boolean(value, priv->color_set);
310 g_value_set_boolean(value,
311 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->chk_bold)));
315 g_value_set_boolean(value,
316 !gtk_toggle_button_get_inconsistent
317 (GTK_TOGGLE_BUTTON(priv->chk_bold)));
321 g_value_set_boolean(value,
322 gtk_toggle_button_get_active
323 (GTK_TOGGLE_BUTTON(priv->chk_italic)));
326 case PROP_ITALIC_SET:
327 g_value_set_boolean(value,
328 !gtk_toggle_button_get_inconsistent
329 (GTK_TOGGLE_BUTTON(priv->chk_italic)));
333 g_value_set_boolean(value,
334 gtk_toggle_button_get_active
335 (GTK_TOGGLE_BUTTON(priv->chk_underline)));
338 case PROP_UNDERLINE_SET:
339 g_value_set_boolean(value,
340 !gtk_toggle_button_get_inconsistent
341 (GTK_TOGGLE_BUTTON(priv->chk_underline)));
344 case PROP_STRIKETHROUGH:
345 g_value_set_boolean(value,
346 gtk_toggle_button_get_active
347 (GTK_TOGGLE_BUTTON(priv->chk_strikethrough)));
350 case PROP_STRIKETHROUGH_SET:
351 g_value_set_boolean(value,
352 !gtk_toggle_button_get_inconsistent
353 (GTK_TOGGLE_BUTTON(priv->chk_strikethrough)));
357 i = gtk_combo_box_get_active(GTK_COMBO_BOX(priv->cbx_positioning));
359 g_value_set_int(value, 1);
360 else if(i == 2)/*sub*/
361 g_value_set_int(value, -1);
363 g_value_set_int(value, 0);
366 case PROP_FONT_SCALING:
367 g_value_set_double(value, priv->font_scaling);
370 case PROP_POSITION_SET:
371 i = gtk_combo_box_get_active(GTK_COMBO_BOX(priv->cbx_positioning));
373 g_value_set_boolean(value, TRUE);
375 g_value_set_boolean(value, FALSE);
378 case PROP_PREVIEW_TEXT:
379 g_value_set_string(value,
380 hildon_font_selection_dialog_get_preview_text(
381 HILDON_FONT_SELECTION_DIALOG(object)));
385 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
391 hildon_font_selection_dialog_set_property (GObject *object,
399 GdkColor *color = NULL;
402 HildonFontSelectionDialogPrivate *priv =
403 HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(
404 HILDON_FONT_SELECTION_DIALOG(object));
405 black.red = black.green = black.blue = 0;
410 str = g_value_get_string(value);
411 for(i = 0; i < priv->n_families; i++)
413 if(strcmp(str, pango_font_family_get_name(priv->families[i]))
416 gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_font_type), i);
422 case PROP_FAMILY_SET:
423 b = g_value_get_boolean(value);
425 gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_font_type), -1);
429 size = g_value_get_int(value);
430 for(i = 0; i < G_N_ELEMENTS(font_sizes); i++)
432 if(size == font_sizes[i])
434 gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_font_size), i);
441 b = g_value_get_boolean(value);
443 gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_font_size), -1);
447 color = (GdkColor *) g_value_get_boxed(value);
449 hildon_color_button_set_color(HILDON_COLOR_BUTTON
450 (priv->font_color_button),
453 hildon_color_button_set_color(HILDON_COLOR_BUTTON
454 (priv->font_color_button),
459 priv->color_set = g_value_get_boolean(value);
462 /*set color to black, but block our signal handler*/
463 g_signal_handler_block((gpointer) priv->font_color_button,
464 priv->color_modified_signal_handler);
466 hildon_color_button_set_color(HILDON_COLOR_BUTTON
467 (priv->font_color_button),
470 g_signal_handler_unblock((gpointer) priv->font_color_button,
471 priv->color_modified_signal_handler);
476 /*this call will make sure that we dont get extra clicked signal*/
477 gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(priv->chk_bold),
479 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->chk_bold),
480 g_value_get_boolean(value));
484 gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(priv->chk_bold),
485 !g_value_get_boolean(value));
489 gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(priv->chk_italic),
491 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->chk_italic),
492 g_value_get_boolean(value));
495 case PROP_ITALIC_SET:
496 gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(priv->chk_italic),
497 !g_value_get_boolean(value));
501 gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON
502 (priv->chk_underline),
504 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->chk_underline),
505 g_value_get_boolean(value));
508 case PROP_UNDERLINE_SET:
509 gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(priv->chk_underline),
510 !g_value_get_boolean(value));
513 case PROP_STRIKETHROUGH:
514 gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON
515 (priv->chk_strikethrough),
517 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->chk_strikethrough),
518 g_value_get_boolean(value));
521 case PROP_STRIKETHROUGH_SET:
522 gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON
523 (priv->chk_strikethrough),
524 !g_value_get_boolean(value));
528 i = g_value_get_int(value);
530 gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_positioning), 1);
532 gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_positioning), 2);
534 gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_positioning), 0);
537 case PROP_FONT_SCALING:
538 priv->font_scaling = g_value_get_double(value);
541 case PROP_POSITION_SET:
542 b = g_value_get_boolean(value);
544 gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_positioning), -1);
547 case PROP_PREVIEW_TEXT:
548 hildon_font_selection_dialog_set_preview_text(
549 HILDON_FONT_SELECTION_DIALOG(object),
550 g_value_get_string(value));
554 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
560 hildon_font_selection_dialog_class_init(HildonFontSelectionDialogClass *
563 GObjectClass *gobject_class;
565 font_selection_dialog_parent_class = g_type_class_peek_parent(klass);
566 gobject_class = G_OBJECT_CLASS(klass);
567 gobject_class->finalize = hildon_font_selection_dialog_finalize;
568 gobject_class->get_property = hildon_font_selection_dialog_get_property;
569 gobject_class->set_property = hildon_font_selection_dialog_set_property;
571 /* Install property to the class */
572 g_object_class_install_property(gobject_class, PROP_FAMILY,
573 g_param_spec_string("family",
574 "Font family", "String defines"
575 " the font family", "Sans",
578 g_object_class_install_property(gobject_class, PROP_FAMILY_SET,
579 g_param_spec_boolean ("family-set",
580 "family inconsistent state",
581 "Whether the family property"
582 " is inconsistent", FALSE,
583 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
585 g_object_class_install_property(gobject_class, PROP_SIZE,
586 g_param_spec_int ("size",
592 g_object_class_install_property(gobject_class, PROP_SIZE_SET,
593 g_param_spec_boolean ("size-set",
594 "size inconsistent state",
595 "Whether the size property"
596 " is inconsistent", FALSE,
597 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
599 g_object_class_install_property(gobject_class, PROP_COLOR,
600 g_param_spec_boxed ("color",
602 "gdk color for the text",
606 g_object_class_install_property(gobject_class, PROP_COLOR_SET,
607 g_param_spec_boolean ("color-set",
608 "color inconsistent state",
609 "Whether the color property"
610 " is inconsistent", FALSE,
611 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
613 g_object_class_install_property(gobject_class, PROP_BOLD,
614 g_param_spec_boolean ("bold",
616 "Whether the text is bold",
620 g_object_class_install_property(gobject_class, PROP_BOLD_SET,
621 g_param_spec_boolean ("bold-set",
622 "bold inconsistent state",
624 " is inconsistent", FALSE,
625 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
627 g_object_class_install_property(gobject_class, PROP_ITALIC,
628 g_param_spec_boolean ("italic",
630 "Whether the text is italic",
634 g_object_class_install_property(gobject_class, PROP_ITALIC_SET,
635 g_param_spec_boolean ("italic-set",
636 "italic inconsistent state",
638 " is inconsistent", FALSE,
639 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
641 g_object_class_install_property(gobject_class, PROP_UNDERLINE,
642 g_param_spec_boolean ("underline",
644 "Whether the text is underlined",
648 g_object_class_install_property(gobject_class, PROP_UNDERLINE_SET,
649 g_param_spec_boolean ("underline-set",
650 "underline inconsistent state",
651 "Whether the underline"
652 " is inconsistent", FALSE,
653 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
655 g_object_class_install_property(gobject_class, PROP_STRIKETHROUGH,
656 g_param_spec_boolean ("strikethrough",
657 "strikethroughed text",
658 "Whether the text is strikethroughed",
662 g_object_class_install_property(gobject_class, PROP_STRIKETHROUGH_SET,
663 g_param_spec_boolean ("strikethrough-set",
664 "strikethrough inconsistent state",
665 "Whether the strikethrough"
666 " is inconsistent", FALSE,
667 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
669 g_object_class_install_property(gobject_class, PROP_POSITION,
670 g_param_spec_int ("position",
672 "Font position super or subscript",
676 /* FIXME This was introduced in 0.14.1. We don't have documentation for
677 * properties anyways, but once it's there it needs to be marked as
679 g_object_class_install_property(gobject_class, PROP_FONT_SCALING,
680 g_param_spec_double ("font-scaling",
682 "Font scaling for the preview dialog",
686 g_object_class_install_property(gobject_class, PROP_POSITION_SET,
687 g_param_spec_boolean ("position-set",
688 "position inconsistent state",
689 "Whether the position"
690 " is inconsistent", FALSE,
691 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
693 g_object_class_install_property(gobject_class, PROP_PREVIEW_TEXT,
694 g_param_spec_string("preview-text",
696 "the text in preview dialog, which does"
697 "not include the reference text",
702 g_type_class_add_private(klass,
703 sizeof(struct _HildonFontSelectionDialogPrivate));
708 hildon_font_selection_dialog_init(HildonFontSelectionDialog *fontseldiag)
710 HildonFontSelectionDialogPrivate *priv =
711 HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(fontseldiag);
712 GtkWidget *preview_button;
714 priv->notebook = GTK_NOTEBOOK(gtk_notebook_new());
716 hildon_font_selection_dialog_construct_notebook(fontseldiag);
718 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(fontseldiag)->vbox),
719 GTK_WIDGET(priv->notebook), TRUE, TRUE, 0);
721 /* Add dialog buttons */
722 gtk_dialog_add_button(GTK_DIALOG(fontseldiag),
723 _("ecdg_bd_font_dialog_ok"),
726 preview_button = gtk_button_new_with_label(_("ecdg_bd_font_dialog_preview"));
727 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(fontseldiag)->action_area),
728 preview_button, FALSE, TRUE, 0);
729 g_signal_connect_swapped(preview_button, "clicked",
731 (hildon_font_selection_dialog_show_preview),
733 gtk_widget_show(preview_button);
735 gtk_dialog_add_button(GTK_DIALOG(fontseldiag),
736 _("ecdg_bd_font_dialog_cancel"),
737 GTK_RESPONSE_CANCEL);
739 /*Set default preview text*/
740 priv->preview_text = g_strdup(_("ecdg_fi_preview_font_preview_text"));
742 gtk_window_set_title(GTK_WINDOW(fontseldiag), _("ecdg_ti_font"));
743 /*here is the line to make sure that notebook has the default focus*/
744 gtk_container_set_focus_child(GTK_CONTAINER(GTK_DIALOG(fontseldiag)->vbox),
745 GTK_WIDGET(priv->notebook));
749 hildon_font_selection_dialog_construct_notebook (HildonFontSelectionDialog
753 GtkWidget *vbox_tab[3];
754 GtkWidget *font_color_box;
755 GtkWidget *caption_control;
758 HildonFontSelectionDialogPrivate *priv =
759 HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(fontsel);
761 for (i = 0; i < 3; i++)
762 vbox_tab[i] = gtk_vbox_new(TRUE, 0);
765 GTK_SIZE_GROUP(gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL));
767 /* Build the first page of the GtkNotebook: font style */
768 priv->cbx_font_type = gtk_combo_box_new_text();
769 hildon_font_selection_dialog_show_available_fonts(fontsel);
770 caption_control = hildon_caption_new(group,
771 _("ecdg_fi_font_font"),
774 HILDON_CAPTION_OPTIONAL);
775 gtk_box_pack_start(GTK_BOX(vbox_tab[0]), caption_control,
778 priv->cbx_font_size = gtk_combo_box_new_text();
779 hildon_font_selection_dialog_show_available_sizes(priv);
780 caption_control = hildon_caption_new(group,
781 _("ecdg_fi_font_size"),
784 HILDON_CAPTION_OPTIONAL);
785 gtk_box_pack_start(GTK_BOX(vbox_tab[0]), caption_control,
788 font_color_box = gtk_hbox_new(FALSE, 0);
789 priv->font_color_button = hildon_color_button_new();
790 priv->color_set = FALSE;
791 priv->font_scaling = 1.0;
792 priv->color_modified_signal_handler =
793 g_signal_connect(G_OBJECT(priv->font_color_button), "notify::color",
794 G_CALLBACK(color_modified_cb), (gpointer) priv);
795 gtk_box_pack_start(GTK_BOX(font_color_box),
796 priv->font_color_button, FALSE, FALSE, 0);
799 hildon_caption_new(group, _("ecdg_fi_font_colour_selector"),
801 NULL, HILDON_CAPTION_OPTIONAL);
803 gtk_box_pack_start(GTK_BOX(vbox_tab[0]), caption_control,
806 /* Build the second page of the GtkNotebook: font formatting */
807 priv->chk_bold = gtk_check_button_new();
808 caption_control = hildon_caption_new(group,
809 _("ecdg_fi_font_bold"),
812 HILDON_CAPTION_OPTIONAL);
813 gtk_box_pack_start(GTK_BOX(vbox_tab[1]), caption_control,
815 g_signal_connect(G_OBJECT(priv->chk_bold), "clicked",
816 G_CALLBACK(toggle_clicked), NULL);
818 priv->chk_italic = gtk_check_button_new();
820 hildon_caption_new(group, _("ecdg_fi_font_italic"),
822 NULL, HILDON_CAPTION_OPTIONAL);
823 gtk_box_pack_start(GTK_BOX(vbox_tab[1]), caption_control,
825 g_signal_connect(G_OBJECT(priv->chk_italic), "clicked",
826 G_CALLBACK(toggle_clicked), NULL);
828 priv->chk_underline = gtk_check_button_new();
830 hildon_caption_new(group, _("ecdg_fi_font_underline"),
831 priv->chk_underline, NULL,
832 HILDON_CAPTION_OPTIONAL);
833 gtk_box_pack_start(GTK_BOX(vbox_tab[1]), caption_control,
835 g_signal_connect(G_OBJECT(priv->chk_underline), "clicked",
836 G_CALLBACK(toggle_clicked), NULL);
838 /* Build the third page of the GtkNotebook: other font properties */
839 priv->chk_strikethrough = gtk_check_button_new();
841 hildon_caption_new(group, _("ecdg_fi_font_strikethrough"),
842 priv->chk_strikethrough, NULL,
843 HILDON_CAPTION_OPTIONAL);
844 gtk_box_pack_start(GTK_BOX(vbox_tab[2]), caption_control,
846 g_signal_connect(G_OBJECT(priv->chk_strikethrough), "clicked",
847 G_CALLBACK(toggle_clicked), NULL);
849 priv->cbx_positioning = gtk_combo_box_new_text();
850 hildon_font_selection_dialog_show_available_positionings(priv);
852 hildon_caption_new(group, _("ecdg_fi_font_special"),
853 priv->cbx_positioning, NULL,
854 HILDON_CAPTION_OPTIONAL);
855 gtk_box_pack_start(GTK_BOX(vbox_tab[2]), caption_control,
858 /* Populate notebook */
859 gtk_notebook_insert_page(priv->notebook, vbox_tab[0], NULL, 0);
860 gtk_notebook_insert_page(priv->notebook, vbox_tab[1], NULL, 1);
861 gtk_notebook_insert_page(priv->notebook, vbox_tab[2], NULL, 2);
862 gtk_notebook_set_tab_label_text(priv->notebook, vbox_tab[0],
863 _("ecdg_ti_font_dialog_style"));
864 gtk_notebook_set_tab_label_text(priv->notebook, vbox_tab[1],
865 _("ecdg_ti_font_dialog_format"));
866 gtk_notebook_set_tab_label_text(priv->notebook, vbox_tab[2],
867 _("ecdg_ti_font_dialog_other"));
869 gtk_widget_show_all(GTK_WIDGET(priv->notebook));
873 color_modified_cb(HildonColorButton *button,
877 HildonFontSelectionDialogPrivate *priv =
878 (HildonFontSelectionDialogPrivate *) fsd_priv;
880 priv->color_set = TRUE;
884 hildon_font_selection_dialog_finalize(GObject * object)
886 HildonFontSelectionDialogPrivate *priv;
887 HildonFontSelectionDialog *fontsel;
889 g_assert(HILDON_IS_FONT_SELECTION_DIALOG(object));
890 fontsel = HILDON_FONT_SELECTION_DIALOG(object);
892 priv = HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(fontsel);
894 g_free(priv->preview_text);
895 g_free(priv->families);
897 if (G_OBJECT_CLASS(font_selection_dialog_parent_class)->finalize)
898 G_OBJECT_CLASS(font_selection_dialog_parent_class)->finalize(object);
902 cmp_families(const void *a, const void *b)
905 pango_font_family_get_name(*(PangoFontFamily **) a);
907 pango_font_family_get_name(*(PangoFontFamily **) b);
909 return g_utf8_collate(a_name, b_name);
912 /* Exits the preview dialog with GTK_RESPONSE_CANCEL if Esc key
915 hildon_font_selection_dialog_preview_key_press(GtkWidget * widget,
922 if (event->keyval == GDK_Escape)
924 gtk_dialog_response(GTK_DIALOG(widget), GTK_RESPONSE_CANCEL);
932 add_preview_text_attr(PangoAttrList *list, PangoAttribute *attr,
933 guint start, guint len)
935 attr->start_index = start;
936 attr->end_index = start + len;
937 pango_attr_list_insert(list, attr);
940 static PangoAttrList*
941 hildon_font_selection_dialog_create_attrlist(HildonFontSelectionDialog *
942 fontsel, guint start_index, guint len)
945 PangoAttribute *attr;
947 gboolean family_set, size_set, color_set, bold, bold_set,
948 italic, italic_set, underline, underline_set,
949 strikethrough, strikethrough_set, position_set;
950 GdkColor *color = NULL;
951 gchar *family = NULL;
952 gdouble font_scaling = 1.0;
954 list = pango_attr_list_new();
956 g_object_get(G_OBJECT(fontsel),
957 "family", &family, "family-set", &family_set,
958 "size", &size, "size-set", &size_set,
959 "color", &color, "color-set", &color_set,
960 "bold", &bold, "bold-set", &bold_set,
961 "italic", &italic, "italic-set", &italic_set,
962 "underline", &underline, "underline-set", &underline_set,
963 "strikethrough", &strikethrough, "strikethrough-set",
964 &strikethrough_set, "position", &position,
965 "position-set", &position_set,
966 "font-scaling", &font_scaling,
972 attr = pango_attr_family_new(family);
973 add_preview_text_attr(list, attr, start_index, len);
980 attr = pango_attr_size_new(size * PANGO_SCALE);
981 add_preview_text_attr(list, attr, start_index, len);
987 attr = pango_attr_foreground_new(color->red, color->green, color->blue);
988 add_preview_text_attr(list, attr, start_index, len);
992 gdk_color_free(color);
998 attr = pango_attr_weight_new(PANGO_WEIGHT_BOLD);
1000 attr = pango_attr_weight_new(PANGO_WEIGHT_NORMAL);
1002 add_preview_text_attr(list, attr, start_index, len);
1009 attr = pango_attr_style_new(PANGO_STYLE_ITALIC);
1011 attr = pango_attr_style_new(PANGO_STYLE_NORMAL);
1013 add_preview_text_attr(list, attr, start_index, len);
1020 attr = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE);
1022 attr = pango_attr_underline_new(PANGO_UNDERLINE_NONE);
1024 add_preview_text_attr(list, attr, start_index, len);
1028 if(strikethrough_set)
1031 attr = pango_attr_strikethrough_new(TRUE);
1033 attr = pango_attr_strikethrough_new(FALSE);
1035 add_preview_text_attr(list, attr, start_index, len);
1044 attr = pango_attr_rise_new(SUPERSCRIPT_RISE);
1047 attr = pango_attr_rise_new(SUBSCRIPT_LOW);
1050 attr = pango_attr_rise_new(0);
1054 add_preview_text_attr(list, attr, start_index, len);
1057 /*font scaling for preview*/
1060 attr = pango_attr_scale_new(font_scaling);
1061 add_preview_text_attr(list, attr, 0, len + start_index);
1068 hildon_font_selection_dialog_show_preview(HildonFontSelectionDialog *
1071 HildonFontSelectionDialogPrivate *priv =
1072 HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(fontsel);
1074 gboolean family_set, size_set;
1075 PangoAttribute *attr;
1076 PangoAttrList *list;
1077 GtkWidget *preview_dialog;
1078 GtkWidget *preview_label;
1080 gboolean position_set = FALSE;
1082 gboolean show_ref = FALSE;
1084 g_object_get(G_OBJECT(fontsel), "position-set", &position_set, NULL);
1086 g_object_get(G_OBJECT(fontsel), "position", &position, NULL);
1087 if (position == 1 || position == -1)
1091 /*Preview dialog init*/
1093 gtk_dialog_new_with_buttons(_("ecdg_ti_preview_font"), NULL,
1095 GTK_DIALOG_DESTROY_WITH_PARENT |
1096 GTK_DIALOG_NO_SEPARATOR,
1097 _("ecdg_bd_font_dialog_ok"),
1098 GTK_RESPONSE_ACCEPT,
1101 str = (show_ref) ? g_strconcat(_("ecdg_fi_preview_font_preview_reference"), priv->preview_text, 0) :
1102 g_strdup (priv->preview_text);
1104 preview_label = gtk_label_new(str);
1105 gtk_label_set_line_wrap(GTK_LABEL(preview_label), TRUE);
1110 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(preview_dialog)->vbox),
1114 /* set keypress handler (ESC hardkey) */
1115 g_signal_connect(G_OBJECT(preview_dialog), "key-press-event",
1116 G_CALLBACK(hildon_font_selection_dialog_preview_key_press),
1121 list = (show_ref) ? hildon_font_selection_dialog_create_attrlist(fontsel,
1122 strlen(_("ecdg_fi_preview_font_preview_reference")),
1123 strlen(priv->preview_text)) :
1124 hildon_font_selection_dialog_create_attrlist(fontsel,
1126 strlen(priv->preview_text));
1128 g_object_get(G_OBJECT(fontsel), "family", &str, "family-set",
1129 &family_set, "size", &size, "size-set", &size_set,
1132 /* FIXME: This is a slightly ugly hack to force the width of the window so that
1133 * the whole text fits with various font sizes. It's being done in such a way,
1134 * because of some GtkLabel wrapping issues and other mysterious bugs related to
1135 * truncating ellipsizing. Needs a rethink in future. (MDK) */
1137 gint dialog_width = (size_set && size > 24) ? 600 : 500;
1138 gtk_window_set_default_size (GTK_WINDOW(preview_dialog), dialog_width, -1);
1140 /*make reference text to have the same fontface and size*/
1143 attr = pango_attr_family_new(str);
1144 add_preview_text_attr(list, attr, 0, strlen(_("ecdg_fi_preview_font_preview_reference")));
1151 attr = pango_attr_size_new(size * PANGO_SCALE);
1152 add_preview_text_attr(list, attr, 0, strlen(_("ecdg_fi_preview_font_preview_reference")));
1155 gtk_label_set_attributes(GTK_LABEL(preview_label), list);
1156 pango_attr_list_unref(list);
1158 /*And show the dialog*/
1159 gtk_window_set_transient_for(GTK_WINDOW(preview_dialog),
1160 GTK_WINDOW(fontsel));
1162 gtk_widget_show_all(preview_dialog);
1163 gtk_dialog_run(GTK_DIALOG(preview_dialog));
1164 gtk_widget_destroy(preview_dialog);
1168 static gboolean is_internal_font(const gchar * name){
1169 return strcmp(name, "DeviceSymbols") == 0
1170 || strcmp(name, "Nokia Smiley" ) == 0
1171 || strcmp(name, "NewCourier" ) == 0
1172 || strcmp(name, "NewTimes" ) == 0
1173 || strcmp(name, "SwissA" ) == 0
1174 || strcmp(name, "Nokia Sans" ) == 0
1175 || strcmp(name, "Nokia Sans Cn") == 0;
1178 static void filter_out_internal_fonts(PangoFontFamily **families, int *n_families){
1180 int n; /* counts valid fonts */
1181 const gchar * name = NULL;
1183 for(i = 0, n = 0; i < *n_families; i++){
1185 name = pango_font_family_get_name(families[i]);
1187 if(!is_internal_font(name)){
1189 if(i!=n){ /* there are filtered out families */
1190 families[n] = families[i]; /* shift the current family */
1193 n++; /* count one more valid */
1195 }/* foreach font family */
1202 hildon_font_selection_dialog_show_available_fonts(HildonFontSelectionDialog
1208 HildonFontSelectionDialogPrivate *priv =
1209 HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(fontsel);
1211 pango_context_list_families(gtk_widget_get_pango_context
1212 (GTK_WIDGET(fontsel)), &priv->families,
1215 filter_out_internal_fonts(priv->families, &priv->n_families);
1217 qsort(priv->families, priv->n_families, sizeof(PangoFontFamily *),
1221 for (i = 0; i < priv->n_families; i++)
1223 const gchar *name = pango_font_family_get_name(priv->families[i]);
1225 gtk_combo_box_append_text(GTK_COMBO_BOX(priv->cbx_font_type),
1232 hildon_font_selection_dialog_show_available_positionings
1233 (HildonFontSelectionDialogPrivate
1236 gtk_combo_box_append_text(GTK_COMBO_BOX(priv->cbx_positioning),
1237 _("ecdg_va_font_printpos_1"));
1238 gtk_combo_box_append_text(GTK_COMBO_BOX(priv->cbx_positioning),
1239 _("ecdg_va_font_printpos_2"));
1240 gtk_combo_box_append_text(GTK_COMBO_BOX(priv->cbx_positioning),
1241 _("ecdg_va_font_printpos_3"));
1244 /*Loads the sizes from a pre-allocated table*/
1246 hildon_font_selection_dialog_show_available_sizes
1247 (HildonFontSelectionDialogPrivate
1253 for (i = 0; i < G_N_ELEMENTS(font_sizes); i++)
1255 size_str = g_strdup_printf ("%i%s",
1257 _("ecdg_va_font_size_trailer"));
1259 gtk_combo_box_append_text(GTK_COMBO_BOX(priv->cbx_font_size),
1266 toggle_clicked(GtkButton *button, gpointer unused)
1268 GtkToggleButton *t_b = GTK_TOGGLE_BUTTON(button);
1270 /*we have to remove the inconsistent state ourselves*/
1271 if(gtk_toggle_button_get_inconsistent(t_b))
1273 gtk_toggle_button_set_inconsistent(t_b, FALSE);
1274 gtk_toggle_button_set_active(t_b, FALSE);
1278 /*******************/
1279 /*Public functions*/
1280 /*******************/
1283 * hildon_font_selection_dialog_new:
1284 * @parent: the parent window
1285 * @title: the title of font selection dialog
1287 * If NULL is passed for title, then default title
1288 * "Font" will be used.
1290 * Returns: a new #HildonFontSelectionDialog
1293 hildon_font_selection_dialog_new(GtkWindow * parent,
1294 const gchar * title)
1296 HildonFontSelectionDialog *fontseldiag;
1298 fontseldiag = g_object_new(HILDON_TYPE_FONT_SELECTION_DIALOG,
1299 "has-separator", FALSE, NULL);
1302 gtk_window_set_title(GTK_WINDOW(fontseldiag), title);
1305 gtk_window_set_transient_for(GTK_WINDOW(fontseldiag), parent);
1307 return GTK_WIDGET(fontseldiag);
1311 * hildon_font_selection_dialog_get_preview_text:
1312 * @fsd: the font selection dialog
1314 * Gets the text in preview dialog, which does not include the
1315 * reference text. The returned string must be freed by the user.
1317 * Returns: a string pointer
1320 hildon_font_selection_dialog_get_preview_text(HildonFontSelectionDialog * fsd)
1322 HildonFontSelectionDialogPrivate *priv;
1324 g_return_val_if_fail(HILDON_IS_FONT_SELECTION_DIALOG(fsd), FALSE);
1325 priv = HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(fsd);
1326 return g_strdup(priv->preview_text);
1330 * hildon_font_selection_dialog_set_preview_text:
1331 * @fsd: the font selection dialog
1332 * @text: the text to be displayed in the preview dialog
1334 * The default preview text is
1335 * "The quick brown fox jumped over the lazy dogs"
1338 hildon_font_selection_dialog_set_preview_text(HildonFontSelectionDialog *
1339 fsd, const gchar * text)
1341 HildonFontSelectionDialogPrivate *priv = NULL;
1343 g_return_if_fail(HILDON_IS_FONT_SELECTION_DIALOG(fsd));
1344 g_return_if_fail(text);
1346 priv = HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(fsd);
1348 g_free(priv->preview_text);
1349 priv->preview_text = g_strdup(text);
1350 g_object_notify (G_OBJECT (fsd), "preview-text");