Simplify psppire-var-view and its relationship to psppire-means-layer
authorJohn Darrington <john@darrington.wattle.id.au>
Tue, 8 Oct 2013 04:46:38 +0000 (06:46 +0200)
committerJohn Darrington <john@darrington.wattle.id.au>
Tue, 8 Oct 2013 10:14:18 +0000 (12:14 +0200)
src/ui/gui/psppire-dialog-action-means.c
src/ui/gui/psppire-means-layer.c
src/ui/gui/psppire-means-layer.h
src/ui/gui/psppire-selector.c
src/ui/gui/psppire-var-view.c
src/ui/gui/psppire-var-view.h

index 6ebda5055180cc04291a72fff93d40d441ac891d..81e9bb905216d1f414840d7b365b7ff118def8cf 100644 (file)
@@ -47,18 +47,15 @@ generate_syntax (PsppireDialogAction *act)
 
   for (l = 0; l < layer->n_layers; ++l)
     {
-      gboolean ok;
       GtkTreeIter iter;
-      PsppireVarView *vv = PSPPIRE_VAR_VIEW (layer->var_view);
-      psppire_var_view_set_current_model (vv, l);
-      ok = psppire_var_view_get_iter_first (vv, &iter);
+
+      GtkTreeModel *m = psppire_means_layer_get_model_n (layer, l);
+      gboolean ok = gtk_tree_model_get_iter_first (m, &iter);
       if (ok)
        g_string_append (string, "\n\tBY");
-      for (;
-          ok;
-          ok = psppire_var_view_get_iter_next (vv, &iter))
+      for (; ok; ok = gtk_tree_model_iter_next (m, &iter))
          {
-           const struct variable *var = psppire_var_view_get_variable (vv, 0, &iter);
+           const struct variable *var = psppire_var_view_get_var_from_model (m, 0, &iter);
            g_string_append (string, " ");
            g_string_append (string, var_get_name (var));
          }
index 24178b8a35c4b52fac0b78e2b8b29e1d7e62e34c..a9b1139f18c6be631c82e73996c0baa0ffbdb747 100644 (file)
@@ -32,28 +32,54 @@ static void psppire_means_layer_init          (PsppireMeansLayer      *window);
 
 G_DEFINE_TYPE (PsppireMeansLayer, psppire_means_layer, GTK_TYPE_VBOX);
 
+static GObjectClass *parent_class = NULL;
+
+static void
+psppire_means_layer_dispose (GObject *obj)
+{
+  PsppireMeansLayer *w = (PsppireMeansLayer *)obj;
+
+  if (w->dispose_has_run)
+    return;
+
+  /* Make sure dispose does not run twice. */
+  w->dispose_has_run = TRUE;
+
+  g_ptr_array_unref (w->layer);
+
+  /* Chain up to the parent class */
+  G_OBJECT_CLASS (parent_class)->dispose (obj);
+}
+
 
 static void 
 psppire_means_layer_class_init    (PsppireMeansLayerClass *class)
 {
-  //  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+  parent_class = g_type_class_peek_parent (class);
+
+
+  object_class->dispose = psppire_means_layer_dispose;
 }
 
 static void
 update (PsppireMeansLayer *ml)
 {
-  gchar *l = g_strdup_printf (_("Layer %d of %d"),
+  gchar *l;
+
+  if (!gtk_widget_get_realized (GTK_WIDGET (ml)))
+    return;
+
+  l = g_strdup_printf (_("Layer %d of %d"),
                              ml->current_layer + 1, ml->n_layers);
   
   gtk_label_set_text (GTK_LABEL (ml->label), l);
   g_free (l);
 
-  psppire_var_view_set_current_model (PSPPIRE_VAR_VIEW (ml->var_view),
-                                     ml->current_layer);
-
   gtk_widget_set_sensitive (ml->back, ml->current_layer > 0);
   gtk_widget_set_sensitive (ml->forward,
-                           psppire_var_view_get_iter_first (PSPPIRE_VAR_VIEW (ml->var_view), NULL));
+                           psppire_var_view_get_iter_first (PSPPIRE_VAR_VIEW (ml->var_view),
+                                                            NULL));
 }
 
 static void
@@ -62,20 +88,29 @@ on_forward (PsppireMeansLayer *ml)
   ml->current_layer++;
   if (ml->current_layer >= ml->n_layers)
     {
-      ml->n_layers = ml->current_layer + 1;
-      psppire_var_view_push_model (PSPPIRE_VAR_VIEW (ml->var_view));
+      GtkTreeModel *tm;
+      psppire_var_view_clear (PSPPIRE_VAR_VIEW (ml->var_view));
+      tm = gtk_tree_view_get_model (GTK_TREE_VIEW (ml->var_view));
+      g_ptr_array_add (ml->layer, tm);
+      g_object_ref (tm);
+      ml->n_layers = ml->current_layer + 1;      
+    }
+  else
+    {
+      GtkTreeModel *tm = g_ptr_array_index (ml->layer, ml->current_layer);
+      gtk_tree_view_set_model (GTK_TREE_VIEW (ml->var_view), tm);
     }
-
-  update (ml);
 }
 
 static void
 on_back (PsppireMeansLayer *ml)
 {
+  GtkTreeModel *tm;
   g_return_if_fail (ml->current_layer > 0);
   ml->current_layer--;
 
-  update (ml);
+  tm = g_ptr_array_index (ml->layer, ml->current_layer);
+  gtk_tree_view_set_model (GTK_TREE_VIEW (ml->var_view), tm);
 }
 
 
