Weight cases dialog: Convert from add hoc to PsppireDialogAction
[pspp] / src / ui / gui / psppire-dialog-action-weight.c
1 /* PSPPIRE - a graphical user interface for PSPP.
2    Copyright (C) 2015  Free Software Foundation
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
16
17
18 #include <config.h>
19
20 #include "psppire-dialog-action-weight.h"
21 #include "psppire-selector.h"
22 #include "psppire-var-view.h"
23 #include "dict-display.h"
24
25 #include "psppire-dialog.h"
26 #include "builder-wrapper.h"
27
28 #include <gettext.h>
29 #define _(msgid) gettext (msgid)
30 #define N_(msgid) msgid
31
32 static void psppire_dialog_action_weight_init            (PsppireDialogActionWeight      *act);
33 static void psppire_dialog_action_weight_class_init      (PsppireDialogActionWeightClass *class);
34
35 G_DEFINE_TYPE (PsppireDialogActionWeight, psppire_dialog_action_weight, PSPPIRE_TYPE_DIALOG_ACTION);
36
37
38 static char *
39 generate_syntax (PsppireDialogAction *pda)
40 {
41   gchar *syntax = NULL;
42   PsppireDialogActionWeight *wcd = PSPPIRE_DIALOG_ACTION_WEIGHT (pda);
43
44   const gchar *text  = gtk_entry_get_text (GTK_ENTRY (wcd->entry));
45
46   const struct variable *var = psppire_dict_lookup_var (pda->dict, text);
47
48   if ( var == NULL)
49     syntax = g_strdup ("WEIGHT OFF.\n");
50   else
51     syntax = g_strdup_printf ("WEIGHT BY %s.\n",
52                               var_get_name (var));
53
54   return syntax;
55 }
56
57
58 static gboolean
59 dialog_state_valid (gpointer data)
60 {
61   return TRUE;
62 }
63
64 static void
65 refresh (PsppireDialogAction *pda)
66 {
67   PsppireDialogActionWeight *wcd = PSPPIRE_DIALOG_ACTION_WEIGHT (pda);
68
69   const struct variable *var = dict_get_weight (pda->dict->dict);
70
71   if ( ! var )
72     {
73       gtk_entry_set_text (GTK_ENTRY (wcd->entry), "");
74       gtk_label_set_text (GTK_LABEL (wcd->status), _("Do not weight cases"));
75       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (wcd->off), TRUE);
76     }
77   else
78     {
79       gchar *text =
80         g_strdup_printf (_("Weight cases by %s"), var_get_name (var));
81
82       gtk_entry_set_text (GTK_ENTRY (wcd->entry), var_get_name (var));
83       gtk_label_set_text (GTK_LABEL (wcd->status), text);
84
85       g_free (text);
86       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (wcd->on), TRUE);
87     }
88
89   g_signal_emit_by_name (wcd->entry, "activate");
90 }
91
92 static void
93 on_select (PsppireSelector *sel, gpointer data)
94 {
95   PsppireDialogActionWeight *wcd = data;
96
97   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (wcd->on), TRUE);
98   gtk_widget_set_sensitive (GTK_WIDGET (wcd->on), TRUE);
99 }
100
101 static void
102 on_deselect (PsppireSelector *sel, gpointer data)
103 {
104   PsppireDialogActionWeight *wcd = data;
105
106   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (wcd->off), TRUE);
107   gtk_widget_set_sensitive (GTK_WIDGET (wcd->on), FALSE);
108 }
109
110 static void
111 on_toggle (GtkToggleButton *off, gpointer data)
112 {
113   PsppireDialogActionWeight *wcd = data;
114
115   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (wcd->off)))
116     {
117       gtk_entry_set_text (GTK_ENTRY (wcd->entry), "");
118     }
119 }
120
121
122 static void
123 psppire_dialog_action_weight_activate (PsppireDialogAction *pda)
124 {
125   PsppireDialogActionWeight *act = PSPPIRE_DIALOG_ACTION_WEIGHT (pda);
126
127   GHashTable *thing = psppire_dialog_action_get_hash_table (pda);
128   GtkBuilder *xml = g_hash_table_lookup (thing, pda);
129   if (!xml)
130     {
131       xml = builder_new ("weight.ui");
132       g_hash_table_insert (thing, pda, xml);
133
134       pda->dialog = get_widget_assert   (xml, "weight-cases-dialog");
135       pda->source = get_widget_assert   (xml, "weight-cases-treeview");
136
137       act->entry = get_widget_assert (xml, "weight-cases-entry");
138       act->off = get_widget_assert (xml,"weight-cases-radiobutton1");
139       act->on = get_widget_assert (xml, "radiobutton2");
140       act->status  = get_widget_assert (xml, "weight-status-label");
141       GtkWidget *selector = get_widget_assert (xml, "weight-cases-selector");
142
143       g_signal_connect (selector, "selected", G_CALLBACK (on_select), act);
144       g_signal_connect (selector, "de-selected", G_CALLBACK (on_deselect), act);
145       g_signal_connect (act->off, "toggled", G_CALLBACK (on_toggle), act);
146
147       g_object_set (pda->source,
148                     "selection-mode", GTK_SELECTION_SINGLE,
149                     "predicate", var_is_numeric,
150                     NULL);
151       
152       psppire_selector_set_filter_func (PSPPIRE_SELECTOR (selector),
153                                         is_currently_in_entry);
154     }
155   
156   psppire_dialog_action_set_valid_predicate (pda, dialog_state_valid);
157   psppire_dialog_action_set_refresh (pda, refresh);
158
159   if (PSPPIRE_DIALOG_ACTION_CLASS (psppire_dialog_action_weight_parent_class)->activate)
160     PSPPIRE_DIALOG_ACTION_CLASS (psppire_dialog_action_weight_parent_class)->activate (pda);
161 }
162
163 static void
164 psppire_dialog_action_weight_class_init (PsppireDialogActionWeightClass *class)
165 {
166   psppire_dialog_action_set_activation (class, psppire_dialog_action_weight_activate);
167   PSPPIRE_DIALOG_ACTION_CLASS (class)->generate_syntax = generate_syntax;
168 }
169
170
171 static void
172 psppire_dialog_action_weight_init (PsppireDialogActionWeight *act)
173 {
174 }
175