gtkcellrenderertext.c 69 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/* gtkcellrenderertext.c
 * Copyright (C) 2000  Red Hat, Inc.,  Jonathan Blandford <jrb@redhat.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
Javier Jardón's avatar
Javier Jardón committed
15
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16 17
 */

18
#include "config.h"
19

20
#include "gtkcellrenderertext.h"
21 22 23

#include <stdlib.h>

24 25
#include "gtkeditable.h"
#include "gtkentry.h"
26
#include "gtksizerequest.h"
27
#include "gtkmarshalers.h"
28
#include "gtkintl.h"
29
#include "gtkprivate.h"
30
#include "gtktreeprivate.h"
31
#include "a11y/gtktextcellaccessible.h"
32

33

34 35 36 37 38 39 40 41 42 43 44 45 46 47
/**
 * SECTION:gtkcellrenderertext
 * @Short_description: Renders text in a cell
 * @Title: GtkCellRendererText
 *
 * A #GtkCellRendererText renders a given text in its cell, using the font, color and
 * style information provided by its properties. The text will be ellipsized if it is
 * too long and the #GtkCellRendererText:ellipsize property allows it.
 *
 * If the #GtkCellRenderer:mode is %GTK_CELL_RENDERER_MODE_EDITABLE,
 * the #GtkCellRendererText allows to edit its text using an entry.
 */


48
static void gtk_cell_renderer_text_finalize   (GObject                  *object);
49

50 51 52
static void gtk_cell_renderer_text_get_property  (GObject                  *object,
						  guint                     param_id,
						  GValue                   *value,
Tim Janik's avatar
Tim Janik committed
53
						  GParamSpec               *pspec);
54 55 56
static void gtk_cell_renderer_text_set_property  (GObject                  *object,
						  guint                     param_id,
						  const GValue             *value,
Tim Janik's avatar
Tim Janik committed
57
						  GParamSpec               *pspec);
58
static void gtk_cell_renderer_text_render     (GtkCellRenderer          *cell,
59
					       cairo_t                  *cr,
60
					       GtkWidget                *widget,
61 62
					       const GdkRectangle       *background_area,
					       const GdkRectangle       *cell_area,
63
					       GtkCellRendererState      flags);
64

65 66 67
static GtkCellEditable *gtk_cell_renderer_text_start_editing (GtkCellRenderer      *cell,
							      GdkEvent             *event,
							      GtkWidget            *widget,
68
							      const gchar          *path,
69 70
							      const GdkRectangle   *background_area,
							      const GdkRectangle   *cell_area,
71
							      GtkCellRendererState  flags);
72

73 74 75 76 77 78 79 80 81 82 83 84 85
static void       gtk_cell_renderer_text_get_preferred_width            (GtkCellRenderer       *cell,
                                                                         GtkWidget             *widget,
                                                                         gint                  *minimal_size,
                                                                         gint                  *natural_size);
static void       gtk_cell_renderer_text_get_preferred_height           (GtkCellRenderer       *cell,
                                                                         GtkWidget             *widget,
                                                                         gint                  *minimal_size,
                                                                         gint                  *natural_size);
static void       gtk_cell_renderer_text_get_preferred_height_for_width (GtkCellRenderer       *cell,
                                                                         GtkWidget             *widget,
                                                                         gint                   width,
                                                                         gint                  *minimum_height,
                                                                         gint                  *natural_height);
86 87 88 89 90 91 92
static void       gtk_cell_renderer_text_get_aligned_area               (GtkCellRenderer       *cell,
									 GtkWidget             *widget,
									 GtkCellRendererState   flags,
									 const GdkRectangle    *cell_area,
									 GdkRectangle          *aligned_area);


93

94 95 96 97
enum {
  EDITED,
  LAST_SIGNAL
};
98

99
enum {
100 101
  PROP_0,

102
  PROP_TEXT,
103
  PROP_MARKUP,
104
  PROP_ATTRIBUTES,
105
  PROP_SINGLE_PARAGRAPH_MODE,
106
  PROP_WIDTH_CHARS,
107
  PROP_MAX_WIDTH_CHARS,
108
  PROP_WRAP_WIDTH,
109
  PROP_ALIGN,
110 111
  PROP_PLACEHOLDER_TEXT,

112
  /* Style args */
113 114
  PROP_BACKGROUND,
  PROP_FOREGROUND,
115
  PROP_BACKGROUND_GDK,
116
  PROP_FOREGROUND_GDK,
117 118
  PROP_BACKGROUND_RGBA,
  PROP_FOREGROUND_RGBA,
119 120 121 122 123 124 125 126 127
  PROP_FONT,
  PROP_FONT_DESC,
  PROP_FAMILY,
  PROP_STYLE,
  PROP_VARIANT,
  PROP_WEIGHT,
  PROP_STRETCH,
  PROP_SIZE,
  PROP_SIZE_POINTS,
Havoc Pennington's avatar
Havoc Pennington committed
128
  PROP_SCALE,
129
  PROP_EDITABLE,
130 131
  PROP_STRIKETHROUGH,
  PROP_UNDERLINE,
132
  PROP_RISE,
133
  PROP_LANGUAGE,
134
  PROP_ELLIPSIZE,
135
  PROP_WRAP_MODE,
136

137 138 139 140 141 142 143 144 145
  /* Whether-a-style-arg-is-set args */
  PROP_BACKGROUND_SET,
  PROP_FOREGROUND_SET,
  PROP_FAMILY_SET,
  PROP_STYLE_SET,
  PROP_VARIANT_SET,
  PROP_WEIGHT_SET,
  PROP_STRETCH_SET,
  PROP_SIZE_SET,
Havoc Pennington's avatar
Havoc Pennington committed
146
  PROP_SCALE_SET,
147 148 149
  PROP_EDITABLE_SET,
  PROP_STRIKETHROUGH_SET,
  PROP_UNDERLINE_SET,
150
  PROP_RISE_SET,
151
  PROP_LANGUAGE_SET,
152
  PROP_ELLIPSIZE_SET,
153 154 155
  PROP_ALIGN_SET,

  LAST_PROP
156 157
};

158
static guint text_cell_renderer_signals [LAST_SIGNAL];
159
static GParamSpec *text_cell_renderer_props [LAST_PROP];
160 161

#define GTK_CELL_RENDERER_TEXT_PATH "gtk-cell-renderer-text-path"
162

