aboutsummaryrefslogtreecommitdiffstats
path: root/calendar/importers
diff options
context:
space:
mode:
Diffstat (limited to 'calendar/importers')
-rw-r--r--calendar/importers/Makefile.am1
-rw-r--r--calendar/importers/icalendar-importer.c304
2 files changed, 177 insertions, 128 deletions
diff --git a/calendar/importers/Makefile.am b/calendar/importers/Makefile.am
index 84867931a6..4cf7c40cf2 100644
--- a/calendar/importers/Makefile.am
+++ b/calendar/importers/Makefile.am
@@ -24,6 +24,7 @@ libevolution_calendar_importers_la_LDFLAGS = -avoid-version -module
libevolution_calendar_importers_la_LIBADD = \
$(top_builddir)/shell/importer/libevolution-importer.la \
+ $(top_builddir)/e-util/libeutil.la \
$(top_builddir)/calendar/common/libevolution-calendarprivate.la \
$(IMPORTERS_LIBS)
diff --git a/calendar/importers/icalendar-importer.c b/calendar/importers/icalendar-importer.c
index baeab1e70d..69e0e554c8 100644
--- a/calendar/importers/icalendar-importer.c
+++ b/calendar/importers/icalendar-importer.c
@@ -27,16 +27,22 @@
#include <gtk/gtksignal.h>
#include <gtk/gtkcheckbutton.h>
#include <gtk/gtkhbox.h>
+#include <gtk/gtkvbox.h>
#include <gtk/gtkmain.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkradiobutton.h>
+#include <gtk/gtknotebook.h>
#include <libgnome/gnome-util.h>
#include <libgnome/gnome-i18n.h>
#include <bonobo/bonobo-control.h>
#include <bonobo/bonobo-exception.h>
#include <libecal/e-cal.h>
+#include <widgets/misc/e-source-selector.h>
#include <importer/evolution-importer.h>
#include <importer/evolution-intelligent-importer.h>
#include <importer/GNOME_Evolution_Importer.h>
#include <libical/icalvcal.h>
+#include <e-util/e-dialog-widgets.h>
#include "evolution-calendar-importer.h"
#include "common/authentication.h"
@@ -45,12 +51,17 @@
typedef struct {
- ECal *client;
- ECal *tasks_client;
EvolutionImporter *importer;
+
+ GtkWidget *nb;
+
+ ESource *primary;
+ ESourceSelector *selectors[E_CAL_SOURCE_TYPE_LAST];
+
+ ECal *client;
+ ECalSourceType source_type;
+
icalcomponent *icalcomp;
- gboolean folder_contains_events;
- gboolean folder_contains_tasks;
} ICalImporter;
typedef struct {
@@ -58,6 +69,19 @@ typedef struct {
gboolean do_tasks;
} ICalIntelligentImporter;
+static const int import_type_map[] = {
+ E_CAL_SOURCE_TYPE_EVENT,
+ E_CAL_SOURCE_TYPE_TODO,
+ -1
+};
+
+static const char *import_type_strings[] = {
+ N_("Appointments and Meetings"),
+ N_("Tasks"),
+ NULL
+};
+
+
/*
* Functions shared by iCalendar & vCalendar importer.
*/
@@ -66,12 +90,12 @@ static void
importer_destroy_cb (gpointer user_data)
{
ICalImporter *ici = (ICalImporter *) user_data;
-
+
g_return_if_fail (ici != NULL);
-
- g_object_unref (ici->client);
- g_object_unref (ici->tasks_client);
-
+
+ if (ici->client)
+ g_object_unref (ici->client);
+
if (ici->icalcomp != NULL) {
icalcomponent_free (ici->icalcomp);
ici->icalcomp = NULL;
@@ -80,15 +104,16 @@ importer_destroy_cb (gpointer user_data)
g_free (ici);
}
-/* This removes all components except VEVENTs and VTIMEZONEs from the toplevel
- icalcomponent, and returns a GList of the VTODO components. */
-static GList*
-prepare_events (icalcomponent *icalcomp)
+/* This removes all components except VEVENTs and VTIMEZONEs from the toplevel */
+static void
+prepare_events (icalcomponent *icalcomp, GList **vtodos)
{
icalcomponent *subcomp;
- GList *vtodos = NULL;
icalcompiter iter;
+ if (vtodos)
+ *vtodos = NULL;
+
iter = icalcomponent_begin_component (icalcomp, ICAL_ANY_COMPONENT);
while ((subcomp = icalcompiter_deref (&iter)) != NULL) {
icalcomponent_kind child_kind = icalcomponent_isa (subcomp);
@@ -98,18 +123,18 @@ prepare_events (icalcomponent *icalcomp)
icalcompiter_next (&iter);
icalcomponent_remove_component (icalcomp, subcomp);
- if (child_kind == ICAL_VTODO_COMPONENT)
- vtodos = g_list_prepend (vtodos, subcomp);
+ if (child_kind == ICAL_VTODO_COMPONENT && vtodos)
+ *vtodos = g_list_prepend (*vtodos, subcomp);
else
- icalcomponent_free (subcomp);
+ icalcomponent_free (subcomp);
+
+ icalcomponent_free (subcomp);
continue;
}
icalcompiter_next (&iter);
}
-
- return vtodos;
}
@@ -199,32 +224,112 @@ update_objects (ECal *client, icalcomponent *icalcomp)
}
static void
+button_toggled_cb (GtkWidget *widget, gpointer data)
+{
+ ICalImporter *ici = data;
+
+ ici->source_type = e_dialog_radio_get (widget, import_type_map);
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (ici->nb), ici->source_type);
+
+ /* If we switched pages we have a new primary source */
+ if (ici->primary)
+ g_object_unref (ici->primary);
+ ici->primary = g_object_ref (e_source_selector_peek_primary_selection (ici->selectors[ici->source_type]));
+}
+
+static void
+primary_selection_changed_cb (ESourceSelector *selector, gpointer data)
+{
+ ICalImporter *ici = data;
+
+ if (ici->primary)
+ g_object_unref (ici->primary);
+ ici->primary = g_object_ref (e_source_selector_peek_primary_selection (selector));
+}
+
+static void
+create_control_fn (EvolutionImporter *importer, Bonobo_Control *control, void *closure)
+{
+ ICalImporter *ici = (ICalImporter *) closure;
+ GtkWidget *vbox, *hbox, *rb = NULL;
+ GSList *group = NULL;
+ ESourceList *source_list;
+ int i;
+
+ vbox = gtk_vbox_new (FALSE, FALSE);
+
+ hbox = gtk_hbox_new (FALSE, FALSE);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 6);
+
+ /* Type of icalendar items */
+ for (i = 0; import_type_map[i] != -1; i++) {
+ rb = gtk_radio_button_new_with_label (group, import_type_strings[i]);
+ gtk_box_pack_start (GTK_BOX (hbox), rb, FALSE, FALSE, 6);
+ g_signal_connect (G_OBJECT (rb), "toggled", G_CALLBACK (button_toggled_cb), ici);
+ if (!group)
+ group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (rb));
+ }
+ e_dialog_radio_set (rb, import_type_map[0], import_type_map);
+
+ /* The source selector notebook */
+ ici->nb = gtk_notebook_new ();
+ gtk_notebook_set_show_tabs (GTK_NOTEBOOK (ici->nb), FALSE);
+ gtk_container_add (GTK_CONTAINER (vbox), ici->nb);
+
+ /* The source selectors */
+ for (i = 0; import_type_map[i] != -1; i++) {
+ GtkWidget *selector;
+ ESource *primary;
+
+ /* FIXME Better error handling */
+ if (!e_cal_get_sources (&source_list, import_type_map[i], NULL))
+ return;
+
+ selector = e_source_selector_new (source_list);
+ e_source_selector_show_selection (E_SOURCE_SELECTOR (selector), FALSE);
+ gtk_notebook_append_page (GTK_NOTEBOOK (ici->nb), selector, NULL);
+
+ /* FIXME What if no sources? */
+ primary = e_source_list_peek_source_any (source_list);
+ e_source_selector_set_primary_selection (E_SOURCE_SELECTOR (selector), primary);
+ if (!ici->primary)
+ ici->primary = g_object_ref (primary);
+ g_object_unref (source_list);
+
+ g_signal_connect (G_OBJECT (selector), "primary_selection_changed",
+ G_CALLBACK (primary_selection_changed_cb), ici);
+
+ ici->selectors[import_type_map[i]] = E_SOURCE_SELECTOR (selector);
+ }
+
+ gtk_widget_show_all (vbox);
+
+ *control = BONOBO_OBJREF (bonobo_control_new (vbox));
+}
+
+static void
process_item_fn (EvolutionImporter *importer,
CORBA_Object listener,
void *closure,
CORBA_Environment *ev)
{
- ECalLoadState state, tasks_state;
+ ECalLoadState state;
ICalImporter *ici = (ICalImporter *) closure;
GNOME_Evolution_ImporterListener_ImporterResult result;
-
+
result = GNOME_Evolution_ImporterListener_OK;
g_return_if_fail (ici != NULL);
- g_return_if_fail (E_IS_CAL (ici->client));
g_return_if_fail (ici->icalcomp != NULL);
state = e_cal_get_load_state (ici->client);
- tasks_state = e_cal_get_load_state (ici->tasks_client);
- if (state == E_CAL_LOAD_LOADING
- || tasks_state == E_CAL_LOAD_LOADING) {
+ if (state == E_CAL_LOAD_LOADING) {
GNOME_Evolution_ImporterListener_notifyResult (
listener,
GNOME_Evolution_ImporterListener_BUSY,
TRUE, ev);
return;
- } else if (state != E_CAL_LOAD_LOADED
- || tasks_state != E_CAL_LOAD_LOADED) {
+ } else if (state != E_CAL_LOAD_LOADED) {
GNOME_Evolution_ImporterListener_notifyResult (
listener,
GNOME_Evolution_ImporterListener_UNSUPPORTED_OPERATION,
@@ -232,30 +337,22 @@ process_item_fn (EvolutionImporter *importer,
return;
}
- /* If the folder contains events & tasks we can just import everything
- into it. If it contains just events, we have to strip out the
- VTODOs and import them into the default tasks folder. If the folder
- contains just tasks, we strip out the VEVENTs, which do not get
- imported at all. */
- if (ici->folder_contains_events && ici->folder_contains_tasks) {
- if (!update_objects (ici->client, ici->icalcomp))
- result = GNOME_Evolution_ImporterListener_BAD_DATA;
- } else if (ici->folder_contains_events) {
- GList *vtodos = prepare_events (ici->icalcomp);
+ switch (ici->source_type) {
+ case E_CAL_SOURCE_TYPE_EVENT:
+ prepare_events (ici->icalcomp, NULL);
if (!update_objects (ici->client, ici->icalcomp))
result = GNOME_Evolution_ImporterListener_BAD_DATA;
-
- prepare_tasks (ici->icalcomp, vtodos);
- if (!update_objects (ici->tasks_client, ici->icalcomp))
- result = GNOME_Evolution_ImporterListener_BAD_DATA;
- } else {
+ break;
+ case E_CAL_SOURCE_TYPE_TODO:
prepare_tasks (ici->icalcomp, NULL);
if (!update_objects (ici->client, ici->icalcomp))
result = GNOME_Evolution_ImporterListener_BAD_DATA;
+ break;
+ default:
+ g_assert_not_reached ();
}
- GNOME_Evolution_ImporterListener_notifyResult (listener, result, FALSE,
- ev);
+ GNOME_Evolution_ImporterListener_notifyResult (listener, result, FALSE, ev);
}
@@ -292,29 +389,14 @@ support_format_fn (EvolutionImporter *importer,
static gboolean
load_file_fn (EvolutionImporter *importer,
const char *filename,
- const char *physical_uri,
- const char *folder_type,
void *closure)
{
- char *contents, *f;
+ char *contents;
gboolean ret = FALSE;
ICalImporter *ici = (ICalImporter *) closure;
g_return_val_if_fail (ici != NULL, FALSE);
- if (!strcmp (folder_type, "calendar")) {
- ici->folder_contains_events = TRUE;
- ici->folder_contains_tasks = FALSE;
-
- f = g_strdup ("calendar.ics");
- } else {
- ici->folder_contains_events = FALSE;
- ici->folder_contains_tasks = TRUE;
-
- f = g_strdup ("tasks.ics");
- }
-
-
if (g_file_get_contents (filename, &contents, NULL, NULL)) {
icalcomponent *icalcomp;
@@ -323,32 +405,20 @@ load_file_fn (EvolutionImporter *importer,
g_free (contents);
if (icalcomp) {
- char *real_uri;
-
- if (!g_strncasecmp (physical_uri, "file", 4) &&
- g_strcasecmp (physical_uri + (strlen (physical_uri) - strlen (f)), f)) {
- real_uri = g_concat_dir_and_file (physical_uri, f);
- } else
- real_uri = g_strdup (physical_uri);
-
- /* create ECal's */
- if (!ici->client)
- ici->client = auth_new_cal_from_uri (real_uri, E_CAL_SOURCE_TYPE_EVENT);
- if (!ici->tasks_client)
- ici->tasks_client = auth_new_cal_from_uri ("", E_CAL_SOURCE_TYPE_TODO); /* FIXME */
-
- if (e_cal_open (ici->client, TRUE, NULL)
- && e_cal_open (ici->tasks_client, FALSE, NULL)) {
- ici->icalcomp = icalcomp;
- ret = TRUE;
+ /* create the neccessary ECal */
+ if (ici->client)
+ g_object_unref (ici->client);
+ ici->client = auth_new_cal_from_source (ici->primary, ici->source_type);
+
+ if (ici->client) {
+ if (e_cal_open (ici->client, TRUE, NULL)) {
+ ici->icalcomp = icalcomp;
+ ret = TRUE;
+ }
}
-
- g_free (real_uri);
}
}
- g_free (f);
-
return ret;
}
@@ -356,12 +426,13 @@ BonoboObject *
ical_importer_new (void)
{
ICalImporter *ici;
-
+
ici = g_new0 (ICalImporter, 1);
+
ici->client = NULL;
- ici->tasks_client = NULL;
ici->icalcomp = NULL;
- ici->importer = evolution_importer_new (support_format_fn,
+ ici->importer = evolution_importer_new (create_control_fn,
+ support_format_fn,
load_file_fn,
process_item_fn,
NULL,
@@ -443,56 +514,29 @@ load_vcalendar_file (const char *filename)
static gboolean
vcal_load_file_fn (EvolutionImporter *importer,
const char *filename,
- const char *physical_uri,
- const char *folder_type,
void *closure)
{
gboolean ret = FALSE;
- char *f;
ICalImporter *ici = (ICalImporter *) closure;
icalcomponent *icalcomp;
g_return_val_if_fail (ici != NULL, FALSE);
- if (!strcmp (folder_type, "calendar")) {
- ici->folder_contains_events = TRUE;
- ici->folder_contains_tasks = FALSE;
-
- f = g_strdup ("calendar.ics");
- } else {
- ici->folder_contains_events = FALSE;
- ici->folder_contains_tasks = TRUE;
-
- f = g_strdup ("tasks.ics");
- }
-
icalcomp = load_vcalendar_file (filename);
if (icalcomp) {
- char *real_uri;
-
- if (!g_strncasecmp (physical_uri, "file", 4) &&
- g_strcasecmp (physical_uri + (strlen (physical_uri) - strlen (f)), f)) {
- real_uri = g_concat_dir_and_file (physical_uri, f);
- } else
- real_uri = g_strdup (physical_uri);
-
- /* create ECal's */
- if (!ici->client)
- ici->client = auth_new_cal_from_uri (real_uri, E_CAL_SOURCE_TYPE_EVENT);
- if (!ici->tasks_client)
- ici->tasks_client = auth_new_cal_from_uri ("", E_CAL_SOURCE_TYPE_TODO);
-
- if (e_cal_open (ici->client, TRUE, NULL)
- && e_cal_open (ici->tasks_client, FALSE, NULL)) {
- ici->icalcomp = icalcomp;
- ret = TRUE;
+ /* create the neccessary ECal */
+ if (ici->client)
+ g_object_unref (ici->client);
+ ici->client = auth_new_cal_from_source (ici->primary, ici->source_type);
+
+ if (ici->client) {
+ if (e_cal_open (ici->client, TRUE, NULL)) {
+ ici->icalcomp = icalcomp;
+ ret = TRUE;
+ }
}
-
- g_free (real_uri);
}
- g_free (f);
-
return ret;
}
@@ -502,10 +546,9 @@ vcal_importer_new (void)
ICalImporter *ici;
ici = g_new0 (ICalImporter, 1);
- ici->client = NULL;
- ici->tasks_client = NULL;
ici->icalcomp = NULL;
- ici->importer = evolution_importer_new (vcal_support_format_fn,
+ ici->importer = evolution_importer_new (create_control_fn,
+ vcal_support_format_fn,
vcal_load_file_fn,
process_item_fn,
NULL,
@@ -564,15 +607,20 @@ gnome_calendar_import_data_fn (EvolutionIntelligentImporter *ii,
return;
}
+ /* FIXME */
/* Try to open the default calendar & tasks folders. */
if (ici->do_calendar) {
- calendar_client = auth_new_cal_from_uri ("", E_CAL_SOURCE_TYPE_EVENT); /* FIXME: use default folder */
+ if (!e_cal_open_default (&calendar_client, E_CAL_SOURCE_TYPE_EVENT, NULL))
+ goto out;
+
if (!e_cal_open (calendar_client, FALSE, NULL))
goto out;
}
if (ici->do_tasks) {
- tasks_client = auth_new_cal_from_uri ("", E_CAL_SOURCE_TYPE_TODO); /* FIXME: use default folder */
+ if (!e_cal_open_default (&tasks_client, E_CAL_SOURCE_TYPE_TODO, NULL))
+ goto out;
+
if (!e_cal_open (tasks_client, FALSE, NULL))
goto out;
}
@@ -589,7 +637,7 @@ gnome_calendar_import_data_fn (EvolutionIntelligentImporter *ii,
/*
* Import the calendar events into the default calendar folder.
*/
- vtodos = prepare_events (icalcomp);
+ prepare_events (icalcomp, &vtodos);
/* Wait for client to finish opening the calendar & tasks folders. */
for (t = 0; t < IMPORTER_TIMEOUT_SECONDS; t++) {