Merge commit 'HEAD'; commit 'savannah/master'
authorJohn Darrington <john@darrington.wattle.id.au>
Fri, 20 Feb 2009 01:22:49 +0000 (10:22 +0900)
committerJohn Darrington <john@darrington.wattle.id.au>
Fri, 20 Feb 2009 01:22:49 +0000 (10:22 +0900)
Conflicts:

src/ui/gui/crosstabs-dialog.c
src/ui/gui/goto-case-dialog.c
src/ui/gui/helper.c
src/ui/gui/output-viewer.c
src/ui/gui/output-viewer.h
src/ui/gui/psppire.c
src/ui/gui/regression-dialog.c

48 files changed:
src/ui/gui/automake.mk
src/ui/gui/comments-dialog.c
src/ui/gui/compute-dialog.c
src/ui/gui/crosstabs-dialog.c
src/ui/gui/data-editor.c [deleted file]
src/ui/gui/data-editor.h [deleted file]
src/ui/gui/descriptives-dialog.c
src/ui/gui/examine-dialog.c
src/ui/gui/find-dialog.c
src/ui/gui/frequencies-dialog.c
src/ui/gui/goto-case-dialog.c
src/ui/gui/helper.c
src/ui/gui/helper.h
src/ui/gui/oneway-anova-dialog.c
src/ui/gui/output-viewer.c [deleted file]
src/ui/gui/output-viewer.glade
src/ui/gui/output-viewer.h [deleted file]
src/ui/gui/psppire-data-store.c
src/ui/gui/psppire-data-window.c [new file with mode: 0644]
src/ui/gui/psppire-data-window.h [new file with mode: 0644]
src/ui/gui/psppire-output-window.c [new file with mode: 0644]
src/ui/gui/psppire-output-window.h [new file with mode: 0644]
src/ui/gui/psppire-syntax-window.c [new file with mode: 0644]
src/ui/gui/psppire-syntax-window.h [new file with mode: 0644]
src/ui/gui/psppire-window-register.c [new file with mode: 0644]
src/ui/gui/psppire-window-register.h [new file with mode: 0644]
src/ui/gui/psppire-window.c [new file with mode: 0644]
src/ui/gui/psppire-window.h [new file with mode: 0644]
src/ui/gui/psppire.c
src/ui/gui/rank-dialog.c
src/ui/gui/recode-dialog.c
src/ui/gui/regression-dialog.c
src/ui/gui/select-cases-dialog.c
src/ui/gui/sort-cases-dialog.c
src/ui/gui/split-file-dialog.c
src/ui/gui/syntax-editor-source.c
src/ui/gui/syntax-editor-source.h
src/ui/gui/syntax-editor.c [deleted file]
src/ui/gui/syntax-editor.h [deleted file]
src/ui/gui/t-test-independent-samples-dialog.c
src/ui/gui/t-test-one-sample.c
src/ui/gui/t-test-paired-samples.c
src/ui/gui/text-data-import-dialog.c
src/ui/gui/transpose-dialog.c
src/ui/gui/variable-info-dialog.c
src/ui/gui/weight-cases-dialog.c
src/ui/gui/window-manager.c [deleted file]
src/ui/gui/window-manager.h [deleted file]

index 1549da4760dbf2b7c5950a321f16359f661d7f8d..6440215a7667f684edceb3f647314b136d0efb1f 100644 (file)
@@ -131,8 +131,6 @@ src_ui_gui_psppire_SOURCES = \
        src/ui/gui/frequencies-dialog.h \
        src/ui/gui/goto-case-dialog.c \
        src/ui/gui/goto-case-dialog.h \
-       src/ui/gui/data-editor.c \
-       src/ui/gui/data-editor.h \
        src/ui/gui/descriptives-dialog.c \
        src/ui/gui/descriptives-dialog.h \
        src/ui/gui/examine-dialog.c \
@@ -154,8 +152,6 @@ src_ui_gui_psppire_SOURCES = \
        src/ui/gui/missing-val-dialog.h \
         src/ui/gui/oneway-anova-dialog.c \
         src/ui/gui/oneway-anova-dialog.h \
-       src/ui/gui/output-viewer.c \
-       src/ui/gui/output-viewer.h \
        src/ui/gui/psppire-acr.h \
        src/ui/gui/psppire-buttonbox.h \
        src/ui/gui/psppire-hbuttonbox.h \
@@ -187,8 +183,6 @@ src_ui_gui_psppire_SOURCES = \
        src/ui/gui/sort-cases-dialog.h \
        src/ui/gui/split-file-dialog.c \
        src/ui/gui/split-file-dialog.h \
-       src/ui/gui/syntax-editor.c \
-       src/ui/gui/syntax-editor.h \
        src/ui/gui/syntax-editor-source.c \
        src/ui/gui/syntax-editor-source.h \
        src/ui/gui/text-data-import-dialog.c \
@@ -215,8 +209,16 @@ src_ui_gui_psppire_SOURCES = \
        src/ui/gui/weight-cases-dialog.h \
        src/ui/gui/widget-io.c \
        src/ui/gui/widget-io.h \
-       src/ui/gui/window-manager.c \
-       src/ui/gui/window-manager.h
+       src/ui/gui/psppire-data-window.c \
+       src/ui/gui/psppire-data-window.h \
+       src/ui/gui/psppire-output-window.c \
+       src/ui/gui/psppire-output-window.h \
+       src/ui/gui/psppire-window.c \
+       src/ui/gui/psppire-window.h \
+       src/ui/gui/psppire-window-register.c \
+       src/ui/gui/psppire-window-register.h \
+       src/ui/gui/psppire-syntax-window.c \
+       src/ui/gui/psppire-syntax-window.h
 
 nodist_src_ui_gui_psppire_SOURCES = \
        src/ui/gui/psppire-marshal.c \
index f425fac2364d2d285429b6fdd48a4db9485d2b8d..49d143cb6c51f379df11ad5172c789fada53a7f6 100644 (file)
 
 #include "psppire-dialog.h"
 #include "helper.h"
-#include "data-editor.h"
+#include "psppire-data-window.h"
+#include "psppire-data-editor.h"
 #include <language/syntax-string-source.h>
-#include "syntax-editor.h"
+#include "helper.h"
 #include "psppire-var-store.h"
 #include <ui/syntax-gen.h>
 
