/* Evolution calendar - Migrate tasks from the calendar folder to the tasks folder
*
* Copyright (C) 2001 Ximian, Inc.
*
* Authors: Federico Mena-Quintero <federico@ximian.com>
*
* 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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gtk/gtkwindow.h>
#include <gtk/gtksignal.h>
#include <libgnome/gnome-defs.h>
#include <libgnome/gnome-i18n.h>
#include <libgnomeui/gnome-dialog-util.h>
#include <cal-client/cal-client.h>
#include "component-factory.h"
#include "tasks-migrate.h"
/* Client for the calendar folder */
static CalClient *calendar_client = NULL;
/* Client for the tasks folder */
static CalClient *tasks_client = NULL;
/* Whether we have done the migration yet */
static gboolean migrated = FALSE;
/* Performs the actual migration process */
static void
migrate (void)
{
GList *uids;
GList *l;
gboolean success;
gboolean at_least_one;
g_assert (calendar_client != NULL);
g_assert (tasks_client != NULL);
g_assert (cal_client_get_load_state (calendar_client) == CAL_CLIENT_LOAD_LOADED);
g_assert (cal_client_get_load_state (tasks_client) == CAL_CLIENT_LOAD_LOADED);
uids = cal_client_get_uids (calendar_client, CALOBJ_TYPE_TODO);
success = TRUE;
at_least_one = FALSE;
for (l = uids; l; l = l->next) {
const char *uid;
CalComponent *comp;
CalClientGetStatus status;
at_least_one = TRUE;
uid = l->data;
status = cal_client_get_object (calendar_client, uid, &comp);
switch (status) {
case CAL_CLIENT_GET_SUCCESS:
if (cal_client_update_object (tasks_client, comp) == CAL_CLIENT_RESULT_SUCCESS)
cal_client_remove_object (calendar_client, uid);
else
success = FALSE;
gtk_object_unref (GTK_OBJECT (comp));
break;
case CAL_CLIENT_GET_NOT_FOUND:
/* This is OK; the object may have disappeared from the server */
break;
case CAL_CLIENT_GET_SYNTAX_ERROR:
success = FALSE;
break;
default:
g_assert_not_reached ();
}
}
cal_obj_uid_list_free (uids);
if (!at_least_one)
return;
if (success)
gnome_ok_dialog (_("Evolution has taken the tasks that were in your calendar folder "
"and automatically migrated them to the new tasks folder."));
else
gnome_ok_dialog (_("Evolution has tried to take the tasks that were in your "
"calendar folder and migrate them to the new tasks folder.\n"
"Some of the tasks could not be migrated, so "
"this process may be attempted again in the future."));
}
/* Displays an error to indicate that a calendar could not be opened */
static void
open_error (const char *uri)
{
char *msg;
msg = g_strdup_printf (_("Could not open `%s'; no items from the calendar folder "
"will be migrated to the tasks folder."),
uri);
gnome_error_dialog (msg);
g_free (msg);
}
/* Displays an error to indicate that a URI method is not supported */
static void
method_error (const char *uri)
{
char *msg;
msg = g_strdup_printf (_("The method required to load `%s' is not supported; "
"no items from the calendar folder will be migrated "
"to the tasks folder."),
uri);
gnome_error_dialog (msg);
g_free (msg);
}
/* Callback used when the tasks client is finished loading */
static void
tasks_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer data)
{
g_assert (calendar_client != NULL);
g_assert (cal_client_get_load_state (calendar_client) == CAL_CLIENT_LOAD_LOADED);
switch (status) {
case CAL_CLIENT_OPEN_SUCCESS:
migrate ();
break;
case CAL_CLIENT_OPEN_ERROR:
open_error (cal_client_get_uri (client));
migrated = FALSE;
break;
case CAL_CLIENT_OPEN_NOT_FOUND:
/* This can't happen because we did not specify only_if_exists when
* issuing the open request.
*/
g_assert_not_reached ();
break;
case CAL_CLIENT_OPEN_METHOD_NOT_SUPPORTED:
method_error (cal_client_get_uri (client));
migrated = FALSE;
break;
default:
g_assert_not_reached ();
}
gtk_object_unref (GTK_OBJECT (calendar_client));
calendar_client = NULL;
gtk_object_unref (GTK_OBJECT (tasks_client));
tasks_client = NULL;
}
/* Initiates the loading process for the tasks client */
static gboolean
load_tasks_client (void)
{
char *uri;
gboolean success;
g_assert (calendar_client != NULL);
g_assert (cal_client_get_load_state (calendar_client) == CAL_CLIENT_LOAD_LOADED);
tasks_client = cal_client_new ();
if (!tasks_client)
goto error;
gtk_signal_connect (GTK_OBJECT (tasks_client), "cal_opened",
GTK_SIGNAL_FUNC (tasks_opened_cb),
NULL);
uri = g_strdup_printf ("%s/local/Tasks/tasks.ics", evolution_dir);
success = cal_client_open_calendar (tasks_client, uri, FALSE);
g_free (uri);
if (success)
return TRUE;
error:
g_message ("load_tasks_client(): could not issue open request for the tasks client");
if (tasks_client) {
gtk_object_unref (GTK_OBJECT (tasks_client));
tasks_client = NULL;
}
return FALSE;
}
/* Callback used when the calendar client finishes loading */
static void
calendar_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer data)
{
switch (status) {
case CAL_CLIENT_OPEN_SUCCESS:
if (!load_tasks_client ()) {
migrated = FALSE;
break;
}
return;
case CAL_CLIENT_OPEN_ERROR:
open_error (cal_client_get_uri (client));
migrated = FALSE;
break;
case CAL_CLIENT_OPEN_NOT_FOUND:
/* This is OK; the calendar folder did not exist in the first
* place so there is nothing to migrate.
*/
break;
case CAL_CLIENT_OPEN_METHOD_NOT_SUPPORTED:
method_error (cal_client_get_uri (client));
migrated = FALSE;
break;
default:
g_assert_not_reached ();
}
gtk_object_unref (GTK_OBJECT (calendar_client));
calendar_client = NULL;
}
/* Initiates the loading process for the calendar client */
static gboolean
load_calendar_client (void)
{
char *uri;
gboolean success;
/* First we load the calendar client; the tasks client will be loaded
* later only if the former one succeeds.
*/
calendar_client = cal_client_new ();
if (!calendar_client)
goto error;
gtk_signal_connect (GTK_OBJECT (calendar_client), "cal_opened",
GTK_SIGNAL_FUNC (calendar_opened_cb),
NULL);
uri = g_strdup_printf ("%s/local/Calendar/calendar.ics", evolution_dir);
success = cal_client_open_calendar (calendar_client, uri, TRUE);
g_free (uri);
if (success)
return TRUE;
error:
g_message ("load_calendar_client(): could not issue open request for the calendar client");
if (calendar_client) {
gtk_object_unref (GTK_OBJECT (calendar_client));
calendar_client = NULL;
}
return FALSE;
}
/**
* tasks_migrate:
*
* Initiates the asynchronous process that migrates the tasks from the default
* user calendar folder to the default tasks folder. This is because Evolution
* used to store tasks in the same folder as the calendar by default, but they
* are separate folders now.
**/
void
tasks_migrate (void)
{
g_assert (!migrated);
migrated = TRUE;
if (!load_calendar_client ())
migrated = FALSE;
}