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
134 dialog = gtk_message_dialog_new (NULL,
138 _("Sorry. The help system hasn't yet "
139 "been implemented."));
140 gtk_dialog_run (GTK_DIALOG (dialog));
141 gtk_widget_destroy (dialog);
145 connect_help (GladeXML *xml)
147 GList *helps = glade_xml_get_widget_prefix (xml, "help_button_");
150 for ( i = g_list_first (helps); i ; i = g_list_next (i))
151 g_signal_connect (GTK_WIDGET (i->data), "clicked", give_help, 0);
157 reference_manual (GtkMenuItem *menu, gpointer data)
160 if ( ! g_spawn_command_line_async ("yelp info:pspp", &err) )
162 msg (ME, _("Cannot open reference manual: %s"), err->message);
164 g_clear_error (&err);
168 extern struct dataset *the_dataset;
169 extern struct source_stream *the_source_stream;
170 extern PsppireDataStore *the_data_store;
172 /* Lazy casereader callback function used by execute_syntax. */
173 static struct casereader *
174 create_casereader_from_data_store (void *data_store_)
176 PsppireDataStore *data_store = data_store_;
177 return psppire_data_store_get_reader (data_store);
181 execute_syntax (struct getl_interface *sss)
184 gboolean retval = TRUE;
186 struct casereader *reader;
189 unsigned long int lazy_serial;
191 /* When the user executes a number of snippets of syntax in a
192 row, none of which read from the active file, the GUI becomes
193 progressively less responsive. The reason is that each syntax
194 execution encapsulates the active file data in another
195 datasheet layer. The cumulative effect of having a number of
196 layers of datasheets wastes time and space.
198 To solve the problem, we use a "lazy casereader", a wrapper
199 around the casereader obtained from the data store, that
200 only actually instantiates that casereader when it is
201 needed. If the data store casereader is never needed, then
202 it is reused the next time syntax is run, without wrapping
203 it in another layer. */
204 value_cnt = psppire_data_store_get_value_count (the_data_store);
205 case_cnt = psppire_data_store_get_case_count (the_data_store);
206 reader = lazy_casereader_create (value_cnt, case_cnt,
207 create_casereader_from_data_store,
208 the_data_store, &lazy_serial);
209 proc_set_active_file_data (the_dataset, reader);
211 g_return_val_if_fail (proc_has_active_file (the_dataset), FALSE);
213 lexer = lex_create (the_source_stream);
215 getl_append_source (the_source_stream, sss, GETL_BATCH, ERRMODE_CONTINUE);
219 enum cmd_result result = cmd_parse (lexer, the_dataset);
221 if ( cmd_result_is_failure (result))
224 if ( source_stream_current_error_mode (the_source_stream)
229 if ( result == CMD_EOF || result == CMD_FINISH)
233 getl_abort_noninteractive (the_source_stream);
237 psppire_dict_replace_dictionary (the_data_store->dict,
238 dataset_dict (the_dataset));
240 reader = proc_extract_active_file_data (the_dataset);
241 if (!lazy_casereader_destroy (reader, lazy_serial))
242 psppire_data_store_set_case_file (the_data_store,
243 psppire_case_file_new (reader));
247 reload_the_viewer ();
254 #ifdef G_ENABLE_DEBUG
255 # define g_marshal_value_peek_int(v) g_value_get_int (v)
257 # define g_marshal_value_peek_int(v) (v)->data[0].v_int
261 /* VOID:INT,INT,INT */
263 marshaller_VOID__INT_INT_INT (GClosure *closure,
264 GValue *return_value,
265 guint n_param_values,
266 const GValue *param_values,
267 gpointer invocation_hint,
268 gpointer marshal_data)
270 typedef void (*GMarshalFunc_VOID__INT_INT_INT) (gpointer data1,
275 register GMarshalFunc_VOID__INT_INT_INT callback;
276 register GCClosure *cc = (GCClosure*) closure;
277 register gpointer data1, data2;
279 g_return_if_fail (n_param_values == 4);
281 if (G_CCLOSURE_SWAP_DATA (closure))
283 data1 = closure->data;
284 data2 = g_value_peek_pointer (param_values + 0);
288 data1 = g_value_peek_pointer (param_values + 0);
289 data2 = closure->data;
291 callback = (GMarshalFunc_VOID__INT_INT_INT) (marshal_data ? marshal_data : cc->callback);
294 g_marshal_value_peek_int (param_values + 1),
295 g_marshal_value_peek_int (param_values + 2),
296 g_marshal_value_peek_int (param_values + 3),
300 /* Create a deep copy of SRC */
302 clone_list_store (const GtkListStore *src)
304 GtkTreeIter src_iter;
307 const gint n_cols = gtk_tree_model_get_n_columns (GTK_TREE_MODEL (src));
308 GType *types = g_malloc (sizeof (*types) * n_cols);
313 for (i = 0 ; i < n_cols; ++i )
314 types[i] = gtk_tree_model_get_column_type (GTK_TREE_MODEL (src), i);
316 dest = gtk_list_store_newv (n_cols, types);
318 for (ok = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (src),
321 ok = gtk_tree_model_iter_next (GTK_TREE_MODEL (src), &src_iter))
323 GtkTreeIter dest_iter;
324 gtk_list_store_append (dest, &dest_iter);
326 for (i = 0 ; i < n_cols; ++i )
330 gtk_tree_model_get_value (GTK_TREE_MODEL (src), &src_iter, i, &val);
331 gtk_list_store_set_value (dest, &dest_iter, i, &val);
333 g_value_unset (&val);