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);
123 get_object_assert (GtkBuilder *builder, const gchar *name)
128 o = gtk_builder_get_object (builder, name);
131 g_critical ("Object \"%s\" could not be found\n", name);
137 get_widget_assert (gpointer x, const gchar *name)
139 GObject *obj = G_OBJECT (x);
143 if (GTK_IS_BUILDER (obj))
144 w = GTK_WIDGET (gtk_builder_get_object (GTK_BUILDER (obj), name));
147 g_critical ("Widget \"%s\" could not be found\n", name);
152 /* Converts a string in the pspp locale to utf-8.
153 The return value must be freed when no longer required*/
155 pspp_locale_to_utf8 (const gchar *text, gssize len, GError **err)
157 return recode_string (CONV_PSPP_TO_UTF8, text, len);
160 #define _(msgid) gettext (msgid)
161 #define N_(msgid) msgid
169 dialog = gtk_message_dialog_new (NULL,
173 _("Sorry. The help system hasn't yet "
174 "been implemented."));
175 gtk_dialog_run (GTK_DIALOG (dialog));
176 gtk_widget_destroy (dialog);
180 connect_help (GtkBuilder *xml)
182 GSList *helps = gtk_builder_get_objects (xml);
185 for ( i = helps; i ; i = g_slist_next (i))
187 GObject *o = i->data;
188 if ( GTK_IS_WIDGET (o) )
192 g_object_get (o, "name", &name, NULL);
195 strncpy (s, name, 11);
199 if ( 0 == strcmp ("help_button", s))
201 g_signal_connect (GTK_WIDGET (o), "clicked", give_help, 0);
206 g_slist_free (helps);
211 reference_manual (GtkMenuItem *menu, gpointer data)
214 if ( ! g_spawn_command_line_async ("yelp info:pspp", &err) )
216 msg (ME, _("Cannot open reference manual: %s"), err->message);
218 g_clear_error (&err);
222 extern struct dataset *the_dataset;
223 extern struct source_stream *the_source_stream;
224 extern PsppireDataStore *the_data_store;
226 /* Lazy casereader callback function used by execute_syntax. */
227 static struct casereader *
228 create_casereader_from_data_store (void *data_store_)
230 PsppireDataStore *data_store = data_store_;
231 return psppire_data_store_get_reader (data_store);
235 execute_syntax (struct getl_interface *sss)
238 gboolean retval = TRUE;
240 struct casereader *reader;
243 unsigned long int lazy_serial;
245 /* When the user executes a number of snippets of syntax in a
246 row, none of which read from the active file, the GUI becomes
247 progressively less responsive. The reason is that each syntax
248 execution encapsulates the active file data in another
249 datasheet layer. The cumulative effect of having a number of
250 layers of datasheets wastes time and space.
252 To solve the problem, we use a "lazy casereader", a wrapper
253 around the casereader obtained from the data store, that
254 only actually instantiates that casereader when it is
255 needed. If the data store casereader is never needed, then
256 it is reused the next time syntax is run, without wrapping
257 it in another layer. */
258 value_cnt = psppire_data_store_get_value_count (the_data_store);
259 case_cnt = psppire_data_store_get_case_count (the_data_store);
260 reader = lazy_casereader_create (value_cnt, case_cnt,
261 create_casereader_from_data_store,
262 the_data_store, &lazy_serial);
263 proc_set_active_file_data (the_dataset, reader);
265 g_return_val_if_fail (proc_has_active_file (the_dataset), FALSE);
267 lexer = lex_create (the_source_stream);
269 getl_append_source (the_source_stream, sss, GETL_BATCH, ERRMODE_CONTINUE);
273 enum cmd_result result = cmd_parse (lexer, the_dataset);
275 if ( cmd_result_is_failure (result))
278 if ( source_stream_current_error_mode (the_source_stream)
283 if ( result == CMD_EOF || result == CMD_FINISH)
287 getl_abort_noninteractive (the_source_stream);
291 psppire_dict_replace_dictionary (the_data_store->dict,
292 dataset_dict (the_dataset));
294 reader = proc_extract_active_file_data (the_dataset);
295 if (!lazy_casereader_destroy (reader, lazy_serial))
296 psppire_data_store_set_reader (the_data_store, reader);
300 psppire_output_window_reload ();
307 /* Create a deep copy of SRC */
309 clone_list_store (const GtkListStore *src)
311 GtkTreeIter src_iter;
314 const gint n_cols = gtk_tree_model_get_n_columns (GTK_TREE_MODEL (src));
315 GType *types = g_malloc (sizeof (*types) * n_cols);
320 for (i = 0 ; i < n_cols; ++i )
321 types[i] = gtk_tree_model_get_column_type (GTK_TREE_MODEL (src), i);
323 dest = gtk_list_store_newv (n_cols, types);
325 for (ok = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (src),
328 ok = gtk_tree_model_iter_next (GTK_TREE_MODEL (src), &src_iter))
330 GtkTreeIter dest_iter;
331 gtk_list_store_append (dest, &dest_iter);
333 for (i = 0 ; i < n_cols; ++i )
337 gtk_tree_model_get_value (GTK_TREE_MODEL (src), &src_iter, i, &val);
338 gtk_list_store_set_value (dest, &dest_iter, i, &val);
340 g_value_unset (&val);
352 paste_syntax_in_new_window (const gchar *syntax)
354 GtkWidget *se = psppire_syntax_window_new ();
356 gtk_text_buffer_insert_at_cursor (PSPPIRE_SYNTAX_WINDOW (se)->buffer, syntax, -1);
358 gtk_widget_show (se);