1 /* 2 * Copyright (C) 2010 David King <davidk@openismus.com> 3 * Copyright (C) 2010 - 2012 Vivien Malerba <malerba@gnome-db.org> 4 * Copyright (C) 2011 Murray Cumming <murrayc@murrayc.com> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 2 9 * of the License, or (at your option) any later version. 10 * 11 * This program 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 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 */ 20 21 #include <string.h> 22 #include <glib/gi18n-lib.h> 23 #include <libgda/libgda.h> 24 #include "ui-formgrid.h" 25 #include <libgda-ui/gdaui-data-proxy.h> 26 #include <libgda-ui/gdaui-raw-form.h> 27 #include <libgda-ui/gdaui-data-selector.h> 28 #include "../support.h" 29 #include "../browser-window.h" 30 #include "../browser-stock-icons.h" 31 #include "widget-overlay.h" 32 #include <libgda/gda-data-model-extra.h> 33 #include "favorites-actions.h" 34 #ifdef HAVE_LDAP 35 #include "../ldap-browser/ldap-browser-perspective.h" 36 #endif 37 #include "../../tool-utils.h" 38 39 static void ui_formgrid_class_init (UiFormGridClass * class); 40 static void ui_formgrid_init (UiFormGrid *wid); 41 static void ui_formgrid_dispose (GObject *object); 42 43 static void ui_formgrid_set_property (GObject *object, 44 guint param_id, 45 const GValue *value, 46 GParamSpec *pspec); 47 static void ui_formgrid_get_property (GObject *object, 48 guint param_id, 49 GValue *value, 50 GParamSpec *pspec); 51 static void ui_formgrid_show (GtkWidget *widget); 52 static BrowserConnection *get_browser_connection (UiFormGrid *formgrid); 53 static void compute_modification_statements (UiFormGrid *formgrid, GdaDataModel *model); 54 55 #define GRID_FLAGS (GDAUI_DATA_PROXY_INFO_CURRENT_ROW | GDAUI_DATA_PROXY_INFO_CHUNCK_CHANGE_BUTTONS) 56 #define FORM_FLAGS (GDAUI_DATA_PROXY_INFO_CURRENT_ROW | GDAUI_DATA_PROXY_INFO_ROW_MOVE_BUTTONS) 57 58 typedef enum { 59 MOD_INSERT, 60 MOD_UPDATE, 61 MOD_DELETE, 62 MOD_LAST 63 } ModType; 64 65 struct _UiFormGridPriv 66 { 67 GtkWidget *nb; 68 GtkWidget *raw_form; 69 GtkWidget *raw_grid; 70 GtkWidget *info; 71 GtkWidget *overlay_form; 72 GtkWidget *overlay_grid; 73 GtkWidget *autoupdate_toggle; 74 gboolean autoupdate; 75 gboolean autoupdate_possible; 76 GdauiDataProxyInfoFlag flags; 77 78 BrowserConnection *bcnc; 79 gboolean scroll_form; 80 81 /* modifications to the data */ 82 gboolean compute_mod_stmt; /* if %TRUE, then the INSERT, UPDATE and DELETE 83 * statements are automatically computed, see the PROP_AUTOMOD property */ 84 gboolean mod_stmt_auto_computed; /* %TRUE if mod_stmt[*] have automatically 85 * been computed */ 86 GdaStatement *mod_stmt[MOD_LAST]; 87 }; 88 89 /* get a pointer to the parents to be able to call their destructor */ 90 static GObjectClass *parent_class = NULL; 91 92 /* signals */ 93 enum { 94 DATA_SET_CHANGED, 95 LAST_SIGNAL 96 }; 97 98 gint ui_formgrid_signals [LAST_SIGNAL] = { 0 }; 99 100 /* properties */ 101 enum { 102 PROP_0, 103 PROP_RAW_GRID, 104 PROP_RAW_FORM, 105 PROP_INFO, 106 PROP_SCROLL_FORM, 107 PROP_AUTOMOD 108 }; 109 110 GType 111 ui_formgrid_get_type (void) 112 { 113 static GType type = 0; 114 115 if (!type) { 116 static const GTypeInfo info = { 117 sizeof (UiFormGridClass), 118 (GBaseInitFunc) NULL, 119 (GBaseFinalizeFunc) NULL, 120 (GClassInitFunc) ui_formgrid_class_init, 121 NULL, 122 NULL, 123 sizeof (UiFormGrid), 124 0, 125 (GInstanceInitFunc) ui_formgrid_init, 126 0 127 }; 128 129 type = g_type_register_static (GTK_TYPE_BOX, "UiFormGrid", &info, 0); 130 } 131 132 return type; 133 } 134 135 static void 136 ui_formgrid_class_init (UiFormGridClass *klass) 137 { 138 GObjectClass *object_class = G_OBJECT_CLASS (klass); 139 140 parent_class = g_type_class_peek_parent (klass); 141 object_class->dispose = ui_formgrid_dispose; 142 GTK_WIDGET_CLASS (klass)->show = ui_formgrid_show; 143 144 /* signals */ 145 ui_formgrid_signals [DATA_SET_CHANGED] = 146 g_signal_new ("data-set-changed", 147 G_TYPE_FROM_CLASS (object_class), 148 G_SIGNAL_RUN_FIRST, 149 G_STRUCT_OFFSET (UiFormGridClass, data_set_changed), 150 NULL, NULL, 151 g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); 152 klass->data_set_changed = NULL; 153 154 /* Properties */ 155 object_class->set_property = ui_formgrid_set_property; 156 object_class->get_property = ui_formgrid_get_property; 157 g_object_class_install_property (object_class, PROP_RAW_GRID, 158 g_param_spec_object ("raw_grid", NULL, NULL, 159 GDAUI_TYPE_RAW_GRID, 160 G_PARAM_READABLE)); 161 g_object_class_install_property (object_class, PROP_RAW_FORM, 162 g_param_spec_object ("raw_form", NULL, NULL, 163 GDAUI_TYPE_RAW_GRID, 164 G_PARAM_READABLE)); 165 g_object_class_install_property (object_class, PROP_INFO, 166 g_param_spec_object ("widget_info", NULL, NULL, 167 GDAUI_TYPE_DATA_PROXY_INFO, 168 G_PARAM_READABLE)); 169 g_object_class_install_property (object_class, PROP_SCROLL_FORM, 170 g_param_spec_boolean ("scroll-form", NULL, NULL, 171 FALSE, 172 G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); 173 g_object_class_install_property (object_class, PROP_AUTOMOD, 174 g_param_spec_boolean ("compute-mod-statements", NULL, NULL, 175 FALSE, 176 G_PARAM_WRITABLE | G_PARAM_CONSTRUCT)); 177 } 178 179 static void 180 ui_formgrid_dispose (GObject *object) 181 { 182 UiFormGrid *formgrid; 183 184 formgrid = UI_FORMGRID (object); 185 if (formgrid->priv) { 186 if (formgrid->priv->bcnc) 187 g_object_unref (formgrid->priv->bcnc); 188 189 ModType mod; 190 for (mod = MOD_INSERT; mod < MOD_LAST; mod++) { 191 if (formgrid->priv->mod_stmt[mod]) { 192 g_object_unref (formgrid->priv->mod_stmt[mod]); 193 formgrid->priv->mod_stmt[mod] = NULL; 194 } 195 } 196 197 g_free (formgrid->priv); 198 formgrid->priv = NULL; 199 } 200 201 /* parent class */ 202 parent_class->dispose (object); 203 } 204 205 static void 206 ui_formgrid_show (GtkWidget *widget) 207 { 208 UiFormGrid *formgrid; 209 GtkWidget *ovl, *packed; 210 formgrid = UI_FORMGRID (widget); 211 212 if (! formgrid->priv->overlay_grid) { 213 /* finalize packing */ 214 GtkWidget *sw, *vp; 215 sw = gtk_scrolled_window_new (NULL, NULL); 216 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), 217 GTK_POLICY_AUTOMATIC, 218 GTK_POLICY_AUTOMATIC); 219 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), 220 GTK_SHADOW_NONE); 221 gtk_container_add (GTK_CONTAINER (sw), formgrid->priv->raw_grid); 222 gtk_widget_show_all (sw); 223 packed = sw; 224 225 /* overlay */ 226 ovl = widget_overlay_new (); 227 formgrid->priv->overlay_grid = ovl; 228 g_object_set (G_OBJECT (ovl), "add-scale", TRUE, NULL); 229 g_object_set (G_OBJECT (ovl), "add-scale", FALSE, NULL); 230 gtk_container_add (GTK_CONTAINER (ovl), packed); 231 widget_overlay_set_child_props (WIDGET_OVERLAY (ovl), packed, 232 WIDGET_OVERLAY_CHILD_HALIGN, 233 WIDGET_OVERLAY_ALIGN_FILL, 234 WIDGET_OVERLAY_CHILD_VALIGN, 235 WIDGET_OVERLAY_ALIGN_FILL, 236 WIDGET_OVERLAY_CHILD_SCALE, .9, 237 -1); 238 gtk_widget_show (ovl); 239 gtk_notebook_append_page (GTK_NOTEBOOK (formgrid->priv->nb), ovl, NULL); 240 } 241 242 if (! formgrid->priv->overlay_form) { 243 /* finalize packing */ 244 if (formgrid->priv->scroll_form) { 245 GtkWidget *sw, *vp; 246 sw = gtk_scrolled_window_new (NULL, NULL); 247 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), 248 GTK_POLICY_AUTOMATIC, 249 GTK_POLICY_AUTOMATIC); 250 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), 251 GTK_SHADOW_NONE); 252 vp = gtk_viewport_new (NULL, NULL); 253 gtk_widget_set_name (vp, "gdaui-transparent-background"); 254 gtk_container_add (GTK_CONTAINER (sw), vp); 255 gtk_viewport_set_shadow_type (GTK_VIEWPORT (vp), GTK_SHADOW_NONE); 256 gtk_container_add (GTK_CONTAINER (vp), formgrid->priv->raw_form); 257 gtk_widget_show_all (sw); 258 packed = sw; 259 } 260 else { 261 gtk_widget_show (formgrid->priv->raw_form); 262 packed = formgrid->priv->raw_form; 263 } 264 265 /* overlay */ 266 ovl = widget_overlay_new (); 267 formgrid->priv->overlay_form = ovl; 268 g_object_set (G_OBJECT (ovl), "add-scale", TRUE, NULL); 269 g_object_set (G_OBJECT (ovl), "add-scale", FALSE, NULL); 270 gtk_container_add (GTK_CONTAINER (ovl), packed); 271 widget_overlay_set_child_props (WIDGET_OVERLAY (ovl), packed, 272 WIDGET_OVERLAY_CHILD_HALIGN, 273 WIDGET_OVERLAY_ALIGN_FILL, 274 WIDGET_OVERLAY_CHILD_VALIGN, 275 WIDGET_OVERLAY_ALIGN_FILL, 276 WIDGET_OVERLAY_CHILD_SCALE, 1., 277 -1); 278 gtk_widget_show (ovl); 279 gtk_notebook_append_page (GTK_NOTEBOOK (formgrid->priv->nb), ovl, NULL); 280 gtk_notebook_set_current_page (GTK_NOTEBOOK (formgrid->priv->nb), 281 0); 282 } 283 284 ((GtkWidgetClass *)parent_class)->show (widget); 285 if (! formgrid->priv->autoupdate_possible) 286 gtk_widget_hide (formgrid->priv->autoupdate_toggle); 287 } 288 289 static void form_grid_autoupdate_cb (GtkToggleButton *button, UiFormGrid *formgrid); 290 static void form_grid_toggled_cb (GtkToggleAction *action, UiFormGrid *formgrid); 291 static void form_grid_populate_popup_cb (GtkWidget *wid, GtkMenu *menu, UiFormGrid *formgrid); 292 static void selection_changed_cb (GdauiDataSelector *sel, UiFormGrid *formgrid); 293 294 static void 295 ui_formgrid_init (UiFormGrid *formgrid) 296 { 297 GtkWidget *sw; 298 GtkWidget *hbox, *button; 299 300 formgrid->priv = g_new0 (UiFormGridPriv, 1); 301 formgrid->priv->raw_grid = NULL; 302 formgrid->priv->info = NULL; 303 formgrid->priv->flags = GDAUI_DATA_PROXY_INFO_CURRENT_ROW | GDAUI_DATA_PROXY_INFO_ROW_MODIFY_BUTTONS; 304 formgrid->priv->bcnc = NULL; 305 formgrid->priv->autoupdate = TRUE; 306 formgrid->priv->autoupdate_possible = FALSE; 307 formgrid->priv->scroll_form = FALSE; 308 formgrid->priv->compute_mod_stmt = FALSE; 309 310 gtk_orientable_set_orientation (GTK_ORIENTABLE (formgrid), GTK_ORIENTATION_VERTICAL); 311 312 /* notebook */ 313 formgrid->priv->nb = gtk_notebook_new (); 314 gtk_notebook_set_show_tabs (GTK_NOTEBOOK (formgrid->priv->nb), FALSE); 315 gtk_notebook_set_show_border (GTK_NOTEBOOK (formgrid->priv->nb), FALSE); 316 gtk_box_pack_start (GTK_BOX (formgrid), formgrid->priv->nb, TRUE, TRUE, 0); 317 gtk_widget_show (formgrid->priv->nb); 318 319 /* grid on 1st page of notebook, not added there */ 320 formgrid->priv->raw_grid = gdaui_raw_grid_new (NULL); 321 gdaui_data_proxy_column_show_actions (GDAUI_DATA_PROXY (formgrid->priv->raw_grid), -1, FALSE); 322 g_signal_connect (formgrid->priv->raw_grid, "populate-popup", 323 G_CALLBACK (form_grid_populate_popup_cb), formgrid); 324 325 /* form on the 2nd page of the notebook, not added there */ 326 formgrid->priv->raw_form = gdaui_raw_form_new (NULL); 327 gdaui_data_proxy_column_show_actions (GDAUI_DATA_PROXY (formgrid->priv->raw_form), -1, FALSE); 328 g_signal_connect (formgrid->priv->raw_form, "populate-popup", 329 G_CALLBACK (form_grid_populate_popup_cb), formgrid); 330 331 /* info widget and toggle button at last */ 332 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); 333 gtk_box_pack_start (GTK_BOX (formgrid), hbox, FALSE, TRUE, 0); 334 gtk_widget_show (hbox); 335 336 /* button to toggle between auto update and not */ 337 button = gtk_toggle_button_new (); 338 GtkWidget *img = gtk_image_new_from_stock (GTK_STOCK_EXECUTE, GTK_ICON_SIZE_MENU); 339 gtk_button_set_image (GTK_BUTTON (button), img); 340 formgrid->priv->autoupdate_toggle = button; 341 342 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), formgrid->priv->autoupdate); 343 gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, TRUE, 0); 344 g_signal_connect (G_OBJECT (button), "toggled", 345 G_CALLBACK (form_grid_autoupdate_cb), formgrid); 346 gtk_widget_set_tooltip_text (button, _("Enable or disable auto update of data")); 347 348 /* Proxy info */ 349 formgrid->priv->info = gdaui_data_proxy_info_new (GDAUI_DATA_PROXY (formgrid->priv->raw_grid), 350 formgrid->priv->flags | 351 GDAUI_DATA_PROXY_INFO_CURRENT_ROW | 352 GDAUI_DATA_PROXY_INFO_CHUNCK_CHANGE_BUTTONS); 353 354 GtkUIManager *uimanager; 355 GtkActionGroup *agroup; 356 GtkAction *action; 357 guint mid; 358 359 g_object_get (G_OBJECT (formgrid->priv->info), "ui-manager", &uimanager, NULL); 360 agroup = gtk_action_group_new ("FormGrid"); 361 gtk_action_group_set_translation_domain (agroup, GETTEXT_PACKAGE); 362 363 action = GTK_ACTION (gtk_toggle_action_new ("FGToggle", "FGToggle", 364 _("Toggle between grid and form presentations"), 365 BROWSER_STOCK_GRID)); 366 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE); 367 gtk_action_group_add_action (agroup, action); 368 g_signal_connect (G_OBJECT (action), "toggled", 369 G_CALLBACK (form_grid_toggled_cb), formgrid); 370 g_object_unref (action); 371 gtk_ui_manager_insert_action_group (uimanager, agroup, 0); 372 g_object_unref (agroup); 373 374 mid = gtk_ui_manager_new_merge_id (uimanager); 375 gtk_ui_manager_add_ui (uimanager, mid, "/ToolBar", "FGToggle", "FGToggle", 376 GTK_UI_MANAGER_AUTO, TRUE); 377 gtk_ui_manager_ensure_update (uimanager); 378 gtk_box_pack_start (GTK_BOX (hbox), formgrid->priv->info, TRUE, TRUE, 0); 379 gtk_widget_show (formgrid->priv->info); 380 g_object_unref (G_OBJECT (uimanager)); 381 382 383 /*gchar *tmp; 384 g_object_get (uimanager, "ui", &tmp, NULL); 385 g_print ("==>[%s]\n", tmp); 386 g_free (tmp); 387 */ 388 389 /* keep data in sync */ 390 g_signal_connect (formgrid->priv->raw_grid, "selection-changed", 391 G_CALLBACK (selection_changed_cb), formgrid); 392 g_signal_connect (formgrid->priv->raw_form, "selection-changed", 393 G_CALLBACK (selection_changed_cb), formgrid); 394 } 395 396 /** 397 * ui_formgrid_get_ui_manager: 398 * 399 * Returns: (transfer none): the #GtkUIManager 400 */ 401 GtkUIManager * 402 ui_formgrid_get_ui_manager (UiFormGrid *formgrid) 403 { 404 GtkUIManager *uimanager; 405 g_return_val_if_fail (UI_IS_FORMGRID (formgrid), NULL); 406 g_object_get (G_OBJECT (formgrid->priv->info), "ui-manager", &uimanager, NULL); 407 g_object_unref (uimanager); 408 return uimanager; 409 } 410 411 static void 412 selection_changed_cb (GdauiDataSelector *sel, UiFormGrid *formgrid) 413 { 414 GdaDataModelIter *iter; 415 GdauiDataSelector *tosel; 416 gint row; 417 if (sel == (GdauiDataSelector*) formgrid->priv->raw_grid) 418 tosel = (GdauiDataSelector*) formgrid->priv->raw_form; 419 else 420 tosel = (GdauiDataSelector*) formgrid->priv->raw_grid; 421 422 iter = gdaui_data_selector_get_data_set (sel); 423 g_assert (iter); 424 row = gda_data_model_iter_get_row (iter); 425 /*g_print ("Moved %s to row %d\n", sel == (GdauiDataSelector*) formgrid->priv->raw_grid ? "grid" : "form", row);*/ 426 iter = gdaui_data_selector_get_data_set (tosel); 427 if (iter) { 428 g_signal_handlers_block_by_func (tosel, G_CALLBACK (selection_changed_cb), formgrid); 429 gda_data_model_iter_move_to_row (iter, row >= 0 ? row : 0); 430 g_signal_handlers_unblock_by_func (tosel, G_CALLBACK (selection_changed_cb), formgrid); 431 } 432 } 433 434 static void 435 form_grid_autoupdate_cb (GtkToggleButton *button, UiFormGrid *formgrid) 436 { 437 formgrid->priv->autoupdate = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)); 438 } 439 440 static void 441 form_grid_toggled_cb (GtkToggleAction *action, UiFormGrid *formgrid) 442 { 443 if (!gtk_toggle_action_get_active (action)) { 444 /* switch to form view */ 445 gtk_notebook_set_current_page (GTK_NOTEBOOK (formgrid->priv->nb), 1); 446 g_object_set (G_OBJECT (formgrid->priv->info), 447 "data-proxy", formgrid->priv->raw_form, 448 "flags", formgrid->priv->flags | FORM_FLAGS, NULL); 449 450 g_object_set (G_OBJECT (action), "stock-id", BROWSER_STOCK_FORM, NULL); 451 } 452 else { 453 /* switch to grid view */ 454 gtk_notebook_set_current_page (GTK_NOTEBOOK (formgrid->priv->nb), 0); 455 g_object_set (G_OBJECT (formgrid->priv->info), 456 "data-proxy", formgrid->priv->raw_grid, 457 "flags", formgrid->priv->flags | GRID_FLAGS, NULL); 458 459 g_object_set (G_OBJECT (action), "stock-id", BROWSER_STOCK_GRID, NULL); 460 } 461 } 462 463 static BrowserConnection * 464 get_browser_connection (UiFormGrid *formgrid) 465 { 466 if (formgrid->priv->bcnc) 467 return formgrid->priv->bcnc; 468 else { 469 GtkWidget *toplevel; 470 471 toplevel = gtk_widget_get_toplevel (GTK_WIDGET (formgrid)); 472 if (BROWSER_IS_WINDOW (toplevel)) 473 return browser_window_get_connection (BROWSER_WINDOW (toplevel)); 474 } 475 return NULL; 476 } 477 478 479 static void execute_action_mitem_cb (GtkMenuItem *menuitem, UiFormGrid *formgrid); 480 #ifdef HAVE_LDAP 481 static void ldap_view_dn_mitem_cb (GtkMenuItem *menuitem, UiFormGrid *formgrid); 482 #endif 483 static void zoom_form_mitem_cb (GtkCheckMenuItem *checkmenuitem, UiFormGrid *formgrid); 484 static void zoom_grid_mitem_cb (GtkCheckMenuItem *checkmenuitem, UiFormGrid *formgrid); 485 486 static void 487 form_grid_populate_popup_cb (GtkWidget *wid, GtkMenu *menu, UiFormGrid *formgrid) 488 { 489 /* add actions to execute to menu */ 490 GdaDataModelIter *iter; 491 BrowserConnection *bcnc = NULL; 492 493 bcnc = get_browser_connection (formgrid); 494 if (!bcnc) 495 return; 496 497 iter = gdaui_data_selector_get_data_set (GDAUI_DATA_SELECTOR (formgrid->priv->raw_grid)); 498 499 /* actions */ 500 GSList *actions_list, *list; 501 actions_list = gda_tools_favorites_get_actions (browser_connection_get_favorites (bcnc), 502 bcnc, GDA_SET (iter)); 503 if (actions_list) { 504 GtkWidget *mitem, *submenu; 505 mitem = gtk_menu_item_new_with_label (_("Execute action")); 506 gtk_widget_show (mitem); 507 gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), mitem); 508 509 submenu = gtk_menu_new (); 510 gtk_menu_item_set_submenu (GTK_MENU_ITEM (mitem), submenu); 511 for (list = actions_list; list; list = list->next) { 512 ToolsFavoriteAction *act = (ToolsFavoriteAction*) list->data; 513 mitem = gtk_menu_item_new_with_label (act->name); 514 gtk_widget_show (mitem); 515 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), mitem); 516 g_object_set_data_full (G_OBJECT (mitem), "action", act, 517 (GDestroyNotify) gda_tools_favorites_free_action); 518 g_signal_connect (mitem, "activate", 519 G_CALLBACK (execute_action_mitem_cb), formgrid); 520 } 521 g_slist_free (actions_list); 522 } 523 524 #ifdef HAVE_LDAP 525 /* LDAP specific */ 526 if (browser_connection_is_ldap (bcnc)) { 527 GdaHolder *dnh; 528 dnh = gda_set_get_holder (GDA_SET (iter), "dn"); 529 if (dnh) { 530 const GValue *cvalue; 531 cvalue = gda_holder_get_value (GDA_HOLDER (dnh)); 532 if (!cvalue && (G_VALUE_TYPE (cvalue) != G_TYPE_STRING)) 533 dnh = NULL; 534 } 535 if (!dnh) { 536 GSList *list; 537 for (list = GDA_SET (iter)->holders; list; list = list->next) { 538 const GValue *cvalue; 539 cvalue = gda_holder_get_value (GDA_HOLDER (list->data)); 540 if (cvalue && (G_VALUE_TYPE (cvalue) == G_TYPE_STRING) && 541 gda_ldap_is_dn (g_value_get_string (cvalue))) { 542 dnh = GDA_HOLDER (list->data); 543 break; 544 } 545 } 546 } 547 548 if (dnh) { 549 const GValue *cvalue; 550 cvalue = gda_holder_get_value (dnh); 551 552 GtkWidget *mitem; 553 mitem = gtk_menu_item_new_with_label (_("View LDAP entry's details")); 554 gtk_widget_show (mitem); 555 gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), mitem); 556 g_object_set_data_full (G_OBJECT (mitem), "dn", 557 g_value_dup_string (cvalue), g_free); 558 g_signal_connect (mitem, "activate", 559 G_CALLBACK (ldap_view_dn_mitem_cb), formgrid); 560 } 561 } 562 #endif 563 564 if (wid == formgrid->priv->raw_form) { 565 GtkWidget *mitem; 566 gboolean add_scale; 567 g_object_get (G_OBJECT (formgrid->priv->overlay_form), "add-scale", &add_scale, NULL); 568 mitem = gtk_check_menu_item_new_with_label (_("Zoom...")); 569 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mitem), add_scale); 570 gtk_widget_show (mitem); 571 gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), mitem); 572 g_signal_connect (mitem, "toggled", 573 G_CALLBACK (zoom_form_mitem_cb), formgrid); 574 } 575 else if (wid == formgrid->priv->raw_grid) { 576 GtkWidget *mitem; 577 gboolean add_scale; 578 g_object_get (G_OBJECT (formgrid->priv->overlay_grid), "add-scale", &add_scale, NULL); 579 mitem = gtk_check_menu_item_new_with_label (_("Zoom...")); 580 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mitem), add_scale); 581 gtk_widget_show (mitem); 582 gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), mitem); 583 g_signal_connect (mitem, "toggled", 584 G_CALLBACK (zoom_grid_mitem_cb), formgrid); 585 } 586 } 587 588 static void 589 zoom_form_mitem_cb (GtkCheckMenuItem *checkmenuitem, UiFormGrid *formgrid) 590 { 591 g_object_set (G_OBJECT (formgrid->priv->overlay_form), "add-scale", 592 gtk_check_menu_item_get_active (checkmenuitem), NULL); 593 } 594 595 static void 596 zoom_grid_mitem_cb (GtkCheckMenuItem *checkmenuitem, UiFormGrid *formgrid) 597 { 598 g_object_set (G_OBJECT (formgrid->priv->overlay_grid), "add-scale", 599 gtk_check_menu_item_get_active (checkmenuitem), NULL); 600 } 601 602 typedef struct { 603 BrowserConnection *bcnc; /* ref held */ 604 UiFormGrid *formgrid; /* ref held */ 605 gchar *name; 606 GdaStatement *stmt; /* ref held */ 607 GdaSet *params; /* ref held */ 608 GdaDataModel *model; /* ref held */ 609 guint exec_id; 610 guint timer_id; 611 } ActionExecutedData; 612 613 static void action_executed_holder_changed_cb (G_GNUC_UNUSED GdaSet *params, G_GNUC_UNUSED GdaHolder *holder, 614 ActionExecutedData *aed); 615 static void 616 action_executed_data_free (ActionExecutedData *data) 617 { 618 g_object_unref ((GObject*) data->bcnc); 619 if (data->formgrid) 620 g_object_unref ((GObject*) data->formgrid); 621 g_free (data->name); 622 g_object_unref ((GObject*) data->stmt); 623 624 if (data->params) { 625 g_signal_handlers_disconnect_by_func (data->params, 626 G_CALLBACK (action_executed_holder_changed_cb), data); 627 g_object_unref ((GObject*) data->params); 628 } 629 if (data->model) 630 g_object_unref ((GObject*) data->model); 631 if (data->timer_id) 632 g_source_remove (data->timer_id); 633 g_free (data); 634 } 635 636 static gboolean 637 exec_end_timeout_cb (ActionExecutedData *aed) 638 { 639 GError *error = NULL; 640 GObject *obj; 641 obj = browser_connection_execution_get_result (aed->bcnc, aed->exec_id, 642 NULL, &error); 643 if (obj) { 644 if (GDA_IS_DATA_MODEL (obj)) { 645 g_assert (aed->model == (GdaDataModel*) obj); 646 gda_data_model_thaw (aed->model); 647 gda_data_model_reset (aed->model); 648 649 aed->exec_id = 0; 650 aed->timer_id = 0; 651 return FALSE; 652 } 653 else { 654 g_object_unref (obj); 655 g_set_error (&error, GDA_TOOLS_ERROR, GDA_TOOLS_COMMAND_ARGUMENTS_ERROR, 656 "%s", _("Statement to execute is not a selection statement")); 657 } 658 } 659 660 if (error) { 661 GtkWidget *toplevel; 662 toplevel = gtk_widget_get_toplevel (GTK_WIDGET (aed->formgrid)); 663 browser_show_error (GTK_WINDOW (toplevel), 664 _("Error executing query:\n%s"), 665 error->message ? 666 error->message : _("No detail")); 667 g_clear_error (&error); 668 gda_data_model_thaw (aed->model); 669 aed->exec_id = 0; 670 aed->timer_id = 0; 671 return FALSE; 672 } 673 else 674 return TRUE; /* keep timer */ 675 } 676 677 static void 678 action_executed_holder_changed_cb (G_GNUC_UNUSED GdaSet *params, G_GNUC_UNUSED GdaHolder *holder, 679 ActionExecutedData *aed) 680 { 681 if (! aed->formgrid->priv->autoupdate || ! aed->formgrid->priv->autoupdate_possible) 682 return; 683 684 GError *error = NULL; 685 guint jid; 686 gda_data_model_freeze (aed->model); 687 jid = browser_connection_rerun_select (aed->bcnc, aed->model, &error); 688 if (!jid) { 689 GtkWidget *toplevel; 690 toplevel = gtk_widget_get_toplevel (GTK_WIDGET (aed->formgrid)); 691 browser_show_error (GTK_WINDOW (toplevel), 692 _("Error executing query:\n%s"), 693 error->message ? 694 error->message : _("No detail")); 695 gda_data_model_thaw (aed->model); 696 } 697 else { 698 /* watch the end of execution */ 699 aed->exec_id = jid; 700 if (! aed->timer_id) 701 aed->timer_id = g_timeout_add (50, (GSourceFunc) exec_end_timeout_cb, aed); 702 } 703 } 704 705 /* 706 * Called after an action's statement has been executed 707 */ 708 static void 709 statement_executed_cb (G_GNUC_UNUSED BrowserConnection *bcnc, 710 G_GNUC_UNUSED guint exec_id, 711 GObject *out_result, 712 G_GNUC_UNUSED GdaSet *out_last_inserted_row, GError *error, 713 ActionExecutedData *aed) 714 { 715 GtkWidget *toplevel; 716 717 toplevel = gtk_widget_get_toplevel (GTK_WIDGET (aed->formgrid)); 718 g_object_unref (aed->formgrid); 719 aed->formgrid = NULL; 720 721 if (error) 722 browser_show_error (GTK_WINDOW (toplevel), 723 _("Error executing query:\n%s"), 724 error->message ? 725 error->message : _("No detail")); 726 else if (out_result && GDA_IS_DATA_MODEL (out_result)) { 727 GtkWidget *dialog, *label, *fg; 728 GtkWidget *dcontents; 729 730 gchar *tmp; 731 dialog = gtk_dialog_new_with_buttons (aed->name, 732 NULL, 733 0, 734 GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL); 735 dcontents = gtk_dialog_get_content_area (GTK_DIALOG (dialog)); 736 gtk_box_set_spacing (GTK_BOX (dcontents), 5); 737 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_CLOSE, TRUE); 738 739 tmp = g_markup_printf_escaped ("<b>%s:</b>", aed->name); 740 label = gtk_label_new (""); 741 gtk_label_set_markup (GTK_LABEL (label), tmp); 742 g_free (tmp); 743 gtk_misc_set_alignment (GTK_MISC (label), 0., 0.); 744 gtk_box_pack_start (GTK_BOX (dcontents), label, FALSE, FALSE, 5); 745 746 fg = ui_formgrid_new (GDA_DATA_MODEL (out_result), TRUE, 747 GDAUI_DATA_PROXY_INFO_CURRENT_ROW); 748 ui_formgrid_set_connection (UI_FORMGRID (fg), aed->bcnc); 749 750 if (GDA_IS_DATA_SELECT (out_result)) { 751 GdaStatement *stmt; 752 g_object_get (G_OBJECT (out_result), "select-stmt", &stmt, NULL); 753 if (stmt) { 754 ui_formgrid_handle_user_prefs (UI_FORMGRID (fg), NULL, stmt); 755 g_object_unref (stmt); 756 } 757 aed->model = g_object_ref (out_result); 758 g_signal_connect (aed->params, "holder-changed", 759 G_CALLBACK (action_executed_holder_changed_cb), aed); 760 761 aed->formgrid = g_object_ref (fg); 762 aed->formgrid->priv->autoupdate_possible = TRUE; 763 gtk_widget_show (aed->formgrid->priv->autoupdate_toggle); 764 } 765 gtk_box_pack_start (GTK_BOX (dcontents), fg, TRUE, TRUE, 0); 766 767 gtk_window_set_default_size (GTK_WINDOW (dialog), 400, 600); 768 gtk_widget_show_all (dialog); 769 770 g_signal_connect (dialog, "response", 771 G_CALLBACK (gtk_widget_destroy), NULL); 772 g_signal_connect (dialog, "close", 773 G_CALLBACK (gtk_widget_destroy), NULL); 774 g_object_set_data_full (G_OBJECT (dialog), "aed", aed, 775 (GDestroyNotify) action_executed_data_free); 776 aed = NULL; /* don't free it yet */ 777 } 778 else if (BROWSER_IS_WINDOW (toplevel)) { 779 browser_window_show_notice_printf (BROWSER_WINDOW (toplevel), 780 GTK_MESSAGE_INFO, 781 "ActionExecution", 782 "%s", _("Action successfully executed")); 783 } 784 else 785 browser_show_message (GTK_WINDOW (toplevel), 786 "%s", _("Action successfully executed")); 787 788 if (aed) 789 action_executed_data_free (aed); 790 } 791 792 static void 793 execute_action_mitem_cb (GtkMenuItem *menuitem, UiFormGrid *formgrid) 794 { 795 ToolsFavoriteAction *act; 796 GtkWidget *dlg; 797 gchar *tmp; 798 gint response; 799 GtkWidget *toplevel; 800 801 act = (ToolsFavoriteAction*) g_object_get_data (G_OBJECT (menuitem), "action"); 802 toplevel = gtk_widget_get_toplevel ((GtkWidget*) formgrid); 803 tmp = g_strdup_printf (_("Set or confirm the parameters to execute\n" 804 "action '%s'"), act->name); 805 dlg = gdaui_basic_form_new_in_dialog (act->params, 806 (GtkWindow*) toplevel, 807 _("Execution of action"), tmp); 808 g_free (tmp); 809 response = gtk_dialog_run (GTK_DIALOG (dlg)); 810 gtk_widget_destroy (dlg); 811 if (response == GTK_RESPONSE_ACCEPT) { 812 GError *lerror = NULL; 813 BrowserConnection *bcnc; 814 ActionExecutedData *aed; 815 816 bcnc = get_browser_connection (formgrid); 817 g_assert (bcnc); 818 819 aed = g_new0 (ActionExecutedData, 1); 820 aed->formgrid = g_object_ref (formgrid); 821 aed->bcnc = g_object_ref (bcnc); 822 if (act->name) 823 aed->name = g_strdup (act->name); 824 aed->stmt = g_object_ref (act->stmt); 825 aed->params = g_object_ref (act->params); 826 827 if (! browser_connection_execute_statement_cb (bcnc, 828 act->stmt, act->params, 829 GDA_STATEMENT_MODEL_RANDOM_ACCESS, 830 FALSE, 831 (BrowserConnectionExecuteCallback) statement_executed_cb, 832 aed, &lerror)) { 833 browser_show_error (GTK_WINDOW (toplevel), 834 _("Error executing query: %s"), 835 lerror && lerror->message ? lerror->message : _("No detail")); 836 g_clear_error (&lerror); 837 action_executed_data_free (aed); 838 } 839 } 840 } 841 842 #ifdef HAVE_LDAP 843 static void ldap_view_dn_mitem_cb (GtkMenuItem *menuitem, UiFormGrid *formgrid) 844 { 845 const gchar *dn; 846 BrowserWindow *bwin; 847 BrowserPerspective *pers; 848 849 dn = g_object_get_data (G_OBJECT (menuitem), "dn"); 850 bwin = (BrowserWindow*) gtk_widget_get_toplevel ((GtkWidget*) formgrid); 851 pers = browser_window_change_perspective (bwin, _("LDAP browser")); 852 853 ldap_browser_perspective_display_ldap_entry (LDAP_BROWSER_PERSPECTIVE (pers), dn); 854 } 855 #endif 856 857 static void 858 proxy_changed_cb (G_GNUC_UNUSED GdauiDataProxy *dp, G_GNUC_UNUSED GdaDataProxy *proxy, UiFormGrid *formgrid) 859 { 860 g_signal_emit (formgrid, ui_formgrid_signals [DATA_SET_CHANGED], 0); 861 } 862 863 /** 864 * ui_formgrid_new 865 * @model: a #GdaDataModel 866 * @scroll_form: set to %TRUE to wrap the embedded form in a scrolled window 867 * @flags: the #GdauiDataProxyInfoFlag, specifying what to display in the new widget 868 * 869 * Creates a new #UiFormGrid widget suitable to display the data in @model 870 * 871 * Returns: the new widget 872 */ 873 GtkWidget * 874 ui_formgrid_new (GdaDataModel *model, gboolean scroll_form, GdauiDataProxyInfoFlag flags) 875 { 876 UiFormGrid *formgrid; 877 GdaDataProxy *proxy; 878 879 g_return_val_if_fail (!model || GDA_IS_DATA_MODEL (model), NULL); 880 881 formgrid = (UiFormGrid *) g_object_new (UI_TYPE_FORMGRID, "scroll-form", scroll_form, NULL); 882 formgrid->priv->flags = flags; 883 884 /* a raw form and a raw grid for the same proxy */ 885 g_object_set (formgrid->priv->raw_grid, "model", model, NULL); 886 proxy = gdaui_data_proxy_get_proxy (GDAUI_DATA_PROXY (formgrid->priv->raw_grid)); 887 g_object_set (formgrid->priv->raw_form, "model", proxy, NULL); 888 gdaui_data_proxy_set_write_mode (GDAUI_DATA_PROXY (formgrid->priv->raw_form), 889 GDAUI_DATA_PROXY_WRITE_ON_DEMAND); 890 g_object_set (G_OBJECT (formgrid->priv->info), 891 "flags", formgrid->priv->flags | GRID_FLAGS, NULL); 892 893 g_signal_connect (formgrid->priv->raw_grid, "proxy-changed", 894 G_CALLBACK (proxy_changed_cb), formgrid); 895 896 /* no more than 300 rows at a time */ 897 if (model) { 898 gda_data_proxy_set_sample_size (proxy, 300); 899 if (flags & GDAUI_DATA_PROXY_INFO_ROW_MODIFY_BUTTONS) 900 g_object_set (G_OBJECT (formgrid), "compute-mod-statements", TRUE, NULL); 901 } 902 903 904 return (GtkWidget *) formgrid; 905 } 906 907 static void 908 handle_user_prefs_for_sql_statement (UiFormGrid *formgrid, BrowserConnection *bcnc, 909 GdaSqlStatement *sqlst) 910 { 911 g_assert (sqlst); 912 if (sqlst->stmt_type == GDA_SQL_STATEMENT_COMPOUND) { 913 GdaSqlStatementCompound *comp; 914 GSList *list; 915 comp = (GdaSqlStatementCompound*) sqlst->contents; 916 for (list = comp->stmt_list; list; list = list->next) 917 handle_user_prefs_for_sql_statement (formgrid, bcnc, 918 (GdaSqlStatement *) list->data); 919 } 920 else { 921 GdaSet *set; 922 set = (GdaSet*) ui_formgrid_get_form_data_set (UI_FORMGRID (formgrid)); 923 924 GdaSqlStatementSelect *sel; 925 GSList *list; 926 gint pos; 927 sel = (GdaSqlStatementSelect*) sqlst->contents; 928 for (pos = 0, list = sel->expr_list; list; pos ++, list = list->next) { 929 GdaSqlSelectField *field = (GdaSqlSelectField*) list->data; 930 if (! field->validity_meta_object || 931 (field->validity_meta_object->obj_type != GDA_META_DB_TABLE) || 932 !field->validity_meta_table_column) 933 continue; 934 935 gchar *plugin; 936 plugin = browser_connection_get_table_column_attribute (bcnc, 937 GDA_META_TABLE (field->validity_meta_object), 938 field->validity_meta_table_column, 939 BROWSER_CONNECTION_COLUMN_PLUGIN, NULL); 940 if (!plugin) 941 continue; 942 943 GdaHolder *holder; 944 holder = gda_set_get_nth_holder (set, pos); 945 if (holder) { 946 GValue *value; 947 value = gda_value_new_from_string (plugin, G_TYPE_STRING); 948 gda_holder_set_attribute_static (holder, GDAUI_ATTRIBUTE_PLUGIN, value); 949 gda_value_free (value); 950 } 951 g_free (plugin); 952 } 953 } 954 } 955 956 /** 957 * ui_formgrid_handle_user_prefs 958 * @formgrid: a #UiFormGrid widget 959 * @bcnc: (allow-none): a #BrowserConnection, or %NULL to let @formgrid determine it itself 960 * @stmt: the #GdaStatement which has been executed to produce the #GdaDataModel displayed in @formgrid 961 * 962 * Takes into account the UI preferences of the user 963 */ 964 void 965 ui_formgrid_handle_user_prefs (UiFormGrid *formgrid, BrowserConnection *bcnc, GdaStatement *stmt) 966 { 967 g_return_if_fail (UI_IS_FORMGRID (formgrid)); 968 if (bcnc) 969 g_return_if_fail (BROWSER_IS_CONNECTION (bcnc)); 970 else { 971 bcnc = get_browser_connection (formgrid); 972 if (!bcnc) 973 return; 974 } 975 if (stmt) 976 g_return_if_fail (GDA_IS_STATEMENT (stmt)); 977 else 978 return; 979 980 GdaSqlStatement *sqlst; 981 g_object_get ((GObject*) stmt, "structure", &sqlst, NULL); 982 if (!sqlst) 983 return; 984 985 GError *lerror = NULL; 986 if (((sqlst->stmt_type != GDA_SQL_STATEMENT_SELECT) && 987 (sqlst->stmt_type != GDA_SQL_STATEMENT_COMPOUND)) || 988 !browser_connection_normalize_sql_statement (bcnc, sqlst, &lerror)) { 989 if (lerror) 990 g_print ("[%s]\n", lerror->message); 991 goto out; 992 } 993 994 handle_user_prefs_for_sql_statement (formgrid, bcnc, sqlst); 995 out: 996 gda_sql_statement_free (sqlst); 997 } 998 999 1000 1001 static void 1002 ui_formgrid_set_property (GObject *object, 1003 guint param_id, 1004 G_GNUC_UNUSED const GValue *value, 1005 GParamSpec *pspec) 1006 { 1007 UiFormGrid *formgrid; 1008 1009 formgrid = UI_FORMGRID (object); 1010 1011 switch (param_id) { 1012 case PROP_SCROLL_FORM: 1013 formgrid->priv->scroll_form = g_value_get_boolean (value); 1014 break; 1015 case PROP_AUTOMOD: 1016 formgrid->priv->compute_mod_stmt = g_value_get_boolean (value); 1017 if (formgrid->priv->mod_stmt_auto_computed && !formgrid->priv->compute_mod_stmt) { 1018 /* clean up the mod stmt */ 1019 ModType mod; 1020 GdaDataModel *model; 1021 g_object_get (formgrid->priv->raw_grid, "model", &model, NULL); 1022 for (mod = MOD_INSERT; mod < MOD_LAST; mod++) { 1023 if (! formgrid->priv->mod_stmt[mod]) 1024 continue; 1025 g_object_unref (formgrid->priv->mod_stmt [mod]); 1026 } 1027 g_object_set (model, "delete-stmt", NULL, 1028 "insert-stmt", NULL, NULL, 1029 "update-stmt", NULL, NULL); 1030 g_object_unref (model); 1031 formgrid->priv->mod_stmt_auto_computed = FALSE; 1032 } 1033 else if (!formgrid->priv->mod_stmt_auto_computed && formgrid->priv->compute_mod_stmt) { 1034 GdaDataModel *model; 1035 g_object_get (formgrid->priv->raw_grid, "model", &model, NULL); 1036 compute_modification_statements (formgrid, model); 1037 g_object_unref (model); 1038 } 1039 break; 1040 default: 1041 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); 1042 break; 1043 } 1044 } 1045 1046 static void 1047 ui_formgrid_get_property (GObject *object, 1048 guint param_id, 1049 GValue *value, 1050 GParamSpec *pspec) 1051 { 1052 UiFormGrid *formgrid; 1053 1054 formgrid = UI_FORMGRID (object); 1055 1056 switch (param_id) { 1057 case PROP_RAW_GRID: 1058 g_value_set_object (value, formgrid->priv->raw_grid); 1059 break; 1060 case PROP_RAW_FORM: 1061 g_value_set_object (value, formgrid->priv->raw_form); 1062 break; 1063 case PROP_INFO: 1064 g_value_set_object (value, formgrid->priv->info); 1065 break; 1066 case PROP_AUTOMOD: 1067 g_value_set_boolean (value, formgrid->priv->compute_mod_stmt); 1068 break; 1069 default: 1070 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); 1071 break; 1072 } 1073 } 1074 1075 /** 1076 * ui_formgrid_get_selection 1077 * @formgrid: a #UiFormGrid widget 1078 * 1079 * Returns the list of the currently selected rows in a #UiFormGrid widget. 1080 * The returned value is a list of integers, which represent each of the selected rows. 1081 * 1082 * If new rows have been inserted, then those new rows will have a row number equal to -1. 1083 * This function is a wrapper around the gdaui_raw_grid_get_selection() function. 1084 * 1085 * Returns: a new array, should be freed (by calling g_array_free() and passing %TRUE as last argument) when no longer needed. 1086 */ 1087 GArray * 1088 ui_formgrid_get_selection (UiFormGrid *formgrid) 1089 { 1090 g_return_val_if_fail (UI_IS_FORMGRID (formgrid), NULL); 1091 g_return_val_if_fail (formgrid->priv, NULL); 1092 1093 return gdaui_data_selector_get_selected_rows (GDAUI_DATA_SELECTOR (formgrid->priv->raw_grid)); 1094 } 1095 1096 /** 1097 * ui_formgrid_get_form_data_set 1098 */ 1099 GdaDataModelIter * 1100 ui_formgrid_get_form_data_set (UiFormGrid *formgrid) 1101 { 1102 g_return_val_if_fail (UI_IS_FORMGRID (formgrid), NULL); 1103 g_return_val_if_fail (formgrid->priv, NULL); 1104 1105 return gdaui_data_selector_get_data_set (GDAUI_DATA_SELECTOR (formgrid->priv->raw_form)); 1106 } 1107 1108 /** 1109 * ui_formgrid_get_grid_data_set 1110 */ 1111 GdaDataModelIter * 1112 ui_formgrid_get_grid_data_set (UiFormGrid *formgrid) 1113 { 1114 g_return_val_if_fail (UI_IS_FORMGRID (formgrid), NULL); 1115 g_return_val_if_fail (formgrid->priv, NULL); 1116 1117 return gdaui_data_selector_get_data_set (GDAUI_DATA_SELECTOR (formgrid->priv->raw_grid)); 1118 } 1119 1120 1121 /** 1122 * ui_formgrid_set_sample_size 1123 * @formgrid: a #UiFormGrid widget 1124 * @sample_size: the sample size 1125 * 1126 * Set the size of the sample displayed in @formgrid, see gdaui_raw_grid_set_sample_size() 1127 */ 1128 void 1129 ui_formgrid_set_sample_size (UiFormGrid *formgrid, gint sample_size) 1130 { 1131 g_return_if_fail (UI_IS_FORMGRID (formgrid)); 1132 g_return_if_fail (formgrid->priv); 1133 1134 gdaui_raw_grid_set_sample_size (GDAUI_RAW_GRID (formgrid->priv->raw_grid), sample_size); 1135 } 1136 1137 /** 1138 * ui_formgrid_get_grid_widget 1139 * @formgrid: a #UiFormGrid widget 1140 * 1141 * Returns: the #GdauiRawGrid embedded in @formgrid 1142 */ 1143 GdauiRawGrid * 1144 ui_formgrid_get_grid_widget (UiFormGrid *formgrid) 1145 { 1146 g_return_val_if_fail (UI_IS_FORMGRID (formgrid), NULL); 1147 g_return_val_if_fail (formgrid->priv, NULL); 1148 1149 return GDAUI_RAW_GRID (formgrid->priv->raw_grid); 1150 } 1151 1152 /** 1153 * ui_formgrid_set_connection 1154 * @formgrid: a #UiFormGrid widget 1155 * @bcnc: (allow-none): a #BrowserConnection, or %NULL 1156 * 1157 * Tells @formgrid to use @bcnc as connection when actions have to be executed 1158 */ 1159 void 1160 ui_formgrid_set_connection (UiFormGrid *formgrid, BrowserConnection *bcnc) 1161 { 1162 g_return_if_fail (UI_IS_FORMGRID (formgrid)); 1163 g_return_if_fail (!bcnc || BROWSER_IS_CONNECTION (bcnc)); 1164 1165 if (formgrid->priv->bcnc) { 1166 g_object_unref (formgrid->priv->bcnc); 1167 formgrid->priv->bcnc = NULL; 1168 } 1169 if (bcnc) 1170 formgrid->priv->bcnc = g_object_ref (bcnc); 1171 } 1172 1173 static void 1174 compute_modification_statements (UiFormGrid *formgrid, GdaDataModel *model) 1175 { 1176 /* clear existing modification statements */ 1177 ModType mod; 1178 for (mod = MOD_INSERT; mod < MOD_LAST; mod++) { 1179 if (formgrid->priv->mod_stmt[mod]) { 1180 g_object_unref (formgrid->priv->mod_stmt[mod]); 1181 formgrid->priv->mod_stmt[mod] = NULL; 1182 } 1183 } 1184 1185 if (!model || !GDA_IS_DATA_SELECT (model)) 1186 return; 1187 1188 if (! formgrid->priv->compute_mod_stmt) 1189 return; 1190 1191 gda_data_select_compute_modification_statements_ext (GDA_DATA_SELECT (model), 1192 GDA_DATA_SELECT_COND_ALL_COLUMNS, NULL); 1193 1194 formgrid->priv->mod_stmt_auto_computed = TRUE; 1195 g_object_get (model, 1196 "insert-stmt", &formgrid->priv->mod_stmt[MOD_INSERT], 1197 "update-stmt", &formgrid->priv->mod_stmt[MOD_UPDATE], 1198 "delete-stmt", &formgrid->priv->mod_stmt[MOD_DELETE], NULL); 1199 1200 /* 1201 for (mod = MOD_INSERT; mod < MOD_LAST; mod++) { 1202 if (formgrid->priv->mod_stmt[mod]) { 1203 gchar *sql; 1204 GError *lerror = NULL; 1205 sql = gda_statement_to_sql_extended (formgrid->priv->mod_stmt[mod], NULL, NULL, 1206 GDA_STATEMENT_SQL_PARAMS_LONG, NULL, &lerror); 1207 g_print ("STMT[%d] = [%s]", mod, sql ? sql : "ERR"); 1208 if (!sql) 1209 g_print (" --- %s", lerror && lerror->message ? lerror->message : "No detail"); 1210 g_clear_error (&lerror); 1211 g_print ("\n"); 1212 g_free (sql); 1213 } 1214 else 1215 g_print ("STMT[%d] = ---\n", mod); 1216 } 1217 */ 1218 } 1219