From: John Darrington Date: Sun, 13 Dec 2009 19:39:35 +0000 (+0100) Subject: Merge branch 'master' of ssh://jmd@git.sv.gnu.org/srv/git/pspp X-Git-Tag: sid-i386-build122~8 X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=93b5d67c0fdc08137f308f332fede32543e7bc8e;hp=71fa94505d7d559e3f6bb90092268225db826732;p=pspp-builds.git Merge branch 'master' of ssh://jmd@git.sv.gnu.org/srv/git/pspp --- diff --git a/glade/automake.mk b/glade/automake.mk index 8e51e1f7..bb162886 100644 --- a/glade/automake.mk +++ b/glade/automake.mk @@ -15,6 +15,7 @@ libglade_psppire_la_SOURCES = \ glade/selector.c \ glade/acr.c \ glade/dictview.c \ + glade/var-view.c \ src/ui/gui/psppire-conf.c \ src/ui/gui/psppire-acr.c \ src/ui/gui/psppire-buttonbox.c \ @@ -23,7 +24,8 @@ libglade_psppire_la_SOURCES = \ src/ui/gui/psppire-dialog.c \ src/ui/gui/psppire-keypad.c \ src/ui/gui/psppire-dictview.c \ - src/ui/gui/psppire-selector.c + src/ui/gui/psppire-selector.c \ + src/ui/gui/psppire-var-view.c dist_catalog_DATA = \ glade/psppire.xml diff --git a/glade/psppire.xml b/glade/psppire.xml index 50a03661..db8956b7 100644 --- a/glade/psppire.xml +++ b/glade/psppire.xml @@ -173,8 +173,10 @@ - - + + + + @@ -210,12 +212,33 @@ + + + + + + + + + glade_psppire_var_view_post_create + glade_psppire_var_view_get_children + glade_psppire_var_view_get_internal_child + + + + + + + + + + @@ -223,6 +246,7 @@ + diff --git a/glade/var-view.c b/glade/var-view.c new file mode 100644 index 00000000..7eb6c627 --- /dev/null +++ b/glade/var-view.c @@ -0,0 +1,83 @@ +#include + +#include +#include +#include "psppire-var-view.h" + +#include + + +/* Dummy function to keep the linker happy. + Glade never actually needs to use this return value. + */ +GType +psppire_var_ptr_get_type (void) +{ + return 0; +} + +void +glade_psppire_var_view_post_create (GladeWidgetAdaptor *adaptor, + GObject *object, + GladeCreateReason reason) +{ + GladeWidget *widget ; + + PsppireVarView *var_view = PSPPIRE_VAR_VIEW (object); + + g_return_if_fail (PSPPIRE_IS_VAR_VIEW (var_view)); + + widget = glade_widget_get_from_gobject (GTK_WIDGET (var_view)); + if (!widget) + return; + + if (reason == GLADE_CREATE_USER) + { + /* HIG complient border-width defaults on var_views */ + glade_widget_property_set (widget, "border-width", 5); + } +} + + +GtkWidget * +glade_psppire_var_view_get_internal_child (GladeWidgetAdaptor *adaptor, + PsppireVarView *var_view, + const gchar *name) +{ +#if DEBUGGING + g_print ("%s\n", __FUNCTION__); +#endif + return GTK_WIDGET (var_view); +} + + + +void +glade_psppire_var_view_set_property (GladeWidgetAdaptor *adaptor, + GObject *object, + const gchar *id, + const GValue *value) +{ +#if DEBUGGING + g_print ("%s(%p) Type=\"%s\" Id=\"%s\"\n", __FUNCTION__, object, + G_OBJECT_TYPE_NAME( object ), + id); +#endif + + GWA_GET_CLASS (GTK_TYPE_WINDOW)->set_property (adaptor, object, + id, value); +} + + +GList * +glade_psppire_var_view_get_children (GladeWidgetAdaptor *adaptor, + PsppireVarView *dv) +{ + GList *list = NULL; + + g_return_val_if_fail (PSPPIRE_IS_VAR_VIEW (dv), NULL); + + list = glade_util_container_get_all_children (GTK_CONTAINER (dv)); + + return list; +} diff --git a/src/ui/gui/automake.mk b/src/ui/gui/automake.mk index aaaa05b6..22e2350b 100644 --- a/src/ui/gui/automake.mk +++ b/src/ui/gui/automake.mk @@ -67,6 +67,7 @@ UI_FILES = \ src/ui/gui/recode.ui \ src/ui/gui/regression.ui \ src/ui/gui/reliability.ui \ + src/ui/gui/roc.ui \ src/ui/gui/t-test.ui \ src/ui/gui/text-data-import.ui \ src/ui/gui/var-sheet-dialogs.ui \ @@ -163,6 +164,8 @@ src_ui_gui_psppire_SOURCES = \ src/ui/gui/psppire-keypad.h \ src/ui/gui/psppire-output-window.c \ src/ui/gui/psppire-output-window.h \ + src/ui/gui/psppire-var-view.c \ + src/ui/gui/psppire-var-view.h \ src/ui/gui/psppire-selector.h \ src/ui/gui/psppire-syntax-window.c \ src/ui/gui/psppire-syntax-window.h \ @@ -185,6 +188,8 @@ src_ui_gui_psppire_SOURCES = \ src/ui/gui/regression-dialog.h \ src/ui/gui/reliability-dialog.c \ src/ui/gui/reliability-dialog.h \ + src/ui/gui/roc-dialog.c \ + src/ui/gui/roc-dialog.h \ src/ui/gui/select-cases-dialog.c \ src/ui/gui/select-cases-dialog.h \ src/ui/gui/sort-cases-dialog.c \ diff --git a/src/ui/gui/compute-dialog.c b/src/ui/gui/compute-dialog.c index c09c7571..8a98bb3d 100644 --- a/src/ui/gui/compute-dialog.c +++ b/src/ui/gui/compute-dialog.c @@ -379,7 +379,6 @@ compute_dialog (GObject *o, gpointer data) GtkWidget *functions = get_widget_assert (xml, "compute-treeview2"); GtkWidget *keypad = get_widget_assert (xml, "psppire-keypad1"); GtkWidget *target = get_widget_assert (xml, "compute-entry1"); - GtkWidget *syntax_area = get_widget_assert (xml, "compute-textview1"); GtkWidget *var_selector = get_widget_assert (xml, "compute-selector1"); GtkWidget *func_selector = get_widget_assert (xml, "compute-selector2"); GtkWidget *type_and_label = get_widget_assert (xml, "compute-button1"); @@ -398,25 +397,17 @@ compute_dialog (GObject *o, gpointer data) gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de)); - g_object_set (dict_view, "dictionary", scd.dict, + g_object_set (dict_view, "model", scd.dict, "selection-mode", GTK_SELECTION_SINGLE, NULL); - psppire_selector_set_subjects (PSPPIRE_SELECTOR (var_selector), - dict_view, syntax_area, - insert_source_row_into_text_view, - NULL, - NULL); - + psppire_selector_set_select_func (PSPPIRE_SELECTOR (var_selector), + insert_source_row_into_text_view, NULL); function_list_populate (GTK_TREE_VIEW (functions)); - psppire_selector_set_subjects (PSPPIRE_SELECTOR (func_selector), - functions, syntax_area, - insert_function_into_syntax_area, - NULL, - NULL); - + psppire_selector_set_select_func (PSPPIRE_SELECTOR (func_selector), + insert_function_into_syntax_area, NULL); scd.xml = xml; diff --git a/src/ui/gui/crosstabs-dialog.c b/src/ui/gui/crosstabs-dialog.c index 019d8c36..2b93a77b 100644 --- a/src/ui/gui/crosstabs-dialog.c +++ b/src/ui/gui/crosstabs-dialog.c @@ -18,6 +18,7 @@ #include "checkbox-treeview.h" #include "crosstabs-dialog.h" +#include "psppire-var-view.h" #include #include @@ -259,9 +260,9 @@ generate_syntax (const struct crosstabs_dialog *cd) GString *string = g_string_new ("CROSSTABS"); g_string_append (string, "\n\t/TABLES="); - append_variable_names (string, cd->dict, GTK_TREE_VIEW (cd->row_vars), 0); + psppire_var_view_append_names (PSPPIRE_VAR_VIEW (cd->row_vars), 0, string); g_string_append (string, "\tBY\t"); - append_variable_names (string, cd->dict, GTK_TREE_VIEW (cd->col_vars), 0); + psppire_var_view_append_names (PSPPIRE_VAR_VIEW (cd->col_vars), 0, string); g_string_append (string, "\n\t/FORMAT="); @@ -398,8 +399,6 @@ crosstabs_dialog (GObject *o, gpointer data) GtkWidget *source = get_widget_assert (xml, "dict-treeview"); GtkWidget *dest_rows = get_widget_assert (xml, "rows"); GtkWidget *dest_cols = get_widget_assert (xml, "cols"); - GtkWidget *row_selector = get_widget_assert (xml, "row-selector"); - GtkWidget *col_selector = get_widget_assert (xml, "col-selector"); GtkWidget *format_button = get_widget_assert (xml, "format-button"); GtkWidget *stat_button = get_widget_assert (xml, "stats-button"); GtkWidget *cell_button = get_widget_assert (xml, "cell-button"); @@ -424,24 +423,7 @@ crosstabs_dialog (GObject *o, gpointer data) gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de)); g_object_get (vs, "dictionary", &dict, NULL); - g_object_set (source, "dictionary", dict, NULL); - - set_dest_model (GTK_TREE_VIEW (dest_rows), dict); - set_dest_model (GTK_TREE_VIEW (dest_cols), dict); - - psppire_selector_set_subjects (PSPPIRE_SELECTOR (row_selector), - source, - dest_rows, - insert_source_row_into_tree_view, - NULL, - NULL); - - psppire_selector_set_subjects (PSPPIRE_SELECTOR (col_selector), - source, - dest_cols, - insert_source_row_into_tree_view, - NULL, - NULL); + g_object_set (source, "model", dict, NULL); cd.row_vars = GTK_TREE_VIEW (dest_rows); cd.col_vars = GTK_TREE_VIEW (dest_cols); diff --git a/src/ui/gui/crosstabs.ui b/src/ui/gui/crosstabs.ui index c556c478..e21ae808 100644 --- a/src/ui/gui/crosstabs.ui +++ b/src/ui/gui/crosstabs.ui @@ -34,7 +34,7 @@ automatic etched-in - + True False @@ -73,7 +73,7 @@ automatic etched-in - + True False @@ -173,6 +173,8 @@ True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 5 + dict-treeview + rows 1 @@ -188,6 +190,8 @@ True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 5 + dict-treeview + cols 1 diff --git a/src/ui/gui/data-editor.glade b/src/ui/gui/data-editor.glade index 06776248..ca7efc90 100644 --- a/src/ui/gui/data-editor.glade +++ b/src/ui/gui/data-editor.glade @@ -1,7 +1,7 @@ - - - + + + True @@ -13,8 +13,8 @@ - True gtk-new + True True True @@ -39,8 +39,8 @@ - True gtk-open + True True True @@ -78,16 +78,16 @@ - True gtk-save + True True True - True gtk-save-as + True True True @@ -150,8 +150,8 @@ - True gtk-quit + True True True @@ -185,10 +185,11 @@ + Go To Case True False - Go To Case True + True @@ -199,27 +200,27 @@ + gtk-cut True False - gtk-cut True True + gtk-copy True False - gtk-copy True True + gtk-paste True False - gtk-paste True True @@ -247,9 +248,9 @@ + gtk-find True False - gtk-find True True @@ -332,15 +333,10 @@ + _Sort Cases True - _Sort Cases True - - - True - gtk-sort-ascending - - + True @@ -439,7 +435,7 @@ False _Run Pending Transforms True - + @@ -592,6 +588,13 @@ + + + True + ROC Cur_ve... + True + + @@ -661,28 +664,18 @@ + _Reference Manual True - _Reference Manual True - - - True - gtk-help - - + True + _About True - _About True - - - True - gtk-about - - + True @@ -692,7 +685,6 @@ True - GTK_SHADOW_OUT True @@ -704,6 +696,7 @@ False + True @@ -714,6 +707,7 @@ False + True @@ -724,6 +718,7 @@ False + True @@ -734,14 +729,13 @@ False + True - - + False - False @@ -752,6 +746,7 @@ False + True @@ -762,6 +757,7 @@ False + True @@ -770,7 +766,6 @@ False - False @@ -782,6 +777,7 @@ False + True @@ -793,6 +789,7 @@ False + True @@ -801,7 +798,6 @@ False - False @@ -813,6 +809,7 @@ False + True @@ -821,7 +818,6 @@ False - False @@ -834,6 +830,7 @@ False + True @@ -846,6 +843,7 @@ False + True @@ -854,7 +852,6 @@ False - False @@ -866,6 +863,7 @@ False + True @@ -877,6 +875,7 @@ False + True @@ -889,6 +888,7 @@ False + True @@ -897,7 +897,6 @@ False - False @@ -909,6 +908,7 @@ False + True @@ -919,6 +919,7 @@ False + True @@ -931,7 +932,7 @@ True 0 - GTK_SHADOW_IN + in True @@ -945,12 +946,15 @@ + + 0 + True 0 - GTK_SHADOW_IN + in True @@ -975,7 +979,7 @@ True 0 - GTK_SHADOW_IN + in True @@ -1000,7 +1004,7 @@ True 0 - GTK_SHADOW_IN + in True @@ -1008,7 +1012,7 @@ True - PANGO_ELLIPSIZE_START + start 10 True @@ -1026,7 +1030,7 @@ True 0 - GTK_SHADOW_IN + in True @@ -1034,7 +1038,7 @@ True - PANGO_ELLIPSIZE_START + start 15 True @@ -1052,7 +1056,7 @@ True 0 - GTK_SHADOW_IN + in True @@ -1060,7 +1064,7 @@ True - PANGO_ELLIPSIZE_START + start 15 True diff --git a/src/ui/gui/descriptives-dialog.c b/src/ui/gui/descriptives-dialog.c index 318646f8..9d8502de 100644 --- a/src/ui/gui/descriptives-dialog.c +++ b/src/ui/gui/descriptives-dialog.c @@ -18,6 +18,7 @@ #include "checkbox-treeview.h" #include "descriptives-dialog.h" +#include "psppire-var-view.h" #include #include @@ -117,7 +118,7 @@ generate_syntax (const struct descriptives_dialog *scd) string = g_string_new ("DESCRIPTIVES"); g_string_append (string, "\n /VARIABLES="); - append_variable_names (string, scd->dict, GTK_TREE_VIEW (scd->stat_vars), 0); + psppire_var_view_append_names (PSPPIRE_VAR_VIEW (scd->stat_vars), 0, string); listwise = gtk_toggle_button_get_active (scd->exclude_missing_listwise); include = gtk_toggle_button_get_active (scd->include_user_missing); @@ -212,7 +213,6 @@ descriptives_dialog (GObject *o, gpointer data) GtkWidget *source = get_widget_assert (xml, "all-variables"); - GtkWidget *selector = get_widget_assert (xml, "stat-var-selector"); GtkWidget *dest = get_widget_assert (xml, "stat-variables"); GtkWidget *stats_treeview = get_widget_assert (xml, "statistics"); @@ -226,18 +226,9 @@ descriptives_dialog (GObject *o, gpointer data) gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de)); - g_object_set (source, "dictionary", dict, + g_object_set (source, "model", dict, "predicate", var_is_numeric, NULL); - set_dest_model (GTK_TREE_VIEW (dest), dict); - - psppire_selector_set_subjects (PSPPIRE_SELECTOR (selector), - source, - dest, - insert_source_row_into_tree_view, - NULL, - NULL); - put_checkbox_items_in_treeview (GTK_TREE_VIEW (stats_treeview), B_DS_DEFAULT, N_DESCRIPTIVE_STATS, stats); diff --git a/src/ui/gui/descriptives.ui b/src/ui/gui/descriptives.ui index f5dc93f2..62e601f9 100644 --- a/src/ui/gui/descriptives.ui +++ b/src/ui/gui/descriptives.ui @@ -56,6 +56,8 @@ True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 5 + all-variables + stat-variables @@ -97,7 +99,7 @@ automatic etched-in - + True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK diff --git a/src/ui/gui/dialog-common.c b/src/ui/gui/dialog-common.c index 5d52204c..7edbbe50 100644 --- a/src/ui/gui/dialog-common.c +++ b/src/ui/gui/dialog-common.c @@ -23,66 +23,18 @@ #include "helper.h" - -/* Append the names of selected variables to STRING. - TREEVIEW is the treeview containing the variables. - COLUMN is the column in the treeview containing the variables. - DICT is the dictionary for those variables. +/* A (*GtkTreeCellDataFunc) function. + This function expects TREEMODEL to hold G_TYPE_BOXED, which is a pointer to a variable. + It renders the name of the variable into CELL. */ -gint -append_variable_names (GString *string, - PsppireDict *dict, GtkTreeView *treeview, gint column) -{ - gint n_vars = 0; - GtkTreeIter iter; - - GtkTreeModel *list_store = - gtk_tree_view_get_model (treeview); - - if ( gtk_tree_model_get_iter_first (list_store, &iter) ) - { - do - { - GValue value = {0}; - struct variable *var = NULL; - GtkTreePath *path = gtk_tree_model_get_path (list_store, &iter); - - gtk_tree_model_get_value (list_store, &iter, column, &value); - - /* FIXME: G_TYPE_INT should be deprecated. - As well as being simpler, it'd be unecessary to pass dict */ - if ( G_VALUE_TYPE (&value) == G_TYPE_INT ) - var = psppire_dict_get_variable (dict, g_value_get_int (&value)); - - else 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); - - g_string_append (string, " "); - g_string_append (string, var_get_name (var)); - - gtk_tree_path_free (path); - n_vars++; - } - while (gtk_tree_model_iter_next (list_store, &iter)); - } - - return n_vars; -} - - - -struct variable * -get_selected_variable (GtkTreeModel *treemodel, - GtkTreeIter *iter, - PsppireDict *dict) +void +XXX_cell_var_name (GtkTreeViewColumn *tree_column, + GtkCellRenderer *cell, + GtkTreeModel *treemodel, + GtkTreeIter *iter, + gpointer data) { - struct variable *var; + const struct variable *var; GValue value = {0}; GtkTreePath *path = gtk_tree_model_get_path (treemodel, iter); @@ -91,67 +43,15 @@ get_selected_variable (GtkTreeModel *treemodel, gtk_tree_path_free (path); - var = psppire_dict_get_variable (dict, g_value_get_int (&value)); + var = g_value_get_boxed (&value); g_value_unset (&value); - return var; -} - - - - -/* A (*GtkTreeCellDataFunc) function. - This function expects TREEMODEL to hold G_TYPE_INT. The ints it holds - are the indices of the variables in the dictionary, which DATA points to. - It renders the name of the variable into CELL. -*/ -void -cell_var_name (GtkTreeViewColumn *tree_column, - GtkCellRenderer *cell, - GtkTreeModel *tree_model, - GtkTreeIter *iter, - gpointer data) -{ - PsppireDict *dict = data; - const struct variable *var = get_selected_variable (tree_model, iter, dict); - g_object_set (cell, "text", var_get_name (var), NULL); } -/* Set a model for DEST, which is an GtkListStore of g_int's - whose values are the indices into DICT */ -void -set_dest_model (GtkTreeView *dest, PsppireDict *dict) -{ - GtkTreeViewColumn *col; - GtkListStore *dest_list = gtk_list_store_new (1, G_TYPE_INT); - GtkCellRenderer *renderer = gtk_cell_renderer_text_new (); - - gtk_tree_view_set_model (GTK_TREE_VIEW (dest), GTK_TREE_MODEL (dest_list)); - - col = gtk_tree_view_column_new_with_attributes ("Var", - renderer, - "text", - 0, - NULL); - - gtk_tree_view_column_set_cell_data_func (col, renderer, - cell_var_name, - dict, 0); - - /* FIXME: make this a value in terms of character widths */ - g_object_set (col, "min-width", 100, NULL); - - gtk_tree_view_column_set_sizing (col, GTK_TREE_VIEW_COLUMN_FIXED); - - gtk_tree_view_append_column (GTK_TREE_VIEW (dest), col); -} - - - /* Returns FALSE if the variables represented by the union of the rows currently selected by SOURCE widget, and contents of the DEST widget, are of different types. @@ -224,11 +124,8 @@ homogeneous_types (GtkWidget *source, GtkWidget *dest) ok; ok = gtk_tree_model_iter_next (model, &iter)) { - gint idx; const struct variable *v; - gtk_tree_model_get (model, &iter, 0, &idx, -1); - - v = psppire_dict_get_variable (dict, idx); + gtk_tree_model_get (model, &iter, 0, &v, -1); if ( type != -1 ) { @@ -242,7 +139,6 @@ homogeneous_types (GtkWidget *source, GtkWidget *dest) type = var_get_type (v); } - return retval; } diff --git a/src/ui/gui/dialog-common.h b/src/ui/gui/dialog-common.h index 9a003f35..328904ac 100644 --- a/src/ui/gui/dialog-common.h +++ b/src/ui/gui/dialog-common.h @@ -23,40 +23,18 @@ #include #include "psppire-dict.h" -/* Append the names of selected variables to STRING. - TREEVIEW is the treeview containing the variables. - COLUMN is column in treeview containing the variables. - DICT is the dictionary for those variables. -*/ -gint append_variable_names (GString *string, PsppireDict *dict, - GtkTreeView *treeview, gint column); - - -/* Returns the variable currently selected by the iterator - pointing to TREEMODEL */ -struct variable * get_selected_variable (GtkTreeModel *treemodel, - GtkTreeIter *iter, - PsppireDict *dict); - - - /* A (*GtkTreeCellDataFunc) function. This function expects TREEMODEL to hold G_TYPE_INT. The ints it holds are the indices of the variables in the dictionary, which DATA points to. It renders the name of the variable into CELL. */ -void cell_var_name (GtkTreeViewColumn *tree_column, +void XXX_cell_var_name (GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data); -/* Set a model for DEST, which is an GtkListStore of g_int's - whose values are the indices into DICT */ -void set_dest_model (GtkTreeView *dest, PsppireDict *dict); - - /* Returns FALSE if the variables represented by the union of the rows currently selected by SOURCE widget, and contents of the DEST widget, are of different types. diff --git a/src/ui/gui/dict-display.c b/src/ui/gui/dict-display.c index 1665d7ff..160cdb2a 100644 --- a/src/ui/gui/dict-display.c +++ b/src/ui/gui/dict-display.c @@ -54,7 +54,6 @@ get_base_model (GtkTreeModel *top_model, GtkTreeIter *top_iter, } - void insert_source_row_into_entry (GtkTreeIter iter, GtkWidget *dest, @@ -84,7 +83,6 @@ insert_source_row_into_entry (GtkTreeIter iter, } - void insert_source_row_into_tree_view (GtkTreeIter iter, GtkWidget *dest, @@ -96,24 +94,28 @@ insert_source_row_into_tree_view (GtkTreeIter iter, GtkTreeIter dest_iter; GtkTreeIter dict_iter; gint *row ; - GtkTreeModel *destmodel = gtk_tree_view_get_model ( GTK_TREE_VIEW (dest)); + GtkTreeModel *destmodel = gtk_tree_view_get_model (GTK_TREE_VIEW (dest)); + const struct variable *var; GtkTreeModel *dict; - get_base_model (model, &iter, &dict, &dict_iter); path = gtk_tree_model_get_path (dict, &dict_iter); row = gtk_tree_path_get_indices (path); + var = psppire_dict_get_variable (PSPPIRE_DICT (dict), *row); + gtk_list_store_append (GTK_LIST_STORE (destmodel), &dest_iter); - gtk_list_store_set (GTK_LIST_STORE (destmodel), &dest_iter, 0, *row, -1); + + gtk_list_store_set (GTK_LIST_STORE (destmodel), &dest_iter, 0, var, -1); gtk_tree_path_free (path); } + gboolean is_currently_in_entry (GtkTreeModel *model, GtkTreeIter *iter, PsppireSelector *selector) @@ -125,7 +127,12 @@ is_currently_in_entry (GtkTreeModel *model, GtkTreeIter *iter, gint dict_index; gint *indeces; GtkTreePath *path; - const gchar *text = gtk_entry_get_text (GTK_ENTRY (selector->dest)); + GtkWidget *entry = NULL; + const gchar *text = NULL; + + g_object_get (selector, "dest-widget", &entry, NULL); + + text = gtk_entry_get_text (GTK_ENTRY (entry)); get_base_model (model, iter, &dict, &dict_iter); diff --git a/src/ui/gui/dict-display.h b/src/ui/gui/dict-display.h index 2c8df440..f1a8a001 100644 --- a/src/ui/gui/dict-display.h +++ b/src/ui/gui/dict-display.h @@ -31,7 +31,6 @@ void insert_source_row_into_tree_view (GtkTreeIter source_iter, gpointer data ); - /* A SelectItemsFunc function for GtkEntry widgets */ void insert_source_row_into_entry (GtkTreeIter source_iter, GtkWidget *dest, diff --git a/src/ui/gui/examine-dialog.c b/src/ui/gui/examine-dialog.c index 470c4dbb..67523143 100644 --- a/src/ui/gui/examine-dialog.c +++ b/src/ui/gui/examine-dialog.c @@ -1,5 +1,5 @@ /* PSPPIRE - a graphical user interface for PSPP. - Copyright (C) 2007, 2008 Free Software Foundation + Copyright (C) 2007, 2008, 2009 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 @@ -17,6 +17,7 @@ #include #include "examine-dialog.h" +#include "psppire-var-view.h" #include #include @@ -96,13 +97,13 @@ generate_syntax (const struct examine_dialog *ed) GString *str = g_string_new ("EXAMINE "); g_string_append (str, "\n\t/VARIABLES="); - append_variable_names (str, ed->dict, GTK_TREE_VIEW (ed->dep_list), 0); + psppire_var_view_append_names (PSPPIRE_VAR_VIEW (ed->dep_list), 0, str); if ( 0 < gtk_tree_model_iter_n_children (gtk_tree_view_get_model (GTK_TREE_VIEW (ed->fct_list)), NULL)) { g_string_append (str, "\n\tBY "); - append_variable_names (str, ed->dict, GTK_TREE_VIEW (ed->fct_list), 0); + psppire_var_view_append_names (PSPPIRE_VAR_VIEW (ed->fct_list), 0, str); } label = gtk_entry_get_text (GTK_ENTRY (ed->id_entry)); @@ -250,8 +251,6 @@ examine_dialog (GObject *o, gpointer data) GtkWidget *dep_selector = get_widget_assert (xml, "psppire-selector1"); - GtkWidget *fct_selector = get_widget_assert (xml, "psppire-selector2"); - GtkWidget *id_selector = get_widget_assert (xml, "psppire-selector3"); PsppireVarStore *vs = NULL; @@ -280,36 +279,11 @@ examine_dialog (GObject *o, gpointer data) gtk_window_set_transient_for (GTK_WINDOW (ex_d.opts_dialog), GTK_WINDOW (de)); g_object_get (vs, "dictionary", &ex_d.dict, NULL); - g_object_set (source, "dictionary", ex_d.dict, NULL); - - set_dest_model (GTK_TREE_VIEW (ex_d.dep_list), ex_d.dict); - - - psppire_selector_set_subjects (PSPPIRE_SELECTOR (dep_selector), - source, - ex_d.dep_list, - insert_source_row_into_tree_view, - NULL, NULL); + g_object_set (source, "model", ex_d.dict, NULL); psppire_selector_set_allow (PSPPIRE_SELECTOR (dep_selector), numeric_only); - set_dest_model (GTK_TREE_VIEW (ex_d.fct_list), ex_d.dict); - - - psppire_selector_set_subjects (PSPPIRE_SELECTOR (fct_selector), - source, - ex_d.fct_list, - insert_source_row_into_tree_view, - NULL, NULL); - - - psppire_selector_set_subjects (PSPPIRE_SELECTOR (id_selector), - source, - ex_d.id_entry, - insert_source_row_into_entry, - NULL, NULL); - g_signal_connect (dialog, "refresh", G_CALLBACK (refresh), &ex_d); psppire_dialog_set_valid_predicate (PSPPIRE_DIALOG (dialog), diff --git a/src/ui/gui/examine.ui b/src/ui/gui/examine.ui index 273c19bc..316f1043 100644 --- a/src/ui/gui/examine.ui +++ b/src/ui/gui/examine.ui @@ -81,7 +81,7 @@ automatic etched-in - + True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK @@ -128,7 +128,7 @@ automatic etched-in - + True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK @@ -160,6 +160,8 @@ True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 5 + treeview1 + entry1 1 @@ -177,6 +179,8 @@ True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 5 + treeview1 + treeview3 1 @@ -194,6 +198,9 @@ True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 5 + True + treeview1 + treeview2 1 diff --git a/src/ui/gui/find-dialog.c b/src/ui/gui/find-dialog.c index 11ec0603..40e91bc0 100644 --- a/src/ui/gui/find-dialog.c +++ b/src/ui/gui/find-dialog.c @@ -242,17 +242,13 @@ find_dialog (GObject *o, gpointer data) gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de)); - g_object_set (source, "dictionary", fd.dict, + g_object_set (source, "model", fd.dict, "selection-mode", GTK_SELECTION_SINGLE, NULL); - psppire_selector_set_subjects (PSPPIRE_SELECTOR (selector), - source, - fd.variable_entry, - insert_source_row_into_entry, - is_currently_in_entry, - NULL - ); + + psppire_selector_set_filter_func (PSPPIRE_SELECTOR (selector), + is_currently_in_entry); g_signal_connect (dialog, "refresh", G_CALLBACK (refresh), &fd); diff --git a/src/ui/gui/find.ui b/src/ui/gui/find.ui index 8dae0c99..d1cb203c 100644 --- a/src/ui/gui/find.ui +++ b/src/ui/gui/find.ui @@ -52,6 +52,8 @@ True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 5 + find-variable-treeview + find-variable-entry False diff --git a/src/ui/gui/frequencies-dialog.c b/src/ui/gui/frequencies-dialog.c index 8706f3a4..2d5fcbb4 100644 --- a/src/ui/gui/frequencies-dialog.c +++ b/src/ui/gui/frequencies-dialog.c @@ -18,6 +18,7 @@ #include "checkbox-treeview.h" #include "frequencies-dialog.h" +#include "psppire-var-view.h" #include #include @@ -147,7 +148,7 @@ generate_syntax (const struct frequencies_dialog *fd) GString *string = g_string_new ("FREQUENCIES"); g_string_append (string, "\n\t/VARIABLES="); - append_variable_names (string, fd->dict, GTK_TREE_VIEW (fd->stat_vars), 0); + psppire_var_view_append_names (PSPPIRE_VAR_VIEW (fd->stat_vars), 0, string); g_string_append (string, "\n\t/FORMAT="); @@ -316,7 +317,6 @@ frequencies_dialog (GObject *o, gpointer data) GtkWidget *dialog = get_widget_assert (xml, "frequencies-dialog"); GtkWidget *source = get_widget_assert (xml, "dict-treeview"); GtkWidget *dest = get_widget_assert (xml, "var-treeview"); - GtkWidget *selector = get_widget_assert (xml, "selector1"); GtkWidget *format_button = get_widget_assert (xml, "button1"); GtkWidget *stats_treeview = get_widget_assert (xml, "stats-treeview"); @@ -334,19 +334,7 @@ frequencies_dialog (GObject *o, gpointer data) gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de)); g_object_get (vs, "dictionary", &fd.dict, NULL); - g_object_set (source, "dictionary", fd.dict, NULL); - - - set_dest_model (GTK_TREE_VIEW (dest), fd.dict); - - - psppire_selector_set_subjects (PSPPIRE_SELECTOR (selector), - source, - dest, - insert_source_row_into_tree_view, - NULL, - NULL); - + g_object_set (source, "model", fd.dict, NULL); fd.stat_vars = GTK_TREE_VIEW (dest); fd.table_button = get_widget_assert (xml, "checkbutton1"); diff --git a/src/ui/gui/frequencies.ui b/src/ui/gui/frequencies.ui index 47e25d49..0ab2f29f 100644 --- a/src/ui/gui/frequencies.ui +++ b/src/ui/gui/frequencies.ui @@ -56,6 +56,8 @@ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True 5 + dict-treeview + var-treeview @@ -85,7 +87,7 @@ automatic etched-in - + True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK diff --git a/src/ui/gui/oneway-anova-dialog.c b/src/ui/gui/oneway-anova-dialog.c index 1814dd67..57428667 100644 --- a/src/ui/gui/oneway-anova-dialog.c +++ b/src/ui/gui/oneway-anova-dialog.c @@ -15,12 +15,12 @@ along with this program. If not, see . */ - #include #include #include "oneway-anova-dialog.h" #include "psppire-dict.h" #include "psppire-var-store.h" +#include "psppire-var-view.h" #include "helper.h" #include "psppire-data-window.h" #include "psppire-dialog.h" @@ -29,7 +29,6 @@ #include "psppire-selector.h" #include "dict-display.h" - #include #include "executor.h" @@ -141,9 +140,6 @@ oneway_anova_dialog (GObject *o, gpointer data) GtkWidget *selector2 = get_widget_assert (builder, "oneway-anova-selector2"); - GtkWidget *selector1 = - get_widget_assert (builder, "oneway-anova-selector1"); - GtkWidget *contrasts_button = get_widget_assert (builder, "contrasts-button"); @@ -171,24 +167,11 @@ oneway_anova_dialog (GObject *o, gpointer data) gtk_window_set_transient_for (ow.dialog, GTK_WINDOW (de)); - g_object_set (dict_view, "dictionary", ow.dict, NULL); - - set_dest_model (GTK_TREE_VIEW (ow.vars_treeview), ow.dict); - - - psppire_selector_set_subjects (PSPPIRE_SELECTOR (selector1), - dict_view, ow.vars_treeview, - insert_source_row_into_tree_view, - NULL, - NULL); - + g_object_set (dict_view, "model", ow.dict, NULL); - psppire_selector_set_subjects (PSPPIRE_SELECTOR (selector2), - dict_view, ow.factor_entry, - insert_source_row_into_entry, - is_currently_in_entry, - NULL); + psppire_selector_set_filter_func (PSPPIRE_SELECTOR (selector2), + is_currently_in_entry); g_signal_connect_swapped (ow.dialog, "refresh", G_CALLBACK (refresh), &ow); @@ -265,7 +248,7 @@ static gchar * generate_syntax (const struct oneway_anova_dialog *ow) GString *str = g_string_new ("ONEWAY /VARIABLES="); - append_variable_names (str, ow->dict, GTK_TREE_VIEW (ow->vars_treeview), 0); + psppire_var_view_append_names (PSPPIRE_VAR_VIEW (ow->vars_treeview), 0, str); g_string_append (str, " BY "); diff --git a/src/ui/gui/oneway.ui b/src/ui/gui/oneway.ui index 6ec3120f..7381932b 100644 --- a/src/ui/gui/oneway.ui +++ b/src/ui/gui/oneway.ui @@ -84,7 +84,7 @@ automatic etched-in - + True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK @@ -109,6 +109,8 @@ True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 5 + oneway-anova-treeview1 + oneway-anova-entry 1 @@ -126,6 +128,9 @@ True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 5 + True + oneway-anova-treeview1 + oneway-anova-treeview2 1 diff --git a/src/ui/gui/psppire-data-window.c b/src/ui/gui/psppire-data-window.c index 2707498c..e42d2bd0 100644 --- a/src/ui/gui/psppire-data-window.c +++ b/src/ui/gui/psppire-data-window.c @@ -56,6 +56,7 @@ #include "examine-dialog.h" #include "regression-dialog.h" #include "reliability-dialog.h" +#include "roc-dialog.h" #include "oneway-anova-dialog.h" #include "t-test-independent-samples-dialog.h" #include "t-test-one-sample.h" @@ -1692,6 +1693,20 @@ psppire_data_window_init (PsppireDataWindow *de) G_CALLBACK (reliability_dialog), de); } + { + GtkAction *invoke_roc_dialog = + resolve_action (de->builder, "roc-curve", NULL); + + g_object_set (invoke_roc_dialog, + "tooltip", _("ROC Curve"), + "stock-id", "pspp-roc", + NULL + ); + + g_signal_connect (invoke_roc_dialog, "activate", + G_CALLBACK (roc_dialog), de); + } + { GtkUIManager *uim = GTK_UI_MANAGER (get_object_assert (de->builder, "uimanager1", GTK_TYPE_UI_MANAGER)); diff --git a/src/ui/gui/psppire-dict.c b/src/ui/gui/psppire-dict.c index c82395f2..9e2190b2 100644 --- a/src/ui/gui/psppire-dict.c +++ b/src/ui/gui/psppire-dict.c @@ -21,6 +21,7 @@ #include #include +#include "psppire-var-ptr.h" #include "psppire-dict.h" #include #include @@ -648,7 +649,7 @@ tree_model_column_type (GtkTreeModel *model, gint index) return G_TYPE_STRING; break; case DICT_TVM_COL_VAR: - return G_TYPE_POINTER; + return PSPPIRE_VAR_PTR_TYPE; break; default: g_return_val_if_reached ((GType)0); @@ -765,8 +766,8 @@ tree_model_get_value (GtkTreeModel *model, GtkTreeIter *iter, } break; case DICT_TVM_COL_VAR: - g_value_init (value, G_TYPE_POINTER); - g_value_set_pointer (value, var); + g_value_init (value, PSPPIRE_VAR_PTR_TYPE); + g_value_set_boxed (value, var); break; default: g_return_if_reached (); diff --git a/src/ui/gui/psppire-dictview.c b/src/ui/gui/psppire-dictview.c index f1a168de..4c07d1fd 100644 --- a/src/ui/gui/psppire-dictview.c +++ b/src/ui/gui/psppire-dictview.c @@ -75,7 +75,6 @@ psppire_dict_view_finalize (GObject *object) enum { PROP_0, - PROP_MODEL, PROP_DICTIONARY, PROP_PREDICATE, PROP_SELECTION_MODE @@ -137,11 +136,6 @@ psppire_dict_view_set_property (GObject *object, case PROP_DICTIONARY: dict_view->dict = g_value_get_object (value); break; - case PROP_MODEL: - g_critical ("Don't set the \"model\" property on %s. " - "Use the \"dictionary\" property instead.", - G_OBJECT_TYPE_NAME (dict_view)); - break; case PROP_PREDICATE: dict_view->predicate = g_value_get_pointer (value); break; @@ -201,13 +195,6 @@ psppire_dict_view_class_init (PsppireDictViewClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); - GParamSpec *dictionary_spec = - g_param_spec_object ("dictionary", - "Dictionary", - _("The dictionary to be displayed by this widget"), - PSPPIRE_TYPE_DICT, - G_PARAM_READABLE | G_PARAM_WRITABLE); - GParamSpec *predicate_spec = g_param_spec_pointer ("predicate", "Predicate", @@ -223,23 +210,12 @@ psppire_dict_view_class_init (PsppireDictViewClass *class) GTK_SELECTION_MULTIPLE, G_PARAM_CONSTRUCT | G_PARAM_READABLE | G_PARAM_WRITABLE); - - GParamSpec *dummy_spec = - g_param_spec_pointer ("model", - "Model", - "Don't set the property", - G_PARAM_WRITABLE); - object_class->set_property = psppire_dict_view_set_property; object_class->get_property = psppire_dict_view_get_property; - g_object_class_install_property (object_class, - PROP_MODEL, - dummy_spec); - - g_object_class_install_property (object_class, - PROP_DICTIONARY, - dictionary_spec); + g_object_class_override_property (object_class, + PROP_DICTIONARY, + "model"); g_object_class_install_property (object_class, PROP_PREDICATE, @@ -271,8 +247,7 @@ psppire_dict_view_base_finalize (PsppireDictViewClass *class, static void dv_get_base_model (GtkTreeModel *top_model, GtkTreeIter *top_iter, - GtkTreeModel **model, GtkTreeIter *iter - ) + GtkTreeModel **model, GtkTreeIter *iter) { *model = top_model; diff --git a/src/ui/gui/psppire-selector.c b/src/ui/gui/psppire-selector.c index d6ea3375..2b2b2ed5 100644 --- a/src/ui/gui/psppire-selector.c +++ b/src/ui/gui/psppire-selector.c @@ -1,5 +1,5 @@ /* PSPPIRE - a graphical user interface for PSPP. - Copyright (C) 2007 Free Software Foundation + Copyright (C) 2007, 2009 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 @@ -12,7 +12,8 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program. If not, see . */ + along with this program. If not, see . +*/ /* This module provides a widget, PsppireSelector derived from @@ -57,6 +58,11 @@ #include +#include "psppire-dictview.h" +#include "psppire-var-view.h" + + + #include #include #include @@ -112,22 +118,50 @@ psppire_selector_get_type (void) return psppire_selector_type; } +static GObjectClass * parent_class = NULL; static void -psppire_selector_finalize (GObject *object) +psppire_selector_finalize (GObject *obj) { + /* Chain up to the parent class */ + G_OBJECT_CLASS (parent_class)->finalize (obj); +} + + +static void +psppire_selector_dispose (GObject *obj) +{ + PsppireSelector *sel = PSPPIRE_SELECTOR (obj); + + if (sel->dispose_has_run) + return; + + /* Make sure dispose does not run twice. */ + sel->dispose_has_run = TRUE; + + g_object_unref (sel->dest); + g_object_unref (sel->source); + + /* Chain up to the parent class */ + G_OBJECT_CLASS (parent_class)->dispose (obj); } + /* Properties */ enum { PROP_0, - PROP_ORIENTATION + PROP_ORIENTATION, + PROP_PRIMARY, + PROP_SOURCE_WIDGET, + PROP_DEST_WIDGET }; static void on_activate (PsppireSelector *selector, gpointer data); +static void update_subjects (PsppireSelector *selector); + static void psppire_selector_set_property (GObject *object, @@ -143,6 +177,18 @@ psppire_selector_set_property (GObject *object, selector->orientation = g_value_get_enum (value); set_direction (selector, selector->direction); break; + case PROP_PRIMARY: + selector->primary_requested = TRUE; + update_subjects (selector); + break; + case PROP_SOURCE_WIDGET: + selector->source = g_value_dup_object (value); + update_subjects (selector); + break; + case PROP_DEST_WIDGET: + selector->dest = g_value_dup_object (value); + update_subjects (selector); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -163,14 +209,18 @@ psppire_selector_get_property (GObject *object, case PROP_ORIENTATION: g_value_set_enum (value, selector->orientation); break; + case PROP_SOURCE_WIDGET: + g_value_take_object (value, selector->source); + break; + case PROP_DEST_WIDGET: + g_value_take_object (value, selector->dest); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; }; } - - static void psppire_selector_class_init (PsppireSelectorClass *class) { @@ -184,6 +234,29 @@ psppire_selector_class_init (PsppireSelectorClass *class) G_PARAM_CONSTRUCT_ONLY |G_PARAM_READWRITE); + /* Meaningfull only if more than one selector shares this selectors source */ + GParamSpec *primary_spec = + g_param_spec_boolean ("primary", + "Primary", + "Whether this selector should be the primary selector for the source", + FALSE, + G_PARAM_READWRITE); + + GParamSpec *source_widget_spec = + g_param_spec_object ("source-widget", + "Source Widget", + "The widget to be used as the source for this selector", + GTK_TYPE_WIDGET, + G_PARAM_READWRITE); + + GParamSpec *dest_widget_spec = + g_param_spec_object ("dest-widget", + "Destination Widget", + "The widget to be used as the destination for this selector", + GTK_TYPE_WIDGET, + G_PARAM_READWRITE); + + object_class->set_property = psppire_selector_set_property; object_class->get_property = psppire_selector_get_property; @@ -191,6 +264,20 @@ psppire_selector_class_init (PsppireSelectorClass *class) PROP_ORIENTATION, orientation_spec); + g_object_class_install_property (object_class, + PROP_PRIMARY, + primary_spec); + + g_object_class_install_property (object_class, + PROP_SOURCE_WIDGET, + source_widget_spec); + + g_object_class_install_property (object_class, + PROP_DEST_WIDGET, + dest_widget_spec); + + parent_class = g_type_class_peek_parent (class); + signals [SELECTED] = g_signal_new ("selected", G_TYPE_FROM_CLASS (class), @@ -210,6 +297,8 @@ psppire_selector_class_init (PsppireSelectorClass *class) g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + + class->default_selection_funcs = g_hash_table_new (g_direct_hash, g_direct_equal); } @@ -219,6 +308,7 @@ psppire_selector_base_init (PsppireSelectorClass *class) GObjectClass *object_class = G_OBJECT_CLASS (class); object_class->finalize = psppire_selector_finalize; + object_class->dispose = psppire_selector_dispose; class->source_hash = g_hash_table_new (g_direct_hash, g_direct_equal); } @@ -230,13 +320,82 @@ psppire_selector_base_finalize(PsppireSelectorClass *class, gpointer class_data) { g_hash_table_destroy (class->source_hash); + g_hash_table_destroy (class->default_selection_funcs); } +/* Callback for when the source treeview is activated (double clicked) */ +static void +on_row_activate (GtkTreeView *tree_view, + GtkTreePath *path, + GtkTreeViewColumn *column, + gpointer data) +{ + PsppireSelector *selector = data; + + gtk_action_activate (selector->action); +} + +/* Callback for when the source selection changes */ +static void +on_source_select (GtkTreeSelection *treeselection, gpointer data) +{ + PsppireSelector *selector = data; + + set_direction (selector, PSPPIRE_SELECTOR_SOURCE_TO_DEST); + + if ( selector->allow_selection ) + { + gtk_action_set_sensitive (selector->action, + selector->allow_selection (selector->source, selector->dest)); + } + else if ( GTK_IS_ENTRY (selector->dest) ) + { + gtk_action_set_sensitive (selector->action, + gtk_tree_selection_count_selected_rows + (treeselection) <= 1 ); + } +} + + +static void +on_realize (PsppireSelector *selector) +{ + PsppireSelectorClass *class = g_type_class_peek (PSPPIRE_SELECTOR_TYPE); + GtkTreeSelection* selection ; + + GList *list = g_hash_table_lookup (class->source_hash, selector->source); + + if ( NULL == list) + return; + + if ( g_list_first (list)->data == selector) + { + if ( selector->row_activate_id ) + g_signal_handler_disconnect (selector->source, selector->row_activate_id); + + selector->row_activate_id = + g_signal_connect (selector->source, "row-activated", G_CALLBACK (on_row_activate), selector); + } + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (selector->source)); + + if ( selector->source_select_id ) + g_signal_handler_disconnect (selection, selector->source_select_id); + + selector->source_select_id = + g_signal_connect (selection, "changed", G_CALLBACK (on_source_select), selector); +} static void psppire_selector_init (PsppireSelector *selector) { + selector->primary_requested = FALSE; + selector->select_user_data = NULL; + selector->select_items = NULL; + selector->allow_selection = NULL; + selector->filter = NULL; + selector->arrow = gtk_arrow_new (GTK_ARROW_LEFT, GTK_SHADOW_NONE); selector->filtered_source = NULL; @@ -251,6 +410,18 @@ psppire_selector_init (PsppireSelector *selector) g_signal_connect_swapped (selector->action, "activate", G_CALLBACK (on_activate), selector); selector->selecting = FALSE; + + selector->source = NULL; + selector->dest = NULL; + selector->dispose_has_run = FALSE; + + + selector->row_activate_id = 0; + selector->source_select_id = 0; + + g_signal_connect (selector, "realize", + G_CALLBACK (on_realize), NULL); + } @@ -313,27 +484,6 @@ set_direction (PsppireSelector *selector, enum psppire_selector_dir d) } } -/* Callback for when the source selection changes */ -static void -on_source_select (GtkTreeSelection *treeselection, gpointer data) -{ - PsppireSelector *selector = data; - - set_direction (selector, PSPPIRE_SELECTOR_SOURCE_TO_DEST); - - if ( selector->allow_selection ) - { - gtk_action_set_sensitive (selector->action, - selector->allow_selection (selector->source, selector->dest)); - } - else if ( GTK_IS_ENTRY (selector->dest) ) - { - gtk_action_set_sensitive (selector->action, - gtk_tree_selection_count_selected_rows - (treeselection) <= 1 ); - } -} - /* Callback for when the destination treeview selection changes */ static void on_dest_treeview_select (GtkTreeSelection *treeselection, gpointer data) @@ -480,18 +630,6 @@ select_selection (PsppireSelector *selector) selector->selecting = FALSE; } -/* Callback for when the source treeview is activated (double clicked) */ -static void -on_row_activate (GtkTreeView *tree_view, - GtkTreePath *path, - GtkTreeViewColumn *column, - gpointer data) -{ - PsppireSelector *selector = data; - - gtk_action_activate (selector->action); -} - /* Callback for when the selector button is clicked, or other event which causes the selector's action to occur. */ @@ -512,6 +650,13 @@ on_activate (PsppireSelector *selector, gpointer data) } } +static gboolean +permissive_filter (GtkTreeModel *model, GtkTreeIter *iter, + PsppireSelector *selector) +{ + return FALSE; +} + /* Default visibility filter for GtkTreeView DEST widget */ static gboolean is_item_in_dest (GtkTreeModel *model, GtkTreeIter *iter, @@ -606,18 +751,17 @@ static void set_tree_view_source (PsppireSelector *selector, GtkTreeView *source) { - GtkTreeSelection* selection ; + GList *list = NULL; PsppireSelectorClass *class = g_type_class_peek (PSPPIRE_SELECTOR_TYPE); + + GtkTreeModel *model = gtk_tree_view_get_model (source); if ( ! (list = g_hash_table_lookup (class->source_hash, source))) { selector->filtered_source = - GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new - (gtk_tree_view_get_model (source), NULL)); - - gtk_tree_view_set_model (source, NULL); + GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (model, NULL)); gtk_tree_view_set_model (source, GTK_TREE_MODEL (selector->filtered_source)); @@ -635,20 +779,19 @@ set_tree_view_source (PsppireSelector *selector, { /* Append this selector to the list and push the pair onto the hash table */ - selector->filtered_source = GTK_TREE_MODEL_FILTER ( - gtk_tree_view_get_model (source)); + selector->filtered_source = GTK_TREE_MODEL_FILTER (model); - list = g_list_append (list, selector); - g_hash_table_replace (class->source_hash, source, list); + if ( NULL == g_list_find (list, selector) ) + { + if ( selector->primary_requested ) + list = g_list_prepend (list, selector); + else + list = g_list_append (list, selector); + g_hash_table_replace (class->source_hash, source, list); + } } - selection = gtk_tree_view_get_selection (source); - - g_signal_connect (source, "row-activated", G_CALLBACK (on_row_activate), - selector); - g_signal_connect (selection, "changed", G_CALLBACK (on_source_select), - selector); } @@ -682,7 +825,17 @@ on_dest_data_delete (GtkTreeModel *tree_model, } +static void +xxx (PsppireSelector *selector) +{ + GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (selector->dest)); + + 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); +} /* Set the destination widget to DEST */ static void @@ -690,18 +843,16 @@ set_tree_view_dest (PsppireSelector *selector, GtkTreeView *dest) { GtkTreeSelection* selection = gtk_tree_view_get_selection (dest); - GtkTreeModel *model = gtk_tree_view_get_model (dest); + gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE); g_signal_connect (selection, "changed", G_CALLBACK (on_dest_treeview_select), selector); - 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); + g_signal_connect_swapped (dest, "notify::model", + G_CALLBACK (xxx), selector); } @@ -777,67 +928,120 @@ set_entry_dest (PsppireSelector *selector, G_CALLBACK (on_row_inserted), selector); } +static void +set_default_filter (PsppireSelector *selector) +{ + if ( selector->filter == NULL) + { + if (GTK_IS_TREE_VIEW (selector->dest)) + selector->filter = permissive_filter; + } +} -/* Set SOURCE and DEST for this selector, and - set SELECT_FUNC and FILTER_FUNC */ -void -psppire_selector_set_subjects (PsppireSelector *selector, - GtkWidget *source, - GtkWidget *dest, - SelectItemsFunc *select_func, - FilterItemsFunc *filter_func, - gpointer user_data) +static void +update_subjects (PsppireSelector *selector) { - g_assert(selector); + GtkTreeModel *model = NULL; - selector->filter = filter_func ; + if ( NULL == selector->dest ) + return; - selector->source = source; - selector->dest = dest; - selector->select_user_data = user_data; + set_default_filter (selector); - if ( filter_func == NULL) - { - if (GTK_IS_TREE_VIEW (dest)) - selector->filter = is_item_in_dest; - } + if ( NULL == selector->source ) + return; - if ( GTK_IS_TREE_VIEW (source)) - set_tree_view_source (selector, GTK_TREE_VIEW (source) ); - else - g_error ("Unsupported source widget: %s", G_OBJECT_TYPE_NAME (source)); + g_signal_connect_swapped (selector->source, "notify::model", + G_CALLBACK (update_subjects), selector); + + model = gtk_tree_view_get_model (GTK_TREE_VIEW (selector->source)); - g_assert ( GTK_IS_TREE_MODEL_FILTER (selector->filtered_source)); + if ( NULL == model) + return; - if ( NULL == dest) + + if ( GTK_IS_TREE_VIEW (selector->source)) + set_tree_view_source (selector, GTK_TREE_VIEW (selector->source) ); + else + g_error ("Unsupported source widget: %s", G_OBJECT_TYPE_NAME (selector->source)); + + if ( NULL == selector->dest) ; - else if ( GTK_IS_TREE_VIEW (dest)) - set_tree_view_dest (selector, GTK_TREE_VIEW (dest)); + else if ( GTK_IS_TREE_VIEW (selector->dest)) + { + set_tree_view_dest (selector, GTK_TREE_VIEW (selector->dest)); + } - else if ( GTK_IS_ENTRY (dest)) - set_entry_dest (selector, GTK_ENTRY (dest)); + else if ( GTK_IS_ENTRY (selector->dest)) + set_entry_dest (selector, GTK_ENTRY (selector->dest)); - else if (GTK_IS_TEXT_VIEW (dest)) + else if (GTK_IS_TEXT_VIEW (selector->dest)) { /* Nothing to be done */ } - else - g_error ("Unsupported destination widget: %s", G_OBJECT_TYPE_NAME (dest)); + g_error ("Unsupported destination widget: %s", G_OBJECT_TYPE_NAME (selector->dest)); + + + /* FIXME: Remove this dependency */ + if ( PSPPIRE_IS_DICT_VIEW (selector->source) ) + { + GObjectClass *class = G_OBJECT_GET_CLASS (selector); + GType type = G_OBJECT_TYPE (selector->dest); + + SelectItemsFunc *func = + g_hash_table_lookup (PSPPIRE_SELECTOR_CLASS (class)->default_selection_funcs, (gpointer) type); + if ( func ) + psppire_selector_set_select_func (PSPPIRE_SELECTOR (selector), + func, NULL); + } +} + + +void +psppire_selector_set_default_selection_func (GType type, SelectItemsFunc *func) +{ + GObjectClass *class = g_type_class_ref (PSPPIRE_SELECTOR_TYPE); + + g_hash_table_insert (PSPPIRE_SELECTOR_CLASS (class)->default_selection_funcs, (gpointer) type, func); + + g_type_class_unref (class); +} + + + + +/* Set FILTER_FUNC for this selector */ +void +psppire_selector_set_filter_func (PsppireSelector *selector, + FilterItemsFunc *filter_func) +{ + selector->filter = filter_func ; + + set_default_filter (selector); +} + + +/* Set SELECT_FUNC for this selector */ +void +psppire_selector_set_select_func (PsppireSelector *selector, + SelectItemsFunc *select_func, + gpointer user_data) +{ + selector->select_user_data = user_data; selector->select_items = select_func; } void -psppire_selector_set_allow (PsppireSelector *selector , AllowSelectionFunc *allow) +psppire_selector_set_allow (PsppireSelector *selector, AllowSelectionFunc *allow) { selector->allow_selection = allow; } - GType psppire_selector_orientation_get_type (void) { diff --git a/src/ui/gui/psppire-selector.h b/src/ui/gui/psppire-selector.h index 6fff5d42..bb267cd4 100644 --- a/src/ui/gui/psppire-selector.h +++ b/src/ui/gui/psppire-selector.h @@ -77,7 +77,10 @@ struct _PsppireSelector GtkWidget *arrow; GtkAction *action; + gboolean dispose_has_run; + enum psppire_selector_dir direction; + GtkWidget *source; GtkWidget *dest; @@ -97,6 +100,12 @@ struct _PsppireSelector FilterItemsFunc *filter; AllowSelectionFunc *allow_selection; + + gulong row_activate_id ; + + gulong source_select_id ; + + gboolean primary_requested; }; struct _PsppireSelectorClass @@ -106,18 +115,26 @@ struct _PsppireSelectorClass /* This is a hash of Lists of FilterItemsFunc pointers, keyed by address of the source widget */ GHashTable *source_hash; + + /* A hash of SelectItemFuncs indexed by GType */ + GHashTable *default_selection_funcs; }; GType psppire_selector_get_type (void); GtkWidget* psppire_selector_new (void); -void psppire_selector_set_subjects (PsppireSelector *, - GtkWidget *, - GtkWidget *, - SelectItemsFunc *, - FilterItemsFunc *, - gpointer ); -void psppire_selector_set_allow (PsppireSelector *, AllowSelectionFunc *); + +/* Set FILTER_FUNC for this selector */ +void psppire_selector_set_filter_func (PsppireSelector *selector, + FilterItemsFunc *filter_func); + +/* Set SELECT_FUNC for this selector */ +void psppire_selector_set_select_func (PsppireSelector *selector, + SelectItemsFunc *select_func, + gpointer user_data); + + +void psppire_selector_set_allow (PsppireSelector *, AllowSelectionFunc *); GType psppire_selector_orientation_get_type (void) G_GNUC_CONST; @@ -134,6 +151,8 @@ typedef enum { (psppire_selector_orientation_get_type()) +void psppire_selector_set_default_selection_func (GType type, SelectItemsFunc *); + G_END_DECLS diff --git a/src/ui/gui/psppire-var-view.c b/src/ui/gui/psppire-var-view.c new file mode 100644 index 00000000..2a9ebf2e --- /dev/null +++ b/src/ui/gui/psppire-var-view.c @@ -0,0 +1,316 @@ +/* PSPPIRE - a graphical user interface for PSPP. + Copyright (C) 2009 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 + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include + +#include +#include +#include "psppire-var-view.h" +#include "psppire-var-ptr.h" + +#include + +#include +#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); + + +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, + }; + + psppire_var_view_type = + g_type_register_static (GTK_TYPE_TREE_VIEW, "PsppireVarView", + &psppire_var_view_info, 0); + } + + return psppire_var_view_type; +} + + +static void +psppire_var_view_finalize (GObject *object) +{ + PsppireVarView *var_view = PSPPIRE_VAR_VIEW (object); + g_free (var_view->nums); +} + +/* Properties */ +enum +{ + PROP_0, + PROP_N_COLS +}; + +/* A (*GtkTreeCellDataFunc) function. + This function expects TREEMODEL to hold PSPPIRE_VAR_PTR_TYPE. + It renders the name of the variable into CELL. +*/ +static void +display_cell_var_name (GtkTreeViewColumn *tree_column, + GtkCellRenderer *cell, + GtkTreeModel *treemodel, + GtkTreeIter *iter, + gpointer data) +{ + struct variable *var; + GValue value = {0}; + gint *col = data; + + GtkTreePath *path = gtk_tree_model_get_path (treemodel, iter); + + gtk_tree_model_get_value (treemodel, iter, *col, &value); + + gtk_tree_path_free (path); + + var = g_value_get_boxed (&value); + + g_value_unset (&value); + + g_object_set (cell, "text", var_get_name (var), NULL); +} + + +static void +psppire_var_view_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + PsppireVarView *var_view = PSPPIRE_VAR_VIEW (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)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + }; +} + + +static void +psppire_var_view_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + PsppireVarView *var_view = PSPPIRE_VAR_VIEW (object); + + switch (prop_id) + { + case PROP_N_COLS: + { + gint n_cols = g_value_get_int (value); + gint c; + + + 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); + + 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 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)); + } + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + }; +} + +static void +psppire_var_view_class_init (PsppireVarViewClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + GParamSpec *n_cols_spec = + g_param_spec_int ("n-cols", + "Number of columns", + "The Number of Columns in the Variable View", + 1, 20, + 1, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READABLE | G_PARAM_WRITABLE); + + + object_class->set_property = psppire_var_view_set_property; + object_class->get_property = psppire_var_view_get_property; + + 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; +} + + + +static void +psppire_var_view_base_finalize (PsppireVarViewClass *class, + gpointer class_data) +{ +} + + + +static void +psppire_var_view_init (PsppireVarView *var_view) +{ +} + + +GtkWidget* +psppire_var_view_new (void) +{ + return GTK_WIDGET (g_object_new (psppire_var_view_get_type (), NULL)); +} + + +gboolean +psppire_var_view_get_iter_first (PsppireVarView *vv, GtkTreeIter *iter) +{ + return gtk_tree_model_get_iter_first (GTK_TREE_MODEL (vv->list), iter); +} + +gboolean +psppire_var_view_get_iter_next (PsppireVarView *vv, GtkTreeIter *iter) +{ + return gtk_tree_model_iter_next (GTK_TREE_MODEL (vv->list), 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), 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. +*/ +gint +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) ) + { + do + { + const struct variable *var = psppire_var_view_get_variable (vv, column, &iter); + g_string_append (string, " "); + g_string_append (string, var_get_name (var)); + + n_vars++; + } + while (psppire_var_view_get_iter_next (vv, &iter)); + } + + return n_vars; +} + +/* Returns TRUE iff VV contains the item V. + V must be an initialised value containing a + PSPPIRE_VAR_PTR_TYPE. +*/ +gboolean +psppire_var_view_contains_var (PsppireVarView *vv, const GValue *v) +{ + gboolean ok; + GtkTreeIter iter; + 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; +} + diff --git a/src/ui/gui/psppire-var-view.h b/src/ui/gui/psppire-var-view.h new file mode 100644 index 00000000..3509a46b --- /dev/null +++ b/src/ui/gui/psppire-var-view.h @@ -0,0 +1,75 @@ +/* PSPPIRE - a graphical user interface for PSPP. + Copyright (C) 2009 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 + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + + +#ifndef __PSPPIRE_VAR_VIEW_H__ +#define __PSPPIRE_VAR_VIEW_H__ + + +#include +#include +#include + +G_BEGIN_DECLS + +#define PSPPIRE_VAR_VIEW_TYPE (psppire_var_view_get_type ()) +#define PSPPIRE_VAR_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PSPPIRE_VAR_VIEW_TYPE, PsppireVarView)) +#define PSPPIRE_VAR_VIEW_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \ + PSPPIRE_VAR_VIEW_TYPE, PsppireVarViewClass)) +#define PSPPIRE_IS_VAR_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + PSPPIRE_VAR_VIEW_TYPE)) +#define PSPPIRE_IS_VAR_VIEW_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \ + PSPPIRE_VAR_VIEW_TYPE)) + + +typedef struct _PsppireVarView PsppireVarView; +typedef struct _PsppireVarViewClass PsppireVarViewClass; + +struct variable; + +struct _PsppireVarView +{ + GtkTreeView parent; + + GtkListStore *list; + + gint *nums; + +}; + +struct _PsppireVarViewClass +{ + GtkTreeViewClass parent_class; + +}; + +GType psppire_var_view_get_type (void); + +gboolean psppire_var_view_contains_var (PsppireVarView *vv, const GValue *v); + +gint psppire_var_view_append_names (PsppireVarView *vv, gint column, GString *string); + +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); + + + +G_END_DECLS + +#endif /* __PSPPIRE_VAR_VIEW_H__ */ diff --git a/src/ui/gui/psppire.c b/src/ui/gui/psppire.c index 1cd7ee80..84918513 100644 --- a/src/ui/gui/psppire.c +++ b/src/ui/gui/psppire.c @@ -47,6 +47,9 @@ #include #include "psppire-dict.h" +#include "dict-display.h" +#include "psppire-selector.h" +#include "psppire-var-view.h" #include "psppire-var-store.h" #include "psppire-data-store.h" #include "executor.h" @@ -146,6 +149,10 @@ initialize (struct command_line_processor *clp, int argc, char **argv) the_recent_mgr = gtk_recent_manager_get_default (); + psppire_selector_set_default_selection_func (GTK_TYPE_ENTRY, insert_source_row_into_entry); + psppire_selector_set_default_selection_func (PSPPIRE_VAR_VIEW_TYPE, insert_source_row_into_tree_view); + psppire_selector_set_default_selection_func (GTK_TYPE_TREE_VIEW, insert_source_row_into_tree_view); + the_data_window = psppire_data_window_new (); command_line_processor_replace_aux (clp, &post_init_argp, the_source_stream); diff --git a/src/ui/gui/psppire.ui b/src/ui/gui/psppire.ui index 06cce7be..06e72fb1 100644 --- a/src/ui/gui/psppire.ui +++ b/src/ui/gui/psppire.ui @@ -85,6 +85,8 @@ False False 5 + weight-cases-treeview + weight-cases-entry 0 @@ -297,7 +299,7 @@ never automatic - + True False @@ -324,6 +326,8 @@ False False 5 + source-treeview + new-name-entry 1 @@ -338,6 +342,9 @@ False False 5 + True + source-treeview + variables-treeview @@ -501,6 +508,8 @@ True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 5 + split-file-dict-treeview + split-file-grouping-vars @@ -544,7 +553,7 @@ never automatic - + True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK @@ -821,6 +830,8 @@ True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 5 + compute-treeview1 + compute-textview1 False @@ -934,6 +945,8 @@ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 5 source below destination + compute-treeview2 + compute-textview1 False @@ -1241,6 +1254,8 @@ True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 5 + select-cases-treeview + filter-variable-entry False diff --git a/src/ui/gui/rank-dialog.c b/src/ui/gui/rank-dialog.c index b2894095..aa81e23b 100644 --- a/src/ui/gui/rank-dialog.c +++ b/src/ui/gui/rank-dialog.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "executor.h" #include "gettext.h" @@ -110,7 +111,7 @@ generate_syntax (const struct rank_dialog *rd) GString *str = g_string_new ("RANK VARIABLES="); - append_variable_names (str, rd->dict, GTK_TREE_VIEW (rd->rank_vars), 0); + psppire_var_view_append_names (PSPPIRE_VAR_VIEW (rd->rank_vars), 0, str); g_string_append_printf (str, " (%c)", gtk_toggle_button_get_active (rd->ascending_togglebutton) @@ -120,7 +121,7 @@ generate_syntax (const struct rank_dialog *rd) { g_string_append (str, "\n\tBY "); - append_variable_names (str, rd->dict, GTK_TREE_VIEW (rd->group_vars), 0); + psppire_var_view_append_names (PSPPIRE_VAR_VIEW (rd->group_vars), 0, str); } g_string_append (str, "\n\t/PRINT = "); @@ -227,9 +228,6 @@ rank_dialog (GObject *o, gpointer data) GtkBuilder * builder = builder_new ("rank.ui"); GtkWidget *vars = get_widget_assert (builder, "dict-treeview"); - GtkWidget *selector1 = get_widget_assert (builder, "psppire-selector1"); - GtkWidget *selector2 = get_widget_assert (builder, "psppire-selector2"); - GtkWidget *types_button = get_widget_assert (builder, "button1"); GtkWidget *ties_button = get_widget_assert (builder, "button2"); @@ -306,26 +304,7 @@ rank_dialog (GObject *o, gpointer data) gtk_window_set_transient_for (GTK_WINDOW (rd.dialog), GTK_WINDOW (de)); - g_object_set (vars, "dictionary", rd.dict, NULL); - - set_dest_model (GTK_TREE_VIEW (rd.rank_vars), rd.dict); - - psppire_selector_set_subjects (PSPPIRE_SELECTOR (selector1), - vars, - rd.rank_vars, - insert_source_row_into_tree_view, - NULL, - NULL); - - set_dest_model (GTK_TREE_VIEW (rd.group_vars), rd.dict); - - psppire_selector_set_subjects (PSPPIRE_SELECTOR (selector2), - vars, - rd.group_vars, - insert_source_row_into_tree_view, - NULL, - NULL); - + g_object_set (vars, "model", rd.dict, NULL); g_signal_connect (types_button, "clicked", G_CALLBACK (run_types_dialog), &rd); diff --git a/src/ui/gui/rank.ui b/src/ui/gui/rank.ui index 5b7d6f4b..b05ab450 100644 --- a/src/ui/gui/rank.ui +++ b/src/ui/gui/rank.ui @@ -72,7 +72,7 @@ automatic etched-in - + True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK @@ -119,7 +119,7 @@ automatic etched-in - + True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK @@ -144,6 +144,8 @@ True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 5 + dict-treeview + group-vars-treeview 1 @@ -161,6 +163,9 @@ True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 5 + True + dict-treeview + variables-treeview 1 diff --git a/src/ui/gui/recode-dialog.c b/src/ui/gui/recode-dialog.c index 0bb82eb3..9a1af8d5 100644 --- a/src/ui/gui/recode-dialog.c +++ b/src/ui/gui/recode-dialog.c @@ -26,6 +26,8 @@ #include "executor.h" +#include "psppire-var-view.h" + #include #include @@ -337,13 +339,15 @@ struct recode_dialog gboolean input_var_is_string; - GtkListStore *var_map; GtkWidget *new_name_entry; GtkWidget *new_label_entry; GtkWidget *change_button; GtkWidget *string_button; GtkWidget *width_entry; + + /* A hash table of struct nlp's indexed by variable */ + GHashTable *varmap; }; @@ -352,33 +356,23 @@ static void run_old_and_new_dialog (struct recode_dialog *rd); static void refresh (PsppireDialog *dialog, struct recode_dialog *rd) { + GtkTreeModel *vars = + gtk_tree_view_get_model (GTK_TREE_VIEW (rd->variable_treeview)); + + gtk_list_store_clear (GTK_LIST_STORE (vars)); + gtk_widget_set_sensitive (rd->change_button, FALSE); gtk_widget_set_sensitive (rd->new_name_entry, FALSE); gtk_widget_set_sensitive (rd->new_label_entry, FALSE); - if ( rd->different ) - gtk_list_store_clear (GTK_LIST_STORE (rd->var_map)); - else - { - GtkTreeModel *vars = - gtk_tree_view_get_model (GTK_TREE_VIEW (rd->variable_treeview)); - - gtk_list_store_clear (GTK_LIST_STORE (vars)); - } + g_hash_table_remove_all (rd->varmap); gtk_list_store_clear (GTK_LIST_STORE (rd->value_map)); } static char * generate_syntax (const struct recode_dialog *rd); -enum { - COL_OLD, - COL_NEW_NAME, - COL_NEW_LABEL, - n_COL_VARS -}; - enum { COL_VALUE_OLD, COL_VALUE_NEW, @@ -403,26 +397,10 @@ dialog_state_valid (gpointer data) if ( rd->different ) { - GtkTreeIter iter; - - gboolean ok; + GtkTreeModel *model = GTK_TREE_MODEL (PSPPIRE_VAR_VIEW (rd->variable_treeview)->list); - for (ok = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (rd->var_map), - &iter); - ok; - ok = gtk_tree_model_iter_next (GTK_TREE_MODEL (rd->var_map), - &iter)) - { - gchar *name = NULL; - - gtk_tree_model_get (GTK_TREE_MODEL (rd->var_map), &iter, - COL_NEW_NAME, &name, -1); - - if ( name == NULL ) - return FALSE; - - g_free (name); - } + if (g_hash_table_size (rd->varmap) != gtk_tree_model_iter_n_children (model, NULL) ) + return FALSE; } else { @@ -431,7 +409,6 @@ dialog_state_valid (gpointer data) if ( !gtk_tree_model_get_iter_first (vars, ¬_used)) return FALSE; - } return TRUE; @@ -494,22 +471,6 @@ recode_different_dialog (GObject *o, gpointer data) recode_dialog (de, TRUE); } -static void -render_new_var_name (GtkTreeViewColumn *tree_column, - GtkCellRenderer *cell, - GtkTreeModel *tree_model, - GtkTreeIter *iter, - gpointer data) -{ - gchar *new_var_name = NULL; - - gtk_tree_model_get (tree_model, iter, COL_NEW_NAME, &new_var_name, -1); - - g_object_set (cell, "text", new_var_name, NULL); - - g_free (new_var_name); -} - /* This might need to be changed to something less naive. In particular, what happends with dates, etc? @@ -686,6 +647,41 @@ on_acr_selection_change (GtkTreeSelection *selection, gpointer data) } } +/* Name-Label pair */ +struct nlp +{ + char *name; + char *label; +}; + +static struct nlp * +nlp_create (const char *name, const char *label) +{ + struct nlp *nlp = xmalloc (sizeof *nlp); + + nlp->name = g_strdup (name); + + nlp->label = NULL; + + if ( 0 != strcmp ("", label)) + nlp->label = g_strdup (label); + + return nlp; +} + +static void +nlp_destroy (gpointer data) +{ + struct nlp *nlp = data ; + if ( ! nlp ) + return; + + g_free (nlp->name); + g_free (nlp->label); + g_free (nlp); +} + + /* Callback which gets called when a new row is selected in the variable treeview. It sets the name and label entry widgets to reflect the @@ -695,18 +691,18 @@ static void on_selection_change (GtkTreeSelection *selection, gpointer data) { struct recode_dialog *rd = data; - GtkTreeModel *model = GTK_TREE_MODEL (rd->var_map); + + GtkTreeModel *model = GTK_TREE_MODEL (PSPPIRE_VAR_VIEW (rd->variable_treeview)->list); GList *rows = gtk_tree_selection_get_selected_rows (selection, &model); if ( rows && !rows->next) { /* Exactly one row is selected */ - + struct nlp *nlp; + struct variable *var; gboolean ok; GtkTreeIter iter; - gchar *name = NULL; - gchar *label = NULL; gtk_widget_set_sensitive (rd->change_button, TRUE); gtk_widget_set_sensitive (rd->new_name_entry, TRUE); @@ -714,16 +710,22 @@ on_selection_change (GtkTreeSelection *selection, gpointer data) ok = gtk_tree_model_get_iter (model, &iter, (GtkTreePath*) rows->data); - gtk_tree_model_get (GTK_TREE_MODEL (rd->var_map), &iter, - COL_NEW_NAME, &name, - COL_NEW_LABEL, &label, + gtk_tree_model_get (model, &iter, + 0, &var, -1); - gtk_entry_set_text (GTK_ENTRY (rd->new_name_entry), name ? name : ""); - gtk_entry_set_text (GTK_ENTRY (rd->new_label_entry), label ? label : ""); + nlp = g_hash_table_lookup (rd->varmap, var); - g_free (name); - g_free (label); + if (nlp) + { + gtk_entry_set_text (GTK_ENTRY (rd->new_name_entry), nlp->name ? nlp->name : ""); + gtk_entry_set_text (GTK_ENTRY (rd->new_label_entry), nlp->label ? nlp->label : ""); + } + else + { + gtk_entry_set_text (GTK_ENTRY (rd->new_name_entry), ""); + gtk_entry_set_text (GTK_ENTRY (rd->new_label_entry), ""); + } } else { @@ -735,6 +737,7 @@ on_selection_change (GtkTreeSelection *selection, gpointer data) gtk_entry_set_text (GTK_ENTRY (rd->new_label_entry), ""); } + g_list_foreach (rows, (GFunc) gtk_tree_path_free, NULL); g_list_free (rows); } @@ -762,12 +765,13 @@ on_convert_toggled (GtkToggleButton *b, struct recode_dialog *rd) gtk_widget_set_sensitive (rd->string_button, !active); } - static void on_change_clicked (GObject *obj, gpointer data) { struct recode_dialog *rd = data; - GtkTreeModel *model = GTK_TREE_MODEL (rd->var_map); + struct variable *var = NULL; + struct nlp *nlp; + GtkTreeModel *model = GTK_TREE_MODEL (PSPPIRE_VAR_VIEW (rd->variable_treeview)->list); GtkTreeIter iter; GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (rd->variable_treeview)); @@ -780,16 +784,22 @@ on_change_clicked (GObject *obj, gpointer data) const gchar *dest_var_label = gtk_entry_get_text (GTK_ENTRY (rd->new_label_entry)); - if ( NULL == rows ) - return; + if ( NULL == rows || rows->next != NULL) + goto finish; gtk_tree_model_get_iter (model, &iter, rows->data); - gtk_list_store_set (rd->var_map, &iter, - COL_NEW_NAME, dest_var_name, - COL_NEW_LABEL, dest_var_label, - -1); + gtk_tree_model_get (model, &iter, 0, &var, -1); + + g_hash_table_remove (rd->varmap, var); + + nlp = nlp_create (dest_var_name, dest_var_label); + + g_hash_table_insert (rd->varmap, var, nlp); + gtk_tree_model_row_changed (model, rows->data, &iter); + + finish: g_list_foreach (rows, (GFunc) gtk_tree_path_free, NULL); g_list_free (rows); } @@ -838,6 +848,32 @@ set_acr (struct recode_dialog *rd) psppire_acr_set_enabled (rd->acr, !g_str_equal (text, "")); } +static void +render_new_var_name (GtkTreeViewColumn *tree_column, + GtkCellRenderer *cell, + GtkTreeModel *tree_model, + GtkTreeIter *iter, + gpointer data) +{ + struct nlp *nlp = NULL; + struct recode_dialog *rd = data; + + struct variable *var = NULL; + + gtk_tree_model_get (tree_model, iter, + 0, &var, + -1); + + nlp = g_hash_table_lookup (rd->varmap, var); + + if ( nlp ) + g_object_set (cell, "text", nlp->name, NULL); + else + g_object_set (cell, "text", "", NULL); +} + + + static void recode_dialog (PsppireDataWindow *de, gboolean diff) { @@ -854,13 +890,11 @@ recode_dialog (PsppireDataWindow *de, gboolean diff) GtkWidget *output_variable_box = get_widget_assert (builder,"frame4"); - PsppireVarStore *vs = NULL; - g_object_get (de->data_editor, "var-store", &vs, NULL); rd.change_button = get_widget_assert (builder, "change-button"); - + rd.varmap = NULL; rd.dialog = get_widget_assert (builder, "recode-dialog"); rd.dict_treeview = get_widget_assert (builder, "treeview1"); rd.variable_treeview = get_widget_assert (builder, "treeview2"); @@ -887,77 +921,50 @@ recode_dialog (PsppireDataWindow *de, gboolean diff) gtk_window_set_transient_for (GTK_WINDOW (rd.dialog), GTK_WINDOW (de)); + g_object_set (rd.dict_treeview, "model", rd.dict, NULL); - g_object_set (rd.dict_treeview, "dictionary", rd.dict, NULL); - - if ( ! rd.different ) - { - set_dest_model (GTK_TREE_VIEW (rd.variable_treeview), rd.dict); - } - else + if (rd.different) { + GtkTreeModel *model = GTK_TREE_MODEL (PSPPIRE_VAR_VIEW (rd.variable_treeview)->list); GtkTreeSelection *sel; - GtkTreeViewColumn *col; - GtkCellRenderer *renderer = gtk_cell_renderer_text_new (); - - rd.var_map = gtk_list_store_new (n_COL_VARS, G_TYPE_INT, - G_TYPE_STRING, - G_TYPE_STRING); - - - gtk_tree_view_set_model (GTK_TREE_VIEW (rd.variable_treeview), - GTK_TREE_MODEL (rd.var_map)); + GtkCellRenderer *renderer = gtk_cell_renderer_text_new (); - col = gtk_tree_view_column_new_with_attributes (_("Old"), - renderer, - "text", NULL, - NULL); + GtkTreeViewColumn *col = gtk_tree_view_column_new_with_attributes (_("New"), + renderer, + "text", NULL, + NULL); gtk_tree_view_column_set_cell_data_func (col, renderer, - cell_var_name, - rd.dict, 0); + render_new_var_name, + &rd, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (rd.variable_treeview), col); - renderer = gtk_cell_renderer_text_new (); + col = gtk_tree_view_get_column (GTK_TREE_VIEW (rd.variable_treeview), 0); - col = gtk_tree_view_column_new_with_attributes (_("New"), - renderer, - "text", NULL, - NULL); - - gtk_tree_view_column_set_cell_data_func (col, renderer, - render_new_var_name, - NULL, NULL); - - - gtk_tree_view_append_column (GTK_TREE_VIEW (rd.variable_treeview), col); + g_object_set (col, "title", _("Old"), NULL); g_object_set (rd.variable_treeview, "headers-visible", TRUE, NULL); - g_signal_connect (rd.change_button, "clicked", - G_CALLBACK (on_change_clicked), &rd); + rd.varmap = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, nlp_destroy); sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (rd.variable_treeview)); + g_signal_connect (sel, "changed", G_CALLBACK (on_selection_change), &rd); - g_signal_connect (rd.var_map, "row-inserted", + g_signal_connect (rd.change_button, "clicked", + G_CALLBACK (on_change_clicked), &rd); + +#if 0 + g_signal_connect (model, "row-inserted", G_CALLBACK (select_something), &rd); +#endif } - - - psppire_selector_set_subjects (PSPPIRE_SELECTOR (selector), - rd.dict_treeview, - rd.variable_treeview, - insert_source_row_into_tree_view, - NULL, - NULL); - psppire_selector_set_allow (PSPPIRE_SELECTOR (selector), homogeneous_types); /* Set up the Old & New Values subdialog */ @@ -1103,6 +1110,7 @@ recode_dialog (PsppireDataWindow *de, gboolean diff) break; } + g_hash_table_destroy (rd.varmap); gtk_list_store_clear (GTK_LIST_STORE (rd.value_map)); g_object_unref (rd.value_map); @@ -1276,7 +1284,6 @@ run_old_and_new_dialog (struct recode_dialog *rd) /* Find the type of the first variable (it's invariant that all variables are of the same type) */ const struct variable *v; - gint idx; GtkTreeIter iter; GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (rd->variable_treeview)); @@ -1285,9 +1292,7 @@ run_old_and_new_dialog (struct recode_dialog *rd) g_return_if_fail (not_empty); - gtk_tree_model_get (model, &iter, 0, &idx, -1); - - v = psppire_dict_get_variable (rd->dict, idx); + gtk_tree_model_get (model, &iter, 0, &v, -1); rd->input_var_is_string = var_is_alpha (v); @@ -1416,33 +1421,26 @@ generate_syntax (const struct recode_dialog *rd) if ( rd->different && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (rd->string_button))) { - GtkTreeIter iter; + GHashTableIter iter; + struct variable *var = NULL; + struct nlp *nlp = NULL; - for (ok = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (rd->var_map), - &iter); - ok; - ok = gtk_tree_model_iter_next (GTK_TREE_MODEL (rd->var_map), &iter)) + g_hash_table_iter_init (&iter, rd->varmap); + while (g_hash_table_iter_next (&iter, (void**) &var, (void**) &nlp)) { - gchar *name = NULL; - - gtk_tree_model_get (GTK_TREE_MODEL (rd->var_map), &iter, - COL_NEW_NAME, &name, -1); - g_string_append (str, "\nSTRING "); - g_string_append (str, name); + g_string_append (str, nlp->name); g_string_append_printf (str, " (A%d).", (int) gtk_spin_button_get_value (GTK_SPIN_BUTTON (rd->width_entry) ) ); - - g_free (name); } } g_string_append (str, "\nRECODE "); - append_variable_names (str, rd->dict, GTK_TREE_VIEW (rd->variable_treeview), 0); + psppire_var_view_append_names (PSPPIRE_VAR_VIEW (rd->variable_treeview), 0, str); g_string_append (str, "\n\t"); @@ -1483,67 +1481,43 @@ generate_syntax (const struct recode_dialog *rd) if ( rd->different ) { + GtkTreeIter iter; g_string_append (str, "\n\tINTO "); - for (ok = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (rd->var_map), - &iter); + for (ok = psppire_var_view_get_iter_first (PSPPIRE_VAR_VIEW (rd->variable_treeview), &iter); ok; - ok = gtk_tree_model_iter_next (GTK_TREE_MODEL (rd->var_map), &iter)) - { - gchar *name = NULL; - - gtk_tree_model_get (GTK_TREE_MODEL (rd->var_map), &iter, - COL_NEW_NAME, &name, -1); - - g_string_append (str, name); - g_string_append (str, " "); + ok = psppire_var_view_get_iter_next (PSPPIRE_VAR_VIEW (rd->variable_treeview), &iter)) + { + struct nlp *nlp = NULL; + const struct variable *var = psppire_var_view_get_variable (PSPPIRE_VAR_VIEW (rd->variable_treeview), 0, &iter); - g_free (name); - } + nlp = g_hash_table_lookup (rd->varmap, var); + + g_string_append (str, nlp->name); + g_string_append (str, " "); + } } g_string_append (str, "."); - /* If applicable, set labels for the new variables. */ if ( rd->different ) { - GtkTreeIter iter; + GHashTableIter iter; - for (ok = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (rd->var_map), - &iter); - ok; - ok = gtk_tree_model_iter_next (GTK_TREE_MODEL (rd->var_map), &iter)) + struct variable *var = NULL; + struct nlp *nlp = NULL; + + g_hash_table_iter_init (&iter, rd->varmap); + while (g_hash_table_iter_next (&iter, (void**) &var, (void**) &nlp)) { - struct string ls; - gchar *label = NULL; - gchar *name = NULL; - - gtk_tree_model_get (GTK_TREE_MODEL (rd->var_map), &iter, - COL_NEW_NAME, &name, - COL_NEW_LABEL, &label, -1); - - if ( 0 == strcmp (label, "") ) - { - g_free (name); - g_free (label); - continue; - } - - ds_init_empty (&ls); - syntax_gen_string (&ls, ss_cstr (label)); - g_free (label); - - g_string_append_printf (str, "\nVARIABLE LABELS %s %s.", - name, ds_cstr (&ls)); - - g_free (name); - ds_destroy (&ls); + if (nlp->label) + g_string_append_printf (str, "\nVARIABLE LABELS %s %s.", + nlp->name, nlp->label); } } - g_string_append (str, "\nEXECUTE.\n"); diff --git a/src/ui/gui/recode.ui b/src/ui/gui/recode.ui index 4acd7fc4..c573dba0 100644 --- a/src/ui/gui/recode.ui +++ b/src/ui/gui/recode.ui @@ -720,6 +720,8 @@ True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 5 + treeview1 + treeview2 1 @@ -940,7 +942,7 @@ automatic etched-in - + True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK diff --git a/src/ui/gui/regression-dialog.c b/src/ui/gui/regression-dialog.c index eaca17e0..070d30a6 100644 --- a/src/ui/gui/regression-dialog.c +++ b/src/ui/gui/regression-dialog.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "gettext.h" @@ -157,9 +158,9 @@ generate_syntax (const struct regression_dialog *rd) GString *string = g_string_new ("REGRESSION"); g_string_append (string, "\n\t/VARIABLES="); - append_variable_names (string, rd->dict, GTK_TREE_VIEW (rd->indep_vars), 0); + psppire_var_view_append_names (PSPPIRE_VAR_VIEW (rd->indep_vars), 0, string); g_string_append (string, "\n\t/DEPENDENT=\t"); - append_variable_names (string, rd->dict, GTK_TREE_VIEW (rd->dep_vars), 0); + psppire_var_view_append_names (PSPPIRE_VAR_VIEW (rd->dep_vars), 0, string); selected = 0; for (i = 0, ok = gtk_tree_model_get_iter_first (rd->stat, &iter); ok; @@ -234,8 +235,6 @@ regression_dialog (GObject *o, gpointer data) GtkWidget *source = get_widget_assert (xml, "dict-view"); GtkWidget *dest_dep = get_widget_assert (xml, "dep-view"); GtkWidget *dest_indep = get_widget_assert (xml, "indep-view"); - GtkWidget *dep_selector = get_widget_assert (xml, "dep-selector"); - GtkWidget *indep_selector = get_widget_assert (xml, "indep-selector"); GtkWidget *stat_button = get_widget_assert (xml, "stat-button"); GtkWidget *save_button = get_widget_assert (xml, "save-button"); @@ -254,24 +253,7 @@ regression_dialog (GObject *o, gpointer data) gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de)); g_object_get (vs, "dictionary", &rd.dict, NULL); - g_object_set (source, "dictionary", rd.dict, NULL); - - set_dest_model (GTK_TREE_VIEW (dest_dep), rd.dict); - set_dest_model (GTK_TREE_VIEW (dest_indep), rd.dict); - - psppire_selector_set_subjects (PSPPIRE_SELECTOR (dep_selector), - source, - dest_dep, - insert_source_row_into_tree_view, - NULL, - NULL); - - psppire_selector_set_subjects (PSPPIRE_SELECTOR (indep_selector), - source, - dest_indep, - insert_source_row_into_tree_view, - NULL, - NULL); + g_object_set (source, "model", rd.dict, NULL); rd.dep_vars = GTK_TREE_VIEW (dest_dep); rd.indep_vars = GTK_TREE_VIEW (dest_indep); diff --git a/src/ui/gui/regression.ui b/src/ui/gui/regression.ui index 190e6866..61561f35 100644 --- a/src/ui/gui/regression.ui +++ b/src/ui/gui/regression.ui @@ -67,6 +67,8 @@ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True 5 + dict-view + dep-view 1 @@ -83,6 +85,8 @@ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True 5 + dict-view + indep-view 1 @@ -134,7 +138,7 @@ automatic etched-in - + True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK @@ -179,7 +183,7 @@ automatic etched-in - + True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK diff --git a/src/ui/gui/reliability-dialog.c b/src/ui/gui/reliability-dialog.c index 66c8bf5c..9831ab7f 100644 --- a/src/ui/gui/reliability-dialog.c +++ b/src/ui/gui/reliability-dialog.c @@ -24,6 +24,7 @@ #include "psppire-dialog.h" #include "psppire-data-window.h" +#include "psppire-var-view.h" #include "executor.h" #include "helper.h" @@ -121,8 +122,6 @@ reliability_dialog (GObject *o, gpointer data) GtkWidget *dialog = get_widget_assert (xml, "reliability-dialog"); GtkWidget *source = get_widget_assert (xml, "dict-view"); - GtkWidget *selector = get_widget_assert (xml, "psppire-selector1"); - rd.split_point_hbox = get_widget_assert (xml, "split-point-hbox"); rd.variables = get_widget_assert (xml, "treeview2"); @@ -138,16 +137,7 @@ reliability_dialog (GObject *o, gpointer data) gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de)); g_object_get (vs, "dictionary", &rd.dict, NULL); - g_object_set (source, "dictionary", rd.dict, NULL); - - set_dest_model (GTK_TREE_VIEW (rd.variables), rd.dict); - - psppire_selector_set_subjects (PSPPIRE_SELECTOR (selector), - source, - rd.variables, - insert_source_row_into_tree_view, - NULL, - NULL); + g_object_set (source, "model", rd.dict, NULL); { GtkTreeModel *tm = @@ -206,7 +196,7 @@ generate_syntax (const struct reliability *rd) GString *string = g_string_new ("RELIABILITY"); g_string_append (string, "\n\t/VARIABLES="); - append_variable_names (string, rd->dict, GTK_TREE_VIEW (rd->variables), 0); + psppire_var_view_append_names (PSPPIRE_VAR_VIEW (rd->variables), 0, string); g_string_append (string, "\n\t/MODEL="); diff --git a/src/ui/gui/reliability.ui b/src/ui/gui/reliability.ui index a4236b77..25af6ca1 100644 --- a/src/ui/gui/reliability.ui +++ b/src/ui/gui/reliability.ui @@ -70,6 +70,8 @@ True True 5 + dict-view + treeview2 @@ -96,7 +98,7 @@ automatic etched-in - + True True False diff --git a/src/ui/gui/roc-dialog.c b/src/ui/gui/roc-dialog.c new file mode 100644 index 00000000..4d1a7d30 --- /dev/null +++ b/src/ui/gui/roc-dialog.c @@ -0,0 +1,257 @@ +/* PSPPIRE - a graphical user interface for PSPP. + Copyright (C) 2009 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 + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include + +#include "dialog-common.h" +#include +#include +#include + +#include "roc-dialog.h" +#include "psppire-selector.h" +#include "psppire-dictview.h" +#include "psppire-dialog.h" + +#include "psppire-data-window.h" +#include "psppire-var-view.h" + +#include "executor.h" +#include "helper.h" + +#include + +#include "gettext.h" +#define _(msgid) gettext (msgid) +#define N_(msgid) msgid + + +struct roc +{ + PsppireDict *dict; + + GtkWidget *test_variables; + GtkWidget *state_variable; + GtkWidget *state_value; + + GtkWidget *curve; + GtkWidget *reference; + GtkWidget *standard_error; + GtkWidget *coordinates; +}; + + +static char * generate_syntax (const struct roc *rd); + + +static void +refresh (struct roc *rd) +{ + GtkTreeModel *liststore = + gtk_tree_view_get_model (GTK_TREE_VIEW (rd->test_variables)); + gtk_list_store_clear (GTK_LIST_STORE (liststore)); + + gtk_entry_set_text (GTK_ENTRY (rd->state_variable), ""); + gtk_entry_set_text (GTK_ENTRY (rd->state_value), ""); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rd->curve), TRUE); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rd->reference), FALSE); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rd->standard_error), FALSE); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rd->coordinates), FALSE); +} + + +static gboolean +dialog_state_valid (gpointer data) +{ + struct roc *rd = data; + const gchar *text; + + GtkTreeModel *liststore = + gtk_tree_view_get_model (GTK_TREE_VIEW (rd->test_variables)); + + if (gtk_tree_model_iter_n_children (liststore, NULL) < 1) + return FALSE; + + + text = gtk_entry_get_text (GTK_ENTRY (rd->state_variable)); + if ( 0 == strcmp ("", text)) + return FALSE; + + + text = gtk_entry_get_text (GTK_ENTRY (rd->state_value)); + if ( 0 == strcmp ("", text)) + return FALSE; + + + return TRUE; +} + +static void +on_curve_button_toggle (GtkCheckButton *curve, struct roc *rd) +{ + if ( !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (curve))) + { + if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (rd->reference))) + g_object_set (rd->reference, "inconsistent", TRUE, NULL); + g_object_set (rd->reference, "sensitive", FALSE, NULL); + } + else + { + g_object_set (rd->reference, "inconsistent", FALSE, NULL); + g_object_set (rd->reference, "sensitive", TRUE, NULL); + } +} + + +/* Pops up the Roc dialog box */ +void +roc_dialog (GObject *o, gpointer data) +{ + struct roc rd; + gint response; + + GtkBuilder *xml = builder_new ("roc.ui"); + PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data); + PsppireVarStore *vs; + + GtkWidget *dialog = get_widget_assert (xml, "roc-dialog"); + GtkWidget *source = get_widget_assert (xml, "dict-view"); + + rd.test_variables = get_widget_assert (xml, "psppire-var-view1"); + rd.state_variable = get_widget_assert (xml, "entry1"); + rd.state_value = get_widget_assert (xml, "entry2"); + + rd.curve = get_widget_assert (xml, "curve"); + rd.reference = get_widget_assert (xml, "reference-line"); + rd.standard_error = get_widget_assert (xml, "standard-error"); + rd.coordinates = get_widget_assert (xml, "co-ordinates"); + + + g_object_get (de->data_editor, "var-store", &vs, NULL); + + gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de)); + + g_object_get (vs, "dictionary", &rd.dict, NULL); + g_object_set (source, "model", rd.dict, NULL); + + g_signal_connect (rd.curve, "toggled", G_CALLBACK (on_curve_button_toggle), &rd); + + g_signal_connect_swapped (dialog, "refresh", G_CALLBACK (refresh), &rd); + + psppire_dialog_set_valid_predicate (PSPPIRE_DIALOG (dialog), + dialog_state_valid, &rd); + + response = psppire_dialog_run (PSPPIRE_DIALOG (dialog)); + + switch (response) + { + case GTK_RESPONSE_OK: + { + gchar *syntax = generate_syntax (&rd); + + struct getl_interface *sss = create_syntax_string_source (syntax); + execute_syntax (sss); + + g_free (syntax); + } + break; + case PSPPIRE_RESPONSE_PASTE: + { + gchar *syntax = generate_syntax (&rd); + paste_syntax_in_new_window (syntax); + + g_free (syntax); + } + break; + default: + break; + } + + g_object_unref (xml); +} + + + + +static char * +generate_syntax (const struct roc *rd) +{ + gchar *text; + const gchar *var_name = gtk_entry_get_text (GTK_ENTRY (rd->state_variable)); + GString *string = g_string_new ("ROC"); + + psppire_var_view_append_names (PSPPIRE_VAR_VIEW (rd->test_variables), 0, string); + + g_string_append (string, " BY "); + + g_string_append (string, var_name); + + g_string_append (string, " ("); + { + const gchar *value = gtk_entry_get_text (GTK_ENTRY (rd->state_value)); + + const struct variable *var = psppire_dict_lookup_var (rd->dict, var_name); + + g_return_val_if_fail (var, NULL); + + if ( var_is_alpha (var)) + { + struct string xx; + ds_init_empty (&xx); + syntax_gen_string (&xx, ss_cstr (value)); + g_string_append (string, ds_cstr (&xx)); + ds_destroy (&xx); + } + else + g_string_append (string, value); + } + g_string_append (string, ")"); + + + /* The /PLOT subcommand */ + g_string_append (string, "\n\t/PLOT "); + if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (rd->curve))) + { + g_string_append (string, "CURVE"); + if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (rd->reference))) + g_string_append (string, " (REFERENCE)"); + } + else + g_string_append (string, "NONE"); + + + /* The /PRINT subcommand */ + if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (rd->standard_error)) || + gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (rd->coordinates)) ) + { + g_string_append (string, "\n\t/PRINT"); + + if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (rd->standard_error))) + g_string_append (string, " SE"); + + if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (rd->coordinates))) + g_string_append (string, " COORDINATES"); + } + + g_string_append (string, ".\n"); + + text = string->str; + + g_string_free (string, FALSE); + + return text; +} diff --git a/src/ui/gui/roc-dialog.h b/src/ui/gui/roc-dialog.h new file mode 100644 index 00000000..02449802 --- /dev/null +++ b/src/ui/gui/roc-dialog.h @@ -0,0 +1,25 @@ +/* PSPPIRE - a graphical user interface for PSPP. + Copyright (C) 2009 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 + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifndef __ROC_DIALOG_H +#define __ROC_DIALOG_H + + +#include + +void roc_dialog (GObject *o, gpointer data); + +#endif diff --git a/src/ui/gui/roc.ui b/src/ui/gui/roc.ui new file mode 100644 index 00000000..a3aee25a --- /dev/null +++ b/src/ui/gui/roc.ui @@ -0,0 +1,327 @@ + + + + + + + ROC Curve + True + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 2 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 3 + 3 + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + 5 + dict-view + psppire-var-view1 + + + 1 + 2 + + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + 5 + dict-view + entry1 + + + 1 + 2 + 1 + 2 + + + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + never + automatic + etched-in + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False + + + + + 3 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + none + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + never + automatic + etched-in + + + True + True + 5 + False + False + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + _Test Variable: + True + True + + + + + 2 + 3 + + + + + True + 0 + none + + + True + 12 + + + True + True + + + + + + + + True + _State Variable: + True + True + + + + + 2 + 3 + 1 + 2 + GTK_FILL + + + + + True + vertical + + + True + + + True + 1 + _Value of state variable: + True + entry2 + + + 0 + + + + + True + True + + + + 1 + + + + + 0 + + + + + True + 0 + + + True + 12 + + + True + vertical + + + ROC C_urve + True + True + False + True + True + + + False + False + 0 + + + + + True + + + _With diagonal reference line + True + True + False + True + 0 + True + + + False + False + 12 + 0 + + + + + False + False + 1 + + + + + Standard _Error and Confidence Interval + True + True + False + True + True + + + False + False + 2 + + + + + _Coordinate points of the ROC Curve + True + True + False + True + True + + + False + False + 3 + + + + + + + + + True + Display + True + + + + + 1 + + + + + 1 + 3 + 2 + 3 + GTK_FILL + 5 + 2 + + + + + 0 + + + + + True + 5 + vertical + + + False + False + end + 1 + + + + + + diff --git a/src/ui/gui/select-cases-dialog.c b/src/ui/gui/select-cases-dialog.c index 56b10d2c..5b027825 100644 --- a/src/ui/gui/select-cases-dialog.c +++ b/src/ui/gui/select-cases-dialog.c @@ -326,17 +326,13 @@ select_cases_dialog (GObject *o, gpointer data) { GtkWidget *source = get_widget_assert (scd.xml, "select-cases-treeview"); - g_object_set (source, "dictionary", + g_object_set (source, "model", scd.data_store->dict, "selection-mode", GTK_SELECTION_SINGLE, NULL); - psppire_selector_set_subjects (PSPPIRE_SELECTOR (selector), - source, - entry, - insert_source_row_into_entry, - is_currently_in_entry, - NULL); + psppire_selector_set_filter_func (PSPPIRE_SELECTOR (selector), + is_currently_in_entry); } diff --git a/src/ui/gui/sort-cases-dialog.c b/src/ui/gui/sort-cases-dialog.c index cde70ccf..22c53781 100644 --- a/src/ui/gui/sort-cases-dialog.c +++ b/src/ui/gui/sort-cases-dialog.c @@ -24,6 +24,7 @@ #include "dialog-common.h" #include "psppire-selector.h" #include "dict-display.h" +#include "psppire-var-view.h" #include #include "helper.h" @@ -40,7 +41,7 @@ refresh (PsppireDialog *dialog, GtkTreeView *dest) struct sort_cases_dialog { - GtkTreeView *tv; + PsppireVarView *tv; PsppireDict *dict; GtkToggleButton *ascending; }; @@ -50,7 +51,7 @@ static gboolean dialog_state_valid (gpointer data) { struct sort_cases_dialog *scd = data; - GtkTreeModel *model = gtk_tree_view_get_model (scd->tv); + GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (scd->tv)); gint n_rows = gtk_tree_model_iter_n_children (model, NULL); @@ -65,8 +66,8 @@ generate_syntax (const struct sort_cases_dialog *scd) { gchar *text; GString *string = g_string_new ("SORT CASES BY "); - gint n_vars = append_variable_names (string, - scd->dict, GTK_TREE_VIEW (scd->tv), 0); + + gint n_vars = psppire_var_view_append_names (scd->tv, 0, string); if ( n_vars == 0 ) g_string_assign (string, ""); @@ -102,9 +103,7 @@ sort_cases_dialog (GObject *o, gpointer data) GtkWidget *source = get_widget_assert (xml, "sort-cases-treeview1"); - GtkWidget *selector = get_widget_assert (xml, "sort-cases-selector"); GtkWidget *dest = get_widget_assert (xml, "sort-cases-treeview2"); - PsppireVarStore *vs = NULL; g_object_get (de->data_editor, "var-store", &vs, NULL); @@ -112,20 +111,11 @@ sort_cases_dialog (GObject *o, gpointer data) gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de)); g_object_get (vs, "dictionary", &scd.dict, NULL); - g_object_set (source, "dictionary", scd.dict, NULL); - - set_dest_model (GTK_TREE_VIEW (dest), scd.dict); - - psppire_selector_set_subjects (PSPPIRE_SELECTOR (selector), - source, - dest, - insert_source_row_into_tree_view, - NULL, - NULL); + g_object_set (source, "model", scd.dict, NULL); g_signal_connect (dialog, "refresh", G_CALLBACK (refresh), dest); - scd.tv = GTK_TREE_VIEW (dest); + scd.tv = PSPPIRE_VAR_VIEW (dest); scd.ascending = GTK_TOGGLE_BUTTON (get_widget_assert (xml, "sort-cases-radiobutton0")); diff --git a/src/ui/gui/sort.ui b/src/ui/gui/sort.ui index c7e4b2d4..19f8b719 100644 --- a/src/ui/gui/sort.ui +++ b/src/ui/gui/sort.ui @@ -51,6 +51,8 @@ True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 5 + sort-cases-treeview1 + sort-cases-treeview2 @@ -90,7 +92,7 @@ automatic etched-in - + True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK diff --git a/src/ui/gui/split-file-dialog.c b/src/ui/gui/split-file-dialog.c index 613f8e91..cb226d9f 100644 --- a/src/ui/gui/split-file-dialog.c +++ b/src/ui/gui/split-file-dialog.c @@ -26,6 +26,8 @@ #include "helper.h" #include +#include "psppire-var-view.h" + #include @@ -68,8 +70,7 @@ generate_syntax (const struct split_file_dialog *sfd) GString * varlist = g_string_sized_new (80); GtkWidget *sort = get_widget_assert (sfd->xml, "split-radiobutton3"); GtkWidget *layered = get_widget_assert (sfd->xml, "split-radiobutton1"); - gint n_vars = append_variable_names (varlist, - sfd->dict, GTK_TREE_VIEW (vars), 0); + gint n_vars = psppire_var_view_append_names (PSPPIRE_VAR_VIEW (vars), 0, varlist); if ( n_vars > 0 ) { @@ -191,19 +192,10 @@ split_file_dialog (GObject *o, gpointer data) sfd.selector = PSPPIRE_SELECTOR ( get_widget_assert (sfd.xml, "split-file-selector")); - g_object_set (source, "dictionary", sfd.dict, NULL); + g_object_set (source, "model", sfd.dict, NULL); g_signal_connect (on_off, "toggled", G_CALLBACK(on_off_toggled), sfd.xml); - set_dest_model (GTK_TREE_VIEW (dest), sfd.dict); - - psppire_selector_set_subjects (PSPPIRE_SELECTOR (selector), - source, - dest, - insert_source_row_into_tree_view, - NULL, - NULL); - g_signal_connect (dialog, "refresh", G_CALLBACK (refresh), &sfd); gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de)); diff --git a/src/ui/gui/t-test-independent-samples-dialog.c b/src/ui/gui/t-test-independent-samples-dialog.c index 5d77ce43..90c5ab54 100644 --- a/src/ui/gui/t-test-independent-samples-dialog.c +++ b/src/ui/gui/t-test-independent-samples-dialog.c @@ -21,6 +21,7 @@ #include "t-test-independent-samples-dialog.h" #include "psppire-dict.h" #include "psppire-var-store.h" +#include "psppire-var-view.h" #include "executor.h" #include "psppire-data-window.h" #include "psppire-dialog.h" @@ -160,7 +161,7 @@ generate_syntax (const struct tt_indep_samples_dialog *d) GString *str = g_string_new ("T-TEST /VARIABLES="); - append_variable_names (str, d->dict, GTK_TREE_VIEW (tv), 0); + psppire_var_view_append_names (PSPPIRE_VAR_VIEW (tv), 0, str); g_string_append (str, "\n\t/GROUPS="); @@ -400,9 +401,6 @@ t_test_independent_samples_dialog (GObject *o, gpointer data) GtkWidget *dict_view = get_widget_assert (xml, "indep-samples-t-test-treeview1"); - GtkWidget *test_variables_treeview = - get_widget_assert (xml, "indep-samples-t-test-treeview2"); - GtkWidget *selector2 = get_widget_assert (xml, "indep-samples-t-test-selector2"); @@ -426,26 +424,14 @@ t_test_independent_samples_dialog (GObject *o, gpointer data) gtk_window_set_transient_for (GTK_WINDOW (tt_d.dialog), GTK_WINDOW (de)); - g_object_set (dict_view, "dictionary", tt_d.dict, NULL); - - set_dest_model (GTK_TREE_VIEW (test_variables_treeview), tt_d.dict); - - - psppire_selector_set_subjects (PSPPIRE_SELECTOR (selector1), - dict_view, test_variables_treeview, - insert_source_row_into_tree_view, - NULL, - NULL); + g_object_set (dict_view, "model", tt_d.dict, NULL); psppire_selector_set_allow (PSPPIRE_SELECTOR (selector1), numeric_only); - psppire_selector_set_subjects (PSPPIRE_SELECTOR (selector2), - dict_view, tt_d.groups_entry, - insert_source_row_into_entry, - is_currently_in_entry, - NULL); + psppire_selector_set_filter_func (PSPPIRE_SELECTOR (selector2), + is_currently_in_entry); g_signal_connect_swapped (tt_d.define_groups_button, "clicked", G_CALLBACK (run_define_groups), &tt_d); diff --git a/src/ui/gui/t-test-one-sample.c b/src/ui/gui/t-test-one-sample.c index 8b2d8af7..9301b2c3 100644 --- a/src/ui/gui/t-test-one-sample.c +++ b/src/ui/gui/t-test-one-sample.c @@ -21,6 +21,7 @@ #include "t-test-one-sample.h" #include "psppire-dict.h" #include "psppire-var-store.h" +#include "psppire-var-view.h" #include "helper.h" #include "psppire-data-window.h" #include "psppire-dialog.h" @@ -58,7 +59,7 @@ generate_syntax (const struct tt_one_sample_dialog *d) g_string_append (str, "\n\t/VARIABLES="); - append_variable_names (str, d->dict, GTK_TREE_VIEW (d->vars_treeview), 0); + psppire_var_view_append_names (PSPPIRE_VAR_VIEW (d->vars_treeview), 0, str); tt_options_dialog_append_syntax (d->opt, str); @@ -135,8 +136,6 @@ t_test_one_sample_dialog (GObject *o, gpointer data) GtkWidget *options_button = get_widget_assert (xml, "button1"); - GtkWidget *selector = get_widget_assert (xml, "psppire-selector1"); - GtkWidget *dialog = get_widget_assert (xml, "t-test-one-sample-dialog"); g_object_get (de->data_editor, "var-store", &vs, NULL); @@ -148,21 +147,11 @@ t_test_one_sample_dialog (GObject *o, gpointer data) gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de)); - g_object_set (dict_view, "dictionary", + g_object_set (dict_view, "model", tt_d.dict, "predicate", var_is_numeric, NULL); - set_dest_model (GTK_TREE_VIEW (tt_d.vars_treeview), tt_d.dict); - - - psppire_selector_set_subjects (PSPPIRE_SELECTOR (selector), - dict_view, tt_d.vars_treeview, - insert_source_row_into_tree_view, - NULL, - NULL); - - g_signal_connect_swapped (dialog, "refresh", G_CALLBACK (refresh), &tt_d); diff --git a/src/ui/gui/t-test-paired-samples.c b/src/ui/gui/t-test-paired-samples.c index 15b99ad2..95e212af 100644 --- a/src/ui/gui/t-test-paired-samples.c +++ b/src/ui/gui/t-test-paired-samples.c @@ -21,6 +21,7 @@ #include "psppire-data-window.h" #include "psppire-selector.h" +#include "psppire-var-view.h" #include "psppire-dict.h" #include "psppire-var-store.h" @@ -56,11 +57,11 @@ generate_syntax (const struct tt_paired_samples_dialog *d) gchar *text = NULL; GString *str = g_string_new ("T-TEST \n\tPAIRS = "); - append_variable_names (str, d->dict, GTK_TREE_VIEW (d->pairs_treeview), 0); + psppire_var_view_append_names (PSPPIRE_VAR_VIEW (d->pairs_treeview), 0, str); g_string_append (str, " WITH "); - append_variable_names (str, d->dict, GTK_TREE_VIEW (d->pairs_treeview), 1); + psppire_var_view_append_names (PSPPIRE_VAR_VIEW (d->pairs_treeview), 1, str); g_string_append (str, " (PAIRED)"); g_string_append (str, "\n"); @@ -151,31 +152,6 @@ select_as_pair_member (GtkTreeIter source_iter, } } - -/* Append a new column to TV at position C, and heading TITLE */ -static void -add_new_column (GtkTreeView *tv, const gchar *title, gint c) -{ - GtkTreeViewColumn *col = gtk_tree_view_column_new (); - GtkCellRenderer *renderer = gtk_cell_renderer_text_new (); - - gtk_tree_view_column_set_min_width (col, 100); - gtk_tree_view_column_set_sizing (col, GTK_TREE_VIEW_COLUMN_AUTOSIZE); - gtk_tree_view_column_set_resizable (col, TRUE); - - - gtk_tree_view_column_set_title (col, title); - - gtk_tree_view_column_pack_start (col, renderer, TRUE); - - gtk_tree_view_column_set_sizing (col, GTK_TREE_VIEW_COLUMN_FIXED); - - gtk_tree_view_append_column (tv, col); - - gtk_tree_view_column_add_attribute (col, renderer, "text", c); -} - - /* Pops up the dialog box */ void t_test_paired_samples_dialog (GObject *o, gpointer data) @@ -207,34 +183,16 @@ t_test_paired_samples_dialog (GObject *o, gpointer data) gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de)); - g_object_set (dict_view, "dictionary", tt_d.dict, + g_object_set (dict_view, "model", tt_d.dict, "predicate", var_is_numeric, NULL); - { - tt_d.list_store = - GTK_TREE_MODEL ( - gtk_list_store_new (2, - PSPPIRE_VAR_PTR_TYPE, - PSPPIRE_VAR_PTR_TYPE)); - - - gtk_tree_view_set_model (GTK_TREE_VIEW (tt_d.pairs_treeview), - GTK_TREE_MODEL (tt_d.list_store)); - - - add_new_column (GTK_TREE_VIEW (tt_d.pairs_treeview), _("Var 1"), 0); - add_new_column (GTK_TREE_VIEW (tt_d.pairs_treeview), _("Var 2"), 1); - } - - - psppire_selector_set_subjects (PSPPIRE_SELECTOR (selector), - dict_view, - tt_d.pairs_treeview, - select_as_pair_member, - NULL, - &tt_d); + + tt_d.list_store = gtk_tree_view_get_model (GTK_TREE_VIEW (tt_d.pairs_treeview)); + psppire_selector_set_select_func (PSPPIRE_SELECTOR (selector), + select_as_pair_member, + &tt_d); g_signal_connect_swapped (dialog, "refresh", G_CALLBACK (refresh), &tt_d); diff --git a/src/ui/gui/t-test.ui b/src/ui/gui/t-test.ui index 74d8d068..d8c25113 100644 --- a/src/ui/gui/t-test.ui +++ b/src/ui/gui/t-test.ui @@ -93,6 +93,8 @@ True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 5 + indep-samples-t-test-treeview1 + indep-samples-t-test-treeview2 @@ -106,6 +108,8 @@ True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 5 + indep-samples-t-test-treeview1 + indep-samples-t-test-entry 1 @@ -141,7 +145,7 @@ automatic etched-in - + True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK @@ -562,7 +566,7 @@ automatic etched-in - + True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK @@ -681,6 +685,8 @@ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True 5 + one-sample-t-test-treeview2 + one-sample-t-test-treeview1 @@ -741,6 +747,8 @@ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK True 5 + paired-samples-t-test-treeview1 + paired-samples-t-test-treeview2 @@ -772,15 +780,16 @@ True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - never + always automatic etched-in - + True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK False + 2 diff --git a/src/ui/gui/transpose-dialog.c b/src/ui/gui/transpose-dialog.c index 36640f6f..0061193e 100644 --- a/src/ui/gui/transpose-dialog.c +++ b/src/ui/gui/transpose-dialog.c @@ -18,6 +18,7 @@ #include "transpose-dialog.h" #include "psppire-selector.h" +#include "psppire-var-view.h" #include "psppire-dialog.h" #include "executor.h" #include "psppire-data-window.h" @@ -88,30 +89,15 @@ transpose_dialog (GObject *o, gpointer data) GtkWidget *dialog = get_widget_assert (xml, "transpose-dialog"); GtkWidget *source = get_widget_assert (xml, "source-treeview"); - GtkWidget *dest = get_widget_assert (xml, "variables-treeview"); - GtkWidget *selector1 = get_widget_assert (xml, "psppire-selector2"); GtkWidget *selector2 = get_widget_assert (xml, "psppire-selector3"); - GtkWidget *new_name_entry = get_widget_assert (xml, "new-name-entry"); g_object_get (de->data_editor, "var-store", &vs, NULL); g_object_get (vs, "dictionary", &dict, NULL); - g_object_set (source, "dictionary", dict, NULL); - - set_dest_model (GTK_TREE_VIEW (dest), dict); - - psppire_selector_set_subjects (PSPPIRE_SELECTOR (selector1), - source, dest, - insert_source_row_into_tree_view, - NULL, - NULL); - + g_object_set (source, "model", dict, NULL); - psppire_selector_set_subjects (PSPPIRE_SELECTOR (selector2), - source, new_name_entry, - insert_source_row_into_entry, - is_currently_in_entry, - NULL); + psppire_selector_set_filter_func (PSPPIRE_SELECTOR (selector2), + is_currently_in_entry); g_signal_connect (dialog, "refresh", G_CALLBACK (refresh), xml); @@ -166,7 +152,7 @@ generate_syntax (PsppireDict *dict, GtkBuilder *xml) g_string_append (string, " /VARIABLES = "); - append_variable_names (string, dict, GTK_TREE_VIEW (dest), 0); + psppire_var_view_append_names (PSPPIRE_VAR_VIEW (dest), 0, string); text = gtk_entry_get_text (GTK_ENTRY (entry)); diff --git a/src/ui/gui/variable-info-dialog.c b/src/ui/gui/variable-info-dialog.c index 11cee3e5..cbc4d5ca 100644 --- a/src/ui/gui/variable-info-dialog.c +++ b/src/ui/gui/variable-info-dialog.c @@ -65,7 +65,7 @@ populate_text (PsppireDictView *treeview, gpointer data) if ( var == NULL) return; - g_object_get (treeview, "dictionary", &dict, + g_object_get (treeview, "model", &dict, NULL); gstring = g_string_sized_new (200); @@ -165,7 +165,7 @@ variable_info_dialog (GObject *o, gpointer data) gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de)); g_object_get (vs, "dictionary", &dict, NULL); - g_object_set (treeview, "dictionary", dict, + g_object_set (treeview, "model", dict, "selection-mode", GTK_SELECTION_SINGLE, NULL); diff --git a/src/ui/gui/weight-cases-dialog.c b/src/ui/gui/weight-cases-dialog.c index b3087159..40951360 100644 --- a/src/ui/gui/weight-cases-dialog.c +++ b/src/ui/gui/weight-cases-dialog.c @@ -132,19 +132,13 @@ weight_cases_dialog (GObject *o, gpointer data) radiobutton1); - g_object_set (source, "dictionary", wcd.dict, + g_object_set (source, "model", wcd.dict, "selection-mode", GTK_SELECTION_SINGLE, "predicate", var_is_numeric, NULL); - psppire_selector_set_subjects (PSPPIRE_SELECTOR (selector), - source, - entry, - insert_source_row_into_entry, - is_currently_in_entry, - NULL - ); - + psppire_selector_set_filter_func (PSPPIRE_SELECTOR (selector), + is_currently_in_entry); wcd.entry = GTK_ENTRY (entry); diff --git a/src/ui/gui/widgets.c b/src/ui/gui/widgets.c index 979224fe..a1a55d14 100644 --- a/src/ui/gui/widgets.c +++ b/src/ui/gui/widgets.c @@ -10,6 +10,7 @@ #include "psppire-keypad.h" #include "psppire-acr.h" #include "psppire-dictview.h" +#include "psppire-var-view.h" /* Any custom widgets which are to be used in GtkBuilder ui files @@ -25,4 +26,5 @@ preregister_widgets (void) psppire_keypad_get_type (); psppire_acr_get_type (); psppire_dict_view_get_type (); + psppire_var_view_get_type (); }