aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ephy-notebook.c25
-rw-r--r--src/ephy-notebook.h2
-rw-r--r--src/ephy-window.c146
3 files changed, 166 insertions, 7 deletions
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 <config.h>
+#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 <gtk/gtktoggleaction.h>
#include <gtk/gtkuimanager.h>
#include <gtk/gtktoggleaction.h>
+#include <gtk/gtkdialog.h>
+#include <gtk/gtkmessagedialog.h>
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 ("<span weight=\"bold\" size=\"larger\">%s</span>\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));
}
/**