/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ /* importer.c * * Copyright (C) 2000 Ximian, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License as published by the Free Software Foundation. * * 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 */ #ifdef HAVE_CONFIG_H #include #endif #undef GTK_DISABLE_DEPRECATED #undef G_DISABLE_DEPRECATED #include #include #include #include #include #include #include #include #include #include #include #include #include #include "e-shell.h" #include "e-shell-view.h" #include "e-shell-constants.h" #include "e-shell-folder-selection-dialog.h" #include "importer/evolution-importer-client.h" #include #include #include #include #include "e-util/e-gtk-utils.h" #include "e-shell-importer.h" #include "importer/GNOME_Evolution_Importer.h" typedef struct _ImportDialogFilePage { GtkWidget *vbox; GtkWidget *filename; GtkWidget *filetype; GtkWidget *menu; gboolean need_filename; } ImportDialogFilePage; typedef struct _ImportDialogTypePage { GtkWidget *vbox; GtkWidget *intelligent; GtkWidget *file; } ImportDialogTypePage; typedef struct _ImportDialogImporterPage { GtkWidget *vbox; GList *importers; gboolean prepared; int running; } ImportDialogImporterPage; typedef struct _ImportData { EShell *shell; EShellView *view; GladeXML *wizard; GtkWidget *dialog; GtkWidget *druid; ImportDialogFilePage *filepage; ImportDialogTypePage *typepage; ImportDialogImporterPage *importerpage; GtkWidget *filedialog; GtkWidget *typedialog; GtkWidget *intelligent; GnomeDruidPageEdge *start; GnomeDruidPageEdge *finish; GtkWidget *vbox; char *choosen_iid; } ImportData; typedef struct _IntelligentImporterData { CORBA_Object object; Bonobo_Control control; GtkWidget *widget; char *name; char *blurb; char *iid; } IntelligentImporterData; typedef struct _SelectedImporterData{ CORBA_Object importer; char *iid; } SelectedImporterData; /* #define IMPORTER_DEBUG */ #ifdef IMPORTER_DEBUG #define IN g_print ("=====> %s (%d)\n", G_GNUC_FUNCTION, __LINE__) #define OUT g_print ("<==== %s (%d)\n", G_GNUC_FUNCTION, __LINE__) #else #define IN #define OUT #endif /* Some HTML helper functions copied from mail/mail-config-druid.c */ static struct { char *name; char *text; } info[] = { { "type_html", N_("Choose the type of importer to run:") }, { "file_html", N_("Choose the file that you want to import into Evolution, " "and select what type of file it is from the list.\n\n" "You can select \"Automatic\" if you do not know, and " "Evolution will attempt to work it out.") }, { "intelligent_html", N_("Please select the information that you would like to import:") } }; static int num_info = (sizeof (info) / sizeof (info[0])); static void html_size_req (GtkWidget *widget, GtkRequisition *requisition) { requisition->height = GTK_LAYOUT (widget)->height; } static GtkWidget * create_html (const char *name) { GtkWidget *scrolled, *html; GtkHTMLStream *stream; GtkStyle *style; int i; html = gtk_html_new (); GTK_LAYOUT (html)->height = 0; g_signal_connect (html, "size_request", G_CALLBACK (html_size_req), NULL); gtk_html_set_editable (GTK_HTML (html), FALSE); style = gtk_rc_get_style (html); if (!style) style = gtk_widget_get_style (html); if (style) { gtk_html_set_default_background_color (GTK_HTML (html), &style->bg[0]); } gtk_widget_show (html); scrolled = gtk_scrolled_window_new (NULL, NULL); gtk_widget_show (scrolled); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_NEVER, GTK_POLICY_NEVER); gtk_container_add (GTK_CONTAINER (scrolled), html); for (i = 0; i < num_info; i++) { if (!strcmp (name, info[i].name)) break; } g_return_val_if_fail (i != num_info, scrolled); stream = gtk_html_begin_content (GTK_HTML (html), "text/html; charset=utf-8"); gtk_html_write (GTK_HTML (html), stream, "

", 9); gtk_html_write (GTK_HTML (html), stream, _(info[i].text), strlen (_(info[i].text))); gtk_html_write (GTK_HTML (html), stream, "

