diff options
41 files changed, 1649 insertions, 2360 deletions
diff --git a/addressbook/ChangeLog b/addressbook/ChangeLog index bad55eb3d7..640c480f42 100644 --- a/addressbook/ChangeLog +++ b/addressbook/ChangeLog @@ -30,6 +30,37 @@ bug 206774, 242154. * gui/widgets/eab-popup.h: Fixes the bug 206774, 242154. +2005-07-06 Not Zed <NotZed@Ximian.com> + + * Makefile.am (SUBDIRS): build importers before the gui code. + + * gui/component/Makefile.am (libevolution_addressbook_la_LIBADD): + link to importer plugin builtins. + + * importers/Makefile.am: just build a shared library with all the + importers in it, we dont install a plugin, it is just linked to + the main app for simplicity. + + * importers/GNOME_Evolution_Addressbook_VCard_Importer.server.in.in: + * importers/GNOME_Evolution_Addressbook_LDIF_Importer.server.in.in: + removed. + + * importers/evolution-vcard-importer.c: ported + to eimport, simplified some logic (why test extensions and then test + file content anyway), fixed some memory leaks, etc. + + * importers/evolution-ldif-importer.c (ldif_import): remove + progress dialog stuff, move to update e-import api. + +2005-07-01 Not Zed <NotZed@Ximian.com> + + * gui/component/addressbook-component.c + (addressbook_component_init): hookup the builtin importer + 'plugins'. + + * importers/*: fix for importers->eplugin, also added a + window/progress dialog and cancel button. + 2005-06-25 Harish Krishnaswamy <kharish@novell.com> * gui/contact-list-editor/Makefile.am: The previous commit breaks diff --git a/addressbook/Makefile.am b/addressbook/Makefile.am index c1ff2aa617..8d70a4f13f 100644 --- a/addressbook/Makefile.am +++ b/addressbook/Makefile.am @@ -3,7 +3,7 @@ CONDUIT_SUBDIR=conduit endif SUBDIRS = \ - util printing gui importers tools $(CONDUIT_SUBDIR) + util printing importers gui tools $(CONDUIT_SUBDIR) error_DATA = addressbook.error errordir = $(privdatadir)/errors diff --git a/addressbook/gui/component/Makefile.am b/addressbook/gui/component/Makefile.am index 89d7b26dad..41ba12b9a9 100644 --- a/addressbook/gui/component/Makefile.am +++ b/addressbook/gui/component/Makefile.am @@ -55,6 +55,7 @@ libevolution_addressbook_la_LIBADD = \ $(top_builddir)/widgets/misc/libemiscwidgets.la \ $(top_builddir)/widgets/menus/libmenus.la \ $(top_builddir)/a11y/addressbook/libevolution-addressbook-a11y.la \ + $(top_builddir)/addressbook/importers/libevolution-addressbook-importers.la \ $(EVOLUTION_ADDRESSBOOK_LIBS) $(LDAP_LIBS) diff --git a/addressbook/gui/component/addressbook-component.c b/addressbook/gui/component/addressbook-component.c index 670e5de8ef..fef6f9b7f7 100644 --- a/addressbook/gui/component/addressbook-component.c +++ b/addressbook/gui/component/addressbook-component.c @@ -32,9 +32,11 @@ #include "addressbook/gui/contact-editor/eab-editor.h" #include "addressbook/gui/widgets/eab-gui-util.h" #include "e-util/e-plugin.h" +#include "e-util/e-import.h" #include "addressbook/gui/widgets/eab-popup.h" #include "addressbook/gui/widgets/eab-menu.h" #include "addressbook/gui/widgets/eab-config.h" +#include "addressbook/importers/evolution-addressbook-importers.h" #include "misc/e-task-bar.h" #include "misc/e-info-label.h" @@ -471,10 +473,16 @@ addressbook_component_init (AddressbookComponent *component) #endif if (first) { + EImportClass *klass; + first = FALSE; e_plugin_hook_register_type(eab_popup_hook_get_type()); e_plugin_hook_register_type(eab_menu_hook_get_type()); e_plugin_hook_register_type(eab_config_hook_get_type()); + + klass = g_type_class_ref(e_import_get_type()); + e_import_class_add_importer(klass, evolution_ldif_importer_peek(), NULL, NULL); + e_import_class_add_importer(klass, evolution_vcard_importer_peek(), NULL, NULL); } } diff --git a/addressbook/importers/GNOME_Evolution_Addressbook_LDIF_Importer.server.in.in b/addressbook/importers/GNOME_Evolution_Addressbook_LDIF_Importer.server.in.in deleted file mode 100644 index f9067f550a..0000000000 --- a/addressbook/importers/GNOME_Evolution_Addressbook_LDIF_Importer.server.in.in +++ /dev/null @@ -1,29 +0,0 @@ -<oaf_info> - -<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_LDIF_ImporterFactory:@VERSION@" - type="shlib" - location="@IMPORTERSDIR@/libevolution-addressbook-ldif-importer@SOEXT@"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/ObjectFactory:1.0"/> - </oaf_attribute> - - <oaf_attribute name="name" type="string" - _value="Evolution LDIF importer"/> -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_LDIF_Importer:@VERSION@" - type="factory" - location="OAFIID:GNOME_Evolution_Addressbook_LDIF_ImporterFactory:@VERSION@"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/Evolution/Importer:@VERSION@"/> - </oaf_attribute> - - <oaf_attribute name="evolution:menu_name" type="string" - _value="LDAP Data Interchange Format (.ldif)"/> - <oaf_attribute name="name" type="string" - _value="Evolution LDIF importer"/> -</oaf_server> - -</oaf_info> diff --git a/addressbook/importers/GNOME_Evolution_Addressbook_VCard_Importer.server.in.in b/addressbook/importers/GNOME_Evolution_Addressbook_VCard_Importer.server.in.in deleted file mode 100644 index 92cc6fbce5..0000000000 --- a/addressbook/importers/GNOME_Evolution_Addressbook_VCard_Importer.server.in.in +++ /dev/null @@ -1,29 +0,0 @@ -<oaf_info> - -<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_VCard_ImporterFactory:@VERSION@" - type="shlib" - location="@IMPORTERSDIR@/libevolution-addressbook-vcard-importer@SOEXT@"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/ObjectFactory:1.0"/> - </oaf_attribute> - - <oaf_attribute name="name" type="string" - _value="Evolution VCard Importer"/> -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_VCard_Importer:@VERSION@" - type="factory" - location="OAFIID:GNOME_Evolution_Addressbook_VCard_ImporterFactory:@VERSION@"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/Evolution/Importer:@VERSION@"/> - </oaf_attribute> - - <oaf_attribute name="evolution:menu_name" type="string" - _value="VCard (.vcf, .gcrd)"/> - <oaf_attribute name="name" type="string" - _value="Evolution VCard Importer"/> -</oaf_server> - -</oaf_info> diff --git a/addressbook/importers/Makefile.am b/addressbook/importers/Makefile.am index 3c04c22f37..02f8e366ff 100644 --- a/addressbook/importers/Makefile.am +++ b/addressbook/importers/Makefile.am @@ -1,53 +1,21 @@ -importersdir = $(privlibdir)/evolution-addressbook-importers -importers_LTLIBRARIES = \ - libevolution-addressbook-ldif-importer.la \ - libevolution-addressbook-vcard-importer.la +privlib_LTLIBRARIES = \ + libevolution-addressbook-importers.la INCLUDES = \ -DEVOLUTION_LOCALEDIR=\""$(localedir)"\" \ -DEVOLUTION_SOUNDDIR=\""$(soundsdir)"\" \ -DG_LOG_DOMAIN=\"Evolution-Importer\" \ -I$(top_srcdir) \ - -I$(top_builddir)/shell \ - -I$(top_srcdir)/shell \ -I$(top_srcdir)/addressbook \ -I$(top_builddir)/addressbook \ $(EVOLUTION_ADDRESSBOOK_CFLAGS) -# VCard Importer -libevolution_addressbook_vcard_importer_la_SOURCES = \ - evolution-vcard-importer.c +libevolution_addressbook_importers_la_SOURCES = \ + evolution-ldif-importer.c \ + evolution-vcard-importer.c \ + evolution-addressbook-importers.h -libevolution_addressbook_vcard_importer_la_LDFLAGS = -avoid-version -module - -libevolution_addressbook_vcard_importer_la_LIBADD = \ - $(top_builddir)/shell/importer/libevolution-importer.la \ - $(top_builddir)/e-util/libeutil.la \ - $(IMPORTERS_LIBS) - -# LDIF Importer -libevolution_addressbook_ldif_importer_la_SOURCES = \ - evolution-ldif-importer.c - -libevolution_addressbook_ldif_importer_la_LDFLAGS = -avoid-version -module - -libevolution_addressbook_ldif_importer_la_LIBADD = \ - $(top_builddir)/shell/importer/libevolution-importer.la \ +libevolution_addressbook_importers_la_LIBADD = \ $(top_builddir)/e-util/libeutil.la \ $(IMPORTERS_LIBS) - -server_in_files = \ - GNOME_Evolution_Addressbook_LDIF_Importer.server.in.in \ - GNOME_Evolution_Addressbook_VCard_Importer.server.in.in -server_DATA = $(server_in_files:.server.in.in=_$(BASE_VERSION).server) -@EVO_SERVER_RULE@ -@INTLTOOL_SERVER_RULE@ - -BUILT_SOURCES = $(server_DATA) -CLEANFILES = $(BUILT_SOURCES) - -EXTRA_DIST = $(server_in_files) - -dist-hook: - cd $(distdir); rm -f $(BUILT_SOURCES) diff --git a/addressbook/importers/evolution-addressbook-importers.h b/addressbook/importers/evolution-addressbook-importers.h new file mode 100644 index 0000000000..8cff54473f --- /dev/null +++ b/addressbook/importers/evolution-addressbook-importers.h @@ -0,0 +1,3 @@ + +struct _EImportImporter *evolution_ldif_importer_peek(void); +struct _EImportImporter *evolution_vcard_importer_peek(void); diff --git a/addressbook/importers/evolution-ldif-importer.c b/addressbook/importers/evolution-ldif-importer.c index a2203f7e8b..d5b6aa8dbc 100644 --- a/addressbook/importers/evolution-ldif-importer.c +++ b/addressbook/importers/evolution-ldif-importer.c @@ -10,6 +10,8 @@ * * Multi-line value support, mailing list support, base64 support, and * various fixups: Chris Toshok (toshok@ximian.com) + * + * Made re-entrant, converted to eplugin, Michael Zucchi <notzed@ximian.com> */ #ifdef HAVE_CONFIG_H @@ -20,34 +22,40 @@ #include <ctype.h> #include <string.h> -#include <gtk/gtkwidget.h> +#include <glib/gi18n.h> + #include <gtk/gtkvbox.h> -#include <libgnome/gnome-init.h> -#include <bonobo/bonobo-shlib-factory.h> -#include <bonobo/bonobo-main.h> -#include <bonobo/bonobo-control.h> #include <libebook/e-book.h> #include <libedataserverui/e-source-selector.h> -#include <importer/evolution-importer.h> -#include <importer/GNOME_Evolution_Importer.h> #include <libebook/e-destination.h> -#define COMPONENT_FACTORY_IID "OAFIID:GNOME_Evolution_Addressbook_LDIF_ImporterFactory:" BASE_VERSION -#define COMPONENT_IID "OAFIID:GNOME_Evolution_Addressbook_LDIF_Importer:" BASE_VERSION +#include "e-util/e-import.h" -static GHashTable *dn_contact_hash; +#include "evolution-addressbook-importers.h" typedef struct { - ESource *primary; - - GList *contactlist; - GList *iterator; + EImport *import; + EImportTarget *target; + + guint idle_id; + + GHashTable *dn_contact_hash; + + int state; /* 0 - initial scan, 1 - list cards, 2 - cancelled/complete */ + FILE *file; + gulong size; + EBook *book; - gboolean ready; + + GSList *contacts; + GSList *list_contacts; + GSList *list_iterator; } LDIFImporter; +static void ldif_import_done(LDIFImporter *gci); + static struct { char *ldif_attribute; EContactField contact_field; @@ -204,7 +212,7 @@ getValue( char **src ) } static gboolean -parseLine (EContact *contact, EContactAddress *address, char **buf) +parseLine (LDIFImporter *gci, EContact *contact, EContactAddress *address, char **buf) { char *ptr; char *colon, *value; @@ -284,7 +292,7 @@ parseLine (EContact *contact, EContactAddress *address, char **buf) /* handle objectclass/dn/member out here */ if (!field_handled) { if (!g_ascii_strcasecmp (ptr, "dn")) - g_hash_table_insert (dn_contact_hash, g_strdup(ldif_value->str), contact); + g_hash_table_insert (gci->dn_contact_hash, g_strdup(ldif_value->str), contact); else if (!g_ascii_strcasecmp (ptr, "objectclass") && !g_ascii_strcasecmp (ldif_value->str, "groupofnames")) { e_contact_set (contact, E_CONTACT_IS_LIST, GINT_TO_POINTER (TRUE)); } @@ -316,7 +324,7 @@ parseLine (EContact *contact, EContactAddress *address, char **buf) } static EContact * -getNextLDIFEntry( FILE *f ) +getNextLDIFEntry(LDIFImporter *gci, FILE *f ) { EContact *contact; EContactAddress *address; @@ -345,7 +353,7 @@ getNextLDIFEntry( FILE *f ) buf = str->str; while (buf) { - if (!parseLine (contact, address, &buf)) { + if (!parseLine (gci, contact, address, &buf)) { /* parsing error */ g_object_unref (contact); return NULL; @@ -381,7 +389,7 @@ resolve_list_card (LDIFImporter *gci, EContact *contact) for (l = email; l; l = l->next) { /* mozilla stuffs dn's in the EMAIL list for contact lists */ char *dn = l->data; - EContact *dn_contact = g_hash_table_lookup (dn_contact_hash, dn); + EContact *dn_contact = g_hash_table_lookup (gci->dn_contact_hash, dn); /* break list chains here, since we don't support them just yet */ if (dn_contact && !e_contact_get (dn_contact, E_CONTACT_IS_LIST)) { @@ -407,38 +415,6 @@ resolve_list_card (LDIFImporter *gci, EContact *contact) g_list_free (email_attrs); } -static GList * -create_contacts_from_ldif (const char *filename) -{ - GList * list = NULL; - GList * list_list = NULL; - FILE * file; - EContact *contact; - - if(!( file = fopen( filename, "r" ) )) { - g_warning("Can't open .ldif file"); - return NULL; - } - - dn_contact_hash = g_hash_table_new (g_str_hash, g_str_equal); - - while ((contact = getNextLDIFEntry (file))) { - - if (e_contact_get (contact, E_CONTACT_IS_LIST)) - list_list = g_list_append (list_list, contact); - else - list = g_list_append (list, contact); - } - - fclose (file); - - list = g_list_reverse (list); - list_list = g_list_reverse (list_list); - list = g_list_concat (list, list_list); - - return list; -} - static void add_to_notes (EContact *contact, EContactField field) { @@ -463,101 +439,95 @@ add_to_notes (EContact *contact, EContactField field) g_free (new_text); } -/* EvolutionImporter methods */ -static void -process_item_fn (EvolutionImporter *importer, - CORBA_Object listener, - void *closure, - CORBA_Environment *ev) +static gboolean +ldif_import_contacts(void *d) { - LDIFImporter *gci = (LDIFImporter *) closure; + LDIFImporter *gci = d; + FILE * file; EContact *contact; - - if (gci->iterator == NULL) - gci->iterator = gci->contactlist; - - if (gci->ready == FALSE) { - GNOME_Evolution_ImporterListener_notifyResult (listener, - GNOME_Evolution_ImporterListener_NOT_READY, - gci->iterator ? TRUE : FALSE, - ev); - return; - } - - if (gci->iterator == NULL) { - GNOME_Evolution_ImporterListener_notifyResult (listener, - GNOME_Evolution_ImporterListener_UNSUPPORTED_OPERATION, - FALSE, ev); - return; + GSList *iter; + int count = 0; + + /* We process all normal cards immediately and keep the list + ones till the end */ + + if (gci->state == 0) { + while (count < 50 && (contact = getNextLDIFEntry(gci, file))) { + if (e_contact_get (contact, E_CONTACT_IS_LIST)) { + gci->list_contacts = g_slist_prepend(gci->list_contacts, contact); + } else { + add_to_notes(contact, E_CONTACT_OFFICE); + add_to_notes(contact, E_CONTACT_SPOUSE); + add_to_notes(contact, E_CONTACT_BLOG_URL); + e_book_add_contact(gci->book, contact, NULL); + gci->contacts = g_slist_prepend(gci->contacts, contact); + } + count++; + } + if (contact == NULL) { + gci->state = 1; + gci->list_iterator = gci->list_contacts; + } } - - contact = gci->iterator->data; - if (e_contact_get (contact, E_CONTACT_IS_LIST)) - resolve_list_card (gci, contact); - else { - /* Work around the fact that these fields no longer show up in the UI */ - add_to_notes (contact, E_CONTACT_OFFICE); - add_to_notes (contact, E_CONTACT_SPOUSE); - add_to_notes (contact, E_CONTACT_BLOG_URL); + if (gci->state == 1) { + for (iter = gci->list_iterator;count < 50 && iter;iter=iter->next) { + contact = iter->data; + resolve_list_card(gci, contact); + e_book_add_contact(gci->book, contact, NULL); + count++; + } + gci->list_iterator = iter; + if (iter == NULL) + gci->state = 2; } - - /* FIXME Error checking */ - e_book_add_contact (gci->book, contact, NULL); - - gci->iterator = gci->iterator->next; - - GNOME_Evolution_ImporterListener_notifyResult (listener, - GNOME_Evolution_ImporterListener_OK, - gci->iterator ? TRUE : FALSE, - ev); - if (ev->_major != CORBA_NO_EXCEPTION) { - g_warning ("Error notifying listeners."); + if (gci->state == 2) { + ldif_import_done(gci); + return FALSE; + } else { + e_import_status(gci->import, gci->target, _("Importing ..."), ftell(gci->file) * 100 / gci->size); + return TRUE; } - - return; } static void -primary_selection_changed_cb (ESourceSelector *selector, gpointer data) +primary_selection_changed_cb (ESourceSelector *selector, EImportTarget *target) { - LDIFImporter *gci = data; - - if (gci->primary) - g_object_unref (gci->primary); - gci->primary = g_object_ref (e_source_selector_peek_primary_selection (selector)); + g_datalist_set_data_full(&target->data, "ldif-source", + g_object_ref(e_source_selector_peek_primary_selection(selector)), + g_object_unref); } -static void -create_control_fn (EvolutionImporter *importer, Bonobo_Control *control, void *closure) +static GtkWidget * +ldif_getwidget(EImport *ei, EImportTarget *target, EImportImporter *im) { - LDIFImporter *gci = closure; GtkWidget *vbox, *selector; ESource *primary; ESourceList *source_list; - - vbox = gtk_vbox_new (FALSE, FALSE); - + /* FIXME Better error handling */ if (!e_book_get_addressbooks (&source_list, NULL)) - return; + return NULL; + vbox = gtk_vbox_new (FALSE, FALSE); + selector = e_source_selector_new (source_list); e_source_selector_show_selection (E_SOURCE_SELECTOR (selector), FALSE); gtk_box_pack_start (GTK_BOX (vbox), selector, FALSE, TRUE, 6); - - /* FIXME What if no sources? */ - primary = e_source_list_peek_source_any (source_list); + + primary = g_datalist_get_data(&target->data, "ldif-source"); + if (primary == NULL) { + primary = e_source_list_peek_source_any (source_list); + g_object_ref(primary); + g_datalist_set_data_full(&target->data, "ldif-source", primary, g_object_unref); + } e_source_selector_set_primary_selection (E_SOURCE_SELECTOR (selector), primary); - if (!gci->primary) - gci->primary = g_object_ref (primary); g_object_unref (source_list); - - g_signal_connect (G_OBJECT (selector), "primary_selection_changed", - G_CALLBACK (primary_selection_changed_cb), gci); + + g_signal_connect (selector, "primary_selection_changed", G_CALLBACK (primary_selection_changed_cb), target); gtk_widget_show_all (vbox); - - *control = BONOBO_OBJREF (bonobo_control_new (vbox)); + + return vbox; } static char *supported_extensions[2] = { @@ -565,20 +535,28 @@ static char *supported_extensions[2] = { }; static gboolean -support_format_fn (EvolutionImporter *importer, - const char *filename, - void *closure) +ldif_supported(EImport *ei, EImportTarget *target, EImportImporter *im) { char *ext; int i; + EImportTargetURI *s; - ext = strrchr (filename, '.'); - if (ext == NULL) { + if (target->type != E_IMPORT_TARGET_URI) + return FALSE; + + s = (EImportTargetURI *)target; + if (s->uri_src == NULL) + return TRUE; + + if (!strncmp(s->uri_src, "file:///", 8)) + return FALSE; + + ext = strrchr(s->uri_src, '.'); + if (ext == NULL) return FALSE; - } for (i = 0; supported_extensions[i] != NULL; i++) { - if (strcmp (supported_extensions[i], ext) == 0) + if (g_ascii_strcasecmp(supported_extensions[i], ext) == 0) return TRUE; } @@ -586,70 +564,92 @@ support_format_fn (EvolutionImporter *importer, } static void -importer_destroy_cb (gpointer data, - GObject *where_object_was) +free_dn_hash(void *k, void *v, void *d) { - LDIFImporter *gci = data; + g_free(k); +} - if (gci->primary) - g_object_unref (gci->primary); - - if (gci->book) - g_object_unref (gci->book); +static void +ldif_import_done(LDIFImporter *gci) +{ + if (gci->idle_id) + g_source_remove(gci->idle_id); + + g_object_unref(gci->book); + g_slist_foreach(gci->contacts, (GFunc) g_object_unref, NULL); + g_slist_foreach(gci->list_contacts, (GFunc) g_object_unref, NULL); + g_slist_free(gci->contacts); + g_slist_free(gci->list_contacts); + g_hash_table_foreach(gci->dn_contact_hash, free_dn_hash, NULL); + g_hash_table_destroy(gci->dn_contact_hash); - g_list_foreach (gci->contactlist, (GFunc) g_object_unref, NULL); - g_list_free (gci->contactlist); + e_import_complete(gci->import, gci->target); + g_object_unref(gci->import); g_free (gci); } -static gboolean -load_file_fn (EvolutionImporter *importer, - const char *filename, - void *closure) +static void +ldif_import(EImport *ei, EImportTarget *target, EImportImporter *im) { LDIFImporter *gci; + EBook *book; + FILE *file; + EImportTargetURI *s = (EImportTargetURI *)target; - gci = (LDIFImporter *) closure; - gci->contactlist = NULL; - gci->iterator = NULL; - gci->ready = FALSE; + book = e_book_new(g_datalist_get_data(&target->data, "ldif-source"), NULL); + if (book == NULL) { + g_message(G_STRLOC ":Couldn't create EBook."); + e_import_complete(ei, target); + return; + } - /* Load the book and the cards */ - gci->book = e_book_new (gci->primary, NULL); - if (!gci->book) { - g_message (G_STRLOC ":Couldn't create EBook."); - return FALSE; + file = fopen(s->uri_src, "r"); + if (file == NULL) { + g_message(G_STRLOC ":Can't open .ldif file"); + e_import_complete(ei, target); + g_object_unref(book); + return; } - e_book_open (gci->book, TRUE, NULL); - gci->contactlist = create_contacts_from_ldif (filename); - gci->ready = TRUE; - return TRUE; + gci = g_malloc0(sizeof(*gci)); + g_datalist_set_data(&target->data, "ldif-data", gci); + gci->import = g_object_ref(ei); + gci->target = target; + gci->book = book; + gci->file = file; + gci->size = fseek(file, 0, SEEK_END); + fseek(file, 0, SEEK_SET); + gci->dn_contact_hash = g_hash_table_new(g_str_hash, g_str_equal); + + e_book_open(gci->book, TRUE, NULL); + + gci->idle_id = g_idle_add(ldif_import_contacts, gci); } - -static BonoboObject * -factory_fn (BonoboGenericFactory *_factory, - const char *component_id, - void *closure) + +static void +ldif_cancel(EImport *ei, EImportTarget *target, EImportImporter *im) { - EvolutionImporter *importer; - LDIFImporter *gci; + LDIFImporter *gci = g_datalist_get_data(&target->data, "ldif-data"); - if (!strcmp (component_id, COMPONENT_IID)) { - gci = g_new0 (LDIFImporter, 1); - importer = evolution_importer_new (create_control_fn, support_format_fn, - load_file_fn, process_item_fn, NULL, gci); - - g_object_weak_ref (G_OBJECT (importer), - importer_destroy_cb, gci); - - return BONOBO_OBJECT (importer); - } - else { - g_warning (COMPONENT_FACTORY_IID ": Don't know what to do with %s", component_id); - return NULL; - } + if (gci) + gci->state = 2; } -BONOBO_ACTIVATION_SHLIB_FACTORY (COMPONENT_FACTORY_IID, "Evolution LDIF importer Factory", factory_fn, NULL) +static EImportImporter ldif_importer = { + E_IMPORT_TARGET_URI, + 0, + ldif_supported, + ldif_getwidget, + ldif_import, + ldif_cancel, +}; + +EImportImporter * +evolution_ldif_importer_peek(void) +{ + ldif_importer.name = _("LDAP Data Interchange Format (.ldif)"); + ldif_importer.description = _("Evolution LDIF importer"); + + return &ldif_importer; +} diff --git a/addressbook/importers/evolution-vcard-importer.c b/addressbook/importers/evolution-vcard-importer.c index 8a141466eb..c53d687d26 100644 --- a/addressbook/importers/evolution-vcard-importer.c +++ b/addressbook/importers/evolution-vcard-importer.c @@ -19,7 +19,7 @@ * * Authors: Chris Toshok <toshok@ximian.com> * JP Rosevear <jpr@ximian.com> - * + * Michael Zucchi <notzed@ximian.com> */ #ifdef HAVE_CONFIG_H @@ -29,37 +29,38 @@ #include <stdio.h> #include <string.h> -#include <gtk/gtkcheckbutton.h> -#include <gtk/gtkhbox.h> #include <gtk/gtkvbox.h> -#include <gtk/gtkmain.h> -#include <gtk/gtklabel.h> -#include <gtk/gtkradiobutton.h> -#include <gtk/gtknotebook.h> -#include <bonobo/bonobo-context.h> -#include <bonobo/bonobo-shlib-factory.h> -#include <bonobo/bonobo-control.h> +#include <glib/gi18n.h> #include <libebook/e-book.h> #include <libedataserverui/e-source-selector.h> -#include <importer/evolution-importer.h> -#include <importer/GNOME_Evolution_Importer.h> #include <util/eab-book-util.h> #include <libebook/e-destination.h> -#define COMPONENT_FACTORY_IID "OAFIID:GNOME_Evolution_Addressbook_VCard_ImporterFactory:" BASE_VERSION -#define COMPONENT_IID "OAFIID:GNOME_Evolution_Addressbook_VCard_Importer:" BASE_VERSION +#include "e-util/e-import.h" + +#include "evolution-addressbook-importers.h" typedef struct { + EImport *import; + EImportTarget *target; + + guint idle_id; + + int state; /* 0 - importing, 1 - cancelled/complete */ + int total; + int count; + ESource *primary; GList *contactlist; GList *iterator; EBook *book; - gboolean ready; } VCardImporter; +static void vcard_import_done(VCardImporter *gci); + static void add_to_notes (EContact *contact, EContactField field) { @@ -84,38 +85,12 @@ add_to_notes (EContact *contact, EContactField field) g_free (new_text); } -/* EvolutionImporter methods */ static void -process_item_fn (EvolutionImporter *importer, - CORBA_Object listener, - void *closure, - CORBA_Environment *ev) +vcard_import_contact(VCardImporter *gci, EContact *contact) { - VCardImporter *gci = (VCardImporter *) closure; - EContact *contact; EContactPhoto *photo; GList *attrs, *attr; - if (gci->iterator == NULL) - gci->iterator = gci->contactlist; - - if (gci->ready == FALSE) { - GNOME_Evolution_ImporterListener_notifyResult (listener, - GNOME_Evolution_ImporterListener_NOT_READY, - gci->iterator ? TRUE : FALSE, - ev); - return; - } - - if (gci->iterator == NULL) { - GNOME_Evolution_ImporterListener_notifyResult (listener, - GNOME_Evolution_ImporterListener_UNSUPPORTED_OPERATION, - FALSE, ev); - return; - } - - contact = gci->iterator->data; - /* Apple's addressbook.app exports PHOTO's without a TYPE param, so let's figure out the format here if there's a PHOTO attribute missing a TYPE param. @@ -247,25 +222,34 @@ process_item_fn (EvolutionImporter *importer, /* FIXME Error checking */ e_book_add_contact (gci->book, contact, NULL); - - gci->iterator = gci->iterator->next; - - GNOME_Evolution_ImporterListener_notifyResult (listener, - GNOME_Evolution_ImporterListener_OK, - gci->iterator ? TRUE : FALSE, - ev); - if (ev->_major != CORBA_NO_EXCEPTION) { - g_warning ("Error notifying listeners."); - } - - return; } -static char *supported_extensions[3] = { - ".vcf", - ".gcrd", - NULL -}; +static gboolean +vcard_import_contacts(void *data) +{ + VCardImporter *gci = data; + int count = 0; + GList *iterator = gci->iterator; + + if (gci->state == 0) { + while (count < 50 && iterator) { + vcard_import_contact(gci, iterator->data); + count++; + iterator = iterator->next; + } + gci->count += count; + gci->iterator = iterator; + if (iterator == NULL) + gci->state = 1; + } + if (gci->state == 1) { + vcard_import_done(gci); + return FALSE; + } else { + e_import_status(gci->import, gci->target, _("Importing ..."), gci->count * 100 / gci->total); + return TRUE; + } +} #define BOM (gunichar2)0xFEFF #define ANTIBOM (gunichar2)0xFFFE @@ -321,7 +305,6 @@ utf16_to_utf8 (gunichar2 *utf16) return g_utf16_to_utf8 (utf16, -1, NULL, NULL, NULL); } - enum _VCardEncoding { VCARD_ENCODING_NONE, VCARD_ENCODING_UTF8, @@ -331,7 +314,6 @@ enum _VCardEncoding { typedef enum _VCardEncoding VCardEncoding; - /* Actually check the contents of this file */ static VCardEncoding guess_vcard_encoding (const char *filename) @@ -384,129 +366,123 @@ guess_vcard_encoding (const char *filename) return encoding; } -static gboolean -check_file_is_vcard (const char *filename) -{ - return guess_vcard_encoding (filename) != VCARD_ENCODING_NONE; -} - static void -primary_selection_changed_cb (ESourceSelector *selector, gpointer data) +primary_selection_changed_cb (ESourceSelector *selector, EImportTarget *target) { - VCardImporter *gci = data; - - if (gci->primary) - g_object_unref (gci->primary); - gci->primary = g_object_ref (e_source_selector_peek_primary_selection (selector)); + g_datalist_set_data_full(&target->data, "vcard-source", + g_object_ref(e_source_selector_peek_primary_selection(selector)), + g_object_unref); } -static void -create_control_fn (EvolutionImporter *importer, Bonobo_Control *control, void *closure) +static GtkWidget * +vcard_getwidget(EImport *ei, EImportTarget *target, EImportImporter *im) { - VCardImporter *gci = closure; GtkWidget *vbox, *selector; ESource *primary; ESourceList *source_list; - - vbox = gtk_vbox_new (FALSE, FALSE); - + /* FIXME Better error handling */ if (!e_book_get_addressbooks (&source_list, NULL)) - return; + return NULL; + + vbox = gtk_vbox_new (FALSE, FALSE); selector = e_source_selector_new (source_list); e_source_selector_show_selection (E_SOURCE_SELECTOR (selector), FALSE); gtk_box_pack_start (GTK_BOX (vbox), selector, FALSE, TRUE, 6); - /* FIXME What if no sources? */ - primary = e_source_list_peek_source_any (source_list); + primary = g_datalist_get_data(&target->data, "vcard-source"); + if (primary == NULL) { + primary = e_source_list_peek_source_any (source_list); + g_object_ref(primary); + g_datalist_set_data_full(&target->data, "vcard-source", primary, g_object_unref); + } e_source_selector_set_primary_selection (E_SOURCE_SELECTOR (selector), primary); - if (!gci->primary) - gci->primary = g_object_ref (primary); g_object_unref (source_list); - - g_signal_connect (G_OBJECT (selector), "primary_selection_changed", - G_CALLBACK (primary_selection_changed_cb), gci); + + g_signal_connect (selector, "primary_selection_changed", G_CALLBACK (primary_selection_changed_cb), target); gtk_widget_show_all (vbox); - - *control = BONOBO_OBJREF (bonobo_control_new (vbox)); + + return vbox; } static gboolean -support_format_fn (EvolutionImporter *importer, - const char *filename, - void *closure) +vcard_supported(EImport *ei, EImportTarget *target, EImportImporter *im) { - char *ext; - int i; + EImportTargetURI *s; - ext = strrchr (filename, '.'); - if (ext == NULL) { - return check_file_is_vcard (filename); - } - for (i = 0; supported_extensions[i] != NULL; i++) { - if (g_ascii_strcasecmp (supported_extensions[i], ext) == 0) { - return check_file_is_vcard (filename); - } - } + if (target->type != E_IMPORT_TARGET_URI) + return FALSE; + + s = (EImportTargetURI *)target; + if (s->uri_src == NULL) + return TRUE; - return FALSE; + if (!strncmp(s->uri_src, "file:///", 8)) + return FALSE; + + /* FIXME: need to parse the url properly */ + return guess_vcard_encoding(s->uri_src+7) != VCARD_ENCODING_NONE; } static void -importer_destroy_cb (gpointer data, - GObject *where_object_was) +vcard_import_done(VCardImporter *gci) { - VCardImporter *gci = data; - - if (gci->primary) - g_object_unref (gci->primary); - - if (gci->book) - g_object_unref (gci->book); + if (gci->idle_id) + g_source_remove(gci->idle_id); + g_object_unref (gci->book); g_list_foreach (gci->contactlist, (GFunc) g_object_unref, NULL); g_list_free (gci->contactlist); + e_import_complete(gci->import, gci->target); + g_object_unref(gci->import); g_free (gci); } -static gboolean -load_file_fn (EvolutionImporter *importer, - const char *filename, - void *closure) +static void +vcard_import(EImport *ei, EImportTarget *target, EImportImporter *im) { VCardImporter *gci; char *contents; VCardEncoding encoding; + EBook *book; + EImportTargetURI *s = (EImportTargetURI *)target; - encoding = guess_vcard_encoding (filename); + /* FIXME: get filename properly */ + encoding = guess_vcard_encoding(s->uri_src+7); if (encoding == VCARD_ENCODING_NONE) { - return FALSE; + /* this check is superfluous, we've already checked otherwise we can't get here ... */ + e_import_complete(ei, target); + return; } - gci = (VCardImporter *) closure; - gci->contactlist = NULL; - gci->iterator = NULL; - gci->ready = FALSE; - - /* Load the book */ - gci->book = e_book_new (gci->primary, NULL); - if (!gci->book) { - g_message (G_STRLOC ":Couldn't create EBook."); - return FALSE; + book = e_book_new(g_datalist_get_data(&target->data, "vcard-source"), NULL); + if (book == NULL) { + g_message(G_STRLOC ":Couldn't create EBook."); + e_import_complete(ei, target); + return; } - e_book_open (gci->book, TRUE, NULL); - /* Load the file and the contacts */ - if (!g_file_get_contents (filename, &contents, NULL, NULL)) { + if (!g_file_get_contents (s->uri_src+7, &contents, NULL, NULL)) { g_message (G_STRLOC ":Couldn't read file."); - return FALSE; + e_import_complete(ei, target); + g_object_unref(book); + return; } + gci = g_malloc0(sizeof(*gci)); + g_datalist_set_data(&target->data, "vcard-data", gci); + gci->import = g_object_ref(ei); + gci->target = target; + gci->book = book; + + e_book_open (gci->book, TRUE, NULL); + if (encoding == VCARD_ENCODING_UTF16) { gchar *tmp; + gunichar2 *contents_utf16 = (gunichar2*)contents; tmp = utf16_to_utf8 (contents_utf16); g_free (contents); @@ -520,33 +496,38 @@ load_file_fn (EvolutionImporter *importer, gci->contactlist = eab_contact_list_from_string (contents); g_free (contents); + gci->iterator = gci->contactlist; + gci->total = g_list_length(gci->contactlist); - gci->ready = TRUE; - - return TRUE; + if (gci->iterator) + gci->idle_id = g_idle_add(vcard_import_contacts, gci); + else + vcard_import_done(gci); } -static BonoboObject * -factory_fn (BonoboGenericFactory *_factory, - const char *component_id, - void *closure) +static void +vcard_cancel(EImport *ei, EImportTarget *target, EImportImporter *im) { - EvolutionImporter *importer; - VCardImporter *gci; + VCardImporter *gci = g_datalist_get_data(&target->data, "vcard-data"); - if (!strcmp (component_id, COMPONENT_IID)) { - gci = g_new0 (VCardImporter, 1); - importer = evolution_importer_new (create_control_fn, support_format_fn, - load_file_fn, process_item_fn, NULL, gci); - - g_object_weak_ref (G_OBJECT (importer), - importer_destroy_cb, gci); - return BONOBO_OBJECT (importer); - } - else { - g_warning (COMPONENT_FACTORY_IID ": Don't know what to do with %s", component_id); - return NULL; - } + if (gci) + gci->state = 1; } -BONOBO_ACTIVATION_SHLIB_FACTORY (COMPONENT_FACTORY_IID, "Evolution VCard Importer Factory", factory_fn, NULL) +static EImportImporter vcard_importer = { + E_IMPORT_TARGET_URI, + 0, + vcard_supported, + vcard_getwidget, + vcard_import, + vcard_cancel, +}; + +EImportImporter * +evolution_vcard_importer_peek(void) +{ + vcard_importer.name = _("VCard (.vcf, .gcrd)"); + vcard_importer.description = _("Evolution VCard Importer"); + + return &vcard_importer; +} diff --git a/calendar/ChangeLog b/calendar/ChangeLog index 98296f6a54..e0a93ee5a9 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -127,6 +127,29 @@ (event_editor_construct): Do not desensitize the attachment bar as there will be no way to open an attachement. +2005-07-06 Not Zed <NotZed@Ximian.com> + + * importers/icalendar-importer.c (ivcal_getwidget): fix a missing + init on sd. + (ivcal_getwidget): pack the notebook with fill on. + + * importers/Makefile.am: remove -module flags. + + * Makefile.am: build importers before the gui. + + * gui/main.c (initialize): register the inbuild calendar importers. + + * importers/icalendar-importer.c: Converted to eplugin, cleaned up + some stuff as well. Put the selectors in scrolledwindows so they + dont grow unbounded. + (gnome_calendar_getwidget): set the default actions based on + wether we've run or not. + (update_single_object): removed dead code? + +2005-07-05 Not Zed <NotZed@Ximian.com> + + * importers/icalendar-importer.c: start work on e-plugin importer. + 2005-06-27 Tor Lillqvist <tml@novell.com> * */Makefile.am: Prune unnecessary and nonexistent directories diff --git a/calendar/Makefile.am b/calendar/Makefile.am index 04adbea259..f9a54aff06 100644 --- a/calendar/Makefile.am +++ b/calendar/Makefile.am @@ -4,7 +4,7 @@ else CONDUIT_DIR = endif -SUBDIRS = idl common gui importers $(CONDUIT_DIR) +SUBDIRS = idl common importers gui $(CONDUIT_DIR) error_DATA = calendar.error errordir = $(privdatadir)/errors diff --git a/calendar/gui/Makefile.am b/calendar/gui/Makefile.am index 92667f7038..512278d95c 100644 --- a/calendar/gui/Makefile.am +++ b/calendar/gui/Makefile.am @@ -221,6 +221,7 @@ libevolution_calendar_la_LIBADD = \ $(top_builddir)/shell/libeshell.la \ $(top_builddir)/calendar/common/libevolution-calendarprivate.la \ $(top_builddir)/calendar/gui/dialogs/libcal-dialogs.la \ + $(top_builddir)/calendar/importers/libevolution-calendar-importers.la \ $(top_builddir)/widgets/e-timezone-dialog/libetimezonedialog.la \ $(top_builddir)/widgets/misc/libemiscwidgets.la \ $(top_builddir)/e-util/libeutil.la \ diff --git a/calendar/gui/main.c b/calendar/gui/main.c index b1b5cfdd77..e8bfbafca3 100644 --- a/calendar/gui/main.c +++ b/calendar/gui/main.c @@ -46,10 +46,12 @@ #include "tasks-component.h" #include <e-util/e-plugin.h> +#include <e-util/e-import.h> #include "e-cal-config.h" #include "e-cal-popup.h" #include "e-cal-menu.h" #include "e-cal-event.h" +#include "calendar/importers/evolution-calendar-importer.h" #define FACTORY_ID "OAFIID:GNOME_Evolution_Calendar_Factory:" BASE_VERSION @@ -131,6 +133,8 @@ launch_alarm_daemon (void) static void initialize (void) { + EImportClass *klass; + comp_editor_registry = E_COMP_EDITOR_REGISTRY (e_comp_editor_registry_new ()); #if 0 @@ -148,8 +152,12 @@ initialize (void) e_plugin_hook_register_type (e_cal_menu_hook_get_type()); e_plugin_hook_register_type (e_cal_config_hook_get_type ()); e_plugin_hook_register_type (e_cal_event_hook_get_type ()); -} + klass = g_type_class_ref(e_import_get_type()); + e_import_class_add_importer(klass, gnome_calendar_importer_peek(), NULL, NULL); + e_import_class_add_importer(klass, ical_importer_peek(), NULL, NULL); + e_import_class_add_importer(klass, vcal_importer_peek(), NULL, NULL); +} static BonoboObject * factory (BonoboGenericFactory *factory, diff --git a/calendar/importers/GNOME_Evolution_Calendar_Importer.server.in.in b/calendar/importers/GNOME_Evolution_Calendar_Importer.server.in.in deleted file mode 100644 index 4c19b9f37d..0000000000 --- a/calendar/importers/GNOME_Evolution_Calendar_Importer.server.in.in +++ /dev/null @@ -1,54 +0,0 @@ -<oaf_info> - -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_ImporterFactory:@VERSION@" - type="shlib" - location="@IMPORTERSDIR@/libevolution-calendar-importers@SOEXT@"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/ObjectFactory:1.0"/> - </oaf_attribute> - <oaf_attribute name="name" type="string" - _value="Evolution iCalendar importer"/> -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_iCalendar_Importer:@VERSION@" - type="factory" - location="OAFIID:GNOME_Evolution_Calendar_ImporterFactory:@VERSION@"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/Evolution/Importer:@VERSION@"/> - </oaf_attribute> - <oaf_attribute name="evolution:menu_name" type="string" - _value="iCalendar files (.ics)"/> - <oaf_attribute name="name" type="string" - _value="Evolution iCalendar importer"/> - -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_vCalendar_Importer:@VERSION@" - type="factory" - location="OAFIID:GNOME_Evolution_Calendar_ImporterFactory:@VERSION@"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/Evolution/Importer:@VERSION@"/> - </oaf_attribute> - <oaf_attribute name="evolution:menu_name" type="string" - _value="vCalendar files (.vcf)"/> - <oaf_attribute name="name" type="string" - _value="Evolution vCalendar importer"/> - -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Gnome_Calendar_Intelligent_Importer:@VERSION@" - type="factory" - location="OAFIID:GNOME_Evolution_Calendar_ImporterFactory:@VERSION@"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/Evolution/IntelligentImporter:@VERSION@"/> - </oaf_attribute> - - <oaf_attribute name="name" type="string" - _value="Evolution Calendar intelligent importer"/> - -</oaf_server> -</oaf_info> diff --git a/calendar/importers/Makefile.am b/calendar/importers/Makefile.am index b2c4283f85..5d84f66211 100644 --- a/calendar/importers/Makefile.am +++ b/calendar/importers/Makefile.am @@ -1,4 +1,4 @@ -importersdir = $(privlibdir)/evolution-calendar-importers +importersdir = $(privlibdir) importers_LTLIBRARIES = libevolution-calendar-importers.la @@ -6,34 +6,15 @@ INCLUDES = \ -DEVOLUTION_SOUNDDIR=\""$(soundsdir)"\" \ -DG_LOG_DOMAIN=\"Evolution-Importer\" \ -I$(top_srcdir) \ - -I$(top_builddir)/shell \ - -I$(top_srcdir)/shell \ -I$(top_srcdir)/calendar \ -I$(top_builddir)/calendar \ $(EVOLUTION_CALENDAR_CFLAGS) libevolution_calendar_importers_la_SOURCES = \ evolution-calendar-importer.h \ - icalendar-importer.c \ - main.c - -libevolution_calendar_importers_la_LDFLAGS = -avoid-version -module $(NO_UNDEFINED) + icalendar-importer.c libevolution_calendar_importers_la_LIBADD = \ - $(top_builddir)/shell/importer/libevolution-importer.la \ $(top_builddir)/e-util/libeutil.la \ $(top_builddir)/calendar/common/libevolution-calendarprivate.la \ $(EVOLUTION_CALENDAR_LIBS) - -server_in_files = GNOME_Evolution_Calendar_Importer.server.in.in -server_DATA = $(server_in_files:.server.in.in=_$(BASE_VERSION).server) -@EVO_SERVER_RULE@ -@INTLTOOL_SERVER_RULE@ - -BUILT_SOURCES = $(server_DATA) -CLEANFILES = $(BUILT_SOURCES) - -EXTRA_DIST = $(server_in_files) - -dist-hook: - cd $(distdir); rm -f $(BUILT_SOURCES) diff --git a/calendar/importers/evolution-calendar-importer.h b/calendar/importers/evolution-calendar-importer.h index 0691ee2cab..e28bff77b2 100644 --- a/calendar/importers/evolution-calendar-importer.h +++ b/calendar/importers/evolution-calendar-importer.h @@ -23,14 +23,12 @@ #ifndef EVOLUTION_CALENDAR_IMPORTER_H #define EVOLUTION_CALENDAR_IMPORTER_H -#include <bonobo/bonobo-object.h> - G_BEGIN_DECLS -BonoboObject *ical_importer_new (void); -BonoboObject *vcal_importer_new (void); +struct _EImportImporter *ical_importer_peek(void); +struct _EImportImporter *vcal_importer_peek(void); -BonoboObject *gnome_calendar_importer_new (void); +struct _EImportImporter *gnome_calendar_importer_peek(void); G_END_DECLS diff --git a/calendar/importers/icalendar-importer.c b/calendar/importers/icalendar-importer.c index d52a4a8aac..b35c08e99a 100644 --- a/calendar/importers/icalendar-importer.c +++ b/calendar/importers/icalendar-importer.c @@ -24,52 +24,48 @@ #include <config.h> #endif +#include <glib/gi18n.h> + #include <string.h> #include <unistd.h> #include <sys/types.h> #include <fcntl.h> + +#include <gtk/gtkmain.h> #include <gtk/gtkcheckbutton.h> #include <gtk/gtkhbox.h> #include <gtk/gtkvbox.h> -#include <gtk/gtkmain.h> -#include <gtk/gtklabel.h> #include <gtk/gtkradiobutton.h> #include <gtk/gtknotebook.h> -#include <libgnome/gnome-util.h> -#include <libgnome/gnome-i18n.h> -#include <bonobo/bonobo-control.h> -#include <bonobo/bonobo-exception.h> +#include <gtk/gtkscrolledwindow.h> + #include <libecal/e-cal.h> #include <libedataserverui/e-source-selector.h> -#include <importer/evolution-importer.h> -#include <importer/evolution-intelligent-importer.h> -#include <importer/GNOME_Evolution_Importer.h> #include <libical/icalvcal.h> -#include <e-util/e-dialog-widgets.h> #include "evolution-calendar-importer.h" #include "common/authentication.h" +#include "e-util/e-import.h" + /* We timeout after 2 minutes, when opening the folders. */ #define IMPORTER_TIMEOUT_SECONDS 120 - typedef struct { - EvolutionImporter *importer; + EImport *import; + EImportTarget *target; - GtkWidget *nb; - - ESource *primary; - ESourceSelector *selectors[E_CAL_SOURCE_TYPE_LAST]; + guint idle_id; ECal *client; ECalSourceType source_type; icalcomponent *icalcomp; + + int cancelled:1; } ICalImporter; typedef struct { - gboolean do_calendar; - gboolean do_tasks; + int cancelled:1; } ICalIntelligentImporter; static const int import_type_map[] = { @@ -84,26 +80,18 @@ static const char *import_type_strings[] = { NULL }; - /* * Functions shared by iCalendar & vCalendar importer. */ static void -importer_destroy_cb (gpointer user_data) +ivcal_import_done(ICalImporter *ici) { - ICalImporter *ici = (ICalImporter *) user_data; - - g_return_if_fail (ici != NULL); - - if (ici->client) - g_object_unref (ici->client); - - if (ici->icalcomp != NULL) { - icalcomponent_free (ici->icalcomp); - ici->icalcomp = NULL; - } + g_object_unref (ici->client); + icalcomponent_free (ici->icalcomp); + e_import_complete(ici->import, ici->target); + g_object_unref(ici->import); g_free (ici); } @@ -136,7 +124,6 @@ prepare_events (icalcomponent *icalcomp, GList **vtodos) } } - /* This removes all components except VTODOs and VTIMEZONEs from the toplevel icalcomponent, and adds the given list of VTODO components. The list is freed afterwards. */ @@ -167,28 +154,10 @@ prepare_tasks (icalcomponent *icalcomp, GList *vtodos) } static gboolean -update_single_object (ECal *client, icalcomponent *icalcomp) -{ - char *uid; - icalcomponent *tmp_icalcomp; - - uid = (char *) icalcomponent_get_uid (icalcomp); - - /* FIXME Shouldn't we check for RIDs here? */ - /* FIXME Should we always create a new UID? */ - if (uid && e_cal_get_object (client, uid, NULL, &tmp_icalcomp, NULL)) - return e_cal_modify_object (client, icalcomp, CALOBJ_MOD_ALL, NULL); - - return e_cal_create_object (client, icalcomp, &uid, NULL); -} - -static gboolean update_objects (ECal *client, icalcomponent *icalcomp) { - icalcomponent *subcomp; icalcomponent_kind kind; icalcomponent *vcal; - GError *error = NULL; gboolean success = TRUE; kind = icalcomponent_isa (icalcomp); @@ -214,154 +183,200 @@ update_objects (ECal *client, icalcomponent *icalcomp) return success; } +struct _selector_data { + EImportTarget *target; + GtkWidget *selector; + GtkWidget *notebook; + int page; +}; + static void -button_toggled_cb (GtkWidget *widget, gpointer data) +button_toggled_cb (GtkWidget *widget, struct _selector_data *sd) { - ICalImporter *ici = data; - - ici->source_type = e_dialog_radio_get (widget, import_type_map); - gtk_notebook_set_current_page (GTK_NOTEBOOK (ici->nb), ici->source_type); - - /* If we switched pages we have a new primary source */ - if (ici->primary) - g_object_unref (ici->primary); - ici->primary = g_object_ref (e_source_selector_peek_primary_selection (ici->selectors[ici->source_type])); + g_datalist_set_data_full(&sd->target->data, "primary-source", + g_object_ref(e_source_selector_peek_primary_selection((ESourceSelector *)sd->selector)), + g_object_unref); + g_datalist_set_data(&sd->target->data, "primary-type", GINT_TO_POINTER(import_type_map[sd->page])); + gtk_notebook_set_page((GtkNotebook *)sd->notebook, sd->page); } static void -primary_selection_changed_cb (ESourceSelector *selector, gpointer data) +primary_selection_changed_cb (ESourceSelector *selector, EImportTarget *target) { - ICalImporter *ici = data; - - if (ici->primary) - g_object_unref (ici->primary); - ici->primary = g_object_ref (e_source_selector_peek_primary_selection (selector)); + g_datalist_set_data_full(&target->data, "primary-source", + g_object_ref(e_source_selector_peek_primary_selection(selector)), + g_object_unref); } -static void -create_control_fn (EvolutionImporter *importer, Bonobo_Control *control, void *closure) +static GtkWidget * +ivcal_getwidget(EImport *ei, EImportTarget *target, EImportImporter *im) { - ICalImporter *ici = (ICalImporter *) closure; - GtkWidget *vbox, *hbox, *rb = NULL; + GtkWidget *vbox, *hbox, *first = NULL; GSList *group = NULL; - ESourceList *source_list; int i; - + GtkWidget *nb; + vbox = gtk_vbox_new (FALSE, FALSE); hbox = gtk_hbox_new (FALSE, FALSE); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 6); + nb = gtk_notebook_new (); + gtk_notebook_set_show_tabs (GTK_NOTEBOOK (nb), FALSE); + gtk_box_pack_start (GTK_BOX (vbox), nb, TRUE, TRUE, 6); + /* Type of icalendar items */ for (i = 0; import_type_map[i] != -1; i++) { - rb = gtk_radio_button_new_with_label (group, import_type_strings[i]); - gtk_box_pack_start (GTK_BOX (hbox), rb, FALSE, FALSE, 6); - g_signal_connect (G_OBJECT (rb), "toggled", G_CALLBACK (button_toggled_cb), ici); - if (!group) - group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (rb)); - } - e_dialog_radio_set (rb, import_type_map[0], import_type_map); - - /* The source selector notebook */ - ici->nb = gtk_notebook_new (); - gtk_notebook_set_show_tabs (GTK_NOTEBOOK (ici->nb), FALSE); - gtk_container_add (GTK_CONTAINER (vbox), ici->nb); - - /* The source selectors */ - for (i = 0; import_type_map[i] != -1; i++) { - GtkWidget *selector; + GtkWidget *selector, *rb; + ESourceList *source_list; ESource *primary; + GtkWidget *scrolled; + struct _selector_data *sd; /* FIXME Better error handling */ if (!e_cal_get_sources (&source_list, import_type_map[i], NULL)) - return; + continue; selector = e_source_selector_new (source_list); e_source_selector_show_selection (E_SOURCE_SELECTOR (selector), FALSE); - gtk_notebook_append_page (GTK_NOTEBOOK (ici->nb), selector, NULL); + scrolled = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_set_policy((GtkScrolledWindow *)scrolled, GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); + gtk_container_add((GtkContainer *)scrolled, selector); + gtk_notebook_append_page (GTK_NOTEBOOK (nb), scrolled, NULL); /* FIXME What if no sources? */ primary = e_source_list_peek_source_any (source_list); e_source_selector_set_primary_selection (E_SOURCE_SELECTOR (selector), primary); - if (!ici->primary) - ici->primary = g_object_ref (primary); + + g_signal_connect (selector, "primary_selection_changed", G_CALLBACK (primary_selection_changed_cb), target); + + rb = gtk_radio_button_new_with_label (group, import_type_strings[i]); + gtk_box_pack_start (GTK_BOX (hbox), rb, FALSE, FALSE, 6); + + sd = g_malloc0(sizeof(*sd)); + sd->target = target; + sd->selector = selector; + sd->notebook = nb; + sd->page = i; + g_object_set_data_full((GObject *)rb, "selector-data", sd, g_free); + g_signal_connect(G_OBJECT (rb), "toggled", G_CALLBACK (button_toggled_cb), sd); + + if (!group) + group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (rb)); + if (first == NULL) { + g_datalist_set_data_full(&target->data, "primary-source", g_object_ref(primary), g_object_unref); + g_datalist_set_data(&target->data, "primary-type", GINT_TO_POINTER(import_type_map[i])); + first = rb; + } g_object_unref (source_list); - - g_signal_connect (G_OBJECT (selector), "primary_selection_changed", - G_CALLBACK (primary_selection_changed_cb), ici); - - ici->selectors[import_type_map[i]] = E_SOURCE_SELECTOR (selector); } + if (first) + gtk_toggle_button_set_active((GtkToggleButton *)first, TRUE); gtk_widget_show_all (vbox); - - *control = BONOBO_OBJREF (bonobo_control_new (vbox)); + + return vbox; } -static void -process_item_fn (EvolutionImporter *importer, - CORBA_Object listener, - void *closure, - CORBA_Environment *ev) +static gboolean +ivcal_import_items(void *d) { - ECalLoadState state; - ICalImporter *ici = (ICalImporter *) closure; - GNOME_Evolution_ImporterListener_ImporterResult result; - - result = GNOME_Evolution_ImporterListener_OK; - - g_return_if_fail (ici != NULL); - g_return_if_fail (ici->icalcomp != NULL); - - state = e_cal_get_load_state (ici->client); - if (state == E_CAL_LOAD_LOADING) { - GNOME_Evolution_ImporterListener_notifyResult ( - listener, - GNOME_Evolution_ImporterListener_BUSY, - TRUE, ev); - return; - } else if (state != E_CAL_LOAD_LOADED) { - GNOME_Evolution_ImporterListener_notifyResult ( - listener, - GNOME_Evolution_ImporterListener_UNSUPPORTED_OPERATION, - FALSE, ev); - return; - } + ICalImporter *ici = d; switch (ici->source_type) { case E_CAL_SOURCE_TYPE_EVENT: prepare_events (ici->icalcomp, NULL); if (!update_objects (ici->client, ici->icalcomp)) - result = GNOME_Evolution_ImporterListener_BAD_DATA; + /* FIXME: e_error ... */; break; case E_CAL_SOURCE_TYPE_TODO: prepare_tasks (ici->icalcomp, NULL); if (!update_objects (ici->client, ici->icalcomp)) - result = GNOME_Evolution_ImporterListener_BAD_DATA; + /* FIXME: e_error ... */; break; default: g_assert_not_reached (); } - GNOME_Evolution_ImporterListener_notifyResult (listener, result, FALSE, ev); + ivcal_import_done(ici); + ici->idle_id = 0; + + return FALSE; +} + +static void +ivcal_opened(ECal *ecal, ECalendarStatus status, ICalImporter *ici) +{ + if (!ici->cancelled && status == E_CALENDAR_STATUS_OK) { + e_import_status(ici->import, ici->target, _("Importing ..."), 0); + ici->idle_id = g_idle_add(ivcal_import_items, ici); + } else + ivcal_import_done(ici); +} + +static void +ivcal_import(EImport *ei, EImportTarget *target, icalcomponent *icalcomp) +{ + ECal *client; + ECalSourceType type; + + type = GPOINTER_TO_INT(g_datalist_get_data(&target->data, "primary-type")); + + client = auth_new_cal_from_source (g_datalist_get_data(&target->data, "primary-source"), type); + if (client) { + ICalImporter *ici = g_malloc0(sizeof(*ici)); + + ici->import = ei; + g_datalist_set_data(&target->data, "ivcal-data", ici); + g_object_ref(ei); + ici->target = target; + ici->icalcomp = icalcomp; + ici->client = client; + ici->source_type = type; + e_import_status(ei, target, _("Opening calendar"), 0); + g_signal_connect(client, "cal-opened", G_CALLBACK(ivcal_opened), ici); + e_cal_open_async(client, TRUE); + return; + } else { + icalcomponent_free(icalcomp); + e_import_complete(ei, target); + } } +static void +ivcal_cancel(EImport *ei, EImportTarget *target, EImportImporter *im) +{ + ICalImporter *ici = g_datalist_get_data(&target->data, "ivcal-data"); + + if (ici) + ici->cancelled = 1; +} +/* ********************************************************************** */ /* * iCalendar importer functions. */ static gboolean -support_format_fn (EvolutionImporter *importer, - const char *filename, - void *closure) +ical_supported(EImport *ei, EImportTarget *target, EImportImporter *im) { - char *contents ; - icalcomponent *icalcomp; + char *contents; gboolean ret = FALSE; + EImportTargetURI *s; + + if (target->type != E_IMPORT_TARGET_URI) + return FALSE; + + s = (EImportTargetURI *)target; + if (s->uri_src == NULL) + return TRUE; + + if (strncmp(s->uri_src, "file:///", 8) != 0) + return FALSE; + + if (g_file_get_contents (s->uri_src+7, &contents, NULL, NULL)) { + icalcomponent *icalcomp; - if (g_file_get_contents (filename, &contents, NULL, NULL)) { - /* parse the file */ icalcomp = e_cal_util_parse_ics_string (contents); g_free (contents); @@ -377,78 +392,71 @@ support_format_fn (EvolutionImporter *importer, return ret; } -static gboolean -load_file_fn (EvolutionImporter *importer, - const char *filename, - void *closure) +static void +ical_import(EImport *ei, EImportTarget *target, EImportImporter *im) { char *contents; - gboolean ret = FALSE; - ICalImporter *ici = (ICalImporter *) closure; - - g_return_val_if_fail (ici != NULL, FALSE); - - if (g_file_get_contents (filename, &contents, NULL, NULL)) { - icalcomponent *icalcomp; + icalcomponent *icalcomp; + EImportTargetURI *s = (EImportTargetURI *)target; - /* parse the file */ - icalcomp = e_cal_util_parse_ics_string (contents); - g_free (contents); - - if (icalcomp) { - /* create the neccessary ECal */ - if (ici->client) - g_object_unref (ici->client); - ici->client = auth_new_cal_from_source (ici->primary, ici->source_type); - - if (ici->client) { - if (e_cal_open (ici->client, TRUE, NULL)) { - ici->icalcomp = icalcomp; - ret = TRUE; - } - } - } + /* FIXME: uri */ + if (!g_file_get_contents (s->uri_src+7, &contents, NULL, NULL)) { + e_import_complete(ei, target); + return; } - return ret; -} + icalcomp = e_cal_util_parse_ics_string (contents); + g_free (contents); -BonoboObject * -ical_importer_new (void) -{ - ICalImporter *ici; - - ici = g_new0 (ICalImporter, 1); + if (icalcomp) + ivcal_import(ei, target, icalcomp); + else + e_import_complete(ei, target); +} - ici->client = NULL; - ici->icalcomp = NULL; - ici->importer = evolution_importer_new (create_control_fn, - support_format_fn, - load_file_fn, - process_item_fn, - NULL, - ici); +static EImportImporter ical_importer = { + E_IMPORT_TARGET_URI, + 0, + ical_supported, + ivcal_getwidget, + ical_import, + ivcal_cancel, +}; - g_object_weak_ref (G_OBJECT (ici->importer), (GWeakNotify) importer_destroy_cb, ici); +EImportImporter * +ical_importer_peek(void) +{ + ical_importer.name = _("iCalendar files (.ics)"); + ical_importer.description = _("Evolution iCalendar importer"); - return BONOBO_OBJECT (ici->importer); + return &ical_importer; } - - +/* ********************************************************************** */ /* * vCalendar importer functions. */ static gboolean -vcal_support_format_fn (EvolutionImporter *importer, - const char *filename, - void *closure) +vcal_supported(EImport *ei, EImportTarget *target, EImportImporter *im) { char *contents; gboolean ret = FALSE; + EImportTargetURI *s; - if (g_file_get_contents (filename, &contents, NULL, NULL)) { + if (target->type != E_IMPORT_TARGET_URI) + return FALSE; + + s = (EImportTargetURI *)target; + if (s->uri_src == NULL) + return TRUE; + + if (strncmp(s->uri_src, "file:///", 8) != 0) + return FALSE; + + /* Z: Wow, this is *efficient* */ + + if (g_file_get_contents(s->uri_src+7, &contents, NULL, NULL)) { VObject *vcal; /* parse the file */ @@ -502,116 +510,96 @@ load_vcalendar_file (const char *filename) return icalcomp; } -static gboolean -vcal_load_file_fn (EvolutionImporter *importer, - const char *filename, - void *closure) +static void +vcal_import(EImport *ei, EImportTarget *target, EImportImporter *im) { - gboolean ret = FALSE; - ICalImporter *ici = (ICalImporter *) closure; icalcomponent *icalcomp; + EImportTargetURI *s = (EImportTargetURI *)target; - g_return_val_if_fail (ici != NULL, FALSE); - - icalcomp = load_vcalendar_file (filename); - if (icalcomp) { - /* create the neccessary ECal */ - if (ici->client) - g_object_unref (ici->client); - ici->client = auth_new_cal_from_source (ici->primary, ici->source_type); - - if (ici->client) { - if (e_cal_open (ici->client, TRUE, NULL)) { - ici->icalcomp = icalcomp; - ret = TRUE; - } - } - } - - return ret; -} - -BonoboObject * -vcal_importer_new (void) -{ - ICalImporter *ici; - - ici = g_new0 (ICalImporter, 1); - ici->icalcomp = NULL; - ici->importer = evolution_importer_new (create_control_fn, - vcal_support_format_fn, - vcal_load_file_fn, - process_item_fn, - NULL, - ici); - - g_object_weak_ref (G_OBJECT (ici->importer), (GWeakNotify) importer_destroy_cb, ici); - - return BONOBO_OBJECT (ici->importer); + /* FIXME: uri */ + icalcomp = load_vcalendar_file(s->uri_src+7); + if (icalcomp) + ivcal_import(ei, target, icalcomp); + else + e_import_complete(ei, target); } +static EImportImporter vcal_importer = { + E_IMPORT_TARGET_URI, + 0, + vcal_supported, + ivcal_getwidget, + vcal_import, + ivcal_cancel, +}; - - - - -static void -gnome_calendar_importer_destroy_cb (gpointer user_data) +EImportImporter * +vcal_importer_peek(void) { - ICalIntelligentImporter *ici = (ICalIntelligentImporter *) user_data; - - g_return_if_fail (ici != NULL); + vcal_importer.name = _("vCalendar files (.vcf)"); + vcal_importer.description = _("Evolution vCalendar importer"); - g_free (ici); + return &vcal_importer; } - +/* ********************************************************************** */ static gboolean -gnome_calendar_can_import_fn (EvolutionIntelligentImporter *ii, - void *closure) +gnome_calendar_supported(EImport *ei, EImportTarget *target, EImportImporter *im) { char *filename; - gboolean gnome_calendar_exists; + gboolean res; + EImportTargetHome *s = (EImportTargetHome *)target; + + if (target->type != E_IMPORT_TARGET_HOME) + return FALSE; - filename = gnome_util_home_file ("user-cal.vcf"); - gnome_calendar_exists = g_file_exists (filename); + filename = g_build_filename(s->homedir, "user-cal.vcf", NULL); + res = g_file_test(filename, G_FILE_TEST_IS_REGULAR); g_free (filename); - return gnome_calendar_exists; + return res; } - static void -gnome_calendar_import_data_fn (EvolutionIntelligentImporter *ii, - void *closure) +gnome_calendar_import(EImport *ei, EImportTarget *target, EImportImporter *im) { - ICalIntelligentImporter *ici = closure; icalcomponent *icalcomp = NULL; char *filename; GList *vtodos; ECal *calendar_client = NULL, *tasks_client = NULL; int t; + int do_calendar, do_tasks; + EImportTargetHome *s = (EImportTargetHome *)target; + ICalIntelligentImporter *ici; + + /* This is pretty shitty, everything runs in the gui thread and can block + for quite some time */ + + do_calendar = GPOINTER_TO_INT(g_datalist_get_data(&target->data, "gnomecal-do-cal")); + do_tasks = GPOINTER_TO_INT(g_datalist_get_data(&target->data, "gnomecal-do-tasks")); /* If neither is selected, just return. */ - if (!ici->do_calendar && !ici->do_tasks) { + if (!do_calendar && !do_tasks) return; - } + + e_import_status(ei, target, _("Opening calendar"), 0); /* Try to open the default calendar & tasks folders. */ - if (ici->do_calendar) { + if (do_calendar) { calendar_client = auth_new_cal_from_default (E_CAL_SOURCE_TYPE_EVENT); + if (!calendar_client) goto out; } - if (ici->do_tasks) { + if (do_tasks) { tasks_client = auth_new_cal_from_default (E_CAL_SOURCE_TYPE_TODO); if (!tasks_client) goto out; } /* Load the Gnome Calendar file and convert to iCalendar. */ - filename = gnome_util_home_file ("user-cal.vcf"); + filename = g_build_filename(s->homedir, "user-cal.vcf", NULL); icalcomp = load_vcalendar_file (filename); g_free (filename); @@ -619,10 +607,8 @@ gnome_calendar_import_data_fn (EvolutionIntelligentImporter *ii, if (!icalcomp) goto out; - /* - * Import the calendar events into the default calendar folder. - */ - prepare_events (icalcomp, &vtodos); + ici = g_malloc0(sizeof(*ici)); + g_datalist_set_data_full(&target->data, "gnomecal-data", ici, g_free); /* Wait for client to finish opening the calendar & tasks folders. */ for (t = 0; t < IMPORTER_TIMEOUT_SECONDS; t++) { @@ -635,34 +621,42 @@ gnome_calendar_import_data_fn (EvolutionIntelligentImporter *ii, while (gtk_events_pending ()) gtk_main_iteration (); - if (ici->do_calendar) + if (do_calendar) calendar_state = e_cal_get_load_state (calendar_client); - if (ici->do_tasks) + if (do_tasks) tasks_state = e_cal_get_load_state (tasks_client); if (calendar_state == E_CAL_LOAD_LOADED && tasks_state == E_CAL_LOAD_LOADED) break; - g_usleep (1000000); + sleep(1); + if (ici->cancelled) + goto out; } /* If we timed out, just return. */ if (t == IMPORTER_TIMEOUT_SECONDS) goto out; - /* Import the calendar events. */ - /* FIXME: What do intelligent importers do about errors? */ - if (ici->do_calendar) + e_import_status(ei, target, _("Importing ..."), 0); + + /* + * Import the calendar events into the default calendar folder. + */ + prepare_events (icalcomp, &vtodos); + if (do_calendar) update_objects (calendar_client, icalcomp); + if (ici->cancelled) + goto out; /* * Import the tasks into the default tasks folder. */ prepare_tasks (icalcomp, vtodos); - if (ici->do_tasks) + if (do_tasks) update_objects (tasks_client, icalcomp); out: @@ -672,67 +666,77 @@ gnome_calendar_import_data_fn (EvolutionIntelligentImporter *ii, g_object_unref (calendar_client); if (tasks_client) g_object_unref (tasks_client); + + e_import_complete(ei, target); } +static void +calendar_toggle_cb(GtkToggleButton *tb, EImportTarget *target) +{ + g_datalist_set_data(&target->data, "gnomecal-do-cal", GINT_TO_POINTER(gtk_toggle_button_get_active(tb))); +} -/* Fun with aggregation */ static void -checkbox_toggle_cb (GtkToggleButton *tb, - gboolean *do_item) +tasks_toggle_cb(GtkToggleButton *tb, EImportTarget *target) { - *do_item = gtk_toggle_button_get_active (tb); + g_datalist_set_data(&target->data, "gnomecal-do-tasks", GINT_TO_POINTER(gtk_toggle_button_get_active(tb))); } -static BonoboControl * -create_checkboxes_control (ICalIntelligentImporter *ici) +static GtkWidget * +gnome_calendar_getwidget(EImport *ei, EImportTarget *target, EImportImporter *im) { - GtkWidget *hbox, *calendar_checkbox, *tasks_checkbox; - BonoboControl *control; + GtkWidget *hbox, *w; + GConfClient *gconf; + gboolean done_cal, done_tasks; + + gconf = gconf_client_get_default (); + done_cal = gconf_client_get_bool (gconf, "/apps/evolution/importer/gnome-calendar/calendar", NULL); + done_tasks = gconf_client_get_bool (gconf, "/apps/evolution/importer/gnome-calendar/tasks", NULL); + g_object_unref(gconf); + + g_datalist_set_data(&target->data, "gnomecal-do-cal", GINT_TO_POINTER(!done_cal)); + g_datalist_set_data(&target->data, "gnomecal-do-tasks", GINT_TO_POINTER(!done_tasks)); hbox = gtk_hbox_new (FALSE, 2); - calendar_checkbox = gtk_check_button_new_with_label (_("Calendar Events")); - g_signal_connect (G_OBJECT (calendar_checkbox), "toggled", - G_CALLBACK (checkbox_toggle_cb), - &ici->do_calendar); - gtk_box_pack_start (GTK_BOX (hbox), calendar_checkbox, - FALSE, FALSE, 0); + w = gtk_check_button_new_with_label (_("Calendar Events")); + gtk_toggle_button_set_active((GtkToggleButton *)w, !done_cal); + g_signal_connect (w, "toggled", G_CALLBACK (calendar_toggle_cb), target); + gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0); - tasks_checkbox = gtk_check_button_new_with_label (_("Tasks")); - g_signal_connect (G_OBJECT (tasks_checkbox), "toggled", - G_CALLBACK (checkbox_toggle_cb), - &ici->do_tasks); - gtk_box_pack_start (GTK_BOX (hbox), tasks_checkbox, - FALSE, FALSE, 0); + w = gtk_check_button_new_with_label (_("Tasks")); + gtk_toggle_button_set_active((GtkToggleButton *)w, !done_tasks); + g_signal_connect (w, "toggled", G_CALLBACK (tasks_toggle_cb), target); + gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0); gtk_widget_show_all (hbox); - control = bonobo_control_new (hbox); - return control; + + return hbox; } -BonoboObject * -gnome_calendar_importer_new (void) +static void +gnome_calendar_cancel(EImport *ei, EImportTarget *target, EImportImporter *im) { - EvolutionIntelligentImporter *importer; - ICalIntelligentImporter *ici; - BonoboControl *control; - char *message = N_("Evolution has found Gnome Calendar files.\n" - "Would you like to import them into Evolution?"); - - ici = g_new0 (ICalIntelligentImporter, 1); - - importer = evolution_intelligent_importer_new (gnome_calendar_can_import_fn, - gnome_calendar_import_data_fn, - _("Gnome Calendar"), - _(message), - ici); + ICalIntelligentImporter *ici = g_datalist_get_data(&target->data, "gnomecal-data"); + if (ici) + ici->cancelled = 1; +} - g_object_weak_ref (G_OBJECT (importer), (GWeakNotify) gnome_calendar_importer_destroy_cb, ici); +static EImportImporter gnome_calendar_importer = { + E_IMPORT_TARGET_HOME, + 0, + gnome_calendar_supported, + gnome_calendar_getwidget, + gnome_calendar_import, + gnome_calendar_cancel, +}; - control = create_checkboxes_control (ici); - bonobo_object_add_interface (BONOBO_OBJECT (importer), - BONOBO_OBJECT (control)); +EImportImporter * +gnome_calendar_importer_peek(void) +{ + gnome_calendar_importer.name = _("Gnome Calendar"); + gnome_calendar_importer.description = _("Evolution Calendar intelligent importer"); - return BONOBO_OBJECT (importer); + return &gnome_calendar_importer; } diff --git a/e-util/ChangeLog b/e-util/ChangeLog index bdde3b3347..c80f44b93a 100644 --- a/e-util/ChangeLog +++ b/e-util/ChangeLog @@ -11,6 +11,17 @@ * e-util/e-account-list.[ch]: Add functions to remove proxy accounts and account's proxies. +2005-07-06 Not Zed <NotZed@Ximian.com> + + * e-import.c (e_import_status): added callback for importers to + report status. + (e_import_cancel): added function for driver to abort an import. + (eih_cancel): implemented for hook. + +2005-07-05 Not Zed <NotZed@Ximian.com> + + * e-import.c: cleaned up/finished api. + 2005-06-18 Tor Lillqvist <tml@novell.com> * Makefile.am (WIN32_BOOTSTRAP_LIBS): Use bootstrap library for diff --git a/e-util/e-error.h b/e-util/e-error.h index fe097656ab..a09f7b4236 100644 --- a/e-util/e-error.h +++ b/e-util/e-error.h @@ -33,6 +33,8 @@ struct _GtkWindow; * Several more basic ones are needed. */ +#define E_ERROR_INFO "builtin:info" +#define E_ERROR_INFO_PRIMARY "builtin:info-primary" #define E_ERROR_WARNING "builtin:warning" #define E_ERROR_WARNING_PRIMARY "builtin:warning-primary" #define E_ERROR_ERROR "builtin:error" diff --git a/e-util/e-import.c b/e-util/e-import.c index 717805203e..042dd53680 100644 --- a/e-util/e-import.c +++ b/e-util/e-import.c @@ -106,37 +106,12 @@ ec_target_free(EImport *ep, EImportTarget *t) break; } } + g_datalist_clear(&t->data); g_free(t); g_object_unref(ep); } static void -ec_set_target(EImport *emp, EImportTarget *target) -{ - EImportClass *k = (EImportClass *)G_OBJECT_GET_CLASS(emp); - struct _EImportImporters *ei; - - if (emp->target) - e_import_target_free(emp, target); - - emp->target = target; - emp->importer = NULL; - - if (target== NULL) - return; - - for (ei = (struct _EImportImporters *)k->importers.head; - ei->next; - ei = ei->next) { - if (ei->importer->type == target->type - && ei->importer->supported(emp, ei->importer, ei->importer->user_data)) { - emp->importer = ei->importer; - break; - } - } -} - -static void ep_class_init(GObjectClass *klass) { d(printf("EImport class init %p '%s'\n", klass, g_type_name(((GObjectClass *)klass)->g_type_class.g_type))); @@ -144,7 +119,6 @@ ep_class_init(GObjectClass *klass) g_type_class_add_private(klass, sizeof(struct _EImportPrivate)); klass->finalize = ep_finalise; - ((EImportClass *)klass)->set_target = ec_set_target; ((EImportClass *)klass)->target_free = ec_target_free; } @@ -198,10 +172,20 @@ EImport *e_import_construct(EImport *ep, const char *id) return ep; } +EImport *e_import_new(const char *id) +{ + EImport *ei = g_object_new(e_import_get_type(), NULL); + + return e_import_construct(ei, id); +} + /** * e_import_import: * @ei: - * @done: + * @t: Target to import. + * @im: Importer to use. + * @status: Status callback, called with progress information. + * @done: Complete callback, will always be called once complete. * @data: * * Run the import function of the selected importer. Once the @@ -212,66 +196,64 @@ EImport *e_import_construct(EImport *ep, const char *id) * When complete, the @done callback will be called. **/ void -e_import_import(EImport *ei, EImportCompleteFunc done, void *data) +e_import_import(EImport *ei, EImportTarget *t, EImportImporter *im, EImportStatusFunc status, EImportCompleteFunc done, void *data) { - g_return_if_fail(ei->importer != NULL); - g_return_if_fail(ei->target != NULL); + g_return_if_fail(im != NULL); + g_return_if_fail(im != NULL); + ei->status = status; ei->done = done; ei->done_data = data; - ei->importer->import(ei, ei->importer, ei->importer->user_data); + im->import(ei, t, im); +} + +void e_import_cancel(EImport *ei, EImportTarget *t, EImportImporter *im) +{ + if (im->cancel) + im->cancel(ei, t, im); } /** * e_import_get_widget: - * @ei: An import object on which the target has been set. + * @ei: + * @target: Target of interest + * @im: Importer to get widget of * * Gets a widget that the importer uses to configure its * destination. This widget should be packed into a container - * widget. + * widget. It should not be shown_all. * * Return value: NULL if the importer doesn't support/require * a destination. **/ struct _GtkWidget * -e_import_get_widget(EImport *ei) +e_import_get_widget(EImport *ei, EImportTarget *target, EImportImporter *im) { - g_return_val_if_fail(ei->importer != NULL, NULL); - g_return_val_if_fail(ei->target != NULL, NULL); + g_return_val_if_fail(im != NULL, NULL); + g_return_val_if_fail(target != NULL, NULL); - return ei->importer->get_widget(ei, ei->importer, ei->importer->user_data); + return im->get_widget(ei, target, im); } /** * e_import_complete: * @ei: + * @target: Target just completed (unused currently) * * Signify that an import is complete. This must be called by * importer implementations when they are done. **/ -void e_import_complete(EImport *ei) +void e_import_complete(EImport *ei, EImportTarget *target) { if (ei->done) ei->done(ei, ei->done_data); } -/** - * e_import_set_target: - * @emp: An initialised EImport. - * @target: A target allocated from @emp. - * - * Sets the target object for the import window. Generally the target - * is set only once, and will supply its own "changed" signal which - * can be used to drive the modal. This is a virtual method so that - * the implementing class can connect to the changed signal and - * initiate a e_import_target_changed() call where appropriate. - **/ -void -e_import_set_target(EImport *emp, EImportTarget *target) +void e_import_status(EImport *ei, EImportTarget *target, const char *what, int pc) { - if (emp->target != target) - ((EImportClass *)G_OBJECT_GET_CLASS(emp))->set_target(emp, target); + if (ei->status) + ei->status(ei, what, pc, ei->done_data); } /** @@ -280,8 +262,9 @@ e_import_set_target(EImport *emp, EImportTarget *target) * @target: * * Get a list of importers. If @target is supplied, then only - * importers which support the location specified by the target are - * listed. If @target is NULL, then all importers are listed. + * importers which support the type and location specified by the + * target are listed. If @target is NULL, then all importers are + * listed. * * Return value: A list of importers. The list should be freed when * no longer needed. @@ -298,9 +281,8 @@ e_import_get_importers(EImport *emp, EImportTarget *target) ei = ei->next) { if (target == NULL || (ei->importer->type == target->type - && ei->importer->supported(emp, ei->importer, ei->importer->user_data))) { + && ei->importer->supported(emp, target, ei->importer))) { importers = g_slist_append(importers, ei->importer); - break; } } @@ -334,10 +316,14 @@ e_import_class_add_importer(EImportClass *klass, EImportImporter *importer, EImp en = en->next; } - node->next = ei->next; - node->next->prev = node; - node->prev = ei; - ei->next = node; + if (en == NULL) + e_dlist_addtail(&klass->importers, (EDListNode *)node); + else { + node->next = ei->next; + node->next->prev = node; + node->prev = ei; + ei->next = node; + } } void e_import_class_remove_importer(EImportClass *klass, EImportImporter *f) @@ -377,6 +363,7 @@ void *e_import_target_new(EImport *ep, int type, size_t size) t->import = ep; g_object_ref(ep); t->type = type; + g_datalist_init(&t->data); return t; } @@ -452,32 +439,40 @@ static const EImportHookTargetMask eih_no_masks[] = { static const EImportHookTargetMap eih_targets[] = { { "uri", E_IMPORT_TARGET_URI, eih_no_masks }, - { "home", E_IMPORT_TARGET_URI, eih_no_masks }, + { "home", E_IMPORT_TARGET_HOME, eih_no_masks }, { 0 } }; -static gboolean eih_supported(EImport *ei, EImportImporter *im, void *data) +static gboolean eih_supported(EImport *ei, EImportTarget *target, EImportImporter *im) +{ + struct _EImportHookImporter *ihook = (EImportHookImporter *)im; + EImportHook *hook = im->user_data; + + return e_plugin_invoke(hook->hook.plugin, ihook->supported, target) != NULL; +} + +static struct _GtkWidget *eih_get_widget(EImport *ei, EImportTarget *target, EImportImporter *im) { struct _EImportHookImporter *ihook = (EImportHookImporter *)im; EImportHook *hook = im->user_data; - return e_plugin_invoke(hook->hook.plugin, ihook->supported, ei) != NULL; + return e_plugin_invoke(hook->hook.plugin, ihook->get_widget, target); } -static struct _GtkWidget *eih_get_widget(EImport *ei, EImportImporter *im, void *data) +static void eih_import(EImport *ei, EImportTarget *target, EImportImporter *im) { struct _EImportHookImporter *ihook = (EImportHookImporter *)im; EImportHook *hook = im->user_data; - return e_plugin_invoke(hook->hook.plugin, ihook->get_widget, ei); + e_plugin_invoke(hook->hook.plugin, ihook->import, target); } -static void eih_import(EImport *ei, EImportImporter *im, void *data) +static void eih_cancel(EImport *ei, EImportTarget *target, EImportImporter *im) { struct _EImportHookImporter *ihook = (EImportHookImporter *)im; EImportHook *hook = im->user_data; - e_plugin_invoke(hook->hook.plugin, ihook->import, ei); + e_plugin_invoke(hook->hook.plugin, ihook->cancel, target); } static void @@ -514,6 +509,7 @@ emph_construct_importer(EPluginHook *eph, xmlNodePtr root) item->supported = e_plugin_xml_prop(root, "supported"); item->get_widget = e_plugin_xml_prop(root, "get-widget"); item->import = e_plugin_xml_prop(root, "import"); + item->cancel = e_plugin_xml_prop(root, "cancel"); item->importer.name = e_plugin_xml_prop(root, "name"); item->importer.description = e_plugin_xml_prop(root, "description"); @@ -527,6 +523,8 @@ emph_construct_importer(EPluginHook *eph, xmlNodePtr root) item->importer.import = eih_import; if (item->get_widget) item->importer.get_widget = eih_get_widget; + if (item->cancel) + item->importer.cancel = eih_cancel; return item; error: @@ -585,7 +583,6 @@ emph_class_init(EPluginHookClass *klass) ((GObjectClass *)klass)->finalize = emph_finalise; klass->construct = emph_construct; - /* this is actually an abstract implementation but list it anyway */ klass->id = "org.gnome.evolution.import:1.0"; d(printf("EImportHook: init class %p '%s'\n", klass, g_type_name(((GObjectClass *)klass)->g_type_class.g_type))); diff --git a/e-util/e-import.h b/e-util/e-import.h index e5bf9b393a..4d913c232b 100644 --- a/e-util/e-import.h +++ b/e-util/e-import.h @@ -44,12 +44,13 @@ typedef struct _EImportFactory EImportFactory; typedef struct _EImportTarget EImportTarget; typedef void (*EImportCompleteFunc)(EImport *ei, void *data); +typedef void (*EImportStatusFunc)(EImport *ei, const char *what, int pc, void *data); typedef void (*EImportFactoryFunc)(EImport *ei, void *data); typedef void (*EImportImporterFunc)(EImportImporter *importer, void *data); -typedef gboolean (*EImportSupportedFunc)(EImport *ei, EImportImporter *im, void *data); -typedef struct _GtkWidget *(*EImportWidgetFunc)(EImport *ei, EImportImporter *im, void *data); -typedef void (*EImportImportFunc)(EImport *ei, EImportImporter *im, void *data); +typedef gboolean (*EImportSupportedFunc)(EImport *ei, EImportTarget *, EImportImporter *im); +typedef struct _GtkWidget *(*EImportWidgetFunc)(EImport *ei, EImportTarget *, EImportImporter *im); +typedef void (*EImportImportFunc)(EImport *ei, EImportTarget *, EImportImporter *im); /* The global target types, implementors may add additional ones */ enum _e_import_target_t { @@ -78,6 +79,7 @@ struct _EImportImporter { EImportSupportedFunc supported; EImportWidgetFunc get_widget; EImportImportFunc import; + EImportImportFunc cancel; void *user_data; @@ -91,6 +93,9 @@ struct _EImportImporter { * * @import: The parent object. * @type: The type of target, defined by implementing classes. + * @data: This can be used to store run-time information + * about this target. Any allocated data must be set so + * as to free it when the target is freed. * * The base target object is used as the parent and placeholder for * import context for a given importer. @@ -100,6 +105,8 @@ struct _EImportTarget { guint32 type; + GData *data; + /* implementation fields follow, depends on target type */ }; @@ -124,8 +131,9 @@ struct _EImportTargetHome { * * @object: Superclass. * @id: ID of importer. - * @target: The current target. - * @importer: The chosen importer for the target. + * @status: Status callback of current running import. + * @done: Completion callback of current running import. + * @done_data: Callback data for both of above. * **/ struct _EImport { @@ -133,9 +141,7 @@ struct _EImport { char *id; - EImportTarget *target; - EImportImporter *importer; - + EImportStatusFunc status; EImportCompleteFunc done; void *done_data; }; @@ -158,12 +164,13 @@ struct _EImportClass { EDList importers; - void (*set_target)(EImport *ep, EImportTarget *t); void (*target_free)(EImport *ep, EImportTarget *t); }; GType e_import_get_type(void); +EImport *e_import_new(const char *id); + /* Static class methods */ void e_import_class_add_importer(EImportClass *klass, EImportImporter *importer, EImportImporterFunc freefunc, void *data); void e_import_class_remove_importer(EImportClass *klass, EImportImporter *f); @@ -171,13 +178,14 @@ void e_import_class_remove_importer(EImportClass *klass, EImportImporter *f); GSList *e_import_get_importers(EImport *emp, EImportTarget *target); EImport *e_import_construct(EImport *, const char *id); -void e_import_import(EImport *ei, EImportCompleteFunc done, void *data); -struct _GtkWidget *e_import_get_widget(EImport *ei); +void e_import_import(EImport *ei, EImportTarget *, EImportImporter *, EImportStatusFunc status, EImportCompleteFunc done, void *data); +void e_import_cancel(EImport *, EImportTarget *, EImportImporter *); + +struct _GtkWidget *e_import_get_widget(EImport *ei, EImportTarget *, EImportImporter *); -void e_import_set_target(EImport *emp, EImportTarget *target); -struct _GtkWidget *e_import_create_window(EImport *emp, struct _GtkWindow *parent, const char *title); -void e_import_complete(EImport *); +void e_import_status(EImport *, EImportTarget *, const char *what, int pc); +void e_import_complete(EImport *, EImportTarget *); void *e_import_target_new(EImport *ep, int type, size_t size); void e_import_target_free(EImport *ep, void *o); @@ -210,6 +218,7 @@ struct _EImportHookImporter { char *supported; char *get_widget; char *import; + char *cancel; }; /** diff --git a/mail/ChangeLog b/mail/ChangeLog index 810b854133..0cdd62fcf9 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -52,6 +52,27 @@ * mail-component.c: (handleuri_got_folder): Added "forward" command-line option. +2005-07-06 Not Zed <NotZed@Ximian.com> + + * importers/evolution-mbox-importer.c (mbox_getwidget): wrap the + widgets in another vbox so they display properly. + + * importers/pine-importer.c (pine_getwidget): pack the 'mail' + widget. + + * importers/pine-importer.c (pine_import): + importers/elm-importer.c (elm_import): + importers/evolution-mbox-importer.c (mbox_import): Dont create + widgets anymore, report progress through the EImport and handle + cancel. + +2005-07-01 Not Zed <NotZed@Ximian.com> + + * importers/Makefile.am: remove shell/importer link & take out + netscape & outlook temporarily. + + * Makefile.am: Removed importer link. + 2005-06-24 Matt Brown <matt@mattb.net.nz> * em-inline-filter.c: implement extraction of inline signed/encrypted pgp diff --git a/mail/Makefile.am b/mail/Makefile.am index 9e4cafdc2d..779ccb34d8 100644 --- a/mail/Makefile.am +++ b/mail/Makefile.am @@ -11,8 +11,6 @@ INCLUDES = \ -I$(top_builddir)/composer \ -I$(top_builddir)/shell \ -I$(top_srcdir)/shell \ - -I$(top_srcdir)/shell/importer \ - -I$(top_builddir)/shell/importer \ -I$(top_srcdir)/smime/lib \ -I$(top_srcdir)/smime/gui \ $(EVOLUTION_MAIL_CFLAGS) \ @@ -211,7 +209,6 @@ SMIME_LIB=$(top_builddir)/smime/gui/libevolution-smime.la endif libevolution_mail_la_LIBADD = \ - $(top_builddir)/shell/importer/libevolution-importer.la \ $(top_builddir)/mail/importers/libevolution-mail-importers.la\ $(top_builddir)/e-util/libeutil.la \ $(top_builddir)/shell/libeshell.la \ diff --git a/mail/importers/GNOME_Evolution_Mail_Importers.server.in.in b/mail/importers/GNOME_Evolution_Mail_Importers.server.in.in deleted file mode 100644 index e3c5f91e6b..0000000000 --- a/mail/importers/GNOME_Evolution_Mail_Importers.server.in.in +++ /dev/null @@ -1,66 +0,0 @@ -<oaf_info> - -<oaf_server iid="OAFIID:GNOME_Evolution_Mail_Elm_Intelligent_Importer:@VERSION@" - type="factory" - location="OAFIID:GNOME_Evolution_Mail_Factory:@VERSION@"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/Evolution/IntelligentImporter:@VERSION@"/> - </oaf_attribute> - - <oaf_attribute name="name" type="string" - _value="Evolution Elm importer"/> -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Mail_Mbox_Importer:@VERSION@" - type="factory" - location="OAFIID:GNOME_Evolution_Mail_Factory:@VERSION@"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/Evolution/Importer:@VERSION@"/> - </oaf_attribute> - - <oaf_attribute name="evolution:menu_name" type="string" - _value="MBox (mbox)"/> - <oaf_attribute name="name" type="string" - _value="Evolution mbox importer"/> -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Mail_Netscape_Intelligent_Importer:@VERSION@" - type="factory" - location="OAFIID:GNOME_Evolution_Mail_Factory:@VERSION@"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/Evolution/IntelligentImporter:@VERSION@"/> - </oaf_attribute> - - <oaf_attribute name="name" type="string" - _value="Evolution Netscape Mail importer"/> -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Mail_Outlook_Importer:@VERSION@" - type="factory" - location="OAFIID:GNOME_Evolution_Mail_Factory:@VERSION@"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/Evolution/Importer:@VERSION@"/> - </oaf_attribute> - - <oaf_attribute name="evolution:menu_name" type="string" - _value="Outlook Express 4 (.mbx)"/> - <oaf_attribute name="name" type="string" - _value="Evolution Outlook Express 4 importer"/> -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Mail_Pine_Intelligent_Importer:@VERSION@" - type="factory" - location="OAFIID:GNOME_Evolution_Mail_Factory:@VERSION@"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/Evolution/IntelligentImporter:@VERSION@"/> - </oaf_attribute> - - <oaf_attribute name="name" type="string" - _value="Evolution Pine importer"/> -</oaf_server> -</oaf_info> diff --git a/mail/importers/Makefile.am b/mail/importers/Makefile.am index f567e6e0db..b33c7e4265 100644 --- a/mail/importers/Makefile.am +++ b/mail/importers/Makefile.am @@ -4,8 +4,6 @@ privlib_LTLIBRARIES = libevolution-mail-importers.la INCLUDES = -I.. \ -I$(srcdir)/.. \ -I$(top_srcdir) \ - -I$(top_srcdir)/shell \ - -I$(top_builddir)/shell \ -DG_LOG_DOMAIN=\"evolution-mail-importer\" \ -I$(top_srcdir)/addressbook/backend \ -I$(top_builddir)/addressbook/backend \ @@ -17,27 +15,13 @@ libevolution_mail_importers_la_SOURCES = \ mail-importer.h \ elm-importer.c \ pine-importer.c \ - netscape-importer.c \ - evolution-outlook-importer.c \ evolution-mbox-importer.c +# these haven't been converted to plugins yet +# netscape-importer.c +# evolution-outlook-importer.c + libevolution_mail_importers_la_LIBADD = \ - $(top_builddir)/shell/importer/libevolution-importer.la \ $(top_builddir)/e-util/libeutil.la \ $(top_builddir)/filter/libfilter.la \ - $(top_builddir)/shell/libeshell.la \ $(IMPORTERS_LIBS) - -server_in_files = \ - GNOME_Evolution_Mail_Importers.server.in.in -server_DATA = $(server_in_files:.server.in.in=_$(BASE_VERSION).server) -@EVO_SERVER_RULE@ -@INTLTOOL_SERVER_RULE@ - -BUILT_SOURCES = $(server_DATA) -CLEANFILES = $(BUILT_SOURCES) - -EXTRA_DIST = $(server_in_files) - -dist-hook: - cd $(distdir); rm -f $(BUILT_SOURCES) diff --git a/mail/importers/elm-importer.c b/mail/importers/elm-importer.c index 2793f58f50..7d8abdfa04 100644 --- a/mail/importers/elm-importer.c +++ b/mail/importers/elm-importer.c @@ -31,107 +31,51 @@ #include <sys/stat.h> #include <unistd.h> #include <dirent.h> +#include <string.h> #include <glib.h> -#include <gnome.h> +#include <glib/gi18n.h> +#include <gtk/gtkvbox.h> +#include <gtk/gtkcheckbutton.h> -#include <gconf/gconf.h> #include <gconf/gconf-client.h> #include <camel/camel-operation.h> -#include <bonobo/bonobo-object.h> -#include <bonobo/bonobo-control.h> - -#include <importer/evolution-intelligent-importer.h> -#include <importer/evolution-importer-client.h> -#include <importer/GNOME_Evolution_Importer.h> - #include "mail-importer.h" #include "mail/mail-mt.h" +#include "e-util/e-import.h" +#include "e-util/e-error.h" -#define KEY "elm-mail-imported" - -/*#define SUPER_IMPORTER_DEBUG*/ -#ifdef SUPER_IMPORTER_DEBUG #define d(x) x -#else -#define d(x) -#endif -typedef struct { - EvolutionIntelligentImporter *ii; +struct _elm_import_msg { + struct _mail_msg msg; - GHashTable *prefs; + EImport *import; + EImportTargetHome *target; GMutex *status_lock; char *status_what; int status_pc; int status_timeout_id; - CamelOperation *cancel; /* cancel/status port */ - - GtkWidget *mail; - gboolean do_mail; - gboolean done_mail; - - GtkWidget *dialog; - GtkWidget *label; - GtkWidget *progressbar; -} ElmImporter; - -static GtkWidget * -create_importer_gui (ElmImporter *importer) -{ - GtkWidget *dialog; - - dialog = gnome_message_box_new (_("Evolution is importing your old Elm mail"), GNOME_MESSAGE_BOX_INFO, NULL); - gtk_window_set_title (GTK_WINDOW (dialog), _("Importing...")); - - importer->label = gtk_label_new (_("Please wait")); - importer->progressbar = gtk_progress_bar_new (); - gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), importer->label, FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), importer->progressbar, FALSE, FALSE, 0); - - return dialog; -} - -static void -elm_store_settings (ElmImporter *importer) -{ - GConfClient *gconf; - - gconf = gconf_client_get_default (); - gconf_client_set_bool (gconf, "/apps/evolution/importer/elm/mail", importer->done_mail, NULL); - g_object_unref(gconf); -} - -static void -elm_restore_settings (ElmImporter *importer) -{ - GConfClient *gconf = gconf_client_get_default (); - - importer->done_mail = gconf_client_get_bool (gconf, "/apps/evolution/importer/elm/mail", NULL); - g_object_unref(gconf); -} + CamelOperation *status; +}; -static void -parse_elm_rc(ElmImporter *importer, const char *elmrc) +static GHashTable * +parse_elm_rc(const char *elmrc) { char line[4096]; FILE *handle; + GHashTable *prefs = g_hash_table_new(g_str_hash, g_str_equal); - if (importer->prefs) - return; - - importer->prefs = g_hash_table_new(g_str_hash, g_str_equal); - - if (!g_file_exists(elmrc)) - return; + if (!g_file_test(elmrc, G_FILE_TEST_IS_REGULAR)) + return prefs; handle = fopen (elmrc, "r"); if (handle == NULL) - return; + return prefs; while (fgets (line, 4096, handle) != NULL) { char *linestart, *end; @@ -167,77 +111,82 @@ parse_elm_rc(ElmImporter *importer, const char *elmrc) *end = 0; value = g_strdup (linestart); - g_hash_table_insert (importer->prefs, key, value); + g_hash_table_insert(prefs, key, value); } fclose (handle); + + return prefs; +} + +static void +elm_free_rc_item(void *k, void *v, void *d) +{ + g_free(k); + g_free(v); +} + +static void +elm_free_rc(void *prefs) +{ + g_hash_table_foreach(prefs, elm_free_rc_item, NULL); } static char * -elm_get_rc_value(ElmImporter *importer, const char *value) +elm_get_rc(EImport *ei, const char *name) { - return g_hash_table_lookup(importer->prefs, value); + GHashTable *prefs; + char *elmrc; + + prefs = g_object_get_data((GObject *)ei, "elm-rc"); + if (prefs == NULL) { + elmrc = g_build_filename(g_get_home_dir(), ".elm/elmrc", NULL); + prefs = parse_elm_rc(elmrc); + g_free(elmrc); + g_object_set_data_full((GObject *)ei, "elm-rc", prefs, elm_free_rc); + } + + if (prefs == NULL) + return NULL; + else + return g_hash_table_lookup(prefs, name); } static gboolean -elm_can_import(EvolutionIntelligentImporter *ii, void *closure) +elm_supported(EImport *ei, EImportTarget *target, EImportImporter *im) { - ElmImporter *importer = closure; + EImportTargetHome *s; const char *maildir; - char *elmdir, *elmrc; + char *elmdir; gboolean mailexists, exists; -#if 0 - char *aliasfile; - gboolean aliasexists; -#endif struct stat st; - elm_restore_settings(importer); + if (target->type != E_IMPORT_TARGET_HOME) + return FALSE; - importer->do_mail = !importer->done_mail; - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (importer->mail), importer->do_mail); - - elmdir = g_build_filename(g_get_home_dir(), ".elm", NULL); + s = (EImportTargetHome *)target; + + elmdir = g_build_filename(s->homedir, ".elm", NULL); exists = lstat(elmdir, &st) == 0 && S_ISDIR(st.st_mode); - g_free (elmdir); + g_free(elmdir); if (!exists) return FALSE; - elmrc = g_build_filename(g_get_home_dir(), ".elm/elmrc", NULL); - parse_elm_rc (importer, elmrc); - g_free(elmrc); - - maildir = elm_get_rc_value(importer, "maildir"); + maildir = elm_get_rc(ei, "maildir"); if (maildir == NULL) maildir = "Mail"; - if (!g_path_is_absolute (maildir)) - elmdir = g_build_filename(g_get_home_dir(), maildir, NULL); + if (!g_path_is_absolute(maildir)) + elmdir = g_build_filename(s->homedir, maildir, NULL); else elmdir = g_strdup (maildir); mailexists = lstat(elmdir, &st) == 0 && S_ISDIR(st.st_mode); g_free (elmdir); -#if 0 - aliasfile = gnome_util_prepend_user_home (".elm/aliases"); - aliasexists = lstat(aliasfile, &st) == 0 && S_ISREG(st.st_mode); - g_free (aliasfile); - - exists = (aliasexists || mailexists); -#endif - return mailexists; } -/* Almost all that follows is a direct copy of pine-importer.c with - * search and replace run on it */ -struct _elm_import_msg { - struct _mail_msg msg; - - ElmImporter *importer; -}; - static char * elm_import_describe (struct _mail_msg *mm, int complete) { @@ -253,62 +202,60 @@ static void elm_import_import(struct _mail_msg *mm) { struct _elm_import_msg *m = (struct _elm_import_msg *) mm; + const char *maildir; + char *elmdir; - if (m->importer->do_mail) { - const char *maildir; - char *elmdir; + maildir = elm_get_rc(m->import, "maildir"); + if (maildir == NULL) + maildir = "Mail"; - maildir = elm_get_rc_value(m->importer, "maildir"); - if (maildir == NULL) - maildir = "Mail"; - - if (!g_path_is_absolute(maildir)) - elmdir = g_build_filename(g_get_home_dir(), maildir, NULL); - else - elmdir = g_strdup(maildir); + if (!g_path_is_absolute(maildir)) + elmdir = g_build_filename(m->target->homedir, maildir, NULL); + else + elmdir = g_strdup(maildir); - mail_importer_import_folders_sync(elmdir, elm_special_folders, 0, m->importer->cancel); - } + mail_importer_import_folders_sync(elmdir, elm_special_folders, 0, m->status); + g_free(elmdir); } static void elm_import_imported(struct _mail_msg *mm) { + struct _elm_import_msg *m = (struct _elm_import_msg *)mm; + + printf("importing complete\n"); + + if (!camel_exception_is_set(&mm->ex)) { + GConfClient *gconf; + + gconf = gconf_client_get_default(); + gconf_client_set_bool(gconf, "/apps/evolution/importer/elm/mail", TRUE, NULL); + g_object_unref(gconf); + } + + e_import_complete(m->import, (EImportTarget *)m->target); } static void elm_import_free(struct _mail_msg *mm) { - /*struct _elm_import_msg *m = (struct _elm_import_msg *)mm;*/ -} + struct _elm_import_msg *m = (struct _elm_import_msg *)mm; -static struct _mail_msg_op elm_import_op = { - elm_import_describe, - elm_import_import, - elm_import_imported, - elm_import_free, -}; - -static int -mail_importer_elm_import(ElmImporter *importer) -{ - struct _elm_import_msg *m; - int id; + camel_operation_unref(m->status); - m = mail_msg_new(&elm_import_op, NULL, sizeof (*m)); - m->importer = importer; + g_free(m->status_what); + g_mutex_free(m->status_lock); - id = m->msg.seq; - - e_thread_put(mail_thread_queued, (EMsg *) m); + g_source_remove(m->status_timeout_id); + m->status_timeout_id = 0; - return id; + g_object_unref(m->import); } static void elm_status(CamelOperation *op, const char *what, int pc, void *data) { - ElmImporter *importer = data; + struct _elm_import_msg *importer = data; if (pc == CAMEL_OPERATION_START) pc = 0; @@ -325,129 +272,115 @@ elm_status(CamelOperation *op, const char *what, int pc, void *data) static gboolean elm_status_timeout(void *data) { - ElmImporter *importer = data; + struct _elm_import_msg *importer = data; int pc; char *what; - if (!importer->status_what) - return TRUE; + if (importer->status_what) { + g_mutex_lock(importer->status_lock); + what = importer->status_what; + importer->status_what = NULL; + pc = importer->status_pc; + g_mutex_unlock(importer->status_lock); - g_mutex_lock(importer->status_lock); - what = importer->status_what; - importer->status_what = NULL; - pc = importer->status_pc; - g_mutex_unlock(importer->status_lock); + e_import_status(importer->import, (EImportTarget *)importer->target, what, pc); + } - gtk_progress_bar_set_fraction((GtkProgressBar *)importer->progressbar, (gfloat)(pc/100.0)); - gtk_progress_bar_set_text((GtkProgressBar *)importer->progressbar, what); - return TRUE; } -static void -elm_create_structure (EvolutionIntelligentImporter *ii, - void *closure) -{ - ElmImporter *importer = closure; - - if (importer->do_mail) { - importer->dialog = create_importer_gui(importer); - gtk_widget_show_all(importer->dialog); - importer->status_timeout_id = g_timeout_add(100, elm_status_timeout, importer); - importer->cancel = camel_operation_new(elm_status, importer); - - mail_msg_wait(mail_importer_elm_import(importer)); +static struct _mail_msg_op elm_import_op = { + elm_import_describe, + elm_import_import, + elm_import_imported, + elm_import_free, +}; - camel_operation_unref(importer->cancel); - g_source_remove(importer->status_timeout_id); - importer->status_timeout_id = 0; +static int +mail_importer_elm_import(EImport *ei, EImportTarget *target) +{ + struct _elm_import_msg *m; + int id; - importer->done_mail = TRUE; - } + m = mail_msg_new(&elm_import_op, NULL, sizeof (*m)); + g_datalist_set_data(&target->data, "elm-msg", m); + m->import = ei; + g_object_ref(m->import); + m->target = (EImportTargetHome *)target; + m->status_timeout_id = g_timeout_add(100, elm_status_timeout, m); + m->status_lock = g_mutex_new(); + m->status = camel_operation_new(elm_status, m); - elm_store_settings (importer); + id = m->msg.seq; + + e_thread_put(mail_thread_queued, (EMsg *)m); - bonobo_object_unref (BONOBO_OBJECT (ii)); + return id; } static void -free_pref(void *key, void *value, void *data) +checkbox_toggle_cb (GtkToggleButton *tb, EImportTarget *target) { - g_free(key); - g_free(value); + g_datalist_set_data(&target->data, "elm-do-mail", GINT_TO_POINTER(gtk_toggle_button_get_active(tb))); } -static void -elm_destroy_cb (ElmImporter *importer, GtkObject *object) +static GtkWidget * +elm_getwidget(EImport *ei, EImportTarget *target, EImportImporter *im) { - elm_store_settings(importer); + GtkWidget *box, *w; + GConfClient *gconf; + gboolean done_mail; - if (importer->status_timeout_id) - g_source_remove(importer->status_timeout_id); - g_free(importer->status_what); - g_mutex_free(importer->status_lock); + gconf = gconf_client_get_default (); + done_mail = gconf_client_get_bool (gconf, "/apps/evolution/importer/elm/mail", NULL); + g_object_unref(gconf); - if (importer->dialog) - gtk_widget_destroy(importer->dialog); + g_datalist_set_data(&target->data, "elm-do-mail", GINT_TO_POINTER(!done_mail)); - if (importer->prefs) { - g_hash_table_foreach(importer->prefs, free_pref, NULL); - g_hash_table_destroy(importer->prefs); - } + box = gtk_vbox_new(FALSE, 2); + + w = gtk_check_button_new_with_label(_("Mail")); + gtk_toggle_button_set_active((GtkToggleButton *)w, !done_mail); + g_signal_connect(w, "toggled", G_CALLBACK(checkbox_toggle_cb), target); + + gtk_box_pack_start((GtkBox *)box, w, FALSE, FALSE, 0); + gtk_widget_show_all(box); - g_free(importer); + return box; } -/* Fun initialisation stuff */ -/* Fun control stuff */ static void -checkbox_toggle_cb (GtkToggleButton *tb, - gboolean *do_item) +elm_import(EImport *ei, EImportTarget *target, EImportImporter *im) { - *do_item = gtk_toggle_button_get_active (tb); + if (GPOINTER_TO_INT(g_datalist_get_data(&target->data, "elm-do-mail"))) + mail_importer_elm_import(ei, target); + else + e_import_complete(ei, target); } -static BonoboControl * -create_checkboxes_control (ElmImporter *importer) +static void +elm_cancel(EImport *ei, EImportTarget *target, EImportImporter *im) { - GtkWidget *hbox; - BonoboControl *control; - - hbox = gtk_vbox_new (FALSE, 2); - - importer->mail = gtk_check_button_new_with_label (_("Mail")); - gtk_signal_connect (GTK_OBJECT (importer->mail), "toggled", - GTK_SIGNAL_FUNC (checkbox_toggle_cb), - &importer->do_mail); + struct _elm_import_msg *m = g_datalist_get_data(&target->data, "elm-msg"); - gtk_box_pack_start (GTK_BOX (hbox), importer->mail, FALSE, FALSE, 0); - - gtk_widget_show_all (hbox); - control = bonobo_control_new (hbox); - return control; + if (m) + camel_operation_cancel(m->status); } -BonoboObject * -elm_intelligent_importer_new(void) +static EImportImporter elm_importer = { + E_IMPORT_TARGET_HOME, + 0, + elm_supported, + elm_getwidget, + elm_import, + elm_cancel, +}; + +EImportImporter * +elm_importer_peek(void) { - EvolutionIntelligentImporter *importer; - BonoboControl *control; - ElmImporter *elm; - char *message = N_("Evolution has found Elm mail files\n" - "Would you like to import them into Evolution?"); - - elm = g_new0 (ElmImporter, 1); - elm->status_lock = g_mutex_new(); - elm_restore_settings (elm); - importer = evolution_intelligent_importer_new (elm_can_import, - elm_create_structure, - _("Elm"), - _(message), elm); - g_object_weak_ref(G_OBJECT (importer), (GWeakNotify)elm_destroy_cb, elm); - elm->ii = importer; - - control = create_checkboxes_control(elm); - bonobo_object_add_interface(BONOBO_OBJECT(importer), BONOBO_OBJECT(control)); - - return BONOBO_OBJECT(importer); + elm_importer.name = _("Evolution Elm importer"); + elm_importer.description = _("Import mail from Elm."); + + return &elm_importer; } diff --git a/mail/importers/evolution-mbox-importer.c b/mail/importers/evolution-mbox-importer.c index 3630277cdd..804a137543 100644 --- a/mail/importers/evolution-mbox-importer.c +++ b/mail/importers/evolution-mbox-importer.c @@ -36,18 +36,13 @@ #include <string.h> #include <gtk/gtkhbox.h> +#include <gtk/gtkvbox.h> #include <gtk/gtklabel.h> -#include <gtk/gtkmessagedialog.h> -#include <gtk/gtkprogressbar.h> -#include <bonobo/bonobo-control.h> -#include <libgnome/gnome-i18n.h> +#include <glib/gi18n.h> #include <camel/camel-exception.h> -#include <importer/evolution-importer.h> -#include <importer/GNOME_Evolution_Importer.h> - #include "mail/em-folder-selection-button.h" #include "mail/mail-component.h" @@ -55,17 +50,11 @@ #include "mail-importer.h" -/* #define IMPORTER_DEBUG */ -#ifdef IMPORTER_DEBUG -#define IN g_print ("=====> %s (%d)\n", G_GNUC_FUNCTION, __LINE__) -#define OUT g_print ("<==== %s (%d)\n", G_GNUC_FUNCTION, __LINE__) -#else -#define IN -#define OUT -#endif +#include "e-util/e-import.h" typedef struct { - EvolutionImporter *ii; + EImport *import; + EImportTarget *target; GMutex *status_lock; char *status_what; @@ -73,42 +62,18 @@ typedef struct { int status_timeout_id; CamelOperation *cancel; /* cancel/status port */ - GtkWidget *selector; - GtkWidget *label; - GtkWidget *progressbar; - GtkWidget *dialog; - char *uri; } MboxImporter; static void -process_item_fn(EvolutionImporter *eimporter, CORBA_Object listener, void *data, CORBA_Environment *ev) -{ - /*MboxImporter *importer = data;*/ - GNOME_Evolution_ImporterListener_ImporterResult result; - - /* This is essentially a NOOP, it merely returns ok/fail and is only called once */ - -#if 0 - if (camel_exception_is_set(importer->ex)) - result = GNOME_Evolution_ImporterListener_BAD_FILE; - else -#endif - result = GNOME_Evolution_ImporterListener_OK; - - GNOME_Evolution_ImporterListener_notifyResult(listener, result, FALSE, ev); - bonobo_object_unref(BONOBO_OBJECT(eimporter)); -} - -static void -folder_selected(EMFolderSelectionButton *button, MboxImporter *importer) +folder_selected(EMFolderSelectionButton *button, EImportTargetURI *target) { - g_free(importer->uri); - importer->uri = g_strdup(em_folder_selection_button_get_selection(button)); + g_free(target->uri_dest); + target->uri_dest = g_strdup(em_folder_selection_button_get_selection(button)); } -static void -create_control_fn(EvolutionImporter *importer, Bonobo_Control *control, void *data) +static GtkWidget * +mbox_getwidget(EImport *ei, EImportTarget *target, EImportImporter *im) { GtkWidget *hbox, *w; @@ -120,23 +85,35 @@ create_control_fn(EvolutionImporter *importer, Bonobo_Control *control, void *da w = em_folder_selection_button_new(_("Select folder"), _("Select folder to import into")); em_folder_selection_button_set_selection((EMFolderSelectionButton *)w, mail_component_get_folder_uri(NULL, MAIL_COMPONENT_FOLDER_INBOX)); - g_signal_connect(w, "selected", G_CALLBACK(folder_selected), data); + g_signal_connect(w, "selected", G_CALLBACK(folder_selected), target); gtk_box_pack_start((GtkBox *)hbox, w, FALSE, TRUE, 6); - gtk_widget_show_all(hbox); + w = gtk_vbox_new(FALSE, 0); + gtk_box_pack_start((GtkBox *)w, hbox, FALSE, FALSE, 0); + gtk_widget_show_all(w); - /* Another weird-arsed shell api */ - *control = BONOBO_OBJREF(bonobo_control_new(hbox)); + return w; } static gboolean -support_format_fn(EvolutionImporter *importer, const char *filename, void *closure) +mbox_supported(EImport *ei, EImportTarget *target, EImportImporter *im) { char signature[6]; gboolean ret = FALSE; int fd, n; + EImportTargetURI *s; + + if (target->type != E_IMPORT_TARGET_URI) + return FALSE; - fd = open(filename, O_RDONLY); + s = (EImportTargetURI *)target; + if (s->uri_src == NULL) + return TRUE; + + if (strncmp(s->uri_src, "file:///", strlen("file:///")) != 0) + return FALSE; + + fd = open(s->uri_src + strlen("file://"), O_RDONLY); if (fd != -1) { n = read(fd, signature, 5); ret = n == 5 && memcmp(signature, "From ", 5) == 0; @@ -147,22 +124,6 @@ support_format_fn(EvolutionImporter *importer, const char *filename, void *closu } static void -importer_destroy_cb(void *data, GObject *object) -{ - MboxImporter *importer = data; - - if (importer->status_timeout_id) - g_source_remove(importer->status_timeout_id); - g_free(importer->status_what); - g_mutex_free(importer->status_lock); - - if (importer->dialog) - gtk_widget_destroy(importer->dialog); - - g_free(importer); -} - -static void mbox_status(CamelOperation *op, const char *what, int pc, void *data) { MboxImporter *importer = data; @@ -186,72 +147,74 @@ mbox_status_timeout(void *data) int pc; char *what; - if (!importer->status_what) - return TRUE; + if (importer->status_what) { + g_mutex_lock(importer->status_lock); + what = importer->status_what; + importer->status_what = NULL; + pc = importer->status_pc; + g_mutex_unlock(importer->status_lock); - g_mutex_lock(importer->status_lock); - what = importer->status_what; - importer->status_what = NULL; - pc = importer->status_pc; - g_mutex_unlock(importer->status_lock); + e_import_status(importer->import, (EImportTarget *)importer->target, what, pc); + } - gtk_progress_bar_set_fraction((GtkProgressBar *)importer->progressbar, (gfloat)(pc/100.0)); - gtk_progress_bar_set_text((GtkProgressBar *)importer->progressbar, what); - return TRUE; } static void -mbox_importer_response(GtkWidget *w, guint button, void *data) +mbox_import_done(void *data, CamelException *ex) { MboxImporter *importer = data; - if (button == GTK_RESPONSE_CANCEL - && importer->cancel) - camel_operation_cancel(importer->cancel); + g_source_remove(importer->status_timeout_id); + g_free(importer->status_what); + g_mutex_free(importer->status_lock); + camel_operation_unref(importer->cancel); + + e_import_complete(importer->import, importer->target); + g_free(importer); } -static gboolean -load_file_fn(EvolutionImporter *eimporter, const char *filename, void *data) +static void +mbox_import(EImport *ei, EImportTarget *target, EImportImporter *im) { - MboxImporter *importer = data; - char *utf8_filename; - - utf8_filename = g_filename_to_utf8 (filename, -1, NULL, NULL, NULL); - importer->dialog = gtk_message_dialog_new(NULL, 0/*GTK_DIALOG_NO_SEPARATOR*/, - GTK_MESSAGE_INFO, GTK_BUTTONS_CANCEL, - _("Importing `%s'"), utf8_filename); - g_free (utf8_filename); - gtk_window_set_title (GTK_WINDOW (importer->dialog), _("Importing...")); - - importer->label = gtk_label_new (_("Please wait")); - importer->progressbar = gtk_progress_bar_new (); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (importer->dialog)->vbox), importer->label, FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (importer->dialog)->vbox), importer->progressbar, FALSE, FALSE, 0); - g_signal_connect(importer->dialog, "response", G_CALLBACK(mbox_importer_response), importer); - gtk_widget_show_all(importer->dialog); + MboxImporter *importer; + /* TODO: do we validate target? */ + + importer = g_malloc0(sizeof(*importer)); + g_datalist_set_data(&target->data, "mbox-data", importer); + importer->import = ei; + importer->target = target; + importer->status_lock = g_mutex_new(); importer->status_timeout_id = g_timeout_add(100, mbox_status_timeout, importer); importer->cancel = camel_operation_new(mbox_status, importer); - mail_msg_wait(mail_importer_import_mbox(filename, importer->uri, importer->cancel)); + mail_importer_import_mbox(((EImportTargetURI *)target)->uri_src+strlen("file://"), ((EImportTargetURI *)target)->uri_dest, importer->cancel, mbox_import_done, importer); +} - camel_operation_unref(importer->cancel); - g_source_remove(importer->status_timeout_id); - importer->status_timeout_id = 0; +static void +mbox_cancel(EImport *ei, EImportTarget *target, EImportImporter *im) +{ + MboxImporter *importer = g_datalist_get_data(&target->data, "mbox-data"); - return TRUE; + if (importer) + camel_operation_cancel(importer->cancel); } -BonoboObject * -mbox_importer_new(void) +static EImportImporter mbox_importer = { + E_IMPORT_TARGET_URI, + 0, + mbox_supported, + mbox_getwidget, + mbox_import, + mbox_cancel, +}; + +EImportImporter * +mbox_importer_peek(void) { - MboxImporter *mbox; - - mbox = g_new0 (MboxImporter, 1); - mbox->status_lock = g_mutex_new(); - mbox->ii = evolution_importer_new(create_control_fn, support_format_fn, load_file_fn, process_item_fn, NULL, mbox); - g_object_weak_ref(G_OBJECT(mbox->ii), importer_destroy_cb, mbox); - - return BONOBO_OBJECT (mbox->ii); + mbox_importer.name = _("Berkeley Mailbox (mbox)"); + mbox_importer.description = _("Importer Berkeley Mailbox format folders"); + + return &mbox_importer; } diff --git a/mail/importers/mail-importer.c b/mail/importers/mail-importer.c index 7bd2fffcc3..e1a7110be7 100644 --- a/mail/importers/mail-importer.c +++ b/mail/importers/mail-importer.c @@ -112,6 +112,7 @@ mail_importer_add_line (MailImporter *importer, struct _BonoboObject *mail_importer_factory_cb(struct _BonoboGenericFactory *factory, const char *iid, void *data) { +#if 0 if (strcmp(iid, ELM_INTELLIGENT_IMPORTER_IID) == 0) return elm_intelligent_importer_new(); else if (strcmp(iid, PINE_INTELLIGENT_IMPORTER_IID) == 0) @@ -122,7 +123,7 @@ struct _BonoboObject *mail_importer_factory_cb(struct _BonoboGenericFactory *fac return mbox_importer_new(); else if (strcmp(iid, OUTLOOK_IMPORTER_IID) == 0) return outlook_importer_new(); - +#endif return NULL; } @@ -132,6 +133,9 @@ struct _import_mbox_msg { char *path; char *uri; CamelOperation *cancel; + + void (*done)(void *data, CamelException *ex); + void *done_data; }; static char * @@ -281,6 +285,10 @@ fail1: static void import_mbox_done(struct _mail_msg *mm) { + struct _import_mbox_msg *m = (struct _import_mbox_msg *)mm; + + if (m->done) + m->done(m->done_data, &mm->ex); } static void @@ -302,7 +310,7 @@ static struct _mail_msg_op import_mbox_op = { }; int -mail_importer_import_mbox(const char *path, const char *folderuri, CamelOperation *cancel) +mail_importer_import_mbox(const char *path, const char *folderuri, CamelOperation *cancel, void (*done)(void *data, CamelException *), void *data) { struct _import_mbox_msg *m; int id; @@ -310,6 +318,8 @@ mail_importer_import_mbox(const char *path, const char *folderuri, CamelOperatio m = mail_msg_new(&import_mbox_op, NULL, sizeof (*m)); m->path = g_strdup(path); m->uri = g_strdup(folderuri); + m->done = done; + m->done_data = data; if (cancel) { m->cancel = cancel; camel_operation_ref(cancel); diff --git a/mail/importers/mail-importer.h b/mail/importers/mail-importer.h index 17eeea1fb9..5b8e5b666a 100644 --- a/mail/importers/mail-importer.h +++ b/mail/importers/mail-importer.h @@ -49,6 +49,12 @@ char *mail_importer_make_local_folder(const char *folderpath); struct _BonoboObject; struct _BonoboGenericFactory; struct _CamelOperation; +struct _CamelException; + +struct _EImportImporter *mbox_importer_peek(void); + +struct _EImportImporter *elm_importer_peek(void); +struct _EImportImporter *pine_importer_peek(void); #define ELM_INTELLIGENT_IMPORTER_IID "OAFIID:GNOME_Evolution_Mail_Elm_Intelligent_Importer:" BASE_VERSION #define PINE_INTELLIGENT_IMPORTER_IID "OAFIID:GNOME_Evolution_Mail_Pine_Intelligent_Importer:" BASE_VERSION @@ -74,7 +80,7 @@ struct _BonoboObject *mail_importer_factory_cb(struct _BonoboGenericFactory *fac #define MSG_FLAG_MARKED 0x0004 #define MSG_FLAG_EXPUNGED 0x0008 -int mail_importer_import_mbox(const char *path, const char *folderuri, struct _CamelOperation *cancel); +int mail_importer_import_mbox(const char *path, const char *folderuri, struct _CamelOperation *cancel, void (*done)(void *data, struct _CamelException *), void *data); void mail_importer_import_mbox_sync(const char *path, const char *folderuri, struct _CamelOperation *cancel); struct _MailImporterSpecial { diff --git a/mail/importers/pine-importer.c b/mail/importers/pine-importer.c index 6c9d0449f7..ea6c9b669b 100644 --- a/mail/importers/pine-importer.c +++ b/mail/importers/pine-importer.c @@ -33,140 +33,62 @@ #include <sys/stat.h> #include <unistd.h> #include <dirent.h> -#include <ctype.h> #include <string.h> #include <glib.h> +#include <glib/gi18n.h> +#include <gtk/gtkvbox.h> +#include <gtk/gtkcheckbutton.h> -#include <libgnomeui/gnome-messagebox.h> -#include <gtk/gtk.h> - -#include <gconf/gconf.h> #include <gconf/gconf-client.h> -#include <bonobo/bonobo-object.h> -#include <bonobo/bonobo-generic-factory.h> -#include <bonobo/bonobo-control.h> -#include <bonobo/bonobo-context.h> -#include <bonobo/bonobo-main.h> -#include <bonobo/bonobo-exception.h> -#include <bonobo/bonobo-moniker-util.h> +#include <libebook/e-book.h> +#include <libebook/e-destination.h> -#include <importer/evolution-intelligent-importer.h> -#include <importer/evolution-importer-client.h> -#include <importer/GNOME_Evolution_Importer.h> +#include <camel/camel-operation.h> #include "mail-importer.h" #include "mail/mail-mt.h" -#include "mail/mail-component.h" - -#include <libebook/e-book.h> -#include <libebook/e-destination.h> +#include "e-util/e-import.h" +#include "e-util/e-error.h" -#define KEY "pine-mail-imported" - -/*#define SUPER_IMPORTER_DEBUG*/ -#ifdef SUPER_IMPORTER_DEBUG #define d(x) x -#else -#define d(x) -#endif -typedef struct { - EvolutionIntelligentImporter *ii; +struct _pine_import_msg { + struct _mail_msg msg; + + EImport *import; + EImportTarget *target; GMutex *status_lock; char *status_what; int status_pc; int status_timeout_id; - CamelOperation *cancel; /* cancel/status port */ - - GtkWidget *mail; - GtkWidget *address; - - gboolean do_mail; - gboolean done_mail; - gboolean do_address; - gboolean done_address; - - /* GUI */ - GtkWidget *dialog; - GtkWidget *label; - GtkWidget *progressbar; -} PineImporter; - -static void -pine_importer_response(GtkWidget *w, guint button, void *data) -{ - PineImporter *importer = data; - - if (button == GTK_RESPONSE_CANCEL - && importer->cancel) - camel_operation_cancel(importer->cancel); -} - -static GtkWidget * -create_importer_gui (PineImporter *importer) -{ - GtkWidget *dialog; - - dialog = gtk_message_dialog_new(NULL, 0/*GTK_DIALOG_NO_SEPARATOR*/, - GTK_MESSAGE_INFO, GTK_BUTTONS_CANCEL, - _("Evolution is importing your old Pine data")); - gtk_window_set_title (GTK_WINDOW (dialog), _("Importing...")); - - importer->label = gtk_label_new (_("Please wait")); - importer->progressbar = gtk_progress_bar_new (); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), importer->label, FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), importer->progressbar, FALSE, FALSE, 0); - g_signal_connect(dialog, "response", G_CALLBACK(pine_importer_response), importer); - - return dialog; -} - -static void -pine_store_settings (PineImporter *importer) -{ - GConfClient *gconf = gconf_client_get_default (); - - gconf_client_set_bool (gconf, "/apps/evolution/importer/pine/mail", importer->done_mail, NULL); - gconf_client_set_bool (gconf, "/apps/evolution/importer/pine/address", importer->done_address, NULL); - g_object_unref(gconf); -} - -static void -pine_restore_settings (PineImporter *importer) -{ - GConfClient *gconf = gconf_client_get_default (); - - importer->done_mail = gconf_client_get_bool (gconf, "/apps/evolution/importer/pine/mail", NULL); - importer->done_address = gconf_client_get_bool (gconf, "/apps/evolution/importer/pine/address", NULL); - g_object_unref(gconf); -} + CamelOperation *status; +}; static gboolean -pine_can_import (EvolutionIntelligentImporter *ii, void *closure) +pine_supported(EImport *ei, EImportTarget *target, EImportImporter *im) { - PineImporter *importer = closure; + EImportTargetHome *s; char *maildir, *addrfile; - gboolean md_exists = FALSE, addr_exists = FALSE; + gboolean md_exists, addr_exists; struct stat st; - - maildir = g_build_filename(g_get_home_dir(), "mail", NULL); - md_exists = lstat(maildir, &st) == 0 && S_ISDIR(st.st_mode); - g_free (maildir); - importer->do_mail = md_exists && !importer->done_mail; - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (importer->mail), importer->do_mail); - gtk_widget_set_sensitive (importer->mail, md_exists); + if (target->type != E_IMPORT_TARGET_HOME) + return FALSE; + + s = (EImportTargetHome *)target; + + maildir = g_build_filename(s->homedir, "mail", NULL); + md_exists = lstat(maildir, &st) == 0 && S_ISDIR(st.st_mode); + g_free(maildir); - addrfile = g_build_filename(g_get_home_dir(), ".addressbook", NULL); + addrfile = g_build_filename(s->homedir, ".addressbook", NULL); addr_exists = lstat(addrfile, &st) == 0 && S_ISREG(st.st_mode); g_free (addrfile); - gtk_widget_set_sensitive (importer->address, addr_exists); - return md_exists || addr_exists; } @@ -243,7 +165,7 @@ import_contact(EBook *book, char *line) } static void -import_contacts(PineImporter *importer) +import_contacts(void) { ESource *primary; ESourceList *source_list; @@ -302,12 +224,6 @@ import_contacts(PineImporter *importer) g_object_unref(book); } -struct _pine_import_msg { - struct _mail_msg msg; - - PineImporter *importer; -}; - static char * pine_import_describe (struct _mail_msg *mm, int complete) { @@ -325,14 +241,14 @@ pine_import_import(struct _mail_msg *mm) { struct _pine_import_msg *m = (struct _pine_import_msg *) mm; - if (m->importer->do_address) - import_contacts(m->importer); + if (GPOINTER_TO_INT(g_datalist_get_data(&m->target->data, "pine-do-addr"))) + import_contacts(); - if (m->importer->do_mail) { + if (GPOINTER_TO_INT(g_datalist_get_data(&m->target->data, "pine-do-mail"))) { char *path; path = g_build_filename(g_get_home_dir(), "mail", NULL); - mail_importer_import_folders_sync(path, pine_special_folders, 0, m->importer->cancel); + mail_importer_import_folders_sync(path, pine_special_folders, 0, m->status); g_free(path); } } @@ -340,41 +256,44 @@ pine_import_import(struct _mail_msg *mm) static void pine_import_imported(struct _mail_msg *mm) { + struct _pine_import_msg *m = (struct _pine_import_msg *)mm; + + printf("importing complete\n"); + + if (!camel_exception_is_set(&mm->ex)) { + GConfClient *gconf; + + gconf = gconf_client_get_default(); + if (GPOINTER_TO_INT(g_datalist_get_data(&m->target->data, "pine-do-addr"))) + gconf_client_set_bool(gconf, "/apps/evolution/importer/pine/addr", TRUE, NULL); + if (GPOINTER_TO_INT(g_datalist_get_data(&m->target->data, "pine-do-mail"))) + gconf_client_set_bool(gconf, "/apps/evolution/importer/pine/mail", TRUE, NULL); + g_object_unref(gconf); + } + + e_import_complete(m->import, (EImportTarget *)m->target); } static void pine_import_free(struct _mail_msg *mm) { - /*struct _pine_import_msg *m = (struct _pine_import_msg *)mm;*/ -} + struct _pine_import_msg *m = (struct _pine_import_msg *)mm; -static struct _mail_msg_op pine_import_op = { - pine_import_describe, - pine_import_import, - pine_import_imported, - pine_import_free, -}; + camel_operation_unref(m->status); -static int -mail_importer_pine_import(PineImporter *importer) -{ - struct _pine_import_msg *m; - int id; + g_free(m->status_what); + g_mutex_free(m->status_lock); - m = mail_msg_new(&pine_import_op, NULL, sizeof (*m)); - m->importer = importer; - - id = m->msg.seq; - - e_thread_put(mail_thread_queued, (EMsg *) m); + g_source_remove(m->status_timeout_id); + m->status_timeout_id = 0; - return id; + g_object_unref(m->import); } static void pine_status(CamelOperation *op, const char *what, int pc, void *data) { - PineImporter *importer = data; + struct _pine_import_msg *importer = data; if (pc == CAMEL_OPERATION_START) pc = 0; @@ -391,125 +310,129 @@ pine_status(CamelOperation *op, const char *what, int pc, void *data) static gboolean pine_status_timeout(void *data) { - PineImporter *importer = data; + struct _pine_import_msg *importer = data; int pc; char *what; - if (!importer->status_what) - return TRUE; + if (importer->status_what) { + g_mutex_lock(importer->status_lock); + what = importer->status_what; + importer->status_what = NULL; + pc = importer->status_pc; + g_mutex_unlock(importer->status_lock); - g_mutex_lock(importer->status_lock); - what = importer->status_what; - importer->status_what = NULL; - pc = importer->status_pc; - g_mutex_unlock(importer->status_lock); + e_import_status(importer->import, (EImportTarget *)importer->target, what, pc); + } - gtk_progress_bar_set_fraction((GtkProgressBar *)importer->progressbar, (gfloat)(pc/100.0)); - gtk_progress_bar_set_text((GtkProgressBar *)importer->progressbar, what); - return TRUE; } -static void -pine_create_structure (EvolutionIntelligentImporter *ii, void *closure) -{ - PineImporter *importer = closure; - - if (importer->do_address || importer->do_mail) { - importer->dialog = create_importer_gui (importer); - gtk_widget_show_all (importer->dialog); - importer->status_timeout_id = g_timeout_add(100, pine_status_timeout, importer); - importer->cancel = camel_operation_new(pine_status, importer); - - mail_msg_wait(mail_importer_pine_import(importer)); +static struct _mail_msg_op pine_import_op = { + pine_import_describe, + pine_import_import, + pine_import_imported, + pine_import_free, +}; - camel_operation_unref(importer->cancel); - g_source_remove(importer->status_timeout_id); - importer->status_timeout_id = 0; +static int +mail_importer_pine_import(EImport *ei, EImportTarget *target) +{ + struct _pine_import_msg *m; + int id; - if (importer->do_address) - importer->done_address = TRUE; - if (importer->do_mail) - importer->done_mail = TRUE; - } + m = mail_msg_new(&pine_import_op, NULL, sizeof (*m)); + g_datalist_set_data(&target->data, "pine-msg", m); + m->import = ei; + g_object_ref(m->import); + m->target = target; + m->status_timeout_id = g_timeout_add(100, pine_status_timeout, m); + m->status_lock = g_mutex_new(); + m->status = camel_operation_new(pine_status, m); - pine_store_settings (importer); + id = m->msg.seq; + + e_thread_put(mail_thread_queued, (EMsg *)m); - bonobo_object_unref (BONOBO_OBJECT (ii)); + return id; } static void -pine_destroy_cb (PineImporter *importer, GtkObject *object) +checkbox_mail_toggle_cb(GtkToggleButton *tb, EImportTarget *target) { - pine_store_settings (importer); - - if (importer->status_timeout_id) - g_source_remove(importer->status_timeout_id); - g_free(importer->status_what); - g_mutex_free(importer->status_lock); - - if (importer->dialog) - gtk_widget_destroy(importer->dialog); - - g_free(importer); + g_datalist_set_data(&target->data, "pine-do-mail", GINT_TO_POINTER(gtk_toggle_button_get_active(tb))); } -/* Fun inity stuff */ - -/* Fun control stuff */ static void -checkbox_toggle_cb(GtkToggleButton *tb, gboolean *do_item) +checkbox_addr_toggle_cb(GtkToggleButton *tb, EImportTarget *target) { - *do_item = gtk_toggle_button_get_active(tb); + g_datalist_set_data(&target->data, "pine-do-addr", GINT_TO_POINTER(gtk_toggle_button_get_active(tb))); } -static BonoboControl * -create_checkboxes_control (PineImporter *importer) +static GtkWidget * +pine_getwidget(EImport *ei, EImportTarget *target, EImportImporter *im) { - GtkWidget *hbox; - BonoboControl *control; + GtkWidget *box, *w; + GConfClient *gconf; + gboolean done_mail, done_addr; + + gconf = gconf_client_get_default (); + done_mail = gconf_client_get_bool (gconf, "/apps/evolution/importer/pine/mail", NULL); + done_addr = gconf_client_get_bool (gconf, "/apps/evolution/importer/pine/address", NULL); + g_object_unref(gconf); + + g_datalist_set_data(&target->data, "pine-do-mail", GINT_TO_POINTER(!done_mail)); + g_datalist_set_data(&target->data, "pine-do-addr", GINT_TO_POINTER(!done_addr)); + + box = gtk_vbox_new(FALSE, 2); + + w = gtk_check_button_new_with_label(_("Mail")); + gtk_toggle_button_set_active((GtkToggleButton *)w, !done_mail); + g_signal_connect(w, "toggled", G_CALLBACK(checkbox_mail_toggle_cb), target); + gtk_box_pack_start((GtkBox *)box, w, FALSE, FALSE, 0); - hbox = gtk_hbox_new (FALSE, 2); + w = gtk_check_button_new_with_label(_("Addressbook")); + gtk_toggle_button_set_active((GtkToggleButton *)w, !done_addr); + g_signal_connect(w, "toggled", G_CALLBACK(checkbox_addr_toggle_cb), target); + gtk_box_pack_start((GtkBox *)box, w, FALSE, FALSE, 0); - importer->mail = gtk_check_button_new_with_label (_("Mail")); - gtk_signal_connect (GTK_OBJECT (importer->mail), "toggled", - GTK_SIGNAL_FUNC (checkbox_toggle_cb), - &importer->do_mail); + gtk_widget_show_all(box); - importer->address = gtk_check_button_new_with_label (_("Addressbook")); - gtk_signal_connect (GTK_OBJECT (importer->address), "toggled", - GTK_SIGNAL_FUNC (checkbox_toggle_cb), - &importer->do_address); + return box; +} + +static void +pine_import(EImport *ei, EImportTarget *target, EImportImporter *im) +{ + if (GPOINTER_TO_INT(g_datalist_get_data(&target->data, "pine-do-mail")) + || GPOINTER_TO_INT(g_datalist_get_data(&target->data, "pine-do-addr"))) + mail_importer_pine_import(ei, target); + else + e_import_complete(ei, target); +} - gtk_box_pack_start (GTK_BOX (hbox), importer->mail, FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (hbox), importer->address, FALSE, FALSE, 0); +static void +pine_cancel(EImport *ei, EImportTarget *target, EImportImporter *im) +{ + struct _pine_import_msg *m = g_datalist_get_data(&target->data, "pine-msg"); - gtk_widget_show_all (hbox); - control = bonobo_control_new (hbox); - return control; + if (m) + camel_operation_cancel(m->status); } -BonoboObject * -pine_intelligent_importer_new(void) +static EImportImporter pine_importer = { + E_IMPORT_TARGET_HOME, + 0, + pine_supported, + pine_getwidget, + pine_import, + pine_cancel, +}; + +EImportImporter * +pine_importer_peek(void) { - EvolutionIntelligentImporter *importer; - BonoboControl *control; - PineImporter *pine; - char *message = N_("Evolution has found Pine mail files.\n" - "Would you like to import them into Evolution?"); - - pine = g_new0 (PineImporter, 1); - pine->status_lock = g_mutex_new(); - pine_restore_settings(pine); - importer = evolution_intelligent_importer_new (pine_can_import, - pine_create_structure, - _("Pine"), - _(message), pine); - g_object_weak_ref((GObject *)importer, (GWeakNotify)pine_destroy_cb, pine); - pine->ii = importer; - - control = create_checkboxes_control(pine); - bonobo_object_add_interface(BONOBO_OBJECT(importer), BONOBO_OBJECT(control)); - - return BONOBO_OBJECT(importer); + pine_importer.name = _("Evolution Pine importer"); + pine_importer.description = _("Import mail from Pine."); + + return &pine_importer; } diff --git a/mail/mail-component-factory.c b/mail/mail-component-factory.c index cb0b10a6d0..c430525563 100644 --- a/mail/mail-component-factory.c +++ b/mail/mail-component-factory.c @@ -44,6 +44,7 @@ #include "em-format-html-display.h" #include "importers/mail-importer.h" +#include "e-util/e-import.h" #include <bonobo-activation/bonobo-activation.h> #include <bonobo/bonobo-shlib-factory.h> @@ -89,6 +90,8 @@ make_factory (PortableServer_POA poa, const char *iid, gpointer impl_ptr, CORBA_ static int init = 0; if (!init) { + EImportClass *klass; + init = 1; mail_config_init(); @@ -106,6 +109,11 @@ make_factory (PortableServer_POA poa, const char *iid, gpointer impl_ptr, CORBA_ e_plugin_hook_register_type(em_format_hook_get_type()); e_plugin_hook_register_type(em_event_hook_get_type()); e_plugin_hook_register_type(em_junk_hook_get_type()); + + klass = g_type_class_ref(e_import_get_type()); + e_import_class_add_importer(klass, mbox_importer_peek(), NULL, NULL); + e_import_class_add_importer(klass, elm_importer_peek(), NULL, NULL); + e_import_class_add_importer(klass, pine_importer_peek(), NULL, NULL); } return bonobo_shlib_factory_std (FACTORY_ID, poa, impl_ptr, factory, NULL, ev); diff --git a/po/ChangeLog b/po/ChangeLog index 6231adf91a..416ff5127e 100644 --- a/po/ChangeLog +++ b/po/ChangeLog @@ -114,6 +114,17 @@ * POTFILES.skip: Added the gal files which need to be skipped. +2005-07-06 Not Zed <NotZed@Ximian.com> + + * POTFILES.in: removed addressbook importer .server files, added + addressbook importer .c files. + remove mail & calendar importer .server file + +2005-07-01 Not Zed <NotZed@Ximian.com> + + * POTFILES.in: move import.glade to shell/ and remove + intelligent.c + 2005-06-27 Francisco Javier F. Serrador <serrador@cvs.gnome.org> * es.po: Updated Spanish translation. diff --git a/po/POTFILES.in b/po/POTFILES.in index 19513cc6e9..23dcafdabb 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -62,8 +62,8 @@ addressbook/gui/widgets/eab-vcard-control.c addressbook/gui/widgets/gal-view-factory-minicard.c addressbook/gui/widgets/gal-view-factory-treeview.c addressbook/gui/widgets/test-reflow.c -addressbook/importers/GNOME_Evolution_Addressbook_LDIF_Importer.server.in.in -addressbook/importers/GNOME_Evolution_Addressbook_VCard_Importer.server.in.in +addressbook/importers/evolution-ldif-importer.c +addressbook/importers/evolution-vcard-importer.c addressbook/printing/e-contact-print-envelope.c addressbook/printing/e-contact-print.c addressbook/printing/e-contact-print.glade @@ -170,7 +170,6 @@ calendar/gui/print.c calendar/gui/tasks-component.c calendar/gui/tasks-control.c calendar/gui/weekday-picker.c -calendar/importers/GNOME_Evolution_Calendar_Importer.server.in.in calendar/importers/icalendar-importer.c calendar/zones.h composer/e-msg-composer-attachment-bar.c @@ -233,7 +232,6 @@ mail/em-utils.c mail/em-vfolder-editor.c mail/em-vfolder-rule.c mail/evolution-mail.schemas.in.in -mail/importers/GNOME_Evolution_Mail_Importers.server.in.in mail/importers/elm-importer.c mail/importers/evolution-mbox-importer.c mail/importers/evolution-outlook-importer.c @@ -346,8 +344,7 @@ shell/e-shell.c shell/e-user-creatable-items-handler.c shell/evolution-shell-component-utils.c shell/evolution-test-component.c -shell/importer/import.glade -shell/importer/intelligent.c +shell/import.glade shell/main.c shell/shell.error.xml smime/gui/ca-trust-dialog.c diff --git a/shell/ChangeLog b/shell/ChangeLog index cbb74aea70..0f786487e5 100644 --- a/shell/ChangeLog +++ b/shell/ChangeLog @@ -1,3 +1,18 @@ +2005-07-06 Not Zed <NotZed@Ximian.com> + + * e-shell-importer.c (import_druid_finish): now setup a window to + display importer progress, so it doesn't have to be copied for all + importers & they can all share it. + (import_druid_finish): fix the error id/prompt + +2005-07-01 Not Zed <NotZed@Ximian.com> + + * import.glade: moved from importer/ to here. + + * importer/*: Killed all of this off. + + * Makefile.am: remove importer/ and related stuff. + 2005-06-24 Harish Krishnaswamy <kharish@novell.com> (patch submitted by Andre Klapper <a9016009@gmx.de>) diff --git a/shell/Makefile.am b/shell/Makefile.am index 171e33cfa6..68f04c9b72 100644 --- a/shell/Makefile.am +++ b/shell/Makefile.am @@ -1,5 +1,3 @@ -SUBDIRS = importer - INCLUDES = \ -I$(top_srcdir)/widgets \ -I$(top_srcdir)/widgets/misc \ @@ -134,7 +132,6 @@ evolution_SOURCES = \ evolution_LDADD = \ libeshell.la \ - importer/libevolution-importer.la \ $(top_builddir)/widgets/e-timezone-dialog/libetimezonedialog.la \ $(top_builddir)/widgets/misc/libemiscwidgets.la \ $(top_builddir)/e-util/libeutil.la \ @@ -176,7 +173,8 @@ errordir = $(privdatadir)/errors @EVO_PLUGIN_RULE@ glade_DATA = \ - e-active-connection-dialog.glade + e-active-connection-dialog.glade \ + import.glade # GConf schemas diff --git a/shell/e-shell-importer.c b/shell/e-shell-importer.c index a11272f289..39216cb5b9 100644 --- a/shell/e-shell-importer.c +++ b/shell/e-shell-importer.c @@ -38,26 +38,20 @@ #include <libgnomeui/gnome-druid-page-standard.h> #include <libgnomeui/gnome-file-entry.h> -#include <bonobo-activation/bonobo-activation.h> - -#include <bonobo/bonobo-exception.h> -#include <bonobo/bonobo-widget.h> - #include "e-shell.h" #include "e-shell-window.h" #include "e-shell-constants.h" -#include "importer/evolution-importer-client.h" - #include <glade/glade.h> #include <misc/e-gui-utils.h> #include <e-util/e-gtk-utils.h> #include <e-util/e-dialog-utils.h> #include <e-util/e-icon-factory.h> +#include <e-util/e-import.h> +#include <e-util/e-error.h> #include "e-shell-importer.h" -#include "importer/GNOME_Evolution_Importer.h" typedef struct _ImportDialogFilePage { GtkWidget *vbox; @@ -65,11 +59,16 @@ typedef struct _ImportDialogFilePage { GtkWidget *filetype; GtkWidget *menu; - gboolean need_filename; + GSList *items; + + EImportTargetURI *target; + EImportImporter *importer; } ImportDialogFilePage; typedef struct _ImportDialogDestPage { GtkWidget *vbox; + + GtkWidget *control; } ImportDialogDestPage; typedef struct _ImportDialogTypePage { @@ -81,9 +80,9 @@ typedef struct _ImportDialogTypePage { typedef struct _ImportDialogImporterPage { GtkWidget *vbox; - GList *importers; - gboolean prepared; - int running; + GSList *importers; + GSList *current; + EImportTargetHome *target; } ImportDialogImporterPage; typedef struct _ImportData { @@ -93,7 +92,6 @@ typedef struct _ImportData { GladeXML *wizard; GtkWidget *dialog; GtkWidget *druid; - GtkWidget *control; ImportDialogFilePage *filepage; ImportDialogDestPage *destpage; ImportDialogTypePage *typepage; @@ -107,28 +105,16 @@ typedef struct _ImportData { GnomeDruidPageEdge *finish; GtkWidget *vbox; - char *filename; - char *choosen_iid; - EvolutionImporterClient *client; -} ImportData; + EImport *import; -typedef struct _IntelligentImporterData { - CORBA_Object object; - Bonobo_Control control; - GtkWidget *widget; - - char *name; - char *blurb; - char *iid; -} IntelligentImporterData; - -typedef struct _SelectedImporterData{ - CORBA_Object importer; - char *iid; -} SelectedImporterData; + /* Used for importing phase of operation */ + EImportTarget *import_target; + EImportImporter *import_importer; + GtkWidget *import_dialog; + GtkWidget *import_label; + GtkWidget *import_progress; +} ImportData; -#define IMPORTER_REPO_ID_QUERY "repo_ids.has ('IDL:GNOME/Evolution/Importer:" BASE_VERSION "')" -#define IMPORTER_INTEL_REPO_ID_QUERY "repo_ids.has ('IDL:GNOME/Evolution/IntelligentImporter:" BASE_VERSION "')" /*#define IMPORTER_DEBUG*/ #ifdef IMPORTER_DEBUG @@ -188,373 +174,73 @@ create_help (const char *name) /* Importing functions */ -/* Data to be passed around */ -typedef struct _ImporterComponentData { - EvolutionImporterClient *client; - EvolutionImporterListener *listener; - char *filename; - - GtkDialog *dialog; - GtkWidget *contents; - - int item; - - gboolean stop; -} ImporterComponentData; - -static gboolean importer_timeout_fn (gpointer data); -static void -import_cb (EvolutionImporterListener *listener, - EvolutionImporterResult result, - gboolean more_items, - void *data) -{ - ImporterComponentData *icd = (ImporterComponentData *) data; - char *label; - - IN; - if (icd->stop != TRUE) { - if (result == EVOLUTION_IMPORTER_NOT_READY) { - g_timeout_add (500, importer_timeout_fn, data); - OUT; - return; - } - - if (result == EVOLUTION_IMPORTER_BUSY) { - g_timeout_add (500, importer_timeout_fn, data); - OUT; - return; - } - - if (more_items) { - char *utf8_filename; - - utf8_filename = g_filename_to_utf8 (icd->filename, -1, NULL, NULL, NULL); - label = g_strdup_printf (_("Importing %s\nImporting item %d."), - utf8_filename, ++(icd->item)); - gtk_label_set_text (GTK_LABEL (icd->contents), label); - g_free (label); - g_free (utf8_filename); - while (gtk_events_pending ()) - gtk_main_iteration (); - - g_idle_add_full (G_PRIORITY_LOW, importer_timeout_fn, - data, NULL); - OUT; - return; - } - } - - g_free (icd->filename); - if (icd->dialog != NULL) - gtk_widget_destroy ((GtkWidget *)icd->dialog); - bonobo_object_unref (BONOBO_OBJECT (icd->listener)); - g_object_unref (icd->client); - g_free (icd); - - OUT; -} - -static gboolean -importer_timeout_fn (gpointer data) -{ - ImporterComponentData *icd = (ImporterComponentData *) data; - char *label, *utf8_filename; - - IN; - - utf8_filename = g_filename_to_utf8 (icd->filename, -1, NULL, NULL, NULL); - label = g_strdup_printf (_("Importing %s\nImporting item %d."), - utf8_filename, icd->item); - gtk_label_set_text (GTK_LABEL (icd->contents), label); - g_free (label); - g_free (utf8_filename); - while (gtk_events_pending ()) - gtk_main_iteration (); - - evolution_importer_client_process_item (icd->client, icd->listener); - OUT; - return FALSE; -} - -static void -dialog_response_cb (GtkDialog *dialog, - int button_number, - ImporterComponentData *icd) -{ - if (button_number != GTK_RESPONSE_CANCEL) - return; /* Interesting... */ - - icd->stop = TRUE; -} - -static void -dialog_destroy_notify (void *data, - GObject *where_the_dialog_was) -{ - ImporterComponentData *icd = (ImporterComponentData *) data; - - icd->dialog = NULL; - icd->stop = TRUE; -} - -struct _IIDInfo { - char *iid; - char *name; -}; - static void -free_iid_list (GList *list) -{ - for (; list; list = list->next) { - struct _IIDInfo *iid = list->data; - - g_free (iid->iid); - g_free (iid->name); - g_free (iid); - } -} - -static const char * -get_name_from_component_info (const Bonobo_ServerInfo *info) -{ - const char *name = NULL; - - GSList *language_list = NULL; - const GList *l = gnome_i18n_get_language_list("LC_MESSAGES"); - - /* copy this piece of code from e-shell-settings-dialog.c:load_pages () */ - for (language_list=NULL;l;l=l->next) - language_list = g_slist_append(language_list, l->data); - - name = bonobo_server_info_prop_lookup ((Bonobo_ServerInfo *) info, - "evolution:menu_name", - language_list); - - g_slist_free (language_list); - - return name; -} - -static char * -choose_importer_from_list (GList *importer_list) +filename_changed (GtkEntry *entry, + ImportData *data) { - GtkWidget *dialog, *clist; - GList *p; - int ans; - char *iid; - - dialog = gtk_dialog_new_with_buttons(_("Select importer"), NULL, GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OK, GTK_RESPONSE_OK, - NULL); - gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); - gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); - - clist = gtk_clist_new (1); - for (p = importer_list; p; p = p->next) { - struct _IIDInfo *iid; - char *text[1]; - int row; - - iid = p->data; - text[0] = iid->name; - row = gtk_clist_append (GTK_CLIST (clist), text); - gtk_clist_set_row_data (GTK_CLIST (clist), row, iid->iid); - } + ImportDialogFilePage *page; + const char *filename; + int fileok; - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), clist, TRUE, TRUE, 0); - gtk_clist_set_selection_mode (GTK_CLIST (clist), GTK_SELECTION_BROWSE); - gtk_widget_show (clist); - - ans = gtk_dialog_run((GtkDialog *)dialog); - switch (ans) { - case GTK_RESPONSE_OK: - ans = GPOINTER_TO_INT (GTK_CLIST (clist)->selection->data); - iid = gtk_clist_get_row_data (GTK_CLIST (clist), ans); - break; - - case 1: - default: - iid = NULL; - break; - } - - gtk_widget_destroy (dialog); + page = data->filepage; - return g_strdup (iid); -} + filename = gtk_entry_get_text (entry); -static gboolean -get_iid_for_filetype (const char *filename, char **ret_iid) -{ - Bonobo_ServerInfoList *info_list; - CORBA_Environment ev; - GList *can_handle = NULL; - int i, len = 0; - - CORBA_exception_init (&ev); - info_list = bonobo_activation_query (IMPORTER_REPO_ID_QUERY, NULL, &ev); - - for (i = 0; i < info_list->_length; i++) { - CORBA_Environment ev2; - CORBA_Object importer; - const Bonobo_ServerInfo *info; - - info = info_list->_buffer + i; - - CORBA_exception_init (&ev2); - importer = bonobo_activation_activate_from_id ((char *) info->iid, 0, NULL, &ev2); - if (ev2._major != CORBA_NO_EXCEPTION) { - g_warning ("Error activating %s", info->iid); - CORBA_exception_free (&ev2); - continue; + fileok = filename && filename[0] && g_file_test(filename, G_FILE_TEST_IS_REGULAR); + if (fileok) { + GSList *l, *item; + EImportImporter *first = NULL; + int i=0, firstitem=0; + + g_free(page->target->uri_src); + page->target->uri_src = g_strdup_printf("file://%s", filename); + + l = e_import_get_importers(data->import, (EImportTarget *)page->target); + item = page->items; + while (item) { + EImportImporter *eii = g_object_get_data(item->data, "importer"); + + if (g_slist_find(l, eii) != NULL) { + if (first == NULL) { + firstitem = i; + first = eii; + } + gtk_widget_set_sensitive(item->data, TRUE); + fileok = TRUE; + } else { + if (page->importer == eii) + page->importer = NULL; + gtk_widget_set_sensitive(item->data, FALSE); + } + i++; + item = item->next; } + g_slist_free(l); - if (GNOME_Evolution_Importer_supportFormat (importer, - filename, &ev2)) { - struct _IIDInfo *iid; - - iid = g_new (struct _IIDInfo, 1); - iid->iid = g_strdup (info->iid); - iid->name = g_strdup (get_name_from_component_info (info)); - - can_handle = g_list_prepend (can_handle, iid); - len++; + if (page->importer == NULL && first) { + page->importer = first; + gtk_option_menu_set_history((GtkOptionMenu *)page->filetype, firstitem); } - - bonobo_object_release_unref (importer, &ev2); - CORBA_exception_free (&ev2); - } - - CORBA_free (info_list); - - if (len == 1) { - struct _IIDInfo *iid; - - iid = can_handle->data; - - *ret_iid = g_strdup (iid->iid); - - free_iid_list (can_handle); - g_list_free (can_handle); - - return TRUE; - } else if (len > 1) { - /* Display all the IIDs */ - *ret_iid = choose_importer_from_list (can_handle); - - free_iid_list (can_handle); - g_list_free (can_handle); - - return *ret_iid ? TRUE : FALSE; + fileok = first != NULL; } else { - *ret_iid = NULL; - - return TRUE; - } -} - -static void -start_import (gpointer parent, const char *filename, EvolutionImporterClient *client) -{ - ImporterComponentData *icd; - char *label; - char *utf8_filename; - - utf8_filename = g_filename_to_utf8 (filename, -1, NULL, NULL, NULL); - if (!g_file_test (filename, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) { + GSList *item; - e_notice (parent, GTK_MESSAGE_ERROR, _("File %s does not exist"), utf8_filename); - g_free (utf8_filename); - return; + for (item = page->items;item;item=item->next) + gtk_widget_set_sensitive(item->data, FALSE); } - icd = g_new (ImporterComponentData, 1); - icd->client = g_object_ref (client); - icd->stop = FALSE; - icd->dialog = GTK_DIALOG (gtk_dialog_new_with_buttons(_("Importing"), NULL, 0, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - NULL)); - gtk_dialog_set_has_separator (icd->dialog, FALSE); - g_signal_connect (icd->dialog, "response", G_CALLBACK (dialog_response_cb), icd); - - g_object_weak_ref (G_OBJECT(icd->dialog), dialog_destroy_notify, icd); - - label = g_strdup_printf (_("Importing %s.\n"), utf8_filename); - icd->contents = gtk_label_new (label); - g_free (label); - - gtk_box_pack_start (GTK_BOX (icd->dialog->vbox), icd->contents, TRUE, TRUE, 0); - gtk_widget_show_all (GTK_WIDGET (icd->dialog)); - while (gtk_events_pending ()) - gtk_main_iteration (); - - if (evolution_importer_client_load_file (icd->client, filename) == FALSE) { - label = g_strdup_printf (_("Error loading %s"), utf8_filename); - e_notice (icd->dialog, GTK_MESSAGE_ERROR, _("Error loading %s"), filename); - - gtk_label_set_text (GTK_LABEL (icd->contents), label); - g_free (label); - while (gtk_events_pending ()) - gtk_main_iteration (); - - g_object_unref (icd->client); - if (icd->dialog) - gtk_widget_destroy (GTK_WIDGET (icd->dialog)); - g_free (icd); - g_free (utf8_filename); - return; - } - - icd->filename = g_strdup (filename); - icd->item = 1; - - label = g_strdup_printf (_("Importing %s\nImporting item 1."), - utf8_filename); - gtk_label_set_text (GTK_LABEL (icd->contents), label); - g_free (label); - g_free (utf8_filename); - while (gtk_events_pending ()) - gtk_main_iteration (); - - icd->listener = evolution_importer_listener_new (import_cb, icd); - evolution_importer_client_process_item (icd->client, icd->listener); -} - -static void -filename_changed (GtkEntry *entry, - ImportData *data) -{ - ImportDialogFilePage *page; - const char *filename; - - page = data->filepage; - - filename = gtk_entry_get_text (entry); - if (filename != NULL && *filename != '\0') - page->need_filename = FALSE; - else - page->need_filename = TRUE; - - gnome_druid_set_buttons_sensitive (GNOME_DRUID (data->druid), - TRUE, !page->need_filename, TRUE, FALSE); + gnome_druid_set_buttons_sensitive(GNOME_DRUID (data->druid), TRUE, fileok, TRUE, FALSE); } static void item_selected (GtkWidget *item, ImportData *data) { - char *iid; - - g_free (data->choosen_iid); - iid = g_object_get_data (G_OBJECT (item), "bonoboiid"); - if (iid == NULL) - data->choosen_iid = g_strdup ("Automatic"); - else - data->choosen_iid = g_strdup (iid); + data->filepage->importer = g_object_get_data((GObject *)item, "importer"); + filename_changed((GtkEntry *)gnome_file_entry_gtk_entry((GnomeFileEntry *)data->filepage->filename), data); } +#if 0 static int compare_info_name (const void *data1, const void *data2) { @@ -575,54 +261,7 @@ compare_info_name (const void *data1, const void *data2) } return g_utf8_collate (name1, name2); } - -static GtkWidget * -create_plugin_menu (ImportData *data) -{ - Bonobo_ServerInfoList *info_list; - CORBA_Environment ev; - int i; - GtkWidget *menu; - GtkWidget *item; - - menu = gtk_menu_new (); - item = gtk_menu_item_new_with_label (_("Automatic")); - g_object_set_data_full ((GObject *)item, "bonoboiid", g_strdup ("Automatic"), g_free); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); - - CORBA_exception_init (&ev); - info_list = bonobo_activation_query (IMPORTER_REPO_ID_QUERY, NULL, &ev); - /* Sort info list to get a consistent ordering of the items in the - * combo box from one run of evolution to another. - */ - qsort (info_list->_buffer, info_list->_length, - sizeof (Bonobo_ServerInfo), - compare_info_name); - - for (i = 0; i < info_list->_length; i++) { - const Bonobo_ServerInfo *info; - char *name = NULL; - - info = info_list->_buffer + i; - - name = g_strdup (get_name_from_component_info (info)); - if (name == NULL) { - name = g_strdup (info->iid); - } - - item = gtk_menu_item_new_with_label (name); - g_free (name); - gtk_widget_show (item); - g_signal_connect (item, "activate", - G_CALLBACK (item_selected), data); - - g_object_set_data_full ((GObject *)item, "bonoboiid", g_strdup (info->iid), g_free); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); - } - CORBA_free (info_list); - - return menu; -} +#endif static ImportDialogFilePage * importer_file_page_new (ImportData *data) @@ -634,7 +273,6 @@ importer_file_page_new (ImportData *data) page = g_new0 (ImportDialogFilePage, 1); page->vbox = gtk_vbox_new (FALSE, 5); - page->need_filename = TRUE; table = gtk_table_new (2, 2, FALSE); gtk_table_set_row_spacings (GTK_TABLE (table), 2); @@ -665,8 +303,6 @@ importer_file_page_new (ImportData *data) gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5); page->filetype = gtk_option_menu_new (); - page->menu = create_plugin_menu (data); - gtk_option_menu_set_menu (GTK_OPTION_MENU (page->filetype), page->menu); gtk_table_attach (GTK_TABLE (table), page->filetype, 1, 2, row, row + 1, GTK_EXPAND | GTK_FILL, 0, 0, 0); gtk_label_set_mnemonic_widget(GTK_LABEL(label), page->filetype); @@ -676,7 +312,6 @@ importer_file_page_new (ImportData *data) return page; } - static ImportDialogDestPage * importer_dest_page_new (ImportData *data) { @@ -721,214 +356,60 @@ importer_importer_page_new (ImportData *data) sep = gtk_hseparator_new (); gtk_box_pack_start (GTK_BOX (page->vbox), sep, FALSE, FALSE, 0); - page->prepared = FALSE; gtk_widget_show_all (page->vbox); return page; } -static GList * -get_intelligent_importers (void) -{ - Bonobo_ServerInfoList *info_list; - GList *iids_ret = NULL; - CORBA_Environment ev; - int i; - - CORBA_exception_init (&ev); - info_list = bonobo_activation_query (IMPORTER_INTEL_REPO_ID_QUERY, NULL, &ev); - CORBA_exception_free (&ev); - - for (i = 0; i < info_list->_length; i++) { - const Bonobo_ServerInfo *info; - - info = info_list->_buffer + i; - iids_ret = g_list_prepend (iids_ret, g_strdup (info->iid)); - } - - return iids_ret; -} - static gboolean -prepare_intelligent_page (GnomeDruidPage *page, +prepare_intelligent_page (GnomeDruidPage *dpage, GnomeDruid *druid, ImportData *data) { - GtkWidget *dialog; - ImportDialogImporterPage *import; - GList *l, *importers; - GtkWidget *table, *no_data; - int running = 0; - - if (data->importerpage->prepared == TRUE) { - if (data->importerpage->running == 0) - gnome_druid_set_buttons_sensitive(druid, TRUE, FALSE, TRUE, FALSE); - return TRUE; - } + GSList *l; + GtkWidget *table; + int row; + ImportDialogImporterPage *page = data->importerpage; - data->importerpage->prepared = TRUE; - - dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_INFO, GTK_BUTTONS_NONE, "%s", - _("Please wait...\nScanning for existing setups")); - e_make_widget_backing_stored (dialog); -#if !GTK_CHECK_VERSION(2,4,0) - /* not needed for message_dialog with GTK+ 2.4 */ - gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); -#endif - - gtk_window_set_title (GTK_WINDOW (dialog), _("Starting Intelligent Importers")); - gtk_widget_show_all (dialog); - gtk_widget_show_now (dialog); + if (page->target != NULL) + return FALSE; - gtk_widget_queue_draw (dialog); - gdk_flush (); + page->target = e_import_target_new_home(data->import, g_get_home_dir()); - while (gtk_events_pending ()) { - gtk_main_iteration (); - } + if (data->importerpage->importers) + g_slist_free(data->importerpage->importers); + l = data->importerpage->importers = e_import_get_importers(data->import, (EImportTarget *)page->target); - import = data->importerpage; - importers = get_intelligent_importers (); - if (importers == NULL) { - /* No importers, go directly to finish, do not pass go - Do not collect $200 */ - import->running = 0; - no_data = create_help ("nodata_html"); - gtk_box_pack_start (GTK_BOX (data->importerpage->vbox), no_data, - FALSE, TRUE, 0); + if (l == NULL) { + gtk_box_pack_start(GTK_BOX (data->importerpage->vbox), create_help("nodata_html"), FALSE, TRUE, 0); gnome_druid_set_buttons_sensitive(druid, TRUE, FALSE, TRUE, FALSE); - gtk_widget_destroy (dialog); return TRUE; } - table = gtk_table_new (g_list_length (importers), 2, FALSE); - for (l = importers; l; l = l->next) { - GtkWidget *label; - IntelligentImporterData *id; - CORBA_Environment ev; - gboolean can_run; + table = gtk_table_new(g_slist_length(l), 2, FALSE); + row = 0; + for (;l;l=l->next) { + EImportImporter *eii = l->data; char *str; - - id = g_new0 (IntelligentImporterData, 1); - id->iid = g_strdup (l->data); - - CORBA_exception_init (&ev); - id->object = bonobo_activation_activate_from_id ((char *) id->iid, 0, NULL, &ev); - if (BONOBO_EX (&ev)) { - g_warning ("Could not start %s:%s", id->iid, - CORBA_exception_id (&ev)); - - CORBA_exception_free (&ev); - /* Clean up the IID */ - g_free (id->iid); - g_free (id); - continue; - } - - if (id->object == CORBA_OBJECT_NIL) { - g_warning ("Could not activate component %s", id->iid); - CORBA_exception_free (&ev); - - g_free (id->iid); - g_free (id); - continue; - } - - can_run = GNOME_Evolution_IntelligentImporter_canImport (id->object, &ev); - if (BONOBO_EX (&ev)) { - g_warning ("Could not call canImport(%s): %s", id->iid, - CORBA_exception_id (&ev)); - bonobo_object_release_unref (id->object, &ev); - CORBA_exception_free (&ev); - - g_free (id->iid); - g_free (id); - continue; - } - - if (can_run == FALSE) { - bonobo_object_release_unref (id->object, &ev); - CORBA_exception_free (&ev); - g_free (id->iid); - g_free (id); - continue; - } - - running++; - id->name = GNOME_Evolution_IntelligentImporter__get_importername (id->object, &ev); - if (BONOBO_EX (&ev)) { - g_warning ("Could not get name(%s): %s", id->iid, - CORBA_exception_id (&ev)); - bonobo_object_release_unref (id->object, &ev); - CORBA_exception_free (&ev); - g_free (id->iid); - g_free (id); - continue; - } - - id->blurb = GNOME_Evolution_IntelligentImporter__get_message (id->object, &ev); - if (BONOBO_EX (&ev)) { - g_warning ("Could not get message(%s): %s", - id->iid, CORBA_exception_id (&ev)); - bonobo_object_release_unref (id->object, &ev); - CORBA_exception_free (&ev); - g_free (id->iid); - CORBA_free (id->name); - g_free (id); - continue; - } - - id->control = Bonobo_Unknown_queryInterface (id->object, - "IDL:Bonobo/Control:1.0", &ev); - if (BONOBO_EX (&ev)) { - g_warning ("Could not QI for Bonobo/Control:1.0 %s:%s", - id->iid, CORBA_exception_id (&ev)); - bonobo_object_release_unref (id->object, &ev); - CORBA_exception_free (&ev); - g_free (id->iid); - CORBA_free (id->name); - CORBA_free (id->blurb); - continue; - } - - if (id->control != CORBA_OBJECT_NIL) { - id->widget = bonobo_widget_new_control_from_objref (id->control, CORBA_OBJECT_NIL); - gtk_widget_show (id->widget); - } else { - id->widget = gtk_label_new (""); - gtk_widget_show (id->widget); - } + GtkWidget *w, *label; - CORBA_exception_free (&ev); + w = e_import_get_widget(data->import, (EImportTarget *)page->target, eii); - import->importers = g_list_prepend (import->importers, id); - str = g_strdup_printf (_("From %s:"), id->name); - label = gtk_label_new (str); - g_free (str); - - gtk_misc_set_alignment (GTK_MISC (label), 0, .5); - - gtk_table_attach (GTK_TABLE (table), label, 0, 1, running - 1, - running, GTK_FILL, 0, 0, 0); - gtk_table_attach (GTK_TABLE (table), id->widget, 1, 2, - running - 1, running, GTK_FILL, 0, 3, 0); - gtk_box_pack_start (GTK_BOX (data->importerpage->vbox), table, - FALSE, FALSE, 0); - } + str = g_strdup_printf(_("From %s:"), eii->name); + label = gtk_label_new(str); + gtk_widget_show(label); + g_free(str); - gtk_widget_show_all (table); + gtk_misc_set_alignment((GtkMisc *)label, 0, .5); - if (running == 0) { - no_data = create_help ("nodata_html"); - gtk_box_pack_start (GTK_BOX (data->importerpage->vbox), no_data, - FALSE, TRUE, 0); - gnome_druid_set_buttons_sensitive(druid, TRUE, FALSE, TRUE, FALSE); - gtk_widget_destroy (dialog); - return TRUE; + gtk_table_attach((GtkTable *)table, label, 0, 1, row, row+1, GTK_FILL, 0, 0, 0); + if (w) + gtk_table_attach((GtkTable *)table, w, 1, 2, row, row+1, GTK_FILL, 0, 3, 0); + row++; } - import->running = running; - gtk_widget_destroy (dialog); + gtk_widget_show(table); + gtk_box_pack_start((GtkBox *)data->importerpage->vbox, table, FALSE, FALSE, 0); return FALSE; } @@ -958,95 +439,57 @@ import_druid_weak_notify (void *blah, { ImportData *data = (ImportData *) blah; - g_object_unref (data->wizard); - g_free (data->choosen_iid); - g_free (data); + if (data->importerpage->target) + e_import_target_free(data->import, data->importerpage->target); + g_slist_free(data->importerpage->importers); + + if (data->filepage->target) + e_import_target_free(data->import, data->filepage->target); + g_slist_free(data->filepage->items); + + g_object_unref(data->import); + + g_object_unref(data->wizard); + g_free(data); } static void -free_importers (ImportData *data) +import_status(EImport *import, const char *what, int pc, void *d) { - GList *l; - - for (l = data->importerpage->importers; l; l = l->next) { - IntelligentImporterData *iid; - - iid = l->data; - if (iid->object != CORBA_OBJECT_NIL) { - bonobo_object_release_unref (iid->object, NULL); - } - } + ImportData *data = d; - g_list_free (data->importerpage->importers); + gtk_progress_bar_set_fraction((GtkProgressBar *)data->import_progress, (gfloat)(pc/100.0)); + gtk_progress_bar_set_text((GtkProgressBar *)data->import_progress, what); } static void -start_importers (GList *p) +import_dialog_response(GtkDialog *d, guint button, ImportData *data) { - CORBA_Environment ev; - - for (; p; p = p->next) { - SelectedImporterData *sid = p->data; - - CORBA_exception_init (&ev); - GNOME_Evolution_IntelligentImporter_importData (sid->importer, &ev); - if (BONOBO_EX (&ev)) { - g_warning ("Error importing %s\n%s", sid->iid, - CORBA_exception_id (&ev)); - } - CORBA_exception_free (&ev); - } + if (button == GTK_RESPONSE_CANCEL) + e_import_cancel(data->import, data->import_target, data->import_importer); } static void -do_import (ImportData *data) +import_done(EImport *ei, void *d) { - CORBA_Environment ev; - GList *l, *selected = NULL; - - for (l = data->importerpage->importers; l; l = l->next) { - IntelligentImporterData *importer_data; - SelectedImporterData *sid; - char *iid; - - importer_data = l->data; - iid = g_strdup (importer_data->iid); - - sid = g_new (SelectedImporterData, 1); - sid->iid = iid; - - CORBA_exception_init (&ev); - sid->importer = bonobo_object_dup_ref (importer_data->object, &ev); - if (BONOBO_EX (&ev)) { - g_warning ("Error duplication %s\n(%s)", iid, - CORBA_exception_id (&ev)); - g_free (iid); - CORBA_exception_free (&ev); - g_free (sid); - continue; - } - CORBA_exception_free (&ev); - - selected = g_list_prepend (selected, sid); - } - - free_importers (data); - - if (selected != NULL) { - start_importers (selected); + ImportData *data = d; - for (l = selected; l; l = l->next) { - SelectedImporterData *sid = l->data; + gtk_widget_destroy(data->import_dialog); + gtk_widget_destroy(data->dialog); +} - CORBA_exception_init (&ev); - bonobo_object_release_unref (sid->importer, &ev); - CORBA_exception_free (&ev); +static void +import_intelligent_done(EImport *ei, void *d) +{ + ImportData *data = d; - g_free (sid->iid); - g_free (sid); - } - g_list_free (selected); - } + if (data->importerpage->current + && (data->importerpage->current = data->importerpage->current->next)) { + import_status(ei, "", 0, d); + data->import_importer = data->importerpage->current->data; + e_import_import(data->import, (EImportTarget *)data->importerpage->target, data->import_importer, import_status, import_intelligent_done, data); + } else + import_done(ei, d); } static void @@ -1054,94 +497,110 @@ import_druid_finish (GnomeDruidPage *page, GnomeDruid *druid, ImportData *data) { - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->typepage->intelligent))) { - do_import (data); + EImportCompleteFunc done = NULL; + char *msg = NULL; + + if (gtk_toggle_button_get_active((GtkToggleButton *)data->typepage->intelligent)) { + data->importerpage->current = data->importerpage->importers; + if (data->importerpage->current) { + data->import_target = (EImportTarget *)data->importerpage->target; + data->import_importer = data->importerpage->current->data; + done = import_intelligent_done; + msg = g_strdup_printf(_("Importing data.")); + } + } else { + if (data->filepage->importer) { + data->import_importer = data->filepage->importer; + data->import_target = (EImportTarget *)data->filepage->target; + done = import_done; + msg = g_strdup_printf(_("Importing `%s'"), data->filepage->target->uri_src); + } + } + + if (done) { + data->import_dialog = e_error_new(NULL, "shell:importing", msg, NULL); + g_signal_connect(data->import_dialog, "response", G_CALLBACK(import_dialog_response), data); + data->import_label = gtk_label_new(_("Please wait")); + data->import_progress = gtk_progress_bar_new(); + gtk_box_pack_start(GTK_BOX(((GtkDialog *)data->import_dialog)->vbox), data->import_label, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(((GtkDialog *)data->import_dialog)->vbox), data->import_progress, FALSE, FALSE, 0); + gtk_widget_show_all(data->import_dialog); + + e_import_import(data->import, data->import_target, data->import_importer, import_status, import_done, data); } else { - start_import (druid, data->filename, data->client); + gtk_widget_destroy(data->dialog); } - gtk_widget_destroy (data->dialog); + g_free(msg); } static gboolean -prepare_file_page (GnomeDruidPage *page, +prepare_file_page (GnomeDruidPage *dpage, GnomeDruid *druid, ImportData *data) { - gnome_druid_set_buttons_sensitive (druid, TRUE, - !data->filepage->need_filename, - TRUE, FALSE); - return FALSE; -} + GtkWidget *item, *menu; + GSList *importers; + ImportDialogFilePage *page = data->filepage; -static gboolean -next_file_page (GnomeDruidPage *page, - GnomeDruid *druid, - ImportData *data) -{ - char *real_iid = NULL; - char *utf8_filename; - - /* Get and test the file name */ - if (data->filename) - g_free (data->filename); - utf8_filename = gnome_file_entry_get_full_path (GNOME_FILE_ENTRY (data->filepage->filename), FALSE); - data->filename = g_filename_from_utf8 (utf8_filename, -1, NULL, NULL, NULL); - - if (!g_file_test (data->filename, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) { - e_notice (druid, GTK_MESSAGE_ERROR, _("File %s does not exist"), utf8_filename); - gnome_druid_set_page (druid, GNOME_DRUID_PAGE (data->filedialog)); - g_free (utf8_filename); - return TRUE; + if (page->target != NULL) { + filename_changed((GtkEntry *)gnome_file_entry_gtk_entry((GnomeFileEntry *)data->filepage->filename), data); + return FALSE; } - /* Work out the component to use */ - if (data->choosen_iid == NULL || strcmp (data->choosen_iid, "Automatic") == 0) { - if (!get_iid_for_filetype (data->filename, &real_iid)) { - gnome_druid_set_page (druid, GNOME_DRUID_PAGE (data->filedialog)); + page->target = e_import_target_new_uri(data->import, NULL, NULL); + importers = e_import_get_importers(data->import, (EImportTarget *)page->target); - g_free (utf8_filename); - return TRUE; - } - } else { - real_iid = g_strdup (data->choosen_iid); - } + menu = gtk_menu_new(); + while (importers) { + EImportImporter *eii = importers->data; - if (!real_iid) { - e_notice (druid, GTK_MESSAGE_ERROR, _("No importer available for file %s"), utf8_filename); - gnome_druid_set_page (druid, GNOME_DRUID_PAGE (data->filedialog)); + item = gtk_menu_item_new_with_label(eii->name); + gtk_widget_show(item); + g_object_set_data((GObject *)item, "importer", eii); + g_signal_connect(item, "activate", G_CALLBACK(item_selected), data); + gtk_menu_shell_append((GtkMenuShell *)menu, item); - g_free (utf8_filename); - return TRUE; + data->filepage->items = g_slist_append(data->filepage->items, item); + importers = importers->next; } + g_slist_free(importers); - if (data->client) - g_object_unref (data->client); - data->client = evolution_importer_client_new_from_id (real_iid); - g_free (real_iid); - g_free (utf8_filename); + data->filepage->menu = menu; + gtk_option_menu_set_menu((GtkOptionMenu *)data->filepage->filetype, menu); - if (!data->client) { - e_notice (druid, GTK_MESSAGE_ERROR, _("Unable to execute importer")); - gnome_druid_set_page (druid, GNOME_DRUID_PAGE (data->filedialog)); + filename_changed((GtkEntry *)gnome_file_entry_gtk_entry((GnomeFileEntry *)data->filepage->filename), data); - return TRUE; - } - return FALSE; } static gboolean -prepare_dest_page (GnomeDruidPage *page, +next_file_page (GnomeDruidPage *page, + GnomeDruid *druid, + ImportData *data) +{ + /* We dont sensitise the next button if we're not already usable */ + return FALSE; +} + +static gboolean +prepare_dest_page (GnomeDruidPage *dpage, GnomeDruid *druid, ImportData *data) -{ - /* Add the widget */ - if (data->control) - gtk_container_remove (GTK_CONTAINER (data->destpage->vbox), data->control); - data->control = evolution_importer_client_create_control (data->client); - gtk_box_pack_start((GtkBox *)data->destpage->vbox, data->control, FALSE, FALSE, 0); - gtk_widget_show_all (data->destpage->vbox); +{ + ImportDialogDestPage *page = data->destpage; + + if (page->control) + gtk_container_remove((GtkContainer *)page->vbox, page->control); + + page->control = e_import_get_widget(data->import, (EImportTarget *)data->filepage->target, data->filepage->importer); + if (page->control == NULL) { + /* Coding error, not needed for translators */ + page->control = gtk_label_new("** PLUGIN ERROR ** No settings for importer"); + gtk_widget_show(page->control); + } + + gtk_box_pack_start((GtkBox *)data->destpage->vbox, page->control, TRUE, TRUE, 0); return FALSE; } @@ -1175,11 +634,7 @@ back_finish_page (GnomeDruidPage *page, ImportData *data) { if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->typepage->intelligent))) { - if (data->importerpage->running != 0) { - gnome_druid_set_page (druid, GNOME_DRUID_PAGE (data->intelligent)); - } else { - gnome_druid_set_page (druid, GNOME_DRUID_PAGE (data->typedialog)); - } + gnome_druid_set_page (druid, GNOME_DRUID_PAGE (data->intelligent)); } else { gnome_druid_set_page (druid, GNOME_DRUID_PAGE (data->destdialog)); } @@ -1216,7 +671,9 @@ e_shell_importer_start_import (EShellWindow *shell_window) if (dialog_open) { return; } - + + data->import = e_import_new("org.gnome.evolution.shell.importer"); + icon = e_icon_factory_get_icon ("stock_mail-import", E_ICON_SIZE_DIALOG); dialog_open = TRUE; diff --git a/shell/e-shell.c b/shell/e-shell.c index 5726535bad..98b60ab5b2 100644 --- a/shell/e-shell.c +++ b/shell/e-shell.c @@ -43,8 +43,6 @@ #include "evolution-shell-component-utils.h" -#include "importer/intelligent.h" - #include <glib.h> #include <gtk/gtkmain.h> diff --git a/shell/import.glade b/shell/import.glade new file mode 100644 index 0000000000..8af6884822 --- /dev/null +++ b/shell/import.glade @@ -0,0 +1,124 @@ +<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> +<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd"> + +<glade-interface> +<requires lib="gnome"/> + +<widget class="GtkWindow" id="importwizard"> + <property name="title" translatable="yes">Evolution Import Assistant</property> + <property name="type">GTK_WINDOW_TOPLEVEL</property> + <property name="window_position">GTK_WIN_POS_NONE</property> + <property name="modal">False</property> + <property name="resizable">True</property> + <property name="destroy_with_parent">False</property> + + <child> + <widget class="GnomeDruid" id="druid1"> + <property name="border_width">4</property> + <property name="visible">True</property> + <property name="show_help">False</property> + + <child> + <widget class="GnomeDruidPageEdge" id="page0"> + <property name="visible">True</property> + <property name="position">GNOME_EDGE_START</property> + <property name="title" translatable="yes">Evolution Import Assistant</property> + <property name="text" translatable="yes">Welcome to the Evolution Import Assistant. +With this assistant you will be guided through the process of +importing external files into Evolution.</property> + </widget> + </child> + + <child> + <widget class="GnomeDruidPageStandard" id="page1"> + <property name="visible">True</property> + <property name="title" translatable="yes">Importer Type</property> + + <child internal-child="vbox"> + <widget class="GtkVBox" id="druid-vbox2"> + <property name="border_width">16</property> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <placeholder/> + </child> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GnomeDruidPageStandard" id="page2-file"> + <property name="visible">True</property> + <property name="title" translatable="yes">Select a File</property> + + <child internal-child="vbox"> + <widget class="GtkVBox" id="druid-vbox1"> + <property name="border_width">16</property> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <placeholder/> + </child> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GnomeDruidPageStandard" id="page3-file"> + <property name="visible">True</property> + <property name="title" translatable="yes">Import Location</property> + + <child internal-child="vbox"> + <widget class="GtkVBox" id="druid-vbox3"> + <property name="border_width">16</property> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <placeholder/> + </child> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GnomeDruidPageStandard" id="page2-intelligent"> + <property name="visible">True</property> + <property name="title" translatable="yes">Select Importers</property> + + <child internal-child="vbox"> + <widget class="GtkVBox" id="druid-vbox3"> + <property name="border_width">16</property> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <placeholder/> + </child> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GnomeDruidPageEdge" id="page4"> + <property name="visible">True</property> + <property name="position">GNOME_EDGE_FINISH</property> + <property name="title" translatable="yes">Import File</property> + <property name="text" translatable="yes">Click "Import" to begin importing the file into Evolution. </property> + </widget> + </child> + </widget> + </child> +</widget> + +</glade-interface> diff --git a/shell/importer/.cvsignore b/shell/importer/.cvsignore deleted file mode 100644 index a1e30a4161..0000000000 --- a/shell/importer/.cvsignore +++ /dev/null @@ -1,10 +0,0 @@ -.deps -.libs -Makefile.in -Makefile -GNOME_Evolution_Importer-stubs.c -GNOME_Evolution_Importer-skels.c -GNOME_Evolution_Importer-common.c -GNOME_Evolution_Importer.h -*.lo -*.la diff --git a/shell/shell.error.xml b/shell/shell.error.xml index 390516a1de..e4d0506476 100644 --- a/shell/shell.error.xml +++ b/shell/shell.error.xml @@ -1,6 +1,12 @@ <?xml version="1.0" encoding="UTF-8"?> <error-list domain="shell"> + <error id="importing" type="info"> + <_title>Importing ...</_title> + <secondary>{0}</secondary> + <button stock="gtk-cancel" response="GTK_RESPONSE_CANCEL"/> + </error> + <error id="upgrade-nospace" type="error"> <_primary>Insufficient disk space for upgrade.</_primary> <_secondary xml:space="preserve">Upgrading your data and settings will require upto {0} of disk space, but you only have {1} available. |