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_reader (the_data_store, reader);
249 reload_the_viewer ();
256 /* Create a deep copy of SRC */
258 clone_list_store (const GtkListStore *src)
260 GtkTreeIter src_iter;
263 const gint n_cols = gtk_tree_model_get_n_columns (GTK_TREE_MODEL (src));
264 GType *types = g_malloc (sizeof (*types) * n_cols);
269 for (i = 0 ; i < n_cols; ++i )
270 types[i] = gtk_tree_model_get_column_type (GTK_TREE_MODEL (src), i);
272 dest = gtk_list_store_newv (n_cols, types);
274 for (ok = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (src),
277 ok = gtk_tree_model_iter_next (GTK_TREE_MODEL (src), &src_iter))
279 GtkTreeIter dest_iter;
280 gtk_list_store_append (dest, &dest_iter);
282 for (i = 0 ; i < n_cols; ++i )
286 gtk_tree_model_get_value (GTK_TREE_MODEL (src), &src_iter, i, &val);
287 gtk_list_store_set_value (dest, &dest_iter, i, &val);
289 g_value_unset (&val);