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