psppire-output-view: Set tooltips on tables from table_item notes.
[pspp] / src / ui / gui / psppire-var-view.c
index c71a5e66103e2821814972461c12b46e1de0aa5a..0a020008fb0c0c0630cca080deb4e7c177120960 100644 (file)
@@ -21,6 +21,7 @@
 #include "psppire-var-ptr.h"
 #include "psppire-select-dest.h"
 
+#include <libpspp/cast.h>
 #include <libpspp/str.h>
 #include <data/variable.h>
 
@@ -28,8 +29,6 @@
 #define _(msgid) gettext (msgid)
 #define N_(msgid) msgid
 
-static void psppire_var_view_base_finalize (PsppireVarViewClass *, gpointer);
-static void psppire_var_view_base_init     (PsppireVarViewClass *class);
 static void psppire_var_view_class_init    (PsppireVarViewClass *class);
 static void psppire_var_view_init          (PsppireVarView      *var_view);
 
@@ -63,71 +62,23 @@ model_init (PsppireSelectDestWidgetIface *iface)
   iface->contains_var = var_view_contains_var;
 }
 
-GType
-psppire_var_view_get_type (void)
-{
-  static GType psppire_var_view_type = 0;
-
-  if (!psppire_var_view_type)
-    {
-      static const GTypeInfo psppire_var_view_info =
-      {
-       sizeof (PsppireVarViewClass),
-       (GBaseInitFunc) psppire_var_view_base_init,
-        (GBaseFinalizeFunc) psppire_var_view_base_finalize,
-       (GClassInitFunc)psppire_var_view_class_init,
-       (GClassFinalizeFunc) NULL,
-       NULL,
-        sizeof (PsppireVarView),
-       0,
-       (GInstanceInitFunc) psppire_var_view_init,
-      };
-
-      static const GInterfaceInfo var_view_model_info = {
-       (GInterfaceInitFunc) model_init, /* Fill this in */
-       NULL,
-       NULL
-      };
-
-      psppire_var_view_type =
-       g_type_register_static (GTK_TYPE_TREE_VIEW, "PsppireVarView",
-                               &psppire_var_view_info, 0);
-
-      g_type_add_interface_static (psppire_var_view_type,
-                                  PSPPIRE_TYPE_SELECT_DEST_WIDGET,
-                                  &var_view_model_info);
-    }
+G_DEFINE_TYPE_WITH_CODE (PsppireVarView, psppire_var_view, GTK_TYPE_TREE_VIEW,
+               G_IMPLEMENT_INTERFACE (PSPPIRE_TYPE_SELECT_DEST_WIDGET, model_init))
 
-  return psppire_var_view_type;
-}
-
-void 
+void
 psppire_var_view_clear (PsppireVarView *vv)
 {
-  gint i;
-  for (i = 0; i < vv->n_lists; ++i)
-    g_object_unref (vv->list[i]);
-
-  g_free (vv->list);
-
-  vv->n_lists = 0;
-  vv->l_idx = -1;
-  vv->list = NULL;
+  GtkListStore *l = gtk_list_store_newv  (vv->n_cols, vv->cols);
 
-  psppire_var_view_push_model (vv);
+  gtk_tree_view_set_model (GTK_TREE_VIEW (vv), GTK_TREE_MODEL (l));
 }
 
 
 static void
 psppire_var_view_finalize (GObject *object)
 {
-  gint i;
   PsppireVarView *var_view = PSPPIRE_VAR_VIEW (object);
   g_free (var_view->nums);
-  for (i = 0; i < var_view->n_lists; ++i)
-    g_object_unref (var_view->list[i]);
-
-  g_free (var_view->list);
   g_free (var_view->cols);
 }
 
