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 <gtk/gtkbuilder.h>
36 #include <libpspp/i18n.h>
41 #include <data/settings.h>
43 #include <language/command.h>
44 #include <data/lazy-casereader.h>
45 #include <data/procedure.h>
46 #include <language/lexer/lexer.h>
47 #include "psppire-data-store.h"
48 #include <output/manager.h>
49 #include "output-viewer.h"
55 /* Formats a value according to FORMAT
56 The returned string must be freed when no longer required */
58 value_to_text (union value v, struct fmt_spec format)
62 s = g_new (gchar, format.w + 1);
63 data_out (&v, &format, s);
73 text_to_value (const gchar *text, union value *v,
74 struct fmt_spec format)
78 if ( format.type != FMT_A)
80 if ( ! text ) return FALSE;
83 const gchar *s = text;
91 if ( !*s) return FALSE;
96 ok = data_in (ss_cstr (text), LEGACY_NATIVE, format.type, 0, 0, 0,
97 v, fmt_var_width (&format));
105 builder_new_real (const gchar *name)
107 GtkBuilder *builder = gtk_builder_new ();
110 if ( ! gtk_builder_add_from_file (builder, name, &err))
112 g_critical ("Couldnt open user interface file %s: %s", name, err->message);
113 g_clear_error (&err);
122 get_widget_assert (gpointer x, const gchar *name)
124 GObject *obj = G_OBJECT (x);
128 if (GTK_IS_BUILDER (obj))
129 w = GTK_WIDGET (gtk_builder_get_object (GTK_BUILDER (obj), name));
131 if (GLADE_IS_XML (obj))
132 w = glade_xml_get_widget (GLADE_XML (obj), name);
135 g_critical ("Widget \"%s\" could not be found\n", name);
140 /* Converts a string in the pspp locale to utf-8.
141 The return value must be freed when no longer required*/
143 pspp_locale_to_utf8 (const gchar *text, gssize len, GError **err)
145 return recode_string (CONV_PSPP_TO_UTF8, text, len);
148 #define _(msgid) gettext (msgid)
149 #define N_(msgid) msgid
157 dialog = gtk_message_dialog_new (NULL,
161 _("Sorry. The help system hasn't yet "
162 "been implemented."));
163 gtk_dialog_run (GTK_DIALOG (dialog));
164 gtk_widget_destroy (dialog);
168 connect_help (GladeXML *xml)
170 GList *helps = glade_xml_get_widget_prefix (xml, "help_button_");
173 for ( i = g_list_first (helps); i ; i = g_list_next (i))
174 g_signal_connect (GTK_WIDGET (i->data), "clicked", give_help, 0);
182 reference_manual (GtkMenuItem *menu, gpointer data)
185 if ( ! g_spawn_command_line_async ("yelp info:pspp", &err) )
187 msg (ME, _("Cannot open reference manual: %s"), err->message);
189 g_clear_error (&err);
193 extern struct dataset *the_dataset;
194 extern struct source_stream *the_source_stream;
195 extern PsppireDataStore *the_data_store;
197 /* Lazy casereader callback function used by execute_syntax. */
198 static struct casereader *
199 create_casereader_from_data_store (void *data_store_)
201 PsppireDataStore *data_store = data_store_;
202 return psppire_data_store_get_reader (data_store);
206 execute_syntax (struct getl_interface *sss)
209 gboolean retval = TRUE;
211 struct casereader *reader;
214 unsigned long int lazy_serial;
216 /* When the user executes a number of snippets of syntax in a
217 row, none of which read from the active file, the GUI becomes
218 progressively less responsive. The reason is that each syntax
219 execution encapsulates the active file data in another
220 datasheet layer. The cumulative effect of having a number of
221 layers of datasheets wastes time and space.
223 To solve the problem, we use a "lazy casereader", a wrapper
224 around the casereader obtained from the data store, that
225 only actually instantiates that casereader when it is
226 needed. If the data store casereader is never needed, then
227 it is reused the next time syntax is run, without wrapping
228 it in another layer. */
229 value_cnt = psppire_data_store_get_value_count (the_data_store);
230 case_cnt = psppire_data_store_get_case_count (the_data_store);
231 reader = lazy_casereader_create (value_cnt, case_cnt,
232 create_casereader_from_data_store,
233 the_data_store, &lazy_serial);
234 proc_set_active_file_data (the_dataset, reader);
236 g_return_val_if_fail (proc_has_active_file (the_dataset), FALSE);
238 lexer = lex_create (the_source_stream);
240 getl_append_source (the_source_stream, sss, GETL_BATCH, ERRMODE_CONTINUE);
244 enum cmd_result result = cmd_parse (lexer, the_dataset);
246 if ( cmd_result_is_failure (result))
249 if ( source_stream_current_error_mode (the_source_stream)
254 if ( result == CMD_EOF || result == CMD_FINISH)
258 getl_abort_noninteractive (the_source_stream);
262 psppire_dict_replace_dictionary (the_data_store->dict,
263 dataset_dict (the_dataset));
265 reader = proc_extract_active_file_data (the_dataset);
266 if (!lazy_casereader_destroy (reader, lazy_serial))
267 psppire_data_store_set_reader (the_data_store, reader);
271 reload_the_viewer ();
278 /* Create a deep copy of SRC */
280 clone_list_store (const GtkListStore *src)
282 GtkTreeIter src_iter;
285 const gint n_cols = gtk_tree_model_get_n_columns (GTK_TREE_MODEL (src));
286 GType *types = g_malloc (sizeof (*types) * n_cols);
291 for (i = 0 ; i < n_cols; ++i )
292 types[i] = gtk_tree_model_get_column_type (GTK_TREE_MODEL (src), i);
294 dest = gtk_list_store_newv (n_cols, types);
296 for (ok = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (src),
299 ok = gtk_tree_model_iter_next (GTK_TREE_MODEL (src), &src_iter))
301 GtkTreeIter dest_iter;
302 gtk_list_store_append (dest, &dest_iter);
304 for (i = 0 ; i < n_cols; ++i )
308 gtk_tree_model_get_value (GTK_TREE_MODEL (src), &src_iter, i, &val);
309 gtk_list_store_set_value (dest, &dest_iter, i, &val);
311 g_value_unset (&val);