diff options
author | Matthew Barnes <mbarnes@src.gnome.org> | 2008-11-14 11:56:01 +0800 |
---|---|---|
committer | Matthew Barnes <mbarnes@src.gnome.org> | 2008-11-14 11:56:01 +0800 |
commit | 8c0bd86d5fdd6d87c3170e2a01423e7c7018a981 (patch) | |
tree | 22da2df051cb6f1bc988d15aca08ebb0a5baf7e4 | |
parent | 6760cc72334346b8654fcd9fe1440890db55ac1b (diff) | |
download | gsoc2013-evolution-8c0bd86d5fdd6d87c3170e2a01423e7c7018a981.tar gsoc2013-evolution-8c0bd86d5fdd6d87c3170e2a01423e7c7018a981.tar.gz gsoc2013-evolution-8c0bd86d5fdd6d87c3170e2a01423e7c7018a981.tar.bz2 gsoc2013-evolution-8c0bd86d5fdd6d87c3170e2a01423e7c7018a981.tar.lz gsoc2013-evolution-8c0bd86d5fdd6d87c3170e2a01423e7c7018a981.tar.xz gsoc2013-evolution-8c0bd86d5fdd6d87c3170e2a01423e7c7018a981.tar.zst gsoc2013-evolution-8c0bd86d5fdd6d87c3170e2a01423e7c7018a981.zip |
Rearranged some of the addressbook code to try and eliminate some circular
dependencies in our libraries. The circular dependency between the composer
and the mail module is still causing me headaches. And it doesn't help that
the addressbook and calendar also want to link to the composer.
svn path=/branches/kill-bonobo/; revision=36782
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'/> |