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 /* Create a deep copy of SRC */
259 clone_list_store (const GtkListStore *src)
261 GtkTreeIter src_iter;
264 const gint n_cols = gtk_tree_model_get_n_columns (GTK_TREE_MODEL (src));
265 GType *types = g_malloc (sizeof (*types) * n_cols);
270 for (i = 0 ; i < n_cols; ++i )
271 types[i] = gtk_tree_model_get_column_type (GTK_TREE_MODEL (src), i);
273 dest = gtk_list_store_newv (n_cols, types);
275 for (ok = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (src),
278 ok = gtk_tree_model_iter_next (GTK_TREE_MODEL (src), &src_iter))
280 GtkTreeIter dest_iter;
281 gtk_list_store_append (dest, &dest_iter);
283 for (i = 0 ; i < n_cols; ++i )
287 gtk_tree_model_get_value (GTK_TREE_MODEL (src), &src_iter, i, &val);
288 gtk_list_store_set_value (dest, &dest_iter, i, &val);
290 g_value_unset (&val);