From 1d5a97ba2afec23855a8294ff2814ab052f6777a Mon Sep 17 00:00:00 2001 From: John Darrington Date: Sat, 31 Mar 2007 11:44:45 +0000 Subject: [PATCH] Fixed the refresh button on the dialogs. Added a "recent-dialogs" toolbar button. --- doc/ChangeLog | 4 + doc/transformation.texi | 6 +- glade.patch | 769 +--------------------------- glade/psppire.xml | 8 +- src/ui/gui/ChangeLog | 9 + src/ui/gui/TODO | 2 - src/ui/gui/automake.mk | 1 + src/ui/gui/data-editor.c | 19 +- src/ui/gui/data-editor.glade | 285 ++++++----- src/ui/gui/data-editor.h | 2 + src/ui/gui/dialog-common.c | 7 + src/ui/gui/icons/recent-dialogs.png | Bin 0 -> 403 bytes src/ui/gui/psppire-buttonbox.c | 2 +- src/ui/gui/psppire-dialog.c | 6 +- src/ui/gui/psppire-dialog.h | 2 +- src/ui/gui/psppire-selector.c | 53 +- src/ui/gui/psppire-selector.h | 5 + src/ui/gui/psppire.c | 7 + src/ui/gui/psppire.glade | 194 ++++++- src/ui/gui/sort-cases-dialog.c | 527 ++++--------------- src/ui/gui/sort-cases-dialog.h | 37 +- src/ui/gui/split-file-dialog.c | 102 +++- src/ui/gui/transpose-dialog.c | 14 + src/ui/gui/weight-cases-dialog.c | 71 ++- 24 files changed, 705 insertions(+), 1427 deletions(-) create mode 100644 src/ui/gui/icons/recent-dialogs.png diff --git a/doc/ChangeLog b/doc/ChangeLog index 9e93153b..607a9390 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,7 @@ +2007-03-31 John Darrington + + * transformation.texi: SORT CASES: elaborated on the (D) (A) flags. + 2007-03-01 Ben Pfaff * automake.mk: Fix "make distcheck" by distributing doc/ni.texi, diff --git a/doc/transformation.texi b/doc/transformation.texi index d8b08a45..5333d954 100644 --- a/doc/transformation.texi +++ b/doc/transformation.texi @@ -525,7 +525,7 @@ separate them from the previous recodings. @vindex SORT CASES @display -SORT CASES BY var_list. +SORT CASES BY var_list[(@{D|A@}] [ var_list[(@{D|A@}] ] ... @end display @cmd{SORT CASES} sorts the active file by the values of one or more @@ -534,8 +534,8 @@ variables. Specify BY and a list of variables to sort by. By default, variables are sorted in ascending order. To override sort order, specify (D) or (DOWN) after a list of variables to get descending order, or (A) or (UP) -for ascending order. These apply to the entire list of variables -preceding them. +for ascending order. These apply to all the listed variables +up until the preceding (A), (D), (UP) or (DOWN). The sort algorithms used by @cmd{SORT CASES} are stable. That is, records that have equal values of the sort variables will have the diff --git a/glade.patch b/glade.patch index 9081dae7..80a5aa01 100644 --- a/glade.patch +++ b/glade.patch @@ -1,9 +1,6 @@ -This patch mitigates a bug in glade-2, which silently deletes stock_ids, which -it thinks are not valid. You may have to apply this patch after editing -data-editor.glade with glade-3. ---- src/ui/gui/data-editor.glade,bad 2007-01-26 16:15:32.000000000 +0900 -+++ src/ui/gui/data-editor.glade 2007-01-26 16:16:18.000000000 +0900 -@@ -506,7 +506,7 @@ +--- /Scratch/john/tmp.vKHTg31290/share/pspp/data-editor.glade 2007-03-31 12:55:02.000000000 +0800 ++++ src/ui/gui/data-editor.glade 2007-03-31 13:04:27.000000000 +0800 +@@ -494,7 +494,7 @@ False Variables True @@ -12,16 +9,16 @@ data-editor.glade with glade-3. False -@@ -547,7 +547,7 @@ +@@ -535,7 +535,7 @@ False Insert Case True - gtk-missing-image + pspp-insert-case - -@@ -560,7 +560,7 @@ + False +@@ -547,7 +547,7 @@ False Insert Variable True @@ -30,8 +27,8 @@ data-editor.glade with glade-3. False -@@ -581,7 +581,7 @@ - False +@@ -567,7 +567,7 @@ + True Split File True - gtk-missing-image @@ -39,7 +36,7 @@ data-editor.glade with glade-3. False -@@ -592,7 +592,7 @@ +@@ -578,7 +578,7 @@ True Weight Cases True @@ -48,7 +45,7 @@ data-editor.glade with glade-3. False -@@ -604,7 +604,7 @@ +@@ -590,7 +590,7 @@ False Select Cases True @@ -57,754 +54,12 @@ data-editor.glade with glade-3. False -@@ -624,7 +624,7 @@ +@@ -610,7 +610,7 @@ True Value Labels True - gtk-missing-image + pspp-value-labels - - - -@@ -667,25 +667,25 @@ - 1 - 2 - -- -+ - True -- True -+ False -+ False -+ 25 - - -- 1 -- 2 -+ GTK_FILL - - - - -- -+ - True -- False -- False -- 25 -+ True - - -- GTK_FILL -+ 1 -+ 2 - - - -@@ -1216,63 +1216,63 @@ - 2 - 1 - -- -+ - True -- 0 -- Decimal Places: -+ -+ -+ True -+ Width: - GTK_JUSTIFY_RIGHT - - -- 1 -- 2 -+ False -+ False -+ GTK_PACK_END -+ -+ -+ -+ - GTK_FILL -- -+ GTK_FILL - - - -- -+ - 25 -+ True - True - - - 1 - 2 -+ 1 -+ 2 - - - - -- -+ - 25 -- True - True - 1 - 2 -- 1 -- 2 - - - - -- -- True -- -- -+ - True -- Width: -+ 0 -+ Decimal Places: - GTK_JUSTIFY_RIGHT - - -- False -- False -- GTK_PACK_END -- -- -- -- -+ 1 -+ 2 - GTK_FILL -- GTK_FILL -+ - - - -@@ -1360,50 +1360,28 @@ - 2 - 5 - -- -- True -- 5 -- -- -- True -- False -- True -- True -- gtk-add -- True -- -- -- -- -+ - True -- False - True -- True -- gtk-apply -- True -- -- -- 1 -- -- -+ GTK_POLICY_NEVER -+ GTK_POLICY_AUTOMATIC -+ GTK_SHADOW_ETCHED_IN - -- -+ - True -- False - True -- True -- gtk-remove -- True -+ False -+ False - -- -- 2 -- - - - -+ 1 -+ 2 - 1 - 2 - GTK_FILL -+ GTK_FILL - - - -@@ -1415,27 +1393,26 @@ - 5 - 4 - -- -+ - True -- 0 -- Value: -+ -+ -+ 85 -+ True -+ True - - -- GTK_FILL -- -+ False -+ False -+ 1 - - -- -- -- True -- 0 -- Value Label: - - -- 1 -- 2 -+ 1 -+ 2 - GTK_FILL -- -+ GTK_FILL - - - -@@ -1452,26 +1429,27 @@ - - - -- -- True -- -- -- 85 -+ - True -- True -+ 0 -+ Value Label: - - -- False -- False -- 1 -+ 1 -+ 2 -+ GTK_FILL -+ - - -+ -+ -+ True -+ 0 -+ Value: - - -- 1 -- 2 - GTK_FILL -- GTK_FILL -+ - - - -@@ -1481,28 +1459,50 @@ - - - -- -+ -+ True -+ 5 -+ -+ - True -+ False - True -- GTK_POLICY_NEVER -- GTK_POLICY_AUTOMATIC -- GTK_SHADOW_ETCHED_IN -+ True -+ gtk-add -+ True -+ -+ - -- -+ - True -+ False - True -- False -- False -+ True -+ gtk-apply -+ True - -+ -+ 1 -+ -+ -+ -+ -+ True -+ False -+ True -+ True -+ gtk-remove -+ True -+ -+ -+ 2 -+ - - - -- 1 -- 2 - 1 - 2 - GTK_FILL -- GTK_FILL - - - -@@ -1590,64 +1590,68 @@ - 2 - 2 - -- -+ - True -- 5 -- 5 -- GTK_BUTTONBOX_START - -- -+ - True - True -- True -- gtk-ok -- True -- -+ _Range plus one optional discrete missing value -+ True -+ False -+ True -+ no_missing - -+ -+ False -+ False -+ - - -- -+ - True -- True -- True -- gtk-cancel -- True -- -+ 5 -+ -+ -+ True -+ -+ -+ True -+ -+ -+ True -+ _Low: -+ True -+ mv-low - - -- 1 -+ False -+ False -+ 20 - - - -- -+ -+ 75 - True - True -- True -- gtk-help -- True - - -- 2 -+ False -+ 1 - - - -- -- 1 -- 2 -- - - -- -+ - True -- 12 - -- -+ - True -- True -- _No missing values -+ _High: - True -- True -- True -+ mv-high - - - False -@@ -1655,97 +1659,102 @@ - - - -- -- True -- -- -+ -+ 75 - True - True -- _Discrete missing values -- True -- False -- True -- no_missing - - -- False -+ 5 -+ 1 -+ -+ -+ -+ - False -+ 20 -+ 1 - - - -- -- True -+ -+ - -- -+ -+ -+ -+ -+ -+ - True -- 5 -- 5 -- True - -- -- 75 -+ - True -- True -+ Di_screte value: -+ True -+ mv-discrete - - - False - False -+ 20 - - - -- -+ - 75 - True - True - - - False -- False - 1 - - -- -- -- 75 -- True -- True - - -- False -- False -- 2 -+ 1 - - - - -- 20 -+ 1 - - - - -- 1 -+ 2 -+ 1 -+ 2 -+ GTK_FILL - - -+ -+ -+ True -+ 12 -+ -+ -+ True -+ True -+ _No missing values -+ True -+ True -+ True - - - False - False -- 1 -- -- -- -- -- GTK_FILL - - - -- -+ - True - -- -+ - True - True -- _Range plus one optional discrete missing value -+ _Discrete missing values - True - False - True -@@ -1757,125 +1766,116 @@ - - - -- -- True -- 5 -- -- -+ - True - -- -+ - True -+ 5 -+ 5 -+ True - -- -+ -+ 75 - True -- _Low: -- True -- mv-low -+ True - - - False - False -- 20 - - - -- -+ - 75 - True - True - - - False -+ False - 1 - - -- -- -- -- -- True - -- -+ -+ 75 - True -- _High: -- True -- mv-high -+ True - - - False - False -+ 2 -+ -+ -+ -+ -+ 20 - - -- -- -- 75 -- True -- True - - -- 5 - 1 - - - - -+ False - False -- 20 - 1 - - -- -- -- -- -- -- - -+ -+ GTK_FILL -+ - - -- -+ - True -+ 5 -+ 5 -+ GTK_BUTTONBOX_START - -- -+ - True -- Di_screte value: -- True -- mv-discrete -+ True -+ True -+ gtk-ok -+ True -+ - -- -- False -- False -- 20 -- - - -- -- 75 -+ - True - True -- -- -- False -- 1 -- -- -+ True -+ gtk-cancel -+ True -+ - - - 1 - - -+ -+ -+ True -+ True -+ True -+ gtk-help -+ True - - -- 1 -+ 2 - - - - -+ 1 - 2 -- 1 -- 2 -- GTK_FILL - - - + False diff --git a/glade/psppire.xml b/glade/psppire.xml index 45902b56..9fb55bae 100644 --- a/glade/psppire.xml +++ b/glade/psppire.xml @@ -49,6 +49,7 @@ + @@ -85,11 +86,16 @@ title="Keypad"> - + + + + + + diff --git a/src/ui/gui/ChangeLog b/src/ui/gui/ChangeLog index 03d6a8ee..b2790bf1 100644 --- a/src/ui/gui/ChangeLog +++ b/src/ui/gui/ChangeLog @@ -1,3 +1,12 @@ +2007-03-31 John Darrington + + * data-editor.c data-editor.glade data-editor.h dialog-common.c + psppire-buttonbox.c psppire-dialog.c psppire-dialog.h + psppire-selector.c psppire-selector.h psppire.c psppire.glade + sort-cases-dialog.c sort-cases-dialog.h split-file-dialog.c + transpose-dialog.c weight-cases-dialog.c : Fixed the Refresh + button on all the dialogs. + 2007-03-31 John Darrington * data-editor.c: Added hooks for the split-file-dialog diff --git a/src/ui/gui/TODO b/src/ui/gui/TODO index 37edbb97..dcc5efe1 100644 --- a/src/ui/gui/TODO +++ b/src/ui/gui/TODO @@ -4,8 +4,6 @@ * Cell Ref Entry populate/depopulate. -* Case weights. - * Goto Variable. Wishlist diff --git a/src/ui/gui/automake.mk b/src/ui/gui/automake.mk index 18ba45a0..e8da4c4d 100644 --- a/src/ui/gui/automake.mk +++ b/src/ui/gui/automake.mk @@ -56,6 +56,7 @@ dist_src_ui_gui_psppire_DATA = \ $(top_srcdir)/src/ui/gui/icons/goto-variable.png\ $(top_srcdir)/src/ui/gui/icons/insert-case.png \ $(top_srcdir)/src/ui/gui/icons/insert-variable.png \ + $(top_srcdir)/src/ui/gui/icons/recent-dialogs.png \ $(top_srcdir)/src/ui/gui/icons/split-file.png \ $(top_srcdir)/src/ui/gui/icons/select-cases.png \ $(top_srcdir)/src/ui/gui/icons/weight-cases.png diff --git a/src/ui/gui/data-editor.c b/src/ui/gui/data-editor.c index d0433c64..111a8327 100644 --- a/src/ui/gui/data-editor.c +++ b/src/ui/gui/data-editor.c @@ -34,6 +34,7 @@ #include "weight-cases-dialog.h" #include "split-file-dialog.h" #include "transpose-dialog.h" +#include "sort-cases-dialog.h" #include "dict-display.h" #define _(msgid) gettext (msgid) @@ -183,11 +184,21 @@ new_data_editor (void) _("Split the active file"), "pspp-split-file"); - g_signal_connect (de->invoke_split_file_dialog, "activate", G_CALLBACK (split_file_dialog), de); + + de->invoke_sort_cases_dialog = + gtk_action_new ("sort-cases-dialog", + _("Sort"), + _("Sort cases in the active file"), + "pspp-sort-cases"); + + g_signal_connect (de->invoke_sort_cases_dialog, "activate", + G_CALLBACK (sort_cases_dialog), de); + + e->window = GTK_WINDOW (get_widget_assert (de->xml, "data_editor")); g_signal_connect_swapped (get_widget_assert (de->xml,"file_new_data"), @@ -244,6 +255,10 @@ new_data_editor (void) get_widget_assert (de->xml, "data_split-file") ); + gtk_action_connect_proxy (de->invoke_sort_cases_dialog, + get_widget_assert (de->xml, "data_sort-cases") + ); + g_signal_connect (get_widget_assert (de->xml,"help_about"), "activate", @@ -1040,7 +1055,7 @@ open_data_dialog (GtkAction *action, struct data_editor *de) gen_quoted_string (&filename); - sss = create_syntax_string_source ("GET FILE=%s.", + sss = create_syntax_string_source ("GET FILE=%s.", ds_cstr (&filename)); execute_syntax (sss); diff --git a/src/ui/gui/data-editor.glade b/src/ui/gui/data-editor.glade index 2d06312a..71e977be 100644 --- a/src/ui/gui/data-editor.glade +++ b/src/ui/gui/data-editor.glade @@ -280,9 +280,8 @@ - + True - False Sort Cases True @@ -438,6 +437,18 @@ False + + + True + False + Recall + pspp-recent-dialogs + + + False + + + True @@ -653,25 +664,25 @@ 1 2 - + True - False - False - 25 + True - GTK_FILL + 1 + 2 - + True - True + False + False + 25 - 1 - 2 + GTK_FILL @@ -1208,9 +1219,9 @@ True Width: - GTK_JUSTIFY_RIGHT - - + GTK_JUSTIFY_RIGHT + + False False GTK_PACK_END @@ -1249,12 +1260,12 @@ - True + True 0 Decimal Places: - GTK_JUSTIFY_RIGHT - - + GTK_JUSTIFY_RIGHT + + 1 2 GTK_FILL @@ -1346,8 +1357,8 @@ 5 - True - True + True + True GTK_POLICY_NEVER GTK_POLICY_AUTOMATIC GTK_SHADOW_ETCHED_IN @@ -1385,13 +1396,13 @@ 85 True True - - + + False False 1 - - + + 1 @@ -1415,17 +1426,17 @@ - True + True 0 Value Label: - - + + 1 2 GTK_FILL - - + + True @@ -1449,9 +1460,9 @@ 5 - True + True False - True + True True gtk-add True @@ -1606,60 +1617,60 @@ _Low: True mv-low - - + + False False 20 - - - + + + 75 - True - True - - + True + True + + False 1 - - - - - + + + + + - True - + True + - True + True _High: - True + True mv-high - - - False - False - - - + + + False + False + + + 75 - True - True - - + True + True + + 5 1 - False + False 20 1 - - - + + + @@ -1669,49 +1680,49 @@ - True - + True + - True + True Di_screte value: True mv-discrete - - - False - False + + + False + False 20 - - - + + + - 75 - True - True - - - False - 1 - - - - - 1 - - + 75 + True + True - 1 + False + 1 + 1 + + + + + 1 + + + + 2 1 2 GTK_FILL - - + + True @@ -1728,27 +1739,27 @@ False False - - - - - True - - - True - True - _Discrete missing values - True - False - True - no_missing - - - False - False + + True + + + True + True + _Discrete missing values + True + False + True + no_missing + + + False + False + + + True @@ -1795,52 +1806,52 @@ 20 - - - - - 1 - - - - - False - False - 1 + + 1 + + + + + False + False + 1 + + + GTK_FILL - - + + - True + True 5 5 GTK_BUTTONBOX_START - + - True + True True True gtk-ok True - - - + + + - True - True + True + True True gtk-cancel True - - - 1 - - + + + 1 + + True @@ -1913,7 +1924,7 @@ True gtk-ok True - -5 + 5 diff --git a/src/ui/gui/data-editor.h b/src/ui/gui/data-editor.h index e16e713b..0fe62ea6 100644 --- a/src/ui/gui/data-editor.h +++ b/src/ui/gui/data-editor.h @@ -38,6 +38,8 @@ struct data_editor GtkAction *invoke_transpose_dialog; GtkAction *invoke_split_file_dialog; + GtkAction *invoke_sort_cases_dialog; + GladeXML *xml; gboolean save_as_portable; diff --git a/src/ui/gui/dialog-common.c b/src/ui/gui/dialog-common.c index 42e2fbd4..4de43677 100644 --- a/src/ui/gui/dialog-common.c +++ b/src/ui/gui/dialog-common.c @@ -21,6 +21,13 @@ #include #include "dialog-common.h" +#include "helper.h" + + +/* Append the names of selected variables to STRING. + TREEVIEW is the treeview containing the variables. + DICT is the dictionary for those variables. +*/ gint append_variable_names (GString *string, PsppireDict *dict, GtkTreeView *treeview) diff --git a/src/ui/gui/icons/recent-dialogs.png b/src/ui/gui/icons/recent-dialogs.png new file mode 100644 index 0000000000000000000000000000000000000000..62493cbaee39aea8c72533c71d47558761b9b53c GIT binary patch literal 403 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjY)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYYs>cdx@v7EBke3c}`_UFR$Za3=E74o-U3d9>=#%+v|12L8R6Hkb^>~ zT*`*oAz^0!9Gi4bFAy+kUE-;la?^c+tjAQhAQyp4T}}19Q>R|`lslr8k{GzULHk&$ z@4J`FET5nG+jd$a+0x47pqIc4=5FP*rm2Y%K|dC2bWLJ(xNNfGbyYy|?QM(0%Y>m>21qhelF{r5}E+`L7;{J literal 0 HcmV?d00001 diff --git a/src/ui/gui/psppire-buttonbox.c b/src/ui/gui/psppire-buttonbox.c index 08abd6ff..e5c1c561 100644 --- a/src/ui/gui/psppire-buttonbox.c +++ b/src/ui/gui/psppire-buttonbox.c @@ -113,7 +113,7 @@ refresh_clicked (GtkWidget *w, gpointer data) dialog = PSPPIRE_DIALOG (gtk_widget_get_toplevel (w)); - psppire_dialog_reload (dialog, data); + psppire_dialog_reload (dialog); } diff --git a/src/ui/gui/psppire-dialog.c b/src/ui/gui/psppire-dialog.c index cd152c3a..f0d76de9 100644 --- a/src/ui/gui/psppire-dialog.c +++ b/src/ui/gui/psppire-dialog.c @@ -160,6 +160,8 @@ psppire_dialog_run (PsppireDialog *dialog) gtk_widget_show (GTK_WIDGET (dialog)); + g_signal_emit (dialog, signals [DIALOG_REFRESH], 0); + g_main_loop_run (dialog->loop); return dialog->response; @@ -167,7 +169,7 @@ psppire_dialog_run (PsppireDialog *dialog) void -psppire_dialog_reload (PsppireDialog *dialog, gpointer data) +psppire_dialog_reload (PsppireDialog *dialog) { - g_signal_emit (dialog, signals [DIALOG_REFRESH], 0, data); + g_signal_emit (dialog, signals [DIALOG_REFRESH], 0); } diff --git a/src/ui/gui/psppire-dialog.h b/src/ui/gui/psppire-dialog.h index 2748c96b..b7e39a7c 100644 --- a/src/ui/gui/psppire-dialog.h +++ b/src/ui/gui/psppire-dialog.h @@ -38,8 +38,8 @@ struct _PsppireDialogClass GType psppire_dialog_get_type (void); GtkWidget* psppire_dialog_new (void); +void psppire_dialog_reload (PsppireDialog *); void psppire_dialog_close (PsppireDialog *); -void psppire_dialog_reload (PsppireDialog *, gpointer data); gint psppire_dialog_run (PsppireDialog *); diff --git a/src/ui/gui/psppire-selector.c b/src/ui/gui/psppire-selector.c index 68d8270d..f3f684a1 100644 --- a/src/ui/gui/psppire-selector.c +++ b/src/ui/gui/psppire-selector.c @@ -242,9 +242,7 @@ psppire_selector_init (PsppireSelector *selector) gtk_widget_show (selector->arrow); - /* FIXME: This shouldn't be necessary, but Glade interfaces seem to - need it. */ - gtk_widget_show (GTK_WIDGET (selector)); + selector->selecting = FALSE; } @@ -397,6 +395,8 @@ de_select_selection_tree_view (PsppireSelector *selector) static void de_select_selection (PsppireSelector *selector) { + selector->selecting = TRUE; + if ( GTK_IS_TREE_VIEW (selector->dest ) ) de_select_selection_tree_view (selector); @@ -406,6 +406,8 @@ de_select_selection (PsppireSelector *selector) else g_assert_not_reached (); + selector->selecting = FALSE; + gtk_tree_model_filter_refilter (selector->filtered_source); g_signal_emit (selector, signals [DE_SELECTED], 0); @@ -428,6 +430,7 @@ select_selection (PsppireSelector *selector) g_return_if_fail (selector->select_items); + selector->selecting = TRUE; for (item = g_list_first (selected_rows); item != NULL; @@ -456,9 +459,11 @@ select_selection (PsppireSelector *selector) gtk_tree_model_filter_refilter (selector->filtered_source); g_signal_emit (selector, signals [SELECTED], 0); + + selector->selecting = FALSE; } -/* Callback fro then the source treeview is activated (double clicked) */ +/* Callback for when the source treeview is activated (double clicked) */ static void on_row_activate (GtkTreeView *tree_view, GtkTreePath *path, @@ -617,17 +622,57 @@ set_tree_view_source (PsppireSelector *selector, } +/* + Callback for when the destination treeview's data changes + */ +static void +on_dest_data_change (GtkTreeModel *tree_model, + GtkTreePath *path, + GtkTreeIter *iter, + gpointer user_data) +{ + PsppireSelector *selector = user_data; + + if ( selector->selecting) return; + + gtk_tree_model_filter_refilter (selector->filtered_source); +} + + +static void +on_dest_data_delete (GtkTreeModel *tree_model, + GtkTreePath *path, + gpointer user_data) +{ + PsppireSelector *selector = user_data; + + if ( selector->selecting ) return; + + gtk_tree_model_filter_refilter (selector->filtered_source); +} + + + + /* Set the destination widget to DEST */ static void 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); + } /* Callback for when the DEST GtkEntry is activated (Enter is pressed) */ diff --git a/src/ui/gui/psppire-selector.h b/src/ui/gui/psppire-selector.h index 07213910..cb3f10f8 100644 --- a/src/ui/gui/psppire-selector.h +++ b/src/ui/gui/psppire-selector.h @@ -79,6 +79,11 @@ struct _PsppireSelector GtkWidget *source; GtkWidget *dest; + /* A flag indicating that the object is in the process of + updating its subjects. + (not thread safe if two threads access the same object) + */ + gboolean selecting; gint orientation; diff --git a/src/ui/gui/psppire.c b/src/ui/gui/psppire.c index 557130d3..f6bf1de3 100644 --- a/src/ui/gui/psppire.c +++ b/src/ui/gui/psppire.c @@ -275,6 +275,13 @@ create_icon_factory (void) g_object_unref (pixbuf); gtk_icon_factory_add ( factory, "pspp-select-cases", icon_set); + pixbuf = PIXBUF_NEW_FROM_FILE ("recent-dialogs.png"); + icon_set = gtk_icon_set_new_from_pixbuf (pixbuf); + g_object_unref (pixbuf); + gtk_icon_factory_add ( factory, "pspp-recent-dialogs", icon_set); + + + gtk_icon_factory_add_default (factory); } diff --git a/src/ui/gui/psppire.glade b/src/ui/gui/psppire.glade index 356d02ff..75352ab6 100644 --- a/src/ui/gui/psppire.glade +++ b/src/ui/gui/psppire.glade @@ -110,6 +110,7 @@ True + True 5 @@ -185,6 +186,9 @@ + + 5 + @@ -201,6 +205,7 @@ + Transpose True @@ -327,6 +332,7 @@ + True 5 @@ -338,6 +344,7 @@ + True 5 @@ -347,10 +354,14 @@ + 5 1 + + 5 + @@ -660,7 +671,6 @@ - True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK @@ -936,7 +946,6 @@ True True True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 5 @@ -1109,4 +1118,185 @@ + + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Sort Cases + 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 + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + GTK_POLICY_NEVER + GTK_POLICY_AUTOMATIC + GTK_SHADOW_ETCHED_IN + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False + True + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0.25 + 0 + 0 + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 + + + + + 1 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + Sort by: + + + False + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + GTK_POLICY_NEVER + GTK_POLICY_AUTOMATIC + GTK_SHADOW_ETCHED_IN + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False + True + + + + + 1 + + + + + 5 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + GTK_BUTTONBOX_SPREAD + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Ascending + True + True + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Descending + True + sort-cases-radiobutton0 + + + 1 + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Sort Order + True + + + label_item + + + + + 5 + 1 + + + + + 2 + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 + + + False + False + GTK_PACK_END + 1 + + + + + diff --git a/src/ui/gui/sort-cases-dialog.c b/src/ui/gui/sort-cases-dialog.c index 057e9433..1d5c5510 100644 --- a/src/ui/gui/sort-cases-dialog.c +++ b/src/ui/gui/sort-cases-dialog.c @@ -1,481 +1,134 @@ -/* - PSPPIRE --- A Graphical User Interface for PSPP - Copyright (C) 2006 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 2 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, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. */ - -/* This module describes the behaviour of the Sort Cases dialog box. */ - - -/* This code is rather quick and dirty. Some of the issues are: - - 1. Character set conversion when displaying dictionary tree view. - - 2. The interaction between the dictionary treeview, the criteria - list treeview and the button, needs to be abstracted and made - available as an external interface. - - 3. There's no destroy function for this dialog. - - 4. Some of the functionality might be better implemented with - GtkAction. - - 5. Double clicking the tree view rows should insert/delete them - from the criteria list. - - 6. Changing the Ascending/Descending flag ought to be possible for - a criteria already in the criteria tree view. - - 7. Variables which are in the criteria tree view should not be - shown in the dictionary treeview. - - 8. The dialog box structure itself ought to be a GtkWindow and - abstracted better. -*/ - - -#include -#include "helper.h" +#include #include "sort-cases-dialog.h" -#include "psppire-dict.h" -#include - -#include -#define _(msgid) gettext (msgid) -#define N_(msgid) msgid - - -enum {CRIT_TVM_IDX = 0, CRIT_TVM_DIR}; - -/* Occurs when the dictionary tree view selection changes */ -static void -dictionary_selection_changed (GtkTreeSelection *selection, - gpointer data) -{ - GtkTreeSelection *otherselection ; - struct sort_cases_dialog *dialog = (struct sort_cases_dialog*) data; - - if ( 0 == gtk_tree_selection_count_selected_rows (selection) ) - return ; - - gtk_arrow_set (dialog->arrow, GTK_ARROW_RIGHT, GTK_SHADOW_OUT); - dialog->button_state = VAR_SELECT; - - otherselection = gtk_tree_view_get_selection (dialog->criteria_view); - - gtk_tree_selection_unselect_all (otherselection); -} - - -/* Occurs when the sort criteria tree view selection changes */ -static void -criteria_selection_changed (GtkTreeSelection *selection, - gpointer data) -{ - GtkTreeSelection *otherselection ; - struct sort_cases_dialog *dialog = (struct sort_cases_dialog*) data; - - if ( 0 == gtk_tree_selection_count_selected_rows (selection) ) - return ; - - otherselection = gtk_tree_view_get_selection (dialog->dict_view); - - gtk_arrow_set (dialog->arrow, GTK_ARROW_LEFT, GTK_SHADOW_OUT); - dialog->button_state = VAR_DESELECT; - - gtk_tree_selection_unselect_all (otherselection); -} - - -/* Occurs when the dialog box is deleted (eg: closed via the title bar) */ -static gint -delete_event_callback (GtkWidget *widget, - GdkEvent *event, - gpointer data) -{ - struct sort_cases_dialog *dialog = (struct sort_cases_dialog*) data; - - g_main_loop_quit (dialog->loop); - - gtk_widget_hide_on_delete (widget); - - dialog->response = GTK_RESPONSE_DELETE_EVENT; - - return TRUE; -} - -/* Occurs when the cancel button is clicked */ -static void -sort_cases_cancel_callback (GObject *obj, gpointer data) -{ - struct sort_cases_dialog *dialog = (struct sort_cases_dialog*) data; - - gtk_widget_hide (dialog->window); - - g_main_loop_quit (dialog->loop); +#include "helper.h" +#include "psppire-dialog.h" +#include "data-editor.h" +#include +#include "psppire-var-store.h" +#include "dialog-common.h" +#include "dict-display.h" - dialog->response = GTK_RESPONSE_CANCEL; -} +#include +#include "syntax-editor.h" -/* Occurs when the reset button is clicked */ static void -sort_cases_reset_callback (GObject *obj, gpointer data) +refresh (PsppireDialog *dialog, GtkTreeView *dest) { - struct sort_cases_dialog *dialog = (struct sort_cases_dialog*) data; + GtkTreeModel *liststore = gtk_tree_view_get_model (dest); - gtk_arrow_set (dialog->arrow, GTK_ARROW_RIGHT, GTK_SHADOW_OUT); - dialog->button_state = VAR_SELECT; - gtk_list_store_clear (dialog->criteria_list); + gtk_list_store_clear (GTK_LIST_STORE (liststore)); } -/* Add variables currently selected in the dictionary tree view to the - list of criteria */ -static void -select_criteria (GtkTreeModel *model, GtkTreePath *path, - GtkTreeIter *iter, gpointer data) +struct sort_cases_dialog { - GtkTreeIter new_iter; - gint index; - gint dir; - struct variable *variable; - struct sort_cases_dialog *dialog = (struct sort_cases_dialog*) data; - - /* Get the variable from the dictionary */ - gtk_tree_model_get (model, iter, - DICT_TVM_COL_VAR, &variable, - -1); - - index = var_get_dict_index (variable); - - dir = gtk_toggle_button_get_active (dialog->ascending_button) ? - SRT_ASCEND:SRT_DESCEND; - - /* Append to the list of criteria */ - gtk_list_store_append (dialog->criteria_list, &new_iter); - gtk_list_store_set (dialog->criteria_list, - &new_iter, CRIT_TVM_IDX, index, -1); - gtk_list_store_set (dialog->criteria_list, - &new_iter, CRIT_TVM_DIR, dir, -1); -} + GtkTreeView *tv; + PsppireDict *dict; + GtkToggleButton *ascending; +}; -/* Create a list of the RowRefs which are to be removed from the - criteria list */ -static void -path_to_row_ref (GtkTreeModel *model, GtkTreePath *path, - GtkTreeIter *iter, gpointer data) +static char * +generate_syntax (const struct sort_cases_dialog *scd) { - GList **rrlist = data; - GtkTreeRowReference *rowref = gtk_tree_row_reference_new (model, path); - - *rrlist = g_list_append (*rrlist, rowref); -} - - -/* Remove a row from the list of criteria */ -static void -deselect_criteria (gpointer data, - gpointer user_data) -{ - GtkTreeIter iter; - GtkTreeRowReference *row_ref = data; - GtkTreePath *path; - struct sort_cases_dialog *dialog = (struct sort_cases_dialog*) user_data; - - path = gtk_tree_row_reference_get_path (row_ref); + gchar *text; + GString *string = g_string_new ("SORT CASES BY "); + gint n_vars = append_variable_names (string, + scd->dict, GTK_TREE_VIEW (scd->tv)); - gtk_tree_model_get_iter (GTK_TREE_MODEL (dialog->criteria_list), &iter, path); - - gtk_list_store_remove (dialog->criteria_list, &iter); - - gtk_tree_row_reference_free (row_ref); -} - - - -/* Callback which occurs when the button to remove variables from the list - of criteria is clicked. */ -static void -sort_cases_button_callback (GObject *obj, gpointer data) -{ - struct sort_cases_dialog *dialog = (struct sort_cases_dialog*) data; - - if ( dialog->button_state == VAR_SELECT) /* Right facing arrow */ + if ( n_vars == 0 ) + g_string_assign (string, ""); + else { - GtkTreeSelection *selection = - gtk_tree_view_get_selection (dialog->dict_view); - - gtk_tree_selection_selected_foreach (selection, select_criteria, dialog); + const char up_down = + gtk_toggle_button_get_active (scd->ascending) ? 'A' : 'D'; + g_string_append_printf (string, "(%c)", up_down); + g_string_append (string, "."); } - else /* Left facing arrow */ - { - GList *selectedRows = NULL; - GtkTreeSelection *selection = - gtk_tree_view_get_selection (dialog->criteria_view); - - /* Make a list of rows to be deleted */ - gtk_tree_selection_selected_foreach (selection, path_to_row_ref, - &selectedRows); - - /* ... and delete them */ - g_list_foreach (selectedRows, deselect_criteria, dialog); - - g_list_free (selectedRows); - } -} -/* Callback which occurs when the OK button is clicked */ -static void -sort_cases_ok_callback (GObject *obj, gpointer data) -{ - struct sort_cases_dialog *dialog = (struct sort_cases_dialog*) data; + text = string->str; - gtk_widget_hide (dialog->window); - g_main_loop_quit (dialog->loop); + g_string_free (string, FALSE); - dialog->response = GTK_RESPONSE_OK; + return text; } -/* This function is responsible for rendering a criterion in the - criteria list */ -static void -criteria_render_func (GtkTreeViewColumn *column, GtkCellRenderer *renderer, - GtkTreeModel *model, GtkTreeIter *iter, - gpointer data) +/* Pops up the Sort Cases dialog box */ +void +sort_cases_dialog (GObject *o, gpointer data) { - gint var_index; - struct variable *variable ; - gint direction; - gchar *buf; - gchar *varname; - PsppireDict *dict = data; - - gtk_tree_model_get (model, iter, - CRIT_TVM_IDX, &var_index, - CRIT_TVM_DIR, &direction, -1); - - variable = psppire_dict_get_variable (dict, var_index); - - varname = pspp_locale_to_utf8 (var_get_name (variable), - -1, 0); - - if ( direction == SRT_ASCEND) - buf = g_strdup_printf ("%s: %s", varname, _("Ascending")); - else - buf = g_strdup_printf ("%s: %s", varname, _("Descending")); - - g_free (varname); - - g_object_set (renderer, "text", buf, NULL); - - g_free (buf); -} - - -/* Create the dialog */ -struct sort_cases_dialog * -sort_cases_dialog_create (GladeXML *xml) -{ - struct sort_cases_dialog *dialog = g_malloc (sizeof (*dialog)); - - dialog->loop = g_main_loop_new (NULL, FALSE); - - dialog->window = get_widget_assert (xml, "sort-cases-dialog"); - - dialog->dict_view = GTK_TREE_VIEW (get_widget_assert - (xml, "sort-cases-treeview-dict")); - dialog->criteria_view = GTK_TREE_VIEW (get_widget_assert - (xml, "sort-cases-treeview-criteria")); - - dialog->arrow = GTK_ARROW (get_widget_assert (xml, "sort-cases-arrow")); - dialog->button = GTK_BUTTON (get_widget_assert (xml, "sort-cases-button")); - - dialog->ascending_button = - GTK_TOGGLE_BUTTON (get_widget_assert (xml, "sort-cases-button-ascending")); - - g_signal_connect (dialog->window, "delete-event", - G_CALLBACK (delete_event_callback), dialog); - - g_signal_connect (get_widget_assert (xml, "sort-cases-cancel"), - "clicked", G_CALLBACK (sort_cases_cancel_callback), dialog); - - g_signal_connect (get_widget_assert (xml, "sort-cases-ok"), - "clicked", G_CALLBACK (sort_cases_ok_callback), dialog); - - - g_signal_connect (get_widget_assert (xml, "sort-cases-reset"), - "clicked", G_CALLBACK (sort_cases_reset_callback), dialog); - + gint response; + struct data_editor *de = data; - g_signal_connect (get_widget_assert (xml, "sort-cases-button"), - "clicked", G_CALLBACK (sort_cases_button_callback), dialog); + struct sort_cases_dialog scd; + GladeXML *xml = XML_NEW ("psppire.glade"); - { - /* Set up the dictionary treeview */ - GtkTreeViewColumn *col; + GtkWidget *dialog = get_widget_assert (xml, "sort-cases-dialog"); - GtkTreeSelection *selection = - gtk_tree_view_get_selection (dialog->dict_view); - GtkCellRenderer *renderer = gtk_cell_renderer_text_new (); + 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"); - col = gtk_tree_view_column_new_with_attributes (_("Var"), - renderer, - "text", - 0, - NULL); + GtkSheet *var_sheet = + GTK_SHEET (get_widget_assert (de->xml, "variable_sheet")); - /* FIXME: make this a value in terms of character widths */ - g_object_set (col, "min-width", 100, NULL); + PsppireVarStore *vs = PSPPIRE_VAR_STORE (gtk_sheet_get_model (var_sheet)); - gtk_tree_view_column_set_sizing (col, GTK_TREE_VIEW_COLUMN_FIXED); + gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window); - gtk_tree_view_append_column (dialog->dict_view, col); + attach_dictionary_to_treeview (GTK_TREE_VIEW (source), + vs->dict, + GTK_SELECTION_MULTIPLE, NULL); - gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE); + set_dest_model (GTK_TREE_VIEW (dest), vs->dict); - g_signal_connect (selection, "changed", - G_CALLBACK (dictionary_selection_changed), dialog); - } + psppire_selector_set_subjects (PSPPIRE_SELECTOR (selector), + source, + dest, + insert_source_row_into_tree_view, + NULL); - { - /* Set up the variable list treeview */ - GtkTreeSelection *selection = - gtk_tree_view_get_selection (dialog->criteria_view); + g_signal_connect (dialog, "refresh", G_CALLBACK (refresh), dest); - gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE); + scd.tv = GTK_TREE_VIEW (dest); + scd.dict = vs->dict; + scd.ascending = + GTK_TOGGLE_BUTTON (get_widget_assert (xml, "sort-cases-radiobutton0")); - dialog->crit_renderer = gtk_cell_renderer_text_new (); + response = psppire_dialog_run (PSPPIRE_DIALOG (dialog)); - dialog->crit_col = gtk_tree_view_column_new_with_attributes (_("Criteria"), - dialog->crit_renderer, - "text", - 0, - NULL); - gtk_tree_view_column_set_sizing (dialog->crit_col, GTK_TREE_VIEW_COLUMN_FIXED); - - gtk_tree_view_append_column (GTK_TREE_VIEW (dialog->criteria_view), - dialog->crit_col); - - g_signal_connect (selection, "changed", - G_CALLBACK (criteria_selection_changed), dialog); - } - - { - /* Create the list of criteria */ - dialog->criteria_list = gtk_list_store_new (2, - G_TYPE_INT, /* index of the variable */ - G_TYPE_INT /* Ascending/Descending */ - ); - - gtk_tree_view_set_model (dialog->criteria_view, - GTK_TREE_MODEL (dialog->criteria_list)); - } - - dialog->response = GTK_RESPONSE_NONE; - - return dialog; -} - - -static void -convert_list_store_to_criteria (GtkListStore *list, - PsppireDict *dict, - struct sort_criteria *criteria); - - -/* Run the dialog. - If the return value is GTK_RESPONSE_OK, then CRITERIA gets filled - with a valid sort criteria which can be used to sort the data. - This structure and its contents must be freed by the caller. */ -gint -sort_cases_dialog_run (struct sort_cases_dialog *dialog, - PsppireDict *dict, - struct sort_criteria *criteria - ) -{ - g_assert (! g_main_loop_is_running (dialog->loop)); - - gtk_tree_view_set_model (GTK_TREE_VIEW (dialog->dict_view), - GTK_TREE_MODEL (dict)); - - - gtk_tree_view_column_set_cell_data_func (dialog->crit_col, - dialog->crit_renderer, - criteria_render_func, dict, 0); - - gtk_list_store_clear (dialog->criteria_list); - - gtk_arrow_set (dialog->arrow, GTK_ARROW_RIGHT, GTK_SHADOW_OUT); - dialog->button_state = VAR_SELECT; - - gtk_widget_show (dialog->window); - - g_main_loop_run (dialog->loop); - - if ( GTK_RESPONSE_OK == dialog->response) - convert_list_store_to_criteria (dialog->criteria_list, - dict, criteria); - - return dialog->response; -} - - - -/* Convert the GtkListStore to a struct sort_criteria*/ -static void -convert_list_store_to_criteria (GtkListStore *list, - PsppireDict *dict, - struct sort_criteria *criteria) -{ - GtkTreeIter iter; - gboolean valid; - gint n = 0; - - GtkTreeModel *model = GTK_TREE_MODEL (list); - - criteria->crit_cnt = gtk_tree_model_iter_n_children (model, NULL); - - criteria->crits = g_malloc (sizeof (struct sort_criterion) * - criteria->crit_cnt); - - for (valid = gtk_tree_model_get_iter_first (model, &iter); - valid; - valid = gtk_tree_model_iter_next (model, &iter)) + switch (response) { - struct variable *variable; - gint index; - struct sort_criterion *scn = &criteria->crits[n]; - g_assert ( n < criteria->crit_cnt); - n++; - - gtk_tree_model_get (model, &iter, - CRIT_TVM_IDX, &index, - CRIT_TVM_DIR, &scn->dir, - -1); - - variable = psppire_dict_get_variable (dict, index); - - scn->fv = var_get_case_index (variable); - scn->width = var_get_width (variable); + case GTK_RESPONSE_OK: + { + gchar *syntax = generate_syntax (&scd); + struct getl_interface *sss = create_syntax_string_source (syntax); + execute_syntax (sss); + + g_free (syntax); + } + break; + case PSPPIRE_RESPONSE_PASTE: + { + gchar *syntax = generate_syntax (&scd); + + struct syntax_editor *se = + (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL); + + gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1); + + g_free (syntax); + } + break; + default: + break; } + + g_object_unref (xml); } diff --git a/src/ui/gui/sort-cases-dialog.h b/src/ui/gui/sort-cases-dialog.h index 88d1a21f..ef2e72b1 100644 --- a/src/ui/gui/sort-cases-dialog.h +++ b/src/ui/gui/sort-cases-dialog.h @@ -23,43 +23,8 @@ #include #include -#include "psppire-dict.h" -struct sort_criteria; -struct sort_cases_dialog -{ - GtkWidget *window; - GMainLoop *loop; - - GtkTreeView *dict_view; - - - GtkTreeView *criteria_view; - GtkTreeViewColumn *crit_col; - GtkCellRenderer *crit_renderer; - - GtkListStore *criteria_list; - - struct sort_criteria *sc; - - GtkArrow *arrow; - GtkButton *button; - - GtkToggleButton *ascending_button; - - /* FIXME: Could this be done better with a GtkToggleAction ?? */ - enum {VAR_SELECT, VAR_DESELECT} button_state; - - gint response; -}; - -struct sort_cases_dialog * sort_cases_dialog_create (GladeXML *xml); - - -gint sort_cases_dialog_run (struct sort_cases_dialog *dialog, - PsppireDict *dict, - struct sort_criteria *criteria - ); +void sort_cases_dialog (GObject *o, gpointer data); #endif diff --git a/src/ui/gui/split-file-dialog.c b/src/ui/gui/split-file-dialog.c index 35aaf701..731995ca 100644 --- a/src/ui/gui/split-file-dialog.c +++ b/src/ui/gui/split-file-dialog.c @@ -39,25 +39,41 @@ #include "psppire-var-store.h" +struct split_file_dialog +{ + /* The XML that created the dialog */ + GladeXML *xml; + + /* The dictionary to which this dialog pertains */ + PsppireDict *dict; + + /* The treeview widget containing the list of variables + upon which the file should be split */ + GtkTreeView *tv; + + + PsppireSelector *selector; +}; + static gchar * -generate_syntax (GladeXML *xml, PsppireDict *dict) +generate_syntax (const struct split_file_dialog *sfd) { gchar *text; - GtkWidget *off = get_widget_assert (xml, "split-radiobutton0"); + GtkWidget *off = get_widget_assert (sfd->xml, "split-radiobutton0"); GtkWidget *vars = - get_widget_assert (xml, "split-file-grouping-vars"); + get_widget_assert (sfd->xml, "split-file-grouping-vars"); GString *string = g_string_new ("SPLIT FILE OFF."); if ( ! gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (off))) { GString * varlist = g_string_sized_new (80); - GtkWidget *sort = get_widget_assert (xml, "split-radiobutton3"); - GtkWidget *layered = get_widget_assert (xml, "split-radiobutton1"); + 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, - dict, GTK_TREE_VIEW (vars)); + sfd->dict, GTK_TREE_VIEW (vars)); if ( n_vars > 0 ) { @@ -113,47 +129,81 @@ on_off_toggled (GtkToggleButton *togglebutton, } static void -refresh (GladeXML *xml) +refresh (PsppireDialog *dialog, struct split_file_dialog *d) { - GtkWidget *off = get_widget_assert (xml, "split-radiobutton0"); + GtkWidget *off = get_widget_assert (d->xml, "split-radiobutton0"); + GtkWidget *on = get_widget_assert (d->xml, "split-radiobutton1"); + + GtkTreeModel *liststore = gtk_tree_view_get_model (d->tv); - g_print ("%s\n", __FUNCTION__); + gint n_vars = dict_get_split_cnt (d->dict->dict); + + + gtk_list_store_clear (GTK_LIST_STORE (liststore)); + + if ( n_vars == 0 ) + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(off), TRUE); + else + { + GtkTreeIter iter; + gint i; + struct variable *const *vars = dict_get_split_vars (d->dict->dict); + + for (i = 0 ; i < n_vars; ++i ) + { + gint idx = var_get_dict_index (vars[i]); + + gtk_list_store_append (GTK_LIST_STORE (liststore), &iter); + gtk_list_store_set (GTK_LIST_STORE (liststore), &iter, 0, idx, -1); + } + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(on), TRUE); + } - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(off), TRUE); gtk_toggle_button_toggled (GTK_TOGGLE_BUTTON(off)); } -/* Pops up the Weight Cases dialog box */ +/* Pops up the Split File dialog box */ void split_file_dialog (GObject *o, gpointer data) { gint response; struct data_editor *de = data; - PsppireDict *dict; + struct split_file_dialog sfd; - GladeXML *xml = XML_NEW ("psppire.glade"); + GtkWidget *dialog ; + GtkWidget *source ; + GtkWidget *dest ; + GtkWidget *selector ; + GtkWidget *on_off ; - GtkWidget *dialog = get_widget_assert (xml, "split-file-dialog"); - GtkWidget *source = get_widget_assert (xml, "split-file-dict-treeview"); - GtkWidget *dest = get_widget_assert (xml, "split-file-grouping-vars"); - GtkWidget *selector = get_widget_assert (xml, "split-file-selector"); - GtkWidget *on_off = get_widget_assert (xml, "split-radiobutton0"); + GtkSheet *var_sheet ; + + sfd.xml = XML_NEW ("psppire.glade"); + + dialog = get_widget_assert (sfd.xml, "split-file-dialog"); + source = get_widget_assert (sfd.xml, "split-file-dict-treeview"); + dest = get_widget_assert (sfd.xml, "split-file-grouping-vars"); + selector = get_widget_assert (sfd.xml, "split-file-selector"); + on_off = get_widget_assert (sfd.xml, "split-radiobutton0"); - GtkSheet *var_sheet = - GTK_SHEET (get_widget_assert (de->xml, "variable_sheet")); + var_sheet = GTK_SHEET (get_widget_assert (de->xml, "variable_sheet")); PsppireVarStore *vs = PSPPIRE_VAR_STORE (gtk_sheet_get_model (var_sheet)); - dict = vs->dict; + sfd.dict = vs->dict; + sfd.tv = GTK_TREE_VIEW (dest); + sfd.selector = PSPPIRE_SELECTOR ( + get_widget_assert (sfd.xml, "split-file-selector")); attach_dictionary_to_treeview (GTK_TREE_VIEW (source), vs->dict, GTK_SELECTION_MULTIPLE, NULL); - g_signal_connect (on_off, "toggled", G_CALLBACK(on_off_toggled), xml); + g_signal_connect (on_off, "toggled", G_CALLBACK(on_off_toggled), sfd.xml); set_dest_model (GTK_TREE_VIEW (dest), vs->dict); @@ -164,7 +214,7 @@ split_file_dialog (GObject *o, gpointer data) insert_source_row_into_tree_view, NULL); - refresh (xml); + g_signal_connect (dialog, "refresh", G_CALLBACK (refresh), &sfd); response = psppire_dialog_run (PSPPIRE_DIALOG (dialog)); @@ -173,7 +223,7 @@ split_file_dialog (GObject *o, gpointer data) { case GTK_RESPONSE_OK: { - gchar *syntax = generate_syntax (xml, dict); + gchar *syntax = generate_syntax (&sfd); struct getl_interface *sss = create_syntax_string_source (syntax); execute_syntax (sss); @@ -182,7 +232,7 @@ split_file_dialog (GObject *o, gpointer data) break; case PSPPIRE_RESPONSE_PASTE: { - gchar *syntax = generate_syntax (xml, dict); + gchar *syntax = generate_syntax (&sfd); struct syntax_editor *se = (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL); @@ -196,6 +246,6 @@ split_file_dialog (GObject *o, gpointer data) break; } - g_object_unref (xml); + g_object_unref (sfd.xml); } diff --git a/src/ui/gui/transpose-dialog.c b/src/ui/gui/transpose-dialog.c index 14c1b3a2..aa6ed5c5 100644 --- a/src/ui/gui/transpose-dialog.c +++ b/src/ui/gui/transpose-dialog.c @@ -46,6 +46,18 @@ static gchar * generate_syntax (PsppireDict *dict, GladeXML *xml); +static void +refresh (PsppireDialog *dialog, gpointer data) +{ + GladeXML *xml = data; + GtkWidget *dest = get_widget_assert (xml, "variables-treeview"); + GtkWidget *entry = get_widget_assert (xml, "new-name-entry"); + GtkTreeModel *dmodel = gtk_tree_view_get_model (dest); + + gtk_list_store_clear (GTK_LIST_STORE (dmodel)); + gtk_entry_set_text (GTK_ENTRY (entry), ""); +} + void transpose_dialog (GObject *o, gpointer data) { @@ -84,6 +96,8 @@ transpose_dialog (GObject *o, gpointer data) is_currently_in_entry); + g_signal_connect (dialog, "refresh", G_CALLBACK (refresh), xml); + response = psppire_dialog_run (PSPPIRE_DIALOG (dialog)); switch (response) diff --git a/src/ui/gui/weight-cases-dialog.c b/src/ui/gui/weight-cases-dialog.c index 31907a15..1a637f3c 100644 --- a/src/ui/gui/weight-cases-dialog.c +++ b/src/ui/gui/weight-cases-dialog.c @@ -31,6 +31,11 @@ #include #include +#include +#define _(msgid) gettext (msgid) +#define N_(msgid) msgid + + /* FIXME: These shouldn't be here */ #include #include "psppire-var-store.h" @@ -60,10 +65,43 @@ on_toggle (GtkToggleButton *button, gpointer data) gtk_entry_set_text (entry, ""); } +struct weight_cases_dialog +{ + PsppireDict *dict; + GtkEntry *entry; + GtkLabel *status; + GtkToggleButton *off; + GtkToggleButton *on; +}; +static void +refresh (PsppireDialog *dialog, const struct weight_cases_dialog *wcd) +{ + const struct variable *var = dict_get_weight (wcd->dict->dict); + if ( ! var ) + { + gtk_entry_set_text (wcd->entry, ""); + gtk_label_set_text (wcd->status, _("Do not weight cases")); + gtk_toggle_button_set_active (wcd->off, TRUE); + } + else + { + gchar *text = + g_strdup_printf (_("Weight cases by %s"), var_get_name (var)); -static gchar * generate_syntax (PsppireDict *, GtkEntry *); + gtk_entry_set_text (wcd->entry, var_get_name (var)); + gtk_label_set_text (wcd->status, text); + + g_free (text); + gtk_toggle_button_set_active (wcd->on, TRUE); + } + + g_signal_emit_by_name (wcd->entry, "activate"); +} + + +static gchar * generate_syntax (const struct weight_cases_dialog *wcd); /* Pops up the Weight Cases dialog box */ @@ -72,8 +110,7 @@ weight_cases_dialog (GObject *o, gpointer data) { gint response; struct data_editor *de = data; - PsppireDict *dict; - struct variable *var; + struct weight_cases_dialog wcd; GladeXML *xml = XML_NEW ("psppire.glade"); @@ -84,13 +121,14 @@ weight_cases_dialog (GObject *o, gpointer data) GtkWidget *radiobutton1 = get_widget_assert (xml, "weight-cases-radiobutton1"); GtkWidget *radiobutton2 = get_widget_assert (xml, "radiobutton2"); + GtkWidget *status = get_widget_assert (xml, "weight-status-label"); GtkSheet *var_sheet = GTK_SHEET (get_widget_assert (de->xml, "variable_sheet")); PsppireVarStore *vs = PSPPIRE_VAR_STORE (gtk_sheet_get_model (var_sheet)); - dict = vs->dict; + gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window); g_signal_connect (radiobutton1, "toggled", G_CALLBACK (on_toggle), entry); g_signal_connect (selector, "selected", G_CALLBACK (on_select), @@ -100,7 +138,7 @@ weight_cases_dialog (GObject *o, gpointer data) radiobutton1); attach_dictionary_to_treeview (GTK_TREE_VIEW (source), - dict, + vs->dict, GTK_SELECTION_SINGLE, var_is_numeric ); @@ -112,13 +150,14 @@ weight_cases_dialog (GObject *o, gpointer data) is_currently_in_entry ); - var = dict_get_weight (dict->dict); - if ( ! var ) - gtk_entry_set_text (GTK_ENTRY (entry), ""); - else - gtk_entry_set_text (GTK_ENTRY (entry), var_get_name (var)); - g_signal_emit_by_name (entry, "activate"); + wcd.dict = vs->dict; + wcd.entry = GTK_ENTRY (entry); + wcd.status = GTK_LABEL (status); + wcd.off = GTK_TOGGLE_BUTTON (radiobutton1); + wcd.on = GTK_TOGGLE_BUTTON (radiobutton2); + + g_signal_connect (dialog, "refresh", G_CALLBACK (refresh), &wcd); response = psppire_dialog_run (PSPPIRE_DIALOG (dialog)); @@ -128,7 +167,7 @@ weight_cases_dialog (GObject *o, gpointer data) { case GTK_RESPONSE_OK: { - gchar *syntax = generate_syntax (dict, GTK_ENTRY (entry)); + gchar *syntax = generate_syntax (&wcd); struct getl_interface *sss = create_syntax_string_source (syntax); execute_syntax (sss); @@ -137,7 +176,7 @@ weight_cases_dialog (GObject *o, gpointer data) break; case PSPPIRE_RESPONSE_PASTE: { - gchar *syntax = generate_syntax (dict, GTK_ENTRY (entry)); + gchar *syntax = generate_syntax (&wcd); struct syntax_editor *se = (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL); @@ -154,13 +193,13 @@ weight_cases_dialog (GObject *o, gpointer data) static gchar * -generate_syntax (PsppireDict *dict, GtkEntry *entry) +generate_syntax (const struct weight_cases_dialog *wcd) { gchar *syntax; - const gchar *text = gtk_entry_get_text (entry); + const gchar *text = gtk_entry_get_text (wcd->entry); - struct variable *var = psppire_dict_lookup_var (dict, text); + struct variable *var = psppire_dict_lookup_var (wcd->dict, text); if ( var == NULL) syntax = g_strdup ("WEIGHT OFF."); -- 2.30.2