@@ -94,7 +95,7 @@ comments_dialog (GObject *o, gpointer data)
 {
   GtkTextIter iter;
   gint response ;
-  struct data_editor *de = data;
+  PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
   struct comment_dialog cd;
 
   GtkBuilder *xml = builder_new ("psppire.ui");
@@ -108,7 +109,7 @@ comments_dialog (GObject *o, gpointer data)
 
   g_object_get (de->data_editor, "var-store", &vs, NULL);
 
-  gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window);
+  gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de));
 
   {
     PangoContext * context ;
@@ -166,6 +167,7 @@ comments_dialog (GObject *o, gpointer data)
     case GTK_RESPONSE_OK:
       {
        gchar *syntax = generate_syntax (&cd);
+
        struct getl_interface *sss = create_syntax_string_source (syntax);
        execute_syntax (sss);
 
@@ -176,10 +178,7 @@ comments_dialog (GObject *o, gpointer data)
       {
        gchar *syntax = generate_syntax (&cd);
 
-       struct syntax_editor *se =
-         (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL);
-
-       gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1);
+       paste_syntax_in_new_window (syntax);
 
        g_free (syntax);
       }
index 76b9a7d1ce5e48d58faffc1810f78872bc763183..7269ab79750e76c3ed2cf5c7431045d5506545c3 100644 (file)
 #include "helper.h"
 #include "psppire-dialog.h"
 #include "psppire-keypad.h"
-#include "data-editor.h"
+#include "psppire-data-window.h"
 #include "psppire-var-store.h"
 #include "dialog-common.h"
 #include "dict-display.h"
 
 #include <language/expressions/public.h>
 #include <language/syntax-string-source.h>
-#include "syntax-editor.h"
+#include "helper.h"
 
 static void function_list_populate (GtkTreeView *tv);
 
@@ -365,7 +365,7 @@ void
 compute_dialog (GObject *o, gpointer data)
 {
   gint response;
-  struct data_editor *de = data;
+  PsppireDataWindow *de = data;
 
   PsppireVarStore *vs = NULL;
   struct compute_dialog scd;
@@ -394,7 +394,7 @@ compute_dialog (GObject *o, gpointer data)
   g_signal_connect (expression, "toggled",
                    G_CALLBACK(on_expression_toggle), &scd);
 
-  gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window);
+  gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de));
 
 
   attach_dictionary_to_treeview (GTK_TREE_VIEW (dict_view),
@@ -447,6 +447,7 @@ compute_dialog (GObject *o, gpointer data)
     case GTK_RESPONSE_OK:
       {
        gchar *syntax = generate_syntax (&scd);
+
        struct getl_interface *sss = create_syntax_string_source (syntax);
        execute_syntax (sss);
 
@@ -457,10 +458,7 @@ compute_dialog (GObject *o, gpointer data)
       {
        gchar *syntax = generate_syntax (&scd);
 
-       struct syntax_editor *se =
-         (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL);
-
-       gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1);
+       paste_syntax_in_new_window (syntax);
 
        g_free (syntax);
       }
index 2c50b461844d38de4587e1bcc9fcad01212b4d04..a3498d1f6d72c4b70b72a46ccc6569721898c29e 100644 (file)
 #include <stdlib.h>
 
 #include <language/syntax-string-source.h>
-#include <ui/gui/data-editor.h>
+#include <ui/gui/psppire-data-window.h>
 #include <ui/gui/dialog-common.h>
 #include <ui/gui/dict-display.h>
 #include "helper.h"
 #include <ui/gui/psppire-dialog.h>
 #include <ui/gui/psppire-var-store.h>
-#include <ui/gui/syntax-editor.h>
+#include <ui/gui/helper.h>
 
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
@@ -385,13 +385,15 @@ void
 crosstabs_dialog (GObject *o, gpointer data)
 {
   gint response;
-  struct data_editor *de = data;
-
   struct crosstabs_dialog cd;
 
   GtkBuilder *xml = builder_new ("crosstabs.ui");
+
   PsppireVarStore *vs = NULL;
 
+  PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
+
+
   GtkWidget *dialog = get_widget_assert   (xml, "crosstabs-dialog");
   GtkWidget *source = get_widget_assert   (xml, "dict-treeview");
   GtkWidget *dest_rows =   get_widget_assert   (xml, "rows");
@@ -419,7 +421,7 @@ crosstabs_dialog (GObject *o, gpointer data)
                                  cells
                                  );
 
-  gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window);
+  gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de));
 
   attach_dictionary_to_treeview (GTK_TREE_VIEW (source),
                                 vs->dict,
@@ -461,9 +463,9 @@ crosstabs_dialog (GObject *o, gpointer data)
   cd.current_opts.table = TRUE;
   cd.current_opts.pivot = TRUE;
 
-  gtk_window_set_transient_for (GTK_WINDOW (cd.format_dialog), de->parent.window);
-  gtk_window_set_transient_for (GTK_WINDOW (cd.cell_dialog), de->parent.window);
-  gtk_window_set_transient_for (GTK_WINDOW (cd.stat_dialog), de->parent.window);
+  gtk_window_set_transient_for (GTK_WINDOW (cd.format_dialog), GTK_WINDOW (de));
+  gtk_window_set_transient_for (GTK_WINDOW (cd.cell_dialog), GTK_WINDOW (de));
+  gtk_window_set_transient_for (GTK_WINDOW (cd.stat_dialog), GTK_WINDOW (de));
 
   g_signal_connect (dialog, "refresh", G_CALLBACK (refresh),  &cd);
 
@@ -485,6 +487,7 @@ crosstabs_dialog (GObject *o, gpointer data)
     case GTK_RESPONSE_OK:
       {
        gchar *syntax = generate_syntax (&cd);
+
        struct getl_interface *sss = create_syntax_string_source (syntax);
        execute_syntax (sss);
 
@@ -495,10 +498,7 @@ crosstabs_dialog (GObject *o, gpointer data)
       {
        gchar *syntax = generate_syntax (&cd);
 
-       struct syntax_editor *se =
-         (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL);
-
-       gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1);
+       paste_syntax_in_new_window (syntax);
 
        g_free (syntax);
       }
diff --git a/src/ui/gui/data-editor.c b/src/ui/gui/data-editor.c
deleted file mode 100644 (file)
index 13cc29a..0000000
+++ /dev/null
@@ -1,1699 +0,0 @@
-/* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2006, 2007, 2008  Free Software Foundation
-
-   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.
-
-   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 <gettext.h>
-
-#include <glade/glade.h>
-#include <gtk/gtk.h>
-
-#include "window-manager.h"
-
-#include "psppire-data-editor.h"
-
-#include "helper.h"
-#include "about.h"
-#include <data/procedure.h>
-#include "psppire-dialog.h"
-#include "psppire-selector.h"
-#include "weight-cases-dialog.h"
-#include "split-file-dialog.h"
-#include "transpose-dialog.h"
-#include "sort-cases-dialog.h"
-#include "select-cases-dialog.h"
-#include "compute-dialog.h"
-#include "goto-case-dialog.h"
-#include "find-dialog.h"
-#include "rank-dialog.h"
-#include "recode-dialog.h"
-#include "comments-dialog.h"
-#include "variable-info-dialog.h"
-#include "descriptives-dialog.h"
-#include "crosstabs-dialog.h"
-#include "frequencies-dialog.h"
-#include "examine-dialog.h"
-#include "dict-display.h"
-#include "regression-dialog.h"
-#include "text-data-import-dialog.h"
-
-#include "oneway-anova-dialog.h"
-#include "t-test-independent-samples-dialog.h"
-#include "t-test-one-sample.h"
-#include "t-test-paired-samples.h"
-
-#define _(msgid) gettext (msgid)
-#define N_(msgid) msgid
-
-#include "data-editor.h"
-#include "syntax-editor.h"
-#include <language/syntax-string-source.h>
-#include <language/command.h>
-#include <ui/syntax-gen.h>
-#include "window-manager.h"
-
-#include "psppire-data-store.h"
-#include "psppire-var-store.h"
-
-static void on_edit_copy (GtkMenuItem *, gpointer);
-static void on_edit_cut (GtkMenuItem *, gpointer);
-static void on_edit_paste (GtkAction *a, gpointer data);
-
-
-static GtkWidget * create_data_sheet_variable_popup_menu (struct data_editor *);
-
-static GtkWidget * create_var_sheet_variable_popup_menu (struct data_editor *);
-
-static GtkWidget * create_data_sheet_cases_popup_menu (struct data_editor *);
-
-static void register_data_editor_actions (struct data_editor *de);
-static void on_insert_variable (GtkAction *, gpointer data);
-static void insert_case (GtkAction *a, gpointer data);
-
-static void toggle_value_labels (GtkToggleAction *a, gpointer data);
-static void toggle_split_window (GtkToggleAction *ta, gpointer data);
-
-
-/* Callback for when the dictionary changes properties*/
-static void on_weight_change (GObject *, gint, gpointer);
-static void on_filter_change (GObject *, gint, gpointer);
-static void on_split_change (PsppireDict *, gpointer);
-
-static void on_switch_sheet (GtkNotebook *notebook,
-                           GtkNotebookPage *page,
-                           guint page_num,
-                           gpointer user_data);
-
-static void status_bar_activate (GtkCheckMenuItem *, gpointer);
-
-static void grid_lines_activate (GtkCheckMenuItem *, gpointer);
-
-static void data_view_activate (GtkCheckMenuItem *, gpointer);
-
-static void variable_view_activate (GtkCheckMenuItem *, gpointer );
-
-static void fonts_activate (GtkMenuItem *, gpointer);
-
-static void file_quit (GtkCheckMenuItem *, gpointer );
-
-static void
-enable_delete_cases (GtkWidget *w, gint case_num, gpointer data)
-{
-  struct data_editor *de = data;
-
-  gtk_action_set_visible (de->delete_cases, case_num != -1);
-}
-
-
-static void
-enable_delete_variables (GtkWidget *w, gint var, gpointer data)
-{
-  struct data_editor *de = data;
-
-  gtk_action_set_visible (de->delete_variables, var != -1);
-}
-
-
-
-/* Run the EXECUTE command. */
-static void
-execute (GtkMenuItem *mi, gpointer data)
-{
-  struct getl_interface *sss = create_syntax_string_source ("EXECUTE.");
-
-  execute_syntax (sss);
-}
-
-static void
-transformation_change_callback (bool transformations_pending,
-                               gpointer data)
-{
-  struct data_editor *de = data;
-  GtkWidget *menuitem =
-    get_widget_assert (de->xml, "transform_run-pending");
-  GtkWidget *status_label  =
-    get_widget_assert (de->xml, "case-counter-area");
-
-  gtk_widget_set_sensitive (menuitem, transformations_pending);
-
-
-  if ( transformations_pending)
-    gtk_label_set_text (GTK_LABEL (status_label),
-                       _("Transformations Pending"));
-  else
-    gtk_label_set_text (GTK_LABEL (status_label), "");
-}
-
-
-static void open_data_file (const gchar *, struct data_editor *);
-
-
-/* Puts FILE_NAME into the recent list.
-   If it's already in the list, it moves it to the top
-*/
-static void
-add_most_recent (const char *file_name)
-{
-#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);
-#endif
-}
-
-
-
-#if RECENT_LISTS_AVAILABLE
-
-static void
-on_recent_data_select (GtkMenuShell *menushell,   gpointer user_data)
-{
-  gchar *file;
-  struct data_editor *de = user_data;
-
-  gchar *uri =
-    gtk_recent_chooser_get_current_uri (GTK_RECENT_CHOOSER (menushell));
-
-  file = g_filename_from_uri (uri, NULL, NULL);
-
-  g_free (uri);
-
-  open_data_file (file, de);
-
-  g_free (file);
-}
-
-static void
-on_recent_files_select (GtkMenuShell *menushell,   gpointer user_data)
-{
-  gchar *file;
-
-  struct syntax_editor *se ;
-
-  gchar *uri =
-    gtk_recent_chooser_get_current_uri (GTK_RECENT_CHOOSER (menushell));
-
-  file = g_filename_from_uri (uri, NULL, NULL);
-
-  g_free (uri);
-
-  se = (struct syntax_editor *)
-    window_create (WINDOW_SYNTAX, file);
-
-  load_editor_from_file (se, file, NULL);
-
-  g_free (file);
-}
-
-#endif
-
-
-static void
-update_paste_menuitems (GtkWidget *w, gboolean x, gpointer data)
-{
-  struct data_editor *de = data;
-
-  GtkWidget * edit_paste = get_widget_assert (de->xml, "edit_paste");
-
-  gtk_widget_set_sensitive (edit_paste, x);
-}
-
-static void
-update_cut_copy_menuitems (GtkWidget *w, gboolean x, gpointer data)
-{
-  struct data_editor *de = data;
-
-  GtkWidget * edit_copy = get_widget_assert (de->xml, "edit_copy");
-  GtkWidget * edit_cut = get_widget_assert (de->xml, "edit_cut");
-
-  gtk_widget_set_sensitive (edit_copy, x);
-  gtk_widget_set_sensitive (edit_cut, x);
-}
-
-extern PsppireVarStore *the_var_store;
-extern struct dataset *the_dataset;
-extern PsppireDataStore *the_data_store ;
-
-
-/*
-  Create a new data editor.
-*/
-struct data_editor *
-new_data_editor (void)
-{
-  struct data_editor *de ;
-  struct editor_window *e;
-  PsppireVarStore *vs;
-  GtkWidget *vbox ;
-
-  de = g_malloc0 (sizeof (*de));
-
-  e = (struct editor_window *) de;
-
-  de->xml = XML_NEW ("data-editor.glade");
-
-
-  vbox = get_widget_assert (de->xml, "vbox1");
-
-  de->data_editor = PSPPIRE_DATA_EDITOR (psppire_data_editor_new (the_var_store, the_data_store));
-
-  g_signal_connect (de->data_editor, "data-selection-changed",
-                   G_CALLBACK (update_cut_copy_menuitems), de);
-
-  g_signal_connect (de->data_editor, "data-available-changed",
-                   G_CALLBACK (update_paste_menuitems), de);
-
-
-  gtk_widget_show (GTK_WIDGET (de->data_editor));
-
-  gtk_container_add (GTK_CONTAINER (vbox), GTK_WIDGET (de->data_editor));
-  gtk_box_reorder_child (GTK_BOX (vbox) , GTK_WIDGET (de->data_editor), 2);
-  dataset_add_transform_change_callback (the_dataset,
-                                        transformation_change_callback,
-                                        de);
-
-  vs = the_var_store;
-
-  g_assert(vs); /* Traps a possible bug in w32 build */
-
-  g_signal_connect (vs->dict, "weight-changed",
-                   G_CALLBACK (on_weight_change),
-                   de);
-
-  g_signal_connect (vs->dict, "filter-changed",
-                   G_CALLBACK (on_filter_change),
-                   de);
-
-  g_signal_connect (vs->dict, "split-changed",
-                   G_CALLBACK (on_split_change),
-                   de);
-
-  connect_help (de->xml);
-
-
-
-  g_signal_connect (get_widget_assert (de->xml, "edit_copy"),
-                   "activate",
-                   G_CALLBACK (on_edit_copy), de);
-
-  g_signal_connect (get_widget_assert (de->xml, "edit_cut"),
-                   "activate",
-                   G_CALLBACK (on_edit_cut), de);
-
-
-  register_data_editor_actions (de);
-
-  de->toggle_value_labels =
-    gtk_toggle_action_new ("toggle-value-labels",
-                          _("_Labels"),
-                          _("Show/hide value labels"),
-                          "pspp-value-labels");
-
-  g_signal_connect (de->toggle_value_labels, "toggled",
-                   G_CALLBACK (toggle_value_labels), de);
-
-
-  gtk_action_connect_proxy (GTK_ACTION (de->toggle_value_labels),
-                           get_widget_assert (de->xml,
-                                              "togglebutton-value-labels"));
-
-
-  gtk_action_connect_proxy (GTK_ACTION (de->toggle_value_labels),
-                           get_widget_assert (de->xml,
-                                              "view_value-labels"));
-
-  de->delete_cases =
-    gtk_action_new ("clear-cases",
-                   _("Clear"),
-                   _("Delete the cases at the selected position(s)"),
-                   "pspp-clear-cases");
-
-  g_signal_connect_swapped (de->delete_cases, "activate",
-                   G_CALLBACK (psppire_data_editor_delete_cases),
-                   de->data_editor);
-
-  gtk_action_connect_proxy (de->delete_cases,
-                           get_widget_assert (de->xml, "edit_clear-cases"));
-
-  g_signal_connect (get_widget_assert (de->xml, "edit_paste"), "activate",
-                   G_CALLBACK (on_edit_paste),
-                   de);
-
-  gtk_action_set_visible (de->delete_cases, FALSE);
-
-  de->delete_variables =
-    gtk_action_new ("clear-variables",
-                   _("Clear"),
-                   _("Delete the variables at the selected position(s)"),
-                   "pspp-clear-variables");
-
-  g_signal_connect_swapped (de->delete_variables, "activate",
-                           G_CALLBACK (psppire_data_editor_delete_variables),
-                           de->data_editor);
-
-  gtk_action_connect_proxy (de->delete_variables,
-                           get_widget_assert (de->xml, "edit_clear-variables")
-                           );
-
-  gtk_action_set_visible (de->delete_variables, FALSE);
-
-  de->insert_variable =
-    gtk_action_new ("insert-variable",
-                   _("Insert _Variable"),
-                   _("Create a new variable at the current position"),
-                   "pspp-insert-variable");
-
-  g_signal_connect (de->insert_variable, "activate",
-                   G_CALLBACK (on_insert_variable), de->data_editor);
-
-
-  gtk_action_connect_proxy (de->insert_variable,
-                           get_widget_assert (de->xml, "button-insert-variable")
-                           );
-
-  gtk_action_connect_proxy (de->insert_variable,
-                           get_widget_assert (de->xml, "edit_insert-variable")
-                           );
-
-
-  de->insert_case =
-    gtk_action_new ("insert-case",
-                   _("Insert Ca_se"),
-                   _("Create a new case at the current position"),
-                   "pspp-insert-case");
-
-  g_signal_connect (de->insert_case, "activate",
-                   G_CALLBACK (insert_case), de);
-
-
-  gtk_action_connect_proxy (de->insert_case,
-                           get_widget_assert (de->xml, "button-insert-case")
-                           );
-
-
-  gtk_action_connect_proxy (de->insert_case,
-                           get_widget_assert (de->xml, "edit_insert-case")
-                           );
-
-
-
-  de->invoke_goto_dialog =
-    gtk_action_new ("goto-case-dialog",
-                   _("_Goto Case"),
-                   _("Jump to a Case in the Data Sheet"),
-                   "gtk-jump-to");
-
-
-  gtk_action_connect_proxy (de->invoke_goto_dialog,
-                           get_widget_assert (de->xml, "button-goto-case")
-                           );
-
-  gtk_action_connect_proxy (de->invoke_goto_dialog,
-                           get_widget_assert (de->xml, "edit_goto-case")
-                           );
-
-
-  g_signal_connect (de->invoke_goto_dialog, "activate",
-                   G_CALLBACK (goto_case_dialog), de);
-
-
-  de->invoke_weight_cases_dialog =
-    gtk_action_new ("weight-cases-dialog",
-                   _("_Weights"),
-                   _("Weight cases by variable"),
-                   "pspp-weight-cases");
-
-  g_signal_connect (de->invoke_weight_cases_dialog, "activate",
-                   G_CALLBACK (weight_cases_dialog), de);
-
-
-  de->invoke_transpose_dialog =
-    gtk_action_new ("transpose-dialog",
-                   _("_Transpose"),
-                   _("Transpose the cases with the variables"),
-                   NULL);
-
-
-  g_signal_connect (de->invoke_transpose_dialog, "activate",
-                   G_CALLBACK (transpose_dialog), de);
-
-
-
-  de->invoke_split_file_dialog =
-    gtk_action_new ("split-file-dialog",
-                   _("S_plit"),
-                   _("Split the active file"),
-                   "pspp-split-file");
-
-  g_signal_connect (de->invoke_split_file_dialog, "activate",
-                   G_CALLBACK (split_file_dialog), de);
-
-
-
-  de->invoke_sort_cases_dialog =
-    gtk_action_new ("sort-cases-dialog",
-                   _("_Sort"),
-                   _("Sort cases in the active file"),
-                   "pspp-sort-cases");
-
-  g_signal_connect (de->invoke_sort_cases_dialog, "activate",
-                   G_CALLBACK (sort_cases_dialog), de);
-
-  de->invoke_select_cases_dialog =
-    gtk_action_new ("select-cases-dialog",
-                   _("Select _Cases"),
-                   _("Select cases from the active file"),
-                   "pspp-select-cases");
-
-  g_signal_connect (de->invoke_select_cases_dialog, "activate",
-                   G_CALLBACK (select_cases_dialog), de);
-
-
-  de->invoke_compute_dialog =
-    gtk_action_new ("compute-dialog",
-                   _("_Compute"),
-                   _("Compute new values for a variable"),
-                   "pspp-compute");
-
-  g_signal_connect (de->invoke_compute_dialog, "activate",
-                   G_CALLBACK (compute_dialog), de);
-
-  de->invoke_oneway_anova_dialog =
-    gtk_action_new ("oneway-anova",
-                   _("Oneway _ANOVA"),
-                   _("Perform one way analysis of variance"),
-                   NULL);
-
-  g_signal_connect (de->invoke_oneway_anova_dialog, "activate",
-                   G_CALLBACK (oneway_anova_dialog), de);
-
-  de->invoke_t_test_independent_samples_dialog =
-    gtk_action_new ("t-test-independent-samples",
-                   _("_Independent Samples T Test"),
-                   _("Calculate T Test for samples from independent groups"),
-                   NULL);
-
-  g_signal_connect (de->invoke_t_test_independent_samples_dialog, "activate",
-                   G_CALLBACK (t_test_independent_samples_dialog), de);
-
-
-  de->invoke_t_test_paired_samples_dialog =
-    gtk_action_new ("t-test-paired-samples",
-                   _("_Paired Samples T Test"),
-                   _("Calculate T Test for paired samples"),
-                   NULL);
-
-  g_signal_connect (de->invoke_t_test_paired_samples_dialog, "activate",
-                   G_CALLBACK (t_test_paired_samples_dialog), de);
-
-
-  de->invoke_t_test_one_sample_dialog =
-    gtk_action_new ("t-test-one-sample",
-                   _("One _Sample T Test"),
-                   _("Calculate T Test for sample from a single distribution"),
-                   NULL);
-
-  g_signal_connect (de->invoke_t_test_one_sample_dialog, "activate",
-                   G_CALLBACK (t_test_one_sample_dialog), de);
-
-
-  de->invoke_comments_dialog =
-    gtk_action_new ("commments-dialog",
-                   _("Data File _Comments"),
-                   _("Commentary text for the data file"),
-                   NULL);
-
-  g_signal_connect (de->invoke_comments_dialog, "activate",
-                   G_CALLBACK (comments_dialog), de);
-
-  de->invoke_find_dialog  =
-    gtk_action_new ("find-dialog",
-                   _("_Find"),
-                   _("Find Case"),
-                   "gtk-find");
-
-  g_signal_connect (de->invoke_find_dialog, "activate",
-                   G_CALLBACK (find_dialog), de);
-
-
-  de->invoke_rank_dialog  =
-    gtk_action_new ("rank-dialog",
-                   _("Ran_k Cases"),
-                   _("Rank Cases"),
-                   "pspp-rank-cases");
-
-  g_signal_connect (de->invoke_rank_dialog, "activate",
-                   G_CALLBACK (rank_dialog), de);
-
-
-  de->invoke_recode_same_dialog  =
-    gtk_action_new ("recode-same-dialog",
-                   _("Recode into _Same Variables"),
-                   _("Recode values into the same Variables"),
-                   "pspp-recode-same");
-
-  g_signal_connect (de->invoke_recode_same_dialog, "activate",
-                   G_CALLBACK (recode_same_dialog), de);
-
-
-  de->invoke_recode_different_dialog  =
-    gtk_action_new ("recode-different-dialog",
-                   _("Recode into _Different Variables"),
-                   _("Recode values into different Variables"),
-                   "pspp-recode-different");
-
-  g_signal_connect (de->invoke_recode_different_dialog, "activate",
-                   G_CALLBACK (recode_different_dialog), de);
-
-
-  de->invoke_variable_info_dialog  =
-    gtk_action_new ("variable-info-dialog",
-                   _("_Variables"),
-                   _("Jump to Variable"),
-                   "pspp-goto-variable");
-
-  g_signal_connect (de->invoke_variable_info_dialog, "activate",
-                   G_CALLBACK (variable_info_dialog), de);
-
-  de->invoke_descriptives_dialog =
-    gtk_action_new ("descriptives-dialog",
-                   _("_Descriptives"),
-                   _("Calculate descriptive statistics (mean, variance, ...)"),
-                   "pspp-descriptives");
-
-  g_signal_connect (de->invoke_descriptives_dialog, "activate",
-                   G_CALLBACK (descriptives_dialog), de);
-
-
-  de->invoke_frequencies_dialog =
-    gtk_action_new ("frequencies-dialog",
-                   _("_Frequencies"),
-                   _("Generate frequency statistics"),
-                   "pspp-frequencies");
-
-  g_signal_connect (de->invoke_frequencies_dialog, "activate",
-                   G_CALLBACK (frequencies_dialog), de);
-
-  de->invoke_crosstabs_dialog =
-    gtk_action_new ("crosstabs-dialog",
-                   _("_Crosstabs"),
-                   _("Generate crosstabulations"),
-                   "pspp-crosstabs");
-
-  g_signal_connect (de->invoke_crosstabs_dialog, "activate",
-                   G_CALLBACK (crosstabs_dialog), de);
-
-
-  de->invoke_examine_dialog =
-    gtk_action_new ("examine-dialog",
-                   _("_Explore"),
-                   _("Examine Data by Factors"),
-                   "pspp-examine");
-
-  g_signal_connect (de->invoke_examine_dialog, "activate",
-                   G_CALLBACK (examine_dialog), de);
-
-
-  de->invoke_regression_dialog =
-    gtk_action_new ("regression-dialog",
-                   _("Linear _Regression"),
-                   _("Estimate parameters of the linear model"),
-                   "pspp-regression");
-
-  g_signal_connect (de->invoke_regression_dialog, "activate",
-                   G_CALLBACK (regression_dialog), de);
-
-  e->window = GTK_WINDOW (get_widget_assert (de->xml, "data_editor"));
-
-  g_signal_connect_swapped (get_widget_assert (de->xml,"file_new_data"),
-                           "activate",
-                           G_CALLBACK (gtk_action_activate),
-                           de->action_data_new);
-
-  g_signal_connect_swapped (get_widget_assert (de->xml,"file_open_data"),
-                           "activate",
-                           G_CALLBACK (gtk_action_activate),
-                           de->action_data_open);
-
-#if RECENT_LISTS_AVAILABLE
-  {
-    GtkRecentManager *rm = gtk_recent_manager_get_default ();
-    GtkWidget *recent_data = get_widget_assert (de->xml, "file_recent-data");
-    GtkWidget *recent_files = get_widget_assert (de->xml, "file_recent-files");
-    GtkWidget *recent_separator = get_widget_assert (de->xml, "file_separator1");
-
-    GtkWidget *menu = gtk_recent_chooser_menu_new_for_manager (rm);
-
-    GtkRecentFilter *filter = gtk_recent_filter_new ();
-
-    gtk_widget_show (recent_data);
-    gtk_widget_show (recent_files);
-    gtk_widget_show (recent_separator);
-
-    gtk_recent_filter_add_pattern (filter, "*.sav");
-    gtk_recent_filter_add_pattern (filter, "*.SAV");
-
-    gtk_recent_chooser_add_filter (GTK_RECENT_CHOOSER (menu), filter);
-
-    gtk_widget_set_sensitive (recent_data, TRUE);
-    g_signal_connect (menu, "selection-done",
-                     G_CALLBACK (on_recent_data_select), de);
-
-    gtk_menu_item_set_submenu (GTK_MENU_ITEM (recent_data), menu);
-
-
-    filter = gtk_recent_filter_new ();
-    menu = gtk_recent_chooser_menu_new_for_manager (rm);
-
-    gtk_recent_filter_add_pattern (filter, "*.sps");
-    gtk_recent_filter_add_pattern (filter, "*.SPS");
-
-    gtk_recent_chooser_add_filter (GTK_RECENT_CHOOSER (menu), filter);
-
-    gtk_widget_set_sensitive (recent_files, TRUE);
-    g_signal_connect (menu, "selection-done",
-                     G_CALLBACK (on_recent_files_select), de);
-
-    gtk_menu_item_set_submenu (GTK_MENU_ITEM (recent_files), menu);
-  }
-#endif
-
-  g_signal_connect (get_widget_assert (de->xml,"file_new_syntax"),
-                   "activate",
-                   G_CALLBACK (new_syntax_window),
-                   e->window);
-
-  g_signal_connect (get_widget_assert (de->xml,"file_open_syntax"),
-                   "activate",
-                   G_CALLBACK (open_syntax_window),
-                   e->window);
-
-  g_signal_connect_swapped (get_widget_assert (de->xml,"file_import-text"),
-                           "activate",
-                           G_CALLBACK (gtk_action_activate),
-                           de->invoke_text_import_assistant);
-
-  g_signal_connect_swapped (get_widget_assert (de->xml,"file_save"),
-                           "activate",
-                           G_CALLBACK (gtk_action_activate),
-                           de->action_data_save);
-
-  g_signal_connect_swapped (get_widget_assert (de->xml,"file_save_as"),
-                           "activate",
-                           G_CALLBACK (gtk_action_activate),
-                           de->action_data_save_as);
-
-  gtk_action_connect_proxy (de->invoke_find_dialog,
-                           get_widget_assert (de->xml, "edit_find")
-                           );
-
-  gtk_action_connect_proxy (de->invoke_find_dialog,
-                           get_widget_assert (de->xml, "button-find")
-                           );
-
-  gtk_action_connect_proxy (de->invoke_rank_dialog,
-                           get_widget_assert (de->xml, "transform_rank")
-                           );
-
-  gtk_action_connect_proxy (de->invoke_recode_same_dialog,
-                           get_widget_assert (de->xml,
-                                              "transform_recode-same")
-                           );
-
-  gtk_action_connect_proxy (de->invoke_recode_different_dialog,
-                           get_widget_assert (de->xml,
-                                              "transform_recode-different")
-                           );
-
-  gtk_action_connect_proxy (de->invoke_weight_cases_dialog,
-                           get_widget_assert (de->xml, "data_weight-cases")
-                           );
-
-  gtk_action_connect_proxy (de->invoke_transpose_dialog,
-                           get_widget_assert (de->xml, "data_transpose")
-                           );
-
-  gtk_action_connect_proxy (de->invoke_split_file_dialog,
-                           get_widget_assert (de->xml, "data_split-file")
-                           );
-
-  gtk_action_connect_proxy (de->invoke_sort_cases_dialog,
-                           get_widget_assert (de->xml, "data_sort-cases")
-                           );
-
-  gtk_action_connect_proxy (de->invoke_select_cases_dialog,
-                           get_widget_assert (de->xml, "data_select-cases")
-                           );
-
-  gtk_action_connect_proxy (de->invoke_compute_dialog,
-                           get_widget_assert (de->xml, "transform_compute")
-                           );
-
-  gtk_action_connect_proxy (de->invoke_t_test_independent_samples_dialog,
-                           get_widget_assert (de->xml,
-                                              "indep-t-test")
-                           );
-
-
-  gtk_action_connect_proxy (de->invoke_t_test_paired_samples_dialog,
-                           get_widget_assert (de->xml,
-                                              "paired-t-test")
-                           );
-
-
-  gtk_action_connect_proxy (de->invoke_t_test_one_sample_dialog,
-                           get_widget_assert (de->xml,
-                                              "one-sample-t-test")
-                           );
-
-
-  gtk_action_connect_proxy (de->invoke_oneway_anova_dialog,
-                           get_widget_assert (de->xml,
-                                              "oneway-anova")
-                           );
-
-
-  gtk_action_connect_proxy (de->invoke_comments_dialog,
-                           get_widget_assert (de->xml, "utilities_comments")
-                           );
-
-  gtk_action_connect_proxy (de->invoke_variable_info_dialog,
-                           get_widget_assert (de->xml, "utilities_variables")
-                           );
-
-  gtk_action_connect_proxy (de->invoke_descriptives_dialog,
-                           get_widget_assert (de->xml, "analyze_descriptives")
-                           );
-
-  gtk_action_connect_proxy (de->invoke_crosstabs_dialog,
-                           get_widget_assert (de->xml, "crosstabs")
-                           );
-
-  gtk_action_connect_proxy (de->invoke_frequencies_dialog,
-                           get_widget_assert (de->xml, "analyze_frequencies")
-                           );
-
-
-  gtk_action_connect_proxy (de->invoke_examine_dialog,
-                           get_widget_assert (de->xml, "analyze_explore")
-                           );
-
-  gtk_action_connect_proxy (de->invoke_regression_dialog,
-                           get_widget_assert (de->xml, "linear-regression")
-                           );
-
-  g_signal_connect (get_widget_assert (de->xml,"help_about"),
-                   "activate",
-                   G_CALLBACK (about_new),
-                   e->window);
-
-
-  g_signal_connect (get_widget_assert (de->xml,"help_reference"),
-                   "activate",
-                   G_CALLBACK (reference_manual),
-                   e->window);
-
-
-  g_signal_connect (de->data_editor,
-                   "cases-selected",
-                   G_CALLBACK (enable_delete_cases),
-                   de);
-
-
-  g_signal_connect (de->data_editor,
-                   "variables-selected",
-                   G_CALLBACK (enable_delete_variables),
-                   de);
-
-
-  g_signal_connect (GTK_NOTEBOOK (de->data_editor),
-                   "switch-page",
-                   G_CALLBACK (on_switch_sheet), de);
-
-  gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_VARIABLE_VIEW);
-  gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_DATA_VIEW);
-
-  g_signal_connect (get_widget_assert (de->xml, "view_statusbar"),
-                   "activate",
-                   G_CALLBACK (status_bar_activate), de);
-
-
-  g_signal_connect (get_widget_assert (de->xml, "view_gridlines"),
-                   "activate",
-                   G_CALLBACK (grid_lines_activate), de);
-
-
-
-  g_signal_connect (get_widget_assert (de->xml, "view_data"),
-                   "activate",
-                   G_CALLBACK (data_view_activate), de);
-
-  g_signal_connect (get_widget_assert (de->xml, "view_variables"),
-                   "activate",
-                   G_CALLBACK (variable_view_activate), de);
-
-
-
-  g_signal_connect (get_widget_assert (de->xml, "view_fonts"),
-                   "activate",
-                   G_CALLBACK (fonts_activate), de);
-
-
-
-
-  gtk_action_connect_proxy (de->action_data_open,
-                           get_widget_assert (de->xml, "button-open")
-                           );
-
-  gtk_action_connect_proxy (de->action_data_save,
-                           get_widget_assert (de->xml, "button-save")
-                           );
-
-  gtk_action_connect_proxy (de->invoke_variable_info_dialog,
-                           get_widget_assert (de->xml, "button-goto-variable")
-                           );
-
-  gtk_action_connect_proxy (de->invoke_weight_cases_dialog,
-                           get_widget_assert (de->xml, "button-weight-cases")
-                           );
-
-  gtk_action_connect_proxy (de->invoke_split_file_dialog,
-                           get_widget_assert (de->xml, "button-split-file")
-                           );
-
-  gtk_action_connect_proxy (de->invoke_select_cases_dialog,
-                           get_widget_assert (de->xml, "button-select-cases")
-                           );
-
-
-  g_signal_connect (get_widget_assert (de->xml, "file_quit"),
-                   "activate",
-                   G_CALLBACK (file_quit), de);
-
-  g_signal_connect (get_widget_assert (de->xml, "transform_run-pending"),
-                   "activate",
-                   G_CALLBACK (execute), de);
-
-
-  g_signal_connect (get_widget_assert (de->xml, "windows_minimise_all"),
-                   "activate",
-                   G_CALLBACK (minimise_all_windows), NULL);
-
-  de->toggle_split_window =
-    gtk_toggle_action_new ("toggle-split-window",
-                          _("_Split Window"),
-                          _("Split the window vertically and horizontally"),
-                          "pspp-split-window");
-
-  g_signal_connect (de->toggle_split_window, "toggled",
-                   G_CALLBACK (toggle_split_window),
-                   de);
-
-  gtk_action_connect_proxy (GTK_ACTION (de->toggle_split_window),
-                           get_widget_assert (de->xml,
-                                              "windows_split"));
-
-  de->data_sheet_variable_popup_menu =
-    GTK_MENU (create_data_sheet_variable_popup_menu (de));
-
-  de->var_sheet_variable_popup_menu =
-    GTK_MENU (create_var_sheet_variable_popup_menu (de));
-
-  de->data_sheet_cases_popup_menu =
-    GTK_MENU (create_data_sheet_cases_popup_menu (de));
-
-
-  g_object_set (de->data_editor,
-               "datasheet-column-menu", de->data_sheet_variable_popup_menu,
-               "datasheet-row-menu", de->data_sheet_cases_popup_menu,
-               "varsheet-row-menu", de->var_sheet_variable_popup_menu,
-               NULL);
-
-
-  return de;
-}
-
-
-void
-new_data_window (GtkMenuItem *menuitem, gpointer parent)
-{
-  window_create (WINDOW_DATA, NULL);
-}
-
-/* Callback for when the datasheet/varsheet is selected */
-static void
-on_switch_sheet (GtkNotebook *notebook,
-               GtkNotebookPage *page,
-               guint page_num,
-               gpointer user_data)
-{
-  struct data_editor *de = user_data;
-
-  GtkWidget *view_data = get_widget_assert (de->xml, "view_data");
-  GtkWidget *view_variables = get_widget_assert (de->xml, "view_variables");
-
-  switch (page_num)
-    {
-    case PSPPIRE_DATA_EDITOR_VARIABLE_VIEW:
-      gtk_widget_hide (view_variables);
-      gtk_widget_show (view_data);
-      gtk_action_set_sensitive (de->insert_variable, TRUE);
-      gtk_action_set_sensitive (de->insert_case, FALSE);
-      gtk_action_set_sensitive (de->invoke_goto_dialog, FALSE);
-      break;
-    case PSPPIRE_DATA_EDITOR_DATA_VIEW:
-      gtk_widget_show (view_variables);
-      gtk_widget_hide (view_data);
-      gtk_action_set_sensitive (de->invoke_goto_dialog, TRUE);
-      gtk_action_set_sensitive (de->insert_case, TRUE);
-      break;
-    default:
-      g_assert_not_reached ();
-      break;
-    }
-
-#if 0
-  update_paste_menuitem (de, page_num);
-#endif
-}
-
-
-static void
-status_bar_activate (GtkCheckMenuItem *menuitem, gpointer data)
-{
-  struct data_editor *de = data;
-  GtkWidget *statusbar = get_widget_assert (de->xml, "status-bar");
-
-  if ( gtk_check_menu_item_get_active (menuitem) )
-    gtk_widget_show (statusbar);
-  else
-    gtk_widget_hide (statusbar);
-}
-
-
-static void
-grid_lines_activate (GtkCheckMenuItem *menuitem, gpointer data)
-{
-  struct data_editor *de = data;
-  const gboolean grid_visible = gtk_check_menu_item_get_active (menuitem);
-
-  psppire_data_editor_show_grid (de->data_editor, grid_visible);
-}
-
-
-
-static void
-data_view_activate (GtkCheckMenuItem *menuitem, gpointer data)
-{
-  struct data_editor *de = data;
-
-  gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_DATA_VIEW);
-}
-
-
-static void
-variable_view_activate (GtkCheckMenuItem *menuitem, gpointer data)
-{
-  struct data_editor *de = data;
-
-  gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_VARIABLE_VIEW);
-}
-
-
-static void
-fonts_activate (GtkMenuItem *menuitem, gpointer data)
-{
-  struct data_editor *de = data;
-  PangoFontDescription *current_font;
-  gchar *font_name;
-  GtkWidget *dialog =
-    gtk_font_selection_dialog_new (_("Font Selection"));
-
-
-  current_font = GTK_WIDGET(de->data_editor)->style->font_desc;
-  font_name = pango_font_description_to_string (current_font);
-
-  gtk_font_selection_dialog_set_font_name (GTK_FONT_SELECTION_DIALOG (dialog), font_name);
-
-  g_free (font_name);
-
-  gtk_window_set_transient_for (GTK_WINDOW (dialog),
-                               GTK_WINDOW (get_widget_assert (de->xml,
-                                                              "data_editor")));
-  if ( GTK_RESPONSE_OK == gtk_dialog_run (GTK_DIALOG (dialog)) )
-    {
-      const gchar *font = gtk_font_selection_dialog_get_font_name
-       (GTK_FONT_SELECTION_DIALOG (dialog));
-
-      PangoFontDescription* font_desc =
-       pango_font_description_from_string (font);
-
-      psppire_data_editor_set_font (de->data_editor, font_desc);
-    }
-
-  gtk_widget_hide (dialog);
-}
-
-
-
-/* Callback for the value labels action */
-static void
-toggle_value_labels (GtkToggleAction *ta, gpointer data)
-{
-  struct data_editor *de = data;
-
-  g_object_set (de->data_editor, "value-labels", gtk_toggle_action_get_active (ta), NULL);
-}
-
-
-
-static void
-toggle_split_window (GtkToggleAction *ta, gpointer data)
-{
-  struct data_editor *de = data;
-
-  psppire_data_editor_split_window (de->data_editor,
-                                   gtk_toggle_action_get_active (ta));
-}
-
-
-
-
-static void
-file_quit (GtkCheckMenuItem *menuitem, gpointer data)
-{
-  /* FIXME: Need to be more intelligent here.
-     Give the user the opportunity to save any unsaved data.
-  */
-  g_object_unref (the_data_store);
-  gtk_main_quit ();
-}
-
-
-static void
-insert_case (GtkAction *action, gpointer data)
-{
-  struct data_editor *de = data;
-
-  psppire_data_editor_insert_case (de->data_editor);
-}
-
-static void
-on_insert_variable (GtkAction *action, gpointer data)
-{
-  PsppireDataEditor *de = PSPPIRE_DATA_EDITOR (data);
-  psppire_data_editor_insert_variable (de);
-}
-
-
-/* Callback for when the dictionary changes its split variables */
-static void
-on_split_change (PsppireDict *dict, gpointer data)
-{
-  struct data_editor *de = data;
-
-  size_t n_split_vars = dict_get_split_cnt (dict->dict);
-
-  GtkWidget *split_status_area =
-    get_widget_assert (de->xml, "split-file-status-area");
-
-  if ( n_split_vars == 0 )
-    {
-      gtk_label_set_text (GTK_LABEL (split_status_area), _("No Split"));
-    }
-  else
-    {
-      gint i;
-      GString *text;
-      const struct variable *const * split_vars =
-       dict_get_split_vars (dict->dict);
-
-      text = g_string_new (_("Split by "));
-
-      for (i = 0 ; i < n_split_vars - 1; ++i )
-       {
-         g_string_append_printf (text, "%s, ", var_get_name (split_vars[i]));
-       }
-      g_string_append (text, var_get_name (split_vars[i]));
-
-      gtk_label_set_text (GTK_LABEL (split_status_area), text->str);
-
-      g_string_free (text, TRUE);
-    }
-}
-
-
-/* Callback for when the dictionary changes its filter variable */
-static void
-on_filter_change (GObject *o, gint filter_index, gpointer data)
-{
-  struct data_editor *de = data;
-  GtkWidget *filter_status_area =
-    get_widget_assert (de->xml, "filter-use-status-area");
-
-  if ( filter_index == -1 )
-    {
-      gtk_label_set_text (GTK_LABEL (filter_status_area), _("Filter off"));
-    }
-  else
-    {
-      PsppireVarStore *vs = NULL;
-      struct variable *var ;
-      gchar *text ;
-
-      g_object_get (de->data_editor, "var-store", &vs, NULL);
-
-      var = psppire_dict_get_variable (vs->dict, filter_index);
-
-      text = g_strdup_printf (_("Filter by %s"), var_get_name (var));
-
-      gtk_label_set_text (GTK_LABEL (filter_status_area), text);
-
-      g_free (text);
-    }
-}
-
-/* Callback for when the dictionary changes its weights */
-static void
-on_weight_change (GObject *o, gint weight_index, gpointer data)
-{
-  struct data_editor *de = data;
-  GtkWidget *weight_status_area =
-    get_widget_assert (de->xml, "weight-status-area");
-
-  if ( weight_index == -1 )
-    {
-      gtk_label_set_text (GTK_LABEL (weight_status_area), _("Weights off"));
-    }
-  else
-    {
-      struct variable *var ;
-      PsppireVarStore *vs = NULL;
-      gchar *text;
-
-      g_object_get (de->data_editor, "var-store", &vs, NULL);
-
-      var = psppire_dict_get_variable (vs->dict, weight_index);
-
-      text = g_strdup_printf (_("Weight by %s"), var_get_name (var));
-
-      gtk_label_set_text (GTK_LABEL (weight_status_area), text);
-
-      g_free (text);
-    }
-}
-
-
-
-\f
-static void data_save_as_dialog (GtkAction *, struct data_editor *de);
-static void new_file (GtkAction *, struct editor_window *de);
-static void open_data_dialog (GtkAction *, struct data_editor *de);
-static void data_save (GtkAction *action, struct data_editor *e);
-
-
-/* Create the GtkActions and connect to their signals */
-static void
-register_data_editor_actions (struct data_editor *de)
-{
-  de->action_data_open =
-    gtk_action_new ("data-open-dialog",
-                   _("Open"),
-                   _("Open a data file"),
-                   "gtk-open");
-
-  g_signal_connect (de->action_data_open, "activate",
-                   G_CALLBACK (open_data_dialog), de);
-
-
-  de->action_data_save = gtk_action_new ("data-save",
-                                           _("Save"),
-                                           _("Save data to file"),
-                                           "gtk-save");
-
-  g_signal_connect (de->action_data_save, "activate",
-                   G_CALLBACK (data_save), de);
-
-
-
-  de->action_data_save_as = gtk_action_new ("data-save-as-dialog",
-                                           _("Save As"),
-                                           _("Save data to file"),
-                                           "gtk-save");
-
-  g_signal_connect (de->action_data_save_as, "activate",
-                   G_CALLBACK (data_save_as_dialog), de);
-
-  de->action_data_new =
-    gtk_action_new ("data-new",
-                   _("New"),
-                   _("New data file"),
-                   NULL);
-
-  g_signal_connect (de->action_data_new, "activate",
-                   G_CALLBACK (new_file), de);
-
-  de->invoke_text_import_assistant =
-    gtk_action_new ("file_import-text",
-                   _("_Import Text Data"),
-                   _("Import text data file"),
-                   "");
-
-  g_signal_connect (de->invoke_text_import_assistant, "activate",
-                   G_CALLBACK (text_data_import_assistant), de);
-}
-
-/* Returns true if NAME has a suffix which might denote a PSPP file */
-static gboolean
-name_has_suffix (const gchar *name)
-{
-  if ( g_str_has_suffix (name, ".sav"))
-    return TRUE;
-  if ( g_str_has_suffix (name, ".SAV"))
-    return TRUE;
-  if ( g_str_has_suffix (name, ".por"))
-    return TRUE;
-  if ( g_str_has_suffix (name, ".POR"))
-    return TRUE;
-
-  return FALSE;
-}
-
-/* Append SUFFIX to the filename of DE */
-static void
-append_filename_suffix (struct data_editor *de, const gchar *suffix)
-{
-  if ( ! name_has_suffix (de->file_name))
-    {
-      gchar *s = de->file_name;
-      de->file_name = g_strconcat (de->file_name, suffix, NULL);
-      g_free (s);
-    }
-}
-
-/* Save DE to file */
-static void
-save_file (struct data_editor *de)
-{
-  struct getl_interface *sss;
-  struct string file_name ;
-
-  g_assert (de->file_name);
-
-  ds_init_empty (&file_name);
-  syntax_gen_string (&file_name, ss_cstr (de->file_name));
-
-  if ( de->save_as_portable )
-    {
-      append_filename_suffix (de, ".por");
-      sss = create_syntax_string_source ("EXPORT OUTFILE=%s.",
-                                        ds_cstr (&file_name));
-    }
-  else
-    {
-      append_filename_suffix (de, ".sav");
-      sss = create_syntax_string_source ("SAVE OUTFILE=%s.",
-                                        ds_cstr (&file_name));
-    }
-
-  ds_destroy (&file_name);
-
-  execute_syntax (sss);
-}
-
-
-/* Callback for data_save action.
-   If there's an existing file name, then just save,
-   otherwise prompt for a file name, then save */
-static void
-data_save (GtkAction *action, struct data_editor *de)
-{
-  if ( de->file_name)
-    save_file (de);
-  else
-    data_save_as_dialog (action, de);
-}
-
-
-/* Callback for data_save_as action. Prompt for a filename and save */
-static void
-data_save_as_dialog (GtkAction *action, struct data_editor *de)
-{
-  struct editor_window *e = (struct editor_window *) de;
-
-  GtkWidget *button_sys;
-  GtkWidget *dialog =
-    gtk_file_chooser_dialog_new (_("Save"),
-                                GTK_WINDOW (e->window),
-                                GTK_FILE_CHOOSER_ACTION_SAVE,
-                                GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-                                GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
-                                NULL);
-
-  GtkFileFilter *filter = gtk_file_filter_new ();
-  gtk_file_filter_set_name (filter, _("System Files (*.sav)"));
-  gtk_file_filter_add_pattern (filter, "*.sav");
-  gtk_file_filter_add_pattern (filter, "*.SAV");
-  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
-
-  filter = gtk_file_filter_new ();
-  gtk_file_filter_set_name (filter, _("Portable Files (*.por) "));
-  gtk_file_filter_add_pattern (filter, "*.por");
-  gtk_file_filter_add_pattern (filter, "*.POR");
-  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);
-
-  {
-    GtkWidget *button_por;
-    GtkWidget *vbox = gtk_vbox_new (TRUE, 5);
-    button_sys =
-      gtk_radio_button_new_with_label (NULL, _("System File"));
-
-    button_por =
-      gtk_radio_button_new_with_label
-      (gtk_radio_button_get_group (GTK_RADIO_BUTTON(button_sys)),
-       _("Portable File"));
-
-    gtk_box_pack_start_defaults (GTK_BOX (vbox), button_sys);
-    gtk_box_pack_start_defaults (GTK_BOX (vbox), button_por);
-
-    gtk_widget_show_all (vbox);
-
-    gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER(dialog), vbox);
-  }
-
-  switch (gtk_dialog_run (GTK_DIALOG (dialog)))
-    {
-    case GTK_RESPONSE_ACCEPT:
-      {
-       g_free (de->file_name);
-
-       de->file_name =
-         gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
-
-       de->save_as_portable =
-         ! gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button_sys));
-
-       if ( de->save_as_portable)
-         append_filename_suffix (de, ".por");
-       else
-         append_filename_suffix (de, ".sav");
-
-       save_file (de);
-
-       window_set_name_from_filename (e, de->file_name);
-      }
-      break;
-    default:
-      break;
-    }
-
-  gtk_widget_destroy (dialog);
-}
-
-
-/* Callback for data_new action.
-   Performs the NEW FILE command */
-static void
-new_file (GtkAction *action, struct editor_window *e)
-{
-  struct data_editor *de = (struct data_editor *) e;
-
-  struct getl_interface *sss =
-    create_syntax_string_source ("NEW FILE.");
-
-  execute_syntax (sss);
-
-  g_free (de->file_name);
-  de->file_name = NULL;
-
-  default_window_name (e);
-}
-
-
-static void
-open_data_file (const gchar *file_name, struct data_editor *de)
-{
-  struct getl_interface *sss;
-  struct string filename;
-
-  ds_init_empty (&filename);
-  syntax_gen_string (&filename, ss_cstr (file_name));
-
-  sss = create_syntax_string_source ("GET FILE=%s.",
-                                    ds_cstr (&filename));
-  ds_destroy (&filename);
-
-  if (execute_syntax (sss) )
-  {
-    window_set_name_from_filename ((struct editor_window *) de, file_name);
-    add_most_recent (file_name);
-  }
-}
-
-
-
-/* Callback for the data_open action.
-   Prompts for a filename and opens it */
-static void
-open_data_dialog (GtkAction *action, struct data_editor *de)
-{
-  struct editor_window *e = (struct editor_window *) de;
-
-  GtkWidget *dialog =
-    gtk_file_chooser_dialog_new (_("Open"),
-                                GTK_WINDOW (e->window),
-                                GTK_FILE_CHOOSER_ACTION_OPEN,
-                                GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-                                GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
-                                NULL);
-
-  GtkFileFilter *filter = gtk_file_filter_new ();
-  gtk_file_filter_set_name (filter, _("System Files (*.sav)"));
-  gtk_file_filter_add_pattern (filter, "*.sav");
-  gtk_file_filter_add_pattern (filter, "*.SAV");
-  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
-
-  filter = gtk_file_filter_new ();
-  gtk_file_filter_set_name (filter, _("Portable Files (*.por) "));
-  gtk_file_filter_add_pattern (filter, "*.por");
-  gtk_file_filter_add_pattern (filter, "*.POR");
-  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);
-
-
-  if ( de->file_name)
-    {
-      gchar *dir_name = g_path_get_dirname (de->file_name);
-      gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog),
-                                          dir_name);
-      free (dir_name);
-    }
-
-  switch (gtk_dialog_run (GTK_DIALOG (dialog)))
-    {
-    case GTK_RESPONSE_ACCEPT:
-      {
-       g_free (de->file_name);
-       de->file_name =
-         gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
-
-       open_data_file (de->file_name, de);
-      }
-      break;
-    default:
-      break;
-    }
-
-  gtk_widget_destroy (dialog);
-}
-
-
-static GtkWidget *
-create_data_sheet_variable_popup_menu (struct data_editor *de)
-{
-  GtkWidget *menu = gtk_menu_new ();
-
-  GtkWidget *sort_ascending =
-    gtk_menu_item_new_with_label (_("Sort Ascending"));
-
-  GtkWidget *sort_descending =
-    gtk_menu_item_new_with_label (_("Sort Descending"));
-
-  GtkWidget *insert_variable =
-    gtk_menu_item_new_with_label (_("Insert Variable"));
-
-  GtkWidget *clear_variable =
-    gtk_menu_item_new_with_label (_("Clear"));
-
-
-  gtk_action_connect_proxy (de->delete_variables,
-                           clear_variable );
-
-
-  gtk_menu_shell_append (GTK_MENU_SHELL (menu), insert_variable);
-
-
-  gtk_menu_shell_append (GTK_MENU_SHELL (menu),
-                        gtk_separator_menu_item_new ());
-
-
-  gtk_menu_shell_append (GTK_MENU_SHELL (menu), clear_variable);
-
-
-  gtk_menu_shell_append (GTK_MENU_SHELL (menu),
-                        gtk_separator_menu_item_new ());
-
-
-  gtk_menu_shell_append (GTK_MENU_SHELL (menu), sort_ascending);
-
-
-  g_signal_connect_swapped (G_OBJECT (sort_ascending), "activate",
-                           G_CALLBACK (psppire_data_editor_sort_ascending),
-                           de->data_editor);
-
-  g_signal_connect_swapped (G_OBJECT (sort_descending), "activate",
-                           G_CALLBACK (psppire_data_editor_sort_descending),
-                           de->data_editor);
-
-  g_signal_connect_swapped (G_OBJECT (insert_variable), "activate",
-                           G_CALLBACK (gtk_action_activate),
-                           de->insert_variable);
-
-
-  gtk_menu_shell_append (GTK_MENU_SHELL (menu), sort_descending);
-
-  gtk_widget_show_all (menu);
-
-  return menu;
-}
-
-
-static GtkWidget *
-create_data_sheet_cases_popup_menu (struct data_editor *de)
-{
-  GtkWidget *menu = gtk_menu_new ();
-
-  GtkWidget *insert_case =
-    gtk_menu_item_new_with_label (_("Insert Case"));
-
-  GtkWidget *delete_case =
-    gtk_menu_item_new_with_label (_("Clear"));
-
-
-  gtk_action_connect_proxy (de->delete_cases,
-                           delete_case);
-
-
-  gtk_menu_shell_append (GTK_MENU_SHELL (menu), insert_case);
-
-  g_signal_connect_swapped (G_OBJECT (insert_case), "activate",
-                           G_CALLBACK (gtk_action_activate),
-                           de->insert_case);
-
-
-  gtk_menu_shell_append (GTK_MENU_SHELL (menu),
-                        gtk_separator_menu_item_new ());
-
-
-  gtk_menu_shell_append (GTK_MENU_SHELL (menu), delete_case);
-
-
-  gtk_widget_show_all (menu);
-
-  return menu;
-}
-
-
-static GtkWidget *
-create_var_sheet_variable_popup_menu (struct data_editor *de)
-{
-  GtkWidget *menu = gtk_menu_new ();
-
-  GtkWidget *insert_variable =
-    gtk_menu_item_new_with_label (_("Insert Variable"));
-
-  GtkWidget *delete_variable =
-    gtk_menu_item_new_with_label (_("Clear"));
-
-
-  gtk_action_connect_proxy (de->delete_variables,
-                           delete_variable);
-
-
-  gtk_menu_shell_append (GTK_MENU_SHELL (menu), insert_variable);
-
-  g_signal_connect_swapped (G_OBJECT (insert_variable), "activate",
-                           G_CALLBACK (gtk_action_activate),
-                           de->insert_variable);
-
-
-  gtk_menu_shell_append (GTK_MENU_SHELL (menu),
-                        gtk_separator_menu_item_new ());
-
-
-  gtk_menu_shell_append (GTK_MENU_SHELL (menu), delete_variable);
-
-
-  gtk_widget_show_all (menu);
-
-  return menu;
-}
-
-
-
-\f
-
-static void
-on_edit_paste (GtkAction *a, gpointer data)
-{
-  struct data_editor *de = data;
-
-  psppire_data_editor_clip_paste (de->data_editor);
-}
-
-static void
-on_edit_copy (GtkMenuItem *m, gpointer data)
-{
-  struct data_editor *de = data;
-
-  psppire_data_editor_clip_copy (de->data_editor);
-}
-
-
-
-static void
-on_edit_cut (GtkMenuItem *m, gpointer data)
-{
-  struct data_editor *de = data;
-
-  psppire_data_editor_clip_cut (de->data_editor);
-}
diff --git a/src/ui/gui/data-editor.h b/src/ui/gui/data-editor.h
deleted file mode 100644 (file)
index af282e2..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2006, 2007  Free Software Foundation
-
-   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.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
-
-
-#ifndef DATA_EDITOR_H
-#define DATA_EDITOR_H
-
-#include <glade/glade.h>
-#include <gtk/gtk.h>
-#include "window-manager.h"
-#include "psppire-data-editor.h"
-
-struct data_editor
-{
-  struct editor_window parent;
-
-  GtkAction *action_data_new;
-  GtkAction *action_data_open;
-  GtkAction *action_data_save_as;
-  GtkAction *action_data_save;
-
-
-  GtkAction *invoke_text_import_assistant;
-
-  /* Actions which invoke dialog boxes */
-  GtkAction *invoke_weight_cases_dialog;
-  GtkAction *invoke_transpose_dialog;
-  GtkAction *invoke_split_file_dialog;
-  GtkAction *invoke_sort_cases_dialog;
-  GtkAction *invoke_compute_dialog;
-  GtkAction *invoke_comments_dialog;
-  GtkAction *invoke_select_cases_dialog;
-  GtkAction *invoke_goto_dialog;
-  GtkAction *invoke_variable_info_dialog;
-  GtkAction *invoke_find_dialog;
-  GtkAction *invoke_rank_dialog;
-  GtkAction *invoke_recode_same_dialog;
-  GtkAction *invoke_recode_different_dialog;
-
-  GtkAction *invoke_crosstabs_dialog;
-  GtkAction *invoke_descriptives_dialog;
-  GtkAction *invoke_frequencies_dialog;
-  GtkAction *invoke_examine_dialog;
-  GtkAction *invoke_regression_dialog;
-
-  GtkAction *invoke_t_test_independent_samples_dialog;
-  GtkAction *invoke_t_test_paired_samples_dialog;
-  GtkAction *invoke_oneway_anova_dialog;
-  GtkAction *invoke_t_test_one_sample_dialog;
-
-  GtkToggleAction *toggle_split_window;
-
-
-  /* Actions which do things */
-  GtkAction *insert_variable;
-  GtkAction *insert_case;
-  GtkAction *delete_variables;
-  GtkAction *delete_cases;
-
-  GtkToggleAction *toggle_value_labels;
-
-  GladeXML *xml;
-
-  GtkMenu *data_sheet_variable_popup_menu;
-  GtkMenu *data_sheet_cases_popup_menu;
-
-  GtkMenu *var_sheet_variable_popup_menu;
-
-  PsppireDataEditor *data_editor;
-
-  gboolean save_as_portable;
-
-  /* Name of the file this data is associated with (ie, was loaded from or
-     has been  saved to), in "filename encoding",  or NULL, if it's not
-     associated with any file */
-  gchar *file_name;
-};
-
-
-struct data_editor * new_data_editor (void);
-
-void new_data_window (GtkMenuItem *, gpointer);
-
-void data_editor_select_sheet (struct data_editor *de, gint page);
-
-#endif
index 7b33eae21026e454362cbb238f15c828034b21ff..aaed7eee2c8b2dd7fd04e265b183e5521eae3f38 100644 (file)
 #include <stdlib.h>
 
 #include <language/syntax-string-source.h>
