Merge remote-tracking branch 'origin/master' into sheet
[pspp] / src / ui / gui / psppire-data-editor.c
index 1c6143aaf4df167310b2d517915f09b4e43bd247..147ffcd4c3b50ec4f0ea479d27a2278cd69d241d 100644 (file)
 #include "libpspp/range-set.h"
 #include "libpspp/str.h"
 #include "ui/gui/helper.h"
-#include "ui/gui/pspp-sheet-selection.h"
-#include "ui/gui/psppire-data-sheet.h"
 #include "ui/gui/psppire-data-store.h"
 #include "ui/gui/psppire-value-entry.h"
-#include "ui/gui/psppire-var-sheet.h"
 #include "ui/gui/psppire-conf.h"
+#include "ui/gui/psppire-var-sheet-header.h"
+
+#include "ui/gui/efficient-sheet/jmd-sheet.h"
 
 #include <gettext.h>
 #define _(msgid) gettext (msgid)
 
-#define FOR_EACH_DATA_SHEET(DATA_SHEET, IDX, DATA_EDITOR)       \
-  for ((IDX) = 0;                                               \
-       (IDX) < 4                                                \
-         && ((DATA_SHEET) = PSPPIRE_DATA_SHEET (                \
-               (DATA_EDITOR)->data_sheets[IDX])) != NULL;       \
-       (IDX)++)
+
+static GtkCellRenderer *
+create_spin_renderer (GType type)
+{
+  GtkCellRenderer *r = gtk_cell_renderer_spin_new ();
+      
+  GtkAdjustment *adj = gtk_adjustment_new (0,
+                                          0, G_MAXDOUBLE,
+                                          1, 1,
+                                          0);
+  g_object_set (r,
+               "adjustment", adj,
+               NULL);
+  
+  return r;
+}
+
+static GtkCellRenderer *
+create_combo_renderer (GType type)
+{
+  GtkListStore *list_store = gtk_list_store_new (2, G_TYPE_INT, G_TYPE_STRING);
+  
+  GEnumClass *ec = g_type_class_ref (type);
+  
+  const GEnumValue *ev ;
+  for (ev = ec->values; ev->value_name; ++ev)
+    {
+      GtkTreeIter iter;
+
+      gtk_list_store_append (list_store, &iter);
+
+      gtk_list_store_set (list_store, &iter,
+                         0, ev->value,
+                         1, gettext (ev->value_nick),
+                         -1);
+    }
+
+  GtkCellRenderer *r = gtk_cell_renderer_combo_new ();
+
+  g_object_set (r,
+               "model", list_store,
+               "text-column", 1,
+               "has-entry", TRUE,
+               NULL);
+
+  return r;
+}
+
+GtkCellRenderer *xx ;
+GtkCellRenderer *column_width_renderer ;
+GtkCellRenderer *measure_renderer ;
+GtkCellRenderer *alignment_renderer ;
+
+
+
+static GtkCellRenderer *
+select_renderer_func (gint col, gint row, GType type)
+{
+  if (!xx)
+    xx = create_spin_renderer (type);
+
+  if (col == DICT_TVM_COL_ROLE && !column_width_renderer)
+    column_width_renderer = create_combo_renderer (type);
+
+  if (col == DICT_TVM_COL_MEASURE && !measure_renderer)
+    measure_renderer = create_combo_renderer (type);
+
+  if (col == DICT_TVM_COL_ALIGNMENT && !alignment_renderer)
+    alignment_renderer = create_combo_renderer (type);
+
+  switch  (col)
+    {
+    case DICT_TVM_COL_WIDTH:
+    case DICT_TVM_COL_DECIMAL:
+    case DICT_TVM_COL_COLUMNS:
+      return xx;
+      
+    case DICT_TVM_COL_ALIGNMENT:
+      return alignment_renderer;
+
+    case DICT_TVM_COL_MEASURE:
+      return measure_renderer;
+      
+    case DICT_TVM_COL_ROLE:
+      return column_width_renderer;
+    }
+  
+  return NULL;
+}
+
 
 static void psppire_data_editor_class_init          (PsppireDataEditorClass *klass);
 static void psppire_data_editor_init                (PsppireDataEditor      *de);
