Save window contents on closing.
authorJohn Darrington <john@darrington.wattle.id.au>
Mon, 2 Mar 2009 06:51:53 +0000 (15:51 +0900)
committerJohn Darrington <john@darrington.wattle.id.au>
Mon, 2 Mar 2009 06:51:53 +0000 (15:51 +0900)
src/ui/gui/psppire-data-store.c
src/ui/gui/psppire-data-window.c
src/ui/gui/psppire-output-window.c
src/ui/gui/psppire-syntax-window.c
src/ui/gui/psppire-window.c
src/ui/gui/psppire-window.h
src/ui/gui/psppire.c
src/ui/gui/psppire.h

index 1bbd2bb8e517ddb48dd989a9734a88f9c46f1dc5..c8804f48ba0ee5a0a974fe459302e38e8fe4dd9a 100644 (file)
@@ -311,9 +311,9 @@ delete_variable_callback (GObject *obj, gint dict_index,
 static void
 variable_changed_callback (GObject *obj, gint var_num, gpointer data)
 {
+#if AXIS_TRANSITION
   PsppireDataStore *store  = PSPPIRE_DATA_STORE (data);
 
-#if AXIS_TRANSITION
   psppire_sheet_column_columns_changed (PSPPIRE_SHEET_COLUMN (store),
                                  var_num, 1);
 
index 84fc50717aa3b023ceed12768e35149fd4ccd9af..c82631839244e5350aae6a7b859adbcc894e91ff 100644 (file)
@@ -30,6 +30,8 @@
 
 #include <data/procedure.h>
 
+#include "psppire.h"
+#include "psppire-window.h"
 #include "psppire-data-window.h"
 #include "psppire-syntax-window.h"
 
@@ -71,6 +73,9 @@ static void psppire_data_window_class_init    (PsppireDataWindowClass *class);
 static void psppire_data_window_init          (PsppireDataWindow      *data_editor);
 
 
+static void psppire_data_window_iface_init (PsppireWindowIface *iface);
+
+
 GType
 psppire_data_window_get_type (void)
 {
@@ -91,9 +96,21 @@ psppire_data_window_get_type (void)
          (GInstanceInitFunc) psppire_data_window_init,
        };
 
+      static const GInterfaceInfo window_interface_info =
+       {
+         (GInterfaceInitFunc) psppire_data_window_iface_init,
+         NULL,
+         NULL
+       };
+
       psppire_data_window_type =
-       g_type_register_static (PSPPIRE_WINDOW_TYPE, "PsppireDataWindow",
+       g_type_register_static (PSPPIRE_TYPE_WINDOW, "PsppireDataWindow",
                                &psppire_data_window_info, 0);
+
+      
+      g_type_add_interface_static (psppire_data_window_type,
+                                  PSPPIRE_TYPE_WINDOW_MODEL,
+                                  &window_interface_info);
     }
 
   return psppire_data_window_type;
@@ -568,14 +585,14 @@ data_save_as_dialog (PsppireDataWindow *de)
 /* Callback for data_save action.
  */
 static void
-data_save (PsppireDataWindow *de)
+data_save (PsppireWindow *de)
 {
-  const gchar *fn = psppire_window_get_filename (PSPPIRE_WINDOW (de));
+  const gchar *fn = psppire_window_get_filename (de);
 
   if ( NULL != fn)
-    save_file (de);
+    save_file (PSPPIRE_DATA_WINDOW (de));
   else
-    data_save_as_dialog (de);
+    data_save_as_dialog (PSPPIRE_DATA_WINDOW (de));
 }
 
 
@@ -723,7 +740,8 @@ file_quit (GtkCheckMenuItem *menuitem, gpointer data)
      Give the user the opportunity to save any unsaved data.
   */
   g_object_unref (the_data_store);
-  gtk_main_quit ();
+
+  psppire_quit ();
 }
 
 
@@ -866,7 +884,7 @@ create_var_sheet_variable_popup_menu (PsppireDataWindow *de)
 }
 
 
-#if RECENT_LISTS_AVAILABLE
+#if RECENT_LISTS_AVAILABLE && 0
 
 static void
 on_recent_data_select (GtkMenuShell *menushell,   gpointer user_data)
