diff options
Diffstat (limited to 'calendar/gui')
-rw-r--r-- | calendar/gui/comp-util.c | 363 | ||||
-rw-r--r-- | calendar/gui/comp-util.h | 17 | ||||
-rw-r--r-- | calendar/gui/e-calendar-selector.c | 320 |
3 files changed, 599 insertions, 101 deletions
diff --git a/calendar/gui/comp-util.c b/calendar/gui/comp-util.c index be6721164c..a5c231e0eb 100644 --- a/calendar/gui/comp-util.c +++ b/calendar/gui/comp-util.c @@ -822,3 +822,366 @@ icalcomp_suggest_filename (icalcomponent *icalcomp, return g_strconcat (summary, ".ics", NULL); } + +typedef struct _AsyncContext { + ECalClient *src_client; + icalcomponent *icalcomp_clone; + gboolean do_copy; +} AsyncContext; + +struct ForeachTzidData +{ + ECalClient *source_client; + ECalClient *destination_client; + GCancellable *cancellable; + GError **error; + gboolean success; +}; + +static void +async_context_free (AsyncContext *async_context) +{ + if (async_context->src_client) + g_object_unref (async_context->src_client); + + if (async_context->icalcomp_clone) + icalcomponent_free (async_context->icalcomp_clone); + + g_slice_free (AsyncContext, async_context); +} + +static void +add_timezone_to_cal_cb (icalparameter *param, + gpointer data) +{ + struct ForeachTzidData *ftd = data; + icaltimezone *tz = NULL; + const gchar *tzid; + + g_return_if_fail (ftd != NULL); + g_return_if_fail (ftd->source_client != NULL); + g_return_if_fail (ftd->destination_client != NULL); + + if (!ftd->success) + return; + + if (ftd->cancellable && g_cancellable_is_cancelled (ftd->cancellable)) { + ftd->success = FALSE; + return; + } + + tzid = icalparameter_get_tzid (param); + if (!tzid || !*tzid) + return; + + if (e_cal_client_get_timezone_sync (ftd->source_client, tzid, &tz, ftd->cancellable, NULL) && tz) + ftd->success = e_cal_client_add_timezone_sync ( + ftd->destination_client, tz, ftd->cancellable, ftd->error); +} + +/* Helper for cal_comp_transfer_item_to() */ +static void +cal_comp_transfer_item_to_thread (GSimpleAsyncResult *simple, + GObject *source_object, + GCancellable *cancellable) +{ + AsyncContext *async_context; + GError *local_error = NULL; + + async_context = g_simple_async_result_get_op_res_gpointer (simple); + + cal_comp_transfer_item_to_sync ( + async_context->src_client, + E_CAL_CLIENT (source_object), + async_context->icalcomp_clone, + async_context->do_copy, + cancellable, &local_error); + + if (local_error != NULL) + g_simple_async_result_take_error (simple, local_error); +} + +void +cal_comp_transfer_item_to (ECalClient *src_client, + ECalClient *dest_client, + icalcomponent *icalcomp_vcal, + gboolean do_copy, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + AsyncContext *async_context; + + g_return_val_if_fail (E_IS_CAL_CLIENT (src_client), FALSE); + g_return_val_if_fail (E_IS_CAL_CLIENT (dest_client), FALSE); + g_return_val_if_fail (icalcomp_vcal != NULL, FALSE); + + async_context = g_slice_new0 (AsyncContext); + async_context->src_client = g_object_ref (src_client); + async_context->icalcomp_clone = icalcomponent_new_clone (icalcomp_vcal); + async_context->do_copy = do_copy; + + simple = g_simple_async_result_new ( + G_OBJECT (dest_client), callback, user_data, + cal_comp_transfer_item_to); + + g_simple_async_result_set_check_cancellable (simple, cancellable); + + g_simple_async_result_set_op_res_gpointer ( + simple, async_context, (GDestroyNotify) async_context_free); + + g_simple_async_result_run_in_thread ( + simple, cal_comp_transfer_item_to_thread, + G_PRIORITY_DEFAULT, cancellable); + + g_object_unref (simple); +} + +gboolean +cal_comp_transfer_item_to_finish (ECalClient *client, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail ( + g_simple_async_result_is_valid (result, G_OBJECT (client), cal_comp_transfer_item_to), + FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + + return TRUE; +} + +gboolean +cal_comp_transfer_item_to_sync (ECalClient *src_client, + ECalClient *dest_client, + icalcomponent *icalcomp_vcal, + gboolean do_copy, + GCancellable *cancellable, + GError **error) +{ + icalcomponent *icalcomp; + icalcomponent *icalcomp_event, *subcomp; + icalcomponent_kind icalcomp_kind; + const gchar *uid; + gchar *new_uid = NULL; + struct ForeachTzidData ftd; + ECalClientSourceType source_type; + GHashTable *processed_uids; + gboolean success = FALSE; + + g_return_val_if_fail (E_IS_CAL_CLIENT (src_client), FALSE); + g_return_val_if_fail (E_IS_CAL_CLIENT (dest_client), FALSE); + g_return_val_if_fail (icalcomp_vcal != NULL, FALSE); + + icalcomp_event = icalcomponent_get_inner (icalcomp_vcal); + g_return_val_if_fail (icalcomp_event != NULL, FALSE); + + source_type = e_cal_client_get_source_type (src_client); + switch (source_type) { + case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: + icalcomp_kind = ICAL_VEVENT_COMPONENT; + break; + case E_CAL_CLIENT_SOURCE_TYPE_TASKS: + icalcomp_kind = ICAL_VTODO_COMPONENT; + break; + case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: + icalcomp_kind = ICAL_VJOURNAL_COMPONENT; + break; + default: + g_return_val_if_reached (FALSE); + } + + processed_uids = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + + icalcomp_event = icalcomponent_get_first_component (icalcomp_vcal, icalcomp_kind); + /* + * This check should be removed in the near future. + * We should be able to work properly with multiselection, which means that we always + * will receive a component with subcomponents. + */ + if (icalcomp_event == NULL) + icalcomp_event = icalcomp_vcal; + for (; + icalcomp_event; + icalcomp_event = icalcomponent_get_next_component (icalcomp_vcal, icalcomp_kind)) { + GError *local_error = NULL; + + uid = icalcomponent_get_uid (icalcomp_event); + + if (g_hash_table_lookup (processed_uids, uid)) + continue; + + success = e_cal_client_get_object_sync (dest_client, uid, NULL, &icalcomp, cancellable, &local_error); + if (success) { + success = e_cal_client_modify_object_sync ( + dest_client, icalcomp_event, CALOBJ_MOD_ALL, cancellable, error); + + icalcomponent_free (icalcomp); + if (!success) + goto exit; + + if (!do_copy) { + ECalObjModType mod_type = CALOBJ_MOD_THIS; + + /* Remove the item from the source calendar. */ + if (e_cal_util_component_is_instance (icalcomp_event) || + e_cal_util_component_has_recurrences (icalcomp_event)) + mod_type = CALOBJ_MOD_ALL; + + success = e_cal_client_remove_object_sync ( + src_client, uid, NULL, mod_type, cancellable, error); + if (!success) + goto exit; + } + + continue; + } else if (local_error != NULL && !g_error_matches ( + local_error, E_CAL_CLIENT_ERROR, E_CAL_CLIENT_ERROR_OBJECT_NOT_FOUND)) { + g_propagate_error (error, local_error); + goto exit; + } else { + g_clear_error (&local_error); + } + + if (e_cal_util_component_is_instance (icalcomp_event)) { + GSList *ecalcomps = NULL, *eiter; + ECalComponent *comp ; + + success = e_cal_client_get_objects_for_uid_sync (src_client, uid, &ecalcomps, cancellable, error); + if (!success) + goto exit; + + if (ecalcomps && !ecalcomps->next) { + /* only one component, no need for a vCalendar list */ + comp = ecalcomps->data; + icalcomp = icalcomponent_new_clone (e_cal_component_get_icalcomponent (comp)); + } else { + icalcomp = icalcomponent_new (ICAL_VCALENDAR_COMPONENT); + for (eiter = ecalcomps; eiter; eiter = g_slist_next (eiter)) { + comp = eiter->data; + + icalcomponent_add_component (icalcomp, + icalcomponent_new_clone (e_cal_component_get_icalcomponent (comp))); + } + } + + e_cal_client_free_ecalcomp_slist (ecalcomps); + } else { + icalcomp = icalcomponent_new_clone (icalcomp_event); + } + + if (do_copy) { + /* Change the UID to avoid problems with duplicated UID */ + new_uid = e_cal_component_gen_uid (); + if (icalcomponent_isa (icalcomp) == ICAL_VCALENDAR_COMPONENT) { + /* in case of a vCalendar, the component might have detached instances, + thus change the UID on all of the subcomponents of it */ + for (subcomp = icalcomponent_get_first_component (icalcomp, icalcomp_kind); + subcomp; + subcomp = icalcomponent_get_next_component (icalcomp, icalcomp_kind)) { + icalcomponent_set_uid (subcomp, new_uid); + } + } else { + icalcomponent_set_uid (icalcomp, new_uid); + } + g_free (new_uid); + new_uid = NULL; + } + + ftd.source_client = src_client; + ftd.destination_client = dest_client; + ftd.cancellable = cancellable; + ftd.error = error; + ftd.success = TRUE; + + if (icalcomponent_isa (icalcomp) == ICAL_VCALENDAR_COMPONENT) { + /* in case of a vCalendar, the component might have detached instances, + thus check timezones on all of the subcomponents of it */ + for (subcomp = icalcomponent_get_first_component (icalcomp, icalcomp_kind); + subcomp && ftd.success; + subcomp = icalcomponent_get_next_component (icalcomp, icalcomp_kind)) { + icalcomponent_foreach_tzid (subcomp, add_timezone_to_cal_cb, &ftd); + } + } else { + icalcomponent_foreach_tzid (icalcomp, add_timezone_to_cal_cb, &ftd); + } + + if (!ftd.success) { + success = FALSE; + goto exit; + } + + if (icalcomponent_isa (icalcomp) == ICAL_VCALENDAR_COMPONENT) { + gboolean did_add = FALSE; + + /* in case of a vCalendar, the component might have detached instances, + thus add the master object first, and then all of the subcomponents of it */ + for (subcomp = icalcomponent_get_first_component (icalcomp, icalcomp_kind); + subcomp && !did_add; + subcomp = icalcomponent_get_next_component (icalcomp, icalcomp_kind)) { + if (icaltime_is_null_time (icalcomponent_get_recurrenceid (subcomp))) { + did_add = TRUE; + success = e_cal_client_create_object_sync (dest_client, subcomp, + &new_uid, cancellable, error); + g_free (new_uid); + } + } + + if (!success) { + icalcomponent_free (icalcomp); + goto exit; + } + + /* deal with detached instances */ + for (subcomp = icalcomponent_get_first_component (icalcomp, icalcomp_kind); + subcomp && success; + subcomp = icalcomponent_get_next_component (icalcomp, icalcomp_kind)) { + if (!icaltime_is_null_time (icalcomponent_get_recurrenceid (subcomp))) { + if (did_add) { + success = e_cal_client_modify_object_sync (dest_client, subcomp, + CALOBJ_MOD_THIS, cancellable, error); + } else { + /* just in case there are only detached instances and no master object */ + did_add = TRUE; + success = e_cal_client_create_object_sync (dest_client, subcomp, + &new_uid, cancellable, error); + g_free (new_uid); + } + } + } + } else { + success = e_cal_client_create_object_sync (dest_client, icalcomp, &new_uid, cancellable, error); + g_free (new_uid); + } + + icalcomponent_free (icalcomp); + if (!success) + goto exit; + + if (!do_copy) { + ECalObjModType mod_type = CALOBJ_MOD_THIS; + + /* Remove the item from the source calendar. */ + if (e_cal_util_component_is_instance (icalcomp_event) || + e_cal_util_component_has_recurrences (icalcomp_event)) + mod_type = CALOBJ_MOD_ALL; + + success = e_cal_client_remove_object_sync (src_client, uid, NULL, mod_type, cancellable, error); + if (!success) + goto exit; + } + + g_hash_table_insert (processed_uids, g_strdup (uid), GINT_TO_POINTER (1)); + } + + exit: + g_hash_table_destroy (processed_uids); + + return success; +} diff --git a/calendar/gui/comp-util.h b/calendar/gui/comp-util.h index dcf5844c79..56ddd54e08 100644 --- a/calendar/gui/comp-util.h +++ b/calendar/gui/comp-util.h @@ -75,4 +75,21 @@ void comp_util_sanitize_recurrence_master (ECalComponent *comp, ECalClient *clie gchar *icalcomp_suggest_filename (icalcomponent *icalcomp, const gchar *default_name); +void cal_comp_transfer_item_to (ECalClient *src_client, + ECalClient *dest_client, + icalcomponent *icalcomp_vcal, + gboolean do_copy, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean cal_comp_transfer_item_to_finish (ECalClient *client, + GAsyncResult *result, + GError **error); +gboolean cal_comp_transfer_item_to_sync (ECalClient *src_client, + ECalClient *dest_client, + icalcomponent *icalcomp_event, + gboolean do_copy, + GCancellable *cancellable, + GError **error); + #endif diff --git a/calendar/gui/e-calendar-selector.c b/calendar/gui/e-calendar-selector.c index 9557c44f9a..b588c6a107 100644 --- a/calendar/gui/e-calendar-selector.c +++ b/calendar/gui/e-calendar-selector.c @@ -20,7 +20,10 @@ #include <config.h> +#include <glib/gi18n.h> + #include "e-calendar-selector.h" +#include "comp-util.h" #include <libecal/libecal.h> @@ -30,6 +33,8 @@ struct _ECalendarSelectorPrivate { EShellView *shell_view; + + gpointer transfer_alert; /* weak pointer to EAlert */ }; G_DEFINE_TYPE ( @@ -42,118 +47,188 @@ enum { PROP_SHELL_VIEW, }; -static gboolean -calendar_selector_update_single_object (ECalClient *client, - icalcomponent *icalcomp) +static void +cal_transferring_update_alert (ECalendarSelector *calendar_selector, + EShellView *shell_view, + const gchar *domain, + const gchar *calendar, + const gchar *message) { - gchar *uid; - icalcomponent *tmp_icalcomp = NULL; - gboolean success; - - uid = (gchar *) icalcomponent_get_uid (icalcomp); + ECalendarSelectorPrivate *priv; + EShellContent *shell_content; + EAlert *alert; - e_cal_client_get_object_sync ( - client, uid, NULL, &tmp_icalcomp, NULL, NULL); + g_return_if_fail (calendar_selector != NULL); + g_return_if_fail (calendar_selector->priv != NULL); - if (tmp_icalcomp != NULL) { - icalcomponent_free (tmp_icalcomp); + priv = calendar_selector->priv; - return e_cal_client_modify_object_sync ( - client, icalcomp, CALOBJ_MOD_ALL, NULL, NULL); + if (priv->transfer_alert) { + e_alert_response ( + priv->transfer_alert, + e_alert_get_default_response (priv->transfer_alert)); + priv->transfer_alert = NULL; } - uid = NULL; - success = e_cal_client_create_object_sync ( - client, icalcomp, &uid, NULL, NULL); + if (!message) + return; - if (uid != NULL) { - icalcomponent_set_uid (icalcomp, uid); - g_free (uid); - } + alert = e_alert_new (domain, calendar, message, NULL); + g_return_if_fail (alert != NULL); - return success; + priv->transfer_alert = alert; + g_object_add_weak_pointer (G_OBJECT (alert), &priv->transfer_alert); + e_alert_start_timer (priv->transfer_alert, 300); + + shell_content = e_shell_view_get_shell_content (shell_view); + e_alert_sink_submit_alert (E_ALERT_SINK (shell_content), priv->transfer_alert); + g_object_unref (priv->transfer_alert); } -static gboolean -calendar_selector_update_objects (ECalClient *client, - icalcomponent *icalcomp) +typedef struct _TransferItemToData { + ESource *destination; + ESourceSelector *selector; + EClient *src_client; + EShellView *shell_view; + EActivity *activity; + icalcomponent *icalcomp; + const gchar *display_name; + gboolean do_copy; +} TransferItemToData; + +static void +transfer_item_to_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) { - icalcomponent *subcomp; - icalcomponent_kind kind; - - kind = icalcomponent_isa (icalcomp); - if (kind == ICAL_VTODO_COMPONENT || kind == ICAL_VEVENT_COMPONENT) - return calendar_selector_update_single_object ( - client, icalcomp); - else if (kind != ICAL_VCALENDAR_COMPONENT) - return FALSE; - - subcomp = icalcomponent_get_first_component ( - icalcomp, ICAL_ANY_COMPONENT); - while (subcomp != NULL) { - gboolean success; - - kind = icalcomponent_isa (subcomp); - if (kind == ICAL_VTIMEZONE_COMPONENT) { - icaltimezone *zone; - GError *error = NULL; - - zone = icaltimezone_new (); - icaltimezone_set_component (zone, subcomp); - - e_cal_client_add_timezone_sync (client, zone, NULL, &error); - icaltimezone_free (zone, 1); - - if (error != NULL) { - g_warning ( - "%s: Failed to add timezone: %s", - G_STRFUNC, error->message); - g_error_free (error); - return FALSE; - } - } else if (kind == ICAL_VTODO_COMPONENT || - kind == ICAL_VEVENT_COMPONENT) { - success = calendar_selector_update_single_object ( - client, subcomp); - if (!success) - return FALSE; - } - - subcomp = icalcomponent_get_next_component ( - icalcomp, ICAL_ANY_COMPONENT); + TransferItemToData *titd = user_data; + GError *error = NULL; + GCancellable *cancellable; + gboolean success; + + success = cal_comp_transfer_item_to_finish (E_CAL_CLIENT (source_object), result, &error); + + if (!success) { + cal_transferring_update_alert ( + E_CALENDAR_SELECTOR (titd->selector), + titd->shell_view, + titd->do_copy ? "calendar:failed-copy-event" : "calendar:failed-move-event", + titd->display_name, + error->message); + g_clear_error (&error); } - return TRUE; + cancellable = e_activity_get_cancellable (titd->activity); + e_activity_set_state ( + titd->activity, + g_cancellable_is_cancelled (cancellable) ? E_ACTIVITY_CANCELLED : E_ACTIVITY_COMPLETED); + + g_object_unref (titd->activity); + icalcomponent_free (titd->icalcomp); + g_free (titd); } static void -client_connect_cb (GObject *source_object, - GAsyncResult *result, - gpointer user_data) +destination_client_connect_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) { EClient *client; - icalcomponent *icalcomp = user_data; + TransferItemToData *titd = user_data; + GCancellable *cancellable; GError *error = NULL; - g_return_if_fail (icalcomp != NULL); + client = e_client_selector_get_client_finish (E_CLIENT_SELECTOR (source_object), result, &error); + + /* Sanity check. */ + g_return_if_fail ( + ((client != NULL) && (error == NULL)) || + ((client == NULL) && (error != NULL))); + + cancellable = e_activity_get_cancellable (titd->activity); + + if (error != NULL) { + cal_transferring_update_alert ( + E_CALENDAR_SELECTOR (titd->selector), + titd->shell_view, + titd->do_copy ? "calendar:failed-copy-event" : "calendar:failed-move-event", + titd->display_name, + error->message); + g_clear_error (&error); + + goto exit; + } + + if (g_cancellable_is_cancelled (cancellable)) + goto exit; + + cal_comp_transfer_item_to ( + E_CAL_CLIENT (titd->src_client), E_CAL_CLIENT (client), + titd->icalcomp, titd->do_copy, cancellable, transfer_item_to_cb, titd); + + return; + +exit: + e_activity_set_state ( + titd->activity, + g_cancellable_is_cancelled (cancellable) ? E_ACTIVITY_CANCELLED : E_ACTIVITY_COMPLETED); + + g_object_unref (titd->activity); + icalcomponent_free (titd->icalcomp); + g_free (titd); + +} + +static void +source_client_connect_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + EClient *client; + TransferItemToData *titd = user_data; + GCancellable *cancellable; + GError *error = NULL; - client = e_client_selector_get_client_finish ( - E_CLIENT_SELECTOR (source_object), result, &error); + client = e_client_selector_get_client_finish (E_CLIENT_SELECTOR (source_object), result, &error); /* Sanity check. */ g_return_if_fail ( ((client != NULL) && (error == NULL)) || ((client == NULL) && (error != NULL))); + cancellable = e_activity_get_cancellable (titd->activity); + if (error != NULL) { - g_warning ("%s: %s", G_STRFUNC, error->message); - g_error_free (error); + cal_transferring_update_alert ( + E_CALENDAR_SELECTOR (titd->selector), + titd->shell_view, + titd->do_copy ? "calendar:failed-copy-event" : "calendar:failed-move-event", + titd->display_name, + error->message); + g_clear_error (&error); + + goto exit; } - calendar_selector_update_objects (E_CAL_CLIENT (client), icalcomp); - g_object_unref (client); + if (g_cancellable_is_cancelled (cancellable)) + goto exit; + + titd->src_client = client; + + e_client_selector_get_client ( + E_CLIENT_SELECTOR (titd->selector), titd->destination, cancellable, + destination_client_connect_cb, titd); + + return; + +exit: + e_activity_set_state ( + titd->activity, + g_cancellable_is_cancelled (cancellable) ? E_ACTIVITY_CANCELLED : E_ACTIVITY_COMPLETED); - icalcomponent_free (icalcomp); + g_object_unref (titd->activity); + icalcomponent_free (titd->icalcomp); + g_free (titd); } static void @@ -239,40 +314,83 @@ calendar_selector_data_dropped (ESourceSelector *selector, GdkDragAction action, guint info) { - GtkTreePath *path = NULL; icalcomponent *icalcomp; + EActivity *activity; + EShellBackend *shell_backend; + EShellView *shell_view; + ESource *source; + ESourceRegistry *registry; + GCancellable *cancellable; + gchar **segments; + gchar *source_uid = NULL; + gchar *message; + const gchar *display_name; const guchar *data; - gboolean success = FALSE; - gpointer object = NULL; + gboolean do_copy; + TransferItemToData *titd; data = gtk_selection_data_get_data (selection_data); - icalcomp = icalparser_parse_string ((const gchar *) data); + g_return_val_if_fail (data != NULL, FALSE); - if (icalcomp == NULL) + segments = g_strsplit ((const gchar *) data, "\n", 2); + if (g_strv_length (segments) != 2) goto exit; - /* FIXME Deal with GDK_ACTION_ASK. */ - if (action == GDK_ACTION_COPY) { - gchar *uid; + source_uid = g_strdup (segments[0]); + icalcomp = icalparser_parse_string (segments[1]); - uid = e_cal_component_gen_uid (); - icalcomponent_set_uid (icalcomp, uid); - } + if (!icalcomp) + goto exit; - e_client_selector_get_client ( - E_CLIENT_SELECTOR (selector), destination, NULL, - client_connect_cb, icalcomp); + registry = e_source_selector_get_registry (selector); + source = e_source_registry_ref_source (registry, source_uid); + if (!source) + goto exit; + + shell_view = e_calendar_selector_get_shell_view (E_CALENDAR_SELECTOR (selector)); + shell_backend = e_shell_view_get_shell_backend (shell_view); - success = TRUE; + display_name = e_source_get_display_name (destination); + + do_copy = action == GDK_ACTION_COPY ? TRUE : FALSE; + + message = do_copy ? + g_strdup_printf (_("Copying an event into the calendar %s"), display_name) : + g_strdup_printf (_("Moving an event into the calendar %s"), display_name); + + cancellable = g_cancellable_new (); + activity = e_activity_new (); + e_activity_set_cancellable (activity, cancellable); + e_activity_set_state (activity, E_ACTIVITY_RUNNING); + e_activity_set_text (activity, message); + g_free (message); + + e_shell_backend_add_activity (shell_backend, activity); + + titd = g_new0 (TransferItemToData, 1); + + titd->destination = destination; + titd->icalcomp = icalcomponent_new_clone (icalcomp); + titd->selector = selector; + titd->shell_view = shell_view; + titd->activity = activity; + titd->display_name = display_name; + titd->do_copy = do_copy; + + e_client_selector_get_client ( + E_CLIENT_SELECTOR (selector), source, cancellable, + source_client_connect_cb, titd); exit: - if (path != NULL) - gtk_tree_path_free (path); + if (source) + g_object_unref (source); - if (object != NULL) - g_object_unref (object); + if (icalcomp) + icalcomponent_free (icalcomp); - return success; + g_free (source_uid); + g_strfreev (segments); + return TRUE; } static void |