X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fui%2Fgui%2Fpsppire-var-view.c;h=c71a5e66103e2821814972461c12b46e1de0aa5a;hb=7fbadad9d6d9cad8805cafdd9ea157e753029ea0;hp=da1cc8c109020d9f1886aeeb39d1510227e96767;hpb=fd0c595927a23ea0373551a1eed4570388ea0fc5;p=pspp diff --git a/src/ui/gui/psppire-var-view.c b/src/ui/gui/psppire-var-view.c index da1cc8c109..c71a5e6610 100644 --- a/src/ui/gui/psppire-var-view.c +++ b/src/ui/gui/psppire-var-view.c @@ -1,5 +1,5 @@ /* PSPPIRE - a graphical user interface for PSPP. - Copyright (C) 2009 Free Software Foundation + Copyright (C) 2009, 2010, 2011 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 @@ -16,11 +16,12 @@ #include -#include -#include +#include #include "psppire-var-view.h" #include "psppire-var-ptr.h" +#include "psppire-select-dest.h" +#include #include #include @@ -32,6 +33,35 @@ 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); +/* Returns TRUE iff VV contains the item V. + V must be an initialised value containing a + PSPPIRE_VAR_PTR_TYPE. +*/ +static gboolean +var_view_contains_var (PsppireSelectDestWidget *sdm, const GValue *v) +{ + gboolean ok; + GtkTreeIter iter; + PsppireVarView *vv = PSPPIRE_VAR_VIEW (sdm); + g_return_val_if_fail (G_VALUE_HOLDS (v, PSPPIRE_VAR_PTR_TYPE), FALSE); + + for (ok = psppire_var_view_get_iter_first (vv, &iter); + ok; + ok = psppire_var_view_get_iter_next (vv, &iter)) + { + const struct variable *var = psppire_var_view_get_variable (vv, 0, &iter); + if (var == g_value_get_boxed (v)) + return TRUE; + } + + return FALSE; +} + +static void +model_init (PsppireSelectDestWidgetIface *iface) +{ + iface->contains_var = var_view_contains_var; +} GType psppire_var_view_get_type (void) @@ -53,22 +83,56 @@ psppire_var_view_get_type (void) (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); } return psppire_var_view_type; } +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; + + psppire_var_view_push_model (vv); +} + 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); } + + /* Properties */ enum { @@ -101,7 +165,7 @@ display_cell_var_name (GtkTreeViewColumn *tree_column, g_value_unset (&value); - g_object_set (cell, "text", var_get_name (var), NULL); + g_object_set (cell, "text", var ? var_get_name (var) : "", NULL); } @@ -116,7 +180,7 @@ psppire_var_view_get_property (GObject *object, switch (prop_id) { case PROP_N_COLS: - g_value_set_int (value, gtk_tree_model_iter_n_children (GTK_TREE_MODEL (var_view->list), NULL)); + g_value_set_int (value, var_view->n_cols); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -124,6 +188,64 @@ psppire_var_view_get_property (GObject *object, }; } +static void +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) +{ + 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; +} static void psppire_var_view_set_property (GObject *object, @@ -137,42 +259,17 @@ psppire_var_view_set_property (GObject *object, { case PROP_N_COLS: { - gint n_cols = g_value_get_int (value); gint c; + var_view->n_cols = g_value_get_int (value); + var_view->cols = xrealloc (var_view->cols, sizeof (GType) * var_view->n_cols); - GType *array = g_alloca (sizeof (GType) * n_cols); - - var_view->nums = g_malloc (sizeof *var_view->nums * n_cols); - - for (c = 0 ; c < 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); + for (c = 0 ; c < var_view->n_cols; ++c) + var_view->cols[c] = PSPPIRE_VAR_PTR_TYPE; - 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); - array[c] = PSPPIRE_VAR_PTR_TYPE; - } + set_renderers (var_view); - /* Set a model, which is an GtkListStore of gpointers which point to a variable */ - var_view->list = gtk_list_store_newv (n_cols, array); - gtk_tree_view_set_model (GTK_TREE_VIEW (var_view), GTK_TREE_MODEL (var_view->list)); + psppire_var_view_clear (var_view); } break; default: @@ -201,15 +298,17 @@ psppire_var_view_class_init (PsppireVarViewClass *class) g_object_class_install_property (object_class, PROP_N_COLS, 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; } @@ -224,8 +323,12 @@ psppire_var_view_base_finalize (PsppireVarViewClass *class, static void -psppire_var_view_init (PsppireVarView *var_view) +psppire_var_view_init (PsppireVarView *vv) { + vv->cols = 0; + vv->n_lists = 0; + vv->l_idx = -1; + vv->list = NULL; } @@ -236,6 +339,43 @@ psppire_var_view_new (void) } +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); +} + +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); +} + +const struct variable * +psppire_var_view_get_variable (PsppireVarView *vv, 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); + + 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.", + G_VALUE_TYPE_NAME (&value)); + + g_value_unset (&value); + + return var; +} + /* Append the names of selected variables to STRING. Returns the number of variables appended. @@ -246,31 +386,44 @@ psppire_var_view_append_names (PsppireVarView *vv, gint column, GString *string) gint n_vars = 0; GtkTreeIter iter; - if ( gtk_tree_model_get_iter_first (GTK_TREE_MODEL (vv->list), &iter) ) + if ( psppire_var_view_get_iter_first (vv, &iter) ) { do { - GValue value = {0}; - struct variable *var = NULL; - GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL (vv->list), &iter); + const struct variable *var = psppire_var_view_get_variable (vv, column, &iter); + g_string_append (string, " "); + g_string_append (string, var_get_name (var)); - gtk_tree_model_get_value (GTK_TREE_MODEL (vv->list), &iter, column, &value); + n_vars++; + } + while (psppire_var_view_get_iter_next (vv, &iter)); + } - 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.", - G_VALUE_TYPE_NAME (&value)); + return n_vars; +} - g_value_unset (&value); - g_string_append (string, " "); - g_string_append (string, var_get_name (var)); +/* + Append the names of selected variables to STR + Returns the number of variables appended. +*/ +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) ) + { + do + { + const struct variable *var = psppire_var_view_get_variable (vv, column, &iter); + ds_put_cstr (str, " "); + ds_put_cstr (str, var_get_name (var)); - gtk_tree_path_free (path); n_vars++; } - while (gtk_tree_model_iter_next (GTK_TREE_MODEL (vv->list), &iter)); + while (psppire_var_view_get_iter_next (vv, &iter)); } return n_vars;