@@ -119,13 +203,52 @@ enum
 static void
 psppire_data_editor_refresh_model (PsppireDataEditor *de)
 {
-  PsppireVarSheet *var_sheet = PSPPIRE_VAR_SHEET (de->var_sheet);
-  PsppireDataSheet *data_sheet;
-  int i;
+}
+
+static void
+change_var_property (PsppireDict *dict, gint col, gint row, GValue *value)
+{
+  /* Return the IDXth variable */
+  struct variable *var =  psppire_dict_get_variable (dict, row);
+
+  switch (col)
+    {
+    case DICT_TVM_COL_NAME:
+      dict_rename_var (dict->dict, var, g_value_get_string (value));
+      break;
+    case DICT_TVM_COL_LABEL:
+      var_set_label (var, g_value_get_string (value));
+      break;
+    case DICT_TVM_COL_COLUMNS:
+      var_set_display_width (var, g_value_get_int (value));
+      break;
+    case DICT_TVM_COL_MEASURE:
+      var_set_measure (var, g_value_get_enum (value));
+      break;
+    case DICT_TVM_COL_ALIGNMENT:
+      var_set_alignment (var, g_value_get_enum (value));
+      break;
+    case DICT_TVM_COL_ROLE:
+      var_set_role (var, g_value_get_enum (value));
+      break;
+    default:
+      g_message ("Changing col %d of var sheet not yet supported", col);
+      break;
+    }
+}
+
+static void
+change_data_value (PsppireDataStore *store, gint col, gint row, GValue *value)
+{
+  const struct variable *var = psppire_dict_get_variable (store->dict, col);
+
+  union value v;
+  value_init (&v, var_get_width (var));
+  v.f = g_value_get_double (value);
+  
+  psppire_data_store_set_value (store, row, var, &v);
 
-  FOR_EACH_DATA_SHEET (data_sheet, i, de)
-    psppire_data_sheet_set_data_store (data_sheet, de->data_store);
-  psppire_var_sheet_set_dictionary (var_sheet, de->dict);
+  value_destroy (&v, var_get_width (var));
 }
 
 static void
