Remove HILDON_ENABLE_UNSTABLE_API.
[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;
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             hildon_color_button_get_color
259                 (HILDON_COLOR_BUTTON (priv->font_color_button), &color);
260             g_value_set_boxed (value, (gconstpointer) &color);
261             break;
262
263         case PROP_COLOR_SET:
264             g_value_set_boolean (value, priv->color_set);
265             break;
266
267         case PROP_BOLD:
268             g_value_set_boolean (value, 
269                     gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->chk_bold)));
270             break;
271
272         case PROP_BOLD_SET:
273             g_value_set_boolean (value,
274                     ! gtk_toggle_button_get_inconsistent
275                     (GTK_TOGGLE_BUTTON (priv->chk_bold)));
276             break;
277
278         case PROP_ITALIC:
279             g_value_set_boolean (value, 
280                     gtk_toggle_button_get_active
281                     (GTK_TOGGLE_BUTTON (priv->chk_italic)));
282             break;
283
284         case PROP_ITALIC_SET:
285             g_value_set_boolean (value,
286                     ! gtk_toggle_button_get_inconsistent
287                     (GTK_TOGGLE_BUTTON (priv->chk_italic)));
288             break;
289
290         case PROP_UNDERLINE:
291             g_value_set_boolean (value, 
292                     gtk_toggle_button_get_active
293                     (GTK_TOGGLE_BUTTON (priv->chk_underline)));
294             break;
295
296         case PROP_UNDERLINE_SET:
297             g_value_set_boolean (value,
298                     ! gtk_toggle_button_get_inconsistent
299                     (GTK_TOGGLE_BUTTON (priv->chk_underline)));
300             break;
301
302         case PROP_STRIKETHROUGH:
303             g_value_set_boolean(value, 
304                     gtk_toggle_button_get_active
305                     (GTK_TOGGLE_BUTTON (priv->chk_strikethrough)));
306             break;
307
308         case PROP_STRIKETHROUGH_SET:
309             g_value_set_boolean(value,
310                     ! gtk_toggle_button_get_inconsistent
311                     (GTK_TOGGLE_BUTTON (priv->chk_strikethrough)));
312             break;
313
314         case PROP_POSITION:
315             i = gtk_combo_box_get_active (GTK_COMBO_BOX (priv->cbx_positioning));
316             if(i == 1) /* super */
317                 g_value_set_int (value, 1);
318             else if(i == 2)/* sub */
319                 g_value_set_int (value, -1);
320             else
321                 g_value_set_int (value, 0);
322             break;
323
324         case PROP_FONT_SCALING:
325             g_value_set_double (value, priv->font_scaling);
326             break;
327
328         case PROP_POSITION_SET:
329             i = gtk_combo_box_get_active (GTK_COMBO_BOX (priv->cbx_positioning));
330             if(i >= 0 && i < 3)
331                 g_value_set_boolean (value, TRUE);
332             else
333                 g_value_set_boolean (value, FALSE);
334             break;
335
336         case PROP_PREVIEW_TEXT:
337             g_value_set_string (value,
338                     hildon_font_selection_dialog_get_preview_text (HILDON_FONT_SELECTION_DIALOG (object)));
339             break;
340
341         default:
342             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
343             break;
344     }
345 }
346
347 static void 
348 hildon_font_selection_dialog_set_property       (GObject *object,
349                                                  guint prop_id,
350                                                  const GValue *value,
351                                                  GParamSpec *pspec)
352 {
353     gint i, size;
354     const gchar *str;
355     gboolean b;
356     GdkColor *color = NULL;
357     GdkColor black;
358
359     HildonFontSelectionDialogPrivate *priv = HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE (object);
360     g_assert (priv);
361
362     black.red = black.green = black.blue = 0;
363
364     switch (prop_id)
365     {
366         case PROP_FAMILY:
367             str = g_value_get_string (value);
368             for(i = 0; i < priv->n_families; i++)
369             {
370                 if (strcmp (str, pango_font_family_get_name (priv->families[i]))
371                         == 0)
372                 {
373                     gtk_combo_box_set_active (GTK_COMBO_BOX (priv->cbx_font_type), i);
374                     break;
375                 }
376             }
377             break;
378
379         case PROP_FAMILY_SET:
380             b = g_value_get_boolean (value);
381             if(!b)
382                 gtk_combo_box_set_active (GTK_COMBO_BOX (priv->cbx_font_type), -1);
383             break;
384
385         case PROP_SIZE:
386             size = g_value_get_int (value);
387             for(i = 0; i < G_N_ELEMENTS (font_sizes); i++)
388             {
389                 if(size == font_sizes[i])
390                 {
391                     gtk_combo_box_set_active (GTK_COMBO_BOX (priv->cbx_font_size), i);
392                     break;
393                 }
394             }
395             break;
396
397         case PROP_SIZE_SET:
398             b = g_value_get_boolean (value);
399             if(!b)
400                 gtk_combo_box_set_active (GTK_COMBO_BOX (priv->cbx_font_size), -1);
401             break;
402
403         case PROP_COLOR:
404             color = (GdkColor *) g_value_get_boxed (value);
405             if(color != NULL)
406                 hildon_color_button_set_color (HILDON_COLOR_BUTTON
407                         (priv->font_color_button),
408                         color);
409             else
410                 hildon_color_button_set_color (HILDON_COLOR_BUTTON
411                         (priv->font_color_button),
412                         &black);
413             break;
414
415         case PROP_COLOR_SET:
416             priv->color_set = g_value_get_boolean (value);
417             if(! priv->color_set)
418             {
419                 /* set color to black, but block our signal handler */
420                 g_signal_handler_block ((gpointer) priv->font_color_button,
421                         priv->color_modified_signal_handler);
422
423                 hildon_color_button_set_color (HILDON_COLOR_BUTTON
424                         (priv->font_color_button), 
425                         &black);
426
427                 g_signal_handler_unblock ((gpointer) priv->font_color_button,
428                         priv->color_modified_signal_handler);
429             }
430             break;
431
432         case PROP_BOLD:
433             /* this call will make sure that we dont get extra clicked signal */
434             gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON(priv->chk_bold), FALSE);
435             gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(priv->chk_bold), g_value_get_boolean (value));
436             break;
437
438         case PROP_BOLD_SET:
439             gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (priv->chk_bold),! g_value_get_boolean(value));
440             break;
441
442         case PROP_ITALIC:
443             gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(priv->chk_italic),
444                     FALSE);
445             gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->chk_italic),
446                     g_value_get_boolean(value));
447             break;
448
449         case PROP_ITALIC_SET:
450             gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(priv->chk_italic),
451                     !g_value_get_boolean(value));
452             break;
453
454         case PROP_UNDERLINE:
455             gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON
456                     (priv->chk_underline),
457                     FALSE);
458             gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->chk_underline),
459                     g_value_get_boolean(value));
460             break;
461
462         case PROP_UNDERLINE_SET:
463             gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(priv->chk_underline),
464                     !g_value_get_boolean(value));
465             break;
466
467         case PROP_STRIKETHROUGH:
468             gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON
469                     (priv->chk_strikethrough),
470                     FALSE);
471             gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->chk_strikethrough),
472                     g_value_get_boolean(value));
473             break;
474
475         case PROP_STRIKETHROUGH_SET:
476             gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON
477                     (priv->chk_strikethrough),
478                     !g_value_get_boolean(value));
479             break;
480
481         case PROP_POSITION:
482             i = g_value_get_int(value);
483             if( i == 1 )
484                 gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_positioning), 1);
485             else if(i == -1)
486                 gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_positioning), 2);
487             else
488                 gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_positioning), 0);
489             break;
490
491         case PROP_FONT_SCALING:
492             priv->font_scaling = g_value_get_double(value);
493             break;
494
495         case PROP_POSITION_SET:
496             b = g_value_get_boolean(value);
497             if(!b)
498                 gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_positioning), -1);
499             break;
500
501         case PROP_PREVIEW_TEXT:
502             hildon_font_selection_dialog_set_preview_text(
503                     HILDON_FONT_SELECTION_DIALOG(object),
504                     g_value_get_string(value));
505             break;
506
507         default:
508             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
509             break;
510     }
511 }
512
513 static void
514 hildon_font_selection_dialog_class_init         (HildonFontSelectionDialogClass *klass)
515 {
516     GObjectClass *gobject_class;
517
518     parent_class = g_type_class_peek_parent (klass);
519     gobject_class = G_OBJECT_CLASS (klass);
520
521     gobject_class->finalize         = hildon_font_selection_dialog_finalize;
522     gobject_class->get_property     = hildon_font_selection_dialog_get_property;
523     gobject_class->set_property     = hildon_font_selection_dialog_set_property;
524
525     /* Install properties to the class */
526
527     /**
528      * HildonFontSelectionDialog:family:
529      *
530      * Font family used.
531      */
532     g_object_class_install_property (gobject_class, PROP_FAMILY,
533             g_param_spec_string ("family",
534                 "Font family", "String defines"
535                 " the font family", "Sans",
536                 G_PARAM_READWRITE));
537
538     /**
539      * HildonFontSelectionDialog:family-set:
540      *
541      * Is font family set or inconsistent.
542      */
543     g_object_class_install_property (gobject_class, PROP_FAMILY_SET,
544             g_param_spec_boolean ("family-set",
545                 "family inconsistent state",
546                 "Whether the family property"
547                 " is inconsistent", FALSE,
548                 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
549
550     /**
551      * HildonFontSelectionDialog:size:
552      *
553      * Font size.
554      */
555     g_object_class_install_property (gobject_class, PROP_SIZE,
556             g_param_spec_int ("size",
557                 "Font size",
558                 "Font size in Pt",
559                 6, 32, 16,
560                 G_PARAM_READWRITE));
561
562     /**
563      * HildonFontSelectionDialog:size-set:
564      *
565      * Is font size set or inconsistent.
566      */
567     g_object_class_install_property (gobject_class, PROP_SIZE_SET,
568             g_param_spec_boolean ("size-set",
569                 "size inconsistent state",
570                 "Whether the size property"
571                 " is inconsistent", FALSE,
572                 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
573
574     /**
575      * HildonFontSelectionDialog:color:
576      *
577      * GdkColor for the text.
578      */
579     g_object_class_install_property (gobject_class, PROP_COLOR,
580             g_param_spec_boxed ("color",
581                 "text color",
582                 "gdk color for the text",
583                 GDK_TYPE_COLOR,
584                 G_PARAM_READWRITE));
585
586     /**
587      * HildonFontSelectionDialog:color-set:
588      *
589      * Is font color set or inconsistent.
590      */
591     g_object_class_install_property (gobject_class, PROP_COLOR_SET,
592             g_param_spec_boolean ("color-set",
593                 "color inconsistent state",
594                 "Whether the color property"
595                 " is inconsistent", FALSE,
596                 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
597
598     /**
599      * HildonFontSelectionDialog:color-set:
600      *
601      * Is font set as bold.
602      */
603     g_object_class_install_property (gobject_class, PROP_BOLD,
604             g_param_spec_boolean ("bold",
605                 "text weight",
606                 "Whether the text is bold",
607                 FALSE,
608                 G_PARAM_READWRITE));
609
610     /**
611      * HildonFontSelectionDialog:color-set:
612      *
613      * Is font bold status set or inconsistent.
614      */
615     g_object_class_install_property (gobject_class, PROP_BOLD_SET,
616             g_param_spec_boolean ("bold-set",
617                 "bold inconsistent state",
618                 "Whether the bold"
619                 " is inconsistent", FALSE,
620                 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
621
622     /**
623      * HildonFontSelectionDialog:italic:
624      *
625      * Is font set as italic.
626      */
627     g_object_class_install_property (gobject_class, PROP_ITALIC,
628             g_param_spec_boolean ("italic",
629                 "text style",
630                 "Whether the text is italic",
631                 FALSE,
632                 G_PARAM_READWRITE));
633
634     /**
635      * HildonFontSelectionDialog:italic-set:
636      *
637      * Is font italic status set or inconsistent.
638      */
639     g_object_class_install_property (gobject_class, PROP_ITALIC_SET,
640             g_param_spec_boolean ("italic-set",
641                 "italic inconsistent state",
642                 "Whether the italic"
643                 " is inconsistent", FALSE,
644                 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
645
646     /**
647      * HildonFontSelectionDialog:underline:
648      *
649      * Is the font underlined.
650      */
651     g_object_class_install_property (gobject_class, PROP_UNDERLINE,
652             g_param_spec_boolean ("underline",
653                 "text underline",
654                 "Whether the text is underlined",
655                 FALSE,
656                 G_PARAM_READWRITE));
657
658     /**
659      * HildonFontSelectionDialog:underline:
660      *
661      * Is font underline status set or inconsistent.
662      */
663     g_object_class_install_property (gobject_class, PROP_UNDERLINE_SET,
664             g_param_spec_boolean ("underline-set",
665                 "underline inconsistent state",
666                 "Whether the underline"
667                 " is inconsistent", FALSE,
668                 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
669
670     /**
671      * HildonFontSelectionDialog:strikethrough:
672      *
673      * Is the font striken-through.
674      */
675     g_object_class_install_property (gobject_class, PROP_STRIKETHROUGH,
676             g_param_spec_boolean ("strikethrough",
677                 "strikethroughed text",
678                 "Whether the text is strikethroughed",
679                 FALSE,
680                 G_PARAM_READWRITE));
681
682     /**
683      * HildonFontSelectionDialog:strikethrough-set:
684      *
685      * Is the font strikenthrough status set.
686      */
687     g_object_class_install_property (gobject_class, PROP_STRIKETHROUGH_SET,
688             g_param_spec_boolean ("strikethrough-set",
689                 "strikethrough inconsistent state",
690                 "Whether the strikethrough"
691                 " is inconsistent", FALSE,
692                 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
693
694     /**
695      * HildonFontSelectionDialog:position:
696      *
697      * The font positioning versus baseline.
698      */
699     g_object_class_install_property (gobject_class, PROP_POSITION,
700             g_param_spec_int ("position",
701                 "Font position",
702                 "Font position super or subscript",
703                 -1, 1, 0,
704                 G_PARAM_READWRITE));
705
706     /**
707      * HildonFontSelectionDialog:position-set:
708      *
709      * Is the font positioning set.
710      */
711     g_object_class_install_property (gobject_class, PROP_POSITION_SET,
712             g_param_spec_boolean ("position-set",
713                 "position inconsistent state",
714                 "Whether the position"
715                 " is inconsistent", FALSE,
716                 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
717
718     /**
719      * HildonFontSelectionDialog:font-scaling:
720      *
721      * The font scaling factor applied to the preview dialog.
722      */
723     g_object_class_install_property (gobject_class, PROP_FONT_SCALING,
724             g_param_spec_double ("font-scaling",
725                 "Font scaling",
726                 "Font scaling for the preview dialog",
727                 0, 10, 1,
728                 G_PARAM_READWRITE));
729
730     /**
731      * HildonFontSelectionDialog:preview-text:
732      *
733      * The text used for the preview dialog.
734      */
735     g_object_class_install_property (gobject_class, PROP_PREVIEW_TEXT,
736             g_param_spec_string("preview-text",
737                 "Preview Text", 
738                 "the text in preview dialog, which does" 
739                 "not include the reference text",
740                 "",
741                 G_PARAM_READWRITE));
742
743     g_type_class_add_private (klass, 
744             sizeof (struct _HildonFontSelectionDialogPrivate));
745 }
746
747 static void 
748 hildon_font_selection_dialog_init               (HildonFontSelectionDialog *fontseldiag)
749 {
750     HildonFontSelectionDialogPrivate *priv = HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE (fontseldiag);
751     GtkWidget *preview_button;
752
753     g_assert (priv);
754     priv->notebook = GTK_NOTEBOOK (gtk_notebook_new ());
755
756     hildon_font_selection_dialog_construct_notebook (fontseldiag);
757
758     gtk_box_pack_start (GTK_BOX (GTK_DIALOG (fontseldiag)->vbox),
759             GTK_WIDGET (priv->notebook), TRUE, TRUE, 0);
760
761     /* Add dialog buttons */
762     gtk_dialog_add_button (GTK_DIALOG (fontseldiag),
763             _("ecdg_bd_font_dialog_ok"),
764             GTK_RESPONSE_OK);
765
766     preview_button = gtk_button_new_with_label (_("ecdg_bd_font_dialog_preview"));
767     gtk_box_pack_start (GTK_BOX(GTK_DIALOG (fontseldiag)->action_area), 
768             preview_button, FALSE, TRUE, 0);
769
770     g_signal_connect_swapped (preview_button, "clicked",
771             G_CALLBACK
772             (hildon_font_selection_dialog_show_preview),
773             fontseldiag);
774     gtk_widget_show(preview_button);
775
776     gtk_dialog_add_button (GTK_DIALOG (fontseldiag),
777             _("ecdg_bd_font_dialog_cancel"),
778             GTK_RESPONSE_CANCEL);
779
780     /*Set default preview text*/
781     priv->preview_text = g_strdup (_("ecdg_fi_preview_font_preview_text"));
782
783     gtk_window_set_title (GTK_WINDOW (fontseldiag), _("ecdg_ti_font"));
784     /*here is the line to make sure that notebook has the default focus*/
785     gtk_container_set_focus_child (GTK_CONTAINER (GTK_DIALOG (fontseldiag)->vbox),
786             GTK_WIDGET (priv->notebook));
787 }
788
789 static void 
790 hildon_font_selection_dialog_construct_notebook (HildonFontSelectionDialog *fontsel)
791 {
792     gint i;
793     GtkWidget *vbox_tab[3];
794     GtkWidget *font_color_box;
795     GtkWidget *caption_control;
796     GtkSizeGroup *group;
797
798     HildonFontSelectionDialogPrivate *priv = HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE (fontsel);
799     g_assert (priv);
800
801     for (i = 0; i < 3; i++)
802         vbox_tab[i] = gtk_vbox_new (TRUE, 0);
803
804     group = GTK_SIZE_GROUP (gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL));
805
806     /* Build the first page of the GtkNotebook: font style */
807     priv->cbx_font_type = gtk_combo_box_new_text ();
808     hildon_font_selection_dialog_show_available_fonts (fontsel);
809     caption_control = hildon_caption_new (group,
810             _("ecdg_fi_font_font"),
811             priv->cbx_font_type,
812             NULL,
813             HILDON_CAPTION_OPTIONAL);
814
815     gtk_box_pack_start (GTK_BOX (vbox_tab[0]), caption_control, FALSE, FALSE, 0);
816
817     priv->cbx_font_size = gtk_combo_box_new_text ();
818     hildon_font_selection_dialog_show_available_sizes (priv);
819     caption_control = hildon_caption_new (group,
820             _("ecdg_fi_font_size"),
821             priv->cbx_font_size,
822             NULL,
823             HILDON_CAPTION_OPTIONAL);
824
825     gtk_box_pack_start (GTK_BOX (vbox_tab[0]), caption_control, FALSE, FALSE, 0);
826
827     font_color_box = gtk_hbox_new (FALSE, 0);
828     priv->font_color_button = hildon_color_button_new ();
829     priv->color_set = FALSE;
830     priv->font_scaling = 1.0;
831     priv->color_modified_signal_handler = 
832         g_signal_connect (G_OBJECT (priv->font_color_button), "notify::color",
833                 G_CALLBACK (color_modified_cb), (gpointer) priv);
834
835     gtk_box_pack_start (GTK_BOX (font_color_box), priv->font_color_button, FALSE, FALSE, 0);
836
837     caption_control =
838         hildon_caption_new (group, _("ecdg_fi_font_colour_selector"),
839                 font_color_box,
840                 NULL, HILDON_CAPTION_OPTIONAL);
841
842     gtk_box_pack_start (GTK_BOX (vbox_tab[0]), caption_control, FALSE, FALSE, 0);
843
844     /* Build the second page of the GtkNotebook: font formatting */ 
845     priv->chk_bold = gtk_check_button_new ();
846     caption_control = hildon_caption_new (group,
847             _("ecdg_fi_font_bold"),
848             priv->chk_bold,
849             NULL,
850             HILDON_CAPTION_OPTIONAL);
851
852     gtk_box_pack_start (GTK_BOX (vbox_tab[1]), caption_control, FALSE, FALSE, 0);
853     g_signal_connect (G_OBJECT (priv->chk_bold), "clicked", 
854             G_CALLBACK(toggle_clicked), NULL);
855
856     priv->chk_italic = gtk_check_button_new ();
857     caption_control = hildon_caption_new (group, _("ecdg_fi_font_italic"),
858                 priv->chk_italic,
859                 NULL, HILDON_CAPTION_OPTIONAL);
860
861     gtk_box_pack_start (GTK_BOX (vbox_tab[1]), caption_control, FALSE, FALSE, 0);
862     g_signal_connect(G_OBJECT(priv->chk_italic), "clicked", 
863             G_CALLBACK(toggle_clicked), NULL);
864
865     priv->chk_underline = gtk_check_button_new();
866     caption_control =
867         hildon_caption_new (group, _("ecdg_fi_font_underline"),
868                 priv->chk_underline, NULL,
869                 HILDON_CAPTION_OPTIONAL);
870
871     gtk_box_pack_start (GTK_BOX (vbox_tab[1]), caption_control, FALSE, FALSE, 0);
872     g_signal_connect (G_OBJECT(priv->chk_underline), "clicked", 
873             G_CALLBACK (toggle_clicked), NULL);
874
875     /* Build the third page of the GtkNotebook: other font properties */
876     priv->chk_strikethrough = gtk_check_button_new ();
877     caption_control = hildon_caption_new(group, _("ecdg_fi_font_strikethrough"),
878                 priv->chk_strikethrough, NULL,
879                 HILDON_CAPTION_OPTIONAL);
880
881     gtk_box_pack_start (GTK_BOX (vbox_tab[2]), caption_control, FALSE, FALSE, 0);
882     g_signal_connect (G_OBJECT(priv->chk_strikethrough), "clicked", 
883             G_CALLBACK (toggle_clicked), NULL);
884
885     priv->cbx_positioning = gtk_combo_box_new_text ();
886     hildon_font_selection_dialog_show_available_positionings (priv);
887     caption_control =
888         hildon_caption_new(group, _("ecdg_fi_font_special"),
889                 priv->cbx_positioning, NULL,
890                 HILDON_CAPTION_OPTIONAL);
891
892     g_object_unref (group);
893
894     gtk_box_pack_start (GTK_BOX (vbox_tab[2]), caption_control, FALSE, FALSE, 0);
895
896     /* Populate notebook */
897     gtk_notebook_insert_page (priv->notebook, vbox_tab[0], NULL, 0);
898     gtk_notebook_insert_page (priv->notebook, vbox_tab[1], NULL, 1);
899     gtk_notebook_insert_page (priv->notebook, vbox_tab[2], NULL, 2);
900
901     gtk_notebook_set_tab_label_text (priv->notebook, vbox_tab[0],
902             _("ecdg_ti_font_dialog_style"));
903     gtk_notebook_set_tab_label_text (priv->notebook, vbox_tab[1],
904             _("ecdg_ti_font_dialog_format"));
905     gtk_notebook_set_tab_label_text (priv->notebook, vbox_tab[2],
906             _("ecdg_ti_font_dialog_other"));
907
908     gtk_widget_show_all (GTK_WIDGET (priv->notebook));
909 }
910
911 static void 
912 color_modified_cb                               (HildonColorButton *button, 
913                                                  GParamSpec *pspec, 
914                                                  gpointer fsd_priv)
915 {
916     HildonFontSelectionDialogPrivate *priv = (HildonFontSelectionDialogPrivate *) fsd_priv;
917     g_assert (priv);
918
919     priv->color_set = TRUE;
920 }
921
922 static void 
923 hildon_font_selection_dialog_finalize           (GObject *object)
924 {
925     HildonFontSelectionDialogPrivate *priv;
926     HildonFontSelectionDialog *fontsel;
927
928     g_assert (HILDON_IS_FONT_SELECTION_DIALOG (object));
929     fontsel = HILDON_FONT_SELECTION_DIALOG (object);
930
931     priv = HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE (fontsel);
932     g_assert (priv);
933
934     if (priv->preview_text != NULL) {
935         g_free (priv->preview_text);
936         priv->preview_text = NULL;
937     }
938
939     if (priv->families != NULL) {
940         g_free (priv->families);
941         priv->families = NULL;
942     }
943
944     if (G_OBJECT_CLASS (parent_class)->finalize)
945         G_OBJECT_CLASS (parent_class)->finalize (object);
946 }
947
948 static int 
949 cmp_families                                    (const void *a, 
950                                                  const void *b)
951 {
952     const char *a_name =
953         pango_font_family_get_name (* (PangoFontFamily **) a);
954
955     const char *b_name =
956         pango_font_family_get_name (* (PangoFontFamily **) b);
957
958     return g_utf8_collate (a_name, b_name);
959 }
960
961 /* Exits the preview dialog with GTK_RESPONSE_CANCEL if Esc key
962  * was pressed 
963  * FIXME This should be handled automatically */
964 static gboolean
965 hildon_font_selection_dialog_preview_key_press  (GtkWidget *widget,
966                                                  GdkEventKey *event,
967                                                  gpointer unused)
968 {
969     g_assert (widget);
970     g_assert (event);
971
972     if (event->keyval == GDK_Escape)
973     {
974         gtk_dialog_response (GTK_DIALOG (widget), GTK_RESPONSE_CANCEL);
975         return TRUE;
976     }
977
978     return FALSE;
979 }
980
981 static void
982 add_preview_text_attr                           (PangoAttrList *list, 
983                                                  PangoAttribute *attr, 
984                                                  guint start, 
985                                                  guint len)
986 {
987     attr->start_index = start;
988     attr->end_index = start + len;
989     pango_attr_list_insert (list, attr);
990 }
991
992 static PangoAttrList*
993 hildon_font_selection_dialog_create_attrlist    (HildonFontSelectionDialog *fontsel, 
994                                                  guint start_index, 
995                                                  guint len)
996 {
997     PangoAttrList *list;
998     PangoAttribute *attr;
999     gint size, position;
1000     gboolean family_set, size_set, color_set, bold, bold_set,
1001              italic, italic_set, underline, underline_set,
1002              strikethrough, strikethrough_set, position_set;
1003     GdkColor *color = NULL;
1004     gchar *family = NULL;
1005     gdouble font_scaling = 1.0;
1006
1007     list = pango_attr_list_new ();
1008
1009     g_object_get (G_OBJECT (fontsel),
1010             "family", &family, "family-set", &family_set,
1011             "size", &size, "size-set", &size_set,
1012             "color", &color, "color-set", &color_set,
1013             "bold", &bold, "bold-set", &bold_set,
1014             "italic", &italic, "italic-set", &italic_set,
1015             "underline", &underline, "underline-set", &underline_set,
1016             "strikethrough", &strikethrough, "strikethrough-set", 
1017             &strikethrough_set, "position", &position, 
1018             "position-set", &position_set, 
1019             "font-scaling", &font_scaling,
1020             NULL);
1021
1022     /* family */
1023     if (family_set)
1024     {
1025         attr = pango_attr_family_new (family);
1026         add_preview_text_attr (list, attr, start_index, len);
1027     }
1028     g_free (family);
1029
1030     /* size */
1031     if (size_set)
1032     {
1033         attr = pango_attr_size_new (size * PANGO_SCALE);
1034         add_preview_text_attr (list, attr, start_index, len);
1035     }
1036
1037     /*color*/
1038     if (color_set)
1039     {
1040         attr = pango_attr_foreground_new (color->red, color->green, color->blue);
1041         add_preview_text_attr (list, attr, start_index, len);
1042     }
1043
1044     if (color != NULL)
1045         gdk_color_free (color);
1046
1047     /*weight*/
1048     if (bold_set)
1049     {
1050         if (bold)
1051             attr = pango_attr_weight_new (PANGO_WEIGHT_BOLD);
1052         else
1053             attr = pango_attr_weight_new (PANGO_WEIGHT_NORMAL);
1054
1055         add_preview_text_attr(list, attr, start_index, len);
1056     }
1057
1058     /* style */
1059     if (italic_set)
1060     {
1061         if (italic)
1062             attr = pango_attr_style_new (PANGO_STYLE_ITALIC);
1063         else
1064             attr = pango_attr_style_new (PANGO_STYLE_NORMAL);
1065
1066         add_preview_text_attr(list, attr, start_index, len);
1067     }
1068
1069     /* underline */
1070     if (underline_set)
1071     {
1072         if (underline)
1073             attr = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE);
1074         else
1075             attr = pango_attr_underline_new (PANGO_UNDERLINE_NONE);
1076
1077         add_preview_text_attr(list, attr, start_index, len);
1078     }
1079
1080     /* strikethrough */
1081     if (strikethrough_set)
1082     {
1083         if (strikethrough)
1084             attr = pango_attr_strikethrough_new (TRUE);
1085         else
1086             attr = pango_attr_strikethrough_new (FALSE);
1087
1088         add_preview_text_attr(list, attr, start_index, len);
1089     }
1090
1091     /* position */
1092     if (position_set)
1093     {
1094         switch (position)
1095         {
1096             case 1: /*super*/
1097                 attr = pango_attr_rise_new (SUPERSCRIPT_RISE);
1098                 break;
1099             case -1: /*sub*/
1100                 attr = pango_attr_rise_new (SUBSCRIPT_LOW);
1101                 break;
1102             default: /*normal*/
1103                 attr = pango_attr_rise_new (0);
1104                 break;
1105         }
1106
1107         add_preview_text_attr (list, attr, start_index, len);
1108     }
1109
1110     /* font scaling for preview */
1111     if (font_scaling)
1112     {
1113         attr = pango_attr_scale_new(font_scaling);
1114         add_preview_text_attr(list, attr, 0, len + start_index);
1115     }
1116
1117     return list;
1118 }
1119
1120 static void
1121 hildon_font_selection_dialog_show_preview       (HildonFontSelectionDialog *fontsel)
1122 {
1123     HildonFontSelectionDialogPrivate *priv = HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE (fontsel);
1124     gint size;
1125     gboolean family_set, size_set;
1126     PangoAttribute *attr;
1127     PangoAttrList *list;
1128     GtkWidget *preview_dialog;
1129     GtkWidget *preview_label;
1130     gchar *str = NULL;
1131     gboolean position_set = FALSE;
1132     gint position = 0;
1133     gboolean show_ref = FALSE;
1134
1135     g_assert (priv);
1136
1137     g_object_get (G_OBJECT (fontsel), "position-set", &position_set, NULL);
1138
1139     if (position_set) {
1140         g_object_get (G_OBJECT (fontsel), "position", &position, NULL);
1141         if (position == 1 || position == -1)
1142             show_ref = TRUE;
1143     }
1144
1145     /* preview dialog init */
1146     preview_dialog =
1147         gtk_dialog_new_with_buttons (_("ecdg_ti_preview_font"), NULL,
1148                 GTK_DIALOG_MODAL |
1149                 GTK_DIALOG_DESTROY_WITH_PARENT |
1150                 GTK_DIALOG_NO_SEPARATOR,
1151                 _("ecdg_bd_font_dialog_ok"),
1152                 GTK_RESPONSE_ACCEPT,
1153                 NULL);
1154
1155     str = (show_ref) ? g_strconcat (_("ecdg_fi_preview_font_preview_reference"), priv->preview_text, 0) :
1156         g_strdup (priv->preview_text);
1157
1158     preview_label = gtk_label_new (str);
1159     gtk_label_set_line_wrap (GTK_LABEL(preview_label), TRUE);
1160
1161     if (str) 
1162         g_free (str);
1163
1164     str = NULL;
1165
1166     /* set keypress handler (ESC hardkey) */
1167     g_signal_connect (G_OBJECT (preview_dialog), "key-press-event",
1168             G_CALLBACK(hildon_font_selection_dialog_preview_key_press),
1169             NULL);
1170
1171     /* Set the font */
1172     list = (show_ref) ? hildon_font_selection_dialog_create_attrlist (fontsel, 
1173             strlen (_("ecdg_fi_preview_font_preview_reference")),
1174             strlen (priv->preview_text)) :
1175         hildon_font_selection_dialog_create_attrlist (fontsel, 0, strlen(priv->preview_text));
1176
1177     g_object_get (G_OBJECT (fontsel), "family", &str, "family-set",
1178             &family_set, "size", &size, "size-set", &size_set,
1179             NULL);
1180
1181     /* A smallish hack to add scrollbar when font size is really big */
1182
1183     if (size_set && size > 24) {
1184         GtkScrolledWindow *scrolled = GTK_SCROLLED_WINDOW (gtk_scrolled_window_new (NULL, NULL));
1185         gtk_scrolled_window_set_policy (scrolled, GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1186         gtk_scrolled_window_add_with_viewport (scrolled, GTK_WIDGET (preview_label));
1187         gtk_container_add (GTK_CONTAINER (GTK_DIALOG(preview_dialog)->vbox), GTK_WIDGET (scrolled));
1188         gtk_widget_set_size_request (GTK_WIDGET (scrolled), -1, 400);
1189     } else 
1190         gtk_container_add (GTK_CONTAINER (GTK_DIALOG(preview_dialog)->vbox), GTK_WIDGET (preview_label));
1191
1192     /* make reference text to have the same fontface and size */
1193     if (family_set)
1194     {
1195         attr = pango_attr_family_new (str);
1196         add_preview_text_attr (list, attr, 0, strlen (_("ecdg_fi_preview_font_preview_reference")));
1197     }
1198     if (str != NULL)
1199         g_free (str);
1200
1201     str = NULL;
1202
1203     /* size */
1204     if (size_set)
1205     {
1206         attr = pango_attr_size_new (size * PANGO_SCALE);
1207         add_preview_text_attr (list, attr, 0, strlen (_("ecdg_fi_preview_font_preview_reference")));
1208     }
1209
1210     gtk_label_set_attributes (GTK_LABEL (preview_label), list);
1211     pango_attr_list_unref (list);
1212
1213     /*And show the dialog*/
1214     gtk_window_set_transient_for (GTK_WINDOW (preview_dialog), 
1215             GTK_WINDOW (fontsel));
1216
1217     gtk_widget_show_all (preview_dialog);
1218     gtk_dialog_set_default_response (GTK_DIALOG (preview_dialog), GTK_RESPONSE_OK);
1219     
1220     GtkBox *action_area = (GtkBox *) GTK_DIALOG (preview_dialog)->action_area;
1221     GtkWidget *button = ((GtkBoxChild *) ((GSList *) action_area->children)->data)->widget;
1222     gtk_widget_grab_focus (button);
1223
1224     gtk_dialog_run (GTK_DIALOG (preview_dialog));
1225     gtk_widget_destroy (preview_dialog);
1226 }
1227
1228 static gboolean 
1229 is_internal_font                                (const gchar * name)
1230 {
1231     /* FIXME Extremally BAD BAD BAD way of doing things */
1232
1233     return strcmp(name, "DeviceSymbols") == 0
1234         || strcmp(name, "Nokia Smiley" ) == 0
1235         || strcmp(name, "NewCourier" ) == 0
1236         || strcmp(name, "NewTimes" ) == 0
1237         || strcmp(name, "SwissA" ) == 0
1238         || strcmp(name, "Nokia Sans"   ) == 0
1239         || strcmp(name, "Nokia Sans Cn") == 0;
1240 }
1241
1242 static void 
1243 filter_out_internal_fonts                       (PangoFontFamily **families, 
1244                                                  int *n_families)
1245 {
1246     int i;
1247     int n; /* counts valid fonts */
1248     const gchar * name = NULL;
1249
1250     for(i = 0, n = 0; i < * n_families; i++){
1251
1252         name = pango_font_family_get_name (families[i]);
1253
1254         if(!is_internal_font(name))
1255         {
1256
1257             if (i!=n){ /* there are filtered out families */
1258                 families[n] = families[i]; /* shift the current family */
1259             }
1260
1261             n++; /* count one more valid */
1262         }
1263     } /* foreach font family */
1264
1265     *n_families = n;  
1266 }
1267
1268 static void
1269 hildon_font_selection_dialog_show_available_fonts (HildonFontSelectionDialog *fontsel)
1270
1271 {
1272     gint i;
1273
1274     HildonFontSelectionDialogPrivate *priv = HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE (fontsel);
1275     g_assert (priv);
1276
1277     pango_context_list_families (gtk_widget_get_pango_context
1278             (GTK_WIDGET (fontsel)), &priv->families,
1279             &priv->n_families);
1280
1281     filter_out_internal_fonts (priv->families, &priv->n_families);
1282
1283     qsort (priv->families, priv->n_families, sizeof(PangoFontFamily *), cmp_families);
1284
1285     for (i = 0; i < priv->n_families; i++) 
1286     {
1287         const gchar *name = pango_font_family_get_name (priv->families[i]);
1288         gtk_combo_box_append_text (GTK_COMBO_BOX (priv->cbx_font_type), name);
1289     }
1290 }
1291
1292 static void
1293 hildon_font_selection_dialog_show_available_positionings (HildonFontSelectionDialogPrivate *priv)
1294 {
1295     gtk_combo_box_append_text (GTK_COMBO_BOX (priv->cbx_positioning), _("ecdg_va_font_printpos_1"));
1296     gtk_combo_box_append_text (GTK_COMBO_BOX (priv->cbx_positioning), _("ecdg_va_font_printpos_2"));
1297     gtk_combo_box_append_text (GTK_COMBO_BOX (priv->cbx_positioning), _("ecdg_va_font_printpos_3"));
1298 }
1299
1300 /* Loads the sizes from a pre-allocated table */
1301 static void
1302 hildon_font_selection_dialog_show_available_sizes (HildonFontSelectionDialogPrivate *priv)
1303 {
1304     gchar *size_str;
1305     gint i;
1306
1307     g_assert (priv);
1308
1309     for (i = 0; i < G_N_ELEMENTS (font_sizes); i++) 
1310     {
1311         size_str = g_strdup_printf ("%i%s",
1312                 font_sizes[i],
1313                 _("ecdg_va_font_size_trailer"));
1314
1315         gtk_combo_box_append_text (GTK_COMBO_BOX (priv->cbx_font_size), size_str);
1316         g_free (size_str);
1317     }
1318 }
1319
1320 static void
1321 toggle_clicked                                  (GtkButton *button, 
1322                                                  gpointer unused)
1323 {
1324     GtkToggleButton *t_b = GTK_TOGGLE_BUTTON (button);
1325
1326     /* we have to remove the inconsistent state ourselves */
1327     if (gtk_toggle_button_get_inconsistent (t_b))
1328     {
1329         gtk_toggle_button_set_inconsistent (t_b, FALSE);
1330         gtk_toggle_button_set_active (t_b, FALSE);
1331     }
1332 }
1333
1334 /**
1335  * hildon_font_selection_dialog_new:
1336  * @parent: the parent window
1337  * @title: the title of font selection dialog
1338  *
1339  * If NULL is passed for title, then default title
1340  * "Font" will be used.
1341  *
1342  * Returns: a new #HildonFontSelectionDialog
1343  */
1344 GtkWidget*
1345 hildon_font_selection_dialog_new                (GtkWindow *parent,
1346                                                  const gchar *title)
1347 {
1348     HildonFontSelectionDialog *fontseldiag;
1349
1350     fontseldiag = g_object_new (HILDON_TYPE_FONT_SELECTION_DIALOG,
1351             "has-separator", FALSE, NULL);
1352
1353     if (title)
1354         gtk_window_set_title (GTK_WINDOW (fontseldiag), title);
1355
1356     if (parent)
1357         gtk_window_set_transient_for (GTK_WINDOW (fontseldiag), parent);
1358
1359     return GTK_WIDGET (fontseldiag);
1360 }
1361
1362 /**
1363  * hildon_font_selection_dialog_get_preview_text:
1364  * @fsd: the font selection dialog
1365  *
1366  * Gets the text in preview dialog, which does not include the 
1367  * reference text. The returned string must be freed by the user.
1368  *
1369  * Returns: a string pointer
1370  */
1371 gchar*
1372 hildon_font_selection_dialog_get_preview_text   (HildonFontSelectionDialog * fsd)
1373 {
1374     /* FIXME Return a const pointer? */
1375     HildonFontSelectionDialogPrivate *priv;
1376
1377     g_return_val_if_fail (HILDON_IS_FONT_SELECTION_DIALOG (fsd), FALSE);
1378         
1379     priv = HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE (fsd);
1380     g_assert (priv);
1381
1382     return g_strdup (priv->preview_text);
1383 }
1384
1385 /**
1386  * hildon_font_selection_dialog_set_preview_text:
1387  * @fsd: the font selection dialog
1388  * @text: the text to be displayed in the preview dialog
1389  *
1390  * The default preview text is
1391  * "The quick brown fox jumped over the lazy dogs"
1392  */
1393 void
1394 hildon_font_selection_dialog_set_preview_text   (HildonFontSelectionDialog *fsd, 
1395                                                  const gchar * text)
1396 {
1397     HildonFontSelectionDialogPrivate *priv = NULL;
1398
1399     g_return_if_fail (HILDON_IS_FONT_SELECTION_DIALOG (fsd));
1400     g_return_if_fail (text);
1401
1402     priv = HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE (fsd);
1403     g_assert (priv);
1404
1405     g_free (priv->preview_text);
1406     priv->preview_text = g_strdup (text);
1407     g_object_notify (G_OBJECT (fsd), "preview-text");
1408 }
1409