1 /* PSPPIRE - a graphical user interface for PSPP.
2 Copyright (C) 2007 Free Software Foundation
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.
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.
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/>. */
18 /* This file is a rubbish bin where stuff gets put when it doesn't seem to
23 #include <glib-object.h>
27 #include "message-dialog.h"
28 #include <data/data-in.h>
29 #include <data/data-out.h>
30 #include <data/dictionary.h>
31 #include <data/casereader-provider.h>
32 #include <libpspp/message.h>
34 #include <libpspp/i18n.h>
39 #include <data/settings.h>
41 #include <language/command.h>
42 #include <data/lazy-casereader.h>
43 #include <data/procedure.h>
44 #include <language/lexer/lexer.h>
45 #include "psppire-data-store.h"
46 #include <output/manager.h>
47 #include "output-viewer.h"
53 /* Formats a value according to FORMAT
54 The returned string must be freed when no longer required */
56 value_to_text (union value v, struct fmt_spec format)
60 s = g_new (gchar, format.w + 1);
61 data_out (&v, &format, s);
71 text_to_value (const gchar *text, union value *v,
72 struct fmt_spec format)
76 if ( format.type != FMT_A)
78 if ( ! text ) return FALSE;
81 const gchar *s = text;
89 if ( !*s) return FALSE;
94 ok = data_in (ss_cstr (text), LEGACY_NATIVE, format.type, 0, 0,
95 v, fmt_var_width (&format));
103 get_widget_assert (GladeXML *xml, const gchar *name)
109 w = glade_xml_get_widget (xml, name);
112 g_critical ("Widget \"%s\" could not be found\n", name);
117 /* Converts a string in the pspp locale to utf-8.
118 The return value must be freed when no longer required*/
120 pspp_locale_to_utf8 (const gchar *text, gssize len, GError **err)
122 return recode_string (CONV_PSPP_TO_UTF8, text, len);
125 #define _(msgid) gettext (msgid)
126 #define N_(msgid) msgid
132 static struct msg m = {
140 m.text=g_strdup (_("Sorry. The help system hasn't yet been implemented."));
146 connect_help (GladeXML *xml)
148 GList *helps = glade_xml_get_widget_prefix (xml, "help_button_");
151 for ( i = g_list_first (helps); i ; i = g_list_next (i))
152 g_signal_connect (GTK_WIDGET (i->data), "clicked", give_help, 0);
158 reference_manual (GtkMenuItem *menu, gpointer data)
161 if ( ! g_spawn_command_line_async ("yelp info:pspp", &err) )
163 msg (ME, _("Cannot open reference manual: %s"), err->message);
165 g_clear_error (&err);
169 extern struct dataset *the_dataset;
170 extern struct source_stream *the_source_stream;
171 extern PsppireDataStore *the_data_store;
173 /* Lazy casereader callback function used by execute_syntax. */
174 static struct casereader *
175 create_casereader_from_data_store (void *data_store_)
177 PsppireDataStore *data_store = data_store_;
178 return psppire_data_store_get_reader (data_store);
182 execute_syntax (struct getl_interface *sss)
185 gboolean retval = TRUE;
187 struct casereader *reader;
190 unsigned long int lazy_serial;
192 /* When the user executes a number of snippets of syntax in a
193 row, none of which read from the active file, the GUI becomes
194 progressively less responsive. The reason is that each syntax
195 execution encapsulates the active file data in another
196 datasheet layer. The cumulative effect of having a number of
197 layers of datasheets wastes time and space.
199 To solve the problem, we use a "lazy casereader", a wrapper
200 around the casereader obtained from the data store, that
201 only actually instantiates that casereader when it is
202 needed. If the data store casereader is never needed, then
203 it is reused the next time syntax is run, without wrapping
204 it in another layer. */
205 value_cnt = psppire_data_store_get_value_count (the_data_store);
206 case_cnt = psppire_data_store_get_case_count (the_data_store);
207 reader = lazy_casereader_create (value_cnt, case_cnt,
208 create_casereader_from_data_store,
209 the_data_store, &lazy_serial);
210 proc_set_active_file_data (the_dataset, reader);
212 g_return_val_if_fail (proc_has_active_file (the_dataset), FALSE);
214 lexer = lex_create (the_source_stream);
216 getl_append_source (the_source_stream, sss, GETL_BATCH, ERRMODE_CONTINUE);
220 enum cmd_result result = cmd_parse (lexer, the_dataset);
222 if ( cmd_result_is_failure (result))
225 if ( source_stream_current_error_mode (the_source_stream)
230 if ( result == CMD_EOF || result == CMD_FINISH)
234 getl_abort_noninteractive (the_source_stream);
238 psppire_dict_replace_dictionary (the_data_store->dict,
239 dataset_dict (the_dataset));
241 reader = proc_extract_active_file_data (the_dataset);
242 if (!lazy_casereader_destroy (reader, lazy_serial))
243 psppire_data_store_set_case_file (the_data_store,
244 psppire_case_file_new (reader));
248 reload_the_viewer ();
255 #ifdef G_ENABLE_DEBUG
256 # define g_marshal_value_peek_int(v) g_value_get_int (v)
258 # define g_marshal_value_peek_int(v) (v)->data[0].v_int
262 /* VOID:INT,INT,INT */
264 marshaller_VOID__INT_INT_INT (GClosure *closure,
265 GValue *return_value,
266 guint n_param_values,
267 const GValue *param_values,
268 gpointer invocation_hint,
269 gpointer marshal_data)
271 typedef void (*GMarshalFunc_VOID__INT_INT_INT) (gpointer data1,
276 register GMarshalFunc_VOID__INT_INT_INT callback;
277 register GCClosure *cc = (GCClosure*) closure;
278 register gpointer data1, data2;
280 g_return_if_fail (n_param_values == 4);
282 if (G_CCLOSURE_SWAP_DATA (closure))
284 data1 = closure->data;
285 data2 = g_value_peek_pointer (param_values + 0);
289 data1 = g_value_peek_pointer (param_values + 0);
290 data2 = closure->data;
292 callback = (GMarshalFunc_VOID__INT_INT_INT) (marshal_data ? marshal_data : cc->callback);
295 g_marshal_value_peek_int (param_values + 1),
296 g_marshal_value_peek_int (param_values + 2),
297 g_marshal_value_peek_int (param_values + 3),
301 /* Create a deep copy of SRC */
303 clone_list_store (const GtkListStore *src)
305 GtkTreeIter src_iter;
308 const gint n_cols = gtk_tree_model_get_n_columns (GTK_TREE_MODEL (src));
309 GType *types = g_malloc (sizeof (*types) * n_cols);
314 for (i = 0 ; i < n_cols; ++i )
315 types[i] = gtk_tree_model_get_column_type (GTK_TREE_MODEL (src), i);
317 dest = gtk_list_store_newv (n_cols, types);
319 for (ok = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (src),
322 ok = gtk_tree_model_iter_next (GTK_TREE_MODEL (src), &src_iter))
324 GtkTreeIter dest_iter;
325 gtk_list_store_append (dest, &dest_iter);
327 for (i = 0 ; i < n_cols; ++i )
331 gtk_tree_model_get_value (GTK_TREE_MODEL (src), &src_iter, i, &val);
332 gtk_list_store_set_value (dest, &dest_iter, i, &val);
334 g_value_unset (&val);