diff options
53 files changed, 1061 insertions, 786 deletions
diff --git a/Makefile.am b/Makefile.am index a5aa96fc79..18467ceb43 100644 --- a/Makefile.am +++ b/Makefile.am @@ -58,17 +58,18 @@ endif SUBDIRS = \ win32 \ - data \ - e-util \ + data \ + e-util \ a11y \ filter \ - widgets \ - shell \ + widgets \ + shell \ $(SMIME_DIR) \ composer \ addressbook \ calendar \ - art \ + mail \ + art \ plugins \ doc \ ui \ diff --git a/a11y/addressbook/ea-minicard-view.c b/a11y/addressbook/ea-minicard-view.c index 944060b91a..aed11ed2ac 100644 --- a/a11y/addressbook/ea-minicard-view.c +++ b/a11y/addressbook/ea-minicard-view.c @@ -362,11 +362,9 @@ static gboolean atk_action_interface_do_action (AtkAction *action, gint i) { gboolean return_value = TRUE; EMinicardView *card_view; - EContact *contact = e_contact_new(); AtkGObjectAccessible *atk_gobj= NULL; EReflow *reflow = NULL; - EBook *book; atk_gobj = ATK_GOBJECT_ACCESSIBLE (action); reflow = E_REFLOW (atk_gobject_accessible_get_object (atk_gobj)); @@ -375,26 +373,21 @@ static gboolean atk_action_interface_do_action (AtkAction *action, gint i) return FALSE; card_view = E_MINICARD_VIEW (reflow); - g_object_get(card_view, - "book", &book, - NULL); - g_return_val_if_fail (E_IS_BOOK (book), FALSE); switch (i) { case 0: /* New Contact */ - eab_show_contact_editor (book, contact, TRUE, TRUE); + e_minicard_view_create_contact (card_view); break; case 1: /* New Contact List */ - eab_show_contact_list_editor (book, contact, TRUE, TRUE); + e_minicard_view_create_contact_list (card_view); break; default: return_value = FALSE; break; } - g_object_unref (book); - g_object_unref (contact); + return return_value; } diff --git a/addressbook/gui/Makefile.am b/addressbook/gui/Makefile.am index a737452bd3..630744169e 100644 --- a/addressbook/gui/Makefile.am +++ b/addressbook/gui/Makefile.am @@ -1 +1 @@ -SUBDIRS = merging contact-editor contact-list-editor widgets component +SUBDIRS = merging widgets contact-editor contact-list-editor component diff --git a/addressbook/gui/component/Makefile.am b/addressbook/gui/component/Makefile.am index 9bfdabe13d..0e4747f2a5 100644 --- a/addressbook/gui/component/Makefile.am +++ b/addressbook/gui/component/Makefile.am @@ -30,8 +30,8 @@ libevolution_addressbook_la_SOURCES = \ addressbook-config.h \ autocompletion-config.c \ autocompletion-config.h \ - addressbook.c \ - addressbook.h \ + eab-composer-util.c \ + eab-composer-util.h \ e-book-shell-content.c \ e-book-shell-content.h \ e-book-shell-module.c \ @@ -53,6 +53,7 @@ endif libevolution_addressbook_la_LIBADD = \ $(SMIME_LIB) \ $(top_builddir)/e-util/libeutil.la \ + $(top_builddir)/composer/libcomposer.la \ $(top_builddir)/addressbook/printing/libecontactprint.la \ $(top_builddir)/shell/libeshell.la \ $(top_builddir)/addressbook/gui/merging/libeabbookmerging.la \ diff --git a/addressbook/gui/component/e-book-shell-content.c b/addressbook/gui/component/e-book-shell-content.c index 8190a5958a..c9066c9ef1 100644 --- a/addressbook/gui/component/e-book-shell-content.c +++ b/addressbook/gui/component/e-book-shell-content.c @@ -44,6 +44,16 @@ enum { static gpointer parent_class; static void +book_shell_content_send_message_cb (EBookShellContent *book_shell_content, + EDestination *destination, + EABContactDisplay *display) +{ + GList node = { destination, NULL, NULL }; + + eab_send_message (&node, EAB_DISPOSITION_AS_TO); +} + +static void book_shell_content_set_property (GObject *object, guint property_id, const GValue *value, @@ -176,6 +186,10 @@ book_shell_content_constructed (GObject *object) priv->preview = g_object_ref (widget); gtk_widget_show (widget); + g_signal_connect_swapped ( + priv->preview, "send-message", + book_shell_content_send_message_cb, object); + /* Bind GObject properties to GConf keys. */ bridge = gconf_bridge_get (); diff --git a/addressbook/gui/component/e-book-shell-content.h b/addressbook/gui/component/e-book-shell-content.h index 7f48503a88..e8fe856a86 100644 --- a/addressbook/gui/component/e-book-shell-content.h +++ b/addressbook/gui/component/e-book-shell-content.h @@ -24,10 +24,11 @@ #include <libebook/e-contact.h> -#include <e-shell-content.h> -#include <e-shell-view.h> +#include "shell/e-shell-content.h" +#include "shell/e-shell-view.h" -#include <e-addressbook-view.h> +#include "addressbook/gui/component/eab-composer-util.h" +#include "addressbook/gui/widgets/e-addressbook-view.h" /* Standard GObject macros */ #define E_TYPE_BOOK_SHELL_CONTENT \ diff --git a/addressbook/gui/component/e-book-shell-module.c b/addressbook/gui/component/e-book-shell-module.c index fbe660b7b6..a3f8a7aea0 100644 --- a/addressbook/gui/component/e-book-shell-module.c +++ b/addressbook/gui/component/e-book-shell-module.c @@ -32,10 +32,12 @@ #include "shell/e-shell-window.h" #include "e-util/e-import.h" +#include "addressbook/gui/widgets/eab-gui-util.h" +#include "addressbook/gui/contact-editor/e-contact-editor.h" +#include "addressbook/gui/contact-list-editor/e-contact-list-editor.h" #include "addressbook/importers/evolution-addressbook-importers.h" #include <eab-config.h> -#include <eab-gui-util.h> #include <addressbook-config.h> #include <autocompletion-config.h> @@ -214,6 +216,7 @@ book_shell_module_book_loaded_cb (EBook *book, { EContact *contact; GtkAction *action; + GtkWidget *editor; const gchar *action_name; /* XXX Handle errors better. */ @@ -225,10 +228,12 @@ book_shell_module_book_loaded_cb (EBook *book, action_name = gtk_action_get_name (action); if (strcmp (action_name, "contact-new") == 0) - eab_show_contact_editor (book, contact, TRUE, TRUE); + editor = e_contact_editor_new (book, contact, TRUE, TRUE); if (strcmp (action_name, "contact-new-list") == 0) - eab_show_contact_list_editor (book, contact, TRUE, TRUE); + editor = e_contact_list_editor_new (book, contact, TRUE, TRUE); + + eab_editor_show (EAB_EDITOR (editor)); g_object_unref (contact); g_object_unref (book); diff --git a/addressbook/gui/component/e-book-shell-view-actions.c b/addressbook/gui/component/e-book-shell-view-actions.c index 15838f96bc..646715d88a 100644 --- a/addressbook/gui/component/e-book-shell-view-actions.c +++ b/addressbook/gui/component/e-book-shell-view-actions.c @@ -285,12 +285,30 @@ action_contact_forward_cb (GtkAction *action, { EBookShellContent *book_shell_content; EAddressbookView *view; + GList *list, *iter; 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); - e_addressbook_view_send (view); + list = e_addressbook_view_get_selected (view); + g_return_if_fail (list != NULL); + + /* Convert the list of contacts to a list of destinations. */ + for (iter = list; iter != NULL; iter = iter->next) { + EContact *contact = iter->data; + EDestination *destination; + + destination = e_destination_new (); + e_destination_set_contact (destination, contact, 0); + g_object_unref (contact); + + iter->data = destination; + } + + eab_send_message (list, EAB_DISPOSITION_AS_ATTACHMENT); + g_list_foreach (list, (GFunc) g_object_unref, NULL); + g_list_free (list); } static void @@ -315,6 +333,7 @@ action_contact_new_cb (GtkAction *action, EAddressbookView *view; EAddressbookModel *model; EContact *contact; + GtkWidget *editor; EBook *book; book_shell_content = book_shell_view->priv->book_shell_content; @@ -326,7 +345,8 @@ action_contact_new_cb (GtkAction *action, g_return_if_fail (book != NULL); contact = e_contact_new (); - eab_show_contact_editor (book, contact, TRUE, TRUE); + editor = e_contact_editor_new (book, contact, TRUE, TRUE); + eab_editor_show (EAB_EDITOR (editor)); g_object_unref (contact); } @@ -338,6 +358,7 @@ action_contact_new_list_cb (GtkAction *action, EAddressbookView *view; EAddressbookModel *model; EContact *contact; + GtkWidget *editor; EBook *book; book_shell_content = book_shell_view->priv->book_shell_content; @@ -349,7 +370,8 @@ action_contact_new_list_cb (GtkAction *action, g_return_if_fail (book != NULL); contact = e_contact_new (); - eab_show_contact_list_editor (book, contact, TRUE, TRUE); + editor = e_contact_list_editor_new (book, contact, TRUE, TRUE); + eab_editor_show (EAB_EDITOR (editor)); g_object_unref (contact); } @@ -445,12 +467,30 @@ action_contact_send_message_cb (GtkAction *action, { EBookShellContent *book_shell_content; EAddressbookView *view; + GList *list, *iter; 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); - e_addressbook_view_send_to (view); + list = e_addressbook_view_get_selected (view); + g_return_if_fail (list != NULL); + + /* Convert the list of contacts to a list of destinations. */ + for (iter = list; iter != NULL; iter = iter->next) { + EContact *contact = iter->data; + EDestination *destination; + + destination = e_destination_new (); + e_destination_set_contact (destination, contact, 0); + g_object_unref (contact); + + iter->data = destination; + } + + eab_send_message (list, EAB_DISPOSITION_AS_TO); + g_list_foreach (list, (GFunc) g_object_unref, NULL); + g_list_free (list); } static void diff --git a/addressbook/gui/component/e-book-shell-view-private.c b/addressbook/gui/component/e-book-shell-view-private.c index c3eecb5a8a..90ebad94f8 100644 --- a/addressbook/gui/component/e-book-shell-view-private.c +++ b/addressbook/gui/component/e-book-shell-view-private.c @@ -27,6 +27,31 @@ #include <addressbook.h> static void +open_contact (EBookShellView *book_shell_view, + EContact *contact, + gboolean is_new_contact, + EAddressbookView *view) +{ + EAddressbookModel *model; + GtkWidget *editor; + EBook *book; + gboolean editable; + + 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); + else + editor = e_contact_editor_new ( + book, contact, is_new_contact, editable); + + eab_editor_show (EAB_EDITOR (editor)); +} + +static void popup_event (EBookShellView *book_shell_view, GdkEventButton *event) { @@ -215,6 +240,10 @@ book_shell_view_activate_selected_source (EBookShellView *book_shell_view, g_object_ref (widget)); g_signal_connect_swapped ( + widget, "open-contact", + G_CALLBACK (open_contact), book_shell_view); + + g_signal_connect_swapped ( widget, "popup-event", G_CALLBACK (popup_event), book_shell_view); diff --git a/addressbook/gui/component/e-book-shell-view-private.h b/addressbook/gui/component/e-book-shell-view-private.h index 0d7fd706f6..d53ced9440 100644 --- a/addressbook/gui/component/e-book-shell-view-private.h +++ b/addressbook/gui/component/e-book-shell-view-private.h @@ -32,15 +32,17 @@ #include <libedataserver/e-sexp.h> #include <libedataserverui/e-source-selector.h> -#include <e-util/gconf-bridge.h> -#include <shell/e-shell-content.h> -#include <shell/e-shell-sidebar.h> +#include "e-util/gconf-bridge.h" +#include "shell/e-shell-content.h" +#include "shell/e-shell-sidebar.h" + +#include "addressbook/gui/contact-editor/e-contact-editor.h" +#include "addressbook/gui/contact-list-editor/e-contact-list-editor.h" +#include "addressbook/gui/widgets/eab-gui-util.h" +#include "addressbook/gui/widgets/e-addressbook-view.h" -#include <eab-gui-util.h> -#include <e-addressbook-view.h> #include <e-book-shell-content.h> #include <e-book-shell-sidebar.h> - #include <e-book-shell-view-actions.h> #define E_BOOK_SHELL_VIEW_GET_PRIVATE(obj) \ diff --git a/addressbook/gui/component/eab-composer-util.c b/addressbook/gui/component/eab-composer-util.c new file mode 100644 index 0000000000..ce3a96cc13 --- /dev/null +++ b/addressbook/gui/component/eab-composer-util.c @@ -0,0 +1,214 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "eab-composer-util.h" + +#include <glib/gi18n.h> +#include <libebook/e-contact.h> +#include <libebook/e-destination.h> + +#include "mail/em-composer-utils.h" +#include "composer/e-msg-composer.h" +#include "addressbook/util/eab-book-util.h" +#include "addressbook/gui/widgets/eab-gui-util.h" + +static void +eab_send_as_to (GList *destinations) +{ + EMsgComposer *composer; + EComposerHeaderTable *table; + GPtrArray *to_array; + GPtrArray *bcc_array; + + union { + gpointer *pdata; + EDestination **destinations; + } convert; + + if (destinations == NULL) + return; + + composer = e_msg_composer_new (); + table = e_msg_composer_get_header_table (composer); + em_composer_utils_setup_default_callbacks (composer); + + to_array = g_ptr_array_new (); + bcc_array = g_ptr_array_new (); + + /* Sort contacts into "To" and "Bcc" destinations. */ + while (destinations != NULL) { + EDestination *destination = destinations->data; + + if (e_destination_is_evolution_list (destination)) { + if (e_destination_list_show_addresses (destination)) + g_ptr_array_add (to_array, destination); + else + g_ptr_array_add (bcc_array, destination); + } else + g_ptr_array_add (to_array, destination); + + destinations = g_list_next (destinations); + } + + /* Add sentinels to each array. */ + g_ptr_array_add (to_array, NULL); + g_ptr_array_add (bcc_array, NULL); + + /* XXX Acrobatics like this make me question whether NULL-terminated + * arrays are really the best argument type for passing a list of + * destinations to the header table. */ + + /* Add "To" destinations. */ + convert.pdata = to_array->pdata; + e_composer_header_table_set_destinations_to ( + table, convert.destinations); + g_ptr_array_free (to_array, FALSE); + e_destination_freev (convert.destinations); + + /* Add "Bcc" destinations. */ + convert.pdata = bcc_array->pdata; + e_composer_header_table_set_destinations_bcc ( + table, convert.destinations); + g_ptr_array_free (bcc_array, FALSE); + e_destination_freev (convert.destinations); + + gtk_widget_show (GTK_WIDGET (composer)); +} + +static const char * +get_email (EContact *contact, EContactField field_id, gchar **to_free) +{ + char *name = NULL, *mail = NULL; + const char *value = e_contact_get_const (contact, field_id); + + *to_free = NULL; + + if (eab_parse_qp_email (value, &name, &mail)) { + *to_free = g_strdup_printf ("%s <%s>", name, mail); + value = *to_free; + } + + g_free (name); + g_free (mail); + + return value; +} + +static void +eab_send_as_attachment (GList *destinations) +{ + EMsgComposer *composer; + EComposerHeaderTable *table; + CamelMimePart *attachment; + GList *contacts, *iter; + gchar *data; + + if (contacts == NULL) + return; + + composer = e_msg_composer_new (); + table = e_msg_composer_get_header_table (composer); + em_composer_utils_setup_default_callbacks (composer); + + attachment = camel_mime_part_new (); + + contacts = g_list_copy (destinations); + for (iter = contacts; iter != NULL; iter = iter->next) + iter->data = e_destination_get_contact (iter->data); + data = eab_contact_list_to_string (contacts); + g_list_free (contacts); + + camel_mime_part_set_content ( + attachment, data, strlen (data), "text/x-vcard"); + + if (destinations->next != NULL) + camel_mime_part_set_description ( + attachment, _("Multiple vCards")); + else { + EContact *contact; + const gchar *file_as; + gchar *description; + + contact = e_destination_get_contact (destinations->data); + file_as = e_contact_get_const (contact, E_CONTACT_FILE_AS); + description = g_strdup_printf (_("vCard for %s"), file_as); + camel_mime_part_set_description (attachment, description); + g_free (description); + } + + camel_mime_part_set_disposition (attachment, "attachment"); + + e_msg_composer_attach (composer, attachment); + camel_object_unref (attachment); + + if (destinations->next != NULL) + e_composer_header_table_set_subject ( + table, _("Contact information")); + else { + EContact *contact; + gchar *tempstr; + const gchar *tempstr2; + gchar *tempfree = NULL; + + contact = e_destination_get_contact (destinations->data); + tempstr2 = e_contact_get_const (contact, E_CONTACT_FILE_AS); + if (!tempstr2 || !*tempstr2) + tempstr2 = e_contact_get_const (contact, E_CONTACT_FULL_NAME); + if (!tempstr2 || !*tempstr2) + tempstr2 = e_contact_get_const (contact, E_CONTACT_ORG); + if (!tempstr2 || !*tempstr2) { + g_free (tempfree); + tempstr2 = get_email (contact, E_CONTACT_EMAIL_1, &tempfree); + } + if (!tempstr2 || !*tempstr2) { + g_free (tempfree); + tempstr2 = get_email (contact, E_CONTACT_EMAIL_2, &tempfree); + } + if (!tempstr2 || !*tempstr2) { + g_free (tempfree); + tempstr2 = get_email (contact, E_CONTACT_EMAIL_3, &tempfree); + } + + if (!tempstr2 || !*tempstr2) + tempstr = g_strdup_printf (_("Contact information")); + else + tempstr = g_strdup_printf (_("Contact information for %s"), tempstr2); + + e_composer_header_table_set_subject (table, tempstr); + + g_free (tempstr); + g_free (tempfree); + } + + gtk_widget_show (GTK_WIDGET (composer)); +} + +void +eab_send_message (GList *destinations, + EABDisposition disposition) +{ + switch (disposition) { + case EAB_DISPOSITION_AS_TO: + eab_send_as_to (destinations); + break; + + case EAB_DISPOSITION_AS_ATTACHMENT: + eab_send_as_attachment (destinations); + break; + } +} diff --git a/addressbook/gui/component/eab-composer-util.h b/addressbook/gui/component/eab-composer-util.h new file mode 100644 index 0000000000..4e9ce581d0 --- /dev/null +++ b/addressbook/gui/component/eab-composer-util.h @@ -0,0 +1,36 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef EAB_COMPOSER_UTIL_H +#define EAB_COMPOSER_UTIL_H + +#include <gtk/gtk.h> + +G_BEGIN_DECLS + +typedef enum { + EAB_DISPOSITION_AS_ATTACHMENT, + EAB_DISPOSITION_AS_TO, +} EABDisposition; + +void eab_send_message (GList *destinations, + EABDisposition disposition); + +G_END_DECLS + +#endif /* EAB_COMPOSER_UTIL_H */ diff --git a/addressbook/gui/contact-editor/Makefile.am b/addressbook/gui/contact-editor/Makefile.am index bed73df00b..f813db72e8 100644 --- a/addressbook/gui/contact-editor/Makefile.am +++ b/addressbook/gui/contact-editor/Makefile.am @@ -33,10 +33,14 @@ libecontacteditor_la_SOURCES = \ libecontacteditor_la_LDFLAGS = $(NO_UNDEFINED) -libecontacteditor_la_LIBADD = \ - $(WIN32_BOOTSTRAP_LIBS) \ - $(top_builddir)/widgets/misc/libemiscwidgets.la \ - $(top_builddir)/e-util/libeutil.la \ +libecontacteditor_la_LIBADD = \ + $(WIN32_BOOTSTRAP_LIBS) \ + $(top_builddir)/e-util/libeutil.la \ + $(top_builddir)/widgets/misc/libemiscwidgets.la \ + $(top_builddir)/addressbook/util/libeabutil.la \ + $(top_builddir)/addressbook/gui/widgets/libeabwidgets.la \ + $(top_builddir)/addressbook/gui/merging/libeabbookmerging.la \ + $(top_builddir)/addressbook/printing/libecontactprint.la \ $(EVOLUTION_ADDRESSBOOK_LIBS) glade_DATA = \ diff --git a/addressbook/gui/contact-editor/e-contact-editor.c b/addressbook/gui/contact-editor/e-contact-editor.c index 07d4a9ec0f..30d672161a 100644 --- a/addressbook/gui/contact-editor/e-contact-editor.c +++ b/addressbook/gui/contact-editor/e-contact-editor.c @@ -40,7 +40,7 @@ #include <camel/camel.h> -#include "addressbook/gui/component/addressbook.h" +#include "addressbook/util/addressbook.h" #include "addressbook/printing/e-contact-print.h" #include "addressbook/gui/widgets/eab-gui-util.h" #include "e-util/e-util.h" @@ -199,6 +199,54 @@ static const gint email_default [] = { 0, 1, 2, 2 }; #define STRING_IS_EMPTY(x) (!(x) || !(*(x))) #define STRING_MAKE_NON_NULL(x) ((x) ? (x) : "") +static void +e_contact_editor_contact_added (EABEditor *editor, + EBookStatus status, + EContact *contact) +{ + if (status == E_BOOK_ERROR_OK) + return; + + if (status == E_BOOK_ERROR_CANCELLED) + return; + + eab_error_dialog (_("Error adding contact"), status); +} + +static void +e_contact_editor_contact_modified (EABEditor *editor, + EBookStatus status, + EContact *contact) +{ + if (status == E_BOOK_ERROR_OK) + return; + + if (status == E_BOOK_ERROR_CANCELLED) + return; + + eab_error_dialog (_("Error modifying contact"), status); +} + +static void +e_contact_editor_contact_deleted (EABEditor *editor, + EBookStatus status, + EContact *contact) +{ + if (status == E_BOOK_ERROR_OK) + return; + + if (status == E_BOOK_ERROR_CANCELLED) + return; + + eab_error_dialog (_("Error removing contact"), status); +} + +static void +e_contact_editor_closed (EABEditor *editor) +{ + g_object_unref (editor); +} + GType e_contact_editor_get_type (void) { @@ -242,6 +290,10 @@ e_contact_editor_class_init (EContactEditorClass *klass) editor_class->save_contact = e_contact_editor_save_contact; editor_class->is_changed = e_contact_editor_is_changed; editor_class->get_window = e_contact_editor_get_window; + editor_class->contact_added = e_contact_editor_contact_added; + editor_class->contact_modified = e_contact_editor_contact_modified; + editor_class->contact_deleted = e_contact_editor_contact_deleted; + editor_class->editor_closed = e_contact_editor_closed; g_object_class_install_property (object_class, PROP_SOURCE_BOOK, g_param_spec_object ("source_book", @@ -3470,7 +3522,7 @@ contact_editor_destroy_notify (void *data, eab_editor_remove (EAB_EDITOR (data)); } -EContactEditor * +GtkWidget * e_contact_editor_new (EBook *book, EContact *contact, gboolean is_new_contact, @@ -3496,7 +3548,7 @@ e_contact_editor_new (EBook *book, if (book) e_book_async_get_supported_fields (book, (EBookEListCallback)supported_fields_cb, ce); - return ce; + return GTK_WIDGET (ce); } static void diff --git a/addressbook/gui/contact-editor/e-contact-editor.h b/addressbook/gui/contact-editor/e-contact-editor.h index 7fd94698c8..d4af1495c2 100644 --- a/addressbook/gui/contact-editor/e-contact-editor.h +++ b/addressbook/gui/contact-editor/e-contact-editor.h @@ -109,11 +109,11 @@ struct _EContactEditorClass EABEditorClass parent_class; }; -EContactEditor *e_contact_editor_new (EBook *book, - EContact *contact, - gboolean is_new_contact, - gboolean editable); -GType e_contact_editor_get_type (void); +GType e_contact_editor_get_type (void); +GtkWidget *e_contact_editor_new (EBook *book, + EContact *contact, + gboolean is_new_contact, + gboolean editable); G_END_DECLS diff --git a/addressbook/gui/contact-editor/e-contact-quick-add.c b/addressbook/gui/contact-editor/e-contact-quick-add.c index 175af68d43..6de903d16f 100644 --- a/addressbook/gui/contact-editor/e-contact-quick-add.c +++ b/addressbook/gui/contact-editor/e-contact-quick-add.c @@ -29,7 +29,7 @@ #include <libebook/e-book.h> #include <libebook/e-contact.h> #include <libedataserverui/e-source-combo-box.h> -#include <addressbook/gui/component/addressbook.h> +#include <addressbook/util/addressbook.h> #include <addressbook/util/eab-book-util.h> #include "e-contact-editor.h" #include "e-contact-quick-add.h" @@ -195,7 +195,7 @@ ce_have_book (EBook *book, EBookStatus status, gpointer closure) g_warning ("Couldn't open local address book."); quick_add_unref (qa); } else { - EContactEditor *contact_editor = e_contact_editor_new (book, qa->contact, TRUE, TRUE /* XXX */); + GtkWidget *contact_editor = e_contact_editor_new (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 25a6e5d3e5..d45fb688ea 100644 --- a/addressbook/gui/contact-editor/eab-editor.c +++ b/addressbook/gui/contact-editor/eab-editor.c @@ -310,51 +310,6 @@ eab_editor_get_all_editors (void) return all_editors; } -gboolean -eab_editor_confirm_delete (GtkWindow *parent, gboolean plural, gboolean is_list, char *name) -{ - GtkWidget *dialog; - gint result; - char *msg; - - if (is_list) { - /* contact list(s) */ - if (!plural) - msg = g_strdup_printf (_("Are you sure you want\nto delete contact list (%s)?"), - name?name:""); - else - msg = g_strdup (_("Are you sure you want\nto delete these contact lists?")); - } - else { - /* contact(s) */ - if (!plural) - msg = g_strdup_printf (_("Are you sure you want\nto delete contact (%s)?"), - name?name:""); - else - msg = g_strdup (_("Are you sure you want\nto delete these contacts?")); - } - - dialog = gtk_message_dialog_new (parent, - 0, - GTK_MESSAGE_QUESTION, - GTK_BUTTONS_NONE, - "%s", - msg); - g_free (msg); - - gtk_dialog_add_buttons (GTK_DIALOG (dialog), - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_DELETE, GTK_RESPONSE_ACCEPT, - NULL); - - result = gtk_dialog_run(GTK_DIALOG (dialog)); - - gtk_widget_destroy (dialog); - - return (result == GTK_RESPONSE_ACCEPT); -} - - void eab_editor_contact_added (EABEditor *editor, EBookStatus status, EContact *contact) { diff --git a/addressbook/gui/contact-editor/eab-editor.h b/addressbook/gui/contact-editor/eab-editor.h index c106ec75a6..cc95e003e1 100644 --- a/addressbook/gui/contact-editor/eab-editor.h +++ b/addressbook/gui/contact-editor/eab-editor.h @@ -92,7 +92,6 @@ 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); -gboolean eab_editor_confirm_delete (GtkWindow *parent, gboolean plural, gboolean is_list, char *name); /* these four generate EABEditor signals */ void eab_editor_contact_added (EABEditor *editor, EBookStatus status, EContact *contact); 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 7f15ff1350..ccaf9b740f 100644 --- a/addressbook/gui/contact-list-editor/e-contact-list-editor.c +++ b/addressbook/gui/contact-list-editor/e-contact-list-editor.c @@ -34,8 +34,8 @@ #include <libedataserverui/e-source-combo-box.h> -#include "addressbook/gui/component/addressbook.h" #include "addressbook/gui/widgets/eab-gui-util.h" +#include "addressbook/util/addressbook.h" #include "addressbook/util/eab-book-util.h" #include "eab-editor.h" @@ -922,87 +922,6 @@ contact_list_editor_create_name_selector (gchar *name, return GTK_WIDGET (name_selector_entry); } -/**************************** EABEditor Callbacks ****************************/ - -static void -contact_list_editor_show (EABEditor *editor) -{ - gtk_widget_show (WIDGET (DIALOG)); -} - -static void -contact_list_editor_close (EABEditor *editor) -{ - gtk_widget_destroy (WIDGET (DIALOG)); - eab_editor_closed (editor); -} - -static void -contact_list_editor_raise (EABEditor *editor) -{ - gdk_window_raise (WIDGET (DIALOG)->window); -} - -static void -contact_list_editor_save_contact (EABEditor *eab_editor, - gboolean should_close) -{ - EContactListEditor *editor = E_CONTACT_LIST_EDITOR (eab_editor); - EContactListEditorPrivate *priv = editor->priv; - EditorCloseStruct *ecs; - EContact *contact; - - contact = e_contact_list_editor_get_contact (editor); - - if (priv->book == NULL) - return; - - ecs = g_new (EditorCloseStruct, 1); - ecs->editor = g_object_ref (editor); - ecs->should_close = should_close; - - gtk_widget_set_sensitive (WIDGET (DIALOG), FALSE); - priv->in_async_call = TRUE; - - if (priv->is_new_list) - eab_merging_book_add_contact ( - priv->book, contact, (EBookIdCallback) - contact_list_editor_list_added_cb, ecs); - else - eab_merging_book_commit_contact ( - priv->book, contact, (EBookCallback) - contact_list_editor_list_modified_cb, ecs); - - priv->changed = FALSE; -} - -static gboolean -contact_list_editor_is_valid (EABEditor *editor) -{ - GtkEditable *editable; - gboolean valid; - gchar *chars; - - editable = GTK_EDITABLE (WIDGET (LIST_NAME_ENTRY)); - chars = gtk_editable_get_chars (editable, 0, -1); - valid = (chars != NULL && *chars != '\0'); - g_free (chars); - - return valid; -} - -static gboolean -contact_list_editor_is_changed (EABEditor *editor) -{ - return E_CONTACT_LIST_EDITOR_GET_PRIVATE (editor)->changed; -} - -static GtkWindow* -contact_list_editor_get_window (EABEditor *editor) -{ - return GTK_WINDOW (WIDGET (DIALOG)); -} - /***************************** GObject Callbacks *****************************/ static GObject * @@ -1112,6 +1031,135 @@ contact_list_editor_dispose (GObject *object) G_OBJECT_CLASS (parent_class)->dispose (object); } +/**************************** EABEditor Callbacks ****************************/ + +static void +contact_list_editor_show (EABEditor *editor) +{ + gtk_widget_show (WIDGET (DIALOG)); +} + +static void +contact_list_editor_close (EABEditor *editor) +{ + gtk_widget_destroy (WIDGET (DIALOG)); + eab_editor_closed (editor); +} + +static void +contact_list_editor_raise (EABEditor *editor) +{ + gdk_window_raise (WIDGET (DIALOG)->window); +} + +static void +contact_list_editor_save_contact (EABEditor *eab_editor, + gboolean should_close) +{ + EContactListEditor *editor = E_CONTACT_LIST_EDITOR (eab_editor); + EContactListEditorPrivate *priv = editor->priv; + EditorCloseStruct *ecs; + EContact *contact; + + contact = e_contact_list_editor_get_contact (editor); + + if (priv->book == NULL) + return; + + ecs = g_new (EditorCloseStruct, 1); + ecs->editor = g_object_ref (editor); + ecs->should_close = should_close; + + gtk_widget_set_sensitive (WIDGET (DIALOG), FALSE); + priv->in_async_call = TRUE; + + if (priv->is_new_list) + eab_merging_book_add_contact ( + priv->book, contact, (EBookIdCallback) + contact_list_editor_list_added_cb, ecs); + else + eab_merging_book_commit_contact ( + priv->book, contact, (EBookCallback) + contact_list_editor_list_modified_cb, ecs); + + priv->changed = FALSE; +} + +static gboolean +contact_list_editor_is_valid (EABEditor *editor) +{ + GtkEditable *editable; + gboolean valid; + gchar *chars; + + editable = GTK_EDITABLE (WIDGET (LIST_NAME_ENTRY)); + chars = gtk_editable_get_chars (editable, 0, -1); + valid = (chars != NULL && *chars != '\0'); + g_free (chars); + + return valid; +} + +static gboolean +contact_list_editor_is_changed (EABEditor *editor) +{ + return E_CONTACT_LIST_EDITOR_GET_PRIVATE (editor)->changed; +} + +static GtkWindow * +contact_list_editor_get_window (EABEditor *editor) +{ + return GTK_WINDOW (WIDGET (DIALOG)); +} + +static void +contact_list_editor_contact_added (EABEditor *editor, + EBookStatus status, + EContact *contact) +{ + if (status == E_BOOK_ERROR_OK) + return; + + if (status == E_BOOK_ERROR_CANCELLED) + return; + + eab_error_dialog (_("Error adding list"), status); +} + +static void +contact_list_editor_contact_modified (EABEditor *editor, + EBookStatus status, + EContact *contact) +{ + if (status == E_BOOK_ERROR_OK) + return; + + if (status == E_BOOK_ERROR_CANCELLED) + return; + + eab_error_dialog (_("Error modifying list"), status); +} + +static void +contact_list_editor_contact_deleted (EABEditor *editor, + EBookStatus status, + EContact *contact) +{ + if (status == E_BOOK_ERROR_OK) + return; + + if (status == E_BOOK_ERROR_CANCELLED) + return; + + eab_error_dialog (_("Error removing list"), status); +} + +static void +contact_list_editor_closed (EABEditor *editor) +{ + g_object_unref (editor); +} + /****************************** GType Callbacks ******************************/ static void @@ -1137,6 +1185,10 @@ contact_list_editor_class_init (EContactListEditorClass *class) editor_class->is_valid = contact_list_editor_is_valid; editor_class->is_changed = contact_list_editor_is_changed; editor_class->get_window = contact_list_editor_get_window; + editor_class->contact_added = contact_list_editor_contact_added; + editor_class->contact_modified = contact_list_editor_contact_modified; + editor_class->contact_deleted = contact_list_editor_contact_deleted; + editor_class->editor_closed = contact_list_editor_closed; g_object_class_install_property ( object_class, @@ -1274,7 +1326,7 @@ contact_list_editor_destroy_notify (gpointer data, eab_editor_remove (EAB_EDITOR (data)); } -EContactListEditor * +GtkWidget * e_contact_list_editor_new (EBook *book, EContact *list_contact, gboolean is_new_list, @@ -1295,7 +1347,7 @@ e_contact_list_editor_new (EBook *book, "editable", editable, NULL); - return editor; + return GTK_WIDGET (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 a2bd50acf5..2c420fcbd2 100644 --- a/addressbook/gui/contact-list-editor/e-contact-list-editor.h +++ b/addressbook/gui/contact-list-editor/e-contact-list-editor.h @@ -70,7 +70,7 @@ struct _EContactListEditorClass }; GType e_contact_list_editor_get_type (void); -EContactListEditor * e_contact_list_editor_new (EBook *book, +GtkWidget * e_contact_list_editor_new (EBook *book, EContact *list_contact, gboolean is_new_list, gboolean editable); diff --git a/addressbook/gui/merging/eab-contact-compare.c b/addressbook/gui/merging/eab-contact-compare.c index adc6938c8d..b5597abb29 100644 --- a/addressbook/gui/merging/eab-contact-compare.c +++ b/addressbook/gui/merging/eab-contact-compare.c @@ -24,8 +24,8 @@ #include <config.h> #include <ctype.h> #include <string.h> -#include "util/eab-book-util.h" -#include "../component/addressbook.h" +#include "addressbook/util/addressbook.h" +#include "addressbook/util/eab-book-util.h" #include "eab-contact-compare.h" /* This is an "optimistic" combiner: the best of the two outcomes is diff --git a/addressbook/gui/widgets/Makefile.am b/addressbook/gui/widgets/Makefile.am index c06328c2aa..b5afef0374 100644 --- a/addressbook/gui/widgets/Makefile.am +++ b/addressbook/gui/widgets/Makefile.am @@ -10,9 +10,7 @@ INCLUDES = \ -I$(top_srcdir)/filter \ -I$(top_srcdir)/widgets \ -I$(top_srcdir)/addressbook \ - -I$(top_srcdir)/addressbook/gui/contact-editor \ -I$(top_srcdir)/addressbook/gui/merging \ - -I$(top_srcdir)/addressbook/gui/component \ -I$(top_srcdir)/addressbook/util \ -I$(top_srcdir)/widgets/misc \ -I$(top_builddir)/shell \ @@ -56,8 +54,8 @@ libeabwidgets_la_SOURCES = \ gal-view-factory-minicard.h libeabwidgets_la_LIBADD = \ - $(top_builddir)/composer/libcomposer.la \ - $(top_builddir)/widgets/misc/libemiscwidgets.la + $(top_builddir)/widgets/misc/libemiscwidgets.la \ + $(top_builddir)/a11y/addressbook/libevolution-addressbook-a11y.la CLEANFILES = $(BUILT_SOURCES) diff --git a/addressbook/gui/widgets/e-addressbook-reflow-adapter.c b/addressbook/gui/widgets/e-addressbook-reflow-adapter.c index d344641c8f..2a2f1a2d87 100644 --- a/addressbook/gui/widgets/e-addressbook-reflow-adapter.c +++ b/addressbook/gui/widgets/e-addressbook-reflow-adapter.c @@ -54,10 +54,11 @@ enum { enum { DRAG_BEGIN, + OPEN_CONTACT, LAST_SIGNAL }; -static guint e_addressbook_reflow_adapter_signals [LAST_SIGNAL] = {0, }; +static guint signals [LAST_SIGNAL] = {0, }; static void unlink_model(EAddressbookReflowAdapter *adapter) @@ -227,12 +228,20 @@ adapter_drag_begin (EMinicard *card, GdkEvent *event, EAddressbookReflowAdapter gint ret_val = 0; g_signal_emit (adapter, - e_addressbook_reflow_adapter_signals[DRAG_BEGIN], 0, + signals[DRAG_BEGIN], 0, event, &ret_val); return ret_val; } +static void +adapter_open_contact (EMinicard *card, + EContact *contact, + EAddressbookReflowAdapter *adapter) +{ + g_signal_emit (adapter, signals[OPEN_CONTACT], 0, contact); +} + static GnomeCanvasItem * addressbook_incarnate (EReflowModel *erm, int i, GnomeCanvasGroup *parent) { @@ -252,7 +261,10 @@ addressbook_incarnate (EReflowModel *erm, int i, GnomeCanvasGroup *parent) #endif g_signal_connect (item, "drag_begin", - G_CALLBACK(adapter_drag_begin), adapter); + G_CALLBACK (adapter_drag_begin), adapter); + + g_signal_connect (item, "open-contact", + G_CALLBACK (adapter_open_contact), adapter); return item; } @@ -427,7 +439,7 @@ e_addressbook_reflow_adapter_class_init (GObjectClass *object_class) E_TYPE_ADDRESSBOOK_MODEL, G_PARAM_READABLE)); - e_addressbook_reflow_adapter_signals [DRAG_BEGIN] = + signals [DRAG_BEGIN] = g_signal_new ("drag_begin", G_OBJECT_CLASS_TYPE(object_class), G_SIGNAL_RUN_LAST, @@ -436,6 +448,16 @@ e_addressbook_reflow_adapter_class_init (GObjectClass *object_class) e_marshal_INT__POINTER, G_TYPE_INT, 1, G_TYPE_POINTER); + signals [OPEN_CONTACT] = + g_signal_new ("open-contact", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EAddressbookReflowAdapterClass, open_contact), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + E_TYPE_CONTACT); + model_class->set_width = addressbook_set_width; model_class->count = addressbook_count; model_class->height = addressbook_height; diff --git a/addressbook/gui/widgets/e-addressbook-reflow-adapter.h b/addressbook/gui/widgets/e-addressbook-reflow-adapter.h index 99925d2dce..5032f3e2d0 100644 --- a/addressbook/gui/widgets/e-addressbook-reflow-adapter.h +++ b/addressbook/gui/widgets/e-addressbook-reflow-adapter.h @@ -48,7 +48,10 @@ struct _EAddressbookReflowAdapterClass { /* * Signals */ - gint (* drag_begin) (EAddressbookReflowAdapter *adapter, GdkEvent *event); + gint (*drag_begin) (EAddressbookReflowAdapter *adapter, + GdkEvent *event); + void (*open_contact) (EAddressbookReflowAdapter *adapter, + EContact *contact); }; diff --git a/addressbook/gui/widgets/e-addressbook-view.c b/addressbook/gui/widgets/e-addressbook-view.c index 1120ae2569..f7c506ee78 100644 --- a/addressbook/gui/widgets/e-addressbook-view.c +++ b/addressbook/gui/widgets/e-addressbook-view.c @@ -53,7 +53,6 @@ #include "e-util/e-error.h" #include "e-util/e-util-private.h" -#include "e-contact-editor.h" #include <gdk/gdkkeysyms.h> #include <ctype.h> #include <string.h> @@ -69,7 +68,6 @@ static void search_result (EAddressbookView *view, EBookViewStatus status); static void folder_bar_message (EAddressbookView *view, const gchar *status); static void stop_state_changed (GtkObject *object, EAddressbookView *view); static void backend_died (EAddressbookView *view); -static GList *get_selected_contacts (EAddressbookView *view); static void command_state_change (EAddressbookView *view); @@ -98,6 +96,7 @@ enum { }; enum { + OPEN_CONTACT, POPUP_EVENT, COMMAND_STATE_CHANGE, SELECTION_CHANGE, @@ -119,6 +118,14 @@ static guint signals[LAST_SIGNAL]; static GdkAtom clipboard_atom = GDK_NONE; static void +addressbook_view_emit_open_contact (EAddressbookView *view, + EContact *contact, + gboolean is_new_contact) +{ + g_signal_emit (view, signals[OPEN_CONTACT], 0, contact, is_new_contact); +} + +static void addressbook_view_emit_popup_event (EAddressbookView *view, GdkEvent *event) { @@ -132,6 +139,34 @@ addressbook_view_emit_selection_change (EAddressbookView *view) } static void +addressbook_view_open_contact (EAddressbookView *view, + EContact *contact) +{ + addressbook_view_emit_open_contact (view, contact, FALSE); +} + +static void +addressbook_view_create_contact (EAddressbookView *view) +{ + EContact *contact; + + contact = e_contact_new (); + addressbook_view_emit_open_contact (view, contact, TRUE); + g_object_unref (contact); +} + +static void +addressbook_view_create_contact_list (EAddressbookView *view) +{ + EContact *contact; + + contact = e_contact_new (); + e_contact_set (contact, E_CONTACT_IS_LIST, GINT_TO_POINTER (TRUE)); + addressbook_view_emit_open_contact (view, contact, TRUE); + g_object_unref (contact); +} + +static void table_double_click (ETableScrolled *table, gint row, gint col, @@ -140,23 +175,13 @@ table_double_click (ETableScrolled *table, { EAddressbookModel *model; EContact *contact; - EBook *book; - gboolean editable; if (!E_IS_ADDRESSBOOK_TABLE_ADAPTER (view->priv->object)) return; - model = view->priv->model; + model = e_addressbook_view_get_model (view); contact = e_addressbook_model_get_contact (model, row); - editable = e_addressbook_model_get_editable (model); - book = e_addressbook_model_get_book (model); - g_return_if_fail (E_IS_BOOK (book)); - - if (e_contact_get (contact, E_CONTACT_IS_LIST)) - eab_show_contact_list_editor (book, contact, FALSE, editable); - else - eab_show_contact_editor (book, contact, FALSE, editable); - + addressbook_view_emit_open_contact (view, contact, FALSE); g_object_unref (contact); } @@ -209,7 +234,7 @@ table_drag_data_get (ETable *table, model = e_addressbook_view_get_model (view); book = e_addressbook_model_get_book (model); - contact_list = get_selected_contacts (view); + contact_list = e_addressbook_view_get_selected (view); switch (info) { case DND_TARGET_TYPE_VCARD: @@ -300,6 +325,18 @@ addressbook_view_create_minicard_view (EAddressbookView *view) minicard_view = e_minicard_view_widget_new (adapter); g_signal_connect_swapped ( + adapter, "open-contact", + G_CALLBACK (addressbook_view_open_contact), view); + + g_signal_connect_swapped ( + minicard_view, "create-contact", + G_CALLBACK (addressbook_view_create_contact), view); + + g_signal_connect_swapped ( + minicard_view, "create-contact-list", + G_CALLBACK (addressbook_view_create_contact_list), view); + + g_signal_connect_swapped ( minicard_view, "selection_change", G_CALLBACK (addressbook_view_emit_selection_change), view); @@ -644,6 +681,16 @@ addressbook_view_class_init (EAddressbookViewClass *class) G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + signals[OPEN_CONTACT] = g_signal_new ( + "open-contact", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EAddressbookViewClass, open_contact), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + E_TYPE_CONTACT); + signals[POPUP_EVENT] = g_signal_new ( "popup-event", G_TYPE_FROM_CLASS (class), @@ -801,6 +848,34 @@ e_addressbook_view_get_view_widget (EAddressbookView *view) return view->priv->widget; } +/* Helper for e_addressbook_view_get_selected() */ +static void +add_to_list (gint model_row, gpointer closure) +{ + GList **list = closure; + *list = g_list_prepend (*list, GINT_TO_POINTER (model_row)); +} + +GList * +e_addressbook_view_get_selected (EAddressbookView *view) +{ + GList *list, *iter; + ESelectionModel *selection; + + g_return_val_if_fail (E_IS_ADDRESSBOOK_VIEW (view), NULL); + + list = NULL; + selection = e_addressbook_view_get_selection_model (view); + e_selection_model_foreach (selection, add_to_list, &list); + + for (iter = list; iter != NULL; iter = iter->next) + iter->data = e_addressbook_model_get_contact ( + view->priv->model, GPOINTER_TO_INT (iter->data)); + list = g_list_reverse (list); + + return list; +} + ESelectionModel * e_addressbook_view_get_selection_model (EAddressbookView *view) { @@ -1011,7 +1086,7 @@ e_addressbook_view_print (EAddressbookView *view, query = NULL; g_free (query_string); - contact_list = get_selected_contacts (view); + contact_list = e_addressbook_view_get_selected (view); e_contact_print (book, query, contact_list, action); g_list_foreach (contact_list, (GFunc) g_object_unref, NULL); g_list_free (contact_list); @@ -1054,6 +1129,62 @@ delete_contacts_cb (EBook *book, EBookStatus status, gpointer closure) } } +static gboolean +addressbook_view_confirm_delete (GtkWindow *parent, + gboolean plural, + gboolean is_list, + const gchar *name) +{ + GtkWidget *dialog; + gchar *message; + gint response; + + if (is_list) { + if (plural) { + message = g_strdup ( + _("Are you sure you want to " + "delete these contact lists?")); + } else if (name == NULL) { + message = g_strdup ( + _("Are you sure you want to " + "delete this contact list?")); + } else { + message = g_strdup_printf ( + _("Are you sure you want to delete " + "this contact list (%s)?"), name); + } + } else { + if (plural) { + message = g_strdup ( + _("Are you sure you want to " + "delete these contacts?")); + } else if (name == NULL) { + message = g_strdup ( + _("Are you sure you want to " + "delete this contact?")); + } else { + message = g_strdup_printf ( + _("Are you sure you want to delete " + "this contact (%s)?"), name); + } + } + + dialog = gtk_message_dialog_new ( + parent, 0, GTK_MESSAGE_QUESTION, + GTK_BUTTONS_NONE, "%s", message); + gtk_dialog_add_buttons ( + GTK_DIALOG (dialog), + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_DELETE, GTK_RESPONSE_ACCEPT, + NULL); + response = gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + + g_free (message); + + return (response == GTK_RESPONSE_ACCEPT); +} + void e_addressbook_view_delete_selection(EAddressbookView *view, gboolean is_delete) { @@ -1076,7 +1207,7 @@ e_addressbook_view_delete_selection(EAddressbookView *view, gboolean is_delete) view_instance = e_addressbook_view_get_view_instance (view); gal_view = gal_view_instance_get_current_view (view_instance); - list = get_selected_contacts (view); + list = e_addressbook_view_get_selected (view); contact = list->data; if (g_list_next(list)) @@ -1100,9 +1231,9 @@ e_addressbook_view_delete_selection(EAddressbookView *view, gboolean is_delete) } /* confirm delete */ - if (is_delete && - !eab_editor_confirm_delete(GTK_WINDOW(gtk_widget_get_toplevel(view->priv->widget)), - plural, is_list, name)) { + if (is_delete && !addressbook_view_confirm_delete ( + GTK_WINDOW (gtk_widget_get_toplevel ( + view->priv->widget)), plural, is_list, name)) { g_free (name); g_list_foreach (list, (GFunc) g_object_unref, NULL); g_list_free (list); @@ -1168,30 +1299,6 @@ e_addressbook_view_delete_selection(EAddressbookView *view, gboolean is_delete) g_list_free (list); } -static void -add_to_list (int model_row, gpointer closure) -{ - GList **list = closure; - *list = g_list_prepend (*list, GINT_TO_POINTER (model_row)); -} - -static GList * -get_selected_contacts (EAddressbookView *view) -{ - GList *list; - GList *iterator; - ESelectionModel *selection = e_addressbook_view_get_selection_model (view); - - list = NULL; - e_selection_model_foreach (selection, add_to_list, &list); - - for (iterator = list; iterator; iterator = iterator->next) { - iterator->data = e_addressbook_model_get_contact (view->priv->model, GPOINTER_TO_INT (iterator->data)); - } - list = g_list_reverse (list); - return list; -} - void e_addressbook_view_save_as (EAddressbookView *view, gboolean all) @@ -1210,7 +1317,7 @@ e_addressbook_view_save_as (EAddressbookView *view, e_book_get_contacts (book, query, &list, NULL); e_book_query_unref (query); } else - list = get_selected_contacts (view); + list = e_addressbook_view_get_selected (view); if (list != NULL) { eab_contact_list_save (_("Save as vCard..."), list, NULL); @@ -1224,8 +1331,10 @@ e_addressbook_view_view (EAddressbookView *view) { EAddressbookModel *model; EBook *book; - GList *list; + GList *list, *iter; gboolean editable; + gint response; + guint length; g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view)); @@ -1233,42 +1342,36 @@ e_addressbook_view_view (EAddressbookView *view) book = e_addressbook_model_get_book (model); editable = e_addressbook_model_get_editable (model); - list = get_selected_contacts (view); - eab_show_multiple_contacts (book, list, editable); - g_list_foreach (list, (GFunc) g_object_unref, NULL); - g_list_free (list); -} - -void -e_addressbook_view_send (EAddressbookView *view) -{ - GList *list; - - g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view)); - - list = get_selected_contacts (view); - - if (list != NULL) { - eab_send_contact_list (list, EAB_DISPOSITION_AS_ATTACHMENT); - g_list_foreach (list, (GFunc) g_object_unref, NULL); - g_list_free (list); + list = e_addressbook_view_get_selected (view); + length = g_list_length (list); + response = GTK_RESPONSE_YES; + + if (length > 5) { + GtkWidget *dialog; + + /* XXX Use e_error_new(). */ + /* XXX Provide a parent window. */ + dialog = gtk_message_dialog_new ( + NULL, 0, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, + _("Opening %d contacts will open %d new windows as " + "well.\nDo you really want to display all of these " + "contacts?"), length, length); + gtk_dialog_add_buttons ( + GTK_DIALOG (dialog), + _("_Don't Display"), GTK_RESPONSE_NO, + _("Display _All Contacts"), GTK_RESPONSE_YES, + NULL); + response = gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); } -} - -void -e_addressbook_view_send_to (EAddressbookView *view) -{ - GList *list; - - g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view)); - list = get_selected_contacts (view); + if (response == GTK_RESPONSE_YES) + for (iter = list; iter != NULL; iter = iter->next) + addressbook_view_emit_open_contact ( + view, iter->data, FALSE); - if (list != NULL) { - eab_send_contact_list (list, EAB_DISPOSITION_AS_TO); - g_list_foreach (list, (GFunc) g_object_unref, NULL); - g_list_free (list); - } + g_list_foreach (list, (GFunc) g_object_unref, NULL); + g_list_free (list); } void @@ -1285,7 +1388,7 @@ e_addressbook_view_copy (EAddressbookView *view) { g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view)); - view->priv->clipboard_contacts = get_selected_contacts (view); + view->priv->clipboard_contacts = e_addressbook_view_get_selected (view); gtk_selection_owner_set ( view->priv->invisible, @@ -1346,7 +1449,7 @@ view_transfer_contacts (EAddressbookView *view, gboolean delete_from_source, gbo e_book_query_unref(query); } else { - contacts = get_selected_contacts (view); + contacts = e_addressbook_view_get_selected (view); } parent_window = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (view))); diff --git a/addressbook/gui/widgets/e-addressbook-view.h b/addressbook/gui/widgets/e-addressbook-view.h index 009222fd71..4e4e7c8178 100644 --- a/addressbook/gui/widgets/e-addressbook-view.h +++ b/addressbook/gui/widgets/e-addressbook-view.h @@ -25,6 +25,7 @@ #include <e-shell-view.h> #include <libebook/e-book.h> +#include <libebook/e-contact.h> #include <widgets/menus/gal-view-instance.h> #include <widgets/misc/e-selection-model.h> @@ -65,6 +66,9 @@ struct _EAddressbookViewClass { GtkVBoxClass parent_class; /* Signals */ + void (*open_contact) (EAddressbookView *view, + EContact *contact, + gboolean is_new_contact); void (*popup_event) (EAddressbookView *view, GdkEvent *event); void (*status_message) (EAddressbookView *view, @@ -85,6 +89,7 @@ GObject * e_addressbook_view_get_view_object (EAddressbookView *view); GtkWidget * e_addressbook_view_get_view_widget (EAddressbookView *view); +GList * e_addressbook_view_get_selected (EAddressbookView *view); ESelectionModel * e_addressbook_view_get_selection_model (EAddressbookView *view); @@ -94,8 +99,6 @@ ESource * e_addressbook_view_get_source (EAddressbookView *view); void e_addressbook_view_save_as (EAddressbookView *view, gboolean all); void e_addressbook_view_view (EAddressbookView *view); -void e_addressbook_view_send (EAddressbookView *view); -void e_addressbook_view_send_to (EAddressbookView *view); void e_addressbook_view_print (EAddressbookView *view, GtkPrintOperationAction action); void e_addressbook_view_delete_selection diff --git a/addressbook/gui/widgets/e-minicard-view-widget.c b/addressbook/gui/widgets/e-minicard-view-widget.c index 0f9ae7c143..3ad49cf2b3 100644 --- a/addressbook/gui/widgets/e-minicard-view-widget.c +++ b/addressbook/gui/widgets/e-minicard-view-widget.c @@ -53,6 +53,8 @@ enum { }; enum { + CREATE_CONTACT, + CREATE_CONTACT_LIST, SELECTION_CHANGE, COLUMN_WIDTH_CHANGED, RIGHT_CLICK, @@ -140,6 +142,24 @@ e_minicard_view_widget_class_init (EMinicardViewWidgetClass *class) 0.0, G_MAXDOUBLE, 150.0, G_PARAM_READWRITE)); + signals [CREATE_CONTACT] = + g_signal_new ("create-contact", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EMinicardViewWidgetClass, create_contact), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals [CREATE_CONTACT_LIST] = + g_signal_new ("create-contact-list", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EMinicardViewWidgetClass, create_contact_list), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + signals [SELECTION_CHANGE] = g_signal_new ("selection_change", G_OBJECT_CLASS_TYPE (object_class), @@ -315,6 +335,18 @@ column_width_changed (ESelectionModel *esm, double width, EMinicardViewWidget *w signals [COLUMN_WIDTH_CHANGED], 0, width); } +static void +create_contact (EMinicardView *view, EMinicardViewWidget *widget) +{ + g_signal_emit (widget, signals[CREATE_CONTACT], 0); +} + +static void +create_contact_list (EMinicardView *view, EMinicardViewWidget *widget) +{ + g_signal_emit (widget, signals[CREATE_CONTACT_LIST], 0); +} + static guint right_click (EMinicardView *view, GdkEvent *event, EMinicardViewWidget *widget) { @@ -370,6 +402,12 @@ e_minicard_view_widget_realize (GtkWidget *widget) "column_width_changed", G_CALLBACK (column_width_changed), view); g_signal_connect (view->emv, + "create-contact", + G_CALLBACK (create_contact), view); + g_signal_connect (view->emv, + "create-contact-list", + G_CALLBACK (create_contact_list), view); + g_signal_connect (view->emv, "right_click", G_CALLBACK (right_click), view); diff --git a/addressbook/gui/widgets/e-minicard-view-widget.h b/addressbook/gui/widgets/e-minicard-view-widget.h index 1c4323523f..917d1b588a 100644 --- a/addressbook/gui/widgets/e-minicard-view-widget.h +++ b/addressbook/gui/widgets/e-minicard-view-widget.h @@ -58,6 +58,8 @@ struct _EMinicardViewWidget struct _EMinicardViewWidgetClass { ECanvasClass parent_class; + void (*create_contact) (EMinicardViewWidget *emvw); + void (*create_contact_list) (EMinicardViewWidget *emvw); void (*selection_change) (EMinicardViewWidget *emvw); void (*column_width_changed) (EMinicardViewWidget *emvw, double width); guint (*right_click) (EMinicardViewWidget *emvw); diff --git a/addressbook/gui/widgets/e-minicard-view.c b/addressbook/gui/widgets/e-minicard-view.c index 37ffc8844d..cca2a54a3c 100644 --- a/addressbook/gui/widgets/e-minicard-view.c +++ b/addressbook/gui/widgets/e-minicard-view.c @@ -56,6 +56,8 @@ enum { enum { + CREATE_CONTACT, + CREATE_CONTACT_LIST, RIGHT_CLICK, LAST_SIGNAL }; @@ -383,13 +385,8 @@ e_minicard_view_event (GnomeCanvasItem *item, GdkEvent *event) g_object_get(view->adapter, "editable", &editable, NULL); - if (editable) { - EBook *book; - g_object_get(view, "book", &book, NULL); - - if (book && E_IS_BOOK (book)) - eab_show_contact_editor (book, e_contact_new(), TRUE, editable); - } + if (editable) + e_minicard_view_create_contact (view); return TRUE; } case GDK_BUTTON_PRESS: @@ -547,6 +544,22 @@ e_minicard_view_class_init (EMinicardViewClass *klass) FALSE, G_PARAM_READWRITE)); + signals [CREATE_CONTACT] = + g_signal_new ("create-contact", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + 0, NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals [CREATE_CONTACT_LIST] = + g_signal_new ("create-contact-list", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + 0, NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + signals [RIGHT_CLICK] = g_signal_new ("right_click", G_OBJECT_CLASS_TYPE (object_class), @@ -655,3 +668,19 @@ e_minicard_view_get_card_list (EMinicardView *view) mal.list = g_list_reverse (mal.list); return mal.list; } + +void +e_minicard_view_create_contact (EMinicardView *view) +{ + g_return_if_fail (E_IS_MINICARD_VIEW (view)); + + g_signal_emit (view, signals[CREATE_CONTACT], 0); +} + +void +e_minicard_view_create_contact_list (EMinicardView *view) +{ + g_return_if_fail (E_IS_MINICARD_VIEW (view)); + + g_signal_emit (view, signals[CREATE_CONTACT_LIST], 0); +} diff --git a/addressbook/gui/widgets/e-minicard-view.h b/addressbook/gui/widgets/e-minicard-view.h index 7d0a5b1842..4cdf9be7be 100644 --- a/addressbook/gui/widgets/e-minicard-view.h +++ b/addressbook/gui/widgets/e-minicard-view.h @@ -91,6 +91,8 @@ void e_minicard_view_remove_selection (EMinicardView *view, void e_minicard_view_jump_to_letter (EMinicardView *view, gunichar letter); GList *e_minicard_view_get_card_list (EMinicardView *view); +void e_minicard_view_create_contact (EMinicardView *view); +void e_minicard_view_create_contact_list (EMinicardView *view); G_END_DECLS diff --git a/addressbook/gui/widgets/e-minicard.c b/addressbook/gui/widgets/e-minicard.c index cbbcc80d5c..3e5e8ec3bf 100644 --- a/addressbook/gui/widgets/e-minicard.c +++ b/addressbook/gui/widgets/e-minicard.c @@ -35,7 +35,6 @@ #include "e-minicard.h" #include "e-minicard-label.h" #include "e-minicard-view.h" -#include "e-contact-editor.h" #include <e-util/e-html-utils.h> #include <e-util/e-icon-factory.h> #include <libebook/e-destination.h> @@ -86,6 +85,7 @@ enum { enum { SELECTED, DRAG_BEGIN, + OPEN_CONTACT, STYLE_SET, LAST_SIGNAL }; @@ -101,7 +101,7 @@ common_location [] = { "OTHER", N_ ("Other Email") } }; -static guint e_minicard_signals [LAST_SIGNAL] = {0, }; +static guint signals [LAST_SIGNAL] = {0, }; GType e_minicard_get_type (void) @@ -200,7 +200,7 @@ e_minicard_class_init (EMinicardClass *class) E_TYPE_CONTACT, G_PARAM_READWRITE)); - e_minicard_signals [SELECTED] = + signals [SELECTED] = g_signal_new ("selected", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, @@ -209,7 +209,7 @@ e_minicard_class_init (EMinicardClass *class) e_marshal_INT__POINTER, G_TYPE_INT, 1, G_TYPE_POINTER); - e_minicard_signals [DRAG_BEGIN] = + signals [DRAG_BEGIN] = g_signal_new ("drag_begin", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, @@ -218,7 +218,17 @@ e_minicard_class_init (EMinicardClass *class) e_marshal_INT__POINTER, G_TYPE_INT, 1, G_TYPE_POINTER); - e_minicard_signals [STYLE_SET] = + signals [OPEN_CONTACT] = + g_signal_new ("open-contact", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EMinicardClass, open_contact), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + E_TYPE_CONTACT); + + signals [STYLE_SET] = g_signal_new ("style_set", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_FIRST, @@ -249,8 +259,6 @@ e_minicard_init (EMinicard *minicard) minicard->list_icon_pixbuf = e_icon_factory_get_icon (LIST_ICON_NAME, E_ICON_SIZE_MENU); minicard->list_icon_size = gdk_pixbuf_get_height (minicard->list_icon_pixbuf); - minicard->editor = NULL; - minicard->changed = FALSE; e_canvas_item_set_reflow_callback(GNOME_CANVAS_ITEM(minicard), e_minicard_reflow); @@ -528,50 +536,12 @@ e_minicard_unrealize (GnomeCanvasItem *item) (* GNOME_CANVAS_ITEM_CLASS(parent_class)->unrealize) (item); } -/* Callback used when the contact editor is closed */ -static void -editor_closed_cb (GtkObject *editor, gpointer data) -{ - EMinicard *minicard = data; - g_object_unref (editor); - minicard->editor = NULL; -} - -gboolean -e_minicard_activate_editor(EMinicard *minicard) +void +e_minicard_activate_editor (EMinicard *minicard) { - GnomeCanvasItem *item = (GnomeCanvasItem *)minicard; - - if (minicard->editor) { - eab_editor_raise (minicard->editor); - } - else { - EBook *book = NULL; - if (E_IS_MINICARD_VIEW(item->parent)) { - g_object_get(item->parent, "book", &book, NULL); - } - - if (book != NULL) { - if (e_contact_get (minicard->contact, E_CONTACT_IS_LIST)) { - EContactListEditor *editor = eab_show_contact_list_editor (book, minicard->contact, - FALSE, e_book_is_writable (book)); - minicard->editor = EAB_EDITOR (editor); - } - else { - EContactEditor *editor = eab_show_contact_editor (book, minicard->contact, - FALSE, e_book_is_writable (book)); - minicard->editor = EAB_EDITOR (editor); - } - - g_object_ref (minicard->editor); - g_signal_connect (minicard->editor, "editor_closed", - G_CALLBACK (editor_closed_cb), minicard); - - g_object_unref (book); - } - } + g_return_if_fail (E_IS_MINICARD (minicard)); - return TRUE; + g_signal_emit (minicard, signals[OPEN_CONTACT], 0, minicard->contact); } static gboolean @@ -655,7 +625,8 @@ e_minicard_event (GnomeCanvasItem *item, GdkEvent *event) break; case GDK_2BUTTON_PRESS: if (event->button.button == 1 && E_IS_MINICARD_VIEW (item->parent)) { - return e_minicard_activate_editor (e_minicard); + e_minicard_activate_editor (e_minicard); + return TRUE; } break; case GDK_KEY_PRESS: @@ -725,7 +696,8 @@ e_minicard_event (GnomeCanvasItem *item, GdkEvent *event) } else if (event->key.keyval == GDK_Return || event->key.keyval == GDK_KP_Enter) { - return e_minicard_activate_editor (e_minicard); + e_minicard_activate_editor (e_minicard); + return TRUE; } break; default: @@ -1154,7 +1126,7 @@ e_minicard_drag_begin (EMinicard *minicard, GdkEvent *event) gint ret_val = 0; GnomeCanvasItem *parent; g_signal_emit (minicard, - e_minicard_signals[DRAG_BEGIN], 0, + signals[DRAG_BEGIN], 0, event, &ret_val); parent = GNOME_CANVAS_ITEM (minicard)->parent; diff --git a/addressbook/gui/widgets/e-minicard.h b/addressbook/gui/widgets/e-minicard.h index 71c976745f..98a4629ad9 100644 --- a/addressbook/gui/widgets/e-minicard.h +++ b/addressbook/gui/widgets/e-minicard.h @@ -24,7 +24,6 @@ #define __E_MINICARD_H__ #include <gtk/gtk.h> -#include "addressbook/gui/contact-editor/eab-editor.h" #include <libgnomecanvas/gnome-canvas.h> #include <libebook/e-contact.h> @@ -75,8 +74,6 @@ struct _EMinicard GdkPixbuf *list_icon_pixbuf; double list_icon_size; - EABEditor *editor; - GList *fields; /* Of type EMinicardField */ guint needs_remodeling : 1; @@ -105,6 +102,7 @@ struct _EMinicardClass gint (* selected) (EMinicard *minicard, GdkEvent *event); gint (* drag_begin) (EMinicard *minicard, GdkEvent *event); + void (* open_contact) (EMinicard *minicard, EContact *contact); void (* style_set) (EMinicard *minicard, GtkStyle *previous_style); }; @@ -125,7 +123,7 @@ int e_minicard_compare (EMinicard *minicard1, int e_minicard_selected (EMinicard *minicard, GdkEvent *event); -gboolean e_minicard_activate_editor (EMinicard *minicard); +void e_minicard_activate_editor (EMinicard *minicard); #ifdef __cplusplus } diff --git a/addressbook/gui/widgets/eab-contact-display.c b/addressbook/gui/widgets/eab-contact-display.c index 1cbe322a96..1d22f3ea70 100644 --- a/addressbook/gui/widgets/eab-contact-display.c +++ b/addressbook/gui/widgets/eab-contact-display.c @@ -62,6 +62,11 @@ enum { PROP_MODE }; +enum { + SEND_MESSAGE, + LAST_SIGNAL +}; + static struct { gchar *name; gchar *pretty_name; @@ -101,6 +106,7 @@ static const gchar *ui = "</ui>"; static gpointer parent_class; +static guint signals[LAST_SIGNAL]; static void action_copy_address_cb (GtkAction *action, @@ -169,6 +175,7 @@ static void action_send_message_cb (GtkAction *action, EABContactDisplay *display) { + EDestination *destination; EContact *contact; const gchar *uri; gint row; @@ -177,8 +184,11 @@ action_send_message_cb (GtkAction *action, row = atoi (uri + strlen ("internal-mailto:")); g_return_if_fail (row >= 0); + destination = e_destination_new (); contact = eab_contact_display_get_contact (display); - eab_send_contact (contact, row, EAB_DISPOSITION_AS_TO); + e_destination_set_contact (destination, contact, row); + g_signal_emit (display, signals[SEND_MESSAGE], 0, destination); + g_object_unref (destination); } static GtkActionEntry email_entries[] = { @@ -283,12 +293,19 @@ contact_display_on_link_clicked (GtkHTML *html, #ifdef HANDLE_MAILTO_INTERNALLY if (!strncmp (url, "internal-mailto:", strlen ("internal-mailto:"))) { - int mail_num = atoi (url + strlen ("internal-mailto:")); + EDestination *destination; + EContact *contact; + gint email_num; - if (mail_num == -1) + email_num = atoi (url + strlen ("internal-mailto:")); + if (email_num == -1) return; - eab_send_contact (display->priv->contact, mail_num, EAB_DISPOSITION_AS_TO); + destination = e_destination_new (); + contact = eab_contact_display_get_contact (display); + e_destination_set_contact (destination, contact, email_num); + g_signal_emit (display, signals[SEND_MESSAGE], 0, destination); + g_object_unref (destination); return; } @@ -1067,6 +1084,16 @@ eab_contact_display_class_init (EABContactDisplayClass *class) EAB_CONTACT_DISPLAY_RENDER_COMPACT, EAB_CONTACT_DISPLAY_RENDER_NORMAL, G_PARAM_READWRITE)); + + signals[SEND_MESSAGE] = g_signal_new ( + "send-message", + G_OBJECT_CLASS_TYPE (class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (EABContactDisplayClass, send_message), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + E_TYPE_DESTINATION); } static void diff --git a/addressbook/gui/widgets/eab-contact-display.h b/addressbook/gui/widgets/eab-contact-display.h index 803a23d79f..096a910f2f 100644 --- a/addressbook/gui/widgets/eab-contact-display.h +++ b/addressbook/gui/widgets/eab-contact-display.h @@ -25,6 +25,7 @@ #include <gtkhtml/gtkhtml.h> #include <libebook/e-contact.h> +#include <libebook/e-destination.h> /* Standard GObject macros */ #define EAB_TYPE_CONTACT_DISPLAY \ @@ -63,6 +64,10 @@ struct _EABContactDisplay { struct _EABContactDisplayClass { GtkHTMLClass parent_class; + + /* Signals */ + void (*send_message) (EABContactDisplay *display, + EDestination *destination); }; GType eab_contact_display_get_type (void); diff --git a/addressbook/gui/widgets/eab-gui-util.c b/addressbook/gui/widgets/eab-gui-util.c index 3ba848ecc8..d3c0910827 100644 --- a/addressbook/gui/widgets/eab-gui-util.c +++ b/addressbook/gui/widgets/eab-gui-util.c @@ -40,16 +40,11 @@ #include "misc/e-image-chooser.h" #include <e-util/e-icon-factory.h> #include "eab-contact-merging.h" -#include <composer/e-msg-composer.h> -#include <mail/em-composer-utils.h> /* we link to camel for decoding quoted printable email addresses */ #include <camel/camel-mime-utils.h> -#include "addressbook/gui/contact-editor/eab-editor.h" -#include "addressbook/gui/contact-editor/e-contact-editor.h" -#include "addressbook/gui/contact-list-editor/e-contact-list-editor.h" -#include "addressbook/gui/component/addressbook.h" +#include "addressbook/util/addressbook.h" /* the NULL's in this table correspond to the status codes that should *never* be generated by a backend */ @@ -201,140 +196,6 @@ eab_prompt_save_dialog (GtkWindow *parent) return e_error_run (parent, "addressbook:prompt-save", NULL); } -static void -added_cb (EBook* book, EBookStatus status, EContact *contact, - gpointer data) -{ - gboolean is_list = GPOINTER_TO_INT (data); - - if (status != E_BOOK_ERROR_OK && status != E_BOOK_ERROR_CANCELLED) { - eab_error_dialog (is_list ? _("Error adding list") : _("Error adding contact"), status); - } -} - -static void -modified_cb (EBook* book, EBookStatus status, EContact *contact, - gpointer data) -{ - gboolean is_list = GPOINTER_TO_INT (data); - - if (status != E_BOOK_ERROR_OK && status != E_BOOK_ERROR_CANCELLED) { - eab_error_dialog (is_list ? _("Error modifying list") : _("Error modifying contact"), - status); - } -} - -static void -deleted_cb (EBook* book, EBookStatus status, EContact *contact, - gpointer data) -{ - gboolean is_list = GPOINTER_TO_INT (data); - - if (status != E_BOOK_ERROR_OK) { - eab_error_dialog (is_list ? _("Error removing list") : _("Error removing contact"), - status); - } -} - -static void -editor_closed_cb (GtkObject *editor, gpointer data) -{ - g_object_unref (editor); -} - -EContactEditor * -eab_show_contact_editor (EBook *book, EContact *contact, - gboolean is_new_contact, - gboolean editable) -{ - EContactEditor *ce; - - ce = e_contact_editor_new (book, contact, is_new_contact, editable); - - g_signal_connect (ce, "contact_added", - G_CALLBACK (added_cb), GINT_TO_POINTER (FALSE)); - g_signal_connect (ce, "contact_modified", - G_CALLBACK (modified_cb), GINT_TO_POINTER (FALSE)); - g_signal_connect (ce, "contact_deleted", - G_CALLBACK (deleted_cb), GINT_TO_POINTER (FALSE)); - g_signal_connect (ce, "editor_closed", - G_CALLBACK (editor_closed_cb), NULL); - - return ce; -} - -EContactListEditor * -eab_show_contact_list_editor (EBook *book, EContact *contact, - gboolean is_new_contact, - gboolean editable) -{ - EContactListEditor *ce; - - ce = e_contact_list_editor_new (book, contact, is_new_contact, editable); - - g_signal_connect (ce, "contact_added", - G_CALLBACK (added_cb), GINT_TO_POINTER (TRUE)); - g_signal_connect (ce, "contact_modified", - G_CALLBACK (modified_cb), GINT_TO_POINTER (TRUE)); - g_signal_connect (ce, "contact_deleted", - G_CALLBACK (deleted_cb), GINT_TO_POINTER (TRUE)); - g_signal_connect (ce, "editor_closed", - G_CALLBACK (editor_closed_cb), GINT_TO_POINTER (TRUE)); - - eab_editor_show (EAB_EDITOR (ce)); - - return ce; -} - -static void -view_contacts (EBook *book, GList *list, gboolean editable) -{ - for (; list; list = list->next) { - EContact *contact = list->data; - if (e_contact_get (contact, E_CONTACT_IS_LIST)) - eab_show_contact_list_editor (book, contact, FALSE, editable); - else - eab_show_contact_editor (book, contact, FALSE, editable); - } -} - -void -eab_show_multiple_contacts (EBook *book, - GList *list, - gboolean editable) -{ - if (list) { - int length = g_list_length (list); - if (length > 5) { - GtkWidget *dialog; - gint response; - - dialog = gtk_message_dialog_new (NULL, - 0, - GTK_MESSAGE_QUESTION, - GTK_BUTTONS_NONE, - ngettext("Opening %d contact will open %d new window as well.\n" - "Do you really want to display this contact?", - "Opening %d contacts will open %d new windows as well.\n" - "Do you really want to display all of these contacts?", - length), - length, - length); - gtk_dialog_add_buttons (GTK_DIALOG (dialog), - _("_Don't Display"), GTK_RESPONSE_NO, - _("Display _All Contacts"), GTK_RESPONSE_YES, - NULL); - response = gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - if (response == GTK_RESPONSE_YES) - view_contacts (book, list, editable); - } else { - view_contacts (book, list, editable); - } - } -} - - static gint file_exists(GtkWindow *window, const char *filename) { @@ -773,232 +634,6 @@ eab_transfer_contacts (EBook *source, GList *contacts /* adopted */, gboolean de addressbook_load (dest, got_book_cb, process); } -typedef struct { - EContact *contact; - int email_num; /* if the contact is a person (not a list), the email address to use */ -} ContactAndEmailNum; - -static void -eab_send_to_contact_and_email_num_list (GList *contact_list) -{ - EMsgComposer *composer; - EComposerHeaderTable *table; - GPtrArray *to_array; - GPtrArray *bcc_array; - - union { - gpointer *pdata; - EDestination **destinations; - } convert; - - if (contact_list == NULL) - return; - - composer = e_msg_composer_new (); - table = e_msg_composer_get_header_table (composer); - em_composer_utils_setup_default_callbacks (composer); - - to_array = g_ptr_array_new (); - bcc_array = g_ptr_array_new (); - - /* Sort contacts into "To" and "Bcc" destinations. */ - while (contact_list != NULL) { - ContactAndEmailNum *ce = contact_list->data; - EContact *contact = ce->contact; - EDestination *destination; - - destination = e_destination_new (); - e_destination_set_contact (destination, contact, 0); - - if (e_destination_is_evolution_list (destination)) { - if (e_destination_list_show_addresses (destination)) - g_ptr_array_add (to_array, destination); - else - g_ptr_array_add (bcc_array, destination); - } else - g_ptr_array_add (to_array, destination); - - contact_list = g_list_next (contact_list); - } - - /* Add sentinels to each array. */ - g_ptr_array_add (to_array, NULL); - g_ptr_array_add (bcc_array, NULL); - - /* XXX Acrobatics like this make me question whether NULL-terminated - * arrays are really the best argument type for passing a list of - * destinations to the header table. */ - - /* Add "To" destinations. */ - convert.pdata = to_array->pdata; - e_composer_header_table_set_destinations_to ( - table, convert.destinations); - g_ptr_array_free (to_array, FALSE); - e_destination_freev (convert.destinations); - - /* Add "Bcc" destinations. */ - convert.pdata = bcc_array->pdata; - e_composer_header_table_set_destinations_bcc ( - table, convert.destinations); - g_ptr_array_free (bcc_array, FALSE); - e_destination_freev (convert.destinations); - - gtk_widget_show (GTK_WIDGET (composer)); -} - -static const char * -get_email (EContact *contact, EContactField field_id, gchar **to_free) -{ - char *name = NULL, *mail = NULL; - const char *value = e_contact_get_const (contact, field_id); - - *to_free = NULL; - - if (eab_parse_qp_email (value, &name, &mail)) { - *to_free = g_strdup_printf ("%s <%s>", name, mail); - value = *to_free; - } - - g_free (name); - g_free (mail); - - return value; -} - -static void -eab_send_contact_list_as_attachment (GList *contacts) -{ - EMsgComposer *composer; - EComposerHeaderTable *table; - CamelMimePart *attachment; - gchar *data; - - if (contacts == NULL) - return; - - composer = e_msg_composer_new (); - table = e_msg_composer_get_header_table (composer); - em_composer_utils_setup_default_callbacks (composer); - - attachment = camel_mime_part_new (); - data = eab_contact_list_to_string (contacts); - - camel_mime_part_set_content ( - attachment, data, strlen (data), "text/x-vcard"); - - if (contacts->next != NULL) - camel_mime_part_set_description ( - attachment, _("Multiple vCards")); - else { - EContact *contact = contacts->data; - const gchar *file_as; - gchar *description; - - file_as = e_contact_get_const (contact, E_CONTACT_FILE_AS); - description = g_strdup_printf (_("vCard for %s"), file_as); - camel_mime_part_set_description (attachment, description); - g_free (description); - } - - camel_mime_part_set_disposition (attachment, "attachment"); - - e_msg_composer_attach (composer, attachment); - camel_object_unref (attachment); - - if (contacts->next != NULL) - e_composer_header_table_set_subject ( - table, _("Contact information")); - else { - EContact *contact = contacts->data; - gchar *tempstr; - const gchar *tempstr2; - gchar *tempfree = NULL; - - tempstr2 = e_contact_get_const (contact, E_CONTACT_FILE_AS); - if (!tempstr2 || !*tempstr2) - tempstr2 = e_contact_get_const (contact, E_CONTACT_FULL_NAME); - if (!tempstr2 || !*tempstr2) - tempstr2 = e_contact_get_const (contact, E_CONTACT_ORG); - if (!tempstr2 || !*tempstr2) { - g_free (tempfree); - tempstr2 = get_email (contact, E_CONTACT_EMAIL_1, &tempfree); - } - if (!tempstr2 || !*tempstr2) { - g_free (tempfree); - tempstr2 = get_email (contact, E_CONTACT_EMAIL_2, &tempfree); - } - if (!tempstr2 || !*tempstr2) { - g_free (tempfree); - tempstr2 = get_email (contact, E_CONTACT_EMAIL_3, &tempfree); - } - - if (!tempstr2 || !*tempstr2) - tempstr = g_strdup_printf (_("Contact information")); - else - tempstr = g_strdup_printf (_("Contact information for %s"), tempstr2); - - e_composer_header_table_set_subject (table, tempstr); - - g_free (tempstr); - g_free (tempfree); - } - - gtk_widget_show (GTK_WIDGET (composer)); -} - -void -eab_send_contact_list (GList *contacts, EABDisposition disposition) -{ - switch (disposition) { - case EAB_DISPOSITION_AS_TO: { - GList *list = NULL, *l; - - for (l = contacts; l; l = l->next) { - ContactAndEmailNum *ce = g_new (ContactAndEmailNum, 1); - ce->contact = l->data; - ce->email_num = 0; /* hardcode this */ - - list = g_list_append (list, ce); - } - - eab_send_to_contact_and_email_num_list (list); - - g_list_foreach (list, (GFunc)g_free, NULL); - g_list_free (list); - break; - } - case EAB_DISPOSITION_AS_ATTACHMENT: - eab_send_contact_list_as_attachment (contacts); - break; - } -} - -void -eab_send_contact (EContact *contact, int email_num, EABDisposition disposition) -{ - GList *list = NULL; - - switch (disposition) { - case EAB_DISPOSITION_AS_TO: { - ContactAndEmailNum ce; - - ce.contact = contact; - ce.email_num = email_num; - - list = g_list_prepend (NULL, &ce); - eab_send_to_contact_and_email_num_list (list); - break; - } - case EAB_DISPOSITION_AS_ATTACHMENT: { - list = g_list_prepend (NULL, contact); - eab_send_contact_list_as_attachment (list); - break; - } - } - - g_list_free (list); -} - GtkWidget * eab_create_image_chooser_widget(gchar *name, gchar *string1, gchar *string2, diff --git a/addressbook/gui/widgets/eab-gui-util.h b/addressbook/gui/widgets/eab-gui-util.h index 79dbe5493a..8d878cff14 100644 --- a/addressbook/gui/widgets/eab-gui-util.h +++ b/addressbook/gui/widgets/eab-gui-util.h @@ -26,8 +26,6 @@ #include <gtk/gtk.h> #include <libebook/e-book.h> -#include "addressbook/gui/contact-editor/e-contact-editor.h" -#include "addressbook/gui/contact-list-editor/e-contact-list-editor.h" G_BEGIN_DECLS @@ -40,17 +38,6 @@ void eab_search_result_dialog (GtkWidget *parent, EBookViewStatus status); gint eab_prompt_save_dialog (GtkWindow *parent); -EContactEditor *eab_show_contact_editor (EBook *book, - EContact *contact, - gboolean is_new_contact, - gboolean editable); -EContactListEditor *eab_show_contact_list_editor (EBook *book, - EContact *contact, - gboolean is_new_contact, - gboolean editable); -void eab_show_multiple_contacts (EBook *book, - GList *list, - gboolean editable); void eab_transfer_contacts (EBook *source, GList *contacts, /* adopted */ gboolean delete_from_source, @@ -64,26 +51,17 @@ void eab_contact_list_save (char *title, GList *list, GtkWindow *parent_window); -typedef enum { - EAB_DISPOSITION_AS_ATTACHMENT, - EAB_DISPOSITION_AS_TO, -} EABDisposition; - -void eab_send_contact (EContact *contact, - int email_num, - EABDisposition disposition); -void eab_send_contact_list (GList *contacts, - EABDisposition disposition); - GtkWidget *eab_create_image_chooser_widget (gchar *name, gchar *string1, gchar *string2, gint int1, gint int2); ESource *eab_select_source (const gchar *title, const gchar *message, const gchar *select_uid, GtkWindow *parent); -/* To parse quoted printable address & return email & name fields */ -gboolean eab_parse_qp_email (const gchar *string, gchar **name, gchar **email); -char *eab_parse_qp_email_to_html (const gchar *string); +/* To parse quoted printable address & return email & name fields */ +gboolean eab_parse_qp_email (const gchar *string, + gchar **name, + gchar **email); +gchar * eab_parse_qp_email_to_html (const gchar *string); G_END_DECLS diff --git a/addressbook/util/Makefile.am b/addressbook/util/Makefile.am index ca7340017a..1a1fced7bd 100644 --- a/addressbook/util/Makefile.am +++ b/addressbook/util/Makefile.am @@ -13,6 +13,8 @@ INCLUDES = \ privsolib_LTLIBRARIES = libeabutil.la libeabutil_la_SOURCES = \ + addressbook.c \ + addressbook.h \ eab-book-util.c \ eab-book-util.h diff --git a/addressbook/gui/component/addressbook.c b/addressbook/util/addressbook.c index c8285d8171..c8285d8171 100644 --- a/addressbook/gui/component/addressbook.c +++ b/addressbook/util/addressbook.c diff --git a/addressbook/gui/component/addressbook.h b/addressbook/util/addressbook.h index 2e25448717..2e25448717 100644 --- a/addressbook/gui/component/addressbook.h +++ b/addressbook/util/addressbook.h diff --git a/addressbook/util/eab-book-util.h b/addressbook/util/eab-book-util.h index 66c3a6c23e..2051c77ad0 100644 --- a/addressbook/util/eab-book-util.h +++ b/addressbook/util/eab-book-util.h @@ -24,8 +24,6 @@ #ifndef __EAB_UTIL_H__ #define __EAB_UTIL_H__ -#include <bonobo/bonobo-object.h> -#include <bonobo/bonobo-moniker-util.h> #include <libebook/e-book.h> #include "e-util/e-config-listener.h" diff --git a/composer/Makefile.am b/composer/Makefile.am index 4b46b3eb54..ee5ffe1259 100644 --- a/composer/Makefile.am +++ b/composer/Makefile.am @@ -47,7 +47,7 @@ libcomposer_la_SOURCES = \ e-msg-composer.c \ e-msg-composer.h -libcomposer_la_LIBADD = \ +libcomposer_la_LIBADD = \ $(top_builddir)/widgets/misc/libemiscwidgets.la uidir = $(evolutionuidir) diff --git a/composer/e-msg-composer.c b/composer/e-msg-composer.c index 0efcbfcbe9..36b6479fbf 100644 --- a/composer/e-msg-composer.c +++ b/composer/e-msg-composer.c @@ -69,8 +69,8 @@ #include "e-util/e-util.h" #include <mail/em-event.h> #include "e-signature-combo-box.h" +#include "shell/e-shell.h" -#include <camel/camel-session.h> #include <camel/camel-charset-map.h> #include <camel/camel-iconv.h> #include <camel/camel-stream-filter.h> @@ -94,7 +94,6 @@ #include "mail/mail-crypto.h" #include "mail/mail-mt.h" #include "mail/mail-ops.h" -#include "mail/mail-session.h" #include "mail/mail-tools.h" #include "e-msg-composer.h" @@ -875,7 +874,9 @@ build_message (EMsgComposer *composer, if (smime_sign) { CamelMimePart *npart = camel_mime_part_new (); + CamelSession *session; + session = e_msg_composer_get_session (composer); cipher = camel_smime_context_new (session); /* if we're also encrypting, envelope-sign rather than clear-sign */ @@ -899,10 +900,13 @@ build_message (EMsgComposer *composer, } if (smime_encrypt) { + CamelSession *session; + /* check to see if we should encrypt to self, NB removed after use */ if (account->smime_encrypt_to_self) g_ptr_array_add (recipients, g_strdup (account->smime_encrypt_key)); + session = e_msg_composer_get_session (composer); cipher = camel_smime_context_new (session); camel_smime_context_set_encrypt_key ((CamelSMIMEContext *)cipher, TRUE, account->smime_encrypt_key); @@ -2932,6 +2936,7 @@ create_composer (gint visible_mask) /** * e_msg_composer_new_with_type: + * @type: the type of composer to create * * Create a new message composer widget. The type can be * E_MSG_COMPOSER_MAIL, E_MSG_COMPOSER_POST or E_MSG_COMPOSER_MAIL_POST. @@ -2940,7 +2945,7 @@ create_composer (gint visible_mask) **/ EMsgComposer * -e_msg_composer_new_with_type (int type) +e_msg_composer_new_with_type (gint type) { EMsgComposer *composer; gint visible_mask; @@ -3750,6 +3755,32 @@ e_msg_composer_new_redirect (CamelMimeMessage *message, } /** + * e_msg_composer_get_session: + * @composer: an #EMsgComposer + * + * Returns the mail module's global #CamelSession instance. Calling + * this function will load the mail module if it isn't already loaded. + * + * Returns: the mail module's #CamelSession + **/ +CamelSession * +e_msg_composer_get_session (EMsgComposer *composer) +{ + EShellModule *shell_module; + CamelSession *session; + EShell *shell; + + g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), NULL); + + shell = e_shell_get_default (); + shell_module = e_shell_get_module_by_name (shell, "mail"); + session = g_object_get_data (G_OBJECT (shell_module), "session"); + g_return_val_if_fail (CAMEL_IS_SESSION (session), NULL); + + return session; +} + +/** * e_msg_composer_send: * @composer: an #EMsgComposer * diff --git a/composer/e-msg-composer.h b/composer/e-msg-composer.h index f0ef682999..7303069bc9 100644 --- a/composer/e-msg-composer.h +++ b/composer/e-msg-composer.h @@ -25,6 +25,7 @@ #include <camel/camel-internet-address.h> #include <camel/camel-mime-message.h> +#include <camel/camel-session.h> #include <libedataserver/e-account.h> #include <libebook/e-destination.h> #include <gtkhtml-editor.h> @@ -78,6 +79,7 @@ EMsgComposer * e_msg_composer_new_with_message (CamelMimeMessage *msg); EMsgComposer * e_msg_composer_new_from_url (const gchar *url); EMsgComposer * e_msg_composer_new_redirect (CamelMimeMessage *message, const gchar *resent_from); +CamelSession * e_msg_composer_get_session (EMsgComposer *composer); void e_msg_composer_send (EMsgComposer *composer); void e_msg_composer_save_draft (EMsgComposer *composer); @@ -155,7 +157,7 @@ struct _EAttachmentBar * e_msg_composer_get_attachment_bar (EMsgComposer *composer); -gboolean e_msg_composer_is_exiting (EMsgComposer *composer); +gboolean e_msg_composer_is_exiting (EMsgComposer *composer); G_END_DECLS diff --git a/doc/reference/shell/tmpl/e-shell.sgml b/doc/reference/shell/tmpl/e-shell.sgml index 1ab11c689d..c747834f4e 100644 --- a/doc/reference/shell/tmpl/e-shell.sgml +++ b/doc/reference/shell/tmpl/e-shell.sgml @@ -29,6 +29,7 @@ EShell </para> @eshell: the object which received the signal. +@Param2: <!-- ##### SIGNAL EShell::handle-uri ##### --> <para> @@ -78,15 +79,6 @@ EShell @E_SHELL_LINE_STATUS_OFFLINE: @E_SHELL_LINE_STATUS_FORCED_OFFLINE: -<!-- ##### FUNCTION e_shell_new ##### --> -<para> - -</para> - -@online: -@Returns: - - <!-- ##### FUNCTION e_shell_list_modules ##### --> <para> diff --git a/doc/reference/shell/tmpl/eshell-unused.sgml b/doc/reference/shell/tmpl/eshell-unused.sgml index 47c012875b..334903498f 100644 --- a/doc/reference/shell/tmpl/eshell-unused.sgml +++ b/doc/reference/shell/tmpl/eshell-unused.sgml @@ -1964,6 +1964,14 @@ intelligent @error: @Returns: +<!-- ##### FUNCTION e_shell_new ##### --> +<para> + +</para> + +@online: +@Returns: + <!-- ##### FUNCTION e_shell_sidebar_get_primary_text ##### --> <para> diff --git a/mail/Makefile.am b/mail/Makefile.am index 2f44ada1ff..09f26f5d56 100644 --- a/mail/Makefile.am +++ b/mail/Makefile.am @@ -161,8 +161,10 @@ libevolution_module_mail_la_LIBADD = \ $(top_builddir)/widgets/table/libetable.la \ $(top_builddir)/widgets/text/libetext.la \ $(top_builddir)/widgets/misc/libemiscwidgets.la \ + $(top_builddir)/mail/importers/libevolution-mail-importers.la \ $(top_builddir)/addressbook/gui/contact-editor/libecontacteditor.la \ - $(top_builddir)/mail/importers/libevolution-mail-importers.la + $(top_builddir)/addressbook/gui/contact-list-editor/libecontactlisteditor.la \ + $(SMIME_LIBS) # plugin mail api #mailinclude_HEADERS = \ diff --git a/mail/e-mail-shell-module.c b/mail/e-mail-shell-module.c index b7aa7a68c1..493cbfff63 100644 --- a/mail/e-mail-shell-module.c +++ b/mail/e-mail-shell-module.c @@ -459,21 +459,30 @@ mail_shell_module_init_preferences (void) } static gboolean -mail_shell_module_handle_uri (EShellModule *shell_module, - const gchar *uri) +mail_shell_module_handle_uri_cb (EShell *shell, + const gchar *uri, + EShellModule *shell_module) { /* FIXME */ return FALSE; } static void -mail_shell_module_window_created (EShellModule *shell_module, - EShellWindow *shell_window) +mail_shell_module_window_weak_notify_cb (EShell *shell, + GObject *where_the_object_was) +{ + g_signal_handlers_disconnect_by_func ( + shell, mail_shell_module_new_mail_cb, + where_the_object_was); +} + +static void +mail_shell_module_window_created_cb (EShell *shell, + EShellWindow *shell_window, + EShellModule *shell_module) { - EShell *shell; const gchar *module_name; - shell = e_shell_module_get_shell (shell_module); module_name = G_TYPE_MODULE (shell_module)->name; e_shell_window_register_new_item_actions ( @@ -487,6 +496,10 @@ mail_shell_module_window_created (EShellModule *shell_module, g_signal_connect_swapped ( shell, "event::new-mail", G_CALLBACK (mail_shell_module_new_mail_cb), shell_window); + + g_object_weak_ref ( + G_OBJECT (shell_window), (GWeakNotify) + mail_shell_module_window_weak_notify_cb, shell); } static EShellModuleInfo module_info = { @@ -532,13 +545,15 @@ e_shell_module_init (GTypeModule *type_module) folder_tree_model = em_folder_tree_model_new (shell_module); - g_signal_connect_swapped ( + g_signal_connect ( shell, "handle-uri", - G_CALLBACK (mail_shell_module_handle_uri), shell_module); + G_CALLBACK (mail_shell_module_handle_uri_cb), + shell_module); - g_signal_connect_swapped ( + g_signal_connect ( shell, "window-created", - G_CALLBACK (mail_shell_module_window_created), shell_module); + G_CALLBACK (mail_shell_module_window_created_cb), + shell_module); mail_config_init (); mail_msg_init (); diff --git a/mail/mail-folder-cache.c b/mail/mail-folder-cache.c index 8f85f3f521..49479faa7a 100644 --- a/mail/mail-folder-cache.c +++ b/mail/mail-folder-cache.c @@ -198,7 +198,7 @@ real_flush_updates (EShellModule *shell_module) t->name = em_folder_tree_model_get_folder_name (model, up->store, up->full_name); if (t->new > 0) - e_shell_event (shell, "new-mail"); + e_shell_event (shell, "new-mail", NULL); /** @Event: folder.changed * @Title: Folder changed diff --git a/shell/e-shell-window-actions.c b/shell/e-shell-window-actions.c index 348daae89e..38f33d99e9 100644 --- a/shell/e-shell-window-actions.c +++ b/shell/e-shell-window-actions.c @@ -1781,7 +1781,6 @@ shell_window_extract_actions (EShellWindow *shell_window, { const gchar *current_view; GList *match_list = NULL; - GList *primary = NULL; GList *iter; /* Pick out the actions from the source list that are tagged diff --git a/shell/e-shell.c b/shell/e-shell.c index c875dcb5cf..d6884b0a69 100644 --- a/shell/e-shell.c +++ b/shell/e-shell.c @@ -62,6 +62,7 @@ enum { LAST_SIGNAL }; +EShell *default_shell = NULL; static gpointer parent_class; static guint signals[LAST_SIGNAL]; @@ -362,8 +363,9 @@ shell_class_init (EShellClass *class) G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST | G_SIGNAL_DETAILED | G_SIGNAL_ACTION, 0, NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, + G_TYPE_POINTER); signals[HANDLE_URI] = g_signal_new ( "handle-uri", @@ -451,9 +453,12 @@ e_shell_get_type (void) } EShell * -e_shell_new (gboolean online_mode) +e_shell_get_default (void) { - return g_object_new (E_TYPE_SHELL, "online-mode", online_mode, NULL); + /* Emit a warning if we call this too early. */ + g_return_val_if_fail (default_shell != NULL, NULL); + + return default_shell; } GList * @@ -626,7 +631,8 @@ e_shell_get_preferences_window (void) void e_shell_event (EShell *shell, - const gchar *event_name) + const gchar *event_name, + gpointer event_data) { GQuark detail; @@ -634,7 +640,7 @@ e_shell_event (EShell *shell, g_return_if_fail (event_name != NULL); detail = g_quark_from_string (event_name); - g_signal_emit (shell, signals[EVENT], detail); + g_signal_emit (shell, signals[EVENT], detail, event_data); } gboolean diff --git a/shell/e-shell.h b/shell/e-shell.h index 7bee6b9fff..2c942097c5 100644 --- a/shell/e-shell.h +++ b/shell/e-shell.h @@ -81,7 +81,7 @@ enum _EShellLineStatus { }; GType e_shell_get_type (void); -EShell * e_shell_new (gboolean online); +EShell * e_shell_get_default (void); GList * e_shell_list_modules (EShell *shell); const gchar * e_shell_get_canonical_name (EShell *shell, const gchar *name); @@ -104,7 +104,8 @@ void e_shell_set_line_status (EShell *shell, EShellLineStatus status); GtkWidget * e_shell_get_preferences_window (void); void e_shell_event (EShell *shell, - const gchar *event_name); + const gchar *event_name, + gpointer event_data); gboolean e_shell_is_busy (EShell *shell); gboolean e_shell_do_quit (EShell *shell); gboolean e_shell_quit (EShell *shell); diff --git a/shell/main.c b/shell/main.c index 5d9405fcfe..47400798ab 100644 --- a/shell/main.c +++ b/shell/main.c @@ -96,11 +96,13 @@ static gboolean disable_eplugin = FALSE; static gboolean disable_preview = FALSE; static gboolean idle_cb (gchar **uris); -static EShell *global_shell; static char *requested_view = NULL; static char *evolution_debug_log = NULL; static gchar **remaining_args; +/* Defined in <e-shell.h> */ +extern EShell *default_shell; + #ifdef KILL_PROCESS_CMD static void @@ -265,12 +267,15 @@ destroy_config (GConfClient *client) static void open_uris (gchar **uris) { + EShell *shell; guint ii; g_return_if_fail (uris != NULL); + shell = e_shell_get_default (); + for (ii = 0; uris[ii] != NULL; ii++) - if (!e_shell_handle_uri (global_shell, uris[ii])) + if (!e_shell_handle_uri (shell, uris[ii])) g_warning ("Invalid URI: %s", uris[ii]); } @@ -279,6 +284,7 @@ open_uris (gchar **uris) static gboolean idle_cb (gchar **uris) { + EShell *shell; GtkWidget *shell_window; const gchar *initial_view; @@ -293,8 +299,8 @@ idle_cb (gchar **uris) return FALSE; } - initial_view = e_shell_get_canonical_name ( - global_shell, requested_view); + shell = e_shell_get_default (); + initial_view = e_shell_get_canonical_name (shell, requested_view); if (initial_view != NULL) { GConfClient *client; @@ -306,7 +312,7 @@ idle_cb (gchar **uris) g_object_unref (client); } - shell_window = e_shell_create_window (global_shell); + shell_window = e_shell_create_window (shell); #if 0 /* MBARNES */ if (shell == NULL) { @@ -481,7 +487,7 @@ master_client_die_cb (GnomeClient *client, } static void -create_shell (void) +create_default_shell (void) { EShell *shell; GConfClient *conf_client; @@ -510,7 +516,7 @@ create_shell (void) } } - shell = e_shell_new (online_mode); + shell = g_object_new (E_TYPE_SHELL, "online-mode", online_mode, NULL); g_signal_connect ( shell, "window-destroyed", @@ -526,7 +532,7 @@ create_shell (void) g_object_unref (conf_client); - global_shell = shell; + default_shell = shell; } int @@ -662,7 +668,7 @@ main (int argc, char **argv) g_object_unref (client); - create_shell (); + create_default_shell (); gtk_main (); diff --git a/ui/evolution-shell.ui b/ui/evolution-shell.ui index 9802059a6c..7a89e11adc 100644 --- a/ui/evolution-shell.ui +++ b/ui/evolution-shell.ui @@ -38,17 +38,17 @@ <menu action='window-menu'/> <menu action='layout-menu'> <menuitem action='show-toolbar'/> - <menuitem action='show-statusbar'/> - <menuitem action='show-sidebar'/> + <menuitem action='show-statusbar'/> + <menuitem action='show-sidebar'/> </menu> <placeholder name='view-custom-menus'/> <menu action='switcher-menu'> <menuitem action='switcher-style-both'/> - <menuitem action='switcher-style-icons'/> - <menuitem action='switcher-style-text'/> - <menuitem action='switcher-style-user'/> - <separator/> - <menuitem action='show-switcher'/> + <menuitem action='switcher-style-icons'/> + <menuitem action='switcher-style-text'/> + <menuitem action='switcher-style-user'/> + <separator/> + <menuitem action='show-switcher'/> </menu> </menu> <placeholder name='custom-menus'/> |