31580dd9f97e347f923447cd0f1d4db26e3340d7
[pspp] / src / ui / gui / psppire-dialog-action-var-info.c
1 /* PSPPIRE - a graphical user interface for PSPP.
2    Copyright (C) 2007, 2009, 2010, 2011, 2012, 2013, 2014  Free Software Foundation
3
4
5    This program is free software: you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation, either version 3 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
17
18
19 #include <config.h>
20
21 #include "ui/gui/psppire-dialog-action-var-info.h"
22
23 #include <gtk/gtk.h>
24
25 #include "data/format.h"
26 #include "data/value-labels.h"
27 #include "data/variable.h"
28 #include "libpspp/i18n.h"
29 #include "output/driver.h"
30 #include "ui/gui/builder-wrapper.h"
31 #include "ui/gui/executor.h"
32 #include "ui/gui/helper.h"
33 #include "ui/gui/psppire-data-window.h"
34 #include "ui/gui/psppire-dialog.h"
35 #include "ui/gui/psppire-dictview.h"
36 #include "ui/gui/psppire-output-view.h"
37 #include "ui/gui/var-display.h"
38
39 static void psppire_dialog_action_var_info_init            (PsppireDialogActionVarInfo      *act);
40 static void psppire_dialog_action_var_info_class_init      (PsppireDialogActionVarInfoClass *class);
41
42 G_DEFINE_TYPE (PsppireDialogActionVarInfo, psppire_dialog_action_var_info, PSPPIRE_TYPE_DIALOG_ACTION);
43
44 #include <gettext.h>
45 #define _(msgid) gettext (msgid)
46 #define N_(msgid) msgid
47
48 static gboolean
49 treeview_item_selected (gpointer data)
50 {
51   PsppireDialogAction *pda = data;
52   GtkTreeView *tv = GTK_TREE_VIEW (pda->source);
53   GtkTreeSelection *selection = gtk_tree_view_get_selection (tv);
54
55   return gtk_tree_selection_count_selected_rows (selection) == 1;
56 }
57
58 static gchar *
59 generate_syntax__ (PsppireDialogAction *act, const char *prefix)
60 {
61   struct variable **vars;
62   size_t n_vars;
63   size_t line_len;
64   GString *s;
65   char *str;
66   size_t i;
67
68   psppire_dict_view_get_selected_variables (PSPPIRE_DICT_VIEW (act->source),
69                                             &vars, &n_vars);
70
71   s = g_string_new (prefix);
72   line_len = 0;
73   for (i = 0; i < n_vars; i++)
74     {
75       const char *name = var_get_name (vars[i]);
76       size_t name_len = strlen (name);
77
78       if (line_len > 0)
79         {
80           if (line_len + 1 + name_len > 69)
81             {
82               g_string_append_c (s, '\n');
83               line_len = 0;
84             }
85           else
86             {
87               g_string_append_c (s, ' ');
88               line_len++;
89             }
90         }
91
92       g_string_append (s, name);
93       line_len += name_len;
94     }
95
96   g_free (vars);
97
98   str = s->str;
99   g_string_free (s, FALSE);
100   return str;
101 }
102
103 static gchar *
104 generate_syntax (PsppireDialogAction *act)
105 {
106   return generate_syntax__ (act, "");
107 }
108 \f
109 static void
110 populate_output (GtkTreeSelection *selection, gpointer data)
111 {
112   PsppireDialogActionVarInfo *act = data;
113   GtkTreeView *treeview = gtk_tree_selection_get_tree_view (selection);
114   PsppireDict *dict;
115   size_t n_vars;
116
117   struct variable **vars;
118
119   g_object_get (treeview, "model", &dict,
120                 NULL);
121
122   psppire_dict_view_get_selected_variables (PSPPIRE_DICT_VIEW (treeview),
123                                             &vars, &n_vars);
124
125   if (n_vars > 0)
126     {
127       PsppireDataWindow *dw;
128
129       g_object_get (act, "top-level", &dw, NULL);
130
131       psppire_output_view_clear (act->output);
132
133       output_engine_push ();
134       psppire_output_view_register_driver (act->output);
135       g_free (execute_syntax_string (
136                 dw, generate_syntax__ (&act->parent,
137                                        "DISPLAY DICTIONARY /VARIABLES=")));
138       output_engine_pop ();
139     }
140 }
141
142
143 static void
144 jump_to (PsppireDialog *d, gint response, gpointer data)
145 {
146   PsppireDataWindow *dw;
147   PsppireDialogAction *pda = PSPPIRE_DIALOG_ACTION (data);
148   struct variable **vars;
149   size_t n_vars;
150
151   if (response !=  PSPPIRE_RESPONSE_GOTO)
152     return;
153
154   psppire_dict_view_get_selected_variables (PSPPIRE_DICT_VIEW (pda->source),
155                                             &vars, &n_vars);
156   if (n_vars > 0)
157     {
158       g_object_get (pda, "top-level", &dw, NULL);
159
160       psppire_data_editor_goto_variable (dw->data_editor,
161                                          var_get_dict_index (vars[0]));
162     }
163   g_free (vars);
164 }
165
166 static void
167 psppire_dialog_action_var_info_activate (GtkAction *a)
168 {
169   PsppireDialogAction *pda = PSPPIRE_DIALOG_ACTION (a);
170   PsppireDialogActionVarInfo *act = PSPPIRE_DIALOG_ACTION_VAR_INFO (pda);
171
172   GHashTable *thing = psppire_dialog_action_get_hash_table (pda);
173   GtkBuilder *xml = g_hash_table_lookup (thing, a);
174   if (!xml)
175     {
176       xml = builder_new ("variable-info.ui");
177       g_hash_table_insert (thing, a, xml);
178     }
179
180   act->output = psppire_output_view_new (
181     GTK_LAYOUT (get_widget_assert (xml, "layout1")), NULL, NULL, NULL);
182
183   pda->dialog = get_widget_assert (xml, "variable-info-dialog");
184   pda->source = get_widget_assert (xml, "treeview2");
185
186   g_object_set (pda->source,
187                 "selection-mode", GTK_SELECTION_MULTIPLE,
188                 NULL);
189
190   g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (pda->source)),
191                     "changed", G_CALLBACK (populate_output),
192                     act);
193
194   g_signal_connect (pda->dialog, "response", G_CALLBACK (jump_to),
195                     pda);
196
197   psppire_dialog_action_set_valid_predicate (pda,
198                                              treeview_item_selected);
199
200   if (PSPPIRE_DIALOG_ACTION_CLASS (psppire_dialog_action_var_info_parent_class)->activate)
201     PSPPIRE_DIALOG_ACTION_CLASS (psppire_dialog_action_var_info_parent_class)->activate (pda);
202 }
203
204 static void
205 psppire_dialog_action_var_info_class_init (PsppireDialogActionVarInfoClass *class)
206 {
207   psppire_dialog_action_set_activation (class, psppire_dialog_action_var_info_activate);
208   PSPPIRE_DIALOG_ACTION_CLASS (class)->generate_syntax = generate_syntax;
209 }
210
211
212 static void
213 psppire_dialog_action_var_info_init (PsppireDialogActionVarInfo *act)
214 {
215 }