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/format.h>
29 #include <data/data-in.h>
30 #include <data/data-out.h>
31 #include <data/dictionary.h>
32 #include <data/casereader-provider.h>
33 #include <libpspp/message.h>
35 #include <libpspp/i18n.h>
40 #include <data/settings.h>
42 #include <language/command.h>
43 #include <data/lazy-casereader.h>
44 #include <data/procedure.h>
45 #include <language/lexer/lexer.h>
46 #include "psppire-data-store.h"
47 #include <output/manager.h>
48 #include "output-viewer.h"
54 /* Formats a value according to FORMAT
55 The returned string must be freed when no longer required */
57 value_to_text (union value v, struct fmt_spec format)
61 s = g_new (gchar, format.w + 1);
62 data_out (&v, &format, s);
72 text_to_value (const gchar *text, union value *v,
73 struct fmt_spec format)
77 if ( format.type != FMT_A)
79 if ( ! text ) return FALSE;
82 const gchar *s = text;
90 if ( !*s) return FALSE;
95 ok = data_in (ss_cstr (text), LEGACY_NATIVE, format.type, 0, 0, 0,
96 v, fmt_var_width (&format));
104 get_widget_assert (GladeXML *xml, const gchar *name)
110 w = glade_xml_get_widget (xml, name);
113 g_critical ("Widget \"%s\" could not be found\n", name);
118 /* Converts a string in the pspp locale to utf-8.
119 The return value must be freed when no longer required*/
121 pspp_locale_to_utf8 (const gchar *text, gssize len, GError **err)
123 return recode_string (CONV_PSPP_TO_UTF8, text, len);
126 #define _(msgid) gettext (msgid)
127 #define N_(msgid) msgid
135 dialog = gtk_message_dialog_new (NULL,
139 _("Sorry. The help system hasn't yet "
140 "been implemented."));
141 gtk_dialog_run (GTK_DIALOG (dialog));
142 gtk_widget_destroy (dialog);
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);
160 reference_manual (GtkMenuItem *menu, gpointer data)
163 if ( ! g_spawn_command_line_async ("yelp info:pspp", &err) )
165 msg (ME, _("Cannot open reference manual: %s"), err->message);
167 g_clear_error (&err);
171 extern struct dataset *the_dataset;
172 extern struct source_stream *the_source_stream;
173 extern PsppireDataStore *the_data_store;
175 /* Lazy casereader callback function used by execute_syntax. */
176 static struct casereader *
177 create_casereader_from_data_store (void *data_store_)
179 PsppireDataStore *data_store = data_store_;
180 return psppire_data_store_get_reader (data_store);
184 execute_syntax (struct getl_interface *sss)
187 gboolean retval = TRUE;
189 struct casereader *reader;
192 unsigned long int lazy_serial;
194 /* When the user executes a number of snippets of syntax in a
195 row, none of which read from the active file, the GUI becomes
196 progressively less responsive. The reason is that each syntax
197 execution encapsulates the active file data in another
198 datasheet layer. The cumulative effect of having a number of
199 layers of datasheets wastes time and space.
201 To solve the problem, we use a "lazy casereader", a wrapper
202 around the casereader obtained from the data store, that
203 only actually instantiates that casereader when it is
204 needed. If the data store casereader is never needed, then
205 it is reused the next time syntax is run, without wrapping
206 it in another layer. */
207 value_cnt = psppire_data_store_get_value_count (the_data_store);
208 case_cnt = psppire_data_store_get_case_count (the_data_store);
209 reader = lazy_casereader_create (value_cnt, case_cnt,
210 create_casereader_from_data_store,
211 the_data_store, &lazy_serial);
212 proc_set_active_file_data (the_dataset, reader);
214 g_return_val_if_fail (proc_has_active_file (the_dataset), FALSE);
216 lexer = lex_create (the_source_stream);
218 getl_append_source (the_source_stream, sss, GETL_BATCH, ERRMODE_CONTINUE);
222 enum cmd_result result = cmd_parse (lexer, the_dataset);
224 if ( cmd_result_is_failure (result))
227 if ( source_stream_current_error_mode (the_source_stream)
232 if ( result == CMD_EOF || result == CMD_FINISH)
236 getl_abort_noninteractive (the_source_stream);
240 psppire_dict_replace_dictionary (the_data_store->dict,
241 dataset_dict (the_dataset));
243 reader = proc_extract_active_file_data (the_dataset);
244 if (!lazy_casereader_destroy (reader, lazy_serial))
245 psppire_data_store_set_case_file (the_data_store,
246 psppire_case_file_new (reader));
250 reload_the_viewer ();
257 #ifdef G_ENABLE_DEBUG
258 # define g_marshal_value_peek_int(v) g_value_get_int (v)
260 # define g_marshal_value_peek_int(v) (v)->data[0].v_int
264 /* VOID:INT,INT,INT */
266 marshaller_VOID__INT_INT_INT (GClosure *closure,
267 GValue *return_value,
268 guint n_param_values,
269 const GValue *param_values,
270 gpointer invocation_hint,
271 gpointer marshal_data)
273 typedef void (*GMarshalFunc_VOID__INT_INT_INT) (gpointer data1,
278 register GMarshalFunc_VOID__INT_INT_INT callback;
279 register GCClosure *cc = (GCClosure*) closure;
280 register gpointer data1, data2;
282 g_return_if_fail (n_param_values == 4);
284 if (G_CCLOSURE_SWAP_DATA (closure))
286 data1 = closure->data;
287 data2 = g_value_peek_pointer (param_values + 0);
291 data1 = g_value_peek_pointer (param_values + 0);
292 data2 = closure->data;
294 callback = (GMarshalFunc_VOID__INT_INT_INT) (marshal_data ? marshal_data : cc->callback);
297 g_marshal_value_peek_int (param_values + 1),
298 g_marshal_value_peek_int (param_values + 2),
299 g_marshal_value_peek_int (param_values + 3),
303 /* Create a deep copy of SRC */
305 clone_list_store (const GtkListStore *src)
307 GtkTreeIter src_iter;
310 const gint n_cols = gtk_tree_model_get_n_columns (GTK_TREE_MODEL (src));
311 GType *types = g_malloc (sizeof (*types) * n_cols);
316 for (i = 0 ; i < n_cols; ++i )
317 types[i] = gtk_tree_model_get_column_type (GTK_TREE_MODEL (src), i);
319 dest = gtk_list_store_newv (n_cols, types);
321 for (ok = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (src),
324 ok = gtk_tree_model_iter_next (GTK_TREE_MODEL (src), &src_iter))
326 GtkTreeIter dest_iter;
327 gtk_list_store_append (dest, &dest_iter);
329 for (i = 0 ; i < n_cols; ++i )
333 gtk_tree_model_get_value (GTK_TREE_MODEL (src), &src_iter, i, &val);
334 gtk_list_store_set_value (dest, &dest_iter, i, &val);
336 g_value_unset (&val);