The VVolumebar example now uses slightly bigger height. Adding some checks before...
[hildon] / src / hildon-font-selection-dialog.c
1 /*
2  * This file is a part of hildon
3  *
4  * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
5  *
6  * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
7  *
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
11  * the License, or (at your option) any later version.
12  *
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.
17  *
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
21  * 02110-1301 USA
22  *
23  */
24
25 /**
26  * SECTION:hildon-font-selection-dialog
27  * @short_description: A widget used to allow users to select a font 
28  * with certain properties.
29  *
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.
32  */
33
34 #ifdef                                          HAVE_CONFIG_H
35 #include                                        <config.h>
36 #endif
37
38 #include                                        <stdlib.h>
39 #include                                        <string.h>
40 #include                                        <gtk/gtkstock.h>
41 #include                                        <gtk/gtkcombobox.h>
42 #include                                        <gtk/gtktogglebutton.h>
43 #include                                        <gtk/gtkcheckbutton.h>
44 #include                                        <gtk/gtklabel.h>
45 #include                                        <gtk/gtkvbox.h>
46 #include                                        <gtk/gtkliststore.h>
47 #include                                        <gtk/gtknotebook.h>
48 #include                                        <gtk/gtk.h>
49 #include                                        <glib.h>
50 #include                                        <gdk/gdkkeysyms.h>
51 #include                                        "hildon-font-selection-dialog.h"
52 #include                                        "hildon-caption.h"
53 #include                                        "hildon-color-button.h"
54 #include                                        <libintl.h>
55 #include                                        "hildon-font-selection-dialog-private.h"
56
57 /* These are what we use as the standard font sizes, for the size list */
58
59 static const guint16                            font_sizes[] = 
60 {
61   6, 8, 10, 12, 16, 24, 32
62 };
63
64 enum
65 {
66     PROP_0,
67     PROP_FAMILY,
68     PROP_FAMILY_SET,
69     PROP_SIZE,
70     PROP_SIZE_SET,
71     PROP_COLOR,
72     PROP_COLOR_SET,
73     PROP_BOLD,
74     PROP_BOLD_SET,
75     PROP_ITALIC,
76     PROP_ITALIC_SET,
77     PROP_UNDERLINE,
78     PROP_UNDERLINE_SET,
79     PROP_STRIKETHROUGH,
80     PROP_STRIKETHROUGH_SET,
81     PROP_POSITION,
82     PROP_POSITION_SET,
83     PROP_PREVIEW_TEXT,
84     PROP_FONT_SCALING
85 };
86
87 /* combo box active row indicator -2--inconsistent, -1--undefined 
88  * please make sure that you use settings_init settings_apply
89  * and settings_destroy, dont even try to touch this structure 
90  * without using the three above interface functions, of course
91  * if you know what you are doing, do as you please ;-)*/
92 typedef struct
93 {
94     HildonFontSelectionDialog *fsd;             /* pointer to our font selection dialog */
95
96     gint family;                                /* combo box indicator */
97     gint size;                                  /* combo box indicator */
98     GdkColor *color;                            /* free after read the setting */
99     gboolean color_inconsist;
100     gint weight;                                /* bit mask */
101     gint style;                                 /* bit mask */
102     gint underline;                             /* bit mask */
103     gint strikethrough;                         /* bit mask */
104     gint position;                              /* combo box indicator */
105
106 }                                               HildonFontSelectionDialogSettings;
107
108 static gboolean
109 hildon_font_selection_dialog_preview_key_press  (GtkWidget *widget,
110                                                  GdkEventKey *event,
111                                                  gpointer unused);
112
113 static int
114 cmp_families                                    (const void *a, 
115                                                  const void *b);
116
117 static void   
118 hildon_font_selection_dialog_show_preview       (HildonFontSelectionDialog *fontsel);
119
120 static PangoAttrList*
121 hildon_font_selection_dialog_create_attrlist    (HildonFontSelectionDialog *fontsel, 
122                                                  guint start_index,
123                                                  guint len);
124
125 static void   
126 hildon_font_selection_dialog_show_available_positionings (HildonFontSelectionDialogPrivate *priv);
127
128 static void   
129 hildon_font_selection_dialog_show_available_fonts (HildonFontSelectionDialog *fontsel);
130
131 static void   
132 hildon_font_selection_dialog_show_available_sizes (HildonFontSelectionDialogPrivate *priv);
133
134 static void   
135 hildon_font_selection_dialog_class_init         (HildonFontSelectionDialogClass *klass);
136
137 static void   
138 hildon_font_selection_dialog_init               (HildonFontSelectionDialog *fontseldiag);
139
140 static void   
141 hildon_font_selection_dialog_finalize           (GObject *object);
142
143 static void   
144 hildon_font_selection_dialog_construct_notebook (HildonFontSelectionDialog *fontsel);
145
146 static void   
147 color_modified_cb                               (HildonColorButton *button,
148                                                  GParamSpec *pspec,
149                                                  gpointer fsd_priv);
150
151 static void   
152 add_preview_text_attr                           (PangoAttrList *list, 
153                                                  PangoAttribute *attr, 
154                                                  guint start, 
155                                                  guint len);
156
157 static void   
158 toggle_clicked                                  (GtkButton *button, 
159                                                  gpointer unused);
160
161 static GtkDialogClass*                          parent_class = NULL;
162
163 #define                                         _(String) dgettext("hildon-libs", String)
164
165 #define                                         SUPERSCRIPT_RISE 3333
166
167 #define                                         SUBSCRIPT_LOW -3333
168
169 #define                                         ON_BIT  0x01
170
171 #define                                         OFF_BIT 0x02
172
173 /**
174  * hildon_font_selection_dialog_get_type:
175  *
176  * Initializes and returns the type of a hildon font selection dialog
177  *
178  * @Returns: GType of #HildonFontSelectionDialog
179  */
180 GType G_GNUC_CONST
181 hildon_font_selection_dialog_get_type           (void)
182 {
183     static GType font_selection_dialog_type = 0;
184
185     if (! font_selection_dialog_type) {
186         static const GTypeInfo fontsel_diag_info = {
187             sizeof(HildonFontSelectionDialogClass),
188             NULL,       /* base_init */
189             NULL,       /* base_finalize */
190             (GClassInitFunc) hildon_font_selection_dialog_class_init,
191             NULL,       /* class_finalize */
192             NULL,       /* class_data */
193             sizeof(HildonFontSelectionDialog),
194             0,  /* n_preallocs */
195             (GInstanceInitFunc) hildon_font_selection_dialog_init,
196         };
197
198         font_selection_dialog_type =
199             g_type_register_static (GTK_TYPE_DIALOG,
200                     "HildonFontSelectionDialog",
201                     &fontsel_diag_info, 0);
202     }
203
204     return font_selection_dialog_type;
205 }
206
207 static void
208 hildon_font_selection_dialog_get_property       (GObject *object,
209                                                  guint prop_id,
210                                                  GValue *value,
211                                                  GParamSpec *pspec)
212 {
213     gint i;
214     GdkColor *color = NULL;
215
216     HildonFontSelectionDialogPrivate *priv =
217         HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(object);
218
219     g_assert (priv);
220
221     switch (prop_id)
222     {
223         case PROP_FAMILY:
224             i = gtk_combo_box_get_active (GTK_COMBO_BOX (priv->cbx_font_type));
225             if(i >= 0 && i < priv->n_families)
226                 g_value_set_string(value, 
227                         pango_font_family_get_name (priv->families[i]));
228             else
229                 g_value_set_string (value, "Sans");
230                 /* FIXME Bad hardcoding here */
231             break;
232
233         case PROP_FAMILY_SET:
234             i = gtk_combo_box_get_active (GTK_COMBO_BOX (priv->cbx_font_type));
235             if(i >= 0 && i < priv->n_families)
236                 g_value_set_boolean (value, TRUE);
237             else
238                 g_value_set_boolean (value, FALSE);
239             break;
240
241         case PROP_SIZE:
242             i = gtk_combo_box_get_active (GTK_COMBO_BOX (priv->cbx_font_size));
243             if(i >= 0 && i < G_N_ELEMENTS (font_sizes))
244                 g_value_set_int (value, font_sizes[i]);
245             else
246                 g_value_set_int (value, 16);
247             break;
248
249         case PROP_SIZE_SET:
250             i = gtk_combo_box_get_active (GTK_COMBO_BOX (priv->cbx_font_size));
251             if(i >= 0 && i < G_N_ELEMENTS (font_sizes))
252                 g_value_set_boolean (value, TRUE);
253             else
254                 g_value_set_boolean (value, FALSE);
255             break;
256
257         case PROP_COLOR:
258             color = g_new (GdkColor, 1);
259             hildon_color_button_get_color
260                 (HILDON_COLOR_BUTTON (priv->font_color_button), color);
261             g_value_set_boxed (value, (gconstpointer) color);
262             if(color != NULL)
263                 gdk_color_free (color);
264             break;
265
266         case PROP_COLOR_SET:
267             g_value_set_boolean (value, priv->color_set);
268             break;
269
270         case PROP_BOLD:
271             g_value_set_boolean (value, 
272                     gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->chk_bold)));
273             break;
274
275         case PROP_BOLD_SET:
276             g_value_set_boolean (value,
277                     ! gtk_toggle_button_get_inconsistent
278                     (GTK_TOGGLE_BUTTON (priv->chk_bold)));
279             break;
280
281         case PROP_ITALIC:
282             g_value_set_boolean (value, 
283                     gtk_toggle_button_get_active
284                     (GTK_TOGGLE_BUTTON (priv->chk_italic)));
285             break;
286
287         case PROP_ITALIC_SET:
288             g_value_set_boolean (value,
289                     ! gtk_toggle_button_get_inconsistent
290                     (GTK_TOGGLE_BUTTON (priv->chk_italic)));
291             break;
292
293         case PROP_UNDERLINE:
294             g_value_set_boolean (value, 
295                     gtk_toggle_button_get_active
296                     (GTK_TOGGLE_BUTTON (priv->chk_underline)));
297             break;
298
299         case PROP_UNDERLINE_SET:
300             g_value_set_boolean (value,
301                     ! gtk_toggle_button_get_inconsistent
302                     (GTK_TOGGLE_BUTTON (priv->chk_underline)));
303             break;
304
305         case PROP_STRIKETHROUGH:
306             g_value_set_boolean(value, 
307                     gtk_toggle_button_get_active
308                     (GTK_TOGGLE_BUTTON (priv->chk_strikethrough)));
309             break;
310
311         case PROP_STRIKETHROUGH_SET:
312             g_value_set_boolean(value,
313                     ! gtk_toggle_button_get_inconsistent
314                     (GTK_TOGGLE_BUTTON (priv->chk_strikethrough)));
315             break;
316
317         case PROP_POSITION:
318             i = gtk_combo_box_get_active (GTK_COMBO_BOX (priv->cbx_positioning));
319             if(i == 1) /* super */
320                 g_value_set_int (value, 1);
321             else if(i == 2)/* sub */
322                 g_value_set_int (value, -1);
323             else
324                 g_value_set_int (value, 0);
325             break;
326
327         case PROP_FONT_SCALING:
328             g_value_set_double (value, priv->font_scaling);
329             break;
330
331         case PROP_POSITION_SET:
332             i = gtk_combo_box_get_active (GTK_COMBO_BOX (priv->cbx_positioning));
333             if(i >= 0 && i < 3)
334                 g_value_set_boolean (value, TRUE);
335             else
336                 g_value_set_boolean (value, FALSE);
337             break;
338
339         case PROP_PREVIEW_TEXT:
340             g_value_set_string (value,
341                     hildon_font_selection_dialog_get_preview_text (HILDON_FONT_SELECTION_DIALOG (object)));
342             break;
343
344         default:
345             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
346             break;
347     }
348 }
349
350 static void 
351 hildon_font_selection_dialog_set_property       (GObject *object,
352                                                  guint prop_id,
353                                                  const GValue *value,
354                                                  GParamSpec *pspec)
355 {
356     gint i, size;
357     const gchar *str;
358     gboolean b;
359     GdkColor *color = NULL;
360     GdkColor black;
361
362     HildonFontSelectionDialogPrivate *priv = HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE (object);
363     g_assert (priv);
364
365     black.red = black.green = black.blue = 0;
366
367     switch (prop_id)
368     {
369         case PROP_FAMILY:
370             str = g_value_get_string (value);
371             for(i = 0; i < priv->n_families; i++)
372             {
373                 if (strcmp (str, pango_font_family_get_name (priv->families[i]))
374                         == 0)
375                 {
376                     gtk_combo_box_set_active (GTK_COMBO_BOX (priv->cbx_font_type), i);
377                     break;
378                 }
379             }
380             break;
381
382         case PROP_FAMILY_SET:
383             b = g_value_get_boolean (value);
384             if(!b)
385                 gtk_combo_box_set_active (GTK_COMBO_BOX (priv->cbx_font_type), -1);
386             break;
387
388         case PROP_SIZE:
389             size = g_value_get_int (value);
390             for(i = 0; i < G_N_ELEMENTS (font_sizes); i++)
391             {
392                 if(size == font_sizes[i])
393                 {
394                     gtk_combo_box_set_active (GTK_COMBO_BOX (priv->cbx_font_size), i);
395                     break;
396                 }
397             }
398             break;
399
400         case PROP_SIZE_SET:
401             b = g_value_get_boolean (value);
402             if(!b)
403                 gtk_combo_box_set_active (GTK_COMBO_BOX (priv->cbx_font_size), -1);
404             break;
405
406         case PROP_COLOR:
407             color = (GdkColor *) g_value_get_boxed (value);
408             if(color != NULL)
409                 hildon_color_button_set_color (HILDON_COLOR_BUTTON
410                         (priv->font_color_button),
411                         color);
412             else
413                 hildon_color_button_set_color (HILDON_COLOR_BUTTON
414                         (priv->font_color_button),
415                         &black);
416             break;
417
418         case PROP_COLOR_SET:
419             priv->color_set = g_value_get_boolean (value);
420             if(! priv->color_set)
421             {
422                 /* set color to black, but block our signal handler */
423                 g_signal_handler_block ((gpointer) priv->font_color_button,
424                         priv->color_modified_signal_handler);
425
426                 hildon_color_button_set_color (HILDON_COLOR_BUTTON
427                         (priv->font_color_button), 
428                         &black);
429
430                 g_signal_handler_unblock ((gpointer) priv->font_color_button,
431                         priv->color_modified_signal_handler);
432             }
433             break;
434
435         case PROP_BOLD:
436             /* this call will make sure that we dont get extra clicked signal */
437             gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON(priv->chk_bold), FALSE);
438             gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(priv->chk_bold), g_value_get_boolean (value));
439             break;
440
441         case PROP_BOLD_SET:
442             gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (priv->chk_bold),! g_value_get_boolean(value));
443             break;
444
445         case PROP_ITALIC:
446             gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(priv->chk_italic),
447                     FALSE);
448             gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->chk_italic),
449                     g_value_get_boolean(value));
450             break;
451
452         case PROP_ITALIC_SET:
453             gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(priv->chk_italic),
454                     !g_value_get_boolean(value));
455             break;
456
457         case PROP_UNDERLINE:
458             gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON
459                     (priv->chk_underline),
460                     FALSE);
461             gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->chk_underline),
462                     g_value_get_boolean(value));
463             break;
464
465         case PROP_UNDERLINE_SET:
466             gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(priv->chk_underline),
467                     !g_value_get_boolean(value));
468             break;
469
470         case PROP_STRIKETHROUGH:
471             gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON
472                     (priv->chk_strikethrough),
473                     FALSE);
474             gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->chk_strikethrough),
475                     g_value_get_boolean(value));
476             break;
477
478         case PROP_STRIKETHROUGH_SET:
479             gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON
480                     (priv->chk_strikethrough),
481                     !g_value_get_boolean(value));
482             break;
483
484         case PROP_POSITION:
485             i = g_value_get_int(value);
486             if( i == 1 )
487                 gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_positioning), 1);
488             else if(i == -1)
489                 gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_positioning), 2);
490             else
491                 gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_positioning), 0);
492             break;
493
494         case PROP_FONT_SCALING:
495             priv->font_scaling = g_value_get_double(value);
496             break;
497
498         case PROP_POSITION_SET:
499             b = g_value_get_boolean(value);
500             if(!b)
501                 gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_positioning), -1);
502             break;
503
504         case PROP_PREVIEW_TEXT:
505             hildon_font_selection_dialog_set_preview_text(
506                     HILDON_FONT_SELECTION_DIALOG(object),
507                     g_value_get_string(value));
508             break;
509
510         default:
511             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
512             break;
513     }
514 }
515
516 static void
517 hildon_font_selection_dialog_class_init         (HildonFontSelectionDialogClass *klass)
518 {
519     GObjectClass *gobject_class;
520
521     parent_class = g_type_class_peek_parent (klass);
522     gobject_class = G_OBJECT_CLASS (klass);
523
524     gobject_class->finalize         = hildon_font_selection_dialog_finalize;
525     gobject_class->get_property     = hildon_font_selection_dialog_get_property;
526     gobject_class->set_property     = hildon_font_selection_dialog_set_property;
527
528     /* Install properties to the class */
529
530     /**
531      * HildonFontSelectionDialog:family:
532      *
533      * Font family used.
534      */
535     g_object_class_install_property (gobject_class, PROP_FAMILY,
536             g_param_spec_string ("family",
537                 "Font family", "String defines"
538                 " the font family", "Sans",
539                 G_PARAM_READWRITE));
540
541     /**
542      * HildonFontSelectionDialog:family-set:
543      *
544      * Is font family set or inconsistent.
545      */
546     g_object_class_install_property (gobject_class, PROP_FAMILY_SET,
547             g_param_spec_boolean ("family-set",
548                 "family inconsistent state",
549                 "Whether the family property"
550                 " is inconsistent", FALSE,
551                 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
552
553     /**
554      * HildonFontSelectionDialog:size:
555      *
556      * Font size.
557      */
558     g_object_class_install_property (gobject_class, PROP_SIZE,
559             g_param_spec_int ("size",
560                 "Font size",
561                 "Font size in Pt",
562                 6, 32, 16,
563                 G_PARAM_READWRITE));
564
565     /**
566      * HildonFontSelectionDialog:size-set:
567      *
568      * Is font size set or inconsistent.
569      */
570     g_object_class_install_property (gobject_class, PROP_SIZE_SET,
571             g_param_spec_boolean ("size-set",
572                 "size inconsistent state",
573                 "Whether the size property"
574                 " is inconsistent", FALSE,
575                 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
576
577     /**
578      * HildonFontSelectionDialog:color:
579      *
580      * GdkColor for the text.
581      */
582     g_object_class_install_property (gobject_class, PROP_COLOR,
583             g_param_spec_boxed ("color",
584                 "text color",
585                 "gdk color for the text",
586                 GDK_TYPE_COLOR,
587                 G_PARAM_READWRITE));
588
589     /**
590      * HildonFontSelectionDialog:color-set:
591      *
592      * Is font color set or inconsistent.
593      */
594     g_object_class_install_property (gobject_class, PROP_COLOR_SET,
595             g_param_spec_boolean ("color-set",
596                 "color inconsistent state",
597                 "Whether the color property"
598                 " is inconsistent", FALSE,
599                 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
600
601     /**
602      * HildonFontSelectionDialog:color-set:
603      *
604      * Is font set as bold.
605      */
606     g_object_class_install_property (gobject_class, PROP_BOLD,
607             g_param_spec_boolean ("bold",
608                 "text weight",
609                 "Whether the text is bold",
610                 FALSE,
611                 G_PARAM_READWRITE));
612
613     /**
614      * HildonFontSelectionDialog:color-set:
615      *
616      * Is font bold status set or inconsistent.
617      */
618     g_object_class_install_property (gobject_class, PROP_BOLD_SET,
619             g_param_spec_boolean ("bold-set",
620                 "bold inconsistent state",
621                 "Whether the bold"
622                 " is inconsistent", FALSE,
623                 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
624
625     /**
626      * HildonFontSelectionDialog:italic:
627      *
628      * Is font set as italic.
629      */
630     g_object_class_install_property (gobject_class, PROP_ITALIC,
631             g_param_spec_boolean ("italic",
632                 "text style",
633                 "Whether the text is italic",
634                 FALSE,
635                 G_PARAM_READWRITE));
636
637     /**
638      * HildonFontSelectionDialog:italic-set:
639      *
640      * Is font italic status set or inconsistent.
641      */
642     g_object_class_install_property (gobject_class, PROP_ITALIC_SET,
643             g_param_spec_boolean ("italic-set",
644                 "italic inconsistent state",
645                 "Whether the italic"
646                 " is inconsistent", FALSE,
647                 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
648
649     /**
650      * HildonFontSelectionDialog:underline:
651      *
652      * Is the font underlined.
653      */
654     g_object_class_install_property (gobject_class, PROP_UNDERLINE,
655             g_param_spec_boolean ("underline",
656                 "text underline",
657                 "Whether the text is underlined",
658                 FALSE,
659                 G_PARAM_READWRITE));
660
661     /**
662      * HildonFontSelectionDialog:underline:
663      *
664      * Is font underline status set or inconsistent.
665      */
666     g_object_class_install_property (gobject_class, PROP_UNDERLINE_SET,
667             g_param_spec_boolean ("underline-set",
668                 "underline inconsistent state",
669                 "Whether the underline"
670                 " is inconsistent", FALSE,
671                 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
672
673     /**
674      * HildonFontSelectionDialog:strikethrough:
675      *
676      * Is the font striken-through.
677      */
678     g_object_class_install_property (gobject_class, PROP_STRIKETHROUGH,
679             g_param_spec_boolean ("strikethrough",
680                 "strikethroughed text",
681                 "Whether the text is strikethroughed",
682                 FALSE,
683                 G_PARAM_READWRITE));
684
685     /**
686      * HildonFontSelectionDialog:strikethrough-set:
687      *
688      * Is the font strikenthrough status set.
689      */
690     g_object_class_install_property (gobject_class, PROP_STRIKETHROUGH_SET,
691             g_param_spec_boolean ("strikethrough-set",
692                 "strikethrough inconsistent state",
693                 "Whether the strikethrough"
694                 " is inconsistent", FALSE,
695                 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
696
697     /**
698      * HildonFontSelectionDialog:position:
699      *
700      * The font positioning versus baseline.
701      */
702     g_object_class_install_property (gobject_class, PROP_POSITION,
703             g_param_spec_int ("position",
704                 "Font position",
705                 "Font position super or subscript",
706                 -1, 1, 0,
707                 G_PARAM_READWRITE));
708
709     /**
710      * HildonFontSelectionDialog:position-set:
711      *
712      * Is the font positioning set.
713      */
714     g_object_class_install_property (gobject_class, PROP_POSITION_SET,
715             g_param_spec_boolean ("position-set",
716                 "position inconsistent state",
717                 "Whether the position"
718                 " is inconsistent", FALSE,
719                 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
720
721     /**
722      * HildonFontSelectionDialog:font-scaling:
723      *
724      * The font scaling factor applied to the preview dialog.
725      */
726     g_object_class_install_property (gobject_class, PROP_FONT_SCALING,
727             g_param_spec_double ("font-scaling",
728                 "Font scaling",
729                 "Font scaling for the preview dialog",
730                 0, 10, 1,
731                 G_PARAM_READWRITE));
732
733     /**
734      * HildonFontSelectionDialog:preview-text:
735      *
736      * The text used for the preview dialog.
737      */
738     g_object_class_install_property (gobject_class, PROP_PREVIEW_TEXT,
739             g_param_spec_string("preview-text",
740                 "Preview Text", 
741                 "the text in preview dialog, which does" 
742                 "not include the reference text",
743                 "",
744                 G_PARAM_READWRITE));
745
746     g_type_class_add_private (klass, 
747             sizeof (struct _HildonFontSelectionDialogPrivate));
748 }
749
750 static void 
751 hildon_font_selection_dialog_init               (HildonFontSelectionDialog *fontseldiag)
752 {
753     HildonFontSelectionDialogPrivate *priv = HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE (fontseldiag);
754     GtkWidget *preview_button;
755
756     g_assert (priv);
757     priv->notebook = GTK_NOTEBOOK (gtk_notebook_new ());
758
759     hildon_font_selection_dialog_construct_notebook (fontseldiag);
760
761     gtk_box_pack_start (GTK_BOX (GTK_DIALOG (fontseldiag)->vbox),
762             GTK_WIDGET (priv->notebook), TRUE, TRUE, 0);
763
764     /* Add dialog buttons */
765     gtk_dialog_add_button (GTK_DIALOG (fontseldiag),
766             _("ecdg_bd_font_dialog_ok"),
767             GTK_RESPONSE_OK);
768
769     preview_button = gtk_button_new_with_label (_("ecdg_bd_font_dialog_preview"));
770     gtk_box_pack_start (GTK_BOX(GTK_DIALOG (fontseldiag)->action_area), 
771             preview_button, FALSE, TRUE, 0);
772
773     g_signal_connect_swapped (preview_button, "clicked",
774             G_CALLBACK
775             (hildon_font_selection_dialog_show_preview),
776             fontseldiag);
777     gtk_widget_show(preview_button);
778
779     gtk_dialog_add_button (GTK_DIALOG (fontseldiag),
780             _("ecdg_bd_font_dialog_cancel"),
781             GTK_RESPONSE_CANCEL);
782
783     /*Set default preview text*/
784     priv->preview_text = g_strdup (_("ecdg_fi_preview_font_preview_text"));
785
786     gtk_window_set_title (GTK_WINDOW (fontseldiag), _("ecdg_ti_font"));
787     /*here is the line to make sure that notebook has the default focus*/
788     gtk_container_set_focus_child (GTK_CONTAINER (GTK_DIALOG (fontseldiag)->vbox),
789             GTK_WIDGET (priv->notebook));
790 }
791
792 static void 
793 hildon_font_selection_dialog_construct_notebook (HildonFontSelectionDialog *fontsel)
794 {
795     gint i;
796     GtkWidget *vbox_tab[3];
797     GtkWidget *font_color_box;
798     GtkWidget *caption_control;
799     GtkSizeGroup *group;
800
801     HildonFontSelectionDialogPrivate *priv = HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE (fontsel);
802     g_assert (priv);
803
804     for (i = 0; i < 3; i++)
805         vbox_tab[i] = gtk_vbox_new (TRUE, 0);
806
807     group = GTK_SIZE_GROUP (gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL));
808
809     /* Build the first page of the GtkNotebook: font style */
810     priv->cbx_font_type = gtk_combo_box_new_text ();
811     hildon_font_selection_dialog_show_available_fonts (fontsel);
812     caption_control = hildon_caption_new (group,
813             _("ecdg_fi_font_font"),
814             priv->cbx_font_type,
815             NULL,
816             HILDON_CAPTION_OPTIONAL);
817
818     gtk_box_pack_start (GTK_BOX (vbox_tab[0]), caption_control, FALSE, FALSE, 0);
819
820     priv->cbx_font_size = gtk_combo_box_new_text ();
821     hildon_font_selection_dialog_show_available_sizes (priv);
822     caption_control = hildon_caption_new (group,
823             _("ecdg_fi_font_size"),
824             priv->cbx_font_size,
825             NULL,
826             HILDON_CAPTION_OPTIONAL);
827
828     gtk_box_pack_start (GTK_BOX (vbox_tab[0]), caption_control, FALSE, FALSE, 0);
829
830     font_color_box = gtk_hbox_new (FALSE, 0);
831     priv->font_color_button = hildon_color_button_new ();
832     priv->color_set = FALSE;
833     priv->font_scaling = 1.0;
834     priv->color_modified_signal_handler = 
835         g_signal_connect (G_OBJECT (priv->font_color_button), "notify::color",
836                 G_CALLBACK (color_modified_cb), (gpointer) priv);
837
838     gtk_box_pack_start (GTK_BOX (font_color_box), priv->font_color_button, FALSE, FALSE, 0);
839
840     caption_control =
841         hildon_caption_new (group, _("ecdg_fi_font_colour_selector"),
842                 font_color_box,
843                 NULL, HILDON_CAPTION_OPTIONAL);
844
845     gtk_box_pack_start (GTK_BOX (vbox_tab[0]), caption_control, FALSE, FALSE, 0);
846
847     /* Build the second page of the GtkNotebook: font formatting */ 
848     priv->chk_bold = gtk_check_button_new ();
849     caption_control = hildon_caption_new (group,
850             _("ecdg_fi_font_bold"),
851             priv->chk_bold,
852             NULL,
853             HILDON_CAPTION_OPTIONAL);
854
855     gtk_box_pack_start (GTK_BOX (vbox_tab[1]), caption_control, FALSE, FALSE, 0);
856     g_signal_connect (G_OBJECT (priv->chk_bold), "clicked", 
857             G_CALLBACK(toggle_clicked), NULL);
858
859     priv->chk_italic = gtk_check_button_new ();
860     caption_control = hildon_caption_new (group, _("ecdg_fi_font_italic"),
861                 priv->chk_italic,
862                 NULL, HILDON_CAPTION_OPTIONAL);
863
864     gtk_box_pack_start (GTK_BOX (vbox_tab[1]), caption_control, FALSE, FALSE, 0);
865     g_signal_connect(G_OBJECT(priv->chk_italic), "clicked", 
866             G_CALLBACK(toggle_clicked), NULL);
867
868     priv->chk_underline = gtk_check_button_new();
869     caption_control =
870         hildon_caption_new (group, _("ecdg_fi_font_underline"),
871                 priv->chk_underline, NULL,
872                 HILDON_CAPTION_OPTIONAL);
873
874     gtk_box_pack_start (GTK_BOX (vbox_tab[1]), caption_control, FALSE, FALSE, 0);
875     g_signal_connect (G_OBJECT(priv->chk_underline), "clicked", 
876             G_CALLBACK (toggle_clicked), NULL);
877
878     /* Build the third page of the GtkNotebook: other font properties */
879     priv->chk_strikethrough = gtk_check_button_new ();
880     caption_control = hildon_caption_new(group, _("ecdg_fi_font_strikethrough"),
881                 priv->chk_strikethrough, NULL,
882                 HILDON_CAPTION_OPTIONAL);
883
884     gtk_box_pack_start (GTK_BOX (vbox_tab[2]), caption_control, FALSE, FALSE, 0);
885     g_signal_connect (G_OBJECT(priv->chk_strikethrough), "clicked", 
886             G_CALLBACK (toggle_clicked), NULL);
887
888     priv->cbx_positioning = gtk_combo_box_new_text ();
889     hildon_font_selection_dialog_show_available_positionings (priv);
890     caption_control =
891         hildon_caption_new(group, _("ecdg_fi_font_special"),
892                 priv->cbx_positioning, NULL,
893                 HILDON_CAPTION_OPTIONAL);
894
895     gtk_box_pack_start (GTK_BOX (vbox_tab[2]), caption_control, FALSE, FALSE, 0);
896
897     /* Populate notebook */
898     gtk_notebook_insert_page (priv->notebook, vbox_tab[0], NULL, 0);
899     gtk_notebook_insert_page (priv->notebook, vbox_tab[1], NULL, 1);
900     gtk_notebook_insert_page (priv->notebook, vbox_tab[2], NULL, 2);
901
902     gtk_notebook_set_tab_label_text (priv->notebook, vbox_tab[0],
903             _("ecdg_ti_font_dialog_style"));
904     gtk_notebook_set_tab_label_text (priv->notebook, vbox_tab[1],
905             _("ecdg_ti_font_dialog_format"));
906     gtk_notebook_set_tab_label_text (priv->notebook, vbox_tab[2],
907             _("ecdg_ti_font_dialog_other"));
908
909     gtk_widget_show_all (GTK_WIDGET (priv->notebook));
910 }
911
912 static void 
913 color_modified_cb                               (HildonColorButton *button, 
914                                                  GParamSpec *pspec, 
915                                                  gpointer fsd_priv)
916 {
917     HildonFontSelectionDialogPrivate *priv = (HildonFontSelectionDialogPrivate *) fsd_priv;
918     g_assert (priv);
919
920     priv->color_set = TRUE;
921 }
922
923 static void 
924 hildon_font_selection_dialog_finalize           (GObject *object)
925 {
926     HildonFontSelectionDialogPrivate *priv;
927     HildonFontSelectionDialog *fontsel;
928
929     g_assert (HILDON_IS_FONT_SELECTION_DIALOG (object));
930     fontsel = HILDON_FONT_SELECTION_DIALOG (object);
931
932     priv = HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE (fontsel);
933     g_assert (priv);
934
935     if (priv->preview_text != NULL) {
936         g_free (priv->preview_text);
937         priv->preview_text = NULL;
938     }
939
940     if (priv->families != NULL) {
941         g_free (priv->families);
942         priv->families = NULL;
943     }
944
945     if (G_OBJECT_CLASS (parent_class)->finalize)
946         G_OBJECT_CLASS (parent_class)->finalize (object);
947 }
948
949 static int 
950 cmp_families                                    (const void *a, 
951                                                  const void *b)
952 {
953     const char *a_name =
954         pango_font_family_get_name (* (PangoFontFamily **) a);
955
956     const char *b_name =
957         pango_font_family_get_name (* (PangoFontFamily **) b);
958
959     return g_utf8_collate (a_name, b_name);
960 }
961
962 /* Exits the preview dialog with GTK_RESPONSE_CANCEL if Esc key
963  * was pressed 
964  * FIXME This should be handled automatically */
965 static gboolean
966 hildon_font_selection_dialog_preview_key_press  (GtkWidget *widget,
967                                                  GdkEventKey *event,
968                                                  gpointer unused)
969 {
970     g_assert (widget);
971     g_assert (event);
972
973     if (event->keyval == GDK_Escape)
974     {
975         gtk_dialog_response (GTK_DIALOG (widget), GTK_RESPONSE_CANCEL);
976         return TRUE;
977     }
978
979     return FALSE;
980 }
981
982 static void
983 add_preview_text_attr                           (PangoAttrList *list, 
984                                                  PangoAttribute *attr, 
985                                                  guint start, 
986                                                  guint len)
987 {
988     attr->start_index = start;
989     attr->end_index = start + len;
990     pango_attr_list_insert (list, attr);
991 }
992
993 static PangoAttrList*
994 hildon_font_selection_dialog_create_attrlist    (HildonFontSelectionDialog *fontsel, 
995                                                  guint start_index, 
996                                                  guint len)
997 {
998     PangoAttrList *list;
999     PangoAttribute *attr;
1000     gint size, position;
1001     gboolean family_set, size_set, color_set, bold, bold_set,
1002              italic, italic_set, underline, underline_set,
1003              strikethrough, strikethrough_set, position_set;
1004     GdkColor *color = NULL;
1005     gchar *family = NULL;
1006     gdouble font_scaling = 1.0;
1007
1008     list = pango_attr_list_new ();
1009
1010     g_object_get (G_OBJECT (fontsel),
1011             "family", &family, "family-set", &family_set,
1012             "size", &size, "size-set", &size_set,
1013             "color", &color, "color-set", &color_set,
1014             "bold", &bold, "bold-set", &bold_set,
1015             "italic", &italic, "italic-set", &italic_set,
1016             "underline", &underline, "underline-set", &underline_set,
1017             "strikethrough", &strikethrough, "strikethrough-set", 
1018             &strikethrough_set, "position", &position, 
1019             "position-set", &position_set, 
1020             "font-scaling", &font_scaling,
1021             NULL);
1022
1023     /* family */
1024     if (family_set)
1025     {
1026         attr = pango_attr_family_new (family);
1027         add_preview_text_attr (list, attr, start_index, len);
1028     }
1029     g_free (family);
1030
1031     /* size */
1032     if (size_set)
1033     {
1034         attr = pango_attr_size_new (size * PANGO_SCALE);
1035         add_preview_text_attr (list, attr, start_index, len);
1036     }
1037
1038     /*color*/
1039     if (color_set)
1040     {
1041         attr = pango_attr_foreground_new (color->red, color->green, color->blue);
1042         add_preview_text_attr (list, attr, start_index, len);
1043     }
1044
1045     if (color != NULL)
1046         gdk_color_free (color);
1047
1048     /*weight*/
1049     if (bold_set)
1050     {
1051         if (bold)
1052             attr = pango_attr_weight_new (PANGO_WEIGHT_BOLD);
1053         else
1054             attr = pango_attr_weight_new (PANGO_WEIGHT_NORMAL);
1055
1056         add_preview_text_attr(list, attr, start_index, len);
1057     }
1058
1059     /* style */
1060     if (italic_set)
1061     {
1062         if (italic)
1063             attr = pango_attr_style_new (PANGO_STYLE_ITALIC);
1064         else
1065             attr = pango_attr_style_new (PANGO_STYLE_NORMAL);
1066
1067         add_preview_text_attr(list, attr, start_index, len);
1068     }
1069
1070     /* underline */
1071     if (underline_set)
1072     {
1073         if (underline)
1074             attr = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE);
1075         else
1076             attr = pango_attr_underline_new (PANGO_UNDERLINE_NONE);
1077
1078         add_preview_text_attr(list, attr, start_index, len);
1079     }
1080
1081     /* strikethrough */
1082     if (strikethrough_set)
1083     {
1084         if (strikethrough)
1085             attr = pango_attr_strikethrough_new (TRUE);
1086         else
1087             attr = pango_attr_strikethrough_new (FALSE);
1088
1089         add_preview_text_attr(list, attr, start_index, len);
1090     }
1091
1092     /* position */
1093     if (position_set)
1094     {
1095         switch (position)
1096         {
1097             case 1: /*super*/
1098                 attr = pango_attr_rise_new (SUPERSCRIPT_RISE);
1099                 break;
1100             case -1: /*sub*/
1101                 attr = pango_attr_rise_new (SUBSCRIPT_LOW);
1102                 break;
1103             default: /*normal*/
1104                 attr = pango_attr_rise_new (0);
1105                 break;
1106         }
1107
1108         add_preview_text_attr (list, attr, start_index, len);
1109     }
1110
1111     /* font scaling for preview */
1112     if (font_scaling)
1113     {
1114         attr = pango_attr_scale_new(font_scaling);
1115         add_preview_text_attr(list, attr, 0, len + start_index);
1116     }
1117
1118     return list;
1119 }
1120
1121 static void
1122 hildon_font_selection_dialog_show_preview       (HildonFontSelectionDialog *fontsel)
1123 {
1124     HildonFontSelectionDialogPrivate *priv = HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE (fontsel);
1125     gint size;
1126     gboolean family_set, size_set;
1127     PangoAttribute *attr;
1128     PangoAttrList *list;
1129     GtkWidget *preview_dialog;
1130     GtkWidget *preview_label;
1131     gchar *str = NULL;
1132     gboolean position_set = FALSE;
1133     gint position = 0;
1134     gboolean show_ref = FALSE;
1135
1136     g_assert (priv);
1137
1138     g_object_get (G_OBJECT (fontsel), "position-set", &position_set, NULL);
1139
1140     if (position_set) {
1141         g_object_get (G_OBJECT (fontsel), "position", &position, NULL);
1142         if (position == 1 || position == -1)
1143             show_ref = TRUE;
1144     }
1145
1146     /* preview dialog init */
1147     preview_dialog =
1148         gtk_dialog_new_with_buttons (_("ecdg_ti_preview_font"), NULL,
1149                 GTK_DIALOG_MODAL |
1150                 GTK_DIALOG_DESTROY_WITH_PARENT |
1151                 GTK_DIALOG_NO_SEPARATOR,
1152                 _("ecdg_bd_font_dialog_ok"),
1153                 GTK_RESPONSE_ACCEPT,
1154                 NULL);
1155
1156     str = (show_ref) ? g_strconcat (_("ecdg_fi_preview_font_preview_reference"), priv->preview_text, 0) :
1157         g_strdup (priv->preview_text);
1158
1159     preview_label = gtk_label_new (str);
1160     gtk_label_set_line_wrap (GTK_LABEL(preview_label), TRUE);
1161
1162     if (str) 
1163         g_free (str);
1164
1165     str = NULL;
1166
1167     gtk_container_add (GTK_CONTAINER (GTK_DIALOG(preview_dialog)->vbox),
1168             preview_label);
1169
1170
1171     /* set keypress handler (ESC hardkey) */
1172     g_signal_connect (G_OBJECT (preview_dialog), "key-press-event",
1173             G_CALLBACK(hildon_font_selection_dialog_preview_key_press),
1174             NULL);
1175
1176     /* Set the font */
1177     list = (show_ref) ? hildon_font_selection_dialog_create_attrlist (fontsel, 
1178             strlen (_("ecdg_fi_preview_font_preview_reference")),
1179             strlen (priv->preview_text)) :
1180         hildon_font_selection_dialog_create_attrlist (fontsel, 0, strlen(priv->preview_text));
1181
1182     g_object_get (G_OBJECT (fontsel), "family", &str, "family-set",
1183             &family_set, "size", &size, "size-set", &size_set,
1184             NULL);
1185
1186     /* FIXME: This is a slightly ugly hack to force the width of the window so that
1187      * the whole text fits with various font sizes. It's being done in such a way, 
1188      * because of some GtkLabel wrapping issues and other mysterious bugs related to 
1189      * truncating ellipsizing. Needs a rethink in future */
1190
1191     gint dialog_width = (size_set && size > 24) ? 600 : 500; 
1192     gtk_window_set_default_size (GTK_WINDOW (preview_dialog), dialog_width, -1);
1193
1194     /* make reference text to have the same fontface and size */
1195     if (family_set)
1196     {
1197         attr = pango_attr_family_new (str);
1198         add_preview_text_attr (list, attr, 0, strlen (_("ecdg_fi_preview_font_preview_reference")));
1199     }
1200     if (str != NULL)
1201         g_free (str);
1202
1203     str = NULL;
1204
1205     /* size */
1206     if (size_set)
1207     {
1208         attr = pango_attr_size_new (size * PANGO_SCALE);
1209         add_preview_text_attr (list, attr, 0, strlen (_("ecdg_fi_preview_font_preview_reference")));
1210     }
1211
1212     gtk_label_set_attributes (GTK_LABEL (preview_label), list);
1213     pango_attr_list_unref (list);
1214
1215     /*And show the dialog*/
1216     gtk_window_set_transient_for (GTK_WINDOW (preview_dialog), 
1217             GTK_WINDOW (fontsel));
1218
1219     gtk_widget_show_all (preview_dialog);
1220     gtk_dialog_run (GTK_DIALOG (preview_dialog));
1221     gtk_widget_destroy (preview_dialog);
1222 }
1223
1224 static gboolean 
1225 is_internal_font                                (const gchar * name)
1226 {
1227     /* FIXME Extremally BAD BAD BAD way of doing things */
1228
1229     return strcmp(name, "DeviceSymbols") == 0
1230         || strcmp(name, "Nokia Smiley" ) == 0
1231         || strcmp(name, "NewCourier" ) == 0
1232         || strcmp(name, "NewTimes" ) == 0
1233         || strcmp(name, "SwissA" ) == 0
1234         || strcmp(name, "Nokia Sans"   ) == 0
1235         || strcmp(name, "Nokia Sans Cn") == 0;
1236 }
1237
1238 static void 
1239 filter_out_internal_fonts                       (PangoFontFamily **families, 
1240                                                  int *n_families)
1241 {
1242     int i;
1243     int n; /* counts valid fonts */
1244     const gchar * name = NULL;
1245
1246     for(i = 0, n = 0; i < * n_families; i++){
1247
1248         name = pango_font_family_get_name (families[i]);
1249
1250         if(!is_internal_font(name))
1251         {
1252
1253             if (i!=n){ /* there are filtered out families */
1254                 families[n] = families[i]; /* shift the current family */
1255             }
1256
1257             n++; /* count one more valid */
1258         }
1259     } /* foreach font family */
1260
1261     *n_families = n;  
1262 }
1263
1264 static void
1265 hildon_font_selection_dialog_show_available_fonts (HildonFontSelectionDialog *fontsel)
1266
1267 {
1268     gint i;
1269
1270     HildonFontSelectionDialogPrivate *priv = HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE (fontsel);
1271     g_assert (priv);
1272
1273     pango_context_list_families (gtk_widget_get_pango_context
1274             (GTK_WIDGET (fontsel)), &priv->families,
1275             &priv->n_families);
1276
1277     filter_out_internal_fonts (priv->families, &priv->n_families);
1278
1279     qsort (priv->families, priv->n_families, sizeof(PangoFontFamily *), cmp_families);
1280
1281     for (i = 0; i < priv->n_families; i++) 
1282     {
1283         const gchar *name = pango_font_family_get_name (priv->families[i]);
1284         gtk_combo_box_append_text (GTK_COMBO_BOX (priv->cbx_font_type), name);
1285     }
1286 }
1287
1288 static void
1289 hildon_font_selection_dialog_show_available_positionings (HildonFontSelectionDialogPrivate *priv)
1290 {
1291     gtk_combo_box_append_text (GTK_COMBO_BOX (priv->cbx_positioning), _("ecdg_va_font_printpos_1"));
1292     gtk_combo_box_append_text (GTK_COMBO_BOX (priv->cbx_positioning), _("ecdg_va_font_printpos_2"));
1293     gtk_combo_box_append_text (GTK_COMBO_BOX (priv->cbx_positioning), _("ecdg_va_font_printpos_3"));
1294 }
1295
1296 /* Loads the sizes from a pre-allocated table */
1297 static void
1298 hildon_font_selection_dialog_show_available_sizes (HildonFontSelectionDialogPrivate *priv)
1299 {
1300     gchar *size_str;
1301     gint i;
1302
1303     g_assert (priv);
1304
1305     for (i = 0; i < G_N_ELEMENTS (font_sizes); i++) 
1306     {
1307         size_str = g_strdup_printf ("%i%s",
1308                 font_sizes[i],
1309                 _("ecdg_va_font_size_trailer"));
1310
1311         gtk_combo_box_append_text (GTK_COMBO_BOX (priv->cbx_font_size), size_str);
1312         g_free (size_str);
1313     }
1314 }
1315
1316 static void
1317 toggle_clicked                                  (GtkButton *button, 
1318                                                  gpointer unused)
1319 {
1320     GtkToggleButton *t_b = GTK_TOGGLE_BUTTON (button);
1321
1322     /* we have to remove the inconsistent state ourselves */
1323     if (gtk_toggle_button_get_inconsistent (t_b))
1324     {
1325         gtk_toggle_button_set_inconsistent (t_b, FALSE);
1326         gtk_toggle_button_set_active (t_b, FALSE);
1327     }
1328 }
1329
1330 /**
1331  * hildon_font_selection_dialog_new:
1332  * @parent: the parent window
1333  * @title: the title of font selection dialog
1334  *
1335  * If NULL is passed for title, then default title
1336  * "Font" will be used.
1337  *
1338  * Returns: a new #HildonFontSelectionDialog
1339  */
1340 GtkWidget*
1341 hildon_font_selection_dialog_new                (GtkWindow *parent,
1342                                                  const gchar *title)
1343 {
1344     HildonFontSelectionDialog *fontseldiag;
1345
1346     fontseldiag = g_object_new (HILDON_TYPE_FONT_SELECTION_DIALOG,
1347             "has-separator", FALSE, NULL);
1348
1349     if (title)
1350         gtk_window_set_title (GTK_WINDOW (fontseldiag), title);
1351
1352     if (parent)
1353         gtk_window_set_transient_for (GTK_WINDOW (fontseldiag), parent);
1354
1355     return GTK_WIDGET (fontseldiag);
1356 }
1357
1358 /**
1359  * hildon_font_selection_dialog_get_preview_text:
1360  * @fsd: the font selection dialog
1361  *
1362  * Gets the text in preview dialog, which does not include the 
1363  * reference text. The returned string must be freed by the user.
1364  *
1365  * Returns: a string pointer
1366  */
1367 gchar*
1368 hildon_font_selection_dialog_get_preview_text   (HildonFontSelectionDialog * fsd)
1369 {
1370     /* FIXME Return a const pointer? */
1371     HildonFontSelectionDialogPrivate *priv;
1372
1373     g_return_val_if_fail (HILDON_IS_FONT_SELECTION_DIALOG (fsd), FALSE);
1374         
1375     priv = HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE (fsd);
1376     g_assert (priv);
1377
1378     return g_strdup (priv->preview_text);
1379 }
1380
1381 /**
1382  * hildon_font_selection_dialog_set_preview_text:
1383  * @fsd: the font selection dialog
1384  * @text: the text to be displayed in the preview dialog
1385  *
1386  * The default preview text is
1387  * "The quick brown fox jumped over the lazy dogs"
1388  */
1389 void
1390 hildon_font_selection_dialog_set_preview_text   (HildonFontSelectionDialog *fsd, 
1391                                                  const gchar * text)
1392 {
1393     HildonFontSelectionDialogPrivate *priv = NULL;
1394
1395     g_return_if_fail (HILDON_IS_FONT_SELECTION_DIALOG (fsd));
1396     g_return_if_fail (text);
1397
1398     priv = HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE (fsd);
1399     g_assert (priv);
1400
1401     g_free (priv->preview_text);
1402     priv->preview_text = g_strdup (text);
1403     g_object_notify (G_OBJECT (fsd), "preview-text");
1404 }
1405