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, GType type)
128 o = gtk_builder_get_object (builder, name);
131 g_critical ("Object \"%s\" could not be found\n", name);
133 if ( ! g_type_is_a (G_OBJECT_TYPE (o), type))
135 g_critical ("Object \"%s\" was expected to have type %s, but in fact has type %s",
136 name, g_type_name (type), G_OBJECT_TYPE_NAME (o));
144 get_action_assert (GtkBuilder *builder, const gchar *name)
146 return GTK_ACTION (get_object_assert (builder, name, GTK_TYPE_ACTION));
150 get_widget_assert (GtkBuilder *builder, const gchar *name)
152 return GTK_WIDGET (get_object_assert (builder, name, GTK_TYPE_WIDGET));
155 /* Converts a string in the pspp locale to utf-8.
156 The return value must be freed when no longer required*/
158 pspp_locale_to_utf8 (const gchar *text, gssize len, GError **err)
160 return recode_string (CONV_PSPP_TO_UTF8, text, len);
164 utf8_to_pspp_locale (const gchar *text, gssize len, GError **err)
166 return recode_string (CONV_UTF8_TO_PSPP, text, len);
170 #define _(msgid) gettext (msgid)
171 #define N_(msgid) msgid
179 dialog = gtk_message_dialog_new (NULL,
183 _("Sorry. The help system hasn't yet "
184 "been implemented."));
185 gtk_dialog_run (GTK_DIALOG (dialog));
186 gtk_widget_destroy (dialog);
190 connect_help (GtkBuilder *xml)
192 GSList *helps = gtk_builder_get_objects (xml);
195 for ( i = helps; i ; i = g_slist_next (i))
197 GObject *o = i->data;
198 if ( GTK_IS_WIDGET (o) )
202 g_object_get (o, "name", &name, NULL);
205 strncpy (s, name, 11);
209 if ( 0 == strcmp ("help_button", s))
211 g_signal_connect (o, "clicked", give_help, 0);
216 g_slist_free (helps);
221 reference_manual (GtkMenuItem *menu, gpointer data)
224 gchar *cmd = g_strdup_printf ("yelp file://%s", relocate (DOCDIR "/pspp.xml"));
226 if ( ! g_spawn_command_line_async (cmd, &err) )
228 msg (ME, _("Cannot open reference manual: %s"), err->message);
232 g_clear_error (&err);
236 extern struct dataset *the_dataset;
237 extern struct source_stream *the_source_stream;
238 extern PsppireDataStore *the_data_store;
240 /* Lazy casereader callback function used by execute_syntax. */
241 static struct casereader *
242 create_casereader_from_data_store (void *data_store_)
244 PsppireDataStore *data_store = data_store_;
245 return psppire_data_store_get_reader (data_store);
249 execute_syntax (struct getl_interface *sss)
252 gboolean retval = TRUE;
254 struct casereader *reader;
257 unsigned long int lazy_serial;
259 /* When the user executes a number of snippets of syntax in a
260 row, none of which read from the active file, the GUI becomes
261 progressively less responsive. The reason is that each syntax
262 execution encapsulates the active file data in another
263 datasheet layer. The cumulative effect of having a number of
264 layers of datasheets wastes time and space.
266 To solve the problem, we use a "lazy casereader", a wrapper
267 around the casereader obtained from the data store, that
268 only actually instantiates that casereader when it is
269 needed. If the data store casereader is never needed, then
270 it is reused the next time syntax is run, without wrapping
271 it in another layer. */
272 value_cnt = psppire_data_store_get_value_count (the_data_store);
273 case_cnt = psppire_data_store_get_case_count (the_data_store);
274 reader = lazy_casereader_create (value_cnt, case_cnt,
275 create_casereader_from_data_store,
276 the_data_store, &lazy_serial);
277 proc_set_active_file_data (the_dataset, reader);
279 g_return_val_if_fail (proc_has_active_file (the_dataset), FALSE);
281 lexer = lex_create (the_source_stream);
283 getl_append_source (the_source_stream, sss, GETL_BATCH, ERRMODE_CONTINUE);
287 enum cmd_result result = cmd_parse (lexer, the_dataset);
289 if ( cmd_result_is_failure (result))
292 if ( source_stream_current_error_mode (the_source_stream)
297 if ( result == CMD_EOF || result == CMD_FINISH)
301 getl_abort_noninteractive (the_source_stream);
305 psppire_dict_replace_dictionary (the_data_store->dict,
306 dataset_dict (the_dataset));
308 reader = proc_extract_active_file_data (the_dataset);
309 if (!lazy_casereader_destroy (reader, lazy_serial))
310 psppire_data_store_set_reader (the_data_store, reader);
314 psppire_output_window_reload ();
321 /* Create a deep copy of SRC */
323 clone_list_store (const GtkListStore *src)
325 GtkTreeIter src_iter;
328 const gint n_cols = gtk_tree_model_get_n_columns (GTK_TREE_MODEL (src));
329 GType *types = g_malloc (sizeof (*types) * n_cols);
334 for (i = 0 ; i < n_cols; ++i )
335 types[i] = gtk_tree_model_get_column_type (GTK_TREE_MODEL (src), i);
337 dest = gtk_list_store_newv (n_cols, types);
339 for (ok = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (src),
342 ok = gtk_tree_model_iter_next (GTK_TREE_MODEL (src), &src_iter))
344 GtkTreeIter dest_iter;
345 gtk_list_store_append (dest, &dest_iter);
347 for (i = 0 ; i < n_cols; ++i )
351 gtk_tree_model_get_value (GTK_TREE_MODEL (src), &src_iter, i, &val);
352 gtk_list_store_set_value (dest, &dest_iter, i, &val);
354 g_value_unset (&val);
366 paste_syntax_in_new_window (const gchar *syntax)
368 GtkWidget *se = psppire_syntax_window_new ();
370 gtk_text_buffer_insert_at_cursor (PSPPIRE_SYNTAX_WINDOW (se)->buffer, syntax, -1);
372 gtk_widget_show (se);