1 /*
2 * Copyright (C) 2009 - 2011 Vivien Malerba <malerba@gnome-db.org>
3 * Copyright (C) 2010 David King <davidk@openismus.com>
4 * Copyright (C) 2011 Murray Cumming <murrayc@murrayc.com>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 */
21
22 #include <string.h>
23 #include <glib/gi18n-lib.h>
24 #include <libgda/libgda.h>
25 #include "gdaui-form.h"
26 #include "gdaui-data-proxy.h"
27 #include "gdaui-data-selector.h"
28 #include "gdaui-raw-form.h"
29 #include "gdaui-data-proxy-info.h"
30 #include "gdaui-enum-types.h"
31
32 static void gdaui_form_class_init (GdauiFormClass * class);
33 static void gdaui_form_init (GdauiForm *wid);
34 static void gdaui_form_dispose (GObject *object);
35
36 static void gdaui_form_set_property (GObject *object,
37 guint param_id,
38 const GValue *value,
39 GParamSpec *pspec);
40 static void gdaui_form_get_property (GObject *object,
41 guint param_id,
42 GValue *value,
43 GParamSpec *pspec);
44
45 /* GdauiDataProxy interface */
46 static void gdaui_form_widget_init (GdauiDataProxyIface *iface);
47 static GdaDataProxy *gdaui_form_get_proxy (GdauiDataProxy *iface);
48 static void gdaui_form_set_column_editable (GdauiDataProxy *iface, gint column, gboolean editable);
49 static void gdaui_form_show_column_actions (GdauiDataProxy *iface, gint column, gboolean show_actions);
50 static GtkActionGroup *gdaui_form_get_actions_group (GdauiDataProxy *iface);
51 static gboolean gdaui_form_widget_set_write_mode (GdauiDataProxy *iface, GdauiDataProxyWriteMode mode);
52 static GdauiDataProxyWriteMode gdaui_form_widget_get_write_mode (GdauiDataProxy *iface);
53
54 /* GdauiDataSelector interface */
55 static void gdaui_form_selector_init (GdauiDataSelectorIface *iface);
56 static GdaDataModel *gdaui_form_selector_get_model (GdauiDataSelector *iface);
57 static void gdaui_form_selector_set_model (GdauiDataSelector *iface, GdaDataModel *model);
58 static GArray *gdaui_form_selector_get_selected_rows (GdauiDataSelector *iface);
59 static GdaDataModelIter *gdaui_form_selector_get_data_set (GdauiDataSelector *iface);
60 static gboolean gdaui_form_selector_select_row (GdauiDataSelector *iface, gint row);
61 static void gdaui_form_selector_unselect_row (GdauiDataSelector *iface, gint row);
62 static void gdaui_form_selector_set_column_visible (GdauiDataSelector *iface, gint column, gboolean visible);
63
64 struct _GdauiFormPriv
65 {
66 GtkWidget *raw_form;
67 GtkWidget *info;
68 };
69
70 /* get a pointer to the parents to be able to call their destructor */
71 static GObjectClass *parent_class = NULL;
72
73 /* properties */
74 enum {
75 PROP_0,
76 PROP_RAW_FORM,
77 PROP_INFO,
78 PROP_MODEL,
79 PROP_INFO_FLAGS
80 };
81
82 GType
gdaui_form_get_type(void)83 gdaui_form_get_type (void)
84 {
85 static GType type = 0;
86
87 if (G_UNLIKELY (type == 0)) {
88 static const GTypeInfo info = {
89 sizeof (GdauiFormClass),
90 (GBaseInitFunc) NULL,
91 (GBaseFinalizeFunc) NULL,
92 (GClassInitFunc) gdaui_form_class_init,
93 NULL,
94 NULL,
95 sizeof (GdauiForm),
96 0,
97 (GInstanceInitFunc) gdaui_form_init,
98 0
99 };
100
101 static const GInterfaceInfo proxy_info = {
102 (GInterfaceInitFunc) gdaui_form_widget_init,
103 NULL,
104 NULL
105 };
106
107 static const GInterfaceInfo selector_info = {
108 (GInterfaceInitFunc) gdaui_form_selector_init,
109 NULL,
110 NULL
111 };
112
113 type = g_type_register_static (GTK_TYPE_BOX, "GdauiForm", &info, 0);
114 g_type_add_interface_static (type, GDAUI_TYPE_DATA_PROXY, &proxy_info);
115 g_type_add_interface_static (type, GDAUI_TYPE_DATA_SELECTOR, &selector_info);
116 }
117
118 return type;
119 }
120
121 static void
gdaui_form_widget_init(GdauiDataProxyIface * iface)122 gdaui_form_widget_init (GdauiDataProxyIface *iface)
123 {
124 iface->get_proxy = gdaui_form_get_proxy;
125 iface->set_column_editable = gdaui_form_set_column_editable;
126 iface->show_column_actions = gdaui_form_show_column_actions;
127 iface->get_actions_group = gdaui_form_get_actions_group;
128 iface->set_write_mode = gdaui_form_widget_set_write_mode;
129 iface->get_write_mode = gdaui_form_widget_get_write_mode;
130 }
131
132 static void
gdaui_form_selector_init(GdauiDataSelectorIface * iface)133 gdaui_form_selector_init (GdauiDataSelectorIface *iface)
134 {
135 iface->get_model = gdaui_form_selector_get_model;
136 iface->set_model = gdaui_form_selector_set_model;
137 iface->get_selected_rows = gdaui_form_selector_get_selected_rows;
138 iface->get_data_set = gdaui_form_selector_get_data_set;
139 iface->select_row = gdaui_form_selector_select_row;
140 iface->unselect_row = gdaui_form_selector_unselect_row;
141 iface->set_column_visible = gdaui_form_selector_set_column_visible;
142 }
143
144 static void
gdaui_form_class_init(GdauiFormClass * class)145 gdaui_form_class_init (GdauiFormClass *class)
146 {
147 GObjectClass *object_class = G_OBJECT_CLASS (class);
148
149 parent_class = g_type_class_peek_parent (class);
150 object_class->dispose = gdaui_form_dispose;
151
152 /* Properties */
153
154 object_class->set_property = gdaui_form_set_property;
155 object_class->get_property = gdaui_form_get_property;
156 g_object_class_install_property (object_class, PROP_RAW_FORM,
157 g_param_spec_object ("raw-form", NULL, NULL, GDAUI_TYPE_RAW_FORM,
158 G_PARAM_READABLE));
159 g_object_class_install_property (object_class, PROP_INFO,
160 g_param_spec_object ("info", NULL, NULL, GDAUI_TYPE_DATA_PROXY_INFO,
161 G_PARAM_READABLE));
162
163 g_object_class_install_property (object_class, PROP_INFO_FLAGS,
164 g_param_spec_flags ("info-flags", NULL, NULL,
165 GDAUI_TYPE_DATA_PROXY_INFO_FLAG,
166 GDAUI_DATA_PROXY_INFO_CURRENT_ROW,
167 G_PARAM_READABLE | G_PARAM_WRITABLE));
168
169 g_object_class_install_property (object_class, PROP_MODEL,
170 g_param_spec_object ("model", NULL, NULL,
171 GDA_TYPE_DATA_MODEL,
172 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
173 }
174
175 static void
form_layout_changed_cb(G_GNUC_UNUSED GdauiBasicForm * raw_form,GdauiForm * form)176 form_layout_changed_cb (G_GNUC_UNUSED GdauiBasicForm *raw_form, GdauiForm *form)
177 {
178 gboolean expand;
179 g_object_get (G_OBJECT (form->priv->raw_form), "can-expand-v", &expand, NULL);
180 gtk_container_child_set (GTK_CONTAINER (form), form->priv->raw_form,
181 "expand", expand, "fill", expand, NULL);
182 gtk_widget_queue_resize ((GtkWidget*) form);
183 }
184
185 static void
form_selection_changed_cb(G_GNUC_UNUSED GdauiRawForm * rawform,GdauiForm * form)186 form_selection_changed_cb (G_GNUC_UNUSED GdauiRawForm *rawform, GdauiForm *form)
187 {
188 g_signal_emit_by_name (G_OBJECT (form), "selection-changed");
189 }
190
191 static void
gdaui_form_init(GdauiForm * form)192 gdaui_form_init (GdauiForm *form)
193 {
194 form->priv = g_new0 (GdauiFormPriv, 1);
195 form->priv->raw_form = NULL;
196 form->priv->info = NULL;
197
198 gtk_orientable_set_orientation (GTK_ORIENTABLE (form), GTK_ORIENTATION_VERTICAL);
199
200 form->priv->raw_form = gdaui_raw_form_new (NULL);
201 gtk_box_pack_start (GTK_BOX (form), form->priv->raw_form, FALSE, FALSE, 0);
202 gtk_widget_show (form->priv->raw_form);
203 g_signal_connect (form->priv->raw_form, "layout-changed",
204 G_CALLBACK (form_layout_changed_cb), form);
205 g_signal_connect (form->priv->raw_form, "selection-changed",
206 G_CALLBACK (form_selection_changed_cb), form);
207
208 form->priv->info = gdaui_data_proxy_info_new (GDAUI_DATA_PROXY (form->priv->raw_form),
209 GDAUI_DATA_PROXY_INFO_CURRENT_ROW |
210 GDAUI_DATA_PROXY_INFO_ROW_MOVE_BUTTONS);
211 gtk_box_pack_start (GTK_BOX (form), form->priv->info, FALSE, FALSE, 0);
212 gtk_widget_show (form->priv->info);
213
214 }
215
216 static void
gdaui_form_dispose(GObject * object)217 gdaui_form_dispose (GObject *object)
218 {
219 GdauiForm *form;
220
221 g_return_if_fail (GDAUI_IS_FORM (object));
222 form = GDAUI_FORM (object);
223
224 if (form->priv) {
225 g_signal_handlers_disconnect_by_func (form->priv->raw_form,
226 G_CALLBACK (form_layout_changed_cb), form);
227 g_signal_handlers_disconnect_by_func (form->priv->raw_form,
228 G_CALLBACK (form_selection_changed_cb), form);
229
230 /* the private area itself */
231 g_free (form->priv);
232 form->priv = NULL;
233 }
234
235 /* for the parent class */
236 parent_class->dispose (object);
237 }
238
239
240 /**
241 * gdaui_form_new:
242 * @model: a #GdaDataModel
243 *
244 * Creates a new #GdauiForm widget suitable to display the data in @model
245 *
246 * Returns: (transfer full): the new widget
247 *
248 * Since: 4.2
249 */
250 GtkWidget *
gdaui_form_new(GdaDataModel * model)251 gdaui_form_new (GdaDataModel *model)
252 {
253 GdauiForm *form;
254
255 g_return_val_if_fail (!model || GDA_IS_DATA_MODEL (model), NULL);
256
257 form = (GdauiForm *) g_object_new (GDAUI_TYPE_FORM, "model", model, NULL);
258
259 return (GtkWidget *) form;
260 }
261
262
263 static void
gdaui_form_set_property(GObject * object,guint param_id,const GValue * value,GParamSpec * pspec)264 gdaui_form_set_property (GObject *object,
265 guint param_id,
266 const GValue *value,
267 GParamSpec *pspec)
268 {
269 GdauiForm *form;
270 GdaDataModel *model;
271
272 form = GDAUI_FORM (object);
273
274 if (form->priv) {
275 switch (param_id) {
276 case PROP_MODEL: {
277 model = GDA_DATA_MODEL (g_value_get_object (value));
278 g_object_set (G_OBJECT (form->priv->raw_form), "model", model, NULL);
279 gtk_container_child_set (GTK_CONTAINER (form), form->priv->raw_form,
280 "expand", TRUE, "fill", TRUE, NULL);
281 gtk_widget_queue_resize ((GtkWidget*) form);
282 break;
283 }
284 case PROP_INFO_FLAGS:
285 g_object_set (G_OBJECT (form->priv->info), "flags", g_value_get_flags (value), NULL);
286 break;
287 default:
288 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
289 break;
290 }
291 }
292 }
293
294 static void
gdaui_form_get_property(GObject * object,guint param_id,GValue * value,GParamSpec * pspec)295 gdaui_form_get_property (GObject *object,
296 guint param_id,
297 GValue *value,
298 GParamSpec *pspec)
299 {
300 GdauiForm *form;
301 GdaDataModel *model;
302
303 form = GDAUI_FORM (object);
304 if (form->priv) {
305 switch (param_id) {
306 case PROP_RAW_FORM:
307 g_value_set_object (value, form->priv->raw_form);
308 break;
309 case PROP_INFO:
310 g_value_set_object (value, form->priv->info);
311 break;
312 case PROP_INFO_FLAGS: {
313 GdauiDataProxyInfoFlag flags;
314 g_object_get (G_OBJECT (form->priv->info), "flags", &flags, NULL);
315 g_value_set_flags (value, flags);
316 break;
317 }
318 case PROP_MODEL:
319 g_object_get (G_OBJECT (form->priv->raw_form), "model", &model, NULL);
320 g_value_take_object (value, G_OBJECT (model));
321 break;
322 default:
323 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
324 break;
325 }
326 }
327 }
328
329 /* GdauiDataProxy interface */
330 static GdaDataProxy *
gdaui_form_get_proxy(GdauiDataProxy * iface)331 gdaui_form_get_proxy (GdauiDataProxy *iface)
332 {
333 return gdaui_data_proxy_get_proxy ((GdauiDataProxy*) GDAUI_FORM (iface)->priv->raw_form);
334 }
335
336 static void
gdaui_form_set_column_editable(GdauiDataProxy * iface,gint column,gboolean editable)337 gdaui_form_set_column_editable (GdauiDataProxy *iface, gint column, gboolean editable)
338 {
339 gdaui_data_proxy_column_set_editable ((GdauiDataProxy*) GDAUI_FORM (iface)->priv->raw_form,
340 column, editable);
341 }
342
343 static void
gdaui_form_show_column_actions(GdauiDataProxy * iface,gint column,gboolean show_actions)344 gdaui_form_show_column_actions (GdauiDataProxy *iface, gint column, gboolean show_actions)
345 {
346 gdaui_data_proxy_column_show_actions ((GdauiDataProxy*) GDAUI_FORM (iface)->priv->raw_form,
347 column, show_actions);
348 }
349
350 static GtkActionGroup *
gdaui_form_get_actions_group(GdauiDataProxy * iface)351 gdaui_form_get_actions_group (GdauiDataProxy *iface)
352 {
353 return gdaui_data_proxy_get_actions_group ((GdauiDataProxy*) GDAUI_FORM (iface)->priv->raw_form);
354 }
355
356 static gboolean
gdaui_form_widget_set_write_mode(GdauiDataProxy * iface,GdauiDataProxyWriteMode mode)357 gdaui_form_widget_set_write_mode (GdauiDataProxy *iface, GdauiDataProxyWriteMode mode)
358 {
359 return gdaui_data_proxy_set_write_mode ((GdauiDataProxy*) GDAUI_FORM (iface)->priv->raw_form, mode);
360 }
361
362 static GdauiDataProxyWriteMode
gdaui_form_widget_get_write_mode(GdauiDataProxy * iface)363 gdaui_form_widget_get_write_mode (GdauiDataProxy *iface)
364 {
365 return gdaui_data_proxy_get_write_mode ((GdauiDataProxy*) GDAUI_FORM (iface)->priv->raw_form);
366 }
367
368 /* GdauiDataSelector interface */
369 static GdaDataModel *
gdaui_form_selector_get_model(GdauiDataSelector * iface)370 gdaui_form_selector_get_model (GdauiDataSelector *iface)
371 {
372 return gdaui_data_selector_get_model ((GdauiDataSelector*) GDAUI_FORM (iface)->priv->raw_form);
373 }
374
375 static void
gdaui_form_selector_set_model(GdauiDataSelector * iface,GdaDataModel * model)376 gdaui_form_selector_set_model (GdauiDataSelector *iface, GdaDataModel *model)
377 {
378 gdaui_data_selector_set_model ((GdauiDataSelector*) GDAUI_FORM (iface)->priv->raw_form, model);
379 }
380
381 static GArray *
gdaui_form_selector_get_selected_rows(GdauiDataSelector * iface)382 gdaui_form_selector_get_selected_rows (GdauiDataSelector *iface)
383 {
384 return gdaui_data_selector_get_selected_rows ((GdauiDataSelector*) GDAUI_FORM (iface)->priv->raw_form);
385 }
386
387 static GdaDataModelIter *
gdaui_form_selector_get_data_set(GdauiDataSelector * iface)388 gdaui_form_selector_get_data_set (GdauiDataSelector *iface)
389 {
390 return gdaui_data_selector_get_data_set ((GdauiDataSelector*) GDAUI_FORM (iface)->priv->raw_form);
391 }
392
393 static gboolean
gdaui_form_selector_select_row(GdauiDataSelector * iface,gint row)394 gdaui_form_selector_select_row (GdauiDataSelector *iface, gint row)
395 {
396 return gdaui_data_selector_select_row ((GdauiDataSelector*) GDAUI_FORM (iface)->priv->raw_form, row);
397 }
398
399 static void
gdaui_form_selector_unselect_row(GdauiDataSelector * iface,gint row)400 gdaui_form_selector_unselect_row (GdauiDataSelector *iface, gint row)
401 {
402 gdaui_data_selector_unselect_row ((GdauiDataSelector*) GDAUI_FORM (iface)->priv->raw_form, row);
403 }
404
405 static void
gdaui_form_selector_set_column_visible(GdauiDataSelector * iface,gint column,gboolean visible)406 gdaui_form_selector_set_column_visible (GdauiDataSelector *iface, gint column, gboolean visible)
407 {
408 gdaui_data_selector_set_column_visible ((GdauiDataSelector*) GDAUI_FORM (iface)->priv->raw_form,
409 column, visible);
410 }
411