2006-09-21 Tommi Komulainen <tommi.komulainen@nokia.com>
[hildon] / hildon-widgets / hildon-font-selection-dialog.c
1 /*
2  * This file is part of hildon-libs
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 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 #include <stdlib.h>
35 #include <string.h>
36
37 #include <gtk/gtkstock.h>
38 #include <gtk/gtkcombobox.h>
39 #include <gtk/gtktogglebutton.h>
40 #include <gtk/gtkcheckbutton.h>
41 #include <gtk/gtklabel.h>
42 #include <gtk/gtkvbox.h>
43 #include <gtk/gtkliststore.h>
44 #include <gtk/gtknotebook.h>
45 #include <gtk/gtk.h>
46 #include <glib.h>
47 #include <gdk/gdkkeysyms.h>
48
49 #include "hildon-font-selection-dialog.h"
50 #include <hildon-widgets/hildon-caption.h>
51 #include <hildon-widgets/hildon-color-selector.h>
52 #include <hildon-widgets/hildon-color-button.h>
53
54 #ifdef HAVE_CONFIG_H
55 #include <config.h>
56 #endif
57
58 #include <libintl.h>
59 #define _(String) dgettext(PACKAGE, String)
60
61 #define SUPERSCRIPT_RISE 3333
62 #define SUBSCRIPT_LOW   -3333
63 #define ON_BIT  0x01
64 #define OFF_BIT 0x02
65
66 /*
67  * These are what we use as the standard font sizes, for the size list.
68  */
69 static const guint16 font_sizes[] = 
70 {
71   6, 8, 10, 12, 16, 24, 32
72 };
73
74 #define HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(obj) \
75 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
76                               HILDON_TYPE_FONT_SELECTION_DIALOG, \
77                               HildonFontSelectionDialogPrivate))
78
79 /*None of designed api function works, so now it all comes down to 
80  *use properties to achieve what we are supposed to achieve*/
81 enum
82 {
83   PROP_FAMILY = 1,
84   PROP_FAMILY_SET,
85   PROP_SIZE,
86   PROP_SIZE_SET,
87   PROP_COLOR,
88   PROP_COLOR_SET,
89   PROP_BOLD,
90   PROP_BOLD_SET,
91   PROP_ITALIC,
92   PROP_ITALIC_SET,
93   PROP_UNDERLINE,
94   PROP_UNDERLINE_SET,
95   PROP_STRIKETHROUGH,
96   PROP_STRIKETHROUGH_SET,
97   PROP_POSITION,
98   PROP_POSITION_SET,
99   PROP_PREVIEW_TEXT,
100   PROP_FONT_SCALING
101 };
102
103 typedef struct
104 _HildonFontSelectionDialogPrivate HildonFontSelectionDialogPrivate;
105
106 struct _HildonFontSelectionDialogPrivate 
107 {  
108   GtkNotebook *notebook;
109
110   gchar *preview_text;
111
112   /*Tab one*/
113   GtkWidget *cbx_font_type;
114   GtkWidget *cbx_font_size;
115   GtkWidget *font_color_button;
116
117   /*Tab two*/
118   GtkWidget *chk_bold;
119   GtkWidget *chk_italic;
120   GtkWidget *chk_underline;
121
122   /*Tab three*/
123   GtkWidget *chk_strikethrough;
124   GtkWidget *cbx_positioning;
125
126   /*Every family*/
127   PangoFontFamily **families;
128   gint n_families;
129
130   /*color_set is used to show whether the color is inconsistent
131    * The handler id is used to block the signal emission
132    * when we change the color setting*/
133   
134   gboolean color_set;
135
136   /* font_scaling is the scaling factor applied to font
137    * scale in the preview dialog */
138
139   gdouble font_scaling;
140   gulong color_modified_signal_handler;
141 };
142
143 /*combo box active row indicator -2--inconsistent, -1--undefined 
144  * please make sure that you use settings_init settings_apply
145  * and settings_destroy, dont even try to touch this structure 
146  * without using the three above interface functions, of course
147  * if you know what you are doing, do as you please ;-)*/
148 typedef struct
149 {
150   HildonFontSelectionDialog
151                *fsd; /*pointer to our font selection dialog*/
152   
153   gint         family; /*combo box indicator*/
154   gint         size; /*combo box indicator*/
155   GdkColor     *color; /*free after read the setting*/
156   gboolean     color_inconsist;
157   gint         weight; /*bit mask*/
158   gint         style;  /*bit mask*/
159   gint         underline; /*bit mask*/
160   gint         strikethrough; /*bit mask*/
161   gint         position; /*combo box indicator*/
162
163 }HildonFontSelectionDialogSettings;
164
165 static gboolean
166               hildon_font_selection_dialog_preview_key_press
167                                             (GtkWidget * widget,
168                                              GdkEventKey * event,
169                                              gpointer unused);
170
171 /*Some tools from gtk_font_selection*/
172 static int    cmp_families                   (const void *a, const void *b);
173
174 static void   hildon_font_selection_dialog_show_preview
175                                              (HildonFontSelectionDialog 
176                                               *fontsel);
177                                              
178 static PangoAttrList*
179               hildon_font_selection_dialog_create_attrlist
180                                              (HildonFontSelectionDialog 
181                                               *fontsel, guint start_index,
182                                               guint len);
183
184 static void   hildon_font_selection_dialog_show_available_positionings
185                                              (HildonFontSelectionDialogPrivate
186                                               *priv);
187                                                  
188 static void   hildon_font_selection_dialog_show_available_fonts
189                                              (HildonFontSelectionDialog
190                                               *fontsel);
191                                                  
192 static void   hildon_font_selection_dialog_show_available_sizes
193                                              (HildonFontSelectionDialogPrivate
194                                               *priv);
195
196 static void   hildon_font_selection_dialog_class_init
197                                              (HildonFontSelectionDialogClass 
198                                               *klass);
199                                                  
200 static void   hildon_font_selection_dialog_init
201                                              (HildonFontSelectionDialog 
202                                               *fontseldiag);
203
204 static void   hildon_font_selection_dialog_finalize
205                                              (GObject * object);
206
207 static void   hildon_font_selection_dialog_construct_notebook  
208                                              (HildonFontSelectionDialog
209                                               *fontsel);
210                                              
211 static void   color_modified_cb              (HildonColorButton *button,
212                                               GParamSpec *pspec,
213                                               gpointer fsd_priv);
214
215 static void   check_tags                     (gpointer data,
216                                               gpointer user_data);
217
218 static void   settings_init                  (HildonFontSelectionDialogSettings
219                                               *setttings,
220                                               HildonFontSelectionDialog
221                                               *fsd);
222
223 static void   settings_apply                 (HildonFontSelectionDialogSettings
224                                               *setttings);
225
226 static void   settings_destroy               (HildonFontSelectionDialogSettings
227                                               *setttings);
228
229 static void   bit_mask_toggle                (gint mask, GtkToggleButton*
230                                               button, GObject *object, 
231                                               const gchar *prop, 
232                                               const gchar *prop_set);
233
234 static void   combo_active                   (gint active, GtkComboBox *box,
235                                               GObject *object, 
236                                               const gchar *prop,
237                                               const gchar *prop_set);
238
239 static void   add_preview_text_attr          (PangoAttrList *list, 
240                                               PangoAttribute *attr, 
241                                               guint start, 
242                                               guint len);
243
244 static void   toggle_clicked                 (GtkButton *button, 
245                                               gpointer unused);
246         
247                                              
248                                              
249 static GtkDialogClass *font_selection_dialog_parent_class = NULL;
250
251 GType hildon_font_selection_dialog_get_type(void)
252 {
253   static GType font_selection_dialog_type = 0;
254
255   if (!font_selection_dialog_type) {
256     static const GTypeInfo fontsel_diag_info = {
257       sizeof(HildonFontSelectionDialogClass),
258       NULL,       /* base_init */
259       NULL,       /* base_finalize */
260       (GClassInitFunc) hildon_font_selection_dialog_class_init,
261       NULL,       /* class_finalize */
262       NULL,       /* class_data */
263       sizeof(HildonFontSelectionDialog),
264       0,  /* n_preallocs */
265       (GInstanceInitFunc) hildon_font_selection_dialog_init,
266     };
267
268     font_selection_dialog_type =
269       g_type_register_static(GTK_TYPE_DIALOG,
270                              "HildonFontSelectionDialog",
271                              &fontsel_diag_info, 0);
272   }
273
274   return font_selection_dialog_type;
275 }
276
277 static void
278 hildon_font_selection_dialog_get_property (GObject      *object,
279                                            guint         prop_id,
280                                            GValue       *value,
281                                            GParamSpec   *pspec)
282 {
283   gint i;
284   GdkColor *color = NULL;
285   
286   HildonFontSelectionDialogPrivate *priv =
287     HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(
288         HILDON_FONT_SELECTION_DIALOG(object));
289   
290   
291   switch (prop_id)
292     {
293     case PROP_FAMILY:
294       i = gtk_combo_box_get_active(GTK_COMBO_BOX(priv->cbx_font_type));
295       if(i >= 0 && i < priv->n_families)
296         g_value_set_string(value, 
297                            pango_font_family_get_name(priv->families[i]));
298       else
299         g_value_set_string(value, "Sans");
300       break;
301       
302     case PROP_FAMILY_SET:
303       i = gtk_combo_box_get_active(GTK_COMBO_BOX(priv->cbx_font_type));
304       if(i >= 0 && i < priv->n_families)
305         g_value_set_boolean(value, TRUE);
306       else
307         g_value_set_boolean(value, FALSE);
308       break;
309       
310     case PROP_SIZE:
311       i = gtk_combo_box_get_active(GTK_COMBO_BOX(priv->cbx_font_size));
312       if(i >= 0 && i < G_N_ELEMENTS(font_sizes))
313         g_value_set_int(value, font_sizes[i]);
314       else
315         g_value_set_int(value, 16);
316       break;
317       
318     case PROP_SIZE_SET:
319       i = gtk_combo_box_get_active(GTK_COMBO_BOX(priv->cbx_font_size));
320       if(i >= 0 && i < G_N_ELEMENTS(font_sizes))
321         g_value_set_boolean(value, TRUE);
322       else
323         g_value_set_boolean(value, FALSE);
324       break;
325
326     case PROP_COLOR:
327       color = hildon_color_button_get_color
328         (HILDON_COLOR_BUTTON(priv->font_color_button));
329       g_value_set_boxed(value, (gconstpointer) color);
330       if(color != NULL)
331         gdk_color_free(color);
332       break;
333       
334     case PROP_COLOR_SET:
335       g_value_set_boolean(value, priv->color_set);
336       break;
337
338     case PROP_BOLD:
339       g_value_set_boolean(value, 
340         gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->chk_bold)));
341       break;
342
343     case PROP_BOLD_SET:
344       g_value_set_boolean(value,
345         !gtk_toggle_button_get_inconsistent
346         (GTK_TOGGLE_BUTTON(priv->chk_bold)));
347       break;
348       
349     case PROP_ITALIC:
350       g_value_set_boolean(value, 
351         gtk_toggle_button_get_active
352         (GTK_TOGGLE_BUTTON(priv->chk_italic)));
353       break;
354
355     case PROP_ITALIC_SET:
356       g_value_set_boolean(value,
357         !gtk_toggle_button_get_inconsistent
358         (GTK_TOGGLE_BUTTON(priv->chk_italic)));
359       break;
360       
361     case PROP_UNDERLINE:
362       g_value_set_boolean(value, 
363         gtk_toggle_button_get_active
364         (GTK_TOGGLE_BUTTON(priv->chk_underline)));
365       break;
366
367     case PROP_UNDERLINE_SET:
368       g_value_set_boolean(value,
369         !gtk_toggle_button_get_inconsistent
370         (GTK_TOGGLE_BUTTON(priv->chk_underline)));
371       break;
372       
373     case PROP_STRIKETHROUGH:
374       g_value_set_boolean(value, 
375         gtk_toggle_button_get_active
376         (GTK_TOGGLE_BUTTON(priv->chk_strikethrough)));
377       break;
378
379     case PROP_STRIKETHROUGH_SET:
380       g_value_set_boolean(value,
381         !gtk_toggle_button_get_inconsistent
382         (GTK_TOGGLE_BUTTON(priv->chk_strikethrough)));
383       break;
384
385     case PROP_POSITION:
386       i = gtk_combo_box_get_active(GTK_COMBO_BOX(priv->cbx_positioning));
387       if(i == 1)/*super*/
388         g_value_set_int(value, 1);
389       else if(i == 2)/*sub*/
390         g_value_set_int(value, -1);
391       else
392         g_value_set_int(value, 0);
393       break;
394     
395     case PROP_FONT_SCALING:
396         g_value_set_double(value, priv->font_scaling);
397       break;
398   
399     case PROP_POSITION_SET:
400       i = gtk_combo_box_get_active(GTK_COMBO_BOX(priv->cbx_positioning));
401       if(i >= 0 && i < 3)
402         g_value_set_boolean(value, TRUE);
403       else
404         g_value_set_boolean(value, FALSE);
405       break;
406     
407     case PROP_PREVIEW_TEXT:
408         g_value_set_string(value,
409                 hildon_font_selection_dialog_get_preview_text(
410                     HILDON_FONT_SELECTION_DIALOG(object)));
411       break;
412     
413     default:
414       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
415       break;
416     }
417 }
418
419 static void 
420 hildon_font_selection_dialog_set_property (GObject         *object,
421                                            guint            prop_id,
422                                            const GValue    *value,
423                                            GParamSpec      *pspec)
424 {
425   gint i, size;
426   const gchar *str;
427   gboolean b;
428   GdkColor *color = NULL;
429   GdkColor black;
430   
431   HildonFontSelectionDialogPrivate *priv =
432     HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(
433         HILDON_FONT_SELECTION_DIALOG(object));
434   black.red = black.green = black.blue = 0;
435   
436   switch (prop_id)
437     {
438     case PROP_FAMILY:
439       str = g_value_get_string(value);
440       for(i = 0; i < priv->n_families; i++)
441         {
442           if(strcmp(str, pango_font_family_get_name(priv->families[i]))
443              == 0)
444             {
445               gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_font_type), i);
446               break;
447             }
448         }
449       break;
450       
451     case PROP_FAMILY_SET:
452       b = g_value_get_boolean(value);
453       if(!b)
454         gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_font_type), -1);
455       break;
456     
457     case PROP_SIZE:
458       size = g_value_get_int(value);
459       for(i = 0; i < G_N_ELEMENTS(font_sizes); i++)
460         {
461           if(size == font_sizes[i])
462             {
463               gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_font_size), i);
464               break;
465             }
466         }
467       break;
468       
469     case PROP_SIZE_SET:
470       b = g_value_get_boolean(value);
471       if(!b)
472         gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_font_size), -1);
473       break;
474
475     case PROP_COLOR:
476       color = (GdkColor *) g_value_get_boxed(value);
477       if(color != NULL)
478         hildon_color_button_set_color(HILDON_COLOR_BUTTON
479                                       (priv->font_color_button),
480                                       color);
481       else
482         hildon_color_button_set_color(HILDON_COLOR_BUTTON
483                                       (priv->font_color_button),
484                                       &black);
485       break;
486
487     case PROP_COLOR_SET:
488       priv->color_set = g_value_get_boolean(value);
489       if(!priv->color_set)
490         {
491           /*set color to black, but block our signal handler*/
492           g_signal_handler_block((gpointer) priv->font_color_button,
493                                  priv->color_modified_signal_handler);
494           
495           hildon_color_button_set_color(HILDON_COLOR_BUTTON
496                                         (priv->font_color_button), 
497                                         &black);
498           
499           g_signal_handler_unblock((gpointer) priv->font_color_button,
500                                  priv->color_modified_signal_handler);
501         }
502       break;
503
504     case PROP_BOLD:
505       /*this call will make sure that we dont get extra clicked signal*/
506       gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(priv->chk_bold),
507                                          FALSE);
508       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->chk_bold),
509                                    g_value_get_boolean(value));
510       break;
511
512     case PROP_BOLD_SET:
513       gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(priv->chk_bold),
514                                          !g_value_get_boolean(value));
515       break;
516       
517     case PROP_ITALIC:
518       gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(priv->chk_italic),
519                                          FALSE);
520       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->chk_italic),
521                                    g_value_get_boolean(value));
522       break;
523
524     case PROP_ITALIC_SET:
525       gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(priv->chk_italic),
526                                          !g_value_get_boolean(value));
527       break;
528       
529     case PROP_UNDERLINE:
530       gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON
531                                          (priv->chk_underline),
532                                          FALSE);
533       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->chk_underline),
534                                    g_value_get_boolean(value));
535       break;
536
537     case PROP_UNDERLINE_SET:
538       gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(priv->chk_underline),
539                                          !g_value_get_boolean(value));
540       break;
541   
542     case PROP_STRIKETHROUGH:
543       gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON
544                                          (priv->chk_strikethrough),
545                                          FALSE);
546       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->chk_strikethrough),
547                                    g_value_get_boolean(value));
548       break;
549
550     case PROP_STRIKETHROUGH_SET:
551       gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON
552                                          (priv->chk_strikethrough),
553                                          !g_value_get_boolean(value));
554       break;
555
556     case PROP_POSITION:
557       i = g_value_get_int(value);
558       if( i == 1 )
559         gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_positioning), 1);
560       else if(i == -1)
561         gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_positioning), 2);
562       else
563         gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_positioning), 0);
564       break;
565
566     case PROP_FONT_SCALING:
567       priv->font_scaling = g_value_get_double(value);
568       break;
569       
570     case PROP_POSITION_SET:
571       b = g_value_get_boolean(value);
572       if(!b)
573         gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_positioning), -1);
574       break;
575
576     case PROP_PREVIEW_TEXT:
577       hildon_font_selection_dialog_set_preview_text(
578               HILDON_FONT_SELECTION_DIALOG(object),
579               g_value_get_string(value));
580       break;
581     
582     default:
583       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
584       break;
585     }
586 }
587
588 static void
589 hildon_font_selection_dialog_class_init(HildonFontSelectionDialogClass *
590                                         klass)
591 {
592   GObjectClass *gobject_class;
593
594   font_selection_dialog_parent_class = g_type_class_peek_parent(klass);
595   gobject_class = G_OBJECT_CLASS(klass);
596   gobject_class->finalize = hildon_font_selection_dialog_finalize;
597   gobject_class->get_property = hildon_font_selection_dialog_get_property;
598   gobject_class->set_property = hildon_font_selection_dialog_set_property;
599
600   /* Install property to the class */
601   g_object_class_install_property(gobject_class, PROP_FAMILY,
602                                   g_param_spec_string("family",
603                                   "Font family", "String defines"
604                                   " the font family", "Sans",
605                                   G_PARAM_READWRITE));
606   
607   g_object_class_install_property(gobject_class, PROP_FAMILY_SET,
608                                   g_param_spec_boolean ("family-set",
609                                   "family inconsistent state",
610                                   "Whether the family property"
611                                   " is inconsistent", FALSE,
612                                   G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
613   
614   g_object_class_install_property(gobject_class, PROP_SIZE,
615                                    g_param_spec_int ("size",
616                                    "Font size",
617                                    "Font size in Pt",
618                                    6, 32, 16,
619                                    G_PARAM_READWRITE));
620   
621   g_object_class_install_property(gobject_class, PROP_SIZE_SET,
622                                   g_param_spec_boolean ("size-set",
623                                   "size inconsistent state",
624                                   "Whether the size property"
625                                   " is inconsistent", FALSE,
626                                   G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
627   
628   g_object_class_install_property(gobject_class, PROP_COLOR,
629                                   g_param_spec_boxed ("color",
630                                   "text color",
631                                   "gdk color for the text",
632                                   GDK_TYPE_COLOR,
633                                   G_PARAM_READWRITE));
634
635   g_object_class_install_property(gobject_class, PROP_COLOR_SET,
636                                   g_param_spec_boolean ("color-set",
637                                   "color inconsistent state",
638                                   "Whether the color property"
639                                   " is inconsistent", FALSE,
640                                   G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
641
642   g_object_class_install_property(gobject_class, PROP_BOLD,
643                                   g_param_spec_boolean ("bold",
644                                   "text weight",
645                                   "Whether the text is bold",
646                                   FALSE,
647                                   G_PARAM_READWRITE));
648   
649   g_object_class_install_property(gobject_class, PROP_BOLD_SET,
650                                   g_param_spec_boolean ("bold-set",
651                                   "bold inconsistent state",
652                                   "Whether the bold"
653                                   " is inconsistent", FALSE,
654                                   G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
655   
656   g_object_class_install_property(gobject_class, PROP_ITALIC,
657                                   g_param_spec_boolean ("italic",
658                                   "text style",
659                                   "Whether the text is italic",
660                                   FALSE,
661                                   G_PARAM_READWRITE));
662   
663   g_object_class_install_property(gobject_class, PROP_ITALIC_SET,
664                                   g_param_spec_boolean ("italic-set",
665                                   "italic inconsistent state",
666                                   "Whether the italic"
667                                   " is inconsistent", FALSE,
668                                   G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
669   
670   g_object_class_install_property(gobject_class, PROP_UNDERLINE,
671                                   g_param_spec_boolean ("underline",
672                                   "text underline",
673                                   "Whether the text is underlined",
674                                   FALSE,
675                                   G_PARAM_READWRITE));
676   
677   g_object_class_install_property(gobject_class, PROP_UNDERLINE_SET,
678                                   g_param_spec_boolean ("underline-set",
679                                   "underline inconsistent state",
680                                   "Whether the underline"
681                                   " is inconsistent", FALSE,
682                                   G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
683   
684   g_object_class_install_property(gobject_class, PROP_STRIKETHROUGH,
685                                   g_param_spec_boolean ("strikethrough",
686                                   "strikethroughed text",
687                                   "Whether the text is strikethroughed",
688                                   FALSE,
689                                   G_PARAM_READWRITE));
690   
691   g_object_class_install_property(gobject_class, PROP_STRIKETHROUGH_SET,
692                                   g_param_spec_boolean ("strikethrough-set",
693                                   "strikethrough inconsistent state",
694                                   "Whether the strikethrough"
695                                   " is inconsistent", FALSE,
696                                   G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
697   
698   g_object_class_install_property(gobject_class, PROP_POSITION,
699                                    g_param_spec_int ("position",
700                                    "Font position",
701                                    "Font position super or subscript",
702                                    -1, 1, 0,
703                                    G_PARAM_READWRITE));
704
705   /* FIXME This was introduced in 0.14.1. We don't have documentation for 
706    * properties anyways, but once it's there it needs to be marked as 
707    * Since: 0.14.1 */
708   g_object_class_install_property(gobject_class, PROP_FONT_SCALING,
709                                    g_param_spec_double ("font-scaling",
710                                    "Font scaling",
711                                    "Font scaling for the preview dialog",
712                                    0, 10, 1,
713                                    G_PARAM_READWRITE));
714   
715   g_object_class_install_property(gobject_class, PROP_POSITION_SET,
716                                   g_param_spec_boolean ("position-set",
717                                   "position inconsistent state",
718                                   "Whether the position"
719                                   " is inconsistent", FALSE,
720                                   G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
721   
722   g_object_class_install_property(gobject_class, PROP_PREVIEW_TEXT,
723                                   g_param_spec_string("preview-text",
724                                   "Preview Text", 
725                                   "the text in preview dialog, which does" 
726                                   "not include the reference text",
727                                   "",
728                                   G_PARAM_READWRITE));
729   
730
731   g_type_class_add_private(klass,
732                            sizeof(struct _HildonFontSelectionDialogPrivate));
733 }
734
735
736 static void 
737 hildon_font_selection_dialog_init(HildonFontSelectionDialog *fontseldiag)
738 {
739   HildonFontSelectionDialogPrivate *priv =
740     HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(fontseldiag);
741   GtkWidget *preview_button;
742   
743   priv->notebook = GTK_NOTEBOOK(gtk_notebook_new());
744
745   hildon_font_selection_dialog_construct_notebook(fontseldiag);
746   
747   gtk_box_pack_start(GTK_BOX(GTK_DIALOG(fontseldiag)->vbox),
748                      GTK_WIDGET(priv->notebook), TRUE, TRUE, 0);
749   
750   /* Add dialog buttons */
751   gtk_dialog_add_button(GTK_DIALOG(fontseldiag),
752                         _("ecdg_bd_font_dialog_ok"),
753                         GTK_RESPONSE_OK);
754   
755   preview_button = gtk_button_new_with_label(_("ecdg_bd_font_dialog_preview"));
756   gtk_box_pack_start(GTK_BOX(GTK_DIALOG(fontseldiag)->action_area), 
757                      preview_button, FALSE, TRUE, 0);
758   g_signal_connect_swapped(preview_button, "clicked",
759                            G_CALLBACK
760                            (hildon_font_selection_dialog_show_preview),
761                            fontseldiag);
762   gtk_widget_show(preview_button);
763
764   gtk_dialog_add_button(GTK_DIALOG(fontseldiag),
765                         _("ecdg_bd_font_dialog_cancel"),
766                         GTK_RESPONSE_CANCEL);
767
768   /*Set default preview text*/
769   priv->preview_text = g_strdup(_("ecdg_fi_preview_font_preview_text"));
770
771   gtk_window_set_title(GTK_WINDOW(fontseldiag), _("ecdg_ti_font"));
772   /*here is the line to make sure that notebook has the default focus*/
773   gtk_container_set_focus_child(GTK_CONTAINER(GTK_DIALOG(fontseldiag)->vbox),
774                                 GTK_WIDGET(priv->notebook));
775 }
776
777 static void 
778 hildon_font_selection_dialog_construct_notebook (HildonFontSelectionDialog
779                                                  *fontsel)
780 {
781   gint i;
782   GtkWidget *vbox_tab[3];
783   GtkWidget *font_color_box;
784   GtkWidget *caption_control;
785   GtkSizeGroup *group;
786   
787   HildonFontSelectionDialogPrivate *priv =
788     HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(fontsel);
789
790   for (i = 0; i < 3; i++)
791     vbox_tab[i] = gtk_vbox_new(TRUE, 0);
792
793   group =
794     GTK_SIZE_GROUP(gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL));
795   
796   /* Build the first page of the GtkNotebook: font style */
797   priv->cbx_font_type = gtk_combo_box_new_text();
798   hildon_font_selection_dialog_show_available_fonts(fontsel);
799   caption_control = hildon_caption_new(group,
800                                        _("ecdg_fi_font_font"),
801                                        priv->cbx_font_type,
802                                        NULL,
803                                        HILDON_CAPTION_OPTIONAL);
804   gtk_box_pack_start(GTK_BOX(vbox_tab[0]), caption_control,
805                      FALSE, FALSE, 0);
806
807   priv->cbx_font_size = gtk_combo_box_new_text();
808   hildon_font_selection_dialog_show_available_sizes(priv);
809   caption_control = hildon_caption_new(group,
810                                        _("ecdg_fi_font_size"),
811                                        priv->cbx_font_size,
812                                        NULL,
813                                        HILDON_CAPTION_OPTIONAL);
814   gtk_box_pack_start(GTK_BOX(vbox_tab[0]), caption_control,
815                      FALSE, FALSE, 0);
816
817   font_color_box = gtk_hbox_new(FALSE, 0);
818   priv->font_color_button = hildon_color_button_new();
819   priv->color_set = FALSE;
820   priv->font_scaling = 1.0;
821   priv->color_modified_signal_handler = 
822     g_signal_connect(G_OBJECT(priv->font_color_button), "notify::color",
823                      G_CALLBACK(color_modified_cb), (gpointer) priv);
824   gtk_box_pack_start(GTK_BOX(font_color_box),
825                      priv->font_color_button, FALSE, FALSE, 0);
826   
827   caption_control =
828     hildon_caption_new(group, _("ecdg_fi_font_colour_selector"),
829                        font_color_box,
830                        NULL, HILDON_CAPTION_OPTIONAL);
831   
832   gtk_box_pack_start(GTK_BOX(vbox_tab[0]), caption_control,
833                      FALSE, FALSE, 0);
834
835   /* Build the second page of the GtkNotebook: font formatting */ 
836   priv->chk_bold = gtk_check_button_new();
837   caption_control = hildon_caption_new(group,
838                                        _("ecdg_fi_font_bold"),
839                                        priv->chk_bold,
840                                        NULL,
841                                        HILDON_CAPTION_OPTIONAL);
842   gtk_box_pack_start(GTK_BOX(vbox_tab[1]), caption_control,
843                      FALSE, FALSE, 0);
844   g_signal_connect(G_OBJECT(priv->chk_bold), "clicked", 
845                    G_CALLBACK(toggle_clicked), NULL);
846
847   priv->chk_italic = gtk_check_button_new();
848   caption_control =
849     hildon_caption_new(group, _("ecdg_fi_font_italic"),
850                        priv->chk_italic,
851                        NULL, HILDON_CAPTION_OPTIONAL);
852   gtk_box_pack_start(GTK_BOX(vbox_tab[1]), caption_control,
853                      FALSE, FALSE, 0);
854   g_signal_connect(G_OBJECT(priv->chk_italic), "clicked", 
855                    G_CALLBACK(toggle_clicked), NULL);
856
857   priv->chk_underline = gtk_check_button_new();
858   caption_control =
859     hildon_caption_new(group, _("ecdg_fi_font_underline"),
860                        priv->chk_underline, NULL,
861                        HILDON_CAPTION_OPTIONAL);
862   gtk_box_pack_start(GTK_BOX(vbox_tab[1]), caption_control,
863                      FALSE, FALSE, 0);
864   g_signal_connect(G_OBJECT(priv->chk_underline), "clicked", 
865                    G_CALLBACK(toggle_clicked), NULL);
866
867   /* Build the third page of the GtkNotebook: other font properties */
868   priv->chk_strikethrough = gtk_check_button_new();
869   caption_control =
870     hildon_caption_new(group, _("ecdg_fi_font_strikethrough"),
871                        priv->chk_strikethrough, NULL,
872                        HILDON_CAPTION_OPTIONAL);
873   gtk_box_pack_start(GTK_BOX(vbox_tab[2]), caption_control,
874                      FALSE, FALSE, 0);
875   g_signal_connect(G_OBJECT(priv->chk_strikethrough), "clicked", 
876                    G_CALLBACK(toggle_clicked), NULL);
877
878   priv->cbx_positioning = gtk_combo_box_new_text();
879   hildon_font_selection_dialog_show_available_positionings(priv);
880   caption_control =
881     hildon_caption_new(group, _("ecdg_fi_font_special"),
882                        priv->cbx_positioning, NULL,
883                        HILDON_CAPTION_OPTIONAL);
884   gtk_box_pack_start(GTK_BOX(vbox_tab[2]), caption_control,
885                      FALSE, FALSE, 0);
886   
887   /* Populate notebook */
888   gtk_notebook_insert_page(priv->notebook, vbox_tab[0], NULL, 0);
889   gtk_notebook_insert_page(priv->notebook, vbox_tab[1], NULL, 1);
890   gtk_notebook_insert_page(priv->notebook, vbox_tab[2], NULL, 2);
891   gtk_notebook_set_tab_label_text(priv->notebook, vbox_tab[0],
892                                   _("ecdg_ti_font_dialog_style"));
893   gtk_notebook_set_tab_label_text(priv->notebook, vbox_tab[1],
894                                   _("ecdg_ti_font_dialog_format"));
895   gtk_notebook_set_tab_label_text(priv->notebook, vbox_tab[2],
896                                   _("ecdg_ti_font_dialog_other"));
897   
898   gtk_widget_show_all(GTK_WIDGET(priv->notebook));
899 }
900
901 static void 
902 color_modified_cb(HildonColorButton *button, 
903                   GParamSpec *pspec, 
904                   gpointer fsd_priv)
905 {
906   HildonFontSelectionDialogPrivate *priv = 
907           (HildonFontSelectionDialogPrivate *) fsd_priv;
908
909   priv->color_set = TRUE;
910 }
911
912 static void 
913 hildon_font_selection_dialog_finalize(GObject * object)
914 {
915   HildonFontSelectionDialogPrivate *priv;
916   HildonFontSelectionDialog *fontsel;
917
918   g_assert(HILDON_IS_FONT_SELECTION_DIALOG(object));
919   fontsel = HILDON_FONT_SELECTION_DIALOG(object);
920
921   priv = HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(fontsel);
922   
923   g_free(priv->preview_text);
924   g_free(priv->families);
925
926   if (G_OBJECT_CLASS(font_selection_dialog_parent_class)->finalize)
927     G_OBJECT_CLASS(font_selection_dialog_parent_class)->finalize(object);
928 }
929
930 static int 
931 cmp_families(const void *a, const void *b)
932 {
933   const char *a_name =
934     pango_font_family_get_name(*(PangoFontFamily **) a);
935   const char *b_name =
936     pango_font_family_get_name(*(PangoFontFamily **) b);
937
938   return g_utf8_collate(a_name, b_name);
939 }
940
941 /* Exits the preview dialog with GTK_RESPONSE_CANCEL if Esc key
942  * was pressed */
943 static gboolean
944 hildon_font_selection_dialog_preview_key_press(GtkWidget   * widget,
945                                                GdkEventKey * event,
946                                                gpointer      unused)
947 {
948   g_assert(widget);
949   g_assert(event);
950   
951   if (event->keyval == GDK_Escape)
952     {
953       gtk_dialog_response(GTK_DIALOG(widget), GTK_RESPONSE_CANCEL);
954       return TRUE;
955     }
956
957   return FALSE;
958 }
959
960 static void
961 add_preview_text_attr(PangoAttrList *list, PangoAttribute *attr, 
962                       guint start, guint len)
963 {
964   attr->start_index = start;
965   attr->end_index = start + len;
966   pango_attr_list_insert(list, attr);
967 }
968
969 static PangoAttrList*
970 hildon_font_selection_dialog_create_attrlist(HildonFontSelectionDialog *
971                                          fontsel, guint start_index, guint len)
972 {
973   PangoAttrList *list;
974   PangoAttribute *attr;
975   gint size, position;
976   gboolean family_set, size_set, color_set, bold, bold_set,
977            italic, italic_set, underline, underline_set,
978            strikethrough, strikethrough_set, position_set;
979   GdkColor *color = NULL;
980   gchar *family = NULL;
981   gdouble font_scaling = 1.0;
982
983   list = pango_attr_list_new();
984  
985   g_object_get(G_OBJECT(fontsel),
986                "family", &family, "family-set", &family_set,
987                "size", &size, "size-set", &size_set,
988                "color", &color, "color-set", &color_set,
989                "bold", &bold, "bold-set", &bold_set,
990                "italic", &italic, "italic-set", &italic_set,
991                "underline", &underline, "underline-set", &underline_set,
992                "strikethrough", &strikethrough, "strikethrough-set", 
993                &strikethrough_set, "position", &position, 
994                "position-set", &position_set, 
995                "font-scaling", &font_scaling,
996                NULL);
997
998   /*family*/
999   if(family_set)
1000     {
1001       attr = pango_attr_family_new(family);
1002       add_preview_text_attr(list, attr, start_index, len);
1003     }
1004   g_free(family);
1005   
1006   /*size*/
1007   if(size_set)
1008     {
1009       attr = pango_attr_size_new(size * PANGO_SCALE);
1010       add_preview_text_attr(list, attr, start_index, len);
1011     }
1012   
1013   /*color*/
1014   if(color_set)
1015     {
1016       attr = pango_attr_foreground_new(color->red, color->green, color->blue);
1017       add_preview_text_attr(list, attr, start_index, len);
1018     }
1019   
1020   if(color != NULL)
1021     gdk_color_free(color);
1022   
1023   /*weight*/
1024   if(bold_set)
1025     {
1026       if(bold)
1027         attr = pango_attr_weight_new(PANGO_WEIGHT_BOLD);
1028       else
1029         attr = pango_attr_weight_new(PANGO_WEIGHT_NORMAL);
1030
1031       add_preview_text_attr(list, attr, start_index, len);
1032     }
1033   
1034   /*style*/
1035   if(italic_set)
1036     {
1037       if(italic)
1038         attr = pango_attr_style_new(PANGO_STYLE_ITALIC);
1039       else
1040         attr = pango_attr_style_new(PANGO_STYLE_NORMAL);
1041
1042       add_preview_text_attr(list, attr, start_index, len);
1043     }
1044   
1045   /*underline*/
1046   if(underline_set)
1047     {
1048       if(underline)
1049         attr = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE);
1050       else
1051         attr = pango_attr_underline_new(PANGO_UNDERLINE_NONE);
1052
1053       add_preview_text_attr(list, attr, start_index, len);
1054     }
1055   
1056   /*strikethrough*/
1057   if(strikethrough_set)
1058     {
1059       if(strikethrough)
1060         attr = pango_attr_strikethrough_new(TRUE);
1061       else
1062         attr = pango_attr_strikethrough_new(FALSE);
1063
1064       add_preview_text_attr(list, attr, start_index, len);
1065     }
1066   
1067   /*position*/
1068   if(position_set)
1069     {
1070       switch(position)
1071         {
1072         case 1: /*super*/
1073           attr = pango_attr_rise_new(SUPERSCRIPT_RISE);
1074           break;
1075         case -1: /*sub*/
1076           attr = pango_attr_rise_new(SUBSCRIPT_LOW);
1077           break;
1078         default: /*normal*/
1079           attr = pango_attr_rise_new(0);
1080           break;
1081         }
1082
1083       add_preview_text_attr(list, attr, start_index, len);
1084     }
1085
1086   /*font scaling for preview*/
1087   if(font_scaling)
1088     {
1089       attr = pango_attr_scale_new(font_scaling);
1090       add_preview_text_attr(list, attr, 0, len + start_index);
1091     }
1092    
1093   return list;
1094 }
1095
1096 static void
1097 hildon_font_selection_dialog_show_preview(HildonFontSelectionDialog *
1098                                           fontsel)
1099 {
1100   HildonFontSelectionDialogPrivate *priv =
1101     HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(fontsel);
1102   gint size;
1103   gboolean family_set, size_set;
1104   PangoAttribute *attr;
1105   PangoAttrList *list;
1106   GtkWidget *preview_dialog;
1107   GtkWidget *preview_label;
1108   gchar *str = NULL;
1109   gboolean position_set = FALSE;
1110   gint position = 0;
1111   gboolean show_ref = FALSE;
1112
1113   g_object_get(G_OBJECT(fontsel), "position-set", &position_set, NULL);
1114   if (position_set) {
1115     g_object_get(G_OBJECT(fontsel), "position", &position, NULL);
1116     if (position == 1 || position == -1)
1117       show_ref = TRUE;
1118   }
1119   
1120   /*Preview dialog init*/
1121   preview_dialog=
1122     gtk_dialog_new_with_buttons(_("ecdg_ti_preview_font"), NULL,
1123                                 GTK_DIALOG_MODAL |
1124                                 GTK_DIALOG_DESTROY_WITH_PARENT |
1125                                 GTK_DIALOG_NO_SEPARATOR,
1126                                 _("ecdg_bd_font_dialog_ok"),
1127                                 GTK_RESPONSE_ACCEPT,
1128                                 NULL);
1129
1130   str = (show_ref) ? g_strconcat(_("ecdg_fi_preview_font_preview_reference"), priv->preview_text, 0) :
1131                      g_strdup (priv->preview_text);
1132
1133   preview_label = gtk_label_new(str);
1134   gtk_label_set_line_wrap(GTK_LABEL(preview_label), TRUE);
1135
1136   g_free(str);
1137   str = NULL;
1138
1139   gtk_container_add(GTK_CONTAINER(GTK_DIALOG(preview_dialog)->vbox),
1140                     preview_label);
1141
1142   
1143   /* set keypress handler (ESC hardkey) */
1144   g_signal_connect(G_OBJECT(preview_dialog), "key-press-event",
1145                   G_CALLBACK(hildon_font_selection_dialog_preview_key_press),
1146                   NULL);
1147   
1148   
1149   /*Set the font*/
1150   list = (show_ref) ? hildon_font_selection_dialog_create_attrlist(fontsel, 
1151       strlen(_("ecdg_fi_preview_font_preview_reference")),
1152       strlen(priv->preview_text)) :
1153       hildon_font_selection_dialog_create_attrlist(fontsel, 
1154       0,
1155       strlen(priv->preview_text));
1156
1157   g_object_get(G_OBJECT(fontsel), "family", &str, "family-set",
1158                &family_set, "size", &size, "size-set", &size_set,
1159                NULL);
1160   /*make reference text to have the same fontface and size*/
1161   if(family_set)
1162     {
1163       attr = pango_attr_family_new(str);
1164       add_preview_text_attr(list, attr, 0, strlen(_("ecdg_fi_preview_font_preview_reference")));
1165     }
1166   g_free(str);
1167   
1168   /*size*/
1169   if(size_set)
1170     {
1171       attr = pango_attr_size_new(size * PANGO_SCALE);
1172       add_preview_text_attr(list, attr, 0, strlen(_("ecdg_fi_preview_font_preview_reference")));
1173     }
1174   
1175   gtk_label_set_attributes(GTK_LABEL(preview_label), list);
1176   pango_attr_list_unref(list);
1177   
1178   /*And show the dialog*/
1179   gtk_window_set_transient_for(GTK_WINDOW(preview_dialog), 
1180                                GTK_WINDOW(fontsel));
1181   gtk_widget_show_all(preview_dialog);
1182   gtk_dialog_run(GTK_DIALOG(preview_dialog));
1183   gtk_widget_destroy(preview_dialog);
1184 }
1185
1186
1187 static gboolean is_internal_font(const gchar * name){
1188   return strcmp(name, "DeviceSymbols") == 0
1189       || strcmp(name, "Nokia Smiley" ) == 0
1190       || strcmp(name, "NewCourier" ) == 0
1191       || strcmp(name, "NewTimes" ) == 0
1192       || strcmp(name, "SwissA" ) == 0
1193       || strcmp(name, "Nokia Sans"   ) == 0
1194       || strcmp(name, "Nokia Sans Cn") == 0;
1195 }
1196
1197 static void filter_out_internal_fonts(PangoFontFamily **families, int *n_families){
1198   int i;
1199   int n; /* counts valid fonts */
1200   const gchar * name = NULL;
1201
1202   for(i = 0, n = 0; i < *n_families; i++){
1203
1204     name = pango_font_family_get_name(families[i]);
1205         
1206     if(!is_internal_font(name)){
1207
1208       if(i!=n){ /* there are filtered out families */
1209         families[n] = families[i]; /* shift the current family */
1210       }
1211
1212       n++; /* count one more valid */
1213     }
1214   }/* foreach font family */
1215
1216   *n_families = n;  
1217 }
1218
1219
1220 static void
1221 hildon_font_selection_dialog_show_available_fonts(HildonFontSelectionDialog 
1222                                                   *fontsel)
1223
1224 {
1225   gint i;
1226   
1227   HildonFontSelectionDialogPrivate *priv =
1228     HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(fontsel);
1229
1230   pango_context_list_families(gtk_widget_get_pango_context
1231                               (GTK_WIDGET(fontsel)), &priv->families,
1232                               &priv->n_families);
1233
1234   filter_out_internal_fonts(priv->families, &priv->n_families);
1235
1236   qsort(priv->families, priv->n_families, sizeof(PangoFontFamily *),
1237         cmp_families);
1238
1239
1240   for (i = 0; i < priv->n_families; i++) 
1241     {
1242       const gchar *name = pango_font_family_get_name(priv->families[i]);
1243
1244       gtk_combo_box_append_text(GTK_COMBO_BOX(priv->cbx_font_type),
1245                                 name);
1246     }
1247 }
1248
1249
1250 static void
1251 hildon_font_selection_dialog_show_available_positionings
1252                                              (HildonFontSelectionDialogPrivate
1253                                               *priv)
1254 {
1255   gtk_combo_box_append_text(GTK_COMBO_BOX(priv->cbx_positioning),
1256                             _("ecdg_va_font_printpos_1"));
1257   gtk_combo_box_append_text(GTK_COMBO_BOX(priv->cbx_positioning),
1258                             _("ecdg_va_font_printpos_2"));
1259   gtk_combo_box_append_text(GTK_COMBO_BOX(priv->cbx_positioning),
1260                             _("ecdg_va_font_printpos_3"));
1261 }
1262
1263 /*Loads the sizes from a pre-allocated table*/
1264 static void
1265 hildon_font_selection_dialog_show_available_sizes
1266                                              (HildonFontSelectionDialogPrivate
1267                                               *priv)
1268 {
1269   gchar *size_str;
1270   gint i;
1271
1272   for (i = 0; i < G_N_ELEMENTS(font_sizes); i++) 
1273     {
1274       size_str = g_strdup_printf ("%i %s",
1275                                   font_sizes[i],
1276                                   _("ecdg_va_font_size_trailer"));
1277
1278       gtk_combo_box_append_text(GTK_COMBO_BOX(priv->cbx_font_size),
1279                                 size_str);
1280       g_free (size_str);
1281     }
1282 }
1283
1284 /* WARNING: This function is called only from deprecated API */
1285 static
1286 void check_tags(gpointer data, gpointer user_data)
1287 {
1288   gchar *font_family;
1289   GdkColor *fore_color =  NULL;
1290   gint p_size, p_weight, p_style, p_underline, p_rise;
1291   gboolean b_st, ff_s, size_s, fgc_s, w_s, ss_s, u_s, sth_s, r_s;
1292   
1293   GtkTextTag *tag = (GtkTextTag*) data;
1294   HildonFontSelectionDialogSettings *settings = 
1295     (HildonFontSelectionDialogSettings *) user_data;
1296   HildonFontSelectionDialogPrivate *priv = 
1297     HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(settings->fsd);
1298   
1299   /*get all the properties*/
1300   g_object_get(G_OBJECT(tag),
1301                "family", &font_family, "family-set", &ff_s,
1302                "size", &p_size, "size-set", &size_s,
1303                "foreground-gdk", &fore_color, "foreground-set", &fgc_s,
1304                "weight", &p_weight, "weight-set", &w_s,
1305                "style", &p_style, "style-set", &ss_s,
1306                "underline", &p_underline, "underline-set", &u_s,
1307                "strikethrough", &b_st, "strikethrough-set", &sth_s, 
1308                "rise", &p_rise, "rise-set", & r_s,
1309                NULL);
1310   
1311   /* Check that the given values are valid. 
1312    * If not, set the combobox row indicator to 'inconsistent' */
1313   if(ff_s)
1314     {
1315       gint new_f = -1;
1316       gint i;
1317       
1318       for(i = 0; i < priv->n_families; i++)
1319         {
1320           if(strcmp(font_family, 
1321                     pango_font_family_get_name(priv->families[i])) == 0)
1322             {
1323               new_f = i;
1324               break;
1325             }
1326         }
1327       
1328       if(settings->family == -1)
1329         settings->family = new_f;
1330       else if(settings->family != -2 && 
1331               settings->family != new_f)
1332         settings->family = -2;/*inconsist*/
1333
1334       g_free(font_family);
1335     }
1336   
1337   if(size_s)
1338     {
1339       gint new_size = -1;
1340       gint i;
1341       
1342       for(i = 0; i < G_N_ELEMENTS(font_sizes); i++)
1343         {
1344           if(p_size == font_sizes[i] * PANGO_SCALE)
1345             {
1346               new_size = i;
1347               break;
1348             }
1349         }
1350       
1351       if(settings->size == -1)
1352         settings->size = new_size;
1353       else if(settings->size != -2 && 
1354               settings->size != new_size)
1355         settings->size = -2;/*inconsist*/
1356     }
1357   
1358   if(fgc_s && settings->color == NULL 
1359      && !settings->color_inconsist)
1360         settings->color = fore_color;
1361   else if(fore_color != NULL)
1362     {
1363       if(!gdk_color_equal(fore_color, settings->color) 
1364          && fgc_s)
1365         settings->color_inconsist = TRUE;
1366       
1367       gdk_color_free(fore_color);
1368     }
1369
1370   if(w_s)
1371     settings->weight |= p_weight == PANGO_WEIGHT_NORMAL ? OFF_BIT : ON_BIT;
1372   
1373   if(ss_s)
1374     settings->style |= p_style == PANGO_STYLE_NORMAL ? OFF_BIT : ON_BIT;
1375   
1376   if(u_s)
1377     settings->underline |= 
1378       p_underline == PANGO_UNDERLINE_NONE ? OFF_BIT : ON_BIT;
1379   
1380   if(sth_s)
1381     settings->strikethrough |= b_st ? ON_BIT : OFF_BIT;
1382
1383   if(r_s)
1384     {
1385       gint new_rs = -1;
1386       
1387       if(p_rise == 0)
1388         new_rs = 0;/*normal*/
1389       else if (p_rise > 0)
1390         new_rs = 1;/*super*/
1391       else
1392         new_rs = 2;/*sub*/
1393
1394       if(settings->position == -1)
1395         settings->position = new_rs;
1396       else if(settings->position != -2 && 
1397               settings->position != new_rs)
1398         settings->position = -2;/*inconsist*/
1399     }
1400 }
1401
1402 /* WARNING: This function is called only from deprecated API */
1403 static
1404 void check_attrs(gpointer data, gpointer user_data)
1405 {
1406   PangoAttribute *attr = (PangoAttribute *) data;
1407   HildonFontSelectionDialogSettings *settings = 
1408     (HildonFontSelectionDialogSettings *) user_data;
1409   HildonFontSelectionDialogPrivate *priv = 
1410     HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(settings->fsd);
1411   
1412   gchar *family;
1413   GdkColor color;
1414   gint i;
1415   gint size, weight, style, underline, strikethrough, rise;
1416   gint new_f = -1, new_size = -1, new_rise = -1;
1417
1418   /* Check that the given values are valid.
1419    * If not, set the combobox row indicator to 'inconsistent' */
1420   switch(attr->klass->type)
1421     {
1422     case PANGO_ATTR_FAMILY:
1423       family = ((PangoAttrString *) attr)->value;
1424
1425       for(i = 0; i < priv->n_families; i++)
1426         {
1427           if(strcmp(family, 
1428                     pango_font_family_get_name(priv->families[i])) == 0)
1429             {
1430               new_f = i;
1431               break;
1432             }
1433         }
1434
1435       if(settings->family == -1)
1436         settings->family = new_f;
1437       else if(settings->family != -2 && 
1438               settings->family != new_f)
1439         settings->family = -2;/*inconsist*/
1440       
1441       break;
1442     case PANGO_ATTR_SIZE:
1443       size = ((PangoAttrInt *) attr)->value;
1444       
1445       for(i = 0; i < G_N_ELEMENTS(font_sizes); i++)
1446         {
1447           if(size == font_sizes[i] * PANGO_SCALE)
1448             {
1449               new_size = i;
1450               break;
1451             }
1452         }
1453       
1454       if(settings->size == -1)
1455         settings->size = new_size;
1456       else if(settings->size != -2 && 
1457               settings->size != new_size)
1458         settings->size = -2;/*inconsist*/
1459
1460       break;
1461     case PANGO_ATTR_FOREGROUND:
1462       color.red = ((PangoAttrColor *) attr)->color.red;
1463       color.green = ((PangoAttrColor *) attr)->color.green;
1464       color.blue = ((PangoAttrColor *) attr)->color.blue;
1465
1466       if(!settings->color_inconsist &&  settings->color == NULL)
1467         settings->color = gdk_color_copy(&color);
1468       else if(settings->color != NULL && 
1469               !gdk_color_equal(&color, settings->color))
1470         settings->color_inconsist = TRUE;
1471
1472       break;
1473     case PANGO_ATTR_WEIGHT:
1474       weight = ((PangoAttrInt *) attr)->value;
1475
1476       settings->weight |= weight == PANGO_WEIGHT_NORMAL ? OFF_BIT : ON_BIT;
1477       
1478       break;
1479     case PANGO_ATTR_STYLE:
1480       style = ((PangoAttrInt *) attr)->value;
1481
1482       settings->style |= style == PANGO_STYLE_NORMAL ? OFF_BIT : ON_BIT; 
1483       
1484       break;
1485     case PANGO_ATTR_UNDERLINE:
1486       underline = ((PangoAttrInt *) attr)->value;
1487
1488       settings->underline |= 
1489         underline == PANGO_UNDERLINE_NONE ? OFF_BIT : ON_BIT;
1490   
1491       break;
1492     case PANGO_ATTR_STRIKETHROUGH:
1493       strikethrough = ((PangoAttrInt *) attr)->value;
1494       
1495       settings->strikethrough |= strikethrough ? ON_BIT : OFF_BIT;
1496
1497       break;
1498     case PANGO_ATTR_RISE:
1499       rise = ((PangoAttrInt *) attr)->value;
1500       
1501       if(rise == 0)
1502         new_rise = 0;/*normal*/
1503       else if (rise > 0)
1504         new_rise = 1;/*super*/
1505       else
1506         new_rise = 2;/*sub*/
1507
1508       if(settings->position == -1)
1509         settings->position = new_rise;
1510       else if(settings->position != -2 && 
1511               settings->position != new_rise)
1512         settings->position = -2;/*inconsist*/
1513
1514       break;
1515     default:
1516       break;
1517     }
1518
1519   pango_attribute_destroy(attr);
1520 }
1521
1522 /* WARNING: This function is called only from deprecated API */
1523 static void
1524 settings_init(HildonFontSelectionDialogSettings *settings,
1525               HildonFontSelectionDialog  *fsd)
1526 {
1527   settings->fsd = fsd;
1528   settings->family = -1;
1529   settings->size = -1;
1530   settings->color = NULL;
1531   settings->color_inconsist = FALSE;
1532   settings->weight = 0;
1533   settings->style = 0;
1534   settings->underline = 0;
1535   settings->strikethrough = 0;
1536   settings->position = -1;
1537 }
1538
1539 /* WARNING: This function is called only from deprecated API */
1540 static void
1541 bit_mask_toggle(gint mask, GtkToggleButton *button,
1542                 GObject *object, const gchar *prop,
1543                 const gchar *prop_set)
1544 {
1545   
1546   if(mask == 3)
1547     gtk_toggle_button_set_inconsistent(button, TRUE);
1548   else
1549     {
1550       gtk_toggle_button_set_inconsistent(button, FALSE);
1551
1552       if(mask == 1)
1553         gtk_toggle_button_set_active(button, TRUE);
1554       else
1555         gtk_toggle_button_set_active(button, FALSE);
1556
1557       g_object_notify(object, prop);
1558     }
1559
1560   g_object_notify(object, prop_set);
1561 }
1562
1563 /* WARNING: This function is called only from deprecated API */
1564 static void
1565 combo_active(gint active, GtkComboBox *box, 
1566              GObject *object, const gchar *prop, const gchar *prop_set)
1567 {
1568   /*probaly not the best function, but we need all these
1569    * parameters to keep things together*/
1570  
1571   
1572   if(active >= 0)
1573     {
1574       gtk_combo_box_set_active(box, active);
1575       g_object_notify(object, prop);
1576     }
1577   else
1578     gtk_combo_box_set_active(box, -1);
1579
1580   g_object_notify(object, prop_set);
1581 }
1582
1583 /* WARNING: This function is called only from deprecated API */
1584 static void
1585 settings_apply(HildonFontSelectionDialogSettings *settings)
1586 {
1587
1588   HildonFontSelectionDialogPrivate *priv = 
1589     HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(settings->fsd);
1590   
1591   /*family*/
1592   combo_active(settings->family, GTK_COMBO_BOX(priv->cbx_font_type),
1593                G_OBJECT(settings->fsd), "family", "family-set");
1594   
1595   /*size*/
1596   combo_active(settings->size, GTK_COMBO_BOX(priv->cbx_font_size),
1597                G_OBJECT(settings->fsd), "size", "size-set");
1598   
1599   /*block our signal handler indicating color has been changed by
1600    * the user before set the color, and unblock it after setting
1601    * is done*/
1602   
1603   if(settings->color == NULL || settings->color_inconsist)
1604     {
1605       GdkColor black;
1606
1607       black.red = black.green = black.blue = 0;
1608       g_signal_handler_block((gpointer) priv->font_color_button,
1609                              priv->color_modified_signal_handler);
1610       
1611       g_object_set(G_OBJECT(settings->fsd), "color", &black, "color-set", 
1612                    FALSE, NULL);
1613
1614       g_signal_handler_unblock((gpointer) priv->font_color_button,
1615                                priv->color_modified_signal_handler);
1616     }
1617   else 
1618       g_object_set(G_OBJECT(settings->fsd), "color", settings->color, NULL);
1619   
1620   /*weight*/
1621   bit_mask_toggle(settings->weight, GTK_TOGGLE_BUTTON(priv->chk_bold),
1622                   G_OBJECT(settings->fsd), "bold", "bold-set");
1623   
1624   /*style*/
1625   bit_mask_toggle(settings->style, GTK_TOGGLE_BUTTON(priv->chk_italic),
1626                   G_OBJECT(settings->fsd), "italic", "italic-set");
1627   
1628   /*underline*/
1629   bit_mask_toggle(settings->underline, 
1630                   GTK_TOGGLE_BUTTON(priv->chk_underline), 
1631                   G_OBJECT(settings->fsd), "underline", "underline-set");
1632   
1633   /*strikethrough*/
1634   bit_mask_toggle(settings->strikethrough, 
1635                   GTK_TOGGLE_BUTTON(priv->chk_strikethrough),
1636                   G_OBJECT(settings->fsd), "strikethrough", 
1637                   "strikethrough-set");
1638
1639   /*position*/
1640   combo_active(settings->position, GTK_COMBO_BOX(priv->cbx_positioning),
1641                G_OBJECT(settings->fsd), "position", "position-set");
1642 }
1643
1644 static void
1645 settings_destroy(HildonFontSelectionDialogSettings *settings)
1646 {
1647   if(settings->color != NULL)
1648     gdk_color_free(settings->color);
1649 }
1650
1651 static void
1652 toggle_clicked(GtkButton *button, gpointer unused)
1653 {
1654   GtkToggleButton *t_b = GTK_TOGGLE_BUTTON(button);
1655
1656   /*we have to remove the inconsistent state ourselves*/
1657   if(gtk_toggle_button_get_inconsistent(t_b))
1658     {
1659       gtk_toggle_button_set_inconsistent(t_b, FALSE);
1660       gtk_toggle_button_set_active(t_b, FALSE);
1661     }
1662 }
1663
1664 /*******************/
1665 /*Public functions*/
1666 /*******************/
1667
1668 /**
1669  * hildon_font_selection_dialog_new:
1670  * @parent: the parent window
1671  * @title: the title of font selection dialog
1672  *
1673  * If NULL is passed for title, then default title
1674  * "Font" will be used.
1675  *
1676  * Returns: a new #HildonFontSelectionDialog
1677  */
1678 GtkWidget *
1679 hildon_font_selection_dialog_new(GtkWindow * parent,
1680                                  const gchar * title)
1681 {
1682   HildonFontSelectionDialog *fontseldiag;
1683
1684   fontseldiag = g_object_new(HILDON_TYPE_FONT_SELECTION_DIALOG,
1685                              "has-separator", FALSE, NULL);
1686
1687   if (title)
1688     gtk_window_set_title(GTK_WINDOW(fontseldiag), title);
1689
1690   if (parent)
1691     gtk_window_set_transient_for(GTK_WINDOW(fontseldiag), parent);
1692
1693   return GTK_WIDGET(fontseldiag);
1694 }
1695
1696 /**
1697  * hildon_font_selection_dialog_get_preview_text:
1698  * @fsd: the font selection dialog
1699  *
1700  * Gets the text in preview dialog, which does not include the 
1701  * reference text. The returned string must be freed by the user.
1702  *
1703  * Returns: a string pointer
1704  */
1705 gchar *
1706 hildon_font_selection_dialog_get_preview_text(HildonFontSelectionDialog * fsd)
1707 {
1708   HildonFontSelectionDialogPrivate *priv;
1709
1710   g_return_val_if_fail(HILDON_IS_FONT_SELECTION_DIALOG(fsd), FALSE);
1711   priv = HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(fsd);
1712   return g_strdup(priv->preview_text);
1713 }
1714
1715 /**
1716  * hildon_font_selection_dialog_set_preview_text:
1717  * @fsd: the font selection dialog
1718  * @text: the text to be displayed in the preview dialog
1719  *
1720  * The default preview text is
1721  * "The quick brown fox jumped over the lazy dogs"
1722  */
1723 void
1724 hildon_font_selection_dialog_set_preview_text(HildonFontSelectionDialog *
1725                                               fsd, const gchar * text)
1726 {
1727    HildonFontSelectionDialogPrivate *priv = NULL;
1728    
1729    g_return_if_fail(HILDON_IS_FONT_SELECTION_DIALOG(fsd));
1730    g_return_if_fail(text);
1731   
1732    priv = HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(fsd);
1733    
1734    g_free(priv->preview_text);
1735    priv->preview_text = g_strdup(text);
1736    g_object_notify (G_OBJECT (fsd), "preview-text");
1737 }
1738
1739 /**
1740  * hildon_font_selection_dialog_get_text_tag:
1741  * @fsd: the font selection dialog
1742  *
1743  * Get the #GtkTextTag for selections. This function
1744  * is deprecated. The best way to use
1745  * the text tags is to reuse them as much as possible.
1746  * The recommended way is to get the properties of the font
1747  * selection dialog on GTK_RESPONSE_OK, and according to
1748  * these properties use the tags that you have pre-created.
1749  * 
1750  * Returns: a #GtkTextTag having corresponding properties
1751  * set 
1752  */ 
1753 GtkTextTag * 
1754 hildon_font_selection_dialog_get_text_tag (HildonFontSelectionDialog *fsd)
1755 {
1756   GtkTextTag *tag;
1757   gint size, position;
1758   gboolean family_set, size_set, color_set, bold, bold_set,
1759            italic, italic_set, underline, underline_set,
1760            strikethrough, strikethrough_set, position_set;
1761   GdkColor *color = NULL;
1762   gchar *family = NULL;
1763
1764   tag = gtk_text_tag_new(NULL);
1765   
1766   g_object_get(G_OBJECT(fsd),
1767                "family", &family, "family-set", &family_set,
1768                "size", &size, "size-set", &size_set,
1769                "color", &color, "color-set", &color_set,
1770                "bold", &bold, "bold-set", &bold_set,
1771                "italic", &italic, "italic-set", &italic_set,
1772                "underline", &underline, "underline-set", &underline_set,
1773                "strikethrough", &strikethrough, "strikethrough-set", 
1774                &strikethrough_set, "position", &position, 
1775                "position-set", &position_set, NULL);
1776   /*family*/
1777   if(family_set)
1778     g_object_set(G_OBJECT(tag), "family",
1779                  family, "family-set", TRUE, NULL);
1780   else
1781     g_object_set(G_OBJECT(tag), "family-set", FALSE, NULL);
1782
1783   g_free(family);
1784   
1785   /*size*/
1786   if(size_set)
1787     g_object_set(G_OBJECT(tag), "size", size * PANGO_SCALE, 
1788                  "size-set", TRUE, NULL);
1789   else
1790     g_object_set(G_OBJECT(tag), "size-set", FALSE, NULL);
1791   
1792   /*color*/
1793   if(color_set)
1794     g_object_set(G_OBJECT(tag), "foreground-gdk", color, 
1795                  "foreground-set", TRUE ,NULL);
1796   else
1797     g_object_set(G_OBJECT(tag), "foreground-set", FALSE, NULL);
1798
1799   if(color != NULL)
1800     gdk_color_free(color);
1801   
1802   /*weight*/
1803   if(bold_set)
1804     {
1805       if(bold)
1806         g_object_set(G_OBJECT(tag), "weight", PANGO_WEIGHT_BOLD, NULL);
1807       else
1808         g_object_set(G_OBJECT(tag), "weight", PANGO_WEIGHT_NORMAL, NULL);
1809         
1810       g_object_set(G_OBJECT(tag), "weight-set", TRUE, NULL);
1811     }
1812   else
1813     g_object_set(G_OBJECT(tag), "weight-set", FALSE, NULL);
1814   
1815   /*style*/
1816   if(italic_set)
1817     {
1818       if(italic)
1819         g_object_set(G_OBJECT(tag), "style", PANGO_STYLE_ITALIC, NULL);
1820       else
1821         g_object_set(G_OBJECT(tag), "style", PANGO_STYLE_NORMAL, NULL);
1822         
1823       g_object_set(G_OBJECT(tag), "style-set", TRUE, NULL);
1824     }
1825   else
1826     g_object_set(G_OBJECT(tag), "style-set", FALSE, NULL);
1827   
1828   /*underline*/
1829   if(underline_set)
1830     {
1831       if(underline)
1832         g_object_set(G_OBJECT(tag), "underline", PANGO_UNDERLINE_SINGLE, NULL);
1833       else
1834         g_object_set(G_OBJECT(tag), "underline", PANGO_UNDERLINE_NONE, NULL);
1835         
1836       g_object_set(G_OBJECT(tag), "underline-set", TRUE, NULL);
1837     }
1838   else
1839     g_object_set(G_OBJECT(tag), "underline-set", FALSE, NULL);
1840   
1841   /*strikethrough*/
1842   if(strikethrough_set)
1843     {
1844       if(strikethrough)
1845         g_object_set(G_OBJECT(tag), "strikethrough", TRUE, NULL);
1846       else
1847         g_object_set(G_OBJECT(tag), "strikethrough", FALSE, NULL);
1848         
1849       g_object_set(G_OBJECT(tag), "strikethrough-set", TRUE, NULL);
1850     }
1851   else
1852     g_object_set(G_OBJECT(tag), "strikethrough-set", FALSE, NULL);
1853   
1854   /*position*/
1855   if(position_set)
1856     {
1857       switch(position)
1858         {
1859         case 1: /*super*/
1860           g_object_set(G_OBJECT(tag), "rise", SUPERSCRIPT_RISE, NULL);
1861           break;
1862         case -1: /*sub*/
1863           g_object_set(G_OBJECT(tag), "rise", SUBSCRIPT_LOW, NULL);
1864           break;
1865         case 0: /*normal*/
1866           g_object_set(G_OBJECT(tag), "rise", 0, NULL);
1867           break;
1868         }
1869       g_object_set(G_OBJECT(tag), "rise-set", TRUE, NULL);
1870     }
1871   else
1872     g_object_set(G_OBJECT(tag), "rise-set", FALSE, NULL);
1873   
1874   return tag;
1875 }
1876
1877 /** 
1878  * hildon_font_selection_dialog_set_buffer:
1879  * @fsd: the font selection dialog
1880  * @buffer: a #GtkTextBuffer containing the text to which the selections will 
1881  * be applied. Applying is responsibility of application.
1882  *
1883  * This is deprecated. GtkTextBuffer is not enough
1884  * to get the attributes of currently selected text. Please 
1885  * inspect the attributes yourself, and set the properties of
1886  * font selection dialog to reflect your inspection.
1887  */
1888 void 
1889 hildon_font_selection_dialog_set_buffer (HildonFontSelectionDialog *fsd,
1890                                          GtkTextBuffer *buffer)
1891 {
1892   GtkTextIter begin, end, iter;
1893   HildonFontSelectionDialogSettings settings;
1894
1895   gtk_text_buffer_get_selection_bounds(buffer, &begin, &end);
1896   
1897   settings_init(&settings, fsd);
1898   
1899   iter = begin;
1900
1901   /* Keep original settings if the selection includes nothing */ 
1902   if(gtk_text_iter_compare(&iter, &end) == 0)
1903     {
1904       GSList *slist;
1905       
1906       slist = gtk_text_iter_get_tags(&iter);
1907       g_slist_foreach(slist, check_tags, (gpointer) &settings);
1908       g_slist_free(slist);
1909     }
1910
1911   /* Apply the user settings to the selected text */
1912   while(gtk_text_iter_compare(&iter, &end) < 0)
1913     {
1914       GSList *slist;
1915       
1916       slist = gtk_text_iter_get_tags(&iter);
1917       g_slist_foreach(slist, check_tags, (gpointer) &settings);
1918       g_slist_free(slist);
1919       
1920       if(!gtk_text_iter_forward_cursor_position(&iter))
1921         break;
1922     }
1923
1924   settings_apply(&settings);
1925   settings_destroy(&settings);
1926 }
1927
1928 /**
1929  * hildon_font_selection_dialog_get_font:
1930  * @fsd: the font selection dialog
1931  *
1932  * This is deprecated. @PangoAttrList needs
1933  * starting index, and end index on construction.
1934  *
1935  * Returns: pointer to @PangoAttrList
1936  */
1937 PangoAttrList
1938 *hildon_font_selection_dialog_get_font(HildonFontSelectionDialog * fsd)
1939 {
1940   HildonFontSelectionDialogPrivate *priv
1941     = HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(fsd);
1942   
1943   g_return_val_if_fail(HILDON_IS_FONT_SELECTION_DIALOG(fsd), FALSE);
1944   /*an approve of none working api, should have ask for start_index,
1945    * and length in bytes of the string, currently using preview_text 
1946    * length, KLUDGE!*/
1947   
1948   return hildon_font_selection_dialog_create_attrlist(fsd, 
1949                                 0, strlen(priv->preview_text));
1950 }
1951
1952 /**
1953  * hildon_font_selection_dialog_set_font:
1954  * @fsd: the font selection dialog
1955  * @list: the pango attribute list
1956  *
1957  * This is a deprecated.
1958  * 
1959  * Sets the font to the dialog.
1960  */
1961 void 
1962 hildon_font_selection_dialog_set_font(HildonFontSelectionDialog * fsd,
1963                                       PangoAttrList * list)
1964 {
1965   PangoAttrIterator *iter;
1966   HildonFontSelectionDialogSettings settings;
1967
1968   iter = pango_attr_list_get_iterator(list);
1969   
1970   settings_init(&settings, fsd);
1971   
1972   while(iter != NULL)
1973     {
1974       GSList *slist;
1975       
1976       slist = pango_attr_iterator_get_attrs(iter);
1977       g_slist_foreach(slist, check_attrs, (gpointer) &settings);
1978       g_slist_free(slist);
1979       
1980       if(!pango_attr_iterator_next(iter))
1981         break;
1982     }
1983
1984   pango_attr_iterator_destroy(iter);
1985
1986   settings_apply(&settings);
1987   settings_destroy(&settings);
1988 }