1 /* vartable_nbook.c */
2 /*
3  * ggobi
4  * Copyright (C) AT&T, Duncan Temple Lang, Dianne Cook 1999-2005
5  *
6  * ggobi is free software; you may use, redistribute, and/or modify it
7  * under the terms of the Eclipse Public License, which is distributed
8  * with the source code and displayed on the ggobi web site,
9  * www.ggobi.org.  For more information, contact the authors:
10  *
11  *   Deborah F. Swayne   dfs@research.att.com
12  *   Di Cook             dicook@iastate.edu
13  *   Duncan Temple Lang  duncan@wald.ucdavis.edu
14  *   Andreas Buja        andreas.buja@wharton.upenn.edu
15 */
16 
17 /* interface code for the variable statistics table: notebook only */
18 
19 #include <string.h>
20 #include <stdlib.h>
21 
22 #include <gtk/gtk.h>
23 #include "vars.h"
24 #include "externs.h"
25 
26 #include "vartable.h"
27 
28 #include <string.h> /* for strcmp() */
29 
30 
31 extern GtkWidget * vartable_buttonbox_build (ggobid *gg);
32 static void vartable_subwindow_init (GGobiData *d, ggobid *gg);
33 
34 /*-------------------------------------------------------------------------*/
35 /*            Listen for display_selected events                           */
36 /*-------------------------------------------------------------------------*/
37 
38 /* Update variable selection panel */
39 void
vartable_show_page_cb(ggobid * gg,displayd * display)40 vartable_show_page_cb (ggobid *gg, displayd *display) {
41   vartable_show_page(display->d, gg);
42 }
43 
44 /*-------------------------------------------------------------------------*/
45 
close_wmgr_cb(GtkWidget * cl,GdkEventButton * event,ggobid * gg)46 static void close_wmgr_cb (GtkWidget *cl, GdkEventButton *event, ggobid *gg)
47 {
48   gtk_widget_hide (gg->vartable_ui.window);
49 }
destroyit(ggobid * gg)50 static void destroyit (ggobid *gg)
51 {
52   gtk_widget_destroy (gg->vartable_ui.window);
53   gg->vartable_ui.window = NULL;
54 }
55 
56 static void
vartable_notebook_adddata_cb(ggobid * gg,GGobiData * d,void * notebook)57 vartable_notebook_adddata_cb (ggobid *gg, GGobiData *d, void *notebook)
58 {
59   vartable_subwindow_init (d, gg);
60   gtk_notebook_set_show_tabs (GTK_NOTEBOOK (GTK_WIDGET(notebook)),
61     g_slist_length (gg->d) > 1);
62 }
CHECK_EVENT_SIGNATURE(vartable_notebook_adddata_cb,datad_added_f)63 CHECK_EVENT_SIGNATURE(vartable_notebook_adddata_cb, datad_added_f)
64 
65 vartyped
66 tree_view_get_type (GGobiData *d, GtkWidget *tree_view)
67 {
68   vartyped vtype = all_vartypes;
69   if (d->vartable_tree_view[real] != NULL) {
70     if (tree_view == d->vartable_tree_view[real])
71       vtype = real;
72   } else if (d->vartable_tree_view[categorical] != NULL) {
73     if (tree_view == d->vartable_tree_view[categorical])
74       vtype = categorical;
75   } else if (d->vartable_tree_view[integer] != NULL) {
76     if (tree_view == d->vartable_tree_view[integer])
77       vtype = integer;
78   } else if (d->vartable_tree_view[counter] != NULL) {
79     if (tree_view == d->vartable_tree_view[counter])
80       vtype = counter;
81   } else if (d->vartable_tree_view[uniform] != NULL) {
82     if (tree_view == d->vartable_tree_view[uniform])
83       vtype = uniform;
84   }
85 
86   return vtype;
87 }
88 
89 /*
90  * Clear all selected rows from notebook pages when they're
91  * de-selected.  This callback applies to swapping pages for
92  * variable types within a datad.
93 */
94 void
vartable_switch_page_cb(GtkNotebook * notebook,GtkNotebookPage * page,gint page_num,ggobid * gg)95 vartable_switch_page_cb (GtkNotebook *notebook, GtkNotebookPage *page,
96   gint page_num, ggobid *gg)
97 {
98   gint prev_page = gtk_notebook_get_current_page (notebook);
99   GtkWidget *swin, *tree_view;
100   GList *children;
101 
102   if (prev_page > -1) {
103     GtkTreeSelection *tree_sel;
104     swin = gtk_notebook_get_nth_page (notebook, prev_page);
105     children = gtk_container_get_children (GTK_CONTAINER (swin));
106     tree_view = g_list_nth_data (children, 0);
107     tree_sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view));
108     gtk_tree_selection_unselect_all(tree_sel);
109   }
110 
111   // Figure out the page type from page_num -- doesn't do anything
112   // yet.  dfs
113   if (page_num > -1) {
114     vartyped vtype;
115     GGobiData *d = datad_get_from_notebook (gg->vartable_ui.notebook, gg);
116     swin = gtk_notebook_get_nth_page (notebook, page_num);
117     children = gtk_container_get_children (GTK_CONTAINER (swin));
118     tree_view = g_list_nth_data (children, 0);
119     vtype = tree_view_get_type(d, tree_view);
120     //vartable_buttons_update(vtype, gg);
121     // g_printerr ("vtype %d\n", vtype);
122   }
123 
124 
125 }
126 
127 GtkTreeModel *
vartable_tree_model_get(GGobiData * d)128 vartable_tree_model_get (GGobiData *d)
129 {
130   return(d->vartable_tree_model);
131 }
132 
133 GtkWidget *
vartable_tree_view_get(ggobid * gg)134 vartable_tree_view_get (ggobid *gg) {
135   GtkNotebook *nb, *subnb;
136   gint indx, subindx;
137   GtkWidget *swin;
138   GList *children;
139 /*
140  * Each page of vartable_ui.notebook has one child, which is
141  * another notebook.
142  * That notebook has two children, two scrolled windows, and
143  * each scrolled window has one child, a tree_view
144 */
145 /*
146   vartable_ui.notebook
147     page 0: datad 0
148       nbook
149         page 0: swin -> real
150         page 1: swin -> categorical
151     page n: datad n
152       nbook
153         page 0: swin -> real
154         page 1: swin -> categorical
155 */
156 
157   nb = GTK_NOTEBOOK (gg->vartable_ui.notebook);
158   indx = gtk_notebook_get_current_page (nb);
159   /*-- get the current page of the vartable notebook --*/
160   subnb = (GtkNotebook *) gtk_notebook_get_nth_page (nb, indx);
161   subindx = gtk_notebook_get_current_page (subnb);
162   /*-- get the current page of the variable type notebook --*/
163   swin = gtk_notebook_get_nth_page (subnb, subindx);
164   children = gtk_container_get_children (GTK_CONTAINER (swin));
165 
166   return ((GtkWidget *) g_list_nth_data (children, 0));
167 /*
168   swin = gtk_notebook_get_nth_page (nb, indx);
169   GList *swin_children = gtk_container_get_children (GTK_CONTAINER (swin));
170 */
171 }
172 
173 void
vartable_show_page(GGobiData * d,ggobid * gg)174 vartable_show_page (GGobiData *d, ggobid *gg)
175 {
176   GtkNotebook *nb;
177   gint page, page_new;
178   GList *l, *children;
179   GtkWidget *child, *tab_label;
180 
181   if (gg == NULL || gg->vartable_ui.notebook == NULL)
182     return;
183 
184 
185   nb = GTK_NOTEBOOK (gg->vartable_ui.notebook);
186   page = gtk_notebook_get_current_page (nb);
187 
188   if (page < 0)
189     return;
190 
191   page_new = 0;
192   children = gtk_container_get_children (GTK_CONTAINER (gg->vartable_ui.notebook));
193   for (l = children; l; l = l->next) {
194     child = l->data;
195     tab_label = (GtkWidget *) gtk_notebook_get_tab_label (nb, child);
196     if (tab_label && GTK_IS_LABEL (tab_label)) {
197       if (strcmp (GTK_LABEL (tab_label)->label, d->name) == 0) {
198         if (page != page_new) {
199           gtk_notebook_set_current_page (nb, page_new);
200           break;
201         }
202       }
203     }
204     page_new++;
205   }
206 }
207 
208 gint
vartable_varno_from_path(GtkTreeModel * model,GtkTreePath * path)209 vartable_varno_from_path(GtkTreeModel *model, GtkTreePath *path)
210 {
211   GtkTreeModel *unsorted_model, *root_model;
212   GtkTreePath *unsorted_path, *root_path;
213   gint varno;
214 
215   unsorted_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(model));
216   g_object_get(G_OBJECT(unsorted_model), "child-model", &root_model, NULL);
217 
218   unsorted_path = gtk_tree_model_sort_convert_path_to_child_path(
219     GTK_TREE_MODEL_SORT(model), path);
220   root_path = gtk_tree_model_filter_convert_path_to_child_path(
221     GTK_TREE_MODEL_FILTER(unsorted_model), unsorted_path);
222 
223   varno = gtk_tree_path_get_indices(root_path)[0];
224 
225   gtk_tree_path_free(unsorted_path);
226   gtk_tree_path_free(root_path);
227 
228   return(varno);
229 }
230 gboolean
vartable_iter_from_varno(gint var,GGobiData * d,GtkTreeModel ** model,GtkTreeIter * iter)231 vartable_iter_from_varno(gint var, GGobiData *d, GtkTreeModel **model, GtkTreeIter *iter)
232 {
233   GtkTreeModel *loc_model;
234   GtkTreePath *path;
235   gboolean valid;
236 
237   loc_model = vartable_tree_model_get(d);
238   if (!loc_model)
239 	  return(FALSE);
240   path = gtk_tree_path_new_from_indices(var, -1);
241   valid = gtk_tree_model_get_iter(loc_model, iter, path);
242   gtk_tree_path_free(path);
243 
244   if (model)
245     *model = loc_model;
246 
247   return(valid);
248 }
249 
250 /* GtkTreeSelection only tells us when the selection has changed,
251 	so we have to reset the selected status of the vartable */
252 void
selection_changed_cb(GtkTreeSelection * tree_sel,ggobid * gg)253 selection_changed_cb (GtkTreeSelection *tree_sel, ggobid *gg)
254 {
255   gint j;
256   GGobiData *d = datad_get_from_notebook (gg->vartable_ui.notebook, gg);
257   vartabled *vt;
258   GList *rows, *l;
259   GtkTreeModel *model;
260 
261   for (j = 0 ; j < d->ncols ; j++) { /* clear selection */
262     vt = vartable_element_get (j, d);
263 	vt->selected = false;
264   }
265 
266   rows = gtk_tree_selection_get_selected_rows(tree_sel, &model);
267   for (l = rows; l; l = l->next) {
268     gint varno;
269     GtkTreePath *path = (GtkTreePath*)l->data;
270     varno = vartable_varno_from_path(model, path);
271     gtk_tree_path_free(path);
272 
273     vt = vartable_element_get (varno, d);
274     vt->selected = true;
275   }
276   g_list_free(rows);
277 }
278 
279 /** 'row' here corresponds to 'variable' (top-level rows) */
280 void
vartable_row_append(gint jvar,GGobiData * d)281 vartable_row_append (gint jvar, GGobiData *d)
282 {
283   gint k;
284   vartabled *vt = vartable_element_get (jvar, d);
285   GtkTreeModel *model = vartable_tree_model_get(d);
286   GtkTreeIter iter;
287   GtkTreeIter child;
288   if (!model)
289 	  return;
290   gtk_tree_store_append(GTK_TREE_STORE(model), &iter, NULL);
291   for (k=0; k<vt->nlevels; k++)
292 	  gtk_tree_store_append(GTK_TREE_STORE(model), &child, &iter);
293 }
294 
295 static gboolean
real_filter_func(GtkTreeModel * model,GtkTreeIter * iter,GGobiData * d)296 real_filter_func (GtkTreeModel *model, GtkTreeIter *iter, GGobiData *d)
297 {
298   GtkTreePath *path = gtk_tree_model_get_path(model, iter);
299   if (gtk_tree_path_get_depth(path) > 1)
300     return(false);
301   vartabled *vt = vartable_element_get (gtk_tree_path_get_indices(path)[0], d);
302   gtk_tree_path_free(path);
303   return(vt->vartype != categorical);
304 }
305 static gboolean
cat_filter_func(GtkTreeModel * model,GtkTreeIter * iter,GGobiData * d)306 cat_filter_func (GtkTreeModel *model, GtkTreeIter *iter, GGobiData *d)
307 {
308   GtkTreePath *path = gtk_tree_model_get_path(model, iter);
309   if (gtk_tree_path_get_depth(path) > 1)
310     return(true);
311   vartabled *vt = vartable_element_get (gtk_tree_path_get_indices(path)[0], d);
312   gtk_tree_path_free(path);
313   return(vt->vartype == categorical);
314 }
315 
316 static void
vartable_subwindow_init(GGobiData * d,ggobid * gg)317 vartable_subwindow_init (GGobiData *d, ggobid *gg)
318 {
319   gint j;
320   GtkWidget *sw, *wlbl;
321   gchar *lbl;
322   static gchar *titles[] = {
323     "Variable",
324     "Transform",
325     "Min (user)", "Max (user)",
326     "Min (data)", "Max (data)",
327     "Mean", "Median",
328 	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
329     "N NAs"};
330   static gchar *titles_cat[] = {
331     "Variable",
332 	NULL, NULL, NULL, NULL, NULL, NULL, NULL,
333     "N Levels",
334     "Level",
335     "Value",
336     "Count",
337     "Min (user)", "Max (user)",
338     "Min (data)", "Max (data)",
339     "N NAs",
340   };
341   GtkWidget *nbook = gtk_notebook_new ();
342   GtkTreeStore *model;
343   GtkTreeModel *sort_model, *filter_model;
344 
345   g_signal_connect (G_OBJECT (nbook), "switch-page",
346     G_CALLBACK (vartable_switch_page_cb), gg);
347 
348   lbl = ggobi_data_get_name (d);
349   /*
350    * We're showing all datasets for now, whether they have variables
351    * or not.  That could change.
352   */
353   g_object_set_data(G_OBJECT(nbook), "datad", d);  /*setdata*/
354   gtk_notebook_append_page (GTK_NOTEBOOK (gg->vartable_ui.notebook),
355     nbook, gtk_label_new (lbl));
356   g_free (lbl);
357 
358 
359   /* Pack each tree_view into a scrolled window */
360   sw = gtk_scrolled_window_new (NULL, NULL);
361   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_NONE);
362 
363 /*
364  * Page for real, counter and integer variables
365 */
366   model = gtk_tree_store_new(NCOLS_VT, G_TYPE_STRING, G_TYPE_STRING,
367     G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_DOUBLE,
368     G_TYPE_DOUBLE, G_TYPE_INT, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT,
369     G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT);
370 
371   d->vartable_tree_model = GTK_TREE_MODEL(model);
372 
373   /*-- populate the tables BEFORE attaching filters --*/
374   for (j = 0 ; j < d->ncols ; j++) {
375     vartable_row_append(j, d);
376     vartable_cells_set_by_var(j, d);
377   }
378 
379   filter_model = gtk_tree_model_filter_new(GTK_TREE_MODEL(model), NULL);
380   gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(filter_model),
381   	(GtkTreeModelFilterVisibleFunc)real_filter_func, d, NULL);
382   sort_model = gtk_tree_model_sort_new_with_model(filter_model);
383   d->vartable_tree_view[real] = gtk_tree_view_new_with_model(sort_model);
384   populate_tree_view(d->vartable_tree_view[real], titles,
385     G_N_ELEMENTS(titles), true,
386     GTK_SELECTION_MULTIPLE, G_CALLBACK(selection_changed_cb), gg);
387   gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(d->vartable_tree_view[real]), true);
388 
389   /*-- right justify all the numerical columns --*/
390   /*-- set the column width automatically --*/
391 
392   gtk_container_add (GTK_CONTAINER (sw), d->vartable_tree_view[real]);
393   wlbl = gtk_label_new_with_mnemonic("_Real");
394 /*
395 This works for showing tooltips in the tabs, but unfortunately it
396 interferes with the normal operation of the widget -- I can't switch
397 pages any more!
398   GtkWidget *ebox;
399   ebox = gtk_event_box_new ();
400   gtk_container_add (GTK_CONTAINER (ebox), wlbl);
401   gtk_widget_show(wlbl);
402   gtk_tooltips_set_tip (GTK_TOOLTIPS (gg->tips), ebox,
403     "Table of statistics for real, integer and counter variables", NULL);
404   gtk_notebook_append_page (GTK_NOTEBOOK (nbook), scrolled_window, ebox);
405 */
406   gtk_notebook_append_page (GTK_NOTEBOOK (nbook), sw, wlbl);
407 
408   sw = gtk_scrolled_window_new (NULL, NULL);
409   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_NONE);
410 
411 /*
412  * Page for categorical variables
413 */
414 
415   filter_model = gtk_tree_model_filter_new(GTK_TREE_MODEL(model), NULL);
416   gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(filter_model),
417   	(GtkTreeModelFilterVisibleFunc)cat_filter_func, d, NULL);
418   sort_model = gtk_tree_model_sort_new_with_model(filter_model);
419   d->vartable_tree_view[categorical] = gtk_tree_view_new_with_model(sort_model);
420   populate_tree_view(d->vartable_tree_view[categorical], titles_cat,
421   	G_N_ELEMENTS(titles_cat), true, GTK_SELECTION_MULTIPLE, G_CALLBACK(selection_changed_cb), gg);
422   gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(d->vartable_tree_view[categorical]), true);
423 
424   /*-- right justify all the numerical columns --*/
425 
426   gtk_container_add (GTK_CONTAINER (sw),
427     d->vartable_tree_view[categorical]);
428   wlbl = gtk_label_new_with_mnemonic("_Categorical");
429 /*
430   ebox = gtk_event_box_new ();
431   gtk_container_add (GTK_CONTAINER (ebox), wlbl);
432   gtk_widget_show(wlbl);
433   gtk_tooltips_set_tip (GTK_TOOLTIPS (gg->tips), ebox,
434     "Table of statistics for categorical variables", NULL);
435   gtk_notebook_append_page (GTK_NOTEBOOK (nbook), scrolled_window, ebox);
436 */
437   gtk_notebook_append_page (GTK_NOTEBOOK (nbook), sw, wlbl);
438 
439   /*-- 3 = COLUMN_INSET --*/
440 
441   gtk_widget_show_all (nbook);
442 
443 }
444 
445 void
vartable_open(ggobid * gg)446 vartable_open (ggobid *gg)
447 {
448   GtkWidget *vbox, *hbox;
449   GSList *l;
450   GGobiData *d;
451 
452   /*-- if used before we have data, bail out --*/
453   if (gg->d == NULL || g_slist_length (gg->d) == 0)
454 	  return;
455 
456   /*-- if new datad's have been added, the user has to reopen the window --*/
457   if (gg->vartable_ui.window != NULL) {
458     destroyit (gg);
459   }
460 
461   gg->vartable_ui.window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
462   gtk_window_set_default_size(GTK_WINDOW(gg->vartable_ui.window), 750, 300);
463   g_signal_connect (G_OBJECT (gg->vartable_ui.window),
464     "delete_event", G_CALLBACK (close_wmgr_cb), gg);
465   gtk_window_set_title (GTK_WINDOW (gg->vartable_ui.window),
466     "Variable Manipulation");
467 
468   vbox = gtk_vbox_new (false, 5);
469   gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
470   gtk_container_add (GTK_CONTAINER (gg->vartable_ui.window), vbox);
471   gtk_widget_show (vbox);
472 
473   /* Create a notebook, set the position of the tabs */
474   gg->vartable_ui.notebook = gtk_notebook_new ();
475   gtk_notebook_set_tab_pos (GTK_NOTEBOOK (gg->vartable_ui.notebook),
476     GTK_POS_TOP);
477   gtk_notebook_set_show_tabs (GTK_NOTEBOOK (gg->vartable_ui.notebook),
478     g_slist_length (gg->d) > 1);
479   gtk_box_pack_start (GTK_BOX (vbox), gg->vartable_ui.notebook,
480     true, true, 2);
481   /* Needed?: a switch-page callback so that we can keep track of
482    * the vartyped of the current page, and show or hide buttons
483    * as appropriate -- dfs */
484 
485   /* Connecting to display_selected event */
486   g_signal_connect (G_OBJECT (gg), "display_selected",
487     G_CALLBACK (vartable_show_page_cb), NULL);
488   /* */
489 
490   for (l = gg->d; l; l = l->next) {
491     d = (GGobiData *) l->data;
492     vartable_subwindow_init (d, gg);
493   }
494 
495   /*-- listen for datad_added events --*/
496   g_signal_connect (G_OBJECT (gg),
497     "datad_added", G_CALLBACK (vartable_notebook_adddata_cb),
498      GTK_OBJECT (gg->vartable_ui.notebook));
499 
500   hbox = vartable_buttonbox_build (gg);
501   gtk_box_pack_start (GTK_BOX (vbox), hbox, false, false, 1);
502 
503   gtk_widget_show_all (gg->vartable_ui.window);
504 
505   /*-- set it to the page corresponding to the current display --*/
506   d = (gg->current_display ? gg->current_display->d : (GGobiData *)gg->d->data);
507   vartable_show_page (d, gg);
508 }
509 
510 /*-------------------------------------------------------------------------*/
511 /*                 set values in the table                                 */
512 /*-------------------------------------------------------------------------*/
513 
514 /*-- sets the name of the un-transformed variable --*/
515 void
vartable_collab_set_by_var(gint j,GGobiData * d)516 vartable_collab_set_by_var (gint j, GGobiData *d)
517 {
518   vartabled *vt = vartable_element_get (j, d);
519   gint k;
520   GtkTreeModel *model;
521   GtkTreeIter iter;
522   GtkTreeIter child;
523   gchar *fmtname;
524 
525   if (!vartable_iter_from_varno(j, d, &model, &iter))
526 	  return;
527 
528   if (vt) {
529     switch (vt->vartype) {
530       case categorical:
531 
532         gtk_tree_store_set(GTK_TREE_STORE(model), &iter,
533           VT_NLEVELS, vt->nlevels, -1);
534         gtk_tree_model_iter_children(model, &child, &iter);
535         /*-- set the level fields --*/
536      	  for (k=0; k<vt->nlevels; k++) {
537           fmtname = g_markup_printf_escaped("%s", vt->level_names[k]);
538           gtk_tree_store_set(GTK_TREE_STORE(model), &child, VT_LEVEL_NAME,
539             fmtname, VT_LEVEL_VALUE, vt->level_values[k],
540             VT_LEVEL_COUNT, vt->level_counts[k], -1);
541           g_free(fmtname);
542           gtk_tree_model_iter_next(model, &child);
543         }
544 	   // no more break
545       case integer:
546       case counter:
547       case uniform:
548       case real:
549         gtk_tree_store_set(GTK_TREE_STORE(model), &iter,
550           VT_VARNAME, vt->collab, -1);
551       break;
552       case all_vartypes:
553         g_printerr ("(vartable_collab_set_by_var) illegal variable type %d\n", all_vartypes);
554       break;
555     }
556   }
557 }
558 
559 /*-- sets the name of the transformed variable --*/
560 void
vartable_collab_tform_set_by_var(gint j,GGobiData * d)561 vartable_collab_tform_set_by_var (gint j, GGobiData *d)
562 {
563   vartabled *vt;
564   GtkTreeModel *model;
565   GtkTreeIter iter;
566 
567   if (!vartable_iter_from_varno(j, d, &model, &iter))
568 	  return;
569 
570   vt = vartable_element_get (j, d);
571   if (vt->tform0 == NO_TFORM0 &&
572 	vt->tform1 == NO_TFORM1 &&
573 	vt->tform2 == NO_TFORM2)
574   {
575     gtk_tree_store_set(GTK_TREE_STORE(model), &iter,
576 			VT_TFORM, "", -1);
577   } else {
578     gtk_tree_store_set(GTK_TREE_STORE(model), &iter,
579 			VT_TFORM, vt->collab_tform, -1);
580   }
581 }
582 
583 /*-- sets the limits for a variable --*/
584 void
vartable_limits_set_by_var(gint j,GGobiData * d)585 vartable_limits_set_by_var (gint j, GGobiData *d)
586 {
587   vartabled *vt = vartable_element_get (j, d);
588   GtkTreeModel *model;
589   GtkTreeIter iter;
590 
591   if (!vartable_iter_from_varno(j, d, &model, &iter))
592 	  return;
593 
594   if (vt) {
595 
596     switch (vt->vartype) {
597       case integer:
598       case counter:
599       case uniform:
600       case real:
601 	gtk_tree_store_set(GTK_TREE_STORE(model), &iter,
602 	 	VT_REAL_DATA_MIN, vt->lim_display.min,
603 		VT_REAL_DATA_MAX, vt->lim_display.max, -1);
604 	if (vt->lim_specified_p) {
605 		gtk_tree_store_set(GTK_TREE_STORE(model), &iter,
606 	  	  VT_REAL_USER_MIN, vt->lim_specified_tform.min,
607 		  VT_REAL_USER_MAX, vt->lim_specified_tform.max, -1);
608         }
609       break;
610 
611       case categorical:
612 	gtk_tree_store_set(GTK_TREE_STORE(model), &iter,
613 		VT_CAT_DATA_MIN, (gint)vt->lim_display.min,
614 		VT_CAT_DATA_MAX, (gint)vt->lim_display.max, -1);
615         if (vt->lim_specified_p) {
616 		gtk_tree_store_set(GTK_TREE_STORE(model), &iter,
617 	  	  VT_CAT_USER_MIN, (gint)vt->lim_specified_tform.min,
618 		  VT_CAT_USER_MAX, (gint)vt->lim_specified_tform.max, -1);
619         }
620       break;
621       case all_vartypes:
622         g_printerr ("(vartable_limits_set_by_var) %d: illegal variable type %d\n",
623           j, all_vartypes);
624       break;
625     }
626   }
627 }
628 void
vartable_limits_set(GGobiData * d)629 vartable_limits_set (GGobiData *d)
630 {
631   gint j;
632   if (d->vartable_tree_model != NULL)
633     for (j=0; j<d->ncols; j++)
634       vartable_limits_set_by_var (j, d);
635 }
636 
637 /*-- sets the mean, median, and number of missings for a variable --*/
638 void
vartable_stats_set_by_var(gint j,GGobiData * d)639 vartable_stats_set_by_var (gint j, GGobiData *d) {
640   vartabled *vt = vartable_element_get (j, d);
641   vartyped type;
642   GtkTreeModel *model;
643   GtkTreeIter iter;
644 
645   if (!vartable_iter_from_varno(j, d, &model, &iter))
646 	  return;
647 
648   if (vt) {
649     switch (vt->vartype) {
650       case integer:
651       case counter:
652       case uniform:
653       case real:
654         type = real;
655         /*-- for counter variables, don't display the mean --*/
656 	if (vt->vartype != counter)
657 	  gtk_tree_store_set(GTK_TREE_STORE(model), &iter,
658 		VT_MEAN, vt->mean, VT_MEDIAN, vt->median, -1);
659       //break;
660       case categorical:
661         gtk_tree_store_set(GTK_TREE_STORE(model), &iter,
662 			VT_NMISSING, ggobi_data_get_col_n_missing(d, j), -1);
663       break;
664       case all_vartypes:
665         g_printerr ("(vartable_stats_set_by_var) %d: illegal variable type %d\n",
666           j, vt->vartype);
667       break;
668     }
669   }
670 }
671 
672 void
vartable_stats_set(GGobiData * d)673 vartable_stats_set (GGobiData *d) {
674   gint j;
675 
676   if (d->vartable_tree_model != NULL)
677     for (j=0; j<d->ncols; j++)
678       vartable_stats_set_by_var (j, d);
679 }
680 
681 /*
682  * in one routine, populate every cell in a row -- all these
683  * functions call gtk_tree_view_set_text.
684 */
685 void
vartable_cells_set_by_var(gint j,GGobiData * d)686 vartable_cells_set_by_var (gint j, GGobiData *d)
687 {
688   vartable_stats_set_by_var (j, d);
689   vartable_limits_set_by_var (j, d);
690   vartable_collab_set_by_var (j, d);
691   vartable_collab_tform_set_by_var (j, d);
692 }
693