-#include <ui/gui/data-editor.h>
+#include <ui/gui/psppire-data-window.h>
 #include <ui/gui/dialog-common.h>
 #include <ui/gui/dict-display.h>
 #include <ui/gui/helper.h>
 #include <ui/gui/psppire-dialog.h>
 #include <ui/gui/psppire-var-store.h>
-#include <ui/gui/syntax-editor.h>
+#include <ui/gui/helper.h>
 
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
@@ -202,7 +202,7 @@ void
 descriptives_dialog (GObject *o, gpointer data)
 {
   gint response;
-  struct data_editor *de = data;
+  PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
 
   struct descriptives_dialog scd;
 
@@ -221,7 +221,7 @@ descriptives_dialog (GObject *o, gpointer data)
 
   g_object_get (de->data_editor, "var-store", &vs, NULL);
 
-  gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window);
+  gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de));
 
   attach_dictionary_to_treeview (GTK_TREE_VIEW (source),
                                 vs->dict,
@@ -263,6 +263,7 @@ descriptives_dialog (GObject *o, gpointer data)
     case GTK_RESPONSE_OK:
       {
        gchar *syntax = generate_syntax (&scd);
+
        struct getl_interface *sss = create_syntax_string_source (syntax);
        execute_syntax (sss);
 
@@ -272,12 +273,7 @@ descriptives_dialog (GObject *o, gpointer data)
     case PSPPIRE_RESPONSE_PASTE:
       {
        gchar *syntax = generate_syntax (&scd);
-
-       struct syntax_editor *se =
-         (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL);
-
-       gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1);
-
+       paste_syntax_in_new_window (syntax);
        g_free (syntax);
       }
       break;
index 682af46bfe80bfa156bfc976879adb21180b0084..171d88cfc2f9f6def60a12b6fee571f22825bbce 100644 (file)
 #include <stdlib.h>
 
 #include <language/syntax-string-source.h>
-#include <ui/gui/data-editor.h>
+#include <ui/gui/psppire-data-window.h>
 #include <ui/gui/dialog-common.h>
 #include <ui/gui/dict-display.h>
 #include <ui/gui/helper.h>
 #include <ui/gui/psppire-dialog.h>
 #include <ui/gui/psppire-var-store.h>
-#include <ui/gui/syntax-editor.h>
+#include <ui/gui/helper.h>
 
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
@@ -236,7 +236,7 @@ void
 examine_dialog (GObject *o, gpointer data)
 {
   gint response;
-  struct data_editor *de = data;
+  PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
 
   struct examine_dialog ex_d;
 
@@ -275,9 +275,9 @@ examine_dialog (GObject *o, gpointer data)
   ex_d.percentiles_button = GTK_TOGGLE_BUTTON
     (get_widget_assert (xml, "percentiles-button"));
 
-  gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window);
-  gtk_window_set_transient_for (GTK_WINDOW (ex_d.stats_dialog), de->parent.window);
-  gtk_window_set_transient_for (GTK_WINDOW (ex_d.opts_dialog), de->parent.window);
+  gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de));
+  gtk_window_set_transient_for (GTK_WINDOW (ex_d.stats_dialog), GTK_WINDOW (de));
+  gtk_window_set_transient_for (GTK_WINDOW (ex_d.opts_dialog), GTK_WINDOW (de));
 
   attach_dictionary_to_treeview (GTK_TREE_VIEW (source),
                                 vs->dict,
@@ -344,12 +344,7 @@ examine_dialog (GObject *o, gpointer data)
     case PSPPIRE_RESPONSE_PASTE:
       {
        gchar *syntax = generate_syntax (&ex_d);
-
-       struct syntax_editor *se =
-         (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL);
-
-       gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1);
-
+       paste_syntax_in_new_window (syntax);
        g_free (syntax);
       }
       break;
index 985e73fbc321f8dc5793a2dab193f4edc634a19a..130b25cfafe54db8f73eca358dada6da80f77b41 100644 (file)
@@ -24,7 +24,7 @@ which match particular strings */
 #include "psppire-selector.h"
 #include "psppire-dialog.h"
 #include "helper.h"
-#include "data-editor.h"
+#include "psppire-data-window.h"
 #include "dict-display.h"
 #include <data/value.h>
 #include <data/format.h>
@@ -54,7 +54,7 @@ struct find_dialog
   GtkBuilder *xml;
   PsppireDict *dict;
   struct datasheet *data;
-  struct data_editor *de;
+  PsppireDataWindow *de;
   GtkWidget *variable_entry;
   GtkWidget *value_entry;
   GtkWidget *value_labels_checkbox;
@@ -185,7 +185,7 @@ value_labels_toggled (GtkToggleButton *tb, gpointer data)
 void
 find_dialog (GObject *o, gpointer data)
 {
-  struct data_editor *de = data;
+  PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
 
   struct find_dialog fd;
 
@@ -238,7 +238,7 @@ find_dialog (GObject *o, gpointer data)
 
 
 
-  gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window);
+  gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de));
 
 
   attach_dictionary_to_treeview (GTK_TREE_VIEW (source),
index 89cf7683e890cfad1ca97697047ae29fe77be832..37e301b88babb099490ed752a075e5e7f44da9f5 100644 (file)
 #include <stdlib.h>
 
 #include <language/syntax-string-source.h>
-#include <ui/gui/data-editor.h>
+#include <ui/gui/psppire-data-window.h>
 #include <ui/gui/dialog-common.h>
 #include <ui/gui/dict-display.h>
 #include <ui/gui/helper.h>
 #include <ui/gui/psppire-dialog.h>
 #include <ui/gui/psppire-var-store.h>
-#include <ui/gui/syntax-editor.h>
+#include <ui/gui/helper.h>
 
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
@@ -307,7 +307,7 @@ void
 frequencies_dialog (GObject *o, gpointer data)
 {
   gint response;
-  struct data_editor *de = data;
+  PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
 
   struct frequencies_dialog fd;
 
@@ -331,7 +331,7 @@ frequencies_dialog (GObject *o, gpointer data)
                                  );
 
 
-  gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window);
+  gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de));
 
   attach_dictionary_to_treeview (GTK_TREE_VIEW (source),
                                 vs->dict,
@@ -369,7 +369,7 @@ frequencies_dialog (GObject *o, gpointer data)
   fd.current_opts.limit = 50;
 
 
-  gtk_window_set_transient_for (GTK_WINDOW (fd.format_dialog), de->parent.window);
+  gtk_window_set_transient_for (GTK_WINDOW (fd.format_dialog), GTK_WINDOW (de));
 
 
   g_signal_connect (dialog, "refresh", G_CALLBACK (refresh),  &fd);
@@ -393,6 +393,7 @@ frequencies_dialog (GObject *o, gpointer data)
     case GTK_RESPONSE_OK:
       {
        gchar *syntax = generate_syntax (&fd);
+
        struct getl_interface *sss = create_syntax_string_source (syntax);
        execute_syntax (sss);
 
@@ -402,12 +403,7 @@ frequencies_dialog (GObject *o, gpointer data)
     case PSPPIRE_RESPONSE_PASTE:
       {
        gchar *syntax = generate_syntax (&fd);
-
-       struct syntax_editor *se =
-         (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL);
-
-       gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1);
-
+       paste_syntax_in_new_window (syntax);
        g_free (syntax);
       }
       break;
index a22b5cb0ebe4077f202de1a35931950b13822118..9a523943b1c5686e639d4df34b56530d4f1b55a5 100644 (file)
 #include "goto-case-dialog.h"
 #include "helper.h"
 #include "psppire-dialog.h"
-#include "data-editor.h"
+#include "psppire-data-window.h"
 #include "psppire-data-store.h"
 
 
 static void
-refresh (const struct data_editor *de, GtkBuilder *xml)
+refresh (const PsppireDataWindow *de, GtkBuilder *xml)
 {
   PsppireDataStore *ds = NULL;
   casenumber case_count ;
@@ -44,12 +44,12 @@ goto_case_dialog (GObject *o, gpointer data)
 {
   gint response;
   GtkBuilder *xml = builder_new ("psppire.ui");
-  struct data_editor *de = data;
+  PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
 
   GtkWidget *dialog = get_widget_assert   (xml, "goto-case-dialog");
 
 
-  gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window);
+  gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de));
 
   refresh (de, xml);
 
index fc9105d75921456a8f94ea41e1246d7065c59a55..6a3a0f9e6ce0b83ee360f62ca9f790205084da7e 100644 (file)
@@ -20,6 +20,8 @@
 */
 #include <config.h>
 
+#include "psppire-syntax-window.h"
+
 #include       <glib-object.h>
 
 #include <glib.h>
@@ -46,7 +48,7 @@
 #include <language/lexer/lexer.h>
 #include "psppire-data-store.h"
 #include <output/manager.h>
-#include "output-viewer.h"
+#include "psppire-output-window.h"
 
 #include "xalloc.h"
 
@@ -268,7 +270,7 @@ execute_syntax (struct getl_interface *sss)
 
   som_flush ();
 
-  reload_the_viewer ();
+  psppire_output_window_reload ();
 
   return retval;
 }
@@ -320,3 +322,12 @@ clone_list_store (const GtkListStore *src)
 
 
 
+void
+paste_syntax_in_new_window (const gchar *syntax)
+{
+  GtkWidget *se = psppire_syntax_window_new ();
+
+  gtk_text_buffer_insert_at_cursor (PSPPIRE_SYNTAX_WINDOW (se)->buffer, syntax, -1);
+
+  gtk_widget_show (se);
+}
index d08a17526bc59e6389d3d1ac996c1711238a7728..d388ccb41821b132afaf5670647ea3dd961a0cd4 100644 (file)
 #include <gtk/gtk.h>
 #include <glade/glade.h>
 
+
+
+void paste_syntax_in_new_window (const gchar *syntax);
+
 /*
    GtkRecentChooserMenu was added in 2.10.0
    but it didn't support GtkRecentFilters until
index 59b65b4a2487dfc1ce793381d407cc1e6cb402f9..d41b2760aa97630510ca82315ae96c1b1eb1f87c 100644 (file)
@@ -22,7 +22,7 @@
 #include "psppire-dict.h"
 #include "psppire-var-store.h"
 #include "helper.h"
-#include "data-editor.h"
+#include "psppire-data-window.h"
 #include "psppire-dialog.h"
 #include "dialog-common.h"
 #include "dict-display.h"
@@ -30,7 +30,7 @@
 
 
 #include <language/syntax-string-source.h>
-#include "syntax-editor.h"
+#include "helper.h"
 
 
 #include "gettext.h"
@@ -126,7 +126,7 @@ void
 oneway_anova_dialog (GObject *o, gpointer data)
 {
   gint response;
-  struct data_editor *de = data;
+  PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
 
   PsppireVarStore *vs = NULL;
 
@@ -168,7 +168,7 @@ oneway_anova_dialog (GObject *o, gpointer data)
   ow.dialog =
     GTK_WINDOW (get_widget_assert (builder, "oneway-anova-dialog"));
 
-  gtk_window_set_transient_for (ow.dialog, de->parent.window);
+  gtk_window_set_transient_for (ow.dialog, GTK_WINDOW (de));
 
   attach_dictionary_to_treeview (GTK_TREE_VIEW (dict_view),
                                 vs->dict,
@@ -222,7 +222,7 @@ oneway_anova_dialog (GObject *o, gpointer data)
     psppire_acr_set_entry (cd->acr, entry);
 
     gtk_window_set_transient_for (GTK_WINDOW (cd->contrasts_dialog),
-                                 de->parent.window);
+                                 GTK_WINDOW (de));
   }
 
   response = psppire_dialog_run (PSPPIRE_DIALOG (ow.dialog));
@@ -232,6 +232,7 @@ oneway_anova_dialog (GObject *o, gpointer data)
     case GTK_RESPONSE_OK:
       {
        gchar *syntax = generate_syntax (&ow);
+
        struct getl_interface *sss = create_syntax_string_source (syntax);
        execute_syntax (sss);
 
@@ -241,11 +242,7 @@ oneway_anova_dialog (GObject *o, gpointer data)
     case PSPPIRE_RESPONSE_PASTE:
       {
        gchar *syntax = generate_syntax (&ow);
-
-       struct syntax_editor *se =
-         (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL);
-
-       gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1);
+        paste_syntax_in_new_window (syntax);
 
        g_free (syntax);
       }
diff --git a/src/ui/gui/output-viewer.c b/src/ui/gui/output-viewer.c
deleted file mode 100644 (file)
index 2b0c4af..0000000
+++ /dev/null
@@ -1,294 +0,0 @@
-/* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2007 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 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.
-
-   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 <gtk/gtk.h>
-#include <data/file-name.h>
-#include "window-manager.h"
-#include "output-viewer.h"
-#include "helper.h"
-#include "about.h"
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include <glade/glade.h>
-#include <ctype.h>
-
-#include "xalloc.h"
-
-struct output_viewer
-{
-  struct editor_window parent;
-  GtkTextBuffer *buffer;  /* The buffer which contains the text */
-  GtkWidget *textview ;
-  FILE *fp;               /* The file it's viewing */
-};
-
-
-static void
-cancel_urgency (GtkWindow *window,  gpointer data)
-{
-  gtk_window_set_urgency_hint (window, FALSE);
-}
-
-
-static struct output_viewer *the_output_viewer = NULL;
-
-int viewer_length = 16;
-int viewer_width = 59;
-
-/* Callback for the "delete" action (clicking the x on the top right
-   hand corner of the window) */
-static gboolean
-on_delete (GtkWidget *w, GdkEvent *event, gpointer user_data)
-{
-  struct output_viewer *ov = user_data;
-
-  g_free (ov);
-
-  the_output_viewer = NULL;
-
-  unlink (output_file_name ());
-
-  return FALSE;
-}
-
-
-/* Sets width and length according to the new size
-   of the output window */
-static void
-on_textview_resize (GtkWidget     *widget,
-                   GtkAllocation *allocation,
-                   gpointer       user_data)
-{
-  PangoContext * context ;
-  PangoLayout *layout ;
-  PangoRectangle logical;
-  GtkStyle *style;
-  gint right_margin, left_margin;
-  GtkTextView *text_view = GTK_TEXT_VIEW (widget);
-
-  context = gtk_widget_create_pango_context (widget);
-  layout = pango_layout_new (context);
-
-  style = gtk_widget_get_style (widget);
-
-  pango_layout_set_font_description (layout, style->font_desc);
-
-  /* Find the width of one character.  We can use any character, because
-     the textview has a monospaced font */
-  pango_layout_set_text (layout, "M", 1);
-
-  pango_layout_get_extents (layout,  NULL, &logical);
-
-  left_margin = gtk_text_view_get_left_margin (text_view);
-  right_margin = gtk_text_view_get_right_margin (text_view);
-
-  viewer_length = allocation->height / PANGO_PIXELS (logical.height);
-  viewer_width = (allocation->width - right_margin - left_margin)
-    / PANGO_PIXELS (logical.width);
-
-  g_object_unref (G_OBJECT (layout));
-  g_object_unref (G_OBJECT (context));
-}
-
-
-
-/*
-  Create a new output viewer
-*/
-struct output_viewer *
-new_output_viewer (void)
-{
-  GladeXML *xml = XML_NEW ("output-viewer.glade");
-
-  struct output_viewer *ov ;
-  struct editor_window *e;
-
-  connect_help (xml);
-
-  ov = g_malloc (sizeof (*ov));
-
-  e = (struct editor_window *)ov;
-
-
-  e->window = GTK_WINDOW (get_widget_assert (xml, "output-viewer-window"));
-  ov->textview = get_widget_assert (xml, "output-viewer-textview");
-  ov->buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (ov->textview));
-
-  g_signal_connect (e->window,
-                   "focus-in-event",
-                   G_CALLBACK (cancel_urgency),
-                   NULL);
-
-  {
-    /* Output uses ascii characters for tabular material.
-       So we need a monospaced font otherwise it'll look silly */
-    PangoFontDescription *font_desc =
-      pango_font_description_from_string ("monospace");
-
-    gtk_widget_modify_font (ov->textview, font_desc);
-    pango_font_description_free (font_desc);
-  }
-
-  g_signal_connect (ov->textview, "size-allocate",
-                   G_CALLBACK (on_textview_resize), NULL);
-
-  ov->fp = NULL;
-
-  g_signal_connect (get_widget_assert (xml,"help_about"),
-                   "activate",
-                   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,"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), ov);
-
-  return ov;
-}
-
-
-void
-reload_the_viewer (void)
-{
-  struct stat buf;
-
-  /* If there is no output, then don't do anything */
-  if (0 != stat (output_file_name (), &buf))
-    return ;
-
-  if ( NULL == the_output_viewer )
-    {
-      the_output_viewer =
-       (struct output_viewer *) window_create (WINDOW_OUTPUT, NULL);
-    }
-
-  reload_viewer (the_output_viewer);
-}
-
-#define OUTPUT_FILE_NAME "psppire.txt"
-
-void
-reload_viewer (struct output_viewer *ov)
-{
-  GtkTextIter end_iter;
-  GtkTextMark *mark ;
-
-  static char *line = NULL;
-
-  gboolean chars_inserted = FALSE;
-
-  gtk_text_buffer_get_end_iter (ov->buffer, &end_iter);
-
-  line = xrealloc (line, sizeof (char) * (viewer_width + 1));
-
-
-  mark = gtk_text_buffer_create_mark (ov->buffer, NULL, &end_iter, TRUE);
-
-#ifdef __CYGWIN__
-  /*
-    Apparently Windoze is not capabale of writing to a file whilst
-    another (or the same) process is reading from it.   Therefore, we
-    must close the file after reading it, and clear the entire buffer
-    before writing to it.
-    This will be slower for large buffers, but should work
-    (in so far as anything ever works on windows).
-  */
-  {
-    GtkTextIter start_iter;
-    FILE *fp = fopen (OUTPUT_FILE_NAME, "r");
-    if ( !fp)
-      {
-       g_print ("Cannot open %s\n", OUTPUT_FILE_NAME);
-       return;
-      }
-
-    /* Delete all the entire buffer */
-    gtk_text_buffer_get_start_iter (ov->buffer, &start_iter);
-    gtk_text_buffer_delete (ov->buffer, &start_iter, &end_iter);
-
-
-    gtk_text_buffer_get_start_iter (ov->buffer, &start_iter);
-    /* Read in the next lot of text */
-    while (fgets (line, viewer_width + 1, fp) != NULL)
-      {
-       chars_inserted = TRUE;
-       gtk_text_buffer_insert (ov->buffer, &start_iter, line, -1);
-      }
-
-    fclose (fp);
-  }
-#else
-  {
-    if ( ov->fp == NULL)
-      {
-       ov->fp = fopen (output_file_name (), "r");
-       if ( ov->fp == NULL)
-         {
-           g_print ("Cannot open %s\n", output_file_name ());
-           return;
-         }
-      }
-
-    /* Read in the next lot of text */
-    while (fgets (line, viewer_width + 1, ov->fp) != NULL)
-      {
-       chars_inserted = TRUE;
-       gtk_text_buffer_insert (ov->buffer, &end_iter, line, -1);
-      }
-  }
-#endif
-
-  /* Scroll to where the start of this lot of text begins */
-  gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (ov->textview),
-                               mark,
-                               0.1, TRUE, 0.0, 0.0);
-
-
-  if ( chars_inserted )
-    gtk_window_set_urgency_hint ( ((struct editor_window *)ov)->window, TRUE);
-}
-
-
-
-
-const char *
-output_file_name (void)
-{
-  const char *dir = default_output_path ();
-  static char *filename = NULL;
-
-  if ( NULL == filename )
-    filename = xasprintf ("%s%s", dir, OUTPUT_FILE_NAME);
-
-
-  return filename;
-}
index 0bcf5f3e407d8cce0f5207d99c127ebe4136fa7c..aeb8879340d53912a36cc3efd2a9612d9866e20c 100644 (file)
@@ -78,7 +78,7 @@
                 <property name="label" translatable="yes">_Windows</property>
                 <property name="use_underline">True</property>
                 <child>
-                  <widget class="GtkMenu" id="menu4">
+                  <widget class="GtkMenu" id="windows_menu">
                     <property name="visible">True</property>
                     <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                     <child>
diff --git a/src/ui/gui/output-viewer.h b/src/ui/gui/output-viewer.h
deleted file mode 100644 (file)
index e5bf5c1..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2007  Free Software Foundation
-
-   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.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
-
-
-#ifndef OUTPUT_VIEWER_H
-#define OUTPUT_VIEWER_H
-
-#include <gtk/gtk.h>
-
-#include "window-manager.h"
-
-
-extern int viewer_length ;
-extern int viewer_width ;
-
-struct output_viewer * new_output_viewer (void);
-
-void reload_viewer (struct output_viewer *);
-
-void reload_the_viewer (void);
-
-
-const char * output_file_name (void);
-
-#endif
index 71d7d5f53976c124fc779a7a56fa127b13eaa09e..1bbd2bb8e517ddb48dd989a9734a88f9c46f1dc5 100644 (file)
@@ -308,8 +308,6 @@ delete_variable_callback (GObject *obj, gint dict_index,
 #endif
 }
 
