-/* psppire-var-store.c
-
- PSPPIRE --- A Graphical User Interface for PSPP
+/* PSPPIRE - a graphical user interface for PSPP.
Copyright (C) 2006 Free Software Foundation
- This program is free software; you can redistribute it and/or modify
+ This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <string.h>
#include "missing-val-dialog.h"
#include <data/value-labels.h>
+#include "var-display.h"
-#define TRAILING_ROWS 40
+enum
+ {
+ PSPPIRE_VAR_STORE_TRAILING_ROWS = 1,
+ PSPPIRE_VAR_STORE_FORMAT_TYPE
+ };
static void psppire_var_store_init (PsppireVarStore *var_store);
static void psppire_var_store_class_init (PsppireVarStoreClass *class);
static void psppire_var_store_sheet_model_init (GSheetModelIface *iface);
static void psppire_var_store_finalize (GObject *object);
-static gchar *psppire_var_store_get_string (const GSheetModel *sheet_model, gint row, gint column);
-static gboolean psppire_var_store_clear (GSheetModel *model, gint row, gint col);
+gchar * missing_values_to_string (const struct variable *pv, GError **err);
+
+
+static gchar *psppire_var_store_get_string (const GSheetModel *sheet_model, glong row, glong column);
+
+static gboolean psppire_var_store_clear (GSheetModel *model, glong row, glong col);
static gboolean psppire_var_store_set_string (GSheetModel *model,
- const gchar *text, gint row, gint column);
+ const gchar *text, glong row, glong column);
-static gint psppire_var_store_get_row_count (const GSheetModel * model);
+static glong psppire_var_store_get_row_count (const GSheetModel * model);
+static glong psppire_var_store_get_column_count (const GSheetModel * model);
static gchar *text_for_column (const struct variable *pv, gint c, GError **err);
static GObjectClass *parent_class = NULL;
+GType
+psppire_var_store_format_type_get_type (void)
+{
+ static GType etype = 0;
+ if (etype == 0)
+ {
+ static const GEnumValue values[] =
+ {
+ { PSPPIRE_VAR_STORE_INPUT_FORMATS,
+ "PSPPIRE_VAR_STORE_INPUT_FORMATS",
+ "input" },
+ { PSPPIRE_VAR_STORE_OUTPUT_FORMATS,
+ "PSPPIRE_VAR_STORE_OUTPUT_FORMATS",
+ "output" },
+ { 0, NULL, NULL }
+ };
+
+ etype = g_enum_register_static
+ (g_intern_static_string ("PsppireVarStoreFormatType"), values);
+
+ }
+ return etype;
+}
+
GType
psppire_var_store_get_type (void)
{
return var_store_type;
}
+static void
+psppire_var_store_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ PsppireVarStore *self = (PsppireVarStore *) object;
+
+ switch (property_id)
+ {
+ case PSPPIRE_VAR_STORE_TRAILING_ROWS:
+ self->trailing_rows = g_value_get_int (value);
+ break;
+
+ case PSPPIRE_VAR_STORE_FORMAT_TYPE:
+ self->format_type = g_value_get_enum (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+psppire_var_store_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ PsppireVarStore *self = (PsppireVarStore *) object;
+
+ switch (property_id)
+ {
+ case PSPPIRE_VAR_STORE_TRAILING_ROWS:
+ g_value_set_int (value, self->trailing_rows);
+ break;
+
+ case PSPPIRE_VAR_STORE_FORMAT_TYPE:
+ g_value_set_enum (value, self->format_type);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ break;
+ }
+}
+
+
static void
psppire_var_store_class_init (PsppireVarStoreClass *class)
{
GObjectClass *object_class;
+ GParamSpec *pspec;
parent_class = g_type_class_peek_parent (class);
object_class = (GObjectClass*) class;
object_class->finalize = psppire_var_store_finalize;
+ object_class->set_property = psppire_var_store_set_property;
+ object_class->get_property = psppire_var_store_get_property;
+
+ /* The minimum value for trailing-rows is 1 to prevent the
+ var-store from ever having 0 rows, which breaks invariants
+ in gtksheet. */
+ pspec = g_param_spec_int ("trailing-rows",
+ "Trailing rows",
+ "Number of rows displayed after last variable",
+ 1 /* minimum value */,
+ 100 /* maximum value */,
+ 40 /* default value */,
+ G_PARAM_READWRITE);
+ g_object_class_install_property (object_class,
+ PSPPIRE_VAR_STORE_TRAILING_ROWS,
+ pspec);
+
+ pspec = g_param_spec_enum ("format-type",
+ "Variable format type",
+ ("Whether variables have input or output "
+ "formats"),
+ G_TYPE_PSPPIRE_VAR_STORE_FORMAT_TYPE,
+ PSPPIRE_VAR_STORE_OUTPUT_FORMATS,
+ G_PARAM_READWRITE);
+ g_object_class_install_property (object_class,
+ PSPPIRE_VAR_STORE_FORMAT_TYPE,
+ pspec);
}
-
static void
psppire_var_store_init (PsppireVarStore *var_store)
{
gdk_colormap_alloc_color (colormap, &var_store->disabled, FALSE, TRUE);
var_store->dict = 0;
+ var_store->trailing_rows = 40;
+ var_store->format_type = PSPPIRE_VAR_STORE_OUTPUT_FORMATS;
}
static gboolean
-psppire_var_store_item_editable (PsppireVarStore *var_store, gint row, gint column)
+psppire_var_store_item_editable (PsppireVarStore *var_store, glong row, glong column)
{
const struct fmt_spec *write_spec ;
if ( !pv )
return TRUE;
- if ( VAR_STRING == var_get_type (pv) && column == COL_DECIMALS )
+ if ( var_is_alpha (pv) && column == COL_DECIMALS )
return FALSE;
- write_spec =var_get_write_format (pv);
+ write_spec = var_get_print_format (pv);
switch ( write_spec->type )
{
struct variable *
-psppire_var_store_get_var (PsppireVarStore *store, gint row)
+psppire_var_store_get_var (PsppireVarStore *store, glong row)
{
return psppire_dict_get_variable (store->dict, row);
}
static gboolean
-psppire_var_store_is_editable (const GSheetModel *model, gint row, gint column)
+psppire_var_store_is_editable (const GSheetModel *model, glong row, glong column)
{
PsppireVarStore *store = PSPPIRE_VAR_STORE (model);
return psppire_var_store_item_editable (store, row, column);
static const GdkColor *
-psppire_var_store_get_foreground (const GSheetModel *model, gint row, gint column)
+psppire_var_store_get_foreground (const GSheetModel *model, glong row, glong column)
{
PsppireVarStore *store = PSPPIRE_VAR_STORE (model);
const PangoFontDescription *
psppire_var_store_get_font_desc (const GSheetModel *model,
- gint row, gint column)
+ glong row, glong column)
{
PsppireVarStore *store = PSPPIRE_VAR_STORE (model);
+
static void
psppire_var_store_sheet_model_init (GSheetModelIface *iface)
{
iface->get_row_count = psppire_var_store_get_row_count;
+ iface->get_column_count = psppire_var_store_get_column_count;
iface->free_strings = TRUE;
iface->get_string = psppire_var_store_get_string;
iface->set_string = psppire_var_store_set_string;
static void
-var_delete_callback (GtkWidget *w, gint first, gint n, gpointer data)
+var_delete_callback (GtkWidget *w, gint dict_idx, gint case_idx, gint val_cnt, gpointer data)
{
GSheetModel *model = G_SHEET_MODEL (data);
- g_sheet_model_rows_deleted (model, first, n);
+ g_sheet_model_rows_deleted (model, dict_idx, 1);
}
static void
-var_insert_callback (GtkWidget *w, gint row, gpointer data)
+var_insert_callback (GtkWidget *w, glong row, gpointer data)
{
GSheetModel *model = G_SHEET_MODEL (data);
g_sheet_model_rows_inserted (model, row, 1);
}
+static void
+refresh (PsppireDict *d, gpointer data)
+{
+ PsppireVarStore *vs = data;
+ g_sheet_model_range_changed (G_SHEET_MODEL (vs), -1, -1, -1, -1);
+}
/**
* psppire_var_store_replace_set_dictionary:
g_signal_connect (dict, "variable-changed", G_CALLBACK (var_change_callback),
var_store);
- g_signal_connect (dict, "variables-deleted", G_CALLBACK (var_delete_callback),
+ g_signal_connect (dict, "variable-deleted", G_CALLBACK (var_delete_callback),
var_store);
- g_signal_connect (dict, "variable-inserted", G_CALLBACK (var_insert_callback),
- var_store);
+ g_signal_connect (dict, "variable-inserted",
+ G_CALLBACK (var_insert_callback), var_store);
+ g_signal_connect (dict, "backend-changed", G_CALLBACK (refresh),
+ var_store);
/* The entire model has changed */
g_sheet_model_range_changed (G_SHEET_MODEL (var_store), -1, -1, -1, -1);
}
static gchar *
-psppire_var_store_get_string (const GSheetModel *model, gint row, gint column)
+psppire_var_store_get_string (const GSheetModel *model, glong row, glong column)
{
PsppireVarStore *store = PSPPIRE_VAR_STORE (model);
Returns true if anything was updated, false otherwise.
*/
static gboolean
-psppire_var_store_clear (GSheetModel *model, gint row, gint col)
+psppire_var_store_clear (GSheetModel *model, glong row, glong col)
{
struct variable *pv ;
*/
static gboolean
psppire_var_store_set_string (GSheetModel *model,
- const gchar *text, gint row, gint col)
+ const gchar *text, glong row, glong col)
{
struct variable *pv ;
var_set_width (pv, width);
else
{
+ bool for_input
+ = var_store->format_type == PSPPIRE_VAR_STORE_INPUT_FORMATS;
struct fmt_spec fmt ;
fmt = *var_get_write_format (pv);
- if ( width < fmt_min_output_width (fmt.type)
+ if ( width < fmt_min_width (fmt.type, for_input)
||
- width > fmt_max_output_width (fmt.type))
+ width > fmt_max_width (fmt.type, for_input))
return FALSE;
fmt.w = width;
- fmt.d = MIN (fmt_max_output_decimals (fmt.type, width), fmt.d);
+ fmt.d = MIN (fmt_max_decimals (fmt.type, width, for_input), fmt.d);
var_set_both_formats (pv, &fmt);
}
break;
case COL_DECIMALS:
{
+ bool for_input
+ = var_store->format_type == PSPPIRE_VAR_STORE_INPUT_FORMATS;
int decimals;
struct fmt_spec fmt;
if ( ! text) return FALSE;
decimals = atoi (text);
fmt = *var_get_write_format (pv);
if ( decimals >
- fmt_max_output_decimals (fmt.type,
- fmt.w
- ))
+ fmt_max_decimals (fmt.type,
+ fmt.w,
+ for_input
+ ))
return FALSE;
fmt.d = decimals;
}
+const static gchar none[] = N_("None");
+
static gchar *
text_for_column (const struct variable *pv, gint c, GError **err)
{
- static gchar none[] = N_("None");
-
static const gchar *const type_label[] =
{
N_("Numeric"),
case COL_MISSING:
{
- gchar *s;
- const struct missing_values *miss = var_get_missing_values (pv);
- if ( mv_is_empty (miss))
- return g_locale_to_utf8 (gettext (none), -1, 0, 0, err);
- else
- {
- if ( ! mv_has_range (miss))
- {
- GString *gstr = g_string_sized_new (10);
- const int n = mv_n_values (miss);
- gchar *mv[4] = {0,0,0,0};
- gint i;
- for (i = 0 ; i < n; ++i )
- {
- union value v;
- mv_peek_value (miss, &v, i);
- mv[i] = value_to_text (v, *write_spec);
- if ( i > 0 )
- g_string_append (gstr, ", ");
- g_string_append (gstr, mv[i]);
- g_free (mv[i]);
- }
- s = pspp_locale_to_utf8 (gstr->str, gstr->len, err);
- g_string_free (gstr, TRUE);
- }
- else
- {
- GString *gstr = g_string_sized_new (10);
- gchar *l, *h;
- union value low, high;
- mv_peek_range (miss, &low.f, &high.f);
-
- l = value_to_text (low, *write_spec);
- h = value_to_text (high, *write_spec);
-
- g_string_printf (gstr, "%s - %s", l, h);
- g_free (l);
- g_free (h);
-
- if ( mv_has_value (miss))
- {
- gchar *ss = 0;
- union value v;
- mv_peek_value (miss, &v, 0);
-
- ss = value_to_text (v, *write_spec);
-
- g_string_append (gstr, ", ");
- g_string_append (gstr, ss);
- free (ss);
- }
- s = pspp_locale_to_utf8 (gstr->str, gstr->len, err);
- g_string_free (gstr, TRUE);
- }
-
- return s;
- }
+ return missing_values_to_string (pv, err);
}
break;
case COL_VALUES:
break;
case COL_MEASURE:
{
- const gint measure = var_get_measure (pv);
-
- g_assert (measure < n_MEASURES);
- return g_locale_to_utf8 (gettext (measures[measure]),
- -1, 0, 0, err);
+ return measure_to_string (pv, err);
}
break;
}
}
-static gint
+static glong
psppire_var_store_get_row_count (const GSheetModel * model)
{
gint rows = 0;
return rows ;
}
+static glong
+psppire_var_store_get_column_count (const GSheetModel * model)
+{
+ return n_COLS ;
+}
+
+
/* Row related funcs */
-static gint
+static glong
geometry_get_row_count (const GSheetRow *geom, gpointer data)
{
gint rows = 0;
if (vs->dict)
rows = psppire_dict_get_var_cnt (vs->dict);
- return rows + TRAILING_ROWS;
+ return rows + vs->trailing_rows;
}
static gint
-geometry_get_height (const GSheetRow *geom, gint row, gpointer data)
+geometry_get_height (const GSheetRow *geom, glong row, gpointer data)
{
return 25;
}
static gboolean
-geometry_is_sensitive (const GSheetRow *geom, gint row, gpointer data)
+geometry_is_sensitive (const GSheetRow *geom, glong row, gpointer data)
{
PsppireVarStore *vs = PSPPIRE_VAR_STORE (geom);
static gchar *
-geometry_get_button_label (const GSheetRow *geom, gint unit, gpointer data)
+geometry_get_button_label (const GSheetRow *geom, glong unit, gpointer data)
{
- gchar *label = g_strdup_printf (_("%d"), unit);
+ gchar *label = g_strdup_printf (_("%ld"), unit + 1);
return label;
}
-
static void
psppire_var_store_sheet_row_init (GSheetRowIface *iface)
{
iface->get_button_label = geometry_get_button_label;
}
+
+
+