2 PSPPIRE --- A Graphical User Interface for PSPP
3 Copyright (C) 2006 Free Software Foundation
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 #define _(msgid) gettext (msgid)
24 #define N_(msgid) msgid
26 #include <glade/glade.h>
28 #include <libpspp/message.h>
29 #include <libpspp/getl.h>
31 #include "data-editor.h"
34 #include "window-manager.h"
36 #include <language/lexer/lexer.h>
37 #include <language/command.h>
38 #include <data/procedure.h>
39 #include "syntax-editor.h"
40 #include "syntax-editor-source.h"
42 extern struct source_stream *the_source_stream ;
43 extern struct dataset *the_dataset;
45 static gboolean save_editor_to_file (struct syntax_editor *se,
46 const gchar *filename,
49 /* If the buffer's modified flag is set, then save it, and close the window.
50 Otherwise just close the window.
53 save_if_modified (struct syntax_editor *se)
55 struct editor_window *e = (struct editor_window *) se;
56 if ( TRUE == gtk_text_buffer_get_modified (se->buffer))
60 gtk_message_dialog_new (GTK_WINDOW (e->window),
64 _("Save contents of syntax editor to %s?"),
65 e->name ? e->name : _("Untitled")
68 gtk_dialog_add_button (GTK_DIALOG (dialog),
71 gtk_dialog_add_button (GTK_DIALOG (dialog),
74 gtk_dialog_add_button (GTK_DIALOG (dialog),
79 response = gtk_dialog_run (GTK_DIALOG (dialog));
81 gtk_widget_destroy (dialog);
83 if ( response == GTK_RESPONSE_ACCEPT )
87 if ( ! save_editor_to_file (se, e->name ? e->name : _("Untitled"),
90 msg (ME, err->message);
95 if ( response == GTK_RESPONSE_CANCEL )
99 gtk_widget_destroy (e->window);
102 /* Callback for the File->SaveAs menuitem */
104 on_syntax_save_as (GtkMenuItem *menuitem,
107 GtkFileFilter *filter;
109 struct syntax_editor *se = user_data;
110 struct editor_window *e = user_data;
113 gtk_file_chooser_dialog_new (_("Save Syntax"),
114 GTK_WINDOW (e->window),
115 GTK_FILE_CHOOSER_ACTION_SAVE,
116 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
117 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
120 filter = gtk_file_filter_new ();
121 gtk_file_filter_set_name (filter, _("Syntax Files (*.sps) "));
122 gtk_file_filter_add_pattern (filter, "*.sps");
123 gtk_file_filter_add_pattern (filter, "*.SPS");
124 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
126 filter = gtk_file_filter_new ();
127 gtk_file_filter_set_name (filter, _("All Files"));
128 gtk_file_filter_add_pattern (filter, "*");
129 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
131 gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog),
133 response = gtk_dialog_run (GTK_DIALOG (dialog));
135 if ( response == GTK_RESPONSE_ACCEPT )
139 gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog) );
141 if ( save_editor_to_file (se, filename, &err) )
144 e->name = g_strdup (filename);
148 msg ( ME, err->message );
155 gtk_widget_destroy ( dialog );
158 /* Callback for the File->Save menuitem */
160 on_syntax_save (GtkMenuItem *menuitem,
163 struct syntax_editor *se = user_data;
164 struct editor_window *e = user_data;
166 if ( e->name == NULL )
167 on_syntax_save_as (menuitem, user_data);
171 save_editor_to_file (se, e->name, &err);
172 msg (ME, err->message);
178 /* Callback for the "delete" action (clicking the x on the top right
179 hand corner of the window) */
181 on_delete (GtkWidget *w, GdkEvent *event, gpointer user_data)
183 struct syntax_editor *se = user_data;
184 save_if_modified (se);
189 /* Callback for the File->Quit menuitem */
191 on_quit (GtkMenuItem *menuitem, gpointer user_data)
193 struct syntax_editor *se = user_data;
194 save_if_modified (se);
199 execute_syntax (const struct syntax_editor *se, GtkTextIter start,
202 getl_append_source (the_source_stream,
203 create_syntax_editor_source (se, start, stop));
206 int result = cmd_parse (se->lexer, the_dataset,
207 proc_has_source (the_dataset)
208 ? CMD_STATE_DATA : CMD_STATE_INITIAL);
210 if (result == CMD_EOF || result == CMD_FINISH)
215 /* Parse and execute all the text in the buffer */
217 on_run_all (GtkMenuItem *menuitem, gpointer user_data)
219 GtkTextIter begin, end;
220 struct syntax_editor *se = user_data;
222 gtk_text_buffer_get_iter_at_line (se->buffer, &begin, 0);
223 gtk_text_buffer_get_iter_at_line (se->buffer, &end, -1);
226 execute_syntax (se, begin, end);
229 /* Parse and execute the currently selected text */
231 on_run_selection (GtkMenuItem *menuitem, gpointer user_data)
233 GtkTextIter begin, end;
234 struct syntax_editor *se = user_data;
236 if ( gtk_text_buffer_get_selection_bounds (se->buffer, &begin, &end) )
237 execute_syntax (se, begin, end);
241 /* Parse and execute the current line */
243 on_run_current_line (GtkMenuItem *menuitem, gpointer user_data)
245 GtkTextIter begin, end;
249 struct syntax_editor *se = user_data;
251 /* Get the current line */
252 gtk_text_buffer_get_iter_at_mark (se->buffer,
254 gtk_text_buffer_get_insert (se->buffer)
257 line = gtk_text_iter_get_line (&here) ;
259 /* Now set begin and end to the start of this line, and start of
260 following line respectively */
261 gtk_text_buffer_get_iter_at_line (se->buffer, &begin, line);
262 gtk_text_buffer_get_iter_at_line (se->buffer, &end, line + 1);
264 execute_syntax (se, begin, end);
269 /* Parse and execute the from the current line, to the end of the
272 on_run_to_end (GtkMenuItem *menuitem, gpointer user_data)
274 GtkTextIter begin, end;
278 struct syntax_editor *se = user_data;
280 /* Get the current line */
281 gtk_text_buffer_get_iter_at_mark (se->buffer,
283 gtk_text_buffer_get_insert (se->buffer)
286 line = gtk_text_iter_get_line (&here) ;
288 /* Now set begin and end to the start of this line, and end of buffer
290 gtk_text_buffer_get_iter_at_line (se->buffer, &begin, line);
291 gtk_text_buffer_get_iter_at_line (se->buffer, &end, -1);
293 execute_syntax (se, begin, end);
300 Create a new syntax editor with NAME.
301 If NAME is NULL, a name will be automatically assigned
303 struct syntax_editor *
304 new_syntax_editor (void)
307 glade_xml_new (PKGDATADIR "/syntax-editor.glade", NULL, NULL);
309 GtkWidget *text_view;
310 struct syntax_editor *se ;
311 struct editor_window *e;
313 se = g_malloc (sizeof (*se));
315 e = (struct editor_window *)se;
317 e->window = get_widget_assert (xml, "syntax_editor");
318 text_view = get_widget_assert (xml, "syntax_text_view");
319 se->buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
320 se->lexer = lex_create (the_source_stream);
322 g_signal_connect (get_widget_assert (xml,"file_new_syntax"),
324 G_CALLBACK (new_syntax_window),
327 g_signal_connect (get_widget_assert (xml,"file_open_syntax"),
329 G_CALLBACK (open_syntax_window),
332 g_signal_connect (get_widget_assert (xml,"file_new_data"),
334 G_CALLBACK (new_data_window),
337 g_signal_connect (get_widget_assert (xml,"file_open_data"),
339 G_CALLBACK (open_data_window),
343 g_signal_connect (get_widget_assert (xml,"help_about"),
345 G_CALLBACK (about_new),
351 g_signal_connect (get_widget_assert (xml,"file_save"),
353 G_CALLBACK (on_syntax_save),
356 g_signal_connect (get_widget_assert (xml,"file_save_as"),
358 G_CALLBACK (on_syntax_save_as),
363 g_signal_connect (get_widget_assert (xml,"file_quit"),
365 G_CALLBACK (on_quit),
369 g_signal_connect (get_widget_assert (xml,"run_all"),
371 G_CALLBACK (on_run_all),
375 g_signal_connect (get_widget_assert (xml,"run_selection"),
377 G_CALLBACK (on_run_selection),
380 g_signal_connect (get_widget_assert (xml,"run_current_line"),
382 G_CALLBACK (on_run_current_line),
386 g_signal_connect (get_widget_assert (xml,"run_to_end"),
388 G_CALLBACK (on_run_to_end),
392 g_object_unref (xml);
394 g_signal_connect (e->window, "delete-event",
395 G_CALLBACK (on_delete), se);
403 Callback for the File->New->Syntax menuitem
406 new_syntax_window (GtkMenuItem *menuitem,
409 window_create (WINDOW_SYNTAX, NULL);
414 Save BUFFER to the file called FILENAME.
415 If successful, clears the buffer's modified flag
418 save_editor_to_file (struct syntax_editor *se,
419 const gchar *filename,
422 GtkTextBuffer *buffer = se->buffer;
424 GtkTextIter start, stop;
430 glibfilename = g_filename_from_utf8 (filename, -1, 0, 0, err);
432 if ( ! glibfilename )
435 gtk_text_buffer_get_iter_at_line (buffer, &start, 0);
436 gtk_text_buffer_get_iter_at_offset (buffer, &stop, -1);
438 text = gtk_text_buffer_get_text (buffer, &start, &stop, FALSE);
440 result = g_file_set_contents (glibfilename, text, -1, err);
444 window_set_name_from_filename ((struct editor_window *) se, filename);
445 gtk_text_buffer_set_modified (buffer, FALSE);
453 Loads the buffer from the file called FILENAME
456 load_editor_from_file (struct syntax_editor *se,
457 const gchar *filename,
460 GtkTextBuffer *buffer = se->buffer;
464 gchar *glibfilename = g_filename_from_utf8 (filename, -1, 0, 0, err);
466 if ( ! glibfilename )
469 /* FIXME: What if it's a very big file ? */
470 if ( ! g_file_get_contents (glibfilename, &text, NULL, err) )
472 g_free (glibfilename);
475 g_free (glibfilename);
477 gtk_text_buffer_get_iter_at_line (buffer, &iter, 0);
479 gtk_text_buffer_insert (buffer, &iter, text, -1);
481 window_set_name_from_filename ((struct editor_window *)se, filename);
482 gtk_text_buffer_set_modified (buffer, FALSE);
488 /* Callback for the File->Open->Syntax menuitem */
490 open_syntax_window (GtkMenuItem *menuitem, gpointer parent)
492 GtkFileFilter *filter;
496 gtk_file_chooser_dialog_new (_("Open Syntax"),
498 GTK_FILE_CHOOSER_ACTION_OPEN,
499 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
500 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
503 filter = gtk_file_filter_new ();
504 gtk_file_filter_set_name (filter, _("Syntax Files (*.sps) "));
505 gtk_file_filter_add_pattern (filter, "*.sps");
506 gtk_file_filter_add_pattern (filter, "*.SPS");
507 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
509 filter = gtk_file_filter_new ();
510 gtk_file_filter_set_name (filter, _("All Files"));
511 gtk_file_filter_add_pattern (filter, "*");
512 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
514 response = gtk_dialog_run (GTK_DIALOG (dialog));
516 if (response == GTK_RESPONSE_ACCEPT)
518 const char *file_name = gtk_file_chooser_get_filename
519 (GTK_FILE_CHOOSER (dialog));
521 struct syntax_editor *se = (struct syntax_editor *)
522 window_create (WINDOW_SYNTAX, file_name);
524 load_editor_from_file (se, file_name, NULL);
527 gtk_widget_destroy (dialog);