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 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 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 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 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 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 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 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 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 * 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 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 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 * 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 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 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 * 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 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 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 * 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 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 * 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 * 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 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 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 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