163
struct _GtkCellRendererTextPrivate
164
{
165 166 167
  GtkWidget *entry;

  PangoAttrList        *extra_attrs;
168 169
  GdkRGBA               foreground;
  GdkRGBA               background;
170
  PangoAlignment        align;
171 172 173 174 175 176 177
  PangoEllipsizeMode    ellipsize;
  PangoFontDescription *font;
  PangoLanguage        *language;
  PangoUnderline        underline_style;
  PangoWrapMode         wrap_mode;

  gchar *text;
178
  gchar *placeholder_text;
179 180 181 182 183

  gdouble font_scale;

  gint rise;
  gint fixed_height_rows;
184
  gint width_chars;
185
  gint max_width_chars;
186
  gint wrap_width;
187

188
  guint in_entry_menu     : 1;
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
  guint strikethrough     : 1;
  guint editable          : 1;
  guint scale_set         : 1;
  guint foreground_set    : 1;
  guint background_set    : 1;
  guint underline_set     : 1;
  guint rise_set          : 1;
  guint strikethrough_set : 1;
  guint editable_set      : 1;
  guint calc_fixed_height : 1;
  guint single_paragraph  : 1;
  guint language_set      : 1;
  guint markup_set        : 1;
  guint ellipsize_set     : 1;
  guint align_set         : 1;

  gulong focus_out_id;
  gulong populate_popup_id;
  gulong entry_menu_popdown_timeout;
208 209
};

210
G_DEFINE_TYPE_WITH_PRIVATE (GtkCellRendererText, gtk_cell_renderer_text, GTK_TYPE_CELL_RENDERER)
211 212 213 214

static void
gtk_cell_renderer_text_init (GtkCellRendererText *celltext)
{
215
  GtkCellRendererTextPrivate *priv;
216
  GtkCellRenderer *cell = GTK_CELL_RENDERER (celltext);
217

218
  celltext->priv = gtk_cell_renderer_text_get_instance_private (celltext);
219
  priv = celltext->priv;
220

221 222
  gtk_cell_renderer_set_alignment (cell, 0.0, 0.5);
  gtk_cell_renderer_set_padding (cell, 2, 2);
223 224 225
  priv->font_scale = 1.0;
  priv->fixed_height_rows = -1;
  priv->font = pango_font_description_new ();
226 227

  priv->width_chars = -1;
228
  priv->max_width_chars = -1;
229
  priv->wrap_width = -1;
230
  priv->wrap_mode = PANGO_WRAP_CHAR;
231
  priv->align = PANGO_ALIGN_LEFT;
232
  priv->align_set = FALSE;
233 234 235 236 237 238 239 240
}

