1 /* PSPPIRE - a graphical user interface for PSPP.
2 Copyright (C) 2006 Free Software Foundation, Inc.
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/>. */
20 #define _(msgid) gettext (msgid)
21 #define N_(msgid) msgid
23 #include <glade/glade.h>
25 #include <libpspp/message.h>
26 #include <libpspp/getl.h>
28 #include "data-editor.h"
31 #include "window-manager.h"
33 #include <data/dictionary.h>
34 #include <language/lexer/lexer.h>
35 #include <language/command.h>
36 #include <data/procedure.h>
37 #include "syntax-editor.h"
38 #include "syntax-editor-source.h"
40 extern struct source_stream *the_source_stream ;
41 extern struct dataset *the_dataset;
43 static gboolean save_editor_to_file (struct syntax_editor *se,
44 const gchar *filename,
47 /* Append ".sps" to FILENAME if necessary.
48 The returned result must be freed when no longer required.
51 append_suffix (const gchar *filename)
53 if ( ! g_str_has_suffix (filename, ".sps" ) &&
54 ! g_str_has_suffix (filename, ".SPS" ) )
56 return g_strdup_printf ("%s.sps", filename);
59 return strdup (filename);
62 /* If the buffer's modified flag is set, then save it, and close the window.
63 Otherwise just close the window.
66 save_if_modified (struct syntax_editor *se)
68 struct editor_window *e = (struct editor_window *) se;
69 if ( TRUE == gtk_text_buffer_get_modified (se->buffer))
73 gtk_message_dialog_new (GTK_WINDOW (e->window),
77 _("Save contents of syntax editor to %s?"),
81 gtk_dialog_add_button (GTK_DIALOG (dialog),
84 gtk_dialog_add_button (GTK_DIALOG (dialog),
87 gtk_dialog_add_button (GTK_DIALOG (dialog),
92 response = gtk_dialog_run (GTK_DIALOG (dialog));
94 gtk_widget_destroy (dialog);
96 if ( response == GTK_RESPONSE_ACCEPT )
100 if ( ! save_editor_to_file (se, e->name, &err) )
102 msg (ME, err->message);
107 if ( response == GTK_RESPONSE_CANCEL )
111 gtk_widget_destroy (GTK_WIDGET (e->window));
114 /* Callback for the File->SaveAs menuitem */
116 on_syntax_save_as (GtkMenuItem *menuitem, gpointer user_data)
118 GtkFileFilter *filter;
120 struct syntax_editor *se = user_data;
121 struct editor_window *e = user_data;
124 gtk_file_chooser_dialog_new (_("Save Syntax"),
125 GTK_WINDOW (e->window),
126 GTK_FILE_CHOOSER_ACTION_SAVE,
127 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
128 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
131 filter = gtk_file_filter_new ();
132 gtk_file_filter_set_name (filter, _("Syntax Files (*.sps) "));
133 gtk_file_filter_add_pattern (filter, "*.sps");
134 gtk_file_filter_add_pattern (filter, "*.SPS");
135 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
137 filter = gtk_file_filter_new ();
138 gtk_file_filter_set_name (filter, _("All Files"));
139 gtk_file_filter_add_pattern (filter, "*");
140 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
142 gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog),
144 response = gtk_dialog_run (GTK_DIALOG (dialog));
146 if ( response == GTK_RESPONSE_ACCEPT )
150 gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog) );
152 if ( save_editor_to_file (se, filename, &err) )
155 e->name = g_strdup (filename);
159 msg ( ME, err->message );
166 gtk_widget_destroy ( dialog );
169 /* Callback for the File->Save menuitem */
171 on_syntax_save (GtkMenuItem *menuitem, gpointer user_data)
173 struct syntax_editor *se = user_data;
174 struct editor_window *e = user_data;
176 if ( e->name == NULL )
177 on_syntax_save_as (menuitem, user_data);
181 save_editor_to_file (se, e->name, &err);
184 msg (ME, err->message);
191 /* Callback for the "delete" action (clicking the x on the top right
192 hand corner of the window) */
194 on_delete (GtkWidget *w, GdkEvent *event, gpointer user_data)
196 struct syntax_editor *se = user_data;
197 save_if_modified (se);
202 /* Callback for the File->Quit menuitem */
204 on_quit (GtkMenuItem *menuitem, gpointer user_data)
206 struct syntax_editor *se = user_data;
207 save_if_modified (se);
212 editor_execute_syntax (const struct syntax_editor *se, GtkTextIter start,
215 execute_syntax (create_syntax_editor_source (se, start, stop));
218 /* Parse and execute all the text in the buffer */
220 on_run_all (GtkMenuItem *menuitem, gpointer user_data)
222 GtkTextIter begin, end;
223 struct syntax_editor *se = user_data;
225 gtk_text_buffer_get_iter_at_offset (se->buffer, &begin, 0);
226 gtk_text_buffer_get_iter_at_offset (se->buffer, &end, -1);
228 editor_execute_syntax (se, begin, end);
231 /* Parse and execute the currently selected text */
233 on_run_selection (GtkMenuItem *menuitem, gpointer user_data)
235 GtkTextIter begin, end;
236 struct syntax_editor *se = user_data;
238 if ( gtk_text_buffer_get_selection_bounds (se->buffer, &begin, &end) )
239 editor_execute_syntax (se, begin, end);
243 /* Parse and execute the current line */
245 on_run_current_line (GtkMenuItem *menuitem, gpointer user_data)
247 GtkTextIter begin, end;
251 struct syntax_editor *se = user_data;
253 /* Get the current line */
254 gtk_text_buffer_get_iter_at_mark (se->buffer,
256 gtk_text_buffer_get_insert (se->buffer)
259 line = gtk_text_iter_get_line (&here) ;
261 /* Now set begin and end to the start of this line, and start of
262 following line respectively */
263 gtk_text_buffer_get_iter_at_line (se->buffer, &begin, line);
264 gtk_text_buffer_get_iter_at_line (se->buffer, &end, line + 1);
266 editor_execute_syntax (se, begin, end);
271 /* Parse and execute the from the current line, to the end of the
274 on_run_to_end (GtkMenuItem *menuitem, gpointer user_data)
276 GtkTextIter begin, end;
280 struct syntax_editor *se = user_data;
282 /* Get the current line */
283 gtk_text_buffer_get_iter_at_mark (se->buffer,
285 gtk_text_buffer_get_insert (se->buffer)
288 line = gtk_text_iter_get_line (&here) ;
290 /* Now set begin and end to the start of this line, and end of buffer
292 gtk_text_buffer_get_iter_at_line (se->buffer, &begin, line);
293 gtk_text_buffer_get_iter_at_line (se->buffer, &end, -1);
295 editor_execute_syntax (se, begin, end);
302 Create a new syntax editor with NAME.
303 If NAME is NULL, a name will be automatically assigned
305 struct syntax_editor *
306 new_syntax_editor (void)
308 GladeXML *xml = XML_NEW ("syntax-editor.glade");
310 GtkWidget *text_view;
311 struct syntax_editor *se ;
312 struct editor_window *e;
316 se = g_malloc (sizeof (*se));
318 e = (struct editor_window *)se;
320 e->window = GTK_WINDOW (get_widget_assert (xml, "syntax_editor"));
321 text_view = get_widget_assert (xml, "syntax_text_view");
322 se->buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
323 se->lexer = lex_create (the_source_stream);
325 g_signal_connect (get_widget_assert (xml,"file_new_syntax"),
327 G_CALLBACK (new_syntax_window),
330 g_signal_connect (get_widget_assert (xml,"file_open_syntax"),
332 G_CALLBACK (open_syntax_window),
335 g_signal_connect (get_widget_assert (xml,"file_new_data"),
337 G_CALLBACK (new_data_window),
340 g_signal_connect (get_widget_assert (xml,"help_about"),
342 G_CALLBACK (about_new),
345 g_signal_connect (get_widget_assert (xml,"help_reference"),
347 G_CALLBACK (reference_manual),
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),
362 g_signal_connect (get_widget_assert (xml,"file_quit"),
364 G_CALLBACK (on_quit),
368 g_signal_connect (get_widget_assert (xml,"run_all"),
370 G_CALLBACK (on_run_all),
374 g_signal_connect (get_widget_assert (xml,"run_selection"),
376 G_CALLBACK (on_run_selection),
379 g_signal_connect (get_widget_assert (xml,"run_current_line"),
381 G_CALLBACK (on_run_current_line),
385 g_signal_connect (get_widget_assert (xml,"run_to_end"),
387 G_CALLBACK (on_run_to_end),
391 g_signal_connect (get_widget_assert (xml,"windows_minimise_all"),
393 G_CALLBACK (minimise_all_windows),
398 g_object_unref (xml);
400 g_signal_connect (e->window, "delete-event",
401 G_CALLBACK (on_delete), se);
409 Callback for the File->New->Syntax menuitem
412 new_syntax_window (GtkMenuItem *menuitem,
415 window_create (WINDOW_SYNTAX, NULL);
420 Save BUFFER to the file called FILENAME.
421 If successful, clears the buffer's modified flag
424 save_editor_to_file (struct syntax_editor *se,
425 const gchar *filename,
428 GtkTextBuffer *buffer = se->buffer;
430 GtkTextIter start, stop;
437 suffixedname = append_suffix (filename);
439 glibfilename = g_filename_from_utf8 (suffixedname, -1, 0, 0, err);
441 g_free ( suffixedname);
443 if ( ! glibfilename )
446 gtk_text_buffer_get_iter_at_line (buffer, &start, 0);
447 gtk_text_buffer_get_iter_at_offset (buffer, &stop, -1);
449 text = gtk_text_buffer_get_text (buffer, &start, &stop, FALSE);
451 result = g_file_set_contents (glibfilename, text, -1, err);
455 window_set_name_from_filename ((struct editor_window *) se, filename);
456 gtk_text_buffer_set_modified (buffer, FALSE);
464 Loads the buffer from the file called FILENAME
467 load_editor_from_file (struct syntax_editor *se,
468 const gchar *filename,
471 GtkTextBuffer *buffer = se->buffer;
475 gchar *glibfilename = g_filename_from_utf8 (filename, -1, 0, 0, err);
477 if ( ! glibfilename )
480 /* FIXME: What if it's a very big file ? */
481 if ( ! g_file_get_contents (glibfilename, &text, NULL, err) )
483 g_free (glibfilename);
486 g_free (glibfilename);
488 gtk_text_buffer_get_iter_at_line (buffer, &iter, 0);
490 gtk_text_buffer_insert (buffer, &iter, text, -1);
495 window_set_name_from_filename ((struct editor_window *)se, filename);
496 gtk_text_buffer_set_modified (buffer, FALSE);
502 /* Callback for the File->Open->Syntax menuitem */
504 open_syntax_window (GtkMenuItem *menuitem, gpointer parent)
506 GtkFileFilter *filter;
510 gtk_file_chooser_dialog_new (_("Open Syntax"),
512 GTK_FILE_CHOOSER_ACTION_OPEN,
513 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
514 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
517 filter = gtk_file_filter_new ();
518 gtk_file_filter_set_name (filter, _("Syntax Files (*.sps) "));
519 gtk_file_filter_add_pattern (filter, "*.sps");
520 gtk_file_filter_add_pattern (filter, "*.SPS");
521 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
523 filter = gtk_file_filter_new ();
524 gtk_file_filter_set_name (filter, _("All Files"));
525 gtk_file_filter_add_pattern (filter, "*");
526 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
528 response = gtk_dialog_run (GTK_DIALOG (dialog));
530 if (response == GTK_RESPONSE_ACCEPT)
532 const char *file_name = gtk_file_chooser_get_filename
533 (GTK_FILE_CHOOSER (dialog));
535 struct syntax_editor *se = (struct syntax_editor *)
536 window_create (WINDOW_SYNTAX, file_name);
538 load_editor_from_file (se, file_name, NULL);
540 #if RECENT_LISTS_AVAILABLE
542 GtkRecentManager *manager = gtk_recent_manager_get_default();
543 gchar *uri = g_filename_to_uri (file_name, NULL, NULL);
545 if ( ! gtk_recent_manager_add_item (manager, uri))
546 g_warning ("Could not add item %s to recent list\n",uri);
554 gtk_widget_destroy (dialog);