", 11); gtk_html_end (GTK_HTML (html), stream, GTK_HTML_STREAM_OK); return scrolled; } /* Importing functions */ /* Data to be passed around */ typedef struct _ImporterComponentData { EvolutionImporterClient *client; EvolutionImporterListener *listener; char *filename; GtkDialog *dialog; GtkWidget *contents; int item; gboolean stop; } ImporterComponentData; static gboolean importer_timeout_fn (gpointer data); static void import_cb (EvolutionImporterListener *listener, EvolutionImporterResult result, gboolean more_items, void *data) { ImporterComponentData *icd = (ImporterComponentData *) data; char *label; IN; if (icd->stop != TRUE) { if (result == EVOLUTION_IMPORTER_NOT_READY) { gtk_timeout_add (500, importer_timeout_fn, data); OUT; return; } if (result == EVOLUTION_IMPORTER_BUSY) { gtk_timeout_add (500, importer_timeout_fn, data); OUT; return; } if (more_items) { label = g_strdup_printf (_("Importing %s\nImporting item %d."), icd->filename, ++(icd->item)); gtk_label_set_text (GTK_LABEL (icd->contents), label); g_free (label); while (gtk_events_pending ()) gtk_main_iteration (); g_idle_add_full (G_PRIORITY_LOW, importer_timeout_fn, data, NULL); OUT; return; } } g_free (icd->filename); if (icd->dialog != NULL) gtk_widget_destroy ((GtkWidget *)icd->dialog); bonobo_object_unref (BONOBO_OBJECT (icd->listener)); g_object_unref (icd->client); g_free (icd); OUT; } static gboolean importer_timeout_fn (gpointer data) { ImporterComponentData *icd = (ImporterComponentData *) data; char *label; IN; label = g_strdup_printf (_("Importing %s\nImporting item %d."), icd->filename, icd->item); gtk_label_set_text (GTK_LABEL (icd->contents), label); g_free (label); while (gtk_events_pending ()) gtk_main_iteration (); evolution_importer_client_process_item (icd->client, icd->listener); OUT; return FALSE; } static void dialog_response_cb (GtkDialog *dialog, int button_number, ImporterComponentData *icd) { if (button_number != GTK_RESPONSE_CANCEL) return; /* Interesting... */ icd->stop = TRUE; } static void dialog_destroy_notify (void *data, GObject *where_the_dialog_was) { ImporterComponentData *icd = (ImporterComponentData *) data; icd->dialog = NULL; icd->stop = TRUE; } struct _IIDInfo { char *iid; char *name; }; static void free_iid_list (GList *list) { for (; list; list = list->next) { struct _IIDInfo *iid = list->data; g_free (iid->iid); g_free (iid->name); g_free (iid); } } static const char * get_name_from_component_info (const Bonobo_ServerInfo *info) { Bonobo_ActivationProperty *property; const char *name; property = bonobo_server_info_prop_find ((Bonobo_ServerInfo *) info, "evolution:menu_name"); if (property == NULL || property->v._d != Bonobo_ACTIVATION_P_STRING) return NULL; name = property->v._u.value_string; return name; } static char * choose_importer_from_list (GList *importer_list) { GtkWidget *dialog, *clist; GList *p; int ans; char *iid; dialog = gtk_dialog_new_with_buttons(_("Select importer"), NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); clist = gtk_clist_new (1); for (p = importer_list; p; p = p->next) { struct _IIDInfo *iid; char *text[1]; int row; iid = p->data; text[0] = iid->name; row = gtk_clist_append (GTK_CLIST (clist), text); gtk_clist_set_row_data (GTK_CLIST (clist), row, iid->iid); } gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), clist, TRUE, TRUE, 0); gtk_clist_set_selection_mode (GTK_CLIST (clist), GTK_SELECTION_BROWSE); gtk_widget_show (clist); ans = gtk_dialog_run((GtkDialog *)dialog); switch (ans) { case GTK_RESPONSE_OK: ans = GPOINTER_TO_INT (GTK_CLIST (clist)->selection->data); iid = gtk_clist_get_row_data (GTK_CLIST (clist), ans); break; case 1: default: iid = NULL; break; } gtk_widget_destroy (dialog); return g_strdup (iid); } static char * get_iid_for_filetype (const char *filename) { Bonobo_ServerInfoList *info_list; CORBA_Environment ev; GList *can_handle = NULL; char *ret_iid; int i, len = 0; CORBA_exception_init (&ev); info_list = bonobo_activation_query ("repo_ids.has ('IDL:GNOME/Evolution/Importer:1.0')", NULL, &ev); for (i = 0; i < info_list->_length; i++) { CORBA_Environment ev2; CORBA_Object importer; const Bonobo_ServerInfo *info; info = info_list->_buffer + i; CORBA_exception_init (&ev2); importer = bonobo_activation_activate_from_id ((char *) info->iid, 0, NULL, &ev2); if (ev2._major != CORBA_NO_EXCEPTION) { g_warning ("Error activating %s", info->iid); CORBA_exception_free (&ev2); continue; } if (GNOME_Evolution_Importer_supportFormat (importer, filename, &ev2)) { struct _IIDInfo *iid; iid = g_new (struct _IIDInfo, 1); iid->iid = g_strdup (info->iid); iid->name = g_strdup (get_name_from_component_info (info)); can_handle = g_list_prepend (can_handle, iid); len++; } bonobo_object_release_unref (importer, &ev2); CORBA_exception_free (&ev2); } CORBA_free (info_list); if (len == 1) { struct _IIDInfo *iid; iid = can_handle->data; ret_iid = g_strdup (iid->iid); free_iid_list (can_handle); g_list_free (can_handle); return ret_iid; } else if (len > 1) { /* Display all the IIDs */ ret_iid = choose_importer_from_list (can_handle); free_iid_list (can_handle); g_list_free (can_handle); return ret_iid; } else { return NULL; } } static void error_response_cb(GtkWidget *w, int button, void *data) { gtk_widget_destroy(w); } static void show_error (const char *message, const char *title) { GtkWidget *box; box = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", message); gtk_window_set_title (GTK_WINDOW (box), title); g_signal_connect(box, "response", G_CALLBACK(error_response_cb), box); gtk_widget_show (box); } static void start_import (const char *folderpath, const char *filename, const char *iid) { ImporterComponentData *icd; char *label; char *real_iid; struct stat buf; if (stat (filename, &buf) == -1) { char *message; message = g_strdup_printf (_("File %s does not exist"), filename); show_error (message, _("Evolution Error")); g_free (message); return; } if (iid == NULL || strcmp (iid, "Automatic") == 0) { /* Work out the component to use */ real_iid = get_iid_for_filetype (filename); } else { real_iid = g_strdup (iid); } if (real_iid == NULL) { char *message; message = g_strdup_printf (_("There is no importer that is able to handle\n%s"), filename); show_error (message, _("Evolution Error")); g_free (message); return; } icd = g_new (ImporterComponentData, 1); icd->stop = FALSE; icd->dialog = GTK_DIALOG (gtk_dialog_new_with_buttons(_("Importing"), NULL, 0, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL)); g_signal_connect (icd->dialog, "response", G_CALLBACK (dialog_response_cb), icd); g_object_weak_ref (G_OBJECT(icd->dialog), dialog_destroy_notify, icd); label = g_strdup_printf (_("Importing %s.\nStarting %s"), filename, real_iid); icd->contents = gtk_label_new (label); g_free (label); gtk_box_pack_start (GTK_BOX (icd->dialog->vbox), icd->contents, TRUE, TRUE, 0); gtk_widget_show_all (GTK_WIDGET (icd->dialog)); while (gtk_events_pending ()) gtk_main_iteration (); icd->client = evolution_importer_client_new_from_id (real_iid); if (icd->client == NULL) { label = g_strdup_printf (_("Error starting %s"), real_iid); g_free (real_iid); gtk_label_set_text (GTK_LABEL (icd->contents), label); g_free (label); while (gtk_events_pending ()) gtk_main_iteration (); g_object_unref (icd->dialog); g_free (icd); return; } g_free (real_iid); /* NULL for folderpath means use Inbox */ if (*folderpath == '/') { folderpath = strchr (folderpath + 1, '/'); } if (evolution_importer_client_load_file (icd->client, filename, folderpath) == FALSE) { label = g_strdup_printf (_("Error loading %s"), filename); show_error (label, _("Evolution Error")); gtk_label_set_text (GTK_LABEL (icd->contents), label); g_free (label); while (gtk_events_pending ()) gtk_main_iteration (); g_object_unref (icd->client); g_object_unref (icd->dialog); g_free (icd); return; } icd->filename = g_strdup (filename); icd->item = 1; label = g_strdup_printf (_("Importing %s\nImporting item 1."), filename); gtk_label_set_text (GTK_LABEL (icd->contents), label); g_free (label); while (gtk_events_pending ()) gtk_main_iteration (); icd->listener = evolution_importer_listener_new (import_cb, icd); evolution_importer_client_process_item (icd->client, icd->listener); } static void filename_changed (GtkEntry *entry, ImportData *data) { ImportDialogFilePage *page; const char *filename; page = data->filepage; filename = gtk_entry_get_text (entry); if (filename != NULL && *filename != '\0') page->need_filename = FALSE; else page->need_filename = TRUE; gnome_druid_set_buttons_sensitive (GNOME_DRUID (data->druid), TRUE, !page->need_filename, TRUE, FALSE); } static void item_selected (GtkWidget *item, ImportData *data) { char *iid; g_free (data->choosen_iid); iid = g_object_get_data (G_OBJECT (item), "bonoboiid"); if (iid == NULL) data->choosen_iid = g_strdup ("Automatic"); else data->choosen_iid = g_strdup (iid); } static GtkWidget * create_plugin_menu (ImportData *data) { Bonobo_ServerInfoList *info_list; CORBA_Environment ev; int i; GtkWidget *menu; GtkWidget *item; menu = gtk_menu_new (); item = gtk_menu_item_new_with_label (_("Automatic")); g_object_set_data_full ((GObject *)item, "bonoboiid", g_strdup ("Automatic"), g_free); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); CORBA_exception_init (&ev); info_list = bonobo_activation_query ("repo_ids.has ('IDL:GNOME/Evolution/Importer:1.0')", NULL, &ev); for (i = 0; i < info_list->_length; i++) { const Bonobo_ServerInfo *info; char *name = NULL; info = info_list->_buffer + i; name = g_strdup (get_name_from_component_info (info)); if (name == NULL) { name = g_strdup (info->iid); } item = gtk_menu_item_new_with_label (name); g_free (name); gtk_widget_show (item); g_signal_connect (item, "activate", G_CALLBACK (item_selected), data); g_object_set_data_full ((GObject *)item, "bonoboiid", g_strdup (info->iid), g_free); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); } CORBA_free (info_list); return menu; } static ImportDialogFilePage * importer_file_page_new (ImportData *data) { ImportDialogFilePage *page; GtkWidget *table, *label; int row = 0; page = g_new0 (ImportDialogFilePage, 1); page->vbox = gtk_vbox_new (FALSE, 5); page->need_filename = TRUE; table = gtk_table_new (2, 2, FALSE); gtk_table_set_row_spacings (GTK_TABLE (table), 2); gtk_table_set_col_spacings (GTK_TABLE (table), 10); gtk_container_set_border_width (GTK_CONTAINER (table), 8); gtk_box_pack_start (GTK_BOX (page->vbox), table, TRUE, TRUE, 0); label = gtk_label_new (_("Filename:")); gtk_table_attach (GTK_TABLE (table), label, 0, 1, row, row + 1, GTK_FILL, 0, 0, 0); gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5); page->filename = gnome_file_entry_new ("Evolution_Importer_FileName", _("Select a file")); g_signal_connect (gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (page->filename)), "changed", G_CALLBACK (filename_changed), data); gtk_table_attach (GTK_TABLE (table), page->filename, 1, 2, row, row + 1, GTK_EXPAND | GTK_FILL, 0, 0, 0); row++; label = gtk_label_new (_("File type:")); gtk_table_attach (GTK_TABLE (table), label, 0, 1, row, row + 1, GTK_FILL, 0, 0, 0); gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5); page->filetype = gtk_option_menu_new (); page->menu = create_plugin_menu (data); gtk_option_menu_set_menu (GTK_OPTION_MENU (page->filetype), page->menu); gtk_table_attach (GTK_TABLE (table), page->filetype, 1, 2, row, row + 1, GTK_EXPAND | GTK_FILL, 0, 0, 0); gtk_widget_show_all (table); return page; } static ImportDialogTypePage * importer_type_page_new (ImportData *data) { ImportDialogTypePage *page; page = g_new0 (ImportDialogTypePage, 1); page->vbox = gtk_vbox_new (FALSE, 5); page->intelligent = gtk_radio_button_new_with_label (NULL, _("Import data and settings from older programs")); gtk_box_pack_start (GTK_BOX (page->vbox), page->intelligent, FALSE, FALSE, 0); page->file = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (page->intelligent), _("Import a single file")); gtk_box_pack_start (GTK_BOX (page->vbox), page->file, FALSE, FALSE, 0); gtk_widget_show_all (page->vbox); return page; } static ImportDialogImporterPage * importer_importer_page_new (ImportData *data) { ImportDialogImporterPage *page; GtkWidget *sep; page = g_new0 (ImportDialogImporterPage, 1); page->vbox = gtk_vbox_new (FALSE, 5); gtk_container_set_border_width (GTK_CONTAINER (page->vbox), 4); sep = gtk_hseparator_new (); gtk_box_pack_start (GTK_BOX (page->vbox), sep, FALSE, FALSE, 0); page->prepared = FALSE; gtk_widget_show_all (page->vbox); return page; } static GList * get_intelligent_importers (void) { Bonobo_ServerInfoList *info_list; GList *iids_ret = NULL; CORBA_Environment ev; int i; CORBA_exception_init (&ev); info_list = bonobo_activation_query ("repo_ids.has ('IDL:GNOME/Evolution/IntelligentImporter:1.0')", NULL, &ev); CORBA_exception_free (&ev); for (i = 0; i < info_list->_length; i++) { const Bonobo_ServerInfo *info; info = info_list->_buffer + i; iids_ret = g_list_prepend (iids_ret, g_strdup (info->iid)); } return iids_ret; } static gboolean prepare_intelligent_page (GnomeDruidPage *page, GnomeDruid *druid, ImportData *data) { GtkWidget *dialog; ImportDialogImporterPage *import; GList *l, *importers; GtkWidget *table; int running = 0; if (data->importerpage->prepared == TRUE) { return TRUE; } data->importerpage->prepared = TRUE; dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_INFO, GTK_BUTTONS_NONE, "%s", _("Please wait...\nScanning for existing setups")); e_make_widget_backing_stored (dialog); gtk_window_set_title (GTK_WINDOW (dialog), _("Starting Intelligent Importers")); gtk_widget_show_all (dialog); gtk_widget_show_now (dialog); gtk_widget_queue_draw (dialog); gdk_flush (); while (gtk_events_pending ()) { gtk_main_iteration (); } import = data->importerpage; importers = get_intelligent_importers (); if (importers == NULL) { /* No importers, go directly to finish, do not pass go Do not collect $200 */ import->running = 0; gnome_druid_set_page (druid, GNOME_DRUID_PAGE (data->finish)) ; gtk_widget_destroy (dialog); return TRUE; } table = gtk_table_new (g_list_length (importers), 2, FALSE); for (l = importers; l; l = l->next) { GtkWidget *label; IntelligentImporterData *id; CORBA_Environment ev; gboolean can_run; char *str; id = g_new0 (IntelligentImporterData, 1); id->iid = g_strdup (l->data); CORBA_exception_init (&ev); id->object = bonobo_activation_activate_from_id ((char *) id->iid, 0, NULL, &ev); if (BONOBO_EX (&ev)) { g_warning ("Could not start %s:%s", id->iid, CORBA_exception_id (&ev)); CORBA_exception_free (&ev); /* Clean up the IID */ g_free (id->iid); g_free (id); continue; } if (id->object == CORBA_OBJECT_NIL) { g_warning ("Could not activate component %s", id->iid); CORBA_exception_free (&ev); g_free (id->iid); g_free (id); continue; } can_run = GNOME_Evolution_IntelligentImporter_canImport (id->object, &ev); if (BONOBO_EX (&ev)) { g_warning ("Could not call canImport(%s): %s", id->iid, CORBA_exception_id (&ev)); bonobo_object_release_unref (id->object, &ev); CORBA_exception_free (&ev); g_free (id->iid); g_free (id); continue; } if (can_run == FALSE) { bonobo_object_release_unref (id->object, &ev); CORBA_exception_free (&ev); g_free (id->iid); g_free (id); continue; } running++; id->name = GNOME_Evolution_IntelligentImporter__get_importername (id->object, &ev); if (BONOBO_EX (&ev)) { g_warning ("Could not get name(%s): %s", id->iid, CORBA_exception_id (&ev)); bonobo_object_release_unref (id->object, &ev); CORBA_exception_free (&ev); g_free (id->iid); g_free (id); continue; } id->blurb = GNOME_Evolution_IntelligentImporter__get_message (id->object, &ev); if (BONOBO_EX (&ev)) { g_warning ("Could not get message(%s): %s", id->iid, CORBA_exception_id (&ev)); bonobo_object_release_unref (id->object, &ev); CORBA_exception_free (&ev); g_free (id->iid); CORBA_free (id->name); g_free (id); continue; } id->control = Bonobo_Unknown_queryInterface (id->object, "IDL:Bonobo/Control:1.0", &ev); if (BONOBO_EX (&ev)) { g_warning ("Could not QI for Bonobo/Control:1.0 %s:%s", id->iid, CORBA_exception_id (&ev)); bonobo_object_release_unref (id->object, &ev); CORBA_exception_free (&ev); g_free (id->iid); CORBA_free (id->name); CORBA_free (id->blurb); continue; } if (id->control != CORBA_OBJECT_NIL) { id->widget = bonobo_widget_new_control_from_objref (id->control, CORBA_OBJECT_NIL); gtk_widget_show (id->widget); } else { id->widget = gtk_label_new (""); gtk_widget_show (id->widget); } CORBA_exception_free (&ev); import->importers = g_list_prepend (import->importers, id); str = g_strdup_printf (_("From %s:"), id->name); label = gtk_label_new (str); g_free (str); gtk_misc_set_alignment (GTK_MISC (label), 0, .5); gtk_table_attach (GTK_TABLE (table), label, 0, 1, running - 1, running, GTK_FILL, 0, 0, 0); gtk_table_attach (GTK_TABLE (table), id->widget, 1, 2, running - 1, running, GTK_FILL, 0, 3, 0); gtk_box_pack_start (GTK_BOX (data->importerpage->vbox), table, FALSE, FALSE, 0); } gtk_widget_show_all (table); if (running == 0) { gnome_druid_set_page (druid, GNOME_DRUID_PAGE (data->finish)); gtk_widget_destroy (dialog); return TRUE; } import->running = running; gtk_widget_destroy (dialog); return FALSE; } static void import_druid_cancel (GnomeDruid *druid, ImportData *data) { gtk_widget_destroy (GTK_WIDGET (data->dialog)); } static void import_druid_weak_notify (void *blah, GObject *where_the_object_was) { ImportData *data = (ImportData *) blah; g_object_unref (data->wizard); g_free (data->choosen_iid); g_free (data); } static void folder_selected (EShellFolderSelectionDialog *dialog, const char *path, ImportData *data) { char *filename, *iid; iid = g_strdup (data->choosen_iid); filename = gnome_file_entry_get_full_path (GNOME_FILE_ENTRY (data->filepage->filename), FALSE); gtk_widget_destroy (data->dialog); gtk_widget_hide (GTK_WIDGET (dialog)); start_import (path, filename, iid); g_free (iid); g_free (filename); } static void folder_cancelled (EShellFolderSelectionDialog *dialog, ImportData *data) { gtk_widget_destroy (data->dialog); } static void free_importers (ImportData *data) { GList *l; for (l = data->importerpage->importers; l; l = l->next) { IntelligentImporterData *iid; iid = l->data; if (iid->object != CORBA_OBJECT_NIL) { bonobo_object_release_unref (iid->object, NULL); } } g_list_free (data->importerpage->importers); } static void start_importers (GList *p) { CORBA_Environment ev; for (; p; p = p->next) { SelectedImporterData *sid = p->data; CORBA_exception_init (&ev); GNOME_Evolution_IntelligentImporter_importData (sid->importer, &ev); if (BONOBO_EX (&ev)) { g_warning ("Error importing %s\n%s", sid->iid, CORBA_exception_id (&ev)); } CORBA_exception_free (&ev); } } static void do_import (ImportData *data) { CORBA_Environment ev; GList *l, *selected = NULL; for (l = data->importerpage->importers; l; l = l->next) { IntelligentImporterData *importer_data; SelectedImporterData *sid; char *iid; importer_data = l->data; iid = g_strdup (importer_data->iid); sid = g_new (SelectedImporterData, 1); sid->iid = iid; CORBA_exception_init (&ev); sid->importer = bonobo_object_dup_ref (importer_data->object, &ev); if (BONOBO_EX (&ev)) { g_warning ("Error duplication %s\n(%s)", iid, CORBA_exception_id (&ev)); g_free (iid); CORBA_exception_free (&ev); g_free (sid); continue; } CORBA_exception_free (&ev); selected = g_list_prepend (selected, sid); } free_importers (data); if (selected != NULL) { start_importers (selected); for (l = selected; l; l = l->next) { SelectedImporterData *sid = l->data; CORBA_exception_init (&ev); bonobo_object_release_unref (sid->importer, &ev); CORBA_exception_free (&ev); g_free (sid->iid); g_free (sid); } g_list_free (selected); } } static void import_druid_finish (GnomeDruidPage *page, GnomeDruid *druid, ImportData *data) { GtkWidget *folder; if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->typepage->intelligent))) { do_import (data); gtk_widget_destroy (data->dialog); } else { folder = e_shell_folder_selection_dialog_new (data->shell, _("Select folder"), _("Select a destination folder for importing this data"), e_shell_view_get_current_uri (data->view), NULL, TRUE); g_signal_connect (folder, "folder_selected", G_CALLBACK (folder_selected), data); g_signal_connect (folder, "cancelled", G_CALLBACK (folder_cancelled), data); gtk_widget_hide (data->dialog); gtk_widget_show (folder); } } static gboolean prepare_file_page (GnomeDruidPage *page, GnomeDruid *druid, ImportData *data) { gnome_druid_set_buttons_sensitive (druid, TRUE, !data->filepage->need_filename, TRUE, FALSE); return FALSE; } static gboolean next_file_page (GnomeDruidPage *page, GnomeDruid *druid, ImportData *data) { gnome_druid_set_page (druid, GNOME_DRUID_PAGE (data->finish)); return TRUE; } static gboolean back_file_page (GnomeDruidPage *page, GnomeDruid *druid, ImportData *data) { gnome_druid_set_page (druid, GNOME_DRUID_PAGE (data->typedialog)); return TRUE; } static gboolean next_type_page (GnomeDruidPage *page, GnomeDruid *druid, ImportData *data) { if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->typepage->intelligent))) { gnome_druid_set_page (druid, GNOME_DRUID_PAGE (data->intelligent)); } else { gnome_druid_set_page (druid, GNOME_DRUID_PAGE (data->filedialog)); } return TRUE; } static gboolean back_finish_page (GnomeDruidPage *page, GnomeDruid *druid, ImportData *data) { if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->typepage->intelligent))) { if (data->importerpage->running != 0) { gnome_druid_set_page (druid, GNOME_DRUID_PAGE (data->intelligent)); } else { gnome_druid_set_page (druid, GNOME_DRUID_PAGE (data->typedialog)); } } else { gnome_druid_set_page (druid, GNOME_DRUID_PAGE (data->filedialog)); } return TRUE; } static gboolean back_intelligent_page (GnomeDruidPage *page, GnomeDruid *druid, ImportData *data) { gnome_druid_set_page (druid, GNOME_DRUID_PAGE (data->typedialog)); return TRUE; } static gboolean next_intelligent_page (GnomeDruidPage *page, GnomeDruid *druid, ImportData *data) { gnome_druid_set_page (druid, GNOME_DRUID_PAGE (data->finish)); return TRUE; } static void dialog_weak_notify (void *data, GObject *where_the_dialog_was) { gboolean *dialog_open = (gboolean *) data; *dialog_open = FALSE; } void show_import_wizard (BonoboUIComponent *component, gpointer user_data, const char *cname) { ImportData *data = g_new0 (ImportData, 1); GtkWidget *html; static gboolean dialog_open = FALSE; if (dialog_open) { return; } dialog_open = TRUE; data->view = E_SHELL_VIEW (user_data); data->shell = e_shell_view_get_shell (data->view); data->wizard = glade_xml_new (EVOLUTION_GLADEDIR "/import.glade", NULL, NULL); data->dialog = glade_xml_get_widget (data->wizard, "importwizard"); gtk_window_set_wmclass (GTK_WINDOW (data->dialog), "importdruid", "Evolution:shell"); gtk_window_set_transient_for (GTK_WINDOW (data->dialog), GTK_WINDOW (user_data)); g_object_weak_ref ((GObject *)data->dialog, dialog_weak_notify, &dialog_open); data->druid = glade_xml_get_widget (data->wizard, "druid1"); g_signal_connect (data->druid, "cancel", G_CALLBACK (import_druid_cancel), data); gtk_button_set_label((GtkButton *)((GnomeDruid *)data->druid)->finish, _("Import")); data->start = GNOME_DRUID_PAGE_EDGE (glade_xml_get_widget (data->wizard, "page0")); data->typedialog = glade_xml_get_widget (data->wizard, "page1"); g_signal_connect (data->typedialog, "next", G_CALLBACK (next_type_page), data); data->typepage = importer_type_page_new (data); html = create_html ("type_html"); gtk_box_pack_start (GTK_BOX (data->typepage->vbox), html, FALSE, TRUE, 0); gtk_box_reorder_child (GTK_BOX (data->typepage->vbox), html, 0); gtk_box_pack_start (GTK_BOX (GNOME_DRUID_PAGE_STANDARD (data->typedialog)->vbox), data->typepage->vbox, TRUE, TRUE, 0); data->intelligent = glade_xml_get_widget (data->wizard, "page2-intelligent"); g_signal_connect (data->intelligent, "next", G_CALLBACK (next_intelligent_page), data); g_signal_connect (data->intelligent, "back", G_CALLBACK (back_intelligent_page), data); g_signal_connect (data->intelligent, "prepare", G_CALLBACK (prepare_intelligent_page), data); data->importerpage = importer_importer_page_new (data); html = create_html ("intelligent_html"); gtk_box_pack_start (GTK_BOX (data->importerpage->vbox), html, FALSE, TRUE, 0); gtk_box_reorder_child (GTK_BOX (data->importerpage->vbox), html, 0); gtk_box_pack_start (GTK_BOX (GNOME_DRUID_PAGE_STANDARD (data->intelligent)->vbox), data->importerpage->vbox, TRUE, TRUE, 0); data->filedialog = glade_xml_get_widget (data->wizard, "page2-file"); g_signal_connect (data->filedialog, "prepare", G_CALLBACK (prepare_file_page), data); g_signal_connect (data->filedialog, "next", G_CALLBACK (next_file_page), data); g_signal_connect (data->filedialog, "back", G_CALLBACK (back_file_page), data); data->finish = GNOME_DRUID_PAGE_EDGE (glade_xml_get_widget (data->wizard, "page3")); g_signal_connect (data->finish, "back", G_CALLBACK (back_finish_page), data); data->filepage = importer_file_page_new (data); html = create_html ("file_html"); gtk_box_pack_start (GTK_BOX (data->filepage->vbox), html, FALSE, TRUE, 0); gtk_box_reorder_child (GTK_BOX (data->filepage->vbox), html, 0); gtk_box_pack_start (GTK_BOX (GNOME_DRUID_PAGE_STANDARD (data->filedialog)->vbox), data->filepage->vbox, TRUE, TRUE, 0); /* Finish page */ g_signal_connect (data->finish, "finish", G_CALLBACK (import_druid_finish), data); g_object_weak_ref ((GObject *)data->dialog, import_druid_weak_notify, data); gtk_widget_show_all (data->dialog); }