-
-
 static void
 variable_changed_callback (GObject *obj, gint var_num, gpointer data)
 {
@@ -319,7 +317,6 @@ variable_changed_callback (GObject *obj, gint var_num, gpointer data)
   psppire_sheet_column_columns_changed (PSPPIRE_SHEET_COLUMN (store),
                                  var_num, 1);
 
-
   psppire_sheet_model_range_changed (PSPPIRE_SHEET_MODEL (store),
                               -1, var_num,
                               -1, var_num);
diff --git a/src/ui/gui/psppire-data-window.c b/src/ui/gui/psppire-data-window.c
new file mode 100644 (file)
index 0000000..90e749d
--- /dev/null
@@ -0,0 +1,1720 @@
+/* PSPPIRE - a graphical user interface for PSPP.
+   Copyright (C) 2008  Free Software Foundation
+
+   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.
+
+   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 <gtk/gtksignal.h>
+#include <gtk/gtkbox.h>
+#include <glade/glade.h>
+#include "helper.h"
+
+#include "text-data-import-dialog.h"
+
+
+#include <ui/syntax-gen.h>
+#include <language/syntax-string-source.h>
+#include <libpspp/message.h>
+#include <stdlib.h>
+
+#include <data/procedure.h>
+
+#include "psppire-data-window.h"
+#include "psppire-syntax-window.h"
+
+#include "about.h"
+
+#include "goto-case-dialog.h"
+#include "weight-cases-dialog.h"
+#include "split-file-dialog.h"
+#include "transpose-dialog.h"
+#include "sort-cases-dialog.h"
+#include "select-cases-dialog.h"
+#include "compute-dialog.h"
+#include "find-dialog.h"
+#include "rank-dialog.h"
+#include "recode-dialog.h"
+#include "comments-dialog.h"
+#include "variable-info-dialog.h"
+#include "descriptives-dialog.h"
+#include "crosstabs-dialog.h"
+#include "frequencies-dialog.h"
+#include "examine-dialog.h"
+#include "dict-display.h"
+#include "regression-dialog.h"
+#include "oneway-anova-dialog.h"
+#include "t-test-independent-samples-dialog.h"
+#include "t-test-one-sample.h"
+#include "t-test-paired-samples.h"
+
+
+#include <gettext.h>
+#define _(msgid) gettext (msgid)
+#define N_(msgid) msgid
+
+
+
+static void psppire_data_window_base_finalize (PsppireDataWindowClass *, gpointer);
+static void psppire_data_window_base_init     (PsppireDataWindowClass *class);
+static void psppire_data_window_class_init    (PsppireDataWindowClass *class);
+static void psppire_data_window_init          (PsppireDataWindow      *data_editor);
+
+
+GType
+psppire_data_window_get_type (void)
+{
+  static GType psppire_data_window_type = 0;
+
+  if (!psppire_data_window_type)
+    {
+      static const GTypeInfo psppire_data_window_info =
+      {
+       sizeof (PsppireDataWindowClass),
+       (GBaseInitFunc) psppire_data_window_base_init,
+        (GBaseFinalizeFunc) psppire_data_window_base_finalize,
+       (GClassInitFunc)psppire_data_window_class_init,
+       (GClassFinalizeFunc) NULL,
+       NULL,
+        sizeof (PsppireDataWindow),
+       0,
+       (GInstanceInitFunc) psppire_data_window_init,
+      };
+
+      psppire_data_window_type =
+       g_type_register_static (PSPPIRE_WINDOW_TYPE, "PsppireDataWindow",
+                               &psppire_data_window_info, 0);
+    }
+
+  return psppire_data_window_type;
+}
+
+
+static void
+psppire_data_window_finalize (GObject *object)
+{
+  PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (object);
+
+  GObjectClass *class = G_OBJECT_GET_CLASS (object);
+
+  GObjectClass *parent_class = g_type_class_peek_parent (class);
+
+  g_object_unref (de->xml);
+
+
+  if (G_OBJECT_CLASS (parent_class)->finalize)
+    (*G_OBJECT_CLASS (parent_class)->finalize) (object);
+}
+
+
+static void
+psppire_data_window_class_init (PsppireDataWindowClass *class)
+{
+}
+
+
+static void
+psppire_data_window_base_init (PsppireDataWindowClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+  object_class->finalize = psppire_data_window_finalize;
+}
+
+
+
+static void
+psppire_data_window_base_finalize (PsppireDataWindowClass *class,
+                                    gpointer class_data)
+{
+}
+
+
+\f
+
+
+extern PsppireVarStore *the_var_store;
+extern struct dataset *the_dataset;
+extern PsppireDataStore *the_data_store ;
+
+
+static void
+update_paste_menuitems (GtkWidget *w, gboolean x, gpointer data)
+{
+  PsppireDataWindow  *de = PSPPIRE_DATA_WINDOW (data);
+
+  GtkWidget * edit_paste = get_widget_assert (de->xml, "edit_paste");
+
+  gtk_widget_set_sensitive (edit_paste, x);
+}
+
+static void
+update_cut_copy_menuitems (GtkWidget *w, gboolean x, gpointer data)
+{
+  PsppireDataWindow  *de = PSPPIRE_DATA_WINDOW (data);
+
+  GtkWidget * edit_copy = get_widget_assert (de->xml, "edit_copy");
+  GtkWidget * edit_cut = get_widget_assert (de->xml, "edit_cut");
+
+  gtk_widget_set_sensitive (edit_copy, x);
+  gtk_widget_set_sensitive (edit_cut, x);
+}
+
+/* Run the EXECUTE command. */
+static void
+execute (GtkMenuItem *mi, gpointer data)
+{
+  struct getl_interface *sss = create_syntax_string_source ("EXECUTE.");
+
+  execute_syntax (sss);
+}
+
+static void
+transformation_change_callback (bool transformations_pending,
+                               gpointer data)
+{
+  PsppireDataWindow  *de = PSPPIRE_DATA_WINDOW (data);
+
+  GtkWidget *menuitem =
+    get_widget_assert (de->xml, "transform_run-pending");
+  GtkWidget *status_label  =
+    get_widget_assert (de->xml, "case-counter-area");
+
+  gtk_widget_set_sensitive (menuitem, transformations_pending);
+
+
+  if ( transformations_pending)
+    gtk_label_set_text (GTK_LABEL (status_label),
+                       _("Transformations Pending"));
+  else
+    gtk_label_set_text (GTK_LABEL (status_label), "");
+}
+
+/* Callback for when the dictionary changes its filter variable */
+static void
+on_filter_change (GObject *o, gint filter_index, gpointer data)
+{
+  PsppireDataWindow  *de = PSPPIRE_DATA_WINDOW (data);
+
+  GtkWidget *filter_status_area =
+    get_widget_assert (de->xml, "filter-use-status-area");
+
+  if ( filter_index == -1 )
+    {
+      gtk_label_set_text (GTK_LABEL (filter_status_area), _("Filter off"));
+    }
+  else
+    {
+      PsppireVarStore *vs = NULL;
+      struct variable *var ;
+      gchar *text ;
+
+      g_object_get (de->data_editor, "var-store", &vs, NULL);
+
+      var = psppire_dict_get_variable (vs->dict, filter_index);
+
+      text = g_strdup_printf (_("Filter by %s"), var_get_name (var));
+
+      gtk_label_set_text (GTK_LABEL (filter_status_area), text);
+
+      g_free (text);
+    }
+}
+
+/* Callback for when the dictionary changes its split variables */
+static void
+on_split_change (PsppireDict *dict, gpointer data)
+{
+  PsppireDataWindow  *de = PSPPIRE_DATA_WINDOW (data);
+
+  size_t n_split_vars = dict_get_split_cnt (dict->dict);
+
+  GtkWidget *split_status_area =
+    get_widget_assert (de->xml, "split-file-status-area");
+
+  if ( n_split_vars == 0 )
+    {
+      gtk_label_set_text (GTK_LABEL (split_status_area), _("No Split"));
+    }
+  else
+    {
+      gint i;
+      GString *text;
+      const struct variable *const * split_vars =
+       dict_get_split_vars (dict->dict);
+
+      text = g_string_new (_("Split by "));
+
+      for (i = 0 ; i < n_split_vars - 1; ++i )
+       {
+         g_string_append_printf (text, "%s, ", var_get_name (split_vars[i]));
+       }
+      g_string_append (text, var_get_name (split_vars[i]));
+
+      gtk_label_set_text (GTK_LABEL (split_status_area), text->str);
+
+      g_string_free (text, TRUE);
+    }
+}
+
+
+
+
+/* Callback for when the dictionary changes its weights */
+static void
+on_weight_change (GObject *o, gint weight_index, gpointer data)
+{
+  PsppireDataWindow  *de = PSPPIRE_DATA_WINDOW (data);
+
+  GtkWidget *weight_status_area =
+    get_widget_assert (de->xml, "weight-status-area");
+
+  if ( weight_index == -1 )
+    {
+      gtk_label_set_text (GTK_LABEL (weight_status_area), _("Weights off"));
+    }
+  else
+    {
+      struct variable *var ;
+      PsppireVarStore *vs = NULL;
+      gchar *text;
+
+      g_object_get (de->data_editor, "var-store", &vs, NULL);
+
+      var = psppire_dict_get_variable (vs->dict, weight_index);
+
+      text = g_strdup_printf (_("Weight by %s"), var_get_name (var));
+
+      gtk_label_set_text (GTK_LABEL (weight_status_area), text);
+
+      g_free (text);
+    }
+}
+
+/* Puts FILE_NAME into the recent list.
+   If it's already in the list, it moves it to the top
+*/
+static void
+add_most_recent (const char *file_name)
+{
+#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);
+#endif
+}
+
+static void
+open_data_file (const gchar *file_name, PsppireDataWindow *de)
+{
+  struct getl_interface *sss;
+  struct string filename;
+
+  ds_init_empty (&filename);
+  syntax_gen_string (&filename, ss_cstr (file_name));
+
+  sss = create_syntax_string_source ("GET FILE=%s.",
+                                    ds_cstr (&filename));
+  ds_destroy (&filename);
+
+  if (execute_syntax (sss) )
+  {
+    psppire_window_set_filename (PSPPIRE_WINDOW (de), file_name);
+    add_most_recent (file_name);
+  }
+}
+
+
+/* Callback for the data_open action.
+   Prompts for a filename and opens it */
+static void
+open_data_dialog (GtkAction *action, PsppireDataWindow *de)
+{
+  GtkWidget *dialog =
+    gtk_file_chooser_dialog_new (_("Open"),
+                                GTK_WINDOW (de),
+                                GTK_FILE_CHOOSER_ACTION_OPEN,
+                                GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                                GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+                                NULL);
+
+  GtkFileFilter *filter = gtk_file_filter_new ();
+  gtk_file_filter_set_name (filter, _("System Files (*.sav)"));
+  gtk_file_filter_add_pattern (filter, "*.sav");
+  gtk_file_filter_add_pattern (filter, "*.SAV");
+  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
+
+  filter = gtk_file_filter_new ();
+  gtk_file_filter_set_name (filter, _("Portable Files (*.por) "));
+  gtk_file_filter_add_pattern (filter, "*.por");
+  gtk_file_filter_add_pattern (filter, "*.POR");
+  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);
+
+
+  if (de->file_name)
+    {
+      gchar *dir_name = g_path_get_dirname (de->file_name);
+      gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog),
+                                          dir_name);
+      free (dir_name);
+    }
+
+  switch (gtk_dialog_run (GTK_DIALOG (dialog)))
+    {
+    case GTK_RESPONSE_ACCEPT:
+      {
+       g_free (de->file_name);
+       de->file_name =
+         gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+
+       open_data_file (de->file_name, de);
+      }
+      break;
+    default:
+      break;
+    }
+
+  gtk_widget_destroy (dialog);
+}
+
+/* Returns true if NAME has a suffix which might denote a PSPP file */
+static gboolean
+name_has_suffix (const gchar *name)
+{
+  if ( g_str_has_suffix (name, ".sav"))
+    return TRUE;
+  if ( g_str_has_suffix (name, ".SAV"))
+    return TRUE;
+  if ( g_str_has_suffix (name, ".por"))
+    return TRUE;
+  if ( g_str_has_suffix (name, ".POR"))
+    return TRUE;
+
+  return FALSE;
+}
+
+
+/* Append SUFFIX to the filename of DE */
+static void
+append_filename_suffix (PsppireDataWindow *de, const gchar *suffix)
+{
+  if ( ! name_has_suffix (de->file_name))
+    {
+      gchar *s = de->file_name;
+      de->file_name = g_strconcat (de->file_name, suffix, NULL);
+      g_free (s);
+    }
+}
+
+/* Save DE to file */
+static void
+save_file (PsppireDataWindow *de)
+{
+  struct getl_interface *sss;
+  struct string file_name ;
+
+  g_assert (de->file_name);
+
+  ds_init_empty (&file_name);
+  syntax_gen_string (&file_name, ss_cstr (de->file_name));
+
+  if ( de->save_as_portable )
+    {
+      append_filename_suffix (de, ".por");
+      sss = create_syntax_string_source ("EXPORT OUTFILE=%s.",
+                                        ds_cstr (&file_name));
+    }
+  else
+    {
+      append_filename_suffix (de, ".sav");
+      sss = create_syntax_string_source ("SAVE OUTFILE=%s.",
+                                        ds_cstr (&file_name));
+    }
+
+  ds_destroy (&file_name);
+
+  execute_syntax (sss);
+}
+
+
+static void
+insert_case (GtkAction *action, gpointer data)
+{
+  PsppireDataWindow *dw = PSPPIRE_DATA_WINDOW (data);
+
+  psppire_data_editor_insert_case (dw->data_editor);
+}
+
+static void
+on_insert_variable (GtkAction *action, gpointer data)
+{
+  PsppireDataEditor *de = PSPPIRE_DATA_EDITOR (data);
+  psppire_data_editor_insert_variable (de);
+}
+
+
+/* Callback for data_save_as action. Prompt for a filename and save */
+static void
+data_save_as_dialog (GtkAction *action, PsppireDataWindow *de)
+{
+  GtkWidget *button_sys;
+  GtkWidget *dialog =
+    gtk_file_chooser_dialog_new (_("Save"),
+                                GTK_WINDOW (de),
+                                GTK_FILE_CHOOSER_ACTION_SAVE,
+                                GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                                GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
+                                NULL);
+
+  GtkFileFilter *filter = gtk_file_filter_new ();
+  gtk_file_filter_set_name (filter, _("System Files (*.sav)"));
+  gtk_file_filter_add_pattern (filter, "*.sav");
+  gtk_file_filter_add_pattern (filter, "*.SAV");
+  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
+
+  filter = gtk_file_filter_new ();
+  gtk_file_filter_set_name (filter, _("Portable Files (*.por) "));
+  gtk_file_filter_add_pattern (filter, "*.por");
+  gtk_file_filter_add_pattern (filter, "*.POR");
+  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);
+
+  {
+    GtkWidget *button_por;
+    GtkWidget *vbox = gtk_vbox_new (TRUE, 5);
+    button_sys =
+      gtk_radio_button_new_with_label (NULL, _("System File"));
+
+    button_por =
+      gtk_radio_button_new_with_label
+      (gtk_radio_button_get_group (GTK_RADIO_BUTTON(button_sys)),
+       _("Portable File"));
+
+    gtk_box_pack_start_defaults (GTK_BOX (vbox), button_sys);
+    gtk_box_pack_start_defaults (GTK_BOX (vbox), button_por);
+
+    gtk_widget_show_all (vbox);
+
+    gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER(dialog), vbox);
+  }
+
+  switch (gtk_dialog_run (GTK_DIALOG (dialog)))
+    {
+    case GTK_RESPONSE_ACCEPT:
+      {
+       g_free (de->file_name);
+
+       de->file_name =
+         gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+
+       de->save_as_portable =
+         ! gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button_sys));
+
+       if ( de->save_as_portable)
+         append_filename_suffix (de, ".por");
+       else
+         append_filename_suffix (de, ".sav");
+
+       save_file (de);
+
+       psppire_window_set_filename (PSPPIRE_WINDOW (de), de->file_name);
+      }
+      break;
+    default:
+      break;
+    }
+
+  gtk_widget_destroy (dialog);
+}
+
+
+/* Callback for data_save action.
+   If there's an existing file name, then just save,
+   otherwise prompt for a file name, then save */
+static void
+data_save (GtkAction *action, PsppireDataWindow *de)
+{
+  if ( de->file_name)
+    save_file (de);
+  else
+    data_save_as_dialog (action, de);
+}
+
+
+/* Callback for data_new action.
+   Performs the NEW FILE command */
+static void
+new_file (GtkAction *action, PsppireDataWindow *de)
+{
+  struct getl_interface *sss =
+    create_syntax_string_source ("NEW FILE.");
+
+  execute_syntax (sss);
+
+  g_free (de->file_name);
+  de->file_name = NULL;
+
+  psppire_window_set_filename (PSPPIRE_WINDOW (de), NULL);
+}
+
+
+
+/* Create the GtkActions and connect to their signals */
+static void
+register_data_editor_actions (PsppireDataWindow *de)
+{
+  de->action_data_open =
+    gtk_action_new ("data-open-dialog",
+                   _("Open"),
+                   _("Open a data file"),
+                   "gtk-open");
+
+  g_signal_connect (de->action_data_open, "activate",
+                   G_CALLBACK (open_data_dialog), de);
+
+
+  de->action_data_save = gtk_action_new ("data-save",
+                                           _("Save"),
+                                           _("Save data to file"),
+                                           "gtk-save");
+
+  g_signal_connect (de->action_data_save, "activate",
+                   G_CALLBACK (data_save), de);
+
+
+  de->action_data_save_as = gtk_action_new ("data-save-as-dialog",
+                                           _("Save As"),
+                                           _("Save data to file"),
+                                           "gtk-save");
+
+  g_signal_connect (de->action_data_save_as, "activate",
+                   G_CALLBACK (data_save_as_dialog), de);
+
+  de->action_data_new =
+    gtk_action_new ("data-new",
+                   _("New"),
+                   _("New data file"),
+                   NULL);
+
+  g_signal_connect (de->action_data_new, "activate",
+                   G_CALLBACK (new_file), de);
+
+  de->invoke_text_import_assistant =
+    gtk_action_new ("file_import-text",
+                   _("_Import Text Data"),
+                   _("Import text data file"),
+                   "");
+
+  g_signal_connect (de->invoke_text_import_assistant, "activate",
+                   G_CALLBACK (text_data_import_assistant), de);
+}
+
+static void
+on_edit_paste (GtkAction *a, gpointer data)
+{
+  PsppireDataWindow  *de = PSPPIRE_DATA_WINDOW (data);
+
+  psppire_data_editor_clip_paste (de->data_editor);
+}
+
+static void
+on_edit_copy (GtkMenuItem *m, gpointer data)
+{
+  PsppireDataWindow  *de = PSPPIRE_DATA_WINDOW (data);
+
+  psppire_data_editor_clip_copy (de->data_editor);
+}
+
+
+
+static void
+on_edit_cut (GtkMenuItem *m, gpointer data)
+{
+  PsppireDataWindow  *de = PSPPIRE_DATA_WINDOW (data);
+
+  psppire_data_editor_clip_cut (de->data_editor);
+}
+
+
+static void
+status_bar_activate (GtkCheckMenuItem *menuitem, gpointer data)
+{
+  PsppireDataWindow  *de = PSPPIRE_DATA_WINDOW (data);
+  GtkWidget *statusbar = get_widget_assert (de->xml, "status-bar");
+
+  if ( gtk_check_menu_item_get_active (menuitem) )
+    gtk_widget_show (statusbar);
+  else
+    gtk_widget_hide (statusbar);
+}
+
+
+static void
+grid_lines_activate (GtkCheckMenuItem *menuitem, gpointer data)
+{
+  PsppireDataWindow  *de = PSPPIRE_DATA_WINDOW (data);
+  const gboolean grid_visible = gtk_check_menu_item_get_active (menuitem);
+
+  psppire_data_editor_show_grid (de->data_editor, grid_visible);
+}
+
+
+
+static void
+data_view_activate (GtkCheckMenuItem *menuitem, gpointer data)
+{
+  PsppireDataWindow  *de = PSPPIRE_DATA_WINDOW (data);
+
+  gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_DATA_VIEW);
+}
+
+
+static void
+variable_view_activate (GtkCheckMenuItem *menuitem, gpointer data)
+{
+  PsppireDataWindow  *de = PSPPIRE_DATA_WINDOW (data);
+
+  gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_VARIABLE_VIEW);
+}
+
+
+static void
+fonts_activate (GtkMenuItem *menuitem, gpointer data)
+{
+  PsppireDataWindow  *de = PSPPIRE_DATA_WINDOW (data);
+  PangoFontDescription *current_font;
+  gchar *font_name;
+  GtkWidget *dialog =
+    gtk_font_selection_dialog_new (_("Font Selection"));
+
+
+  current_font = GTK_WIDGET(de->data_editor)->style->font_desc;
+  font_name = pango_font_description_to_string (current_font);
+
+  gtk_font_selection_dialog_set_font_name (GTK_FONT_SELECTION_DIALOG (dialog), font_name);
+
+  g_free (font_name);
+
+  gtk_window_set_transient_for (GTK_WINDOW (dialog),
+                               GTK_WINDOW (get_widget_assert (de->xml,
+                                                              "data_editor")));
+  if ( GTK_RESPONSE_OK == gtk_dialog_run (GTK_DIALOG (dialog)) )
+    {
+      const gchar *font = gtk_font_selection_dialog_get_font_name
+       (GTK_FONT_SELECTION_DIALOG (dialog));
+
+      PangoFontDescription* font_desc =
+       pango_font_description_from_string (font);
+
+      psppire_data_editor_set_font (de->data_editor, font_desc);
+    }
+
+  gtk_widget_hide (dialog);
+}
+
+
+
+/* Callback for the value labels action */
+static void
+toggle_value_labels (GtkToggleAction *ta, gpointer data)
+{
+  PsppireDataWindow  *de = PSPPIRE_DATA_WINDOW (data);
+
+  g_object_set (de->data_editor, "value-labels", gtk_toggle_action_get_active (ta), NULL);
+}
+
+static void
+toggle_split_window (GtkToggleAction *ta, gpointer data)
+{
+  PsppireDataWindow  *de = PSPPIRE_DATA_WINDOW (data);
+
+  psppire_data_editor_split_window (de->data_editor,
+                                   gtk_toggle_action_get_active (ta));
+}
+
+
+static void
+file_quit (GtkCheckMenuItem *menuitem, gpointer data)
+{
+  /* FIXME: Need to be more intelligent here.
+     Give the user the opportunity to save any unsaved data.
+  */
+  g_object_unref (the_data_store);
+  gtk_main_quit ();
+}
+
+
+
+static GtkWidget *
+create_data_sheet_variable_popup_menu (PsppireDataWindow *de)
+{
+  GtkWidget *menu = gtk_menu_new ();
+
+  GtkWidget *sort_ascending =
+    gtk_menu_item_new_with_label (_("Sort Ascending"));
+
+  GtkWidget *sort_descending =
+    gtk_menu_item_new_with_label (_("Sort Descending"));
+
+  GtkWidget *insert_variable =
+    gtk_menu_item_new_with_label (_("Insert Variable"));
+
+  GtkWidget *clear_variable =
+    gtk_menu_item_new_with_label (_("Clear"));
+
+
+  gtk_action_connect_proxy (de->delete_variables,
+                           clear_variable );
+
+
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), insert_variable);
+
+
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu),
+                        gtk_separator_menu_item_new ());
+
+
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), clear_variable);
+
+
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu),
+                        gtk_separator_menu_item_new ());
+
+
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), sort_ascending);
+
+
+  g_signal_connect_swapped (G_OBJECT (sort_ascending), "activate",
+                           G_CALLBACK (psppire_data_editor_sort_ascending),
+                           de->data_editor);
+
+  g_signal_connect_swapped (G_OBJECT (sort_descending), "activate",
+                           G_CALLBACK (psppire_data_editor_sort_descending),
+                           de->data_editor);
+
+  g_signal_connect_swapped (G_OBJECT (insert_variable), "activate",
+                           G_CALLBACK (gtk_action_activate),
+                           de->insert_variable);
+
+
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), sort_descending);
+
+  gtk_widget_show_all (menu);
+
+  return menu;
+}
+
+
+static GtkWidget *
+create_data_sheet_cases_popup_menu (PsppireDataWindow *de)
+{
+  GtkWidget *menu = gtk_menu_new ();
+
+  GtkWidget *insert_case =
+    gtk_menu_item_new_with_label (_("Insert Case"));
+
+  GtkWidget *delete_case =
+    gtk_menu_item_new_with_label (_("Clear"));
+
+
+  gtk_action_connect_proxy (de->delete_cases,
+                           delete_case);
+
+
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), insert_case);
+
+  g_signal_connect_swapped (G_OBJECT (insert_case), "activate",
+                           G_CALLBACK (gtk_action_activate),
+                           de->insert_case);
+
+
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu),
+                        gtk_separator_menu_item_new ());
+
+
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), delete_case);
+
+
+  gtk_widget_show_all (menu);
+
+  return menu;
+}
+
+
+static GtkWidget *
+create_var_sheet_variable_popup_menu (PsppireDataWindow *de)
+{
+  GtkWidget *menu = gtk_menu_new ();
+
+  GtkWidget *insert_variable =
+    gtk_menu_item_new_with_label (_("Insert Variable"));
+
+  GtkWidget *delete_variable =
+    gtk_menu_item_new_with_label (_("Clear"));
+
+
+  gtk_action_connect_proxy (de->delete_variables,
+                           delete_variable);
+
+
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), insert_variable);
+
+  g_signal_connect_swapped (G_OBJECT (insert_variable), "activate",
+                           G_CALLBACK (gtk_action_activate),
+                           de->insert_variable);
+
+
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu),
+                        gtk_separator_menu_item_new ());
+
+
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), delete_variable);
+
+
+  gtk_widget_show_all (menu);
+
+  return menu;
+}
+
+
+#if RECENT_LISTS_AVAILABLE
+
+static void
+on_recent_data_select (GtkMenuShell *menushell,   gpointer user_data)
+{
+  gchar *file;
+  PsppireDataWindow  *de = PSPPIRE_DATA_WINDOW (user_data);
+
+  gchar *uri =
+    gtk_recent_chooser_get_current_uri (GTK_RECENT_CHOOSER (menushell));
+
+  file = g_filename_from_uri (uri, NULL, NULL);
+
+  g_free (uri);
+
+  open_data_file (file, de);
+
+  g_free (file);
+}
+
+static void
+on_recent_files_select (GtkMenuShell *menushell,   gpointer user_data)
+{
+  gchar *file;
+
+  GtkWidget *se ;
+
+  gchar *uri =
+    gtk_recent_chooser_get_current_uri (GTK_RECENT_CHOOSER (menushell));
+
+  file = g_filename_from_uri (uri, NULL, NULL);
+
+  g_free (uri);
+
+  se = psppire_syntax_window_new ();
+
+  psppire_syntax_window_load_from_file (PSPPIRE_SYNTAX_WINDOW (se), file, NULL);
+  gtk_widget_show (se);
+
+  g_free (file);
+}
+
+#endif
+
+static void
+enable_delete_cases (GtkWidget *w, gint case_num, gpointer data)
+{
+  PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
+
+  gtk_action_set_visible (de->delete_cases, case_num != -1);
+}
+
+
+static void
+enable_delete_variables (GtkWidget *w, gint var, gpointer data)
+{
+  PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
+
+  gtk_action_set_visible (de->delete_variables, var != -1);
+}
+
+/* Callback for when the datasheet/varsheet is selected */
+static void
+on_switch_sheet (GtkNotebook *notebook,
+               GtkNotebookPage *page,
+               guint page_num,
+               gpointer user_data)
+{
+  PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (user_data);
+
+  GtkWidget *view_data = get_widget_assert (de->xml, "view_data");
+  GtkWidget *view_variables = get_widget_assert (de->xml, "view_variables");
+
+  switch (page_num)
+    {
+    case PSPPIRE_DATA_EDITOR_VARIABLE_VIEW:
+      gtk_widget_hide (view_variables);
+      gtk_widget_show (view_data);
+      gtk_action_set_sensitive (de->insert_variable, TRUE);
+      gtk_action_set_sensitive (de->insert_case, FALSE);
+      gtk_action_set_sensitive (de->invoke_goto_dialog, FALSE);
+      break;
+    case PSPPIRE_DATA_EDITOR_DATA_VIEW:
+      gtk_widget_show (view_variables);
+      gtk_widget_hide (view_data);
+      gtk_action_set_sensitive (de->invoke_goto_dialog, TRUE);
+      gtk_action_set_sensitive (de->insert_case, TRUE);
+      break;
+    default:
+      g_assert_not_reached ();
+      break;
+    }
+
+#if 0
+  update_paste_menuitem (de, page_num);
+#endif
+}
+
+
+
+
+static void
+psppire_data_window_init (PsppireDataWindow *de)
+{
+  PsppireVarStore *vs;
+
+  GtkWidget *menubar;
+  GtkWidget *hb ;
+  GtkWidget *sb ;
+
+  GtkWidget *box = gtk_vbox_new (FALSE, 0);
+  de->xml = XML_NEW ("data-editor.glade");
+
+  menubar = get_widget_assert (de->xml, "menubar");
+  hb = get_widget_assert (de->xml, "handlebox1");
+  sb = get_widget_assert (de->xml, "status-bar");
+
+  de->data_editor =
+    PSPPIRE_DATA_EDITOR (psppire_data_editor_new (the_var_store, the_data_store));
+
+  connect_help (de->xml);
+
+  g_object_ref (menubar);
+  gtk_widget_unparent (menubar);
+
+  g_object_ref (hb);
+  gtk_widget_unparent (hb);
+
+  g_object_ref (sb);
+  gtk_widget_unparent (sb);
+
+  gtk_box_pack_start (GTK_BOX (box), menubar, FALSE, TRUE, 0);
+  gtk_box_pack_start (GTK_BOX (box), hb, FALSE, TRUE, 0);
+  gtk_box_pack_start (GTK_BOX (box), GTK_WIDGET (de->data_editor), TRUE, TRUE, 0);
+  gtk_box_pack_start (GTK_BOX (box), sb, FALSE, TRUE, 0);
+
+  gtk_container_add (GTK_CONTAINER (de), box);
+
+  g_signal_connect (de->data_editor, "data-selection-changed",
+                   G_CALLBACK (update_cut_copy_menuitems), de);
+
+  g_signal_connect (de->data_editor, "data-available-changed",
+                   G_CALLBACK (update_paste_menuitems), de);
+
+  dataset_add_transform_change_callback (the_dataset,
+                                        transformation_change_callback,
+                                        de);
+
+
+  vs = the_var_store;
+
+  g_assert(vs); /* Traps a possible bug in w32 build */
+
+  g_signal_connect (vs->dict, "weight-changed",
+                   G_CALLBACK (on_weight_change),
+                   de);
+
+  g_signal_connect (vs->dict, "filter-changed",
+                   G_CALLBACK (on_filter_change),
+                   de);
+
+  g_signal_connect (vs->dict, "split-changed",
+                   G_CALLBACK (on_split_change),
+                   de);
+
+
+  g_signal_connect (get_widget_assert (de->xml, "edit_copy"),
+                   "activate",
+                   G_CALLBACK (on_edit_copy), de);
+
+  g_signal_connect (get_widget_assert (de->xml, "edit_cut"),
+                   "activate",
+                   G_CALLBACK (on_edit_cut), de);
+
+
+  register_data_editor_actions (de);
+
+  de->toggle_value_labels =
+    gtk_toggle_action_new ("toggle-value-labels",
+                          _("_Labels"),
+                          _("Show/hide value labels"),
+                          "pspp-value-labels");
+
+  g_signal_connect (de->toggle_value_labels, "toggled",
+                   G_CALLBACK (toggle_value_labels), de);
+
+
+  gtk_action_connect_proxy (GTK_ACTION (de->toggle_value_labels),
+                           get_widget_assert (de->xml,
+                                              "togglebutton-value-labels"));
+
+
+  gtk_action_connect_proxy (GTK_ACTION (de->toggle_value_labels),
+                           get_widget_assert (de->xml,
+                                              "view_value-labels"));
+
+
+
+  de->delete_cases =
+    gtk_action_new ("clear-cases",
+                   _("Clear"),
+                   _("Delete the cases at the selected position(s)"),
+                   "pspp-clear-cases");
+
+  g_signal_connect_swapped (de->delete_cases, "activate",
+                   G_CALLBACK (psppire_data_editor_delete_cases),
+                   de->data_editor);
+
+  gtk_action_connect_proxy (de->delete_cases,
+                           get_widget_assert (de->xml, "edit_clear-cases"));
+
+  g_signal_connect (get_widget_assert (de->xml, "edit_paste"), "activate",
+                   G_CALLBACK (on_edit_paste),
+                   de);
+
+  gtk_action_set_visible (de->delete_cases, FALSE);
+
+  de->delete_variables =
+    gtk_action_new ("clear-variables",
+                   _("Clear"),
+                   _("Delete the variables at the selected position(s)"),
+                   "pspp-clear-variables");
+
+  g_signal_connect_swapped (de->delete_variables, "activate",
+                           G_CALLBACK (psppire_data_editor_delete_variables),
+                           de->data_editor);
+
+  gtk_action_connect_proxy (de->delete_variables,
+                           get_widget_assert (de->xml, "edit_clear-variables")
+                           );
+
+  gtk_action_set_visible (de->delete_variables, FALSE);
+
+  de->insert_variable =
+    gtk_action_new ("insert-variable",
+                   _("Insert _Variable"),
+                   _("Create a new variable at the current position"),
+                   "pspp-insert-variable");
+
+  g_signal_connect (de->insert_variable, "activate",
+                   G_CALLBACK (on_insert_variable), de->data_editor);
+
+
+  gtk_action_connect_proxy (de->insert_variable,
+                           get_widget_assert (de->xml, "button-insert-variable")
+                           );
+
+  gtk_action_connect_proxy (de->insert_variable,
+                           get_widget_assert (de->xml, "edit_insert-variable")
+                           );
+
+
+  de->insert_case =
+    gtk_action_new ("insert-case",
+                   _("Insert Ca_se"),
+                   _("Create a new case at the current position"),
+                   "pspp-insert-case");
+
+  g_signal_connect (de->insert_case, "activate",
+                   G_CALLBACK (insert_case), de);
+
+
+  gtk_action_connect_proxy (de->insert_case,
+                           get_widget_assert (de->xml, "button-insert-case")
+                           );
+
+
+  gtk_action_connect_proxy (de->insert_case,
+                           get_widget_assert (de->xml, "edit_insert-case")
+                           );
+
+
+  de->invoke_goto_dialog =
+    gtk_action_new ("goto-case-dialog",
+                   _("_Goto Case"),
+                   _("Jump to a Case in the Data Sheet"),
+                   "gtk-jump-to");
+
+
+  gtk_action_connect_proxy (de->invoke_goto_dialog,
+                           get_widget_assert (de->xml, "button-goto-case")
+                           );
+
+  gtk_action_connect_proxy (de->invoke_goto_dialog,
+                           get_widget_assert (de->xml, "edit_goto-case")
+                           );
+
+
+  g_signal_connect (de->invoke_goto_dialog, "activate",
+                   G_CALLBACK (goto_case_dialog), de);
+
+  de->invoke_weight_cases_dialog =
+    gtk_action_new ("weight-cases-dialog",
+                   _("_Weights"),
+                   _("Weight cases by variable"),
+                   "pspp-weight-cases");
+
+  g_signal_connect (de->invoke_weight_cases_dialog, "activate",
+                   G_CALLBACK (weight_cases_dialog), de);
+
+
+  de->invoke_transpose_dialog =
+    gtk_action_new ("transpose-dialog",
+                   _("_Transpose"),
+                   _("Transpose the cases with the variables"),
+                   NULL);
+
+
+  g_signal_connect (de->invoke_transpose_dialog, "activate",
+                   G_CALLBACK (transpose_dialog), de);
+
+
+
+  de->invoke_split_file_dialog =
+    gtk_action_new ("split-file-dialog",
+                   _("S_plit"),
+                   _("Split the active file"),
+                   "pspp-split-file");
+
+  g_signal_connect (de->invoke_split_file_dialog, "activate",
+                   G_CALLBACK (split_file_dialog), de);
+
+
+
+  de->invoke_sort_cases_dialog =
+    gtk_action_new ("sort-cases-dialog",
+                   _("_Sort"),
+                   _("Sort cases in the active file"),
+                   "pspp-sort-cases");
+
+  g_signal_connect (de->invoke_sort_cases_dialog, "activate",
+                   G_CALLBACK (sort_cases_dialog), de);
+
+  de->invoke_select_cases_dialog =
+    gtk_action_new ("select-cases-dialog",
+                   _("Select _Cases"),
+                   _("Select cases from the active file"),
+                   "pspp-select-cases");
+
+  g_signal_connect (de->invoke_select_cases_dialog, "activate",
+                   G_CALLBACK (select_cases_dialog), de);
+
+
+  de->invoke_compute_dialog =
+    gtk_action_new ("compute-dialog",
+                   _("_Compute"),
+                   _("Compute new values for a variable"),
+                   "pspp-compute");
+
+  g_signal_connect (de->invoke_compute_dialog, "activate",
+                   G_CALLBACK (compute_dialog), de);
+
+  de->invoke_oneway_anova_dialog =
+    gtk_action_new ("oneway-anova",
+                   _("Oneway _ANOVA"),
+                   _("Perform one way analysis of variance"),
+                   NULL);
+
+  g_signal_connect (de->invoke_oneway_anova_dialog, "activate",
+                   G_CALLBACK (oneway_anova_dialog), de);
+
+  de->invoke_t_test_independent_samples_dialog =
+    gtk_action_new ("t-test-independent-samples",
+                   _("_Independent Samples T Test"),
+                   _("Calculate T Test for samples from independent groups"),
+                   NULL);
+
+  g_signal_connect (de->invoke_t_test_independent_samples_dialog, "activate",
+                   G_CALLBACK (t_test_independent_samples_dialog), de);
+
+
+  de->invoke_t_test_paired_samples_dialog =
+    gtk_action_new ("t-test-paired-samples",
+                   _("_Paired Samples T Test"),
+                   _("Calculate T Test for paired samples"),
+                   NULL);
+
+  g_signal_connect (de->invoke_t_test_paired_samples_dialog, "activate",
+                   G_CALLBACK (t_test_paired_samples_dialog), de);
+
+
+  de->invoke_t_test_one_sample_dialog =
+    gtk_action_new ("t-test-one-sample",
+                   _("One _Sample T Test"),
+                   _("Calculate T Test for sample from a single distribution"),
+                   NULL);
+
+  g_signal_connect (de->invoke_t_test_one_sample_dialog, "activate",
+                   G_CALLBACK (t_test_one_sample_dialog), de);
+
+
+  de->invoke_comments_dialog =
+    gtk_action_new ("commments-dialog",
+                   _("Data File _Comments"),
+                   _("Commentary text for the data file"),
+                   NULL);
+
+  g_signal_connect (de->invoke_comments_dialog, "activate",
+                   G_CALLBACK (comments_dialog), de);
+
+  de->invoke_find_dialog  =
+    gtk_action_new ("find-dialog",
+                   _("_Find"),
+                   _("Find Case"),
+                   "gtk-find");
+
+  g_signal_connect (de->invoke_find_dialog, "activate",
+                   G_CALLBACK (find_dialog), de);
+
+
+  de->invoke_rank_dialog  =
+    gtk_action_new ("rank-dialog",
+                   _("Ran_k Cases"),
+                   _("Rank Cases"),
+                   "pspp-rank-cases");
+
+  g_signal_connect (de->invoke_rank_dialog, "activate",
+                   G_CALLBACK (rank_dialog), de);
+
+
+  de->invoke_recode_same_dialog  =
+    gtk_action_new ("recode-same-dialog",
+                   _("Recode into _Same Variables"),
+                   _("Recode values into the same Variables"),
+                   "pspp-recode-same");
+
+  g_signal_connect (de->invoke_recode_same_dialog, "activate",
+                   G_CALLBACK (recode_same_dialog), de);
+
+
+  de->invoke_recode_different_dialog  =
+    gtk_action_new ("recode-different-dialog",
+                   _("Recode into _Different Variables"),
+                   _("Recode values into different Variables"),
+                   "pspp-recode-different");
+
+  g_signal_connect (de->invoke_recode_different_dialog, "activate",
+                   G_CALLBACK (recode_different_dialog), de);
+
+
+  de->invoke_variable_info_dialog  =
+    gtk_action_new ("variable-info-dialog",
+                   _("_Variables"),
+                   _("Jump to Variable"),
+                   "pspp-goto-variable");
+
+  g_signal_connect (de->invoke_variable_info_dialog, "activate",
+                   G_CALLBACK (variable_info_dialog), de);
+
+  de->invoke_descriptives_dialog =
+    gtk_action_new ("descriptives-dialog",
+                   _("_Descriptives"),
+                   _("Calculate descriptive statistics (mean, variance, ...)"),
+                   "pspp-descriptives");
+
+  g_signal_connect (de->invoke_descriptives_dialog, "activate",
+                   G_CALLBACK (descriptives_dialog), de);
+
+
+  de->invoke_frequencies_dialog =
+    gtk_action_new ("frequencies-dialog",
+                   _("_Frequencies"),
+                   _("Generate frequency statistics"),
+                   "pspp-frequencies");
+
+  g_signal_connect (de->invoke_frequencies_dialog, "activate",
+                   G_CALLBACK (frequencies_dialog), de);
+
+  de->invoke_crosstabs_dialog =
+    gtk_action_new ("crosstabs-dialog",
+                   _("_Crosstabs"),
+                   _("Generate crosstabulations"),
+                   "pspp-crosstabs");
+
+  g_signal_connect (de->invoke_crosstabs_dialog, "activate",
+                   G_CALLBACK (crosstabs_dialog), de);
+
+
+  de->invoke_examine_dialog =
+    gtk_action_new ("examine-dialog",
+                   _("_Explore"),
+                   _("Examine Data by Factors"),
+                   "pspp-examine");
+
+  g_signal_connect (de->invoke_examine_dialog, "activate",
+                   G_CALLBACK (examine_dialog), de);
+
+
+  de->invoke_regression_dialog =
+    gtk_action_new ("regression-dialog",
+                   _("Linear _Regression"),
+                   _("Estimate parameters of the linear model"),
+                   "pspp-regression");
+
+  g_signal_connect (de->invoke_regression_dialog, "activate",
+                   G_CALLBACK (regression_dialog), de);
+
+  g_signal_connect_swapped (get_widget_assert (de->xml,"file_new_data"),
+                           "activate",
+                           G_CALLBACK (gtk_action_activate),
+                           de->action_data_new);
+
+  g_signal_connect_swapped (get_widget_assert (de->xml,"file_open_data"),
+                           "activate",
+                           G_CALLBACK (gtk_action_activate),
+                           de->action_data_open);
+
+#if RECENT_LISTS_AVAILABLE
+  {
+    GtkRecentManager *rm = gtk_recent_manager_get_default ();
+    GtkWidget *recent_data = get_widget_assert (de->xml, "file_recent-data");
+    GtkWidget *recent_files = get_widget_assert (de->xml, "file_recent-files");
+    GtkWidget *recent_separator = get_widget_assert (de->xml, "file_separator1");
+
+    GtkWidget *menu = gtk_recent_chooser_menu_new_for_manager (rm);
+
+    GtkRecentFilter *filter = gtk_recent_filter_new ();
+
+    gtk_widget_show (recent_data);
+    gtk_widget_show (recent_files);
+    gtk_widget_show (recent_separator);
+
+    gtk_recent_filter_add_pattern (filter, "*.sav");
+    gtk_recent_filter_add_pattern (filter, "*.SAV");
+
+    gtk_recent_chooser_add_filter (GTK_RECENT_CHOOSER (menu), filter);
+
+    gtk_widget_set_sensitive (recent_data, TRUE);
+    g_signal_connect (menu, "selection-done",
+                     G_CALLBACK (on_recent_data_select), de);
+
+    gtk_menu_item_set_submenu (GTK_MENU_ITEM (recent_data), menu);
+
+
+    filter = gtk_recent_filter_new ();
+    menu = gtk_recent_chooser_menu_new_for_manager (rm);
+
+    gtk_recent_filter_add_pattern (filter, "*.sps");
+    gtk_recent_filter_add_pattern (filter, "*.SPS");
+
+    gtk_recent_chooser_add_filter (GTK_RECENT_CHOOSER (menu), filter);
+
+    gtk_widget_set_sensitive (recent_files, TRUE);
+    g_signal_connect (menu, "selection-done",
+                     G_CALLBACK (on_recent_files_select), de);
+
+    gtk_menu_item_set_submenu (GTK_MENU_ITEM (recent_files), menu);
+  }
+#endif
+
+  g_signal_connect (get_widget_assert (de->xml,"file_new_syntax"),
+                   "activate",
+                   G_CALLBACK (create_syntax_window),
+                   NULL);
+
+  g_signal_connect (get_widget_assert (de->xml,"file_open_syntax"),
+                   "activate",
+                   G_CALLBACK (open_syntax_window),
+                   de);
+
+  g_signal_connect_swapped (get_widget_assert (de->xml,"file_import-text"),
+                           "activate",
+                           G_CALLBACK (gtk_action_activate),
+                           de->invoke_text_import_assistant);
+
+  g_signal_connect_swapped (get_widget_assert (de->xml,"file_save"),
+                           "activate",
+                           G_CALLBACK (gtk_action_activate),
+                           de->action_data_save);
+
+  g_signal_connect_swapped (get_widget_assert (de->xml,"file_save_as"),
+                           "activate",
+                           G_CALLBACK (gtk_action_activate),
+                           de->action_data_save_as);
+
+  gtk_action_connect_proxy (de->invoke_find_dialog,
+                           get_widget_assert (de->xml, "edit_find")
+                           );
+
+  gtk_action_connect_proxy (de->invoke_find_dialog,
+                           get_widget_assert (de->xml, "button-find")
+                           );
+
+  gtk_action_connect_proxy (de->invoke_rank_dialog,
+                           get_widget_assert (de->xml, "transform_rank")
+                           );
+
+  gtk_action_connect_proxy (de->invoke_recode_same_dialog,
+                           get_widget_assert (de->xml,
+                                              "transform_recode-same")
+                           );
+
+  gtk_action_connect_proxy (de->invoke_recode_different_dialog,
+                           get_widget_assert (de->xml,
+                                              "transform_recode-different")
+                           );
+
+  gtk_action_connect_proxy (de->invoke_weight_cases_dialog,
+                           get_widget_assert (de->xml, "data_weight-cases")
+                           );
+
+  gtk_action_connect_proxy (de->invoke_transpose_dialog,
+                           get_widget_assert (de->xml, "data_transpose")
+                           );
+
+  gtk_action_connect_proxy (de->invoke_split_file_dialog,
+                           get_widget_assert (de->xml, "data_split-file")
+                           );
+
+  gtk_action_connect_proxy (de->invoke_sort_cases_dialog,
+                           get_widget_assert (de->xml, "data_sort-cases")
+                           );
+
+  gtk_action_connect_proxy (de->invoke_select_cases_dialog,
+                           get_widget_assert (de->xml, "data_select-cases")
+                           );
+
+  gtk_action_connect_proxy (de->invoke_compute_dialog,
+                           get_widget_assert (de->xml, "transform_compute")
+                           );
+
+  gtk_action_connect_proxy (de->invoke_t_test_independent_samples_dialog,
+                           get_widget_assert (de->xml,
+                                              "indep-t-test")
+                           );
+
+
+  gtk_action_connect_proxy (de->invoke_t_test_paired_samples_dialog,
+                           get_widget_assert (de->xml,
+                                              "paired-t-test")
+                           );
+
+
+  gtk_action_connect_proxy (de->invoke_t_test_one_sample_dialog,
+                           get_widget_assert (de->xml,
+                                              "one-sample-t-test")
+                           );
+
+
+  gtk_action_connect_proxy (de->invoke_oneway_anova_dialog,
+                           get_widget_assert (de->xml,
+                                              "oneway-anova")
+                           );
+
+
+  gtk_action_connect_proxy (de->invoke_comments_dialog,
+                           get_widget_assert (de->xml, "utilities_comments")
+                           );
+
+  gtk_action_connect_proxy (de->invoke_variable_info_dialog,
+                           get_widget_assert (de->xml, "utilities_variables")
+                           );
+
+  gtk_action_connect_proxy (de->invoke_descriptives_dialog,
+                           get_widget_assert (de->xml, "analyze_descriptives")
+                           );
+
+  gtk_action_connect_proxy (de->invoke_crosstabs_dialog,
+                           get_widget_assert (de->xml, "crosstabs")
+                           );
+
+  gtk_action_connect_proxy (de->invoke_frequencies_dialog,
+                           get_widget_assert (de->xml, "analyze_frequencies")
+                           );
+
+
+  gtk_action_connect_proxy (de->invoke_examine_dialog,
+                           get_widget_assert (de->xml, "analyze_explore")
+                           );
+
+  gtk_action_connect_proxy (de->invoke_regression_dialog,
+                           get_widget_assert (de->xml, "linear-regression")
+                           );
+
+  g_signal_connect (get_widget_assert (de->xml,"help_about"),
+                   "activate",
+                   G_CALLBACK (about_new),
+                   de);
+
+
+  g_signal_connect (get_widget_assert (de->xml,"help_reference"),
+                   "activate",
+                   G_CALLBACK (reference_manual),
+                   de);
+
+
+  g_signal_connect (de->data_editor,
+                   "cases-selected",
+                   G_CALLBACK (enable_delete_cases),
+                   de);
+
+  g_signal_connect (de->data_editor,
+                   "variables-selected",
+                   G_CALLBACK (enable_delete_variables),
+                   de);
+
+
+  g_signal_connect (GTK_NOTEBOOK (de->data_editor),
+                   "switch-page",
+                   G_CALLBACK (on_switch_sheet), de);
+
+  gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_VARIABLE_VIEW);
+  gtk_notebook_set_current_page (GTK_NOTEBOOK (de->data_editor), PSPPIRE_DATA_EDITOR_DATA_VIEW);
+
+  g_signal_connect (get_widget_assert (de->xml, "view_statusbar"),
+                   "activate",
+                   G_CALLBACK (status_bar_activate), de);
+
+
+  g_signal_connect (get_widget_assert (de->xml, "view_gridlines"),
+                   "activate",
+                   G_CALLBACK (grid_lines_activate), de);
+
+
+
+  g_signal_connect (get_widget_assert (de->xml, "view_data"),
+                   "activate",
+                   G_CALLBACK (data_view_activate), de);
+
+  g_signal_connect (get_widget_assert (de->xml, "view_variables"),
+                   "activate",
+                   G_CALLBACK (variable_view_activate), de);
+
+
+
+  g_signal_connect (get_widget_assert (de->xml, "view_fonts"),
+                   "activate",
+                   G_CALLBACK (fonts_activate), de);
+
+
+
+
+  gtk_action_connect_proxy (de->action_data_open,
+                           get_widget_assert (de->xml, "button-open")
+                           );
+
+  gtk_action_connect_proxy (de->action_data_save,
+                           get_widget_assert (de->xml, "button-save")
+                           );
+
+  gtk_action_connect_proxy (de->invoke_variable_info_dialog,
+                           get_widget_assert (de->xml, "button-goto-variable")
+                           );
+
+  gtk_action_connect_proxy (de->invoke_weight_cases_dialog,
+                           get_widget_assert (de->xml, "button-weight-cases")
+                           );
+
+  gtk_action_connect_proxy (de->invoke_split_file_dialog,
+                           get_widget_assert (de->xml, "button-split-file")
+                           );
+
+  gtk_action_connect_proxy (de->invoke_select_cases_dialog,
+                           get_widget_assert (de->xml, "button-select-cases")
+                           );
+
+
+  g_signal_connect (get_widget_assert (de->xml, "file_quit"),
+                   "activate",
+                   G_CALLBACK (file_quit), de);
+
+  g_signal_connect (get_widget_assert (de->xml, "transform_run-pending"),
+                   "activate",
+                   G_CALLBACK (execute), de);
+
+
+  g_signal_connect (get_widget_assert (de->xml, "windows_minimise_all"),
+                   "activate",
+                   G_CALLBACK (psppire_window_minimise_all), NULL);
+
+  de->toggle_split_window =
+    gtk_toggle_action_new ("toggle-split-window",
+                          _("_Split Window"),
+                          _("Split the window vertically and horizontally"),
+                          "pspp-split-window");
+
+  g_signal_connect (de->toggle_split_window, "toggled",
+                   G_CALLBACK (toggle_split_window),
+                   de);
+
+  gtk_action_connect_proxy (GTK_ACTION (de->toggle_split_window),
+                           get_widget_assert (de->xml,
+                                              "windows_split"));
+
+  de->data_sheet_variable_popup_menu =
+    GTK_MENU (create_data_sheet_variable_popup_menu (de));
+
+  de->var_sheet_variable_popup_menu =
+    GTK_MENU (create_var_sheet_variable_popup_menu (de));
+
+  de->data_sheet_cases_popup_menu =
+    GTK_MENU (create_data_sheet_cases_popup_menu (de));
+
+  PSPPIRE_WINDOW (de)->menu = GTK_MENU_SHELL (get_widget_assert (de->xml,"Windows_menu"));
+
+  g_object_set (de->data_editor,
+               "datasheet-column-menu", de->data_sheet_variable_popup_menu,
+               "datasheet-row-menu", de->data_sheet_cases_popup_menu,
+               "varsheet-row-menu", de->var_sheet_variable_popup_menu,
+               NULL);
+
+  gtk_widget_show (GTK_WIDGET (de->data_editor));
+  gtk_widget_show (box);
+}
+
+
+GtkWidget*
+psppire_data_window_new (void)
+{
+  return GTK_WIDGET (g_object_new (psppire_data_window_get_type (),
+                                  "usage", PSPPIRE_WINDOW_USAGE_DATA,
+                                  NULL));
+}
+
diff --git a/src/ui/gui/psppire-data-window.h b/src/ui/gui/psppire-data-window.h
new file mode 100644 (file)
index 0000000..77687dc
--- /dev/null
@@ -0,0 +1,120 @@
+/* PSPPIRE - a graphical user interface for PSPP.
+   Copyright (C) 2008  Free Software Foundation
+
+   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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+
+#ifndef __PSPPIRE_DATA_WINDOW_H__
+#define __PSPPIRE_DATA_WINDOW_H__
+
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtkaction.h>
+#include "psppire-window.h"
+#include "psppire-data-editor.h"
+#include <glade/glade.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define PSPPIRE_DATA_WINDOW_TYPE            (psppire_data_window_get_type ())
+#define PSPPIRE_DATA_WINDOW(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), PSPPIRE_DATA_WINDOW_TYPE, PsppireDataWindow))
+#define PSPPIRE_DATA_WINDOW_CLASS(class)    (G_TYPE_CHECK_CLASS_CAST ((class), \
+    PSPPIRE_DATA_WINDOW_TYPE, PsppireData_WindowClass))
+#define PSPPIRE_IS_DATA_WINDOW(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+    PSPPIRE_DATA_WINDOW_TYPE))
+#define PSPPIRE_IS_DATA_WINDOW_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \
+    PSPPIRE_DATA_WINDOW_TYPE))
+
+
+typedef struct _PsppireDataWindow       PsppireDataWindow;
+typedef struct _PsppireDataWindowClass  PsppireDataWindowClass;
+
+
+struct _PsppireDataWindow
+{
+  PsppireWindow parent;
+
+  /* <private> */
+  PsppireDataEditor *data_editor;
+  GladeXML *xml;
+  GtkAction *action_data_new;
+  GtkAction *action_data_open;
+  GtkAction *action_data_save_as;
+  GtkAction *action_data_save;
+
+  GtkAction *invoke_text_import_assistant;
+
+  /* Actions which invoke dialog boxes */
+  GtkAction *invoke_weight_cases_dialog;
+  GtkAction *invoke_transpose_dialog;
+  GtkAction *invoke_split_file_dialog;
+  GtkAction *invoke_sort_cases_dialog;
+  GtkAction *invoke_compute_dialog;
+  GtkAction *invoke_comments_dialog;
+  GtkAction *invoke_select_cases_dialog;
+  GtkAction *invoke_goto_dialog;
+  GtkAction *invoke_variable_info_dialog;
+  GtkAction *invoke_find_dialog;
+  GtkAction *invoke_rank_dialog;
+  GtkAction *invoke_recode_same_dialog;
+  GtkAction *invoke_recode_different_dialog;
+
+  GtkAction *invoke_crosstabs_dialog;
+  GtkAction *invoke_descriptives_dialog;
+  GtkAction *invoke_frequencies_dialog;
+  GtkAction *invoke_examine_dialog;
+  GtkAction *invoke_regression_dialog;
+
+  GtkAction *invoke_t_test_independent_samples_dialog;
+  GtkAction *invoke_t_test_paired_samples_dialog;
+  GtkAction *invoke_oneway_anova_dialog;
+  GtkAction *invoke_t_test_one_sample_dialog;
+
+  GtkToggleAction *toggle_split_window;
+  GtkToggleAction *toggle_value_labels;
+
+
+  GtkAction *insert_variable;
+  GtkAction *insert_case;
+  GtkAction *delete_variables;
+  GtkAction *delete_cases;
+
+
+  GtkMenu *data_sheet_variable_popup_menu;
+  GtkMenu *data_sheet_cases_popup_menu;
+  GtkMenu *var_sheet_variable_popup_menu;
+
+
+  gboolean save_as_portable;
+
+  /* Name of the file this data is associated with (ie, was loaded from or
+     has been  saved to), in "filename encoding",  or NULL, if it's not
+     associated with any file */
+  gchar *file_name;
+};
+
+struct _PsppireDataWindowClass
+{
+  PsppireWindowClass parent_class;
+};
+
+GType      psppire_data_window_get_type        (void);
+GtkWidget* psppire_data_window_new             (void);
+
+
+G_END_DECLS
+
+#endif /* __PSPPIRE_DATA_WINDOW_H__ */
diff --git a/src/ui/gui/psppire-output-window.c b/src/ui/gui/psppire-output-window.c
new file mode 100644 (file)
index 0000000..5fc52e9
--- /dev/null
@@ -0,0 +1,376 @@
+/* PSPPIRE - a graphical user interface for PSPP.
+   Copyright (C) 2008  Free Software Foundation
+
+   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.
+
+   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 <gtk/gtksignal.h>
+#include <gtk/gtkbox.h>
+#include <glade/glade.h>
+#include "helper.h"
+
+#include <libpspp/message.h>
+#include <stdlib.h>
+
+#include "about.h"
+
+#include "psppire-output-window.h"
+
+
+#include "xalloc.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <gettext.h>
+#define _(msgid) gettext (msgid)
+#define N_(msgid) msgid
+
+
+
+static void psppire_output_window_base_finalize (PsppireOutputWindowClass *, gpointer);
+static void psppire_output_window_base_init     (PsppireOutputWindowClass *class);
+static void psppire_output_window_class_init    (PsppireOutputWindowClass *class);
+static void psppire_output_window_init          (PsppireOutputWindow      *window);
+
+
+GType
+psppire_output_window_get_type (void)
+{
+  static GType psppire_output_window_type = 0;
+
+  if (!psppire_output_window_type)
+    {
+      static const GTypeInfo psppire_output_window_info =
+      {
+       sizeof (PsppireOutputWindowClass),
+       (GBaseInitFunc) psppire_output_window_base_init,
+        (GBaseFinalizeFunc) psppire_output_window_base_finalize,
+       (GClassInitFunc)psppire_output_window_class_init,
+       (GClassFinalizeFunc) NULL,
+       NULL,
+        sizeof (PsppireOutputWindow),
+       0,
+       (GInstanceInitFunc) psppire_output_window_init,
+      };
+
+      psppire_output_window_type =
+       g_type_register_static (PSPPIRE_WINDOW_TYPE, "PsppireOutputWindow",
+                               &psppire_output_window_info, 0);
+    }
+
+  return psppire_output_window_type;
+}
+
+
+static void
+psppire_output_window_finalize (GObject *object)
+{
+  GObjectClass *class = G_OBJECT_GET_CLASS (object);
+
+  GObjectClass *parent_class = g_type_class_peek_parent (class);
+
+
+  if (G_OBJECT_CLASS (parent_class)->finalize)
+    (*G_OBJECT_CLASS (parent_class)->finalize) (object);
+
+}
+
+
+static void
+psppire_output_window_class_init (PsppireOutputWindowClass *class)
+{
+}
+
+
+static void
+psppire_output_window_base_init (PsppireOutputWindowClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+  object_class->finalize = psppire_output_window_finalize;
+}
+
+
+
+static void
+psppire_output_window_base_finalize (PsppireOutputWindowClass *class,
+                                    gpointer class_data)
+{
+}
+
+
+\f
+
+static PsppireOutputWindow *the_output_viewer = NULL;
+
+
+int viewer_length = 16;
+int viewer_width = 59;
+
+/* Callback for the "delete" action (clicking the x on the top right
+   hand corner of the window) */
+static gboolean
+on_delete (GtkWidget *w, GdkEvent *event, gpointer user_data)
+{
+  PsppireOutputWindow *ow = PSPPIRE_OUTPUT_WINDOW (user_data);
+
+  gtk_widget_destroy (GTK_WIDGET (ow));
+
+  the_output_viewer = NULL;
+
+  unlink (OUTPUT_FILE_NAME);
+
+  return FALSE;
+}
+
+
+
+static void
+cancel_urgency (GtkWindow *window,  gpointer data)
+{
+  gtk_window_set_urgency_hint (window, FALSE);
+}
+/* Sets width and length according to the new size
+   of the output window */
+static void
+on_textview_resize (GtkWidget     *widget,
+                   GtkAllocation *allocation,
+                   gpointer       user_data)
+{
+  PangoContext * context ;
+  PangoLayout *layout ;
+  PangoRectangle logical;
+  GtkStyle *style;
+  gint right_margin, left_margin;
+  GtkTextView *text_view = GTK_TEXT_VIEW (widget);
+
+  context = gtk_widget_create_pango_context (widget);
+  layout = pango_layout_new (context);
+
+  style = gtk_widget_get_style (widget);
+
+  pango_layout_set_font_description (layout, style->font_desc);
+
+  /* Find the width of one character.  We can use any character, because
+     the textview has a monospaced font */
+  pango_layout_set_text (layout, "M", 1);
+
+  pango_layout_get_extents (layout,  NULL, &logical);
+
+  left_margin = gtk_text_view_get_left_margin (text_view);
+  right_margin = gtk_text_view_get_right_margin (text_view);
+
+  viewer_length = allocation->height / PANGO_PIXELS (logical.height);
+  viewer_width = (allocation->width - right_margin - left_margin)
+    / PANGO_PIXELS (logical.width);
+
+  g_object_unref (G_OBJECT (layout));
+  g_object_unref (G_OBJECT (context));
+}
+
+
+static void
+psppire_output_window_init (PsppireOutputWindow *window)
+{
+  GladeXML *xml = XML_NEW ("output-viewer.glade");
+
+  GtkWidget *box = gtk_vbox_new (FALSE, 0);
+
+  GtkWidget *sw = get_widget_assert (xml, "scrolledwindow1");
+
+  GtkWidget *menubar = get_widget_assert (xml, "menubar1");
+
+  window->textview = get_widget_assert (xml, "output-viewer-textview");
+
+
+  gtk_container_add (GTK_CONTAINER (window), box);
+
+
+  g_object_ref (menubar);
+  gtk_widget_unparent (menubar);
+
+  g_object_ref (sw);
+  gtk_widget_unparent (sw);
+
+
+  gtk_box_pack_start (GTK_BOX (box), menubar, FALSE, TRUE, 0);
+  gtk_box_pack_start (GTK_BOX (box), sw, TRUE, TRUE, 0);
+
+
+  gtk_widget_show_all (box);
+
+  connect_help (xml);
+
+  window->buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (window->textview));
+
+  g_signal_connect (window,
+                   "focus-in-event",
+                   G_CALLBACK (cancel_urgency),
+                   NULL);
+
+  {
+    /* Output uses ascii characters for tabular material.
+       So we need a monospaced font otherwise it'll look silly */
+    PangoFontDescription *font_desc =
+      pango_font_description_from_string ("monospace");
+
+    gtk_widget_modify_font (window->textview, font_desc);
+    pango_font_description_free (font_desc);
+  }
+
+  g_signal_connect (window->textview, "size-allocate",
+                   G_CALLBACK (on_textview_resize), NULL);
+
+  window->fp = NULL;
+
+  g_signal_connect (get_widget_assert (xml,"help_about"),
+                   "activate",
+                   G_CALLBACK (about_new),
+                   window);
+
+  g_signal_connect (get_widget_assert (xml,"help_reference"),
+                   "activate",
+                   G_CALLBACK (reference_manual),
+                   NULL);
+
+  g_signal_connect (get_widget_assert (xml,"windows_minimise-all"),
+                   "activate",
+                   G_CALLBACK (psppire_window_minimise_all),
+                   NULL);
+
+  PSPPIRE_WINDOW (window)->menu = GTK_MENU_SHELL (get_widget_assert (xml,"windows_menu"));
+
+
+  g_object_unref (xml);
+
+  g_signal_connect (window, "delete-event",
+                   G_CALLBACK (on_delete), window);
+}
+
+
+GtkWidget*
+psppire_output_window_new (void)
+{
+  return GTK_WIDGET (g_object_new (psppire_output_window_get_type (),
+                                  "usage", PSPPIRE_WINDOW_USAGE_OUTPUT,
+                                  NULL));
+}
+
+static void reload_viewer (PsppireOutputWindow *ow);
+
+void
+psppire_output_window_reload (void)
+{
+  struct stat buf;
+
+  /* If there is no output, then don't do anything */
+  if (0 != stat (OUTPUT_FILE_NAME, &buf))
+    return ;
+
+  if ( NULL == the_output_viewer )
+    {
+      the_output_viewer = PSPPIRE_OUTPUT_WINDOW (psppire_output_window_new ());
+      gtk_widget_show (GTK_WIDGET (the_output_viewer));
+    }
+
+  reload_viewer (the_output_viewer);
+
+}
+
+
+static void
+reload_viewer (PsppireOutputWindow *ow)
+{
+  GtkTextIter end_iter;
+  GtkTextMark *mark ;
+
+  static char *line = NULL;
+
+  gboolean chars_inserted = FALSE;
+
+  gtk_text_buffer_get_end_iter (ow->buffer, &end_iter);
+
+  line = xrealloc (line, sizeof (char) * (viewer_width + 1));
+
+  mark = gtk_text_buffer_create_mark (ow->buffer, NULL, &end_iter, TRUE);
+
+#ifdef __CYGWIN__
+  /*
+    Apparently Windoze is not capabale of writing to a file whilst
+    another (or the same) process is reading from it.   Therefore, we
+    must close the file after reading it, and clear the entire buffer
+    before writing to it.
+    This will be slower for large buffers, but should work
+    (in so far as anything ever works on windows).
+  */
+  {
+    GtkTextIter start_iter;
+    FILE *fp = fopen (OUTPUT_FILE_NAME, "r");
+    if ( !fp)
+      {
+       g_print ("Cannot open %s\n", OUTPUT_FILE_NAME);
+       return;
+      }
+
+    /* Delete all the entire buffer */
+    gtk_text_buffer_get_start_iter (ov->buffer, &start_iter);
+    gtk_text_buffer_delete (ov->buffer, &start_iter, &end_iter);
+
+
+    gtk_text_buffer_get_start_iter (ov->buffer, &start_iter);
+    /* Read in the next lot of text */
+    while (fgets (line, viewer_width + 1, fp) != NULL)
+      {
+       chars_inserted = TRUE;
+       gtk_text_buffer_insert (ov->buffer, &start_iter, line, -1);
+      }
+
+    fclose (fp);
+  }
+#else
+  {
+    if ( ow->fp == NULL)
+      {
+       ow->fp = fopen (OUTPUT_FILE_NAME, "r");
+       if ( ow->fp == NULL)
+         {
+           g_print ("Cannot open %s\n", OUTPUT_FILE_NAME);
+           return;
+         }
+      }
+
+    /* Read in the next lot of text */
+    while (fgets (line, viewer_width + 1, ow->fp) != NULL)
+      {
+       chars_inserted = TRUE;
+       gtk_text_buffer_insert (ow->buffer, &end_iter, line, -1);
+      }
+  }
+#endif
+
+  /* Scroll to where the start of this lot of text begins */
+  gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (ow->textview),
+                               mark,
+                               0.1, TRUE, 0.0, 0.0);
+
+
+  if ( chars_inserted )
+    gtk_window_set_urgency_hint ( GTK_WINDOW (ow), TRUE);
+}
+
+
+
diff --git a/src/ui/gui/psppire-output-window.h b/src/ui/gui/psppire-output-window.h
new file mode 100644 (file)
index 0000000..621a9e2
--- /dev/null
@@ -0,0 +1,78 @@
+/* PSPPIRE - a graphical user interface for PSPP.
+   Copyright (C) 2008  Free Software Foundation
+
+   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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+
+#ifndef __PSPPIRE_OUTPUT_WINDOW_H__
+#define __PSPPIRE_OUTPUT_WINDOW_H__
+
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtkaction.h>
+#include <gtk/gtktextbuffer.h>
+#include "psppire-window.h"
+#include <gtk/gtk.h>
+
+extern int viewer_length;
+extern int viewer_width ;
+
+
+#define OUTPUT_FILE_NAME "psppire.txt"
+
+
+
+G_BEGIN_DECLS
+
+#define PSPPIRE_OUTPUT_WINDOW_TYPE            (psppire_output_window_get_type ())
+#define PSPPIRE_OUTPUT_WINDOW(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), PSPPIRE_OUTPUT_WINDOW_TYPE, PsppireOutputWindow))
+#define PSPPIRE_OUTPUT_WINDOW_CLASS(class)    (G_TYPE_CHECK_CLASS_CAST ((class), \
+    PSPPIRE_OUTPUT_WINDOW_TYPE, PsppireOutput_WindowClass))
+#define PSPPIRE_IS_OUTPUT_WINDOW(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+    PSPPIRE_OUTPUT_WINDOW_TYPE))
+#define PSPPIRE_IS_OUTPUT_WINDOW_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \
+    PSPPIRE_OUTPUT_WINDOW_TYPE))
+
+
+typedef struct _PsppireOutputWindow       PsppireOutputWindow;
+typedef struct _PsppireOutputWindowClass  PsppireOutputWindowClass;
+
+
+struct _PsppireOutputWindow
+{
+  PsppireWindow parent;
+
+  /* <private> */
+  GtkTextBuffer *buffer;  /* The buffer which contains the text */
+  GtkWidget *textview ;
+  FILE *fp;               /* The file it's viewing */
+};
+
+struct _PsppireOutputWindowClass
+{
+  PsppireWindowClass parent_class;
+
+};
+
+GType      psppire_output_window_get_type        (void);
+GtkWidget* psppire_output_window_new             (void);
+
+
+void psppire_output_window_reload (void);
+
+
+G_END_DECLS
+
+#endif /* __PSPPIRE_OUTPUT_WINDOW_H__ */
diff --git a/src/ui/gui/psppire-syntax-window.c b/src/ui/gui/psppire-syntax-window.c
new file mode 100644 (file)
index 0000000..37bfd35
--- /dev/null
@@ -0,0 +1,631 @@
+/* PSPPIRE - a graphical user interface for PSPP.
+   Copyright (C) 2008  Free Software Foundation
+
+   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.
+
+   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 <gtk/gtksignal.h>
+#include <gtk/gtkbox.h>
+#include <glade/glade.h>
+#include "helper.h"
+
+#include <libpspp/message.h>
+#include <stdlib.h>
+
+#include "psppire-syntax-window.h"
+
+#include "psppire-data-window.h"
+#include "psppire-window-register.h"
+#include "about.h"
+#include "psppire-syntax-window.h"
+#include "syntax-editor-source.h"
+#include <language/lexer/lexer.h>
+
+#include <gettext.h>
+#define _(msgid) gettext (msgid)
+#define N_(msgid) msgid
+
+static void psppire_syntax_window_base_finalize (PsppireSyntaxWindowClass *, gpointer);
+static void psppire_syntax_window_base_init     (PsppireSyntaxWindowClass *class);
+static void psppire_syntax_window_class_init    (PsppireSyntaxWindowClass *class);
+static void psppire_syntax_window_init          (PsppireSyntaxWindow      *syntax_editor);
+
+GType
+psppire_syntax_window_get_type (void)
+{
+  static GType psppire_syntax_window_type = 0;
+
+  if (!psppire_syntax_window_type)
+    {
+      static const GTypeInfo psppire_syntax_window_info =
+      {
+       sizeof (PsppireSyntaxWindowClass),
+       (GBaseInitFunc) psppire_syntax_window_base_init,
+        (GBaseFinalizeFunc) psppire_syntax_window_base_finalize,
+       (GClassInitFunc)psppire_syntax_window_class_init,
+       (GClassFinalizeFunc) NULL,
+       NULL,
+        sizeof (PsppireSyntaxWindow),
+       0,
+       (GInstanceInitFunc) psppire_syntax_window_init,
+      };
+
+      psppire_syntax_window_type =
+       g_type_register_static (PSPPIRE_WINDOW_TYPE, "PsppireSyntaxWindow",
+                               &psppire_syntax_window_info, 0);
+    }
+
+  return psppire_syntax_window_type;
+}
+
+static void
+psppire_syntax_window_finalize (GObject *object)
+{
+  GObjectClass *class = G_OBJECT_GET_CLASS (object);
+
+  GObjectClass *parent_class = g_type_class_peek_parent (class);
+
+  if (G_OBJECT_CLASS (parent_class)->finalize)
+    (*G_OBJECT_CLASS (parent_class)->finalize) (object);
+}
+
+
+static void
+psppire_syntax_window_class_init (PsppireSyntaxWindowClass *class)
+{
+}
+
+
+static void
+psppire_syntax_window_base_init (PsppireSyntaxWindowClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+  object_class->finalize = psppire_syntax_window_finalize;
+}
+
+
+
+static void
+psppire_syntax_window_base_finalize (PsppireSyntaxWindowClass *class,
+                                    gpointer class_data)
+{
+}
+
+
+static void
+editor_execute_syntax (const PsppireSyntaxWindow *sw, GtkTextIter start,
+                      GtkTextIter stop)
+{
+  PsppireWindow *win = PSPPIRE_WINDOW (sw);
+  const gchar *name = psppire_window_get_filename (win);
+  execute_syntax (create_syntax_editor_source (sw->buffer, start, stop, name));
+}
+
+
+/* Parse and execute all the text in the buffer */
+static void
+on_run_all (GtkMenuItem *menuitem, gpointer user_data)
+{
+  GtkTextIter begin, end;
+  PsppireSyntaxWindow *se = PSPPIRE_SYNTAX_WINDOW (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;
+  PsppireSyntaxWindow *se = PSPPIRE_SYNTAX_WINDOW (user_data);
+
+  if ( gtk_text_buffer_get_selection_bounds (se->buffer, &begin, &end) )
+    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;
+
+  PsppireSyntaxWindow *se = PSPPIRE_SYNTAX_WINDOW (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);
+}
+
+
+
+/* Parse and execute the current line */
+static void
+on_run_current_line (GtkMenuItem *menuitem, gpointer user_data)
+{
+  GtkTextIter begin, end;
+  GtkTextIter here;
+  gint line;
+
+  PsppireSyntaxWindow *se = PSPPIRE_SYNTAX_WINDOW (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);
+}
+
+
+
+/* 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);
+}
+
+/*
+  Save BUFFER to the file called FILENAME.
+  If successful, clears the buffer's modified flag
+*/
+static gboolean
+save_editor_to_file (PsppireSyntaxWindow *se,
+                    const gchar *filename,
+                    GError **err)
+{
+  GtkTextBuffer *buffer = se->buffer;
+  gboolean result ;
+  GtkTextIter start, stop;
+  gchar *text;
+
+  gchar *suffixedname;
+  gchar *glibfilename;
+  g_assert (filename);
+
+  suffixedname = append_suffix (filename);
+
+  glibfilename = g_filename_from_utf8 (suffixedname, -1, 0, 0, err);
+
+  g_free ( suffixedname);
+
+  if ( ! glibfilename )
+    return FALSE;
+
+  gtk_text_buffer_get_iter_at_line (buffer, &start, 0);
+  gtk_text_buffer_get_iter_at_offset (buffer, &stop, -1);
+
+  text = gtk_text_buffer_get_text (buffer, &start, &stop, FALSE);
+
+  result =  g_file_set_contents (glibfilename, text, -1, err);
+
+  if ( result )
+    {
+      psppire_window_set_filename (PSPPIRE_WINDOW (se), filename);
+      gtk_text_buffer_set_modified (buffer, FALSE);
+    }
+
+  return result;
+}
+
+/* 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 (PsppireSyntaxWindow *se)
+{
+
+  if ( TRUE == gtk_text_buffer_get_modified (se->buffer))
+    {
+      gint response;
+      GtkWidget *dialog;
+
+      const gchar *filename = psppire_window_get_filename (PSPPIRE_WINDOW (se));
+
+      g_return_if_fail (filename != NULL);
+
+      dialog =
+       gtk_message_dialog_new (GTK_WINDOW (se),
+                               GTK_DIALOG_MODAL,
+                               GTK_MESSAGE_QUESTION,
+                               GTK_BUTTONS_NONE,
+                               _("Save contents of syntax editor to %s?"),
+                               filename);
+
+      gtk_dialog_add_button  (GTK_DIALOG (dialog),
+                             GTK_STOCK_YES,
+                             GTK_RESPONSE_ACCEPT);
+      gtk_dialog_add_button  (GTK_DIALOG (dialog),
+                             GTK_STOCK_NO,
+                             GTK_RESPONSE_REJECT);
+      gtk_dialog_add_button  (GTK_DIALOG (dialog),
+                             GTK_STOCK_CANCEL,
+                             GTK_RESPONSE_CANCEL);
+
+
+      response = gtk_dialog_run (GTK_DIALOG (dialog));
+
+      gtk_widget_destroy (dialog);
+
+      if ( response == GTK_RESPONSE_ACCEPT )
+       {
+         GError *err = NULL;
+
+         if ( ! save_editor_to_file (se, filename, &err) )
+           {
+             msg (ME, err->message);
+             g_error_free (err);
+           }
+       }
+
+      if ( response == GTK_RESPONSE_CANCEL )
+       return ;
+    }
+
+  gtk_widget_destroy (GTK_WIDGET (se));
+}
+
+/* Callback for the File->SaveAs menuitem */
+static void
+on_syntax_save_as (GtkMenuItem *menuitem, gpointer user_data)
+{
+  GtkFileFilter *filter;
+  gint response;
+
+  PsppireSyntaxWindow *se = PSPPIRE_SYNTAX_WINDOW (user_data);
+
+  GtkWidget *dialog =
+    gtk_file_chooser_dialog_new (_("Save Syntax"),
+                                GTK_WINDOW (se),
+                                GTK_FILE_CHOOSER_ACTION_SAVE,
+                                GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                                GTK_STOCK_SAVE,   GTK_RESPONSE_ACCEPT,
+                                NULL);
+
+  filter = gtk_file_filter_new ();
+  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);
+
+  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),
+                                                 TRUE);
+  response = gtk_dialog_run (GTK_DIALOG (dialog));
+
+  if ( response == GTK_RESPONSE_ACCEPT )
+    {
+      GError *err = NULL;
+      char *filename =
+       gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog) );
+
+      if ( ! save_editor_to_file (se, filename, &err) )
+       {
+         msg ( ME, err->message );
+         g_error_free (err);
+       }
+
+      free (filename);
+    }
+
+  gtk_widget_destroy (dialog);
+}
+
+
+/* Callback for the File->Save menuitem */
+static void
+on_syntax_save (GtkMenuItem *menuitem, gpointer user_data)
+{
+  PsppireSyntaxWindow *se = PSPPIRE_SYNTAX_WINDOW (user_data);
+  const gchar *filename = psppire_window_get_filename (PSPPIRE_WINDOW (se));
+
+
+  if ( filename == NULL )
+    on_syntax_save_as (menuitem, se);
+  else
+    {
+      GError *err = NULL;
+      save_editor_to_file (se, filename, &err);
+      if ( err )
+       {
+         msg (ME, err->message);
+         g_error_free (err);
+       }
+    }
+}
+
+
+/* Callback for the File->Quit menuitem */
+static gboolean
+on_quit (GtkMenuItem *menuitem, gpointer    user_data)
+{
+  PsppireSyntaxWindow *se = PSPPIRE_SYNTAX_WINDOW (user_data);
+  save_if_modified (se);
+  return FALSE;
+}
+
+
+/* Callback for the "delete" action (clicking the x on the top right
+   hand corner of the window) */
+static gboolean
+on_delete (GtkWidget *w, GdkEvent *event, gpointer user_data)
+{
+  PsppireSyntaxWindow *se = PSPPIRE_SYNTAX_WINDOW (user_data);
+
+  save_if_modified (se);
+  return TRUE;
+}
+
+
+void
+create_syntax_window (void)
+{
+  GtkWidget *w = psppire_syntax_window_new ();
+  gtk_widget_show (w);
+}
+
+/* Callback for the File->Open->Syntax menuitem */
+void
+open_syntax_window (GtkMenuItem *menuitem, gpointer parent)
+{
+  GtkFileFilter *filter;
+  gint response;
+
+  GtkWidget *dialog =
+    gtk_file_chooser_dialog_new (_("Open Syntax"),
+                                GTK_WINDOW (parent),
+                                GTK_FILE_CHOOSER_ACTION_OPEN,
+                                GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                                GTK_STOCK_OPEN,   GTK_RESPONSE_ACCEPT,
+                                NULL);
+
+  filter = gtk_file_filter_new ();
+  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);
+
+  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);
+
+  response = gtk_dialog_run (GTK_DIALOG (dialog));
+
+  if (response == GTK_RESPONSE_ACCEPT)
+    {
+      const char *file_name = gtk_file_chooser_get_filename
+       (GTK_FILE_CHOOSER (dialog));
+
+      GtkWidget *se = psppire_syntax_window_new ();
+
+      if ( psppire_syntax_window_load_from_file (PSPPIRE_SYNTAX_WINDOW (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
+      gtk_widget_show (se);
+    }
+
+  gtk_widget_destroy (dialog);
+}
+
+
+
+extern struct source_stream *the_source_stream ;
+
+static void
+psppire_syntax_window_init (PsppireSyntaxWindow *window)
+{
+  GladeXML *xml = XML_NEW ("syntax-editor.glade");
+  GtkWidget *box = gtk_vbox_new (FALSE, 0);
+  
+  GtkWidget *menubar = get_widget_assert (xml, "menubar2");
+  GtkWidget *sw = get_widget_assert (xml, "scrolledwindow8");
+  GtkWidget *sb = get_widget_assert (xml, "statusbar2");
+
+  GtkWidget *text_view = get_widget_assert (xml, "syntax_text_view");
+  window->buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
+  window->lexer = lex_create (the_source_stream);
+
+  connect_help (xml);
+
+  gtk_container_add (GTK_CONTAINER (window), box);
+
+  g_object_ref (menubar);
+  gtk_widget_unparent (menubar);
+
+  g_object_ref (sw);
+  gtk_widget_unparent (sw);
+
+  g_object_ref (sb);
+  gtk_widget_unparent (sb);
+
+
+  gtk_box_pack_start (GTK_BOX (box), menubar, FALSE, TRUE, 0);
+  gtk_box_pack_start (GTK_BOX (box), sw, TRUE, TRUE, 0);
+  gtk_box_pack_start (GTK_BOX (box), sb, FALSE, TRUE, 0);
+
+  gtk_widget_show_all (box);
+
+  g_signal_connect (get_widget_assert (xml,"file_new_syntax"),
+                   "activate",
+                   G_CALLBACK (create_syntax_window),
+                   NULL);
+
+  g_signal_connect (get_widget_assert (xml,"file_open_syntax"),
+                   "activate",
+                   G_CALLBACK (open_syntax_window),
+                   window);
+
+#if 0
+  g_signal_connect (get_widget_assert (xml,"file_new_data"),
+                   "activate",
+                   G_CALLBACK (create_data_window),
+                   window);
+#endif
+
+  g_signal_connect (get_widget_assert (xml,"help_about"),
+                   "activate",
+                   G_CALLBACK (about_new),
+                   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),
+                   window);
+
+  g_signal_connect (get_widget_assert (xml, "file_save_as"),
+                   "activate",
+                   G_CALLBACK (on_syntax_save_as),
+                   window);
+
+  g_signal_connect (get_widget_assert (xml,"file_quit"),
+                   "activate",
+                   G_CALLBACK (on_quit),
+                   window);
+
+  g_signal_connect (get_widget_assert (xml,"run_all"),
+                   "activate",
+                   G_CALLBACK (on_run_all),
+                   window);
+
+
+  g_signal_connect (get_widget_assert (xml,"run_selection"),
+                   "activate",
+                   G_CALLBACK (on_run_selection),
+                   window);
+
+  g_signal_connect (get_widget_assert (xml,"run_current_line"),
+                   "activate",
+                   G_CALLBACK (on_run_current_line),
+                   window);
+
+  g_signal_connect (get_widget_assert (xml,"run_to_end"),
+                   "activate",
+                   G_CALLBACK (on_run_to_end),
+                   window);
+
+  g_signal_connect (get_widget_assert (xml,"windows_minimise_all"),
+                   "activate",
+                   G_CALLBACK (psppire_window_minimise_all), NULL);
+
+  PSPPIRE_WINDOW (window)->menu = GTK_MENU_SHELL (get_widget_assert (xml,"windows_menu"));
+
+  g_object_unref (xml);
+
+  g_signal_connect (window, "delete-event",
+                   G_CALLBACK (on_delete), window);
+}
+
+
+GtkWidget*
+psppire_syntax_window_new (void)
+{
+  return GTK_WIDGET (g_object_new (psppire_syntax_window_get_type (),
+                                  "usage", PSPPIRE_WINDOW_USAGE_SYNTAX,
+                                  NULL));
+}
+
+
+/*
+  Loads the buffer from the file called FILENAME
+*/
+gboolean
+psppire_syntax_window_load_from_file (PsppireSyntaxWindow *se,
+                                     const gchar *filename,
+                                     GError **err)
+{
+  gchar *text;
+  GtkTextIter iter;
+
+  gchar *glibfilename = g_filename_from_utf8 (filename, -1, 0, 0, err);
+
+  if ( ! glibfilename )
+    return FALSE;
+
+  /* FIXME: What if it's a very big file ? */
+  if ( ! g_file_get_contents (glibfilename, &text, NULL, err) )
+    {
+      g_free (glibfilename);
+      return FALSE;
+    }
+  g_free (glibfilename);
+
+  gtk_text_buffer_get_iter_at_line (se->buffer, &iter, 0);
+
+  gtk_text_buffer_insert (se->buffer, &iter, text, -1);
+
+  psppire_window_set_filename (PSPPIRE_WINDOW (se), filename);
+
+  gtk_text_buffer_set_modified (se->buffer, FALSE);
+
+  return TRUE;
+}
+
diff --git a/src/ui/gui/psppire-syntax-window.h b/src/ui/gui/psppire-syntax-window.h
new file mode 100644 (file)
index 0000000..c434e07
--- /dev/null
@@ -0,0 +1,73 @@
+/* PSPPIRE - a graphical user interface for PSPP.
+   Copyright (C) 2008  Free Software Foundation
+
+   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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+
+#ifndef __PSPPIRE_SYNTAX_WINDOW_H__
+#define __PSPPIRE_SYNTAX_WINDOW_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtkaction.h>
+#include <gtk/gtktextbuffer.h>
+#include "psppire-window.h"
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define PSPPIRE_SYNTAX_WINDOW_TYPE            (psppire_syntax_window_get_type ())
+#define PSPPIRE_SYNTAX_WINDOW(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), PSPPIRE_SYNTAX_WINDOW_TYPE, PsppireSyntaxWindow))
+#define PSPPIRE_SYNTAX_WINDOW_CLASS(class)    (G_TYPE_CHECK_CLASS_CAST ((class), \
+    PSPPIRE_SYNTAX_WINDOW_TYPE, PsppireSyntax_WindowClass))
+#define PSPPIRE_IS_SYNTAX_WINDOW(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+    PSPPIRE_SYNTAX_WINDOW_TYPE))
+#define PSPPIRE_IS_SYNTAX_WINDOW_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \
+    PSPPIRE_SYNTAX_WINDOW_TYPE))
+
+
+typedef struct _PsppireSyntaxWindow       PsppireSyntaxWindow;
+typedef struct _PsppireSyntaxWindowClass  PsppireSyntaxWindowClass;
+
+
+struct _PsppireSyntaxWindow
+{
+  PsppireWindow parent;
+
+  /* <private> */
+
+  GtkTextBuffer *buffer;  /* The buffer which contains the text */
+  struct lexer *lexer;    /* Lexer to parse syntax */
+};
+
+struct _PsppireSyntaxWindowClass
+{
+  PsppireWindowClass parent_class;
+
+};
+
+GType      psppire_syntax_window_get_type        (void);
+GtkWidget* psppire_syntax_window_new             (void);
+
+gboolean   psppire_syntax_window_load_from_file (PsppireSyntaxWindow *se,
+                                                       const gchar *filename,
+                                                       GError **err);
+
+void open_syntax_window (GtkMenuItem *menuitem, gpointer parent);
+void create_syntax_window (void);
+
+
+G_END_DECLS
+
+#endif /* __PSPPIRE_SYNTAX_WINDOW_H__ */
diff --git a/src/ui/gui/psppire-window-register.c b/src/ui/gui/psppire-window-register.c
new file mode 100644 (file)
index 0000000..dfa46c6
--- /dev/null
@@ -0,0 +1,189 @@
+/* PSPPIRE - a graphical user interface for PSPP.
+   Copyright (C) 2008  Free Software Foundation
+
+   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.
+
+   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 "psppire-window-register.h"
+
+static void psppire_window_register_init            (PsppireWindowRegister      *window_register);
+static void psppire_window_register_class_init      (PsppireWindowRegisterClass *class);
+
+static void psppire_window_register_finalize        (GObject   *object);
+static void psppire_window_register_dispose        (GObject   *object);
+
+static GObjectClass *parent_class = NULL;
+
+
+enum  {
+  INSERTED,
+  REMOVED,
+  n_SIGNALS
+};
+
+static guint signals [n_SIGNALS];
+
+GType
+psppire_window_register_get_type (void)
+{
+  static GType window_register_type = 0;
+
+  if (!window_register_type)
+    {
+      static const GTypeInfo window_register_info =
+      {
+       sizeof (PsppireWindowRegisterClass),
+       NULL,           /* base_init */
+       NULL,           /* base_finalize */
+        (GClassInitFunc) psppire_window_register_class_init,
+       NULL,           /* class_finalize */
+       NULL,           /* class_data */
+        sizeof (PsppireWindowRegister),
+       0,
+        (GInstanceInitFunc) psppire_window_register_init,
+      };
+
+      window_register_type = g_type_register_static (G_TYPE_OBJECT,
+                                               "PsppireWindowRegister",
+                                               &window_register_info, 0);
+    }
+
+  return window_register_type;
+}
+
+
+static void
+psppire_window_register_finalize (GObject *object)
+{
+}
+
+static void
+psppire_window_register_dispose  (GObject *object)
+{
+}
+
+static PsppireWindowRegister *the_instance = NULL;
+
+static GObject*
+psppire_window_register_construct   (GType                  type,
+                                    guint                  n_construct_params,
+                                    GObjectConstructParam *construct_params)
+{
+  GObject *object;
+  
+  if (!the_instance)
+    {
+      object = G_OBJECT_CLASS (parent_class)->constructor (type,
+                                                           n_construct_params,
+                                                           construct_params);
+      the_instance = PSPPIRE_WINDOW_REGISTER (object);
+    }
+  else
+    object = g_object_ref (G_OBJECT (the_instance));
+
+  return object;
+}
+
+static void
+psppire_window_register_class_init (PsppireWindowRegisterClass *class)
+{
+  GObjectClass *object_class;
+
+  parent_class = g_type_class_peek_parent (class);
+  object_class = (GObjectClass*) class;
+
+  object_class->finalize = psppire_window_register_finalize;
+  object_class->dispose = psppire_window_register_dispose;
+  object_class->constructor = psppire_window_register_construct;
+
+  signals [INSERTED] =
+    g_signal_new ("inserted",
+                 G_TYPE_FROM_CLASS (class),
+                 G_SIGNAL_RUN_FIRST,
+                 0,
+                 NULL, NULL,
+                 g_cclosure_marshal_VOID__POINTER,
+                 G_TYPE_NONE,
+                 1,
+                 G_TYPE_POINTER);
+
+  signals [REMOVED] =
+    g_signal_new ("removed",
+                 G_TYPE_FROM_CLASS (class),
+                 G_SIGNAL_RUN_FIRST,
+                 0,
+                 NULL, NULL,
+                 g_cclosure_marshal_VOID__POINTER,
+                 G_TYPE_NONE,
+                 1,
+                 G_TYPE_POINTER);
+}
+
+static void
+psppire_window_register_init (PsppireWindowRegister *window_register)
+{
+  window_register->dispose_has_run = FALSE;
+  window_register->name_table = g_hash_table_new (g_str_hash, g_str_equal);
+}
+
+void
+psppire_window_register_insert (PsppireWindowRegister *wr, PsppireWindow *window, const gchar *name)
+{
+  g_hash_table_insert (wr->name_table, (gpointer) name, window);
+
+  g_signal_emit (wr, signals[INSERTED], 0, name);
+}
+
+
+void
+psppire_window_register_remove (PsppireWindowRegister *wr, const gchar *name)
+{
+  g_signal_emit (wr, signals[REMOVED], 0, name);
+
+  g_hash_table_remove (wr->name_table, (gpointer) name);
+}
+
+PsppireWindow *
+psppire_window_register_lookup (PsppireWindowRegister *wr, const gchar *name)
+{
+  return g_hash_table_lookup (wr->name_table, name);
+}
+
+void
+psppire_window_register_foreach (PsppireWindowRegister *wr, GHFunc func, PsppireWindow *win)
+{
+  g_hash_table_foreach (wr->name_table, func, win);
+}
+
+static void
+minimise_window (gpointer key, gpointer value, gpointer data)
+{
+  gtk_window_iconify (GTK_WINDOW (value));
+}
+
+
+void
+psppire_window_register_minimise_all (PsppireWindowRegister *wr)
+{
+  g_hash_table_foreach (wr->name_table, minimise_window, wr);
+}
+
+
+
+PsppireWindowRegister *
+psppire_window_register_new (void)
+{
+  return g_object_new (psppire_window_register_get_type (), NULL);
+}
diff --git a/src/ui/gui/psppire-window-register.h b/src/ui/gui/psppire-window-register.h
new file mode 100644 (file)
index 0000000..cc24f4e
--- /dev/null
@@ -0,0 +1,92 @@
+/* PSPPIRE - a graphical user interface for PSPP.
+   Copyright (C) 2008  Free Software Foundation
+
+   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.
+
+   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 <glib-object.h>
+#include <glib.h>
+
+#include "psppire-window.h"
+
+#ifndef __PSPPIRE_WINDOW_REGISTER_H__
+#define __PSPPIRE_WINDOW_REGISTER_H__
+
+G_BEGIN_DECLS
+
+
+#define PSPPIRE_TYPE_WINDOW_REGISTER (psppire_window_register_get_type ())
+
+#define PSPPIRE_WINDOW_REGISTER(obj)   \
+                     (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+                   PSPPIRE_TYPE_WINDOW_REGISTER, PsppireWindowRegister))
+
+#define PSPPIRE_WINDOW_REGISTER_CLASS(klass) \
+                     (G_TYPE_CHECK_CLASS_CAST ((klass), \
+                                PSPPIRE_TYPE_WINDOW_REGISTER, \
+                                 PsppireWindowRegisterClass))
+
+
+#define PSPPIRE_IS_WINDOW_REGISTER(obj) \
+                    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PSPPIRE_TYPE_WINDOW_REGISTER))
+
+#define PSPPIRE_IS_WINDOW_REGISTER_CLASS(klass) \
+                     (G_TYPE_CHECK_CLASS_TYPE ((klass), PSPPIRE_TYPE_WINDOW_REGISTER))
+
+
+#define PSPPIRE_WINDOW_REGISTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+                                  PSPPIRE_TYPE_WINDOW_REGISTER, \
+                                  PsppireWindowRegisterClass))
+
+typedef struct _PsppireWindowRegister       PsppireWindowRegister;
+typedef struct _PsppireWindowRegisterClass  PsppireWindowRegisterClass;
+
+
+struct _PsppireWindowRegister
+{
+  GObject parent;
+
+  /*< private >*/
+  gboolean dispose_has_run ;
+  GHashTable *name_table;
+};
+
+
+struct _PsppireWindowRegisterClass
+{
+  GObjectClass parent_class;
+};
+
+
+GType psppire_window_register_get_type (void) G_GNUC_CONST;
+
+PsppireWindowRegister * psppire_window_register_new (void);
+
+void psppire_window_register_insert (PsppireWindowRegister *wr, PsppireWindow *window,
+                                    const gchar *name);
+
+void psppire_window_register_remove (PsppireWindowRegister *wr, const gchar *name);
+
+
+PsppireWindow *psppire_window_register_lookup (PsppireWindowRegister *wr, const gchar *name);
+
+
+void psppire_window_register_foreach (PsppireWindowRegister *wr, GHFunc func, PsppireWindow *);
+
+void psppire_window_register_minimise_all (PsppireWindowRegister *wr);
+
+
+G_END_DECLS
+
+#endif /* __PSPPIRE_WINDOW_REGISTER_H__ */
diff --git a/src/ui/gui/psppire-window.c b/src/ui/gui/psppire-window.c
new file mode 100644 (file)
index 0000000..ebced6d
--- /dev/null
@@ -0,0 +1,444 @@
+/* PSPPIRE - a graphical user interface for PSPP.
+   Copyright (C) 2008  Free Software Foundation
+
+   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.
+
+   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 <gtk/gtksignal.h>
+#include <gtk/gtkwindow.h>
+#include <gtk/gtkcheckmenuitem.h>
+
+#include <stdlib.h>
+
+#include <gettext.h>
+#define _(msgid) gettext (msgid)
+#define N_(msgid) msgid
+
+#include "psppire-window.h"
+#include "psppire-window-register.h"
+
+static void psppire_window_base_finalize (PsppireWindowClass *, gpointer);
+static void psppire_window_base_init     (PsppireWindowClass *class);
+static void psppire_window_class_init    (PsppireWindowClass *class);
+static void psppire_window_init          (PsppireWindow      *window);
+
+
+static PsppireWindowClass *the_class;
+static GObjectClass *parent_class;
+
+GType
+psppire_window_get_type (void)
+{
+  static GType psppire_window_type = 0;
+
+  if (!psppire_window_type)
+    {
+      static const GTypeInfo psppire_window_info =
+      {
+       sizeof (PsppireWindowClass),
+       (GBaseInitFunc) psppire_window_base_init,
+        (GBaseFinalizeFunc) psppire_window_base_finalize,
+       (GClassInitFunc) psppire_window_class_init,
+       (GClassFinalizeFunc) NULL,
+       NULL,
+        sizeof (PsppireWindow),
+       0,
+       (GInstanceInitFunc) psppire_window_init,
+      };
+
+      psppire_window_type =
+       g_type_register_static (GTK_TYPE_WINDOW, "PsppireWindow",
+                               &psppire_window_info, 0);
+    }
+
+  return psppire_window_type;
+}
+
+
+/* Properties */
+enum
+{
+  PROP_0,
+  PROP_FILENAME,
+  PROP_USAGE
+};
+
+
+gchar *
+uniquify (const gchar *str, int *x)
+{
+  return g_strdup_printf ("%s%d", str, (*x)++);
+}
+
+
+
+static void
+psppire_window_set_property (GObject         *object,
+                            guint            prop_id,
+                            const GValue    *value,
+                            GParamSpec      *pspec)
+{
+  PsppireWindow *window = PSPPIRE_WINDOW (object);
+
+  switch (prop_id)
+    {
+    case PROP_USAGE:
+      window->usage = g_value_get_enum (value);
+      break;
+    case PROP_FILENAME:
+      {
+       PsppireWindowRegister *reg = psppire_window_register_new ();
+       gchar mdash[6] = {0,0,0,0,0,0};
+       gchar *basename, *title;
+       const gchar *name = g_value_get_string (value);
+       int x = 0;
+       gchar *candidate_name ;
+       GValue def = {0};
+       g_value_init (&def, pspec->value_type);
+
+       if ( NULL == name)
+         {
+           g_param_value_set_default (pspec, &def);
+           name = g_value_get_string (&def);
+         }
+       
+        candidate_name = strdup (name);
+
+       while ( psppire_window_register_lookup (reg, candidate_name))
+         {
+           free (candidate_name);
+           candidate_name = uniquify (name, &x);
+         }
+
+       basename = g_path_get_basename (candidate_name);
+       g_unichar_to_utf8 (0x2014, mdash);
+
+       g_value_unset (&def);
+
+       switch (window->usage)
+         {
+         case PSPPIRE_WINDOW_USAGE_SYNTAX:
+           title = g_strdup_printf ( _("%s %s PSPPIRE Syntax Editor"),
+                                     basename, mdash);
+           break;
+         case PSPPIRE_WINDOW_USAGE_OUTPUT:
+           title = g_strdup_printf ( _("%s %s PSPPIRE Output"),
+                                     basename, mdash);
+         case PSPPIRE_WINDOW_USAGE_DATA:
+           title = g_strdup_printf ( _("%s %s PSPPIRE Data Editor"),
+                                     basename, mdash);
+           break;
+         default:
+           g_assert_not_reached ();
+           break;
+         }
+
+       gtk_window_set_title (GTK_WINDOW (window), title);
+
+       if ( window->name)
+         psppire_window_register_remove (reg, window->name);
+
+       free (window->name);
+       window->name = candidate_name;
+
+       psppire_window_register_insert (reg, window, window->name);
+
+       free (basename);
+       free (title);
+      }
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    };
+}
+
+
+static void
+psppire_window_get_property (GObject         *object,
+                            guint            prop_id,
+                            GValue          *value,
+                            GParamSpec      *pspec)
+{
+  PsppireWindow *window = PSPPIRE_WINDOW (object);
+
+  switch (prop_id)
+    {
+    case PROP_USAGE:
+      g_value_set_enum (value, window->usage);
+      break;
+    case PROP_FILENAME:
+      g_value_set_string (value, window->name);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    };
+}
+
+
+
+static void
+psppire_window_finalize (GObject *object)
+{
+  PsppireWindow *window = PSPPIRE_WINDOW (object);
+  
+  PsppireWindowRegister *reg = psppire_window_register_new ();
+
+  psppire_window_register_remove (reg, window->name);
+  free (window->name);
+
+  g_signal_handler_disconnect (psppire_window_register_new (),
+                              window->remove_handler);
+
+  g_signal_handler_disconnect (psppire_window_register_new (),
+                              window->insert_handler);
+
+  g_hash_table_destroy (window->menuitem_table);
+
+  if (G_OBJECT_CLASS (parent_class)->finalize)
+    G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+
+static void
+psppire_window_class_init (PsppireWindowClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+  GParamSpec *use_class_spec =
+    g_param_spec_enum ("usage",
+                      "Usage",
+                      "What the window is used for",
+                      G_TYPE_PSPPIRE_WINDOW_USAGE,
+                      PSPPIRE_WINDOW_USAGE_SYNTAX /* default value */,
+                      G_PARAM_CONSTRUCT_ONLY |G_PARAM_READABLE | G_PARAM_WRITABLE);
+
+
+  GParamSpec *filename_spec =
+    g_param_spec_string ("filename",
+                      "File name",
+                      "The name of the file associated with this window, if any",
+                        "Untitled",
+                        G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT
+                        );
+
+
+  object_class->set_property = psppire_window_set_property;
+  object_class->get_property = psppire_window_get_property;
+
+  g_object_class_install_property (object_class,
+                                   PROP_FILENAME,
+                                   filename_spec);
+
+  g_object_class_install_property (object_class,
+                                   PROP_USAGE,
+                                   use_class_spec);
+
+
+  the_class = class;
+  parent_class = g_type_class_peek_parent (class);
+}
+
+
+static void
+psppire_window_base_init (PsppireWindowClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+  object_class->finalize = psppire_window_finalize;
+}
+
+
+
+static void
+psppire_window_base_finalize (PsppireWindowClass *class,
+                               gpointer class_data)
+{
+}
+
+static void
+menu_toggled (GtkCheckMenuItem *mi, gpointer data)
+{
+  /* Prohibit changes to the state */
+  mi->active = !mi->active;
+}
+
+
+/* Look up the window associated with this menuitem and present it to the user */
+static void
+menu_activate (GtkMenuItem *mi, gpointer data)
+{
+  const gchar *key = data;
+
+  PsppireWindowRegister *reg = psppire_window_register_new ();
+
+  PsppireWindow *window = psppire_window_register_lookup (reg, key);
+
+  gtk_window_present (GTK_WINDOW (window));
+}
+
+static void
+insert_menuitem_into_menu (PsppireWindow *window, gpointer key)
+{
+  GtkWidget *item = gtk_check_menu_item_new_with_label (key);
+
+  g_signal_connect (item, "toggled", G_CALLBACK (menu_toggled), NULL);
+  g_signal_connect (item, "activate", G_CALLBACK (menu_activate), key);
+
+  gtk_widget_show (item);
+  
+  gtk_menu_shell_append (window->menu, item);
+
+  /* Set the state without emitting a signal */
+  GTK_CHECK_MENU_ITEM (item)->active =
+   (psppire_window_register_lookup (psppire_window_register_new (), key) == window);
+
+  g_hash_table_insert (window->menuitem_table, key, item);
+}
+
+static void
+insert_item (gpointer key, gpointer value, gpointer data)
+{
+  PsppireWindow *window = PSPPIRE_WINDOW (data);
+
+  if ( NULL != g_hash_table_lookup (window->menuitem_table, key))
+    return;
+
+  insert_menuitem_into_menu (window, key);
+}
+
+/* Insert a new item into the window menu */
+static void
+insert_menuitem (GObject *reg, const gchar *key, gpointer data)
+{
+  PsppireWindow *window = PSPPIRE_WINDOW (data);
+  
+  insert_menuitem_into_menu (window, (gpointer) key);
+}
+
+
+static void
+remove_menuitem (PsppireWindowRegister *reg, const gchar *key, gpointer data)
+{
+  PsppireWindow *window = PSPPIRE_WINDOW (data);
+  GtkWidget *item ;
+
+  item = g_hash_table_lookup (window->menuitem_table, key);
+
+  g_hash_table_remove (window->menuitem_table, key);
+
+  if (GTK_IS_CONTAINER (window->menu))
+    gtk_container_remove (GTK_CONTAINER (window->menu), item);
+}
+
+static void
+insert_existing_items (PsppireWindow *window)
+{
+  psppire_window_register_foreach (psppire_window_register_new (), insert_item, window);
+}
+
+static void
+psppire_window_init (PsppireWindow *window)
+{
+  window->name = NULL;
+  window->menu = NULL;
+
+  window->menuitem_table  = g_hash_table_new (g_str_hash, g_str_equal);
+
+
+  g_signal_connect (window,  "realize", G_CALLBACK (insert_existing_items), NULL);
+
+  window->insert_handler = g_signal_connect (psppire_window_register_new (),
+                                            "inserted",
+                                            G_CALLBACK (insert_menuitem),
+                                            window);
+
+  window->remove_handler = g_signal_connect (psppire_window_register_new (),
+                                            "removed",
+                                            G_CALLBACK (remove_menuitem),
+                                            window);
+}
+
+
+GtkWidget*
+psppire_window_new (PsppireWindowUsage usage)
+{
+  return GTK_WIDGET (g_object_new (psppire_window_get_type (),
+                                  "type", GTK_WINDOW_TOPLEVEL,
+                                  "usage", usage,
+                                  NULL));
+}
+
+
+const gchar *
+psppire_window_get_filename (PsppireWindow *w)
+{
+  const gchar *name = NULL;
+  g_object_get (w, "filename", &name, NULL);
+  return name;
+}
+
+
+void
+psppire_window_set_filename (PsppireWindow *w, const gchar *filename)
+{
+  g_object_set (w, "filename", filename, NULL);
+}
+
+\f
+
+GType
+psppire_window_usage_get_type (void)
+{
+  static GType etype = 0;
+  if (etype == 0)
+    {
+      static const GEnumValue values[] = {
+       { PSPPIRE_WINDOW_USAGE_SYNTAX, "PSPPIRE_WINDOW_USAGE_SYNTAX",
+         "Syntax" },
+
+       { PSPPIRE_WINDOW_USAGE_OUTPUT, "PSPPIRE_WINDOW_USAGE_OUTPUT",
+         "Output" },
+
+       { PSPPIRE_WINDOW_USAGE_DATA,   "PSPPIRE_WINDOW_USAGE_DATA",
+         "Data" },
+
+       { 0, NULL, NULL }
+      };
+
+      etype = g_enum_register_static (g_intern_static_string ("PsppireWindowUsage"),
+                                     values);
+    }
+
+  return etype;
+}
+
+
+
+static void
+minimise_window (gpointer key, gpointer value, gpointer data)
+{
+  gtk_window_iconify (GTK_WINDOW (value));
+}
+
+
+void
+psppire_window_minimise_all (void)
+{
+  PsppireWindowRegister *reg = psppire_window_register_new ();
+
+  g_hash_table_foreach (reg->name_table, minimise_window, NULL);
+}
diff --git a/src/ui/gui/psppire-window.h b/src/ui/gui/psppire-window.h
new file mode 100644 (file)
index 0000000..ef7feb2
--- /dev/null
@@ -0,0 +1,92 @@
+/* PSPPIRE - a graphical user interface for PSPP.
+   Copyright (C) 2008  Free Software Foundation
+
+   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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+
+#ifndef __PSPPIRE_WINDOW_H__
+#define __PSPPIRE_WINDOW_H__
+
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtkwindow.h>
+#include <gtk/gtkaction.h>
+#include <gtk/gtkmenushell.h>
+
+G_BEGIN_DECLS
+
+typedef enum {
+  PSPPIRE_WINDOW_USAGE_SYNTAX,
+  PSPPIRE_WINDOW_USAGE_OUTPUT,
+  PSPPIRE_WINDOW_USAGE_DATA
+} PsppireWindowUsage;
+
+
+GType psppire_window_usage_get_type (void);
+
+
+#define G_TYPE_PSPPIRE_WINDOW_USAGE \
+  (psppire_window_usage_get_type())
+
+\f
+
+
+#define PSPPIRE_WINDOW_TYPE            (psppire_window_get_type ())
+#define PSPPIRE_WINDOW(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), PSPPIRE_WINDOW_TYPE, PsppireWindow))
+#define PSPPIRE_WINDOW_CLASS(class)    (G_TYPE_CHECK_CLASS_CAST ((class), \
+    PSPPIRE_WINDOW_TYPE, PsppireWindowClass))
+#define PSPPIRE_IS_WINDOW(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+    PSPPIRE_WINDOW_TYPE))
+#define PSPPIRE_IS_WINDOW_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \
+    PSPPIRE_WINDOW_TYPE))
+
+
+typedef struct _PsppireWindow       PsppireWindow;
+typedef struct _PsppireWindowClass  PsppireWindowClass;
+
+
+struct _PsppireWindow
+{
+  GtkWindow parent;
+
+  /* <private> */
+  gchar *name;
+  PsppireWindowUsage usage;
+
+  GHashTable *menuitem_table;
+  GtkMenuShell *menu;
+
+  guint insert_handler;
+  guint remove_handler;
+};
+
+struct _PsppireWindowClass
+{
+  GtkWindowClass parent_class;
+};
+
+GType      psppire_window_get_type        (void);
+GtkWidget* psppire_window_new             (PsppireWindowUsage usage);
+
+const gchar * psppire_window_get_filename (PsppireWindow *);
+
+void psppire_window_set_filename (PsppireWindow *w, const gchar *filename);
+
+void psppire_window_minimise_all (void);
+
+
+G_END_DECLS
+
+#endif /* __PSPPIRE_WINDOW_H__ */
index 9dd3b71372f6334fea60115c325aa35724353f06..bdd5ad5332f4062d4b0bf6927a42ea2b57223d30 100644 (file)
@@ -25,7 +25,7 @@
 #include <ui/command-line.h>
 #include "relocatable.h"
 
