(Re)enabled cell reference entry and datum entry widgets.
[pspp-builds.git] / src / ui / gui / psppire-data-store.c
index d75348584211afe2e72b3dbe5da8f8975c6d7fc9..af205ccde2c8613c6653ccfe61449b5b459435c2 100644 (file)
@@ -25,8 +25,8 @@
 #define _(msgid) gettext (msgid)
 #define N_(msgid) msgid
 
-#include <data/casefile.h>
-#include <data/case.h>
+#include <data/casewriter.h>
+#include <data/datasheet.h>
 #include <data/data-out.h>
 #include <data/variable.h>
 
@@ -58,11 +58,6 @@ static void psppire_data_store_sheet_row_init (GSheetRowIface *iface);
 
 static void psppire_data_store_finalize        (GObject           *object);
 
-static gchar *psppire_data_store_get_string (const GSheetModel *sheet_model, gint row, gint column);
-
-static gboolean psppire_data_store_set_string (GSheetModel *model,
-                                         const gchar *text, gint row, gint column);
-
 static gboolean psppire_data_store_clear_datum (GSheetModel *model,
                                          gint row, gint column);
 
@@ -77,7 +72,7 @@ static GObjectClass *parent_class = NULL;
 enum  {FONT_CHANGED,
        n_SIGNALS};
 
-static guint signal[n_SIGNALS];
+static guint signal[n_SIGNALS];
 
 
 inline GType
@@ -152,7 +147,7 @@ psppire_data_store_class_init (PsppireDataStoreClass *class)
 
   object_class->finalize = psppire_data_store_finalize;
 
