/[pspp]/psppire/src/var_sheet.c
ViewVC logotype

Diff of /psppire/src/var_sheet.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.8 by jmd, Sun Oct 30 10:12:27 2005 UTC revision 1.9 by jmd, Wed Nov 2 09:44:02 2005 UTC
# Line 1  Line 1 
1  /*  /*
2      PSPPIRE --- A Graphical User Interface for PSPP      PSPPIRE --- A Graphical User Interface for PSPP
3      Copyright (C) 2004  Free Software Foundation      Copyright (C) 2004,2005  Free Software Foundation
4      Written by John Darrington      Written by John Darrington
5    
6      This program is free software; you can redistribute it and/or modify      This program is free software; you can redistribute it and/or modify
# Line 15  Line 15 
15    
16      You should have received a copy of the GNU General Public License      You should have received a copy of the GNU General Public License
17      along with this program; if not, write to the Free Software      along with this program; if not, write to the Free Software
18      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  */      02110-1301, USA. */
20    
21    
22    /* This module creates the Variable Sheet used for inputing the
23       variables in the  dictonary */
24    
25    
26    
27  #ifdef HAVE_CONFIG_H  #ifdef HAVE_CONFIG_H
28  #  include <config.h>  #  include <config.h>
29  #endif  #endif
30    
31    #include <glade/glade.h>
32    
33  #include <gtk/gtk.h>  #include <gtk/gtk.h>
34  #include "gtksheet.h"  #include "gtksheet.h"
35    
# Line 29  Line 37 
37    
38  #include "pspp-dict.h"  #include "pspp-dict.h"
39    
40    #include "var_type_dialog.h"
41    
42  #define _(A) A  #define _(A) A
43  #define N_(A) A  #define N_(A) A
44    
45    
46  static struct G_Object *pspp_dictionary;  /* The dictionary associated with this var sheet */
47  extern GtkWindow *window1;  static PSPP_Dict *pspp_dictionary;
   
48    
 /* The next new row */  
 static gint next_new_row=0;  
49    
50    static gint last_populated_row = -1;
51    
52  static gint var_sheet_update_callback(GObject *obj,  static gint var_sheet_update_callback(GObject *obj,
53                                        gint var_idx, gpointer data);                                        gint var_idx, gpointer data);
# Line 47  static gint var_sheet_update_callback(GO Line 55  static gint var_sheet_update_callback(GO
55  static gint update_variable(GtkSheet *sheet, gint row, gint col);  static gint update_variable(GtkSheet *sheet, gint row, gint col);
56    
57    
58    static struct var_type_dialog *var_type_dialog;
59    
60  void var_sheet_row_open(GtkSheet *sheet,gint row);  extern GladeXML *xml;
 void var_sheet_row_close(GtkSheet *sheet,gint row);  
   
   
   
 static  GdkColor colour_disabled;  
 static  GdkColor colour_enabled;  
   
 typedef void (*psppire_construct_entry_func) (GtkSheet *sheet);  
   
   
 void psppire_construct_entry(GtkSheet *sheet);  
 void psppire_name_entry(GtkSheet *sheet);  
