aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--addressbook/gui/contact-editor/e-contact-editor.c40
-rw-r--r--addressbook/gui/contact-editor/e-contact-editor.h3
-rw-r--r--addressbook/gui/contact-editor/e-contact-quick-add.c7
-rw-r--r--addressbook/gui/contact-editor/eab-editor.c352
-rw-r--r--addressbook/gui/contact-editor/eab-editor.h100
-rw-r--r--addressbook/gui/contact-list-editor/e-contact-list-editor.c64
-rw-r--r--addressbook/gui/contact-list-editor/e-contact-list-editor.h3
-rw-r--r--doc/reference/shell/tmpl/e-shell.sgml9
-rw-r--r--doc/reference/shell/tmpl/eshell-unused.sgml8
-rw-r--r--modules/addressbook/e-book-shell-backend.c70
-rw-r--r--modules/addressbook/e-book-shell-view-actions.c18
-rw-r--r--modules/addressbook/e-book-shell-view-private.c15
-rw-r--r--shell/e-shell-window.c3
-rw-r--r--shell/e-shell.c104
-rw-r--r--shell/e-shell.h1
15 files changed, 489 insertions, 308 deletions
diff --git a/addressbook/gui/contact-editor/e-contact-editor.c b/addressbook/gui/contact-editor/e-contact-editor.c
index 69d11b0e3c..d4768ae675 100644
--- a/addressbook/gui/contact-editor/e-contact-editor.c
+++ b/addressbook/gui/contact-editor/e-contact-editor.c
@@ -2253,7 +2253,7 @@ fill_in_simple_field (EContactEditor *editor, GtkWidget *widget, gint field_id)
editor->image_set = TRUE;
}
else {
- gchar *file_name = e_icon_factory_get_icon_filename ("stock_person", 48);
+ gchar *file_name = e_icon_factory_get_icon_filename ("stock_person", GTK_ICON_SIZE_DIALOG);
e_image_chooser_set_from_file (E_IMAGE_CHOOSER (widget), file_name);
editor->image_set = FALSE;
g_free (file_name);
@@ -3518,7 +3518,7 @@ static void
supported_fields_cb (EBook *book, EBookStatus status,
EList *fields, EContactEditor *ce)
{
- if (!g_slist_find ((GSList*)eab_editor_get_all_editors (), ce)) {
+ if (!g_slist_find (eab_editor_get_all_editors (), ce)) {
g_warning ("supported_fields_cb called for book that's still around, but contact editor that's been destroyed.");
return;
}
@@ -3537,7 +3537,7 @@ required_fields_cb (EBook *book, EBookStatus status,
EList *fields, EContactEditor *ce)
{
- if (!g_slist_find ((GSList*)eab_editor_get_all_editors (), ce)) {
+ if (!g_slist_find (eab_editor_get_all_editors (), ce)) {
g_warning ("supported_fields_cb called for book that's still around, but contact editor that's been destroyed.");
return;
}
@@ -3549,31 +3549,22 @@ required_fields_cb (EBook *book, EBookStatus status,
}
-
-static void
-contact_editor_destroy_notify (gpointer data,
- GObject *where_the_object_was)
+EABEditor *
+e_contact_editor_new (EShell *shell,
+ EBook *book,
+ EContact *contact,
+ gboolean is_new_contact,
+ gboolean editable)
{
- eab_editor_remove (EAB_EDITOR (data));
-}
-
-GtkWidget *
-e_contact_editor_new (EBook *book,
- EContact *contact,
- gboolean is_new_contact,
- gboolean editable)
-{
- EContactEditor *ce;
+ EABEditor *editor;
+ g_return_val_if_fail (E_IS_SHELL (shell), NULL);
g_return_val_if_fail (E_IS_BOOK (book), NULL);
g_return_val_if_fail (E_IS_CONTACT (contact), NULL);
- ce = g_object_new (E_TYPE_CONTACT_EDITOR, NULL);
+ editor = g_object_new (E_TYPE_CONTACT_EDITOR, "shell", shell, NULL);
- eab_editor_add (EAB_EDITOR (ce));
- g_object_weak_ref (G_OBJECT (ce), contact_editor_destroy_notify, ce);
-
- g_object_set (ce,
+ g_object_set (editor,
"source_book", book,
"contact", contact,
"is_new_contact", is_new_contact,
@@ -3581,9 +3572,10 @@ e_contact_editor_new (EBook *book,
NULL);
if (book)
- e_book_async_get_supported_fields (book, (EBookEListCallback)supported_fields_cb, ce);
+ e_book_async_get_supported_fields (
+ book, (EBookEListCallback)supported_fields_cb, editor);
- return GTK_WIDGET (ce);
+ return editor;
}
static void
diff --git a/addressbook/gui/contact-editor/e-contact-editor.h b/addressbook/gui/contact-editor/e-contact-editor.h
index 1000cdc544..6228dc3499 100644
--- a/addressbook/gui/contact-editor/e-contact-editor.h
+++ b/addressbook/gui/contact-editor/e-contact-editor.h
@@ -108,7 +108,8 @@ struct _EContactEditorClass
};
GType e_contact_editor_get_type (void);
-GtkWidget *e_contact_editor_new (EBook *book,
+EABEditor *e_contact_editor_new (EShell *shell,
+ EBook *book,
EContact *contact,
gboolean is_new_contact,
gboolean editable);
diff --git a/addressbook/gui/contact-editor/e-contact-quick-add.c b/addressbook/gui/contact-editor/e-contact-quick-add.c
index cd81d28690..df3eb6ec58 100644
--- a/addressbook/gui/contact-editor/e-contact-quick-add.c
+++ b/addressbook/gui/contact-editor/e-contact-quick-add.c
@@ -194,7 +194,12 @@ ce_have_book (EBook *book, EBookStatus status, gpointer closure)
g_warning ("Couldn't open local address book.");
quick_add_unref (qa);
} else {
- GtkWidget *contact_editor = e_contact_editor_new (book, qa->contact, TRUE, TRUE /* XXX */);
+ EShell *shell;
+ EABEditor *contact_editor;
+
+ shell = e_shell_get_default ();
+ contact_editor = e_contact_editor_new (
+ shell, book, qa->contact, TRUE, TRUE /* XXX */);
/* mark it as changed so the Save buttons are enabled when we bring up the dialog. */
g_object_set (contact_editor,
diff --git a/addressbook/gui/contact-editor/eab-editor.c b/addressbook/gui/contact-editor/eab-editor.c
index b5a4683540..554db9aa7b 100644
--- a/addressbook/gui/contact-editor/eab-editor.c
+++ b/addressbook/gui/contact-editor/eab-editor.c
@@ -31,13 +31,19 @@
#include "e-util/e-util.h"
#include "addressbook/gui/widgets/eab-gui-util.h"
-static void eab_editor_default_show (EABEditor *editor);
-static void eab_editor_default_raise (EABEditor *editor);
-static void eab_editor_default_close (EABEditor *editor);
-static void eab_editor_class_init (EABEditorClass *klass);
-static void eab_editor_init (EABEditor *editor);
+#define EAB_EDITOR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), EAB_TYPE_EDITOR, EABEditorPrivate))
+
+struct _EABEditorPrivate {
+ EShell *shell;
+};
+
+enum {
+ PROP_0,
+ PROP_SHELL
+};
-/* Signal IDs */
enum {
CONTACT_ADDED,
CONTACT_MODIFIED,
@@ -46,97 +52,125 @@ enum {
LAST_SIGNAL
};
-static GSList *all_editors = NULL;
-
-static GtkObjectClass *parent_class = NULL;
-
-static guint editor_signals[LAST_SIGNAL];
+static GSList *all_editors;
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
-GType
-eab_editor_get_type (void)
+static void
+eab_editor_quit_requested_cb (EABEditor *editor,
+ EShell *shell)
{
- static GType editor_type = 0;
-
- if (!editor_type) {
- static const GTypeInfo editor_info = {
- sizeof (EABEditorClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) eab_editor_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (EABEditor),
- 0, /* n_preallocs */
- (GInstanceInitFunc) eab_editor_init,
- };
+ GtkWindow *window;
- editor_type = g_type_register_static (G_TYPE_OBJECT, "EABEditor", &editor_info, 0);
- }
+ window = eab_editor_get_window (editor);
- return editor_type;
+ eab_editor_raise (editor);
+ if (!eab_editor_prompt_to_save_changes (editor, window))
+ e_shell_cancel_quit (shell);
}
static void
-eab_editor_default_show (EABEditor *editor)
+eab_editor_set_shell (EABEditor *editor,
+ EShell *shell)
{
- g_warning ("abstract eab_editor_show called");
+ g_return_if_fail (editor->priv->shell == NULL);
+ g_return_if_fail (E_IS_SHELL (shell));
+
+ editor->priv->shell = g_object_ref (shell);
+
+ g_signal_connect_swapped (
+ shell, "quit-requested",
+ G_CALLBACK (eab_editor_quit_requested_cb), editor);
}
static void
-eab_editor_default_close (EABEditor *editor)
+eab_editor_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- g_warning ("abstract eab_editor_close called");
+ switch (property_id) {
+ case PROP_SHELL:
+ eab_editor_set_shell (
+ EAB_EDITOR (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
-eab_editor_default_raise (EABEditor *editor)
+eab_editor_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- g_warning ("abstract eab_editor_raise called");
+ switch (property_id) {
+ case PROP_SHELL:
+ g_value_set_object (
+ value, eab_editor_get_shell (
+ EAB_EDITOR (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
-eab_editor_default_save_contact (EABEditor *editor, gboolean should_close)
+eab_editor_dispose (GObject *object)
{
- g_warning ("abstract eab_editor_save_contact called");
-}
+ EABEditorPrivate *priv;
-static gboolean
-eab_editor_default_is_valid (EABEditor *editor)
-{
- g_warning ("abstract eab_editor_is_valid called");
- return FALSE;
-}
+ priv = EAB_EDITOR_GET_PRIVATE (object);
-static gboolean
-eab_editor_default_is_changed (EABEditor *editor)
-{
- g_warning ("abstract eab_editor_is_changed called");
- return FALSE;
-}
+ if (priv->shell != NULL) {
+ g_signal_handlers_disconnect_matched (
+ priv->shell, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, object);
+ g_object_unref (priv->shell);
+ priv->shell = NULL;
+ }
-static GtkWindow*
-eab_editor_default_get_window (EABEditor *editor)
-{
- g_warning ("abstract eab_editor_get_window called");
- return NULL;
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
-eab_editor_class_init (EABEditorClass *klass)
+eab_editor_finalize (GObject *object)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ all_editors = g_slist_remove (all_editors, object);
- parent_class = g_type_class_ref (G_TYPE_OBJECT);
-
- klass->show = eab_editor_default_show;
- klass->close = eab_editor_default_close;
- klass->raise = eab_editor_default_raise;
- klass->save_contact = eab_editor_default_save_contact;
- klass->is_valid = eab_editor_default_is_valid;
- klass->is_changed = eab_editor_default_is_changed;
- klass->get_window = eab_editor_default_get_window;
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
- editor_signals[CONTACT_ADDED] =
+static void
+eab_editor_class_init (EABEditorClass *class)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EABEditorPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = eab_editor_set_property;
+ object_class->get_property = eab_editor_get_property;
+ object_class->dispose = eab_editor_dispose;
+ object_class->finalize = eab_editor_finalize;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL,
+ g_param_spec_object (
+ "shell",
+ _("Shell"),
+ _("The EShell singleton"),
+ E_TYPE_SHELL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ signals[CONTACT_ADDED] =
g_signal_new ("contact_added",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
@@ -146,7 +180,7 @@ eab_editor_class_init (EABEditorClass *klass)
G_TYPE_NONE, 2,
G_TYPE_INT, G_TYPE_OBJECT);
- editor_signals[CONTACT_MODIFIED] =
+ signals[CONTACT_MODIFIED] =
g_signal_new ("contact_modified",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
@@ -156,7 +190,7 @@ eab_editor_class_init (EABEditorClass *klass)
G_TYPE_NONE, 2,
G_TYPE_INT, G_TYPE_OBJECT);
- editor_signals[CONTACT_DELETED] =
+ signals[CONTACT_DELETED] =
g_signal_new ("contact_deleted",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
@@ -166,7 +200,7 @@ eab_editor_class_init (EABEditorClass *klass)
G_TYPE_NONE, 2,
G_TYPE_INT, G_TYPE_OBJECT);
- editor_signals[EDITOR_CLOSED] =
+ signals[EDITOR_CLOSED] =
g_signal_new ("editor_closed",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
@@ -179,78 +213,143 @@ eab_editor_class_init (EABEditorClass *klass)
static void
eab_editor_init (EABEditor *editor)
{
+ editor->priv = EAB_EDITOR_GET_PRIVATE (editor);
+
+ all_editors = g_slist_prepend (all_editors, editor);
+}
+
+GType
+eab_editor_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EABEditorClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) eab_editor_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EABEditor),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) eab_editor_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ G_TYPE_OBJECT, "EABEditor", &type_info,
+ G_TYPE_FLAG_ABSTRACT);
+ }
+
+ return type;
+}
+
+EShell *
+eab_editor_get_shell (EABEditor *editor)
+{
+ g_return_val_if_fail (EAB_IS_EDITOR (editor), NULL);
+
+ return E_SHELL (editor->priv->shell);
}
-
+GSList *
+eab_editor_get_all_editors (void)
+{
+ return all_editors;
+}
void
eab_editor_show (EABEditor *editor)
{
+ EABEditorClass *class;
+
g_return_if_fail (EAB_IS_EDITOR (editor));
- if (EAB_EDITOR_GET_CLASS(editor)->show)
- EAB_EDITOR_GET_CLASS(editor)->show (editor);
+ class = EAB_EDITOR_GET_CLASS (editor);
+ g_return_if_fail (class->show != NULL);
+
+ class->show (editor);
}
void
eab_editor_close (EABEditor *editor)
{
+ EABEditorClass *class;
+
g_return_if_fail (EAB_IS_EDITOR (editor));
- if (EAB_EDITOR_GET_CLASS(editor)->close)
- EAB_EDITOR_GET_CLASS(editor)->close (editor);
+ class = EAB_EDITOR_GET_CLASS (editor);
+ g_return_if_fail (class->close != NULL);
+
+ class->close (editor);
}
void
eab_editor_raise (EABEditor *editor)
{
+ EABEditorClass *class;
+
g_return_if_fail (EAB_IS_EDITOR (editor));
- if (EAB_EDITOR_GET_CLASS(editor)->raise)
- EAB_EDITOR_GET_CLASS(editor)->raise (editor);
+ class = EAB_EDITOR_GET_CLASS (editor);
+ g_return_if_fail (class->raise != NULL);
+
+ class->raise (editor);
}
void
eab_editor_save_contact (EABEditor *editor, gboolean should_close)
{
+ EABEditorClass *class;
+
g_return_if_fail (EAB_IS_EDITOR (editor));
- if (EAB_EDITOR_GET_CLASS(editor)->save_contact)
- EAB_EDITOR_GET_CLASS(editor)->save_contact (editor, should_close);
+ class = EAB_EDITOR_GET_CLASS (editor);
+ g_return_if_fail (class->save_contact != NULL);
+
+ class->save_contact (editor, should_close);
}
gboolean
eab_editor_is_changed (EABEditor *editor)
{
+ EABEditorClass *class;
+
g_return_val_if_fail (EAB_IS_EDITOR (editor), FALSE);
- if (EAB_EDITOR_GET_CLASS(editor)->is_changed)
- return EAB_EDITOR_GET_CLASS(editor)->is_changed (editor);
- else
- return FALSE;
+ class = EAB_EDITOR_GET_CLASS (editor);
+ g_return_val_if_fail (class->is_changed != NULL, FALSE);
+
+ return class->is_changed (editor);
}
gboolean
eab_editor_is_valid (EABEditor *editor)
{
+ EABEditorClass *class;
+
g_return_val_if_fail (EAB_IS_EDITOR (editor), FALSE);
- if (EAB_EDITOR_GET_CLASS(editor)->is_valid)
- return EAB_EDITOR_GET_CLASS(editor)->is_valid (editor);
- else
- return FALSE;
+ class = EAB_EDITOR_GET_CLASS (editor);
+ g_return_val_if_fail (class->is_valid != NULL, FALSE);
+
+ return class->is_valid (editor);
}
GtkWindow*
eab_editor_get_window (EABEditor *editor)
{
+ EABEditorClass *class;
+
g_return_val_if_fail (EAB_IS_EDITOR (editor), NULL);
- if (EAB_EDITOR_GET_CLASS(editor)->get_window)
- return EAB_EDITOR_GET_CLASS(editor)->get_window (editor);
- else
- return NULL;
+ class = EAB_EDITOR_GET_CLASS (editor);
+ g_return_val_if_fail (class->get_window != NULL, NULL);
+
+ return class->get_window (editor);
}
+
/* This function prompts for saving if editor conents are in changed state and
save or discards or cancels(just returns with out doing anything) according to user input.
Editor gets destoryed in case of save and discard case.
@@ -280,64 +379,37 @@ eab_editor_prompt_to_save_changes (EABEditor *editor, GtkWindow *window)
}
}
-gboolean
-eab_editor_request_close_all (void)
-{
- GSList *p;
- GSList *pnext;
- gboolean retval;
-
- retval = TRUE;
- for (p = all_editors; p != NULL; p = pnext) {
- EABEditor *editor = EAB_EDITOR (p->data);
- GtkWindow *window = eab_editor_get_window (editor);
-
- pnext = p->next;
-
- eab_editor_raise (editor);
- if (! eab_editor_prompt_to_save_changes (editor, window)) {
- retval = FALSE;
- break;
- }
- }
-
- return retval;
-}
-
-const GSList*
-eab_editor_get_all_editors (void)
-{
- return all_editors;
-}
-
void
-eab_editor_contact_added (EABEditor *editor, EBookStatus status, EContact *contact)
+eab_editor_contact_added (EABEditor *editor,
+ EBookStatus status,
+ EContact *contact)
{
g_return_if_fail (EAB_IS_EDITOR (editor));
g_return_if_fail (E_IS_CONTACT (contact));
- g_signal_emit (editor, editor_signals[CONTACT_ADDED], 0,
- status, contact);
+ g_signal_emit (editor, signals[CONTACT_ADDED], 0, status, contact);
}
void
-eab_editor_contact_modified (EABEditor *editor, EBookStatus status, EContact *contact)
+eab_editor_contact_modified (EABEditor *editor,
+ EBookStatus status,
+ EContact *contact)
{
g_return_if_fail (EAB_IS_EDITOR (editor));
g_return_if_fail (E_IS_CONTACT (contact));
- g_signal_emit (editor, editor_signals[CONTACT_MODIFIED], 0,
- status, contact);
+ g_signal_emit (editor, signals[CONTACT_MODIFIED], 0, status, contact);
}
void
-eab_editor_contact_deleted (EABEditor *editor, EBookStatus status, EContact *contact)
+eab_editor_contact_deleted (EABEditor *editor,
+ EBookStatus status,
+ EContact *contact)
{
g_return_if_fail (EAB_IS_EDITOR (editor));
g_return_if_fail (E_IS_CONTACT (contact));
- g_signal_emit (editor, editor_signals[CONTACT_DELETED], 0,
- status, contact);
+ g_signal_emit (editor, signals[CONTACT_DELETED], 0, status, contact);
}
void
@@ -345,21 +417,5 @@ eab_editor_closed (EABEditor *editor)
{
g_return_if_fail (EAB_IS_EDITOR (editor));
- g_signal_emit (editor, editor_signals[EDITOR_CLOSED], 0);
-}
-
-void
-eab_editor_add (EABEditor *editor)
-{
- g_return_if_fail (EAB_IS_EDITOR (editor));
-
- all_editors = g_slist_prepend (all_editors, editor);
-}
-
-void
-eab_editor_remove (EABEditor *editor)
-{
- g_return_if_fail (EAB_IS_EDITOR (editor));
-
- all_editors = g_slist_remove (all_editors, editor);
+ g_signal_emit (editor, signals[EDITOR_CLOSED], 0);
}
diff --git a/addressbook/gui/contact-editor/eab-editor.h b/addressbook/gui/contact-editor/eab-editor.h
index 1b3de4b28a..f3803e7341 100644
--- a/addressbook/gui/contact-editor/eab-editor.h
+++ b/addressbook/gui/contact-editor/eab-editor.h
@@ -24,42 +24,42 @@
#ifndef __EAB_EDITOR_H__
#define __EAB_EDITOR_H__
-#include <glade/glade.h>
-
+#include <gtk/gtk.h>
#include <libebook/e-book.h>
#include <libebook/e-contact.h>
-
-#include <gtk/gtk.h>
+#include <shell/e-shell.h>
+
+/* Standard GObject macros */
+#define EAB_TYPE_EDITOR \
+ (eab_editor_get_type ())
+#define EAB_EDITOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), EAB_TYPE_EDITOR, EABEditor))
+#define EAB_EDITOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), EAB_TYPE_EDITOR, EABEditorClass))
+#define EAB_IS_EDITOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), EAB_TYPE_EDITOR))
+#define EAB_IS_EDITOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), EAB_TYPE_EDITOR))
+#define EAB_EDITOR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), EAB_EDITOR_TYPE, EABEditorClass))
G_BEGIN_DECLS
-/* EABEditor - A dialog displaying information about a contact.
- *
- * The following arguments are available:
- *
- * name type read/write description
- * --------------------------------------------------------------------------------
- * card ECard * RW The card currently being edited
- */
-
-#define EAB_TYPE_EDITOR (eab_editor_get_type ())
-#define EAB_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EAB_TYPE_EDITOR, EABEditor))
-#define EAB_EDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EAB_TYPE_EDITOR, EABEditorClass))
-#define EAB_IS_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EAB_TYPE_EDITOR))
-#define EAB_IS_EDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EAB_TYPE_EDITOR))
-#define EAB_EDITOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EAB_EDITOR_TYPE, EABEditorClass))
-
+typedef struct _EABEditor EABEditor;
+typedef struct _EABEditorClass EABEditorClass;
+typedef struct _EABEditorPrivate EABEditorPrivate;
-typedef struct _EABEditor EABEditor;
-typedef struct _EABEditorClass EABEditorClass;
-
-struct _EABEditor
-{
+struct _EABEditor {
GObject parent;
+ EABEditorPrivate *priv;
};
-struct _EABEditorClass
-{
+struct _EABEditorClass {
GObjectClass parent_class;
/* virtual functions */
@@ -78,31 +78,35 @@ struct _EABEditorClass
void (* editor_closed) (EABEditor *editor);
};
-GType eab_editor_get_type (void);
+GType eab_editor_get_type (void);
+EShell * eab_editor_get_shell (EABEditor *editor);
+GSList * eab_editor_get_all_editors (void);
/* virtual functions */
-void eab_editor_show (EABEditor *editor);
-void eab_editor_close (EABEditor *editor);
-void eab_editor_raise (EABEditor *editor);
-void eab_editor_save_contact (EABEditor *editor, gboolean should_close);
-gboolean eab_editor_is_valid (EABEditor *editor);
-gboolean eab_editor_is_changed (EABEditor *editor);
-GtkWindow* eab_editor_get_window (EABEditor *editor);
-
-gboolean eab_editor_prompt_to_save_changes (EABEditor *editor, GtkWindow *window);
+void eab_editor_show (EABEditor *editor);
+void eab_editor_close (EABEditor *editor);
+void eab_editor_raise (EABEditor *editor);
+void eab_editor_save_contact (EABEditor *editor,
+ gboolean should_close);
+gboolean eab_editor_is_valid (EABEditor *editor);
+gboolean eab_editor_is_changed (EABEditor *editor);
+GtkWindow * eab_editor_get_window (EABEditor *editor);
+
+gboolean eab_editor_prompt_to_save_changes
+ (EABEditor *editor,
+ GtkWindow *window);
/* these four generate EABEditor signals */
-void eab_editor_contact_added (EABEditor *editor, EBookStatus status, EContact *contact);
-void eab_editor_contact_modified (EABEditor *editor, EBookStatus status, EContact *contact);
-void eab_editor_contact_deleted (EABEditor *editor, EBookStatus status, EContact *contact);
-void eab_editor_closed (EABEditor *editor);
-
-/* these maintain the global list of editors so we can prompt the user
- if there are unsaved changes when they exit. */
-void eab_editor_add (EABEditor *editor);
-void eab_editor_remove (EABEditor *editor);
-gboolean eab_editor_request_close_all (void);
-const GSList* eab_editor_get_all_editors (void);
+void eab_editor_contact_added (EABEditor *editor,
+ EBookStatus status,
+ EContact *contact);
+void eab_editor_contact_modified (EABEditor *editor,
+ EBookStatus status,
+ EContact *contact);
+void eab_editor_contact_deleted (EABEditor *editor,
+ EBookStatus status,
+ EContact *contact);
+void eab_editor_closed (EABEditor *editor);
G_END_DECLS
diff --git a/addressbook/gui/contact-list-editor/e-contact-list-editor.c b/addressbook/gui/contact-list-editor/e-contact-list-editor.c
index cc64cd5af3..77d91357c5 100644
--- a/addressbook/gui/contact-list-editor/e-contact-list-editor.c
+++ b/addressbook/gui/contact-list-editor/e-contact-list-editor.c
@@ -881,6 +881,36 @@ contact_list_editor_create_name_selector (gchar *name,
gint int1,
gint int2);
+static gpointer
+contact_editor_fudge_new (EBook *book,
+ EContact *contact,
+ gboolean is_new,
+ gboolean editable)
+{
+ EShell *shell = e_shell_get_default ();
+
+ /* XXX Putting this function signature in libedataserverui
+ * was a terrible idea. Now we're stuck with it. */
+
+ return e_contact_editor_new (
+ shell, book, contact, is_new, editable);
+}
+
+static gpointer
+contact_list_editor_fudge_new (EBook *book,
+ EContact *contact,
+ gboolean is_new,
+ gboolean editable)
+{
+ EShell *shell = e_shell_get_default ();
+
+ /* XXX Putting this function signature in libedataserverui
+ * was a terrible idea. Now we're stuck with it. */
+
+ return e_contact_list_editor_new (
+ shell, book, contact, is_new, editable);
+}
+
GtkWidget *
contact_list_editor_create_name_selector (gchar *name,
gchar *string1,
@@ -901,9 +931,9 @@ contact_list_editor_create_name_selector (gchar *name,
name_selector, "Members");
e_name_selector_entry_set_contact_editor_func (
- name_selector_entry, e_contact_editor_new);
+ name_selector_entry, contact_editor_fudge_new);
e_name_selector_entry_set_contact_list_editor_func (
- name_selector_entry, e_contact_list_editor_new);
+ name_selector_entry, contact_list_editor_fudge_new);
gtk_widget_show (GTK_WIDGET (name_selector_entry));
g_signal_connect (
@@ -1319,26 +1349,20 @@ e_contact_list_editor_get_type (void)
return type;
}
-static void
-contact_list_editor_destroy_notify (gpointer data,
- GObject *where_the_object_was)
-{
- eab_editor_remove (EAB_EDITOR (data));
-}
-
-GtkWidget *
-e_contact_list_editor_new (EBook *book,
- EContact *list_contact,
- gboolean is_new_list,
- gboolean editable)
+EABEditor *
+e_contact_list_editor_new (EShell *shell,
+ EBook *book,
+ EContact *list_contact,
+ gboolean is_new_list,
+ gboolean editable)
{
- EContactListEditor *editor;
+ EABEditor *editor;
- editor = g_object_new (E_TYPE_CONTACT_LIST_EDITOR, NULL);
+ g_return_val_if_fail (E_IS_SHELL (shell), NULL);
- eab_editor_add (EAB_EDITOR (editor));
- g_object_weak_ref (
- G_OBJECT (editor), contact_list_editor_destroy_notify, editor);
+ editor = g_object_new (
+ E_TYPE_CONTACT_LIST_EDITOR,
+ "shell", shell, NULL);
g_object_set (editor,
"book", book,
@@ -1347,7 +1371,7 @@ e_contact_list_editor_new (EBook *book,
"editable", editable,
NULL);
- return GTK_WIDGET (editor);
+ return editor;
}
EBook *
diff --git a/addressbook/gui/contact-list-editor/e-contact-list-editor.h b/addressbook/gui/contact-list-editor/e-contact-list-editor.h
index 5b67fe0126..8e258597aa 100644
--- a/addressbook/gui/contact-list-editor/e-contact-list-editor.h
+++ b/addressbook/gui/contact-list-editor/e-contact-list-editor.h
@@ -68,7 +68,8 @@ struct _EContactListEditorClass
};
GType e_contact_list_editor_get_type (void);
-GtkWidget * e_contact_list_editor_new (EBook *book,
+EABEditor * e_contact_list_editor_new (EShell *shell,
+ EBook *book,
EContact *list_contact,
gboolean is_new_list,
gboolean editable);
diff --git a/doc/reference/shell/tmpl/e-shell.sgml b/doc/reference/shell/tmpl/e-shell.sgml
index 42d93485df..1f8f3b0824 100644
--- a/doc/reference/shell/tmpl/e-shell.sgml
+++ b/doc/reference/shell/tmpl/e-shell.sgml
@@ -56,7 +56,7 @@ EShell
@eshell: the object which received the signal.
@arg1:
-<!-- ##### SIGNAL EShell::prepare-for-shutdown ##### -->
+<!-- ##### SIGNAL EShell::prepare-for-quit ##### -->
<para>
</para>
@@ -64,6 +64,13 @@ EShell
@eshell: the object which received the signal.
@arg1:
+<!-- ##### SIGNAL EShell::quit-requested ##### -->
+<para>
+
+</para>
+
+@eshell: the object which received the signal.
+
<!-- ##### SIGNAL EShell::send-receive ##### -->
<para>
diff --git a/doc/reference/shell/tmpl/eshell-unused.sgml b/doc/reference/shell/tmpl/eshell-unused.sgml
index 7d19de5082..58ddf1024e 100644
--- a/doc/reference/shell/tmpl/eshell-unused.sgml
+++ b/doc/reference/shell/tmpl/eshell-unused.sgml
@@ -457,6 +457,14 @@ intelligent
@minor:
@revision:
+<!-- ##### SIGNAL EShell::prepare-for-shutdown ##### -->
+<para>
+
+</para>
+
+@eshell: the object which received the signal.
+@arg1:
+
<!-- ##### ARG EShell:online-mode ##### -->
<para>
diff --git a/modules/addressbook/e-book-shell-backend.c b/modules/addressbook/e-book-shell-backend.c
index 53737b538e..9fe000aea8 100644
--- a/modules/addressbook/e-book-shell-backend.c
+++ b/modules/addressbook/e-book-shell-backend.c
@@ -226,30 +226,50 @@ book_shell_backend_init_importers (void)
}
static void
-book_shell_backend_book_loaded_cb (EBook *book,
+book_shell_backend_new_contact_cb (EBook *book,
EBookStatus status,
gpointer user_data)
{
+ EShell *shell;
EContact *contact;
- GtkAction *action;
- GtkWidget *editor;
- const gchar *action_name;
+ EABEditor *editor;
/* XXX Handle errors better. */
if (status != E_BOOK_ERROR_OK)
return;
contact = e_contact_new ();
- action = GTK_ACTION (user_data);
- action_name = gtk_action_get_name (action);
+ shell = E_SHELL (user_data);
- if (strcmp (action_name, "contact-new") == 0)
- editor = e_contact_editor_new (book, contact, TRUE, TRUE);
+ editor = e_contact_editor_new (
+ shell, book, contact, TRUE, TRUE);
+
+ eab_editor_show (editor);
+
+ g_object_unref (contact);
+ g_object_unref (book);
+}
+
+static void
+book_shell_backend_new_contact_list_cb (EBook *book,
+ EBookStatus status,
+ gpointer user_data)
+{
+ EShell *shell;
+ EContact *contact;
+ EABEditor *editor;
+
+ /* XXX Handle errors better. */
+ if (status != E_BOOK_ERROR_OK)
+ return;
+
+ contact = e_contact_new ();
+ shell = E_SHELL (user_data);
- if (strcmp (action_name, "contact-new-list") == 0)
- editor = e_contact_list_editor_new (book, contact, TRUE, TRUE);
+ editor = e_contact_list_editor_new (
+ shell, book, contact, TRUE, TRUE);
- eab_editor_show (EAB_EDITOR (editor));
+ eab_editor_show (editor);
g_object_unref (contact);
g_object_unref (book);
@@ -263,6 +283,7 @@ action_contact_new_cb (GtkAction *action,
EBook *book = NULL;
GConfClient *client;
ESourceList *source_list;
+ const gchar *action_name;
const gchar *key;
gchar *uid;
@@ -275,6 +296,7 @@ action_contact_new_cb (GtkAction *action,
shell = e_shell_window_get_shell (shell_window);
client = e_shell_get_gconf_client (shell);
+ action_name = gtk_action_get_name (action);
key = "/apps/evolution/addressbook/display/primary_addressbook";
uid = gconf_client_get_string (client, key, NULL);
@@ -291,8 +313,15 @@ action_contact_new_cb (GtkAction *action,
if (book == NULL)
book = e_book_new_default_addressbook (NULL);
- e_book_async_open (
- book, FALSE, book_shell_backend_book_loaded_cb, action);
+ if (strcmp (action_name, "contact-new") == 0)
+ e_book_async_open (
+ book, FALSE,
+ book_shell_backend_new_contact_cb, shell);
+
+ if (strcmp (action_name, "contact-list-new") == 0)
+ e_book_async_open (
+ book, FALSE,
+ book_shell_backend_new_contact_list_cb, shell);
}
static void
@@ -396,16 +425,6 @@ book_shell_backend_handle_uri_cb (EShellBackend *shell_backend,
}
static void
-book_shell_backend_prepare_for_shutdown_cb (EShellBackend *shell_backend,
- EActivity *activity)
-{
- /* FIXME Should specify whether Cancel is allowed. Currently,
- * clicking Cancel when prompted to save during shutdown
- * just discards changes. */
- eab_editor_request_close_all ();
-}
-
-static void
book_shell_backend_window_created_cb (EShellBackend *shell_backend,
GtkWindow *window)
{
@@ -486,11 +505,6 @@ book_shell_backend_constructed (GObject *object)
shell_backend);
g_signal_connect_swapped (
- shell, "prepare-for-shutdown",
- G_CALLBACK (book_shell_backend_prepare_for_shutdown_cb),
- shell_backend);
-
- g_signal_connect_swapped (
shell, "window-created",
G_CALLBACK (book_shell_backend_window_created_cb),
shell_backend);
diff --git a/modules/addressbook/e-book-shell-view-actions.c b/modules/addressbook/e-book-shell-view-actions.c
index 773eb3fa7a..9886e59dcd 100644
--- a/modules/addressbook/e-book-shell-view-actions.c
+++ b/modules/addressbook/e-book-shell-view-actions.c
@@ -332,6 +332,9 @@ static void
action_contact_new_cb (GtkAction *action,
EBookShellView *book_shell_view)
{
+ EShell *shell;
+ EShellView *shell_view;
+ EShellWindow *shell_window;
EBookShellContent *book_shell_content;
EAddressbookView *view;
EAddressbookModel *model;
@@ -339,6 +342,10 @@ action_contact_new_cb (GtkAction *action,
GtkWidget *editor;
EBook *book;
+ shell_view = E_SHELL_VIEW (book_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ shell = e_shell_window_get_shell (shell_window);
+
book_shell_content = book_shell_view->priv->book_shell_content;
view = e_book_shell_content_get_current_view (book_shell_content);
g_return_if_fail (view != NULL);
@@ -348,7 +355,7 @@ action_contact_new_cb (GtkAction *action,
g_return_if_fail (book != NULL);
contact = e_contact_new ();
- editor = e_contact_editor_new (book, contact, TRUE, TRUE);
+ editor = e_contact_editor_new (shell, book, contact, TRUE, TRUE);
eab_editor_show (EAB_EDITOR (editor));
g_object_unref (contact);
}
@@ -357,6 +364,9 @@ static void
action_contact_new_list_cb (GtkAction *action,
EBookShellView *book_shell_view)
{
+ EShell *shell;
+ EShellView *shell_view;
+ EShellWindow *shell_window;
EBookShellContent *book_shell_content;
EAddressbookView *view;
EAddressbookModel *model;
@@ -364,6 +374,10 @@ action_contact_new_list_cb (GtkAction *action,
GtkWidget *editor;
EBook *book;
+ shell_view = E_SHELL_VIEW (book_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ shell = e_shell_window_get_shell (shell_window);
+
book_shell_content = book_shell_view->priv->book_shell_content;
view = e_book_shell_content_get_current_view (book_shell_content);
g_return_if_fail (view != NULL);
@@ -373,7 +387,7 @@ action_contact_new_list_cb (GtkAction *action,
g_return_if_fail (book != NULL);
contact = e_contact_new ();
- editor = e_contact_list_editor_new (book, contact, TRUE, TRUE);
+ editor = e_contact_list_editor_new (shell, book, contact, TRUE, TRUE);
eab_editor_show (EAB_EDITOR (editor));
g_object_unref (contact);
}
diff --git a/modules/addressbook/e-book-shell-view-private.c b/modules/addressbook/e-book-shell-view-private.c
index ec3562e87a..95e4980c57 100644
--- a/modules/addressbook/e-book-shell-view-private.c
+++ b/modules/addressbook/e-book-shell-view-private.c
@@ -32,23 +32,30 @@ open_contact (EBookShellView *book_shell_view,
gboolean is_new_contact,
EAddressbookView *view)
{
+ EShell *shell;
+ EShellView *shell_view;
+ EShellWindow *shell_window;
EAddressbookModel *model;
- GtkWidget *editor;
+ EABEditor *editor;
EBook *book;
gboolean editable;
+ shell_view = E_SHELL_VIEW (book_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ shell = e_shell_window_get_shell (shell_window);
+
model = e_addressbook_view_get_model (view);
book = e_addressbook_model_get_book (model);
editable = e_addressbook_model_get_editable (model);
if (e_contact_get (contact, E_CONTACT_IS_LIST))
editor = e_contact_list_editor_new (
- book, contact, is_new_contact, editable);
+ shell, book, contact, is_new_contact, editable);
else
editor = e_contact_editor_new (
- book, contact, is_new_contact, editable);
+ shell, book, contact, is_new_contact, editable);
- eab_editor_show (EAB_EDITOR (editor));
+ eab_editor_show (editor);
}
static void
diff --git a/shell/e-shell-window.c b/shell/e-shell-window.c
index f22d30e1fd..c838235616 100644
--- a/shell/e-shell-window.c
+++ b/shell/e-shell-window.c
@@ -143,8 +143,7 @@ shell_window_set_shell (EShellWindow *shell_window,
shell_window->priv->shell = shell;
g_object_add_weak_pointer (
- G_OBJECT (shell_window),
- &shell_window->priv->shell);
+ G_OBJECT (shell), &shell_window->priv->shell);
/* Need to disconnect these when the window is closing. */
diff --git a/shell/e-shell.c b/shell/e-shell.c
index 15aed4303e..83fc6dc112 100644
--- a/shell/e-shell.c
+++ b/shell/e-shell.c
@@ -32,8 +32,6 @@
#include "e-shell-migrate.h"
#include "e-shell-window.h"
-#define SHUTDOWN_TIMEOUT 500 /* milliseconds */
-
#define E_SHELL_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
((obj), E_TYPE_SHELL, EShellPrivate))
@@ -50,11 +48,12 @@ struct _EShellPrivate {
GHashTable *backends_by_scheme;
gpointer preparing_for_line_change; /* weak pointer */
- gpointer preparing_for_shutdown; /* weak pointer */
+ gpointer preparing_for_quit; /* weak pointer */
guint auto_reconnect : 1;
guint network_available : 1;
guint online : 1;
+ guint quit_cancelled : 1;
guint safe_mode : 1;
};
@@ -70,7 +69,8 @@ enum {
HANDLE_URI,
PREPARE_FOR_OFFLINE,
PREPARE_FOR_ONLINE,
- PREPARE_FOR_SHUTDOWN,
+ PREPARE_FOR_QUIT,
+ QUIT_REQUESTED,
SEND_RECEIVE,
WINDOW_CREATED,
WINDOW_DESTROYED,
@@ -123,7 +123,7 @@ shell_window_delete_event_cb (EShell *shell,
if (g_list_length (shell->priv->watched_windows) > 1)
return FALSE;
- /* Otherwise we initiate application shutdown. */
+ /* Otherwise we initiate application quit. */
e_shell_quit (shell);
return TRUE;
@@ -276,9 +276,9 @@ shell_prepare_for_online (EShell *shell)
}
static void
-shell_ready_for_shutdown (EShell *shell,
- EActivity *activity,
- gboolean is_last_ref)
+shell_ready_for_quit (EShell *shell,
+ EActivity *activity,
+ gboolean is_last_ref)
{
GList *list;
@@ -293,12 +293,12 @@ shell_ready_for_shutdown (EShell *shell,
g_object_remove_toggle_ref (
G_OBJECT (activity), (GToggleNotify)
- shell_ready_for_shutdown, shell);
+ shell_ready_for_quit, shell);
/* Finalize the activity. */
g_object_ref (activity);
- g_message ("Shutdown preparations complete.");
+ g_message ("Quit preparations complete.");
/* Destroy all watched windows. Note, we iterate over a -copy-
* of the watched windows list because the act of destroying a
@@ -750,13 +750,13 @@ shell_class_init (EShellClass *class)
E_TYPE_ACTIVITY);
/**
- * EShell::prepare-for-shutdown
+ * EShell::prepare-for-quit
* @shell: the #EShell which emitted the signal
- * @activity: the #EActivity for shutdown preparations
+ * @activity: the #EActivity for quit preparations
*
- * Emitted when the user elects to quit the application. An
- * #EShellBackend should listen for this signal and make
- * preparations for shutting down.
+ * Emitted when the user elects to quit the application, after
+ * #EShell::quit-requested. An #EShellBackend should listen for
+ * this signal and make preparations for shutting down.
*
* If preparations for shutting down cannot immediately be completed
* (such as when there are uncompleted network operations), the
@@ -765,8 +765,8 @@ shell_class_init (EShellClass *class)
* delay Evolution from actually shutting down until all backends
* have unreferenced @activity.
**/
- signals[PREPARE_FOR_SHUTDOWN] = g_signal_new (
- "prepare-for-shutdown",
+ signals[PREPARE_FOR_QUIT] = g_signal_new (
+ "prepare-for-quit",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
0, NULL, NULL,
@@ -775,6 +775,27 @@ shell_class_init (EShellClass *class)
E_TYPE_ACTIVITY);
/**
+ * EShell::quit-requested
+ * @shell: the #EShell which emitted the signal
+ *
+ * Emitted when the user elects to quit the application, before
+ * #EShell::prepare-for-quit.
+ *
+ * #EShellBackend<!-- -->s and editor windows can listen for
+ * this signal to prompt the user to save changes or finish
+ * scheduled operations immediately (such as sending mail in
+ * Outbox). If the user elects to cancel, the signal handler
+ * should call e_shell_cancel_quit() to abort the quit.
+ **/
+ signals[QUIT_REQUESTED] = g_signal_new (
+ "quit-requested",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ /**
* EShell::send-receive
* @shell: the #EShell which emitted the signal
* @parent: a parent #GtkWindow
@@ -1433,30 +1454,57 @@ e_shell_quit (EShell *shell)
g_return_if_fail (E_IS_SHELL (shell));
/* Are preparations already in progress? */
- if (shell->priv->preparing_for_shutdown != NULL)
+ if (shell->priv->preparing_for_quit != NULL)
+ return;
+
+ /* First give backends a chance to cancel quit. */
+ shell->priv->quit_cancelled = FALSE;
+ g_signal_emit (shell, signals[QUIT_REQUESTED], 0);
+ if (shell->priv->quit_cancelled)
return;
- g_message ("Preparing for shutdown...");
+ g_message ("Preparing to quit...");
- shell->priv->preparing_for_shutdown =
- e_activity_new (_("Preparing to shut down..."));
+ shell->priv->preparing_for_quit =
+ e_activity_new (_("Preparing to quit..."));
g_object_add_toggle_ref (
- G_OBJECT (shell->priv->preparing_for_shutdown),
- (GToggleNotify) shell_ready_for_shutdown, shell);
+ G_OBJECT (shell->priv->preparing_for_quit),
+ (GToggleNotify) shell_ready_for_quit, shell);
g_object_add_weak_pointer (
- G_OBJECT (shell->priv->preparing_for_shutdown),
- &shell->priv->preparing_for_shutdown);
+ G_OBJECT (shell->priv->preparing_for_quit),
+ &shell->priv->preparing_for_quit);
g_signal_emit (
- shell, signals[PREPARE_FOR_SHUTDOWN], 0,
- shell->priv->preparing_for_shutdown);
+ shell, signals[PREPARE_FOR_QUIT], 0,
+ shell->priv->preparing_for_quit);
- g_object_unref (shell->priv->preparing_for_shutdown);
+ g_object_unref (shell->priv->preparing_for_quit);
/* Desensitize all watched windows to prevent user action. */
list = e_shell_get_watched_windows (shell);
for (iter = list; iter != NULL; iter = iter->next)
gtk_widget_set_sensitive (GTK_WIDGET (iter->data), FALSE);
}
+
+/**
+ * e_shell_cancel_quit:
+ * @shell: an #EShell
+ *
+ * This function may only be called from #EShell::quit-requested signal
+ * handlers to prevent Evolution from quitting. Calling this will stop
+ * further emission of the #EShell::quit-requested signal.
+ *
+ * Note: This function has no effect during a #EShell::prepare-for-quit
+ * signal emission.
+ **/
+void
+e_shell_cancel_quit (EShell *shell)
+{
+ g_return_if_fail (E_IS_SHELL (shell));
+
+ shell->priv->quit_cancelled = TRUE;
+
+ g_signal_stop_emission (shell, signals[QUIT_REQUESTED], 0);
+}
diff --git a/shell/e-shell.h b/shell/e-shell.h
index 3b414e641c..818607e1fb 100644
--- a/shell/e-shell.h
+++ b/shell/e-shell.h
@@ -105,6 +105,7 @@ void e_shell_event (EShell *shell,
const gchar *event_name,
gpointer event_data);
void e_shell_quit (EShell *shell);
+void e_shell_cancel_quit (EShell *shell);
G_END_DECLS