Merge remote-tracking branch 'origin/master' into sheet
[pspp] / src / ui / gui / psppire-data-editor.c
index b643acf0462a6ee59d29cd16c67f8c3e05ecfc1c..40a2c490b4460fcdb5a874dd28fb1d648ce3f55f 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+   Copyright (C) 2008, 2009, 2010, 2011, 2012, 2016 Free Software Foundation, Inc.
 
    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
 #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-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 "value-variant.h"
+
+
 #include "ui/gui/efficient-sheet/jmd-sheet.h"
+#include "ui/gui/efficient-sheet/jmd-sheet-body.h"
 
 #include <gettext.h>
 #define _(msgid) gettext (msgid)
@@ -134,7 +136,6 @@ static void psppire_data_editor_init                (PsppireDataEditor      *de)
 
 static void disconnect_data_sheets (PsppireDataEditor *);
 static void refresh_entry (PsppireDataEditor *);
-static void psppire_data_editor_update_ui_manager (PsppireDataEditor *);
 
 GType
 psppire_data_editor_get_type (void)
@@ -190,12 +191,6 @@ psppire_data_editor_dispose (GObject *obj)
       de->font = NULL;
     }
 
-  if (de->ui_manager)
-    {
-      g_object_unref (de->ui_manager);
-      de->ui_manager = NULL;
-    }
-
   /* Chain up to the parent class */
   G_OBJECT_CLASS (parent_class)->dispose (obj);
 }
@@ -206,8 +201,7 @@ enum
     PROP_DATA_STORE,
     PROP_DICTIONARY,
     PROP_VALUE_LABELS,
-    PROP_SPLIT_WINDOW,
-    PROP_UI_MANAGER
+    PROP_SPLIT_WINDOW
   };
 
 static void
@@ -252,13 +246,18 @@ change_data_value (PsppireDataStore *store, gint col, gint row, GValue *value)
 {
   const struct variable *var = psppire_dict_get_variable (store->dict, col);
 
+  if (NULL == var)
+    return;
+
   union value v;
-  value_init (&v, var_get_width (var));
-  v.f = g_value_get_double (value);
+
+  GVariant *vrnt = g_value_get_variant (value);
+  
+  value_variant_get (&v, vrnt);
   
   psppire_data_store_set_value (store, row, var, &v);
 
-  value_destroy (&v, var_get_width (var));
+  value_destroy_from_variant (&v, vrnt);
 }
 
 static void
@@ -311,7 +310,7 @@ psppire_data_editor_set_property (GObject         *object,
       break;
     case PROP_VALUE_LABELS:
       break;
-    case PROP_UI_MANAGER:
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -339,9 +338,6 @@ psppire_data_editor_get_property (GObject         *object,
       break;
     case PROP_VALUE_LABELS:
       break;
-    case PROP_UI_MANAGER:
-      g_value_set_object (value, psppire_data_editor_get_ui_manager (de));
-      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -354,7 +350,7 @@ psppire_data_editor_switch_page (GtkNotebook     *notebook,
                                  guint            page_num)
 {
   GTK_NOTEBOOK_CLASS (parent_class)->switch_page (notebook, w, page_num);
-  psppire_data_editor_update_ui_manager (PSPPIRE_DATA_EDITOR (notebook));
+
 }
 
 static void
@@ -362,7 +358,7 @@ psppire_data_editor_set_focus_child (GtkContainer *container,
                                      GtkWidget    *widget)
 {
   GTK_CONTAINER_CLASS (parent_class)->set_focus_child (container, widget);
-  psppire_data_editor_update_ui_manager (PSPPIRE_DATA_EDITOR (container));
+
 }
 
 static void
@@ -372,7 +368,7 @@ psppire_data_editor_class_init (PsppireDataEditorClass *klass)
   GParamSpec *dict_spec ;
   GParamSpec *value_labels_spec;
   GParamSpec *split_window_spec;
-  GParamSpec *ui_manager_spec;
+
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
   GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
   GtkNotebookClass *notebook_class = GTK_NOTEBOOK_CLASS (klass);
@@ -430,20 +426,11 @@ psppire_data_editor_class_init (PsppireDataEditorClass *klass)
                                    PROP_SPLIT_WINDOW,
                                    split_window_spec);
 
-  ui_manager_spec =
-    g_param_spec_object ("ui-manager",
-                         "UI Manager",
-                         "UI manager for the active notebook tab.  The client should merge this UI manager with the active UI manager to obtain menu items and tool bar items specific to the active notebook tab.",
-                         GTK_TYPE_UI_MANAGER,
-                         G_PARAM_READABLE);
-  g_object_class_install_property (object_class,
-                                   PROP_UI_MANAGER,
-                                   ui_manager_spec);
 }
 
 
 static void
