-/*
- PSPPIRE --- A Graphical User Interface for PSPP
- Copyright (C) 2006 Free Software Foundation
- Written by John Darrington
+/* PSPPIRE - a graphical user interface for PSPP.
+ Copyright (C) 2006 Free Software Foundation, Inc.
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <stdlib.h>
#include <glade/glade.h>
#include <gtk/gtk.h>
#include <libpspp/message.h>
-
+#include <libpspp/getl.h>
#include "helper.h"
+#include "data-editor.h"
+#include "about.h"
-extern GladeXML *xml;
+#include "window-manager.h"
-struct syntax_editor
-{
- GtkWidget *window; /* The top level window of the editor */
- GtkTextBuffer *buffer; /* The buffer which contains the text */
- gchar *name; /* The name of this syntax buffer/editor */
-};
+#include <data/dictionary.h>
+#include <language/lexer/lexer.h>
+#include <language/command.h>
+#include <data/procedure.h>
+#include "syntax-editor.h"
+#include "syntax-editor-source.h"
+
+extern struct source_stream *the_source_stream ;
+extern struct dataset *the_dataset;
static gboolean save_editor_to_file (struct syntax_editor *se,
const gchar *filename,
GError **err);
+/* Append ".sps" to FILENAME if necessary.
+ The returned result must be freed when no longer required.
+ */
+static gchar *
+append_suffix (const gchar *filename)
+{
+ if ( ! g_str_has_suffix (filename, ".sps" ) &&
+ ! g_str_has_suffix (filename, ".SPS" ) )
+ {
+ return g_strdup_printf ("%s.sps", filename);
+ }
+
+ return strdup (filename);
+}
+
/* If the buffer's modified flag is set, then save it, and close the window.
Otherwise just close the window.
*/
static void
save_if_modified (struct syntax_editor *se)
{
+ struct editor_window *e = (struct editor_window *) se;
if ( TRUE == gtk_text_buffer_get_modified (se->buffer))
{
gint response;
GtkWidget *dialog =
- gtk_message_dialog_new (GTK_WINDOW(se->window),
+ gtk_message_dialog_new (GTK_WINDOW (e->window),
GTK_DIALOG_MODAL,
GTK_MESSAGE_QUESTION,
GTK_BUTTONS_NONE,
_("Save contents of syntax editor to %s?"),
- se->name ? se->name : _("Untitled")
+ e->name
);
- gtk_dialog_add_button (GTK_DIALOG(dialog),
+ gtk_dialog_add_button (GTK_DIALOG (dialog),
GTK_STOCK_YES,
GTK_RESPONSE_ACCEPT);
- gtk_dialog_add_button (GTK_DIALOG(dialog),
+ gtk_dialog_add_button (GTK_DIALOG (dialog),
GTK_STOCK_NO,
GTK_RESPONSE_REJECT);
- gtk_dialog_add_button (GTK_DIALOG(dialog),
+ gtk_dialog_add_button (GTK_DIALOG (dialog),
GTK_STOCK_CANCEL,
GTK_RESPONSE_CANCEL);
- response = gtk_dialog_run (GTK_DIALOG(dialog));
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_destroy (dialog);
{
GError *err = NULL;
- if ( ! save_editor_to_file (se, se->name ? se->name : _("Untitled"),
- err) )
+ if ( ! save_editor_to_file (se, e->name, &err) )
{
msg (ME, err->message);
g_error_free (err);
return ;
}
- gtk_widget_destroy (se->window);
+ gtk_widget_destroy (GTK_WIDGET (e->window));
}
/* Callback for the File->SaveAs menuitem */
static void
-on_syntax_save_as (GtkMenuItem *menuitem,
- gpointer user_data)
+on_syntax_save_as (GtkMenuItem *menuitem, gpointer user_data)
{
GtkFileFilter *filter;
gint response;
struct syntax_editor *se = user_data;
+ struct editor_window *e = user_data;
GtkWidget *dialog =
gtk_file_chooser_dialog_new (_("Save Syntax"),
- GTK_WINDOW(se->window),
+ GTK_WINDOW (e->window),
GTK_FILE_CHOOSER_ACTION_SAVE,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
gtk_file_filter_set_name (filter, _("Syntax Files (*.sps) "));
gtk_file_filter_add_pattern (filter, "*.sps");
gtk_file_filter_add_pattern (filter, "*.SPS");
- gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(dialog), filter);
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
filter = gtk_file_filter_new ();
gtk_file_filter_set_name (filter, _("All Files"));
gtk_file_filter_add_pattern (filter, "*");
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
- gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER(dialog),
+ gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog),
TRUE);
response = gtk_dialog_run (GTK_DIALOG (dialog));
if ( save_editor_to_file (se, filename, &err) )
{
- g_free (se->name);
- se->name = g_strdup (filename);
+ g_free (e->name);
+ e->name = g_strdup (filename);
}
else
{
}
/* Callback for the File->Save menuitem */
-void
-on_syntax_save (GtkMenuItem *menuitem,
- gpointer user_data)
+static void
+on_syntax_save (GtkMenuItem *menuitem, gpointer user_data)
{
struct syntax_editor *se = user_data;
+ struct editor_window *e = user_data;
- if ( se->name == NULL )
+ if ( e->name == NULL )
on_syntax_save_as (menuitem, user_data);
else
{
- GError *err;
- save_editor_to_file (se, se->name, &err);
- msg (ME, err->message);
- g_error_free (err);
+ GError *err = NULL;
+ save_editor_to_file (se, e->name, &err);
+ if ( err )
+ {
+ msg (ME, err->message);
+ g_error_free (err);
+ }
}
}
return FALSE;
}
-void
-new_syntax_window (GtkMenuItem *menuitem,
- gpointer user_data);
+static void
+editor_execute_syntax (const struct syntax_editor *se, GtkTextIter start,
+ GtkTextIter stop)
+{
+ execute_syntax (create_syntax_editor_source (se, start, stop));
+}
+
+/* Parse and execute all the text in the buffer */
+static void
+on_run_all (GtkMenuItem *menuitem, gpointer user_data)
+{
+ GtkTextIter begin, end;
+ struct syntax_editor *se = user_data;
+
+ gtk_text_buffer_get_iter_at_offset (se->buffer, &begin, 0);
+ gtk_text_buffer_get_iter_at_offset (se->buffer, &end, -1);
+
+ editor_execute_syntax (se, begin, end);
+}
+
+/* Parse and execute the currently selected text */
+static void
+on_run_selection (GtkMenuItem *menuitem, gpointer user_data)
+{
+ GtkTextIter begin, end;
+ struct syntax_editor *se = user_data;
+
+ if ( gtk_text_buffer_get_selection_bounds (se->buffer, &begin, &end) )
+ editor_execute_syntax (se, begin, end);
+}
+
+
+/* Parse and execute the current line */
+static void
+on_run_current_line (GtkMenuItem *menuitem, gpointer user_data)
+{
+ GtkTextIter begin, end;
+ GtkTextIter here;
+ gint line;
+
+ struct syntax_editor *se = user_data;
+
+ /* Get the current line */
+ gtk_text_buffer_get_iter_at_mark (se->buffer,
+ &here,
+ gtk_text_buffer_get_insert (se->buffer)
+ );
+
+ line = gtk_text_iter_get_line (&here) ;
+
+ /* Now set begin and end to the start of this line, and start of
+ following line respectively */
+ gtk_text_buffer_get_iter_at_line (se->buffer, &begin, line);
+ gtk_text_buffer_get_iter_at_line (se->buffer, &end, line + 1);
+
+ editor_execute_syntax (se, begin, end);
+}
+
+
+/* Parse and execute the from the current line, to the end of the
+ buffer */
+static void
+on_run_to_end (GtkMenuItem *menuitem, gpointer user_data)
+{
+ GtkTextIter begin, end;
+ GtkTextIter here;
+ gint line;
+
+ struct syntax_editor *se = user_data;
+
+ /* Get the current line */
+ gtk_text_buffer_get_iter_at_mark (se->buffer,
+ &here,
+ gtk_text_buffer_get_insert (se->buffer)
+ );
+
+ line = gtk_text_iter_get_line (&here) ;
+
+ /* Now set begin and end to the start of this line, and end of buffer
+ respectively */
+ gtk_text_buffer_get_iter_at_line (se->buffer, &begin, line);
+ gtk_text_buffer_get_iter_at_line (se->buffer, &end, -1);
+
+ editor_execute_syntax (se, begin, end);
+}
-static void open_syntax_window (GtkMenuItem *menuitem,
- gpointer user_data);
-/* Create a new syntax editor with NAME.
- If NAME is NULL, a name will be automatically assigned
+/*
+ Create a new syntax editor with NAME.
+ If NAME is NULL, a name will be automatically assigned
*/
-static struct syntax_editor *
-new_syntax_editor (const gchar *name)
+struct syntax_editor *
+new_syntax_editor (void)
{
- GladeXML *new_xml ;
+ GladeXML *xml = XML_NEW ("syntax-editor.glade");
+
GtkWidget *text_view;
struct syntax_editor *se ;
+ struct editor_window *e;
- new_xml = glade_xml_new (xml->filename, "syntax_editor", NULL);
+ connect_help (xml);
se = g_malloc (sizeof (*se));
- se->window = get_widget_assert (new_xml, "syntax_editor");
- text_view = get_widget_assert (new_xml, "syntax_text_view");
- se->buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(text_view));
- if ( name )
- se->name = g_strdup (name);
- else
- se->name = NULL;
+ e = (struct editor_window *)se;
- g_signal_connect (get_widget_assert (new_xml,"file_new_syntax"),
+ e->window = GTK_WINDOW (get_widget_assert (xml, "syntax_editor"));
+ text_view = get_widget_assert (xml, "syntax_text_view");
+ se->buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
+ se->lexer = lex_create (the_source_stream);
+
+ g_signal_connect (get_widget_assert (xml,"file_new_syntax"),
+ "activate",
+ G_CALLBACK (new_syntax_window),
+ e->window);
+
+ g_signal_connect (get_widget_assert (xml,"file_open_syntax"),
"activate",
- G_CALLBACK(new_syntax_window),
- se->window);
+ G_CALLBACK (open_syntax_window),
+ e->window);
- g_signal_connect (get_widget_assert (new_xml,"file_open_syntax"),
+ g_signal_connect (get_widget_assert (xml,"file_new_data"),
"activate",
- G_CALLBACK(open_syntax_window),
- se->window);
+ G_CALLBACK (new_data_window),
+ e->window);
- g_signal_connect (get_widget_assert (new_xml,"file_quit"),
+ g_signal_connect (get_widget_assert (xml,"help_about"),
"activate",
- G_CALLBACK(on_quit),
+ G_CALLBACK (about_new),
+ e->window);
+
+ g_signal_connect (get_widget_assert (xml,"help_reference"),
+ "activate",
+ G_CALLBACK (reference_manual),
+ NULL);
+
+
+ g_signal_connect (get_widget_assert (xml, "file_save"),
+ "activate",
+ G_CALLBACK (on_syntax_save),
+ se);
+
+ g_signal_connect (get_widget_assert (xml, "file_save_as"),
+ "activate",
+ G_CALLBACK (on_syntax_save_as),
+ se);
+
+
+ g_signal_connect (get_widget_assert (xml,"file_quit"),
+ "activate",
+ G_CALLBACK (on_quit),
+ se);
+
+
+ g_signal_connect (get_widget_assert (xml,"run_all"),
+ "activate",
+ G_CALLBACK (on_run_all),
+ se);
+
+
+ g_signal_connect (get_widget_assert (xml,"run_selection"),
+ "activate",
+ G_CALLBACK (on_run_selection),
se);
- g_signal_connect (get_widget_assert (new_xml,"file_save"),
+ g_signal_connect (get_widget_assert (xml,"run_current_line"),
"activate",
- G_CALLBACK(on_syntax_save),
+ G_CALLBACK (on_run_current_line),
se);
- g_signal_connect (get_widget_assert (new_xml,"file_save_as"),
+
+ g_signal_connect (get_widget_assert (xml,"run_to_end"),
"activate",
- G_CALLBACK(on_syntax_save_as),
+ G_CALLBACK (on_run_to_end),
se);
- g_object_unref (new_xml);
- g_signal_connect (se->window, "delete-event",
- G_CALLBACK(on_delete), se);
+ g_signal_connect (get_widget_assert (xml,"windows_minimise_all"),
+ "activate",
+ G_CALLBACK (minimise_all_windows),
+ NULL);
+
+
+
+ g_object_unref (xml);
+
+ g_signal_connect (e->window, "delete-event",
+ G_CALLBACK (on_delete), se);
+
+
return se;
}
-/* Callback for the File->New->Syntax menuitem */
+/*
+ Callback for the File->New->Syntax menuitem
+*/
void
new_syntax_window (GtkMenuItem *menuitem,
gpointer user_data)
{
- struct syntax_editor *se = new_syntax_editor (NULL);
- gtk_widget_show (se->window);
+ window_create (WINDOW_SYNTAX, NULL);
}
-static void
-set_window_title_from_filename (struct syntax_editor *se,
- const gchar *filename)
-{
- gchar *title;
- gchar *basename ;
- g_free (se->name);
- se->name = strdup (filename);
- basename = g_path_get_basename (filename);
- title =
- g_strdup_printf (_("%s --- PSPP Syntax Editor"), basename);
- g_free (basename);
- gtk_window_set_title (GTK_WINDOW(se->window), title);
- g_free (title);
-}
-
-
-/* Save BUFFER to the file called FILENAME.
- If successful, clears the buffer's modified flag */
+/*
+ Save BUFFER to the file called FILENAME.
+ If successful, clears the buffer's modified flag
+*/
static gboolean
save_editor_to_file (struct syntax_editor *se,
const gchar *filename,
GtkTextIter start, stop;
gchar *text;
+ gchar *suffixedname;
gchar *glibfilename;
g_assert (filename);
- glibfilename = g_filename_from_utf8 (filename, -1, 0, 0, err);
+ suffixedname = append_suffix (filename);
+
+ glibfilename = g_filename_from_utf8 (suffixedname, -1, 0, 0, err);
+
+ g_free ( suffixedname);
if ( ! glibfilename )
return FALSE;
if ( result )
{
- set_window_title_from_filename (se, filename);
+ window_set_name_from_filename ((struct editor_window *) se, filename);
gtk_text_buffer_set_modified (buffer, FALSE);
}
}
-/* Loads the buffer from the file called FILENAME
+/*
+ Loads the buffer from the file called FILENAME
*/
-static gboolean
+gboolean
load_editor_from_file (struct syntax_editor *se,
const gchar *filename,
GError **err)
gtk_text_buffer_insert (buffer, &iter, text, -1);
- set_window_title_from_filename (se, filename);
+
+ window_set_name_from_filename ((struct editor_window *)se, filename);
gtk_text_buffer_set_modified (buffer, FALSE);
return TRUE;
/* Callback for the File->Open->Syntax menuitem */
-static void
+void
open_syntax_window (GtkMenuItem *menuitem, gpointer parent)
{
GtkFileFilter *filter;
GtkWidget *dialog =
gtk_file_chooser_dialog_new (_("Open Syntax"),
- GTK_WINDOW(parent),
+ GTK_WINDOW (parent),
GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
gtk_file_filter_set_name (filter, _("Syntax Files (*.sps) "));
gtk_file_filter_add_pattern (filter, "*.sps");
gtk_file_filter_add_pattern (filter, "*.SPS");
- gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(dialog), filter);
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
filter = gtk_file_filter_new ();
gtk_file_filter_set_name (filter, _("All Files"));
const char *file_name = gtk_file_chooser_get_filename
(GTK_FILE_CHOOSER (dialog));
- struct syntax_editor *se = new_syntax_editor (file_name);
+ struct syntax_editor *se = (struct syntax_editor *)
+ window_create (WINDOW_SYNTAX, file_name);
- load_editor_from_file (se, file_name, NULL);
-
- gtk_widget_show (se->window);
- }
-
- gtk_widget_destroy (dialog);
-}
-
-
-#if 1
-/* FIXME: get rid of these functions */
-void
-on_syntax4_activate (GtkMenuItem *menuitem,
- gpointer user_data)
-{
- g_print ("%s\n", __FUNCTION__);
-}
+ if ( load_editor_from_file (se, file_name, NULL) )
+#if RECENT_LISTS_AVAILABLE
+ {
+ GtkRecentManager *manager = gtk_recent_manager_get_default();
+ gchar *uri = g_filename_to_uri (file_name, NULL, NULL);
+ gtk_recent_manager_remove_item (manager, uri, NULL);
+ if ( ! gtk_recent_manager_add_item (manager, uri))
+ g_warning ("Could not add item %s to recent list\n",uri);
+ g_free (uri);
+ }
+#else
+ ;
+#endif
-void
-on_syntax2_activate (GtkMenuItem *menuitem,
- gpointer user_data)
-{
- g_print ("%s\n", __FUNCTION__);
-}
+ }
-void
-on_syntax1_activate (GtkMenuItem *menuitem,
- gpointer user_data)
-{
- g_print ("%s\n", __FUNCTION__);
- new_syntax_window (menuitem, user_data);
+ gtk_widget_destroy (dialog);
}
-#endif