1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
3 * Copyright (C) 2001, 2002 Anders Carlsson <andersca@gnu.org>
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 License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "gconf-cell-renderer.h"
24 #include <glib/gi18n.h>
26 #include "gconf-util.h"
27 #include "gconf-marshal.h"
29 #define GCONF_CELL_RENDERER_TEXT_PATH "gconf-cell-renderer-text-path"
30 #define GCONF_CELL_RENDERER_VALUE "gconf-cell-renderer-value"
31 #define SCHEMA_TEXT "<schema>"
44 static guint gconf_cell_signals[LAST_SIGNAL] = { 0 };
46 G_DEFINE_TYPE(GConfCellRenderer, gconf_cell_renderer, GTK_TYPE_CELL_RENDERER)
50 gconf_cell_renderer_get_property (GObject *object, guint param_id, GValue *value, GParamSpec *pspec)
52 GConfCellRenderer *cellvalue;
54 cellvalue = GCONF_CELL_RENDERER (object);
58 g_value_set_boxed (value, cellvalue->value);
61 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
68 gconf_cell_renderer_set_property (GObject *object, guint param_id, const GValue *value, GParamSpec *pspec)
70 GConfCellRenderer *cellvalue;
71 GConfValue *gconf_value;
72 GtkCellRendererMode new_mode = GTK_CELL_RENDERER_MODE_INERT;
74 cellvalue = GCONF_CELL_RENDERER (object);
79 gconf_value_free (cellvalue->value);
81 gconf_value = g_value_get_boxed (value);
84 cellvalue->value = gconf_value_copy (gconf_value);
86 switch (gconf_value->type) {
88 case GCONF_VALUE_FLOAT:
89 case GCONF_VALUE_STRING:
90 new_mode = GTK_CELL_RENDERER_MODE_EDITABLE;
93 case GCONF_VALUE_BOOL:
94 new_mode = GTK_CELL_RENDERER_MODE_ACTIVATABLE;
97 case GCONF_VALUE_LIST:
98 case GCONF_VALUE_SCHEMA:
99 case GCONF_VALUE_PAIR:
100 new_mode = GTK_CELL_RENDERER_MODE_INERT;
103 g_warning ("unhandled value type %d", gconf_value->type);
108 cellvalue->value = NULL;
111 g_object_set (object, "mode", new_mode, NULL);
114 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
120 gconf_cell_renderer_finalize (GObject *object)
122 GConfCellRenderer *renderer = GCONF_CELL_RENDERER (object);
125 gconf_value_free (renderer->value);
127 g_object_unref (renderer->text_renderer);
128 g_object_unref (renderer->toggle_renderer);
130 (* G_OBJECT_CLASS (gconf_cell_renderer_parent_class)->finalize) (object);
134 gconf_cell_renderer_get_size (GtkCellRenderer *cell, GtkWidget *widget, GdkRectangle *cell_area,
135 gint *x_offset, gint *y_offset, gint *width, gint *height)
137 GConfCellRenderer *cellvalue;
140 cellvalue = GCONF_CELL_RENDERER (cell);
142 if (cellvalue->value == NULL) {
143 g_object_set (G_OBJECT (cellvalue->text_renderer),
144 "text", _("<no value>"),
146 gtk_cell_renderer_get_size (cellvalue->text_renderer, widget, cell_area,
147 x_offset, y_offset, width, height);
151 switch (cellvalue->value->type) {
152 case GCONF_VALUE_FLOAT:
153 case GCONF_VALUE_INT:
154 tmp_str = gconf_value_to_string (cellvalue->value);
155 g_object_set (G_OBJECT (cellvalue->text_renderer),
158 gtk_cell_renderer_get_size (cellvalue->text_renderer, widget, cell_area,
159 x_offset, y_offset, width, height);
162 case GCONF_VALUE_STRING:
163 g_object_set (G_OBJECT (cellvalue->text_renderer),
164 "text", gconf_value_get_string (cellvalue->value),
166 gtk_cell_renderer_get_size (cellvalue->text_renderer, widget, cell_area,
167 x_offset, y_offset, width, height);
169 case GCONF_VALUE_BOOL:
170 g_object_set (G_OBJECT (cellvalue->toggle_renderer),
172 "active", gconf_value_get_bool (cellvalue->value),
174 gtk_cell_renderer_get_size (cellvalue->toggle_renderer, widget, cell_area,
175 x_offset, y_offset, width, height);
177 case GCONF_VALUE_SCHEMA:
178 g_object_set (G_OBJECT (cellvalue->text_renderer),
181 gtk_cell_renderer_get_size (cellvalue->text_renderer,
183 x_offset, y_offset, width, height);
185 case GCONF_VALUE_LIST:
186 tmp_str = gconf_value_to_string (cellvalue->value);
187 g_object_set (G_OBJECT (cellvalue->text_renderer),
190 gtk_cell_renderer_get_size (cellvalue->text_renderer,
192 x_offset, y_offset, width, height);
195 case GCONF_VALUE_PAIR:
196 tmp_str = gconf_value_to_string (cellvalue->value);
197 g_object_set (G_OBJECT (cellvalue->text_renderer),
200 gtk_cell_renderer_get_size (cellvalue->text_renderer,
202 x_offset, y_offset, width, height);
206 g_print ("get_size: Unknown type: %d\n", cellvalue->value->type);
212 gconf_cell_renderer_text_editing_done (GtkCellEditable *entry, GConfCellRenderer *cell)
215 const gchar *new_text;
218 if (GTK_ENTRY (entry)->editing_canceled)
221 path = g_object_get_data (G_OBJECT (entry), GCONF_CELL_RENDERER_TEXT_PATH);
222 value = g_object_get_data (G_OBJECT (entry), GCONF_CELL_RENDERER_VALUE);
223 new_text = gtk_entry_get_text (GTK_ENTRY (entry));
225 switch (value->type) {
226 case GCONF_VALUE_STRING:
227 gconf_value_set_string (value, new_text);
229 case GCONF_VALUE_FLOAT:
230 gconf_value_set_float (value, (gdouble)(g_ascii_strtod (new_text, NULL)));
232 case GCONF_VALUE_INT:
233 gconf_value_set_int (value, (gint)(g_ascii_strtod (new_text, NULL)));
236 g_error ("editing done, unknown value %d", value->type);
240 g_signal_emit (cell, gconf_cell_signals[CHANGED], 0, path, value);
244 gconf_cell_renderer_check_writability (GConfCellRenderer *cell, const gchar *path)
247 g_signal_emit (cell, gconf_cell_signals[CHECK_WRITABLE], 0, path, &ret);
251 static GtkCellEditable *
252 gconf_cell_renderer_start_editing (GtkCellRenderer *cell,
256 GdkRectangle *background_area,
257 GdkRectangle *cell_area,
258 GtkCellRendererState flags)
261 GConfCellRenderer *cellvalue;
264 cellvalue = GCONF_CELL_RENDERER (cell);
266 /* If not writable then we definately can't edit */
267 if ( ! gconf_cell_renderer_check_writability (cellvalue, path))
270 switch (cellvalue->value->type) {
271 case GCONF_VALUE_INT:
272 case GCONF_VALUE_FLOAT:
273 case GCONF_VALUE_STRING:
274 tmp_str = gconf_value_to_string (cellvalue->value);
275 entry = g_object_new (GTK_TYPE_ENTRY,
280 g_signal_connect (entry, "editing_done",
281 G_CALLBACK (gconf_cell_renderer_text_editing_done), cellvalue);
283 g_object_set_data_full (G_OBJECT (entry), GCONF_CELL_RENDERER_TEXT_PATH, g_strdup (path), g_free);
284 g_object_set_data_full (G_OBJECT (entry), GCONF_CELL_RENDERER_VALUE, gconf_value_copy (cellvalue->value), (GDestroyNotify)gconf_value_free);
286 gtk_widget_show (entry);
288 return GTK_CELL_EDITABLE (entry);
291 g_error ("%d shouldn't be handled here", cellvalue->value->type);
300 gconf_cell_renderer_activate (GtkCellRenderer *cell,
304 GdkRectangle *background_area,
305 GdkRectangle *cell_area,
306 GtkCellRendererState flags)
308 GConfCellRenderer *cellvalue;
310 cellvalue = GCONF_CELL_RENDERER (cell);
312 if (cellvalue->value == NULL)
315 switch (cellvalue->value->type) {
316 case GCONF_VALUE_BOOL:
317 gconf_value_set_bool (cellvalue->value, !gconf_value_get_bool (cellvalue->value));
318 g_signal_emit (cell, gconf_cell_signals[CHANGED], 0, path, cellvalue->value);
322 g_error ("%d shouldn't be handled here", cellvalue->value->type);
330 gconf_cell_renderer_render (GtkCellRenderer *cell, GdkWindow *window, GtkWidget *widget,
331 GdkRectangle *background_area, GdkRectangle *cell_area, GdkRectangle *expose_area,
332 GtkCellRendererState flags)
334 GConfCellRenderer *cellvalue;
337 cellvalue = GCONF_CELL_RENDERER (cell);
339 if (cellvalue->value == NULL) {
340 g_object_set (G_OBJECT (cellvalue->text_renderer),
341 "text", _("<no value>"),
344 gtk_cell_renderer_render (cellvalue->text_renderer, window, widget,
345 background_area, cell_area, expose_area, flags);
349 switch (cellvalue->value->type) {
350 case GCONF_VALUE_FLOAT:
351 case GCONF_VALUE_INT:
352 tmp_str = gconf_value_to_string (cellvalue->value);
353 g_object_set (G_OBJECT (cellvalue->text_renderer),
356 gtk_cell_renderer_render (cellvalue->text_renderer, window, widget,
357 background_area, cell_area, expose_area, flags);
360 case GCONF_VALUE_STRING:
361 g_object_set (G_OBJECT (cellvalue->text_renderer),
362 "text", gconf_value_get_string (cellvalue->value),
364 gtk_cell_renderer_render (cellvalue->text_renderer, window, widget,
365 background_area, cell_area, expose_area, flags);
367 case GCONF_VALUE_BOOL:
368 g_object_set (G_OBJECT (cellvalue->toggle_renderer),
370 "active", gconf_value_get_bool (cellvalue->value),
373 gtk_cell_renderer_render (cellvalue->toggle_renderer, window, widget,
374 background_area, cell_area, expose_area, flags);
377 case GCONF_VALUE_SCHEMA:
378 g_object_set (G_OBJECT (cellvalue->text_renderer),
382 gtk_cell_renderer_render (cellvalue->text_renderer, window, widget,
383 background_area, cell_area, expose_area, flags);
386 case GCONF_VALUE_LIST:
387 tmp_str = gconf_value_to_string (cellvalue->value);
388 g_object_set (G_OBJECT (cellvalue->text_renderer),
392 gtk_cell_renderer_render (cellvalue->text_renderer, window, widget,
393 background_area, cell_area, expose_area, flags);
396 case GCONF_VALUE_PAIR:
397 tmp_str = gconf_value_to_string (cellvalue->value);
398 g_object_set (G_OBJECT (cellvalue->text_renderer),
401 gtk_cell_renderer_render (cellvalue->text_renderer, window, widget,
402 background_area, cell_area, expose_area, flags);
407 g_print ("render: Unknown type: %d\n", cellvalue->value->type);
413 gconf_cell_renderer_class_init (GConfCellRendererClass *klass)
415 GObjectClass *object_class = (GObjectClass *)klass;
416 GtkCellRendererClass *cell_renderer_class = (GtkCellRendererClass *)klass;
418 object_class->get_property = gconf_cell_renderer_get_property;
419 object_class->set_property = gconf_cell_renderer_set_property;
420 object_class->finalize = gconf_cell_renderer_finalize;
422 cell_renderer_class->get_size = gconf_cell_renderer_get_size;
423 cell_renderer_class->render = gconf_cell_renderer_render;
424 cell_renderer_class->activate = gconf_cell_renderer_activate;
425 cell_renderer_class->start_editing = gconf_cell_renderer_start_editing;
427 g_object_class_install_property (object_class, PROP_VALUE,
428 g_param_spec_boxed ("value",
433 gconf_cell_signals[CHANGED] =
434 g_signal_new ("changed",
435 G_TYPE_FROM_CLASS (object_class),
437 G_STRUCT_OFFSET (GConfCellRendererClass, changed),
438 (GSignalAccumulator) NULL, NULL,
439 gconf_marshal_VOID__STRING_BOXED,
443 gconf_cell_signals[CHECK_WRITABLE] =
444 g_signal_new ("check_writable",
445 G_TYPE_FROM_CLASS (object_class),
447 G_STRUCT_OFFSET (GConfCellRendererClass, changed),
448 (GSignalAccumulator) NULL, NULL,
449 gconf_marshal_BOOLEAN__STRING,
455 gconf_cell_renderer_init (GConfCellRenderer *renderer)
457 GTK_CELL_RENDERER (renderer)->mode = GTK_CELL_RENDERER_MODE_ACTIVATABLE;
459 renderer->text_renderer = gtk_cell_renderer_text_new ();
460 g_object_ref_sink (renderer->text_renderer);
462 renderer->toggle_renderer = gtk_cell_renderer_toggle_new ();
463 g_object_ref_sink (renderer->toggle_renderer);
469 gconf_cell_renderer_new (void)
471 return GTK_CELL_RENDERER (g_object_new (GCONF_TYPE_CELL_RENDERER, NULL));