@@ -87,6 +122,7 @@ psppire_means_layer_init  (PsppireMeansLayer      *ml)
   GtkWidget *alignment = gtk_alignment_new (0, 0.5, 0, 0);
   GtkWidget *sw = gtk_scrolled_window_new (NULL, NULL);
 
+  ml->dispose_has_run = FALSE;
   ml->forward = gtk_button_new_from_stock (GTK_STOCK_GO_FORWARD);
   ml->back = gtk_button_new_from_stock (GTK_STOCK_GO_BACK);
   ml->var_view = psppire_var_view_new ();
@@ -109,6 +145,7 @@ psppire_means_layer_init  (PsppireMeansLayer      *ml)
                NULL);
 
   g_object_set (ml->selector, "dest-widget", ml->var_view, NULL);
+  g_signal_connect_swapped (ml->var_view, "notify::model", G_CALLBACK (update), ml);
 
   gtk_box_pack_start (GTK_BOX (hbox_upper), ml->back, FALSE, FALSE, 5);
   gtk_box_pack_start (GTK_BOX (hbox_upper), ml->label, TRUE, FALSE, 5);
@@ -122,8 +159,16 @@ psppire_means_layer_init  (PsppireMeansLayer      *ml)
   gtk_box_pack_start (GTK_BOX (ml), hbox_upper, FALSE, FALSE, 5);
   gtk_box_pack_start (GTK_BOX (ml), hbox_lower, TRUE, TRUE, 5);
 
+
+
   ml->n_layers = 1;
   ml->current_layer = 0;
+  ml->layer = g_ptr_array_new_full (3, g_object_unref);
+
+  /* Add a model and take a reference to it */
+  g_ptr_array_add (ml->layer, gtk_tree_view_get_model (GTK_TREE_VIEW (ml->var_view)));
+  g_object_ref (g_ptr_array_index (ml->layer, ml->current_layer));
+
   update (ml);
 
   gtk_widget_show_all (hbox_upper);
@@ -147,8 +192,14 @@ psppire_means_layer_set_source (PsppireMeansLayer *ml, GtkWidget *w)
 void
 psppire_means_layer_clear (PsppireMeansLayer *ml)
 {
-  psppire_var_view_clear (PSPPIRE_VAR_VIEW (ml->var_view));
   ml->n_layers = 1;
   ml->current_layer = 0;
-  update (ml);
+  psppire_var_view_clear (PSPPIRE_VAR_VIEW (ml->var_view));
+}
+
+
+GtkTreeModel *
+psppire_means_layer_get_model_n (PsppireMeansLayer *ml, gint n)
+{
+  return g_ptr_array_index (ml->layer, n);
 }