@@ -135,8 +258,6 @@ psppire_data_editor_set_property (GObject         *object,
                                  GParamSpec      *pspec)
 {
   PsppireDataEditor *de = PSPPIRE_DATA_EDITOR (object);
-  PsppireDataSheet *data_sheet;
-  int i;
 
   switch (prop_id)
     {
@@ -154,8 +275,14 @@ psppire_data_editor_set_property (GObject         *object,
 
       de->data_store = g_value_get_pointer (value);
       g_object_ref (de->data_store);
+      g_print ("NEW STORE\n");
+
+      g_object_set (de->data_sheet, "data-model", de->data_store, NULL);
       psppire_data_editor_refresh_model (de);
 
+      g_signal_connect_swapped (de->data_sheet, "value-changed",
+                               G_CALLBACK (change_data_value), de->data_store);
+      
       g_signal_connect_swapped (de->data_store, "case-changed",
                                 G_CALLBACK (refresh_entry), de);
 
@@ -166,13 +293,13 @@ psppire_data_editor_set_property (GObject         *object,
       de->dict = g_value_get_pointer (value);
       g_object_ref (de->dict);
 
-      psppire_var_sheet_set_dictionary (PSPPIRE_VAR_SHEET (de->var_sheet),
-                                        de->dict);
+      g_object_set (de->data_sheet, "hmodel", de->dict, NULL);
+      g_object_set (de->var_sheet, "data-model", de->dict, NULL);
+      g_signal_connect_swapped (de->var_sheet, "value-changed",
+                               G_CALLBACK (change_var_property), de->dict);
+
       break;
     case PROP_VALUE_LABELS:
-      FOR_EACH_DATA_SHEET (data_sheet, i, de)
-        psppire_data_sheet_set_value_labels (data_sheet,
-                                          g_value_get_boolean (value));
       break;
 
     default:
@@ -201,9 +328,6 @@ psppire_data_editor_get_property (GObject         *object,
       g_value_set_pointer (value, de->dict);
       break;
     case PROP_VALUE_LABELS:
-      g_value_set_boolean (value,
-                           psppire_data_sheet_get_value_labels (
-                             PSPPIRE_DATA_SHEET (de->data_sheets[0])));
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -295,390 +419,98 @@ psppire_data_editor_class_init (PsppireDataEditorClass *klass)
 
 }
 
-static gboolean
-on_data_sheet_var_double_clicked (PsppireDataSheet *data_sheet,
-                                  gint dict_index,
-                                  PsppireDataEditor *de)
+
+static void
+on_var_sheet_var_double_clicked (void *var_sheet, gint dict_index,
+                                 PsppireDataEditor *de)
 {
   gtk_notebook_set_current_page (GTK_NOTEBOOK (de),
-                                 PSPPIRE_DATA_EDITOR_VARIABLE_VIEW);
-
-  psppire_var_sheet_goto_variable (PSPPIRE_VAR_SHEET (de->var_sheet),
-                                   dict_index);
+                                 PSPPIRE_DATA_EDITOR_DATA_VIEW);
 
-  return TRUE;
+  jmd_sheet_scroll_to (JMD_SHEET (de->data_sheet), dict_index, -1);
 }
 
-static gboolean
-on_var_sheet_var_double_clicked (PsppireVarSheet *var_sheet, gint dict_index,
+
+static void
+on_data_sheet_var_double_clicked (JmdSheet *data_sheet, gint dict_index,
                                  PsppireDataEditor *de)
 {
-  PsppireDataSheet *data_sheet;
-
+  
   gtk_notebook_set_current_page (GTK_NOTEBOOK (de),
-                                 PSPPIRE_DATA_EDITOR_DATA_VIEW);
-
-  data_sheet = psppire_data_editor_get_active_data_sheet (de);
-  psppire_data_sheet_goto_variable (data_sheet, dict_index);
+                                 PSPPIRE_DATA_EDITOR_VARIABLE_VIEW);
 
-  return TRUE;
+  jmd_sheet_scroll_to (JMD_SHEET (de->var_sheet), -1, dict_index);
 }
 
+
+
 /* Refreshes 'de->cell_ref_label' and 'de->datum_entry' from the currently
    active cell or cells. */
 static void
 refresh_entry (PsppireDataEditor *de)
 {
-  PsppireDataSheet *data_sheet = psppire_data_editor_get_active_data_sheet (de);
-  PsppSheetView *sheet_view = PSPP_SHEET_VIEW (data_sheet);
-  PsppSheetSelection *selection = pspp_sheet_view_get_selection (sheet_view);
-
-  gchar *ref_cell_text;
-  GList *selected_columns, *iter;
-  struct variable *var;
-  gint n_cases;
-  gint n_vars;
-
-  selected_columns = pspp_sheet_selection_get_selected_columns (selection);
-  n_vars = 0;
-  var = NULL;
-  for (iter = selected_columns; iter != NULL; iter = iter->next)
-    {
-      PsppSheetViewColumn *column = iter->data;
-      struct variable *v = g_object_get_data (G_OBJECT (column), "variable");
-      if (v != NULL)
-        {
-          var = v;
-          n_vars++;
-        }
-    }
-  g_list_free (selected_columns);
-
-  n_cases = pspp_sheet_selection_count_selected_rows (selection);
-  if (n_cases > 0)
-    {
-      /* The final row is selectable but it isn't a case (it's just used to add
-         more cases), so don't count it. */
-      GtkTreePath *path;
-      gint case_count;
-
-      case_count = psppire_data_store_get_case_count (de->data_store);
-      path = gtk_tree_path_new_from_indices (case_count, -1);
-      if (pspp_sheet_selection_path_is_selected (selection, path))
-        n_cases--;
-      gtk_tree_path_free (path);
-    }
-
-  ref_cell_text = NULL;
-  if (n_cases == 1 && n_vars == 1)
-    {
-      PsppireValueEntry *value_entry = PSPPIRE_VALUE_ENTRY (de->datum_entry);
-      struct range_set *selected_rows;
-      gboolean show_value_labels;
-      union value value;
-      int width;
-      gint row;
-
-      selected_rows = pspp_sheet_selection_get_range_set (selection);
-      row = range_set_scan (selected_rows, 0);
-      range_set_destroy (selected_rows);
-
-      ref_cell_text = g_strdup_printf ("%d : %s", row + 1, var_get_name (var));
-
-      show_value_labels = psppire_data_sheet_get_value_labels (data_sheet);
-
-      psppire_value_entry_set_variable (value_entry, var);
-      psppire_value_entry_set_show_value_label (value_entry,
-                                                show_value_labels);
-
-      width = var_get_width (var);
-      value_init (&value, width);
-      datasheet_get_value (de->data_store->datasheet,
-                           row, var_get_case_index (var), &value);
-      psppire_value_entry_set_value (value_entry, &value, width);
-      value_destroy (&value, width);
-
-      gtk_widget_set_sensitive (de->datum_entry, TRUE);
-    }
-  else
-    {
-      if (n_cases == 0 || n_vars == 0)
-        {
-          ref_cell_text = NULL;
-        }
-      else
-        {
-          struct string s;
-
-          /* The glib string library does not understand the ' printf modifier
-             on all platforms, but the "struct string" library does (because
-             Gnulib fixes that problem), so use the latter.  */
-          ds_init_empty (&s);
-          ds_put_format (&s, ngettext ("%'d case", "%'d cases", n_cases),
-                         n_cases);
-          ds_put_byte (&s, ' ');
-          ds_put_unichar (&s, 0xd7); /* U+00D7 MULTIPLICATION SIGN */
-          ds_put_byte (&s, ' ');
-          ds_put_format (&s, ngettext ("%'d variable", "%'d variables",
-                                       n_vars),
-                         n_vars);
-          ref_cell_text = ds_steal_cstr (&s);
-        }
-
-      psppire_value_entry_set_variable (PSPPIRE_VALUE_ENTRY (de->datum_entry),
-                                        NULL);
-      gtk_entry_set_text (
-        GTK_ENTRY (gtk_bin_get_child (GTK_BIN (de->datum_entry))), "");
-      gtk_widget_set_sensitive (de->datum_entry, FALSE);
-    }
-
-  gtk_label_set_label (GTK_LABEL (de->cell_ref_label),
-                       ref_cell_text ? ref_cell_text : "");
-  g_free (ref_cell_text);
+  g_print ("%s\n", __FUNCTION__);
 }
 
 static void
 on_datum_entry_activate (PsppireValueEntry *entry, PsppireDataEditor *de)
 {
-  PsppireDataSheet *data_sheet = psppire_data_editor_get_active_data_sheet (de);
-  struct variable *var;
-  union value value;
-  int width;
-  gint row;
-
-  row = psppire_data_sheet_get_current_case (data_sheet);
-  var = psppire_data_sheet_get_current_variable (data_sheet);
-  if (row < 0 || !var)
-    return;
-
-  width = var_get_width (var);
-  value_init (&value, width);
-  if (psppire_value_entry_get_value (PSPPIRE_VALUE_ENTRY (de->datum_entry),
-                                     &value, width))
-    psppire_data_store_set_value (de->data_store, row, var, &value);
-  value_destroy (&value, width);
-}
-
-static void
-on_data_sheet_selection_changed (PsppSheetSelection *selection,
-                                 PsppireDataEditor *de)
-{
-  /* In a split view, ensure that only a single data sheet has a nonempty
-     selection.  */
-  if (de->split
-      && pspp_sheet_selection_count_selected_rows (selection)
-      && pspp_sheet_selection_count_selected_columns (selection))
-    {
-      PsppireDataSheet *ds;
-      int i;
-
-      FOR_EACH_DATA_SHEET (ds, i, de)
-        {
-          PsppSheetSelection *s;
-
-          s = pspp_sheet_view_get_selection (PSPP_SHEET_VIEW (ds));
-          if (s != selection)
-            pspp_sheet_selection_unselect_all (s);
-        }
-    }
-
-  refresh_entry (de);
 }
 
-/* Ensures that rows in the right-hand panes in the split view have the same
-   row height as the left-hand panes.  Otherwise, the rows in the right-hand
-   pane tend to be smaller, because the right-hand pane doesn't have buttons
-   for case numbers. */
-static void
-on_data_sheet_fixed_height_notify (PsppireDataSheet *ds,
-                                   GParamSpec *pspec,
-                                   PsppireDataEditor *de)
-{
-  enum
-    {
-      TL = GTK_XPANED_TOP_LEFT,
-      TR = GTK_XPANED_TOP_RIGHT,
-      BL = GTK_XPANED_BOTTOM_LEFT,
-      BR = GTK_XPANED_BOTTOM_RIGHT
-    };
-
-  int fixed_height = pspp_sheet_view_get_fixed_height (PSPP_SHEET_VIEW (ds));
-
-  pspp_sheet_view_set_fixed_height (PSPP_SHEET_VIEW (de->data_sheets[TR]),
-                                    fixed_height);
-  pspp_sheet_view_set_fixed_height (PSPP_SHEET_VIEW (de->data_sheets[BR]),
-                                    fixed_height);
-}
 
 static void
 disconnect_data_sheets (PsppireDataEditor *de)
 {
-  PsppireDataSheet *ds;
-  int i;
-
-  FOR_EACH_DATA_SHEET (ds, i, de)
-    {
-      PsppSheetSelection *selection;
-
-      if (ds == NULL)
-        {
-          /* This can only happen if 'dispose' runs more than once. */
-          continue;
-        }
-
-      if (i == GTK_XPANED_TOP_LEFT)
-        g_signal_handlers_disconnect_by_func (
-          ds, G_CALLBACK (on_data_sheet_fixed_height_notify), de);
-
-      g_signal_handlers_disconnect_by_func (
-        ds, G_CALLBACK (refresh_entry), de);
-      g_signal_handlers_disconnect_by_func (
-        ds, G_CALLBACK (on_data_sheet_var_double_clicked), de);
-
-      selection = pspp_sheet_view_get_selection (PSPP_SHEET_VIEW (ds));
-      g_signal_handlers_disconnect_by_func (
-        selection, G_CALLBACK (on_data_sheet_selection_changed), de);
-
-      de->data_sheets[i] = NULL;
-    }
-}
-
-static GtkWidget *
-make_data_sheet (PsppireDataEditor *de, GtkTreeViewGridLines grid_lines,
-                 gboolean show_value_labels)
-{
-  PsppSheetSelection *selection;
-  GtkWidget *ds;
-
-  ds = psppire_data_sheet_new ();
-  pspp_sheet_view_set_grid_lines (PSPP_SHEET_VIEW (ds), grid_lines);
-  psppire_data_sheet_set_value_labels (PSPPIRE_DATA_SHEET (ds),
-                                       show_value_labels);
-
-  g_signal_connect_swapped (ds, "notify::value-labels",
-                            G_CALLBACK (refresh_entry), de);
-  g_signal_connect (ds, "var-double-clicked",
-                    G_CALLBACK (on_data_sheet_var_double_clicked), de);
-
-  selection = pspp_sheet_view_get_selection (PSPP_SHEET_VIEW (ds));
-  g_signal_connect (selection, "changed",
-                    G_CALLBACK (on_data_sheet_selection_changed), de);
-
-  return ds;
 }
 
-static GtkWidget *
-make_single_datasheet (PsppireDataEditor *de, GtkTreeViewGridLines grid_lines,
-                       gboolean show_value_labels)
+/* Called when the active cell or the selection in the data sheet changes */
+static void
+on_data_selection_change (PsppireDataEditor *de, JmdRange *sel)
 {
-  GtkWidget *data_sheet_scroller;
-
-  de->data_sheets[0] = make_data_sheet (de, grid_lines, show_value_labels);
-  de->data_sheets[1] = de->data_sheets[2] = de->data_sheets[3] = NULL;
-
-  /* Put data sheet in scroller. */
-  data_sheet_scroller = gtk_scrolled_window_new (NULL, NULL);
-  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (data_sheet_scroller),
-                                  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
-  gtk_container_add (GTK_CONTAINER (data_sheet_scroller), de->data_sheets[0]);
+  gchar *ref_cell_text = NULL;
 
-  return data_sheet_scroller;
-}
+  gint n_cases = abs (sel->end_y - sel->start_y) + 1;
+  gint n_vars = abs (sel->end_x - sel->start_x) + 1;
 
-static GtkWidget *
-make_split_datasheet (PsppireDataEditor *de, GtkTreeViewGridLines grid_lines,
-                      gboolean show_value_labels)
-{
-  /* Panes, in the order in which we want to create them. */
-  enum
+  if (n_cases == 1 && n_vars == 1)
     {
-      TL,                       /* top left */
-      TR,                       /* top right */
-      BL,                       /* bottom left */
-      BR                        /* bottom right */
-    };
-
-  PsppSheetView *ds[4];
-  GtkXPaned *xpaned;
-  int i;
-
-  xpaned = GTK_XPANED (gtk_xpaned_new ());
-
-  for (i = 0; i < 4; i++)
+      /* A single cell is selected */
+      const struct variable *var = psppire_dict_get_variable (de->dict, sel->start_x);
+      
+      ref_cell_text = g_strdup_printf (_("%d : %s"),
+                                      sel->start_y + 1, var_get_name (var));
+    }
+  else
     {
-      GtkAdjustment *hadjust, *vadjust;
-      GtkPolicyType hpolicy, vpolicy;
-      GtkWidget *scroller;
-
-      de->data_sheets[i] = make_data_sheet (de, grid_lines, show_value_labels);
-      ds[i] = PSPP_SHEET_VIEW (de->data_sheets[i]);
-
-      if (i == BL)
-        hadjust = pspp_sheet_view_get_hadjustment (ds[TL]);
-      else if (i == BR)
-        hadjust = pspp_sheet_view_get_hadjustment (ds[TR]);
-      else
-        hadjust = NULL;
-
-      if (i == TR)
-        vadjust = pspp_sheet_view_get_vadjustment (ds[TL]);
-      else if (i == BR)
-        vadjust = pspp_sheet_view_get_vadjustment (ds[BL]);
-      else
-        vadjust = NULL;
-
-      scroller = gtk_scrolled_window_new (hadjust, vadjust);
-      gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroller),
-                                           GTK_SHADOW_ETCHED_IN);
-      hpolicy = i == TL || i == TR ? GTK_POLICY_NEVER : GTK_POLICY_ALWAYS;
-      vpolicy = i == TL || i == BL ? GTK_POLICY_NEVER : GTK_POLICY_ALWAYS;
-      gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroller),
-                                      hpolicy, vpolicy);
-      gtk_container_add (GTK_CONTAINER (scroller), GTK_WIDGET (ds[i]));
-
-      switch (i)
-        {
-        case TL:
-          gtk_xpaned_pack_top_left (xpaned, scroller, TRUE, TRUE);
-          break;
-
-        case TR:
-          gtk_xpaned_pack_top_right (xpaned, scroller, TRUE, TRUE);
-          break;
-
-        case BL:
-          gtk_xpaned_pack_bottom_left (xpaned, scroller, TRUE, TRUE);
-          break;
-
-        case BR:
-          gtk_xpaned_pack_bottom_right (xpaned, scroller, TRUE, TRUE);
-          break;
-
-        default:
-          g_warn_if_reached ();
-        }
+      struct string s;
+
+      /* The glib string library does not understand the ' printf modifier
+        on all platforms, but the "struct string" library does (because
+        Gnulib fixes that problem), so use the latter.  */
+      ds_init_empty (&s);
+      ds_put_format (&s, ngettext ("%'d case", "%'d cases", n_cases),
+                    n_cases);
+      ds_put_byte (&s, ' ');
+      ds_put_unichar (&s, 0xd7); /* U+00D7 MULTIPLICATION SIGN */
+      ds_put_byte (&s, ' ');
+      ds_put_format (&s, ngettext ("%'d variable", "%'d variables",
+                                  n_vars),
+                    n_vars);
+      ref_cell_text = ds_steal_cstr (&s);
     }