@@ -997,22 +1015,6 @@ set_unsaved (gpointer w)
   psppire_window_set_unsaved (PSPPIRE_WINDOW (w), TRUE);
 }
 
-/* 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)
-{
-  PsppireDataWindow *dw = PSPPIRE_DATA_WINDOW (user_data);
-
-  if (psppire_window_query_save (PSPPIRE_WINDOW (dw)))
-    {
-      data_save (dw);
-    }
-
-  return FALSE;
-}
-
-
 static void
 psppire_data_window_init (PsppireDataWindow *de)
 {
@@ -1756,9 +1758,6 @@ psppire_data_window_init (PsppireDataWindow *de)
                "varsheet-row-menu", de->var_sheet_variable_popup_menu,
                NULL);
 
-  g_signal_connect (de, "delete-event", G_CALLBACK (on_delete), de);
-
-
   gtk_widget_show (GTK_WIDGET (de->data_editor));
   gtk_widget_show (box);
 }
@@ -1772,3 +1771,13 @@ psppire_data_window_new (void)
                                   NULL));
 }
 
+
+
+
+\f
+
+static void
+psppire_data_window_iface_init (PsppireWindowIface *iface)
+{
+  iface->save = data_save;
+}
index 986742d0f65e40b0a84e6d67a361e92a8ac8a67e..9c1e73a55a9c6115e3251d458a49cc96b3717e84 100644 (file)
@@ -67,7 +67,7 @@ psppire_output_window_get_type (void)
       };
 
       psppire_output_window_type =
-       g_type_register_static (PSPPIRE_WINDOW_TYPE, "PsppireOutputWindow",
+       g_type_register_static (PSPPIRE_TYPE_WINDOW, "PsppireOutputWindow",
                                &psppire_output_window_info, 0);
     }
 
@@ -247,10 +247,12 @@ psppire_output_window_init (PsppireOutputWindow *window)
                    G_CALLBACK (psppire_window_minimise_all),
                    NULL);
 
-  GtkUIManager *uim = GTK_UI_MANAGER (get_object_assert (xml, "uimanager1"));
+  {
+    GtkUIManager *uim = GTK_UI_MANAGER (get_object_assert (xml, "uimanager1"));
 
-  PSPPIRE_WINDOW (window)->menu =
-    GTK_MENU_SHELL (gtk_ui_manager_get_widget (uim,"/ui/menubar1/windows_menuitem/windows_minimise-all")->parent);
+    PSPPIRE_WINDOW (window)->menu =
+      GTK_MENU_SHELL (gtk_ui_manager_get_widget (uim,"/ui/menubar1/windows_menuitem/windows_minimise-all")->parent);
+  }
 
   g_object_unref (xml);
 
index 07e73c13c838e27e7abac30c49ea312e319a7464..2a09c71c027b8a68380866e0011f84f31decbb57 100644 (file)
@@ -23,6 +23,7 @@
 #include <libpspp/message.h>
 #include <stdlib.h>
 
+#include "psppire.h"
 #include "psppire-syntax-window.h"
 
 #include "psppire-data-window.h"
@@ -41,6 +42,10 @@ 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);
 
+
+static void psppire_syntax_window_iface_init (PsppireWindowIface *iface);
+
+
 GType
 psppire_syntax_window_get_type (void)
 {
@@ -61,9 +66,20 @@ psppire_syntax_window_get_type (void)
        (GInstanceInitFunc) psppire_syntax_window_init,
       };
 
+      static const GInterfaceInfo window_interface_info =
+       {
+         (GInterfaceInitFunc) psppire_syntax_window_iface_init,
+         NULL,
+         NULL
+       };
+
       psppire_syntax_window_type =
-       g_type_register_static (PSPPIRE_WINDOW_TYPE, "PsppireSyntaxWindow",
+       g_type_register_static (PSPPIRE_TYPE_WINDOW, "PsppireSyntaxWindow",
                                &psppire_syntax_window_info, 0);
+
+      g_type_add_interface_static (psppire_syntax_window_type,
+                                  PSPPIRE_TYPE_WINDOW_MODEL,
+                                  &window_interface_info);
     }
 
   return psppire_syntax_window_type;
@@ -258,13 +274,11 @@ save_editor_to_file (PsppireSyntaxWindow *se,
 
 /* Callback for the File->SaveAs menuitem */
 static void