-#include "data-editor.h"
+#include "psppire-data-window.h"
 #include "psppire.h"
 
 #include <libpspp/getl.h>
@@ -52,7 +52,8 @@
 #include "message-dialog.h"
 #include <ui/syntax-gen.h>
 
-#include "output-viewer.h"
+
+#include "psppire-output-window.h"
 
 #include <data/sys-file-reader.h>
 #include <data/por-file-reader.h>
@@ -67,6 +68,7 @@ static void create_icon_factory (void);
 struct source_stream *the_source_stream ;
 struct dataset * the_dataset = NULL;
 
+static GtkWidget *the_data_window;
 
 static void
 replace_casereader (struct casereader *s)
@@ -77,6 +79,10 @@ replace_casereader (struct casereader *s)
 #define _(msgid) gettext (msgid)
 #define N_(msgid) msgid
 
+
+const char * output_file_name (void);
+
+
 void
 initialize (struct command_line_processor *clp, int argc, char **argv)
 {
@@ -116,8 +122,6 @@ initialize (struct command_line_processor *clp, int argc, char **argv)
   the_data_store = psppire_data_store_new (dictionary);
   replace_casereader (NULL);
 
-
-
   create_icon_factory ();
 
   {
@@ -143,14 +147,16 @@ initialize (struct command_line_processor *clp, int argc, char **argv)
   journal_enable ();
   textdomain (PACKAGE);
 
+  the_data_window = psppire_data_window_new ();
+
   command_line_processor_replace_aux (clp, &post_init_argp, the_source_stream);
   command_line_processor_replace_aux (clp, &non_option_argp, the_source_stream);
 
   command_line_processor_parse (clp, argc, argv);
 
-  new_data_window (NULL, NULL);
-
   execute_syntax (create_syntax_string_source (""));
+
+  gtk_widget_show (the_data_window);
 }
 
 
@@ -288,6 +294,9 @@ parse_non_options (int key, char *arg, struct argp_state *state)
                            ERRMODE_CONTINUE);
 
        ds_destroy (&syntax);
