1 /* PSPPIRE - a graphical user interface for PSPP.
2 Copyright (C) 2007, 2009, 2010, 2011 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/>. */
19 #include "ui/gui/executor.h"
21 #include "data/dataset.h"
22 #include "data/lazy-casereader.h"
23 #include "data/session.h"
24 #include "language/command.h"
25 #include "language/lexer/lexer.h"
26 #include "libpspp/cast.h"
27 #include "output/driver.h"
28 #include "ui/gui/psppire-data-store.h"
29 #include "ui/gui/psppire-output-window.h"
31 /* Lazy casereader callback function used by execute_syntax. */
32 static struct casereader *
33 create_casereader_from_data_store (void *data_store_)
35 PsppireDataStore *data_store = data_store_;
36 return psppire_data_store_get_reader (data_store);
40 new_pdw_cb (struct dataset *ds, void *aux UNUSED)
42 PsppireDataWindow *pdw = psppire_data_window_for_dataset (ds);
44 pdw = PSPPIRE_DATA_WINDOW (psppire_data_window_new (ds));
46 switch (dataset_get_display (ds))
52 gtk_widget_show (GTK_WIDGET (pdw));
53 gtk_window_deiconify (GTK_WINDOW (pdw));
54 gdk_window_raise (gtk_widget_get_window (GTK_WIDGET (pdw)));
55 psppire_data_window_set_default (pdw);
58 case DATASET_MINIMIZED:
59 gtk_window_iconify (GTK_WINDOW (pdw));
60 gtk_widget_show (GTK_WIDGET (pdw));
61 psppire_data_window_undefault (pdw);
65 gtk_widget_hide (GTK_WIDGET (pdw));
66 psppire_data_window_undefault (pdw);
69 dataset_set_display (ds, DATASET_ASIS);
73 execute_syntax (PsppireDataWindow *window, struct lex_reader *lex_reader)
76 gboolean retval = TRUE;
78 PsppireDataWindow *pdw, *next_pdw;
80 ll_for_each (pdw, PsppireDataWindow, ll, &all_data_windows)
82 const struct caseproto *proto;
83 struct casereader *reader;
86 /* When the user executes a number of snippets of syntax in a
87 row, none of which read from the active dataset, the GUI becomes
88 progressively less responsive. The reason is that each syntax
89 execution encapsulates the active dataset data in another
90 datasheet layer. The cumulative effect of having a number of
91 layers of datasheets wastes time and space.
93 To solve the problem, we use a "lazy casereader", a wrapper
94 around the casereader obtained from the data store, that
95 only actually instantiates that casereader when it is
96 needed. If the data store casereader is never needed, then
97 it is reused the next time syntax is run, without wrapping
98 it in another layer. */
99 proto = psppire_data_store_get_proto (pdw->data_store);
100 case_cnt = psppire_data_store_get_case_count (pdw->data_store);
101 reader = lazy_casereader_create (proto, case_cnt,
102 create_casereader_from_data_store,
103 pdw->data_store, &pdw->lazy_serial);
104 dataset_set_source (pdw->dataset, reader);
107 session_set_active_dataset (the_session, pdw->dataset);
109 g_return_val_if_fail (dataset_has_source (pdw->dataset), FALSE);
111 pdw->dataset_seqno = dataset_seqno (pdw->dataset);
114 lexer = lex_create ();
115 psppire_set_lexer (lexer);
116 lex_append (lexer, lex_reader);
120 struct dataset *ds = session_active_dataset (the_session);
121 enum cmd_result result = cmd_parse (lexer, ds);
123 if ( cmd_result_is_failure (result))
126 if ( lex_get_error_mode (lexer) == LEX_ERROR_STOP )
130 if ( result == CMD_EOF || result == CMD_FINISH)
134 ll_for_each_safe (pdw, next_pdw, PsppireDataWindow, ll, &all_data_windows)
138 ds = session_get_dataset_by_seqno (the_session, pdw->dataset_seqno);
141 struct casereader *reader;
144 proc_execute (pdw->dataset);
146 psppire_dict_replace_dictionary (pdw->data_store->dict,
147 dataset_dict (pdw->dataset));
149 reader = dataset_steal_source (pdw->dataset);
150 if (!lazy_casereader_destroy (reader, pdw->lazy_serial))
151 psppire_data_store_set_reader (pdw->data_store, reader);
153 g_object_set (G_OBJECT (pdw), "id", dataset_name (pdw->dataset),
157 gtk_widget_destroy (GTK_WIDGET (pdw));
160 session_for_each_dataset (the_session, new_pdw_cb, NULL);
162 /* Destroy the lexer only after obtaining the dataset, because the dataset
163 might depend on the lexer, if the casereader specifies inline data. (In
164 such a case then we'll always get an error message--the inline data is
165 missing, otherwise it would have been parsed in the loop above.) */
167 psppire_set_lexer (NULL);
174 /* Executes null-terminated string SYNTAX as syntax.
177 execute_syntax_string (PsppireDataWindow *window, gchar *syntax)
179 execute_const_syntax_string (window, syntax);
183 /* Executes null-terminated string SYNTAX as syntax. */
185 execute_const_syntax_string (PsppireDataWindow *window, const gchar *syntax)
187 execute_syntax (window, lex_reader_for_string (syntax));