-on_syntax_save_as (GtkMenuItem *menuitem, gpointer user_data)
+syntax_save_as (PsppireWindow *se)
 {
   GtkFileFilter *filter;
   gint response;
 
-  PsppireSyntaxWindow *se = PSPPIRE_SYNTAX_WINDOW (user_data);
-
   GtkWidget *dialog =
     gtk_file_chooser_dialog_new (_("Save Syntax"),
                                 GTK_WINDOW (se),
@@ -294,7 +308,7 @@ on_syntax_save_as (GtkMenuItem *menuitem, gpointer user_data)
       char *filename =
        gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog) );
 
-      if ( ! save_editor_to_file (se, filename, &err) )
+      if ( ! save_editor_to_file (PSPPIRE_SYNTAX_WINDOW (se), filename, &err) )
        {
          msg ( ME, err->message );
          g_error_free (err);
@@ -309,18 +323,16 @@ on_syntax_save_as (GtkMenuItem *menuitem, gpointer user_data)
 
 /* Callback for the File->Save menuitem */
 static void
-on_syntax_save (GtkMenuItem *menuitem, gpointer user_data)
+syntax_save (PsppireWindow *se)
 {
-  PsppireSyntaxWindow *se = PSPPIRE_SYNTAX_WINDOW (user_data);
-  const gchar *filename = psppire_window_get_filename (PSPPIRE_WINDOW (se));
-
+  const gchar *filename = psppire_window_get_filename (se);
 
   if ( filename == NULL )
-    on_syntax_save_as (menuitem, se);
+    syntax_save_as (se);
   else
     {
       GError *err = NULL;
-      save_editor_to_file (se, filename, &err);
+      save_editor_to_file (PSPPIRE_SYNTAX_WINDOW (se), filename, &err);
       if ( err )
        {
          msg (ME, err->message);
@@ -334,32 +346,7 @@ on_syntax_save (GtkMenuItem *menuitem, gpointer user_data)
 static gboolean
 on_quit (GtkMenuItem *menuitem, gpointer    user_data)
 {
-  PsppireWindow *se = PSPPIRE_WINDOW (user_data);
-
-  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)
-{
-  PsppireWindow *se = PSPPIRE_WINDOW (user_data);
-
-  if ( psppire_window_query_save (se) )
-    {
-      gchar *filename = NULL;
-      GError *err = NULL;
-
-      g_object_get (se, "filename", &filename, NULL);
-
-      if ( ! save_editor_to_file (se, filename, &err) )
-       {
-         msg (ME, err->message);
-         g_error_free (err);
-       }
-    }
+  psppire_quit ();
 
   return FALSE;
 }
@@ -510,14 +497,14 @@ psppire_syntax_window_init (PsppireSyntaxWindow *window)
                    G_CALLBACK (reference_manual),
                    NULL);
 
-  g_signal_connect (get_object_assert (xml, "file_save"),
+  g_signal_connect_swapped (get_object_assert (xml, "file_save"),
                    "activate",
-                   G_CALLBACK (on_syntax_save),
+                   G_CALLBACK (syntax_save),
                    window);
 
-  g_signal_connect (get_object_assert (xml, "file_save_as"),
+  g_signal_connect_swapped (get_object_assert (xml, "file_save_as"),
                    "activate",
-                   G_CALLBACK (on_syntax_save_as),
+                   G_CALLBACK (syntax_save_as),
                    window);
 
   g_signal_connect (get_object_assert (xml,"file_quit"),
@@ -550,16 +537,15 @@ psppire_syntax_window_init (PsppireSyntaxWindow *window)
                    "activate",
                    G_CALLBACK (psppire_window_minimise_all), NULL);
 
+
+  {
   GtkUIManager *uim = GTK_UI_MANAGER (get_object_assert (xml, "uimanager1"));
 
   PSPPIRE_WINDOW (window)->menu =
     GTK_MENU_SHELL (gtk_ui_manager_get_widget (uim,"/ui/menubar2/windows/windows_minimise_all")->parent);
-
+  }
 
   g_object_unref (xml);
-
-  g_signal_connect (window, "delete-event",
-                   G_CALLBACK (on_delete), window);
 }
 
 
@@ -608,3 +594,10 @@ psppire_syntax_window_load_from_file (PsppireSyntaxWindow *se,
   return TRUE;
 }
 
+\f
+
+static void
+psppire_syntax_window_iface_init (PsppireWindowIface *iface)
+{
+  iface->save = syntax_save;
+}
index db459647a9b9600c9567c0cab70e4952752757df..b7529ed06f1fdaf7bb32c5e3d2cc8a7297d6ad12 100644 (file)
@@ -350,12 +350,22 @@ insert_existing_items (PsppireWindow *window)
 
 
 static gboolean
-on_delete (GtkWidget *w, GdkEvent *event, gpointer user_data)
+on_delete (PsppireWindow *w, GdkEvent *event, gpointer user_data)
 {
-  PsppireWindow *dw = PSPPIRE_WINDOW (user_data);
-
   PsppireWindowRegister *reg = psppire_window_register_new ();
 
+  if ( w->unsaved )
+    {
+      gint response = psppire_window_query_save (w);
+
+      if ( response == GTK_RESPONSE_CANCEL)
+       return TRUE;
+
+      if ( response == GTK_RESPONSE_ACCEPT)
+       {
+         psppire_window_save (w);
+       }
+    }
 
   if ( 1 == psppire_window_register_n_items (reg))
     gtk_main_quit ();
@@ -387,17 +397,18 @@ psppire_window_init (PsppireWindow *window)
 
   window->unsaved = FALSE;
 
-  g_signal_connect (window, "delete-event", G_CALLBACK (on_delete), window);
+  g_signal_connect_swapped (window, "delete-event", G_CALLBACK (on_delete), window);
 
   g_object_set (window, "icon-name", "psppicon", NULL);
+
 }
 
 
-/* If the buffer's modified flag is set,
-   ask the user if the buffer should be saved.
-   Return TRUE if is should.
+/* 
+   Ask the user if the buffer should be saved.
+   Return the response.
 */
-gboolean
+gint
 psppire_window_query_save (PsppireWindow *se)
 {
   gint response;
@@ -406,12 +417,9 @@ psppire_window_query_save (PsppireWindow *se)
   const gchar *description;
   const gchar *filename = psppire_window_get_filename (se);
 
-  if ( ! psppire_window_get_unsaved (se))
-    return FALSE;
-
   g_object_get (se, "description", &description, NULL);
 
-  g_return_val_if_fail (filename != NULL, FALSE);
+  g_return_val_if_fail (filename != NULL, GTK_RESPONSE_NONE);
 
   dialog =
     gtk_message_dialog_new (GTK_WINDOW (se),
@@ -438,12 +446,7 @@ psppire_window_query_save (PsppireWindow *se)
 
   gtk_widget_destroy (dialog);
 
-  if ( response == GTK_RESPONSE_ACCEPT )
-    {
-      return TRUE;
-    }
-
-  return FALSE;
+  return response;
 }
 
 
@@ -494,3 +497,51 @@ psppire_window_minimise_all (void)
 
   g_hash_table_foreach (reg->name_table, minimise_window, NULL);
 }
+
+
+\f
+
+GType
+psppire_window_model_get_type (void)
+{
+  static GType window_model_type = 0;
+
+  if (! window_model_type)
+    {
+      static const GTypeInfo window_model_info =
+      {
+        sizeof (PsppireWindowIface), /* class_size */
+       NULL,           /* base_init */
+       NULL,           /* base_finalize */
+       NULL,
+       NULL,           /* class_finalize */
+       NULL,           /* class_data */
+       0,
+       0,              /* n_preallocs */
+       NULL
+      };
+
+      window_model_type =
+       g_type_register_static (G_TYPE_INTERFACE, "PsppireWindowModel",
+                               &window_model_info, 0);
+
+      g_type_interface_add_prerequisite (window_model_type, G_TYPE_OBJECT);
+    }
+
+  return window_model_type;
+}
+
+
+void
+psppire_window_save (PsppireWindow *w)
+{
+  PsppireWindowIface *i = PSPPIRE_WINDOW_MODEL_GET_IFACE (w);
+
+  g_assert (PSPPIRE_IS_WINDOW_MODEL (w));
+
+  g_assert (i);
+
+  g_return_if_fail (i->save);
+
+  i->save (w);
+}
index ab0efc3fcea95d8e0d5408f7314fe2afb771d3b0..8857429304f78b351f0eb6ccd7a673dec4f0a22c 100644 (file)
 G_BEGIN_DECLS
 
 
-#define PSPPIRE_WINDOW_TYPE            (psppire_window_get_type ())
-#define PSPPIRE_WINDOW(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), PSPPIRE_WINDOW_TYPE, PsppireWindow))
+#define PSPPIRE_TYPE_WINDOW            (psppire_window_get_type ())
+
+#define PSPPIRE_WINDOW(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+    PSPPIRE_TYPE_WINDOW, PsppireWindow))
+
 #define PSPPIRE_WINDOW_CLASS(class)    (G_TYPE_CHECK_CLASS_CAST ((class), \
-    PSPPIRE_WINDOW_TYPE, PsppireWindowClass))
+    PSPPIRE_TYPE_WINDOW, PsppireWindowClass))
+
 #define PSPPIRE_IS_WINDOW(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
