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, 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);
159 reference_manual (GtkMenuItem *menu, gpointer data)
162 if ( ! g_spawn_command_line_async ("yelp info:pspp", &err) )
164 msg (ME, _("Cannot open reference manual: %s"), err->message);
166 g_clear_error (&err);
170 extern struct dataset *the_dataset;
171 extern struct source_stream *the_source_stream;
172 extern PsppireDataStore *the_data_store;
174 /* Lazy casereader callback function used by execute_syntax. */
175 static struct casereader *
176 create_casereader_from_data_store (void *data_store_)
178 PsppireDataStore *data_store = data_store_;
179 return psppire_data_store_get_reader (data_store);
183 execute_syntax (struct getl_interface *sss)
186 gboolean retval = TRUE;
188 struct casereader *reader;
191 unsigned long int lazy_serial;
193 /* When the user executes a number of snippets of syntax in a
194 row, none of which read from the active file, the GUI becomes
195 progressively less responsive. The reason is that each syntax
196 execution encapsulates the active file data in another
197 datasheet layer. The cumulative effect of having a number of
198 layers of datasheets wastes time and space.
200 To solve the problem, we use a "lazy casereader", a wrapper
201 around the casereader obtained from the data store, that
202 only actually instantiates that casereader when it is
203 needed. If the data store casereader is never needed, then
204 it is reused the next time syntax is run, without wrapping
205 it in another layer. */
206 value_cnt = psppire_data_store_get_value_count (the_data_store);
207 case_cnt = psppire_data_store_get_case_count (the_data_store);
208 reader = lazy_casereader_create (value_cnt, case_cnt,
209 create_casereader_from_data_store,
210 the_data_store, &lazy_serial);
211 proc_set_active_file_data (the_dataset, reader);
213 g_return_val_if_fail (proc_has_active_file (the_dataset), FALSE);
215 lexer = lex_create (the_source_stream);
217 getl_append_source (the_source_stream, sss, GETL_BATCH, ERRMODE_CONTINUE);
221 enum cmd_result result = cmd_parse (lexer, the_dataset);
223 if ( cmd_result_is_failure (result))
226 if ( source_stream_current_error_mode (the_source_stream)
231 if ( result == CMD_EOF || result == CMD_FINISH)
235 getl_abort_noninteractive (the_source_stream);
239 psppire_dict_replace_dictionary (the_data_store->dict,
240 dataset_dict (the_dataset));
242 reader = proc_extract_active_file_data (the_dataset);
243 if (!lazy_casereader_destroy (reader, lazy_serial))
244 psppire_data_store_set_case_file (the_data_store,
245 psppire_case_file_new (reader));
249 reload_the_viewer ();
256 #ifdef G_ENABLE_DEBUG
257 # define g_marshal_value_peek_int(v) g_value_get_int (v)
259 # define g_marshal_value_peek_int(v) (v)->data[0].v_int
263 /* VOID:INT,INT,INT */
265 marshaller_VOID__INT_INT_INT (GClosure *closure,
266 GValue *return_value,
267 guint n_param_values,
268 const GValue *param_values,
269 gpointer invocation_hint,
270 gpointer marshal_data)
272 typedef void (*GMarshalFunc_VOID__INT_INT_INT) (gpointer data1,
277 register GMarshalFunc_VOID__INT_INT_INT callback;
278 register GCClosure *cc = (GCClosure*) closure;
279 register gpointer data1, data2;
281 g_return_if_fail (n_param_values == 4);
283 if (G_CCLOSURE_SWAP_DATA (closure))
285 data1 = closure->data;
286 data2 = g_value_peek_pointer (param_values + 0);
290 data1 = g_value_peek_pointer (param_values + 0);
291 data2 = closure->data;
293 callback = (GMarshalFunc_VOID__INT_INT_INT) (marshal_data ? marshal_data : cc->callback);
296 g_marshal_value_peek_int (param_values + 1),
297 g_marshal_value_peek_int (param_values + 2),
298 g_marshal_value_peek_int (param_values + 3),
302 /* Create a deep copy of SRC */
304 clone_list_store (const GtkListStore *src)
306 GtkTreeIter src_iter;
309 const gint n_cols = gtk_tree_model_get_n_columns (GTK_TREE_MODEL (src));
310 GType *types = g_malloc (sizeof (*types) * n_cols);
315 for (i = 0 ; i < n_cols; ++i )
316 types[i] = gtk_tree_model_get_column_type (GTK_TREE_MODEL (src), i);
318 dest = gtk_list_store_newv (n_cols, types);
320 for (ok = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (src),
323 ok = gtk_tree_model_iter_next (GTK_TREE_MODEL (src), &src_iter))
325 GtkTreeIter dest_iter;
326 gtk_list_store_append (dest, &dest_iter);
328 for (i = 0 ; i < n_cols; ++i )
332 gtk_tree_model_get_value (GTK_TREE_MODEL (src), &src_iter, i, &val);
333 gtk_list_store_set_value (dest, &dest_iter, i, &val);
335 g_value_unset (&val);