From d5f42de822479581dded51ade0d997c16404890f Mon Sep 17 00:00:00 2001 From: John Darrington Date: Tue, 8 Oct 2013 06:46:38 +0200 Subject: [PATCH] Simplify psppire-var-view and its relationship to psppire-means-layer --- src/ui/gui/psppire-dialog-action-means.c | 13 ++-- src/ui/gui/psppire-means-layer.c | 77 ++++++++++++++++---- src/ui/gui/psppire-means-layer.h | 6 +- src/ui/gui/psppire-selector.c | 23 +++--- src/ui/gui/psppire-var-view.c | 89 +++++------------------- src/ui/gui/psppire-var-view.h | 17 +---- 6 files changed, 107 insertions(+), 118 deletions(-) diff --git a/src/ui/gui/psppire-dialog-action-means.c b/src/ui/gui/psppire-dialog-action-means.c index 6ebda50551..81e9bb9052 100644 --- a/src/ui/gui/psppire-dialog-action-means.c +++ b/src/ui/gui/psppire-dialog-action-means.c @@ -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)); } diff --git a/src/ui/gui/psppire-means-layer.c b/src/ui/gui/psppire-means-layer.c index 24178b8a35..a9b1139f18 100644 --- a/src/ui/gui/psppire-means-layer.c +++ b/src/ui/gui/psppire-means-layer.c @@ -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); } diff --git a/src/ui/gui/psppire-means-layer.h b/src/ui/gui/psppire-means-layer.h index 327dc9f1e8..7cd0f7b17f 100644 --- a/src/ui/gui/psppire-means-layer.h +++ b/src/ui/gui/psppire-means-layer.h @@ -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 diff --git a/src/ui/gui/psppire-selector.c b/src/ui/gui/psppire-selector.c index 372ef3c531..3b1bfe00ab 100644 --- a/src/ui/gui/psppire-selector.c +++ b/src/ui/gui/psppire-selector.c @@ -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 */ diff --git a/src/ui/gui/psppire-var-view.c b/src/ui/gui/psppire-var-view.c index 8f701a4dc7..47c845cba2 100644 --- a/src/ui/gui/psppire-var-view.c +++ b/src/ui/gui/psppire-var-view.c @@ -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. diff --git a/src/ui/gui/psppire-var-view.h b/src/ui/gui/psppire-var-view.h index bd1dca2df3..430265d4fd 100644 --- a/src/ui/gui/psppire-var-view.h +++ b/src/ui/gui/psppire-var-view.h @@ -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); -- 2.30.2