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 <data/dictionary.h>
37 #include <language/lexer/lexer.h>
38 #include <language/command.h>
39 #include <data/procedure.h>
40 #include "syntax-editor.h"
41 #include "syntax-editor-source.h"
43 extern struct source_stream *the_source_stream ;
44 extern struct dataset *the_dataset;
46 static gboolean save_editor_to_file (struct syntax_editor *se,
47 const gchar *filename,
50 /* Append ".sps" to FILENAME if necessary.
51 The returned result must be freed when no longer required.
54 append_suffix (const gchar *filename)
56 if ( ! g_str_has_suffix (filename, ".sps" ) &&
57 ! g_str_has_suffix (filename, ".SPS" ) )
59 return g_strdup_printf ("%s.sps", filename);
62 return strdup (filename);
65 /* If the buffer's modified flag is set, then save it, and close the window.
66 Otherwise just close the window.
69 save_if_modified (struct syntax_editor *se)
71 struct editor_window *e = (struct editor_window *) se;
72 if ( TRUE == gtk_text_buffer_get_modified (se->buffer))
76 gtk_message_dialog_new (GTK_WINDOW (e->window),
80 _("Save contents of syntax editor to %s?"),
84 gtk_dialog_add_button (GTK_DIALOG (dialog),
87 gtk_dialog_add_button (GTK_DIALOG (dialog),
90 gtk_dialog_add_button (GTK_DIALOG (dialog),
95 response = gtk_dialog_run (GTK_DIALOG (dialog));
97 gtk_widget_destroy (dialog);
99 if ( response == GTK_RESPONSE_ACCEPT )
103 if ( ! save_editor_to_file (se, e->name, &err) )
105 msg (ME, err->message);
110 if ( response == GTK_RESPONSE_CANCEL )
114 gtk_widget_destroy (GTK_WIDGET (e->window));
117 /* Callback for the File->SaveAs menuitem */
119 on_syntax_save_as (GtkMenuItem *menuitem, gpointer user_data)
121 GtkFileFilter *filter;
123 struct syntax_editor *se = user_data;
124 struct editor_window *e = user_data;
127 gtk_file_chooser_dialog_new (_("Save Syntax"),
128 GTK_WINDOW (e->window),
129 GTK_FILE_CHOOSER_ACTION_SAVE,
130 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
131 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
134 filter = gtk_file_filter_new ();
135 gtk_file_filter_set_name (filter, _("Syntax Files (*.sps) "));
136 gtk_file_filter_add_pattern (filter, "*.sps");
137 gtk_file_filter_add_pattern (filter, "*.SPS");
138 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
140 filter = gtk_file_filter_new ();
141 gtk_file_filter_set_name (filter, _("All Files"));
142 gtk_file_filter_add_pattern (filter, "*");
143 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
145 gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog),
147 response = gtk_dialog_run (GTK_DIALOG (dialog));
149 if ( response == GTK_RESPONSE_ACCEPT )
153 gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog) );
155 if ( save_editor_to_file (se, filename, &err) )
158 e->name = g_strdup (filename);
162 msg ( ME, err->message );
169 gtk_widget_destroy ( dialog );
172 /* Callback for the File->Save menuitem */
174 on_syntax_save (GtkMenuItem *menuitem, gpointer user_data)
176 struct syntax_editor *se = user_data;
177 struct editor_window *e = user_data;
179 if ( e->name == NULL )
180 on_syntax_save_as (menuitem, user_data);
184 save_editor_to_file (se, e->name, &err);
187 msg (ME, err->message);
194 /* Callback for the "delete" action (clicking the x on the top right
195 hand corner of the window) */
197 on_delete (GtkWidget *w, GdkEvent *event, gpointer user_data)
199 struct syntax_editor *se = user_data;
200 save_if_modified (se);
205 /* Callback for the File->Quit menuitem */
207 on_quit (GtkMenuItem *menuitem, gpointer user_data)
209 struct syntax_editor *se = user_data;
210 save_if_modified (se);
215 editor_execute_syntax (const struct syntax_editor *se, GtkTextIter start,
218 execute_syntax (create_syntax_editor_source (se, start, stop));
221 /* Parse and execute all the text in the buffer */
223 on_run_all (GtkMenuItem *menuitem, gpointer user_data)
225 GtkTextIter begin, end;
226 struct syntax_editor *se = user_data;
228 gtk_text_buffer_get_iter_at_offset (se->buffer, &begin, 0);
229 gtk_text_buffer_get_iter_at_offset (se->buffer, &end, -1);
231 editor_execute_syntax (se, begin, end);
234 /* Parse and execute the currently selected text */
236 on_run_selection (GtkMenuItem *menuitem, gpointer user_data)
238 GtkTextIter begin, end;
239 struct syntax_editor *se = user_data;
241 if ( gtk_text_buffer_get_selection_bounds (se->buffer, &begin, &end) )
242 editor_execute_syntax (se, begin, end);
246 /* Parse and execute the current line */
248 on_run_current_line (GtkMenuItem *menuitem, gpointer user_data)
250 GtkTextIter begin, end;
254 struct syntax_editor *se = user_data;
256 /* Get the current line */
257 gtk_text_buffer_get_iter_at_mark (se->buffer,
259 gtk_text_buffer_get_insert (se->buffer)
262 line = gtk_text_iter_get_line (&here) ;
264 /* Now set begin and end to the start of this line, and start of
265 following line respectively */
266 gtk_text_buffer_get_iter_at_line (se->buffer, &begin, line);
267 gtk_text_buffer_get_iter_at_line (se->buffer, &end, line + 1);
269 editor_execute_syntax (se, begin, end);
274 /* Parse and execute the from the current line, to the end of the
277 on_run_to_end (GtkMenuItem *menuitem, gpointer user_data)
279 GtkTextIter begin, end;
283 struct syntax_editor *se = user_data;
285 /* Get the current line */
286 gtk_text_buffer_get_iter_at_mark (se->buffer,
288 gtk_text_buffer_get_insert (se->buffer)
291 line = gtk_text_iter_get_line (&here) ;
293 /* Now set begin and end to the start of this line, and end of buffer
295 gtk_text_buffer_get_iter_at_line (se->buffer, &begin, line);
296 gtk_text_buffer_get_iter_at_line (se->buffer, &end, -1);
298 editor_execute_syntax (se, begin, end);
305 Create a new syntax editor with NAME.
306 If NAME is NULL, a name will be automatically assigned
308 struct syntax_editor *
309 new_syntax_editor (void)
312 glade_xml_new (PKGDATADIR "/syntax-editor.glade", NULL, NULL);
314 GtkWidget *text_view;
315 struct syntax_editor *se ;
316 struct editor_window *e;
320 se = g_malloc (sizeof (*se));
322 e = (struct editor_window *)se;
324 e->window = GTK_WINDOW (get_widget_assert (xml, "syntax_editor"));
325 text_view = get_widget_assert (xml, "syntax_text_view");
326 se->buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
327 se->lexer = lex_create (the_source_stream);
329 g_signal_connect (get_widget_assert (xml,"file_new_syntax"),
331 G_CALLBACK (new_syntax_window),
334 g_signal_connect (get_widget_assert (xml,"file_open_syntax"),
336 G_CALLBACK (open_syntax_window),
339 g_signal_connect (get_widget_assert (xml,"file_new_data"),
341 G_CALLBACK (new_data_window),
344 g_signal_connect (get_widget_assert (xml,"help_about"),
346 G_CALLBACK (about_new),
349 g_signal_connect (get_widget_assert (xml,"help_reference"),
351 G_CALLBACK (reference_manual),
355 g_signal_connect (get_widget_assert (xml, "file_save"),
357 G_CALLBACK (on_syntax_save),
360 g_signal_connect (get_widget_assert (xml, "file_save_as"),
362 G_CALLBACK (on_syntax_save_as),
366 g_signal_connect (get_widget_assert (xml,"file_quit"),
368 G_CALLBACK (on_quit),
372 g_signal_connect (get_widget_assert (xml,"run_all"),
374 G_CALLBACK (on_run_all),
378 g_signal_connect (get_widget_assert (xml,"run_selection"),
380 G_CALLBACK (on_run_selection),
383 g_signal_connect (get_widget_assert (xml,"run_current_line"),
385 G_CALLBACK (on_run_current_line),
389 g_signal_connect (get_widget_assert (xml,"run_to_end"),
391 G_CALLBACK (on_run_to_end),
395 g_signal_connect (get_widget_assert (xml,"windows_minimise_all"),
397 G_CALLBACK (minimise_all_windows),
402 g_object_unref (xml);
404 g_signal_connect (e->window, "delete-event",
405 G_CALLBACK (on_delete), se);
413 Callback for the File->New->Syntax menuitem
416 new_syntax_window (GtkMenuItem *menuitem,
419 window_create (WINDOW_SYNTAX, NULL);
424 Save BUFFER to the file called FILENAME.
425 If successful, clears the buffer's modified flag
428 save_editor_to_file (struct syntax_editor *se,
429 const gchar *filename,
432 GtkTextBuffer *buffer = se->buffer;
434 GtkTextIter start, stop;
441 suffixedname = append_suffix (filename);
443 glibfilename = g_filename_from_utf8 (suffixedname, -1, 0, 0, err);
445 g_free ( suffixedname);
447 if ( ! glibfilename )
450 gtk_text_buffer_get_iter_at_line (buffer, &start, 0);
451 gtk_text_buffer_get_iter_at_offset (buffer, &stop, -1);
453 text = gtk_text_buffer_get_text (buffer, &start, &stop, FALSE);
455 result = g_file_set_contents (glibfilename, text, -1, err);
459 window_set_name_from_filename ((struct editor_window *) se, filename);
460 gtk_text_buffer_set_modified (buffer, FALSE);
468 Loads the buffer from the file called FILENAME
471 load_editor_from_file (struct syntax_editor *se,
472 const gchar *filename,
475 GtkTextBuffer *buffer = se->buffer;
479 gchar *glibfilename = g_filename_from_utf8 (filename, -1, 0, 0, err);
481 if ( ! glibfilename )
484 /* FIXME: What if it's a very big file ? */
485 if ( ! g_file_get_contents (glibfilename, &text, NULL, err) )
487 g_free (glibfilename);
490 g_free (glibfilename);
492 gtk_text_buffer_get_iter_at_line (buffer, &iter, 0);
494 gtk_text_buffer_insert (buffer, &iter, text, -1);
496 window_set_name_from_filename ((struct editor_window *)se, filename);
497 gtk_text_buffer_set_modified (buffer, FALSE);
503 /* Callback for the File->Open->Syntax menuitem */
505 open_syntax_window (GtkMenuItem *menuitem, gpointer parent)
507 GtkFileFilter *filter;
511 gtk_file_chooser_dialog_new (_("Open Syntax"),
513 GTK_FILE_CHOOSER_ACTION_OPEN,
514 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
515 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
518 filter = gtk_file_filter_new ();
519 gtk_file_filter_set_name (filter, _("Syntax Files (*.sps) "));
520 gtk_file_filter_add_pattern (filter, "*.sps");
521 gtk_file_filter_add_pattern (filter, "*.SPS");
522 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
524 filter = gtk_file_filter_new ();
525 gtk_file_filter_set_name (filter, _("All Files"));
526 gtk_file_filter_add_pattern (filter, "*");
527 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
529 response = gtk_dialog_run (GTK_DIALOG (dialog));
531 if (response == GTK_RESPONSE_ACCEPT)
533 const char *file_name = gtk_file_chooser_get_filename
534 (GTK_FILE_CHOOSER (dialog));
536 struct syntax_editor *se = (struct syntax_editor *)
537 window_create (WINDOW_SYNTAX, file_name);
539 load_editor_from_file (se, file_name, NULL);
542 gtk_widget_destroy (dialog);