evolution-3.6.4/widgets/table/e-table-field-chooser.c

No issues found

  1 /*
  2  * This program is free software; you can redistribute it and/or
  3  * modify it under the terms of the GNU Lesser General Public
  4  * License as published by the Free Software Foundation; either
  5  * version 2 of the License, or (at your option) version 3.
  6  *
  7  * This program is distributed in the hope that it will be useful,
  8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 10  * Lesser General Public License for more details.
 11  *
 12  * You should have received a copy of the GNU Lesser General Public
 13  * License along with the program; if not, see <http://www.gnu.org/licenses/>
 14  *
 15  *
 16  * Authors:
 17  *		Chris Lahey <clahey@ximian.com>
 18  *
 19  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
 20  *
 21  */
 22 
 23 #ifdef HAVE_CONFIG_H
 24 #include <config.h>
 25 #endif
 26 
 27 #include <gtk/gtk.h>
 28 #include <libgnomecanvas/libgnomecanvas.h>
 29 
 30 #include <glib/gi18n.h>
 31 #include "e-util/e-util.h"
 32 #include "e-util/e-util-private.h"
 33 
 34 #include "misc/e-canvas.h"
 35 
 36 #include "e-table-field-chooser.h"
 37 #include "e-table-field-chooser-item.h"
 38 
 39 static void e_table_field_chooser_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
 40 static void e_table_field_chooser_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
 41 static void e_table_field_chooser_dispose (GObject *object);
 42 
 43 enum {
 44 	PROP_0,
 45 	PROP_FULL_HEADER,
 46 	PROP_HEADER,
 47 	PROP_DND_CODE
 48 };
 49 
 50 G_DEFINE_TYPE (ETableFieldChooser, e_table_field_chooser, GTK_TYPE_VBOX)
 51 
 52 static void
 53 e_table_field_chooser_class_init (ETableFieldChooserClass *class)
 54 {
 55 	GObjectClass *object_class;
 56 
 57 	object_class = (GObjectClass *) class;
 58 
 59 	object_class->set_property = e_table_field_chooser_set_property;
 60 	object_class->get_property = e_table_field_chooser_get_property;
 61 	object_class->dispose      = e_table_field_chooser_dispose;
 62 
 63 	g_object_class_install_property (
 64 		object_class,
 65 		PROP_DND_CODE,
 66 		g_param_spec_string (
 67 			"dnd_code",
 68 			"DnD code",
 69 			NULL,
 70 			NULL,
 71 			G_PARAM_READWRITE));
 72 
 73 	g_object_class_install_property (
 74 		object_class,
 75 		PROP_FULL_HEADER,
 76 		g_param_spec_object (
 77 			"full_header",
 78 			"Full Header",
 79 			NULL,
 80 			E_TYPE_TABLE_HEADER,
 81 			G_PARAM_READWRITE));
 82 
 83 	g_object_class_install_property (
 84 		object_class,
 85 		PROP_HEADER,
 86 		g_param_spec_object (
 87 			"header",
 88 			"Header",
 89 			NULL,
 90 			E_TYPE_TABLE_HEADER,
 91 			G_PARAM_READWRITE));
 92 }
 93 
 94 static void
 95 ensure_nonzero_step_increments (ETableFieldChooser *etfc)
 96 {
 97 	GtkAdjustment *va, *ha;
 98 
 99 	va = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (etfc->canvas));