-on_var_sheet_var_double_clicked (PsppireVarSheet *var_sheet, gint dict_index,
+on_var_sheet_var_double_clicked (void *var_sheet, gint dict_index,
                                  PsppireDataEditor *de)
 {
   gtk_notebook_set_current_page (GTK_NOTEBOOK (de),
@@ -452,10 +439,12 @@ on_var_sheet_var_double_clicked (PsppireVarSheet *var_sheet, gint dict_index,
   jmd_sheet_scroll_to (JMD_SHEET (de->data_sheet), dict_index, -1);
 }
 
+
 static void
 on_data_sheet_var_double_clicked (JmdSheet *data_sheet, gint dict_index,
                                  PsppireDataEditor *de)
 {
+  
   gtk_notebook_set_current_page (GTK_NOTEBOOK (de),
                                  PSPPIRE_DATA_EDITOR_VARIABLE_VIEW);
 
@@ -463,12 +452,27 @@ on_data_sheet_var_double_clicked (JmdSheet *data_sheet, gint dict_index,
 }
 
 
+
 /* Refreshes 'de->cell_ref_label' and 'de->datum_entry' from the currently
    active cell or cells. */
 static void
 refresh_entry (PsppireDataEditor *de)
 {
-  g_print ("%s\n", __FUNCTION__);
+  union value val;
+  gint row, col;
+  jmd_sheet_get_active_cell (JMD_SHEET (de->data_sheet), &col, &row);
+
+  const struct variable *var = psppire_dict_get_variable (de->dict, col);
+  psppire_value_entry_set_variable (PSPPIRE_VALUE_ENTRY (de->datum_entry), var);
+
+  int width = var_get_width (var);
+  if (! psppire_data_store_get_value (PSPPIRE_DATA_STORE (de->data_store),
+                                     row, var, &val))
+    return;
+
+  psppire_value_entry_set_value (PSPPIRE_VALUE_ENTRY (de->datum_entry),
+                                &val, width);
+  value_destroy (&val, width);
 }
 
 static void
@@ -495,9 +499,10 @@ on_data_selection_change (PsppireDataEditor *de, JmdRange *sel)
     {
       /* 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));
+
+      if (var)
+       ref_cell_text = g_strdup_printf (_("%d : %s"),
+                                        sel->start_y + 1, var_get_name (var));
     }
   else
     {
@@ -527,14 +532,20 @@ on_data_selection_change (PsppireDataEditor *de, JmdRange *sel)
 
 static void set_font_recursively (GtkWidget *w, gpointer data);
 
+gchar *myconvfunc (GtkTreeModel *m, gint col, gint row, const GValue *v);
+void myreversefunc (GtkTreeModel *model, gint col, gint row, const gchar *in, GValue *out);
+
+
 static void
 psppire_data_editor_init (PsppireDataEditor *de)
 {
   GtkWidget *hbox;
   gchar *fontname = NULL;
 
+  GtkStyleContext *context = gtk_widget_get_style_context (GTK_WIDGET (de));
+  gtk_style_context_add_class (context, "psppire-data-editor");
+  
   de->font = NULL;
-  de->ui_manager = NULL;
   de->old_vbox_widget = NULL;
 
   g_object_set (de, "tab-pos", GTK_POS_BOTTOM, NULL);
@@ -552,7 +563,11 @@ psppire_data_editor_init (PsppireDataEditor *de)
   gtk_box_pack_start (GTK_BOX (hbox), de->datum_entry, TRUE, TRUE, 0);
 
   de->split = FALSE;
-  de->data_sheet = g_object_new (JMD_TYPE_SHEET, NULL);
+  de->data_sheet = jmd_sheet_new ();
+  jmd_sheet_body_set_conversion_func
+    (JMD_SHEET_BODY (JMD_SHEET(de->data_sheet)->selected_body),
+     myconvfunc, myreversefunc);
+                                     
   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);
@@ -603,7 +618,6 @@ psppire_data_editor_init (PsppireDataEditor *de)
       set_font_recursively (GTK_WIDGET (de), de->font);
     }
 
-  psppire_data_editor_update_ui_manager (de);
 }
 
 GtkWidget*
@@ -621,13 +635,8 @@ psppire_data_editor_new (PsppireDict *dict,
 void
 psppire_data_editor_show_grid (PsppireDataEditor *de, gboolean grid_visible)
 {
-  GtkTreeViewGridLines grid;
-
-  grid = (grid_visible
-          ? GTK_TREE_VIEW_GRID_LINES_BOTH
-          : GTK_TREE_VIEW_GRID_LINES_NONE);
-
-  pspp_sheet_view_set_grid_lines (PSPP_SHEET_VIEW (de->var_sheet), grid);
+  g_object_set (JMD_SHEET (de->var_sheet), "gridlines", grid_visible, NULL);
+  g_object_set (JMD_SHEET (de->data_sheet), "gridlines", grid_visible, NULL);
 }
 
 
@@ -636,7 +645,28 @@ set_font_recursively (GtkWidget *w, gpointer data)
 {
   PangoFontDescription *font_desc = data;
 
-  gtk_widget_override_font (w, font_desc);
+  GtkStyleContext *style = gtk_widget_get_style_context (w);
+  GtkCssProvider *cssp = gtk_css_provider_new ();
+
+  gchar *str = pango_font_description_to_string (font_desc);
+  gchar *css =
+    g_strdup_printf ("* {font: %s}", str);
+  g_free (str);
+
+  GError *err = NULL;
+  gtk_css_provider_load_from_data (cssp, css, -1, &err);
+  if (err)
+    {
+      g_warning ("Failed to load font css \"%s\": %s", css, err->message);
+      g_error_free (err);
+    }
+  g_free (css);
+
+  gtk_style_context_add_provider (style,
+                                 GTK_STYLE_PROVIDER (cssp),
+                                 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+  g_object_unref (cssp);
+
 
   if ( GTK_IS_CONTAINER (w))
     gtk_container_foreach (GTK_CONTAINER (w), set_font_recursively, font_desc);
@@ -657,7 +687,7 @@ psppire_data_editor_set_font (PsppireDataEditor *de, PangoFontDescription *font_
   psppire_conf_set_string (psppire_conf_new (),
                           "Data Editor", "font",
                           font_name);
-
+  g_free (font_name);
 }
 
 /* If SPLIT is TRUE, splits DE's data sheet into four panes.
@@ -679,7 +709,6 @@ psppire_data_editor_split_window (PsppireDataEditor *de, gboolean split)
 
   de->split = split;
   g_object_notify (G_OBJECT (de), "split");
-  psppire_data_editor_update_ui_manager (de);
 }
 
 /* Makes the variable with dictionary index DICT_INDEX in DE's dictionary
@@ -688,49 +717,3 @@ void
 psppire_data_editor_goto_variable (PsppireDataEditor *de, gint dict_index)
 {
 }
-
-
-/* Returns the UI manager that should be merged into DE's toplevel widget's UI
-   manager to display menu items and toolbar items specific to DE's current
-   page and data sheet.
-
-   DE's toplevel widget can watch for changes by connecting to DE's
-   notify::ui-manager signal. */
-GtkUIManager *
-psppire_data_editor_get_ui_manager (PsppireDataEditor *de)
-{
-  psppire_data_editor_update_ui_manager (de);
-  return de->ui_manager;
-}
-
-static void
-psppire_data_editor_update_ui_manager (PsppireDataEditor *de)
-{
-  GtkUIManager *ui_manager;
-
-  ui_manager = NULL;
-
-  switch (gtk_notebook_get_current_page (GTK_NOTEBOOK (de)))
-    {
-    case PSPPIRE_DATA_EDITOR_DATA_VIEW:
-      break;
-
-    case PSPPIRE_DATA_EDITOR_VARIABLE_VIEW:
-      break;
-
-    default:
-      /* This happens transiently in psppire_data_editor_init(). */
-      break;
-    }
-
-  if (ui_manager != de->ui_manager)
-    {
-      if (de->ui_manager)
-        g_object_unref (de->ui_manager);
-      if (ui_manager)
-        g_object_ref (ui_manager);
-      de->ui_manager = ui_manager;
-
-      g_object_notify (G_OBJECT (de), "ui-manager");
-    }
-}