index 327dc9f1e8fa8a65226e19388bfedc875c6ede01..7cd0f7b17f5abe4e23fd2c827fb08c5d870fc287 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2012  Free Software Foundation
+   Copyright (C) 2012, 2013  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
@@ -58,6 +58,9 @@ struct _PsppireMeansLayer
   GtkWidget *var_view;
   int n_layers;
   int current_layer;
+  GPtrArray *layer;
+  gboolean dispose_has_run;
+
   GtkWidget *label;
   GtkWidget *back;
   GtkWidget *forward;
@@ -77,6 +80,7 @@ GtkWidget * psppire_means_layer_new (void);
 void       psppire_means_layer_set_source (PsppireMeansLayer *ml, GtkWidget *w);
 
 void       psppire_means_layer_clear (PsppireMeansLayer *ml);
+GtkTreeModel *psppire_means_layer_get_model_n (PsppireMeansLayer *ml, gint n);
 
 
 G_END_DECLS
index 372ef3c531f18adef3fde1c4dd470e860bffc098..3b1bfe00abd41d208d6a924f00da269d0a118901 100644 (file)
@@ -599,7 +599,8 @@ static gboolean
 refilter (PsppireSelector *selector)
 {
   GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (selector->source));
-  gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (model));
+  if (GTK_IS_TREE_MODEL_FILTER (model))
+    gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (model));
   return FALSE;
 }
 
@@ -887,14 +888,18 @@ on_dest_model_changed (PsppireSelector *selector)
 {
   GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (selector->dest));
 
-  if ( model ) 
-    {
-      g_signal_connect (model, "row-changed", G_CALLBACK (on_dest_data_change),
-                       selector);
-      
-      g_signal_connect (model, "row-deleted", G_CALLBACK (on_dest_data_delete),
-                       selector);
-    }
+  if (model == NULL) 
+    return;
+
+  g_signal_connect (model, "row-changed", G_CALLBACK (on_dest_data_change),
+                   selector);
+  
+  g_signal_connect (model, "row-deleted", G_CALLBACK (on_dest_data_delete),
+                   selector);
+  
+  if ( selector->selecting ) return;
+  
+  refilter (selector);
 }
 
 /* Set the destination widget to DEST */
index 8f701a4dc742e4ac96a85f4cb49201c931af7081..47c845cba2c1e496a51ec4005de66876e4c75a1a 100644 (file)
@@ -104,32 +104,18 @@ psppire_var_view_get_type (void)
 void 
 psppire_var_view_clear (PsppireVarView *vv)
 {
-  gint i;
-  for (i = 0; i < vv->state->n_lists; ++i)
-    g_object_unref (vv->state->list[i]);
+  GtkListStore *l = gtk_list_store_newv  (vv->n_cols, vv->cols);
 
-  g_free (vv->state->list);
-
-  vv->state->n_lists = 0;
-  vv->state->l_idx = -1;
-  vv->state->list = NULL;
-
-  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->state->n_lists; ++i)
-    g_object_unref (var_view->state->list[i]);
-
-  g_free (var_view->state->list);
   g_free (var_view->cols);
-  g_free (var_view->state);
 }
 
 
@@ -221,48 +207,10 @@ set_renderers (PsppireVarView *var_view)
 }
 
 
