Updated for release
[empathy-mirror.git] / libempathy-gtk / empathy-cell-renderer-text.c
blobd48de32b820e56abc7189d1b0cebf867a8804fda
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3 * Copyright (C) 2004-2007 Imendio AB
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public
16 * License along with this program; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
20 * Authors: Mikael Hallendal <micke@imendio.com>
23 #include "config.h"
25 #include <string.h>
27 #include "empathy-cell-renderer-text.h"
29 #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EMPATHY_TYPE_CELL_RENDERER_TEXT, EmpathyCellRendererTextPriv))
31 struct _EmpathyCellRendererTextPriv {
32 gchar *name;
33 gchar *status;
34 gboolean is_group;
36 gboolean is_valid;
37 gboolean is_selected;
39 gboolean show_status;
42 static void empathy_cell_renderer_text_class_init (EmpathyCellRendererTextClass *klass);
43 static void empathy_cell_renderer_text_init (EmpathyCellRendererText *cell);
44 static void cell_renderer_text_finalize (GObject *object);
45 static void cell_renderer_text_get_property (GObject *object,
46 guint param_id,
47 GValue *value,
48 GParamSpec *pspec);
49 static void cell_renderer_text_set_property (GObject *object,
50 guint param_id,
51 const GValue *value,
52 GParamSpec *pspec);
53 static void cell_renderer_text_get_size (GtkCellRenderer *cell,
54 GtkWidget *widget,
55 GdkRectangle *cell_area,
56 gint *x_offset,
57 gint *y_offset,
58 gint *width,
59 gint *height);
60 static void cell_renderer_text_render (GtkCellRenderer *cell,
61 GdkDrawable *window,
62 GtkWidget *widget,
63 GdkRectangle *background_area,
64 GdkRectangle *cell_area,
65 GdkRectangle *expose_area,
66 GtkCellRendererState flags);
67 static void cell_renderer_text_update_text (EmpathyCellRendererText *cell,
68 GtkWidget *widget,
69 gboolean selected);
71 /* Properties */
72 enum {
73 PROP_0,
74 PROP_NAME,
75 PROP_STATUS,
76 PROP_IS_GROUP,
77 PROP_SHOW_STATUS,
80 G_DEFINE_TYPE (EmpathyCellRendererText, empathy_cell_renderer_text, GTK_TYPE_CELL_RENDERER_TEXT);
82 static void
83 empathy_cell_renderer_text_class_init (EmpathyCellRendererTextClass *klass)
85 GObjectClass *object_class;
86 GtkCellRendererClass *cell_class;
88 object_class = G_OBJECT_CLASS (klass);
89 cell_class = GTK_CELL_RENDERER_CLASS (klass);
91 object_class->finalize = cell_renderer_text_finalize;
93 object_class->get_property = cell_renderer_text_get_property;
94 object_class->set_property = cell_renderer_text_set_property;
96 cell_class->get_size = cell_renderer_text_get_size;
97 cell_class->render = cell_renderer_text_render;
99 g_object_class_install_property (object_class,
100 PROP_NAME,
101 g_param_spec_string ("name",
102 "Name",
103 "Contact name",
104 NULL,
105 G_PARAM_READWRITE));
106 g_object_class_install_property (object_class,
107 PROP_STATUS,
108 g_param_spec_string ("status",
109 "Status",
110 "Contact status string",
111 NULL,
112 G_PARAM_READWRITE));
113 g_object_class_install_property (object_class,
114 PROP_IS_GROUP,
115 g_param_spec_boolean ("is_group",
116 "Is group",
117 "Whether this cell is a group",
118 FALSE,
119 G_PARAM_READWRITE));
120 g_object_class_install_property (object_class,
121 PROP_SHOW_STATUS,
122 g_param_spec_boolean ("show-status",
123 "Show status",
124 "Whether to show the status line",
125 TRUE,
126 G_PARAM_READWRITE));
128 g_type_class_add_private (object_class, sizeof (EmpathyCellRendererTextPriv));
131 static void
132 empathy_cell_renderer_text_init (EmpathyCellRendererText *cell)
134 EmpathyCellRendererTextPriv *priv;
136 priv = GET_PRIV (cell);
138 g_object_set (cell,
139 "ellipsize", PANGO_ELLIPSIZE_END,
140 NULL);
142 priv->name = g_strdup ("");
143 priv->status = g_strdup ("");
144 priv->show_status = TRUE;
147 static void
148 cell_renderer_text_finalize (GObject *object)
150 EmpathyCellRendererText *cell;
151 EmpathyCellRendererTextPriv *priv;
153 cell = EMPATHY_CELL_RENDERER_TEXT (object);
154 priv = GET_PRIV (cell);
156 g_free (priv->name);
157 g_free (priv->status);
159 (G_OBJECT_CLASS (empathy_cell_renderer_text_parent_class)->finalize) (object);
162 static void
163 cell_renderer_text_get_property (GObject *object,
164 guint param_id,
165 GValue *value,
166 GParamSpec *pspec)
168 EmpathyCellRendererText *cell;
169 EmpathyCellRendererTextPriv *priv;
171 cell = EMPATHY_CELL_RENDERER_TEXT (object);
172 priv = GET_PRIV (cell);
174 switch (param_id) {
175 case PROP_NAME:
176 g_value_set_string (value, priv->name);
177 break;
178 case PROP_STATUS:
179 g_value_set_string (value, priv->status);
180 break;
181 case PROP_IS_GROUP:
182 g_value_set_boolean (value, priv->is_group);
183 break;
184 case PROP_SHOW_STATUS:
185 g_value_set_boolean (value, priv->show_status);
186 break;
187 default:
188 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
189 break;
193 static void
194 cell_renderer_text_set_property (GObject *object,
195 guint param_id,
196 const GValue *value,
197 GParamSpec *pspec)
199 EmpathyCellRendererText *cell;
200 EmpathyCellRendererTextPriv *priv;
201 const gchar *str;
203 cell = EMPATHY_CELL_RENDERER_TEXT (object);
204 priv = GET_PRIV (cell);
206 switch (param_id) {
207 case PROP_NAME:
208 g_free (priv->name);
209 str = g_value_get_string (value);
210 priv->name = g_strdup (str ? str : "");
211 g_strdelimit (priv->name, "\n\r\t", ' ');
212 priv->is_valid = FALSE;
213 break;
214 case PROP_STATUS:
215 g_free (priv->status);
216 str = g_value_get_string (value);
217 priv->status = g_strdup (str ? str : "");
218 g_strdelimit (priv->status, "\n\r\t", ' ');
219 priv->is_valid = FALSE;
220 break;
221 case PROP_IS_GROUP:
222 priv->is_group = g_value_get_boolean (value);
223 priv->is_valid = FALSE;
224 break;
225 case PROP_SHOW_STATUS:
226 priv->show_status = g_value_get_boolean (value);
227 priv->is_valid = FALSE;
228 break;
229 default:
230 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
231 break;
235 static void
236 cell_renderer_text_get_size (GtkCellRenderer *cell,
237 GtkWidget *widget,
238 GdkRectangle *cell_area,
239 gint *x_offset,
240 gint *y_offset,
241 gint *width,
242 gint *height)
244 EmpathyCellRendererText *celltext;
245 EmpathyCellRendererTextPriv *priv;
247 celltext = EMPATHY_CELL_RENDERER_TEXT (cell);
248 priv = GET_PRIV (cell);
250 /* Only update if not already valid so we get the right size. */
251 cell_renderer_text_update_text (celltext, widget, priv->is_selected);
253 (GTK_CELL_RENDERER_CLASS (empathy_cell_renderer_text_parent_class)->get_size) (cell, widget,
254 cell_area,
255 x_offset, y_offset,
256 width, height);
259 static void
260 cell_renderer_text_render (GtkCellRenderer *cell,
261 GdkWindow *window,
262 GtkWidget *widget,
263 GdkRectangle *background_area,
264 GdkRectangle *cell_area,
265 GdkRectangle *expose_area,
266 GtkCellRendererState flags)
268 EmpathyCellRendererText *celltext;
270 celltext = EMPATHY_CELL_RENDERER_TEXT (cell);
272 cell_renderer_text_update_text (celltext,
273 widget,
274 (flags & GTK_CELL_RENDERER_SELECTED));
276 (GTK_CELL_RENDERER_CLASS (empathy_cell_renderer_text_parent_class)->render) (
277 cell, window,
278 widget,
279 background_area,
280 cell_area,
281 expose_area, flags);
284 static void
285 cell_renderer_text_update_text (EmpathyCellRendererText *cell,
286 GtkWidget *widget,
287 gboolean selected)
289 EmpathyCellRendererTextPriv *priv;
290 PangoAttrList *attr_list;
291 PangoAttribute *attr_color, *attr_style, *attr_size;
292 GtkStyle *style;
293 gchar *str;
295 priv = GET_PRIV (cell);
297 if (priv->is_valid && priv->is_selected == selected) {
298 return;
301 if (priv->is_group) {
302 g_object_set (cell,
303 "visible", TRUE,
304 "weight", PANGO_WEIGHT_BOLD,
305 "text", priv->name,
306 "attributes", NULL,
307 "xpad", 1,
308 "ypad", 1,
309 NULL);
311 priv->is_selected = selected;
312 priv->is_valid = TRUE;
313 return;
316 style = gtk_widget_get_style (widget);
318 attr_list = pango_attr_list_new ();
320 attr_style = pango_attr_style_new (PANGO_STYLE_ITALIC);
321 attr_style->start_index = strlen (priv->name) + 1;
322 attr_style->end_index = -1;
323 pango_attr_list_insert (attr_list, attr_style);
325 if (!selected) {
326 GdkColor color;
328 color = style->text_aa[GTK_STATE_NORMAL];
330 attr_color = pango_attr_foreground_new (color.red, color.green, color.blue);
331 attr_color->start_index = attr_style->start_index;
332 attr_color->end_index = -1;
333 pango_attr_list_insert (attr_list, attr_color);
336 attr_size = pango_attr_size_new (pango_font_description_get_size (style->font_desc) / 1.2);
338 attr_size->start_index = attr_style->start_index;
339 attr_size->end_index = -1;
340 pango_attr_list_insert (attr_list, attr_size);
342 if (!priv->status || !priv->status[0] || !priv->show_status) {
343 str = g_strdup (priv->name);
344 } else {
345 str = g_strdup_printf ("%s\n%s", priv->name, priv->status);
348 g_object_set (cell,
349 "visible", TRUE,
350 "weight", PANGO_WEIGHT_NORMAL,
351 "text", str,
352 "attributes", attr_list,
353 "xpad", 0,
354 "ypad", 1,
355 NULL);
357 g_free (str);
358 pango_attr_list_unref (attr_list);
360 priv->is_selected = selected;
361 priv->is_valid = TRUE;
364 GtkCellRenderer *
365 empathy_cell_renderer_text_new (void)
367 return g_object_new (EMPATHY_TYPE_CELL_RENDERER_TEXT, NULL);