-  signal[FONT_CHANGED] =
+  signal[FONT_CHANGED] =
     g_signal_new ("font_changed",
                  G_TYPE_FROM_CLASS (class),
                  G_SIGNAL_RUN_FIRST,
@@ -199,13 +194,32 @@ psppire_data_store_get_font_desc (const GSheetModel *model,
   return store->font_desc;
 }
 
+static inline gchar *
+psppire_data_store_get_string_wrapper (const GSheetModel *model, gint row,
+                                      gint column)
+{
+  return psppire_data_store_get_string (PSPPIRE_DATA_STORE (model), row, column);
+}
+
+
+static inline gboolean
+psppire_data_store_set_string_wrapper (GSheetModel *model,
+                                      const gchar *text,
+                                      gint row, gint column)
+{
+  return psppire_data_store_set_string (PSPPIRE_DATA_STORE (model), text,
+                                       row, column);
+}
+
+
+
 
 static void
 psppire_data_store_sheet_model_init (GSheetModelIface *iface)
 {
   iface->free_strings = TRUE;
-  iface->get_string = psppire_data_store_get_string;
-  iface->set_string = psppire_data_store_set_string;
+  iface->get_string = psppire_data_store_get_string_wrapper;
+  iface->set_string = psppire_data_store_set_string_wrapper;
   iface->clear_datum = psppire_data_store_clear_datum;
   iface->is_editable = NULL;
   iface->is_visible = NULL;
@@ -286,6 +300,25 @@ delete_variables_callback (GObject *obj, gint var_num, gint n_vars, gpointer dat
                                   var_num, -1);
 }
 
+
+static void
+variable_changed_callback (GObject *obj, gint var_num, gpointer data)
+{
+  PsppireDataStore *store;
+
+  g_return_if_fail (data);
+
+  store  = PSPPIRE_DATA_STORE (data);
+
+  g_sheet_column_columns_changed (G_SHEET_COLUMN (store),
+                                 var_num, 1);
+
+
+  g_sheet_model_range_changed (G_SHEET_MODEL (store),
+                              -1, var_num,
+                              -1, var_num);
+}
+
 static void
 insert_variable_callback (GObject *obj, gint var_num, gpointer data)
 {
@@ -298,8 +331,10 @@ insert_variable_callback (GObject *obj, gint var_num, gpointer data)
 
   if ( var_num > 0 )
     {
-      struct variable *variable;
-      variable = psppire_dict_get_variable (store->dict, var_num);
+      struct variable *variable =
+       psppire_dict_get_variable (store->dict, var_num);
+
+      g_assert (variable != NULL);
 
       posn = var_get_case_index (variable);
     }
@@ -348,34 +383,20 @@ psppire_data_store_new (PsppireDict *dict)
 
   psppire_data_store_set_dictionary (retval, dict);
 
-
   return retval;
 }
 
 
-
-/**
- * psppire_data_store_replace_set_dictionary:
- * @data_store: The variable store
- * @dict: The dictionary to set
- *
- * If a dictionary is already associated with the data-store, then it will be
- * destroyed.
- **/
 void
-psppire_data_store_set_dictionary (PsppireDataStore *data_store, PsppireDict *dict)
+psppire_data_store_set_case_file (PsppireDataStore *data_store,
+                                 PsppireCaseFile *cf)
 {
-  gint var_cnt = psppire_dict_get_next_value_idx (dict);
-
-  data_store->dict = dict;
-
   if ( data_store->case_file)
     {
       g_object_unref (data_store->case_file);
-      data_store->case_file = 0;
     }
 
-  data_store->case_file = psppire_case_file_new (var_cnt);
+  data_store->case_file = cf;
 
   g_signal_connect (data_store->case_file, "cases-deleted",
                   G_CALLBACK (delete_cases_callback),
@@ -389,6 +410,22 @@ psppire_data_store_set_dictionary (PsppireDataStore *data_store, PsppireDict *di
   g_signal_connect (data_store->case_file, "case-changed",
                   G_CALLBACK (changed_case_callback),
                   data_store);
+}
+
+
+
+/**
+ * psppire_data_store_replace_set_dictionary:
+ * @data_store: The variable store
+ * @dict: The dictionary to set
+ *
+ * If a dictionary is already associated with the data-store, then it will be
+ * destroyed.
+ **/
+void
+psppire_data_store_set_dictionary (PsppireDataStore *data_store, PsppireDict *dict)
+{
+  data_store->dict = dict;
 
   g_signal_connect (dict, "variable-inserted",
                   G_CALLBACK (insert_variable_callback),
@@ -398,6 +435,11 @@ psppire_data_store_set_dictionary (PsppireDataStore *data_store, PsppireDict *di
                   G_CALLBACK (delete_variables_callback),
                   data_store);
 
+  g_signal_connect (dict, "variable-changed",
+                  G_CALLBACK (variable_changed_callback),
+                  data_store);
+
+
   g_signal_connect (dict, "dict-size-changed",
                    G_CALLBACK (dict_size_change_callback),
                    data_store);
@@ -429,7 +471,7 @@ psppire_data_store_insert_new_case (PsppireDataStore *ds, gint posn)
 
 
   /* Opportunity for optimisation exists here when creating a blank case */
-  val_cnt = casefile_get_value_cnt (ds->case_file->flexifile) ;
+  val_cnt = datasheet_get_column_cnt (ds->case_file->datasheet) ;
 
   case_create (&cc, val_cnt);
 
@@ -452,16 +494,15 @@ psppire_data_store_insert_new_case (PsppireDataStore *ds, gint posn)
 }
 
 
-static gchar *
-psppire_data_store_get_string (const GSheetModel *model, gint row, gint column)
+gchar *
+psppire_data_store_get_string (PsppireDataStore *store, gint row, gint column)
 {
   gint idx;
   char *text;
   const struct fmt_spec *fp ;
   const struct variable *pv ;
-  const union value *v ;
+  union value *v ;
   GString *s;
-  PsppireDataStore *store = PSPPIRE_DATA_STORE (model);
 
   g_return_val_if_fail (store->dict, NULL);
   g_return_val_if_fail (store->case_file, NULL);
@@ -474,21 +515,25 @@ psppire_data_store_get_string (const GSheetModel *model, gint row, gint column)
 
   pv = psppire_dict_get_variable (store->dict, column);
 
+  g_assert (pv);
+
   idx = var_get_case_index (pv);
 
-  v = psppire_case_file_get_value (store->case_file, row, idx);
+  g_assert (idx >= 0);
+
+  v = psppire_case_file_get_value (store->case_file, row, idx, NULL,
+                                   var_get_width (pv));
 
   g_return_val_if_fail (v, NULL);
 
   if ( store->show_labels)
     {
-      const struct val_labs * vl = var_get_value_labels (pv);
-
-      const gchar *label;
-      if ( (label = val_labs_find (vl, *v)) )
-       {
+      const gchar *label = var_lookup_value_label (pv, v);
+      if (label)
+        {
+          free (v);
          return pspp_locale_to_utf8 (label, -1, 0);
-       }
+        }
     }
 
   fp = var_get_write_format (pv);
@@ -510,6 +555,7 @@ psppire_data_store_get_string (const GSheetModel *model, gint row, gint column)
 
   g_strchomp (text);
 
+  free (v);
   return text;
 }
 
@@ -542,12 +588,10 @@ psppire_data_store_clear_datum (GSheetModel *model,
    to ROW, COL with  the value TEXT.
    Returns true if anything was updated, false otherwise.
 */
-static gboolean
-psppire_data_store_set_string (GSheetModel *model,
-                         const gchar *text, gint row, gint col)
+gboolean
+psppire_data_store_set_string (PsppireDataStore *store,
+                              const gchar *text, gint row, gint col)
 {
-  PsppireDataStore *store = PSPPIRE_DATA_STORE (model);
-
   const struct variable *pv = psppire_dict_get_variable (store->dict, col);
   g_return_val_if_fail (pv, FALSE);
 
@@ -585,7 +629,7 @@ psppire_data_store_set_font (PsppireDataStore *store,
 #if 0
   store->width_of_m = calc_m_width (fd);
 #endif
-  g_signal_emit (store, signal[FONT_CHANGED], 0);
+  g_signal_emit (store, signal[FONT_CHANGED], 0);
 
 
   g_sheet_model_range_changed (G_SHEET_MODEL (store),
@@ -620,7 +664,7 @@ psppire_data_store_create_system_file (PsppireDataStore *store,
     3 /* version */
   };
 
-  struct sfm_writer *writer ;
+  struct casewriter *writer;
 
   g_assert (handle);
 
@@ -635,15 +679,10 @@ psppire_data_store_create_system_file (PsppireDataStore *store,
   for (i = 0 ; i < psppire_case_file_get_case_count (store->case_file); ++i )
     {
       struct ccase c;
-
-      case_create (&c, var_cnt);
       psppire_case_file_get_case (store->case_file, i, &c);
-      sfm_write_case (writer, &c);
-
-      case_destroy (&c);
+      casewriter_write (writer, &c);
     }
-
-  sfm_close_writer (writer);
+  casewriter_destroy (writer);
 }
 
 
@@ -658,6 +697,18 @@ psppire_data_store_clear (PsppireDataStore *data_store)
 
 
 
+/* Return a casereader made from this datastore */
+struct casereader *
+psppire_data_store_get_reader (PsppireDataStore *ds)
+{
+  struct casereader *reader ;
+
+  reader = psppire_case_file_make_reader (ds->case_file);
+
+  return reader;
+}
+
+
 
 /* Column related funcs */
 
@@ -821,3 +872,6 @@ psppire_data_store_sheet_row_init (GSheetRowIface *iface)
 
   iface->get_button_label = geometry_get_row_button_label;
 }
+
+
+