27 |
#include <psppire-conf.h> |
#include <psppire-conf.h> |
28 |
|
|
29 |
#include <glade/glade.h> |
#include <glade/glade.h> |
|
|
|
30 |
#include <gtk/gtk.h> |
#include <gtk/gtk.h> |
31 |
#include "gtksheet.h" |
#include "gtksheet.h" |
32 |
|
|
33 |
#include "callbacks.h" |
#include "callbacks.h" |
|
|
|
34 |
#include "pspp-dict.h" |
#include "pspp-dict.h" |
|
|
|
35 |
#include "var_type_dialog.h" |
#include "var_type_dialog.h" |
36 |
|
#include "var_sheet.h" |
37 |
|
|
38 |
#define _(A) A |
#define _(A) A |
39 |
#define N_(A) A |
#define N_(A) A |
40 |
|
|
41 |
|
|
|
/* Fills F with an output format specification with type TYPE, width |
|
|
W, and D decimals. Iff it's a valid format, then return true. |
|
|
*/ |
|
|
static bool |
|
|
make_output_format_try (struct fmt_spec *f, int type, int w, int d) |
|
|
{ |
|
|
f->type = type; |
|
|
f->w = w; |
|
|
f->d = d; |
|
|
return check_output_specifier (f, true); |
|
|
} |
|
|
|
|
42 |
|
|
43 |
/* The dictionary associated with this var sheet */ |
/* The dictionary associated with this var sheet */ |
44 |
static PSPP_Dict *pspp_dictionary; |
static PSPP_Dict *pspp_dictionary; |
92 |
n_COLS}; |
n_COLS}; |
93 |
|
|
94 |
|
|
95 |
|
/* Fills F with an output format specification with type TYPE, width |
96 |
|
W, and D decimals. Iff it's a valid format, then return true. |
97 |
|
*/ |
98 |
|
static bool |
99 |
|
make_output_format_try (struct fmt_spec *f, int type, int w, int d) |
100 |
|
{ |
101 |
|
f->type = type; |
102 |
|
f->w = w; |
103 |
|
f->d = d; |
104 |
|
return check_output_specifier (f, true); |
105 |
|
} |
106 |
|
|
107 |
/* Callback for when the var type dialog is closed using the OK button*/ |
|
108 |
|
/* Callback for when the var type dialog is closed using the OK button. |
109 |
|
It sets the appropriate variable accordingly. */ |
110 |
static gint |
static gint |
111 |
set_var_type(GtkWidget *w, gpointer data) |
set_var_type(GtkWidget *w, gpointer data) |
112 |
{ |
{ |
184 |
} |
} |
185 |
|
|
186 |
|
|
187 |
gchar * |
/* Returns a valid name for a new variable in DICT. |
188 |
|
The return value must be freed when no longer required. */ |
189 |
|
static gchar * |
190 |
auto_generate_var_name(PSPP_Dict *dict) |
auto_generate_var_name(PSPP_Dict *dict) |
191 |
{ |
{ |
192 |
gint d = 0; |
gint d = 0; |
193 |
gchar *name = g_strdup_printf("VAR%05d",d); |
gchar *name; |
194 |
|
|
195 |
|
while (name = g_strdup_printf("VAR%05d",d++), |
196 |
|
pspp_dict_lookup_var(dict, name)) |
197 |
|
g_free(name); |
198 |
|
|
|
while (pspp_dict_lookup_var(dict, name)) |
|
|
{ |
|
|
g_free(name); |
|
|
name = g_strdup_printf("VAR%05d",++d); |
|
|
} |
|
199 |
return name; |
return name; |
200 |
} |
} |
201 |
|
|
207 |
var_sheet_cell_change_entry (GtkSheet * sheet, gint row, gint column, |
var_sheet_cell_change_entry (GtkSheet * sheet, gint row, gint column, |
208 |
gpointer leaving) |
gpointer leaving) |
209 |
{ |
{ |
210 |
|
g_return_val_if_fail(sheet != NULL, FALSE); |
211 |
|
|
212 |
if ( leaving ) |
if ( leaving ) |
213 |
{ |
{ |
214 |
gtk_sheet_change_entry(sheet, GTK_TYPE_ENTRY); |
gtk_sheet_change_entry(sheet, GTK_TYPE_ENTRY); |
229 |
{ |
{ |
230 |
const gint current_value = |
const gint current_value = |
231 |
atoi(gtk_sheet_cell_get_text(sheet, row, column)); |
atoi(gtk_sheet_cell_get_text(sheet, row, column)); |
232 |
GtkAdjustment *adj = |
|
233 |
|
GtkObject *adj = |
234 |
gtk_adjustment_new(current_value, |
gtk_adjustment_new(current_value, |
235 |
1.0, 100.0, /* min, max */ |
1.0, 100.0, /* min, max */ |
236 |
1.0, 1.0, 1.0 /* steps */ |
1.0, 1.0, 1.0 /* steps */ |
241 |
GtkSpinButton *spinButton = |
GtkSpinButton *spinButton = |
242 |
GTK_SPIN_BUTTON(gtk_sheet_get_entry(sheet)); |
GTK_SPIN_BUTTON(gtk_sheet_get_entry(sheet)); |
243 |
|
|
244 |
gtk_spin_button_set_adjustment(spinButton, adj); |
gtk_spin_button_set_adjustment(spinButton, GTK_ADJUSTMENT(adj)); |
245 |
gtk_spin_button_set_digits(spinButton, 0); |
gtk_spin_button_set_digits(spinButton, 0); |
246 |
} |
} |
247 |
} |
} |
258 |
static gboolean |
static gboolean |
259 |
var_sheet_cell_set (GtkSheet * sheet, gint row, gint column) |
var_sheet_cell_set (GtkSheet * sheet, gint row, gint column) |
260 |
{ |
{ |
261 |
|
g_return_val_if_fail(sheet, FALSE); |
262 |
|
|
263 |
|
if ( ! pspp_dictionary ) |
264 |
|
return ; |
265 |
|
|
266 |
gint r; |
gint r; |
267 |
/* Fill out any rows above, which are empty */ |
/* Fill out any rows above, which are empty */ |
268 |
for ( r = last_populated_row + 1 ; r < row ; ++r ) |
for ( r = last_populated_row + 1 ; r < row ; ++r ) |
327 |
const GtkSheetRange *urange, |
const GtkSheetRange *urange, |
328 |
gboolean editable) |
gboolean editable) |
329 |
{ |
{ |
|
|
|
330 |
gtk_sheet_range_set_editable (sheet, urange, editable); |
gtk_sheet_range_set_editable (sheet, urange, editable); |
331 |
|
|
|
GdkColor *desiredColour = editable ? &enabled : &disabled; |
|
|
|
|
332 |
gtk_sheet_range_set_foreground (sheet, |
gtk_sheet_range_set_foreground (sheet, |
333 |
urange, |
urange, |
334 |
desiredColour); |
editable ? &enabled : &disabled); |
335 |
|
|
336 |
gtk_sheet_range_set_background (sheet, |
gtk_sheet_range_set_background (sheet, |
337 |
urange, |
urange, |
371 |
{ |
{ |
372 |
case FMT_A: |
case FMT_A: |
373 |
{ |
{ |
374 |
|
/* Strings don't have decimal places */ |
375 |
GtkSheetRange range; |
GtkSheetRange range; |
376 |
range.col0 = range.coli = COL_DECIMALS; |
range.col0 = range.coli = COL_DECIMALS; |
377 |
range.row0 = range.rowi = row; |
range.row0 = range.rowi = row; |
382 |
|
|
383 |
case FMT_DATE: |
case FMT_DATE: |
384 |
{ |
{ |
385 |
|
/* Dates don't have decimal places and the width is automatic */ |
386 |
GtkSheetRange range; |
GtkSheetRange range; |
387 |
range.col0 = COL_WIDTH; |
range.col0 = COL_WIDTH; |
388 |
range.coli = COL_DECIMALS; |
range.coli = COL_DECIMALS; |
449 |
GString *s = gint_to_gstring(var->write.d); |
GString *s = gint_to_gstring(var->write.d); |
450 |
gtk_sheet_set_cell_text(sheet, row, c, s->str); |
gtk_sheet_set_cell_text(sheet, row, c, s->str); |
451 |
g_string_free(s, TRUE); |
g_string_free(s, TRUE); |
|
|
|
452 |
} |
} |
453 |
break; |
break; |
454 |
case COL_COLUMNS: |
case COL_COLUMNS: |
535 |
|
|
536 |
g_signal_connect (GTK_OBJECT (sheet), "deactivate", |
g_signal_connect (GTK_OBJECT (sheet), "deactivate", |
537 |
GTK_SIGNAL_FUNC (var_sheet_cell_change_entry), |
GTK_SIGNAL_FUNC (var_sheet_cell_change_entry), |
538 |
1); |
(void *) 1); |
|
|
|
539 |
|
|
540 |
|
|
541 |
g_signal_connect (GTK_OBJECT (sheet), "set_cell", |
g_signal_connect (GTK_OBJECT (sheet), "set_cell", |
561 |
|
|
562 |
gdk_colormap_alloc_color (colormap, &disabled, FALSE, TRUE); |
gdk_colormap_alloc_color (colormap, &disabled, FALSE, TRUE); |
563 |
|
|
564 |
|
PSPP_Dict *d = pspp_dict_new(); |
565 |
|
psppire_var_sheet_set_dictionary(GTK_SHEET(sheet), d); |
566 |
|
|
567 |
gtk_widget_show(sheet); |
gtk_widget_show(sheet); |
568 |
|
|
569 |
return sheet; |
return sheet; |
577 |
static gint |
static gint |
578 |
update_variable(GtkSheet *sheet, gint row, gint col) |
update_variable(GtkSheet *sheet, gint row, gint col) |
579 |
{ |
{ |
580 |
|
g_return_val_if_fail(sheet, FALSE); |
581 |
gint r; |
gint r; |
582 |
g_assert(pspp_dictionary); |
g_assert(pspp_dictionary); |
583 |
g_assert(G_IS_PSPP_DICT(pspp_dictionary)); |
g_assert(G_IS_PSPP_DICT(pspp_dictionary)); |
642 |
if ( !old_var->label || 0 != strcmp(old_var->label, text)) |
if ( !old_var->label || 0 != strcmp(old_var->label, text)) |
643 |
{ |
{ |
644 |
free(old_var->label); |
free(old_var->label); |
645 |
old_var->label = strdup(text); |
old_var->label = g_strdup(text); |
646 |
} |
} |
647 |
} |
} |
648 |
break; |
break; |
688 |
} |
} |
689 |
|
|
690 |
|
|
691 |
|
/* Returns the dictionary associated with the sheet */ |
692 |
|
PSPP_Dict * |
693 |
|
psppire_var_sheet_get_dictionary(GtkWidget *sheet) |
694 |
|
{ |
695 |
|
return pspp_dictionary; |
696 |
|
} |
697 |
|
|
698 |
|
|
699 |
/* Associate a dictionary with the var sheet. |
/* Associate a dictionary with the var sheet. |
700 |
|
If there is already a dictionary associated, then it will be destroyed. |
701 |
*/ |
*/ |
702 |
void |
void |
703 |
psppire_var_sheet_set_dictionary(GtkWidget *sheet, PSPP_Dict *d) |
psppire_var_sheet_set_dictionary(GtkSheet *sheet, PSPP_Dict *d) |
704 |
{ |
{ |
705 |
|
gint v; |
706 |
|
|
707 |
|
g_assert(sheet); |
708 |
|
|
709 |
|
if ( pspp_dictionary) |
710 |
|
g_object_unref(pspp_dictionary); |
711 |
|
|
712 |
pspp_dictionary = d; |
pspp_dictionary = d; |
713 |
|
|
714 |
g_signal_connect(pspp_dictionary, "variable_changed", |
const int c = pspp_dict_get_var_cnt(d); |
715 |
|
|
716 |
|
g_signal_connect(d, "variable_changed", |
717 |
G_CALLBACK(var_sheet_update_callback), sheet); |
G_CALLBACK(var_sheet_update_callback), sheet); |
718 |
|
|
719 |
g_signal_connect(pspp_dictionary, "variable_deleted", |
g_signal_connect(d, "variable_deleted", |
720 |
G_CALLBACK(remove_variable), sheet); |
G_CALLBACK(remove_variable), sheet); |
721 |
|
|
722 |
|
for (v = 0 ; v < c ; ++v ) |
723 |
|
pspp_dict_var_changed(d, v); |
724 |
|
|
725 |
|
last_populated_row = c - 1; |
726 |
} |
} |
727 |
|
|
728 |
|
|
729 |
/* Blank the sheet */ |
/* Blank the sheet */ |
730 |
void |
void |
731 |
psppire_var_sheet_clear(GtkWidget *sheet) |
psppire_var_sheet_clear(GtkSheet *sheet) |
732 |
{ |
{ |
733 |
|
g_return_if_fail(sheet); |
734 |
|
|
735 |
gtk_sheet_range_clear(sheet, NULL); |
gtk_sheet_range_clear(sheet, NULL); |
736 |
last_populated_row = -1; |
last_populated_row = -1; |
737 |
|
|
738 |
|
var_sheet_range_set_editable(sheet, 0, FALSE); |
739 |
} |
} |