diff options
Diffstat (limited to 'shell/importer/importer.c')
-rw-r--r-- | shell/importer/importer.c | 506 |
1 files changed, 506 insertions, 0 deletions
diff --git a/shell/importer/importer.c b/shell/importer/importer.c new file mode 100644 index 0000000000..71373937db --- /dev/null +++ b/shell/importer/importer.c @@ -0,0 +1,506 @@ +/* -*- 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 <iain@helixcode.com> + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gnome.h> + +#include <liboaf/liboaf.h> + +#include <evolution-importer-client.h> + +#include <glade/glade.h> +#include <gtkhtml/gtkhtml.h> +#include <e-util/e-html-utils.h> + +#include "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, "<HTML><BODY>", 12); + gtk_html_write (html, handle, text, strlen (text)); + gtk_html_write (html, handle, "</BODY></HTML>", 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); +} |