From 753b29514d19fd54d51c2346bc6bb08ff1093cac Mon Sep 17 00:00:00 2001 From: Christian Persch Date: Sun, 4 Jan 2004 12:52:05 +0000 Subject: Add API to check if an EphyEmbed has forms with user input in them. 2004-01-04 Christian Persch * embed/ephy-embed.c: (ephy_embed_has_modified_forms): * embed/ephy-embed.h: * embed/mozilla/EphyBrowser.cpp: * embed/mozilla/EphyBrowser.h: * embed/mozilla/mozilla-embed.cpp: Add API to check if an EphyEmbed has forms with user input in them. Currently it required one modified textarea, or two modified text fields. * src/ephy-notebook.c: (ephy_notebook_class_init), (close_button_clicked_cb): * src/ephy-notebook.h: * src/ephy-window.c: (confirm_close_with_modified_forms), (ephy_window_delete_event_cb), (tab_delete_cb), (setup_notebook), (ephy_window_init), (ephy_window_remove_tab): When closing a window or tab, check if there is unsubmitted user input in form fields, and if so, warn the user before closing. Fixes bug #119857. --- src/ephy-notebook.c | 25 +++++++-- src/ephy-notebook.h | 2 + src/ephy-window.c | 146 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 166 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/ephy-notebook.c b/src/ephy-notebook.c index 87bb719a6..799e27b74 100644 --- a/src/ephy-notebook.c +++ b/src/ephy-notebook.c @@ -20,7 +20,7 @@ */ #ifdef HAVE_CONFIG_H -#include +#include "config.h" #endif #include "ephy-notebook.h" @@ -92,13 +92,14 @@ enum TAB_REMOVED, TABS_REORDERED, TAB_DETACHED, + TAB_DELETE, LAST_SIGNAL }; -static GObjectClass *parent_class = NULL; - static guint signals[LAST_SIGNAL] = { 0 }; +static GObjectClass *parent_class = NULL; + GType ephy_notebook_get_type (void) { @@ -175,6 +176,16 @@ ephy_notebook_class_init (EphyNotebookClass *klass) g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + signals[TAB_DELETE] = + g_signal_new ("tab_delete", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EphyNotebookClass, tab_delete), + g_signal_accumulator_true_handled, NULL, + ephy_marshal_BOOLEAN__OBJECT, + G_TYPE_BOOLEAN, + 1, + GTK_TYPE_WIDGET); g_type_class_add_private (object_class, sizeof(EphyNotebookPrivate)); } @@ -852,9 +863,15 @@ static void close_button_clicked_cb (GtkWidget *widget, GtkWidget *child) { EphyNotebook *notebook; + gboolean inhibited = FALSE; notebook = EPHY_NOTEBOOK (gtk_widget_get_parent (child)); - ephy_notebook_remove_page (notebook, child); + g_signal_emit (G_OBJECT (notebook), signals[TAB_DELETE], 0, child, &inhibited); + + if (inhibited == FALSE) + { + ephy_notebook_remove_page (notebook, child); + } } static GtkWidget * diff --git a/src/ephy-notebook.h b/src/ephy-notebook.h index ca93cdf55..314ad098c 100644 --- a/src/ephy-notebook.h +++ b/src/ephy-notebook.h @@ -70,6 +70,8 @@ struct EphyNotebookClass void (* tab_detached) (EphyNotebook *notebook, GtkWidget *child); void (* tabs_reordered) (EphyNotebook *notebook); + void (* tab_delete) (EphyNotebook *notebook, + GtkWidget *child); }; GType ephy_notebook_get_type (void); diff --git a/src/ephy-window.c b/src/ephy-window.c index f5013d9c8..a4f748aa5 100644 --- a/src/ephy-window.c +++ b/src/ephy-window.c @@ -57,6 +57,8 @@ #include #include #include +#include +#include static void ephy_window_class_init (EphyWindowClass *klass); static void ephy_window_init (EphyWindow *gs); @@ -636,6 +638,116 @@ ephy_window_state_event_cb (GtkWidget *widget, GdkEventWindowState *event, EphyW return FALSE; } +static gboolean +confirm_close_with_modified_forms (EphyWindow *window) +{ + GtkWidget *dialog; + GtkWidget *hbox, *vbox, *label, *image; + GtkWindowGroup *group; + char *text; + int response; + + dialog = gtk_dialog_new_with_buttons ("", + GTK_WINDOW (window), + GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_MODAL, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + _("_Close document"), GTK_RESPONSE_OK, + NULL); + + gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); + gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); + gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 14); + + hbox = gtk_hbox_new (FALSE, 6); + gtk_widget_show (hbox); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox, + TRUE, TRUE, 0); + + image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING, + GTK_ICON_SIZE_DIALOG); + gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0); + gtk_widget_show (image); + gtk_box_pack_start (GTK_BOX (hbox), image, TRUE, TRUE, 0); + + vbox = gtk_vbox_new (FALSE, 6); + gtk_widget_show (vbox); + gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0); + + label = gtk_label_new (NULL); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); + + text = g_strdup_printf ("%s\n\n%s", + _("There are unsubmitted changes to form elements."), + _("If you close the document anyway, you will lose that information.")); + gtk_label_set_markup (GTK_LABEL (label), text); + g_free (text); + + gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0); + gtk_widget_show (label); + + group = GTK_WINDOW (window)->group; + if (group == NULL) + { + group = gtk_window_group_new (); + gtk_window_group_add_window (group, GTK_WINDOW (window)); + g_object_unref (group); + } + + gtk_window_group_add_window (group, GTK_WINDOW (dialog)); + + response = gtk_dialog_run (GTK_DIALOG (dialog)); + + gtk_widget_destroy (dialog); + + return response == GTK_RESPONSE_OK; +} + +static gboolean +ephy_window_delete_event_cb (GtkWidget *widget, GdkEvent *event, EphyWindow *window) +{ + EphyTab *modified_tab = NULL; + GList *tabs, *l; + gboolean modified = FALSE; + + tabs = ephy_window_get_tabs (window); + for (l = tabs; l != NULL; l = l->next) + { + EphyTab *tab = (EphyTab *) l->data; + EphyEmbed *embed; + + g_return_val_if_fail (EPHY_IS_TAB (tab), FALSE); + + embed = ephy_tab_get_embed (tab); + g_return_val_if_fail (EPHY_IS_EMBED (embed), FALSE); + + if (ephy_embed_has_modified_forms (embed)) + { + modified = TRUE; + modified_tab = tab; + break; + } + } + g_list_free (tabs); + + if (modified) + { + /* jump to the first tab with modified forms */ + ephy_window_jump_to_tab (window, modified_tab); + + if (confirm_close_with_modified_forms (window) == FALSE) + { + /* stop window close */ + return TRUE; + } + } + + /* See bug #114689 */ + gtk_widget_hide (widget); + + /* proceed with window close */ + return FALSE; +} static void update_edit_actions_sensitivity (EphyWindow *window, gboolean hide) @@ -1445,6 +1557,19 @@ tabs_reordered_cb (EphyNotebook *notebook, EphyWindow *window) ephy_tabs_menu_update (window->priv->tabs_menu); } +static gboolean +tab_delete_cb (EphyNotebook *notebook, GtkWidget *child, EphyWindow *window) +{ + g_return_val_if_fail (EPHY_IS_EMBED (child), FALSE); + + if (ephy_embed_has_modified_forms (EPHY_EMBED (child))) + { + return !confirm_close_with_modified_forms (window); + } + + return FALSE; +} + static GtkNotebook * setup_notebook (EphyWindow *window) { @@ -1468,6 +1593,8 @@ setup_notebook (EphyWindow *window) G_CALLBACK (tab_detached_cb), NULL); g_signal_connect (G_OBJECT (notebook), "tabs_reordered", G_CALLBACK (tabs_reordered_cb), window); + g_signal_connect (G_OBJECT (notebook), "tab_delete", + G_CALLBACK (tab_delete_cb), window); return notebook; } @@ -1662,6 +1789,9 @@ ephy_window_init (EphyWindow *window) g_signal_connect (window, "window-state-event", G_CALLBACK (ephy_window_state_event_cb), window); + g_signal_connect (window, "delete-event", + G_CALLBACK (ephy_window_delete_event_cb), + window); /* lockdown pref notifiers */ window->priv->disable_js_chrome_notifier_id = eel_gconf_notification_add @@ -1834,15 +1964,25 @@ void ephy_window_remove_tab (EphyWindow *window, EphyTab *tab) { - GtkWidget *embed; + EphyEmbed *embed; + gboolean modified; g_return_if_fail (EPHY_IS_WINDOW (window)); g_return_if_fail (EPHY_IS_TAB (tab)); - embed = GTK_WIDGET (ephy_tab_get_embed (tab)); + embed = ephy_tab_get_embed (tab); + g_return_if_fail (EPHY_IS_EMBED (embed)); + + modified = ephy_embed_has_modified_forms (embed); + if (ephy_embed_has_modified_forms (embed) + && confirm_close_with_modified_forms (window) == FALSE) + { + /* don't close the tab */ + return; + } ephy_notebook_remove_page (EPHY_NOTEBOOK (window->priv->notebook), - embed); + GTK_WIDGET (embed)); } /** -- cgit v1.2.3