From 775941da1289c0c3de3895e61cc6e787c6591686 Mon Sep 17 00:00:00 2001 From: John Darrington Date: Tue, 2 Dec 2008 10:42:49 +0900 Subject: [PATCH] Deleted psppire-case-file.[ch] This module was nothing more than a wrapper around src/data/datasheet.c Moved its guts into psppire-data-store.c --- src/ui/gui/automake.mk | 2 - src/ui/gui/find-dialog.c | 2 +- src/ui/gui/helper.c | 3 +- src/ui/gui/psppire-case-file.c | 448 ------------------------------- src/ui/gui/psppire-case-file.h | 112 -------- src/ui/gui/psppire-data-editor.c | 4 +- src/ui/gui/psppire-data-store.c | 283 ++++++++++++++++--- src/ui/gui/psppire-data-store.h | 21 +- src/ui/gui/psppire.c | 4 +- 9 files changed, 263 insertions(+), 616 deletions(-) delete mode 100644 src/ui/gui/psppire-case-file.c delete mode 100644 src/ui/gui/psppire-case-file.h diff --git a/src/ui/gui/automake.mk b/src/ui/gui/automake.mk index 9ac7050c..ee824660 100644 --- a/src/ui/gui/automake.mk +++ b/src/ui/gui/automake.mk @@ -142,8 +142,6 @@ src_ui_gui_psppire_SOURCES = \ src/ui/gui/psppire-buttonbox.h \ src/ui/gui/psppire-hbuttonbox.h \ src/ui/gui/psppire-vbuttonbox.h \ - src/ui/gui/psppire-case-file.c \ - src/ui/gui/psppire-case-file.h \ src/ui/gui/psppire-data-editor.c \ src/ui/gui/psppire-data-editor.h \ src/ui/gui/psppire-data-store.c \ diff --git a/src/ui/gui/find-dialog.c b/src/ui/gui/find-dialog.c index 7764d04a..c69bce82 100644 --- a/src/ui/gui/find-dialog.c +++ b/src/ui/gui/find-dialog.c @@ -221,7 +221,7 @@ find_dialog (GObject *o, gpointer data) NULL); fd.dict = vs->dict; - fd.data = ds->case_file->datasheet; + fd.data = ds->datasheet; fd.variable_entry = get_widget_assert (fd.xml, "find-variable-entry"); fd.value_entry = get_widget_assert (fd.xml, "find-value-entry"); diff --git a/src/ui/gui/helper.c b/src/ui/gui/helper.c index a4ac261c..bae608af 100644 --- a/src/ui/gui/helper.c +++ b/src/ui/gui/helper.c @@ -242,8 +242,7 @@ execute_syntax (struct getl_interface *sss) reader = proc_extract_active_file_data (the_dataset); if (!lazy_casereader_destroy (reader, lazy_serial)) - psppire_data_store_set_case_file (the_data_store, - psppire_case_file_new (reader)); + psppire_data_store_set_reader (the_data_store, reader); som_flush (); diff --git a/src/ui/gui/psppire-case-file.c b/src/ui/gui/psppire-case-file.c deleted file mode 100644 index 717fee48..00000000 --- a/src/ui/gui/psppire-case-file.c +++ /dev/null @@ -1,448 +0,0 @@ -/* 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 - it under the terms of the GNU General Public License as published by - 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, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - 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, see . */ - -#include -#include -#include - -#include "psppire-case-file.h" - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "xalloc.h" -#include "xmalloca.h" - -/* --- prototypes --- */ -static void psppire_case_file_class_init (PsppireCaseFileClass *class); -static void psppire_case_file_init (PsppireCaseFile *case_file); -static void psppire_case_file_finalize (GObject *object); - - -/* --- variables --- */ -static GObjectClass *parent_class = NULL; - -enum {CASE_CHANGED, - CASE_INSERTED, - CASES_DELETED, - n_SIGNALS}; - -static guint signals [n_SIGNALS]; - - -/* --- functions --- */ -/** - * psppire_case_file_get_type: - * @returns: the type ID for accelerator groups. - */ -GType -psppire_case_file_get_type (void) -{ - static GType object_type = 0; - - if (!object_type) - { - static const GTypeInfo object_info = { - sizeof (PsppireCaseFileClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) psppire_case_file_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (PsppireCaseFile), - 0, /* n_preallocs */ - (GInstanceInitFunc) psppire_case_file_init, - }; - - object_type = g_type_register_static (G_TYPE_OBJECT, "PsppireCaseFile", - &object_info, 0); - } - - return object_type; -} - -/* Properties */ -enum -{ - PROP_0, - PROP_DATASHEET, - PROP_READER -}; - - - - -static void -psppire_case_file_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) - -{ - PsppireCaseFile *cf = PSPPIRE_CASE_FILE (object); - - switch (prop_id) - { - case PROP_READER: - cf->datasheet = datasheet_create (g_value_get_pointer (value)); - cf->accessible = TRUE; - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - }; -} - -static void -psppire_case_file_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - PsppireCaseFile *cf = PSPPIRE_CASE_FILE (object); - - switch (prop_id) - { - case PROP_DATASHEET: - g_value_set_pointer (value, cf->datasheet); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - }; -} - - -static void -psppire_case_file_class_init (PsppireCaseFileClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - GParamSpec *datasheet_spec ; - GParamSpec *reader_spec ; - - parent_class = g_type_class_peek_parent (class); - - object_class->finalize = psppire_case_file_finalize; - - datasheet_spec = - g_param_spec_pointer ("datasheet", - "Datasheet", - "A pointer to the datasheet belonging to this object", - G_PARAM_READABLE ); - reader_spec = - g_param_spec_pointer ("casereader", - "CaseReader", - "A pointer to the case reader from which this object is constructed", - G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE ); - - object_class->set_property = psppire_case_file_set_property; - object_class->get_property = psppire_case_file_get_property; - - g_object_class_install_property (object_class, - PROP_DATASHEET, - datasheet_spec); - - g_object_class_install_property (object_class, - PROP_READER, - reader_spec); - - signals [CASE_CHANGED] = - g_signal_new ("case-changed", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_FIRST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, - 1, - G_TYPE_INT); - - - signals [CASE_INSERTED] = - g_signal_new ("case-inserted", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_FIRST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, - 1, - G_TYPE_INT); - - - signals [CASES_DELETED] = - g_signal_new ("cases-deleted", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_FIRST, - 0, - NULL, NULL, - psppire_marshal_VOID__INT_INT, - G_TYPE_NONE, - 2, - G_TYPE_INT, G_TYPE_INT); -} - -static void -psppire_case_file_finalize (GObject *object) -{ - PsppireCaseFile *cf = PSPPIRE_CASE_FILE (object); - - if ( cf->accessible) - datasheet_destroy (cf->datasheet); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -psppire_case_file_init (PsppireCaseFile *cf) -{ - cf->datasheet = NULL; - cf->accessible = FALSE; -} - - -/** - * psppire_case_file_new: - * @returns: a new #PsppireCaseFile object - * - * Creates a new #PsppireCaseFile. - */ -PsppireCaseFile* -psppire_case_file_new (struct casereader *reader) -{ - return g_object_new (G_TYPE_PSPPIRE_CASE_FILE, - "casereader", reader, - NULL); -} - - -gboolean -psppire_case_file_delete_cases (PsppireCaseFile *cf, casenumber n_cases, casenumber first) -{ - g_return_val_if_fail (cf, FALSE); - g_return_val_if_fail (cf->datasheet, FALSE); - g_return_val_if_fail (cf->accessible, FALSE); - - g_return_val_if_fail (first + n_cases <= - psppire_case_file_get_case_count (cf), FALSE); - - datasheet_delete_rows (cf->datasheet, first, n_cases); - - g_signal_emit (cf, signals [CASES_DELETED], 0, first, n_cases); - - return TRUE; -} - -/* Insert case CC into the case file before POSN */ -gboolean -psppire_case_file_insert_case (PsppireCaseFile *cf, - struct ccase *cc, - casenumber posn) -{ - struct ccase tmp; - bool result ; - - g_return_val_if_fail (cf, FALSE); - g_return_val_if_fail (cf->datasheet, FALSE); - g_return_val_if_fail (cf->accessible, FALSE); - - case_clone (&tmp, cc); - result = datasheet_insert_rows (cf->datasheet, posn, &tmp, 1); - - if ( result ) - g_signal_emit (cf, signals [CASE_INSERTED], 0, posn); - else - g_warning ("Cannot insert case at position %ld\n", posn); - - return result; -} - - -casenumber -psppire_case_file_get_case_count (const PsppireCaseFile *cf) -{ - g_return_val_if_fail (cf, FALSE); - g_return_val_if_fail (cf->accessible, FALSE); - - if ( ! cf->datasheet) - return 0; - - return datasheet_get_row_cnt (cf->datasheet); -} - -/* Copies the IDXth value from case CASENUM into VALUE. - If VALUE is null, then memory is allocated is allocated with - malloc. Returns the value if successful, NULL on failure. */ -union value * -psppire_case_file_get_value (const PsppireCaseFile *cf, - casenumber casenum, size_t idx, - union value *value, int width) -{ - bool allocated; - - g_return_val_if_fail (cf, false); - g_return_val_if_fail (cf->datasheet, false); - - g_return_val_if_fail (idx < datasheet_get_column_cnt (cf->datasheet), false); - - if (value == NULL) - { - value = xnmalloc (value_cnt_from_width (width), sizeof *value); - allocated = true; - } - else - allocated = false; - if (!datasheet_get_value (cf->datasheet, casenum, idx, value, width)) - { - if (allocated) - free (value); - value = NULL; - } - return value; -} - -void -psppire_case_file_clear (PsppireCaseFile *cf) -{ - datasheet_destroy (cf->datasheet); - cf->datasheet = NULL; - g_signal_emit (cf, signals [CASES_DELETED], 0, 0, -1); -} - -/* Set the IDXth value of case C to V. - Returns true if successful, false on I/O error. */ -gboolean -psppire_case_file_set_value (PsppireCaseFile *cf, casenumber casenum, gint idx, - union value *v, gint width) -{ - bool ok; - - g_return_val_if_fail (cf, FALSE); - g_return_val_if_fail (cf->datasheet, FALSE); - - g_return_val_if_fail (idx < datasheet_get_column_cnt (cf->datasheet), FALSE); - - ok = datasheet_put_value (cf->datasheet, casenum, idx, v, width); - if (ok) - g_signal_emit (cf, signals [CASE_CHANGED], 0, casenum); - return ok; -} - - - -/* Set the IDXth value of case C using D_IN */ -gboolean -psppire_case_file_data_in (PsppireCaseFile *cf, casenumber casenum, gint idx, - struct substring input, const struct fmt_spec *fmt) -{ - union value *value = NULL; - int width; - bool ok; - - g_return_val_if_fail (cf, FALSE); - g_return_val_if_fail (cf->datasheet, FALSE); - - g_return_val_if_fail (idx < datasheet_get_column_cnt (cf->datasheet), FALSE); - - width = fmt_var_width (fmt); - value = xmalloca (value_cnt_from_width (width) * sizeof *value); - ok = (datasheet_get_value (cf->datasheet, casenum, idx, value, width) - && data_in (input, LEGACY_NATIVE, fmt->type, 0, 0, 0, value, width) - && datasheet_put_value (cf->datasheet, casenum, idx, value, width)); - - if (ok) - g_signal_emit (cf, signals [CASE_CHANGED], 0, casenum); - - freea (value); - - return TRUE; -} - - -void -psppire_case_file_sort (PsppireCaseFile *cf, struct case_ordering *ordering) -{ - struct casereader *sorted_data; - gint c; - - sorted_data = sort_execute (datasheet_make_reader (cf->datasheet), ordering); - cf->datasheet = datasheet_create (sorted_data); - - /* FIXME: Need to have a signal to change a range of cases, instead of - calling a signal many times */ - for ( c = 0 ; c < datasheet_get_row_cnt (cf->datasheet) ; ++c ) - g_signal_emit (cf, signals [CASE_CHANGED], 0, c); -} - - -/* Resize the cases in the casefile, by inserting N_VALUES into every - one of them at the position immediately preceeding WHERE. -*/ -gboolean -psppire_case_file_insert_values (PsppireCaseFile *cf, - gint n_values, gint where) -{ - g_return_val_if_fail (cf, FALSE); - g_return_val_if_fail (cf->accessible, FALSE); - - if ( n_values == 0 ) - return FALSE; - - g_assert (n_values > 0); - - if ( ! cf->datasheet ) - cf->datasheet = datasheet_create (NULL); - - { - union value *values = xcalloc (n_values, sizeof *values); - datasheet_insert_columns (cf->datasheet, values, n_values, where); - free (values); - } - - return TRUE; -} - - -/* Fills C with the CASENUMth case. - Returns true on success, false otherwise. - */ -gboolean -psppire_case_file_get_case (const PsppireCaseFile *cf, casenumber casenum, - struct ccase *c) -{ - g_return_val_if_fail (cf, FALSE); - g_return_val_if_fail (cf->datasheet, FALSE); - - return datasheet_get_row (cf->datasheet, casenum, c); -} - - - -struct casereader * -psppire_case_file_make_reader (PsppireCaseFile *cf) -{ - struct casereader *r = datasheet_make_reader (cf->datasheet); - cf->accessible = FALSE; - return r; -} - diff --git a/src/ui/gui/psppire-case-file.h b/src/ui/gui/psppire-case-file.h deleted file mode 100644 index 12515d2b..00000000 --- a/src/ui/gui/psppire-case-file.h +++ /dev/null @@ -1,112 +0,0 @@ -/* 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 - it under the terms of the GNU General Public License as published by - 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, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - 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, see . */ - - -#ifndef __CASE_FILE_H__ -#define __CASE_FILE_H__ - - -#include -#include - -#include -#include - - - -G_BEGIN_DECLS - - -/* --- type macros --- */ -#define G_TYPE_PSPPIRE_CASE_FILE (psppire_case_file_get_type ()) -#define PSPPIRE_CASE_FILE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), G_TYPE_PSPPIRE_CASE_FILE, PsppireCaseFile)) -#define PSPPIRE_CASE_FILE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), G_TYPE_PSPPIRE_CASE_FILE, PsppireCaseFileClass)) -#define G_IS_PSPPIRE_CASE_FILE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), G_TYPE_PSPPIRE_CASE_FILE)) -#define G_IS_PSPPIRE_CASE_FILE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_PSPPIRE_CASE_FILE)) -#define PSPPIRE_CASE_FILE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_PSPPIRE_CASE_FILE, PsppireCaseFileClass)) - - - - -/* --- typedefs & structures --- */ -typedef struct _PsppireCaseFile PsppireCaseFile; -typedef struct _PsppireCaseFileClass PsppireCaseFileClass; - -struct ccase; -struct casereader; - -struct _PsppireCaseFile -{ - GObject parent; - - /* */ - struct datasheet *datasheet; - gboolean accessible; -}; - - -struct _PsppireCaseFileClass -{ - GObjectClass parent_class; -}; - - -/* -- PsppireCaseFile --- */ -GType psppire_case_file_get_type (void); - -PsppireCaseFile *psppire_case_file_new (struct casereader *); - -gboolean psppire_case_file_insert_case (PsppireCaseFile *cf, struct ccase *c, casenumber row); - -casenumber psppire_case_file_get_case_count (const PsppireCaseFile *cf); - - -union value * psppire_case_file_get_value (const PsppireCaseFile *cf, - casenumber, size_t idx, - union value *, int width); - -struct fmt_spec; - -gboolean psppire_case_file_data_in (PsppireCaseFile *cf, casenumber c, gint idx, - struct substring input, - const struct fmt_spec *); - -gboolean psppire_case_file_set_value (PsppireCaseFile *cf, casenumber casenum, - gint idx, union value *v, gint width); - -void psppire_case_file_clear (PsppireCaseFile *cf); - - -gboolean psppire_case_file_delete_cases (PsppireCaseFile *cf, casenumber n_rows, - casenumber first); - -gboolean psppire_case_file_insert_values (PsppireCaseFile *cf, gint n_values, gint where); - -struct case_ordering; - -void psppire_case_file_sort (PsppireCaseFile *cf, struct case_ordering *); - -gboolean psppire_case_file_get_case (const PsppireCaseFile *cf, - casenumber casenum, - struct ccase *c); - - -struct casereader * psppire_case_file_make_reader (PsppireCaseFile *cf); - - -G_END_DECLS - -#endif /* __PSPPIRE_CASE_FILE_H__ */ diff --git a/src/ui/gui/psppire-data-editor.c b/src/ui/gui/psppire-data-editor.c index 79682fe0..57a08009 100644 --- a/src/ui/gui/psppire-data-editor.c +++ b/src/ui/gui/psppire-data-editor.c @@ -219,7 +219,7 @@ new_data_callback (PsppireDataStore *ds, gpointer data) for (i = 0 ; i < 4 ; ++i) { PsppireAxisUniform *vaxis; - casenumber n_cases = psppire_case_file_get_case_count (ds->case_file); + casenumber n_cases = psppire_data_store_get_case_count (ds); g_object_get (de->data_sheet[i], "vertical-axis", &vaxis, NULL); @@ -1566,7 +1566,7 @@ data_sheet_set_clip (GtkSheet *sheet) { struct ccase old; - if (psppire_case_file_get_case (ds->case_file, i, &old)) + if (psppire_data_store_get_case (ds, i, &old)) { struct ccase new; diff --git a/src/ui/gui/psppire-data-store.c b/src/ui/gui/psppire-data-store.c index 4d5ffcf1..36d1af78 100644 --- a/src/ui/gui/psppire-data-store.c +++ b/src/ui/gui/psppire-data-store.c @@ -30,7 +30,6 @@ #include #include "psppire-data-store.h" -#include "psppire-case-file.h" #include "helper.h" #include @@ -39,6 +38,10 @@ #include #include +#include + +#include "xalloc.h" +#include "xmalloca.h" static void psppire_data_store_init (PsppireDataStore *data_store); static void psppire_data_store_class_init (PsppireDataStoreClass *class); @@ -51,6 +54,18 @@ static gboolean psppire_data_store_clear_datum (GSheetModel *model, glong row, glong column); +static gboolean psppire_data_store_insert_case (PsppireDataStore *ds, + struct ccase *cc, + casenumber posn); + + +static gboolean psppire_data_store_data_in (PsppireDataStore *ds, + casenumber casenum, gint idx, + struct substring input, + const struct fmt_spec *fmt); + + + static GObjectClass *parent_class = NULL; @@ -126,6 +141,23 @@ psppire_data_store_class_init (PsppireDataStoreClass *class) +static gboolean +psppire_data_store_insert_values (PsppireDataStore *ds, + gint n_values, gint where); + +static union value * +psppire_data_store_get_value (const PsppireDataStore *ds, + casenumber casenum, size_t idx, + union value *value, int width); + + +static gboolean +psppire_data_store_set_value (PsppireDataStore *ds, casenumber casenum, + gint idx, union value *v, gint width); + + + + static glong psppire_data_store_get_var_count (const GSheetModel *model) { @@ -137,7 +169,7 @@ psppire_data_store_get_var_count (const GSheetModel *model) casenumber psppire_data_store_get_case_count (const PsppireDataStore *store) { - return psppire_case_file_get_case_count (store->case_file); + return datasheet_get_row_cnt (store->datasheet); } size_t @@ -157,7 +189,7 @@ static void psppire_data_store_init (PsppireDataStore *data_store) { data_store->dict = 0; - data_store->case_file = NULL; + data_store->datasheet = NULL; data_store->dispose_has_run = FALSE; } @@ -239,7 +271,7 @@ insert_case_callback (GtkWidget *w, casenumber casenum, gpointer data) g_sheet_model_range_changed (G_SHEET_MODEL (store), casenum, -1, - psppire_case_file_get_case_count (store->case_file), + psppire_data_store_get_case_count (store), -1); g_sheet_model_rows_inserted (G_SHEET_MODEL (store), casenum, 1); @@ -319,7 +351,7 @@ insert_variable_callback (GObject *obj, gint var_num, gpointer data) posn = 0; } - psppire_case_file_insert_values (store->case_file, 1, posn); + psppire_data_store_insert_values (store, 1, posn); #if AXIS_TRANSITION g_sheet_column_columns_changed (G_SHEET_COLUMN (store), @@ -341,7 +373,7 @@ dict_size_change_callback (GObject *obj, const gint new_val_width = value_cnt_from_width (var_get_width (v)); if ( adjustment > 0 ) - psppire_case_file_insert_values (store->case_file, adjustment, + psppire_data_store_insert_values (store, adjustment, new_val_width - adjustment + var_get_case_index(v)); } @@ -367,25 +399,25 @@ psppire_data_store_new (PsppireDict *dict) return retval; } - void -psppire_data_store_set_case_file (PsppireDataStore *ds, - PsppireCaseFile *cf) +psppire_data_store_set_reader (PsppireDataStore *ds, + struct casereader *reader) { gint i; - if ( ds->case_file) g_object_unref (ds->case_file); - ds->case_file = cf; + + ds->datasheet = datasheet_create (reader); g_sheet_model_range_changed (G_SHEET_MODEL (ds), -1, -1, -1, -1); +#if 0 for (i = 0 ; i < n_cf_signals ; ++i ) { if ( ds->cf_handler_id [i] > 0 ) g_signal_handler_disconnect (ds->case_file, ds->cf_handler_id[i]); } - +#endif if ( ds->dict ) for (i = 0 ; i < n_dict_signals; ++i ) @@ -397,6 +429,7 @@ psppire_data_store_set_case_file (PsppireDataStore *ds, } } +#if 0 ds->cf_handler_id [CASES_DELETED] = g_signal_connect (ds->case_file, "cases-deleted", G_CALLBACK (delete_cases_callback), @@ -411,6 +444,7 @@ psppire_data_store_set_case_file (PsppireDataStore *ds, g_signal_connect (ds->case_file, "case-changed", G_CALLBACK (changed_case_callback), ds); +#endif g_signal_emit (ds, signals[BACKEND_CHANGED], 0); } @@ -500,7 +534,11 @@ psppire_data_store_dispose (GObject *object) if (ds->dispose_has_run) return; - if (ds->case_file) g_object_unref (ds->case_file); + if (ds->datasheet) + { + datasheet_destroy (ds->datasheet); + ds->datasheet = NULL; + } /* must chain up */ (* parent_class->dispose) (object); @@ -509,16 +547,6 @@ psppire_data_store_dispose (GObject *object) } -gboolean -psppire_data_store_delete_cases (PsppireDataStore *ds, - casenumber first, casenumber count) -{ - g_return_val_if_fail (ds, FALSE); - - return psppire_case_file_delete_cases (ds->case_file, count, first); -} - - /* Insert a blank case before POSN */ gboolean @@ -529,7 +557,7 @@ psppire_data_store_insert_new_case (PsppireDataStore *ds, casenumber posn) struct ccase cc; g_return_val_if_fail (ds, FALSE); - val_cnt = datasheet_get_column_cnt (ds->case_file->datasheet) ; + val_cnt = datasheet_get_column_cnt (ds->datasheet) ; g_return_val_if_fail (val_cnt > 0, FALSE); @@ -548,7 +576,7 @@ psppire_data_store_insert_new_case (PsppireDataStore *ds, casenumber posn) case_data_rw (&cc, pv)->f = SYSMIS; } - result = psppire_case_file_insert_case (ds->case_file, &cc, posn); + result = psppire_data_store_insert_case (ds, &cc, posn); case_destroy (&cc); @@ -567,12 +595,12 @@ psppire_data_store_get_string (PsppireDataStore *store, glong row, glong column) GString *s; g_return_val_if_fail (store->dict, NULL); - g_return_val_if_fail (store->case_file, NULL); + g_return_val_if_fail (store->datasheet, NULL); if (column >= psppire_dict_get_var_cnt (store->dict)) return NULL; - if ( row >= psppire_case_file_get_case_count (store->case_file)) + if ( row >= psppire_data_store_get_case_count (store)) return NULL; pv = psppire_dict_get_variable (store->dict, column); @@ -583,7 +611,7 @@ psppire_data_store_get_string (PsppireDataStore *store, glong row, glong column) g_assert (idx >= 0); - v = psppire_case_file_get_value (store->case_file, row, idx, NULL, + v = psppire_data_store_get_value (store, row, idx, NULL, var_get_width (pv)); g_return_val_if_fail (v, NULL); @@ -638,8 +666,8 @@ psppire_data_store_clear_datum (GSheetModel *model, else memcpy (v.s, "", MAX_SHORT_STRING); - psppire_case_file_set_value (store->case_file, row, index, &v, - var_get_width (pv)); + psppire_data_store_set_value (store, row, index, &v, + var_get_width (pv)); return TRUE; } @@ -665,9 +693,9 @@ psppire_data_store_set_string (PsppireDataStore *store, if (row == n_cases) psppire_data_store_insert_new_case (store, row); - psppire_case_file_data_in (store->case_file, row, - var_get_case_index (pv), ss_cstr (text), - var_get_write_format (pv)); + psppire_data_store_data_in (store, row, + var_get_case_index (pv), ss_cstr (text), + var_get_write_format (pv)); return TRUE; } @@ -688,11 +716,14 @@ psppire_data_store_show_labels (PsppireDataStore *store, gboolean show_labels) void -psppire_data_store_clear (PsppireDataStore *data_store) +psppire_data_store_clear (PsppireDataStore *ds) { - psppire_case_file_clear (data_store->case_file); + datasheet_destroy (ds->datasheet); + ds->datasheet = NULL; + + psppire_dict_clear (ds->dict); - psppire_dict_clear (data_store->dict); + g_signal_emit (ds, signals [CASES_DELETED], 0, 0, -1); } @@ -704,11 +735,13 @@ psppire_data_store_get_reader (PsppireDataStore *ds) int i; struct casereader *reader ; +#if 0 for (i = 0 ; i < n_cf_signals ; ++i ) { g_signal_handler_disconnect (ds->case_file, ds->cf_handler_id[i]); ds->cf_handler_id[i] = 0 ; } +#endif if ( ds->dict ) for (i = 0 ; i < n_dict_signals; ++i ) @@ -717,9 +750,7 @@ psppire_data_store_get_reader (PsppireDataStore *ds) ds->dict_handler_id[i]); } - reader = psppire_case_file_make_reader (ds->case_file); - - return reader; + return datasheet_make_reader (ds->datasheet); } @@ -736,8 +767,6 @@ static const gchar null_var_name[]=N_("var"); static gchar * get_row_button_label (const GSheetModel *model, gint unit) { - PsppireDataStore *ds = PSPPIRE_DATA_STORE (model); - gchar *s = g_strdup_printf (_("%d"), unit + FIRST_CASE_NUMBER); gchar *text = pspp_locale_to_utf8 (s, -1, 0); @@ -753,7 +782,7 @@ get_row_sensitivity (const GSheetModel *model, gint unit) { PsppireDataStore *ds = PSPPIRE_DATA_STORE (model); - return (unit < psppire_case_file_get_case_count (ds->case_file)); + return (unit < psppire_data_store_get_case_count (ds)); } @@ -825,3 +854,173 @@ get_column_justification (const GSheetModel *model, gint col) } + + + + +/* Fills C with the CASENUMth case. + Returns true on success, false otherwise. + */ +gboolean +psppire_data_store_get_case (const PsppireDataStore *ds, + casenumber casenum, + struct ccase *c) +{ + g_return_val_if_fail (ds, FALSE); + g_return_val_if_fail (ds->datasheet, FALSE); + + return datasheet_get_row (ds->datasheet, casenum, c); +} + + +gboolean +psppire_data_store_delete_cases (PsppireDataStore *ds, casenumber n_cases, + casenumber first) +{ + g_return_val_if_fail (ds, FALSE); + g_return_val_if_fail (ds->datasheet, FALSE); + + g_return_val_if_fail (first + n_cases <= + psppire_data_store_get_case_count (ds), FALSE); + + datasheet_delete_rows (ds->datasheet, first, n_cases); + + g_signal_emit (ds, signals [CASES_DELETED], 0, first, n_cases); + + return TRUE; +} + + + +/* Insert case CC into the case file before POSN */ +static gboolean +psppire_data_store_insert_case (PsppireDataStore *ds, + struct ccase *cc, + casenumber posn) +{ + struct ccase tmp; + bool result ; + + g_return_val_if_fail (ds, FALSE); + g_return_val_if_fail (ds->datasheet, FALSE); + + case_clone (&tmp, cc); + result = datasheet_insert_rows (ds->datasheet, posn, &tmp, 1); + + if ( result ) + g_signal_emit (ds, signals [CASE_INSERTED], 0, posn); + else + g_warning ("Cannot insert case at position %ld\n", posn); + + return result; +} + + +/* Copies the IDXth value from case CASENUM into VALUE. + If VALUE is null, then memory is allocated is allocated with + malloc. Returns the value if successful, NULL on failure. */ +static union value * +psppire_data_store_get_value (const PsppireDataStore *ds, + casenumber casenum, size_t idx, + union value *value, int width) +{ + bool allocated; + + g_return_val_if_fail (ds, false); + g_return_val_if_fail (ds->datasheet, false); + + g_return_val_if_fail (idx < datasheet_get_column_cnt (ds->datasheet), false); + + if (value == NULL) + { + value = xnmalloc (value_cnt_from_width (width), sizeof *value); + allocated = true; + } + else + allocated = false; + if (!datasheet_get_value (ds->datasheet, casenum, idx, value, width)) + { + if (allocated) + free (value); + value = NULL; + } + return value; +} + + + +/* Set the IDXth value of case C to V. + Returns true if successful, false on I/O error. */ +static gboolean +psppire_data_store_set_value (PsppireDataStore *ds, casenumber casenum, + gint idx, union value *v, gint width) +{ + bool ok; + + g_return_val_if_fail (ds, FALSE); + g_return_val_if_fail (ds->datasheet, FALSE); + + g_return_val_if_fail (idx < datasheet_get_column_cnt (ds->datasheet), FALSE); + + ok = datasheet_put_value (ds->datasheet, casenum, idx, v, width); + if (ok) + g_signal_emit (ds, signals [CASE_CHANGED], 0, casenum); + return ok; +} + + + + +/* Set the IDXth value of case C using D_IN */ +static gboolean +psppire_data_store_data_in (PsppireDataStore *ds, casenumber casenum, gint idx, + struct substring input, const struct fmt_spec *fmt) +{ + union value *value = NULL; + int width; + bool ok; + + g_return_val_if_fail (ds, FALSE); + g_return_val_if_fail (ds->datasheet, FALSE); + + g_return_val_if_fail (idx < datasheet_get_column_cnt (ds->datasheet), FALSE); + + width = fmt_var_width (fmt); + value = xmalloca (value_cnt_from_width (width) * sizeof *value); + ok = (datasheet_get_value (ds->datasheet, casenum, idx, value, width) + && data_in (input, LEGACY_NATIVE, fmt->type, 0, 0, 0, value, width) + && datasheet_put_value (ds->datasheet, casenum, idx, value, width)); + + if (ok) + g_signal_emit (ds, signals [CASE_CHANGED], 0, casenum); + + freea (value); + + return TRUE; +} + +/* Resize the cases in the casefile, by inserting N_VALUES into every + one of them at the position immediately preceeding WHERE. +*/ +static gboolean +psppire_data_store_insert_values (PsppireDataStore *ds, + gint n_values, gint where) +{ + g_return_val_if_fail (ds, FALSE); + + if ( n_values == 0 ) + return FALSE; + + g_assert (n_values > 0); + + if ( ! ds->datasheet ) + ds->datasheet = datasheet_create (NULL); + + { + union value *values = xcalloc (n_values, sizeof *values); + datasheet_insert_columns (ds->datasheet, values, n_values, where); + free (values); + } + + return TRUE; +} diff --git a/src/ui/gui/psppire-data-store.h b/src/ui/gui/psppire-data-store.h index 058f9e14..0e988633 100644 --- a/src/ui/gui/psppire-data-store.h +++ b/src/ui/gui/psppire-data-store.h @@ -18,7 +18,6 @@ #define __PSPPIRE_DATA_STORE_H__ #include "psppire-dict.h" -#include "psppire-case-file.h" #define FIRST_CASE_NUMBER 1 @@ -71,6 +70,9 @@ enum dict_signal_handler { }; +struct datasheet; +struct casereader; + struct _PsppireDataStore { GObject parent; @@ -78,7 +80,7 @@ struct _PsppireDataStore /*< private >*/ gboolean dispose_has_run ; PsppireDict *dict; - PsppireCaseFile *case_file; + struct datasheet *datasheet; gboolean show_labels; @@ -95,8 +97,9 @@ struct _PsppireDataStoreClass GType psppire_data_store_get_type (void) G_GNUC_CONST; PsppireDataStore *psppire_data_store_new (PsppireDict *dict); -void psppire_data_store_set_case_file (PsppireDataStore *data_store, - PsppireCaseFile *cf); + +void psppire_data_store_set_reader (PsppireDataStore *ds, + struct casereader *reader); void psppire_data_store_set_dictionary (PsppireDataStore *data_store, PsppireDict *dict); @@ -124,6 +127,16 @@ gboolean psppire_data_store_set_string (PsppireDataStore *ds, casenumber psppire_data_store_get_case_count (const PsppireDataStore *ds); size_t psppire_data_store_get_value_count (const PsppireDataStore *ds); + + + +gboolean psppire_data_store_get_case (const PsppireDataStore *ds, + casenumber casenum, + struct ccase *c); + + + + G_END_DECLS #endif /* __PSPPIRE_DATA_STORE_H__ */ diff --git a/src/ui/gui/psppire.c b/src/ui/gui/psppire.c index d36a802c..02415d68 100644 --- a/src/ui/gui/psppire.c +++ b/src/ui/gui/psppire.c @@ -72,9 +72,7 @@ struct dataset * the_dataset = NULL; static void replace_casereader (struct casereader *s) { - PsppireCaseFile *pcf = psppire_case_file_new (s); - - psppire_data_store_set_case_file (the_data_store, pcf); + psppire_data_store_set_reader (the_data_store, s); } #define _(msgid) gettext (msgid) -- 2.30.2