1 /* PSPPIRE - a graphical user interface for PSPP.
2 Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
18 /* This module creates the Variable Sheet used for inputing the
19 variables in the dictonary */
23 #define _(msgid) gettext (msgid)
24 #define N_(msgid) msgid
26 #include <data/value-labels.h>
28 #include <glade/glade.h>
34 #include <data/value.h>
36 #include <gtksheet/gtksheet.h>
37 #include <gtksheet/gsheet-hetero-column.h>
38 #include <gtksheet/gsheet-uniform-row.h>
40 #include "localcharset.h"
42 #include "psppire-var-store.h"
44 #include "psppire-dict.h"
45 #include "var-type-dialog.h"
46 #include "var-sheet.h"
47 #include "customentry.h"
49 #include "val-labs-dialog.h"
50 #include "missing-val-dialog.h"
54 static const gint n_initial_rows = 40;
58 struct column_parameters
64 static const struct column_parameters column_def[] = {
79 const gchar *const alignments[n_ALIGNMENTS + 1]={
86 const gchar *const measures[n_MEASURES + 1]={
93 G_DEFINE_TYPE (PsppireVarSheet, psppire_var_sheet, GTK_TYPE_SHEET);
96 psppire_var_sheet_class_init (PsppireVarSheetClass *class)
100 static GtkListStore *
101 create_label_list (const gchar *const *labels)
107 GtkListStore *list_store;
108 list_store = gtk_list_store_new (1, G_TYPE_STRING);
111 while ( (s = labels[i++]))
113 gtk_list_store_append (list_store, &iter);
114 gtk_list_store_set (list_store, &iter,
122 /* Callback for when the alignment combo box
125 change_alignment (GtkComboBox *cb,
128 struct variable *pv = user_data;
129 gint active_item = gtk_combo_box_get_active (cb);
131 if ( active_item < 0 ) return ;
133 var_set_alignment (pv, active_item);
138 /* Callback for when the measure combo box
141 change_measure (GtkComboBox *cb,
144 struct variable *pv = user_data;
145 gint active_item = gtk_combo_box_get_active (cb);
147 if ( active_item < 0 ) return ;
149 var_set_measure (pv, active_item);
155 traverse_cell_callback (GtkSheet * sheet,
156 gint row, gint column,
157 gint *new_row, gint *new_column
160 PsppireVarSheet *var_sheet = PSPPIRE_VAR_SHEET (sheet);
161 PsppireVarStore *var_store = PSPPIRE_VAR_STORE (gtk_sheet_get_model (sheet));
163 gint n_vars = psppire_var_store_get_var_cnt (var_store);
165 if (*new_row >= n_vars && !var_sheet->may_create_vars)
168 if ( row == n_vars && *new_row >= n_vars)
170 GtkEntry *entry = GTK_ENTRY (gtk_sheet_get_entry (sheet));
172 const gchar *name = gtk_entry_get_text (entry);
174 if (! psppire_dict_check_name (var_store->dict, name, TRUE))
177 psppire_dict_insert_variable (var_store->dict, row, name);
182 /* If the destination cell is outside the current variables, then
183 automatically create variables for the new rows.
185 if ( (*new_row > n_vars) ||
186 (*new_row == n_vars && *new_column != COL_NAME) )
189 for ( i = n_vars ; i <= *new_row; ++i )
190 psppire_dict_insert_variable (var_store->dict, i, NULL);
200 Callback whenever the cell on the var sheet is left
203 var_sheet_cell_entry_leave (GtkSheet * sheet, gint row, gint column,
206 gtk_sheet_change_entry (sheet, GTK_TYPE_ENTRY);
213 Callback whenever the cell on the var sheet is entered.
216 var_sheet_cell_entry_enter (GtkSheet * sheet, gint row, gint column,
219 GtkSheetCellAttr attributes;
220 PsppireVarStore *var_store ;
221 struct variable *var ;
225 g_return_val_if_fail (sheet != NULL, FALSE);
227 var_store = PSPPIRE_VAR_STORE (gtk_sheet_get_model (sheet));
229 g_assert (var_store);
231 if ( row >= psppire_var_store_get_var_cnt (var_store))
234 xml = XML_NEW ("data-editor.glade");
236 gtk_sheet_get_attributes (sheet, row, column, &attributes);
238 var = psppire_var_store_get_var (var_store, row);
244 static GtkListStore *list_store = NULL;
245 GtkComboBoxEntry *cbe;
246 gtk_sheet_change_entry (sheet, GTK_TYPE_COMBO_BOX_ENTRY);
248 GTK_COMBO_BOX_ENTRY (gtk_sheet_get_entry (sheet)->parent);
251 if ( ! list_store) list_store = create_label_list (alignments);
253 gtk_combo_box_set_model (GTK_COMBO_BOX (cbe),
254 GTK_TREE_MODEL (list_store));
256 gtk_combo_box_entry_set_text_column (cbe, 0);
259 g_signal_connect (G_OBJECT (cbe),"changed",
260 G_CALLBACK (change_alignment), var);
266 static GtkListStore *list_store = 0;
267 GtkComboBoxEntry *cbe;
268 gtk_sheet_change_entry (sheet, GTK_TYPE_COMBO_BOX_ENTRY);
270 GTK_COMBO_BOX_ENTRY (gtk_sheet_get_entry (sheet)->parent);
273 if ( ! list_store) list_store = create_label_list (measures);
275 gtk_combo_box_set_model (GTK_COMBO_BOX (cbe),
276 GTK_TREE_MODEL (list_store));
278 gtk_combo_box_entry_set_text_column (cbe, 0);
280 g_signal_connect (G_OBJECT (cbe),"changed",
281 G_CALLBACK (change_measure), var);
287 static struct val_labs_dialog *val_labs_dialog = NULL;
289 PsppireCustomEntry *customEntry;
291 gtk_sheet_change_entry (sheet, PSPPIRE_CUSTOM_ENTRY_TYPE);
294 PSPPIRE_CUSTOM_ENTRY (gtk_sheet_get_entry (sheet));
296 if ( var_is_long_string (var))
297 g_object_set (customEntry,
301 if (!val_labs_dialog )
302 val_labs_dialog = val_labs_dialog_create (xml);
304 val_labs_dialog_set_target_variable (val_labs_dialog, var);
306 g_signal_connect_swapped (GTK_OBJECT (customEntry),
308 GTK_SIGNAL_FUNC (val_labs_dialog_show),
315 static struct missing_val_dialog *missing_val_dialog = 0;
316 PsppireCustomEntry *customEntry;
318 gtk_sheet_change_entry (sheet, PSPPIRE_CUSTOM_ENTRY_TYPE);
321 PSPPIRE_CUSTOM_ENTRY (gtk_sheet_get_entry (sheet));
323 if ( var_is_long_string (var))
324 g_object_set (customEntry,
328 if (!missing_val_dialog )
329 missing_val_dialog = missing_val_dialog_create (xml);
331 missing_val_dialog->pv = psppire_var_store_get_var (var_store, row);
333 g_signal_connect_swapped (GTK_OBJECT (customEntry),
335 GTK_SIGNAL_FUNC (missing_val_dialog_show),
342 static struct var_type_dialog *var_type_dialog = 0;
344 PsppireCustomEntry *customEntry;
346 gtk_sheet_change_entry (sheet, PSPPIRE_CUSTOM_ENTRY_TYPE);
349 PSPPIRE_CUSTOM_ENTRY (gtk_sheet_get_entry (sheet));
352 /* Popup the Variable Type dialog box */
353 if (!var_type_dialog )
354 var_type_dialog = var_type_dialog_create (xml);
357 var_type_dialog->pv = var;
359 g_signal_connect_swapped (GTK_OBJECT (customEntry),
361 GTK_SIGNAL_FUNC (var_type_dialog_show),
370 if ( attributes.is_editable)
374 const gchar *s = gtk_sheet_cell_get_text (sheet, row, column);
378 GtkSpinButton *spinButton ;
379 const gint current_value = atoi (s);
382 const struct fmt_spec *fmt = var_get_write_format (var);
386 r_min = MAX (fmt->d + 1, fmt_min_output_width (fmt->type));
387 r_max = fmt_max_output_width (fmt->type);
391 r_max = fmt_max_output_decimals (fmt->type, fmt->w);
395 r_max = 255 ; /* Is this a sensible value ? */
398 g_assert_not_reached ();
401 adj = gtk_adjustment_new (current_value,
403 1.0, 1.0, 1.0 /* steps */
406 gtk_sheet_change_entry (sheet, GTK_TYPE_SPIN_BUTTON);
409 GTK_SPIN_BUTTON (gtk_sheet_get_entry (sheet));
411 gtk_spin_button_set_adjustment (spinButton, GTK_ADJUSTMENT (adj));
412 gtk_spin_button_set_digits (spinButton, 0);
419 gtk_sheet_change_entry (sheet, GTK_TYPE_ENTRY);
424 g_object_unref (xml);
430 psppire_var_sheet_init (PsppireVarSheet *self)
432 self->may_create_vars = true;
434 g_signal_connect (self, "activate",
435 GTK_SIGNAL_FUNC (var_sheet_cell_entry_enter),
438 g_signal_connect (self, "deactivate",
439 GTK_SIGNAL_FUNC (var_sheet_cell_entry_leave),
442 g_signal_connect (self, "traverse",
443 GTK_SIGNAL_FUNC (traverse_cell_callback), 0);
447 psppire_var_sheet_new_with_var_store (PsppireVarStore *var_store)
453 GObject *geo = g_sheet_hetero_column_new (75, n_COLS);
454 g_assert (var_store);
456 sheet = g_object_new (PSPPIRE_TYPE_VAR_SHEET,
457 "row-geometry", var_store,
458 "column-geometry", geo,
461 gtk_sheet_set_model (GTK_SHEET (sheet), G_SHEET_MODEL (var_store));
464 for (i = 0 ; i < n_COLS ; ++i )
466 g_sheet_hetero_column_set_button_label (G_SHEET_HETERO_COLUMN (geo), i,
467 gettext (column_def[i].label));
469 g_sheet_hetero_column_set_width (G_SHEET_HETERO_COLUMN (geo), i,
470 column_def[i].width);
478 /* Create the var sheet */
479 G_MODULE_EXPORT GtkWidget*
480 psppire_variable_sheet_create (gchar *widget_name,
483 gint int1, gint int2)
487 extern PsppireVarStore *the_var_store;
489 /* Since this happens inside glade_xml_new, we must prevent strings from
490 * being re-encoded twice */
491 codeset = xstrdup (bind_textdomain_codeset (PACKAGE, 0));
492 bind_textdomain_codeset (PACKAGE, locale_charset ());
495 sheet = psppire_var_sheet_new_with_var_store (the_var_store);
497 bind_textdomain_codeset (PACKAGE, codeset);
500 gtk_widget_show (sheet);
508 psppire_var_sheet_set_may_create_vars (PsppireVarSheet *sheet,
509 gboolean may_create_vars)
511 sheet->may_create_vars = may_create_vars;