-    PSPPIRE_WINDOW_TYPE))
+    PSPPIRE_TYPE_WINDOW))
+
 #define PSPPIRE_IS_WINDOW_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \
-    PSPPIRE_WINDOW_TYPE))
+    PSPPIRE_TYPE_WINDOW))
+
+
+
+#define PSPPIRE_TYPE_WINDOW_MODEL            (psppire_window_model_get_type ())
+
+#define PSPPIRE_IS_WINDOW_MODEL(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PSPPIRE_TYPE_WINDOW_MODEL))
+
+#define PSPPIRE_WINDOW_MODEL_GET_IFACE(obj) \
+   (G_TYPE_INSTANCE_GET_INTERFACE ((obj), PSPPIRE_TYPE_WINDOW_MODEL, PsppireWindowIface))
 
 
 typedef struct _PsppireWindow       PsppireWindow;
 typedef struct _PsppireWindowClass  PsppireWindowClass;
+typedef struct _PsppireWindowIface  PsppireWindowIface;
 
 
 struct _PsppireWindow
@@ -59,12 +74,23 @@ struct _PsppireWindow
   gboolean unsaved;
 };
 
+
 struct _PsppireWindowClass
 {
   GtkWindowClass parent_class;
 };
 
+
+struct _PsppireWindowIface
+{
+  GTypeInterface g_iface;
+
+  void (*save) (PsppireWindow *w);
+};
+
+
 GType      psppire_window_get_type        (void);
