623 lines
16 KiB
C
623 lines
16 KiB
C
/* -*- 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"
|
|
#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, "<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;
|
|
EvolutionImporterListener *listener;
|
|
char *filename;
|
|
|
|
GnomeDialog *dialog;
|
|
GtkWidget *contents;
|
|
|
|
int item;
|
|
|
|
gboolean stop;
|
|
gboolean destroyed;
|
|
} 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;
|
|
|
|
if (icd->stop != TRUE) {
|
|
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 (result == EVOLUTION_IMPORTER_BUSY) {
|
|
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 ();
|
|
|
|
g_idle_add_full (G_PRIORITY_LOW, importer_timeout_fn,
|
|
data, NULL);
|
|
return;
|
|
}
|
|
}
|
|
|
|
g_free (icd->filename);
|
|
if (!icd->destroyed)
|
|
gtk_object_destroy (GTK_OBJECT (icd->dialog));
|
|
bonobo_object_unref (BONOBO_OBJECT (icd->listener));
|
|
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, icd->listener);
|
|
return FALSE;
|
|
}
|
|
|
|
static void
|
|
dialog_clicked_cb (GnomeDialog *dialog,
|
|
int button_number,
|
|
ImporterComponentData *icd)
|
|
{
|
|
if (button_number != 0)
|
|
return; /* Interesting... */
|
|
|
|
icd->stop = TRUE;
|
|
}
|
|
|
|
static void
|
|
dialog_destroy_cb (GtkObject *object,
|
|
ImporterComponentData *icd)
|
|
{
|
|
icd->stop = TRUE;
|
|
icd->destroyed = TRUE;
|
|
}
|
|
|
|
static char *
|
|
get_iid_for_filetype (const char *filename)
|
|
{
|
|
OAF_ServerInfoList *info_list;
|
|
CORBA_Environment ev;
|
|
GList *can_handle = NULL, *l;
|
|
char *ret_iid;
|
|
int i, len = 0;
|
|
|
|
CORBA_exception_init (&ev);
|
|
info_list = oaf_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 OAF_ServerInfo *info;
|
|
|
|
info = info_list->_buffer + i;
|
|
|
|
CORBA_exception_init (&ev2);
|
|
importer = oaf_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)) {
|
|
can_handle = g_list_prepend (can_handle,
|
|
g_strdup (info->iid));
|
|
len++;
|
|
}
|
|
|
|
bonobo_object_release_unref (importer, &ev2);
|
|
CORBA_exception_free (&ev2);
|
|
}
|
|
|
|
if (len == 1) {
|
|
ret_iid = can_handle->data;
|
|
g_list_free (can_handle);
|
|
return ret_iid;
|
|
} else if (len > 1) {
|
|
/* FIXME: Some way to choose between multiple iids */
|
|
/* FIXME: Free stuff */
|
|
g_warning ("Multiple iids can support %s", filename);
|
|
ret_iid = g_strdup (can_handle->data);
|
|
|
|
for (l = can_handle; l; l = l->next)
|
|
g_free (l->data);
|
|
g_list_free (can_handle);
|
|
return ret_iid;
|
|
} else {
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
static void
|
|
start_import (const char *filename,
|
|
const char *iid)
|
|
{
|
|
ImporterComponentData *icd;
|
|
char *label;
|
|
char *real_iid;
|
|
|
|
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);
|
|
}
|
|
|
|
g_print ("Importing with: %s\n", real_iid);
|
|
|
|
if (real_iid == NULL) {
|
|
char *message;
|
|
|
|
message = g_strdup_printf (_("There is no importer that is able to handle\n%s"), filename);
|
|
e_notice (NULL, GNOME_MESSAGE_BOX_ERROR, message);
|
|
g_free (message);
|
|
|
|
return;
|
|
}
|
|
|
|
icd = g_new (ImporterComponentData, 1);
|
|
icd->stop = FALSE;
|
|
icd->destroyed = FALSE;
|
|
icd->dialog = GNOME_DIALOG (gnome_dialog_new (_("Importing"),
|
|
GNOME_STOCK_BUTTON_CANCEL,
|
|
NULL));
|
|
gtk_signal_connect (GTK_OBJECT (icd->dialog), "clicked",
|
|
GTK_SIGNAL_FUNC (dialog_clicked_cb), icd);
|
|
gtk_signal_connect (GTK_OBJECT (icd->dialog), "destroy",
|
|
GTK_SIGNAL_FUNC (dialog_destroy_cb), 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);
|
|
g_free (real_iid);
|
|
|
|
if (evolution_importer_client_load_file (icd->client, filename) == FALSE) {
|
|
label = g_strdup_printf (_("Error loading %s"), filename);
|
|
gtk_label_set_text (GTK_LABEL (icd->contents), label);
|
|
g_free (label);
|
|
while (gtk_events_pending ())
|
|
gtk_main_iteration ();
|
|
|
|
bonobo_object_unref (BONOBO_OBJECT (icd->client));
|
|
gtk_object_unref (GTK_OBJECT (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;
|
|
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/Importer: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_widget_destroy (GTK_WIDGET (data->dialog));
|
|
}
|
|
|
|
static void
|
|
import_druid_destroy (GtkObject *object,
|
|
ImportData *data)
|
|
{
|
|
gtk_object_unref (GTK_OBJECT (data->wizard));
|
|
g_free (data->choosen_iid);
|
|
g_free (data);
|
|
}
|
|
|
|
static void
|
|
import_druid_finish (GnomeDruidPage *page,
|
|
GnomeDruid *druid,
|
|
ImportData *data)
|
|
{
|
|
char *filename;
|
|
char *iid;
|
|
|
|
filename = g_strdup (gtk_entry_get_text (GTK_ENTRY (gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (data->filepage->filename)))));
|
|
iid = g_strdup (data->choosen_iid);
|
|
|
|
gtk_widget_destroy (data->dialog);
|
|
start_import (filename, iid);
|
|
|
|
g_free (filename);
|
|
g_free (iid);
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
/* Hack to change the Finish button */
|
|
static void
|
|
druid_finish_button_change (GnomeDruid *druid)
|
|
{
|
|
GtkWidget *button = druid->finish;
|
|
GtkWidget *hbox = GTK_BIN (button)->child, *hbox2;
|
|
GtkBoxChild *child;
|
|
GtkWidget *label;
|
|
|
|
/* Get the second item from the children list */
|
|
hbox2 = ((GtkBoxChild *)GTK_BOX (hbox)->children->data)->widget;
|
|
|
|
g_return_if_fail (GTK_IS_BOX (hbox2));
|
|
child = (GtkBoxChild *)g_list_nth_data (GTK_BOX (hbox2)->children, 0);
|
|
label = child->widget;
|
|
|
|
/* Safety check :) */
|
|
g_return_if_fail (GTK_IS_LABEL (label));
|
|
|
|
gtk_label_set_text (GTK_LABEL (label), _("Import"));
|
|
}
|
|
|
|
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);
|
|
|
|
druid_finish_button_change (GNOME_DRUID (data->druid));
|
|
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_destroy), data);
|
|
|
|
gtk_widget_show_all (data->dialog);
|
|
}
|