-
-  /* Bottom sheets don't display variable names. */
-  pspp_sheet_view_set_headers_visible (ds[BL], FALSE);
-  pspp_sheet_view_set_headers_visible (ds[BR], FALSE);
-
-  /* Right sheets don't display case numbers. */
-  psppire_data_sheet_set_case_numbers (PSPPIRE_DATA_SHEET (ds[TR]), FALSE);
-  psppire_data_sheet_set_case_numbers (PSPPIRE_DATA_SHEET (ds[BR]), FALSE);
-
-  g_signal_connect (ds[TL], "notify::fixed-height",
-                    G_CALLBACK (on_data_sheet_fixed_height_notify), de);
-
-  return GTK_WIDGET (xpaned);
+  
+  gtk_label_set_label (GTK_LABEL (de->cell_ref_label),
+                      ref_cell_text ? ref_cell_text : "");
+  
+  g_free (ref_cell_text);
 }
 
+
 static void set_font_recursively (GtkWidget *w, gpointer data);
 
 static void
 psppire_data_editor_init (PsppireDataEditor *de)
 {
-  GtkWidget *var_sheet_scroller;
   GtkWidget *hbox;
   gchar *fontname = NULL;
 
@@ -700,33 +532,46 @@ psppire_data_editor_init (PsppireDataEditor *de)
   gtk_box_pack_start (GTK_BOX (hbox), de->datum_entry, TRUE, TRUE, 0);
 
   de->split = FALSE;
-  de->datasheet_vbox_widget
-    = make_single_datasheet (de, GTK_TREE_VIEW_GRID_LINES_BOTH, FALSE);
-
+  de->data_sheet = g_object_new (JMD_TYPE_SHEET, NULL);
+  GtkWidget *data_button = jmd_sheet_get_button (JMD_SHEET (de->data_sheet));
+  gtk_button_set_label (GTK_BUTTON (data_button), _("Case"));
   de->vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
   gtk_box_pack_start (GTK_BOX (de->vbox), hbox, FALSE, FALSE, 0);
-  gtk_box_pack_start (GTK_BOX (de->vbox), de->datasheet_vbox_widget,
-                      TRUE, TRUE, 0);
+  gtk_box_pack_start (GTK_BOX (de->vbox), de->data_sheet, TRUE, TRUE, 0);
 
+
+  g_signal_connect_swapped (de->data_sheet, "selection-changed",
+                   G_CALLBACK (on_data_selection_change), de);
+  
   gtk_notebook_append_page (GTK_NOTEBOOK (de), de->vbox,
                            gtk_label_new_with_mnemonic (_("Data View")));
 
   gtk_widget_show_all (de->vbox);
 
-  de->var_sheet = GTK_WIDGET (psppire_var_sheet_new ());
-  pspp_sheet_view_set_grid_lines (PSPP_SHEET_VIEW (de->var_sheet),
-                                  GTK_TREE_VIEW_GRID_LINES_BOTH);
-  var_sheet_scroller = gtk_scrolled_window_new (NULL, NULL);
-  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (var_sheet_scroller),
-                                  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
-  gtk_container_add (GTK_CONTAINER (var_sheet_scroller), de->var_sheet);
-  gtk_widget_show_all (var_sheet_scroller);
-  gtk_notebook_append_page (GTK_NOTEBOOK (de), var_sheet_scroller,
+  de->var_sheet = g_object_new (JMD_TYPE_SHEET, NULL);
+
+  PsppireVarSheetHeader *vsh = g_object_new (PSPPIRE_TYPE_VAR_SHEET_HEADER, NULL);
+  
+  g_object_set (de->var_sheet,
+               "hmodel", vsh,
+               "select-renderer-func", select_renderer_func,
+               NULL);
+
+  
+  GtkWidget *var_button = jmd_sheet_get_button (JMD_SHEET (de->var_sheet));
+  gtk_button_set_label (GTK_BUTTON (var_button), _("Variable"));
+  
+  gtk_notebook_append_page (GTK_NOTEBOOK (de), de->var_sheet,
                            gtk_label_new_with_mnemonic (_("Variable View")));
 
-  g_signal_connect (de->var_sheet, "var-double-clicked",
+  gtk_widget_show_all (de->var_sheet);
+  
+  g_signal_connect (de->var_sheet, "row-header-double-clicked",
                     G_CALLBACK (on_var_sheet_var_double_clicked), de);
 
+  g_signal_connect (de->data_sheet, "column-header-double-clicked",
+                    G_CALLBACK (on_data_sheet_var_double_clicked), de);
+
   g_object_set (de, "can-focus", FALSE, NULL);
 
   if (psppire_conf_get_string (psppire_conf_new (),
@@ -755,17 +600,15 @@ psppire_data_editor_new (PsppireDict *dict,
 void
 psppire_data_editor_show_grid (PsppireDataEditor *de, gboolean grid_visible)
 {
+#if 0
   GtkTreeViewGridLines grid;
-  PsppireDataSheet *data_sheet;
-  int i;
 
   grid = (grid_visible
           ? GTK_TREE_VIEW_GRID_LINES_BOTH
           : GTK_TREE_VIEW_GRID_LINES_NONE);
 
-  FOR_EACH_DATA_SHEET (data_sheet, i, de)
-    pspp_sheet_view_set_grid_lines (PSPP_SHEET_VIEW (data_sheet), grid);
   pspp_sheet_view_set_grid_lines (PSPP_SHEET_VIEW (de->var_sheet), grid);
+#endif  
 }
 
 
@@ -803,37 +646,13 @@ psppire_data_editor_set_font (PsppireDataEditor *de, PangoFontDescription *font_
 void
 psppire_data_editor_split_window (PsppireDataEditor *de, gboolean split)
 {
-  GtkTreeViewGridLines grid_lines;
-  gboolean labels;
-
   if (split == de->split)
     return;
 
-
-  grid_lines = pspp_sheet_view_get_grid_lines (
-    PSPP_SHEET_VIEW (de->data_sheets[0]));
-  labels = psppire_data_sheet_get_value_labels (PSPPIRE_DATA_SHEET (
-                                                  de->data_sheets[0]));
-
   disconnect_data_sheets (de);
-  if (de->old_vbox_widget)
-    g_object_unref (de->old_vbox_widget);
-  de->old_vbox_widget = de->datasheet_vbox_widget;
-  g_object_ref (de->old_vbox_widget);
-  /* FIXME:  old_vbox_widget needs to be unreffed in dispose.
-       (currently it seems to provoke an error if I do that.  
-       I don't know why. */
-  gtk_container_remove (GTK_CONTAINER (de->vbox), de->datasheet_vbox_widget);
-
-  if (split)
-    de->datasheet_vbox_widget = make_split_datasheet (de, grid_lines, labels);
-  else
-    de->datasheet_vbox_widget = make_single_datasheet (de, grid_lines, labels);
 
   psppire_data_editor_refresh_model (de);
 
-  gtk_box_pack_start (GTK_BOX (de->vbox), de->datasheet_vbox_widget,
-                      TRUE, TRUE, 0);
   gtk_widget_show_all (de->vbox);
 
   if (de->font)
@@ -848,22 +667,9 @@ psppire_data_editor_split_window (PsppireDataEditor *de, gboolean split)
 void
 psppire_data_editor_goto_variable (PsppireDataEditor *de, gint dict_index)
 {
-  PsppireDataSheet *data_sheet;
-
-  switch (gtk_notebook_get_current_page (GTK_NOTEBOOK (de)))
-    {
-    case PSPPIRE_DATA_EDITOR_DATA_VIEW:
-      data_sheet = psppire_data_editor_get_active_data_sheet (de);
-      psppire_data_sheet_goto_variable (data_sheet, dict_index);
-      break;
-
-    case PSPPIRE_DATA_EDITOR_VARIABLE_VIEW:
-      psppire_var_sheet_goto_variable (PSPPIRE_VAR_SHEET (de->var_sheet),
-                                       dict_index);
-      break;
-    }
 }
 
+#if 0
 /* Returns the "active" data sheet in DE.  If DE is in single-paned mode, this
    is the only data sheet.  If DE is in split mode (showing four data sheets),
    this is the focused data sheet or, if none is focused, the data sheet with
@@ -899,3 +705,4 @@ psppire_data_editor_get_active_data_sheet (PsppireDataEditor *de)
 
   return PSPPIRE_DATA_SHEET (de->data_sheets[0]);
 }
+#endif