@@ -193,58 +144,37 @@ set_renderers (PsppireVarView *var_view)
 {
   gint c;
   var_view->nums = g_malloc (sizeof *var_view->nums * var_view->n_cols);
-  
+
   for (c = 0 ; c < var_view->n_cols; ++c)
     {
       GtkCellRenderer *renderer = gtk_cell_renderer_text_new ();
       GtkTreeViewColumn *col = gtk_tree_view_column_new ();
-      
+
       gchar *label = g_strdup_printf (_("Var%d"), c + 1);
-      
+
       gtk_tree_view_column_set_min_width (col, 100);
       gtk_tree_view_column_set_sizing (col, GTK_TREE_VIEW_COLUMN_FIXED);
       gtk_tree_view_column_set_resizable (col, TRUE);
       gtk_tree_view_column_set_title (col, label);
-      
+
       g_free (label);
-      
+
       var_view->nums[c] = c;
-      
+
       gtk_tree_view_column_pack_start (col, renderer, TRUE);
       gtk_tree_view_column_set_cell_data_func (col, renderer,
                                               display_cell_var_name,
                                               &var_view->nums[c], 0);
-      
+
       gtk_tree_view_append_column (GTK_TREE_VIEW (var_view), col);
     }
 }
 
 
-
-
-/* Set a model, which is an GtkListStore of gpointers which point to a variable */
-void
-psppire_var_view_push_model (PsppireVarView *vv)
+GtkTreeModel *
+psppire_var_view_get_current_model (PsppireVarView *vv)
 {
-  vv->n_lists++;
-  vv->l_idx++;
-  vv->list = xrealloc (vv->list, sizeof (*vv->list) * vv->n_lists);
-  vv->list[vv->l_idx] = gtk_list_store_newv  (vv->n_cols, vv->cols);
-  g_object_ref (vv->list[vv->l_idx]);
-  gtk_tree_view_set_model (GTK_TREE_VIEW (vv), GTK_TREE_MODEL (vv->list[vv->l_idx]));
-}
-
-gboolean
-psppire_var_view_set_current_model (PsppireVarView *vv, gint n)
-{
-  if (n < 0 || n >= vv->n_lists)
-    return FALSE;
-
-  vv->l_idx = n;
-
-  gtk_tree_view_set_model (GTK_TREE_VIEW (vv), GTK_TREE_MODEL (vv->list[vv->l_idx]));
-
-  return TRUE;
+  return gtk_tree_view_get_model (GTK_TREE_VIEW (vv));
 }
 
 static void
@@ -262,7 +192,7 @@ psppire_var_view_set_property (GObject         *object,
        gint c;
        var_view->n_cols = g_value_get_int (value);
 
-       var_view->cols = xrealloc (var_view->cols, sizeof (GType) *  var_view->n_cols);
+       var_view->cols = g_realloc (var_view->cols, sizeof (GType) *  var_view->n_cols);
 
        for (c = 0 ; c < var_view->n_cols; ++c)
          var_view->cols[c] = PSPPIRE_VAR_PTR_TYPE;
@@ -283,6 +213,8 @@ psppire_var_view_class_init (PsppireVarViewClass *class)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (class);
 
+  object_class->finalize = psppire_var_view_finalize;
+
   GParamSpec *n_cols_spec =
     g_param_spec_int ("n-cols",
                      "Number of columns",
@@ -300,35 +232,13 @@ psppire_var_view_class_init (PsppireVarViewClass *class)
                                    n_cols_spec);
 }
 
-
-static void
-psppire_var_view_base_init (PsppireVarViewClass *class)
-{
-
-  GObjectClass *object_class = G_OBJECT_CLASS (class);
-
-
-
-  object_class->finalize = psppire_var_view_finalize;
-}
-
-
-
-static void
-psppire_var_view_base_finalize (PsppireVarViewClass *class,
-                                gpointer class_data)
-{
-}
-
-
-
 static void
 psppire_var_view_init (PsppireVarView *vv)
 {
+  GtkTreeSelection* selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (vv));
   vv->cols = 0;
-  vv->n_lists = 0;
-  vv->l_idx = -1;
-  vv->list = NULL;
+
+  gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
 }
 
 
