00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00034 #include "config.h"
00035
00036 #include <string.h>
00037
00038 #include <glib.h>
00039 #include <gtk/gtk.h>
00040 #include <gnome.h>
00041
00042 #include "duifield.h"
00043 #include "duifield-gtk.h"
00044 #include "duifilter.h"
00045 #include "duiresolver.h"
00046 #include "perr.h"
00047 #include "util.h"
00048 #include "util-gtk.h"
00049 #include "window.h"
00050
00056 struct gtk_widget_s
00057 {
00058 GtkWidget * widget;
00059 int column;
00060 int row;
00061
00064 GtkCTreeNode *ctn;
00065 };
00066
00072 struct gtk_widata_s
00073 {
00074 GtkWidget * widget;
00075 int column;
00076 int row;
00077 char * datakey;
00081 GtkCTreeNode *ctn;
00082 };
00083
00085 struct gtk_widarg_s
00086 {
00087 GtkWidget * widget;
00088 int column;
00089 char * arg;
00090 };
00091
00093 struct gtk_widwhere_s
00094 {
00095 char * match_value;
00096 GtkWidget * widget;
00097 int row;
00098 int column;
00099 char * compareop;
00100
00102 char **blank_row;
00103
00106 GtkCTreeNode *ctn;
00107 };
00108
00109
00110
00111 static void
00112 widget_field_clear (DuiField *f)
00113 {
00114 g_free (f->fieldname);
00115 f->type = DUI_FIELD_NONE;
00116 }
00117
00118 static void
00119 widata_field_clear (DuiField *f)
00120 {
00121 struct gtk_widata_s * gf = (struct gtk_widata_s *) get_gobj_field (f);
00122 g_free (gf->datakey);
00123 g_free (f->fieldname);
00124 f->type = DUI_FIELD_NONE;
00125 }
00126
00127 static void
00128 widarg_field_clear (DuiField *f)
00129 {
00130 struct gtk_widarg_s * gf = (struct gtk_widarg_s *) get_gobj_field (f);
00131 g_free (gf->arg);
00132 g_free (f->fieldname);
00133 f->type = DUI_FIELD_NONE;
00134 }
00135
00136 static void
00137 where_field_clear (DuiField *f)
00138 {
00139 struct gtk_widwhere_s * gf = (struct gtk_widwhere_s *) get_gobj_field (f);
00140 g_free (gf->compareop);
00141 g_free (gf->blank_row);
00142
00143 g_free (f->fieldname);
00144 f->type = DUI_FIELD_NONE;
00145 }
00146
00147
00148
00149 static const char *
00150 widget_get_value (DuiField *fs)
00151 {
00152 GtkWidget *widget;
00153 const gchar * val = NULL;
00154 struct gtk_widget_s * gw = (struct gtk_widget_s *) get_gobj_field (fs);
00155
00156
00157
00158 if (0 != g_ascii_strncasecmp(DUI_FIELD_WIDGET, fs->type, 0)) return NULL;
00159
00160 widget = gw->widget;
00161 if (!widget) return NULL;
00162
00163
00164
00165 if (GTK_IS_CTREE(widget))
00166 {
00167 if (NULL == gw->ctn) return NULL;
00168 gtk_ctree_node_get_text (GTK_CTREE(widget), gw->ctn, gw->column, (gchar **) &val);
00169 }
00170 else
00171 if (GTK_IS_CLIST(widget))
00172 {
00173 if (0 > gw->row) return NULL;
00174 gtk_clist_get_text (GTK_CLIST(widget), gw->row, gw->column, (gchar **) &val);
00175 }
00176 else
00177 if (GTK_IS_MENU(widget))
00178 {
00179 static char menuval[18];
00180 GList *node;
00181 int i=0;
00182 GtkWidget *w = gtk_menu_get_active (GTK_MENU(widget));
00183 for (node=GTK_MENU_SHELL(widget)->children; node; node=node->next)
00184 {
00185 if (w == node->data)
00186 {
00187 snprintf (menuval, 18, "%d", i);
00188 return menuval;
00189 }
00190 i++;
00191 }
00192 }
00193 else
00194 if (GTK_IS_OPTION_MENU(widget))
00195 {
00196 DuiField dfs;
00197 dfs = *fs;
00198 struct gtk_widget_s * dgw;
00199
00200 dgw = (struct gtk_widget_s *) get_gobj_field (&dfs);
00201 dgw->widget = GTK_OPTION_MENU(widget)->menu;
00202
00203
00204 val = widget_get_value (&dfs);
00205 }
00206 else
00207 if (GTK_IS_RADIO_BUTTON(widget))
00208 {
00209 GSList *node;
00210
00211
00212 node = gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget));
00213 for ( ; node; node=node->next)
00214 {
00215 gboolean pushed;
00216 pushed = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(node->data));
00217 if (pushed) break;
00218 }
00219 if (!node) return NULL;
00220 val = gtk_object_get_data (GTK_OBJECT(node->data), "/system/data");
00221 }
00222 else
00223 if (GTK_IS_TOGGLE_BUTTON(widget))
00224 {
00225 static char togbuff[2];
00226 gboolean state;
00227 state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(widget));
00228 if (state) togbuff[0] = '1'; else togbuff[0] = '0';
00229 togbuff[1] = 0;
00230 val = togbuff;
00231 }
00232 else
00233 if (GTK_IS_SPIN_BUTTON(widget))
00234 {
00235 static char spinbuff[40];
00236 gdouble dbl = gtk_spin_button_get_value (GTK_SPIN_BUTTON(widget));
00237 snprintf (spinbuff, 40, "%24.18g", dbl);
00238 return spinbuff;
00239 }
00240 else
00241 if (GTK_IS_ENTRY(widget))
00242 {
00243 val = gtk_entry_get_text (GTK_ENTRY(widget));
00244 }
00245 else
00246 if (GTK_IS_LABEL(widget))
00247 {
00248 gtk_label_get (GTK_LABEL(widget), (gchar **) &val);
00249 }
00250 else
00251 if (GTK_IS_TEXT_VIEW(widget))
00252 {
00253 val = xxxgtk_textview_get_text (GTK_TEXT_VIEW(widget));
00254 }
00255 else
00256 if (GTK_IS_COMBO(widget))
00257 {
00258 val = gtk_entry_get_text (GTK_ENTRY(GTK_COMBO(widget)->entry));
00259 }
00260 else
00261 if (GTK_IS_RANGE(widget))
00262 {
00263 GtkAdjustment *adj = gtk_range_get_adjustment (GTK_RANGE(widget));
00264 double flt = adj->value;
00265 static char rangebuff[40];
00266 snprintf (rangebuff, 40, "%24.18g", flt);
00267 val = rangebuff;
00268 }
00269 else
00270 if (GNOME_IS_FILE_ENTRY (widget))
00271 {
00272 GtkWidget * entry = gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY(widget));
00273 val = gtk_entry_get_text (GTK_ENTRY (entry));
00274 }
00275 else
00276 if (GTK_IS_FILE_SELECTION (widget))
00277 {
00278 val = gtk_entry_get_text (GTK_ENTRY (GTK_FILE_SELECTION
00279 (widget)->selection_entry));
00280 }
00281 else
00282 if (GNOME_IS_DATE_EDIT(widget))
00283 {
00284 static char datebuff[50];
00285 time_t thyme = gnome_date_edit_get_time (GNOME_DATE_EDIT(widget));
00286 xxxgnc_secs_to_iso8601_buff (thyme, datebuff);
00287 return datebuff;
00288 }
00289 else
00290 if (GTK_IS_BIN(widget))
00291 {
00292
00293 DuiField dfs;
00294 dfs = *fs;
00295 struct gtk_widget_s * dgw = (struct gtk_widget_s *) get_gobj_field (&dfs);
00296 dgw->widget = GTK_BIN(widget)->child;
00297
00298
00299 val = widget_get_value (&dfs);
00300 }
00301 else
00302 {
00303 PERR ("unsupported <where> or <update> widget type %s",
00304 gtk_type_name(GTK_OBJECT_TYPE(widget)));
00305 }
00306 return val;
00307 }
00308
00309
00310
00311 static void
00312 widget_set_value (DuiField *fs, const char * val)
00313 {
00314 struct gtk_widget_s *gw = (struct gtk_widget_s *) get_gobj_field (fs);
00315 GtkObject *obj;
00316
00317
00318
00319 if (0 != g_ascii_strncasecmp(DUI_FIELD_WIDGET, fs->type, 0)) return;
00320
00321 obj = GTK_OBJECT (gw->widget);
00322 if (!obj) return;
00323
00324
00325
00326
00327
00328
00329 if (GTK_IS_TREE_VIEW(obj))
00330 {
00331 printf ("duude! DWI doesn't support gtk_tree_view because "
00332 "glade and gtk tree is fundemntaly broken!\n");
00333 printf ("want to set col=%d val=%s\n", gw->column, val);
00334 GtkTreeModel *tm = gtk_tree_view_get_model (GTK_TREE_VIEW(obj));
00335 printf ("gtk tree model=%p\n", tm);
00336
00337 GtkTreeViewColumn *tvc = gtk_tree_view_get_column(GTK_TREE_VIEW(obj), gw->column);
00338 printf ("gtk tree view column=%p\n", tvc);
00339 if (NULL == tm)
00340 {
00341
00342 #if 0
00343
00344
00345 GtkTreeStore *treestore;
00346 treestore = gtk_tree_store_new(NUM_COLS,
00347 G_TYPE_STRING,
00348 G_TYPE_STRING,
00349 G_TYPE_UINT);
00350 GtkTreeIter toplevel;
00351 gtk_tree_store_append(treestore, &toplevel, NULL);
00352 gtk_tree_store_set(treestore, &toplevel,
00353 COL_FIRST_NAME, "Maria",
00354 COL_LAST_NAME, "Incognito",
00355 -1);
00356 tm = GTK_TREE_MODEL(treestore);
00357 #endif
00358 return;
00359 }
00360 }
00361 else
00362 if (GTK_IS_CTREE(obj))
00363 {
00364 if (NULL == gw->ctn) return;
00365 gtk_ctree_node_set_text (GTK_CTREE(obj), gw->ctn,
00366 gw->column, val);
00367 }
00368 else
00369 if (GTK_IS_CLIST(obj))
00370 {
00371 if (0 > gw->row) return;
00372 gtk_clist_set_text (GTK_CLIST(obj), gw->row,
00373 gw->column, val);
00374 }
00375 else
00376 if (GTK_IS_SPIN_BUTTON (obj))
00377 {
00378 gfloat flt;
00379 flt = atof (val);
00380 gtk_spin_button_set_value (GTK_SPIN_BUTTON(obj), flt);
00381 }
00382 else
00383 if (GTK_IS_ENTRY (obj))
00384 {
00385 gtk_entry_set_text (GTK_ENTRY(obj), val);
00386 }
00387 else
00388 if (GTK_IS_LABEL (obj))
00389 {
00390 gtk_label_set_text (GTK_LABEL(obj), val);
00391 }
00392 else
00393 if (GTK_IS_TEXT_VIEW (obj))
00394 {
00395 xxxgtk_textview_set_text (GTK_TEXT_VIEW(obj), val);
00396 }
00397 else
00398 if (GTK_IS_COMBO (obj))
00399 {
00400 gtk_entry_set_text (GTK_ENTRY(GTK_COMBO (obj)->entry), val);
00401 }
00402 else
00403 if (GTK_IS_RANGE (obj))
00404 {
00405 gfloat flt = atof (val);
00406 GtkAdjustment *adj = gtk_range_get_adjustment (GTK_RANGE(obj));
00407 gtk_adjustment_set_value (adj, flt);
00408 }
00409 else
00410 if (GTK_IS_MENU_SHELL (obj))
00411 {
00412
00413 int i=0;
00414 int ival = 0;
00415 GList *node;
00416 GtkMenuShell *menu = GTK_MENU_SHELL(obj);
00417 if (val) ival = atoi (val);
00418 for (node = menu->children; node; node=node->next)
00419 {
00420 if (i == ival)
00421 {
00422 gtk_menu_shell_select_item (menu, node->data);
00423 gtk_menu_shell_activate_item (menu, node->data, 1);
00424 break;
00425 }
00426 i++;
00427 }
00428 }
00429 else
00430 if (GTK_IS_OPTION_MENU (obj))
00431 {
00432 DuiField lf;
00433 lf = *fs;
00434 struct gtk_widget_s * dgw = (struct gtk_widget_s *) get_gobj_field (&lf);
00435 dgw->widget = GTK_WIDGET(GTK_OPTION_MENU(obj)->menu);
00436 widget_set_value (&lf, val);
00437 }
00438 else
00439 if (GTK_IS_RADIO_BUTTON (obj))
00440 {
00441 GSList *node;
00442 const char *data = gtk_object_get_data (obj, "/system/data");
00443
00444 if (!data)
00445 {
00446 gtk_object_set_data (obj, "/system/data", (gpointer) val);
00447 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(obj), 1);
00448 }
00449 else
00450 {
00451
00452 node = gtk_radio_button_group (GTK_RADIO_BUTTON (obj));
00453 for ( ; node; node=node->next)
00454 {
00455 data = gtk_object_get_data (GTK_OBJECT(node->data),
00456 "/system/data");
00457 if (data && !strcmp (data, val)) break;
00458 }
00459 if (node)
00460 {
00461 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(node->data), 1);
00462 }
00463 }
00464 }
00465 else
00466 if (GTK_IS_TOGGLE_BUTTON (obj))
00467 {
00468 int ival = 0;
00469 if (val) ival = dui_util_bool_to_int (val);
00470 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(obj), ival);
00471 }
00472 else
00473 if (GNOME_IS_FILE_ENTRY (obj))
00474 {
00475 GtkWidget * entry = gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY(obj));
00476 gtk_entry_set_text (GTK_ENTRY (entry), val);
00477 }
00478 else
00479 if (GTK_IS_FILE_SELECTION (obj))
00480 {
00481 gtk_entry_set_text (GTK_ENTRY (GTK_FILE_SELECTION
00482 (obj)->selection_entry), val);
00483 }
00484 else
00485 if (GTK_IS_FRAME(obj))
00486 {
00487 gtk_frame_set_label (GTK_FRAME(obj), val);
00488 }
00489 else
00490 if (GTK_IS_WINDOW(obj))
00491 {
00492 gtk_window_set_title (GTK_WINDOW(obj), val);
00493 }
00494 else
00495 if (GTK_IS_BIN (obj))
00496 {
00497 DuiField lf;
00498
00499
00500 lf = *fs;
00501 struct gtk_widget_s * gf = (struct gtk_widget_s*) get_gobj_field (fs);
00502
00503 gf->widget = GTK_WIDGET (GTK_BIN(obj)->child);
00504 widget_set_value (&lf, val);
00505 }
00506 else
00507 if (GNOME_IS_DATE_EDIT (obj))
00508 {
00509
00510
00511
00512
00513 time_t thyme = xxxgnc_iso8601_to_secs_gmt (val);
00514 gnome_date_edit_set_time (GNOME_DATE_EDIT(obj), thyme);
00515 }
00516 else
00517 if (GNOME_IS_ABOUT (obj))
00518 {
00519
00520 }
00521 else
00522 {
00523 SYNTAX ("unsupported report widget \"%s\"\n",
00524 gtk_type_name(GTK_OBJECT_TYPE(obj)));
00525 }
00526 }
00527
00528
00529
00530 static const char *
00531 widget_get_data (DuiField *fs)
00532 {
00533 GtkWidget *widget;
00534 const char * val = NULL;
00535 struct gtk_widata_s *gw = (struct gtk_widata_s *) get_gobj_field (fs);
00536
00537
00538
00539 if (0 != g_ascii_strncasecmp(DUI_FIELD_WID_DATA, fs->type, 0)) return NULL;
00540
00541 widget = gw->widget;
00542 if (!widget) return NULL;
00543
00544
00545 if (GTK_IS_CTREE(widget))
00546 {
00547 GHashTable *tbl;
00548 if (NULL == gw->ctn) return NULL;
00549 tbl = gtk_ctree_node_get_row_data (GTK_CTREE(widget), gw->ctn);
00550 if (tbl) val = g_hash_table_lookup (tbl, gw->datakey);
00551 }
00552 else
00553 if (GTK_IS_CLIST(widget))
00554 {
00555 GHashTable *tbl;
00556 if (0 > gw->row) return NULL;
00557 tbl = gtk_clist_get_row_data (GTK_CLIST(widget), gw->row);
00558 if (tbl) val = g_hash_table_lookup (tbl, gw->datakey);
00559 }
00560 else
00561 if (GTK_IS_RADIO_BUTTON(widget))
00562 {
00563 GSList *node;
00564
00565
00566 node = gtk_radio_button_group (GTK_RADIO_BUTTON (widget));
00567 for ( ; node; node=node->next)
00568 {
00569 gboolean pushed;
00570 pushed = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(node->data));
00571 if (pushed) break;
00572 }
00573 if (!node) return NULL;
00574 val = gtk_object_get_data (GTK_OBJECT(node->data), gw->datakey);
00575 }
00576 else
00577 {
00578 val = gtk_object_get_data (GTK_OBJECT(widget), gw->datakey);
00579 }
00580 return val;
00581 }
00582
00583
00584
00585 static void
00586 widget_set_data (DuiField *fs, const char * val)
00587 {
00588 GtkWidget *widget;
00589 struct gtk_widata_s *gw = (struct gtk_widata_s*) get_gobj_field (fs);
00590 const char * datakey;
00591
00592
00593
00594 if (0 != g_ascii_strncasecmp(DUI_FIELD_WID_DATA, fs->type, 0)) return;
00595
00596 widget = gw->widget;
00597 if (!widget) return;
00598
00599 datakey = gw->datakey;
00600
00601 if (GTK_IS_CTREE(widget))
00602 {
00603 GHashTable *tbl;
00604 if (NULL == gw->ctn) return;
00605 tbl = gtk_ctree_node_get_row_data (GTK_CTREE(widget), gw->ctn);
00606 if (!tbl)
00607 {
00610 tbl = g_hash_table_new (g_str_hash, g_str_equal);
00611
00612
00613 gtk_ctree_node_set_row_data (GTK_CTREE(widget), gw->ctn, tbl);
00614 }
00615 g_hash_table_insert (tbl, g_strdup(datakey), g_strdup(val));
00616 }
00617 else
00618 if (GTK_IS_CLIST(widget))
00619 {
00620 GHashTable *tbl;
00621 if (0 > gw->row) return;
00622 tbl = gtk_clist_get_row_data (GTK_CLIST(widget), gw->row);
00623 if (!tbl)
00624 {
00627 tbl = g_hash_table_new (g_str_hash, g_str_equal);
00628
00629
00630 gtk_clist_set_row_data (GTK_CLIST(widget), gw->row, tbl);
00631 }
00632 g_hash_table_insert (tbl, g_strdup(datakey), g_strdup(val));
00633 }
00634 #if 0
00635 else
00636 if (GTK_IS_RADIO_BUTTON(widget))
00637 {
00638
00639 }
00640 #endif
00641 else
00642 {
00643 gtk_object_set_data (GTK_OBJECT (widget), datakey, g_strdup(val));
00644 }
00645 }
00646
00647
00648
00649 #ifdef BROKEN_IN_GTK_2
00650 XXX fix me later
00651
00652 static void
00653 widget_set_arg (DuiField *fs, const char * val)
00654 {
00655 GtkObject *obj;
00656 const char * argname;
00657 GtkArgInfo *arginfo;
00658 GtkType obj_type, arg_type;
00659 int ival = 0;
00660 double fval = 0.0;
00661
00662
00663 if (DUI_FIELD_WID_ARG != fs->type) return;
00664
00665 obj = GTK_OBJECT (WID_ARG(fs)->widget);
00666 if (!obj) return;
00667
00668 argname = WID_ARG(fs)->arg;
00669
00670 ENTER ("(obj=%p, arg=\'%s\', val=\'%s\')", obj, argname, val);
00671 obj_type = GTK_OBJECT_TYPE(obj);
00672 gtk_object_arg_get_info (obj_type, argname, &arginfo);
00673 arg_type = arginfo->type;
00674 PINFO ("arg is of type (%d) \'%s\'\n", arg_type, gtk_type_name (arg_type));
00675
00676 switch (arg_type)
00677 {
00678 case GTK_TYPE_INVALID:
00679 case GTK_TYPE_NONE:
00680 break;
00681 case GTK_TYPE_CHAR:
00682 case GTK_TYPE_UCHAR:
00683 gtk_object_set (obj, argname, val[0], NULL);
00684 break;
00685 case GTK_TYPE_BOOL:
00686 if (val) ival = atoi(val);
00687 gtk_object_set (obj, argname, (gboolean) ival, NULL);
00688 break;
00689 case GTK_TYPE_INT:
00690 case GTK_TYPE_UINT:
00691 if (val) ival = atoi(val);
00692 gtk_object_set (obj, argname, (int) ival, NULL);
00693 break;
00694 case GTK_TYPE_LONG:
00695 case GTK_TYPE_ULONG:
00696 if (val) ival = atoi(val);
00697 gtk_object_set (obj, argname, (long) ival, NULL);
00698 break;
00699 case GTK_TYPE_FLOAT:
00700 if (val) fval = atof(val);
00701 gtk_object_set (obj, argname, (float) fval, NULL);
00702 break;
00703 case GTK_TYPE_DOUBLE:
00704 if (val) fval = atof(val);
00705 gtk_object_set (obj, argname, fval, NULL);
00706 break;
00707 case GTK_TYPE_STRING:
00708 gtk_object_set (obj, argname, val, NULL);
00709 break;
00710 default:
00711 break;
00712 }
00713 }
00714 #endif
00715
00716
00717
00718
00719 static void
00720 ctree_pre (DuiField *fld, gboolean do_clear)
00721 {
00722 int i, columns;
00723 struct gtk_widwhere_s *tbl = (struct gtk_widwhere_s *)get_gobj_field(fld);
00724
00725 GtkCList *clist = GTK_CLIST (tbl->widget);
00726
00727 gtk_clist_freeze (clist);
00728
00729
00730 if (do_clear)
00731 {
00732 gtk_clist_clear (clist);
00733 }
00734
00735
00736 columns = clist->columns;
00737 if (tbl->blank_row) g_free (tbl->blank_row);
00738 tbl->blank_row = g_new (char *, columns);
00739 for (i=0; i<columns; i++) tbl->blank_row[i] = "";
00740 }
00741
00742 static void
00743 ctree_post (DuiField *fld)
00744 {
00745 struct gtk_widwhere_s *tbl = (struct gtk_widwhere_s *)get_gobj_field(fld);
00746
00747
00748 GtkCList *clist = GTK_CLIST (tbl->widget);
00749
00750 gtk_clist_thaw(clist);
00751 g_free (tbl->blank_row);
00752 tbl->blank_row = NULL;
00753 }
00754
00755
00756
00757
00758
00759
00760
00761 static GtkCTreeNode *
00762 ctree_recur (GtkCTree *ctree, GtkCTreeNode *start_ctn,
00763 int match_col, const char * match_value)
00764 {
00765 GtkCTreeRow *ctr;
00766 GtkCTreeNode *ctn;
00767
00768 ctn = start_ctn;
00769
00770
00771 while (ctn)
00772 {
00773 char * cval;
00774
00775 gtk_ctree_node_get_text (ctree, ctn, match_col, &cval);
00776 if (!strcmp (cval, match_value))
00777 {
00778 return ctn;
00779 }
00780
00781 ctr = ctn->list.data;
00782 if (!ctr) break;
00783 ctn = ctr->sibling;
00784 }
00785
00786
00787 ctn = start_ctn;
00788 while (ctn)
00789 {
00790 GtkCTreeNode *child_ctn, *match_ctn;
00791 ctr = ctn->list.data;
00792 if (!ctr) break;
00793 child_ctn = ctr->children;
00794
00795 match_ctn = ctree_recur (ctree, child_ctn, match_col, match_value);
00796
00797 if (match_ctn) return match_ctn;
00798
00799 ctn = ctr->sibling;
00800 }
00801
00802 return NULL;
00803 }
00804
00805 static gboolean
00806 ctree_iter (DuiField *fld)
00807 {
00808 struct gtk_widwhere_s *tbl = (struct gtk_widwhere_s *)get_gobj_field(fld);
00809 GtkCTree *ctree = GTK_CTREE (tbl->widget);
00810 GtkCTreeNode *ctn;
00811 int match_col;
00812
00813 tbl->ctn = NULL;
00814 if ((NULL == tbl->match_value) || (0 == tbl->match_value[0]))
00815 {
00816 tbl->ctn = gtk_ctree_insert_node (ctree,
00817 NULL, NULL, tbl->blank_row, 0,
00818 NULL, NULL, NULL, NULL, FALSE, FALSE);
00819 return TRUE;
00820 }
00821
00822 match_col = tbl->column;
00823
00824 ctn = gtk_ctree_node_nth (ctree, 0);
00825 ctn = ctree_recur (ctree, ctn, match_col, tbl->match_value);
00826 if (ctn)
00827 {
00828 tbl->ctn = gtk_ctree_insert_node (ctree, ctn,
00829 NULL, tbl->blank_row, 0,
00830 NULL, NULL, NULL, NULL, FALSE, FALSE);
00831 return TRUE;
00832 }
00833
00834 SYNTAX ("could not locate a parent row with value %s", tbl->match_value);
00835 return FALSE;
00836 }
00837
00838
00839
00840 static void
00841 clist_pre (DuiField *fld, gboolean do_clear)
00842 {
00843 int i, columns;
00844 struct gtk_widwhere_s *tbl = (struct gtk_widwhere_s *)get_gobj_field(fld);
00845 GtkCList *clist = GTK_CLIST (tbl->widget);
00846
00847 gtk_clist_freeze (clist);
00848
00849
00850 if (do_clear)
00851 {
00852 gtk_clist_clear (clist);
00853 }
00854
00855 tbl->row = -1;
00856
00857 columns = clist->columns;
00858 if (tbl->blank_row) g_free (tbl->blank_row);
00859 tbl->blank_row = g_new (char *, columns);
00860 for (i=0; i<columns; i++) tbl->blank_row[i] = "";
00861 }
00862
00863 static void
00864 clist_post (DuiField *fld)
00865 {
00866 struct gtk_widwhere_s *tbl = (struct gtk_widwhere_s *)get_gobj_field(fld);
00867 GtkCList *clist = GTK_CLIST (tbl->widget);
00868
00869 gtk_clist_thaw(clist);
00870 g_free (tbl->blank_row);
00871 tbl->blank_row = NULL;
00872 }
00873
00874 static gboolean
00875 clist_iter (DuiField *fld)
00876 {
00877 struct gtk_widwhere_s *tbl = (struct gtk_widwhere_s *)get_gobj_field(fld);
00878 GtkCList *clist = GTK_CLIST (tbl->widget);
00879 tbl->row ++;
00880 gtk_clist_append (clist, tbl->blank_row);
00881 return TRUE;
00882 }
00883
00884
00885
00886
00887
00888 static void
00889 resolve_target (DuiField *target, DuiField *matcher)
00890 {
00891 struct gtk_widwhere_s *tbl;
00892 struct gtk_widget_s * wget;
00893 struct gtk_widata_s * wdat;
00894
00895 if (!target || !matcher) return;
00896 if (!DUI_FIELD_IS_TYPE(matcher,DUI_FIELD_WID_WHERE)) return;
00897 wget = (struct gtk_widget_s *)get_gobj_field(target);
00898 tbl = (struct gtk_widwhere_s *)get_gobj_field(matcher);
00899 wdat = (struct gtk_widata_s *)get_gobj_field(target);
00900 if (DUI_FIELD_IS_TYPE (target, DUI_FIELD_WIDGET))
00901 {
00902 if (tbl->widget != wget->widget) return;
00903 wget->ctn = tbl->ctn;
00904 wget->row = tbl->row;
00905 return;
00906 }
00907 if (DUI_FIELD_IS_TYPE (target, DUI_FIELD_WID_DATA))
00908 {
00909 if (tbl->widget != wdat->widget) return;
00910 wdat->ctn = tbl->ctn;
00911 wdat->row = tbl->row;
00912 return;
00913 }
00914 }
00915
00916 static void
00917 set_match_value (DuiField *fld, const char * val)
00918 {
00919 struct gtk_widwhere_s *gw;
00920 gw = (struct gtk_widwhere_s *)get_gobj_field(fld);
00921 if (gw->match_value) g_free (gw->match_value);
00922
00923 if (val)
00924 {
00925 gw->match_value = g_strdup (val);
00926 }
00927 else
00928 {
00929 gw->match_value = g_strdup ("");
00930 }
00931 }
00932
00933
00934
00935 void
00936 dui_field_set_widget (DuiField *fs, const char * widname, int colnum)
00937 {
00938 struct gtk_widget_s *gw;
00939
00940 if (!fs || !DUI_FIELD_IS_TYPE(fs,DUI_FIELD_NONE)) return;
00941 fs->type = DUI_FIELD_WIDGET;
00942 fs->fieldname = g_strdup (widname),
00943
00944 fs->get_field_value = widget_get_value;
00945 fs->set_field_value = widget_set_value;
00946 fs->clear_field = widget_field_clear;
00947
00948 fs->iter_pre = NULL;
00949 fs->iter_next = NULL;
00950 fs->iter_column = resolve_target;
00951 fs->iter_post = NULL;
00952
00953 gw = (struct gtk_widget_s *)get_gobj_field(fs);
00954 gw->widget = NULL,
00955 gw->column = colnum;
00956 gw->row = -1;
00957 gw->ctn = NULL;
00958 }
00959
00960 void
00961 dui_field_set_wid_data (DuiField *fs, const char * widname,
00962 int colnum,
00963 const char * datakey)
00964 {
00965 struct gtk_widata_s *gw;
00966
00967 if (!fs || !DUI_FIELD_IS_TYPE(fs,DUI_FIELD_NONE)) return;
00968 fs->type = DUI_FIELD_WID_DATA;
00969 fs->fieldname = g_strdup (widname),
00970
00971 fs->get_field_value = widget_get_data;
00972 fs->set_field_value = widget_set_data;
00973 fs->clear_field = widata_field_clear;
00974
00975 fs->iter_pre = NULL;
00976 fs->iter_next = NULL;
00977 fs->iter_column = resolve_target;
00978 fs->iter_post = NULL;
00979
00980 gw = (struct gtk_widata_s *)get_gobj_field(fs);
00981 gw->widget = NULL,
00982 gw->column = colnum;
00983 gw->row = -1;
00984 gw->ctn = NULL;
00985 gw->datakey = g_strdup (datakey);
00986 }
00987
00988 void
00989 dui_field_set_wid_arg (DuiField *fs, const char * widname,
00990 int colnum,
00991 const char * arg)
00992 {
00993 struct gtk_widarg_s *gw;
00994
00995 if (!fs || !DUI_FIELD_IS_TYPE(fs,DUI_FIELD_NONE)) return;
00996 fs->type = DUI_FIELD_WID_ARG;
00997 fs->fieldname = g_strdup (widname),
00998
00999 fs->get_field_value = NULL;
01000
01001 fs->set_field_value = NULL;
01002 fs->clear_field = widarg_field_clear;
01003
01004 fs->iter_pre = NULL;
01005 fs->iter_next = NULL;
01006 fs->iter_column = resolve_target;
01007 fs->iter_post = NULL;
01008
01009 gw = (struct gtk_widarg_s *)get_gobj_field(fs);
01010 gw->widget = NULL,
01011 gw->column = colnum;
01012 gw->arg = g_strdup (arg);
01013 }
01014
01015 void
01016 dui_field_set_wid_where (DuiField *fs, const char * widname,
01017 int colnum, const char * compareop)
01018 {
01019 struct gtk_widwhere_s *gw;
01020
01021 if (!fs || !DUI_FIELD_IS_TYPE(fs,DUI_FIELD_NONE)) return;
01022 fs->type = DUI_FIELD_WID_WHERE;
01023 fs->fieldname = g_strdup (widname);
01024
01025 fs->get_field_value = NULL;
01026 fs->set_field_value = set_match_value;
01027 fs->clear_field = where_field_clear;
01028
01029 fs->iter_pre = NULL;
01030 fs->iter_next = NULL;
01031 fs->iter_column = NULL;
01032 fs->iter_post = NULL;
01033
01034 gw = (struct gtk_widwhere_s *)get_gobj_field(fs);
01035 gw->match_value = NULL;
01036 gw->widget = NULL;
01037 gw->column = colnum;
01038 gw->row = -1;
01039 gw->blank_row = NULL;
01040 gw->compareop = g_strdup(compareop);
01041 gw->ctn = NULL;
01042 }
01043
01044
01045
01046 static void
01047 get_clist_row (GtkCList *clist,
01048 gint row,
01049 gint column,
01050 GdkEvent *event,
01051 DuiField *fs)
01052 {
01053 struct gtk_widget_s *tbl = (struct gtk_widget_s *)get_gobj_field(fs);
01054 struct gtk_widata_s *gd = (struct gtk_widata_s *)get_gobj_field(fs);
01055 if (DUI_FIELD_IS_TYPE (fs, DUI_FIELD_WIDGET)) {
01056 tbl->row = row; return;
01057 }
01058 if (DUI_FIELD_IS_TYPE (fs, DUI_FIELD_WID_DATA)) {
01059 gd->row = row; return;
01060 }
01061 }
01062
01063 static void
01064 unget_clist_row (GtkCList *clist,
01065 gint row,
01066 gint column,
01067 GdkEvent *event,
01068 DuiField *fs)
01069 {
01070 struct gtk_widget_s *tbl = (struct gtk_widget_s *)get_gobj_field(fs);
01071 struct gtk_widata_s *gd = (struct gtk_widata_s *)get_gobj_field(fs);
01072 if (DUI_FIELD_IS_TYPE (fs, DUI_FIELD_WIDGET)) {
01073 tbl->row = -1; return;
01074 }
01075 if (DUI_FIELD_IS_TYPE (fs, DUI_FIELD_WID_DATA)) {
01076 gd->row = -1; return;
01077 }
01078 }
01079
01080 static void
01081 get_ctree_row (GtkCList *clist,
01082 GtkCTreeNode *ctn,
01083 gint column,
01084 DuiField *fs)
01085 {
01086 struct gtk_widget_s *tbl = (struct gtk_widget_s *)get_gobj_field(fs);
01087 struct gtk_widata_s *gd = (struct gtk_widata_s *)get_gobj_field(fs);
01088 if (DUI_FIELD_IS_TYPE (fs, DUI_FIELD_WIDGET)) {
01089 tbl->ctn = ctn; return;
01090 }
01091 if (DUI_FIELD_IS_TYPE (fs, DUI_FIELD_WID_DATA)) {
01092 gd->ctn = ctn; return;
01093 }
01094 }
01095
01096 static void
01097 unget_ctree_row (GtkCList *clist,
01098 GtkCTreeNode *ctn,
01099 gint column,
01100 DuiField *fs)
01101 {
01102 struct gtk_widget_s *tbl = (struct gtk_widget_s *)get_gobj_field(fs);
01103 struct gtk_widata_s *gd = (struct gtk_widata_s *)get_gobj_field(fs);
01104 if (DUI_FIELD_IS_TYPE (fs, DUI_FIELD_WIDGET)) {
01105 tbl->ctn = NULL; return;
01106 }
01107 if (DUI_FIELD_IS_TYPE (fs, DUI_FIELD_WID_DATA)) {
01108 gd->ctn = NULL; return;
01109 }
01110 }
01111
01112 static void
01113 add_watcher (DuiField *fs, GtkWidget *w)
01114 {
01115
01116
01117 if (GTK_IS_CTREE(w))
01118 {
01119 gtk_signal_connect(GTK_OBJECT(w), "tree_select_row",
01120 GTK_SIGNAL_FUNC(get_ctree_row), fs);
01121 gtk_signal_connect(GTK_OBJECT(w), "tree_unselect_row",
01122 GTK_SIGNAL_FUNC(unget_ctree_row), fs);
01123 }
01124 else
01125 if (GTK_IS_CLIST (w))
01126 {
01127 gtk_signal_connect(GTK_OBJECT(w), "select_row",
01128 GTK_SIGNAL_FUNC(get_clist_row), fs);
01129 gtk_signal_connect(GTK_OBJECT(w), "unselect_row",
01130 GTK_SIGNAL_FUNC(unget_clist_row), fs);
01131 }
01132 }
01133
01134
01135
01136
01137 static void
01138 clist_sort_column (GtkCList *clist, gint column, DuiField *f)
01139 {
01140 static GtkSortType direction = GTK_SORT_DESCENDING;
01141
01142 if (GTK_SORT_DESCENDING == direction) direction = GTK_SORT_ASCENDING;
01143 else direction = GTK_SORT_DESCENDING;
01144
01145 gtk_clist_freeze (clist);
01146 gtk_clist_set_sort_type (clist, direction);
01147 gtk_clist_set_sort_column (clist, column);
01148 gtk_clist_sort (clist);
01149
01150 gtk_clist_thaw (clist);
01151 }
01152
01153 static void
01154 add_sorter (DuiField *fld, GtkWidget *w)
01155 {
01156
01157
01158 if ((GTK_IS_CTREE(w)) || (GTK_IS_CLIST(w)))
01159 {
01160 gtk_signal_connect (GTK_OBJECT(w), "click_column",
01161 GTK_SIGNAL_FUNC(clist_sort_column), fld);
01162 }
01163 }
01164
01165
01166
01167 static void
01168 resolve_where (DuiField *fld)
01169 {
01170 struct gtk_widwhere_s *tbl = (struct gtk_widwhere_s *)get_gobj_field(fld);
01171 GtkWidget *w = tbl->widget;
01172
01173
01174
01175 if (GTK_IS_CTREE(w))
01176 {
01177 fld->iter_pre = ctree_pre;
01178 fld->iter_post = ctree_post;
01179 fld->iter_next = ctree_iter;
01180 }
01181 else
01182 if (GTK_IS_CLIST(w))
01183 {
01184 fld->iter_pre = clist_pre;
01185 fld->iter_post = clist_post;
01186 fld->iter_next = clist_iter;
01187 }
01188 else
01189 {
01190 fld->iter_pre = NULL;
01191 fld->iter_post = NULL;
01192 fld->iter_next = NULL;
01193 }
01194 }
01195
01196
01197
01198 static void
01199 resolve_widget (DuiField *fs, GtkWidget *w)
01200 {
01201 struct gtk_widget_s *tbl = (struct gtk_widget_s *)get_gobj_field(fs);
01202 struct gtk_widata_s *gd = (struct gtk_widata_s *)get_gobj_field(fs);
01203 struct gtk_widarg_s *ga = (struct gtk_widarg_s *)get_gobj_field(fs);
01204 struct gtk_widwhere_s *gw = (struct gtk_widwhere_s *)get_gobj_field(fs);
01205 if (DUI_FIELD_IS_TYPE (fs, DUI_FIELD_WIDGET)) {
01206 tbl->widget = w; return;
01207 }
01208 if (DUI_FIELD_IS_TYPE (fs, DUI_FIELD_WID_DATA)) {
01209 gd->widget = w; return;
01210 }
01211 if (DUI_FIELD_IS_TYPE (fs, DUI_FIELD_WID_ARG)) {
01212 ga->widget = w; return;
01213 }
01214 if (DUI_FIELD_IS_TYPE (fs, DUI_FIELD_WID_WHERE)) {
01215 gw->widget = w;
01216 resolve_where (fs);
01217 return;
01218 }
01219 }
01220
01221
01222
01223 void
01224 dui_field_resolve_widget (DuiField *fld, gpointer ud)
01225 {
01226 GtkWidget *w;
01227 const char * widgetname;
01228 DuiWindow *win = ud;
01229
01230 if (!DUI_FIELD_IS_TYPE (fld, DUI_FIELD_WIDGET) &&
01231 !DUI_FIELD_IS_TYPE (fld, DUI_FIELD_WID_DATA) &&
01232 !DUI_FIELD_IS_TYPE (fld, DUI_FIELD_WID_ARG) &&
01233 !DUI_FIELD_IS_TYPE (fld, DUI_FIELD_WID_WHERE) ) return;
01234
01235 widgetname = fld->fieldname;
01236 if (!widgetname) return;
01237 if (0 == widgetname[0]) return;
01238
01239 w = dui_window_get_widget (win, widgetname);
01240 PINFO ("%s:\"%s\" is at %p", fld->type,widgetname, w);
01241 resolve_widget (fld, w);
01242 add_watcher (fld, w);
01243 add_sorter (fld, w);
01244 }
01245
01248