]> Pileus Git - ~andy/gtk/blob - gtk/gtkcellrenderertext.c
Fix #130969.
[~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 "gtkeditable.h"
23 #include "gtkentry.h"
24 #include "gtkmarshalers.h"
25 #include "gtkintl.h"
26 #include "gtktreeprivate.h"
27
28 static void gtk_cell_renderer_text_init       (GtkCellRendererText      *celltext);
29 static void gtk_cell_renderer_text_class_init (GtkCellRendererTextClass *class);
30 static void gtk_cell_renderer_text_finalize   (GObject                  *object);
31
32 static void gtk_cell_renderer_text_get_property  (GObject                  *object,
33                                                   guint                     param_id,
34                                                   GValue                   *value,
35                                                   GParamSpec               *pspec);
36 static void gtk_cell_renderer_text_set_property  (GObject                  *object,
37                                                   guint                     param_id,
38                                                   const GValue             *value,
39                                                   GParamSpec               *pspec);
40 static void gtk_cell_renderer_text_get_size   (GtkCellRenderer          *cell,
41                                                GtkWidget                *widget,
42                                                GdkRectangle             *cell_area,
43                                                gint                     *x_offset,
44                                                gint                     *y_offset,
45                                                gint                     *width,
46                                                gint                     *height);
47 static void gtk_cell_renderer_text_render     (GtkCellRenderer          *cell,
48                                                GdkWindow                *window,
49                                                GtkWidget                *widget,
50                                                GdkRectangle             *background_area,
51                                                GdkRectangle             *cell_area,
52                                                GdkRectangle             *expose_area,
53                                                GtkCellRendererState      flags);
54
55 static GtkCellEditable *gtk_cell_renderer_text_start_editing (GtkCellRenderer      *cell,
56                                                               GdkEvent             *event,
57                                                               GtkWidget            *widget,
58                                                               const gchar          *path,
59                                                               GdkRectangle         *background_area,
60                                                               GdkRectangle         *cell_area,
61                                                               GtkCellRendererState  flags);
62
63 enum {
64   EDITED,
65   LAST_SIGNAL
66 };
67
68 enum {
69   PROP_0,
70
71   PROP_TEXT,
72   PROP_MARKUP,
73   PROP_ATTRIBUTES,
74   PROP_SINGLE_PARAGRAPH_MODE,
75   
76   /* Style args */
77   PROP_BACKGROUND,
78   PROP_FOREGROUND,
79   PROP_BACKGROUND_GDK,
80   PROP_FOREGROUND_GDK,
81   PROP_FONT,
82   PROP_FONT_DESC,
83   PROP_FAMILY,
84   PROP_STYLE,
85   PROP_VARIANT,
86   PROP_WEIGHT,
87   PROP_STRETCH,
88   PROP_SIZE,
89   PROP_SIZE_POINTS,
90   PROP_SCALE,
91   PROP_EDITABLE,
92   PROP_STRIKETHROUGH,
93   PROP_UNDERLINE,
94   PROP_RISE,
95   PROP_LANGUAGE,
96   
97   /* Whether-a-style-arg-is-set args */
98   PROP_BACKGROUND_SET,
99   PROP_FOREGROUND_SET,
100   PROP_FAMILY_SET,
101   PROP_STYLE_SET,
102   PROP_VARIANT_SET,
103   PROP_WEIGHT_SET,
104   PROP_STRETCH_SET,
105   PROP_SIZE_SET,
106   PROP_SCALE_SET,
107   PROP_EDITABLE_SET,
108   PROP_STRIKETHROUGH_SET,
109   PROP_UNDERLINE_SET,
110   PROP_RISE_SET,
111   PROP_LANGUAGE_SET
112 };
113
114 static gpointer parent_class;
115 static guint text_cell_renderer_signals [LAST_SIGNAL];
116
117 #define GTK_CELL_RENDERER_TEXT_PATH "gtk-cell-renderer-text-path"
118
119 #define GTK_CELL_RENDERER_TEXT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_CELL_RENDERER_TEXT, GtkCellRendererTextPrivate))
120
121 typedef struct _GtkCellRendererTextPrivate GtkCellRendererTextPrivate;
122 struct _GtkCellRendererTextPrivate
123 {
124   guint single_paragraph : 1;
125   guint language_set : 1;
126   guint markup_set : 1;
127
128   gulong focus_out_id;
129   PangoLanguage *language;
130 };
131
132
133 GType
134 gtk_cell_renderer_text_get_type (void)
135 {
136   static GType cell_text_type = 0;
137
138   if (!cell_text_type)
139     {
140       static const GTypeInfo cell_text_info =
141       {
142         sizeof (GtkCellRendererTextClass),
143         NULL,           /* base_init */
144         NULL,           /* base_finalize */
145         (GClassInitFunc) gtk_cell_renderer_text_class_init,
146         NULL,           /* class_finalize */
147         NULL,           /* class_data */
148         sizeof (GtkCellRendererText),
149         0,              /* n_preallocs */
150         (GInstanceInitFunc) gtk_cell_renderer_text_init,
151       };
152
153       cell_text_type =
154         g_type_register_static (GTK_TYPE_CELL_RENDERER, "GtkCellRendererText",
155                                 &cell_text_info, 0);
156     }
157
158   return cell_text_type;
159 }
160
161 static void
162 gtk_cell_renderer_text_init (GtkCellRendererText *celltext)
163 {
164   GTK_CELL_RENDERER (celltext)->xalign = 0.0;
165   GTK_CELL_RENDERER (celltext)->yalign = 0.5;
166   GTK_CELL_RENDERER (celltext)->xpad = 2;
167   GTK_CELL_RENDERER (celltext)->ypad = 2;
168   celltext->fixed_height_rows = -1;
169   celltext->font = pango_font_description_new ();
170 }
171
172 static void
173 gtk_cell_renderer_text_class_init (GtkCellRendererTextClass *class)
174 {
175   GObjectClass *object_class = G_OBJECT_CLASS (class);
176   GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (class);
177
178   parent_class = g_type_class_peek_parent (class);
179   
180   object_class->finalize = gtk_cell_renderer_text_finalize;
181   
182   object_class->get_property = gtk_cell_renderer_text_get_property;
183   object_class->set_property = gtk_cell_renderer_text_set_property;
184
185   cell_class->get_size = gtk_cell_renderer_text_get_size;
186   cell_class->render = gtk_cell_renderer_text_render;
187   cell_class->start_editing = gtk_cell_renderer_text_start_editing;
188   
189   g_object_class_install_property (object_class,
190                                    PROP_TEXT,
191                                    g_param_spec_string ("text",
192                                                         _("Text"),
193                                                         _("Text to render"),
194                                                         NULL,
195                                                         G_PARAM_READWRITE));
196   
197   g_object_class_install_property (object_class,
198                                    PROP_MARKUP,
199                                    g_param_spec_string ("markup",
200                                                         _("Markup"),
201                                                         _("Marked up text to render"),
202                                                         NULL,
203                                                         G_PARAM_WRITABLE));
204
205   g_object_class_install_property (object_class,
206                                    PROP_ATTRIBUTES,
207                                    g_param_spec_boxed ("attributes",
208                                                        _("Attributes"),
209                                                        _("A list of style attributes to apply to the text of the renderer"),
210                                                        PANGO_TYPE_ATTR_LIST,
211                                                        G_PARAM_READWRITE));
212
213   g_object_class_install_property (object_class,
214                                    PROP_SINGLE_PARAGRAPH_MODE,
215                                    g_param_spec_boolean ("single_paragraph_mode",
216                                                          _("Single Paragraph Mode"),
217                                                          _("Whether or not to keep all text in a single paragraph"),
218                                                          FALSE,
219                                                          G_PARAM_READWRITE));
220
221   
222   g_object_class_install_property (object_class,
223                                    PROP_BACKGROUND,
224                                    g_param_spec_string ("background",
225                                                         _("Background color name"),
226                                                         _("Background color as a string"),
227                                                         NULL,
228                                                         G_PARAM_WRITABLE));
229
230   g_object_class_install_property (object_class,
231                                    PROP_BACKGROUND_GDK,
232                                    g_param_spec_boxed ("background_gdk",
233                                                        _("Background color"),
234                                                        _("Background color as a GdkColor"),
235                                                        GDK_TYPE_COLOR,
236                                                        G_PARAM_READABLE | G_PARAM_WRITABLE));  
237
238   g_object_class_install_property (object_class,
239                                    PROP_FOREGROUND,
240                                    g_param_spec_string ("foreground",
241                                                         _("Foreground color name"),
242                                                         _("Foreground color as a string"),
243                                                         NULL,
244                                                         G_PARAM_WRITABLE));
245
246   g_object_class_install_property (object_class,
247                                    PROP_FOREGROUND_GDK,
248                                    g_param_spec_boxed ("foreground_gdk",
249                                                        _("Foreground color"),
250                                                        _("Foreground color as a GdkColor"),
251                                                        GDK_TYPE_COLOR,
252                                                        G_PARAM_READABLE | G_PARAM_WRITABLE));
253
254
255   g_object_class_install_property (object_class,
256                                    PROP_EDITABLE,
257                                    g_param_spec_boolean ("editable",
258                                                          _("Editable"),
259                                                          _("Whether the text can be modified by the user"),
260                                                          FALSE,
261                                                          G_PARAM_READABLE | G_PARAM_WRITABLE));
262
263   g_object_class_install_property (object_class,
264                                    PROP_FONT,
265                                    g_param_spec_string ("font",
266                                                         _("Font"),
267                                                         _("Font description as a string"),
268                                                         NULL,
269                                                         G_PARAM_READABLE | G_PARAM_WRITABLE));
270
271   g_object_class_install_property (object_class,
272                                    PROP_FONT_DESC,
273                                    g_param_spec_boxed ("font_desc",
274                                                        _("Font"),
275                                                        _("Font description as a PangoFontDescription struct"),
276                                                        PANGO_TYPE_FONT_DESCRIPTION,
277                                                        G_PARAM_READABLE | G_PARAM_WRITABLE));
278
279   
280   g_object_class_install_property (object_class,
281                                    PROP_FAMILY,
282                                    g_param_spec_string ("family",
283                                                         _("Font family"),
284                                                         _("Name of the font family, e.g. Sans, Helvetica, Times, Monospace"),
285                                                         NULL,
286                                                         G_PARAM_READABLE | G_PARAM_WRITABLE));
287
288   g_object_class_install_property (object_class,
289                                    PROP_STYLE,
290                                    g_param_spec_enum ("style",
291                                                       _("Font style"),
292                                                       _("Font style"),
293                                                       PANGO_TYPE_STYLE,
294                                                       PANGO_STYLE_NORMAL,
295                                                       G_PARAM_READABLE | G_PARAM_WRITABLE));
296
297   g_object_class_install_property (object_class,
298                                    PROP_VARIANT,
299                                    g_param_spec_enum ("variant",
300                                                      _("Font variant"),
301                                                      _("Font variant"),
302                                                       PANGO_TYPE_VARIANT,
303                                                       PANGO_VARIANT_NORMAL,
304                                                       G_PARAM_READABLE | G_PARAM_WRITABLE));
305   
306   g_object_class_install_property (object_class,
307                                    PROP_WEIGHT,
308                                    g_param_spec_int ("weight",
309                                                      _("Font weight"),
310                                                      _("Font weight"),
311                                                      0,
312                                                      G_MAXINT,
313                                                      PANGO_WEIGHT_NORMAL,
314                                                      G_PARAM_READABLE | G_PARAM_WRITABLE));
315
316    g_object_class_install_property (object_class,
317                                    PROP_STRETCH,
318                                    g_param_spec_enum ("stretch",
319                                                       _("Font stretch"),
320                                                       _("Font stretch"),
321                                                       PANGO_TYPE_STRETCH,
322                                                       PANGO_STRETCH_NORMAL,
323                                                       G_PARAM_READABLE | G_PARAM_WRITABLE));
324   
325   g_object_class_install_property (object_class,
326                                    PROP_SIZE,
327                                    g_param_spec_int ("size",
328                                                      _("Font size"),
329                                                      _("Font size"),
330                                                      0,
331                                                      G_MAXINT,
332                                                      0,
333                                                      G_PARAM_READABLE | G_PARAM_WRITABLE));
334
335   g_object_class_install_property (object_class,
336                                    PROP_SIZE_POINTS,
337                                    g_param_spec_double ("size_points",
338                                                         _("Font points"),
339                                                         _("Font size in points"),
340                                                         0.0,
341                                                         G_MAXDOUBLE,
342                                                         0.0,
343                                                         G_PARAM_READABLE | G_PARAM_WRITABLE));  
344
345   g_object_class_install_property (object_class,
346                                    PROP_SCALE,
347                                    g_param_spec_double ("scale",
348                                                         _("Font scale"),
349                                                         _("Font scaling factor"),
350                                                         0.0,
351                                                         G_MAXDOUBLE,
352                                                         1.0,
353                                                         G_PARAM_READABLE | G_PARAM_WRITABLE));
354   
355   g_object_class_install_property (object_class,
356                                    PROP_RISE,
357                                    g_param_spec_int ("rise",
358                                                      _("Rise"),
359                                                      _("Offset of text above the baseline (below the baseline if rise is negative)"),
360                                                      -G_MAXINT,
361                                                      G_MAXINT,
362                                                      0,
363                                                      G_PARAM_READABLE | G_PARAM_WRITABLE));
364
365
366   g_object_class_install_property (object_class,
367                                    PROP_STRIKETHROUGH,
368                                    g_param_spec_boolean ("strikethrough",
369                                                          _("Strikethrough"),
370                                                          _("Whether to strike through the text"),
371                                                          FALSE,
372                                                          G_PARAM_READABLE | G_PARAM_WRITABLE));
373   
374   g_object_class_install_property (object_class,
375                                    PROP_UNDERLINE,
376                                    g_param_spec_enum ("underline",
377                                                       _("Underline"),
378                                                       _("Style of underline for this text"),
379                                                       PANGO_TYPE_UNDERLINE,
380                                                       PANGO_UNDERLINE_NONE,
381                                                       G_PARAM_READABLE | G_PARAM_WRITABLE));
382
383   g_object_class_install_property (object_class,
384                                    PROP_LANGUAGE,
385                                    g_param_spec_string ("language",
386                                                         _("Language"),
387                                                         _("The language this text is in, as an ISO code. Pango can use this as a hint when rendering the text. If you don't understand this parameter, you probably don't need it"),
388                                                         NULL,
389                                                         G_PARAM_READWRITE));
390
391
392   /* Style props are set or not */
393
394 #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))
395
396   ADD_SET_PROP ("background_set", PROP_BACKGROUND_SET,
397                 _("Background set"),
398                 _("Whether this tag affects the background color"));
399
400   ADD_SET_PROP ("foreground_set", PROP_FOREGROUND_SET,
401                 _("Foreground set"),
402                 _("Whether this tag affects the foreground color"));
403   
404   ADD_SET_PROP ("editable_set", PROP_EDITABLE_SET,
405                 _("Editability set"),
406                 _("Whether this tag affects text editability"));
407
408   ADD_SET_PROP ("family_set", PROP_FAMILY_SET,
409                 _("Font family set"),
410                 _("Whether this tag affects the font family"));  
411
412   ADD_SET_PROP ("style_set", PROP_STYLE_SET,
413                 _("Font style set"),
414                 _("Whether this tag affects the font style"));
415
416   ADD_SET_PROP ("variant_set", PROP_VARIANT_SET,
417                 _("Font variant set"),
418                 _("Whether this tag affects the font variant"));
419
420   ADD_SET_PROP ("weight_set", PROP_WEIGHT_SET,
421                 _("Font weight set"),
422                 _("Whether this tag affects the font weight"));
423
424   ADD_SET_PROP ("stretch_set", PROP_STRETCH_SET,
425                 _("Font stretch set"),
426                 _("Whether this tag affects the font stretch"));
427
428   ADD_SET_PROP ("size_set", PROP_SIZE_SET,
429                 _("Font size set"),
430                 _("Whether this tag affects the font size"));
431
432   ADD_SET_PROP ("scale_set", PROP_SCALE_SET,
433                 _("Font scale set"),
434                 _("Whether this tag scales the font size by a factor"));
435   
436   ADD_SET_PROP ("rise_set", PROP_RISE_SET,
437                 _("Rise set"),
438                 _("Whether this tag affects the rise"));
439
440   ADD_SET_PROP ("strikethrough_set", PROP_STRIKETHROUGH_SET,
441                 _("Strikethrough set"),
442                 _("Whether this tag affects strikethrough"));
443
444   ADD_SET_PROP ("underline_set", PROP_UNDERLINE_SET,
445                 _("Underline set"),
446                 _("Whether this tag affects underlining"));
447
448   ADD_SET_PROP ("language_set", PROP_LANGUAGE_SET,
449                 _("Language set"),
450                 _("Whether this tag affects the language the text is rendered as"));
451
452   text_cell_renderer_signals [EDITED] =
453     g_signal_new ("edited",
454                   G_OBJECT_CLASS_TYPE (object_class),
455                   G_SIGNAL_RUN_LAST,
456                   G_STRUCT_OFFSET (GtkCellRendererTextClass, edited),
457                   NULL, NULL,
458                   _gtk_marshal_VOID__STRING_STRING,
459                   G_TYPE_NONE, 2,
460                   G_TYPE_STRING,
461                   G_TYPE_STRING);
462
463   g_type_class_add_private (object_class, sizeof (GtkCellRendererTextPrivate));
464 }
465
466 static void
467 gtk_cell_renderer_text_finalize (GObject *object)
468 {
469   GtkCellRendererText *celltext = GTK_CELL_RENDERER_TEXT (object);
470   GtkCellRendererTextPrivate *priv;
471
472   priv = GTK_CELL_RENDERER_TEXT_GET_PRIVATE (object);
473
474   pango_font_description_free (celltext->font);
475
476   if (celltext->text)
477     g_free (celltext->text);
478
479   if (celltext->extra_attrs)
480     pango_attr_list_unref (celltext->extra_attrs);
481
482   if (priv->language)
483     g_object_unref (priv->language);
484
485   (* G_OBJECT_CLASS (parent_class)->finalize) (object);
486 }
487
488 static PangoFontMask
489 get_property_font_set_mask (guint prop_id)
490 {
491   switch (prop_id)
492     {
493     case PROP_FAMILY_SET:
494       return PANGO_FONT_MASK_FAMILY;
495     case PROP_STYLE_SET:
496       return PANGO_FONT_MASK_STYLE;
497     case PROP_VARIANT_SET:
498       return PANGO_FONT_MASK_VARIANT;
499     case PROP_WEIGHT_SET:
500       return PANGO_FONT_MASK_WEIGHT;
501     case PROP_STRETCH_SET:
502       return PANGO_FONT_MASK_STRETCH;
503     case PROP_SIZE_SET:
504       return PANGO_FONT_MASK_SIZE;
505     }
506
507   return 0;
508 }
509
510 static void
511 gtk_cell_renderer_text_get_property (GObject        *object,
512                                      guint           param_id,
513                                      GValue         *value,
514                                      GParamSpec     *pspec)
515 {
516   GtkCellRendererText *celltext = GTK_CELL_RENDERER_TEXT (object);
517   GtkCellRendererTextPrivate *priv;
518
519   priv = GTK_CELL_RENDERER_TEXT_GET_PRIVATE (object);
520
521   switch (param_id)
522     {
523     case PROP_TEXT:
524       g_value_set_string (value, celltext->text);
525       break;
526
527     case PROP_ATTRIBUTES:
528       g_value_set_boxed (value, celltext->extra_attrs);
529       break;
530
531     case PROP_SINGLE_PARAGRAPH_MODE:
532       g_value_set_boolean (value, priv->single_paragraph);
533       break;
534
535     case PROP_BACKGROUND_GDK:
536       {
537         GdkColor color;
538         
539         color.red = celltext->background.red;
540         color.green = celltext->background.green;
541         color.blue = celltext->background.blue;
542         
543         g_value_set_boxed (value, &color);
544       }
545       break;
546
547     case PROP_FOREGROUND_GDK:
548       {
549         GdkColor color;
550         
551         color.red = celltext->foreground.red;
552         color.green = celltext->foreground.green;
553         color.blue = celltext->foreground.blue;
554         
555         g_value_set_boxed (value, &color);
556       }
557       break;
558
559     case PROP_FONT:
560       {
561         /* FIXME GValue imposes a totally gratuitous string copy
562          * here, we could just hand off string ownership
563          */
564         gchar *str = pango_font_description_to_string (celltext->font);
565         g_value_set_string (value, str);
566         g_free (str);
567       }
568       break;
569       
570     case PROP_FONT_DESC:
571       g_value_set_boxed (value, celltext->font);
572       break;
573
574     case PROP_FAMILY:
575       g_value_set_string (value, pango_font_description_get_family (celltext->font));
576       break;
577
578     case PROP_STYLE:
579       g_value_set_enum (value, pango_font_description_get_style (celltext->font));
580       break;
581
582     case PROP_VARIANT:
583       g_value_set_enum (value, pango_font_description_get_variant (celltext->font));
584       break;
585
586     case PROP_WEIGHT:
587       g_value_set_int (value, pango_font_description_get_weight (celltext->font));
588       break;
589
590     case PROP_STRETCH:
591       g_value_set_enum (value, pango_font_description_get_stretch (celltext->font));
592       break;
593
594     case PROP_SIZE:
595       g_value_set_int (value, pango_font_description_get_size (celltext->font));
596       break;
597
598     case PROP_SIZE_POINTS:
599       g_value_set_double (value, ((double)pango_font_description_get_size (celltext->font)) / (double)PANGO_SCALE);
600       break;
601
602     case PROP_SCALE:
603       g_value_set_double (value, celltext->font_scale);
604       break;
605       
606     case PROP_EDITABLE:
607       g_value_set_boolean (value, celltext->editable);
608       break;
609
610     case PROP_STRIKETHROUGH:
611       g_value_set_boolean (value, celltext->strikethrough);
612       break;
613
614     case PROP_UNDERLINE:
615       g_value_set_enum (value, celltext->underline_style);
616       break;
617
618     case PROP_RISE:
619       g_value_set_int (value, celltext->rise);
620       break;  
621
622     case PROP_LANGUAGE:
623       g_value_set_string (value, pango_language_to_string (priv->language));
624       break;
625
626     case PROP_BACKGROUND_SET:
627       g_value_set_boolean (value, celltext->background_set);
628       break;
629
630     case PROP_FOREGROUND_SET:
631       g_value_set_boolean (value, celltext->foreground_set);
632       break;
633
634     case PROP_FAMILY_SET:
635     case PROP_STYLE_SET:
636     case PROP_VARIANT_SET:
637     case PROP_WEIGHT_SET:
638     case PROP_STRETCH_SET:
639     case PROP_SIZE_SET:
640       {
641         PangoFontMask mask = get_property_font_set_mask (param_id);
642         g_value_set_boolean (value, (pango_font_description_get_set_fields (celltext->font) & mask) != 0);
643         
644         break;
645       }
646
647     case PROP_SCALE_SET:
648       g_value_set_boolean (value, celltext->scale_set);
649       break;
650       
651     case PROP_EDITABLE_SET:
652       g_value_set_boolean (value, celltext->editable_set);
653       break;
654
655     case PROP_STRIKETHROUGH_SET:
656       g_value_set_boolean (value, celltext->strikethrough_set);
657       break;
658
659     case PROP_UNDERLINE_SET:
660       g_value_set_boolean (value, celltext->underline_set);
661       break;
662
663     case  PROP_RISE_SET:
664       g_value_set_boolean (value, celltext->rise_set);
665       break;
666
667     case PROP_LANGUAGE_SET:
668       g_value_set_boolean (value, priv->language_set);
669       break;
670       
671     case PROP_BACKGROUND:
672     case PROP_FOREGROUND:
673     case PROP_MARKUP:
674     default:
675       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
676       break;
677     }
678 }
679
680
681 static void
682 set_bg_color (GtkCellRendererText *celltext,
683               GdkColor            *color)
684 {
685   if (color)
686     {
687       if (!celltext->background_set)
688         {
689           celltext->background_set = TRUE;
690           g_object_notify (G_OBJECT (celltext), "background_set");
691         }
692       
693       celltext->background.red = color->red;
694       celltext->background.green = color->green;
695       celltext->background.blue = color->blue;
696     }
697   else
698     {
699       if (celltext->background_set)
700         {
701           celltext->background_set = FALSE;
702           g_object_notify (G_OBJECT (celltext), "background_set");
703         }
704     }
705 }
706
707
708 static void
709 set_fg_color (GtkCellRendererText *celltext,
710               GdkColor            *color)
711 {
712   if (color)
713     {
714       if (!celltext->foreground_set)
715         {
716           celltext->foreground_set = TRUE;
717           g_object_notify (G_OBJECT (celltext), "foreground_set");
718         }
719       
720       celltext->foreground.red = color->red;
721       celltext->foreground.green = color->green;
722       celltext->foreground.blue = color->blue;
723     }
724   else
725     {
726       if (celltext->foreground_set)
727         {
728           celltext->foreground_set = FALSE;
729           g_object_notify (G_OBJECT (celltext), "foreground_set");
730         }
731     }
732 }
733
734 static PangoFontMask
735 set_font_desc_fields (PangoFontDescription *desc,
736                       PangoFontMask         to_set)
737 {
738   PangoFontMask changed_mask = 0;
739   
740   if (to_set & PANGO_FONT_MASK_FAMILY)
741     {
742       const char *family = pango_font_description_get_family (desc);
743       if (!family)
744         {
745           family = "sans";
746           changed_mask |= PANGO_FONT_MASK_FAMILY;
747         }
748
749       pango_font_description_set_family (desc, family);
750     }
751   if (to_set & PANGO_FONT_MASK_STYLE)
752     pango_font_description_set_style (desc, pango_font_description_get_style (desc));
753   if (to_set & PANGO_FONT_MASK_VARIANT)
754     pango_font_description_set_variant (desc, pango_font_description_get_variant (desc));
755   if (to_set & PANGO_FONT_MASK_WEIGHT)
756     pango_font_description_set_weight (desc, pango_font_description_get_weight (desc));
757   if (to_set & PANGO_FONT_MASK_STRETCH)
758     pango_font_description_set_stretch (desc, pango_font_description_get_stretch (desc));
759   if (to_set & PANGO_FONT_MASK_SIZE)
760     {
761       gint size = pango_font_description_get_size (desc);
762       if (size <= 0)
763         {
764           size = 10 * PANGO_SCALE;
765           changed_mask |= PANGO_FONT_MASK_SIZE;
766         }
767       
768       pango_font_description_set_size (desc, size);
769     }
770
771   return changed_mask;
772 }
773
774 static void
775 notify_set_changed (GObject       *object,
776                     PangoFontMask  changed_mask)
777 {
778   if (changed_mask & PANGO_FONT_MASK_FAMILY)
779     g_object_notify (object, "family_set");
780   if (changed_mask & PANGO_FONT_MASK_STYLE)
781     g_object_notify (object, "style_set");
782   if (changed_mask & PANGO_FONT_MASK_VARIANT)
783     g_object_notify (object, "variant_set");
784   if (changed_mask & PANGO_FONT_MASK_WEIGHT)
785     g_object_notify (object, "weight_set");
786   if (changed_mask & PANGO_FONT_MASK_STRETCH)
787     g_object_notify (object, "stretch_set");
788   if (changed_mask & PANGO_FONT_MASK_SIZE)
789     g_object_notify (object, "size_set");
790 }
791
792 static void
793 notify_fields_changed (GObject       *object,
794                        PangoFontMask  changed_mask)
795 {
796   if (changed_mask & PANGO_FONT_MASK_FAMILY)
797     g_object_notify (object, "family");
798   if (changed_mask & PANGO_FONT_MASK_STYLE)
799     g_object_notify (object, "style");
800   if (changed_mask & PANGO_FONT_MASK_VARIANT)
801     g_object_notify (object, "variant");
802   if (changed_mask & PANGO_FONT_MASK_WEIGHT)
803     g_object_notify (object, "weight");
804   if (changed_mask & PANGO_FONT_MASK_STRETCH)
805     g_object_notify (object, "stretch");
806   if (changed_mask & PANGO_FONT_MASK_SIZE)
807     g_object_notify (object, "size");
808 }
809
810 static void
811 set_font_description (GtkCellRendererText  *celltext,
812                       PangoFontDescription *font_desc)
813 {
814   GObject *object = G_OBJECT (celltext);
815   PangoFontDescription *new_font_desc;
816   PangoFontMask old_mask, new_mask, changed_mask, set_changed_mask;
817   
818   if (font_desc)
819     new_font_desc = pango_font_description_copy (font_desc);
820   else
821     new_font_desc = pango_font_description_new ();
822
823   old_mask = pango_font_description_get_set_fields (celltext->font);
824   new_mask = pango_font_description_get_set_fields (new_font_desc);
825
826   changed_mask = old_mask | new_mask;
827   set_changed_mask = old_mask ^ new_mask;
828
829   pango_font_description_free (celltext->font);
830   celltext->font = new_font_desc;
831   
832   g_object_freeze_notify (object);
833
834   g_object_notify (object, "font_desc");
835   g_object_notify (object, "font");
836   
837   if (changed_mask & PANGO_FONT_MASK_FAMILY)
838     g_object_notify (object, "family");
839   if (changed_mask & PANGO_FONT_MASK_STYLE)
840     g_object_notify (object, "style");
841   if (changed_mask & PANGO_FONT_MASK_VARIANT)
842     g_object_notify (object, "variant");
843   if (changed_mask & PANGO_FONT_MASK_WEIGHT)
844     g_object_notify (object, "weight");
845   if (changed_mask & PANGO_FONT_MASK_STRETCH)
846     g_object_notify (object, "stretch");
847   if (changed_mask & PANGO_FONT_MASK_SIZE)
848     {
849       g_object_notify (object, "size");
850       g_object_notify (object, "size_points");
851     }
852
853   notify_set_changed (object, set_changed_mask);
854   
855   g_object_thaw_notify (object);
856 }
857
858 static void
859 gtk_cell_renderer_text_set_property (GObject      *object,
860                                      guint         param_id,
861                                      const GValue *value,
862                                      GParamSpec   *pspec)
863 {
864   GtkCellRendererText *celltext = GTK_CELL_RENDERER_TEXT (object);
865   GtkCellRendererTextPrivate *priv;
866
867   priv = GTK_CELL_RENDERER_TEXT_GET_PRIVATE (object);
868
869   switch (param_id)
870     {
871     case PROP_TEXT:
872       if (celltext->text)
873         g_free (celltext->text);
874
875       if (priv->markup_set)
876         {
877           if (celltext->extra_attrs)
878             pango_attr_list_unref (celltext->extra_attrs);
879           celltext->extra_attrs = NULL;
880           priv->markup_set = FALSE;
881         }
882
883       celltext->text = g_strdup (g_value_get_string (value));
884       g_object_notify (object, "text");
885       break;
886
887     case PROP_ATTRIBUTES:
888       if (celltext->extra_attrs)
889         pango_attr_list_unref (celltext->extra_attrs);
890
891       celltext->extra_attrs = g_value_get_boxed (value);
892       if (celltext->extra_attrs)
893         pango_attr_list_ref (celltext->extra_attrs);
894       break;
895     case PROP_MARKUP:
896       {
897         const gchar *str;
898         gchar *text = NULL;
899         GError *error = NULL;
900         PangoAttrList *attrs = NULL;
901
902         str = g_value_get_string (value);
903         if (str && !pango_parse_markup (str,
904                                         -1,
905                                         0,
906                                         &attrs,
907                                         &text,
908                                         NULL,
909                                         &error))
910           {
911             g_warning ("Failed to set cell text from markup due to error parsing markup: %s",
912                        error->message);
913             g_error_free (error);
914             return;
915           }
916
917         if (celltext->text)
918           g_free (celltext->text);
919
920         if (celltext->extra_attrs)
921           pango_attr_list_unref (celltext->extra_attrs);
922
923         celltext->text = text;
924         celltext->extra_attrs = attrs;
925         priv->markup_set = TRUE;
926       }
927       break;
928
929     case PROP_SINGLE_PARAGRAPH_MODE:
930       priv->single_paragraph = g_value_get_boolean (value);
931       break;
932       
933     case PROP_BACKGROUND:
934       {
935         GdkColor color;
936
937         if (!g_value_get_string (value))
938           set_bg_color (celltext, NULL);       /* reset to backgrounmd_set to FALSE */
939         else if (gdk_color_parse (g_value_get_string (value), &color))
940           set_bg_color (celltext, &color);
941         else
942           g_warning ("Don't know color `%s'", g_value_get_string (value));
943
944         g_object_notify (object, "background_gdk");
945       }
946       break;
947       
948     case PROP_FOREGROUND:
949       {
950         GdkColor color;
951
952         if (!g_value_get_string (value))
953           set_fg_color (celltext, NULL);       /* reset to foreground_set to FALSE */
954         else if (gdk_color_parse (g_value_get_string (value), &color))
955           set_fg_color (celltext, &color);
956         else
957           g_warning ("Don't know color `%s'", g_value_get_string (value));
958
959         g_object_notify (object, "foreground_gdk");
960       }
961       break;
962
963     case PROP_BACKGROUND_GDK:
964       /* This notifies the GObject itself. */
965       set_bg_color (celltext, g_value_get_boxed (value));
966       break;
967
968     case PROP_FOREGROUND_GDK:
969       /* This notifies the GObject itself. */
970       set_fg_color (celltext, g_value_get_boxed (value));
971       break;
972
973     case PROP_FONT:
974       {
975         PangoFontDescription *font_desc = NULL;
976         const gchar *name;
977
978         name = g_value_get_string (value);
979
980         if (name)
981           font_desc = pango_font_description_from_string (name);
982
983         set_font_description (celltext, font_desc);
984         
985         if (celltext->fixed_height_rows != -1)
986           celltext->calc_fixed_height = TRUE;
987       }
988       break;
989
990     case PROP_FONT_DESC:
991       set_font_description (celltext, g_value_get_boxed (value));
992       
993       if (celltext->fixed_height_rows != -1)
994         celltext->calc_fixed_height = TRUE;
995       break;
996
997     case PROP_FAMILY:
998     case PROP_STYLE:
999     case PROP_VARIANT:
1000     case PROP_WEIGHT:
1001     case PROP_STRETCH:
1002     case PROP_SIZE:
1003     case PROP_SIZE_POINTS:
1004       {
1005         PangoFontMask old_set_mask = pango_font_description_get_set_fields (celltext->font);
1006         
1007         switch (param_id)
1008           {
1009           case PROP_FAMILY:
1010             pango_font_description_set_family (celltext->font,
1011                                                g_value_get_string (value));
1012             break;
1013           case PROP_STYLE:
1014             pango_font_description_set_style (celltext->font,
1015                                               g_value_get_enum (value));
1016             break;
1017           case PROP_VARIANT:
1018             pango_font_description_set_variant (celltext->font,
1019                                                 g_value_get_enum (value));
1020             break;
1021           case PROP_WEIGHT:
1022             pango_font_description_set_weight (celltext->font,
1023                                                g_value_get_int (value));
1024             break;
1025           case PROP_STRETCH:
1026             pango_font_description_set_stretch (celltext->font,
1027                                                 g_value_get_enum (value));
1028             break;
1029           case PROP_SIZE:
1030             pango_font_description_set_size (celltext->font,
1031                                              g_value_get_int (value));
1032             g_object_notify (object, "size_points");
1033             break;
1034           case PROP_SIZE_POINTS:
1035             pango_font_description_set_size (celltext->font,
1036                                              g_value_get_double (value) * PANGO_SCALE);
1037             g_object_notify (object, "size");
1038             break;
1039           }
1040         
1041         if (celltext->fixed_height_rows != -1)
1042           celltext->calc_fixed_height = TRUE;
1043         
1044         notify_set_changed (object, old_set_mask & pango_font_description_get_set_fields (celltext->font));
1045         g_object_notify (object, "font_desc");
1046         g_object_notify (object, "font");
1047
1048         break;
1049       }
1050       
1051     case PROP_SCALE:
1052       celltext->font_scale = g_value_get_double (value);
1053       celltext->scale_set = TRUE;
1054       if (celltext->fixed_height_rows != -1)
1055         celltext->calc_fixed_height = TRUE;
1056       g_object_notify (object, "scale_set");
1057       break;
1058       
1059     case PROP_EDITABLE:
1060       celltext->editable = g_value_get_boolean (value);
1061       celltext->editable_set = TRUE;
1062       if (celltext->editable)
1063         GTK_CELL_RENDERER (celltext)->mode = GTK_CELL_RENDERER_MODE_EDITABLE;
1064       else
1065         GTK_CELL_RENDERER (celltext)->mode = GTK_CELL_RENDERER_MODE_INERT;
1066       g_object_notify (object, "editable_set");
1067       break;
1068
1069     case PROP_STRIKETHROUGH:
1070       celltext->strikethrough = g_value_get_boolean (value);
1071       celltext->strikethrough_set = TRUE;
1072       g_object_notify (object, "strikethrough_set");
1073       break;
1074
1075     case PROP_UNDERLINE:
1076       celltext->underline_style = g_value_get_enum (value);
1077       celltext->underline_set = TRUE;
1078       g_object_notify (object, "underline_set");
1079             
1080       break;
1081
1082     case PROP_RISE:
1083       celltext->rise = g_value_get_int (value);
1084       celltext->rise_set = TRUE;
1085       g_object_notify (object, "rise_set");
1086       if (celltext->fixed_height_rows != -1)
1087         celltext->calc_fixed_height = TRUE;
1088       break;  
1089
1090     case PROP_LANGUAGE:
1091       priv->language_set = TRUE;
1092       if (priv->language)
1093         g_object_unref (priv->language);
1094       priv->language = pango_language_from_string (g_value_get_string (value));
1095       g_object_notify (object, "language_set");
1096       break;
1097
1098     case PROP_BACKGROUND_SET:
1099       celltext->background_set = g_value_get_boolean (value);
1100       break;
1101
1102     case PROP_FOREGROUND_SET:
1103       celltext->foreground_set = g_value_get_boolean (value);
1104       break;
1105
1106     case PROP_FAMILY_SET:
1107     case PROP_STYLE_SET:
1108     case PROP_VARIANT_SET:
1109     case PROP_WEIGHT_SET:
1110     case PROP_STRETCH_SET:
1111     case PROP_SIZE_SET:
1112       if (!g_value_get_boolean (value))
1113         {
1114           pango_font_description_unset_fields (celltext->font,
1115                                                get_property_font_set_mask (param_id));
1116         }
1117       else
1118         {
1119           PangoFontMask changed_mask;
1120           
1121           changed_mask = set_font_desc_fields (celltext->font,
1122                                                get_property_font_set_mask (param_id));
1123           notify_fields_changed (G_OBJECT (celltext), changed_mask);
1124         }
1125       break;
1126
1127     case PROP_SCALE_SET:
1128       celltext->scale_set = g_value_get_boolean (value);
1129       break;
1130       
1131     case PROP_EDITABLE_SET:
1132       celltext->editable_set = g_value_get_boolean (value);
1133       break;
1134
1135     case PROP_STRIKETHROUGH_SET:
1136       celltext->strikethrough_set = g_value_get_boolean (value);
1137       break;
1138
1139     case PROP_UNDERLINE_SET:
1140       celltext->underline_set = g_value_get_boolean (value);
1141       break;
1142
1143     case PROP_RISE_SET:
1144       celltext->rise_set = g_value_get_boolean (value);
1145       break;
1146
1147     case PROP_LANGUAGE_SET:
1148       priv->language_set = g_value_get_boolean (value);
1149       break;
1150
1151     default:
1152       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
1153       break;
1154     }
1155 }
1156
1157 /**
1158  * gtk_cell_renderer_text_new:
1159  * 
1160  * Creates a new #GtkCellRendererText. Adjust how text is drawn using
1161  * object properties. Object properties can be
1162  * set globally (with g_object_set()). Also, with #GtkTreeViewColumn,
1163  * you can bind a property to a value in a #GtkTreeModel. For example,
1164  * you can bind the "text" property on the cell renderer to a string
1165  * value in the model, thus rendering a different string in each row
1166  * of the #GtkTreeView
1167  * 
1168  * Return value: the new cell renderer
1169  **/
1170 GtkCellRenderer *
1171 gtk_cell_renderer_text_new (void)
1172 {
1173   return g_object_new (GTK_TYPE_CELL_RENDERER_TEXT, NULL);
1174 }
1175
1176 static void
1177 add_attr (PangoAttrList  *attr_list,
1178           PangoAttribute *attr)
1179 {
1180   attr->start_index = 0;
1181   attr->end_index = G_MAXINT;
1182   
1183   pango_attr_list_insert (attr_list, attr);
1184 }
1185
1186 static PangoLayout*
1187 get_layout (GtkCellRendererText *celltext,
1188             GtkWidget           *widget,
1189             gboolean             will_render,
1190             GtkCellRendererState flags)
1191 {
1192   PangoAttrList *attr_list;
1193   PangoLayout *layout;
1194   PangoUnderline uline;
1195   GtkCellRendererTextPrivate *priv;
1196
1197   priv = GTK_CELL_RENDERER_TEXT_GET_PRIVATE (celltext);
1198   
1199   layout = gtk_widget_create_pango_layout (widget, celltext->text);
1200
1201   if (celltext->extra_attrs)
1202     attr_list = pango_attr_list_copy (celltext->extra_attrs);
1203   else
1204     attr_list = pango_attr_list_new ();
1205
1206   pango_layout_set_single_paragraph_mode (layout, priv->single_paragraph);
1207
1208   if (will_render)
1209     {
1210       /* Add options that affect appearance but not size */
1211       
1212       /* note that background doesn't go here, since it affects
1213        * background_area not the PangoLayout area
1214        */
1215       
1216       if (celltext->foreground_set)
1217         {
1218           PangoColor color;
1219
1220           color = celltext->foreground;
1221           
1222           add_attr (attr_list,
1223                     pango_attr_foreground_new (color.red, color.green, color.blue));
1224         }
1225
1226       if (celltext->strikethrough_set)
1227         add_attr (attr_list,
1228                   pango_attr_strikethrough_new (celltext->strikethrough));
1229     }
1230
1231   add_attr (attr_list, pango_attr_font_desc_new (celltext->font));
1232
1233   if (celltext->scale_set &&
1234       celltext->font_scale != 1.0)
1235     add_attr (attr_list, pango_attr_scale_new (celltext->font_scale));
1236   
1237   if (celltext->underline_set)
1238     uline = celltext->underline_style;
1239   else
1240     uline = PANGO_UNDERLINE_NONE;
1241
1242   if (priv->language_set)
1243     add_attr (attr_list, pango_attr_language_new (priv->language));
1244   
1245   if ((flags & GTK_CELL_RENDERER_PRELIT) == GTK_CELL_RENDERER_PRELIT)
1246     {
1247       switch (uline)
1248         {
1249         case PANGO_UNDERLINE_NONE:
1250           uline = PANGO_UNDERLINE_SINGLE;
1251           break;
1252
1253         case PANGO_UNDERLINE_SINGLE:
1254           uline = PANGO_UNDERLINE_DOUBLE;
1255           break;
1256
1257         default:
1258           break;
1259         }
1260     }
1261
1262   if (uline != PANGO_UNDERLINE_NONE)
1263     add_attr (attr_list, pango_attr_underline_new (celltext->underline_style));
1264
1265   if (celltext->rise_set)
1266     add_attr (attr_list, pango_attr_rise_new (celltext->rise));
1267   
1268   pango_layout_set_attributes (layout, attr_list);
1269   pango_layout_set_width (layout, -1);
1270
1271   pango_attr_list_unref (attr_list);
1272   
1273   return layout;
1274 }
1275
1276 static void
1277 gtk_cell_renderer_text_get_size (GtkCellRenderer *cell,
1278                                  GtkWidget       *widget,
1279                                  GdkRectangle    *cell_area,
1280                                  gint            *x_offset,
1281                                  gint            *y_offset,
1282                                  gint            *width,
1283                                  gint            *height)
1284 {
1285   GtkCellRendererText *celltext = (GtkCellRendererText *) cell;
1286   PangoRectangle rect;
1287   PangoLayout *layout;
1288
1289   if (celltext->calc_fixed_height)
1290     {
1291       PangoContext *context;
1292       PangoFontMetrics *metrics;
1293       PangoFontDescription *font_desc;
1294       gint row_height;
1295
1296       font_desc = pango_font_description_copy (widget->style->font_desc);
1297       pango_font_description_merge (font_desc, celltext->font, TRUE);
1298
1299       if (celltext->scale_set)
1300         pango_font_description_set_size (font_desc,
1301                                          celltext->font_scale * pango_font_description_get_size (font_desc));
1302
1303       context = gtk_widget_get_pango_context (widget);
1304
1305       metrics = pango_context_get_metrics (context,
1306                                            font_desc,
1307                                            pango_context_get_language (context));
1308       row_height = (pango_font_metrics_get_ascent (metrics) +
1309                     pango_font_metrics_get_descent (metrics));
1310       pango_font_metrics_unref (metrics);
1311       
1312       gtk_cell_renderer_set_fixed_size (cell,
1313                                         cell->width, 2*cell->ypad +
1314                                         celltext->fixed_height_rows * PANGO_PIXELS (row_height));
1315       
1316       if (height)
1317         {
1318           *height = cell->height;
1319           height = NULL;
1320         }
1321       celltext->calc_fixed_height = FALSE;
1322       if (width == NULL)
1323         return;
1324     }
1325   layout = get_layout (celltext, widget, FALSE, 0);
1326   pango_layout_get_pixel_extents (layout, NULL, &rect);
1327
1328   if (width)
1329     *width = GTK_CELL_RENDERER (celltext)->xpad * 2 + rect.width;
1330
1331   if (height)
1332     *height = GTK_CELL_RENDERER (celltext)->ypad * 2 + rect.height;
1333
1334   if (cell_area)
1335     {
1336       if (x_offset)
1337         {
1338           *x_offset = ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) ?
1339                        (1.0 - cell->xalign) : cell->xalign) * (cell_area->width - rect.width - (2 * cell->xpad));
1340           *x_offset = MAX (*x_offset, 0);
1341         }
1342       if (y_offset)
1343         {
1344           *y_offset = cell->yalign * (cell_area->height - rect.height - (2 * cell->ypad));
1345           *y_offset = MAX (*y_offset, 0);
1346         }
1347     }
1348
1349   g_object_unref (layout);
1350 }
1351
1352 static void
1353 gtk_cell_renderer_text_render (GtkCellRenderer      *cell,
1354                                GdkDrawable          *window,
1355                                GtkWidget            *widget,
1356                                GdkRectangle         *background_area,
1357                                GdkRectangle         *cell_area,
1358                                GdkRectangle         *expose_area,
1359                                GtkCellRendererState  flags)
1360
1361 {
1362   GtkCellRendererText *celltext = (GtkCellRendererText *) cell;
1363   PangoLayout *layout;
1364   GtkStateType state;
1365   gint x_offset;
1366   gint y_offset;
1367
1368   layout = get_layout (celltext, widget, TRUE, flags);
1369
1370   gtk_cell_renderer_text_get_size (cell, widget, cell_area, &x_offset, &y_offset, NULL, NULL);
1371
1372   if ((flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED)
1373     {
1374       if (GTK_WIDGET_HAS_FOCUS (widget))
1375         state = GTK_STATE_SELECTED;
1376       else
1377         state = GTK_STATE_ACTIVE;
1378     }
1379   else
1380     {
1381       if (GTK_WIDGET_STATE (widget) == GTK_STATE_INSENSITIVE)
1382         state = GTK_STATE_INSENSITIVE;
1383       else
1384         state = GTK_STATE_NORMAL;
1385     }
1386
1387   if (celltext->background_set && state != GTK_STATE_SELECTED)
1388     {
1389       GdkColor color;
1390       GdkGC *gc;
1391       
1392       color.red = celltext->background.red;
1393       color.green = celltext->background.green;
1394       color.blue = celltext->background.blue;
1395
1396       gc = gdk_gc_new (window);
1397
1398       gdk_gc_set_rgb_fg_color (gc, &color);
1399       
1400       gdk_draw_rectangle (window,
1401                           gc,
1402                           TRUE,
1403                           background_area->x,
1404                           background_area->y,
1405                           background_area->width,
1406                           background_area->height);
1407
1408       g_object_unref (gc);
1409     }
1410
1411   gtk_paint_layout (widget->style,
1412                     window,
1413                     state,
1414                     TRUE,
1415                     cell_area,
1416                     widget,
1417                     "cellrenderertext",
1418                     cell_area->x + x_offset + cell->xpad,
1419                     cell_area->y + y_offset + cell->ypad,
1420                     layout);
1421
1422   g_object_unref (layout);
1423 }
1424
1425 static void
1426 gtk_cell_renderer_text_editing_done (GtkCellEditable *entry,
1427                                      gpointer         data)
1428 {
1429   const gchar *path;
1430   const gchar *new_text;
1431   GtkCellRendererTextPrivate *priv;
1432
1433   priv = GTK_CELL_RENDERER_TEXT_GET_PRIVATE (data);
1434
1435   if (priv->focus_out_id > 0)
1436     {
1437       g_signal_handler_disconnect (entry, priv->focus_out_id);
1438       priv->focus_out_id = 0;
1439     }
1440
1441   if (GTK_ENTRY (entry)->editing_canceled)
1442     {
1443       gtk_cell_renderer_editing_canceled (GTK_CELL_RENDERER (data));
1444       return;
1445     }
1446
1447   path = g_object_get_data (G_OBJECT (entry), GTK_CELL_RENDERER_TEXT_PATH);
1448   new_text = gtk_entry_get_text (GTK_ENTRY (entry));
1449
1450   g_signal_emit (data, text_cell_renderer_signals[EDITED], 0, path, new_text);
1451 }
1452
1453 static gboolean
1454 gtk_cell_renderer_text_focus_out_event (GtkWidget *entry,
1455                                         GdkEvent  *event,
1456                                         gpointer   data)
1457 {
1458   gtk_cell_renderer_text_editing_done (GTK_CELL_EDITABLE (entry), data);
1459
1460   /* entry needs focus-out-event */
1461   return FALSE;
1462 }
1463
1464 static GtkCellEditable *
1465 gtk_cell_renderer_text_start_editing (GtkCellRenderer      *cell,
1466                                       GdkEvent             *event,
1467                                       GtkWidget            *widget,
1468                                       const gchar          *path,
1469                                       GdkRectangle         *background_area,
1470                                       GdkRectangle         *cell_area,
1471                                       GtkCellRendererState  flags)
1472 {
1473   GtkWidget *entry;
1474   GtkCellRendererText *celltext;
1475   GtkCellRendererTextPrivate *priv;
1476
1477   celltext = GTK_CELL_RENDERER_TEXT (cell);
1478   priv = GTK_CELL_RENDERER_TEXT_GET_PRIVATE (cell);
1479
1480   /* If the cell isn't editable we return NULL. */
1481   if (celltext->editable == FALSE)
1482     return NULL;
1483
1484   entry = g_object_new (GTK_TYPE_ENTRY,
1485                         "has_frame", FALSE,
1486                         NULL);
1487
1488   if (celltext->text)
1489     gtk_entry_set_text (GTK_ENTRY (entry), celltext->text);
1490   g_object_set_data_full (G_OBJECT (entry), GTK_CELL_RENDERER_TEXT_PATH, g_strdup (path), g_free);
1491   
1492   gtk_editable_select_region (GTK_EDITABLE (entry), 0, -1);
1493   
1494   gtk_widget_show (entry);
1495   g_signal_connect (entry,
1496                     "editing_done",
1497                     G_CALLBACK (gtk_cell_renderer_text_editing_done),
1498                     celltext);
1499   priv->focus_out_id = g_signal_connect (entry, "focus_out_event",
1500                          G_CALLBACK (gtk_cell_renderer_text_focus_out_event),
1501                          celltext);
1502
1503   return GTK_CELL_EDITABLE (entry);
1504
1505 }
1506
1507 /**
1508  * gtk_cell_renderer_text_set_fixed_height_from_font:
1509  * @renderer: A #GtkCellRendererText
1510  * @number_of_rows: Number of rows of text each cell renderer is allocated, or -1
1511  * 
1512  * Sets the height of a renderer to explicitly be determined by the "font" and
1513  * "y_pad" property set on it.  Further changes in these properties do not
1514  * affect the height, so they must be accompanied by a subsequent call to this
1515  * function.  Using this function is unflexible, and should really only be used
1516  * if calculating the size of a cell is too slow (ie, a massive number of cells
1517  * displayed).  If @number_of_rows is -1, then the fixed height is unset, and
1518  * the height is determined by the properties again.
1519  **/
1520 void
1521 gtk_cell_renderer_text_set_fixed_height_from_font (GtkCellRendererText *renderer,
1522                                                    gint                 number_of_rows)
1523 {
1524   g_return_if_fail (GTK_IS_CELL_RENDERER_TEXT (renderer));
1525   g_return_if_fail (number_of_rows == -1 || number_of_rows > 0);
1526
1527   if (number_of_rows == -1)
1528     {
1529       gtk_cell_renderer_set_fixed_size (GTK_CELL_RENDERER (renderer),
1530                                         GTK_CELL_RENDERER (renderer)->width,
1531                                         -1);
1532     }
1533   else
1534     {
1535       renderer->fixed_height_rows = number_of_rows;
1536       renderer->calc_fixed_height = TRUE;
1537     }
1538 }