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 }