-/* psppire-var-store.c
-
- PSPPIRE --- A Graphical User Interface for PSPP
- Copyright (C) 2006 Free Software Foundation
- Written by John Darrington
+/* PSPPIRE - a graphical user interface for PSPP.
+ Copyright (C) 2006, 2009, 2010, 2011, 2012 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>
#define _(msgid) gettext (msgid)
#define N_(msgid) msgid
-
+#include <libpspp/i18n.h>
#include <gobject/gvaluecollector.h>
-#include <gtksheet/gsheetmodel.h>
-
-#include "psppire-variable.h"
#include "psppire-var-store.h"
-#include "var-sheet.h"
#include "helper.h"
#include <data/dictionary.h>
#include <data/variable.h>
+#include <data/format.h>
#include <data/missing-values.h>
#include "val-labs-dialog.h"
#include "missing-val-dialog.h"
#include <data/value-labels.h>
+#include "var-display.h"
-#define TRAILING_ROWS 40
+enum
+ {
+ PROP_0,
+ PSPPIRE_VAR_STORE_DICT
+ };
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);
-
-
-static gboolean psppire_var_store_set_string(GSheetModel *model,
- const gchar *text, gint row, gint column);
-
-static gint psppire_var_store_get_row_count(const GSheetModel * model);
-
-static gchar *text_for_column(const struct PsppireVariable *pv, gint c, GError **err);
-
-
-static void psppire_var_store_sheet_row_init (GSheetRowIface *iface);
-
+static void psppire_var_store_dispose (GObject *object);
static GObjectClass *parent_class = NULL;
(GInstanceInitFunc) psppire_var_store_init,
};
- static const GInterfaceInfo sheet_model_info =
- {
- (GInterfaceInitFunc) psppire_var_store_sheet_model_init,
- NULL,
- NULL
- };
-
- static const GInterfaceInfo sheet_row_info =
- {
- (GInterfaceInitFunc) psppire_var_store_sheet_row_init,
- NULL,
- NULL
- };
-
var_store_type = g_type_register_static (G_TYPE_OBJECT, "PsppireVarStore", &var_store_info, 0);
-
- g_type_add_interface_static (var_store_type,
- G_TYPE_SHEET_MODEL,
- &sheet_model_info);
-
- g_type_add_interface_static (var_store_type,
- G_TYPE_SHEET_ROW,
- &sheet_row_info);
-
-
}
return var_store_type;
}
static void
-psppire_var_store_class_init (PsppireVarStoreClass *class)
+psppire_var_store_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- GObjectClass *object_class;
+ PsppireVarStore *self = (PsppireVarStore *) object;
- parent_class = g_type_class_peek_parent (class);
- object_class = (GObjectClass*) class;
+ switch (property_id)
+ {
+ case PSPPIRE_VAR_STORE_DICT:
+ if ( self->dictionary)
+ g_object_unref (self->dictionary);
+ self->dictionary = g_value_dup_object (value);
+ break;
- object_class->finalize = psppire_var_store_finalize;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ break;
+ }
}
-
static void
-psppire_var_store_init (PsppireVarStore *var_store)
+psppire_var_store_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- GdkColormap *colormap = gdk_colormap_get_system();
-
- g_assert(gdk_color_parse("gray", &var_store->disabled));
-
- gdk_colormap_alloc_color (colormap, &var_store->disabled, FALSE, TRUE);
+ PsppireVarStore *self = (PsppireVarStore *) object;
- var_store->dict = 0;
-}
-
-static gboolean
-psppire_var_store_item_editable(PsppireVarStore *var_store, gint row, gint column)
-{
- const struct fmt_spec *write_spec ;
-
- struct PsppireVariable *pv = psppire_var_store_get_variable(var_store, row);
-
- if ( !pv )
- return TRUE;
-
- if ( ALPHA == psppire_variable_get_type(pv) && column == COL_DECIMALS )
- return FALSE;
-
- write_spec = psppire_variable_get_write_spec(pv);
-
- switch ( write_spec->type )
+ switch (property_id)
{
- case FMT_DATE:
- case FMT_EDATE:
- case FMT_SDATE:
- case FMT_ADATE:
- case FMT_JDATE:
- case FMT_QYR:
- case FMT_MOYR:
- case FMT_WKYR:
- case FMT_DATETIME:
- case FMT_TIME:
- case FMT_DTIME:
- case FMT_WKDAY:
- case FMT_MONTH:
- if ( column == COL_DECIMALS || column == COL_WIDTH)
- return FALSE;
+ case PSPPIRE_VAR_STORE_DICT:
+ g_value_take_object (value, self->dictionary);
break;
+
default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
-
- return TRUE;
-}
-
-static gboolean
-psppire_var_store_is_editable(const GSheetModel *model, gint row, gint 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)
+static void
+psppire_var_store_class_init (PsppireVarStoreClass *class)
{
- PsppireVarStore *store = PSPPIRE_VAR_STORE(model);
+ GObjectClass *object_class;
+ GParamSpec *dict_pspec;
- if ( ! psppire_var_store_item_editable(store, row, column) )
- return &store->disabled;
-
- return NULL;
-}
+ parent_class = g_type_class_peek_parent (class);
+ object_class = (GObjectClass*) class;
+ object_class->finalize = psppire_var_store_finalize;
+ object_class->dispose = psppire_var_store_dispose;
+ object_class->set_property = psppire_var_store_set_property;
+ object_class->get_property = psppire_var_store_get_property;
-const PangoFontDescription *
-psppire_var_store_get_font_desc(const GSheetModel *model,
- gint row, gint column)
-{
- PsppireVarStore *store = PSPPIRE_VAR_STORE(model);
-
- return store->font_desc;
+ dict_pspec = g_param_spec_object ("dictionary",
+ "Dictionary",
+ "The PsppireDict represented by this var store",
+ PSPPIRE_TYPE_DICT,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
+
+ g_object_class_install_property (object_class,
+ PSPPIRE_VAR_STORE_DICT,
+ dict_pspec);
}
-
-
static void
-psppire_var_store_sheet_model_init (GSheetModelIface *iface)
+psppire_var_store_init (PsppireVarStore *var_store)
{
- iface->get_row_count = psppire_var_store_get_row_count;
- iface->free_strings = TRUE;
- iface->get_string = psppire_var_store_get_string;
- iface->set_string = psppire_var_store_set_string;
- iface->clear_datum = psppire_var_store_clear;
- iface->is_editable = psppire_var_store_is_editable;
- iface->is_visible = NULL;
- iface->get_foreground = psppire_var_store_get_foreground;
- iface->get_background = NULL;
- iface->get_font_desc = psppire_var_store_get_font_desc;
- iface->get_cell_border = NULL;
+ var_store->dictionary = NULL;
}
-
+struct variable *
+psppire_var_store_get_var (PsppireVarStore *store, glong row)
+{
+ return psppire_dict_get_variable (store->dictionary, row);
+}
/**
* psppire_var_store_new:
{
PsppireVarStore *retval;
- retval = g_object_new (GTK_TYPE_VAR_STORE, NULL);
+ retval = g_object_new (GTK_TYPE_VAR_STORE, "dictionary", dict, NULL);
- psppire_var_store_set_dictionary(retval, dict);
+ // psppire_var_store_set_dictionary (retval, dict);
return retval;
}
-static void
-var_change_callback(GtkWidget *w, gint n, gpointer data)
-{
- GSheetModel *model = G_SHEET_MODEL(data);
- g_sheet_model_range_changed (model,
- n, 0, n, n_COLS);
-}
-
-
-static void
-var_delete_callback(GtkWidget *w, gint first, gint n, gpointer data)
-{
- GSheetModel *model = G_SHEET_MODEL(data);
-
- g_sheet_model_rows_deleted (model, first, n);
-}
-
-
-
-static void
-var_insert_callback(GtkWidget *w, gint row, gpointer data)
-{
- GSheetModel *model = G_SHEET_MODEL(data);
-
- g_sheet_model_rows_inserted (model, row, 1);
-}
-
-
-
-/**
- * psppire_var_store_replace_set_dictionary:
- * @var_store: The variable store
- * @dict: The dictionary to set
- *
- * If a dictionary is already associated with the var-store, then it will be
- * destroyed.
- **/
-void
-psppire_var_store_set_dictionary(PsppireVarStore *var_store, PsppireDict *dict)
-{
- if ( var_store->dict ) g_object_unref(var_store->dict);
-
- var_store->dict = dict;
-
- g_signal_connect(dict, "variable-changed", G_CALLBACK(var_change_callback),
- var_store);
-
- g_signal_connect(dict, "variables-deleted", G_CALLBACK(var_delete_callback),
- var_store);
-
- g_signal_connect(dict, "variable-inserted", G_CALLBACK(var_insert_callback),
- var_store);
-
-
- /* The entire model has changed */
- g_sheet_model_range_changed (G_SHEET_MODEL(var_store), -1, -1, -1, -1);
-}
-
static void
psppire_var_store_finalize (GObject *object)
{
(* parent_class->finalize) (object);
}
-static gchar *
-psppire_var_store_get_string(const GSheetModel *model, gint row, gint column)
-{
- PsppireVarStore *store = PSPPIRE_VAR_STORE(model);
-
- struct PsppireVariable *pv;
-
- if ( row >= psppire_dict_get_var_cnt(store->dict))
- return 0;
-
- pv = psppire_dict_get_variable (store->dict, row);
-
- return text_for_column(pv, column, 0);
-}
-
-
-struct PsppireVariable *
-psppire_var_store_get_variable(PsppireVarStore *store, gint row)
-{
- g_return_val_if_fail(store, NULL);
- g_return_val_if_fail(store->dict, NULL);
-
- if ( row >= psppire_dict_get_var_cnt(store->dict))
- return 0;
-
- return psppire_dict_get_variable (store->dict, row);
-}
-
-/* Clears that part of the variable store, if possible, which corresponds
- to ROW, COL.
- Returns true if anything was updated, false otherwise.
-*/
-static gboolean
-psppire_var_store_clear(GSheetModel *model, gint row, gint col)
-{
- struct PsppireVariable *pv ;
-
- PsppireVarStore *var_store = PSPPIRE_VAR_STORE(model);
-
- if ( row >= psppire_dict_get_var_cnt(var_store->dict))
- return FALSE;
-
- pv = psppire_var_store_get_variable(var_store, row);
-
- if ( !pv )
- return FALSE;
-
- switch (col)
- {
- case COL_LABEL:
- psppire_variable_set_label(pv, 0);
- return TRUE;
- break;
- }
-
- return FALSE;
-}
-
-/* Attempts to update that part of the variable store which corresponds
- to ROW, COL with the value TEXT.
- Returns true if anything was updated, false otherwise.
-*/
-static gboolean
-psppire_var_store_set_string(GSheetModel *model,
- const gchar *text, gint row, gint col)
-{
- struct PsppireVariable *pv ;
-
- PsppireVarStore *var_store = PSPPIRE_VAR_STORE(model);
-
- if ( row >= psppire_dict_get_var_cnt(var_store->dict))
- return FALSE;
-
- pv = psppire_var_store_get_variable(var_store, row);
- if ( !pv )
- return FALSE;
-
- switch (col)
- {
- case COL_NAME:
- return psppire_variable_set_name(pv, text);
- break;
- case COL_COLUMNS:
- if ( ! text) return FALSE;
- return psppire_variable_set_columns(pv, atoi(text));
- break;
- case COL_WIDTH:
- if ( ! text) return FALSE;
- return psppire_variable_set_width(pv, atoi(text));
- break;
- case COL_DECIMALS:
- if ( ! text) return FALSE;
- return psppire_variable_set_decimals(pv, atoi(text));
- break;
- case COL_LABEL:
- psppire_variable_set_label(pv, text);
- return TRUE;
- break;
- case COL_TYPE:
- case COL_VALUES:
- case COL_MISSING:
- case COL_ALIGN:
- case COL_MEASURE:
- /* These can be modified only by their respective dialog boxes */
- return FALSE;
- break;
- default:
- g_assert_not_reached();
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-static gchar *
-text_for_column(const struct PsppireVariable *pv, gint c, GError **err)
+static void
+psppire_var_store_dispose (GObject *object)
{
- static gchar none[] = N_("None");
-
- static const gchar *const type_label[] =
- {
- N_("Numeric"),
- N_("Comma"),
- N_("Dot"),
- N_("Scientific"),
- N_("Date"),
- N_("Dollar"),
- N_("Custom"),
- N_("String")
- };
- enum {VT_NUMERIC, VT_COMMA, VT_DOT, VT_SCIENTIFIC, VT_DATE, VT_DOLLAR,
- VT_CUSTOM, VT_STRING};
-
- const struct fmt_spec *write_spec = psppire_variable_get_write_spec(pv);
-
- switch (c)
- {
- case COL_NAME:
- return pspp_locale_to_utf8(psppire_variable_get_name(pv), -1, err);
- break;
- case COL_TYPE:
- {
- switch ( write_spec->type )
- {
- case FMT_F:
- return g_locale_to_utf8(gettext(type_label[VT_NUMERIC]), -1, 0, 0, err);
- break;
- case FMT_COMMA:
- return g_locale_to_utf8(gettext(type_label[VT_COMMA]), -1, 0, 0, err);
- break;
- case FMT_DOT:
- return g_locale_to_utf8(gettext(type_label[VT_DOT]), -1, 0, 0, err);
- break;
- case FMT_E:
- return g_locale_to_utf8(gettext(type_label[VT_SCIENTIFIC]), -1, 0, 0, err);
- break;
- case FMT_DATE:
- case FMT_EDATE:
- case FMT_SDATE:
- case FMT_ADATE:
- case FMT_JDATE:
- case FMT_QYR:
- case FMT_MOYR:
- case FMT_WKYR:
- case FMT_DATETIME:
- case FMT_TIME:
- case FMT_DTIME:
- case FMT_WKDAY:
- case FMT_MONTH:
- return g_locale_to_utf8(type_label[VT_DATE], -1, 0, 0, err);
- break;
- case FMT_DOLLAR:
- return g_locale_to_utf8(type_label[VT_DOLLAR], -1, 0, 0, err);
- break;
- case FMT_CCA:
- case FMT_CCB:
- case FMT_CCC:
- case FMT_CCD:
- case FMT_CCE:
- return g_locale_to_utf8(gettext(type_label[VT_CUSTOM]), -1, 0, 0, err);
- break;
- case FMT_A:
- return g_locale_to_utf8(gettext(type_label[VT_STRING]), -1, 0, 0, err);
- break;
- default:
- {
- char str[FMT_STRING_LEN_MAX + 1];
- g_warning("Unknown format: \"%s\"\n",
- fmt_to_string(write_spec, str));
- }
- break;
- }
- }
- break;
- case COL_WIDTH:
- {
- gchar *s;
- GString *gstr = g_string_sized_new(10);
- g_string_printf(gstr, _("%d"), write_spec->w);
- s = g_locale_to_utf8(gstr->str, gstr->len, 0, 0, err);
- g_string_free(gstr, TRUE);
- return s;
- }
- break;
- case COL_DECIMALS:
- {
- gchar *s;
- GString *gstr = g_string_sized_new(10);
- g_string_printf(gstr, _("%d"), write_spec->d);
- s = g_locale_to_utf8(gstr->str, gstr->len, 0, 0, err);
- g_string_free(gstr, TRUE);
- return s;
- }
- break;
- case COL_COLUMNS:
- {
- gchar *s;
- GString *gstr = g_string_sized_new(10);
- g_string_printf(gstr, _("%d"), psppire_variable_get_columns(pv));
- s = g_locale_to_utf8(gstr->str, gstr->len, 0, 0, err);
- g_string_free(gstr, TRUE);
- return s;
- }
- break;
- case COL_LABEL:
- return pspp_locale_to_utf8(psppire_variable_get_label(pv), -1, err);
- break;
-
- case COL_MISSING:
- {
- gchar *s;
- const struct missing_values *miss = psppire_variable_get_missing(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;
- }
- }
- break;
- case COL_VALUES:
- {
- const struct val_labs *vls = psppire_variable_get_value_labels(pv);
- if ( ! vls || 0 == val_labs_count(vls) )
- return g_locale_to_utf8(gettext(none), -1, 0, 0, err);
- else
- {
- gchar *ss;
- GString *gstr = g_string_sized_new(10);
- struct val_labs_iterator *ip = 0;
- struct val_lab *vl = val_labs_first_sorted (vls, &ip);
-
- g_assert(vl);
-
- {
- gchar *const vstr = value_to_text(vl->value, *write_spec);
-
- g_string_printf(gstr, "{%s,\"%s\"}_", vstr, vl->label);
- g_free(vstr);
- }
-
- val_labs_done(&ip);
-
- ss = pspp_locale_to_utf8(gstr->str, gstr->len, err);
- g_string_free(gstr, TRUE);
- return ss;
- }
- }
- break;
- case COL_ALIGN:
- {
- const gint align = psppire_variable_get_alignment(pv);
+ PsppireVarStore *self = PSPPIRE_VAR_STORE (object);
- g_assert(align < n_ALIGNMENTS);
- return g_locale_to_utf8(gettext(alignments[align]), -1, 0, 0, err);
- }
- break;
- case COL_MEASURE:
- {
- const gint measure = psppire_variable_get_measure(pv);
+ if (self->dictionary)
+ g_object_unref (self->dictionary);
- g_assert(measure < n_MEASURES);
- return g_locale_to_utf8(gettext(measures[measure]), -1, 0, 0, err);
- }
- break;
- }
- return 0;
+ /* must chain up */
+ (* parent_class->finalize) (object);
}
-
/* Return the number of variables */
gint
-psppire_var_store_get_var_cnt(PsppireVarStore *store)
-{
- return psppire_dict_get_var_cnt(store->dict);
-}
-
-
-void
-psppire_var_store_set_font(PsppireVarStore *store, const PangoFontDescription *fd)
-{
- g_return_if_fail (store);
- g_return_if_fail (PSPPIRE_IS_VAR_STORE (store));
-
- store->font_desc = fd;
-
- g_sheet_model_range_changed (G_SHEET_MODEL(store), -1, -1, -1, -1);
-}
-
-
-static gint
-psppire_var_store_get_row_count(const GSheetModel * model)
-{
- gint rows = 0;
- PsppireVarStore *vs = PSPPIRE_VAR_STORE(model);
-
- if (vs->dict)
- rows = psppire_dict_get_var_cnt(vs->dict);
-
- return rows ;
-}
-
-/* Row related funcs */
-
-static gint
-geometry_get_row_count(const GSheetRow *geom, gpointer data)
+psppire_var_store_get_var_cnt (PsppireVarStore *store)
{
- gint rows = 0;
- PsppireVarStore *vs = PSPPIRE_VAR_STORE(geom);
-
- if (vs->dict)
- rows = psppire_dict_get_var_cnt(vs->dict);
-
- return rows + TRAILING_ROWS;
-}
-
-
-static gint
-geometry_get_height(const GSheetRow *geom, gint row, gpointer data)
-{
- return 25;
-}
-
-
-static gboolean
-geometry_is_sensitive(const GSheetRow *geom, gint row, gpointer data)
-{
- PsppireVarStore *vs = PSPPIRE_VAR_STORE(geom);
-
- if ( ! vs->dict)
- return FALSE;
-
- return row < psppire_dict_get_var_cnt(vs->dict);
-}
-
-static
-gboolean always_true()
-{
- return TRUE;
-}
-
-
-static gchar *
-geometry_get_button_label(const GSheetRow *geom, gint unit, gpointer data)
-{
- gchar *label = g_strdup_printf(_("%d"), unit);
-
- return label;
-}
-
-
-static void
-psppire_var_store_sheet_row_init (GSheetRowIface *iface)
-{
- iface->get_row_count = geometry_get_row_count;
- iface->get_height = geometry_get_height;
- iface->set_height = 0;
- iface->get_visibility = always_true;
- iface->get_sensitivity = geometry_is_sensitive;
-
- iface->get_button_label = geometry_get_button_label;
+ return psppire_dict_get_var_cnt (store->dictionary);
}