+
+       psppire_window_set_filename (the_data_window, arg);
+
        break;
       }
     default:
@@ -298,3 +307,17 @@ parse_non_options (int key, char *arg, struct argp_state *state)
 
 
 const struct argp non_option_argp = {NULL, parse_non_options, 0, 0, 0, 0, 0};
+
+
+const char *
+output_file_name (void)
+{
+  const char *dir = default_output_path ();
+  static char *filename = NULL;
+
+  if ( NULL == filename )
+    filename = xasprintf ("%s%s", dir, OUTPUT_FILE_NAME);
+
+
+  return filename;
+}
index bf44dced6464fbc0c73246b71a6ad9734047db39..8ea25a1d9e8e5f9f93f39619ad39f37409bdce84 100644 (file)
 #include <stdlib.h>
 
 #include <language/syntax-string-source.h>
-#include <ui/gui/data-editor.h>
+#include <ui/gui/psppire-data-window.h>
 #include <ui/gui/dialog-common.h>
 #include <ui/gui/dict-display.h>
 #include <ui/gui/helper.h>
 #include <ui/gui/psppire-dialog.h>
 #include <ui/gui/psppire-var-store.h>
-#include <ui/gui/syntax-editor.h>
+#include <ui/gui/helper.h>
 
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
@@ -220,7 +220,7 @@ void
 rank_dialog (GObject *o, gpointer data)
 {
   gint response;
-  struct data_editor *de = data;
+  PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
 
   struct rank_dialog rd;
 
@@ -304,7 +304,7 @@ rank_dialog (GObject *o, gpointer data)
                    G_CALLBACK (on_ntiles_toggle),
                    rd.ntiles_entry);
 