-
-
-/* Set a model, which is an GtkListStore of gpointers which point to a variable */
-void
-psppire_var_view_push_model (PsppireVarView *vv)
-{
-  vv->state->n_lists++;
-  vv->state->l_idx++;
-  vv->state->list = xrealloc (vv->state->list, sizeof (*vv->state->list) * vv->state->n_lists);
-  vv->state->list[vv->state->l_idx] = gtk_list_store_newv  (vv->n_cols, vv->cols);
-  g_object_ref (vv->state->list[vv->state->l_idx]);
-  gtk_tree_view_set_model (GTK_TREE_VIEW (vv), GTK_TREE_MODEL (vv->state->list[vv->state->l_idx]));
-}
-
-
 GtkTreeModel *
 psppire_var_view_get_current_model (PsppireVarView *vv)
 {
-  if (vv->state == NULL) 
-    return NULL;
-
-  if (vv->state->list == NULL) 
-    return NULL;
-
-  if (vv->state->l_idx <= 0) 
-    return NULL;
-
-  return GTK_TREE_MODEL (vv->state->list[vv->state->l_idx]);
-}
-
-
-gboolean
-psppire_var_view_set_current_model (PsppireVarView *vv, gint n)
-{
-  if (n < 0 || n >= vv->state->n_lists)
-    return FALSE;
-
-  vv->state->l_idx = n;
-
-  gtk_tree_view_set_model (GTK_TREE_VIEW (vv), GTK_TREE_MODEL (vv->state->list[vv->state->l_idx]));
-
-  return TRUE;
+  return gtk_tree_view_get_model (GTK_TREE_VIEW (vv));
 }
 
 static void
@@ -325,8 +273,6 @@ psppire_var_view_base_init (PsppireVarViewClass *class)
 
   GObjectClass *object_class = G_OBJECT_CLASS (class);
 
-
-
   object_class->finalize = psppire_var_view_finalize;
 }
 
@@ -344,10 +290,6 @@ static void
 psppire_var_view_init (PsppireVarView *vv)
 {
   vv->cols = 0;
-  vv->state = g_malloc (sizeof *vv->state);
-  vv->state->n_lists = 0;
-  vv->state->l_idx = -1;
-  vv->state->list = NULL;
 }
 
 
@@ -362,27 +304,23 @@ gboolean
 psppire_var_view_get_iter_first (PsppireVarView *vv, GtkTreeIter *iter)
 {
   GtkTreeIter dummy;
-  if ( vv->state->l_idx < 0)
-    return FALSE;
-
-  return gtk_tree_model_get_iter_first (GTK_TREE_MODEL (vv->state->list[vv->state->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->state->l_idx < 0)
-    return FALSE;
-
-  return gtk_tree_model_iter_next (GTK_TREE_MODEL (vv->state->list[vv->state->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->state->list[vv->state->l_idx]), iter, column, &value);
+  gtk_tree_model_get_value (model, iter, column, &value);
 
   if ( G_VALUE_TYPE (&value) == PSPPIRE_VAR_PTR_TYPE)
     var = g_value_get_boxed (&value);
@@ -395,6 +333,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.
index bd1dca2df311535f182bd5e60b1fefb65b3bb7fa..430265d4fd8adafb2bf1aba9162eda5586171bfd 100644 (file)
@@ -40,25 +40,11 @@ typedef struct _PsppireVarViewClass  PsppireVarViewClass;
 
 struct variable;
 
-struct vvstate
-{
-  /* An array of GtkListStores */
-  GtkListStore **list;
-
-  /* The size of the above array */
-  gint n_lists;
-
-  /* The currently selected item in the array */
-  gint l_idx;
-};
-
 struct _PsppireVarView
 {
   GtkTreeView parent;
 
   /* Private */
-  struct vvstate *state;
-  
   GType *cols;
   gint *nums;
   gint n_cols;
@@ -81,10 +67,9 @@ gboolean psppire_var_view_get_iter_first (PsppireVarView *vv, GtkTreeIter *iter)
 gboolean psppire_var_view_get_iter_next (PsppireVarView *vv, GtkTreeIter *iter);
 
 const struct variable * psppire_var_view_get_variable (PsppireVarView *vv, gint column, GtkTreeIter *iter);
+const struct variable * psppire_var_view_get_var_from_model (GtkTreeModel *, gint column, GtkTreeIter *iter);
 
-void     psppire_var_view_push_model (PsppireVarView *vv);
 
-gboolean psppire_var_view_set_current_model (PsppireVarView *vv, gint n);
 GtkTreeModel *psppire_var_view_get_current_model (PsppireVarView *vv);
 
 void psppire_var_view_clear (PsppireVarView *vv);