From ca259adce7a069f58545de7511e17d73c9e0a868 Mon Sep 17 00:00:00 2001 From: John Darrington Date: Mon, 2 Mar 2009 15:51:53 +0900 Subject: [PATCH] Save window contents on closing. --- src/ui/gui/psppire-data-store.c | 2 +- src/ui/gui/psppire-data-window.c | 61 ++++++++++++--------- src/ui/gui/psppire-output-window.c | 10 ++-- src/ui/gui/psppire-syntax-window.c | 83 +++++++++++++--------------- src/ui/gui/psppire-window.c | 87 +++++++++++++++++++++++------- src/ui/gui/psppire-window.h | 40 +++++++++++--- src/ui/gui/psppire.c | 20 ++++++- src/ui/gui/psppire.h | 2 + 8 files changed, 203 insertions(+), 102 deletions(-) diff --git a/src/ui/gui/psppire-data-store.c b/src/ui/gui/psppire-data-store.c index 1bbd2bb8..c8804f48 100644 --- a/src/ui/gui/psppire-data-store.c +++ b/src/ui/gui/psppire-data-store.c @@ -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); diff --git a/src/ui/gui/psppire-data-window.c b/src/ui/gui/psppire-data-window.c index 84fc5071..c8263183 100644 --- a/src/ui/gui/psppire-data-window.c +++ b/src/ui/gui/psppire-data-window.c @@ -30,6 +30,8 @@ #include +#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)); } + + + + + +static void +psppire_data_window_iface_init (PsppireWindowIface *iface) +{ + iface->save = data_save; +} diff --git a/src/ui/gui/psppire-output-window.c b/src/ui/gui/psppire-output-window.c index 986742d0..9c1e73a5 100644 --- a/src/ui/gui/psppire-output-window.c +++ b/src/ui/gui/psppire-output-window.c @@ -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); diff --git a/src/ui/gui/psppire-syntax-window.c b/src/ui/gui/psppire-syntax-window.c index 07e73c13..2a09c71c 100644 --- a/src/ui/gui/psppire-syntax-window.c +++ b/src/ui/gui/psppire-syntax-window.c @@ -23,6 +23,7 @@ #include #include +#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; } + + +static void +psppire_syntax_window_iface_init (PsppireWindowIface *iface) +{ + iface->save = syntax_save; +} diff --git a/src/ui/gui/psppire-window.c b/src/ui/gui/psppire-window.c index db459647..b7529ed0 100644 --- a/src/ui/gui/psppire-window.c +++ b/src/ui/gui/psppire-window.c @@ -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); } + + + + +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); +} diff --git a/src/ui/gui/psppire-window.h b/src/ui/gui/psppire-window.h index ab0efc3f..88574293 100644 --- a/src/ui/gui/psppire-window.h +++ b/src/ui/gui/psppire-window.h @@ -28,18 +28,33 @@ 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 diff --git a/src/ui/gui/psppire.c b/src/ui/gui/psppire.c index 08b930e9..8a23346c 100644 --- a/src/ui/gui/psppire.c +++ b/src/ui/gui/psppire.c @@ -52,7 +52,7 @@ #include "message-dialog.h" #include - +#include "psppire-window-register.h" #include "psppire-output-window.h" #include @@ -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 { diff --git a/src/ui/gui/psppire.h b/src/ui/gui/psppire.h index 92cd1357..a2cba9bb 100644 --- a/src/ui/gui/psppire.h +++ b/src/ui/gui/psppire.h @@ -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 */ -- 2.30.2