61    
62    
63  struct column_parameters  struct column_parameters
64  {  {
65    gchar label[20];      gchar label[20];  
66    psppire_construct_entry_func cef;    gint width ;
67  };  };
68    
69  const struct column_parameters col[] = {  const struct column_parameters col[] = {
70    N_("Name"), 0,    N_("Name"), 80,
71    N_("Type"), psppire_construct_entry,    N_("Type"), 100,
72    N_("Width"),   0,    N_("Width"),   57,
73    N_("Decimals"),0,    N_("Decimals"),91,
74    N_("Label"),   0,    N_("Label"),   95,
75    N_("Values"),  0,    N_("Values"),  103,
76    N_("Missing"), 0,    N_("Missing"), 95,
77    N_("Columns"), 0,    N_("Columns"), 80,
78    N_("Align"),   0,    N_("Align"),   69,
79    N_("Measure"), 0    N_("Measure"), 99
80  };  };
81    
82  enum {COL_NAME,  enum {COL_NAME,
# Line 96  enum {COL_NAME, Line 93  enum {COL_NAME,
93    
94    
95    
96  static gint exit_column = -1;  /* Callback for when the var type dialog is closed using the OK button*/
97    static gint
98    set_var_type(GtkWidget *w, gpointer data)
 /* cell_enter and cell_leave are a pair of mutually cooperating functions  
    which are used to determine if a sheet's column has changed */  
 static gboolean  
 var_sheet_cell_enter (GtkSheet * sheet, gint row, gint column)  
 {  
   
   if ( exit_column != column )  
     {  
       if ( col[column].cef )  
         col[column].cef(sheet);  
       else  
         gtk_sheet_change_entry(sheet,GTK_TYPE_ENTRY);  
   
     }  
   
   return TRUE;  
 }  
   
 static gboolean  
 var_sheet_cell_leave (GtkSheet * sheet, gint row, gint column)  
 {  
   
   exit_column = column;  
   
   return TRUE;  
 }  
   
   
 void  
 psppire_construct_entry(GtkSheet *sheet)  
99  {  {
100    GtkCombo *combo;    gint i;
101      struct fmt_spec spec;
102    gtk_sheet_change_entry (sheet, GTK_TYPE_COMBO);    gint width, decimals;
103      GtkSheet *sheet = data;
104      gint current_row, current_column;
105    
106    combo = GTK_COMBO(gtk_sheet_get_entry_widget(sheet));    /* Set the variable corresponding to the current row */
107        
108    GList *items = NULL;    gtk_sheet_get_active_cell (sheet, &current_row, &current_column);
   
   items = g_list_append (items, _("Numeric") );  
   items = g_list_append (items, _("Alpha") );  
   
   gtk_combo_set_popdown_strings (combo, items);  
   
   gtk_combo_set_value_in_list(combo,FALSE,FALSE);  
 }  
   
 void  
 psppire_name_entry(GtkSheet *sheet)  
 {  
   GtkEntry *entry;  
   gtk_sheet_change_entry (sheet, GTK_TYPE_ENTRY);  
   
   entry = GTK_ENTRY(gtk_sheet_get_entry_widget(sheet));  
 }  
109    
110      struct variable *var = pspp_dict_get_var(pspp_dictionary, current_row);
111    
112  void    g_assert(var_type_dialog);
113  var_sheet_row_open(GtkSheet *sheet, gint row)    g_assert(var);
 {  
   GtkSheetRange range;  
   const gint columns =  gtk_sheet_get_columns_count(sheet);  
114    
115    if ( row != next_new_row )    width = atoi(gtk_entry_get_text
116      return ;                 (GTK_ENTRY(var_type_dialog->entry_width)));
117    
118      decimals =atoi(gtk_entry_get_text
119                     (GTK_ENTRY(var_type_dialog->entry_decimals)));
120    
   range.row0 = row ; range.rowi = row ;  
   range.col0 = 0 ; range.coli = columns - 1 ;  
121    
122    gtk_sheet_range_set_editable (sheet, &range, TRUE);    var->width = width;
123    
124    gtk_sheet_range_set_background (sheet,&range,&colour_enabled);    spec.w = width;
125      spec.d = decimals;
126      
127    /* Just the entry point of the next new row */    for(i = 0; i < num_BUTTONS; ++i )
128    next_new_row++;      {
129    range.row0 = range.rowi = next_new_row;        if ( gtk_toggle_button_get_active
130    range.col0 = range.coli = 0;             (GTK_TOGGLE_BUTTON(var_type_dialog->radioButton[i])) )
131    gtk_sheet_range_set_editable (sheet, &range, TRUE);          {
132    gtk_sheet_range_set_background (sheet,&range,&colour_enabled);            switch (i)
133                {
134                case BUTTON_STRING:
135                  spec.type = FMT_A;
136                  break;
137                case BUTTON_NUMERIC:
138                  spec.type = FMT_F;
139                  break;
140                default:
141                  break;
142                }
143              break;
144            }
145        }
146      
147      var->write = var->print = spec;
148    
149      
150      pspp_dict_var_changed(pspp_dictionary, current_row);
151      
152    
153      return FALSE;
154  }  }
155    
156    
157  /* Set the next new row to be row */  gchar *
158  void  auto_generate_var_name(PSPP_Dict *dict)
 var_sheet_set_next_row(GtkSheet *sheet, gint row)  
159  {  {
160    GtkSheetRange range;    gint d = 0;
161      gchar *name = g_strdup_printf("VAR%05d",d);
   
   /* The old entry point must be closed */  
   range.row0 = range.rowi = next_new_row;  
   range.col0 = range.coli = 0;  
   gtk_sheet_range_set_editable (sheet, &range, FALSE);  
   gtk_sheet_range_set_background (sheet,&range,&colour_disabled);  
   
   
   next_new_row = row;  
   
   /* Just the entry point must remain open */  
   range.row0 = range.rowi = row;  
   range.col0 = range.coli = 0;  
   gtk_sheet_range_set_editable (sheet, &range, TRUE);  
   gtk_sheet_range_set_background (sheet,&range,&colour_enabled);  
162    
163      while (pspp_dict_lookup_var(dict, name))
164        {
165          g_free(name);
166          name = g_strdup_printf("VAR%05d",++d);
167        }
168      return name;
169  }  }
170    
171  /* Makes a row non editable */  /* Callback whenever the cell on the var sheet is entered */
172  void  static gboolean
173  var_sheet_row_close(GtkSheet *sheet, gint row)  var_sheet_cell_set (GtkSheet * sheet, gint row, gint column)
174  {  {
175    GtkSheetRange range;    gint r;
176    const gint columns =  gtk_sheet_get_columns_count(sheet);    g_print("Set row %d\n",row);
   gint c;  
   
   range.row0 = row ; range.rowi = row ;  
   range.col0 = 0 ; range.coli = columns - 1 ;  
   
   gtk_sheet_range_set_editable (sheet, &range, FALSE);  
   
   gtk_sheet_range_set_background (sheet,&range,&colour_disabled);  
   
   for ( c = 0 ; c < columns ; ++c )  
     gtk_sheet_cell_clear(sheet, row, c);  
   
   /* If this was the last row, then now it'll be the next new one */  
   if ( row + 1 == next_new_row )  
       var_sheet_set_next_row(sheet,row);  
   
 }  
177    
178      g_print("%s:%d Last populated row: %d\n",__FILE__,__LINE__,last_populated_row);    
179    
180  /* Closes the entire sheet, ready for new input */    /* Fill out any rows above, which are empty */
181  void    for ( r = last_populated_row + 1 ; r < row ; ++r )
182  var_sheet_close_all(GtkSheet *sheet)      {
183  {        g_print("Autofilling row %d\n",r);
184    GtkSheetRange range;        gchar *name = auto_generate_var_name(pspp_dictionary);
185    const gint columns =  gtk_sheet_get_columns_count(sheet);        pspp_dict_set_name(pspp_dictionary, r, name);
186    const gint rows =  gtk_sheet_get_rows_count(sheet);        g_free(name);
187    gint c;      }
188      if ( row - 1 > last_populated_row)
189        last_populated_row = row - 1;
190      g_print("%s:%d Last populated row: %d\n",__FILE__,__LINE__,last_populated_row);    
191    
192    range.row0 = 0 ; range.rowi = rows - 1;    struct variable *var = pspp_dict_get_var(pspp_dictionary, row);      
193    range.col0 = 0 ; range.coli = columns - 1;    
194      /* Fill out any cells to the left which are empty */
195      if ( var == NULL && column != 0 )
196        {
197          g_print("Filling Left\n");
198          gchar *name = auto_generate_var_name(pspp_dictionary);
199          pspp_dict_set_name(pspp_dictionary, row, name);
200          g_free(name);
201          last_populated_row = row ;
202          var = pspp_dict_get_var(pspp_dictionary, row);      
203        }
204      g_print("%s:%d Last populated row: %d\n",__FILE__,__LINE__,last_populated_row);    
205    
206    gtk_sheet_range_set_editable (sheet, &range, FALSE);    if ( column == COL_TYPE )
207        {
208          /* Popup the Variable Type dialog box */
209    
210    gtk_sheet_range_set_background (sheet,&range,&colour_disabled);        if (!var_type_dialog )
211            {
212              var_type_dialog = var_type_dialog_create(xml);
213    
214              g_signal_connect(GTK_OBJECT(var_type_dialog->ok),
215                               "clicked",
216                               GTK_SIGNAL_FUNC(set_var_type), sheet);
217            }
218    
219    gtk_sheet_range_clear (sheet, NULL);        var_type_dialog_set_state(var_type_dialog, var);
220    
221    /* Set row 0 ready for input */        var_type_dialog_show(var_type_dialog);
222    var_sheet_set_next_row(sheet, 0);      }
223    
224      return FALSE;
225  }  }
226    
227    
228    
   
   
229  static GString *  static GString *
230  gint_to_gstring(gint x)  gint_to_gstring(gint x)
231  {  {
# Line 273  gint_to_gstring(gint x) Line 237  gint_to_gstring(gint x)
237  }  }
238    
239    
240    /* Populate ROW according to the variable VAR */
241  static void  static void
242  populate_row_from_var(GtkSheet *sheet, const struct variable *var,  populate_row_from_var(GtkSheet *sheet, const struct variable *var,
243                        gint var_idx)                        gint row)
244  {  {
245    gint c;    gint c;
246    if (!var)    if (!var)
247      return;      {
248          GtkSheetRange range;
249          range.row0 = range.rowi = row;
250          range.col0 = 0 ; range.coli = gtk_sheet_get_columns_count(sheet) - 1;
251          gtk_sheet_range_clear (sheet, &range);
252          return;
253        }
254    
255    for ( c = 0 ; c < n_COLS ; ++c )    for ( c = 0 ; c < n_COLS ; ++c )
256      {      {
257        switch (c)        switch (c)
258          {          {
259          case COL_NAME:          case COL_NAME:
260            gtk_sheet_set_cell_text (sheet, var_idx, c, var->name);            gtk_sheet_set_cell_text (sheet, row, c, var->name);
261              break;
262            case COL_TYPE:
263              {
264                const struct fmt_spec *write_spec = &var->write;
265                switch ( write_spec->type )
266                  {
267                  case FMT_F:
268                    gtk_sheet_set_cell_text(sheet, row, c, _("Numeric"));
269                    break;
270                  case FMT_COMMA:
271                    gtk_sheet_set_cell_text(sheet, row, c, _("Comma"));
272                    break;
273                  case FMT_DOT:
274                    gtk_sheet_set_cell_text(sheet, row, c, _("Dot"));
275                    break;
276                  case FMT_DOLLAR:
277                    gtk_sheet_set_cell_text(sheet, row, c, _("Dollar"));
278                    break;
279                  case FMT_A:
280                    gtk_sheet_set_cell_text(sheet, row, c, _("String"));
281                    break;
282                  default:
283                    g_print("Format is unknown\n");
284                    break;
285                  }
286              }
287            break;            break;
288          case COL_WIDTH:          case COL_WIDTH:
289            {            {
290            GString *s = gint_to_gstring(var->width);              GString *s = gint_to_gstring(var->width);
291            gtk_sheet_set_cell_text(sheet, var_idx, c, s->str);                  gtk_sheet_set_cell_text(sheet, row, c, s->str);      
292            g_string_free(s, TRUE);              g_string_free(s, TRUE);
293              }
294              break;
295            case COL_DECIMALS:
296              {
297                GString *s = gint_to_gstring(var->write.d);
298                gtk_sheet_set_cell_text(sheet, row, c, s->str);      
299                g_string_free(s, TRUE);
300            }            }
301            break;            break;
302          case COL_COLUMNS:          case COL_COLUMNS:
303            {            {
304            GString *s = gint_to_gstring(var->display_width);              GString *s = gint_to_gstring(var->display_width);
305            gtk_sheet_set_cell_text(sheet, var_idx, c, s->str);                  gtk_sheet_set_cell_text(sheet, row, c, s->str);      
306            g_string_free(s, TRUE);              g_string_free(s, TRUE);
307            }            }
308            break;            break;
309          }          }
# Line 314  repopulate_rows(GtkSheet *sheet, PSPP_Di Line 317  repopulate_rows(GtkSheet *sheet, PSPP_Di
317  {  {
318    gint r;    gint r;
319    
320      /*
321      gtk_sheet_freeze (sheet);
322      */
323    for ( r = from ; r <= to ; ++r )    for ( r = from ; r <= to ; ++r )
324      {      {
325          struct variable *var = pspp_dict_get_var(dict, r);      
326        if ( r < pspp_dict_get_var_cnt(dict) )        populate_row_from_var(sheet, var, r);
         {  
           struct variable *var = pspp_dict_get_var(dict, r);        
           populate_row_from_var(sheet, var, r);  
         }  
       else  
         {  
           var_sheet_row_close(sheet, r);  
         }  
327      }      }
328      /*
329      gtk_sheet_thaw (sheet);
330      */
331  }  }
332    
333    
# Line 341  remove_variable(GObject *obj, gint idx, Line 342  remove_variable(GObject *obj, gint idx,
342    repopulate_rows(sheet, dict, idx,    repopulate_rows(sheet, dict, idx,
343                    gtk_sheet_get_rows_count(sheet) - 1);                    gtk_sheet_get_rows_count(sheet) - 1);
344    
345      last_populated_row--;
346    
347    return FALSE;    return FALSE;
348  }  }
349    
350    
351    
352    /* Create the var sheet */
353  GtkWidget*  GtkWidget*
354  psppire_variable_sheet_create (gchar *widget_name,  psppire_variable_sheet_create (gchar *widget_name,
355                                 gchar *string1,                                 gchar *string1,
# Line 360  psppire_variable_sheet_create (gchar *wi Line 364  psppire_variable_sheet_create (gchar *wi
364    
365    sheet = gtk_sheet_new(rows,columns,"variable sheet");    sheet = gtk_sheet_new(rows,columns,"variable sheet");
366    
367      gtk_sheet_range_set_editable (GTK_SHEET(sheet), 0, TRUE);
368    
   g_assert(gdk_color_parse("dark slate gray",&colour_disabled));  
   g_assert(gdk_color_parse("white",&colour_enabled));  
     
   gdk_colormap_alloc_color(gdk_colormap_get_system(),  
                                    &colour_disabled,FALSE,TRUE);  
   
   gdk_colormap_alloc_color(gdk_colormap_get_system(),  
                                    &colour_enabled,FALSE,TRUE);  
369    
370    
371    g_signal_connect (GTK_OBJECT (sheet), "activate",    g_signal_connect (GTK_OBJECT (sheet), "activate",
372                      GTK_SIGNAL_FUNC (var_sheet_cell_enter),                      GTK_SIGNAL_FUNC (var_sheet_cell_set),
                     0);  
   
   g_signal_connect (GTK_OBJECT (sheet), "deactivate",  
                     GTK_SIGNAL_FUNC (var_sheet_cell_leave),  
373                      0);                      0);
374    
375    
# Line 384  psppire_variable_sheet_create (gchar *wi Line 377  psppire_variable_sheet_create (gchar *wi
377                      GTK_SIGNAL_FUNC (update_variable),                      GTK_SIGNAL_FUNC (update_variable),
378                      0);                      0);
379    
   for (i = 0 ; i < columns ; ++i )  
     gtk_sheet_column_button_add_label (GTK_SHEET(sheet), i, col[i].label);  
380    
   for (i = 0 ; i < rows; ++i )  
     var_sheet_row_close(GTK_SHEET(sheet),i);  
381    
382      for (i = 0 ; i < columns ; ++i )
383        {
384          gtk_sheet_column_button_add_label (GTK_SHEET(sheet), i, col[i].label);
385          gtk_sheet_set_column_width (GTK_SHEET(sheet), i, col[i].width);
386        }
387    
   var_sheet_set_next_row(GTK_SHEET(sheet), 0);  
388    
389    gtk_widget_show(sheet);    gtk_widget_show(sheet);
390    
391    
392    return sheet;    return sheet;
393    
394  }  }
# Line 402  psppire_variable_sheet_create (gchar *wi Line 396  psppire_variable_sheet_create (gchar *wi
396    
397    
398    
399    
400  /* Update a variable.  /* Update a variable.
401     This callback is invoked whenever a cell on the var_sheet is     This callback is invoked whenever a cell on the var_sheet is
402     changed     changed
# Line 409  psppire_variable_sheet_create (gchar *wi Line 404  psppire_variable_sheet_create (gchar *wi
404  static gint  static gint
405  update_variable(GtkSheet *sheet, gint row, gint col)  update_variable(GtkSheet *sheet, gint row, gint col)
406  {  {
407      gint r;
408    g_assert(pspp_dictionary);    g_assert(pspp_dictionary);
409    g_assert(G_IS_PSPP_DICT(pspp_dictionary));    g_assert(G_IS_PSPP_DICT(pspp_dictionary));
410      
411    struct variable *old_var = pspp_dict_get_var(pspp_dictionary, row);    struct variable *old_var = pspp_dict_get_var(pspp_dictionary, row);
412        
413    switch (col)    switch (col)
# Line 433  update_variable(GtkSheet *sheet, gint ro Line 429  update_variable(GtkSheet *sheet, gint ro
429            }            }
430          else if (          else if (
431                   pspp_dict_lookup_var(pspp_dictionary, name)                   pspp_dict_lookup_var(pspp_dictionary, name)
432                   && ( !old_var ||                   &&
433                     /* Allow changes of case */
434                     ( !old_var ||
435                        0 != strncasecmp(old_var->name, name))                        0 != strncasecmp(old_var->name, name))
436                   )                   )
437            {            {
# Line 443  update_variable(GtkSheet *sheet, gint ro Line 441  update_variable(GtkSheet *sheet, gint ro
441          else          else
442            {            {
443              pspp_dict_set_name(pspp_dictionary, row, name);              pspp_dict_set_name(pspp_dictionary, row, name);
             var_sheet_row_open(sheet, row );  
444            }            }
445        }        }
446        break;        break;
# Line 458  update_variable(GtkSheet *sheet, gint ro Line 455  update_variable(GtkSheet *sheet, gint ro
455        break;        break;
456      }      }
457    
458      if ( row > last_populated_row )
459        last_populated_row = row ;
460    
461    
462    return FALSE;    return FALSE;
463  }  }
464    
# Line 498  psppire_var_sheet_set_dictionary(GtkWidg Line 499  psppire_var_sheet_set_dictionary(GtkWidg
499    
500  }  }
501    
502    

Legend:
Removed from v.1.8  
changed lines
  Added in v.1.9

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26