100 	ha = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (etfc->canvas));
101 
102 	/*
103 	  it looks pretty complicated to get height of column header
104 	  so use 16 pixels which should be OK
105 	*/
106 	if (va)
107 		gtk_adjustment_set_step_increment (va, 16.0);
108 	if (ha)
109 		gtk_adjustment_set_step_increment (ha, 16.0);
110 }
111 
112 static void allocate_callback (GtkWidget *canvas, GtkAllocation *allocation, ETableFieldChooser *etfc)
113 {
114 	gdouble height;
115 	etfc->last_alloc = *allocation;
116 	gnome_canvas_item_set (
117 		etfc->item,
118 		"width", (gdouble) allocation->width,
119 		NULL);
120 	g_object_get (
121 		etfc->item,
122 		"height", &height,
123 		NULL);
124 	height = MAX (height, allocation->height);
125 	gnome_canvas_set_scroll_region (GNOME_CANVAS (etfc->canvas), 0, 0, allocation->width - 1, height - 1);
126 	gnome_canvas_item_set (
127 		etfc->rect,
128 		"x2", (gdouble) allocation->width,
129 		"y2", (gdouble) height,
130 		NULL);
131 	ensure_nonzero_step_increments (etfc);
132 }
133 
134 static void resize (GnomeCanvas *canvas, ETableFieldChooser *etfc)
135 {
136 	gdouble height;
137 	g_object_get (
138 		etfc->item,
139 		"height", &height,
140 		NULL);
141 
142 	height = MAX (height, etfc->last_alloc.height);
143 
144 	gnome_canvas_set_scroll_region (GNOME_CANVAS (etfc->canvas), 0, 0, etfc->last_alloc.width - 1, height - 1);
145 	gnome_canvas_item_set (
146 		etfc->rect,
147 		"x2", (gdouble) etfc->last_alloc.width,
148 		"y2", (gdouble) height,
149 		NULL);
150 	ensure_nonzero_step_increments (etfc);
151 }
152 
153 static GtkWidget *
154 create_content (GnomeCanvas **canvas)
155 {
156 	GtkWidget *vbox_top;
157 	GtkWidget *label1;
158 	GtkWidget *scrolledwindow1;
159 	GtkWidget *canvas_buttons;
160 
161 	g_return_val_if_fail (canvas != NULL, NULL);
162 
163 	vbox_top = gtk_vbox_new (FALSE, 4);
164 	gtk_widget_show (vbox_top);
165 
166 	label1 = gtk_label_new (_("To add a column to your table, drag it into\nthe location in which you want it to appear."));
167 	gtk_widget_show (label1);
168 	gtk_box_pack_start (GTK_BOX (vbox_top), label1, FALSE, FALSE, 0);
169 	gtk_label_set_justify (GTK_LABEL (label1), GTK_JUSTIFY_CENTER);
170 
171 	scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
172 	gtk_widget_show (scrolledwindow1);
173 	gtk_box_pack_start (GTK_BOX (vbox_top), scrolledwindow1, TRUE, TRUE, 0);
174 	gtk_widget_set_can_focus (scrolledwindow1, FALSE);
175 	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow1), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
176 
177 	canvas_buttons = e_canvas_new ();
178 	gtk_widget_show (canvas_buttons);
179 	gtk_container_add (GTK_CONTAINER (scrolledwindow1), canvas_buttons);
180 	gtk_widget_set_can_focus (canvas_buttons, FALSE);
181 	gtk_widget_set_can_default (canvas_buttons, FALSE);
182 
183 	*canvas = GNOME_CANVAS (canvas_buttons);
184 
185 	return vbox_top;
186 }
187 
188 static void
189 e_table_field_chooser_init (ETableFieldChooser *etfc)
190 {
191 	GtkWidget *widget;
192 
193 	widget = create_content (&etfc->canvas);
194 	if (!widget) {
195 		return;
196 	}
197 
198 	gtk_widget_set_size_request (widget, -1, 250);
199 	gtk_box_pack_start (GTK_BOX (etfc), widget, TRUE, TRUE, 0);
200 
201 	etfc->rect = gnome_canvas_item_new (
202 		gnome_canvas_root (GNOME_CANVAS (etfc->canvas)),
203 		gnome_canvas_rect_get_type (),
204 		"x1", (gdouble) 0,
205 		"y1", (gdouble) 0,
206 		"x2", (gdouble) 100,
207 		"y2", (gdouble) 100,
208 		"fill_color", "white",
209 		NULL);
210 
211 	etfc->item = gnome_canvas_item_new (
212 		gnome_canvas_root (etfc->canvas),
213 		e_table_field_chooser_item_get_type (),
214 		"width", (gdouble) 100,
215 		"full_header", etfc->full_header,
216 		"header", etfc->header,
217 		"dnd_code", etfc->dnd_code,
218 		NULL);
219 
220 	g_signal_connect (
221 		etfc->canvas, "reflow",
222 		G_CALLBACK (resize), etfc);
223 
224 	gnome_canvas_set_scroll_region (
225 		GNOME_CANVAS (etfc->canvas),
226 		0, 0, 100, 100);
227 
228 	/* Connect the signals */
229 	g_signal_connect (
230 		etfc->canvas, "size_allocate",
231 		G_CALLBACK (allocate_callback), etfc);
232 
233 	gtk_widget_show_all (widget);
234 }
235 
236 static void
237 e_table_field_chooser_dispose (GObject *object)
238 {
239 	ETableFieldChooser *etfc = E_TABLE_FIELD_CHOOSER (object);
240 
241 	g_free (etfc->dnd_code);
242 	etfc->dnd_code = NULL;
243 
244 	if (etfc->full_header)
245 		g_object_unref (etfc->full_header);
246 	etfc->full_header = NULL;
247 
248 	if (etfc->header)
249 		g_object_unref (etfc->header);
250 	etfc->header = NULL;
251 
252 	/* Chain up to parent's dispose() method. */
253 	G_OBJECT_CLASS (e_table_field_chooser_parent_class)->dispose (object);
254 }
255 
256 GtkWidget *
257 e_table_field_chooser_new (void)
258 {
259 	return g_object_new (E_TYPE_TABLE_FIELD_CHOOSER, NULL);
260 }
261 
262 static void
263 e_table_field_chooser_set_property (GObject *object,
264                                     guint property_id,
265                                     const GValue *value,
266                                     GParamSpec *pspec)
267 {
268 	ETableFieldChooser *etfc = E_TABLE_FIELD_CHOOSER (object);
269 
270 	switch (property_id) {
271 	case PROP_DND_CODE:
272 		g_free (etfc->dnd_code);
273 		etfc->dnd_code = g_strdup (g_value_get_string (value));
274 		if (etfc->item)
275 			g_object_set (
276 				etfc->item,
277 				"dnd_code", etfc->dnd_code,
278 				NULL);
279 		break;
280 	case PROP_FULL_HEADER:
281 		if (etfc->full_header)
282 			g_object_unref (etfc->full_header);
283 		if (g_value_get_object (value))
284 			etfc->full_header = E_TABLE_HEADER (g_value_get_object (value));
285 		else
286 			etfc->full_header = NULL;
287 		if (etfc->full_header)
288 			g_object_ref (etfc->full_header);
289 		if (etfc->item)
290 			g_object_set (
291 				etfc->item,
292 				"full_header", etfc->full_header,
293 				NULL);
294 		break;
295 	case PROP_HEADER:
296 		if (etfc->header)
297 			g_object_unref (etfc->header);
298 		if (g_value_get_object (value))
299 			etfc->header = E_TABLE_HEADER (g_value_get_object (value));
300 		else
301 			etfc->header = NULL;
302 		if (etfc->header)
303 			g_object_ref (etfc->header);
304 		if (etfc->item)
305 			g_object_set (
306 				etfc->item,
307 				"header", etfc->header,
308 				NULL);
309 		break;
310 	default:
311 		break;
312 	}
313 }
314 
315 static void
316 e_table_field_chooser_get_property (GObject *object,
317                                     guint property_id,
318                                     GValue *value,
319                                     GParamSpec *pspec)
320 {
321 	ETableFieldChooser *etfc = E_TABLE_FIELD_CHOOSER (object);
322 
323 	switch (property_id) {
324 	case PROP_DND_CODE:
325 		g_value_set_string (value, etfc->dnd_code);
326 		break;
327 	case PROP_FULL_HEADER:
328 		g_value_set_object (value, etfc->full_header);
329 		break;
330 	case PROP_HEADER:
331 		g_value_set_object (value, etfc->header);
332 		break;
333 	default:
334 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
335 		break;
336 	}
337 }