diff options
37 files changed, 3193 insertions, 1553 deletions
@@ -1,3 +1,9 @@ +2001-05-08 Iain Holmes <iain@ximian.com> + + * Makefile.am: Add the importers subdir. + + * configure.in: Make the importers/Makefile + 2001-05-08 Christopher James Lahey <clahey@ximian.com> * configure.in: Bumped check for gal to 0.7.99.3. diff --git a/Makefile.am b/Makefile.am index 84f9d63131..a1fb079cde 100644 --- a/Makefile.am +++ b/Makefile.am @@ -31,6 +31,7 @@ SUBDIRS = \ addressbook \ calendar \ wombat \ + importers \ art \ ui \ default_user \ diff --git a/addressbook/ChangeLog b/addressbook/ChangeLog index f32fbeca29..10e0616c9c 100644 --- a/addressbook/ChangeLog +++ b/addressbook/ChangeLog @@ -1,3 +1,13 @@ +2001-05-08 Iain Holmes <iain@ximian.com> + + * backend/ebook/GNOME_Evolution_Addressbook_VCard_Importer.oaf.in: + Renamed the GnomeCard_Importer.oaf.in to this, and change the IID. + + * Makefile.am: Rename all the GnomeCard to VCard. + + * evolution-vcard-importer.c: Make the GnomeCard a generic + vcard importer. + 2001-05-08 Christopher James Lahey <clahey@ximian.com> * backend/ebook/Makefile.am (libebookinclude_HEADERS): Removed diff --git a/addressbook/backend/ebook/GNOME_Evolution_Addressbook_GnomeCard_Importer.oaf.in b/addressbook/backend/ebook/GNOME_Evolution_Addressbook_VCard_Importer.oaf.in index 69dfa90871..9cd4699633 100644 --- a/addressbook/backend/ebook/GNOME_Evolution_Addressbook_GnomeCard_Importer.oaf.in +++ b/addressbook/backend/ebook/GNOME_Evolution_Addressbook_VCard_Importer.oaf.in @@ -1,29 +1,29 @@ <oaf_info> -<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_GnomeCard_ImporterFactory" +<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_VCard_ImporterFactory" type="exe" - location="evolution-gnomecard-importer"> + location="evolution-vcard-importer"> <oaf_attribute name="repo_ids" type="stringv"> <item value="IDL:GNOME/ObjectFactory:1.0"/> </oaf_attribute> <oaf_attribute name="description" type="string" - _value="Factory to import GnomeCard files into Evolution."/> + _value="Factory to import VCard files into Evolution."/> </oaf_server> -<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_GnomeCard_Importer" +<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_VCard_Importer" type="factory" - location="OAFIID:GNOME_Evolution_Addressbook_GnomeCard_ImporterFactory"> + location="OAFIID:GNOME_Evolution_Addressbook_VCard_ImporterFactory"> <oaf_attribute name="repo_ids" type="stringv"> <item value="IDL:GNOME/Evolution/Importer:1.0"/> </oaf_attribute> <oaf_attribute name="evolution:menu-name" type="string" - value="GnomeCard (.vcf, .gcrd)"/> + value="VCard (.vcf, .gcrd)"/> <oaf_attribute name="description" type="string" - _value="Imports GnomeCard files into Evolution."/> + _value="Imports VCard files into Evolution."/> </oaf_server> </oaf_info> diff --git a/addressbook/backend/ebook/Makefile.am b/addressbook/backend/ebook/Makefile.am index da7307c1a5..624d1b072b 100644 --- a/addressbook/backend/ebook/Makefile.am +++ b/addressbook/backend/ebook/Makefile.am @@ -1,6 +1,6 @@ noinst_PROGRAMS = test-card test-client test-client-list -bin_PROGRAMS = evolution-gnomecard-importer \ +bin_PROGRAMS = evolution-vcard-importer \ load-pine-addressbook load-gnomecard-addressbook CORBA_SOURCE = \ @@ -106,9 +106,9 @@ test_card_LDADD = \ $(top_builddir)/libversit/libversit.la \ $(top_builddir)/e-util/libeutil.la -evolution_gnomecard_importer_SOURCES = \ - evolution-gnomecard-importer.c -evolution_gnomecard_importer_LDADD = \ +evolution_vcard_importer_SOURCES = \ + evolution-vcard-importer.c +evolution_vcard_importer_LDADD = \ libebook.la \ $(BONOBO_GNOME_LIBS) \ $(EXTRA_GNOME_LIBS) \ @@ -148,7 +148,7 @@ dist-hook: cd $(distdir); rm -f $(BUILT_SOURCES) oafdir = $(datadir)/oaf -oaf_in_files = GNOME_Evolution_Addressbook_GnomeCard_Importer.oaf.in +oaf_in_files = GNOME_Evolution_Addressbook_VCard_Importer.oaf.in oaf_DATA = $(oaf_in_files:.oaf.in=.oaf) @XML_I18N_MERGE_OAF_RULE@ diff --git a/addressbook/backend/ebook/evolution-gnomecard-importer.c b/addressbook/backend/ebook/evolution-vcard-importer.c index bb5e45cdd6..2864627a39 100644 --- a/addressbook/backend/ebook/evolution-gnomecard-importer.c +++ b/addressbook/backend/ebook/evolution-vcard-importer.c @@ -12,7 +12,7 @@ #include <importer/evolution-importer.h> #include <importer/GNOME_Evolution_Importer.h> -#define COMPONENT_FACTORY_IID "OAFIID:GNOME_Evolution_Addressbook_GnomeCard_ImporterFactory" +#define COMPONENT_FACTORY_IID "OAFIID:GNOME_Evolution_Addressbook_VCard_ImporterFactory" static BonoboGenericFactory *factory = NULL; @@ -22,14 +22,14 @@ typedef struct { GList *iterator; EBook *book; gboolean ready; -} GnomeCardImporter; +} VCardImporter; static void add_card_cb (EBook *book, EBookStatus status, const gchar *id, gpointer closure) { ECard *card = E_CARD(closure); char *vcard = e_card_get_vcard(card); - g_print ("Saved card: %s\n", vcard); + g_free(vcard); gtk_object_unref(GTK_OBJECT(card)); } @@ -37,14 +37,14 @@ add_card_cb (EBook *book, EBookStatus status, const gchar *id, gpointer closure) static void book_open_cb (EBook *book, EBookStatus status, gpointer closure) { - GnomeCardImporter *gci = (GnomeCardImporter *) closure; + VCardImporter *gci = (VCardImporter *) closure; gci->cardlist = e_card_load_cards_from_file(gci->filename); gci->ready = TRUE; } static void -ebook_create (GnomeCardImporter *gci) +ebook_create (VCardImporter *gci) { gchar *path, *uri; @@ -75,12 +75,12 @@ process_item_fn (EvolutionImporter *importer, void *closure, CORBA_Environment *ev) { - GnomeCardImporter *gci = (GnomeCardImporter *) closure; + VCardImporter *gci = (VCardImporter *) closure; ECard *card; if (gci->iterator == NULL) gci->iterator = gci->cardlist; - + if (gci->ready == FALSE) { GNOME_Evolution_ImporterListener_notifyResult (listener, GNOME_Evolution_ImporterListener_NOT_READY, @@ -95,12 +95,12 @@ process_item_fn (EvolutionImporter *importer, FALSE, ev); return; } - + card = gci->iterator->data; e_book_add_card (gci->book, card, add_card_cb, card); - + gci->iterator = gci->iterator->next; - + GNOME_Evolution_ImporterListener_notifyResult (listener, GNOME_Evolution_ImporterListener_OK, gci->iterator ? TRUE : FALSE, @@ -116,6 +116,35 @@ static char *supported_extensions[3] = { ".vcf", ".gcrd", NULL }; +/* Actually check the contents of this file */ +static gboolean +check_file_is_vcard (const char *filename) +{ + FILE *handle; + char line[4096]; + gboolean result; + + handle = fopen (filename, "r"); + if (handle == NULL) { + return FALSE; + } + + fgets (line, 4096, handle); + if (line == NULL) { + fclose (handle); + return FALSE; + } + + if (strcmp (line, "BEGIN:VCARD") == 0) { + result = TRUE; + } else { + result = FALSE; + } + + fclose (handle); + return result; +} + static gboolean support_format_fn (EvolutionImporter *importer, const char *filename, @@ -127,7 +156,7 @@ support_format_fn (EvolutionImporter *importer, ext = strrchr (filename, '.'); for (i = 0; supported_extensions[i] != NULL; i++) { if (strcmp (supported_extensions[i], ext) == 0) - return TRUE; + return check_file_is_vcard (filename); } return FALSE; @@ -135,7 +164,7 @@ support_format_fn (EvolutionImporter *importer, static void importer_destroy_cb (GtkObject *object, - GnomeCardImporter *gci) + VCardImporter *gci) { gtk_main_quit (); } @@ -146,9 +175,9 @@ load_file_fn (EvolutionImporter *importer, const char *folderpath, void *closure) { - GnomeCardImporter *gci; + VCardImporter *gci; - gci = (GnomeCardImporter *) closure; + gci = (VCardImporter *) closure; gci->filename = g_strdup (filename); gci->cardlist = NULL; gci->iterator = NULL; @@ -163,9 +192,9 @@ factory_fn (BonoboGenericFactory *_factory, void *closure) { EvolutionImporter *importer; - GnomeCardImporter *gci; + VCardImporter *gci; - gci = g_new (GnomeCardImporter, 1); + gci = g_new (VCardImporter, 1); importer = evolution_importer_new (support_format_fn, load_file_fn, process_item_fn, NULL, gci); @@ -197,8 +226,8 @@ main (int argc, { CORBA_ORB orb; - gnome_init_with_popt_table ("Evolution-GnomeCard-Importer", - "0.0", argc, argv, oaf_popt_options, 0, + gnome_init_with_popt_table ("Evolution-VCard-Importer", + PACKAGE, argc, argv, oaf_popt_options, 0, NULL); orb = oaf_init (argc, argv); if (bonobo_init (orb, CORBA_OBJECT_NIL, CORBA_OBJECT_NIL) == FALSE) { diff --git a/configure.in b/configure.in index b1b328e57f..cbbc505104 100644 --- a/configure.in +++ b/configure.in @@ -847,6 +847,7 @@ calendar/conduits/todo/Makefile filter/Makefile wombat/Makefile composer/Makefile +importers/Makefile art/Makefile ui/Makefile default_user/Makefile diff --git a/importers/ChangeLog b/importers/ChangeLog new file mode 100644 index 0000000000..17c630363a --- /dev/null +++ b/importers/ChangeLog @@ -0,0 +1,11 @@ +2001-05-08 Iain Holmes <iain@ximian.com> + + * *: Added everything to CVS. + +2001-04-26 Iain Holmes <iain@ximian.com> + + * elm-importer.c: + pine-importer.c: + netscape-importer.c: Moved these files to their own toplevel. + Made them use the mbox importer component instead of doing it themselves. + Made them quit correctly, and store their settings. diff --git a/mail/importers/GNOME_Evolution_Mail_Pine_Intelligent_Importer.oaf.in b/importers/GNOME_Evolution_Elm_Intelligent_Importer.oaf.in index 1e1c5b79f8..6676042bf6 100644 --- a/mail/importers/GNOME_Evolution_Mail_Pine_Intelligent_Importer.oaf.in +++ b/importers/GNOME_Evolution_Elm_Intelligent_Importer.oaf.in @@ -1,17 +1,17 @@ <oaf_info> -<oaf_server iid="OAFIID:GNOME_Evolution_Mail_Pine_Intelligent_Importer_Factory" +<oaf_server iid="OAFIID:GNOME_Evolution_Elm_Intelligent_Importer_Factory" type="exe" - location="evolution-mail"> + location="evolution-elm-importer"> <oaf_attribute name="repo_ids" type="stringv"> <item value="IDL:GNOME/ObjectFactory:1.0"/> </oaf_attribute> </oaf_server> -<oaf_server iid="OAFIID:GNOME_Evolution_Mail_Pine_Intelligent_Importer" +<oaf_server iid="OAFIID:GNOME_Evolution_Elm_Intelligent_Importer" type="factory" - location="OAFIID:GNOME_Evolution_Mail_Pine_Intelligent_Importer_Factory"> + location="OAFIID:GNOME_Evolution_Elm_Intelligent_Importer_Factory"> <oaf_attribute name="repo_ids" type="stringv"> <item value="IDL:GNOME/Evolution/IntelligentImporter:1.0"/> diff --git a/mail/importers/GNOME_Evolution_Mail_Elm_Intelligent_Importer.oaf.in b/importers/GNOME_Evolution_Netscape_Intelligent_Importer.oaf.in index 7d75c1148d..a53d9bad6c 100644 --- a/mail/importers/GNOME_Evolution_Mail_Elm_Intelligent_Importer.oaf.in +++ b/importers/GNOME_Evolution_Netscape_Intelligent_Importer.oaf.in @@ -1,17 +1,17 @@ <oaf_info> -<oaf_server iid="OAFIID:GNOME_Evolution_Mail_Elm_Intelligent_Importer_Factory" +<oaf_server iid="OAFIID:GNOME_Evolution_Netscape_Intelligent_Importer_Factory" type="exe" - location="evolution-mail"> + location="evolution-netscape-importer"> <oaf_attribute name="repo_ids" type="stringv"> <item value="IDL:GNOME/ObjectFactory:1.0"/> </oaf_attribute> </oaf_server> -<oaf_server iid="OAFIID:GNOME_Evolution_Mail_Elm_Intelligent_Importer" +<oaf_server iid="OAFIID:GNOME_Evolution_Netscape_Intelligent_Importer" type="factory" - location="OAFIID:GNOME_Evolution_Mail_Elm_Intelligent_Importer_Factory"> + location="OAFIID:GNOME_Evolution_Netscape_Intelligent_Importer_Factory"> <oaf_attribute name="repo_ids" type="stringv"> <item value="IDL:GNOME/Evolution/IntelligentImporter:1.0"/> diff --git a/mail/importers/GNOME_Evolution_Mail_Netscape_Intelligent_Importer.oaf.in b/importers/GNOME_Evolution_Pine_Intelligent_Importer.oaf.in index db3f820d7b..00d15710f4 100644 --- a/mail/importers/GNOME_Evolution_Mail_Netscape_Intelligent_Importer.oaf.in +++ b/importers/GNOME_Evolution_Pine_Intelligent_Importer.oaf.in @@ -1,17 +1,17 @@ <oaf_info> -<oaf_server iid="OAFIID:GNOME_Evolution_Mail_Netscape_Intelligent_Importer_Factory" +<oaf_server iid="OAFIID:GNOME_Evolution_Pine_Intelligent_Importer_Factory" type="exe" - location="evolution-mail"> + location="evolution-pine-importer"> <oaf_attribute name="repo_ids" type="stringv"> <item value="IDL:GNOME/ObjectFactory:1.0"/> </oaf_attribute> </oaf_server> -<oaf_server iid="OAFIID:GNOME_Evolution_Mail_Netscape_Intelligent_Importer" +<oaf_server iid="OAFIID:GNOME_Evolution_Pine_Intelligent_Importer" type="factory" - location="OAFIID:GNOME_Evolution_Mail_Netscape_Intelligent_Importer_Factory"> + location="OAFIID:GNOME_Evolution_Pine_Intelligent_Importer_Factory"> <oaf_attribute name="repo_ids" type="stringv"> <item value="IDL:GNOME/Evolution/IntelligentImporter:1.0"/> diff --git a/importers/Makefile.am b/importers/Makefile.am new file mode 100644 index 0000000000..ced3910e63 --- /dev/null +++ b/importers/Makefile.am @@ -0,0 +1,67 @@ +bin_PROGRAMS = evolution-netscape-importer \ + evolution-elm-importer \ + evolution-pine-importer + +INCLUDES = \ + -DGNOMELOCALEDIR=\""$(localedir)"\" \ + -DG_LOG_DOMAIN=\"Evolution-Importer\" \ + -I$(top_srcdir) \ + -I$(top_builddir)/shell \ + -I$(top_srcdir)/shell \ + -I$(top_srcdir)/addressbook/backend/ebook \ + $(BONOBO_GNOME_CFLAGS) \ + $(EXTRA_GNOME_CFLAGS) + +IDLS = \ + $(top_srcdir)/mail/Mail.idl + +MAIL_GENERATED = \ + Mail.h \ + Mail-common.c \ + Mail-skels.c \ + Mail-stubs.c + +$(MAIL_GENERATED): $(IDLS) + $(ORBIT_IDL) -I $(srcdir) `$(GNOME_CONFIG) --cflags idl` $(top_srcdir)/mail/Mail.idl + +evolution_netscape_importer_SOURCES = \ + $(MAIL_GENERATED) \ + netscape-importer.c + +evolution_netscape_importer_LDADD = \ + $(BONOBO_GNOME_LIBS) \ + $(EXTRA_GNOME_LIBS) \ + $(top_builddir)/e-util/libeutil.la \ + $(top_builddir)/shell/importer/libevolution-importer.la + +evolution_elm_importer_SOURCES = \ + elm-importer.c + +evolution_elm_importer_LDADD = \ + $(BONOBO_GNOME_LIBS) \ + $(EXTRA_GNOME_LIBS) \ + $(top_builddir)/e-util/libeutil.la \ + $(top_builddir)/shell/importer/libevolution-importer.la + +evolution_pine_importer_SOURCES = \ + pine-importer.c + +evolution_pine_importer_LDADD = \ + $(BONOBO_GNOME_LIBS) \ + $(EXTRA_GNOME_LIBS) \ + $(top_builddir)/addressbook/backend/ebook/libebook.la \ + $(top_builddir)/e-util/libeutil.la \ + $(top_builddir)/e-util/ename/libename.la \ + $(top_builddir)/libversit/libversit.la \ + $(top_builddir)/shell/importer/libevolution-importer.la + +oafdir = $(datadir)/oaf +oaf_in_files = GNOME_Evolution_Netscape_Intelligent_Importer.oaf.in \ + GNOME_Evolution_Elm_Intelligent_Importer.oaf.in \ + GNOME_Evolution_Pine_Intelligent_Importer.oaf.in + +oaf_DATA = $(oaf_in_files:.oaf.in=.oaf) + +EXTRA_DIST = $(oaf_in_files) $(oaf_DATA) + +@XML_I18N_MERGE_OAF_RULE@ diff --git a/importers/elm-importer.c b/importers/elm-importer.c new file mode 100644 index 0000000000..d62264b973 --- /dev/null +++ b/importers/elm-importer.c @@ -0,0 +1,472 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* elm-importer.c + * + * Authors: + * Iain Holmes <iain@ximian.com> + * + * Copyright 2001 Ximian, Inc. (http://www.ximian.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <dirent.h> + +#include <glib.h> +#include <gnome.h> + +#include <bonobo/bonobo-object.h> +#include <bonobo/bonobo-control.h> +#include <bonobo/bonobo-generic-factory.h> +#include <bonobo/bonobo-main.h> + +#include <importer/evolution-intelligent-importer.h> +#include <importer/evolution-importer-client.h> +#include <importer/GNOME_Evolution_Importer.h> + +#define ELM_INTELLIGENT_IMPORTER_IID "OAFIID:GNOME_Evolution_Elm_Intelligent_Importer_Factory" +#define MBOX_IMPORTER_IID "OAFIID:GNOME_Evolution_Mail_Mbox_Importer" +#define KEY "elm-mail-imported" + +/*#define SUPER_IMPORTER_DEBUG*/ +#ifdef SUPER_IMPORTER_DEBUG +#define d(x) x +#else +#define d(x) +#endif + +typedef struct { + GList *dir_list; + + int num; + + GNOME_Evolution_Importer importer; + EvolutionImporterListener *listener; + + GtkWidget *mail; + gboolean do_mail; + GtkWidget *alias; + gboolean do_alias; +} ElmImporter; + +typedef struct { + char *parent; + char *foldername; + char *path; +} ElmFolder; + +static void import_next (ElmImporter *importer); + +static void +importer_cb (EvolutionImporterListener *listener, + EvolutionImporterResult result, + gboolean more_items, + void *data) +{ + ElmImporter *importer = (ElmImporter *) data; + CORBA_Object objref; + CORBA_Environment ev; + + g_print ("Processed.....\n"); + if (more_items) { + g_print ("Processing.....\n"); + + CORBA_exception_init (&ev); + objref = bonobo_object_corba_objref (BONOBO_OBJECT (importer->listener)); + GNOME_Evolution_Importer_processItem (importer->importer, + objref, &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + g_warning ("Exception: %s", CORBA_exception_id (&ev)); + CORBA_exception_free (&ev); + return; + } + CORBA_exception_free (&ev); + return; + } + + import_next (importer); +} + +static gboolean +elm_import_file (ElmImporter *importer, + const char *path, + const char *folderpath) +{ + CORBA_boolean result; + CORBA_Environment ev; + CORBA_Object objref; + + g_warning ("Importing %s as %s", path, folderpath); + + CORBA_exception_init (&ev); + result = GNOME_Evolution_Importer_loadFile (importer->importer, path, + folderpath, &ev); + if (ev._major != CORBA_NO_EXCEPTION || result == FALSE) { + g_warning ("Exception here: %s", CORBA_exception_id (&ev)); + CORBA_Object_release (importer->importer, &ev); + CORBA_exception_free (&ev); + return FALSE; + } + + importer->listener = evolution_importer_listener_new (importer_cb, + importer); + objref = bonobo_object_corba_objref (BONOBO_OBJECT (importer->listener)); + GNOME_Evolution_Importer_processItem (importer->importer, objref, &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + g_warning ("Exception: %s", CORBA_exception_id (&ev)); + CORBA_exception_free (&ev); + return FALSE; + } + CORBA_exception_free (&ev); + + return TRUE; +} + +static gboolean +is_kmail (const char *maildir) +{ + char *names[5] = + { + "inbox", + "outbox", + "sent-mail", + "trash", + "drafts" + }; + int i; + + for (i = 0; i < 5; i++) { + char *file, *index, *tmp; + + file = g_concat_dir_and_file (maildir, names[i]); + tmp = g_strdup_printf (".%s.index", names[i]); + index = g_concat_dir_and_file (maildir, tmp); + g_free (tmp); + + if (!g_file_exists (file) || + !g_file_exists (index)) { + g_free (index); + g_free (file); + return FALSE; + } + + g_free (index); + g_free (file); + } + + return TRUE; +} + +static gboolean +elm_can_import (EvolutionIntelligentImporter *ii, + void *closure) +{ + char *key, *maildir, *evolution_dir; + gboolean exists; + + evolution_dir = gnome_util_prepend_user_home ("evolution"); + /* Already imported */ + key = g_strdup_printf ("=%s/config/Importers=/importers/", evolution_dir); + g_free (evolution_dir); + + gnome_config_push_prefix (key); + g_free (key); + + if (gnome_config_get_bool (KEY) == TRUE) { + gnome_config_pop_prefix (); + return FALSE; + } + gnome_config_pop_prefix (); + + /* Elm uses ~/Mail + Alas so does MH and KMail. */ + maildir = gnome_util_prepend_user_home ("Mail"); + exists = g_file_exists (maildir); + + if (exists) { + char *mh, *mhdir; + + /* Check for some other files to work out what it is. */ + + /* MH? */ + mh = g_concat_dir_and_file (maildir, "context"); + mhdir = g_concat_dir_and_file (maildir, "inbox"); + if (g_file_exists (mh) && + g_file_test (mhdir, G_FILE_TEST_ISDIR)) { + exists = FALSE; /* Probably MH */ + } + + g_free (mh); + g_free (mhdir); + } + + if (exists) { + /* Check for KMail stuff */ + exists = !is_kmail (maildir); + } + + g_free (maildir); + + return exists; +} + +static void +import_next (ElmImporter *importer) +{ + ElmFolder *data; + + if (importer->dir_list) { + char *folder; + + data = importer->dir_list->data; + + folder = g_concat_dir_and_file (data->parent, data->foldername); + elm_import_file (importer, data->path, folder); + g_free (folder); + g_free (data->parent); + g_free (data->path); + g_free (data->foldername); + g_free (data); + importer->dir_list = importer->dir_list->next; + } +} + +static void +scan_dir (ElmImporter *importer, + const char *dirname, + const char *orig_parent) +{ + DIR *maildir; + struct stat buf; + struct dirent *current; + + maildir = opendir (dirname); + if (maildir == NULL) { + g_warning ("Could not open %s\nopendir returned: %s", + dirname, g_strerror (errno)); + return; + } + + current = readdir (maildir); + while (current) { + ElmFolder *pf; + char *fullname; + + /* Ignore . and .. */ + if (current->d_name[0] == '.') { + if (current->d_name[1] == '\0' || + (current->d_name[1] == '.' && current->d_name[2] == '\0')) { + current = readdir (maildir); + continue; + } + } + + fullname = g_concat_dir_and_file (dirname, current->d_name); + if (stat (fullname, &buf) == -1) { + g_warning ("Could not stat %s\nstat returned: %s", + fullname, g_strerror (errno)); + current = readdir (maildir); + g_free (fullname); + continue; + } + + if (S_ISREG (buf.st_mode)) { + pf = g_new (ElmFolder, 1); + pf->path = g_strdup (fullname); + pf->parent = g_strdup (orig_parent); + pf->foldername = g_strdup (current->d_name); + importer->dir_list = g_list_append (importer->dir_list, pf); + } else if (S_ISDIR (buf.st_mode)) { + char *subdir; + + pf = g_new (ElmFolder, 1); + pf->path = NULL; + pf->parent = g_strdup (orig_parent); + pf->foldername = g_strdup (current->d_name); + importer->dir_list = g_list_append (importer->dir_list, pf); + + subdir = g_concat_dir_and_file (orig_parent, current->d_name); + scan_dir (importer, fullname, subdir); + g_free (subdir); + } + + g_free (fullname); + current = readdir (maildir); + } +} + +static void +elm_create_structure (EvolutionIntelligentImporter *ii, + void *closure) +{ + ElmImporter *importer = closure; + char *maildir, *key, *evolution_dir; + + maildir = gnome_util_prepend_user_home ("Mail"); + scan_dir (importer, maildir, "/"); + g_free (maildir); + + /* Import them */ + import_next (importer); + + evolution_dir = gnome_util_prepend_user_home ("evolution"); + key = g_strdup_printf ("=%s/config/Importers=/importers/", evolution_dir); + g_free (evolution_dir); + + gnome_config_push_prefix (key); + g_free (key); + + gnome_config_set_bool (KEY, TRUE); + gnome_config_pop_prefix (); + + gnome_config_sync (); + gnome_config_drop_all (); +} + +static void +elm_destroy_cb (GtkObject *object, + ElmImporter *importer) +{ + g_print ("\n----------Settings-------\n"); + g_print ("Mail - %s\n", importer->do_mail ? "Yes" : "No"); + g_print ("Alias - %s\n", importer->do_alias ? "Yes" : "No"); + + gtk_main_quit (); +} + +/* Fun initialisation stuff */ +/* Fun control stuff */ +static void +checkbox_toggle_cb (GtkToggleButton *tb, + gboolean *do_item) +{ + *do_item = gtk_toggle_button_get_active (tb); +} + +static BonoboControl * +create_checkboxes_control (ElmImporter *importer) +{ + GtkWidget *container, *vbox; + BonoboControl *control; + + container = gtk_frame_new (_("Import")); + vbox = gtk_vbox_new (FALSE, 2); + gtk_container_set_border_width (GTK_CONTAINER (container), 2); + gtk_container_add (GTK_CONTAINER (container), vbox); + + 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); + importer->alias = gtk_check_button_new_with_label (_("Elm Aliases")); + gtk_signal_connect (GTK_OBJECT (importer->alias), "toggled", + GTK_SIGNAL_FUNC (checkbox_toggle_cb), + &importer->do_alias); + + gtk_box_pack_start (GTK_BOX (vbox), importer->mail, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox), importer->alias, FALSE, FALSE, 0); + + /* Disable the things that can't be done */ + gtk_widget_set_sensitive (importer->alias, FALSE); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (importer->mail), TRUE); + importer->do_mail = TRUE; + importer->do_alias = FALSE; + + gtk_widget_show_all (container); + control = bonobo_control_new (container); + return control; +} + +static BonoboObject * +factory_fn (BonoboGenericFactory *_factory, + void *closure) +{ + EvolutionIntelligentImporter *importer; + BonoboControl *control; + ElmImporter *elm; + CORBA_Environment ev; + char *message = N_("Evolution has found Elm mail files in ~/Mail.\n" + "Would you like to import them into Evolution?"); + + elm = g_new0 (ElmImporter, 1); + CORBA_exception_init (&ev); + elm->importer = oaf_activate_from_id (MBOX_IMPORTER_IID, 0, NULL, &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + g_warning ("Could not start MBox importer\n%s", + CORBA_exception_id (&ev)); + CORBA_exception_free (&ev); + return NULL; + } + CORBA_exception_free (&ev); + + importer = evolution_intelligent_importer_new (elm_can_import, + elm_create_structure, + _("Elm mail"), + _(message), elm); + gtk_signal_connect (GTK_OBJECT (importer), "destroy", + GTK_SIGNAL_FUNC (elm_destroy_cb), elm); + + control = create_checkboxes_control (elm); + bonobo_object_add_interface (BONOBO_OBJECT (importer), + BONOBO_OBJECT (control)); + return BONOBO_OBJECT (importer); +} + +/* Entry point */ +static void +importer_init (void) +{ + BonoboGenericFactory *factory; + + factory = bonobo_generic_factory_new (ELM_INTELLIGENT_IMPORTER_IID, + factory_fn, NULL); + if (factory == NULL) { + g_error ("Could not initialise Elm Intelligent Mail Importer."); + exit (0); + } + + bonobo_running_context_auto_exit_unref (BONOBO_OBJECT (factory)); +} + +int +main (int argc, + char **argv) +{ + CORBA_ORB orb; + + gnome_init_with_popt_table ("Evolution-Elm-Importer", + VERSION, argc, argv, oaf_popt_options, 0, + NULL); + orb = oaf_init (argc, argv); + if (bonobo_init (orb, CORBA_OBJECT_NIL, CORBA_OBJECT_NIL) == FALSE) { + g_error ("Could not initialise Bonobo"); + exit (0); + } + + importer_init (); + bonobo_main (); + + return 0; +} diff --git a/importers/evolution-gnomecard-importer.c b/importers/evolution-gnomecard-importer.c new file mode 100644 index 0000000000..6d220d699a --- /dev/null +++ b/importers/evolution-gnomecard-importer.c @@ -0,0 +1,218 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* evolution-gnomecard-intelligent-importer.c + * + * Copyright (C) 2001 Ximian, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Iain Holmes <iain@ximian.com> + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> + +#include <liboaf/liboaf.h> +#include <bonobo/bonobo-context.h> +#include <bonobo/bonobo-generic-factory.h> +#include <bonobo/bonobo-main.h> + +#include <e-book.h> + +#include <importer/evolution-intelligent-importer.h> +#include <importer/GNOME_Evolution_Importer.h> + +#define COMPONENT_FACTORY_IID "OAFIID:GNOME_Evolution_GnomeCard_Intelligent_ImporterFactory" + +#define KEY "gnomecard-imported" +typedef struct { + GNOME_Evolution_Importer importer; + EvolutionImporterListener *listener; +} GnomeCardImporter; + +static gboolean +gnomecard_can_import (EvolutionIntelligentImporter *ii, + void *closure) +{ + char *evolution_dir; + char *gnomecard; + char *key; + gboolean result; + + evolution_dir = gnome_util_prepend_user_home ("evolution"); + key = g_strdup_printf ("=%s/config/Importers=/importers/", evolution_dir); + g_free (evolution_dir); + + gnome_config_push_prefix (key); + g_free (key); + + if (gnome_config_get_bool (KEY) == TRUE) { + gnome_config_pop_prefix (); + return FALSE; + } + gnome_config_pop_prefix (); + + gnomecard = gnome_util_home_file ("GnomeCard.gcrd"); + result = g_file_exists (gnomecard); + g_free (gnomecard); + + return result; +} + +static gboolean +importer_timeout_fn (gpointer data) +{ + GnomeCardImporter *gci = (GnomeCardImporter *) data; + CORBA_Object objref; + CORBA_Environment ev; + + CORBA_exception_init (&ev); + objref = bonobo_object_corba_objref (BONOBO_OBJECT (gci->listener)); + GNOME_Evolution_Importer_processItem (gci->importer, objref, &ev); + CORBA_exception_free (&ev); + + return FALSE; +} + +static void +importer_cb (EvolutionImporterListener *listener, + EvolutionImporterResult result, + gboolean more_items, + void *data) +{ + GnomeCardImporter *gci = (GnomeCardImporter *) data; + CORBA_Object objref; + CORBA_Environment ev; + + if (result == EVOLUTION_IMPORTER_NOT_READY || + result == EVOLUTION_IMPORTER_BUSY) { + gtk_timeout_add (5000, importer_timeout_fn, data); + return; + } + + if (more_items) { + g_idle_add_full (G_PRIORITY_LOW, importer_timeout_fn, data, NULL); + return; + } + + /* Quit Here */ +} + +static void +gnomecard_import (EvolutionIntelligentImporter *ii, + void *closure) +{ + CORBA_boolean result; + GnomeCardImporter *gci = closure; + CORBA_Object objref; + CORBA_Environment ev; + char *gnomecard; + + gnomecard = gnome_util_home_file ("GnomeCard.gcrd"); + + CORBA_exception_init (&ev); + result = GNOME_Evolution_Importer_loadFile (gci->importer, + gnomecard, NULL, &ev); + if (ev._major != CORBA_NO_EXCEPTION || result == FALSE) { + g_warning ("Exception here: %s", CORBA_exception_id (&ev)); + CORBA_Object_release (gci->importer, &ev); + CORBA_exception_free (&ev); + return FALSE; + } + + gci->listener = evolution_importer_listener_new (importer_cb, gci); + objref = bonobo_object_corba_objref (BONOBO_OBJECT (gci->listener)); + GNOME_Evolution_Importer_processItem (gci->importer, objref, &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + g_warning ("Exception: %s", CORBA_exception_id (&ev)); + return FALSE; + } + + CORBA_exception_free (&ev); + + return TRUE; +} + +static BonoboObject * +factory_fn (BonoboGenericFactory *_factory, + void *closure) +{ + EvolutionIntelligentImporter *importer; + GnomeCardImporter *gci; + char *message = N_("Evolution has found GnomeCard files.\n" + "Would you like them to be imported into Evolution?"); + + gci = g_new (GnomeCardImporter, 1); + + CORBA_exception_init (&ev); + gci->importer = oaf_activate_from_id (VCARD_IMPORTER_IID, 0, NULL, &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + g_warning ("Could not start VCard importer: %s", + CORBA_exception_id (&ev)); + CORBA_exception_free (&ev); + return NULL; + } + CORBA_exception_free (&ev); + + importer = evolution_intelligent_importer_new (gnomecard_can_import, + gnomecard_import, + "GnomeCard", + _(message), gci); + + gtk_signal_connect (GTK_OBJECT (importer), "destroy", + GTK_SIGNAL_FUNC (importer_destroy_cb), gci); + + return BONOBO_OBJECT (importer); +} + +static void +importer_init (void) +{ + BonoboObject *factory; + + factory = bonobo_generic_factory_new (COMPONENT_FACTORY_IID, + factory_fn, NULL); + if (factory == NULL) { + g_error ("Unable to create factory"); + exit (0); + } + + bonobo_running_context_auto_exit_unref (BONOBO_OBJECT (factory)); +} + +int +main (int argc, + char **argv) +{ + CORBA_ORB orb; + + gnome_init_with_popt_table ("Evolution-GnomeCard-Intelligent-Importer", + VERSION, argc, argv, oaf_popt_options, 0, + NULL); + orb = oaf_init (argc, argv); + if (bonobo_init (orb, CORBA_OBJECT_NIL, CORBA_OBJECT_NIL) == FALSE) { + g_error ("Could not initialize Bonobo."); + exit (0); + } + + importer_init (); + bonobo_main (); + + return 0; +} + + diff --git a/importers/netscape-importer.c b/importers/netscape-importer.c new file mode 100644 index 0000000000..41e3a080f6 --- /dev/null +++ b/importers/netscape-importer.c @@ -0,0 +1,910 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* netscape-importer.c + * + * Authors: + * Iain Holmes <iain@ximian.com> + * + * Copyright 2001 Ximian, Inc. (http://www.ximian.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <dirent.h> + +#include <glib.h> +#include <gnome.h> + +#include <bonobo/bonobo-main.h> +#include <bonobo/bonobo-object.h> +#include <bonobo/bonobo-generic-factory.h> +#include <bonobo/bonobo-control.h> + +#include <importer/evolution-intelligent-importer.h> +#include <importer/GNOME_Evolution_Importer.h> +#include <importer/evolution-importer-client.h> + +#include "Mail.h" + +static char *nsmail_dir = NULL; +static GHashTable *user_prefs = NULL; + +#define FACTORY_IID "OAFIID:GNOME_Evolution_Netscape_Intelligent_Importer_Factory" +#define MBOX_IMPORTER_IID "OAFIID:GNOME_Evolution_Mail_Mbox_Importer" +#define MAIL_CONFIG_IID "OAFIID:GNOME_Evolution_MailConfig" + +#define KEY "netscape-mail-imported" + +/*#define SUPER_IMPORTER_DEBUG*/ +#ifdef SUPER_IMPORTER_DEBUG +#define d(x) x +#else +#define d(x) +#endif + +typedef struct { + GList *dir_list; + + int num; + + GNOME_Evolution_Importer importer; + EvolutionImporterListener *listener; + + /* Checkboxes */ + GtkWidget *mail; + gboolean do_mail; + GtkWidget *addrs; + gboolean do_addrs; + GtkWidget *filters; + gboolean do_filters; + GtkWidget *settings; + gboolean do_settings; + + GtkWidget *ask; + gboolean ask_again; +} NetscapeImporter; + +static void import_next (NetscapeImporter *importer); + +static void +netscape_store_settings (NetscapeImporter *importer) +{ + char *evolution_dir, *key; + + evolution_dir = gnome_util_prepend_user_home ("evolution"); + key = g_strdup_printf ("=%s/config/Netscape-Importer=/settings/", + evolution_dir); + g_free (evolution_dir); + + gnome_config_push_prefix (key); + g_free (key); + + gnome_config_set_bool ("mail", importer->do_mail); + gnome_config_set_bool ("address", importer->do_addrs); + gnome_config_set_bool ("filters", importer->do_filters); + gnome_config_set_bool ("settings", importer->do_settings); + + gnome_config_set_bool ("ask-again", importer->ask_again); + gnome_config_pop_prefix (); +} + +static void +netscape_restore_settings (NetscapeImporter *importer) +{ + char *evolution_dir, *key; + + evolution_dir = gnome_util_prepend_user_home ("evolution"); + key = g_strdup_printf ("=%s/config/Netscape-Importer=/settings/", evolution_dir); + g_free (evolution_dir); + + gnome_config_push_prefix (key); + g_free (key); + + importer->do_mail = gnome_config_get_bool ("mail=True"); + importer->do_addrs = gnome_config_get_bool ("address=True"); + importer->do_filters = gnome_config_get_bool ("filters=True"); + importer->do_settings = gnome_config_get_bool ("setting=True"); + + importer->ask_again = gnome_config_get_bool ("ask-again=False"); + gnome_config_pop_prefix (); +} + +static const char * +netscape_get_string (const char *strname) +{ + return g_hash_table_lookup (user_prefs, strname); +} + +static int +netscape_get_integer (const char *strname) +{ + char *intstr; + + intstr = g_hash_table_lookup (user_prefs, strname); + g_print ("Request: %s %s.\n", strname, intstr); + if (intstr == NULL) { + return 0; + } else { + return atoi (intstr); + } +} + +static gboolean +netscape_get_boolean (const char *strname) +{ + char *boolstr; + + boolstr = g_hash_table_lookup (user_prefs, strname); + + g_print ("Request: %s %s.\n", strname, boolstr); + if (boolstr == NULL) { + return FALSE; + } else { + if (strcasecmp (boolstr, "false") == 0) { + return FALSE; + } else if (strcasecmp (boolstr, "true") == 0) { + return TRUE; + } + } + + return FALSE; +} + +static char * +netscape_get_key (const char *line) +{ + char *line_dup; + char *start, *end; + char *key; + + line_dup = g_strdup (line); + start = strchr (line_dup, '\"'); + if (start == NULL) + goto die; + start++; + if (*start == '\0') + goto die; + + end = strchr (start, '\"'); + if (end == NULL) + goto die; + *end = '\0'; + + key = g_strdup (start); + g_free (line_dup); + + g_warning ("Found key: %s", key); + return key; + + die: + g_free (line_dup); + g_warning ("Broken line: %s", line); + return NULL; +} + +static char * +netscape_get_value (const char *line) +{ + char *line_dup; + char *start, *end; + char *value; + + line_dup = g_strdup (line); + start = strchr (line_dup, ','); + if (start == NULL) + goto die; + start++; + if (*start == '\0') + goto die; + + if (*start == ' ') + start++; + if (*start == '\0') + goto die; + + if (*start == '\"') + start++; + if (*start == '\0') + goto die; + + /* Start should now be the start of the value */ + end = strrchr (start, ')'); + if (end == NULL) + goto die; + *end = '\0'; + if (*(end - 1) == '\"') + *(end - 1) = '\0'; + + if (start == (end - 1)) { + g_free (line_dup); + return NULL; + } + + value = g_strdup (start); + g_free (line_dup); + + g_warning ("Found value: %s", value); + return value; + + die: + g_free (line_dup); + g_warning ("Broken line: %s", line); + return NULL; +} + +static void +netscape_init_prefs (void) +{ + FILE *prefs_handle; + char *nsprefs; + char line[4096]; + + user_prefs = g_hash_table_new (g_str_hash, g_str_equal); + + nsprefs = gnome_util_prepend_user_home (".netscape/preferences.js"); + prefs_handle = fopen (nsprefs, "r"); + g_free (nsprefs); + + if (prefs_handle == NULL) { + d(g_warning ("No .netscape/preferences.js")); + g_hash_table_destroy (user_prefs); + user_prefs = NULL; + return; + } + + /* Find the user mail dir */ + while (fgets (line, 4096, prefs_handle)) { + char *key, *value; + + key = netscape_get_key (line); + value = netscape_get_value (line); + + if (key == NULL) + continue; + + g_hash_table_insert (user_prefs, key, value); + } + + return; +} + +static void +netscape_import_accounts (NetscapeImporter *importer) +{ + char *nstr; + char *imap; + GNOME_Evolution_MailConfig_Account account; + GNOME_Evolution_MailConfig_Service source, transport; + GNOME_Evolution_MailConfig_Identity id; + CORBA_Object objref; + CORBA_Environment ev; + + if (user_prefs == NULL) { + netscape_init_prefs (); + if (user_prefs == NULL) + return; + } + + CORBA_exception_init (&ev); + objref = oaf_activate_from_id (MAIL_CONFIG_IID, 0, NULL, &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + g_warning ("Error starting mail config"); + CORBA_exception_free (&ev); + return; + } + + if (objref == CORBA_OBJECT_NIL) { + g_warning ("Error activating mail config"); + return; + } + + /* Create identify structure */ + nstr = netscape_get_string ("mail.identity.username"); + id.name = CORBA_string_dup (nstr ? nstr : "John Doe"); + nstr = netscape_get_string ("mail.identity.useremail"); + id.address = CORBA_string_dup (nstr ? nstr : ""); + nstr = netscape_get_string ("mail.identity.organization"); + id.organization = CORBA_string_dup (nstr ? nstr : ""); + nstr = netscape_get_string ("mail.signature_file"); + id.signature = CORBA_string_dup (nstr ? nstr : ""); + + /* Create transport */ + nstr = netscape_get_string ("network.hosts.smtp_server"); + if (nstr != NULL) { + char *url, *nstr2; + + nstr2 = netscape_get_string ("mail.smtp_name"); + if (nstr2) { + url = g_strconcat ("smtp://", nstr2, "@", nstr, NULL); + } else { + url = g_strconcat ("smtp://", nstr, NULL); + } + transport.url = CORBA_string_dup (url); + transport.keep_on_server = FALSE; + transport.auto_check = FALSE; + transport.auto_check_time = 10; + transport.save_passwd = FALSE; + transport.enabled = TRUE; + g_free (url); + } + + /* Create account */ + nstr = netscape_get_string ("mail.identity.username"); + account.name = CORBA_string_dup (nstr ? nstr : ""); + account.default_account = FALSE; + account.id = id; + account.source = source; + account.transport = transport; + + account.drafts_folder_name = CORBA_string_dup (""); + account.drafts_folder_uri = CORBA_string_dup (""); + account.sent_folder_name = CORBA_string_dup (""); + account.sent_folder_uri = CORBA_string_dup (""); + + /* Create POP3 source */ + nstr = netscape_get_string ("network.hosts.pop_server"); + if (nstr != NULL && *nstr != 0) { + char *url, *nstr2; + + nstr2 = netscape_get_string ("mail.pop_name"); + if (nstr2) { + url = g_strconcat ("pop://", nstr2, "@", nstr, NULL); + } else { + url = g_strconcat ("pop://", nstr, NULL); + } + source.url = CORBA_string_dup (url); + source.keep_on_server = netscape_get_boolean ("mail.leave_on_server"); + source.auto_check = TRUE; + source.auto_check_time = 10; + source.save_passwd = netscape_get_boolean ("mail.remember_password"); + source.enabled = TRUE; + g_free (url); + } else { + /* Are there IMAP accounts? */ + imap = netscape_get_string ("network.hosts.imap_servers"); + if (imap != NULL) { + char **servers; + int i; + + servers = g_strsplit (imap, ",", 1024); + for (i = 0; servers[i] != NULL; i++) { + GNOME_Evolution_MailConfig_Service imapsource; + char *serverstr, *name, *url, *username; + + g_warning ("i: %d", i); + /* Create a server for each of these */ + serverstr = g_strdup_printf ("mail.imap.server.%s.", servers[i]); + name = g_strconcat (serverstr, "userName", NULL); + username = netscape_get_string (name); + g_free (name); + + if (username) + url = g_strconcat ("imap://", username, + "@", servers[i], NULL); + else + url = g_strconcat ("imap://", servers[i], NULL); + + g_warning ("URL: %s", url); + imapsource.url = CORBA_string_dup (url); + + imapsource.keep_on_server = netscape_get_boolean ("mail.leave_on_server"); + + name = g_strconcat (serverstr, "check_new_mail", NULL); + imapsource.auto_check = netscape_get_boolean (name); + g_free (name); + + name = g_strconcat (serverstr, "check_time", NULL); + imapsource.auto_check_time = netscape_get_integer (name); + g_free (name); + + name = g_strconcat (serverstr, "remember_password", NULL); + imapsource.save_passwd = netscape_get_boolean (name); + g_free (name); + imapsource.enabled = TRUE; + + account.source = imapsource; + + GNOME_Evolution_MailConfig_addAccount (objref, &account, &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + g_warning ("Error setting account: %s", CORBA_exception_id (&ev)); + CORBA_exception_free (&ev); + return; + } + + g_free (url); + g_free (serverstr); + } + + CORBA_exception_free (&ev); + g_strfreev (servers); + return; + } + } + + GNOME_Evolution_MailConfig_addAccount (objref, &account, &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + g_warning ("Error setting account: %s", CORBA_exception_id (&ev)); + CORBA_exception_free (&ev); + return; + } + + CORBA_exception_free (&ev); +} + +static gboolean +netscape_can_import (EvolutionIntelligentImporter *ii, + void *closure) +{ + NetscapeImporter *importer = closure; + gboolean mail, settings; + char *evolution_dir; + char *key; + + /* Probably shouldn't hard code this, but there's no way yet to change + the home dir. FIXME */ + evolution_dir = gnome_util_prepend_user_home ("evolution"); + /* Already imported */ + key = g_strdup_printf ("=%s/config/Importers=/netscape-importers/", evolution_dir); + g_free (evolution_dir); + + gnome_config_push_prefix (key); + g_free (key); + + mail = gnome_config_get_bool ("mail-imported"); + settings = gnome_config_get_bool ("settings-imported"); + + if (settings && mail) { + gnome_config_pop_prefix (); + return FALSE; + } + gnome_config_pop_prefix (); + + importer->do_mail = !mail; + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (importer->mail), + importer->do_mail); + importer->do_settings = !settings; + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (importer->settings), + importer->do_settings); + + if (importer->ask_again == TRUE) { + return FALSE; + } + + if (user_prefs == NULL) { + netscape_init_prefs (); + } + + nsmail_dir = g_hash_table_lookup (user_prefs, "mail.directory"); + if (nsmail_dir == NULL) + return FALSE; + else + return TRUE; +} + +static void +importer_cb (EvolutionImporterListener *listener, + EvolutionImporterResult result, + gboolean more_items, + void *data) +{ + NetscapeImporter *importer = (NetscapeImporter *) data; + CORBA_Object objref; + CORBA_Environment ev; + + g_print ("Processed....\n"); + if (more_items) { + g_print ("Processing...\n"); + + CORBA_exception_init (&ev); + objref = bonobo_object_corba_objref (BONOBO_OBJECT (importer->listener)); + GNOME_Evolution_Importer_processItem (importer->importer, + objref, &ev); + if (ev._major != CORBA_OBJECT_NIL) { + g_warning ("Exception: %s", CORBA_exception_id (&ev)); + CORBA_exception_free (&ev); + return; + } + CORBA_exception_free (&ev); + return; + } + + if (importer->dir_list) { + import_next (importer); + } else { + gtk_main_quit (); + } +} + +static gboolean +netscape_import_file (NetscapeImporter *importer, + const char *path, + const char *folderpath) +{ + CORBA_boolean result; + CORBA_Environment ev; + CORBA_Object objref; + + /* Do import */ + g_warning ("Importing %s as %s\n", path, folderpath); + + CORBA_exception_init (&ev); + + result = GNOME_Evolution_Importer_loadFile (importer->importer, path, + folderpath, &ev); + if (ev._major != CORBA_NO_EXCEPTION || result == FALSE) { + g_warning ("Exception here: %s", CORBA_exception_id (&ev)); + CORBA_Object_release (importer->importer, &ev); + CORBA_exception_free (&ev); + return FALSE; + } + + importer->listener = evolution_importer_listener_new (importer_cb, + importer); + objref = bonobo_object_corba_objref (BONOBO_OBJECT (importer->listener)); + g_print ("%s:Processing...\n", __FUNCTION__); + CORBA_exception_init (&ev); + GNOME_Evolution_Importer_processItem (importer->importer, + objref, &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + g_warning ("Exception: %s", CORBA_exception_id (&ev)); + CORBA_exception_free (&ev); + return FALSE; + } + CORBA_exception_free (&ev); + + return TRUE; +} + +typedef struct { + NetscapeImporter *importer; + char *parent; + char *path; + char *foldername; +} NetscapeCreateDirectoryData; + +static void +import_next (NetscapeImporter *importer) +{ + NetscapeCreateDirectoryData *data; + + if (importer->dir_list) { + char *folder; + + /* Do the next in the list */ + data = importer->dir_list->data; + + folder = g_concat_dir_and_file (data->parent, data->foldername); + netscape_import_file (importer, data->path, folder); + g_free (folder); + g_free (data->parent); + g_free (data->path); + g_free (data->foldername); + g_free (data); + importer->dir_list = importer->dir_list->next; + } +} + +static char * +maybe_replace_name (const char *original_name) +{ + if (strcmp (original_name, "Trash") == 0) { + return g_strdup ("Netscape-Trash"); /* Trash is an invalid name */ + } else if (strcmp (original_name, "Unsent Messages") == 0) { + return g_strdup ("Outbox"); + } + + return g_strdup (original_name); +} + +/* This function basically flattens the tree structure. + It makes a list of all the directories that are to be imported. */ +static void +scan_dir (NetscapeImporter *importer, + const char *orig_parent, + const char *dirname) +{ + DIR *nsmail; + struct stat buf; + struct dirent *current; + + nsmail = opendir (dirname); + if (nsmail == NULL) { + d(g_warning ("Could not open %s\nopendir returned: %s", + dirname, g_strerror (errno))); + return; + } + + current = readdir (nsmail); + while (current) { + char *fullname, *foldername; + + /* Ignore things which start with . + which should be ., .., and the summaries. */ + if (current->d_name[0] =='.') { + current = readdir (nsmail); + continue; + } + + if (*orig_parent == '/') { + foldername = maybe_replace_name (current->d_name); + } else { + foldername = g_strdup (current->d_name); + } + + fullname = g_concat_dir_and_file (dirname, current->d_name); + if (stat (fullname, &buf) == -1) { + d(g_warning ("Could not stat %s\nstat returned:%s", + fullname, g_strerror (errno))); + current = readdir (nsmail); + g_free (fullname); + continue; + } + + if (S_ISREG (buf.st_mode)) { + char *sbd, *parent; + NetscapeCreateDirectoryData *data; + + d(g_print ("File: %s\n", fullname)); + + data = g_new0 (NetscapeCreateDirectoryData, 1); + data->importer = importer; + data->parent = g_strdup (orig_parent); + data->path = g_strdup (fullname); + data->foldername = g_strdup (foldername); + + importer->dir_list = g_list_append (importer->dir_list, + data); + + + parent = g_concat_dir_and_file (orig_parent, + data->foldername); + + /* Check if a .sbd folder exists */ + sbd = g_strconcat (fullname, ".sbd", NULL); + if (g_file_exists (sbd)) { + scan_dir (importer, parent, sbd); + } + + g_free (parent); + g_free (sbd); + } + + g_free (fullname); + g_free (foldername); + current = readdir (nsmail); + } +} + +static void +netscape_create_structure (EvolutionIntelligentImporter *ii, + void *closure) +{ + NetscapeImporter *importer = closure; + NetscapeCreateDirectoryData *data; + char *key, *evolution_dir; + + g_return_if_fail (nsmail_dir != NULL); + + /* Reference our object so when the shell release_unrefs us + we will still exist and not go byebye */ + bonobo_object_ref (ii); + + netscape_store_settings (importer); + evolution_dir = gnome_util_prepend_user_home ("evolution"); + /* Set that we've imported the folders so we won't import them again */ + key = g_strdup_printf ("=%s/config/Importers=/netscape-importers/", evolution_dir); + g_free (evolution_dir); + + gnome_config_push_prefix (key); + g_free (key); + + if (importer->do_settings == TRUE) { + gnome_config_set_bool ("settings-imported", TRUE); + netscape_import_accounts (importer); + } + + if (importer->do_mail == TRUE) { + gnome_config_set_bool ("mail-imported", TRUE); + /* Scan the nsmail folder and find out what folders + need to be imported */ + scan_dir (importer, "/", nsmail_dir); + + /* Import them */ + import_next (importer); + } + + gnome_config_pop_prefix (); + + gnome_config_sync (); + gnome_config_drop_all (); + + if (importer->do_mail == FALSE) { + /* Destroy it here if we weren't importing mail + otherwise the mail importer destroys itself + once the mail in imported */ + bonobo_object_unref (ii); + } +} + +static void +netscape_destroy_cb (GtkObject *object, + NetscapeImporter *importer) +{ + /* Save the state of the checkboxes */ + g_print ("\n-------Settings-------\n"); + g_print ("Mail - %s\n", importer->do_mail ? "Yes" : "No"); + g_print ("Addressbook - %s\n", importer->do_addrs ? "Yes" : "No"); + g_print ("Filters - %s\n", importer->do_filters ? "Yes" : "No"); + g_print ("Settings - %s\n", importer->do_settings ? "Yes" : "No"); + + netscape_store_settings (importer); + gtk_main_quit (); +} + +/* Fun initialisation stuff */ + +/* Fun with aggregation */ +static void +checkbox_toggle_cb (GtkToggleButton *tb, + gboolean *do_item) +{ + *do_item = gtk_toggle_button_get_active (tb); +} + +static BonoboControl * +create_checkboxes_control (NetscapeImporter *importer) +{ + GtkWidget *container, *vbox, *sep; + BonoboControl *control; + + container = gtk_frame_new (_("Import")); + vbox = gtk_vbox_new (FALSE, 2); + gtk_container_set_border_width (GTK_CONTAINER (container), 2); + gtk_container_add (GTK_CONTAINER (container), vbox); + + 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); + + importer->settings = gtk_check_button_new_with_label (_("Settings")); + gtk_signal_connect (GTK_OBJECT (importer->settings), "toggled", + GTK_SIGNAL_FUNC (checkbox_toggle_cb), + &importer->do_settings); + + importer->filters = gtk_check_button_new_with_label (_("Filters")); + gtk_signal_connect (GTK_OBJECT (importer->filters), "toggled", + GTK_SIGNAL_FUNC (checkbox_toggle_cb), + &importer->do_filters); + + importer->addrs = gtk_check_button_new_with_label (_("Addressbooks")); + gtk_signal_connect (GTK_OBJECT (importer->addrs), "toggled", + GTK_SIGNAL_FUNC (checkbox_toggle_cb), + &importer->do_addrs); + + sep = gtk_hseparator_new (); + + importer->ask = gtk_check_button_new_with_label (_("Don't ask me again")); + gtk_signal_connect (GTK_OBJECT (importer->ask), "toggled", + GTK_SIGNAL_FUNC (checkbox_toggle_cb), + &importer->ask_again); + + gtk_box_pack_start (GTK_BOX (vbox), importer->mail, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox), importer->settings, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox), importer->filters, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox), importer->addrs, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox), sep, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox), importer->ask, FALSE, FALSE, 0); + + /* Disable the things that can't be done yet :) */ + gtk_widget_set_sensitive (importer->filters, FALSE); + gtk_widget_set_sensitive (importer->addrs, FALSE); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (importer->mail), + importer->do_mail); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (importer->settings), + importer->do_settings); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (importer->filters), + importer->do_filters); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (importer->addrs), + importer->do_addrs); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (importer->ask), + importer->ask_again); + + gtk_widget_show_all (container); + control = bonobo_control_new (container); + return control; +} + +static BonoboObject * +factory_fn (BonoboGenericFactory *_factory, + void *closure) +{ + EvolutionIntelligentImporter *importer; + BonoboControl *control; + NetscapeImporter *netscape; + CORBA_Environment ev; + char *message = N_("Evolution has found Netscape mail files.\n" + "Would you like them to be imported into Evolution?"); + + netscape = g_new0 (NetscapeImporter, 1); + netscape_restore_settings (netscape); + + CORBA_exception_init (&ev); + netscape->importer = oaf_activate_from_id (MBOX_IMPORTER_IID, 0, NULL, &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + g_warning ("Could not start MBox importer\n%s", CORBA_exception_id (&ev)); + CORBA_exception_free (&ev); + return NULL; + } + CORBA_exception_free (&ev); + + importer = evolution_intelligent_importer_new (netscape_can_import, + netscape_create_structure, + "Netscape mail", + _(message), netscape); + gtk_signal_connect (GTK_OBJECT (importer), "destroy", + GTK_SIGNAL_FUNC (netscape_destroy_cb), netscape); + + control = create_checkboxes_control (netscape); + bonobo_object_add_interface (BONOBO_OBJECT (importer), + BONOBO_OBJECT (control)); + return BONOBO_OBJECT (importer); +} + +static void +importer_init (void) +{ + BonoboObject *factory; + + g_print ("Hi"); + factory = bonobo_generic_factory_new (FACTORY_IID, factory_fn, NULL); + if (factory == NULL) { + g_error ("Unable to create factory"); + exit (0); + } + + bonobo_running_context_auto_exit_unref (BONOBO_OBJECT (factory)); +} + +int +main (int argc, + char **argv) +{ + CORBA_ORB orb; + + gnome_init_with_popt_table ("Evolution-Netscape-Importer", + VERSION, argc, argv, oaf_popt_options, 0, + NULL); + orb = oaf_init (argc, argv); + if (bonobo_init (orb, CORBA_OBJECT_NIL, CORBA_OBJECT_NIL) == FALSE) { + g_error ("Could not initialise Bonobo"); + exit (0); + } + + importer_init (); + bonobo_main (); + + return 0; +} diff --git a/importers/pine-importer.c b/importers/pine-importer.c new file mode 100644 index 0000000000..3b3d2c0d57 --- /dev/null +++ b/importers/pine-importer.c @@ -0,0 +1,766 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* pine-importer.c + * + * Authors: + * Iain Holmes <iain@ximian.com> + * + * Copyright 2001 Ximian, Inc. (http://www.ximian.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <dirent.h> + +#include <glib.h> + +#include <bonobo/bonobo-object.h> +#include <bonobo/bonobo-generic-factory.h> +#include <bonobo/bonobo-control.h> +#include <bonobo/bonobo-main.h> + +#include <importer/evolution-intelligent-importer.h> +#include <importer/evolution-importer-client.h> +#include <importer/GNOME_Evolution_Importer.h> + +#include <e-book.h> +#include <e-card-simple.h> + +#define PINE_INTELLIGENT_IMPORTER_IID "OAFIID:GNOME_Evolution_Pine_Intelligent_Importer_Factory" +#define MBOX_IMPORTER_IID "OAFIID:GNOME_Evolution_Mail_Mbox_Importer" +#define KEY "pine-mail-imported" + +/*#define SUPER_IMPORTER_DEBUG*/ +#ifdef SUPER_IMPORTER_DEBUG +#define d(x) x +#else +#define d(x) +#endif + +typedef struct { + GList *dir_list; + + GNOME_Evolution_Importer importer; + EvolutionImporterListener *listener; + + GtkWidget *mail; + gboolean do_mail; + GtkWidget *settings; + gboolean do_settings; + GtkWidget *address; + gboolean do_address; + + GtkWidget *ask; + gboolean ask_again; + + EBook *book; +} PineImporter; + +typedef struct { + char *parent; + char *foldername; + char *path; +} PineFolder; + +static void import_next (PineImporter *importer); + +static void +pine_store_settings (PineImporter *importer) +{ + char *evolution_dir, *key; + + evolution_dir = gnome_util_prepend_user_home ("evolution"); + key = g_strdup_printf ("=%s/config/Pine-Importer=/settings/", evolution_dir); + g_free (evolution_dir); + + gnome_config_push_prefix (key); + g_free (key); + + gnome_config_set_bool ("mail", importer->do_mail); + gnome_config_set_bool ("settings", importer->do_settings); + gnome_config_set_bool ("address", importer->do_address); + + gnome_config_set_bool ("ask-again", importer->ask_again); + gnome_config_pop_prefix (); +} + +static void +pine_restore_settings (PineImporter *importer) +{ + char *evolution_dir, *key; + + evolution_dir = gnome_util_prepend_user_home ("evolution"); + key = g_strdup_printf ("=%s/config/Pine-Importer=/settings/", evolution_dir); + g_free (evolution_dir); + + gnome_config_push_prefix (key); + g_free (key); + + importer->do_mail = gnome_config_get_bool ("mail=True"); + importer->do_settings = gnome_config_get_bool ("settings=True"); + importer->do_address = gnome_config_get_bool ("address=True"); + + importer->ask_again = gnome_config_get_bool ("ask-again=False"); + gnome_config_pop_prefix (); +} + +/* Pass in handle so we can get the next line if we need to */ +static char * +get_field (char **start, + FILE *handle) +{ + char line[4096]; + char *end, *field; + int length; + + /* if this was the last line, just return */ + if (*start == NULL) { + return NULL; + } + + /* if start is just \n then we need the next line */ + if (**start == '\n') { + g_warning ("Need next line"); + if (fgets (line, 4096, handle) == NULL) { + g_warning ("Hmmm, no next line"); + return NULL; + } + + if (line[0] != ' ' || line[1] != ' ' || line[2] != ' ') { + g_warning ("Next line was not a continuation line\n" + "Oppps: %s", line); + return NULL; + } + + *start = line + 3; + } + + if (**start == '\t') { + /* Blank field */ + + *start += 1; + return NULL; + } + + end = strchr (*start, '\t'); + if (end == NULL) { + /* the line was the last comment, so just return the line */ + length = strlen (line); + line[length - 1] = 0; + + field = g_strdup (*start); + + *start = NULL; + } else { + /* Null the end */ + *end = 0; + + field = g_strdup (*start); + *start = end + 1; + } + + g_warning ("Found %s", field); + return field; +} + +/* A very basic address spliter. + Returns the first email address + denoted by <address> */ +static char * +parse_address (const char *address) +{ + char *addr_dup, *result, *start, *end; + + addr_dup = g_strdup (address); + start = strchr (addr_dup, '<'); + if (start == NULL) { + /* Whole line is an address */ + return addr_dup; + } + + start += 1; + end = strchr (start, '>'); + if (end == NULL) { + result = g_strdup (start); + g_free (addr_dup); + + return result; + } + + *end = 0; + result = strdup (start); + g_free (addr_dup); + + return result; +} + +static void +import_addressfile (EBook *book, + EBookStatus status, + PineImporter *importer) +{ + char *addressbook; + FILE *handle; + char line[4096]; + + addressbook = gnome_util_prepend_user_home (".addressbook"); + handle = fopen (addressbook, "r"); + g_free (addressbook); + + if (handle == NULL) { + g_warning ("Cannot open .addressbook"); + return; + } + + while (fgets (line, 4096, handle) != NULL) { + char *nick, *fullname, *address, *comment, *fcc; + char *start; + EList *emaillist = e_list_new (NULL, g_free, NULL); + gboolean distrib = FALSE; + + start = line; + nick = get_field (&start, handle); + g_print ("Nick: %s\n", nick); + + fullname = get_field (&start, handle); + g_print ("Fullname: %s\n", fullname); + + address = get_field (&start, handle); + g_print ("Address: %s\n", address); + + if (*address == '(') { + char nextline[4096]; + /* Fun, it's a distribution list */ + distrib = TRUE; + + /* if the last char of address == ) then this is the + full list */ + while (fgets (nextline, 4096, handle)) { + char *bracket; + if (nextline[0] != ' ' || + nextline[1] != ' ' || + nextline[2] != ' ') { + /* Not a continuation line */ + start = nextline; + break; + } + + bracket = strchr (nextline, ')'); + if (bracket != NULL && + *(bracket + 1) == '\t') { + + *(bracket + 1) = 0; + g_print ("More addresses: %s\n", nextline); +#if 0 + e_list_append (emaillist, g_strdup (nextline)); +#endif + start = bracket + 2; + break; + } else { + g_print ("More addresses: %s\n", nextline); +#if 0 + e_list_append (emaillist, g_strdup (nextline)); +#endif + } + } + } else { + char *real = parse_address (address); + + g_print ("Real address: %s", real); + e_list_append (emaillist, real); + } + + fcc = get_field (&start, handle); + g_print ("FCC: %s\n", fcc); + + comment = get_field (&start, handle); + g_print ("Comment: %s\n", comment); + + if (distrib == FALSE) { + /* This was not a distribution list... + Evolution doesn't handle that yet (070501) + Fixme when it does */ + ECard *card = e_card_new (""); + ECardSimple *simple = e_card_simple_new (card); + + e_card_simple_set (simple, E_CARD_SIMPLE_FIELD_FILE_AS, + fullname ? fullname : nick); + e_card_simple_set (simple, E_CARD_SIMPLE_FIELD_FULL_NAME, + fullname); + e_card_simple_set (simple, E_CARD_SIMPLE_FIELD_EMAIL, + emaillist); + e_card_simple_set (simple, E_CARD_SIMPLE_FIELD_NOTE, + comment); + e_card_simple_set (simple, E_CARD_SIMPLE_FIELD_NICKNAME, + nick); + e_book_add_card (importer->book, simple->card, NULL, NULL); + } + + } + + fclose (handle); +} + +static void +import_addressbook (PineImporter *importer) +{ + char *path, *uri; + + importer->book = e_book_new (); + if (importer->book == NULL) { + g_warning ("Could not create EBook."); + return; + } + + path = g_concat_dir_and_file (g_get_home_dir (), + "evolution/local/Contacts/addressbook.db"); + uri = g_strdup_printf ("file://%s", path); + g_free (path); + + if (!e_book_load_uri (importer->book, uri, import_addressfile, importer)) { + g_warning ("Error calling load_uri"); + } + g_free (uri); +} + +static void +importer_cb (EvolutionImporterListener *listener, + EvolutionImporterResult result, + gboolean more_items, + void *data) +{ + PineImporter *importer = (PineImporter *) data; + CORBA_Object objref; + CORBA_Environment ev; + + g_print ("Processed.....\n"); + if (more_items) { + g_print ("Processing.....\n"); + + CORBA_exception_init (&ev); + objref = bonobo_object_corba_objref (BONOBO_OBJECT (importer->listener)); + GNOME_Evolution_Importer_processItem (importer->importer, + objref, &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + g_warning ("Exception: %s", CORBA_exception_id (&ev)); + CORBA_exception_free (&ev); + return; + } + CORBA_exception_free (&ev); + return; + } + + if (importer->dir_list) { + import_next (importer); + } else { + gtk_main_quit (); + } +} + +static gboolean +pine_import_file (PineImporter *importer, + const char *path, + const char *folderpath) +{ + CORBA_boolean result; + CORBA_Environment ev; + CORBA_Object objref; + + g_warning ("Importing %s as %s", path, folderpath); + + CORBA_exception_init (&ev); + result = GNOME_Evolution_Importer_loadFile (importer->importer, path, + folderpath, &ev); + if (ev._major != CORBA_NO_EXCEPTION || result == FALSE) { + g_warning ("Exception here: %s", CORBA_exception_id (&ev)); + CORBA_Object_release (importer->importer, &ev); + CORBA_exception_free (&ev); + return FALSE; + } + + importer->listener = evolution_importer_listener_new (importer_cb, + importer); + objref = bonobo_object_corba_objref (BONOBO_OBJECT (importer->listener)); + GNOME_Evolution_Importer_processItem (importer->importer, objref, &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + g_warning ("Exception: %s", CORBA_exception_id (&ev)); + CORBA_exception_free (&ev); + } + CORBA_exception_free (&ev); + + return TRUE; +} + +static gboolean +pine_can_import (EvolutionIntelligentImporter *ii, + void *closure) +{ + PineImporter *importer = closure; + char *key, *maildir, *evolution_dir, *addrfile; + gboolean mail, settings, addressbook; + gboolean md_exists, addr_exists; + + /* Already imported */ + evolution_dir = gnome_util_prepend_user_home ("evolution"); + key = g_strdup_printf ("=%s/config/Importers=/pine-importer/", evolution_dir); + g_free (evolution_dir); + + gnome_config_push_prefix (key); + g_free (key); + + mail = gnome_config_get_bool ("mail-imported"); + + if (mail) { + gnome_config_pop_prefix (); + return FALSE; + } + gnome_config_pop_prefix (); + + importer->do_mail = !mail; + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (importer->mail), + importer->do_mail); + + if (importer->ask_again == TRUE) + return FALSE; + + maildir = gnome_util_prepend_user_home ("mail"); + md_exists = g_file_exists (maildir); + gtk_widget_set_sensitive (importer->mail, md_exists); + g_free (maildir); + + addrfile = gnome_util_prepend_user_home (".addressbook"); + addr_exists = g_file_exists (addrfile); + g_free (addrfile); + gtk_widget_set_sensitive (importer->address, addr_exists); + + return md_exists || addr_exists; +} + +static void +import_next (PineImporter *importer) +{ + PineFolder *data; + + if (importer->dir_list) { + char *folder; + + data = importer->dir_list->data; + + folder = g_concat_dir_and_file (data->parent, data->foldername); + pine_import_file (importer, data->path, folder); + g_free (folder); + g_free (data->parent); + g_free (data->path); + g_free (data->foldername); + g_free (data); + importer->dir_list = importer->dir_list->next; + } + +} + +/* Pine uses sent-mail and saved-mail whereas Evolution uses Sent and Drafts */ +static char * +maybe_replace_name (const char *original_name) +{ + if (strcmp (original_name, "sent-mail") == 0) { + return g_strdup ("Sent"); + } else if (strcmp (original_name, "saved-messages") == 0) { + return g_strdup ("Drafts"); + } + + return g_strdup (original_name); +} + +static void +scan_dir (PineImporter *importer, + const char *dirname, + const char *orig_parent) +{ + DIR *maildir; + struct stat buf; + struct dirent *current; + + maildir = opendir (dirname); + if (maildir == NULL) { + g_warning ("Could not open %s\nopendir returned: %s", + dirname, g_strerror (errno)); + return; + } + + current = readdir (maildir); + while (current) { + PineFolder *pf; + char *fullname, *foldername; + + /* Ignore . and .. */ + if (current->d_name[0] == '.') { + if (current->d_name[1] == '\0' || + (current->d_name[1] == '.' && current->d_name[2] == '\0')) { + current = readdir (maildir); + continue; + } + } + + if (*orig_parent == '/') { + foldername = maybe_replace_name (current->d_name); + } else { + foldername = g_strdup (current->d_name); + } + + fullname = g_concat_dir_and_file (dirname, current->d_name); + if (stat (fullname, &buf) == -1) { + g_warning ("Could not stat %s\nstat returned: %s", + fullname, g_strerror (errno)); + current = readdir (maildir); + g_free (fullname); + continue; + } + + if (S_ISREG (buf.st_mode)) { + pf = g_new (PineFolder, 1); + pf->path = g_strdup (fullname); + pf->parent = g_strdup (orig_parent); + pf->foldername = g_strdup (foldername); + importer->dir_list = g_list_append (importer->dir_list, pf); + } else if (S_ISDIR (buf.st_mode)) { + char *subdir; + + pf = g_new (PineFolder, 1); + pf->path = NULL; + pf->parent = g_strdup (orig_parent); + pf->foldername = g_strdup (foldername); + importer->dir_list = g_list_append (importer->dir_list, pf); + + subdir = g_concat_dir_and_file (orig_parent, foldername); + scan_dir (importer, fullname, subdir); + g_free (subdir); + } + + g_free (fullname); + g_free (foldername); + current = readdir (maildir); + } +} + +static void +pine_create_structure (EvolutionIntelligentImporter *ii, + void *closure) +{ + PineImporter *importer = closure; + char *maildir, *key, *evolution_dir; + + bonobo_object_ref (ii); + pine_store_settings (importer); + + evolution_dir = gnome_util_prepend_user_home ("evolution"); + key = g_strdup_printf ("=%s/config/Importers=/pine-importer/", evolution_dir); + g_free (evolution_dir); + + gnome_config_push_prefix (key); + g_free (key); + + if (importer->do_address == TRUE) { + gnome_config_set_bool ("address-imported", TRUE); + + import_addressbook (importer); + } + + if (importer->do_mail == TRUE) { + gnome_config_set_bool ("mail-imported", TRUE); + + maildir = gnome_util_prepend_user_home ("mail"); + scan_dir (importer, maildir, "/"); + g_free (maildir); + + /* Import them */ + import_next (importer); + } + + gnome_config_pop_prefix (); + + gnome_config_sync (); + gnome_config_drop_all (); + + if (importer->do_mail == FALSE && importer->do_address == FALSE) { + /* Destroy it here if we weren't importing mail + otherwise the mail importer destroys itself + once the mail is imported */ + + /* Hmmm, this needs fixed badly */ + bonobo_object_unref (ii); + } +} + +static void +pine_destroy_cb (GtkObject *object, + PineImporter *importer) +{ + g_print ("\n-------Settings-------\n"); + g_print ("Mail - %s\n", importer->do_mail ? "Yes" : "No"); + g_print ("Settings - %s\n", importer->do_settings ? "Yes" : "No"); + g_print ("Address - %s\n", importer->do_address ? "Yes" : "No"); + + pine_store_settings (importer); + gtk_main_quit (); +} + +/* Fun inity stuff */ + +/* Fun control stuff */ +static void +checkbox_toggle_cb (GtkToggleButton *tb, + gboolean *do_item) +{ + *do_item = gtk_toggle_button_get_active (tb); +} + +static BonoboControl * +create_checkboxes_control (PineImporter *importer) +{ + GtkWidget *container, *vbox, *sep; + BonoboControl *control; + + container = gtk_frame_new (_("Import")); + vbox = gtk_vbox_new (FALSE, 2); + gtk_container_set_border_width (GTK_CONTAINER (container), 2); + gtk_container_add (GTK_CONTAINER (container), vbox); + + 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); + + importer->settings = gtk_check_button_new_with_label (_("Settings")); + gtk_signal_connect (GTK_OBJECT (importer->settings), "toggled", + GTK_SIGNAL_FUNC (checkbox_toggle_cb), + &importer->do_settings); + + 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); + + sep = gtk_hseparator_new (); + + importer->ask = gtk_check_button_new_with_label (_("Don't ask me again")); + gtk_signal_connect (GTK_OBJECT (importer->ask), "toggled", + GTK_SIGNAL_FUNC (checkbox_toggle_cb), + &importer->ask_again); + + gtk_box_pack_start (GTK_BOX (vbox), importer->mail, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox), importer->settings, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox), importer->address, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox), sep, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox), importer->ask, FALSE, FALSE, 0); + + /* Disable the don't do anythings */ + gtk_widget_set_sensitive (importer->settings, FALSE); + gtk_widget_set_sensitive (importer->address, FALSE); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (importer->mail), + importer->do_mail); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (importer->settings), + importer->do_settings); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (importer->address), + importer->do_address); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (importer->ask), + importer->ask_again); + + gtk_widget_show_all (container); + control = bonobo_control_new (container); + return control; +} + +static BonoboObject * +factory_fn (BonoboGenericFactory *_factory, + void *closure) +{ + EvolutionIntelligentImporter *importer; + BonoboControl *control; + PineImporter *pine; + CORBA_Environment ev; + char *message = N_("Evolution has found Pine mail files.\n" + "Would you like to import them into Evolution?"); + + pine = g_new0 (PineImporter, 1); + pine_restore_settings (pine); + + CORBA_exception_init (&ev); + pine->importer = oaf_activate_from_id (MBOX_IMPORTER_IID, 0, NULL, &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + g_warning ("Could not start MBox importer\n%s", + CORBA_exception_id (&ev)); + CORBA_exception_free (&ev); + return NULL; + } + CORBA_exception_free (&ev); + + importer = evolution_intelligent_importer_new (pine_can_import, + pine_create_structure, + _("Pine mail"), + _(message), pine); + gtk_signal_connect (GTK_OBJECT (importer), "destroy", + GTK_SIGNAL_FUNC (pine_destroy_cb), pine); + + control = create_checkboxes_control (pine); + bonobo_object_add_interface (BONOBO_OBJECT (importer), + BONOBO_OBJECT (control)); + return BONOBO_OBJECT (importer); +} + +static void +importer_init (void) +{ + BonoboGenericFactory *factory; + + factory = bonobo_generic_factory_new (PINE_INTELLIGENT_IMPORTER_IID, + factory_fn, NULL); + if (factory == NULL) { + g_warning ("Could not initialise Pine Intelligent Mail Importer."); + exit (0); + } + + bonobo_running_context_auto_exit_unref (BONOBO_OBJECT (factory)); +} + +int +main (int argc, + char **argv) +{ + CORBA_ORB orb; + + gnome_init_with_popt_table ("Evolution-Pine-Importer", + VERSION, argc, argv, oaf_popt_options, 0, + NULL); + orb = oaf_init (argc, argv); + if (bonobo_init (orb, CORBA_OBJECT_NIL, CORBA_OBJECT_NIL) == FALSE) { + g_error ("Could not initialise Bonobo"); + exit (0); + } + + importer_init (); + bonobo_main (); + + return 0; +} diff --git a/mail/ChangeLog b/mail/ChangeLog index 16307a3e04..e6138ebde0 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,40 @@ +2001-05-08 Iain Holmes <iain@ximian.com> + + * mail-callbacks.c (filter_edit): Set the title of the dialog. + + * GNOME_Evolution_Mail.oaf.in: Add a reference for the MailConfig + interface stuff. + + * Mail.idl: Add the MailConfig interface, and a MailFilter interface. + + * component-factory.c (component_factory_init): Call + evolution_mail_config_factory_init. + + * mail-account-gui.c (setup_service): Just return if url == NULL, + don't crash. + + * mail-config.c: #include bonobo-object.h, #include Mail.h and define + the Config factory IID. + Implement the MailConfig interface with a BonoboObject. + (impl_GNOME_Evolution_MailConfig_addAccount): Convert the CORBA struct + into the correct MailConfig structures and add the account. + (evolution_mail_config_class_init): Initialise the class. + (evolution_mail_config_init): This function is intentionally left blank. + + (evolution_mail_config_factory_fn): Create an EvolutionMailConfig object + and return it. + (evolution_mail_config_factory_init): Set up the bonobo factory. + + * mail-config.h: #include bonobo-xobject.h and Mail.h + Declare the object structures. + + * importers/Makefile.am: Remove the intelligent importers. + + * importers/evolution-mbox-importer.c (folder_created_cb): Callback + from when the folder is created. Opens the folder and unrefs the + listener. + (load_file_fn): Create the folder if it doesn't exist. + 2001-05-08 Jeffrey Stedfast <fejj@ximian.com> * mail-tools.c (mail_tool_forward_message): Convert the Subject diff --git a/mail/GNOME_Evolution_Mail.oaf.in b/mail/GNOME_Evolution_Mail.oaf.in index a30155258e..58a32dcfaa 100644 --- a/mail/GNOME_Evolution_Mail.oaf.in +++ b/mail/GNOME_Evolution_Mail.oaf.in @@ -102,4 +102,25 @@ _value="Evolution mail composer."/> </oaf_server> +<oaf_server iid="OAFIID:GNOME_Evolution_MailConfig_Factory" + type="exe" + location="evolution-mail"> + + <oaf_attribute name="repo_ids" type="stringv"> + <item value="IDL:GNOME/GenericFactory:1.0"/> + </oaf_attribute> +</oaf_server> + +<oaf_server iid="OAFIID:GNOME_Evolution_MailConfig" + type="factory" + location="OAFIID:GNOME_Evolution_MailConfig_Factory"> + + <oaf_attribute name="repo_ids" type="stringv"> + <item value="IDL:GNOME/Evolution/MailConfig:1.0"/> + </oaf_attribute> + + <oaf_attribute name="description" type="string" + _value="Mail configuration interface"/> +</oaf_server> + </oaf_info> diff --git a/mail/Mail.idl b/mail/Mail.idl index 14e17b3993..09a625e4b0 100644 --- a/mail/Mail.idl +++ b/mail/Mail.idl @@ -27,6 +27,48 @@ module Evolution { interface FolderBrowser : Bonobo::Unknown { MessageList getMessageList (); }; + + interface MailConfig : Bonobo::Unknown { + + struct Identity { + string name; + string address; + string organization; + string signature; + }; + + struct Service { + string url; + boolean keep_on_server; + boolean auto_check; + long auto_check_time; + boolean save_passwd; + boolean enabled; + }; + + struct Account { + string name; + boolean default_account; + + Identity id; + Service source; + Service transport; + + string drafts_folder_name; + string drafts_folder_uri; + string sent_folder_name; + string sent_folder_uri; + }; + + void addAccount (in Account acc); + }; + + interface MailFilter : Bonobo::Unknown { + + void addFilter (in string rule); + + void removeFilter (in string rule); + }; }; }; diff --git a/mail/component-factory.c b/mail/component-factory.c index 239611bd6a..759d7294f1 100644 --- a/mail/component-factory.c +++ b/mail/component-factory.c @@ -324,6 +324,8 @@ component_factory_init (void) summary_factory = bonobo_generic_factory_new (SUMMARY_FACTORY_ID, summary_fn, NULL); + evolution_mail_config_factory_init (); + if (component_factory == NULL || summary_factory == NULL) { e_notice (NULL, GNOME_MESSAGE_BOX_ERROR, _("Cannot initialize Evolution's mail component.")); diff --git a/mail/importers/Makefile.am b/mail/importers/Makefile.am index eb35101291..48200aa909 100644 --- a/mail/importers/Makefile.am +++ b/mail/importers/Makefile.am @@ -1,7 +1,6 @@ importersdir = $(pkglibdir)/evolution-mail-importers/$(VERSION) -importers_LTLIBRARIES = liboutlook.la libmbox.la libiinetscape.la \ - libiipine.la libiielm.la +importers_LTLIBRARIES = liboutlook.la libmbox.la INCLUDES = -I.. \ -I$(srcdir)/.. \ @@ -19,21 +18,9 @@ liboutlook_la_LDFLAGS = -version-info 0:0:0 libmbox_la_SOURCES = evolution-mbox-importer.c libmbox_la_LDFLAGS = -version-info 0:0:0 -libiinetscape_la_SOURCES = netscape-importer.c -libiinetscape_la_LDFLAGS = -version-info 0:0:0 - -libiipine_la_SOURCES = pine-importer.c -libiipine_la_LDFLAGS = -version-info 0:0:0 - -libiielm_la_SOURCES = elm-importer.c -libiielm_la_LDFLAGS = -version-info 0:0:0 - oafdir = $(datadir)/oaf oaf_in_files = GNOME_Evolution_Mail_Mbox_Importer.oaf.in \ - GNOME_Evolution_Mail_Outlook_Importer.oaf.in \ - GNOME_Evolution_Mail_Netscape_Intelligent_Importer.oaf.in \ - GNOME_Evolution_Mail_Pine_Intelligent_Importer.oaf.in \ - GNOME_Evolution_Mail_Elm_Intelligent_Importer.oaf.in + GNOME_Evolution_Mail_Outlook_Importer.oaf.in oaf_DATA = $(oaf_in_files:.oaf.in=.oaf) diff --git a/mail/importers/elm-importer.c b/mail/importers/elm-importer.c deleted file mode 100644 index 1394d0f279..0000000000 --- a/mail/importers/elm-importer.c +++ /dev/null @@ -1,451 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* elm-importer.c - * - * Authors: - * Iain Holmes <iain@ximian.com> - * - * Copyright 2001 Ximian, Inc. (http://www.ximian.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <dirent.h> - -#include <glib.h> -#include <gnome.h> - -#include <bonobo/bonobo-object.h> -#include <bonobo/bonobo-generic-factory.h> -#include <camel/camel-mime-message.h> -#include <camel/camel-mime-part.h> -#include <camel/camel-exception.h> - -#include <importer/evolution-intelligent-importer.h> -#include <importer/GNOME_Evolution_Importer.h> -#include "mail-importer.h" -#include "mail-tools.h" - -extern char *evolution_dir; - -#define ELM_INTELLIGENT_IMPORTER_IID "OAFIID:GNOME_Evolution_Mail_Elm_Intelligent_Importer_Factory" -#define KEY "elm-mail-imported" - -/*#define SUPER_IMPORTER_DEBUG*/ -#ifdef SUPER_IMPORTER_DEBUG -#define d(x) x -#else -#define d(x) -#endif - -typedef struct { - MailImporter importer; - GList *dir_list; - - int num; - CamelMimeParser *mp; - BonoboListener *listener; -} ElmImporter; - -typedef struct { - char *parent; - char *foldername; - char *path; -} ElmFolder; - -static gboolean -elm_is_mbox (const char *filename) -{ - char sig[5]; - int fd; - - fd = open (filename, O_RDONLY); - if (read (fd, sig, 5) != 5) { - close (fd); - return FALSE; - } - - close (fd); - if (strncmp (sig, "From ", 5) != 0) { - return FALSE; - } - - return TRUE; -} - -static gboolean -elm_import_mbox (CamelFolder *folder, - const char *filename) -{ - gboolean done = FALSE; - CamelException *ex; - CamelMimeParser *mp; - int fd, n = 0; - - fd = open (filename, O_RDONLY); - if (fd == -1) { - g_warning ("Cannot open %s", filename); - return FALSE; - } - - camel_object_ref (CAMEL_OBJECT (folder)); - camel_folder_freeze (folder); - - ex = camel_exception_new (); - mp = camel_mime_parser_new (); - camel_mime_parser_scan_from (mp, TRUE); - if (camel_mime_parser_init_with_fd (mp, fd) == -1) { - g_warning ("Unable to process file %s", filename); - camel_object_unref (CAMEL_OBJECT (mp)); - camel_folder_thaw (folder); - camel_object_unref (CAMEL_OBJECT (folder)); - return FALSE; - } - - while (camel_mime_parser_step (mp, 0, 0) == HSCAN_FROM) { - /* Import the next message */ - CamelMimeMessage *msg; - CamelMessageInfo *info; - - msg = camel_mime_message_new (); - if (camel_mime_part_construct_from_parser (CAMEL_MIME_PART (msg), - mp) == -1) { - g_warning ("Failed message %d", n); - camel_object_unref (CAMEL_OBJECT (msg)); - done = TRUE; - } - - info = g_new0 (CamelMessageInfo, 1); - camel_folder_append_message (folder, msg, info, ex); - g_free (info); - camel_object_unref (CAMEL_OBJECT (msg)); - if (camel_exception_is_set (ex)) { - g_warning ("Failed message %d", n); - done = TRUE; - } - - if (!done) { - n++; - camel_mime_parser_step (mp, 0, 0); - } - } - - camel_folder_sync (folder, FALSE, ex); - camel_folder_thaw (folder); - camel_object_unref (CAMEL_OBJECT (folder)); - done = TRUE; - - camel_exception_free (ex); - return done; -} - -static void -elm_import_file (ElmImporter *importer, - const char *path, - const char *fullpath) -{ - char *protocol; - CamelException *ex; - CamelFolder *folder; - - g_warning ("Importing %s into %s", path, fullpath); - protocol = g_strconcat ("file://", fullpath, NULL); - ex = camel_exception_new (); - folder = mail_tool_uri_to_folder (protocol, ex); - g_free (protocol); - - if (camel_exception_is_set (ex)) { - camel_exception_free (ex); - return; - } - camel_exception_free (ex); - - if (folder == NULL) { - return; - } - - elm_import_mbox (folder, path); -} - -static gboolean -is_kmail (const char *maildir) -{ - char *names[5] = - { - "inbox", - "outbox", - "sent-mail", - "trash", - "drafts" - }; - int i; - - for (i = 0; i < 5; i++) { - char *file, *index, *tmp; - - file = g_concat_dir_and_file (maildir, names[i]); - tmp = g_strdup_printf (".%s.index", names[i]); - index = g_concat_dir_and_file (maildir, tmp); - g_free (tmp); - - if (!g_file_exists (file) || - !g_file_exists (index)) { - g_free (index); - g_free (file); - return FALSE; - } - - g_free (index); - g_free (file); - } - - return TRUE; -} - -static gboolean -elm_can_import (EvolutionIntelligentImporter *ii, - void *closure) -{ - ElmImporter *importer = closure; - FILE *prefs_handle; - char *key, *maildir; - gboolean exists; - - /* Already imported */ - key = g_strdup_printf ("=%s/config/Mail=/importers/", evolution_dir); - gnome_config_push_prefix (key); - g_free (key); - - if (gnome_config_get_bool (KEY) == TRUE) { - gnome_config_pop_prefix (); - return FALSE; - } - gnome_config_pop_prefix (); - - /* Elm uses ~/Mail - Alas so does MH and KMail. */ - maildir = gnome_util_prepend_user_home ("Mail"); - exists = g_file_exists (maildir); - - if (exists) { - char *mh, *mhdir; - - /* Check for some other files to work out what it is. */ - - /* MH? */ - mh = g_concat_dir_and_file (maildir, "context"); - mhdir = g_concat_dir_and_file (maildir, "inbox"); - if (g_file_exists (mh) && - g_file_test (mhdir, G_FILE_TEST_ISDIR)) { - exists = FALSE; /* Probably MH */ - } - - g_free (mh); - g_free (mhdir); - } - - if (exists) { - /* Check for KMail stuff */ - exists = !is_kmail (maildir); - } - - g_free (maildir); - - return exists; -} - -static void -scan_dir (ElmImporter *importer, - const char *dirname, - const char *orig_parent) -{ - DIR *maildir; - struct stat buf; - struct dirent *current; - - maildir = opendir (dirname); - if (maildir == NULL) { - g_warning ("Could not open %s\nopendir returned: %s", - dirname, g_strerror (errno)); - return; - } - - current = readdir (maildir); - while (current) { - ElmFolder *pf; - char *fullname; - - /* Ignore . and .. */ - if (current->d_name[0] == '.') { - if (current->d_name[1] == '\0' || - (current->d_name[1] == '.' && current->d_name[2] == '\0')) { - current = readdir (maildir); - continue; - } - } - - fullname = g_concat_dir_and_file (dirname, current->d_name); - if (stat (fullname, &buf) == -1) { - g_warning ("Could not stat %s\nstat returned: %s", - fullname, g_strerror (errno)); - current = readdir (maildir); - g_free (fullname); - continue; - } - - if (S_ISREG (buf.st_mode)) { - pf = g_new (ElmFolder, 1); - pf->path = g_strdup (fullname); - pf->parent = g_strdup (orig_parent); - pf->foldername = g_strdup (current->d_name); - importer->dir_list = g_list_append (importer->dir_list, pf); - } else if (S_ISDIR (buf.st_mode)) { - char *subdir; - - pf = g_new (ElmFolder, 1); - pf->path = NULL; - pf->parent = g_strdup (orig_parent); - pf->foldername = g_strdup (current->d_name); - importer->dir_list = g_list_append (importer->dir_list, pf); - - subdir = g_concat_dir_and_file (orig_parent, current->d_name); - scan_dir (importer, fullname, subdir); - g_free (subdir); - } - - g_free (fullname); - current = readdir (maildir); - } -} - -static void -folder_created_cb (BonoboListener *listener, - const char *event_name, - const BonoboArg *event_data, - CORBA_Environment *ev, - ElmImporter *importer) -{ - ElmFolder *folder; - GList *l; - GNOME_Evolution_Storage_FolderResult *result; - char *fullpath; - - if (strcmp (event_name, "evolution-shell:folder_created") != 0) { - return; /* Unknown event notification */ - } - - result = event_data->_value; - fullpath = result->path; - - l = importer->dir_list; - importer->dir_list = g_list_remove_link (importer->dir_list, l); - folder = l->data; - g_list_free_1 (l); - - /* We got the folder, so try to import the file into it. */ - if (folder->path != NULL && elm_is_mbox (folder->path)) { - elm_import_file (importer, folder->path, fullpath); - } - - g_free (folder->path); - g_free (folder->parent); - g_free (folder->foldername); - g_free (folder); - - if (importer->dir_list) { - /* Do the next in the list */ - folder = importer->dir_list->data; - mail_importer_create_folder (folder->parent, folder->foldername, - NULL, importer->listener); - } -} - -static void -elm_create_structure (EvolutionIntelligentImporter *ii, - void *closure) -{ - ElmFolder *folder; - ElmImporter *importer = closure; - char *maildir, *key; - - maildir = gnome_util_prepend_user_home ("Mail"); - scan_dir (importer, maildir, "/"); - g_free (maildir); - - if (importer->dir_list == NULL) - return; - - folder = importer->dir_list->data; - mail_importer_create_folder (folder->parent, folder->foldername, NULL, - importer->listener); - - key = g_strdup_printf ("=%s/config/Mail=/importers/", evolution_dir); - gnome_config_push_prefix (key); - g_free (key); - - gnome_config_set_bool (KEY, TRUE); - gnome_config_pop_prefix (); - - gnome_config_sync (); - gnome_config_drop_all (); -} - -static BonoboObject * -elm_factory_fn (BonoboGenericFactory *_factory, - void *closure) -{ - EvolutionIntelligentImporter *importer; - 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->listener = bonobo_listener_new (NULL, NULL); - gtk_signal_connect (GTK_OBJECT (elm->listener), "event_notify", - GTK_SIGNAL_FUNC (folder_created_cb), elm); - - importer = evolution_intelligent_importer_new (elm_can_import, - elm_create_structure, - _("Elm mail"), - _(message), elm); - - return BONOBO_OBJECT (importer); -} - -/* Entry point */ -void -mail_importer_module_init (void) -{ - static gboolean initialised = FALSE; - BonoboGenericFactory *factory; - - if (initialised == TRUE) - return; - - factory = bonobo_generic_factory_new (ELM_INTELLIGENT_IMPORTER_IID, - elm_factory_fn, NULL); - if (factory == NULL) - g_warning ("Could not initialise Elm Intelligent Mail Importer."); - initialised = TRUE; -} diff --git a/mail/importers/evolution-mbox-importer.c b/mail/importers/evolution-mbox-importer.c index dcdf0f75ad..ef9b9f1ca5 100644 --- a/mail/importers/evolution-mbox-importer.c +++ b/mail/importers/evolution-mbox-importer.c @@ -115,6 +115,7 @@ process_item_fn (EvolutionImporter *eimporter, } camel_exception_free (ex); + g_print ("Notifying...\n"); GNOME_Evolution_ImporterListener_notifyResult (listener, GNOME_Evolution_ImporterListener_OK, !done, ev); @@ -168,6 +169,40 @@ importer_destroy_cb (GtkObject *object, g_free (mbi); } +static void +folder_created_cb (BonoboListener *listener, + const char *event_name, + const BonoboArg *event_data, + CORBA_Environment *ev, + MailImporter *importer) +{ + char *fullpath; + GNOME_Evolution_Storage_FolderResult *result; + CamelException *ex; + + if (strcmp (event_name, "evolution-shell:folder_created") != 0) { + return; /* Unknown event */ + } + + result = event_data->_value; + fullpath = g_strconcat ("file://", result->path, NULL); + + ex = camel_exception_new (); + importer->folder = mail_tool_uri_to_folder (fullpath, ex); + + if (camel_exception_is_set (ex)) { + g_warning ("Error opening %s", fullpath); + camel_exception_free (ex); + + g_free (fullpath); + return; + } + + g_warning ("%s created", fullpath); + g_free (fullpath); + bonobo_object_unref (BONOBO_OBJECT (listener)); +} + static gboolean load_file_fn (EvolutionImporter *eimporter, const char *filename, @@ -178,6 +213,7 @@ load_file_fn (EvolutionImporter *eimporter, MailImporter *importer; int fd; + g_warning ("%s", __FUNCTION__); mbi = (MboxImporter *) closure; importer = (MailImporter *) mbi; @@ -199,8 +235,28 @@ load_file_fn (EvolutionImporter *eimporter, importer->mstream = NULL; if (folderpath == NULL || *folderpath == '\0') importer->folder = mail_tool_get_local_inbox (NULL); - else - importer->folder = mail_tool_uri_to_folder (folderpath, NULL); + else { + char *parent, *name; + BonoboListener *listener; + + /* Make a new directory */ + name = strrchr (folderpath, '/'); + if (name == NULL) { + parent = g_strdup ("/"); + name = folderpath; + } else { + name += 1; + parent = g_dirname (folderpath); + } + + listener = bonobo_listener_new (NULL, NULL); + gtk_signal_connect (GTK_OBJECT (listener), "event-notify", + GTK_SIGNAL_FUNC (folder_created_cb), + importer); + + mail_importer_create_folder (parent, name, NULL, listener); + g_free (parent); + } if (importer->folder == NULL){ g_print ("Bad folder\n"); @@ -232,7 +288,8 @@ mbox_factory_fn (BonoboGenericFactory *_factory, process_item_fn, NULL, mbox); gtk_signal_connect (GTK_OBJECT (importer), "destroy", GTK_SIGNAL_FUNC (importer_destroy_cb), mbox); - + + g_warning ("Returning"); return BONOBO_OBJECT (importer); } diff --git a/mail/importers/netscape-importer.c b/mail/importers/netscape-importer.c deleted file mode 100644 index 64effc7b4d..0000000000 --- a/mail/importers/netscape-importer.c +++ /dev/null @@ -1,473 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* netscape-importer.c - * - * Authors: - * Iain Holmes <iain@ximian.com> - * - * Copyright 2001 Ximian, Inc. (http://www.ximian.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <dirent.h> - -#include <glib.h> - -#include <bonobo/bonobo-object.h> -#include <bonobo/bonobo-generic-factory.h> -#include <camel/camel-mime-message.h> -#include <camel/camel-mime-part.h> -#include <camel/camel-exception.h> - -#include <importer/evolution-intelligent-importer.h> -#include <importer/GNOME_Evolution_Importer.h> -#include <evolution-storage.h> - -#include "mail-importer.h" -#include "mail-tools.h" - -static char *nsmail_dir = NULL; - -extern char *evolution_dir; - -#define NETSCAPE_INTELLIGENT_IMPORTER_IID "OAFIID:GNOME_Evolution_Mail_Netscape_Intelligent_Importer_Factory" -#define MBOX_IMPORTER_IID "OAFIID:GNOME_Evolution_Mail_Mbox_ImporterFactory" -#define KEY "netscape-mail-imported" - -/*#define SUPER_IMPORTER_DEBUG*/ -#ifdef SUPER_IMPORTER_DEBUG -#define d(x) x -#else -#define d(x) -#endif - -typedef struct { - MailImporter importer; - GList *dir_list; - - int num; - CamelMimeParser *mp; - BonoboListener *listener; -} NetscapeImporter; - -void mail_importer_module_init (void); -void g_module_unload (void); - -static gboolean -netscape_import_mbox (CamelFolder *folder, - const char *filename) -{ - gboolean done = FALSE; - CamelException *ex; - CamelMimeParser *mp; - int fd, n = 0; - - fd = open (filename, O_RDONLY); - if (fd == -1) { - g_warning ("Cannot open %s", filename); - return FALSE; - } - - camel_object_ref (CAMEL_OBJECT (folder)); - camel_folder_freeze (folder); - - ex = camel_exception_new (); - mp = camel_mime_parser_new (); - camel_mime_parser_scan_from (mp, TRUE); - if (camel_mime_parser_init_with_fd (mp, fd) == -1) { - g_warning ("Unable to process file %s", filename); - camel_object_unref (CAMEL_OBJECT (mp)); - camel_folder_thaw (folder); - camel_object_unref (CAMEL_OBJECT (folder)); - return FALSE; - } - - while (camel_mime_parser_step (mp, 0, 0) == HSCAN_FROM) { - /* Import the next message */ - CamelMimeMessage *msg; - CamelMessageInfo *info; - - msg = camel_mime_message_new (); - if (camel_mime_part_construct_from_parser (CAMEL_MIME_PART (msg), - mp) == -1) { - g_warning ("Failed message %d", n); - camel_object_unref (CAMEL_OBJECT (msg)); - done = TRUE; - } - - info = g_new0 (CamelMessageInfo, 1); - camel_folder_append_message (folder, msg, info, ex); - g_free (info); - camel_object_unref (CAMEL_OBJECT (msg)); - if (camel_exception_is_set (ex)) { - g_warning ("Failed message %d", n); - done = TRUE; - } - - if (!done) { - n++; - camel_mime_parser_step (mp, 0, 0); - } - } - - camel_folder_sync (folder, FALSE, ex); - camel_folder_thaw (folder); - camel_object_unref (CAMEL_OBJECT (folder)); - done = TRUE; - - camel_exception_free (ex); - return done; -} - -static void -netscape_clean_up (void) -{ - if (nsmail_dir == NULL) - return; - - g_free (nsmail_dir); - nsmail_dir = NULL; -} - -static gboolean -netscape_can_import (EvolutionIntelligentImporter *ii, - void *closure) -{ - char *nsprefs; - FILE *prefs_handle; - char *key; - - /* Already imported */ - key = g_strdup_printf ("=%s/config/Mail=/importers/", evolution_dir); - gnome_config_push_prefix (key); - g_free (key); - - if (gnome_config_get_bool (KEY) == TRUE) { - gnome_config_pop_prefix (); - return FALSE; - } - gnome_config_pop_prefix (); - - nsprefs = gnome_util_prepend_user_home (".netscape/preferences.js"); - prefs_handle = fopen (nsprefs, "r"); - g_free (nsprefs); - - if (prefs_handle == NULL) { - d(g_warning ("No .netscape/preferences.js")); - return FALSE; - } - - /* Find the user mail dir */ - while (1) { - char line[4096]; - - fgets (line, 4096, prefs_handle); - if (line == NULL) { - g_warning ("No mail.directory entry"); - fclose (prefs_handle); - return FALSE; - } - - if (strstr (line, "mail.directory") != NULL) { - char *sep, *start, *end; - /* Found the line */ - - sep = strchr (line, ','); - if (sep == NULL) { - g_warning ("Bad line %s", line); - fclose (prefs_handle); - return FALSE; - } - - start = strchr (sep, '\"') + 1; - if (start == NULL) { - g_warning ("Bad line %s", line); - fclose (prefs_handle); - return FALSE; - } - - end = strrchr (sep, '\"'); - if (end == NULL) { - g_warning ("Bad line %s", line); - fclose (prefs_handle); - return FALSE; - } - - nsmail_dir = g_strndup (start, end - start); - d(g_warning ("Got nsmail_dir: %s", nsmail_dir)); - fclose (prefs_handle); - return TRUE; - } - } -} - -static void -netscape_import_file (NetscapeImporter *importer, - const char *path, - const char *fullpath) -{ - char *protocol; - CamelException *ex; - CamelFolder *folder; - - /* Do import */ - d(g_warning ("Importing %s as %s\n", filename, fullpath)); - - ex = camel_exception_new (); - protocol = g_strconcat ("file://", fullpath, NULL); - folder = mail_tool_uri_to_folder (protocol, ex); - if (camel_exception_is_set (ex)) { - g_free (protocol); - camel_exception_free (ex); - return; - } - - g_free (protocol); - - if (folder == NULL) { - g_warning ("Folder for %s is NULL", fullpath); - camel_exception_free (ex); - return; - } - - camel_exception_free (ex); - - netscape_import_mbox (folder, path); -} - -typedef struct { - NetscapeImporter *importer; - char *parent; - char *path; - char *foldername; -} NetscapeCreateDirectoryData; - -static void -netscape_dir_created (BonoboListener *listener, - const char *event_name, - const BonoboArg *event_data, - CORBA_Environment *ev, - NetscapeImporter *importer) -{ - EvolutionStorageResult storage_result; - NetscapeCreateDirectoryData *data; - GList *l; - GNOME_Evolution_Storage_FolderResult *result; - char *fullpath; - - if (strcmp (event_name, "evolution-shell:folder_created") != 0) { - return; /* Unknown event notification */ - } - - result = event_data->_value; - storage_result = result->result; - fullpath = result->path; - - g_warning ("path: %s\tresult: %d", fullpath, storage_result); - - l = importer->dir_list; - importer->dir_list = g_list_remove_link (importer->dir_list, l); - data = l->data; - g_list_free_1 (l); - - /* Import the file */ - /* We got the folder, so try to import the file into it. */ - if (fullpath != NULL || *fullpath != '\0') - netscape_import_file (data->importer, data->path, fullpath); - - g_free (data->parent); - g_free (data->path); - g_free (data->foldername); - g_free (data); - - if (importer->dir_list) { - /* Do the next in the list */ - data = importer->dir_list->data; - mail_importer_create_folder (data->parent, data->foldername, - NULL, importer->listener); - } -} - -static char * -maybe_replace_name (const char *original_name) -{ - if (strcmp (original_name, "Trash") == 0) { - return g_strdup ("Netscape-Trash"); /* Trash is an invalid name */ - } else if (strcmp (original_name, "Unsent Messages") == 0) { - return g_strdup ("Outbox"); - } - - return g_strdup (original_name); -} - -/* This function basically flattens the tree structure. - It makes a list of all the directories that are to be imported. */ -static void -scan_dir (NetscapeImporter *importer, - const char *orig_parent, - const char *dirname) -{ - DIR *nsmail; - struct stat buf; - struct dirent *current; - - nsmail = opendir (dirname); - if (nsmail == NULL) { - d(g_warning ("Could not open %s\nopendir returned: %s", - dirname, g_strerror (errno))); - return; - } - - current = readdir (nsmail); - while (current) { - char *fullname, *foldername; - - /* Ignore things which start with . - which should be ., .., and the summaries. */ - if (current->d_name[0] =='.') { - current = readdir (nsmail); - continue; - } - - if (*orig_parent == '/') { - foldername = maybe_replace_name (current->d_name); - } else { - foldername = g_strdup (current->d_name); - } - - fullname = g_concat_dir_and_file (dirname, current->d_name); - if (stat (fullname, &buf) == -1) { - d(g_warning ("Could not stat %s\nstat returned:%s", - fullname, g_strerror (errno))); - current = readdir (nsmail); - g_free (fullname); - continue; - } - - if (S_ISREG (buf.st_mode)) { - char *sbd, *parent; - NetscapeCreateDirectoryData *data; - - d(g_print ("File: %s\n", fullname)); - - data = g_new0 (NetscapeCreateDirectoryData, 1); - data->importer = importer; - data->parent = g_strdup (orig_parent); - data->path = g_strdup (fullname); - data->foldername = g_strdup (foldername); - - importer->dir_list = g_list_append (importer->dir_list, - data); - - - parent = g_concat_dir_and_file (orig_parent, - data->foldername); - - /* Check if a .sbd folder exists */ - sbd = g_strconcat (fullname, ".sbd", NULL); - if (g_file_exists (sbd)) { - scan_dir (importer, parent, sbd); - } - - g_free (parent); - g_free (sbd); - } - - g_free (fullname); - g_free (foldername); - current = readdir (nsmail); - } -} - -static void -netscape_create_structure (EvolutionIntelligentImporter *ii, - void *closure) -{ - NetscapeImporter *importer = closure; - NetscapeCreateDirectoryData *data; - char *key; - - g_return_if_fail (nsmail_dir != NULL); - - scan_dir (importer, "/", nsmail_dir); - - importer->listener = bonobo_listener_new (NULL, NULL); - gtk_signal_connect (GTK_OBJECT (importer->listener), "event_notify", - GTK_SIGNAL_FUNC (netscape_dir_created), importer); - data = importer->dir_list->data; - mail_importer_create_folder (data->parent, data->foldername, NULL, - importer->listener); - - key = g_strdup_printf ("=%s/config/Mail=/importers/", evolution_dir); - gnome_config_push_prefix (key); - g_free (key); - - gnome_config_set_bool (KEY, TRUE); - gnome_config_pop_prefix (); - - gnome_config_sync (); - gnome_config_drop_all (); -} - -static BonoboObject * -netscape_factory_fn (BonoboGenericFactory *_factory, - void *closure) -{ - EvolutionIntelligentImporter *importer; - NetscapeImporter *netscape; - char *message = N_("Evolution has found Netscape mail files.\n" - "Would you like them to be imported into Evolution?"); - - netscape = g_new0 (NetscapeImporter, 1); - importer = evolution_intelligent_importer_new (netscape_can_import, - netscape_create_structure, - "Netscape mail", - message, netscape); - return BONOBO_OBJECT (importer); -} - -/* Entry Point */ -void -mail_importer_module_init (void) -{ - static gboolean initialised = FALSE; - BonoboGenericFactory *factory; - - if (initialised == TRUE) - return; - - factory = bonobo_generic_factory_new (NETSCAPE_INTELLIGENT_IMPORTER_IID, - netscape_factory_fn, NULL); - if (factory == NULL) - g_warning ("Could not initialise Netscape Intelligent Mail Importer."); - initialised = TRUE; -} - -/* GModule g_module_unload routine */ -void -g_module_unload (void) -{ - netscape_clean_up (); -} diff --git a/mail/importers/pine-importer.c b/mail/importers/pine-importer.c deleted file mode 100644 index 310eea3483..0000000000 --- a/mail/importers/pine-importer.c +++ /dev/null @@ -1,416 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* pine-importer.c - * - * Authors: - * Iain Holmes <iain@ximian.com> - * - * Copyright 2001 Ximian, Inc. (http://www.ximian.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <dirent.h> - -#include <glib.h> - -#include <bonobo/bonobo-object.h> -#include <bonobo/bonobo-generic-factory.h> -#include <camel/camel-mime-message.h> -#include <camel/camel-mime-part.h> -#include <camel/camel-exception.h> - -#include <importer/evolution-intelligent-importer.h> -#include <importer/GNOME_Evolution_Importer.h> -#include "mail-importer.h" -#include "mail-tools.h" - -extern char *evolution_dir; - -#define PINE_INTELLIGENT_IMPORTER_IID "OAFIID:GNOME_Evolution_Mail_Pine_Intelligent_Importer_Factory" -#define KEY "pine-mail-imported" - -/*#define SUPER_IMPORTER_DEBUG*/ -#ifdef SUPER_IMPORTER_DEBUG -#define d(x) x -#else -#define d(x) -#endif - -typedef struct { - MailImporter importer; - GList *dir_list; - - int num; - CamelMimeParser *mp; - BonoboListener *listener; -} PineImporter; - -typedef struct { - char *parent; - char *foldername; - char *path; -} PineFolder; - -/* Prototype */ - -void mail_importer_module_init (void); - - -static gboolean -pine_is_mbox (const char *filename) -{ - char sig[5]; - int fd; - - fd = open (filename, O_RDONLY); - if (read (fd, sig, 5) != 5) { - close (fd); - return FALSE; - } - - close (fd); - if (strncmp (sig, "From ", 5) != 0) { - return FALSE; - } - - return TRUE; -} - -static gboolean -pine_import_mbox (CamelFolder *folder, - const char *filename) -{ - gboolean done = FALSE; - CamelException *ex; - CamelMimeParser *mp; - int fd, n = 0; - - fd = open (filename, O_RDONLY); - if (fd == -1) { - g_warning ("Cannot open %s", filename); - return FALSE; - } - - camel_object_ref (CAMEL_OBJECT (folder)); - camel_folder_freeze (folder); - - ex = camel_exception_new (); - mp = camel_mime_parser_new (); - camel_mime_parser_scan_from (mp, TRUE); - if (camel_mime_parser_init_with_fd (mp, fd) == -1) { - g_warning ("Unable to process file %s", filename); - camel_object_unref (CAMEL_OBJECT (mp)); - camel_folder_thaw (folder); - camel_object_unref (CAMEL_OBJECT (folder)); - return FALSE; - } - - while (camel_mime_parser_step (mp, 0, 0) == HSCAN_FROM) { - /* Import the next message */ - CamelMimeMessage *msg; - CamelMessageInfo *info; - - msg = camel_mime_message_new (); - if (camel_mime_part_construct_from_parser (CAMEL_MIME_PART (msg), - mp) == -1) { - g_warning ("Failed message %d", n); - camel_object_unref (CAMEL_OBJECT (msg)); - done = TRUE; - } - - info = g_new0 (CamelMessageInfo, 1); - camel_folder_append_message (folder, msg, info, ex); - g_free (info); - camel_object_unref (CAMEL_OBJECT (msg)); - if (camel_exception_is_set (ex)) { - g_warning ("Failed message %d", n); - done = TRUE; - } - - if (!done) { - n++; - camel_mime_parser_step (mp, 0, 0); - } - } - - camel_folder_sync (folder, FALSE, ex); - camel_folder_thaw (folder); - camel_object_unref (CAMEL_OBJECT (folder)); - done = TRUE; - - camel_exception_free (ex); - return done; -} - -static void -pine_import_file (PineImporter *importer, - const char *path, - const char *fullpath) -{ - char *protocol; - CamelException *ex; - CamelFolder *folder; - - g_warning ("Importing %s into %s", path, fullpath); - protocol = g_strconcat ("file://", fullpath, NULL); - ex = camel_exception_new (); - folder = mail_tool_uri_to_folder (protocol, ex); - g_free (protocol); - - if (camel_exception_is_set (ex)) { - camel_exception_free (ex); - return; - } - camel_exception_free (ex); - - if (folder == NULL) { - return; - } - - pine_import_mbox (folder, path); -} - -static gboolean -pine_can_import (EvolutionIntelligentImporter *ii, - void *closure) -{ - PineImporter *importer = closure; - FILE *prefs_handle; - char *key, *maildir; - gboolean exists; - - /* Already imported */ - key = g_strdup_printf ("=%s/config/Mail=/importers/", evolution_dir); - gnome_config_push_prefix (key); - g_free (key); - - if (gnome_config_get_bool (KEY) == TRUE) { - gnome_config_pop_prefix (); - return FALSE; - } - gnome_config_pop_prefix (); - - maildir = gnome_util_prepend_user_home ("mail"); - exists = g_file_exists (maildir); - g_free (maildir); - - return exists; -} - -/* Pine uses sent-mail and saved-mail whereas Evolution uses Sent and Drafts */ -static char * -maybe_replace_name (const char *original_name) -{ - if (strcmp (original_name, "sent-mail") == 0) { - return g_strdup ("Sent"); - } else if (strcmp (original_name, "saved-messages") == 0) { - return g_strdup ("Drafts"); - } - - return g_strdup (original_name); -} - -static void -scan_dir (PineImporter *importer, - const char *dirname, - const char *orig_parent) -{ - DIR *maildir; - struct stat buf; - struct dirent *current; - - maildir = opendir (dirname); - if (maildir == NULL) { - g_warning ("Could not open %s\nopendir returned: %s", - dirname, g_strerror (errno)); - return; - } - - current = readdir (maildir); - while (current) { - PineFolder *pf; - char *fullname, *foldername; - - /* Ignore . and .. */ - if (current->d_name[0] == '.') { - if (current->d_name[1] == '\0' || - (current->d_name[1] == '.' && current->d_name[2] == '\0')) { - current = readdir (maildir); - continue; - } - } - - if (*orig_parent == '/') { - foldername = maybe_replace_name (current->d_name); - } else { - foldername = g_strdup (current->d_name); - } - - fullname = g_concat_dir_and_file (dirname, current->d_name); - if (stat (fullname, &buf) == -1) { - g_warning ("Could not stat %s\nstat returned: %s", - fullname, g_strerror (errno)); - current = readdir (maildir); - g_free (fullname); - continue; - } - - if (S_ISREG (buf.st_mode)) { - pf = g_new (PineFolder, 1); - pf->path = g_strdup (fullname); - pf->parent = g_strdup (orig_parent); - pf->foldername = g_strdup (foldername); - importer->dir_list = g_list_append (importer->dir_list, pf); - } else if (S_ISDIR (buf.st_mode)) { - char *subdir; - - pf = g_new (PineFolder, 1); - pf->path = NULL; - pf->parent = g_strdup (orig_parent); - pf->foldername = g_strdup (foldername); - importer->dir_list = g_list_append (importer->dir_list, pf); - - subdir = g_concat_dir_and_file (orig_parent, foldername); - scan_dir (importer, fullname, subdir); - g_free (subdir); - } - - g_free (fullname); - g_free (foldername); - current = readdir (maildir); - } -} - -static void -folder_created_cb (BonoboListener *listener, - const char *event_name, - const BonoboArg *event_data, - CORBA_Environment *ev, - PineImporter *importer) -{ - PineFolder *folder; - GList *l; - GNOME_Evolution_Storage_FolderResult *result; - char *fullpath; - - if (strcmp (event_name, "evolution-shell:folder_created") != 0) { - return; /* Unknown event notification */ - } - - result = event_data->_value; - fullpath = result->path; - - l = importer->dir_list; - importer->dir_list = g_list_remove_link (importer->dir_list, l); - folder = l->data; - g_list_free_1 (l); - - /* We got the folder, so try to import the file into it. */ - if (folder->path != NULL && pine_is_mbox (folder->path)) { - pine_import_file (importer, folder->path, fullpath); - } - - g_free (folder->path); - g_free (folder->parent); - g_free (folder->foldername); - g_free (folder); - - if (importer->dir_list) { - /* Do the next in the list */ - folder = importer->dir_list->data; - mail_importer_create_folder (folder->parent, folder->foldername, - NULL, importer->listener); - } -} - -static void -pine_create_structure (EvolutionIntelligentImporter *ii, - void *closure) -{ - PineFolder *folder; - PineImporter *importer = closure; - char *maildir, *key; - - maildir = gnome_util_prepend_user_home ("mail"); - scan_dir (importer, maildir, "/"); - g_free (maildir); - - if (importer->dir_list == NULL) - return; - - folder = importer->dir_list->data; - mail_importer_create_folder (folder->parent, folder->foldername, NULL, - importer->listener); - - key = g_strdup_printf ("=%s/config/Mail=/importers/", evolution_dir); - gnome_config_push_prefix (key); - g_free (key); - - gnome_config_set_bool (KEY, TRUE); - gnome_config_pop_prefix (); - - gnome_config_sync (); - gnome_config_drop_all (); - -} - -static BonoboObject * -pine_factory_fn (BonoboGenericFactory *_factory, - void *closure) -{ - EvolutionIntelligentImporter *importer; - 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->listener = bonobo_listener_new (NULL, NULL); - gtk_signal_connect (GTK_OBJECT (pine->listener), "event_notify", - GTK_SIGNAL_FUNC (folder_created_cb), pine); - - importer = evolution_intelligent_importer_new (pine_can_import, - pine_create_structure, - _("Pine mail"), - _(message), pine); - - return BONOBO_OBJECT (importer); -} - -/* Entry point */ -void -mail_importer_module_init (void) -{ - static gboolean initialised = FALSE; - BonoboGenericFactory *factory; - - if (initialised == TRUE) - return; - - factory = bonobo_generic_factory_new (PINE_INTELLIGENT_IMPORTER_IID, - pine_factory_fn, NULL); - if (factory == NULL) - g_warning ("Could not initialise Pine Intelligent Mail Importer."); - initialised = TRUE; -} diff --git a/mail/mail-account-gui.c b/mail/mail-account-gui.c index 434634c5c6..971d83773c 100644 --- a/mail/mail-account-gui.c +++ b/mail/mail-account-gui.c @@ -702,6 +702,9 @@ setup_service (MailAccountGuiService *gsvc, MailConfigService *service) CamelURL *url = camel_url_new (service->url, NULL); gboolean has_auth = FALSE; + if (url == NULL) + return; + if (url->user && CAMEL_PROVIDER_ALLOWS (gsvc->provider, CAMEL_URL_PART_USER)) gtk_entry_set_text (gsvc->username, url->user); if (url->host && CAMEL_PROVIDER_ALLOWS (gsvc->provider, CAMEL_URL_PART_HOST)) { diff --git a/mail/mail-callbacks.c b/mail/mail-callbacks.c index 98c8350903..4e1741db63 100644 --- a/mail/mail-callbacks.c +++ b/mail/mail-callbacks.c @@ -1463,6 +1463,8 @@ filter_edit (BonoboUIComponent *uih, void *user_data, const char *path) } dialog = (GtkWidget *)filter_editor_new (fc, filter_source_names); + gtk_window_set_title (GTK_WINDOW (dialog), _("Filters")); + gtk_object_set_data_full (GTK_OBJECT (dialog), "context", fc, (GtkDestroyNotify)gtk_object_unref); gtk_signal_connect (GTK_OBJECT (dialog), "clicked", filter_druid_clicked, fb); gtk_widget_show (GTK_WIDGET (dialog)); diff --git a/mail/mail-config.c b/mail/mail-config.c index 52f8e5306c..46ffe62e2a 100644 --- a/mail/mail-config.c +++ b/mail/mail-config.c @@ -35,6 +35,8 @@ #include <gtkhtml/gtkhtml.h> #include <glade/glade.h> +#include <bonobo/bonobo-object.h> + #include <gal/util/e-util.h> #include <e-util/e-html-utils.h> #include <e-util/e-url.h> @@ -43,6 +45,8 @@ #include "mail-ops.h" #include "mail-mt.h" +#include "Mail.h" + typedef struct { gboolean thread_list; gboolean view_source; @@ -64,6 +68,8 @@ typedef struct { static const char GCONFPATH[] = "/apps/Evolution/Mail"; static MailConfig *config = NULL; +#define MAIL_CONFIG_IID "OAFIID:GNOME_Evolution_MailConfig_Factory" + /* Prototypes */ static void config_read (void); @@ -1136,3 +1142,107 @@ mail_config_check_service (const char *url, CamelProviderType type, GList **auth return ret; } + +/* MailConfig Bonobo object */ +#define PARENT_TYPE BONOBO_X_OBJECT_TYPE +static BonoboObjectClass *parent_class = NULL; + +static void +impl_GNOME_Evolution_MailConfig_addAccount (PortableServer_Servant servant, + const GNOME_Evolution_MailConfig_Account *account, + CORBA_Environment *ev) +{ + GNOME_Evolution_MailConfig_Service source, transport; + GNOME_Evolution_MailConfig_Identity id; + MailConfigAccount *mail_account; + MailConfigService *mail_service; + MailConfigIdentity *mail_id; + + mail_account = g_new0 (MailConfigAccount, 1); + mail_account->name = g_strdup (account->name); + mail_account->default_account = account->default_account; + + /* Copy ID */ + id = account->id; + mail_id = g_new0 (MailConfigIdentity, 1); + mail_id->name = g_strdup (id.name); + mail_id->address = g_strdup (id.address); + mail_id->organization = g_strdup (id.organization); + mail_id->signature = g_strdup (id.signature); + + mail_account->id = mail_id; + + /* Copy source */ + source = account->source; + mail_service = g_new0 (MailConfigService, 1); + mail_service->url = g_strdup (source.url); + mail_service->keep_on_server = source.keep_on_server; + mail_service->auto_check = source.auto_check; + mail_service->auto_check_time = source.auto_check_time; + mail_service->save_passwd = source.save_passwd; + mail_service->enabled = source.enabled; + + mail_account->source = mail_service; + + /* Copy transport */ + transport = account->transport; + mail_service = g_new0 (MailConfigService, 1); + mail_service->url = g_strdup (transport.url); + mail_service->keep_on_server = transport.keep_on_server; + mail_service->auto_check = transport.auto_check; + mail_service->auto_check_time = transport.auto_check_time; + mail_service->save_passwd = transport.save_passwd; + mail_service->enabled = transport.enabled; + + mail_account->transport = mail_service; + + /* Add new account */ + mail_config_add_account (mail_account); +} + +static void +evolution_mail_config_class_init (EvolutionMailConfigClass *klass) +{ + POA_GNOME_Evolution_MailConfig__epv *epv = &klass->epv; + + parent_class = gtk_type_class (PARENT_TYPE); + epv->addAccount = impl_GNOME_Evolution_MailConfig_addAccount; +} + +static void +evolution_mail_config_init (EvolutionMailConfig *config) +{ +} + +BONOBO_X_TYPE_FUNC_FULL (EvolutionMailConfig, + GNOME_Evolution_MailConfig, + PARENT_TYPE, + evolution_mail_config); + +static BonoboObject * +evolution_mail_config_factory_fn (BonoboObject *factory, + void *closure) +{ + EvolutionMailConfig *config; + + g_warning ("Made"); + config = gtk_type_new (evolution_mail_config_get_type ()); + return BONOBO_OBJECT (config); +} + +void +evolution_mail_config_factory_init (void) +{ + BonoboObject *factory; + + g_warning ("Starting mail config"); + factory = bonobo_generic_factory_new (MAIL_CONFIG_IID, + evolution_mail_config_factory_fn, + NULL); + if (factory == NULL) { + g_warning ("Error starting MailConfig"); + } + + g_warning ("Registered"); + bonobo_running_context_auto_exit_unref (BONOBO_OBJECT (factory)); +} diff --git a/mail/mail-config.h b/mail/mail-config.h index 10c403389f..896b914249 100644 --- a/mail/mail-config.h +++ b/mail/mail-config.h @@ -26,6 +26,10 @@ #include <glib.h> #include <camel/camel.h> +#include <bonobo/bonobo-xobject.h> + +#include "Mail.h" + #ifdef __cplusplus extern "C" { #pragma } @@ -139,6 +143,20 @@ char *mail_config_folder_to_cachename (CamelFolder *folder, const char *prefix); gboolean mail_config_check_service (const char *url, CamelProviderType type, GList **authtypes); +/* For the bonobo object */ +typedef struct _EvolutionMailConfig EvolutionMailConfig; +typedef struct _EvolutionMailConfigClass EvolutionMailConfigClass; + +struct _EvolutionMailConfig { + BonoboXObject parent; +}; + +struct _EvolutionMailConfigClass { + BonoboXObjectClass parent_class; + + POA_GNOME_Evolution_MailConfig__epv epv; +}; + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/shell/ChangeLog b/shell/ChangeLog index 74cdd3f6ba..6d746217d8 100644 --- a/shell/ChangeLog +++ b/shell/ChangeLog @@ -1,3 +1,22 @@ +2001-05-08 Iain Holmes <iain@ximian.com> + + * importer/evolution-importer-client.c (evolution_importer_client_load_file): + Actually use the duplicated value. + + * e-local-storage.c (create_folder_directory): Assign + physical_path_return before trying to create the directory. + (create_folder): Return the physical_path even if the directory + creation failed. Free the physical path. + + * importer/evolution-importer-client.[ch]: Make EvolutionImporterClient + from a GtkObject instead of a BonoboObject. + + * importer/importer.c: Use gtk_object_unref instead of + bonobo_object_unref on the clients. + + * importer/intelligent.c: New prettier dialog, and multiple importers + done in the same window. + 2001-05-07 Dan Winship <danw@ximian.com> * e-shell-offline-handler.c (update_dialog_clist_hash_foreach): diff --git a/shell/e-local-storage.c b/shell/e-local-storage.c index d0d433abc0..233a3a4107 100644 --- a/shell/e-local-storage.c +++ b/shell/e-local-storage.c @@ -469,12 +469,11 @@ create_folder_directory (ELocalStorage *local_storage, /* Create the directory that holds the folder. */ + *physical_path_return = physical_path; if (mkdir (physical_path, 0700) == -1) { - g_free (physical_path); return errno_to_storage_result (); } - *physical_path_return = physical_path; return E_STORAGE_OK; } @@ -512,10 +511,12 @@ create_folder (ELocalStorage *local_storage, result = create_folder_directory (local_storage, path, type, description, &physical_path); if (result != E_STORAGE_OK) { + g_warning ("physical_path: %s", physical_path); if (callback != NULL) (* callback) (storage, result, data); if (listener != CORBA_OBJECT_NIL) - notify_bonobo_listener (listener, result, NULL); + notify_bonobo_listener (listener, result, physical_path); + g_free (physical_path); return; } diff --git a/shell/evolution-storage.c b/shell/evolution-storage.c index 68cbf0c7f3..20b4372cd5 100644 --- a/shell/evolution-storage.c +++ b/shell/evolution-storage.c @@ -293,6 +293,7 @@ impl_Storage_async_create_folder (PortableServer_Servant servant, bonobo_object = bonobo_object_from_servant (servant); storage = EVOLUTION_STORAGE (bonobo_object); + g_warning ("Path: %s", path); gtk_signal_emit (GTK_OBJECT (storage), signals[CREATE_FOLDER], listener, path, type, description, parent_physical_uri); } diff --git a/shell/importer/evolution-importer-client.c b/shell/importer/evolution-importer-client.c index 25a8f11b65..280e851c14 100644 --- a/shell/importer/evolution-importer-client.c +++ b/shell/importer/evolution-importer-client.c @@ -37,8 +37,8 @@ #include "GNOME_Evolution_Importer.h" -#define PARENT_TYPE BONOBO_OBJECT_CLIENT_TYPE -static BonoboObjectClass *parent_class = NULL; +#define PARENT_TYPE gtk_object_get_type () +static GtkObjectClass *parent_class = NULL; static void @@ -63,17 +63,6 @@ init (EvolutionImporterClient *client) { } -static void -evolution_importer_client_construct (EvolutionImporterClient *client, - CORBA_Object corba_object) -{ - g_return_if_fail (client != NULL); - g_return_if_fail (EVOLUTION_IS_IMPORTER_CLIENT (client)); - g_return_if_fail (corba_object != CORBA_OBJECT_NIL); - - bonobo_object_client_construct (BONOBO_OBJECT_CLIENT (client), corba_object); -} - /** * evolution_importer_client_new: * @objref: The CORBA_Object to make a client for. @@ -90,7 +79,7 @@ evolution_importer_client_new (const CORBA_Object objref) g_return_val_if_fail (objref != CORBA_OBJECT_NIL, NULL); client = gtk_type_new (evolution_importer_client_get_type ()); - evolution_importer_client_construct (client, objref); + client->objref = objref; return client; } @@ -151,7 +140,7 @@ evolution_importer_client_support_format (EvolutionImporterClient *client, g_return_val_if_fail (filename != NULL, FALSE); CORBA_exception_init (&ev); - corba_importer = bonobo_object_corba_objref (BONOBO_OBJECT (client)); + corba_importer = client->objref; result = GNOME_Evolution_Importer_supportFormat (corba_importer, filename, &ev); CORBA_exception_free (&ev); @@ -183,11 +172,17 @@ evolution_importer_client_load_file (EvolutionImporterClient *client, g_return_val_if_fail (filename != NULL, FALSE); CORBA_exception_init (&ev); - corba_importer = bonobo_object_corba_objref (BONOBO_OBJECT (client)); + corba_importer = client->objref; result = GNOME_Evolution_Importer_loadFile (corba_importer, filename, folderpath ? folderpath : "", &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + g_warning ("Oh there *WAS* an exception.\nIt was %s", + CORBA_exception_id (&ev)); + CORBA_exception_free (&ev); + return FALSE; + } CORBA_exception_free (&ev); return result; @@ -216,8 +211,9 @@ evolution_importer_client_process_item (EvolutionImporterClient *client, CORBA_exception_init (&ev); - corba_importer = bonobo_object_corba_objref (BONOBO_OBJECT (client)); + corba_importer = client->objref; corba_listener = bonobo_object_corba_objref (BONOBO_OBJECT (listener)); + g_warning ("%s", __FUNCTION__); GNOME_Evolution_Importer_processItem (corba_importer, corba_listener, &ev); CORBA_exception_free (&ev); @@ -242,7 +238,7 @@ evolution_importer_client_get_error (EvolutionImporterClient *client) g_return_val_if_fail (client != NULL, NULL); g_return_val_if_fail (EVOLUTION_IS_IMPORTER_CLIENT (client), NULL); - corba_importer = bonobo_object_corba_objref (BONOBO_OBJECT (client)); + corba_importer = client->objref; CORBA_exception_init (&ev); str = GNOME_Evolution_Importer_getError (corba_importer, &ev); diff --git a/shell/importer/evolution-importer-client.h b/shell/importer/evolution-importer-client.h index 71b20afc6a..3b38d7bc3f 100644 --- a/shell/importer/evolution-importer-client.h +++ b/shell/importer/evolution-importer-client.h @@ -45,11 +45,13 @@ typedef struct _EvolutionImporterClient EvolutionImporterClient; typedef struct _EvolutionImporterClientClass EvolutionImporterClientClass; struct _EvolutionImporterClient { - BonoboObjectClient parent; + GtkObject parent_type; + + GNOME_Evolution_Importer objref; }; struct _EvolutionImporterClientClass { - BonoboObjectClientClass parent_class; + GtkObjectClass parent_class; }; GtkType evolution_importer_client_get_type (void); diff --git a/shell/importer/evolution-importer-listener.c b/shell/importer/evolution-importer-listener.c index 905ebd72fe..8a547e6f3e 100644 --- a/shell/importer/evolution-importer-listener.c +++ b/shell/importer/evolution-importer-listener.c @@ -109,6 +109,7 @@ impl_GNOME_Evolution_ImporterListener_notifyResult (PortableServer_Servant serva listener = evolution_importer_listener_from_servant (servant); priv = listener->priv; + g_print ("Notified\n"); out_result = corba_result_to_evolution (result); if (priv->callback) { (priv->callback) (listener, out_result, more_items, diff --git a/shell/importer/importer.c b/shell/importer/importer.c index e7163cf329..15d18db10b 100644 --- a/shell/importer/importer.c +++ b/shell/importer/importer.c @@ -217,7 +217,7 @@ import_cb (EvolutionImporterListener *listener, if (!icd->destroyed) gtk_object_destroy (GTK_OBJECT (icd->dialog)); bonobo_object_unref (BONOBO_OBJECT (icd->listener)); - bonobo_object_unref (BONOBO_OBJECT (icd->client)); + gtk_object_unref (GTK_OBJECT (icd->client)); g_free (icd); OUT; @@ -383,7 +383,7 @@ start_import (const char *filename, g_free (real_iid); /* NULL for folderpath means use Inbox */ - if (evolution_importer_client_load_file (icd->client, filename, NULL) == FALSE) { + if (evolution_importer_client_load_file (icd->client, filename, "/Inbox") == FALSE) { label = g_strdup_printf (_("Error loading %s"), filename); gtk_label_set_text (GTK_LABEL (icd->contents), label); g_free (label); diff --git a/shell/importer/intelligent.c b/shell/importer/intelligent.c index 166be226ad..d9589df676 100644 --- a/shell/importer/intelligent.c +++ b/shell/importer/intelligent.c @@ -36,6 +36,10 @@ #include <gtk/gtktogglebutton.h> #include <gtk/gtkwidget.h> #include <gtk/gtkwindow.h> +#include <gtk/gtkframe.h> +#include <gtk/gtkclist.h> +#include <gtk/gtknotebook.h> +#include <gtk/gtkscrolledwindow.h> #include <libgnome/gnome-defs.h> #include <libgnome/gnome-config.h> @@ -46,6 +50,10 @@ #include <liboaf/liboaf.h> +#include <bonobo/bonobo-object.h> +#include <bonobo/bonobo-widget.h> + +#include "intelligent.h" #include "GNOME_Evolution_Importer.h" /* Prototypes */ @@ -54,142 +62,75 @@ void intelligent_importer_init (void); /* End prototypes */ -static void -start_importer (const char *iid) -{ - CORBA_Object importer; - CORBA_Environment ev; - CORBA_char *name; - CORBA_char *message; - CORBA_boolean can_run; +typedef struct { + CORBA_Object object; + Bonobo_Control control; + GtkWidget *widget; - GtkWidget *dialog, *label, *ask; - gboolean dontaskagain; - char *prefix; + char *name; + char *blurb; + char *iid; +} IntelligentImporterData; - if (iid == NULL || *iid == '\0') - return; +typedef struct { + GtkWidget *dialog; + GtkWidget *placeholder; + GtkWidget *clist; + BonoboWidget *current; - /* Check if we want to show this one again */ - prefix = g_strdup_printf ("=%s/evolution/config/Shell=/intelligent-importers/", gnome_util_user_home ()); - gnome_config_push_prefix (prefix); - g_free (prefix); - - dontaskagain = gnome_config_get_bool (iid); - gnome_config_pop_prefix (); + GList *importers; - if (dontaskagain) - return; + int running; +} IntelligentImporterDialog; - CORBA_exception_init (&ev); - importer = oaf_activate_from_id ((char *) iid, 0, NULL, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - CORBA_exception_free (&ev); - g_warning ("Could not start %s", iid); - return; - } - - CORBA_exception_free (&ev); - if (importer == CORBA_OBJECT_NIL) { - g_warning ("Could not activate_component %s", iid); - return; - } - - CORBA_exception_init (&ev); - can_run = GNOME_Evolution_IntelligentImporter_canImport (importer, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("Could not get canImport(%s): %s", iid, CORBA_exception_id (&ev)); - CORBA_Object_release (importer, &ev); - CORBA_exception_free (&ev); - return; - } - CORBA_exception_free (&ev); - - if (can_run == FALSE) { - return; - } - - name = GNOME_Evolution_IntelligentImporter__get_importername (importer, - &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("Could not get name(%s): %s", iid, CORBA_exception_id (&ev)); - CORBA_Object_release (importer, &ev); - CORBA_exception_free (&ev); - return; - } - message = GNOME_Evolution_IntelligentImporter__get_message (importer, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("Could not get message(%s): %s", iid, CORBA_exception_id (&ev)); - CORBA_Object_release (importer, &ev); - CORBA_exception_free (&ev); - return; - } - - CORBA_exception_free (&ev); - - dialog = gnome_dialog_new ("Import files", - GNOME_STOCK_BUTTON_YES, GNOME_STOCK_BUTTON_NO, - NULL); - gtk_window_set_title (GTK_WINDOW (dialog), name); - CORBA_free (name); - - label = gtk_label_new (message); - CORBA_free (message); - - gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), label, - FALSE, FALSE, 0); - gtk_widget_show (label); +typedef struct { + CORBA_Object importer; + char *iid; +} SelectedImporterData; - ask = gtk_check_button_new_with_label (_("Don't ask me again")); - gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), ask, - FALSE, FALSE, 0); - gtk_widget_show (ask); +static void +free_importer_dialog (IntelligentImporterDialog *d) +{ + GList *l; - switch (gnome_dialog_run (GNOME_DIALOG (dialog))) { - case 0: - /* Yes */ - dontaskagain = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ask)); - prefix = g_strdup_printf ("=%s/evolution/config/Shell=/intelligent-importers/", gnome_util_user_home ()); - gnome_config_push_prefix (prefix); - g_free (prefix); + for (l = d->importers; l; l = l->next) { + CORBA_Environment ev; + IntelligentImporterData *data; - gnome_config_set_bool (iid, dontaskagain); - gnome_config_sync (); - gnome_config_drop_all (); + data = l->data; - gnome_config_pop_prefix (); + CORBA_exception_init (&ev); + if (data->object != CORBA_OBJECT_NIL) + bonobo_object_release_unref (data->object, &ev); - gtk_object_destroy (GTK_OBJECT (dialog)); - while (gtk_events_pending ()) - gtk_main_iteration (); + g_free (data->iid); + g_free (data->name); + g_free (data->blurb); + g_free (data); + } - GNOME_Evolution_IntelligentImporter_importData (importer, &ev); - break; - case 1: - case -1: - default: - /* No */ - dontaskagain = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ask)); - prefix = g_strdup_printf ("=%s/evolution/config/Shell=/intelligent-importers/", gnome_util_user_home ()); - gnome_config_push_prefix (prefix); - g_free (prefix); - - gnome_config_set_bool (iid, dontaskagain); - gnome_config_sync (); - gnome_config_drop_all (); - - gnome_config_pop_prefix (); - - gtk_object_destroy (GTK_OBJECT (dialog)); + g_list_free (d->importers); + gtk_widget_destroy (d->dialog); + g_free (d); +} - break; - } +static void +start_importers (GList *selected) +{ + CORBA_Environment ev; CORBA_exception_init (&ev); - CORBA_Object_release (importer, &ev); + for (; selected; selected = selected->next) { + SelectedImporterData *selection = selected->data; + + GNOME_Evolution_IntelligentImporter_importData (selection->importer, &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + g_warning ("Error importing %s\n%s", selection->iid, + CORBA_exception_id (&ev)); + } + } CORBA_exception_free (&ev); } - static GList * get_intelligent_importers (void) @@ -210,26 +151,275 @@ get_intelligent_importers (void) iids_ret = g_list_prepend (iids_ret, g_strdup (info->iid)); } - CORBA_free (info_list); - return iids_ret; } +static void +select_row_cb (GtkCList *clist, + int row, + int column, + GdkEvent *ev, + IntelligentImporterDialog *d) +{ + gtk_notebook_set_page (GTK_NOTEBOOK (d->placeholder), row); +} + +static void +unselect_row_cb (GtkCList *clist, + int row, + int column, + GdkEvent *ev, + IntelligentImporterDialog *d) +{ + gtk_notebook_set_page (GTK_NOTEBOOK (d->placeholder), d->running); +} + +IntelligentImporterDialog * +create_gui (GList *importers) +{ + GtkWidget *dialog, *clist, *placeholder, *sw; + IntelligentImporterDialog *d; + GList *l; + int running = 0; + + d = g_new (IntelligentImporterDialog, 1); + d->dialog = dialog = gnome_dialog_new (_("Importers"), "Import", + GNOME_STOCK_BUTTON_CANCEL, + NULL); + gnome_dialog_close_hides (GNOME_DIALOG (dialog), TRUE); + d->importers = NULL; + d->current = NULL; + + d->clist = clist = gtk_clist_new (1); + gtk_clist_set_selection_mode (GTK_CLIST (d->clist), GTK_SELECTION_MULTIPLE); + + sw = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_set_usize (sw, 300, 150); + gtk_container_add (GTK_CONTAINER (sw), clist); + gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), sw, + TRUE, TRUE, 0); + + d->placeholder = gtk_notebook_new (); + gtk_notebook_set_show_tabs (GTK_NOTEBOOK (d->placeholder), FALSE); + gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), d->placeholder, + FALSE, FALSE, 0); + + for (l = importers; l; l = l->next) { + IntelligentImporterData *data; + CORBA_Environment ev; + gboolean dontaskagain, can_run; + char *text[1], *prefix; + + /* Check if we want to show this one again */ + prefix = g_strdup_printf ("=%s/evolution/config/Shell=/intelligent-importers/", gnome_util_user_home ()); + gnome_config_push_prefix (prefix); + g_free (prefix); + + dontaskagain = gnome_config_get_bool (l->data); + gnome_config_pop_prefix (); + + if (dontaskagain) + continue; + + data = g_new0 (IntelligentImporterData, 1); + data->iid = g_strdup (l->data); + + g_warning ("data->iid %s", data->iid); + CORBA_exception_init (&ev); + data->object = oaf_activate_from_id ((char *) data->iid, 0, + NULL, &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + g_warning ("Could not start %s: %s", data->iid, + CORBA_exception_id (&ev)); + CORBA_exception_free (&ev); + + /* Clean up the IntelligentImporterData */ + g_free (data->iid); + g_free (data); + continue; + } + + CORBA_exception_free (&ev); + if (data->object == CORBA_OBJECT_NIL) { + g_warning ("Could not activate_component %s", data->iid); + g_free (data->iid); + g_free (data); + continue; + } + + CORBA_exception_init (&ev); + can_run = GNOME_Evolution_IntelligentImporter_canImport (data->object, + &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + g_warning ("Could not get canImport(%s): %s", + data->iid, CORBA_exception_id (&ev)); + bonobo_object_release_unref (data->object, &ev); + CORBA_exception_free (&ev); + g_free (data->iid); + g_free (data); + continue; + } + CORBA_exception_free (&ev); + + if (can_run == FALSE) { + CORBA_exception_init (&ev); + bonobo_object_release_unref (data->object, &ev); + CORBA_exception_free (&ev); + g_free (data->iid); + g_free (data); + continue; + } + + running++; + + data->name = g_strdup (GNOME_Evolution_IntelligentImporter__get_importername (data->object, &ev)); + if (ev._major != CORBA_NO_EXCEPTION) { + g_warning ("Could not get name(%s): %s", + data->iid, CORBA_exception_id (&ev)); + bonobo_object_release_unref (data->object, &ev); + CORBA_exception_free (&ev); + g_free (data->iid); + g_free (data); + continue; + } + + data->blurb = g_strdup (GNOME_Evolution_IntelligentImporter__get_message (data->object, &ev)); + if (ev._major != CORBA_NO_EXCEPTION) { + g_warning ("Could not get message(%s): %s", + data->iid, CORBA_exception_id (&ev)); + bonobo_object_release_unref (data->object, &ev); + CORBA_exception_free (&ev); + g_free (data->iid); + g_free (data->name); + g_free (data); + continue; + } + + data->control = Bonobo_Unknown_queryInterface (data->object, + "IDL:Bonobo/Control:1.0", &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + g_warning ("Could not QI for Bonobo/Control:1.0 %s:%s", + data->iid, CORBA_exception_id (&ev)); + bonobo_object_release_unref (data->object, &ev); + CORBA_exception_free (&ev); + g_free (data->iid); + g_free (data->name); + g_free (data->blurb); + continue; + } + if (data->control != CORBA_OBJECT_NIL) { + data->widget = bonobo_widget_new_control_from_objref (data->control, CORBA_OBJECT_NIL); + /* Ref this widget so even if we remove it from the + containers it will always have an extra ref. */ + gtk_widget_show (data->widget); + gtk_widget_ref (data->widget); + } else { + data->widget = gtk_label_new (""); + } + + CORBA_exception_free (&ev); + + d->importers = g_list_prepend (d->importers, data); + gtk_notebook_prepend_page (GTK_NOTEBOOK (d->placeholder), + data->widget, NULL); + text[0] = data->name; + gtk_clist_prepend (GTK_CLIST (clist), text); + } + + d->running = running; + gtk_notebook_append_page (GTK_NOTEBOOK (d->placeholder), + gtk_label_new (""), NULL); + /* Set the start to the blank page */ + gtk_notebook_set_page (GTK_NOTEBOOK (d->placeholder), running); + + gtk_signal_connect (GTK_OBJECT (clist), "select-row", + GTK_SIGNAL_FUNC (select_row_cb), d); + gtk_signal_connect (GTK_OBJECT (clist), "unselect-row", + GTK_SIGNAL_FUNC (unselect_row_cb), d); + + gtk_widget_show_all (GNOME_DIALOG (dialog)->vbox); + return d; +} + void intelligent_importer_init (void) { - GList *importers, *l; + GList *importers, *l, *selected = NULL; + IntelligentImporterDialog *d; importers = get_intelligent_importers (); if (importers == NULL) return; /* No intelligent importers. Easy :) */ - /* Loop through each importer, running it. */ - for (l = importers; l; l = l->next) { - start_importer (l->data); - g_free (l->data); + d = create_gui (importers); + if (d->running == 0) { + free_importer_dialog (d); + return; /* No runnable intelligent importers. */ + } + + switch (gnome_dialog_run_and_close (GNOME_DIALOG (d->dialog))) { + case 0: /* Okay button */ + /* Make a list of the importers */ + + /* FIXME: Sort this list and don't do it a slow way */ + for (l = GTK_CLIST (d->clist)->selection; l; l = l->next) { + IntelligentImporterData *data; + SelectedImporterData *new_data; + CORBA_Environment ev; + char *iid; + + data = g_list_nth_data (d->importers, l->data); + iid = g_strdup (data->iid); + + new_data = g_new (SelectedImporterData, 1); + new_data->iid = iid; + + /* Reference the remote object, and duplicate the + local one. */ + CORBA_exception_init (&ev); + new_data->importer = bonobo_object_dup_ref (data->object, &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + g_warning ("Error duplicating %s\n%s", iid, + CORBA_exception_id (&ev)); + g_free (iid); + CORBA_exception_free (&ev); + g_free (new_data); + continue; + } + CORBA_exception_free (&ev); + + selected = g_list_prepend (selected, new_data); + } + + /* Now destroy all the importers, as we've kept references to + the ones we need */ + free_importer_dialog (d); + + if (selected != NULL) { + /* Restart the selected ones */ + start_importers (selected); + + /* Free the selected list */ + for (l = selected; l; l = l->next) { + CORBA_Environment ev; + SelectedImporterData *selection = l->data; + + CORBA_exception_init (&ev); + bonobo_object_release_unref (selection->importer, &ev); + CORBA_exception_free (&ev); + + g_free (selection->iid); + g_free (selection); + } + g_list_free (selected); + } + + break; + + default: + free_importer_dialog (d); + break; } g_list_free (importers); } - |