From a10cebe053263d7e936b6533a3dbf5ac2f0586a1 Mon Sep 17 00:00:00 2001 From: John Darrington Date: Fri, 26 Jan 2007 07:35:02 +0000 Subject: [PATCH] Added custom psppire-selector widget. Added Transpose Dialog. Reimplemented Weight Cases dialog. --- glade.patch | 868 ++++++++++++++++++++++++++++--- glade/automake.mk | 4 +- glade/psppire.xml | 15 + glade/selector.c | 74 +++ src/data/dictionary.c | 11 +- src/data/variable.h | 3 + src/ui/gui/ChangeLog | 18 + src/ui/gui/automake.mk | 10 +- src/ui/gui/data-editor.c | 109 +--- src/ui/gui/data-editor.glade | 8 +- src/ui/gui/data-editor.h | 1 + src/ui/gui/dict-display.c | 243 +++++++++ src/ui/gui/dict-display.h | 59 +++ src/ui/gui/glade-register.c | 5 + src/ui/gui/helper.c | 5 +- src/ui/gui/psppire-case-file.c | 3 +- src/ui/gui/psppire-dict.c | 169 ++++-- src/ui/gui/psppire-dict.h | 4 +- src/ui/gui/psppire-object.c | 112 ---- src/ui/gui/psppire-object.h | 63 --- src/ui/gui/psppire-selector.c | 598 +++++++++++++++++++++ src/ui/gui/psppire-selector.h | 107 ++++ src/ui/gui/psppire-var-select.c | 289 ---------- src/ui/gui/psppire-var-select.h | 87 ---- src/ui/gui/psppire.glade | 206 ++++++-- src/ui/gui/transpose-dialog.c | 238 +++++++++ src/ui/gui/transpose-dialog.h | 30 ++ src/ui/gui/weight-cases-dialog.c | 176 ++++--- src/ui/gui/weight-cases-dialog.h | 7 +- 29 files changed, 2650 insertions(+), 872 deletions(-) create mode 100644 glade/selector.c create mode 100644 src/ui/gui/dict-display.c create mode 100644 src/ui/gui/dict-display.h delete mode 100644 src/ui/gui/psppire-object.c delete mode 100644 src/ui/gui/psppire-object.h create mode 100644 src/ui/gui/psppire-selector.c create mode 100644 src/ui/gui/psppire-selector.h delete mode 100644 src/ui/gui/psppire-var-select.c delete mode 100644 src/ui/gui/psppire-var-select.h create mode 100644 src/ui/gui/transpose-dialog.c create mode 100644 src/ui/gui/transpose-dialog.h diff --git a/glade.patch b/glade.patch index d4a01e7c..9081dae7 100644 --- a/glade.patch +++ b/glade.patch @@ -1,62 +1,810 @@ 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-2. Glade-3 is another story and might give -problems of its own. ---- src/ui/gui/data-editor.glade,old 2006-12-31 07:29:39.000000000 +0900 -+++ src/ui/gui/data-editor.glade 2006-12-31 07:30:04.000000000 +0900 -@@ -653,6 +653,7 @@ - True - False - Variables -+ pspp-goto-variable - - True - True -@@ -712,6 +713,7 @@ - True - False - Insert Case -+ pspp-insert-case - - True - True -@@ -730,6 +732,7 @@ - True - False - Insert Variable -+ pspp-insert-variable - - True - True -@@ -760,6 +763,7 @@ - True - False - Split File -+ pspp-split-file - - True - True -@@ -777,6 +781,7 @@ - True - False - Weight Cases -+ pspp-weight-cases - - True - True -@@ -794,6 +799,7 @@ - True - False - Select Cases -+ pspp-select-cases - - True - True -@@ -823,6 +829,7 @@ - - True - Value Labels -+ pspp-value-labels - - True - True +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 @@ + False + Variables + True +- gtk-missing-image ++ pspp-goto-variable + + + False +@@ -547,7 +547,7 @@ + False + Insert Case + True +- gtk-missing-image ++ pspp-insert-case + + + +@@ -560,7 +560,7 @@ + False + Insert Variable + True +- gtk-missing-image ++ pspp-insert-variable + + + False +@@ -581,7 +581,7 @@ + False + Split File + True +- gtk-missing-image ++ pspp-split-file + + + False +@@ -592,7 +592,7 @@ + True + Weight Cases + True +- gtk-missing-image ++ pspp-weight-cases + + + False +@@ -604,7 +604,7 @@ + False + Select Cases + True +- gtk-missing-image ++ pspp-select-cases + + + False +@@ -624,7 +624,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 + + + diff --git a/glade/automake.mk b/glade/automake.mk index 144cb6da..5d5a6583 100644 --- a/glade/automake.mk +++ b/glade/automake.mk @@ -8,8 +8,10 @@ catalogdir = `pkg-config --variable=catalogdir libgladeui-1.0` libglade_psppire_la_SOURCES = \ glade/dialog.c \ glade/bbox.c \ + glade/selector.c \ src/ui/gui/psppire-dialog.c \ - src/ui/gui/psppire-buttonbox.c + src/ui/gui/psppire-buttonbox.c \ + src/ui/gui/psppire-selector.c nodist_catalog_DATA = \ glade/psppire.xml diff --git a/glade/psppire.xml b/glade/psppire.xml index 10960e5c..da6f0137 100644 --- a/glade/psppire.xml +++ b/glade/psppire.xml @@ -19,6 +19,7 @@ + @@ -43,11 +44,25 @@ + + + + glade_psppire_selector_post_create + glade_psppire_selector_get_children + + glade_psppire_selector_get_internal_child + + glade_psppire_selector_set_property + + + + + diff --git a/glade/selector.c b/glade/selector.c new file mode 100644 index 00000000..bd85f44d --- /dev/null +++ b/glade/selector.c @@ -0,0 +1,74 @@ +#include +#include + +#include "psppire-selector.h" + +#include + + +void GLADEGTK_API +glade_psppire_selector_post_create (GladeWidgetAdaptor *adaptor, + GObject *object, + GladeCreateReason reason) +{ + GladeWidget *widget ; + + PsppireSelector *selector = PSPPIRE_SELECTOR (object); + + g_return_if_fail (PSPPIRE_IS_SELECTOR (selector)); + + widget = glade_widget_get_from_gobject (GTK_WIDGET (selector)); + if (!widget) + return; + + if (reason == GLADE_CREATE_USER) + { + /* HIG complient border-width defaults on selectors */ + glade_widget_property_set (widget, "border-width", 5); + } +} + + +GtkWidget * +glade_psppire_selector_get_internal_child (GladeWidgetAdaptor *adaptor, + PsppireSelector *selector, + const gchar *name) +{ +#if DEBUGGING + g_print ("%s\n", __FUNCTION__); +#endif + return GTK_WIDGET (selector); +} + + + +void +glade_psppire_selector_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_selector_get_children (GladeWidgetAdaptor *adaptor, + PsppireSelector *selector) +{ + GList *list = NULL; + + g_return_val_if_fail (PSPPIRE_IS_SELECTOR (selector), NULL); + + list = glade_util_container_get_all_children (GTK_CONTAINER (selector)); + + return list; +} diff --git a/src/data/dictionary.c b/src/data/dictionary.c index d38ed5fc..0dadb959 100644 --- a/src/data/dictionary.c +++ b/src/data/dictionary.c @@ -352,9 +352,16 @@ dict_clone_var_assert (struct dictionary *d, const struct variable *old_var, struct variable * dict_lookup_var (const struct dictionary *d, const char *name) { - struct variable *target = var_create (name, 0); - struct variable *result = hsh_find (d->name_tab, target); + struct variable *target ; + struct variable *result ; + + if ( ! var_is_valid_name (name, false)) + return NULL; + + target = var_create (name, 0); + result = hsh_find (d->name_tab, target); var_destroy (target); + return result; } diff --git a/src/data/variable.h b/src/data/variable.h index 88d9b5a7..e487ac51 100644 --- a/src/data/variable.h +++ b/src/data/variable.h @@ -61,6 +61,9 @@ unsigned hash_var_ptr_by_name (const void *, const void *); enum var_type var_get_type (const struct variable *); int var_get_width (const struct variable *); void var_set_width (struct variable *, int width); + +typedef bool var_predicate_func (const struct variable *); + bool var_is_numeric (const struct variable *); bool var_is_alpha (const struct variable *); bool var_is_short_string (const struct variable *); diff --git a/src/ui/gui/ChangeLog b/src/ui/gui/ChangeLog index 0b9592ee..5b0dbec4 100644 --- a/src/ui/gui/ChangeLog +++ b/src/ui/gui/ChangeLog @@ -1,3 +1,21 @@ +Fri Jan 26 15:51:34 WST 2007 John Darrington + + * psppire-var-select.c psppire-var-select.h : Deleted. + + * psppire-selector.c psppire-selector.h : New files. + + * transpose-dialog.c transpose-dialog.h : New files. + + * psppire-dict.c psppire-dict.h : Added missing GtkTreeModel + interface functions. + + * weight-cases-dialog.c weight-cases-dialog.h : Re-implemented, + using new PsppireSelector widget. + + * dict-display.c dict-display.h : New files. + + * psppire-object.c psppire-object.h : Deleted. Seemed like a good idea at the time. + Tue Jan 23 21:10:01 WST 2007 John Darrington * helper.c helper.h: New function execute_syntax. diff --git a/src/ui/gui/automake.mk b/src/ui/gui/automake.mk index 11a27925..6f6fa3c5 100644 --- a/src/ui/gui/automake.mk +++ b/src/ui/gui/automake.mk @@ -62,6 +62,8 @@ src_ui_gui_psppire_SOURCES = \ src/ui/gui/data-sheet.h \ src/ui/gui/data-editor.c \ src/ui/gui/data-editor.h \ + src/ui/gui/dict-display.c \ + src/ui/gui/dict-display.h \ src/ui/gui/flexifile-factory.h \ src/ui/gui/flexifile-factory.c \ src/ui/gui/message-dialog.c \ @@ -81,18 +83,18 @@ src_ui_gui_psppire_SOURCES = \ src/ui/gui/psppire-dialog.h \ src/ui/gui/psppire-buttonbox.c \ src/ui/gui/psppire-buttonbox.h \ - src/ui/gui/psppire-object.c \ - src/ui/gui/psppire-object.h \ + src/ui/gui/psppire-selector.c \ + src/ui/gui/psppire-selector.h \ src/ui/gui/psppire-var-store.c \ src/ui/gui/psppire-var-store.h \ - src/ui/gui/psppire-var-select.h \ - src/ui/gui/psppire-var-select.c \ src/ui/gui/sort-cases-dialog.c \ src/ui/gui/sort-cases-dialog.h \ src/ui/gui/syntax-editor.c \ src/ui/gui/syntax-editor.h \ src/ui/gui/syntax-editor-source.c \ src/ui/gui/syntax-editor-source.h \ + src/ui/gui/transpose-dialog.c \ + src/ui/gui/transpose-dialog.h \ src/ui/gui/val-labs-dialog.c \ src/ui/gui/val-labs-dialog.h \ src/ui/gui/var-sheet.c \ diff --git a/src/ui/gui/data-editor.c b/src/ui/gui/data-editor.c index 07588770..0d60b9cd 100644 --- a/src/ui/gui/data-editor.c +++ b/src/ui/gui/data-editor.c @@ -30,7 +30,10 @@ #include "helper.h" #include "about.h" #include "psppire-dialog.h" -#include "psppire-var-select.h" +#include "psppire-selector.h" +#include "weight-cases-dialog.h" +#include "transpose-dialog.h" +#include "dict-display.h" #define _(msgid) gettext (msgid) #define N_(msgid) msgid @@ -43,8 +46,6 @@ #include "psppire-data-store.h" #include "psppire-var-store.h" -#include "weight-cases-dialog.h" - static void register_data_editor_actions (struct data_editor *de); static void insert_variable (GtkCheckMenuItem *m, gpointer data); @@ -111,8 +112,6 @@ disable_edit_clear (GtkWidget *w, gint x, gint y, gpointer data) return FALSE; } -static void weight_cases_dialog (GObject *o, gpointer data); - /* Create a new data editor. @@ -159,10 +158,21 @@ new_data_editor (void) _("Weight cases by variable"), "pspp-weight-cases"); - g_signal_connect (de->invoke_weight_cases_dialog, "activate", G_CALLBACK (weight_cases_dialog), de); + + de->invoke_transpose_dialog = + gtk_action_new ("transpose-dialog", + _("Transpose"), + _("Transpose the cases with the variables"), + NULL); + + + g_signal_connect (de->invoke_transpose_dialog, "activate", + G_CALLBACK (transpose_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"), @@ -211,6 +221,9 @@ new_data_editor (void) get_widget_assert (de->xml, "data_weight-cases") ); + gtk_action_connect_proxy (de->invoke_transpose_dialog, + get_widget_assert (de->xml, "data_transpose") + ); g_signal_connect (get_widget_assert (de->xml,"help_about"), "activate", @@ -739,90 +752,6 @@ on_weight_change (GObject *o, gint weight_index, gpointer data) } } -static void -weight_cases_dialog (GObject *o, gpointer data) -{ - gint response; - struct data_editor *de = data; - GtkSheet *var_sheet = - GTK_SHEET (get_widget_assert (de->xml, "variable_sheet")); - - - GladeXML *xml = glade_xml_new (PKGDATADIR "/psppire.glade", - "weight-cases-dialog", NULL); - - - GtkWidget *treeview = get_widget_assert (xml, "treeview"); - GtkWidget *entry = get_widget_assert (xml, "entry1"); - - - PsppireVarStore *vs = PSPPIRE_VAR_STORE (gtk_sheet_get_model (var_sheet)); - - PsppireVarSelect *select = psppire_var_select_new (treeview, - entry, vs->dict); - - - PsppireDialog *dialog = create_weight_dialog (select, xml); - - response = psppire_dialog_run (dialog); - - g_object_unref (xml); - - switch (response) - { - case GTK_RESPONSE_OK: - { - struct getl_interface *sss ; - const GList *list = psppire_var_select_get_variables (select); - - g_assert ( g_list_length ((GList *)list) <= 1 ); - - if ( list == NULL) - { - sss = create_syntax_string_source ("WEIGHT OFF."); - } - else - { - struct variable *var = list->data; - - sss = create_syntax_string_source ("WEIGHT BY %s.\n", - var_get_name (var)); - } - - execute_syntax (sss); - } - break; - case PSPPIRE_RESPONSE_PASTE: - { - struct syntax_editor *se = (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL); - - const GList *list = psppire_var_select_get_variables (select); - - g_assert ( g_list_length ((GList *)list) <= 1 ); - - if ( list == NULL) - { - gtk_text_buffer_insert_at_cursor (se->buffer, "WEIGHT OFF.", -1); - } - else - { - struct variable *var = list->data; - - gchar *text = g_strdup_printf ("WEIGHT BY %s.", - var_get_name (var)); - - gtk_text_buffer_insert_at_cursor (se->buffer, - text, -1); - - g_free (text); - } - } - break; - default: - break; - } -} - diff --git a/src/ui/gui/data-editor.glade b/src/ui/gui/data-editor.glade index 11ba2eb9..6ce94bb2 100644 --- a/src/ui/gui/data-editor.glade +++ b/src/ui/gui/data-editor.glade @@ -74,7 +74,6 @@ True - True gtk-save True True @@ -83,7 +82,6 @@ True - True gtk-save-as True True @@ -295,7 +293,7 @@ - + True False Transpose @@ -351,7 +349,6 @@ True - True Weight Cases True @@ -422,7 +419,6 @@ True - True Open gtk-open @@ -433,7 +429,6 @@ True - True Save gtk-save @@ -595,7 +590,6 @@ True - True Weight Cases True pspp-weight-cases diff --git a/src/ui/gui/data-editor.h b/src/ui/gui/data-editor.h index 67302fa9..7100e34e 100644 --- a/src/ui/gui/data-editor.h +++ b/src/ui/gui/data-editor.h @@ -35,6 +35,7 @@ struct data_editor GtkAction *action_data_save; GtkAction *invoke_weight_cases_dialog; + GtkAction *invoke_transpose_dialog; GladeXML *xml; diff --git a/src/ui/gui/dict-display.c b/src/ui/gui/dict-display.c new file mode 100644 index 00000000..68b7b8d4 --- /dev/null +++ b/src/ui/gui/dict-display.c @@ -0,0 +1,243 @@ +/* + PSPPIRE --- A Graphical User Interface for PSPP + Copyright (C) 2007 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. */ + + +#include +#include +#include + +#include "dict-display.h" + +#include "psppire-dict.h" +#include "helper.h" +#include + +#define _(msgid) gettext (msgid) +#define N_(msgid) msgid + + +/* A GtkTreeModelFilterVisibleFunc to filter lines in the treeview */ +static gboolean +filter_variables (GtkTreeModel *model, GtkTreeIter *iter, gpointer data) +{ + var_predicate_func *predicate = data; + struct variable *var; + PsppireDict *dict = PSPPIRE_DICT (model); + + GtkTreePath *path = gtk_tree_model_get_path (model, iter); + + gint *idx = gtk_tree_path_get_indices (path); + + var = psppire_dict_get_variable (dict, *idx); + + gtk_tree_path_free (path); + + return predicate (var); +} + +/* Sets up TREEVIEW to display the variables of DICT. + MODE is the selection mode for TREEVIEW. + PREDICATE determines which variables should be visible, or NULL if + all are to be visible. + */ +void +attach_dictionary_to_treeview (GtkTreeView *treeview, PsppireDict *dict, + GtkSelectionMode mode, + var_predicate_func *predicate + ) +{ + GtkTreeViewColumn *col; + + GtkTreeSelection *selection = + gtk_tree_view_get_selection (treeview); + + GtkCellRenderer *renderer = gtk_cell_renderer_text_new (); + GtkTreeModel *model ; + + if ( predicate ) + { + model = gtk_tree_model_filter_new (GTK_TREE_MODEL (dict), + NULL); + + gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (model), + filter_variables, + predicate, + NULL); + } + else + { + model = GTK_TREE_MODEL (dict); + } + + gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), model); + + + + col = gtk_tree_view_column_new_with_attributes (_("Var"), + renderer, + "text", + 0, + NULL); + + /* 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 (treeview, col); + + gtk_tree_selection_set_mode (selection, mode); +} + + +void +insert_source_row_into_entry (GtkTreeIter iter, + GtkWidget *dest, + GtkTreeModel *model + ) +{ + GtkTreePath *path; + PsppireDict *dict; + gint *idx; + struct variable *var; + GtkTreeIter dict_iter; + gchar *name; + + g_return_if_fail (GTK_IS_ENTRY(dest)); + + + if ( GTK_IS_TREE_MODEL_FILTER (model)) + { + dict = PSPPIRE_DICT (gtk_tree_model_filter_get_model + (GTK_TREE_MODEL_FILTER(model))); + gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER + (model), + &dict_iter, &iter); + } + else + { + dict = PSPPIRE_DICT (model); + dict_iter = iter; + } + + + path = gtk_tree_model_get_path (GTK_TREE_MODEL (dict), &dict_iter); + + idx = gtk_tree_path_get_indices (path); + + var = psppire_dict_get_variable (dict, *idx); + + gtk_tree_path_free (path); + + name = pspp_locale_to_utf8 (var_get_name (var), -1, NULL); + gtk_entry_set_text (GTK_ENTRY (dest), name); + g_free (name); +} + + + +void +insert_source_row_into_tree_view (GtkTreeIter iter, + GtkWidget *dest, + GtkTreeModel *model + ) +{ + GtkTreePath *path; + GtkTreeIter dest_iter; + GtkTreeIter dict_iter; + gint *row ; + GtkTreeModel *destmodel = gtk_tree_view_get_model ( GTK_TREE_VIEW (dest)); + + PsppireDict *dict; + + if ( GTK_IS_TREE_MODEL_FILTER (model)) + { + dict = PSPPIRE_DICT (gtk_tree_model_filter_get_model + (GTK_TREE_MODEL_FILTER(model))); + gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER + (model), + &dict_iter, &iter); + } + else + { + dict = PSPPIRE_DICT (model); + dict_iter = iter; + } + + + path = gtk_tree_model_get_path (GTK_TREE_MODEL (dict), &dict_iter); + + row = gtk_tree_path_get_indices (path); + + gtk_list_store_append (GTK_LIST_STORE (destmodel), &dest_iter); + gtk_list_store_set (GTK_LIST_STORE (destmodel), &dest_iter, 0, *row, -1); + + gtk_tree_path_free (path); +} + + +gboolean +is_currently_in_entry (GtkTreeModel *model, GtkTreeIter *iter, + PsppireSelector *selector) +{ + gboolean result; + gchar *name; + GtkTreeIter dict_iter; + PsppireDict *dict; + struct variable *var; + gint dict_index; + gint *indeces; + GtkTreePath *path; + const gchar *text = gtk_entry_get_text (GTK_ENTRY (selector->dest)); + + + if ( GTK_IS_TREE_MODEL_FILTER (model)) + { + dict = PSPPIRE_DICT (gtk_tree_model_filter_get_model + (GTK_TREE_MODEL_FILTER(model))); + gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER + (model), + &dict_iter, iter); + } + else + { + dict = PSPPIRE_DICT (model); + dict_iter = *iter; + } + + + path = gtk_tree_model_get_path (GTK_TREE_MODEL(dict), + &dict_iter); + + indeces = gtk_tree_path_get_indices (path); + + dict_index = indeces [0]; + + var = psppire_dict_get_variable (dict, dict_index); + + gtk_tree_path_free (path); + + name = pspp_locale_to_utf8 (var_get_name (var), -1, NULL); + result = ( 0 == strcmp (text, name)); + g_free (name); + + return result; +} + + diff --git a/src/ui/gui/dict-display.h b/src/ui/gui/dict-display.h new file mode 100644 index 00000000..71479ba5 --- /dev/null +++ b/src/ui/gui/dict-display.h @@ -0,0 +1,59 @@ +/* + PSPPIRE --- A Graphical User Interface for PSPP + Copyright (C) 2007 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 provides various functions necessary for displaying a + dictionary in GTK widgets. +*/ + +#include + +#include "psppire-selector.h" +#include "psppire-dict.h" +#include + +/* Sets up TREEVIEW to display the variables of DICT. + MODE is the selection mode for TREEVIEW. + PREDICATE determines which variables should be visible, or NULL if + all are to be visible. + */ +void attach_dictionary_to_treeview (GtkTreeView *treeview, PsppireDict *dict, + GtkSelectionMode mode, + var_predicate_func *predicate + ); + + +/* A SelectItemsFunc function for GtkTreeView widgets */ +void insert_source_row_into_tree_view (GtkTreeIter source_iter, + GtkWidget *dest, + GtkTreeModel *source_model + ); + + +/* A SelectItemsFunc function for GtkEntry widgets */ +void insert_source_row_into_entry (GtkTreeIter source_iter, + GtkWidget *dest, + GtkTreeModel *source_model + ); + + + +/* A FilterItemsFunc function for GtkEntry widgets */ +gboolean is_currently_in_entry (GtkTreeModel *model, GtkTreeIter *iter, + PsppireSelector *selector); diff --git a/src/ui/gui/glade-register.c b/src/ui/gui/glade-register.c index b4b3a5b9..3c288238 100644 --- a/src/ui/gui/glade-register.c +++ b/src/ui/gui/glade-register.c @@ -1,6 +1,7 @@ #include #include "psppire-dialog.h" #include "psppire-buttonbox.h" +#include "psppire-selector.h" GLADE_MODULE_CHECK_INIT @@ -28,6 +29,10 @@ glade_module_register_widgets (void) glade_register_widget (PSPPIRE_BUTTONBOX_TYPE, NULL, glade_standard_build_children, NULL); + + glade_register_widget (PSPPIRE_SELECTOR_TYPE, NULL, + glade_standard_build_children, + NULL); } diff --git a/src/ui/gui/helper.c b/src/ui/gui/helper.c index e14ab06a..bd6e2198 100644 --- a/src/ui/gui/helper.c +++ b/src/ui/gui/helper.c @@ -90,8 +90,9 @@ get_widget_assert (GladeXML *xml, const gchar *name) return w; } -/* Converts a string in the pspp locale to utf-8 */ -char * +/* Converts a string in the pspp locale to utf-8. + The return value must be freed when no longer required*/ +gchar * pspp_locale_to_utf8 (const gchar *text, gssize len, GError **err) { return recode_string (CONV_PSPP_TO_UTF8, text, len); diff --git a/src/ui/gui/psppire-case-file.c b/src/ui/gui/psppire-case-file.c index fda12160..ec50b152 100644 --- a/src/ui/gui/psppire-case-file.c +++ b/src/ui/gui/psppire-case-file.c @@ -21,7 +21,6 @@ #include #include -#include "psppire-object.h" #include "psppire-case-file.h" #include @@ -75,7 +74,7 @@ psppire_case_file_get_type (void) (GInstanceInitFunc) psppire_case_file_init, }; - object_type = g_type_register_static (G_TYPE_PSPPIRE_OBJECT, "PsppireCaseFile", + object_type = g_type_register_static (G_TYPE_OBJECT, "PsppireCaseFile", &object_info, 0); } diff --git a/src/ui/gui/psppire-dict.c b/src/ui/gui/psppire-dict.c index b4503125..42025f2d 100644 --- a/src/ui/gui/psppire-dict.c +++ b/src/ui/gui/psppire-dict.c @@ -1,21 +1,21 @@ /* - PSPPIRE --- A Graphical User Interface for PSPP - Copyright (C) 2004, 2006, 2007 Free Software Foundation + PSPPIRE --- A Graphical User Interface for PSPP + Copyright (C) 2004, 2006, 2007 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 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. + 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. */ + 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. */ #include #include @@ -24,7 +24,6 @@ #include #include -#include "psppire-object.h" #include "psppire-dict.h" #include #include @@ -32,6 +31,7 @@ #include #include +#include "helper.h" #include "message-dialog.h" /* --- prototypes --- */ @@ -86,12 +86,12 @@ psppire_dict_get_type (void) NULL }; - object_type = g_type_register_static (G_TYPE_PSPPIRE_OBJECT, + object_type = g_type_register_static (G_TYPE_OBJECT, "PsppireDict", &object_info, 0); g_type_add_interface_static (object_type, GTK_TYPE_TREE_MODEL, - &tree_model_info); + &tree_model_info); } @@ -302,14 +302,14 @@ auto_generate_var_name (PsppireDict *dict) /* Insert a new variable at posn IDX, with the name NAME. If NAME is null, then a name will be automatically assigned. - */ +*/ void psppire_dict_insert_variable (PsppireDict *d, gint idx, const gchar *name) { struct variable *var ; g_return_if_fail (idx >= 0); g_return_if_fail (d); - g_return_if_fail (G_IS_PSPPIRE_DICT (d)); + g_return_if_fail (PSPPIRE_IS_DICT (d)); if ( ! name ) name = auto_generate_var_name (d); @@ -326,7 +326,7 @@ psppire_dict_delete_variables (PsppireDict *d, gint first, gint n) gint idx; g_return_if_fail (d); g_return_if_fail (d->dict); - g_return_if_fail (G_IS_PSPPIRE_DICT (d)); + g_return_if_fail (PSPPIRE_IS_DICT (d)); for (idx = 0 ; idx < n ; ++idx ) { @@ -348,7 +348,7 @@ psppire_dict_set_name (PsppireDict* d, gint idx, const gchar *name) { struct variable *var; g_assert (d); - g_assert (G_IS_PSPPIRE_DICT (d)); + g_assert (PSPPIRE_IS_DICT (d)); if ( idx < dict_get_var_cnt (d->dict)) @@ -422,10 +422,10 @@ psppire_dict_clear (PsppireDict *d) */ gboolean psppire_dict_check_name (const PsppireDict *dict, - const gchar *name, gboolean report) + const gchar *name, gboolean report) { if ( ! var_is_valid_name (name, report ) ) - return FALSE; + return FALSE; if (psppire_dict_lookup_var (dict, name)) { @@ -461,8 +461,8 @@ psppire_dict_resize_variable (PsppireDict *d, const struct variable *pv, fv = var_get_case_index (pv); g_signal_emit (d, signals [VARIABLE_RESIZED], 0, - fv + old_size, - new_size - old_size ); + fv + old_size, + new_size - old_size ); } @@ -488,6 +488,19 @@ static void tree_model_get_value (GtkTreeModel *model, GtkTreeIter *iter, static gboolean tree_model_nth_child (GtkTreeModel *model, GtkTreeIter *iter, GtkTreeIter *parent, gint n); +static gint tree_model_n_children (GtkTreeModel *tree_model, + GtkTreeIter *iter); + +static gboolean tree_model_iter_children (GtkTreeModel *, + GtkTreeIter *, + GtkTreeIter *); + +static gboolean tree_model_iter_parent (GtkTreeModel *tree_model, + GtkTreeIter *iter, + GtkTreeIter *child); + +static gboolean tree_model_iter_has_child (GtkTreeModel *tree_model, + GtkTreeIter *iter); static void dictionary_tree_model_init (GtkTreeModelIface *iface) @@ -500,17 +513,32 @@ dictionary_tree_model_init (GtkTreeModelIface *iface) iface->get_path = tree_model_get_path; iface->get_value = tree_model_get_value; - iface->iter_children = 0; - iface->iter_has_child =0; - iface->iter_n_children =0; + iface->iter_children = tree_model_iter_children ; + iface->iter_has_child = tree_model_iter_has_child ; + iface->iter_n_children = tree_model_n_children ; iface->iter_nth_child = tree_model_nth_child ; - iface->iter_parent =0; + iface->iter_parent = tree_model_iter_parent ; +} + +static gboolean +tree_model_iter_has_child (GtkTreeModel *tree_model, + GtkTreeIter *iter) +{ + return FALSE; +} + +static gboolean +tree_model_iter_parent (GtkTreeModel *tree_model, + GtkTreeIter *iter, + GtkTreeIter *child) +{ + return TRUE; } static GtkTreeModelFlags tree_model_get_flags (GtkTreeModel *model) { - g_return_val_if_fail (G_IS_PSPPIRE_DICT (model), (GtkTreeModelFlags) 0); + g_return_val_if_fail (PSPPIRE_IS_DICT (model), (GtkTreeModelFlags) 0); return GTK_TREE_MODEL_LIST_ONLY; } @@ -525,7 +553,7 @@ tree_model_n_columns (GtkTreeModel *model) static GType tree_model_column_type (GtkTreeModel *model, gint index) { - g_return_val_if_fail (G_IS_PSPPIRE_DICT (model), (GType) 0); + g_return_val_if_fail (PSPPIRE_IS_DICT (model), (GType) 0); switch (index) { @@ -549,7 +577,7 @@ tree_model_get_iter (GtkTreeModel *model, GtkTreeIter *iter, GtkTreePath *path) { gint *indices, depth; gint n; - struct variable *variable; + struct variable *var; PsppireDict *dict = PSPPIRE_DICT (model); @@ -560,17 +588,21 @@ tree_model_get_iter (GtkTreeModel *model, GtkTreeIter *iter, GtkTreePath *path) g_return_val_if_fail (depth == 1, FALSE); - n = indices[0]; + n = indices [0]; if ( n < 0 || n >= psppire_dict_get_var_cnt (dict)) - return FALSE; + { + iter->stamp = 0; + iter->user_data = NULL; + return FALSE; + } - variable = dict_get_var (dict->dict, n); + var = psppire_dict_get_variable (dict, n); - g_assert (var_get_dict_index (variable) == n); + g_assert (var_get_dict_index (var) == n); iter->stamp = dict->stamp; - iter->user_data = variable; + iter->user_data = var; return TRUE; } @@ -580,7 +612,7 @@ static gboolean tree_model_iter_next (GtkTreeModel *model, GtkTreeIter *iter) { PsppireDict *dict = PSPPIRE_DICT (model); - struct variable *variable; + struct variable *var; gint idx; g_return_val_if_fail (iter->stamp == dict->stamp, FALSE); @@ -588,18 +620,22 @@ tree_model_iter_next (GtkTreeModel *model, GtkTreeIter *iter) if ( iter == NULL || iter->user_data == NULL) return FALSE; - variable = (struct variable *) iter->user_data; + var = iter->user_data; - idx = var_get_dict_index (variable); + idx = var_get_dict_index (var); if ( idx + 1 >= psppire_dict_get_var_cnt (dict)) - return FALSE; + { + iter->user_data = NULL; + iter->stamp = 0; + return FALSE; + } - variable = psppire_dict_get_variable (dict, idx + 1); + var = psppire_dict_get_variable (dict, idx + 1); - g_assert (var_get_dict_index (variable) == idx + 1); + g_assert (var_get_dict_index (var) == idx + 1); - iter->user_data = variable; + iter->user_data = var; return TRUE; } @@ -608,15 +644,15 @@ static GtkTreePath * tree_model_get_path (GtkTreeModel *model, GtkTreeIter *iter) { GtkTreePath *path; - struct variable *variable; + struct variable *var; PsppireDict *dict = PSPPIRE_DICT (model); g_return_val_if_fail (iter->stamp == dict->stamp, FALSE); - variable = (struct variable *) iter->user_data; + var = iter->user_data; path = gtk_tree_path_new (); - gtk_tree_path_append_index (path, var_get_dict_index (variable)); + gtk_tree_path_append_index (path, var_get_dict_index (var)); return path; } @@ -624,24 +660,28 @@ tree_model_get_path (GtkTreeModel *model, GtkTreeIter *iter) static void tree_model_get_value (GtkTreeModel *model, GtkTreeIter *iter, - gint column, GValue *value) + gint column, GValue *value) { - struct variable *variable; + struct variable *var; PsppireDict *dict = PSPPIRE_DICT (model); g_return_if_fail (iter->stamp == dict->stamp); - variable = (struct variable *) iter->user_data; + var = iter->user_data; switch (column) { case DICT_TVM_COL_NAME: + { + gchar *name = pspp_locale_to_utf8(var_get_name (var), -1, NULL); g_value_init (value, G_TYPE_STRING); - g_value_set_string (value, var_get_name (variable)); + g_value_set_string (value, name); + g_free (name); + } break; case DICT_TVM_COL_VAR: g_value_init (value, G_TYPE_POINTER); - g_value_set_pointer (value, variable); + g_value_set_pointer (value, var); break; default: g_return_if_reached (); @@ -649,13 +689,33 @@ tree_model_get_value (GtkTreeModel *model, GtkTreeIter *iter, } } +static gboolean +tree_model_iter_children (GtkTreeModel *tree_model, + GtkTreeIter *iter, + GtkTreeIter *parent) +{ + return FALSE; +} + +static gint +tree_model_n_children (GtkTreeModel *model, + GtkTreeIter *iter) +{ + PsppireDict *dict = PSPPIRE_DICT (model); + + if ( iter == NULL ) + return psppire_dict_get_var_cnt (dict); + + return 0; +} static gboolean tree_model_nth_child (GtkTreeModel *model, GtkTreeIter *iter, - GtkTreeIter *parent, gint n) + GtkTreeIter *parent, gint n) { PsppireDict *dict; - g_return_val_if_fail (G_IS_PSPPIRE_DICT (model), FALSE); + + g_return_val_if_fail (PSPPIRE_IS_DICT (model), FALSE); dict = PSPPIRE_DICT (model); @@ -671,7 +731,6 @@ tree_model_nth_child (GtkTreeModel *model, GtkTreeIter *iter, if ( !iter->user_data) return FALSE; - return TRUE; } diff --git a/src/ui/gui/psppire-dict.h b/src/ui/gui/psppire-dict.h index 42a13c63..f070bfeb 100644 --- a/src/ui/gui/psppire-dict.h +++ b/src/ui/gui/psppire-dict.h @@ -36,8 +36,8 @@ G_BEGIN_DECLS #define G_TYPE_PSPPIRE_DICT (psppire_dict_get_type ()) #define PSPPIRE_DICT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), G_TYPE_PSPPIRE_DICT, PsppireDict)) #define PSPPIRE_DICT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), G_TYPE_PSPPIRE_DICT, PsppireDictClass)) -#define G_IS_PSPPIRE_DICT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), G_TYPE_PSPPIRE_DICT)) -#define G_IS_PSPPIRE_DICT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_PSPPIRE_DICT)) +#define PSPPIRE_IS_DICT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), G_TYPE_PSPPIRE_DICT)) +#define PSPPIRE_IS_DICT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_PSPPIRE_DICT)) #define PSPPIRE_DICT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_PSPPIRE_DICT, PsppireDictClass)) diff --git a/src/ui/gui/psppire-object.c b/src/ui/gui/psppire-object.c deleted file mode 100644 index 8674f61b..00000000 --- a/src/ui/gui/psppire-object.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - PSPPIRE --- A Graphical User Interface for PSPP - Copyright (C) 2004 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. */ - - -#include -#include - -#include "psppire-object.h" - - -/* --- prototypes --- */ -static void psppire_object_class_init (PsppireObjectClass *class); -static void psppire_object_init (PsppireObject *accel_group); -static void psppire_object_finalize (GObject *object); - - -/* --- variables --- */ -static GObjectClass *parent_class = NULL; - - -/* --- functions --- */ -/** - * psppire_object_get_type: - * @returns: the type ID for accelerator groups. - */ -GType -psppire_object_get_type (void) -{ - static GType object_type = 0; - - if (!object_type) - { - static const GTypeInfo object_info = { - sizeof (PsppireObjectClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) psppire_object_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (PsppireObject), - 0, /* n_preallocs */ - (GInstanceInitFunc) psppire_object_init, - }; - - object_type = g_type_register_static (G_TYPE_OBJECT, "PsppireObject", - &object_info, G_TYPE_FLAG_ABSTRACT); - } - - return object_type; -} - -static guint signal_changed = 0 ; - -static void -psppire_object_class_init (PsppireObjectClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - parent_class = g_type_class_peek_parent (class); - - object_class->finalize = psppire_object_finalize; - - signal_changed = - g_signal_new ("changed", - G_OBJECT_CLASS_TYPE (class), - G_SIGNAL_RUN_FIRST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - -} - -static void -psppire_object_finalize (GObject *object) -{ - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -psppire_object_init (PsppireObject *psppire_object) -{ - -} - -/** - * psppire_object_new: - * @returns: a new #PsppireObject object - * - * Creates a new #PsppireObject. - */ -PsppireObject* -psppire_object_new (void) -{ - return g_object_new (G_TYPE_PSPPIRE_OBJECT, NULL); -} diff --git a/src/ui/gui/psppire-object.h b/src/ui/gui/psppire-object.h deleted file mode 100644 index 240efb33..00000000 --- a/src/ui/gui/psppire-object.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - PSPPIRE --- A Graphical User Interface for PSPP - Copyright (C) 2004 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. */ - - -#ifndef __PSPPIRE_OBJECT_H__ -#define __PSPPIRE_OBJECT_H__ - -#include -#include - -G_BEGIN_DECLS - - -/* --- type macros --- */ -#define G_TYPE_PSPPIRE_OBJECT (psppire_object_get_type ()) -#define PSPPIRE_OBJECT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), G_TYPE_PSPPIRE_OBJECT, PsppireObject)) -#define PSPPIRE_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), G_TYPE_PSPPIRE_OBJECT, PsppireObjectClass)) -#define G_IS_PSPPIRE_OBJECT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), G_TYPE_PSPPIRE_OBJECT)) -#define G_IS_PSPPIRE_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_PSPPIRE_OBJECT)) -#define PSPPIRE_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_PSPPIRE_OBJECT, PsppireObjectClass)) - - - -/* --- typedefs & structures --- */ -typedef struct _PsppireObject PsppireObject; -typedef struct _PsppireObjectClass PsppireObjectClass; - - -struct _PsppireObject -{ - GObject parent; -}; - -struct _PsppireObjectClass -{ - GObjectClass parent_class; - -}; - - -/* -- PsppireObject --- */ -GType psppire_object_get_type (void); -PsppireObject* psppire_object_new (void); - -G_END_DECLS - -#endif /* __PSPPIRE_OBJECT_H__ */ diff --git a/src/ui/gui/psppire-selector.c b/src/ui/gui/psppire-selector.c new file mode 100644 index 00000000..753a9dc8 --- /dev/null +++ b/src/ui/gui/psppire-selector.c @@ -0,0 +1,598 @@ +/* + PSPPIRE --- A Graphical User Interface for PSPP + Copyright (C) 2007 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 provides a widget, PsppireSelector derived from + GtkButton. + + It contains a GtkArrow, and is used for selecting objects from a + GtkTreeView and putting them into a destination widget (often + another GtkTreeView). Typically this is used in psppire for + selecting variables, thus: + + + +----------------------------------------------------------+ + | | + | Source Widget Dest Widget | + | +----------------+ +----------------+ | + | | Variable0 | | Variable2 | | + | | Variable1 | | | | + | | Variable3 | | | | + | | | Selector | | | + | | | | | | + | | | +------+ | | | + | | | | |\ | | | | + | | | | | \ | | | | + | | | | | / | | | | + | | | | |/ | | | | + | | | +------+ | | | + | | | | | | + | | | | | | + | | | | | | + | | | | | | + | +----------------+ +----------------+ | + | | + +----------------------------------------------------------+ + + The Source Widget is always a GtkTreeView. The Dest Widget may be a + GtkTreeView or a GtkEntry (other destination widgets may be + supported in the future). + + Widgets may be source to more than one PsppireSelector. +*/ + + +#include + +#include +#include + +#include "psppire-selector.h" + +#include +#include +#include + +static void psppire_selector_base_finalize (PsppireSelectorClass *, gpointer); +static void psppire_selector_base_init (PsppireSelectorClass *class); +static void psppire_selector_class_init (PsppireSelectorClass *class); +static void psppire_selector_init (PsppireSelector *selector); + +enum {SELECTED, /* Emitted when an item is inserted into dest */ + DE_SELECTED, /* Emitted when an item is removed from dest */ + n_SIGNALS}; + +static guint signals [n_SIGNALS]; + + +GType +psppire_selector_get_type (void) +{ + static GType psppire_selector_type = 0; + + if (!psppire_selector_type) + { + static const GTypeInfo psppire_selector_info = + { + sizeof (PsppireSelectorClass), + (GBaseInitFunc) psppire_selector_base_init, + (GBaseFinalizeFunc) psppire_selector_base_finalize, + (GClassInitFunc)psppire_selector_class_init, + (GClassFinalizeFunc) NULL, + NULL, + sizeof (PsppireSelector), + 0, + (GInstanceInitFunc) psppire_selector_init, + }; + + psppire_selector_type = + g_type_register_static (GTK_TYPE_BUTTON, "PsppireSelector", + &psppire_selector_info, 0); + } + + return psppire_selector_type; +} + + +static void +psppire_selector_finalize (GObject *object) +{ +} + + + +static void +psppire_selector_class_init (PsppireSelectorClass *class) +{ + signals [SELECTED] = + g_signal_new ("selected", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + + signals [DE_SELECTED] = + g_signal_new ("de-selected", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + + +} + + +static void +psppire_selector_base_init (PsppireSelectorClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->finalize = psppire_selector_finalize; + + class->source_hash = g_hash_table_new (g_direct_hash, g_direct_equal); +} + + + +static void +psppire_selector_base_finalize(PsppireSelectorClass *class, + gpointer class_data) +{ + g_hash_table_destroy (class->source_hash); +} + + +static void +psppire_selector_init (PsppireSelector *selector) +{ + selector->arrow = gtk_arrow_new (GTK_ARROW_LEFT, GTK_SHADOW_NONE); + selector->filtered_source = NULL; + + gtk_container_add (GTK_CONTAINER (selector), selector->arrow); + + gtk_widget_show (selector->arrow); + + /* FIXME: This shouldn't be necessary, but Glade interfaces seem to + need it. */ + gtk_widget_show (GTK_WIDGET (selector)); +} + + +GtkWidget* +psppire_selector_new (void) +{ + return GTK_WIDGET (g_object_new (psppire_selector_get_type (), NULL)); +} + + +static void +set_direction (PsppireSelector *selector, enum psppire_selector_dir d) +{ + selector->direction = d; + + /* FIXME: Need to reverse the arrow direction if an RTL locale is in + effect */ + if ( d == PSPPIRE_SELECTOR_SOURCE_TO_DEST ) + g_object_set (selector->arrow, "arrow-type", GTK_ARROW_RIGHT, NULL); + else + g_object_set (selector->arrow, "arrow-type", GTK_ARROW_LEFT, NULL); +} + +/* 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 ( GTK_IS_ENTRY (selector->dest) ) + { + gtk_widget_set_sensitive (GTK_WIDGET (selector), + 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) +{ + PsppireSelector *selector = data; + + set_direction (selector, PSPPIRE_SELECTOR_DEST_TO_SOURCE); +} + +/* Callback for source deselection, when the dest is GtkEntry */ +static void +de_select_selection_entry (PsppireSelector *selector) +{ + gtk_entry_set_text (GTK_ENTRY (selector->dest), ""); +} + +/* Callback for source deselection, when the dest is GtkTreeView */ +static void +de_select_selection_tree_view (PsppireSelector *selector) +{ + GList *item; + + GtkTreeSelection* selection = + gtk_tree_view_get_selection ( GTK_TREE_VIEW (selector->dest)); + + GtkTreeModel *model = + gtk_tree_view_get_model (GTK_TREE_VIEW (selector->dest)); + + GList *selected_rows = + gtk_tree_selection_get_selected_rows (selection, NULL); + + g_return_if_fail (selector->select_items); + + /* Convert paths to RowRefs */ + for (item = g_list_first (selected_rows); + item != NULL; + item = g_list_next (item)) + { + GtkTreeRowReference* rowref; + GtkTreePath *path = item->data; + + rowref = gtk_tree_row_reference_new (GTK_TREE_MODEL (model), path); + + item->data = rowref ; + gtk_tree_path_free (path); + } + + /* Remove each selected row from the dest widget */ + for (item = g_list_first (selected_rows); + item != NULL; + item = g_list_next (item)) + { + GtkTreeIter iter; + GtkTreeRowReference *rr = item->data; + + GtkTreePath *path = gtk_tree_row_reference_get_path (rr); + + gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path); + + gtk_list_store_remove (GTK_LIST_STORE (model), &iter); + + gtk_tree_path_free (path); + } + + /* Delete list of RowRefs and its contents */ + g_list_foreach (selected_rows, (GFunc) gtk_tree_row_reference_free, NULL); + g_list_free (selected_rows); +} + + +/* Removes something from the DEST widget */ +static void +de_select_selection (PsppireSelector *selector) +{ + if ( GTK_IS_TREE_VIEW (selector->dest ) ) + de_select_selection_tree_view (selector); + + else if ( GTK_IS_ENTRY (selector->dest)) + de_select_selection_entry (selector); + + else + g_assert_not_reached (); + + gtk_tree_model_filter_refilter (selector->filtered_source); + + g_signal_emit (selector, signals [DE_SELECTED], 0); +} + + +/* Puts something into the DEST widget */ +static void +select_selection (PsppireSelector *selector) +{ + GList *item ; + GtkTreeSelection* selection = + gtk_tree_view_get_selection ( GTK_TREE_VIEW (selector->source)); + + GList *selected_rows = + gtk_tree_selection_get_selected_rows (selection, NULL); + + GtkTreeModel *childmodel = gtk_tree_model_filter_get_model + (selector->filtered_source); + + g_return_if_fail (selector->select_items); + + + for (item = g_list_first (selected_rows); + item != NULL; + item = g_list_next (item)) + { + GtkTreeIter child_iter; + GtkTreeIter iter; + GtkTreePath *path = item->data; + + gtk_tree_model_get_iter (GTK_TREE_MODEL (selector->filtered_source), + &iter, path); + + gtk_tree_model_filter_convert_iter_to_child_iter + (selector->filtered_source, + &child_iter, + &iter); + + selector->select_items (child_iter, + selector->dest, + childmodel); + } + + g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL); + g_list_free (selected_rows); + + gtk_tree_model_filter_refilter (selector->filtered_source); + + g_signal_emit (selector, signals [SELECTED], 0); +} + +/* Callback fro then the source treeview is activated (double clicked) */ +static void +on_row_activate (GtkTreeView *tree_view, + GtkTreePath *path, + GtkTreeViewColumn *column, + gpointer data) +{ + PsppireSelector *selector = data; + + select_selection (selector); +} + +/* Callback for when the selector button is clicked */ +static void +on_click (PsppireSelector *selector, gpointer data) +{ + switch (selector->direction) + { + case PSPPIRE_SELECTOR_SOURCE_TO_DEST: + select_selection (selector); + break; + case PSPPIRE_SELECTOR_DEST_TO_SOURCE: + de_select_selection (selector); + break; + default: + g_assert_not_reached (); + break; + } +} + +/* Default visibility filter for GtkTreeView DEST widget */ +static gboolean +is_item_in_dest (GtkTreeModel *model, GtkTreeIter *iter, + PsppireSelector *selector) +{ + GtkTreeModel *dest_model; + GtkTreeIter dest_iter; + GtkTreeIter source_iter; + gint index; + GtkTreePath *path ; + GtkTreeModel *source_model; + + if ( GTK_IS_TREE_MODEL_FILTER (model) ) + { + source_model = gtk_tree_model_filter_get_model + (GTK_TREE_MODEL_FILTER (model)); + + gtk_tree_model_filter_convert_iter_to_child_iter + ( GTK_TREE_MODEL_FILTER (model), &source_iter, iter ); + } + else + { + source_model = model; + source_iter = *iter; + } + + dest_model = gtk_tree_view_get_model (GTK_TREE_VIEW (selector->dest)); + + path = gtk_tree_model_get_path (source_model, &source_iter); + + index = *gtk_tree_path_get_indices (path); + + gtk_tree_path_free (path); + + if ( ! gtk_tree_model_get_iter_first (dest_model, &dest_iter) ) + return FALSE; + + do + { + GValue value = {0}; + gtk_tree_model_get_value (dest_model, &dest_iter, 0, &value); + + if ( g_value_get_int (&value) == index) + return TRUE; + } + while (gtk_tree_model_iter_next (dest_model, &dest_iter)); + + return FALSE; +} + +/* Visibility function for items in the SOURCE widget. + Returns TRUE iff *all* the selectors for which SOURCE is associated + are visible */ +static gboolean +is_source_item_visible (GtkTreeModel *childmodel, + GtkTreeIter *iter, gpointer data) +{ + PsppireSelector *selector = data; + PsppireSelectorClass *class = g_type_class_peek (PSPPIRE_SELECTOR_TYPE); + + GList *list = NULL; + + list = g_hash_table_lookup (class->source_hash, selector->source); + + while (list) + { + PsppireSelector *selector = list->data; + + if ( selector->filter (childmodel, iter, selector)) + return FALSE; + + list = list->next; + } + + + return TRUE; +} + +/* set the source widget to SOURCE */ +static void +set_tree_view_source (PsppireSelector *selector, + GtkTreeView *source) +{ + GtkTreeSelection* selection ; + GList *list = NULL; + + PsppireSelectorClass *class = g_type_class_peek (PSPPIRE_SELECTOR_TYPE); + + 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_view_set_model (source, + GTK_TREE_MODEL (selector->filtered_source)); + + list = g_list_append (list, selector); + g_hash_table_insert (class->source_hash, source, list); + + + gtk_tree_model_filter_set_visible_func (selector->filtered_source, + is_source_item_visible, + selector, + NULL); + } + else + { /* 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)); + + 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); +} + + +/* Set the destination widget to DEST */ +static void +set_tree_view_dest (PsppireSelector *selector, + GtkTreeView *dest) +{ + GtkTreeSelection* selection = gtk_tree_view_get_selection (dest); + + gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE); + + g_signal_connect (selection, "changed", G_CALLBACK (on_dest_treeview_select), + selector); +} + +/* Callback for when the DEST GtkEntry is activated (Enter is pressed) */ +static void +on_entry_activate (GtkEntry *w, gpointer data) +{ + PsppireSelector * selector = data; + + gtk_tree_model_filter_refilter (selector->filtered_source); +} + +/* Callback for when the DEST GtkEntry is selected (clicked) */ +static gboolean +on_entry_dest_select (GtkWidget *widget, GdkEventFocus *event, gpointer data) +{ + PsppireSelector * selector = data; + + set_direction (selector, PSPPIRE_SELECTOR_DEST_TO_SOURCE); + + return FALSE; +} + +/* Set DEST to be the destination GtkEntry widget */ +static void +set_entry_dest (PsppireSelector *selector, + GtkEntry *dest) +{ + g_signal_connect (dest, "activate", G_CALLBACK (on_entry_activate), + selector); + + g_signal_connect (dest, "focus-in-event", G_CALLBACK (on_entry_dest_select), + selector); +} + + +/* 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 ) +{ + selector->filter = filter_func ; + + selector->source = source; + selector->dest = dest; + + if ( filter_func == NULL) + { + if (GTK_IS_TREE_VIEW (dest)) + selector->filter = is_item_in_dest; + } + + g_signal_connect (selector, "clicked", G_CALLBACK (on_click), NULL); + + 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_assert ( GTK_IS_TREE_MODEL_FILTER (selector->filtered_source)); + + if ( GTK_IS_TREE_VIEW (dest)) + set_tree_view_dest (selector, GTK_TREE_VIEW (dest)); + + else if ( GTK_IS_ENTRY (dest)) + set_entry_dest (selector, GTK_ENTRY (dest)); + + else + g_error ("Unsupported destination widget: %s", G_OBJECT_TYPE_NAME (dest)); + + selector->select_items = select_func; +} diff --git a/src/ui/gui/psppire-selector.h b/src/ui/gui/psppire-selector.h new file mode 100644 index 00000000..7ba88a96 --- /dev/null +++ b/src/ui/gui/psppire-selector.h @@ -0,0 +1,107 @@ +/* + PSPPIRE --- A Graphical User Interface for PSPP + Copyright (C) 2007 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. +*/ + + +#ifndef __PSPPIRE_SELECTOR_H__ +#define __PSPPIRE_SELECTOR_H__ + + +#include +#include +#include +#include +#include +#include + +G_BEGIN_DECLS + +#define PSPPIRE_SELECTOR_TYPE (psppire_selector_get_type ()) +#define PSPPIRE_SELECTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PSPPIRE_SELECTOR_TYPE, PsppireSelector)) +#define PSPPIRE_SELECTOR_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \ + PSPPIRE_SELECTOR_TYPE, PsppireSelectorClass)) +#define PSPPIRE_IS_SELECTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + PSPPIRE_SELECTOR_TYPE)) +#define PSPPIRE_IS_SELECTOR_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \ + PSPPIRE_SELECTOR_TYPE)) + + +typedef struct _PsppireSelector PsppireSelector; +typedef struct _PsppireSelectorClass PsppireSelectorClass; + + +/* Function for appending selected items to the destination widget */ +typedef void SelectItemsFunc (GtkTreeIter iter, + GtkWidget *dest, + GtkTreeModel *source_model); + + +/* Function to determine whether an item in MODEL, pointed to by ITER + is currently selected. + + Returns TRUE if the item is currently selected, FALSE otherwise. + */ +typedef gboolean FilterItemsFunc (GtkTreeModel *model, + GtkTreeIter *iter, + PsppireSelector *selector); + +enum psppire_selector_dir + { + PSPPIRE_SELECTOR_SOURCE_TO_DEST, + PSPPIRE_SELECTOR_DEST_TO_SOURCE + }; + + +struct _PsppireSelector +{ + GtkButton parent; + + /* */ + GtkWidget *arrow; + + enum psppire_selector_dir direction; + GtkWidget *source; + GtkWidget *dest; + + + GtkTreeModelFilter *filtered_source; + + SelectItemsFunc *select_items; + FilterItemsFunc *filter; +}; + +struct _PsppireSelectorClass +{ + GtkButtonClass parent_class; + + /* This is a hash of Lists of FilterItemsFunc pointers, keyed by address of + the source widget */ + GHashTable *source_hash; +}; + +GType psppire_selector_get_type (void); +GtkWidget* psppire_selector_new (void); +void psppire_selector_set_subjects (PsppireSelector *, + GtkWidget *, + GtkWidget *, + SelectItemsFunc *, + FilterItemsFunc * ); +G_END_DECLS + +#endif /* __PSPPIRE_SELECTOR_H__ */ diff --git a/src/ui/gui/psppire-var-select.c b/src/ui/gui/psppire-var-select.c deleted file mode 100644 index b4c32b63..00000000 --- a/src/ui/gui/psppire-var-select.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - PSPPIRE --- A Graphical User Interface for PSPP - Copyright (C) 2007 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. */ - -#include - -#include "psppire-var-select.h" -#include "psppire-object.h" - -#include "psppire-dict.h" - -#include - -#define _(msgid) gettext (msgid) -#define N_(msgid) msgid - - -/* This object is an attempt to abstract a situation commonly found in PSPP - dialogs, where two widgets (typically GtkTreeViews) contain a list - of variables, and the variables may be selected by the user and - transfered to between the widgets, in preparation for some - operation. - - Currently it assumes that the first widget is GtkTreeView and the - second is a GtkEntry (as required for the Weight Cases dialog). - It needs to be generalized further to make it useful. -*/ - -static void setup_dictionary_treeview (GtkTreeView *, - const PsppireDict *, - GtkSelectionMode); - - -/* --- prototypes --- */ -static void psppire_var_select_class_init (PsppireVarSelectClass *); -static void psppire_var_select_init (PsppireVarSelect *); -static void psppire_var_select_finalize (GObject *); - - -enum {VARIABLE_SELECTED, - DESELECT_ALL, - n_SIGNALS}; - -static guint signals [n_SIGNALS]; - - -/* --- variables --- */ -static GObjectClass *parent_class = NULL; - -/* --- functions --- */ -/** - * psppire_var_select_get_type: - * @returns: the type ID for accelerator groups. - */ -GType -psppire_var_select_get_type (void) -{ - static GType object_type = 0; - - if (!object_type) - { - static const GTypeInfo object_info = { - sizeof (PsppireVarSelectClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) psppire_var_select_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (PsppireVarSelect), - 0, /* n_preallocs */ - (GInstanceInitFunc) psppire_var_select_init, - }; - - object_type = g_type_register_static (G_TYPE_PSPPIRE_OBJECT, - "PsppireVarSelect", - &object_info, 0); - } - - return object_type; -} - - -static void -psppire_var_select_class_init (PsppireVarSelectClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - parent_class = g_type_class_peek_parent (class); - - - signals [VARIABLE_SELECTED] = - g_signal_new ("variable_selected", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_FIRST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, - 1, - G_TYPE_INT); - - - signals [DESELECT_ALL] = - g_signal_new ("deselect_all", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_FIRST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0); - - object_class->finalize = psppire_var_select_finalize; -} - -static void -psppire_var_select_finalize (GObject *object) -{ - PsppireVarSelect *vs = PSPPIRE_VAR_SELECT (object); - - g_list_free (vs->list); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -psppire_var_select_init (PsppireVarSelect *vs) -{ - vs->list = NULL; - vs->mode = GTK_SELECTION_SINGLE; -} - -/* Return list of all the currently selected variables */ -const GList * -psppire_var_select_get_variables (PsppireVarSelect *vs) -{ - return vs->list; -} - - -static void -add_variable_to_selection (PsppireVarSelect *vs, struct variable *var) -{ - gtk_entry_set_text (GTK_ENTRY (vs->dest), var_get_name (var) ); - - if ( vs->mode == GTK_SELECTION_SINGLE) - { - g_list_free (vs->list); - vs->list = NULL; - } - vs->list = g_list_append (vs->list, var); - - g_signal_emit (vs, signals [VARIABLE_SELECTED], 0, var_get_dict_index (var)); -} - - -/* Add VAR to the list of selected variables */ -void -psppire_var_select_set_variable (PsppireVarSelect *vs, - struct variable *var) -{ - add_variable_to_selection (vs, var); -} - - -static void -on_source_activate (GtkTreeView *tree_view, - GtkTreePath *path, - GtkTreeViewColumn *column, - gpointer user_data) - -{ - PsppireVarSelect *vs = user_data; - GtkTreeModel *model = gtk_tree_view_get_model (tree_view); - - GtkTreeSelection *selection = gtk_tree_view_get_selection (tree_view); - - GList *list = gtk_tree_selection_get_selected_rows (selection, &model); - - while (list) - { - struct variable *var; - GtkTreeIter iter; - GtkTreePath *path = list->data; - - gtk_tree_model_get_iter (model, &iter, path); - - gtk_tree_model_get (model, &iter, DICT_TVM_COL_VAR, &var, -1); - - add_variable_to_selection (vs, var); - - list = list->next; - } -} - - -/** - * psppire_var_select_new: - * @returns: a new #PsppireVarSelect object - * - * Creates a new #PsppireVarSelect. - */ -PsppireVarSelect* -psppire_var_select_new (GtkWidget *source, GtkWidget *dest, - const PsppireDict *dict) -{ - PsppireVarSelect *vs - = g_object_new (G_TYPE_PSPPIRE_VAR_SELECT, NULL); - - GtkTreeSelection *src_selection; - - vs->source = source; - vs->dest = dest; - vs->dict = dict; - - - setup_dictionary_treeview ( GTK_TREE_VIEW (source), - vs->dict, vs->mode); - - - src_selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (vs->source)); - - g_signal_connect (source, "row-activated", - G_CALLBACK (on_source_activate), vs); - - return vs; -} - -void -psppire_var_select_deselect_all (PsppireVarSelect *vs) -{ - g_list_free (vs->list); - vs->list = NULL; - - gtk_entry_set_text ( GTK_ENTRY(vs->dest), ""); - - g_signal_emit (vs, signals [DESELECT_ALL], 0); -} - - -static void -setup_dictionary_treeview (GtkTreeView *treeview, const PsppireDict *dict, - GtkSelectionMode mode) -{ - /* Set up the dictionary treeview */ - GtkTreeViewColumn *col; - - GtkTreeSelection *selection = - gtk_tree_view_get_selection (treeview); - - GtkCellRenderer *renderer = gtk_cell_renderer_text_new (); - - - gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (dict)); - - col = gtk_tree_view_column_new_with_attributes (_("Var"), - renderer, - "text", - 0, - NULL); - - /* 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 (treeview, col); - - gtk_tree_selection_set_mode (selection, mode); -} - - - - diff --git a/src/ui/gui/psppire-var-select.h b/src/ui/gui/psppire-var-select.h deleted file mode 100644 index b169b52b..00000000 --- a/src/ui/gui/psppire-var-select.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - PSPPIRE --- A Graphical User Interface for PSPP - Copyright (C) 2007 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. */ - - -#ifndef __PSPPIRE_VAR_SELECT_H__ -#define __PSPPIRE_VAR_SELECT_H__ - - -#include -#include - -#include -#include "psppire-dict.h" - -G_BEGIN_DECLS - - -/* --- type macros --- */ -#define G_TYPE_PSPPIRE_VAR_SELECT (psppire_var_select_get_type ()) -#define PSPPIRE_VAR_SELECT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), G_TYPE_PSPPIRE_VAR_SELECT, PsppireVarSelect)) -#define PSPPIRE_VAR_SELECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), G_TYPE_PSPPIRE_VAR_SELECT, PsppireVarSelectClass)) -#define G_IS_PSPPIRE_VAR_SELECT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), G_TYPE_PSPPIRE_VAR_SELECT)) -#define G_IS_PSPPIRE_VAR_SELECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_PSPPIRE_VAR_SELECT)) -#define PSPPIRE_VAR_SELECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_PSPPIRE_VAR_SELECT, PsppireVarSelectClass)) - - - -/* --- typedefs & structures --- */ -typedef struct _PsppireVarSelect PsppireVarSelect; -typedef struct _PsppireVarSelectClass PsppireVarSelectClass; - -struct _PsppireVarSelect -{ - GObject parent; - const PsppireDict *dict; - - - /* */ - GtkSelectionMode mode; - GtkWidget *source; - GtkWidget *dest; - GList *list; -}; - -struct _PsppireVarSelectClass -{ - GObjectClass parent_class; -}; - - -/* -- PsppireVarSelect --- */ -GType psppire_var_select_get_type (void); - - -PsppireVarSelect* psppire_var_select_new (GtkWidget *, - GtkWidget *, - const PsppireDict *); - -/* Remove all variables from the selection */ -void psppire_var_select_deselect_all (PsppireVarSelect *); - -/* Return a list of all the currently selected variables */ -const GList *psppire_var_select_get_variables (PsppireVarSelect *); - -/* Append VAR to the list of selected variables */ -void psppire_var_select_set_variable (PsppireVarSelect *, - struct variable *var); - -G_END_DECLS - -#endif /* __PSPPIRE_VAR_SELECT_H__ */ diff --git a/src/ui/gui/psppire.glade b/src/ui/gui/psppire.glade index 80a4dfc2..0a4e6dfa 100644 --- a/src/ui/gui/psppire.glade +++ b/src/ui/gui/psppire.glade @@ -62,7 +62,7 @@ GTK_POLICY_AUTOMATIC GTK_SHADOW_ETCHED_IN - + True False True @@ -84,7 +84,8 @@ True 5 - + True Do not weight cases False @@ -95,10 +96,11 @@ True + False Weight cases by False True - radiobutton1 + weight-cases-radiobutton1 1 @@ -108,32 +110,9 @@ True - - True - - - True - 0 - GTK_SHADOW_NONE - - - 40 - 40 - True - - - True - - - - - - + + 5 - - False - False - @@ -145,7 +124,7 @@ - + True @@ -222,4 +201,173 @@ + + 5 + Transpose + 407 + 225 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK + 2 + + + True + + + True + 0 + GTK_SHADOW_IN + + + True + GTK_POLICY_NEVER + GTK_POLICY_AUTOMATIC + + + True + False + + + + + + + + label_item + + + + + + + True + 2 + 2 + 5 + 5 + + + True + + + True + 0 + Name Variable: + + + False + False + + + + + True + + + False + False + 1 + + + + + 1 + 2 + 1 + 2 + + + + + + True + + + True + 0 + Variable(s): + + + False + False + + + + + True + 0 + GTK_SHADOW_IN + + + True + GTK_POLICY_NEVER + GTK_POLICY_AUTOMATIC + + + True + False + + + + + + + + label_item + + + + + 1 + + + + + 1 + 2 + + + + + 5 + + + 1 + 2 + + GTK_FILL + + + + + 5 + + + + + + + + + 1 + + + + + + + 5 + + + False + False + GTK_PACK_END + 1 + + + + + diff --git a/src/ui/gui/transpose-dialog.c b/src/ui/gui/transpose-dialog.c new file mode 100644 index 00000000..4691fff7 --- /dev/null +++ b/src/ui/gui/transpose-dialog.c @@ -0,0 +1,238 @@ +/* + PSPPIRE --- A Graphical User Interface for PSPP + Copyright (C) 2007 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. */ + +#include + +#include "transpose-dialog.h" +#include "psppire-selector.h" +#include "psppire-dialog.h" +#include "helper.h" +#include "data-editor.h" +#include "dict-display.h" +#include +#include "syntax-editor.h" + +#include +#include + +#include + +#define _(msgid) gettext (msgid) +#define N_(msgid) msgid + + +/* FIXME: These shouldn't be here */ +#include +#include "psppire-var-store.h" + + + +static struct variable * +get_selected_variable (GtkTreeModel *treemodel, + GtkTreeIter *iter, + PsppireDict *dict) +{ + struct variable *var; + GValue value = {0}; + + GtkTreePath *path = gtk_tree_model_get_path (treemodel, iter); + + gtk_tree_model_get_value (treemodel, iter, 0, &value); + + gtk_tree_path_free (path); + + var = psppire_dict_get_variable (dict, g_value_get_int (&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. +*/ +static void +cell_var_name (GtkTreeViewColumn *tree_column, + GtkCellRenderer *cell, + GtkTreeModel *tree_model, + GtkTreeIter *iter, + gpointer data) +{ + PsppireDict *dict = data; + struct variable *var; + gchar *name; + + var = get_selected_variable (tree_model, iter, dict); + + name = pspp_locale_to_utf8 (var_get_name (var), -1, NULL); + g_object_set (cell, "text", name, NULL); + g_free (name); +} + +static gchar * generate_syntax (PsppireDict *dict, GladeXML *xml); + +void +transpose_dialog (GObject *o, gpointer data) +{ + gint response ; + struct data_editor *de = data; + + GladeXML *xml = glade_xml_new (PKGDATADIR "/psppire.glade", + "transpose-dialog", NULL); + + GtkSheet *var_sheet = + GTK_SHEET (get_widget_assert (de->xml, "variable_sheet")); + + PsppireVarStore *vs = PSPPIRE_VAR_STORE (gtk_sheet_get_model (var_sheet)); + + 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"); + + attach_dictionary_to_treeview (GTK_TREE_VIEW (source), + vs->dict, + GTK_SELECTION_MULTIPLE, NULL); + { + 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, + vs->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); + } + + + psppire_selector_set_subjects (PSPPIRE_SELECTOR (selector1), + source, dest, + insert_source_row_into_tree_view, + NULL); + + + psppire_selector_set_subjects (PSPPIRE_SELECTOR (selector2), + source, new_name_entry, + insert_source_row_into_entry, + is_currently_in_entry); + + + response = psppire_dialog_run (PSPPIRE_DIALOG (dialog)); + + switch (response) + { + case GTK_RESPONSE_OK: + { + gchar *syntax = generate_syntax (vs->dict, xml); + struct getl_interface *sss = create_syntax_string_source (syntax); + execute_syntax (sss); + + g_free (syntax); + } + break; + case PSPPIRE_RESPONSE_PASTE: + { + gchar *syntax = generate_syntax (vs->dict, xml); + + 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); +} + + + /* + FLIP /VARIABLES=var_list /NEWNAMES=var_name. + */ +static gchar * +generate_syntax (PsppireDict *dict, GladeXML *xml) +{ + GtkTreeIter iter; + const gchar *text; + GString *string = g_string_new ("FLIP"); + gchar *syntax ; + + GtkWidget *dest = get_widget_assert (xml, "variables-treeview"); + GtkWidget *entry = get_widget_assert (xml, "new-name-entry"); + + GtkTreeModel *list_store = gtk_tree_view_get_model (GTK_TREE_VIEW (dest)); + + if ( gtk_tree_model_get_iter_first (list_store, &iter) ) + { + g_string_append (string, " /VARIABLES ="); + do + { + GValue value = {0}; + struct variable *var; + GtkTreePath *path = gtk_tree_model_get_path (list_store, &iter); + + gtk_tree_model_get_value (list_store, &iter, 0, &value); + + var = psppire_dict_get_variable (dict, g_value_get_int (&value)); + g_value_unset (&value); + + g_string_append (string, " "); + g_string_append (string, var_get_name (var)); + + gtk_tree_path_free (path); + } + while (gtk_tree_model_iter_next (list_store, &iter)); + } + + text = gtk_entry_get_text (GTK_ENTRY (entry)); + + if ( text) + g_string_append_printf (string, " /NEWNAME = %s", text); + + g_string_append (string, "."); + + syntax = string->str; + + g_string_free (string, FALSE); + + return syntax; +} diff --git a/src/ui/gui/transpose-dialog.h b/src/ui/gui/transpose-dialog.h new file mode 100644 index 00000000..70266df4 --- /dev/null +++ b/src/ui/gui/transpose-dialog.h @@ -0,0 +1,30 @@ +/* + PSPPIRE --- A Graphical User Interface for PSPP + Copyright (C) 2007 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. */ + + +#ifndef TRANSPOSE_DIALOG_H +#define TRANSPOSE_DIALOG_H + +#include +#include + +void transpose_dialog (GObject *o, gpointer data); + + +#endif diff --git a/src/ui/gui/weight-cases-dialog.c b/src/ui/gui/weight-cases-dialog.c index 50294de7..3eb1808d 100644 --- a/src/ui/gui/weight-cases-dialog.c +++ b/src/ui/gui/weight-cases-dialog.c @@ -17,111 +17,157 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - #include -#include "psppire-var-select.h" -#include -#include "helper.h" -#include - -#include "psppire-var-store.h" #include "weight-cases-dialog.h" - +#include "psppire-selector.h" #include "psppire-dialog.h" +#include "helper.h" +#include "data-editor.h" +#include "dict-display.h" +#include +#include "syntax-editor.h" + +#include +#include -#define _(msgid) gettext (msgid) -#define N_(msgid) msgid +/* FIXME: These shouldn't be here */ +#include +#include "psppire-var-store.h" static void -refresh_var_select (PsppireVarSelect *vs) +on_select (PsppireSelector *sel, gpointer data) { - struct variable *weight; - - psppire_var_select_deselect_all (vs); - - weight = psppire_dict_get_weight_variable (vs->dict); + GtkRadioButton *radiobutton2 = data; - if ( weight ) - psppire_var_select_set_variable (vs, weight); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radiobutton2), TRUE); } - static void -on_refresh (GtkWidget *dialog, gpointer data) +on_deselect (PsppireSelector *sel, gpointer data) { - refresh_var_select (data); + GtkRadioButton *radiobutton1 = data; + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radiobutton1), TRUE); } static void -on_radiobutton_toggle (GtkToggleButton *button, gpointer data) +on_toggle (GtkToggleButton *button, gpointer data) { - PsppireVarSelect *vs = data; - if ( gtk_toggle_button_get_active (button) ) - { - psppire_var_select_deselect_all (vs); - } + GtkEntry *entry = data; + if ( gtk_toggle_button_get_active (button)) + gtk_entry_set_text (entry, ""); } -/* Callback for when new variable is selected. - IDX is the dict index of the variable selected. - Updates the label and toggle buttons in the dialog box - to reflect this new selection. */ -static void -select_var_callback (PsppireVarSelect *vs, gint idx, gpointer data) -{ - GladeXML * xml = data; - GtkWidget *label = get_widget_assert (xml, "weight-status-label"); - GtkWidget *radiobutton2 = get_widget_assert (xml, "radiobutton2"); +static gchar * generate_syntax (PsppireDict *, GtkEntry *); - struct variable *var = psppire_dict_get_variable (vs->dict, idx); - gtk_label_set_text (GTK_LABEL (label), var_get_name(var)); +/* Pops up the Weight Cases dialog box */ +void +weight_cases_dialog (GObject *o, gpointer data) +{ + gint response; + struct data_editor *de = data; + PsppireDict *dict; + struct variable *var; - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radiobutton2), TRUE); -} + GladeXML *xml = glade_xml_new (PKGDATADIR "/psppire.glade", + "weight-cases-dialog", NULL); + GtkWidget *dialog = get_widget_assert (xml, "weight-cases-dialog"); + GtkWidget *source = get_widget_assert (xml, "weight-cases-treeview"); + GtkWidget *entry = get_widget_assert (xml, "weight-cases-entry"); + GtkWidget *selector = get_widget_assert (xml, "weight-cases-selector"); + GtkWidget *radiobutton1 = get_widget_assert (xml, + "weight-cases-radiobutton1"); + GtkWidget *radiobutton2 = get_widget_assert (xml, "radiobutton2"); + GtkSheet *var_sheet = + GTK_SHEET (get_widget_assert (de->xml, "variable_sheet")); -static void -deselect_all (PsppireVarSelect *vs, gpointer data) -{ - GladeXML * xml = data; + PsppireVarStore *vs = PSPPIRE_VAR_STORE (gtk_sheet_get_model (var_sheet)); - GtkWidget *label = get_widget_assert (xml, "weight-status-label"); + dict = vs->dict; - GtkWidget *radiobutton1 = get_widget_assert (xml, "radiobutton1"); + g_signal_connect (radiobutton1, "toggled", G_CALLBACK (on_toggle), entry); + g_signal_connect (selector, "selected", G_CALLBACK (on_select), + radiobutton2); - gtk_label_set_text (GTK_LABEL (label), _("Do not weight cases")); + g_signal_connect (selector, "de-selected", G_CALLBACK (on_deselect), + radiobutton1); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radiobutton1), TRUE); -} + attach_dictionary_to_treeview (GTK_TREE_VIEW (source), + dict, + GTK_SELECTION_SINGLE, + var_is_numeric + ); + psppire_selector_set_subjects (PSPPIRE_SELECTOR (selector), + source, + entry, + insert_source_row_into_entry, + 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)); -PsppireDialog * -create_weight_dialog (PsppireVarSelect *select, GladeXML *xml) -{ - GtkWidget *dialog = get_widget_assert (xml, "weight-cases-dialog"); - GtkWidget *radiobutton1 = get_widget_assert (xml, "radiobutton1"); + g_signal_emit_by_name (entry, "activate"); + + response = psppire_dialog_run (PSPPIRE_DIALOG (dialog)); + + g_object_unref (xml); + + switch (response) + { + case GTK_RESPONSE_OK: + { + gchar *syntax = generate_syntax (dict, GTK_ENTRY (entry)); + struct getl_interface *sss = create_syntax_string_source (syntax); + execute_syntax (sss); + + g_free (syntax); + } + break; + case PSPPIRE_RESPONSE_PASTE: + { + gchar *syntax = generate_syntax (dict, GTK_ENTRY (entry)); + + 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_signal_connect (dialog, "refresh", G_CALLBACK (on_refresh), select); - g_signal_connect (select, "variable-selected", - G_CALLBACK (select_var_callback), xml); +static gchar * +generate_syntax (PsppireDict *dict, GtkEntry *entry) +{ + gchar *syntax; - g_signal_connect (select, "deselect-all", - G_CALLBACK (deselect_all), xml); + const gchar *text = gtk_entry_get_text (entry); - g_signal_connect (radiobutton1, "toggled", - G_CALLBACK (on_radiobutton_toggle), - select); + struct variable *var = psppire_dict_lookup_var (dict, text); - refresh_var_select (select); + if ( var == NULL) + syntax = g_strdup ("WEIGHT OFF."); + else + syntax = g_strdup_printf ("WEIGHT BY %s.\n", + var_get_name (var)); - return PSPPIRE_DIALOG (dialog); + return syntax; } diff --git a/src/ui/gui/weight-cases-dialog.h b/src/ui/gui/weight-cases-dialog.h index b193fef4..88a7af73 100644 --- a/src/ui/gui/weight-cases-dialog.h +++ b/src/ui/gui/weight-cases-dialog.h @@ -21,8 +21,11 @@ #ifndef WEIGHT_CASES_DIALOG_H #define WEIGHT_CASES_DIALOG_H -#include "psppire-dialog.h" +#include +#include + +/* Pops up the Weight Cases dialog box */ +void weight_cases_dialog (GObject *o, gpointer data); -PsppireDialog * create_weight_dialog (PsppireVarSelect *, GladeXML *); #endif -- 2.30.2