+GType      psppire_window_model_get_type        (void);
 
 const gchar * psppire_window_get_filename (PsppireWindow *);
 
@@ -76,9 +102,9 @@ void psppire_window_set_unsaved (PsppireWindow *, gboolean );
 
 gboolean psppire_window_get_unsaved (PsppireWindow *);
 
+gint psppire_window_query_save (PsppireWindow *);
 
-gboolean psppire_window_query_save (PsppireWindow *);
-
+void psppire_window_save (PsppireWindow *w);
 
 G_END_DECLS
 
index 08b930e9fc166a7fd54ba8f54b045ae9d00be2c5..8a23346ce788667f611a5dede2ac4dd1cfff0b34 100644 (file)
@@ -52,7 +52,7 @@
 #include "message-dialog.h"
 #include <ui/syntax-gen.h>
 
-
+#include "psppire-window-register.h"
 #include "psppire-output-window.h"
 
 #include <data/sys-file-reader.h>
@@ -170,6 +170,24 @@ de_initialize (void)
 }
 
 
+static void
+func (gpointer key, gpointer value, gpointer data)
+{
+  gboolean rv;
+  PsppireWindow *window = PSPPIRE_WINDOW (value);
+
+  g_signal_emit_by_name (window, "delete-event", 0, &rv);
+}
+
+void
+psppire_quit (void)
+{
+  PsppireWindowRegister *reg = psppire_window_register_new ();
+  psppire_window_register_foreach (reg, func, NULL);
+
+  gtk_main_quit ();
+}
+
 
 struct icon_info
 {
index 92cd13571ca15bebd63e50adc87eddc385145048..a2cba9bbe495c8f7d7cc8788bc54a18747007cb4 100644 (file)
@@ -25,5 +25,7 @@ extern const struct argp non_option_argp ;
 
 void initialize (struct command_line_processor *, int argc, char **argv);
 void de_initialize (void);
+void psppire_quit (void);
+
 
 #endif /* PSPPIRE_H */