/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ /* importer.c * * Copyright (C) 2000 Helix Code, 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 */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include "importer.h" #include "GNOME_Evolution_Importer.h" typedef struct _ImportDialogFilePage { GtkWidget *vbox; GtkWidget *filename; GtkWidget *filetype; GtkWidget *menu; gboolean need_filename; } ImportDialogFilePage; typedef struct _ImportData { GladeXML *wizard; GtkWidget *dialog; GtkWidget *druid; ImportDialogFilePage *filepage; GtkWidget *filedialog; GtkWidget *vbox; char *choosen_iid; } ImportData; /* Some HTML helper functions from mail/mail-config-gui.c */ static void html_size_req (GtkWidget *widget, GtkRequisition *requisition) { requisition->height = GTK_LAYOUT (widget)->height; } /* Returns a GtkHTML which is already inside a GtkScrolledWindow. If * @white is TRUE, the GtkScrolledWindow will be inside a GtkFrame. */ static GtkWidget * html_new (gboolean white) { GtkWidget *html, *scrolled, *frame; GtkStyle *style; html = gtk_html_new (); GTK_LAYOUT (html)->height = 0; gtk_signal_connect (GTK_OBJECT (html), "size_request", GTK_SIGNAL_FUNC (html_size_req), NULL); gtk_html_set_editable (GTK_HTML (html), FALSE); style = gtk_rc_get_style (html); if (style) { gtk_html_set_default_background_color (GTK_HTML (html), white ? &style->white: &style->bg[0]); } gtk_widget_set_sensitive (html, FALSE); scrolled = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_NEVER, GTK_POLICY_NEVER); gtk_container_add (GTK_CONTAINER (scrolled), html); if (white) { frame = gtk_frame_new (NULL); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN); gtk_container_add (GTK_CONTAINER (frame), scrolled); gtk_widget_show_all (frame); } else { gtk_widget_show_all (scrolled); } return html; } static void put_html (GtkHTML *html, const char *text) { GtkHTMLStream *handle; char *htmltext; htmltext = e_text_to_html (text, E_TEXT_TO_HTML_CONVERT_NL); handle = gtk_html_begin (html); gtk_html_write (html, handle, "", 12); gtk_html_write (html, handle, text, strlen (text)); gtk_html_write (html, handle, "", 14); g_free (htmltext); gtk_html_end (html, handle, GTK_HTML_STREAM_OK); } /* Importing functions */ /* Data to be passed around */ typedef struct _ImporterComponentData { EvolutionImporterClient *client; char *filename; GnomeDialog *dialog; GtkWidget *contents; int item; } ImporterComponentData; static gboolean importer_timeout_fn (gpointer data); static void import_cb (EvolutionImporterClient *client, EvolutionImporterResult result, gboolean more_items, void *data) { ImporterComponentData *icd = (ImporterComponentData *) data; char *label; g_warning ("Recieved callback. Result: %d\tmore_items: %s", result, more_items ? "TRUE" : "FALSE"); if (result == EVOLUTION_IMPORTER_NOT_READY) { /* Importer isn't ready yet. Wait 5 seconds and try again. */ label = g_strdup_printf (_("Importing %s\nImporter not ready." "\nWaiting 5 seconds to retry."), icd->filename); gtk_label_set_text (GTK_LABEL (icd->contents), label); g_free (label); while (gtk_events_pending ()) gtk_main_iteration (); gtk_timeout_add (5000, importer_timeout_fn, data); 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 (); evolution_importer_client_process_item (client, import_cb, data); return; } g_free (icd->filename); gtk_object_unref (GTK_OBJECT (icd->dialog)); bonobo_object_unref (BONOBO_OBJECT (icd->client)); g_free (icd); } static gboolean importer_timeout_fn (gpointer data) { ImporterComponentData *icd = (ImporterComponentData *) data; char *label; 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, import_cb, data); return FALSE; } static void start_import (const char *filename, const char *iid) { if (iid == NULL || strcmp (iid, "Automatic") == 0) { /* Work out the component to use */ } else { CORBA_Object factory, importer; EvolutionImporterClient *client; ImporterComponentData *icd; CORBA_Environment ev; char *label; icd = g_new (ImporterComponentData, 1); icd->dialog = gnome_dialog_new (_("Importing"), GNOME_STOCK_BUTTON_CANCEL, NULL); label = g_strdup_printf (_("Importing %s.\nStarting %s"), filename, 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 (); CORBA_exception_init (&ev); factory = oaf_activate_from_id ((char *) iid, 0, NULL, &ev); if (ev._major != CORBA_NO_EXCEPTION) { label = g_strdup_printf (_("Importing %s\n" "Cannot activate %s."), filename, iid); gtk_label_set_text (GTK_LABEL (icd->contents), label); g_free (label); while (gtk_events_pending ()) gtk_main_iteration (); g_free (icd); return; } importer = GNOME_Evolution_ImporterFactory_loadFile (factory, filename, &ev); if (ev._major != CORBA_NO_EXCEPTION) { CORBA_Environment ev2; label = g_strdup_printf (_("Unable to load %s.\n%s"), filename, CORBA_exception_id (&ev)); gtk_label_set_text (GTK_LABEL (icd->contents), label); g_free (label); while (gtk_events_pending ()) gtk_main_iteration (); g_free (icd); CORBA_exception_init (&ev2); CORBA_Object_release (factory, &ev2); CORBA_exception_free (&ev2); return; } CORBA_Object_release (factory, &ev); CORBA_exception_free (&ev); client = evolution_importer_client_new (importer); icd->client = client; 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 (); evolution_importer_client_process_item (client, import_cb, icd); } } static void filename_changed (GtkEntry *entry, ImportData *data) { ImportDialogFilePage *page; 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); } static const char * get_name_from_component_info (const OAF_ServerInfo *info) { OAF_Property *property; const char *name; property = oaf_server_info_prop_find ((OAF_ServerInfo *) info, "evolution:menu-name"); if (property == NULL || property->v._d != OAF_P_STRING) return NULL; name = property->v._u.value_string; return name; } static void item_selected (GtkWidget *item, ImportData *data) { char *iid; g_free (data->choosen_iid); iid = gtk_object_get_data (GTK_OBJECT (item), "oafiid"); g_print ("iid: %s\n", iid); if (iid == NULL) data->choosen_iid = g_strdup ("Automatic"); else data->choosen_iid = g_strdup (iid); } static GtkWidget * create_plugin_menu (ImportData *data) { OAF_ServerInfoList *info_list; CORBA_Environment ev; int i; GtkWidget *menu; GtkWidget *item; menu = gtk_menu_new (); item = gtk_menu_item_new_with_label (_("Automatic")); gtk_object_set_data_full (GTK_OBJECT (item), "oafiid", g_strdup ("Automatic"), g_free); gtk_menu_append (GTK_MENU (menu), item); CORBA_exception_init (&ev); info_list = oaf_query ("repo_ids.has ('IDL:GNOME/Evolution/ImporterFactory:1.0')", NULL, &ev); for (i = 0; i < info_list->_length; i++) { const OAF_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_signal_connect (GTK_OBJECT (item), "activate", GTK_SIGNAL_FUNC (item_selected), data); gtk_object_set_data_full (GTK_OBJECT (item), "oafiid", g_strdup (info->iid), g_free); gtk_menu_append (GTK_MENU (menu), item); } 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 (NULL, _("Select a file")); gtk_signal_connect (GTK_OBJECT (gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (page->filename))), "changed", GTK_SIGNAL_FUNC (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 void import_druid_cancel (GnomeDruid *druid, ImportData *data) { gtk_object_unref (GTK_OBJECT (data->wizard)); gtk_widget_destroy (GTK_WIDGET (data->dialog)); g_free (data->choosen_iid); g_free (data); } static void import_druid_finish (GnomeDruidPage *page, GnomeDruid *druid, ImportData *data) { char *filename; filename = g_strdup (gtk_entry_get_text (GTK_ENTRY (gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (data->filepage->filename))))); g_print ("You have selected %s to be imported with %s\n", filename, data->choosen_iid); start_import (filename, data->choosen_iid); gtk_widget_destroy (data->dialog); g_free (filename); } static gboolean prepare_file_page (GnomeDruidPage *page, GnomeDruid *druid, ImportData *data) { g_print ("Prepare thyself\n"); gnome_druid_set_buttons_sensitive (druid, TRUE, !data->filepage->need_filename, TRUE); return FALSE; } void show_import_wizard (void) { ImportData *data = g_new0 (ImportData, 1); GnomeDruidPageStart *start; GnomeDruidPageFinish *finish; GtkWidget *html; data->wizard = glade_xml_new (EVOLUTION_GLADEDIR "/import.glade", NULL); data->dialog = glade_xml_get_widget (data->wizard, "importwizard"); gtk_window_set_wmclass (GTK_WINDOW (data->dialog), "importdruid", "Evolution:shell"); data->druid = glade_xml_get_widget (data->wizard, "druid1"); gtk_signal_connect (GTK_OBJECT (data->druid), "cancel", GTK_SIGNAL_FUNC (import_druid_cancel), data); start = GNOME_DRUID_PAGE_START (glade_xml_get_widget (data->wizard, "page1")); data->filedialog = glade_xml_get_widget (data->wizard, "page2"); gtk_signal_connect (GTK_OBJECT (data->filedialog), "prepare", GTK_SIGNAL_FUNC (prepare_file_page), data); finish = GNOME_DRUID_PAGE_FINISH (glade_xml_get_widget (data->wizard, "page3")); data->filepage = importer_file_page_new (data); data->vbox = data->filepage->vbox; html = html_new (TRUE); put_html (GTK_HTML (html), _("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.")); gtk_box_pack_start (GTK_BOX (data->vbox), html->parent->parent, FALSE, TRUE, 0); gtk_box_reorder_child (GTK_BOX (data->vbox), html->parent->parent, 0); gtk_box_pack_start (GTK_BOX (GNOME_DRUID_PAGE_STANDARD (data->filedialog)->vbox), data->vbox, TRUE, TRUE, 0); /* Finish page */ gtk_signal_connect (GTK_OBJECT (finish), "finish", GTK_SIGNAL_FUNC (import_druid_finish), data); gtk_signal_connect (GTK_OBJECT (data->dialog), "destroy", GTK_SIGNAL_FUNC (import_druid_cancel), data); gtk_widget_show_all (data->dialog); }