static void
gtk_cell_renderer_text_class_init (GtkCellRendererTextClass *class)
{
  GObjectClass *object_class = G_OBJECT_CLASS (class);
  GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (class);

241 242
  object_class->finalize = gtk_cell_renderer_text_finalize;
  
243 244
  object_class->get_property = gtk_cell_renderer_text_get_property;
  object_class->set_property = gtk_cell_renderer_text_set_property;
245 246

  cell_class->render = gtk_cell_renderer_text_render;
247
  cell_class->start_editing = gtk_cell_renderer_text_start_editing;
248 249 250
  cell_class->get_preferred_width = gtk_cell_renderer_text_get_preferred_width;
  cell_class->get_preferred_height = gtk_cell_renderer_text_get_preferred_height;
  cell_class->get_preferred_height_for_width = gtk_cell_renderer_text_get_preferred_height_for_width;
251
  cell_class->get_aligned_area = gtk_cell_renderer_text_get_aligned_area;
252

253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
  text_cell_renderer_props[PROP_TEXT] =
      g_param_spec_string ("text",
                           P_("Text"),
                           P_("Text to render"),
                           NULL,
                           GTK_PARAM_READWRITE);

  text_cell_renderer_props[PROP_MARKUP] =
      g_param_spec_string ("markup",
                           P_("Markup"),
                           P_("Marked up text to render"),
                           NULL,
                           GTK_PARAM_WRITABLE);

  text_cell_renderer_props[PROP_ATTRIBUTES] =
      g_param_spec_boxed ("attributes",
                          P_("Attributes"),
                          P_("A list of style attributes to apply to the text of the renderer"),
                          PANGO_TYPE_ATTR_LIST,
                          GTK_PARAM_READWRITE);

  text_cell_renderer_props[PROP_SINGLE_PARAGRAPH_MODE] =
      g_param_spec_boolean ("single-paragraph-mode",
                            P_("Single Paragraph Mode"),
                            P_("Whether to keep all text in a single paragraph"),
                            FALSE,
                            GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);

  text_cell_renderer_props[PROP_BACKGROUND] =
      g_param_spec_string ("background",
                           P_("Background color name"),
                           P_("Background color as a string"),
                           NULL,
                           GTK_PARAM_WRITABLE);
287

288 289 290 291 292 293 294
  /**
   * GtkCellRendererText:background-gdk:
   *
   * Background color as a #GdkColor
   *
   * Deprecated: 3.4: Use #GtkCellRendererText:background-rgba instead.
   */
Matthias Clasen's avatar
Matthias Clasen committed
295
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
296 297 298 299 300 301
  text_cell_renderer_props[PROP_BACKGROUND_GDK] =
      g_param_spec_boxed ("background-gdk",
                          P_("Background color"),
                          P_("Background color as a GdkColor"),
                          GDK_TYPE_COLOR,
                          GTK_PARAM_READWRITE | G_PARAM_DEPRECATED);
Matthias Clasen's avatar
Matthias Clasen committed
302
G_GNUC_END_IGNORE_DEPRECATIONS
303

304 305 306 307 308 309 310
  /**
   * GtkCellRendererText:background-rgba:
   *
   * Background color as a #GdkRGBA
   *
   * Since: 3.0
   */
311 312 313 314 315 316 317 318 319 320 321 322
  text_cell_renderer_props[PROP_BACKGROUND_RGBA] =
      g_param_spec_boxed ("background-rgba",
                          P_("Background color as RGBA"),
                          P_("Background color as a GdkRGBA"),
                          GDK_TYPE_RGBA,
                          GTK_PARAM_READWRITE);
  text_cell_renderer_props[PROP_FOREGROUND] =
      g_param_spec_string ("foreground",
                           P_("Foreground color name"),
                           P_("Foreground color as a string"),
                           NULL,
                           GTK_PARAM_WRITABLE);
323

324 325 326 327 328 329 330
  /**
   * GtkCellRendererText:foreground-gdk:
   *
   * Foreground color as a #GdkColor
   *
   * Deprecated: 3.4: Use #GtkCellRendererText:foreground-rgba instead.
   */
Matthias Clasen's avatar
Matthias Clasen committed
331
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
332 333 334 335 336 337
  text_cell_renderer_props[PROP_FOREGROUND_GDK] =
      g_param_spec_boxed ("foreground-gdk",
                          P_("Foreground color"),
                          P_("Foreground color as a GdkColor"),
                          GDK_TYPE_COLOR,
                          GTK_PARAM_READWRITE | G_PARAM_DEPRECATED);
Matthias Clasen's avatar
Matthias Clasen committed
338
G_GNUC_END_IGNORE_DEPRECATIONS
339

340 341 342 343 344 345 346
  /**
   * GtkCellRendererText:foreground-rgba:
   *
   * Foreground color as a #GdkRGBA
   *
   * Since: 3.0
   */
347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470
  text_cell_renderer_props[PROP_FOREGROUND_RGBA] =
      g_param_spec_boxed ("foreground-rgba",
                          P_("Foreground color as RGBA"),
                          P_("Foreground color as a GdkRGBA"),
                          GDK_TYPE_RGBA,
                          GTK_PARAM_READWRITE);


  text_cell_renderer_props[PROP_EDITABLE] =
      g_param_spec_boolean ("editable",
                            P_("Editable"),
                            P_("Whether the text can be modified by the user"),
                            FALSE,
                            GTK_PARAM_READWRITE);

  text_cell_renderer_props[PROP_FONT] =
      g_param_spec_string ("font",
                           P_("Font"),
                           P_("Font description as a string, e.g. \"Sans Italic 12\""),
                           NULL,
                           GTK_PARAM_READWRITE);

  text_cell_renderer_props[PROP_FONT_DESC] =
      g_param_spec_boxed ("font-desc",
                          P_("Font"),
                          P_("Font description as a PangoFontDescription struct"),
                          PANGO_TYPE_FONT_DESCRIPTION,
                          GTK_PARAM_READWRITE);

  text_cell_renderer_props[PROP_FAMILY] =
      g_param_spec_string ("family",
                           P_("Font family"),
                           P_("Name of the font family, e.g. Sans, Helvetica, Times, Monospace"),
                           NULL,
                           GTK_PARAM_READWRITE);

  text_cell_renderer_props[PROP_STYLE] =
      g_param_spec_enum ("style",
                         P_("Font style"),
                         P_("Font style"),
                         PANGO_TYPE_STYLE,
                         PANGO_STYLE_NORMAL,
                         GTK_PARAM_READWRITE);

  text_cell_renderer_props[PROP_VARIANT] =
      g_param_spec_enum ("variant",
                         P_("Font variant"),
                         P_("Font variant"),
                         PANGO_TYPE_VARIANT,
                         PANGO_VARIANT_NORMAL,
                         GTK_PARAM_READWRITE);

  text_cell_renderer_props[PROP_WEIGHT] =
      g_param_spec_int ("weight",
                        P_("Font weight"),
                        P_("Font weight"),
                        0, G_MAXINT,
                        PANGO_WEIGHT_NORMAL,
                        GTK_PARAM_READWRITE);

   text_cell_renderer_props[PROP_STRETCH] =
       g_param_spec_enum ("stretch",
                          P_("Font stretch"),
                          P_("Font stretch"),
                          PANGO_TYPE_STRETCH,
                          PANGO_STRETCH_NORMAL,
                          GTK_PARAM_READWRITE);

  text_cell_renderer_props[PROP_SIZE] =
      g_param_spec_int ("size",
                        P_("Font size"),
                        P_("Font size"),
                        0, G_MAXINT,
                        0,
                        GTK_PARAM_READWRITE);

  text_cell_renderer_props[PROP_SIZE_POINTS] =
      g_param_spec_double ("size-points",
                           P_("Font points"),
                           P_("Font size in points"),
                           0.0, G_MAXDOUBLE,
                           0.0,
                           GTK_PARAM_READWRITE);

  text_cell_renderer_props[PROP_SCALE] =
      g_param_spec_double ("scale",
                           P_("Font scale"),
                           P_("Font scaling factor"),
                           0.0, G_MAXDOUBLE,
                           1.0,
                           GTK_PARAM_READWRITE);

  text_cell_renderer_props[PROP_RISE] =
      g_param_spec_int ("rise",
                        P_("Rise"),
                        P_("Offset of text above the baseline (below the baseline if rise is negative)"),
                        -G_MAXINT, G_MAXINT,
                        0,
                        GTK_PARAM_READWRITE);


  text_cell_renderer_props[PROP_STRIKETHROUGH] =
      g_param_spec_boolean ("strikethrough",
                            P_("Strikethrough"),
                            P_("Whether to strike through the text"),
                            FALSE,
                            GTK_PARAM_READWRITE);

  text_cell_renderer_props[PROP_UNDERLINE] =
      g_param_spec_enum ("underline",
                         P_("Underline"),
                         P_("Style of underline for this text"),
                         PANGO_TYPE_UNDERLINE,
                         PANGO_UNDERLINE_NONE,
                         GTK_PARAM_READWRITE);

  text_cell_renderer_props[PROP_LANGUAGE] =
      g_param_spec_string ("language",
                           P_("Language"),
                           P_("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"),
                           NULL,
                           GTK_PARAM_READWRITE);
471

472 473 474
  /**
   * GtkCellRendererText:ellipsize:
   *
475 476
   * Specifies the preferred place to ellipsize the string, if the cell renderer
   * does not have enough room to display the entire string. Setting it to
477 478 479 480 481
   * %PANGO_ELLIPSIZE_NONE turns off ellipsizing. See the wrap-width property
   * for another way of making the text fit into a given width.
   *
   * Since: 2.6
   */
482 483 484 485 486 487 488 489 490
  text_cell_renderer_props[PROP_ELLIPSIZE] =
      g_param_spec_enum ("ellipsize",
                         P_("Ellipsize"),
                         P_("The preferred place to ellipsize the string, "
                            "if the cell renderer does not have enough room "
                            "to display the entire string"),
                         PANGO_TYPE_ELLIPSIZE_MODE,
                         PANGO_ELLIPSIZE_NONE,
                         GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
491 492 493

  /**
   * GtkCellRendererText:width-chars:
494
   *
495 496 497
   * The desired width of the cell, in characters. If this property is set to
   * -1, the width will be calculated automatically, otherwise the cell will
   * request either 3 characters or the property value, whichever is greater.
498
   *
499 500
   * Since: 2.6
   **/
501 502 503 504 505 506 507
  text_cell_renderer_props[PROP_WIDTH_CHARS] =
      g_param_spec_int ("width-chars",
                        P_("Width In Characters"),
                        P_("The desired width of the label, in characters"),
                        -1, G_MAXINT,
                        -1,
                        GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
508 509 510

  /**
   * GtkCellRendererText:max-width-chars:
511 512
   *
   * The desired maximum width of the cell, in characters. If this property
513 514 515 516 517 518 519 520 521 522
   * is set to -1, the width will be calculated automatically.
   *
   * For cell renderers that ellipsize or wrap text; this property
   * controls the maximum reported width of the cell. The
   * cell should not receive any greater allocation unless it is
   * set to expand in its #GtkCellLayout and all of the cell's siblings
   * have received their natural width.
   *
   * Since: 3.0
   **/
523 524 525 526 527 528 529 530
  text_cell_renderer_props[PROP_MAX_WIDTH_CHARS] =
      g_param_spec_int ("max-width-chars",
                        P_("Maximum Width In Characters"),
                        P_("The maximum width of the cell, in characters"),
                        -1, G_MAXINT,
                        -1,
                        GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);

531 532 533
  /**
   * GtkCellRendererText:wrap-mode:
   *
534 535
   * Specifies how to break the string into multiple lines, if the cell
   * renderer does not have enough room to display the entire string.
536
   * This property has no effect unless the wrap-width property is set.
537 538 539
   *
   * Since: 2.8
   */
540 541 542 543 544 545 546 547 548
  text_cell_renderer_props[PROP_WRAP_MODE] =
      g_param_spec_enum ("wrap-mode",
                         P_("Wrap mode"),
                         P_("How to break the string into multiple lines, "
                            "if the cell renderer does not have enough room "
                            "to display the entire string"),
                         PANGO_TYPE_WRAP_MODE,
                         PANGO_WRAP_CHAR,
                         GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
549 550 551 552

  /**
   * GtkCellRendererText:wrap-width:
   *
553
   * Specifies the minimum width at which the text is wrapped. The wrap-mode property can
554 555 556 557 558
   * be used to influence at what character positions the line breaks can be placed.
   * Setting wrap-width to -1 turns wrapping off.
   *
   * Since: 2.8
   */
559 560 561 562 563 564 565
  text_cell_renderer_props[PROP_WRAP_WIDTH] =
      g_param_spec_int ("wrap-width",
                        P_("Wrap width"),
                        P_("The width at which the text is wrapped"),
                        -1, G_MAXINT,
                        -1,
                        GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
566

567 568 569
  /**
   * GtkCellRendererText:alignment:
   *
570
   * Specifies how to align the lines of text with respect to each other.
571
   *
572 573
   * Note that this property describes how to align the lines of text in
   * case there are several of them. The "xalign" property of #GtkCellRenderer,
574
   * on the other hand, sets the horizontal alignment of the whole text.
575 576 577
   *
   * Since: 2.10
   */
578 579 580 581 582 583 584
  text_cell_renderer_props[PROP_ALIGN] =
      g_param_spec_enum ("alignment",
                         P_("Alignment"),
                         P_("How to align the lines"),
                         PANGO_TYPE_ALIGNMENT,
                         PANGO_ALIGN_LEFT,
                         GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
585 586 587 588 589 590 591 592 593

  /**
   * GtkCellRendererText:placeholder-text:
   *
   * The text that will be displayed in the #GtkCellRenderer if
   * #GtkCellRendererText:editable is %TRUE and the cell is empty.
   *
   * Since 3.6
   */
594 595 596 597 598 599
  text_cell_renderer_props[PROP_PLACEHOLDER_TEXT] =
      g_param_spec_string ("placeholder-text",
                           P_("Placeholder text"),
                           P_("Text rendered when an editable cell is empty"),
                           NULL,
                           GTK_PARAM_READWRITE);
600

601 602
  /* Style props are set or not */

603
#define ADD_SET_PROP(propname, propval, nick, blurb) text_cell_renderer_props[propval] = g_param_spec_boolean (propname, nick, blurb, FALSE, GTK_PARAM_READWRITE)
604

Matthias Clasen's avatar
x  
Matthias Clasen committed
605
  ADD_SET_PROP ("background-set", PROP_BACKGROUND_SET,
606 607
                P_("Background set"),
                P_("Whether this tag affects the background color"));
608

Matthias Clasen's avatar
x  
Matthias Clasen committed
609
  ADD_SET_PROP ("foreground-set", PROP_FOREGROUND_SET,
610 611
                P_("Foreground set"),
                P_("Whether this tag affects the foreground color"));
612

Matthias Clasen's avatar
x  
Matthias Clasen committed
613
  ADD_SET_PROP ("editable-set", PROP_EDITABLE_SET,
614 615
                P_("Editability set"),
                P_("Whether this tag affects text editability"));
616

Matthias Clasen's avatar
x  
Matthias Clasen committed
617
  ADD_SET_PROP ("family-set", PROP_FAMILY_SET,
618
                P_("Font family set"),
619
                P_("Whether this tag affects the font family"));
620

Matthias Clasen's avatar
x  
Matthias Clasen committed
621
  ADD_SET_PROP ("style-set", PROP_STYLE_SET,
622 623
                P_("Font style set"),
                P_("Whether this tag affects the font style"));
624

Matthias Clasen's avatar
x  
Matthias Clasen committed
625
  ADD_SET_PROP ("variant-set", PROP_VARIANT_SET,
626 627
                P_("Font variant set"),
                P_("Whether this tag affects the font variant"));
628

Matthias Clasen's avatar
x  
Matthias Clasen committed
629
  ADD_SET_PROP ("weight-set", PROP_WEIGHT_SET,
630 631
                P_("Font weight set"),
                P_("Whether this tag affects the font weight"));
632

Matthias Clasen's avatar
x  
Matthias Clasen committed
633
  ADD_SET_PROP ("stretch-set", PROP_STRETCH_SET,
634 635
                P_("Font stretch set"),
                P_("Whether this tag affects the font stretch"));
636

Matthias Clasen's avatar
x  
Matthias Clasen committed
637
  ADD_SET_PROP ("size-set", PROP_SIZE_SET,
638 639
                P_("Font size set"),
                P_("Whether this tag affects the font size"));
640

Matthias Clasen's avatar
x  
Matthias Clasen committed
641
  ADD_SET_PROP ("scale-set", PROP_SCALE_SET,
642 643
                P_("Font scale set"),
                P_("Whether this tag scales the font size by a factor"));
644

Matthias Clasen's avatar
x  
Matthias Clasen committed
645
  ADD_SET_PROP ("rise-set", PROP_RISE_SET,
646 647
                P_("Rise set"),
                P_("Whether this tag affects the rise"));
648

Matthias Clasen's avatar
x  
Matthias Clasen committed
649
  ADD_SET_PROP ("strikethrough-set", PROP_STRIKETHROUGH_SET,
650 651
                P_("Strikethrough set"),
                P_("Whether this tag affects strikethrough"));
652

Matthias Clasen's avatar
x  
Matthias Clasen committed
653
  ADD_SET_PROP ("underline-set", PROP_UNDERLINE_SET,
654 655
                P_("Underline set"),
                P_("Whether this tag affects underlining"));
656

Matthias Clasen's avatar
x  
Matthias Clasen committed
657
  ADD_SET_PROP ("language-set", PROP_LANGUAGE_SET,
658 659
                P_("Language set"),
                P_("Whether this tag affects the language the text is rendered as"));
660

Matthias Clasen's avatar
x  
Matthias Clasen committed
661
  ADD_SET_PROP ("ellipsize-set", PROP_ELLIPSIZE_SET,
662
                P_("Ellipsize set"),
663
                P_("Whether this tag affects the ellipsize mode"));
664

665 666 667 668
  ADD_SET_PROP ("align-set", PROP_ALIGN_SET,
                P_("Align set"),
                P_("Whether this tag affects the alignment mode"));

669 670
  g_object_class_install_properties (object_class, LAST_PROP, text_cell_renderer_props);

671
  /**
672
   * GtkCellRendererText::edited:
673 674 675
   * @renderer: the object which received the signal
   * @path: the path identifying the edited cell
   * @new_text: the new text
676 677
   *
   * This signal is emitted after @renderer has been edited.
678 679 680
   *
   * It is the responsibility of the application to update the model
   * and store @new_text at the position indicated by @path.
681
   */
682
  text_cell_renderer_signals [EDITED] =
683
    g_signal_new (I_("edited"),
Manish Singh's avatar
Manish Singh committed
684 685 686 687 688 689 690 691
		  G_OBJECT_CLASS_TYPE (object_class),
		  G_SIGNAL_RUN_LAST,
		  G_STRUCT_OFFSET (GtkCellRendererTextClass, edited),
		  NULL, NULL,
		  _gtk_marshal_VOID__STRING_STRING,
		  G_TYPE_NONE, 2,
		  G_TYPE_STRING,
		  G_TYPE_STRING);
692

693
  gtk_cell_renderer_class_set_accessible_type (cell_class, GTK_TYPE_TEXT_CELL_ACCESSIBLE);
694 695 696 697 698 699
}

static void
gtk_cell_renderer_text_finalize (GObject *object)
{
  GtkCellRendererText *celltext = GTK_CELL_RENDERER_TEXT (object);
700
  GtkCellRendererTextPrivate *priv = celltext->priv;
701

702
  pango_font_description_free (priv->font);
703

704
  g_free (priv->text);
705
  g_free (priv->placeholder_text);
706

707 708
  if (priv->extra_attrs)
    pango_attr_list_unref (priv->extra_attrs);
709

710 711 712
  if (priv->language)
    g_object_unref (priv->language);

713 714
  g_clear_object (&priv->entry);

715
  G_OBJECT_CLASS (gtk_cell_renderer_text_parent_class)->finalize (object);
716 717
}

718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739
static PangoFontMask
get_property_font_set_mask (guint prop_id)
{
  switch (prop_id)
    {
    case PROP_FAMILY_SET:
      return PANGO_FONT_MASK_FAMILY;
    case PROP_STYLE_SET:
      return PANGO_FONT_MASK_STYLE;
    case PROP_VARIANT_SET:
      return PANGO_FONT_MASK_VARIANT;
    case PROP_WEIGHT_SET:
      return PANGO_FONT_MASK_WEIGHT;
    case PROP_STRETCH_SET:
      return PANGO_FONT_MASK_STRETCH;
    case PROP_SIZE_SET:
      return PANGO_FONT_MASK_SIZE;
    }

  return 0;
}

740
static void
741 742 743
gtk_cell_renderer_text_get_property (GObject        *object,
				     guint           param_id,
				     GValue         *value,
Tim Janik's avatar
Tim Janik committed
744
				     GParamSpec     *pspec)
745 746
{
  GtkCellRendererText *celltext = GTK_CELL_RENDERER_TEXT (object);
747
  GtkCellRendererTextPrivate *priv = celltext->priv;
748 749 750 751

  switch (param_id)
    {
    case PROP_TEXT:
752
      g_value_set_string (value, priv->text);
753
      break;
754 755

    case PROP_ATTRIBUTES:
756
      g_value_set_boxed (value, priv->extra_attrs);
757 758
      break;

759 760 761 762
    case PROP_SINGLE_PARAGRAPH_MODE:
      g_value_set_boolean (value, priv->single_paragraph);
      break;

763 764 765
    case PROP_BACKGROUND_GDK:
      {
        GdkColor color;
766 767 768 769 770

        color.red = (guint16) (priv->background.red * 65535);
        color.green = (guint16) (priv->background.green * 65535);
        color.blue = (guint16) (priv->background.blue * 65535);

771 772
        g_value_set_boxed (value, &color);
      }
773
      break;
774 775 776 777

    case PROP_FOREGROUND_GDK:
      {
        GdkColor color;
778 779 780 781 782

        color.red = (guint16) (priv->foreground.red * 65535);
        color.green = (guint16) (priv->foreground.green * 65535);
        color.blue = (guint16) (priv->foreground.blue * 65535);

783 784 785 786
        g_value_set_boxed (value, &color);
      }
      break;

787 788 789 790 791 792 793 794
    case PROP_BACKGROUND_RGBA:
      g_value_set_boxed (value, &priv->background);
      break;

    case PROP_FOREGROUND_RGBA:
      g_value_set_boxed (value, &priv->foreground);
      break;

795
    case PROP_FONT:
796
        g_value_take_string (value, pango_font_description_to_string (priv->font));
797
      break;
798 799
      
    case PROP_FONT_DESC:
800
      g_value_set_boxed (value, priv->font);
801 802 803
      break;

    case PROP_FAMILY:
804
      g_value_set_string (value, pango_font_description_get_family (priv->font));
805 806 807
      break;

    case PROP_STYLE:
808
      g_value_set_enum (value, pango_font_description_get_style (priv->font));
809 810 811
      break;

    case PROP_VARIANT:
812
      g_value_set_enum (value, pango_font_description_get_variant (priv->font));
813 814 815
      break;

    case PROP_WEIGHT:
816
      g_value_set_int (value, pango_font_description_get_weight (priv->font));
817 818 819
      break;

    case PROP_STRETCH:
820
      g_value_set_enum (value, pango_font_description_get_stretch (priv->font));
821 822 823
      break;

    case PROP_SIZE:
824
      g_value_set_int (value, pango_font_description_get_size (priv->font));
825 826 827
      break;

    case PROP_SIZE_POINTS:
828
      g_value_set_double (value, ((double)pango_font_description_get_size (priv->font)) / (double)PANGO_SCALE);
829 830
      break;

Havoc Pennington's avatar
Havoc Pennington committed
831
    case PROP_SCALE:
832
      g_value_set_double (value, priv->font_scale);
Havoc Pennington's avatar
Havoc Pennington committed
833 834
      break;
      
835
    case PROP_EDITABLE:
836
      g_value_set_boolean (value, priv->editable);
837
      break;
838 839

    case PROP_STRIKETHROUGH:
840
      g_value_set_boolean (value, priv->strikethrough);
841 842 843
      break;

    case PROP_UNDERLINE:
844
      g_value_set_enum (value, priv->underline_style);
845 846 847
      break;

    case PROP_RISE:
848
      g_value_set_int (value, priv->rise);
849 850
      break;  

851
    case PROP_LANGUAGE:
852
      g_value_set_static_string (value, pango_language_to_string (priv->language));
853 854
      break;

855 856 857 858
    case PROP_ELLIPSIZE:
      g_value_set_enum (value, priv->ellipsize);
      break;
      
859 860 861 862 863 864 865 866
    case PROP_WRAP_MODE:
      g_value_set_enum (value, priv->wrap_mode);
      break;

    case PROP_WRAP_WIDTH:
      g_value_set_int (value, priv->wrap_width);
      break;
      
867 868 869 870
    case PROP_ALIGN:
      g_value_set_enum (value, priv->align);
      break;

871
    case PROP_BACKGROUND_SET:
872
      g_value_set_boolean (value, priv->background_set);
873 874 875
      break;

    case PROP_FOREGROUND_SET:
876
      g_value_set_boolean (value, priv->foreground_set);
877 878 879 880 881 882 883 884
      break;

    case PROP_FAMILY_SET:
    case PROP_STYLE_SET:
    case PROP_VARIANT_SET:
    case PROP_WEIGHT_SET:
    case PROP_STRETCH_SET:
    case PROP_SIZE_SET:
885 886
      {
	PangoFontMask mask = get_property_font_set_mask (param_id);
887
	g_value_set_boolean (value, (pango_font_description_get_set_fields (priv->font) & mask) != 0);
888 889
	
	break;
890
      }
891

Havoc Pennington's avatar
Havoc Pennington committed
892
    case PROP_SCALE_SET:
893
      g_value_set_boolean (value, priv->scale_set);
Havoc Pennington's avatar
Havoc Pennington committed
894 895
      break;
      
896
    case PROP_EDITABLE_SET:
897
      g_value_set_boolean (value, priv->editable_set);
898 899 900
      break;

    case PROP_STRIKETHROUGH_SET:
901
      g_value_set_boolean (value, priv->strikethrough_set);
902 903 904
      break;

    case PROP_UNDERLINE_SET:
905
      g_value_set_boolean (value, priv->underline_set);
906 907 908
      break;

    case  PROP_RISE_SET:
909
      g_value_set_boolean (value, priv->rise_set);
910
      break;
911 912 913 914

    case PROP_LANGUAGE_SET:
      g_value_set_boolean (value, priv->language_set);
      break;
915 916 917 918

    case PROP_ELLIPSIZE_SET:
      g_value_set_boolean (value, priv->ellipsize_set);
      break;
919 920 921 922

    case PROP_ALIGN_SET:
      g_value_set_boolean (value, priv->align_set);
      break;
923
      
924 925 926 927
    case PROP_WIDTH_CHARS:
      g_value_set_int (value, priv->width_chars);
      break;  

928 929 930 931
    case PROP_MAX_WIDTH_CHARS:
      g_value_set_int (value, priv->max_width_chars);
      break;  

932 933 934 935
    case PROP_PLACEHOLDER_TEXT:
      g_value_set_string (value, priv->placeholder_text);
      break;

936 937
    case PROP_BACKGROUND:
    case PROP_FOREGROUND:
938
    case PROP_MARKUP:
939
    default:
940
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
941 942 943 944 945
      break;
    }
}


946 947
static void
set_bg_color (GtkCellRendererText *celltext,
948
              GdkRGBA             *rgba)
949
{
950
  GtkCellRendererTextPrivate *priv = celltext->priv;
951

952
  if (rgba)
953
    {
954
      if (!priv->background_set)
955
        {
956
          priv->background_set = TRUE;
957
          g_object_notify_by_pspec (G_OBJECT (celltext), text_cell_renderer_props[PROP_BACKGROUND_SET]);
958
        }
959 960

      priv->background = *rgba;
961 962 963
    }
  else
    {
964
      if (priv->background_set)
965
        {
966
          priv->background_set = FALSE;
967
          g_object_notify_by_pspec (G_OBJECT (celltext), text_cell_renderer_props[PROP_BACKGROUND_SET]);
968 969 970 971 972 973 974
        }
    }
}


static void
set_fg_color (GtkCellRendererText *celltext,
975
              GdkRGBA             *rgba)
976
{
977
  GtkCellRendererTextPrivate *priv = celltext->priv;
978

979
  if (rgba)
980
    {
981
      if (!priv->foreground_set)
982
        {
983
          priv->foreground_set = TRUE;
984
          g_object_notify_by_pspec (G_OBJECT (celltext), text_cell_renderer_props[PROP_FOREGROUND_SET]);
985
        }
986 987

      priv->foreground = *rgba;
988 989 990
    }
  else
    {
991
      if (priv->foreground_set)
992
        {
993
          priv->foreground_set = FALSE;
994
          g_object_notify_by_pspec (G_OBJECT (celltext), text_cell_renderer_props[PROP_FOREGROUND_SET]);
995 996 997 998
        }
    }
}

999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038
static PangoFontMask
set_font_desc_fields (PangoFontDescription *desc,
		      PangoFontMask         to_set)
{
  PangoFontMask changed_mask = 0;
  
  if (to_set & PANGO_FONT_MASK_FAMILY)
    {
      const char *family = pango_font_description_get_family (desc);
      if (!family)
	{
	  family = "sans";
	  changed_mask |= PANGO_FONT_MASK_FAMILY;
	}

      pango_font_description_set_family (desc, family);
    }
  if (to_set & PANGO_FONT_MASK_STYLE)
    pango_font_description_set_style (desc, pango_font_description_get_style (desc));
  if (to_set & PANGO_FONT_MASK_VARIANT)
    pango_font_description_set_variant (desc, pango_font_description_get_variant (desc));
  if (to_set & PANGO_FONT_MASK_WEIGHT)
    pango_font_description_set_weight (desc, pango_font_description_get_weight (desc));
  if (to_set & PANGO_FONT_MASK_STRETCH)
    pango_font_description_set_stretch (desc, pango_font_description_get_stretch (desc));
  if (to_set & PANGO_FONT_MASK_SIZE)
    {
      gint size = pango_font_description_get_size (desc);
      if (size <= 0)
	{
	  size = 10 * PANGO_SCALE;
	  changed_mask |= PANGO_FONT_MASK_SIZE;
	}
      
      pango_font_description_set_size (desc, size);
    }

  return changed_mask;
}

1039 1040 1041 1042 1043
static void
notify_set_changed (GObject       *object,
		    PangoFontMask  changed_mask)
{
  if (changed_mask & PANGO_FONT_MASK_FAMILY)
1044
    g_object_notify_by_pspec (object, text_cell_renderer_props[PROP_FAMILY_SET]);
1045
  if (changed_mask & PANGO_FONT_MASK_STYLE)
1046
    g_object_notify_by_pspec (object, text_cell_renderer_props[PROP_STYLE_SET]);
1047
  if (changed_mask & PANGO_FONT_MASK_VARIANT)
1048
    g_object_notify_by_pspec (object, text_cell_renderer_props[PROP_VARIANT_SET]);
1049
  if (changed_mask & PANGO_FONT_MASK_WEIGHT)
1050
    g_object_notify_by_pspec (object, text_cell_renderer_props[PROP_WEIGHT_SET]);
1051
  if (changed_mask & PANGO_FONT_MASK_STRETCH)
1052
    g_object_notify_by_pspec (object, text_cell_renderer_props[PROP_STRETCH_SET]);
1053
  if (changed_mask & PANGO_FONT_MASK_SIZE)
1054
    g_object_notify_by_pspec (object, text_cell_renderer_props[PROP_SIZE_SET]);
1055 1056
}

1057 1058 1059 1060 1061
static void
notify_fields_changed (GObject       *object,
		       PangoFontMask  changed_mask)
{
  if (changed_mask & PANGO_FONT_MASK_FAMILY)
1062
    g_object_notify_by_pspec (object, text_cell_renderer_props[PROP_FAMILY]);
1063
  if (changed_mask & PANGO_FONT_MASK_STYLE)
1064
    g_object_notify_by_pspec (object, text_cell_renderer_props[PROP_STYLE]);
1065
  if (changed_mask & PANGO_FONT_MASK_VARIANT)
1066
    g_object_notify_by_pspec (object, text_cell_renderer_props[PROP_VARIANT]);
1067
  if (changed_mask & PANGO_FONT_MASK_WEIGHT)
1068
    g_object_notify_by_pspec (object, text_cell_renderer_props[PROP_WEIGHT]);
1069
  if (changed_mask & PANGO_FONT_MASK_STRETCH)
1070
    g_object_notify_by_pspec (object, text_cell_renderer_props[PROP_STRETCH]);
1071
  if (changed_mask & PANGO_FONT_MASK_SIZE)
1072 1073 1074 1075
    {
      g_object_notify_by_pspec (object, text_cell_renderer_props[PROP_SIZE]);
      g_object_notify_by_pspec (object, text_cell_renderer_props[PROP_SIZE_POINTS]);
    }
1076 1077
}

1078 1079 1080 1081
static void
set_font_description (GtkCellRendererText  *celltext,
                      PangoFontDescription *font_desc)
{
1082
  GtkCellRendererTextPrivate *priv = celltext->priv;
1083 1084 1085
  GObject *object = G_OBJECT (celltext);
  PangoFontDescription *new_font_desc;
  PangoFontMask old_mask, new_mask, changed_mask, set_changed_mask;
1086

1087 1088
  if (font_desc)
    new_font_desc = pango_font_description_copy (font_desc);
1089
  else
1090 1091
    new_font_desc = pango_font_description_new ();

1092
  old_mask = pango_font_description_get_set_fields (priv->font);
1093 1094 1095 1096 1097
  new_mask = pango_font_description_get_set_fields (new_font_desc);

  changed_mask = old_mask | new_mask;
  set_changed_mask = old_mask ^ new_mask;

1098 1099
  pango_font_description_free (priv->font);
  priv->font = new_font_desc;
1100

1101 1102
  g_object_freeze_notify (object);

1103 1104
  g_object_notify_by_pspec (object, text_cell_renderer_props[PROP_FONT_DESC]);
  g_object_notify_by_pspec (object, text_cell_renderer_props[PROP_FONT]);
1105

1106
  notify_fields_changed (object, changed_mask);
1107
  notify_set_changed (object, set_changed_mask);
1108

1109
  g_object_thaw_notify (object);
1110 1111
}

1112
static void
1113 1114 1115
gtk_cell_renderer_text_set_property (GObject      *object,
				     guint         param_id,
				     const GValue *value,
Tim Janik's avatar
Tim Janik committed
1116
				     GParamSpec   *pspec)
1117 1118
{
  GtkCellRendererText *celltext = GTK_CELL_RENDERER_TEXT (object);
1119
  GtkCellRendererTextPrivate *priv = celltext->priv;
1120 1121 1122 1123

  switch (param_id)
    {
    case PROP_TEXT:
1124
      g_free (priv->text);
1125 1126 1127

      if (priv->markup_set)
        {
1128 1129 1130
          if (priv->extra_attrs)
            pango_attr_list_unref (priv->extra_attrs);
          priv->extra_attrs = NULL;
1131 1132 1133
          priv->markup_set = FALSE;
        }

1134
      priv->text = g_value_dup_string (value);
1135
      g_object_notify_by_pspec (object, pspec);
1136
      break;
1137 1138

    case PROP_ATTRIBUTES:
1139 1140
      if (priv->extra_attrs)
	pango_attr_list_unref (priv->extra_attrs);
1141

1142 1143 1144
      priv->extra_attrs = g_value_get_boxed (value);
      if (priv->extra_attrs)
        pango_attr_list_ref (priv->extra_attrs);
1145
      break;
1146 1147 1148 1149 1150 1151 1152 1153
    case PROP_MARKUP:
      {
	const gchar *str;
	gchar *text = NULL;
	GError *error = NULL;
	PangoAttrList *attrs = NULL;

	str = g_value_get_string (value);
1154
	if (str && !pango_parse_markup (str, -1, 0, &attrs, &text, NULL, &error))
1155
	  {
1156
	    g_warning ("Failed to set text from markup due to error parsing markup: %s",
1157 1158 1159 1160
		       error->message);
	    g_error_free (error);
	    return;
	  }
Kristian Rietveld's avatar
Kristian Rietveld committed
1161

1162
	g_free (priv->text);
Kristian Rietveld's avatar
Kristian Rietveld committed
1163

1164 1165
	if (priv->extra_attrs)
	  pango_attr_list_unref (priv->extra_attrs);
Kristian Rietveld's avatar
Kristian Rietveld committed
1166

1167 1168
	priv->text = text;
	priv->extra_attrs = attrs;
1169
        priv->markup_set = TRUE;
1170 1171
      }
      break;
1172 1173

    case PROP_SINGLE_PARAGRAPH_MODE:
1174 1175 1176 1177 1178
      if (priv->single_paragraph != g_value_get_boolean (value))
        {
          priv->single_paragraph = g_value_get_boolean (value);
          g_object_notify_by_pspec (object, pspec);
        }
1179
      break;
1180

1181
    case PROP_BACKGROUND:
1182
      {
1183
        GdkRGBA rgba;
1184

1185
        if (!g_value_get_string (value))
1186
          set_bg_color (celltext, NULL);       /* reset to background_set to FALSE */
1187
        else if (gdk_rgba_parse (&rgba, g_value_get_string (value)))
1188
          set_bg_color (celltext, &rgba);
1189
        else
1190
          g_warning ("Don't know color '%s'", g_value_get_string (value));
1191

1192
        g_object_notify_by_pspec (object, text_cell_renderer_props[PROP_BACKGROUND_GDK]);
1193
      }
1194
      break;
1195

1196
    case PROP_FOREGROUND:
1197
      {
1198
        GdkRGBA rgba;
1199

1200 1201
        if (!g_value_get_string (value))
          set_fg_color (celltext, NULL);       /* reset to foreground_set to FALSE */
1202
        else if (gdk_rgba_parse (&rgba, g_value_get_string (value)))
1203
          set_fg_color (celltext, &rgba);
1204
        else
1205
          g_warning ("Don't know color '%s'", g_value_get_string (value));
1206

1207
        g_object_notify_by_pspec (object, text_cell_renderer_props[PROP_FOREGROUND_GDK]);
1208 1209 1210 1211
      }
      break;

    case PROP_BACKGROUND_GDK:
1212 1213 1214 1215
      {
        GdkColor *color;

        color = g_value_get_boxed (value);
1216 1217 1218 1219 1220 1221 1222 1223
        if (color)
          {
            GdkRGBA rgba;

            rgba.red = color->red / 65535.;
            rgba.green = color->green / 65535.;
            rgba.blue = color->blue / 65535.;
            rgba.alpha = 1;
1224

1225 1226 1227 1228 1229 1230
            set_bg_color (celltext, &rgba);
          }
        else
          {
            set_bg_color (celltext, NULL);
          }
1231 1232 1233 1234 1235 1236 1237 1238
      }
      break;

    case PROP_FOREGROUND_GDK:
      {
        GdkColor *color;

        color = g_value_get_boxed (value);
1239 1240 1241 1242 1243 1244 1245 1246
        if (color)
          {
            GdkRGBA rgba;

            rgba.red = color->red / 65535.;
            rgba.green = color->green / 65535.;
            rgba.blue = color->blue / 65535.;
            rgba.alpha = 1;
1247

1248 1249 1250 1251 1252 1253
            set_fg_color (celltext, &rgba);
          }
        else
          {
            set_fg_color (celltext, NULL);
          }
1254 1255 1256 1257
      }
      break;

    case PROP_BACKGROUND_RGBA:
1258
      set_bg_color (celltext, g_value_get_boxed (value));
1259
      break;
1260

1261
    case PROP_FOREGROUND_RGBA:
1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275
      set_fg_color (celltext, g_value_get_boxed (value));
      break;

    case PROP_FONT:
      {
        PangoFontDescription *font_desc = NULL;
        const gchar *name;

        name = g_value_get_string (value);

        if (name)
          font_desc = pango_font_description_from_string (name);

        set_font_description (celltext, font_desc);
1276 1277

	pango_font_description_free (font_desc);
1278

1279 1280
	if (priv->fixed_height_rows != -1)
	  priv->calc_fixed_height = TRUE;
1281 1282 1283 1284 1285
      }
      break;

    case PROP_FONT_DESC:
      set_font_description (celltext, g_value_get_boxed (value));
1286

1287 1288
      if (priv->fixed_height_rows != -1)
	priv->calc_fixed_height = TRUE;
1289 1290 1291 1292 1293 1294 1295 1296
      break;

    case PROP_FAMILY:
    case PROP_STYLE:
    case PROP_VARIANT:
    case PROP_WEIGHT:
    case PROP_STRETCH:
    case PROP_SIZE:
1297 1298
    case PROP_SIZE_POINTS:
      {
1299
	PangoFontMask old_set_mask = pango_font_description_get_set_fields (priv->font);
1300

1301 1302 1303
	switch (param_id)
	  {
	  case PROP_FAMILY:
1304
	    pango_font_description_set_family (priv->font,
1305 1306 1307
					       g_value_get_string (value));
	    break;
	  case PROP_STYLE:
1308
	    pango_font_description_set_style (priv->font,
1309 1310 1311
					      g_value_get_enum (value));
	    break;
	  case PROP_VARIANT:
1312
	    pango_font_description_set_variant (priv->font,
1313 1314 1315
						g_value_get_enum (value));
	    break;
	  case PROP_WEIGHT:
1316
	    pango_font_description_set_weight (priv->font,
CEST's avatar
CEST committed
1317
					       g_value_get_int (value));
1318 1319
	    break;
	  case PROP_STRETCH:
1320
	    pango_font_description_set_stretch (priv->font,
1321 1322 1323
						g_value_get_enum (value));
	    break;
	  case PROP_SIZE:
1324
	    pango_font_description_set_size (priv->font,
1325
					     g_value_get_int (value));
1326
	    g_object_notify_by_pspec (object, pspec);
1327 1328
	    break;
	  case PROP_SIZE_POINTS:
1329
	    pango_font_description_set_size (priv->font,
1330
					     g_value_get_double (value) * PANGO_SCALE);
1331
	    g_object_notify_by_pspec (object, pspec);
1332 1333
	    break;
	  }
1334

1335 1336
	if (priv->fixed_height_rows != -1)
	  priv->calc_fixed_height = TRUE;
1337

1338
	notify_set_changed (object, old_set_mask & pango_font_description_get_set_fields (priv->font));
1339 1340
	g_object_notify_by_pspec (object, text_cell_renderer_props[PROP_FONT_DESC]);
	g_object_notify_by_pspec (object, text_cell_renderer_props[PROP_FONT]);
1341 1342

	break;
1343
      }
1344

Havoc Pennington's avatar
Havoc Pennington committed
1345
    case PROP_SCALE:
1346 1347 1348 1349
      priv->font_scale = g_value_get_double (value);
      priv->scale_set = TRUE;
      if (priv->fixed_height_rows != -1)
	priv->calc_fixed_height = TRUE;
1350
      g_object_notify_by_pspec (object, text_cell_renderer_props[PROP_SCALE_SET]);
Havoc Pennington's avatar
Havoc Pennington committed
1351
      break;
1352

1353
    case PROP_EDITABLE:
1354 1355 1356
      priv->editable = g_value_get_boolean (value);
      priv->editable_set = TRUE;
      if (priv->edi