@@ -343,29 +253,25 @@ gboolean
 psppire_var_view_get_iter_first (PsppireVarView *vv, GtkTreeIter *iter)
 {
   GtkTreeIter dummy;
-  if ( vv->l_idx < 0)
-    return FALSE;
-
-  return gtk_tree_model_get_iter_first (GTK_TREE_MODEL (vv->list[vv->l_idx]), iter ? iter : &dummy);
+  GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (vv));
+  return gtk_tree_model_get_iter_first (model, iter ? iter : &dummy);
 }
 
 gboolean
 psppire_var_view_get_iter_next (PsppireVarView *vv, GtkTreeIter *iter)
 {
-  if ( vv->l_idx < 0)
-    return FALSE;
-
-  return gtk_tree_model_iter_next (GTK_TREE_MODEL (vv->list[vv->l_idx]), iter);
+  GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (vv));
+  return gtk_tree_model_iter_next (model, iter);
 }
 
 const struct variable *
-psppire_var_view_get_variable (PsppireVarView *vv, gint column, GtkTreeIter *iter)
+psppire_var_view_get_var_from_model (GtkTreeModel *model, gint column, GtkTreeIter *iter)
 {
   const struct variable *var = NULL;
   GValue value = {0};
-  gtk_tree_model_get_value (GTK_TREE_MODEL (vv->list[vv->l_idx]), iter, column, &value);
+  gtk_tree_model_get_value (model, iter, column, &value);
 
-  if ( G_VALUE_TYPE (&value) == PSPPIRE_VAR_PTR_TYPE)
+  if (G_VALUE_TYPE (&value) == PSPPIRE_VAR_PTR_TYPE)
     var = g_value_get_boxed (&value);
   else
     g_critical ("Unsupported type `%s', in variable name treeview.",
@@ -376,6 +282,15 @@ psppire_var_view_get_variable (PsppireVarView *vv, gint column, GtkTreeIter *ite
   return var;
 }
 
+const struct variable *
+psppire_var_view_get_variable (PsppireVarView *vv, gint column, GtkTreeIter *iter)
+{
+  GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (vv));
+  return psppire_var_view_get_var_from_model (model, column, iter);
+}
+
+
+
 /*
   Append the names of selected variables to STRING.
   Returns the number of variables appended.
@@ -386,7 +301,7 @@ psppire_var_view_append_names (PsppireVarView *vv, gint column, GString *string)
   gint n_vars = 0;
   GtkTreeIter iter;
 
-  if ( psppire_var_view_get_iter_first (vv, &iter) )
+  if (psppire_var_view_get_iter_first (vv, &iter))
     {
       do
        {
@@ -402,18 +317,43 @@ psppire_var_view_append_names (PsppireVarView *vv, gint column, GString *string)
   return n_vars;
 }
 
+/* Return a linked list of struct variables which are
+   contained in VV.
+   The caller is responsible for freeing the returned list.
+   The variables however are owned by their dictionary
+   and should not be freed.
+  */
+GSList *
+psppire_var_view_list_names (PsppireVarView *vv, gint column)
+{
+  GtkTreeIter iter;
+  GSList *list = NULL;
+
+  if (psppire_var_view_get_iter_first (vv, &iter))
+    {
+      do
+       {
+         const struct variable *var = psppire_var_view_get_variable (vv, column, &iter);
+         list = g_slist_prepend (list, CONST_CAST (struct variable *, var));
+       }
+      while (psppire_var_view_get_iter_next (vv, &iter));
+    }
+
+  return list;
+}
+
 
 /*
   Append the names of selected variables to STR
   Returns the number of variables appended.
 */
-gint 
+gint
 psppire_var_view_append_names_str (PsppireVarView *vv, gint column, struct string *str)
 {
   gint n_vars = 0;
   GtkTreeIter iter;
 
-  if ( psppire_var_view_get_iter_first (vv, &iter) )
+  if (psppire_var_view_get_iter_first (vv, &iter))
     {
       do
        {