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 "psppire-syntax-window.h"
25 #include <glib-object.h>
29 #include "message-dialog.h"
30 #include <data/format.h>
31 #include <data/data-in.h>
32 #include <data/data-out.h>
33 #include <data/dictionary.h>
34 #include <data/casereader-provider.h>
35 #include <libpspp/message.h>
37 #include <gtk/gtkbuilder.h>
38 #include <libpspp/i18n.h>
43 #include <data/settings.h>
45 #include <language/command.h>
46 #include <data/lazy-casereader.h>
47 #include <data/procedure.h>
48 #include <language/lexer/lexer.h>
49 #include "psppire-data-store.h"
50 #include <output/manager.h>
51 #include "psppire-output-window.h"
57 /* Formats a value according to FORMAT
58 The returned string must be freed when no longer required */
60 value_to_text (union value v, struct fmt_spec format)
64 s = g_new (gchar, format.w + 1);
65 data_out (&v, &format, s);
75 text_to_value (const gchar *text, union value *v,
76 struct fmt_spec format)
80 if ( format.type != FMT_A)
82 if ( ! text ) return FALSE;
85 const gchar *s = text;
93 if ( !*s) return FALSE;
98 ok = data_in (ss_cstr (text), LEGACY_NATIVE, format.type, 0, 0, 0,
99 v, fmt_var_width (&format));
107 builder_new_real (const gchar *name)
109 GtkBuilder *builder = gtk_builder_new ();
112 if ( ! gtk_builder_add_from_file (builder, name, &err))
114 g_critical ("Couldnt open user interface file %s: %s", name, err->message);
115 g_clear_error (&err);
124 get_widget_assert (gpointer x, const gchar *name)
126 GObject *obj = G_OBJECT (x);
130 if (GTK_IS_BUILDER (obj))
131 w = GTK_WIDGET (gtk_builder_get_object (GTK_BUILDER (obj), name));
133 if (GLADE_IS_XML (obj))
134 w = glade_xml_get_widget (GLADE_XML (obj), name);
137 g_critical ("Widget \"%s\" could not be found\n", name);
142 /* Converts a string in the pspp locale to utf-8.
143 The return value must be freed when no longer required*/
145 pspp_locale_to_utf8 (const gchar *text, gssize len, GError **err)
147 return recode_string (CONV_PSPP_TO_UTF8, text, len);
150 #define _(msgid) gettext (msgid)
151 #define N_(msgid) msgid
159 dialog = gtk_message_dialog_new (NULL,
163 _("Sorry. The help system hasn't yet "
164 "been implemented."));
165 gtk_dialog_run (GTK_DIALOG (dialog));
166 gtk_widget_destroy (dialog);
170 connect_help (GladeXML *xml)
172 GList *helps = glade_xml_get_widget_prefix (xml, "help_button_");
175 for ( i = g_list_first (helps); i ; i = g_list_next (i))
176 g_signal_connect (GTK_WIDGET (i->data), "clicked", give_help, 0);
184 reference_manual (GtkMenuItem *menu, gpointer data)
187 if ( ! g_spawn_command_line_async ("yelp info:pspp", &err) )
189 msg (ME, _("Cannot open reference manual: %s"), err->message);
191 g_clear_error (&err);
195 extern struct dataset *the_dataset;
196 extern struct source_stream *the_source_stream;
197 extern PsppireDataStore *the_data_store;
199 /* Lazy casereader callback function used by execute_syntax. */
200 static struct casereader *
201 create_casereader_from_data_store (void *data_store_)
203 PsppireDataStore *data_store = data_store_;
204 return psppire_data_store_get_reader (data_store);
208 execute_syntax (struct getl_interface *sss)
211 gboolean retval = TRUE;
213 struct casereader *reader;
216 unsigned long int lazy_serial;
218 /* When the user executes a number of snippets of syntax in a
219 row, none of which read from the active file, the GUI becomes
220 progressively less responsive. The reason is that each syntax
221 execution encapsulates the active file data in another
222 datasheet layer. The cumulative effect of having a number of
223 layers of datasheets wastes time and space.
225 To solve the problem, we use a "lazy casereader", a wrapper
226 around the casereader obtained from the data store, that
227 only actually instantiates that casereader when it is
228 needed. If the data store casereader is never needed, then
229 it is reused the next time syntax is run, without wrapping
230 it in another layer. */
231 value_cnt = psppire_data_store_get_value_count (the_data_store);
232 case_cnt = psppire_data_store_get_case_count (the_data_store);
233 reader = lazy_casereader_create (value_cnt, case_cnt,
234 create_casereader_from_data_store,
235 the_data_store, &lazy_serial);
236 proc_set_active_file_data (the_dataset, reader);
238 g_return_val_if_fail (proc_has_active_file (the_dataset), FALSE);
240 lexer = lex_create (the_source_stream);
242 getl_append_source (the_source_stream, sss, GETL_BATCH, ERRMODE_CONTINUE);
246 enum cmd_result result = cmd_parse (lexer, the_dataset);
248 if ( cmd_result_is_failure (result))
251 if ( source_stream_current_error_mode (the_source_stream)
256 if ( result == CMD_EOF || result == CMD_FINISH)
260 getl_abort_noninteractive (the_source_stream);
264 psppire_dict_replace_dictionary (the_data_store->dict,
265 dataset_dict (the_dataset));
267 reader = proc_extract_active_file_data (the_dataset);
268 if (!lazy_casereader_destroy (reader, lazy_serial))
269 psppire_data_store_set_reader (the_data_store, reader);
273 psppire_output_window_reload ();
280 /* Create a deep copy of SRC */
282 clone_list_store (const GtkListStore *src)
284 GtkTreeIter src_iter;
287 const gint n_cols = gtk_tree_model_get_n_columns (GTK_TREE_MODEL (src));
288 GType *types = g_malloc (sizeof (*types) * n_cols);
293 for (i = 0 ; i < n_cols; ++i )
294 types[i] = gtk_tree_model_get_column_type (GTK_TREE_MODEL (src), i);
296 dest = gtk_list_store_newv (n_cols, types);
298 for (ok = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (src),
301 ok = gtk_tree_model_iter_next (GTK_TREE_MODEL (src), &src_iter))
303 GtkTreeIter dest_iter;
304 gtk_list_store_append (dest, &dest_iter);
306 for (i = 0 ; i < n_cols; ++i )
310 gtk_tree_model_get_value (GTK_TREE_MODEL (src), &src_iter, i, &val);
311 gtk_list_store_set_value (dest, &dest_iter, i, &val);
313 g_value_unset (&val);
325 paste_syntax_in_new_window (const gchar *syntax)
327 GtkWidget *se = psppire_syntax_window_new ();
329 gtk_text_buffer_insert_at_cursor (PSPPIRE_SYNTAX_WINDOW (se)->buffer, syntax, -1);
331 gtk_widget_show (se);