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)
311 GladeXML *xml = XML_NEW ("syntax-editor.glade");
313 GtkWidget *text_view;
314 struct syntax_editor *se ;
315 struct editor_window *e;
319 se = g_malloc (sizeof (*se));
321 e = (struct editor_window *)se;
323 e->window = GTK_WINDOW (get_widget_assert (xml, "syntax_editor"));
324 text_view = get_widget_assert (xml, "syntax_text_view");
325 se->buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
326 se->lexer = lex_create (the_source_stream);
328 g_signal_connect (get_widget_assert (xml,"file_new_syntax"),
330 G_CALLBACK (new_syntax_window),
333 g_signal_connect (get_widget_assert (xml,"file_open_syntax"),
335 G_CALLBACK (open_syntax_window),
338 g_signal_connect (get_widget_assert (xml,"file_new_data"),
340 G_CALLBACK (new_data_window),
343 g_signal_connect (get_widget_assert (xml,"help_about"),
345 G_CALLBACK (about_new),
348 g_signal_connect (get_widget_assert (xml,"help_reference"),
350 G_CALLBACK (reference_manual),
354 g_signal_connect (get_widget_assert (xml, "file_save"),
356 G_CALLBACK (on_syntax_save),
359 g_signal_connect (get_widget_assert (xml, "file_save_as"),
361 G_CALLBACK (on_syntax_save_as),
365 g_signal_connect (get_widget_assert (xml,"file_quit"),
367 G_CALLBACK (on_quit),
371 g_signal_connect (get_widget_assert (xml,"run_all"),
373 G_CALLBACK (on_run_all),
377 g_signal_connect (get_widget_assert (xml,"run_selection"),
379 G_CALLBACK (on_run_selection),
382 g_signal_connect (get_widget_assert (xml,"run_current_line"),
384 G_CALLBACK (on_run_current_line),
388 g_signal_connect (get_widget_assert (xml,"run_to_end"),
390 G_CALLBACK (on_run_to_end),
394 g_signal_connect (get_widget_assert (xml,"windows_minimise_all"),
396 G_CALLBACK (minimise_all_windows),
401 g_object_unref (xml);
403 g_signal_connect (e->window, "delete-event",
404 G_CALLBACK (on_delete), se);
412 Callback for the File->New->Syntax menuitem
415 new_syntax_window (GtkMenuItem *menuitem,
418 window_create (WINDOW_SYNTAX, NULL);
423 Save BUFFER to the file called FILENAME.
424 If successful, clears the buffer's modified flag
427 save_editor_to_file (struct syntax_editor *se,
428 const gchar *filename,
431 GtkTextBuffer *buffer = se->buffer;
433 GtkTextIter start, stop;
440 suffixedname = append_suffix (filename);
442 glibfilename = g_filename_from_utf8 (suffixedname, -1, 0, 0, err);
444 g_free ( suffixedname);
446 if ( ! glibfilename )
449 gtk_text_buffer_get_iter_at_line (buffer, &start, 0);
450 gtk_text_buffer_get_iter_at_offset (buffer, &stop, -1);
452 text = gtk_text_buffer_get_text (buffer, &start, &stop, FALSE);
454 result = g_file_set_contents (glibfilename, text, -1, err);
458 window_set_name_from_filename ((struct editor_window *) se, filename);
459 gtk_text_buffer_set_modified (buffer, FALSE);
467 Loads the buffer from the file called FILENAME
470 load_editor_from_file (struct syntax_editor *se,
471 const gchar *filename,
474 GtkTextBuffer *buffer = se->buffer;
478 gchar *glibfilename = g_filename_from_utf8 (filename, -1, 0, 0, err);
480 if ( ! glibfilename )
483 /* FIXME: What if it's a very big file ? */
484 if ( ! g_file_get_contents (glibfilename, &text, NULL, err) )
486 g_free (glibfilename);
489 g_free (glibfilename);
491 gtk_text_buffer_get_iter_at_line (buffer, &iter, 0);
493 gtk_text_buffer_insert (buffer, &iter, text, -1);
498 window_set_name_from_filename ((struct editor_window *)se, filename);
499 gtk_text_buffer_set_modified (buffer, FALSE);
505 /* Callback for the File->Open->Syntax menuitem */
507 open_syntax_window (GtkMenuItem *menuitem, gpointer parent)
509 GtkFileFilter *filter;
513 gtk_file_chooser_dialog_new (_("Open Syntax"),
515 GTK_FILE_CHOOSER_ACTION_OPEN,
516 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
517 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
520 filter = gtk_file_filter_new ();
521 gtk_file_filter_set_name (filter, _("Syntax Files (*.sps) "));
522 gtk_file_filter_add_pattern (filter, "*.sps");
523 gtk_file_filter_add_pattern (filter, "*.SPS");
524 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
526 filter = gtk_file_filter_new ();
527 gtk_file_filter_set_name (filter, _("All Files"));
528 gtk_file_filter_add_pattern (filter, "*");
529 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
531 response = gtk_dialog_run (GTK_DIALOG (dialog));
533 if (response == GTK_RESPONSE_ACCEPT)
535 const char *file_name = gtk_file_chooser_get_filename
536 (GTK_FILE_CHOOSER (dialog));
538 struct syntax_editor *se = (struct syntax_editor *)
539 window_create (WINDOW_SYNTAX, file_name);
541 load_editor_from_file (se, file_name, NULL);
543 #if RECENT_LISTS_AVAILABLE
545 GtkRecentManager *manager = gtk_recent_manager_get_default();
546 gchar *uri = g_filename_to_uri (file_name, NULL, NULL);
548 if ( ! gtk_recent_manager_add_item (manager, uri))
549 g_warning ("Could not add item %s to recent list\n",uri);
557 gtk_widget_destroy (dialog);