-  gtk_window_set_transient_for (GTK_WINDOW (rd.dialog), de->parent.window);
+  gtk_window_set_transient_for (GTK_WINDOW (rd.dialog), GTK_WINDOW (de));
 
   attach_dictionary_to_treeview (GTK_TREE_VIEW (vars),
                                 vs->dict,
@@ -349,6 +349,7 @@ rank_dialog (GObject *o, gpointer data)
     case GTK_RESPONSE_OK:
       {
        gchar *syntax = generate_syntax (&rd);
+
        struct getl_interface *sss = create_syntax_string_source (syntax);
        execute_syntax (sss);
 
@@ -358,12 +359,7 @@ rank_dialog (GObject *o, gpointer data)
     case PSPPIRE_RESPONSE_PASTE:
       {
        gchar *syntax = generate_syntax (&rd);
-
-       struct syntax_editor *se =
-         (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL);
-
-       gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1);
-
+       paste_syntax_in_new_window (syntax);
        g_free (syntax);
       }
       break;
index 9d1ad79d6efcc4e29ef87e27bcc24b2d1be0d225..859737f63e7d4d7895c1347f2a585c60d28cb5ab 100644 (file)
 #include <gtk/gtk.h>
 
 #include <language/syntax-string-source.h>
-#include <ui/gui/data-editor.h>
+#include <ui/gui/psppire-data-window.h>
 #include <ui/gui/dialog-common.h>
 #include <ui/gui/dict-display.h>
 #include <ui/gui/helper.h>
 #include <ui/gui/psppire-dialog.h>
 #include <ui/gui/psppire-var-store.h>
-#include <ui/gui/syntax-editor.h>
+#include <ui/gui/helper.h>
 #include <ui/syntax-gen.h>
 
 #include "psppire-acr.h"
@@ -470,14 +470,14 @@ toggle_sensitivity (GtkToggleButton *button, GtkWidget *target)
   gtk_widget_set_sensitive (target, state);
 }
 
-static void recode_dialog (struct data_editor *de, gboolean diff);
+static void recode_dialog (PsppireDataWindow *de, gboolean diff);
 
 
 /* Pops up the Recode Same version of the dialog box */
 void
 recode_same_dialog (GObject *o, gpointer data)
 {
-  struct data_editor *de = data;
+  PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
 
   recode_dialog (de, FALSE);
 }
@@ -486,7 +486,7 @@ recode_same_dialog (GObject *o, gpointer data)
 void
 recode_different_dialog (GObject *o, gpointer data)
 {
-  struct data_editor *de = data;
+  PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
 
   recode_dialog (de, TRUE);
 }
@@ -836,7 +836,7 @@ set_acr (struct recode_dialog *rd)
 }
 
 static void
-recode_dialog (struct data_editor *de, gboolean diff)
+recode_dialog (PsppireDataWindow *de, gboolean diff)
 {
   gint response;
 
@@ -882,7 +882,7 @@ recode_dialog (struct data_editor *de, gboolean diff)
 
   rd.different = diff;
 
-  gtk_window_set_transient_for (GTK_WINDOW (rd.dialog), de->parent.window);
+  gtk_window_set_transient_for (GTK_WINDOW (rd.dialog), GTK_WINDOW (de));
 
 
   attach_dictionary_to_treeview (GTK_TREE_VIEW (rd.dict_treeview),
@@ -993,7 +993,7 @@ recode_dialog (struct data_editor *de, gboolean diff)
       PSPPIRE_DIALOG (get_widget_assert (builder, "old-new-values-dialog"));
 
     gtk_window_set_transient_for (GTK_WINDOW (rd.old_and_new_dialog),
-                                 de->parent.window);
+                                 GTK_WINDOW (de));
 
     rd.acr = PSPPIRE_ACR (get_widget_assert (builder, "psppire-acr1"));
 
@@ -1084,6 +1084,7 @@ recode_dialog (struct data_editor *de, gboolean diff)
     case GTK_RESPONSE_OK:
       {
        gchar *syntax = generate_syntax (&rd);
+
        struct getl_interface *sss = create_syntax_string_source (syntax);
        execute_syntax (sss);
 
@@ -1093,11 +1094,7 @@ recode_dialog (struct data_editor *de, gboolean diff)
     case PSPPIRE_RESPONSE_PASTE:
       {
        gchar *syntax = generate_syntax (&rd);
-
-       struct syntax_editor *se =
-         (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL);
-
-       gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1);
+        paste_syntax_in_new_window (syntax);
 
        g_free (syntax);
       }
index 3e0e0fbc1d226d5815a57b6ea1d6845757661020..2d8aca3ebc6a5d074e3a329211d25c530df83f2e 100644 (file)
 #include <stdlib.h>
 
 #include <language/syntax-string-source.h>
-#include <ui/gui/data-editor.h>
+#include <ui/gui/psppire-data-window.h>
 #include <ui/gui/dialog-common.h>
 #include <ui/gui/dict-display.h>
 #include <ui/gui/helper.h>
 #include <ui/gui/psppire-dialog.h>
 #include <ui/gui/psppire-var-store.h>
-#include <ui/gui/syntax-editor.h>
+#include <ui/gui/helper.h>
 
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
@@ -223,11 +223,10 @@ void
 regression_dialog (GObject *o, gpointer data)
 {
   gint response;
-  struct data_editor *de = data;
-
   struct regression_dialog rd;
 
   GtkBuilder *xml = builder_new ("regression.ui");
+  PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
   PsppireVarStore *vs;
 
   GtkWidget *dialog = get_widget_assert   (xml, "regression-dialog");
@@ -251,7 +250,7 @@ regression_dialog (GObject *o, gpointer data)
                                  stats
                                  );
 
-  gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window);
+  gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de));
 
   attach_dictionary_to_treeview (GTK_TREE_VIEW (source),
                                 vs->dict,
@@ -286,8 +285,8 @@ regression_dialog (GObject *o, gpointer data)
   rd.current_opts.pred = FALSE;
   rd.current_opts.resid = FALSE;
 
-  gtk_window_set_transient_for (GTK_WINDOW (rd.save_dialog), de->parent.window);
-  gtk_window_set_transient_for (GTK_WINDOW (rd.stat_dialog), de->parent.window);
+  gtk_window_set_transient_for (GTK_WINDOW (rd.save_dialog), GTK_WINDOW (de));
+  gtk_window_set_transient_for (GTK_WINDOW (rd.stat_dialog), GTK_WINDOW (de));
 
   g_signal_connect (dialog, "refresh", G_CALLBACK (refresh),  &rd);
 
@@ -307,6 +306,7 @@ regression_dialog (GObject *o, gpointer data)
     case GTK_RESPONSE_OK:
       {
        gchar *syntax = generate_syntax (&rd);
+
        struct getl_interface *sss = create_syntax_string_source (syntax);
        execute_syntax (sss);
 
@@ -316,11 +316,7 @@ regression_dialog (GObject *o, gpointer data)
     case PSPPIRE_RESPONSE_PASTE:
       {
        gchar *syntax = generate_syntax (&rd);
-
-       struct syntax_editor *se =
-         (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL);
-
-       gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1);
+        paste_syntax_in_new_window (syntax);
 
        g_free (syntax);
       }
index 143f7a6d7f122f31144361e7e5513dd571c87a24..d953308a09fbe8b27c92c84ff54c045e8eac4e27 100644 (file)
 #include <gtk/gtk.h>
 #include "helper.h"
 #include "psppire-dialog.h"
-#include "data-editor.h"
+#include "psppire-data-window.h"
 #include "dialog-common.h"
 #include "dict-display.h"
 #include "widget-io.h"
 #include <language/syntax-string-source.h>
-#include "syntax-editor.h"
+#include "helper.h"
 
 
 #include <gettext.h>
@@ -240,7 +240,7 @@ select_cases_dialog (GObject *o, gpointer data)
   gint response;
   struct select_cases_dialog scd = {0,0,0,0,0,0};
   GtkWidget *dialog   ;
-  struct data_editor *de = data;
+  PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
   GtkWidget *entry = NULL;
   GtkWidget *selector ;
   GtkWidget *button_range;
@@ -319,7 +319,7 @@ select_cases_dialog (GObject *o, gpointer data)
 
 
   dialog = get_widget_assert (scd.xml, "select-cases-dialog");
-  gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window);
+  gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de));
 
   {
     GtkWidget *source = get_widget_assert   (scd.xml, "select-cases-treeview");
@@ -353,6 +353,7 @@ select_cases_dialog (GObject *o, gpointer data)
     case GTK_RESPONSE_OK:
       {
        gchar *syntax = generate_syntax (&scd);
+
        struct getl_interface *sss = create_syntax_string_source (syntax);
        execute_syntax (sss);
 
@@ -362,11 +363,7 @@ select_cases_dialog (GObject *o, gpointer data)
     case PSPPIRE_RESPONSE_PASTE:
       {
        gchar *syntax = generate_syntax (&scd);
-
-       struct syntax_editor *se =
-         (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL);
-
-       gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1);
+        paste_syntax_in_new_window (syntax);
 
        g_free (syntax);
       }
index dea226c76098886e43efed67e385d98d36475377..d9c665e69a8db988df983919d7ea6d651cc9c9ea 100644 (file)
 #include "sort-cases-dialog.h"
 #include "helper.h"
 #include "psppire-dialog.h"
-#include "data-editor.h"
+#include "psppire-data-window.h"
 #include "psppire-var-store.h"
 #include "dialog-common.h"
 #include "dict-display.h"
 
 #include <language/syntax-string-source.h>
-#include "syntax-editor.h"
+#include "helper.h"
 
 static void
 refresh (PsppireDialog *dialog, GtkTreeView *dest)
@@ -91,7 +91,7 @@ void
 sort_cases_dialog (GObject *o, gpointer data)
 {
   gint response;
-  struct data_editor *de = data;
+  PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
 
   struct sort_cases_dialog scd;
 
@@ -108,7 +108,7 @@ sort_cases_dialog (GObject *o, gpointer data)
 
   g_object_get (de->data_editor, "var-store", &vs, NULL);
 
-  gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window);
+  gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de));
 
   attach_dictionary_to_treeview (GTK_TREE_VIEW (source),
                                 vs->dict,
@@ -143,6 +143,7 @@ sort_cases_dialog (GObject *o, gpointer data)
     case GTK_RESPONSE_OK:
       {
        gchar *syntax = generate_syntax (&scd);
+
        struct getl_interface *sss = create_syntax_string_source (syntax);
        execute_syntax (sss);
 
@@ -152,11 +153,7 @@ sort_cases_dialog (GObject *o, gpointer data)
     case PSPPIRE_RESPONSE_PASTE:
       {
        gchar *syntax = generate_syntax (&scd);
-
-       struct syntax_editor *se =
-         (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL);
-
-       gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1);
+        paste_syntax_in_new_window (syntax);
 
        g_free (syntax);
       }
index 00f30c627080d53f96848d96c1c7ba4aca128ea7..8708b33f05df2d5613cc0b514d4cf0150e055156 100644 (file)
 #include "psppire-selector.h"
 #include "psppire-dialog.h"
 #include "helper.h"
-#include "data-editor.h"
+#include "psppire-data-window.h"
 #include "dict-display.h"
 #include <language/syntax-string-source.h>
-#include "syntax-editor.h"
+#include "helper.h"
 #include <data/dictionary.h>
 
 #include <gtk/gtk.h>
@@ -166,7 +166,7 @@ void
 split_file_dialog (GObject *o, gpointer data)
 {
   gint response;
-  struct data_editor *de = data;
+  PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
   struct split_file_dialog sfd;
   PsppireVarStore *vs ;
 
@@ -210,7 +210,7 @@ split_file_dialog (GObject *o, gpointer data)
 
   g_signal_connect (dialog, "refresh", G_CALLBACK (refresh),  &sfd);
 
-  gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window);
+  gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de));
 
   response = psppire_dialog_run (PSPPIRE_DIALOG (dialog));
 
@@ -220,6 +220,7 @@ split_file_dialog (GObject *o, gpointer data)
     case GTK_RESPONSE_OK:
       {
        gchar *syntax = generate_syntax (&sfd);
+
        struct getl_interface *sss = create_syntax_string_source (syntax);
        execute_syntax (sss);
 
@@ -229,11 +230,7 @@ split_file_dialog (GObject *o, gpointer data)
     case PSPPIRE_RESPONSE_PASTE:
       {
        gchar *syntax = generate_syntax (&sfd);
-
-       struct syntax_editor *se =
-         (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL);
-
-       gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1);
+        paste_syntax_in_new_window (syntax);
 
        g_free (syntax);
       }
index f7617a893155faf03b786680c6e0c14114603b04..214370513b7369087344f60c636f450704f3b7a7 100644 (file)
 #include <gtk/gtk.h>
 
 #include "syntax-editor-source.h"
-#include "syntax-editor.h"
+#include "psppire-syntax-window.h"
 
 #include "xalloc.h"
 
 struct syntax_editor_source
   {
     struct getl_interface parent;
-    const struct syntax_editor *se;
+    GtkTextBuffer *buffer;
     GtkTextIter i;
     GtkTextIter end;
+    const gchar *name;
   };
 
 
