]> Pileus Git - ~andy/gtk/blob - gtk/gtkcellrenderertext.c
fix some shell typos
[~andy/gtk] / gtk / gtkcellrenderertext.c
1 /* gtkcellrenderertext.c
2  * Copyright (C) 2000  Red Hat, Inc.,  Jonathan Blandford <jrb@redhat.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #include <stdlib.h>
21 #include "gtkcellrenderertext.h"
22 #include "gtkintl.h"
23
24 static void gtk_cell_renderer_text_init       (GtkCellRendererText      *celltext);
25 static void gtk_cell_renderer_text_class_init (GtkCellRendererTextClass *class);
26 static void gtk_cell_renderer_text_finalize   (GObject                  *object);
27
28 static void gtk_cell_renderer_text_get_property  (GObject                  *object,
29                                                   guint                     param_id,
30                                                   GValue                   *value,
31                                                   GParamSpec               *pspec);
32 static void gtk_cell_renderer_text_set_property  (GObject                  *object,
33                                                   guint                     param_id,
34                                                   const GValue             *value,
35                                                   GParamSpec               *pspec);
36 static void gtk_cell_renderer_text_get_size   (GtkCellRenderer          *cell,
37                                                GtkWidget                *widget,
38                                                GdkRectangle             *cell_area,
39                                                gint                     *x_offset,
40                                                gint                     *y_offset,
41                                                gint                     *width,
42                                                gint                     *height);
43 static void gtk_cell_renderer_text_render     (GtkCellRenderer          *cell,
44                                                GdkWindow                *window,
45                                                GtkWidget                *widget,
46                                                GdkRectangle             *background_area,
47                                                GdkRectangle             *cell_area,
48                                                GdkRectangle             *expose_area,
49                                                guint                     flags);
50
51
52
53 enum {
54   PROP_0,
55
56   PROP_TEXT,
57   PROP_MARKUP,
58   
59   /* Style args */
60   PROP_BACKGROUND,
61   PROP_FOREGROUND,
62   PROP_BACKGROUND_GDK,
63   PROP_FOREGROUND_GDK,
64   PROP_FONT,
65   PROP_FONT_DESC,
66   PROP_FAMILY,
67   PROP_STYLE,
68   PROP_VARIANT,
69   PROP_WEIGHT,
70   PROP_STRETCH,
71   PROP_SIZE,
72   PROP_SIZE_POINTS,
73   PROP_SCALE,
74   PROP_EDITABLE,
75   PROP_STRIKETHROUGH,
76   PROP_UNDERLINE,
77   PROP_RISE,
78   
79   /* Whether-a-style-arg-is-set args */
80   PROP_BACKGROUND_SET,
81   PROP_FOREGROUND_SET,
82   PROP_FAMILY_SET,
83   PROP_STYLE_SET,
84   PROP_VARIANT_SET,
85   PROP_WEIGHT_SET,
86   PROP_STRETCH_SET,
87   PROP_SIZE_SET,
88   PROP_SCALE_SET,
89   PROP_EDITABLE_SET,
90   PROP_STRIKETHROUGH_SET,
91   PROP_UNDERLINE_SET,
92   PROP_RISE_SET
93 };
94
95 static gpointer parent_class;
96
97 GtkType
98 gtk_cell_renderer_text_get_type (void)
99 {
100   static GtkType cell_text_type = 0;
101
102   if (!cell_text_type)
103     {
104       static const GTypeInfo cell_text_info =
105       {
106         sizeof (GtkCellRendererTextClass),
107         NULL,           /* base_init */
108         NULL,           /* base_finalize */
109         (GClassInitFunc) gtk_cell_renderer_text_class_init,
110         NULL,           /* class_finalize */
111         NULL,           /* class_data */
112         sizeof (GtkCellRendererText),
113         0,              /* n_preallocs */
114         (GInstanceInitFunc) gtk_cell_renderer_text_init,
115       };
116
117       cell_text_type = g_type_register_static (GTK_TYPE_CELL_RENDERER, "GtkCellRendererText", &cell_text_info, 0);
118     }
119
120   return cell_text_type;
121 }
122
123 static void
124 gtk_cell_renderer_text_init (GtkCellRendererText *celltext)
125 {
126   GTK_CELL_RENDERER (celltext)->xalign = 0.0;
127   GTK_CELL_RENDERER (celltext)->yalign = 0.5;
128   GTK_CELL_RENDERER (celltext)->xpad = 2;
129   GTK_CELL_RENDERER (celltext)->ypad = 2;
130 }
131
132 static void
133 gtk_cell_renderer_text_class_init (GtkCellRendererTextClass *class)
134 {
135   GObjectClass *object_class = G_OBJECT_CLASS (class);
136   GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (class);
137
138   parent_class = g_type_class_peek_parent (class);
139   
140   object_class->finalize = gtk_cell_renderer_text_finalize;
141   
142   object_class->get_property = gtk_cell_renderer_text_get_property;
143   object_class->set_property = gtk_cell_renderer_text_set_property;
144
145   cell_class->get_size = gtk_cell_renderer_text_get_size;
146   cell_class->render = gtk_cell_renderer_text_render;
147
148   g_object_class_install_property (object_class,
149                                    PROP_TEXT,
150                                    g_param_spec_string ("text",
151                                                         _("Text"),
152                                                         _("Text to render"),
153                                                         NULL,
154                                                         G_PARAM_READWRITE));
155   
156   g_object_class_install_property (object_class,
157                                    PROP_MARKUP,
158                                    g_param_spec_string ("markup",
159                                                         _("Markup"),
160                                                         _("Marked up text to render"),
161                                                         NULL,
162                                                         G_PARAM_WRITABLE));
163   
164   g_object_class_install_property (object_class,
165                                    PROP_BACKGROUND,
166                                    g_param_spec_string ("background",
167                                                         _("Background color name"),
168                                                         _("Background color as a string"),
169                                                         NULL,
170                                                         G_PARAM_WRITABLE));
171
172   g_object_class_install_property (object_class,
173                                    PROP_BACKGROUND_GDK,
174                                    g_param_spec_boxed ("background_gdk",
175                                                        _("Background color"),
176                                                        _("Background color as a GdkColor"),
177                                                        GDK_TYPE_COLOR,
178                                                        G_PARAM_READABLE | G_PARAM_WRITABLE));  
179
180   g_object_class_install_property (object_class,
181                                    PROP_FOREGROUND,
182                                    g_param_spec_string ("foreground",
183                                                         _("Foreground color name"),
184                                                         _("Foreground color as a string"),
185                                                         NULL,
186                                                         G_PARAM_WRITABLE));
187
188   g_object_class_install_property (object_class,
189                                    PROP_FOREGROUND_GDK,
190                                    g_param_spec_boxed ("foreground_gdk",
191                                                        _("Foreground color"),
192                                                        _("Foreground color as a GdkColor"),
193                                                        GDK_TYPE_COLOR,
194                                                        G_PARAM_READABLE | G_PARAM_WRITABLE));
195
196
197   g_object_class_install_property (object_class,
198                                    PROP_EDITABLE,
199                                    g_param_spec_boolean ("editable",
200                                                          _("Editable"),
201                                                          _("Whether the text can be modified by the user"),
202                                                          TRUE,
203                                                          G_PARAM_READABLE | G_PARAM_WRITABLE));
204
205   g_object_class_install_property (object_class,
206                                    PROP_FONT,
207                                    g_param_spec_string ("font",
208                                                         _("Font"),
209                                                         _("Font description as a string"),
210                                                         NULL,
211                                                         G_PARAM_READABLE | G_PARAM_WRITABLE));
212
213   g_object_class_install_property (object_class,
214                                    PROP_FONT_DESC,
215                                    g_param_spec_boxed ("font_desc",
216                                                        _("Font"),
217                                                        _("Font description as a PangoFontDescription struct"),
218                                                        GTK_TYPE_PANGO_FONT_DESCRIPTION,
219                                                        G_PARAM_READABLE | G_PARAM_WRITABLE));
220
221   
222   g_object_class_install_property (object_class,
223                                    PROP_FAMILY,
224                                    g_param_spec_string ("family",
225                                                         _("Font family"),
226                                                         _("Name of the font family, e.g. Sans, Helvetica, Times, Monospace"),
227                                                         NULL,
228                                                         G_PARAM_READABLE | G_PARAM_WRITABLE));
229
230   g_object_class_install_property (object_class,
231                                    PROP_STYLE,
232                                    g_param_spec_enum ("style",
233                                                       _("Font style"),
234                                                       _("Font style"),
235                                                       PANGO_TYPE_STYLE,
236                                                       PANGO_STYLE_NORMAL,
237                                                       G_PARAM_READABLE | G_PARAM_WRITABLE));
238
239   g_object_class_install_property (object_class,
240                                    PROP_VARIANT,
241                                    g_param_spec_enum ("variant",
242                                                      _("Font variant"),
243                                                      _("Font variant"),
244                                                       PANGO_TYPE_VARIANT,
245                                                       PANGO_VARIANT_NORMAL,
246                                                       G_PARAM_READABLE | G_PARAM_WRITABLE));
247   
248   g_object_class_install_property (object_class,
249                                    PROP_WEIGHT,
250                                    g_param_spec_int ("weight",
251                                                      _("Font weight"),
252                                                      _("Font weight"),
253                                                      0,
254                                                      G_MAXINT,
255                                                      PANGO_WEIGHT_NORMAL,
256                                                      G_PARAM_READABLE | G_PARAM_WRITABLE));
257   
258
259   g_object_class_install_property (object_class,
260                                    PROP_STRETCH,
261                                    g_param_spec_enum ("stretch",
262                                                       _("Font stretch"),
263                                                       _("Font stretch"),
264                                                       PANGO_TYPE_STRETCH,
265                                                       PANGO_STRETCH_NORMAL,
266                                                       G_PARAM_READABLE | G_PARAM_WRITABLE));
267   
268   g_object_class_install_property (object_class,
269                                    PROP_SIZE,
270                                    g_param_spec_int ("size",
271                                                      _("Font size"),
272                                                      _("Font size"),
273                                                      0,
274                                                      G_MAXINT,
275                                                      0,
276                                                      G_PARAM_READABLE | G_PARAM_WRITABLE));
277
278   g_object_class_install_property (object_class,
279                                    PROP_SIZE_POINTS,
280                                    g_param_spec_double ("size_points",
281                                                         _("Font points"),
282                                                         _("Font size in points"),
283                                                         0.0,
284                                                         G_MAXDOUBLE,
285                                                         0.0,
286                                                         G_PARAM_READABLE | G_PARAM_WRITABLE));  
287
288   g_object_class_install_property (object_class,
289                                    PROP_SCALE,
290                                    g_param_spec_double ("scale",
291                                                         _("Font scale"),
292                                                         _("Font scaling factor"),
293                                                         0.0,
294                                                         G_MAXDOUBLE,
295                                                         1.0,
296                                                         G_PARAM_READABLE | G_PARAM_WRITABLE));
297   
298   g_object_class_install_property (object_class,
299                                    PROP_RISE,
300                                    g_param_spec_int ("rise",
301                                                      _("Rise"),
302                                                      _("Offset of text above the baseline (below the baseline if rise is negative)"),
303                                                      -G_MAXINT,
304                                                      G_MAXINT,
305                                                      0,
306                                                      G_PARAM_READABLE | G_PARAM_WRITABLE));
307
308
309   g_object_class_install_property (object_class,
310                                    PROP_STRIKETHROUGH,
311                                    g_param_spec_boolean ("strikethrough",
312                                                          _("Strikethrough"),
313                                                          _("Whether to strike through the text"),
314                                                          FALSE,
315                                                          G_PARAM_READABLE | G_PARAM_WRITABLE));
316   
317   g_object_class_install_property (object_class,
318                                    PROP_UNDERLINE,
319                                    g_param_spec_enum ("underline",
320                                                       _("Underline"),
321                                                       _("Style of underline for this text"),
322                                                       PANGO_TYPE_UNDERLINE,
323                                                       PANGO_UNDERLINE_NONE,
324                                                       G_PARAM_READABLE | G_PARAM_WRITABLE));
325
326   /* Style props are set or not */
327
328 #define ADD_SET_PROP(propname, propval, nick, blurb) g_object_class_install_property (object_class, propval, g_param_spec_boolean (propname, nick, blurb, FALSE, G_PARAM_READABLE | G_PARAM_WRITABLE))
329
330   ADD_SET_PROP ("background_set", PROP_BACKGROUND_SET,
331                 _("Background set"),
332                 _("Whether this tag affects the background color"));
333
334   ADD_SET_PROP ("foreground_set", PROP_FOREGROUND_SET,
335                 _("Foreground set"),
336                 _("Whether this tag affects the foreground color"));
337   
338   ADD_SET_PROP ("editable_set", PROP_EDITABLE_SET,
339                 _("Editability set"),
340                 _("Whether this tag affects text editability"));
341
342   ADD_SET_PROP ("family_set", PROP_FAMILY_SET,
343                 _("Font family set"),
344                 _("Whether this tag affects the font family"));  
345
346   ADD_SET_PROP ("style_set", PROP_STYLE_SET,
347                 _("Font style set"),
348                 _("Whether this tag affects the font style"));
349
350   ADD_SET_PROP ("variant_set", PROP_VARIANT_SET,
351                 _("Font variant set"),
352                 _("Whether this tag affects the font variant"));
353
354   ADD_SET_PROP ("weight_set", PROP_WEIGHT_SET,
355                 _("Font weight set"),
356                 _("Whether this tag affects the font weight"));
357
358   ADD_SET_PROP ("stretch_set", PROP_STRETCH_SET,
359                 _("Font stretch set"),
360                 _("Whether this tag affects the font stretch"));
361
362   ADD_SET_PROP ("size_set", PROP_SIZE_SET,
363                 _("Font size set"),
364                 _("Whether this tag affects the font size"));
365
366   ADD_SET_PROP ("scale_set", PROP_SCALE_SET,
367                 _("Font scale set"),
368                 _("Whether this tag scales the font size by a factor"));
369   
370   ADD_SET_PROP ("rise_set", PROP_RISE_SET,
371                 _("Rise set"),
372                 _("Whether this tag affects the rise"));
373
374   ADD_SET_PROP ("strikethrough_set", PROP_STRIKETHROUGH_SET,
375                 _("Strikethrough set"),
376                 _("Whether this tag affects strikethrough"));
377
378   ADD_SET_PROP ("underline_set", PROP_UNDERLINE_SET,
379                 _("Underline set"),
380                 _("Whether this tag affects underlining"));
381 }
382
383 static void
384 gtk_cell_renderer_text_finalize (GObject *object)
385 {
386   GtkCellRendererText *celltext = GTK_CELL_RENDERER_TEXT (object);
387
388   if (celltext->font.family_name)
389     g_free (celltext->font.family_name);
390
391   if (celltext->text)
392     g_free (celltext->text);
393
394   if (celltext->extra_attrs)
395     pango_attr_list_unref (celltext->extra_attrs);
396
397   (* G_OBJECT_CLASS (parent_class)->finalize) (object);
398 }
399
400 static void
401 gtk_cell_renderer_text_get_property (GObject        *object,
402                                      guint           param_id,
403                                      GValue         *value,
404                                      GParamSpec     *pspec)
405 {
406   GtkCellRendererText *celltext = GTK_CELL_RENDERER_TEXT (object);
407
408   switch (param_id)
409     {
410     case PROP_TEXT:
411       g_value_set_string (value, celltext->text);
412       break;
413       
414     case PROP_BACKGROUND_GDK:
415       {
416         GdkColor color;
417         
418         color.red = celltext->background.red;
419         color.green = celltext->background.green;
420         color.blue = celltext->background.blue;
421         
422         g_value_set_boxed (value, &color);
423       }
424       break;
425
426     case PROP_FOREGROUND_GDK:
427       {
428         GdkColor color;
429         
430         color.red = celltext->foreground.red;
431         color.green = celltext->foreground.green;
432         color.blue = celltext->foreground.blue;
433         
434         g_value_set_boxed (value, &color);
435       }
436       break;
437
438     case PROP_FONT:
439       {
440         /* FIXME GValue imposes a totally gratuitous string copy
441          * here, we could just hand off string ownership
442          */
443         gchar *str = pango_font_description_to_string (&celltext->font);
444         g_value_set_string (value, str);
445         g_free (str);
446       }
447       break;
448       
449     case PROP_FONT_DESC:
450       g_value_set_boxed (value, &celltext->font);
451       break;
452
453     case PROP_FAMILY:
454       g_value_set_string (value, celltext->font.family_name);
455       break;
456
457     case PROP_STYLE:
458       g_value_set_enum (value, celltext->font.style);
459       break;
460
461     case PROP_VARIANT:
462       g_value_set_enum (value, celltext->font.variant);
463       break;
464
465     case PROP_WEIGHT:
466       g_value_set_int (value, celltext->font.weight);
467       break;
468
469     case PROP_STRETCH:
470       g_value_set_enum (value, celltext->font.stretch);
471       break;
472
473     case PROP_SIZE:
474       g_value_set_int (value, celltext->font.size);
475       break;
476
477     case PROP_SIZE_POINTS:
478       g_value_set_double (value, ((double)celltext->font.size) / (double)PANGO_SCALE);
479       break;
480
481     case PROP_SCALE:
482       g_value_set_double (value, celltext->font_scale);
483       break;
484       
485     case PROP_EDITABLE:
486       g_value_set_boolean (value, celltext->editable);
487       break;
488
489     case PROP_STRIKETHROUGH:
490       g_value_set_boolean (value, celltext->strikethrough);
491       break;
492
493     case PROP_UNDERLINE:
494       g_value_set_enum (value, celltext->underline_style);
495       break;
496
497     case PROP_RISE:
498       g_value_set_int (value, celltext->rise);
499       break;  
500
501     case PROP_BACKGROUND_SET:
502       g_value_set_boolean (value, celltext->background_set);
503       break;
504
505     case PROP_FOREGROUND_SET:
506       g_value_set_boolean (value, celltext->foreground_set);
507       break;
508
509     case PROP_FAMILY_SET:
510       g_value_set_boolean (value, celltext->family_set);
511       break;
512
513     case PROP_STYLE_SET:
514       g_value_set_boolean (value, celltext->style_set);
515       break;
516
517     case PROP_VARIANT_SET:
518       g_value_set_boolean (value, celltext->variant_set);
519       break;
520
521     case PROP_WEIGHT_SET:
522       g_value_set_boolean (value, celltext->weight_set);
523       break;
524
525     case PROP_STRETCH_SET:
526       g_value_set_boolean (value, celltext->stretch_set);
527       break;
528
529     case PROP_SIZE_SET:
530       g_value_set_boolean (value, celltext->size_set);
531       break;
532
533     case PROP_SCALE_SET:
534       g_value_set_boolean (value, celltext->scale_set);
535       break;
536       
537     case PROP_EDITABLE_SET:
538       g_value_set_boolean (value, celltext->editable_set);
539       break;
540
541     case PROP_STRIKETHROUGH_SET:
542       g_value_set_boolean (value, celltext->strikethrough_set);
543       break;
544
545     case PROP_UNDERLINE_SET:
546       g_value_set_boolean (value, celltext->underline_set);
547       break;
548
549     case  PROP_RISE_SET:
550       g_value_set_boolean (value, celltext->rise_set);
551       break;
552       
553     case PROP_BACKGROUND:
554     case PROP_FOREGROUND:
555     case PROP_MARKUP:
556     default:
557       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
558       break;
559     }
560 }
561
562
563 static void
564 set_bg_color (GtkCellRendererText *celltext,
565               GdkColor            *color)
566 {
567   if (color)
568     {
569       if (!celltext->background_set)
570         {
571           celltext->background_set = TRUE;
572           g_object_notify (G_OBJECT (celltext), "background_set");
573         }
574       
575       celltext->background.red = color->red;
576       celltext->background.green = color->green;
577       celltext->background.blue = color->blue;
578     }
579   else
580     {
581       if (celltext->background_set)
582         {
583           celltext->background_set = FALSE;
584           g_object_notify (G_OBJECT (celltext), "background_set");
585         }
586     }
587 }
588
589
590 static void
591 set_fg_color (GtkCellRendererText *celltext,
592               GdkColor            *color)
593 {
594   if (color)
595     {
596       if (!celltext->foreground_set)
597         {
598           celltext->foreground_set = TRUE;
599           g_object_notify (G_OBJECT (celltext), "foreground_set");
600         }
601       
602       celltext->foreground.red = color->red;
603       celltext->foreground.green = color->green;
604       celltext->foreground.blue = color->blue;
605     }
606   else
607     {
608       if (celltext->foreground_set)
609         {
610           celltext->foreground_set = FALSE;
611           g_object_notify (G_OBJECT (celltext), "foreground_set");
612         }
613     }
614 }
615
616 static void
617 set_font_description (GtkCellRendererText  *celltext,
618                       PangoFontDescription *font_desc)
619 {
620   if (font_desc != NULL)
621     {
622       /* pango_font_description_from_string() will sometimes return
623        * a NULL family or -1 size, so handle those cases.
624        */
625       
626       if (font_desc->family_name)
627         g_object_set (G_OBJECT (celltext),
628                       "family", font_desc->family_name,
629                       NULL);
630       
631       if (font_desc->size >= 0)
632         g_object_set (G_OBJECT (celltext),
633                       "size", font_desc->size,
634                       NULL);
635         
636       g_object_set (G_OBJECT (celltext),
637                     "style", font_desc->style,
638                     "variant", font_desc->variant,
639                     "weight", font_desc->weight,
640                     "stretch", font_desc->stretch,
641                     NULL);
642     }
643   else
644     {
645       if (celltext->family_set)
646         {
647           celltext->family_set = FALSE;
648           g_object_notify (G_OBJECT (celltext), "family_set");
649         }
650       if (celltext->style_set)
651         {
652           celltext->style_set = FALSE;
653           g_object_notify (G_OBJECT (celltext), "style_set");
654         }
655       if (celltext->variant_set)
656         {
657           celltext->variant_set = FALSE;
658           g_object_notify (G_OBJECT (celltext), "variant_set");
659         }
660       if (celltext->weight_set)
661         {
662           celltext->weight_set = FALSE;
663           g_object_notify (G_OBJECT (celltext), "weight_set");
664         }
665       if (celltext->stretch_set)
666         {
667           celltext->stretch_set = FALSE;
668           g_object_notify (G_OBJECT (celltext), "stretch_set");
669         }
670       if (celltext->size_set)
671         {
672           celltext->size_set = FALSE;
673           g_object_notify (G_OBJECT (celltext), "size_set");
674         }
675     }
676 }
677
678 static void
679 gtk_cell_renderer_text_set_property (GObject      *object,
680                                      guint         param_id,
681                                      const GValue *value,
682                                      GParamSpec   *pspec)
683 {
684   GtkCellRendererText *celltext = GTK_CELL_RENDERER_TEXT (object);
685
686   switch (param_id)
687     {
688     case PROP_TEXT:
689       if (celltext->text)
690         g_free (celltext->text);
691       celltext->text = g_strdup (g_value_get_string (value));
692       g_object_notify(G_OBJECT(object), "text");
693       break;
694       
695     case PROP_MARKUP:
696       {
697         const gchar *str;
698         gchar *text = NULL;
699         GError *error = NULL;
700         PangoAttrList *attrs = NULL;
701         
702         if (celltext->text)
703           g_free (celltext->text);
704
705         if (celltext->extra_attrs)
706           pango_attr_list_unref (celltext->extra_attrs);
707
708         str = g_value_get_string (value);
709         if (str && !pango_parse_markup (str,
710                                         -1,
711                                         0,
712                                         &attrs,
713                                         &text,
714                                         NULL,
715                                         &error))
716           {
717             g_warning ("Failed to set cell text from markup due to error parsing markup: %s",
718                        error->message);
719             g_error_free (error);
720             return;
721           }
722         
723         celltext->text = text;
724         celltext->extra_attrs = attrs;
725       }
726       break;
727       
728     case PROP_BACKGROUND:
729       {
730         GdkColor color;
731
732         if (!g_value_get_string (value))
733           set_bg_color (celltext, NULL);       /* reset to backgrounmd_set to FALSE */
734         else if (gdk_color_parse (g_value_get_string (value), &color))
735           set_bg_color (celltext, &color);
736         else
737           g_warning ("Don't know color `%s'", g_value_get_string (value));
738
739         g_object_notify (G_OBJECT (celltext), "background_gdk");
740       }
741       break;
742       
743     case PROP_FOREGROUND:
744       {
745         GdkColor color;
746
747         if (!g_value_get_string (value))
748           set_fg_color (celltext, NULL);       /* reset to foreground_set to FALSE */
749         else if (gdk_color_parse (g_value_get_string (value), &color))
750           set_fg_color (celltext, &color);
751         else
752           g_warning ("Don't know color `%s'", g_value_get_string (value));
753
754         g_object_notify (G_OBJECT (celltext), "foreground_gdk");
755       }
756       break;
757
758     case PROP_BACKGROUND_GDK:
759       /* This notifies the GObject itself. */
760       set_bg_color (celltext, g_value_get_boxed (value));
761       break;
762
763     case PROP_FOREGROUND_GDK:
764       /* This notifies the GObject itself. */
765       set_fg_color (celltext, g_value_get_boxed (value));
766       break;
767
768     case PROP_FONT:
769       {
770         PangoFontDescription *font_desc = NULL;
771         const gchar *name;
772
773         name = g_value_get_string (value);
774
775         if (name)
776           font_desc = pango_font_description_from_string (name);
777
778         /* This function notifies the relevant GObjects itself.
779          * I'm not sure how useful the notify() on 'font'
780          * actually is here, but it's here for consistency.
781          */
782         set_font_description (celltext, font_desc);
783         g_object_notify(G_OBJECT(object), "font_desc");
784         g_object_notify(G_OBJECT(object), "font");
785         
786         if (font_desc)
787           pango_font_description_free (font_desc);
788       }
789       break;
790
791     case PROP_FONT_DESC:
792       set_font_description (celltext, g_value_get_boxed (value));
793       break;
794
795     case PROP_FAMILY:
796       if (celltext->font.family_name)
797         g_free (celltext->font.family_name);
798       celltext->font.family_name = g_strdup (g_value_get_string (value));
799
800       celltext->family_set = TRUE;
801       g_object_notify (G_OBJECT (celltext), "family_set");
802       g_object_notify (G_OBJECT (celltext), "font_desc");
803       g_object_notify (G_OBJECT (celltext), "font");
804       break;
805
806     case PROP_STYLE:
807       celltext->font.style = g_value_get_enum (value);
808
809       celltext->style_set = TRUE;
810       g_object_notify (G_OBJECT (celltext), "style_set");
811       g_object_notify (G_OBJECT (celltext), "font_desc");
812       g_object_notify (G_OBJECT (celltext), "font");
813       break;
814
815     case PROP_VARIANT:
816       celltext->font.variant = g_value_get_enum (value);
817
818       celltext->variant_set = TRUE;
819       g_object_notify (G_OBJECT (celltext), "variant_set");
820       g_object_notify (G_OBJECT (celltext), "font_desc");
821       g_object_notify (G_OBJECT (celltext), "font");
822       break;
823
824     case PROP_WEIGHT:
825       celltext->font.weight = g_value_get_int (value);
826       
827       celltext->weight_set = TRUE;
828       g_object_notify (G_OBJECT (celltext), "weight_set");
829       g_object_notify (G_OBJECT (celltext), "font_desc");
830       g_object_notify (G_OBJECT (celltext), "font");
831       break;
832
833     case PROP_STRETCH:
834       celltext->font.stretch = g_value_get_enum (value);
835
836       celltext->stretch_set = TRUE;
837       g_object_notify (G_OBJECT (celltext), "stretch_set");
838       g_object_notify (G_OBJECT (celltext), "font_desc");
839       g_object_notify (G_OBJECT (celltext), "font");
840       break;
841
842     case PROP_SIZE:
843       celltext->font.size = g_value_get_int (value);
844
845       celltext->size_set = TRUE;
846       g_object_notify (G_OBJECT (celltext), "size_set");
847       g_object_notify (G_OBJECT (celltext), "font_desc");
848       g_object_notify (G_OBJECT (celltext), "font");
849       break;
850
851     case PROP_SCALE:
852       celltext->font_scale = g_value_get_double (value);
853       celltext->scale_set = TRUE;
854       break;
855       
856     case PROP_SIZE_POINTS:
857       celltext->font.size = g_value_get_double (value) * PANGO_SCALE;
858
859       celltext->size_set = TRUE;
860       g_object_notify (G_OBJECT (celltext), "size_set");
861       g_object_notify (G_OBJECT (celltext), "font_desc");
862       g_object_notify (G_OBJECT (celltext), "font");
863       break;
864
865     case PROP_EDITABLE:
866       celltext->editable = g_value_get_boolean (value);
867       celltext->editable_set = TRUE;
868       g_object_notify (G_OBJECT (celltext), "editable_set");
869       break;
870
871     case PROP_STRIKETHROUGH:
872       celltext->strikethrough = g_value_get_boolean (value);
873       celltext->strikethrough_set = TRUE;
874       g_object_notify (G_OBJECT (celltext), "strikethrough_set");
875       break;
876
877     case PROP_UNDERLINE:
878       celltext->underline_style = g_value_get_enum (value);
879       celltext->underline_set = TRUE;
880       g_object_notify (G_OBJECT (celltext), "underline_set");
881             
882       break;
883
884     case PROP_RISE:
885       celltext->rise = g_value_get_int (value);
886       celltext->rise_set = TRUE;
887       g_object_notify (G_OBJECT (celltext), "rise_set");
888       break;  
889
890     case PROP_BACKGROUND_SET:
891       celltext->background_set = g_value_get_boolean (value);
892       break;
893
894     case PROP_FOREGROUND_SET:
895       celltext->foreground_set = g_value_get_boolean (value);
896       break;
897
898     case PROP_FAMILY_SET:
899       celltext->family_set = g_value_get_boolean (value);
900       break;
901
902     case PROP_STYLE_SET:
903       celltext->style_set = g_value_get_boolean (value);
904       break;
905
906     case PROP_VARIANT_SET:
907       celltext->variant_set = g_value_get_boolean (value);
908       break;
909
910     case PROP_WEIGHT_SET:
911       celltext->weight_set = g_value_get_boolean (value);
912       break;
913
914     case PROP_STRETCH_SET:
915       celltext->stretch_set = g_value_get_boolean (value);
916       break;
917
918     case PROP_SIZE_SET:
919       celltext->size_set = g_value_get_boolean (value);
920       break;
921
922     case PROP_SCALE_SET:
923       celltext->scale_set = g_value_get_boolean (value);
924       break;
925       
926     case PROP_EDITABLE_SET:
927       celltext->editable_set = g_value_get_boolean (value);
928       break;
929
930     case PROP_STRIKETHROUGH_SET:
931       celltext->strikethrough_set = g_value_get_boolean (value);
932       break;
933
934     case PROP_UNDERLINE_SET:
935       celltext->underline_set = g_value_get_boolean (value);
936       break;
937
938     case PROP_RISE_SET:
939       celltext->rise_set = g_value_get_boolean (value);
940       break;
941
942     default:
943       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
944       break;
945     }
946 }
947
948 /**
949  * gtk_cell_renderer_text_new:
950  * 
951  * Creates a new #GtkCellRendererText. Adjust how text is drawn using
952  * object properties. Object properties can be
953  * set globally (with g_object_set()). Also, with #GtkTreeViewColumn,
954  * you can bind a property to a value in a #GtkTreeModel. For example,
955  * you can bind the "text" property on the cell renderer to a string
956  * value in the model, thus rendering a different string in each row
957  * of the #GtkTreeView
958  * 
959  * Return value: the new cell renderer
960  **/
961 GtkCellRenderer *
962 gtk_cell_renderer_text_new (void)
963 {
964   return GTK_CELL_RENDERER (g_object_new (gtk_cell_renderer_text_get_type (), NULL));
965 }
966
967 static void
968 add_attr (PangoAttrList  *attr_list,
969           PangoAttribute *attr)
970 {
971   attr->start_index = 0;
972   attr->end_index = G_MAXINT;
973   
974   pango_attr_list_insert (attr_list, attr);
975 }
976
977 static PangoLayout*
978 get_layout (GtkCellRendererText *celltext,
979             GtkWidget           *widget,
980             gboolean             will_render,
981             GtkCellRendererState flags)
982 {
983   PangoAttrList *attr_list;
984   PangoLayout *layout;
985   PangoUnderline uline;
986   
987   layout = gtk_widget_create_pango_layout (widget, celltext->text);
988
989   if (celltext->extra_attrs)
990     attr_list = pango_attr_list_copy (celltext->extra_attrs);
991   else
992     attr_list = pango_attr_list_new ();
993
994   if (will_render)
995     {
996       /* Add options that affect appearance but not size */
997       
998       /* note that background doesn't go here, since it affects
999        * background_area not the PangoLayout area
1000        */
1001       
1002       if (celltext->foreground_set)
1003         {
1004           PangoColor color;
1005
1006           color = celltext->foreground;
1007           
1008           add_attr (attr_list,
1009                     pango_attr_foreground_new (color.red, color.green, color.blue));
1010         }
1011
1012       if (celltext->strikethrough_set)
1013         add_attr (attr_list,
1014                   pango_attr_strikethrough_new (celltext->strikethrough));
1015     }
1016
1017   if (celltext->family_set &&
1018       celltext->font.family_name)
1019     add_attr (attr_list, pango_attr_family_new (celltext->font.family_name));
1020   
1021   if (celltext->style_set)
1022     add_attr (attr_list, pango_attr_style_new (celltext->font.style));
1023
1024   if (celltext->variant_set)
1025     add_attr (attr_list, pango_attr_variant_new (celltext->font.variant));
1026
1027   if (celltext->weight_set)
1028     add_attr (attr_list, pango_attr_weight_new (celltext->font.weight));
1029
1030   if (celltext->stretch_set)
1031     add_attr (attr_list, pango_attr_stretch_new (celltext->font.stretch));
1032
1033   if (celltext->size_set &&
1034       celltext->font.size >= 0)
1035     add_attr (attr_list, pango_attr_size_new (celltext->font.size));
1036
1037   if (celltext->scale_set &&
1038       celltext->font_scale != 1.0)
1039     add_attr (attr_list, pango_attr_scale_new (celltext->font_scale));
1040   
1041   if (celltext->underline_set)
1042     uline = celltext->underline_style;
1043   else
1044     uline = PANGO_UNDERLINE_NONE;
1045   
1046   if ((flags & GTK_CELL_RENDERER_PRELIT) == GTK_CELL_RENDERER_PRELIT)
1047     {
1048       switch (uline)
1049         {
1050         case PANGO_UNDERLINE_NONE:
1051           uline = PANGO_UNDERLINE_SINGLE;
1052           break;
1053
1054         case PANGO_UNDERLINE_SINGLE:
1055           uline = PANGO_UNDERLINE_DOUBLE;
1056           break;
1057
1058         default:
1059           break;
1060         }
1061     }
1062
1063   if (uline != PANGO_UNDERLINE_NONE)
1064     add_attr (attr_list, pango_attr_underline_new (celltext->underline_style));
1065
1066   if (celltext->rise_set)
1067     add_attr (attr_list, pango_attr_rise_new (celltext->rise));
1068   
1069   pango_layout_set_attributes (layout, attr_list);
1070   pango_layout_set_width (layout, -1);
1071
1072   pango_attr_list_unref (attr_list);
1073   
1074   return layout;
1075 }
1076
1077 static void
1078 gtk_cell_renderer_text_get_size (GtkCellRenderer *cell,
1079                                  GtkWidget       *widget,
1080                                  GdkRectangle    *cell_area,
1081                                  gint            *x_offset,
1082                                  gint            *y_offset,
1083                                  gint            *width,
1084                                  gint            *height)
1085 {
1086   GtkCellRendererText *celltext = (GtkCellRendererText *)cell;
1087   PangoRectangle rect;
1088   PangoLayout *layout;
1089
1090   layout = get_layout (celltext, widget, FALSE, 0);
1091   pango_layout_get_pixel_extents (layout, NULL, &rect);
1092
1093   if (width)
1094     *width = GTK_CELL_RENDERER (celltext)->xpad * 2 + rect.width;
1095
1096   if (height)
1097     *height = GTK_CELL_RENDERER (celltext)->ypad * 2 + rect.height;
1098
1099   if (cell_area)
1100     {
1101       if (x_offset)
1102         {
1103           *x_offset = cell->xalign * (cell_area->width - rect.width - (2 * cell->xpad));
1104           *x_offset = MAX (*x_offset, 0) + cell->xpad;
1105         }
1106       if (y_offset)
1107         {
1108           *y_offset = cell->yalign * (cell_area->height - rect.height - (2 * cell->ypad));
1109           *y_offset = MAX (*y_offset, 0) + cell->ypad;
1110         }
1111     }
1112
1113   g_object_unref (G_OBJECT (layout));
1114 }
1115
1116 static void
1117 gtk_cell_renderer_text_render (GtkCellRenderer    *cell,
1118                                GdkWindow          *window,
1119                                GtkWidget          *widget,
1120                                GdkRectangle       *background_area,
1121                                GdkRectangle       *cell_area,
1122                                GdkRectangle       *expose_area,
1123                                guint               flags)
1124
1125 {
1126   GtkCellRendererText *celltext = (GtkCellRendererText *) cell;
1127   PangoLayout *layout;
1128   GtkStateType state;
1129   gint x_offset;
1130   gint y_offset;
1131
1132   layout = get_layout (celltext, widget, TRUE, flags);
1133
1134   gtk_cell_renderer_text_get_size (cell, widget, cell_area, &x_offset, &y_offset, NULL, NULL);
1135
1136   if ((flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED)
1137     state = GTK_STATE_SELECTED;
1138   else
1139     state = GTK_STATE_NORMAL;
1140
1141   if (celltext->background_set && state != GTK_STATE_SELECTED)
1142     {
1143       GdkColor color;
1144       GdkGC *gc;
1145       
1146       color.red = celltext->background.red;
1147       color.green = celltext->background.green;
1148       color.blue = celltext->background.blue;
1149
1150       gc = gdk_gc_new (window);
1151
1152       gdk_gc_set_rgb_fg_color (gc, &color);
1153       
1154       gdk_draw_rectangle (window,
1155                           gc,
1156                           TRUE,
1157                           background_area->x,
1158                           background_area->y,
1159                           background_area->width,
1160                           background_area->height);
1161
1162       g_object_unref (G_OBJECT (gc));
1163     }
1164   
1165   gtk_paint_layout (widget->style,
1166                     window,
1167                     state,
1168                     TRUE,
1169                     cell_area,
1170                     widget,
1171                     "cellrenderertext",
1172                     cell_area->x + x_offset,
1173                     cell_area->y + y_offset,
1174                     layout);
1175
1176   g_object_unref (G_OBJECT (layout));
1177 }