@@ -49,10 +50,8 @@ always_false (const struct getl_interface *i UNUSED)
 static const char *
 name (const struct getl_interface *i)
 {
-  const struct syntax_editor_source *ses =
-    (const struct syntax_editor_source *) i;
-
-  return window_name ((const struct editor_window *) ses->se);
+  const struct syntax_editor_source *ses = (const struct syntax_editor_source *) i;
+  return ses->name;
 }
 
 
@@ -81,7 +80,7 @@ read_line_from_buffer (struct getl_interface *i,
   next_line = ses->i;
   gtk_text_iter_forward_line (&next_line);
 
-  text = gtk_text_buffer_get_text (ses->se->buffer,
+  text = gtk_text_buffer_get_text (ses->buffer,
                                   &ses->i, &next_line,
                                   FALSE);
   g_strchomp (text);
@@ -103,16 +102,18 @@ do_close (struct getl_interface *i )
 }
 
 struct getl_interface *
-create_syntax_editor_source (const struct syntax_editor *se,
+create_syntax_editor_source (GtkTextBuffer *buffer,
                             GtkTextIter start,
-                            GtkTextIter stop
+                            GtkTextIter stop,
+                            const gchar *nm
                             )
 {
   struct syntax_editor_source *ses = xzalloc (sizeof *ses);
 
-  ses->se = se;
+  ses->buffer = buffer;
   ses->i = start;
   ses->end = stop;
+  ses->name = nm;
 
 
   ses->parent.interactive = always_false;
index ca198393fbed07e338c2f1686a4274354e16bf61..f8d08eaaadbcde3a28f6ff61cfae0e9f051abf2c 100644 (file)
@@ -23,9 +23,10 @@ struct getl_interface;
 struct syntax_editor;
 
 struct getl_interface *
-create_syntax_editor_source (const struct syntax_editor *se,
+create_syntax_editor_source (GtkTextBuffer *buffer,
                             GtkTextIter start,
-                            GtkTextIter stop
+                            GtkTextIter stop,
+                            const gchar *name
                             );
 
 
diff --git a/src/ui/gui/syntax-editor.c b/src/ui/gui/syntax-editor.c
deleted file mode 100644 (file)
index 35749fc..0000000
+++ /dev/null
@@ -1,556 +0,0 @@
-/* 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 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.
-
-   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 <gettext.h>
-#define _(msgid) gettext (msgid)
-#define N_(msgid) msgid
-
-#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"
-
-#include "window-manager.h"
-
-#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 (e->window),
-                               GTK_DIALOG_MODAL,
-                               GTK_MESSAGE_QUESTION,
-                               GTK_BUTTONS_NONE,
-                               _("Save contents of syntax editor to %s?"),
-                               e->name
-                               );
-
-      gtk_dialog_add_button  (GTK_DIALOG (dialog),
-                             GTK_STOCK_YES,
-                             GTK_RESPONSE_ACCEPT);
-      gtk_dialog_add_button  (GTK_DIALOG (dialog),
-                             GTK_STOCK_NO,
-                             GTK_RESPONSE_REJECT);
-      gtk_dialog_add_button  (GTK_DIALOG (dialog),
-                             GTK_STOCK_CANCEL,
-                             GTK_RESPONSE_CANCEL);
-
-
-      response = gtk_dialog_run (GTK_DIALOG (dialog));
-
-      gtk_widget_destroy (dialog);
-
-      if ( response == GTK_RESPONSE_ACCEPT )
-       {
-         GError *err = NULL;
-
-         if ( ! save_editor_to_file (se, e->name, &err) )
-           {
-             msg (ME, err->message);
-             g_error_free (err);
-           }
-       }
-
-      if ( response == GTK_RESPONSE_CANCEL )
-       return ;
-    }
-
-  gtk_widget_destroy (GTK_WIDGET (e->window));
-}
-
-/* Callback for the File->SaveAs menuitem */
-static void
-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 (e->window),
-                                GTK_FILE_CHOOSER_ACTION_SAVE,
-                                GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-                                GTK_STOCK_SAVE,   GTK_RESPONSE_ACCEPT,
-                                NULL);
-
-  filter = gtk_file_filter_new ();
-  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);
-
-  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),
-                                                 TRUE);
-  response = gtk_dialog_run (GTK_DIALOG (dialog));
-
-  if ( response == GTK_RESPONSE_ACCEPT )
-    {
-      GError *err = NULL;
-      char *filename =
-       gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog) );
-
-      if ( save_editor_to_file (se, filename, &err) )
-       {
-         g_free (e->name);
-         e->name = g_strdup (filename);
-       }
-      else
-       {
-         msg ( ME, err->message );
-         g_error_free (err);
-       }
-
-      free (filename);
-    }
-
-  gtk_widget_destroy ( dialog );
-}
-
-/* Callback for the File->Save menuitem */
-static void
-on_syntax_save (GtkMenuItem *menuitem, gpointer user_data)
-{
-  struct syntax_editor *se = user_data;
-  struct editor_window *e = user_data;
-
-  if ( e->name == NULL )
-    on_syntax_save_as (menuitem, user_data);
-  else
-    {
-      GError *err = NULL;
-      save_editor_to_file (se, e->name, &err);
-      if ( err )
-       {
-         msg (ME, err->message);
-         g_error_free (err);
-       }
-    }
-}
-
-
-/* Callback for the "delete" action (clicking the x on the top right
-   hand corner of the window) */
-static gboolean
-on_delete (GtkWidget *w, GdkEvent *event, gpointer user_data)
-{
-  struct syntax_editor *se = user_data;
-  save_if_modified (se);
-  return TRUE;
-}
-
-
-/* Callback for the File->Quit menuitem */
-static gboolean
-on_quit (GtkMenuItem *menuitem, gpointer    user_data)
-{
-  struct syntax_editor *se = user_data;
-  save_if_modified (se);
-  return FALSE;
-}
-
-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);
-}
-
-
-
-
-/*
-  Create a new syntax editor with NAME.
-  If NAME is NULL, a name will be automatically assigned
-*/
-struct syntax_editor *
-new_syntax_editor (void)
-{
-  GladeXML *xml = XML_NEW ("syntax-editor.glade");
-
-  GtkWidget *text_view;
-  struct syntax_editor *se ;
-  struct editor_window *e;
-
-  connect_help (xml);
-
-  se = g_malloc (sizeof (*se));
-
-  e = (struct editor_window *)se;
-
-  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 (open_syntax_window),
-                   e->window);
-
-  g_signal_connect (get_widget_assert (xml,"file_new_data"),
-                   "activate",
-                   G_CALLBACK (new_data_window),
-                   e->window);
-
-  g_signal_connect (get_widget_assert (xml,"help_about"),
-                   "activate",
-                   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 (xml,"run_current_line"),
-                   "activate",
-                   G_CALLBACK (on_run_current_line),
-                   se);
-
-
-  g_signal_connect (get_widget_assert (xml,"run_to_end"),
-                   "activate",
-                   G_CALLBACK (on_run_to_end),
-                   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
-*/
-void
-new_syntax_window (GtkMenuItem     *menuitem,
-                  gpointer         user_data)
-{
-  window_create (WINDOW_SYNTAX, NULL);
-}
-
-
-/*
-  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,
-                    GError **err)
-{
-  GtkTextBuffer *buffer = se->buffer;
-  gboolean result ;
-  GtkTextIter start, stop;
-  gchar *text;
-
-  gchar *suffixedname;
-  gchar *glibfilename;
-  g_assert (filename);
-
-  suffixedname = append_suffix (filename);
-
-  glibfilename = g_filename_from_utf8 (suffixedname, -1, 0, 0, err);
-
-  g_free ( suffixedname);
-
-  if ( ! glibfilename )
-    return FALSE;
-
-  gtk_text_buffer_get_iter_at_line (buffer, &start, 0);
-  gtk_text_buffer_get_iter_at_offset (buffer, &stop, -1);
-
-  text = gtk_text_buffer_get_text (buffer, &start, &stop, FALSE);
-
-  result =  g_file_set_contents (glibfilename, text, -1, err);
-
-  if ( result )
-    {
-      window_set_name_from_filename ((struct editor_window *) se, filename);
-      gtk_text_buffer_set_modified (buffer, FALSE);
-    }
-
-  return result;
-}
-
-
-/*
-  Loads the buffer from the file called FILENAME
-*/
-gboolean
-load_editor_from_file (struct syntax_editor *se,
-                      const gchar *filename,
-                      GError **err)
-{
-  GtkTextBuffer *buffer = se->buffer;
-  gchar *text;
-  GtkTextIter iter;
-
-  gchar *glibfilename = g_filename_from_utf8 (filename, -1, 0, 0, err);
-
-  if ( ! glibfilename )
-    return FALSE;
-
-  /* FIXME: What if it's a very big file ? */
-  if ( ! g_file_get_contents (glibfilename, &text, NULL, err) )
-    {
-      g_free (glibfilename);
-      return FALSE;
-    }
-  g_free (glibfilename);
-
-  gtk_text_buffer_get_iter_at_line (buffer, &iter, 0);
-
-  gtk_text_buffer_insert (buffer, &iter, text, -1);
-
-
-  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 */
-void
-open_syntax_window (GtkMenuItem *menuitem, gpointer parent)
-{
-  GtkFileFilter *filter;
-  gint response;
-
-  GtkWidget *dialog =
-    gtk_file_chooser_dialog_new (_("Open Syntax"),
-                                GTK_WINDOW (parent),
-                                GTK_FILE_CHOOSER_ACTION_OPEN,
-                                GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-                                GTK_STOCK_OPEN,   GTK_RESPONSE_ACCEPT,
-                                NULL);
-
-  filter = gtk_file_filter_new ();
-  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);
-
-  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);
-
-  response = gtk_dialog_run (GTK_DIALOG (dialog));
-
-  if (response == GTK_RESPONSE_ACCEPT)
-    {
-      const char *file_name = gtk_file_chooser_get_filename
-       (GTK_FILE_CHOOSER (dialog));
-
-      struct syntax_editor *se = (struct syntax_editor *)
-       window_create (WINDOW_SYNTAX, file_name);
-
-      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
-
-    }
-
-  gtk_widget_destroy (dialog);
-}
-
diff --git a/src/ui/gui/syntax-editor.h b/src/ui/gui/syntax-editor.h
deleted file mode 100644 (file)
index b3943ec..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2006  Free Software Foundation
-
-   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.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
-
-
-#ifndef SYNTAX_EDITOR_H
-#define SYNTAX_EDITOR_H
-
-#include <gtk/gtk.h>
-
-#include "window-manager.h"
-
-struct lexer;
-
-struct syntax_editor
-{
-  struct editor_window parent;
-  GtkTextBuffer *buffer;  /* The buffer which contains the text */
-  struct lexer *lexer;    /* Lexer to parse syntax */
-};
-
-
-struct syntax_editor * new_syntax_editor (void);
-
-void new_syntax_window (GtkMenuItem *, gpointer);
-
-void open_syntax_window (GtkMenuItem *, gpointer);
-
-gboolean load_editor_from_file (struct syntax_editor *se,
-                               const gchar *filename,
-                               GError **err);
-#endif
index 22b4526c4d7027a2dccb8a235992d33fa1378427..392867adbb606acd5c62abad6ce6a58286807f13 100644 (file)
@@ -22,7 +22,7 @@
 #include "psppire-dict.h"
 #include "psppire-var-store.h"
 #include "helper.h"
-#include "data-editor.h"
+#include "psppire-data-window.h"
 #include "psppire-dialog.h"
 #include "dialog-common.h"
 #include "dict-display.h"
@@ -31,7 +31,7 @@
 #include <ui/syntax-gen.h>
 
 #include <language/syntax-string-source.h>
-#include "syntax-editor.h"
+#include "helper.h"
 
 #include <gl/xalloc.h>
 
@@ -391,7 +391,7 @@ t_test_independent_samples_dialog (GObject *o, gpointer data)
 {
   struct tt_indep_samples_dialog tt_d;
   gint response;
-  struct data_editor *de = data;
+  PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
 
   PsppireVarStore *vs = NULL;
 
@@ -420,11 +420,11 @@ t_test_independent_samples_dialog (GObject *o, gpointer data)
 
   tt_d.define_groups_button = get_widget_assert (xml, "define-groups-button");
   tt_d.groups_entry = get_widget_assert (xml, "indep-samples-t-test-entry");
-  tt_d.opts = tt_options_dialog_create (xml, de->parent.window);
-  tt_d.grps = tt_groups_dialog_create (xml, de->parent.window);
+  tt_d.opts = tt_options_dialog_create (xml, GTK_WINDOW (de));
+  tt_d.grps = tt_groups_dialog_create (xml, GTK_WINDOW (de));
 
 
-  gtk_window_set_transient_for (GTK_WINDOW (tt_d.dialog), de->parent.window);
+  gtk_window_set_transient_for (GTK_WINDOW (tt_d.dialog), GTK_WINDOW (de));
 
   attach_dictionary_to_treeview (GTK_TREE_VIEW (dict_view),
                                 vs->dict,
@@ -474,6 +474,7 @@ t_test_independent_samples_dialog (GObject *o, gpointer data)
     case GTK_RESPONSE_OK:
       {
        gchar *syntax = generate_syntax (&tt_d);
+
        struct getl_interface *sss = create_syntax_string_source (syntax);
        execute_syntax (sss);
 
@@ -483,12 +484,7 @@ t_test_independent_samples_dialog (GObject *o, gpointer data)
     case PSPPIRE_RESPONSE_PASTE:
       {
        gchar *syntax = generate_syntax (&tt_d);
-
-       struct syntax_editor *se =
-         (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL);
-
-       gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1);
-
+        paste_syntax_in_new_window (syntax);
        g_free (syntax);
       }
       break;
index 98d9601bc4c7c6a2cacc184ac5eea47c7755a791..3cdc91c32721f4780684f2966c5b896ecaae6ef3 100644 (file)
@@ -22,7 +22,7 @@
 #include "psppire-dict.h"
 #include "psppire-var-store.h"
 #include "helper.h"
-#include "data-editor.h"
+#include "psppire-data-window.h"
 #include "psppire-dialog.h"
 #include "dialog-common.h"
 #include "dict-display.h"
@@ -30,7 +30,6 @@
 
 #include "t-test-options.h"
 #include <language/syntax-string-source.h>
-#include "syntax-editor.h"
 
 #include <gettext.h>
 #define _(msgid) gettext (msgid)
@@ -123,7 +122,7 @@ t_test_one_sample_dialog (GObject *o, gpointer data)
 {
   struct tt_one_sample_dialog tt_d;
   gint response;
-  struct data_editor *de = data;
+  PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
 
   PsppireVarStore *vs = NULL;
 
@@ -144,9 +143,9 @@ t_test_one_sample_dialog (GObject *o, gpointer data)
   tt_d.dict = vs->dict;
   tt_d.vars_treeview = get_widget_assert (xml, "one-sample-t-test-treeview1");
   tt_d.test_value_entry = get_widget_assert (xml, "test-value-entry");
-  tt_d.opt = tt_options_dialog_create (xml, de->parent.window);
+  tt_d.opt = tt_options_dialog_create (xml, GTK_WINDOW (de));
 
-  gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window);
+  gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de));
 
   attach_dictionary_to_treeview (GTK_TREE_VIEW (dict_view),
                                 vs->dict,
@@ -180,6 +179,7 @@ t_test_one_sample_dialog (GObject *o, gpointer data)
     case GTK_RESPONSE_OK:
       {
        gchar *syntax = generate_syntax (&tt_d);
+
        struct getl_interface *sss = create_syntax_string_source (syntax);
        execute_syntax (sss);
 
@@ -190,10 +190,7 @@ t_test_one_sample_dialog (GObject *o, gpointer data)
       {
        gchar *syntax = generate_syntax (&tt_d);
 
-       struct syntax_editor *se =
-         (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL);
-
-       gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1);
+        paste_syntax_in_new_window (syntax);
 
        g_free (syntax);
       }
index ec7096035bb68b7f61f25a62e0006d7255bed331..ca1d776a7294f6bed0b91060e4be8f7878ef4b2c 100644 (file)
@@ -19,7 +19,7 @@
 #include <gtk/gtk.h>
 #include <language/syntax-string-source.h>
 
-#include "data-editor.h"
+#include "psppire-data-window.h"
 
 #include "psppire-dict.h"
 #include "psppire-var-store.h"
@@ -30,8 +30,6 @@
 #include "dialog-common.h"
 #include "psppire-dialog.h"
 
-#include "syntax-editor.h"
-
 #include "helper.h"
 
 #include "psppire-var-ptr.h"
@@ -182,7 +180,7 @@ t_test_paired_samples_dialog (GObject *o, gpointer data)
 {
   struct tt_paired_samples_dialog tt_d;
   gint response;
-  struct data_editor *de = data;
+  PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
 
   PsppireVarStore *vs = NULL;
 
@@ -202,9 +200,9 @@ t_test_paired_samples_dialog (GObject *o, gpointer data)
   tt_d.dict = vs->dict;
   tt_d.pairs_treeview =
    get_widget_assert (xml, "paired-samples-t-test-treeview2");
-  tt_d.opt = tt_options_dialog_create (xml, de->parent.window);
+  tt_d.opt = tt_options_dialog_create (xml, GTK_WINDOW (de));
 
-  gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window);
+  gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de));
 
 
   attach_dictionary_to_treeview (GTK_TREE_VIEW (dict_view),
@@ -254,6 +252,7 @@ t_test_paired_samples_dialog (GObject *o, gpointer data)
     case GTK_RESPONSE_OK:
       {
        gchar *syntax = generate_syntax (&tt_d);
+
        struct getl_interface *sss = create_syntax_string_source (syntax);
        execute_syntax (sss);
 
@@ -263,11 +262,7 @@ t_test_paired_samples_dialog (GObject *o, gpointer data)
     case PSPPIRE_RESPONSE_PASTE:
       {
        gchar *syntax = generate_syntax (&tt_d);
-
-       struct syntax_editor *se =
-         (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL);
-
-       gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1);
+        paste_syntax_in_new_window (syntax);
 
        g_free (syntax);
       }
index a82a81a121d5654f435e6fdd8f54516ed9fb5137..fa55bba5e95d64e561682245050b6e3cd56ddf1f 100644 (file)
 #include <libpspp/assertion.h>
 #include <libpspp/message.h>
 #include <ui/syntax-gen.h>
-#include <ui/gui/data-editor.h>
+#include <ui/gui/psppire-data-window.h>
 #include <ui/gui/dialog-common.h>
 #include <ui/gui/helper.h>
 #include <ui/gui/psppire-dialog.h>
 #include <ui/gui/psppire-var-sheet.h>
 #include <ui/gui/psppire-var-store.h>
-#include <ui/gui/syntax-editor.h>
+#include <ui/gui/helper.h>
 
 #include "error.h"
 #include "xalloc.h"
@@ -63,7 +63,7 @@ text_data_import_assistant (GObject *o, gpointer de_)
   struct data_editor *de = de_;
 
   GtkWidget *dialog =
-    gtk_message_dialog_new  (de->parent.window,
+    gtk_message_dialog_new  (GTK_WINDOW (de),
                             GTK_DIALOG_MODAL,
                             GTK_MESSAGE_WARNING,
                             GTK_BUTTONS_CLOSE,
@@ -259,7 +259,7 @@ void
 text_data_import_assistant (GObject *o, gpointer de_)
 {
   struct data_editor *de = de_;
-  GtkWindow *parent_window = de->parent.window;
+  GtkWindow *parent_window = GTK_WINDOW (de);
   struct import_assistant *ia;
 
   ia = xzalloc (sizeof *ia);
@@ -293,9 +293,7 @@ text_data_import_assistant (GObject *o, gpointer de_)
     case PSPPIRE_RESPONSE_PASTE:
       {
        char *syntax = generate_syntax (ia);
-       struct syntax_editor *se =
-         (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL);
-       gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1);
+        paste_syntax_in_new_window (syntax);
        free (syntax);
       }
       break;
@@ -2305,7 +2303,7 @@ pop_watch_cursor (struct import_assistant *ia)
 {
   if (--ia->asst.watch_cursor == 0)
     {
-      GtkWidget *widget = GTK_WIDGET (ia->asst.assistant);;
+      GtkWidget *widget = GTK_WIDGET (ia->asst.assistant);
       gdk_window_set_cursor (widget->window, NULL);
     }
 }
index 272ef1b3934daaa4f07043dc3dc2f5a5d9e04a8d..09756d3738919bc40f2f314b3d4d924a7a287499 100644 (file)
 #include "psppire-selector.h"
 #include "psppire-dialog.h"
 #include "helper.h"
-#include "data-editor.h"
+#include "psppire-data-window.h"
 #include "dict-display.h"
 #include <language/syntax-string-source.h>
-#include "syntax-editor.h"
+#include "helper.h"
 
 #include "dialog-common.h"
 
@@ -79,7 +79,7 @@ void
 transpose_dialog (GObject *o, gpointer data)
 {
   gint response ;
-  struct data_editor *de = data;
+  PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
 
   GtkBuilder *xml = builder_new ("psppire.ui");
 
@@ -116,7 +116,7 @@ transpose_dialog (GObject *o, gpointer data)
 
   g_signal_connect (dialog, "refresh", G_CALLBACK (refresh),  xml);
 
-  gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window);
+  gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de));
 
   psppire_dialog_set_valid_predicate (PSPPIRE_DIALOG (dialog),
                                      dialog_state_valid, xml);
@@ -128,6 +128,7 @@ transpose_dialog (GObject *o, gpointer data)
     case GTK_RESPONSE_OK:
       {
        gchar *syntax = generate_syntax (vs->dict, xml);
+
        struct getl_interface *sss = create_syntax_string_source (syntax);
        execute_syntax (sss);
 
@@ -137,11 +138,7 @@ transpose_dialog (GObject *o, gpointer data)
     case PSPPIRE_RESPONSE_PASTE:
       {
        gchar *syntax = generate_syntax (vs->dict, xml);
-
-       struct syntax_editor *se =
-         (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL);
-
-       gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1);
+        paste_syntax_in_new_window (syntax);
 
        g_free (syntax);
       }
index 22af89f0894f7b5e6f6844c0ff6e9173519067c0..2f5495f137dd5a41f0e889cc847a210f7bf4b3e7 100644 (file)
 #include <data/variable.h>
 #include <data/format.h>
 #include <data/value-labels.h>
-#include "data-editor.h"
+#include "psppire-data-window.h"
 #include "psppire-dialog.h"
 #include "psppire-var-store.h"
 #include "helper.h"
 
 #include <language/syntax-string-source.h>
-#include "syntax-editor.h"
+#include "helper.h"
 
 
 #include <gettext.h>
@@ -163,7 +163,7 @@ static gchar * generate_syntax (GtkTreeView *treeview);
 void
 variable_info_dialog (GObject *o, gpointer data)
 {
-  struct data_editor *de = data;
+  PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
 
   gint response ;
 
@@ -177,7 +177,7 @@ variable_info_dialog (GObject *o, gpointer data)
 
   g_object_get (de->data_editor, "var-store", &vs, NULL);
 
-  gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window);
+  gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de));
 
   attach_dictionary_to_treeview (GTK_TREE_VIEW (treeview),
                                 vs->dict,
@@ -213,11 +213,7 @@ variable_info_dialog (GObject *o, gpointer data)
     case PSPPIRE_RESPONSE_PASTE:
       {
        gchar *syntax = generate_syntax (GTK_TREE_VIEW (treeview));
-
-       struct syntax_editor *se =
-         (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL);
-
-       gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1);
+        paste_syntax_in_new_window (syntax);
 
        g_free (syntax);
       }
index 8b46ca5e8d7c988cfb1f2bd2649c55e92dd28fee..a464646fe7742eeacf0c0ece78467710c0ad5de8 100644 (file)
 #include "psppire-selector.h"
 #include "psppire-dialog.h"
 #include "helper.h"
-#include "data-editor.h"
+#include "psppire-data-window.h"
 #include "dict-display.h"
 #include <language/syntax-string-source.h>
-#include "syntax-editor.h"
+#include "helper.h"
 
 #include <gtk/gtk.h>
 
@@ -103,7 +103,7 @@ void
 weight_cases_dialog (GObject *o, gpointer data)
 {
   gint response;
-  struct data_editor *de = data;
+  PsppireDataWindow *de = PSPPIRE_DATA_WINDOW (data);
   struct weight_cases_dialog wcd;
 
   GtkBuilder *xml = builder_new ("psppire.ui");
@@ -121,7 +121,7 @@ weight_cases_dialog (GObject *o, gpointer data)
 
   g_object_get (de->data_editor, "var-store", &vs,  NULL);
 
-  gtk_window_set_transient_for (GTK_WINDOW (dialog), de->parent.window);
+  gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (de));
 
   g_signal_connect (radiobutton1, "toggled", G_CALLBACK (on_toggle), entry);
   g_signal_connect (selector, "selected", G_CALLBACK (on_select),
@@ -171,12 +171,7 @@ weight_cases_dialog (GObject *o, gpointer data)
     case PSPPIRE_RESPONSE_PASTE:
       {
        gchar *syntax = generate_syntax (&wcd);
-
-       struct syntax_editor *se =
-         (struct syntax_editor *) window_create (WINDOW_SYNTAX, NULL);
-
-       gtk_text_buffer_insert_at_cursor (se->buffer, syntax, -1);
-
+        paste_syntax_in_new_window (syntax);
        g_free (syntax);
       }
       break;
diff --git a/src/ui/gui/window-manager.c b/src/ui/gui/window-manager.c
deleted file mode 100644 (file)
index 91f44a5..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-/* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2006, 2007  Free Software Foundation
-
-   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.
-
-   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 "relocatable.h"
-
-#include <glib.h>
-#include "syntax-editor.h"
-#include "data-editor.h"
-#include "output-viewer.h"
-
-#include <gettext.h>
-#define _(msgid) gettext (msgid)
-#define N_(msgid) msgid
-
-
-#include "window-manager.h"
-
-
-
-/* A list of struct editor_windows */
-static GSList *window_list = NULL;
-
-
-static void
-deregister_window (GtkWindow *w, gpointer data)
-{
-  struct editor_window *e = data;
-
-  window_list = g_slist_remove (window_list, e);
-
-  if ( g_slist_length (window_list) == 0 )
-    gtk_main_quit ();
-};
-
-
-static void
-register_window (struct editor_window *e)
-{
-  window_list = g_slist_prepend (window_list, e);
-}
-
-
-static gint
-next_window_id (void)
-{
-  return g_slist_length (window_list);
-}
-
-void
-minimise_all_windows (void)
-{
-  const GSList *i = NULL;
-
-  for (i = window_list; i != NULL ; i = i->next)
-    {
-      struct editor_window *e = i->data;
-      gtk_window_iconify (e->window);
-    }
-}
-
-static void set_window_name (struct editor_window *e, const gchar *name );
-
-
-struct editor_window *
-window_create (enum window_type type, const gchar *name)
-{
-  struct editor_window *e;
-  switch (type)
-    {
-    case WINDOW_SYNTAX:
-      e = (struct editor_window *) new_syntax_editor ();
-      break;
-    case WINDOW_DATA:
-      e = (struct editor_window *) new_data_editor ();
-      break;
-    case WINDOW_OUTPUT:
-      e = (struct editor_window *) new_output_viewer ();
-      break;
-    default:
-      g_assert_not_reached ();
-    };
-
-  e->type = type;
-  e->name = NULL;
-
-  set_window_name (e, name);
-
-
-  gtk_window_set_icon_from_file (GTK_WINDOW (e->window),
-                                relocate (PKGDATADIR "/psppicon.png"), 0);
-
-  g_signal_connect (e->window, "destroy",
-                   G_CALLBACK (deregister_window), e);
-
-  register_window (e);
-
-  gtk_widget_show (GTK_WIDGET (e->window));
-
-  return e;
-}
-
-void
-default_window_name (struct editor_window *w)
-{
-  set_window_name (w, NULL);
-}
-
-static void
-set_window_name (struct editor_window *e,
-                const gchar *name )
-{
-  gchar *title ;
-  g_free (e->name);
-
-  e->name = NULL;
-
-  if ( name )
-    {
-      e->name =  g_strdup (name);
-      return;
-    }
-
-  switch (e->type )
-    {
-    case WINDOW_SYNTAX:
-      e->name = g_strdup_printf (_("Syntax%d"), next_window_id () );
-      title = g_strdup_printf (_("%s --- PSPP Syntax Editor"), e->name);
-      break;
-    case WINDOW_DATA:
-      e->name = g_strdup_printf (_("Untitled%d"), next_window_id () );
-      title = g_strdup_printf (_("%s --- PSPP Data Editor"), e->name);
-      break;
-    case WINDOW_OUTPUT:
-      e->name = g_strdup_printf (_("Output%d"), next_window_id () );
-      title = g_strdup_printf (_("%s --- PSPP Output"), e->name);
-      break;
-    default:
-      g_assert_not_reached ();
-    }
-
-  gtk_window_set_title (GTK_WINDOW (e->window), title);
-
-  g_free (title);
-}
-
-
-/* Set the name of this window based on FILENAME.
-   FILENAME is in "filename encoding" */
-void
-window_set_name_from_filename (struct editor_window *e,
-                              const gchar *fn)
-{
-  gchar *title;
-  gchar *filename = g_filename_to_utf8 (fn, -1, NULL, NULL, NULL);
-  gchar *basename = g_path_get_basename (filename);
-
-  set_window_name (e, filename);
-
-  switch (e->type)
-    {
-    case WINDOW_SYNTAX:
-      title = g_strdup_printf (_("%s --- PSPP Syntax Editor"), basename);
-      break;
-    case WINDOW_DATA:
-      title = g_strdup_printf (_("%s --- PSPP Data Editor"), basename);
-      break;
-    default:
-      g_assert_not_reached ();
-    }
-  g_free (basename);
-
-  gtk_window_set_title (GTK_WINDOW (e->window), title);
-
-  g_free (title);
-  g_free (filename);
-}
-
-const gchar *
-window_name (const struct editor_window *e)
-{
-  return e->name;
-}
diff --git a/src/ui/gui/window-manager.h b/src/ui/gui/window-manager.h
deleted file mode 100644 (file)
index 2bb2fd7..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/* PSPPIRE - a graphical user interface for PSPP.
-   Copyright (C) 2007  Free Software Foundation
-
-   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.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
-
-
-#ifndef WINDOW_MANAGER_H
-#define WINDOW_MANAGER_H
-
-#include <gtk/gtk.h>
-
-enum window_type
-  {
-    WINDOW_DATA,
-    WINDOW_SYNTAX,
-    WINDOW_OUTPUT
-  };
-
-
-struct editor_window
- {
-  GtkWindow *window;      /* The top level window of the editor */
-  gchar *name;            /* The name of this editor (UTF-8) */
-  enum window_type type;
- } ;
-
-struct editor_window * window_create (enum window_type type,
-                                     const gchar *name);
-
-const gchar * window_name (const struct editor_window *);
-
-/* Set the name of this window based on FILENAME.
-   FILENAME is in "filename encoding" */
-void window_set_name_from_filename (struct editor_window *e,
-                                   const gchar *filename);
-
-void default_window_name (struct editor_window *w);
-
-void minimise_all_windows (void);
-
-
-#endif