Rodrigo, New patch based on HEAD is attached. As I tested, it works. Copy and Paste works now as before, too. Thanks! Harry Rodrigo Moya wrote: On Mon, 2003-10-20 at 12:38, Harry Lu wrote:Rodrigo, Ping :) How about this patch? Harryhave you been able to test it now? As you might know, you can create calendars now from the UI, so that should give you the chance to test it. the path looks mostly ok, but please, first make sure it works, and then submit the patch again when so, and I'll approve it, after testing it. Right now, since new-ui-branch still crashes like crazy for me on startup, I cannot test it :-( so please, do it yourself, if it doesnt crash for you. cheers |
Index: calendar//ChangeLog =================================================================== RCS file: /cvs/gnome/evolution/calendar/ChangeLog,v retrieving revision 1.1882 diff -u -r1.1882 ChangeLog --- calendar//ChangeLog 21 Oct 2003 22:30:58 -0000 1.1882 +++ calendar//ChangeLog 22 Oct 2003 08:37:39 -0000 @@ -1,3 +1,18 @@ +2003-10-22 Harry Lu <harry lu sun com> + + * cal-client/cal-client.c: (cal_client_get_timezone): remove and free + op before return. + * gui/e-cal-view.c (e_cal_view_add_event): modified from + selection_received_add_event() so that it call be called out of + e-cal-view.c. + (selection_received): modified to call e_cal_view_add_event(). + * gui/e-cal-view.h: add declaration for e_cal_view_add_event(). + * gui/e-day-view.c (e_day_view_on_drag_data_get): Provide a + icalcomponent for both TARGET_CALENDAR_EVENT and TARGET_VCALENDAR. + (e_day_view_on_top_canvas_drag_data_received): If dragging between + different windows, make it works like a copy and paste. + (e_day_view_on_main_canvas_drag_data_received): ditto. + 2003-10-21 Rodney Dawes <dobey ximian com> * cal-client/Makefile.am: Fix typo in libcal_client_la_SOURCES Index: calendar//cal-client/cal-client.c =================================================================== RCS file: /cvs/gnome/evolution/calendar/cal-client/cal-client.c,v retrieving revision 1.126 diff -u -r1.126 cal-client.c --- calendar//cal-client/cal-client.c 21 Oct 2003 18:49:12 -0000 1.126 +++ calendar//cal-client/cal-client.c 22 Oct 2003 08:37:42 -0000 @@ -3482,12 +3482,21 @@ g_free (our_op->string); /* FIXME Invalid object status? */ - if (!icalcomp) + if (!icalcomp) { + e_calendar_remove_op (client, our_op); + e_mutex_unlock (our_op->mutex); + e_calendar_free_op (our_op); + E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OBJECT_NOT_FOUND, error); + } *zone = icaltimezone_new (); if (!icaltimezone_set_component (*zone, icalcomp)) { icaltimezone_free (*zone, 1); + + e_calendar_remove_op (client, our_op); + e_mutex_unlock (our_op->mutex); + e_calendar_free_op (our_op); E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OBJECT_NOT_FOUND, error); } Index: calendar//gui/e-cal-view.c =================================================================== RCS file: /cvs/gnome/evolution/calendar/gui/e-cal-view.c,v retrieving revision 1.16 diff -u -r1.16 e-cal-view.c --- calendar//gui/e-cal-view.c 21 Oct 2003 18:49:21 -0000 1.16 +++ calendar//gui/e-cal-view.c 22 Oct 2003 08:37:44 -0000 @@ -268,23 +268,51 @@ } } -static void -selection_received_add_event (ECalView *cal_view, CalClient *client, time_t selected_time_start, - icaltimezone *default_zone, icalcomponent *icalcomp) +void +e_cal_view_add_event (ECalView *cal_view, CalClient *client, time_t dtstart, + icaltimezone *default_zone, icalcomponent *icalcomp, gboolean in_top_canvas) { CalComponent *comp; - struct icaltimetype itime; - time_t tt_start, tt_end; + struct icaltimetype itime, old_dtstart, old_dtend; + time_t tt_start, tt_end, new_dtstart; struct icaldurationtype ic_dur; char *uid; + gint start_offset, end_offset; + gboolean all_day_event; + + start_offset = 0; + end_offset = 0; - tt_start = icaltime_as_timet (icalcomponent_get_dtstart (icalcomp)); - tt_end = icaltime_as_timet (icalcomponent_get_dtend (icalcomp)); + old_dtstart = icalcomponent_get_dtstart (icalcomp); + tt_start = icaltime_as_timet (old_dtstart); + old_dtend = icalcomponent_get_dtend (icalcomp); + tt_end = icaltime_as_timet (old_dtend); ic_dur = icaldurationtype_from_int (tt_end - tt_start); - itime = icaltime_from_timet_with_zone (selected_time_start, FALSE, default_zone); + if (icaldurationtype_as_int (ic_dur) > 60*60*24) { + /* This is a long event */ + start_offset = old_dtstart.hour * 60 + old_dtstart.minute; + end_offset = old_dtstart.hour * 60 + old_dtend.minute; + } + + if (start_offset == 0 && end_offset == 0 && in_top_canvas) + all_day_event = TRUE; + else + all_day_event = FALSE; + + if (in_top_canvas) + new_dtstart = dtstart + start_offset * 60; + else + new_dtstart = dtstart; + + itime = icaltime_from_timet_with_zone (new_dtstart, FALSE, default_zone); + if (all_day_event) + itime.is_date = TRUE; icalcomponent_set_dtstart (icalcomp, itime); + itime = icaltime_add (itime, ic_dur); + if (all_day_event) + itime.is_date = TRUE; icalcomponent_set_dtend (icalcomp, itime); /* FIXME The new uid stuff can go away once we actually set it in the backend */ @@ -295,12 +323,15 @@ cal_component_set_uid (comp, uid); /* FIXME Error handling */ - cal_client_create_object (client, cal_component_get_icalcomponent (comp), NULL, NULL); - if (itip_organizer_is_user (comp, client) && - send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)), + if (cal_client_create_object (client, cal_component_get_icalcomponent (comp), NULL, NULL)) { + if (itip_organizer_is_user (comp, client) && + send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)), client, comp, TRUE)) { - itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp, + itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp, client, NULL); + } + } else { + g_message (G_STRLOC ": Could not create the object!"); } free (uid); @@ -356,8 +387,8 @@ while (subcomp) { child_kind = icalcomponent_isa (subcomp); if (child_kind == ICAL_VEVENT_COMPONENT) - selection_received_add_event (cal_view, client, selected_time_start, - default_zone, subcomp); + e_cal_view_add_event (cal_view, client, selected_time_start, + default_zone, subcomp, FALSE); else if (child_kind == ICAL_VTIMEZONE_COMPONENT) { icaltimezone *zone; @@ -375,7 +406,7 @@ icalcomponent_free (icalcomp); } else { - selection_received_add_event (cal_view, client, selected_time_start, default_zone, icalcomp); + e_cal_view_add_event (cal_view, client, selected_time_start, default_zone, icalcomp, FALSE); } e_cal_view_set_status_message (cal_view, NULL); Index: calendar//gui/e-cal-view.h =================================================================== RCS file: /cvs/gnome/evolution/calendar/gui/e-cal-view.h,v retrieving revision 1.12 diff -u -r1.12 e-cal-view.h --- calendar//gui/e-cal-view.h 21 Oct 2003 18:49:21 -0000 1.12 +++ calendar//gui/e-cal-view.h 22 Oct 2003 08:37:44 -0000 @@ -116,6 +116,8 @@ GtkMenu *e_cal_view_create_popup_menu (ECalView *cal_view); +void e_cal_view_add_event (ECalView *cal_view, CalClient *client, time_t dtstart, + icaltimezone *default_zone, icalcomponent *icalcomp, gboolean in_top_canvas); void e_cal_view_new_appointment_for (ECalView *cal_view, time_t dtstart, time_t dtend, Index: calendar//gui/e-day-view.c =================================================================== RCS file: /cvs/gnome/evolution/calendar/gui/e-day-view.c,v retrieving revision 1.220 diff -u -r1.220 e-day-view.c --- calendar//gui/e-day-view.c 21 Oct 2003 18:49:21 -0000 1.220 +++ calendar//gui/e-day-view.c 22 Oct 2003 08:37:54 -0000 @@ -6734,15 +6734,8 @@ event = &g_array_index (day_view->events[day], EDayViewEvent, event_num); - if (info == TARGET_CALENDAR_EVENT) { - const char *event_uid; - - event_uid = icalcomponent_get_uid (event->comp_data->icalcomp); - g_return_if_fail (event_uid != NULL); - - gtk_selection_data_set (selection_data, selection_data->target, - 8, event_uid, strlen (event_uid)); - } else if (info == TARGET_VCALENDAR) { + if (info == TARGET_CALENDAR_EVENT || info == TARGET_VCALENDAR) { + /* we will pass an icalcalendar component for both types */ char *comp_str; icalcomponent *vcal; @@ -6777,26 +6770,32 @@ ECalViewPosition pos; gint day, start_day, end_day, num_days; gint start_offset, end_offset; - gchar *event_uid; CalComponent *comp; CalComponentDateTime date; struct icaltimetype itt; time_t dt; gboolean all_day_event; CalClient *client; + gboolean drag_from_same_window; + + if (day_view->drag_event_day != -1) + drag_from_same_window = TRUE; + else + drag_from_same_window = FALSE; client = e_cal_model_get_default_client (e_cal_view_get_model (E_CAL_VIEW (day_view))); /* Note that we only support DnD within the EDayView at present. */ if ((data->length >= 0) && (data->format == 8) && (day_view->drag_event_day != -1)) { + /* We are dragging in the same window */ + pos = e_day_view_convert_position_in_top_canvas (day_view, x, y, &day, NULL); if (pos != E_CAL_VIEW_POS_OUTSIDE) { CalObjModType mod = CALOBJ_MOD_ALL; GtkWindow *toplevel; - const char *uid; num_days = 1; start_offset = 0; @@ -6827,13 +6826,6 @@ client = event->comp_data->client; - event_uid = data->data; - - uid = icalcomponent_get_uid (event->comp_data->icalcomp); - - if (!event_uid || !uid || strcmp (event_uid, uid)) - g_warning ("Unexpected event UID"); - /* We clone the event since we don't want to change the original comp here. Otherwise we would not detect that the event's time @@ -6894,6 +6886,7 @@ } toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (day_view))); + cal_component_commit_sequence (comp); if (cal_client_modify_object (client, cal_component_get_icalcomponent (comp), mod, NULL)) { if (itip_organizer_is_user (comp, client) @@ -6908,6 +6901,72 @@ } } + if ((data->length >= 0) && (data->format == 8) + && !drag_from_same_window) { + /* We are dragging between different window */ + + char *comp_str, *default_tzid; + icalcomponent *icalcomp; + icalcomponent_kind kind; + time_t dtstart; + icaltimezone *default_zone; + + pos = e_day_view_convert_position_in_top_canvas (day_view, + x, y, &day, + NULL); + if (pos == E_CAL_VIEW_POS_OUTSIDE) + goto error; + + comp_str = (char *) data->data; + icalcomp = icalparser_parse_string ((const char *) comp_str); + if (!icalcomp) + goto error; + + default_tzid = calendar_config_get_timezone (); + cal_client_get_timezone (client, default_tzid, &default_zone, NULL); + + /* check the type of the component */ + kind = icalcomponent_isa (icalcomp); + if (kind != ICAL_VCALENDAR_COMPONENT && kind != ICAL_VEVENT_COMPONENT) + goto error; + + dtstart = day_view->day_starts[day]; + + if (kind == ICAL_VCALENDAR_COMPONENT) { + icalcomponent_kind child_kind; + icalcomponent *subcomp; + + subcomp = icalcomponent_get_first_component (icalcomp, ICAL_ANY_COMPONENT); + while (subcomp) { + child_kind = icalcomponent_isa (subcomp); + if (child_kind == ICAL_VEVENT_COMPONENT) + e_cal_view_add_event (E_CAL_VIEW (day_view), client, dtstart, + default_zone, subcomp, TRUE); + else if (child_kind == ICAL_VTIMEZONE_COMPONENT) { + icaltimezone *zone; + + zone = icaltimezone_new (); + icaltimezone_set_component (zone, subcomp); + cal_client_add_timezone (client, zone, NULL); + + icaltimezone_free (zone, 1); + } + + subcomp = icalcomponent_get_next_component ( + icalcomp, ICAL_ANY_COMPONENT); + } + + icalcomponent_free (icalcomp); + + } else { + e_cal_add_event (E_CAL_VIEW (day_view), client, dtstart, default_zone, icalcomp, TRUE); + } + + gtk_drag_finish (context, TRUE, TRUE, time); + return; + } + +error: gtk_drag_finish (context, FALSE, FALSE, time); } @@ -6926,12 +6985,17 @@ ECalViewPosition pos; gint day, row, start_row, end_row, num_rows, scroll_x, scroll_y; gint start_offset, end_offset; - gchar *event_uid; CalComponent *comp; CalComponentDateTime date; struct icaltimetype itt; time_t dt; CalClient *client; + gboolean drag_from_same_window; + + if (day_view->drag_event_day != -1) + drag_from_same_window = TRUE; + else + drag_from_same_window = FALSE; client = e_cal_model_get_default_client (e_cal_view_get_model (E_CAL_VIEW (day_view))); @@ -6943,13 +7007,14 @@ /* Note that we only support DnD within the EDayView at present. */ if ((data->length >= 0) && (data->format == 8) && (day_view->drag_event_day != -1)) { + /* We are dragging in the same window */ + pos = e_day_view_convert_position_in_main_canvas (day_view, x, y, &day, &row, NULL); if (pos != E_CAL_VIEW_POS_OUTSIDE) { CalObjModType mod = CALOBJ_MOD_ALL; GtkWindow *toplevel; - const char *uid; num_rows = 1; start_offset = 0; @@ -6980,12 +7045,6 @@ client = event->comp_data->client; - event_uid = data->data; - - uid = icalcomponent_get_uid (event->comp_data->icalcomp); - if (!event_uid || !uid || strcmp (event_uid, uid)) - g_warning ("Unexpected event UID"); - /* We use a temporary shallow copy of comp since we don't want to change the original comp here. Otherwise we would not detect that the event's time @@ -7023,6 +7082,7 @@ } toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (day_view))); + cal_component_commit_sequence (comp); if (cal_client_modify_object (client, cal_component_get_icalcomponent (comp), mod, NULL)) { if (itip_organizer_is_user (comp, client) @@ -7037,6 +7097,72 @@ } } + if ((data->length >= 0) && (data->format == 8) + && !drag_from_same_window) { + /* We are dragging between different window */ + + char *comp_str, *default_tzid;; + icalcomponent *icalcomp; + icalcomponent_kind kind; + time_t dtstart; + icaltimezone *default_zone; + + pos = e_day_view_convert_position_in_main_canvas (day_view, + x, y, &day, + &row, NULL); + if (pos == E_CAL_VIEW_POS_OUTSIDE) + goto error; + + comp_str = (char *) data->data; + icalcomp = icalparser_parse_string ((const char *) comp_str); + if (!icalcomp) + goto error; + + default_tzid = calendar_config_get_timezone (); + cal_client_get_timezone (client, default_tzid, &default_zone, NULL); + + /* check the type of the component */ + kind = icalcomponent_isa (icalcomp); + if (kind != ICAL_VCALENDAR_COMPONENT && kind != ICAL_VEVENT_COMPONENT) + goto error; + + dtstart = e_day_view_convert_grid_position_to_time (day_view, day, row); + + if (kind == ICAL_VCALENDAR_COMPONENT) { + icalcomponent_kind child_kind; + icalcomponent *subcomp; + + subcomp = icalcomponent_get_first_component (icalcomp, ICAL_ANY_COMPONENT); + while (subcomp) { + child_kind = icalcomponent_isa (subcomp); + if (child_kind == ICAL_VEVENT_COMPONENT) + e_cal_view_add_event (E_CAL_VIEW (day_view), client, dtstart, + default_zone, subcomp, FALSE); + else if (child_kind == ICAL_VTIMEZONE_COMPONENT) { + icaltimezone *zone; + + zone = icaltimezone_new (); + icaltimezone_set_component (zone, subcomp); + cal_client_add_timezone (client, zone, NULL); + + icaltimezone_free (zone, 1); + } + + subcomp = icalcomponent_get_next_component ( + icalcomp, ICAL_ANY_COMPONENT); + } + + icalcomponent_free (icalcomp); + + } else { + e_cal_add_event (E_CAL_VIEW (day_view), client, dtstart, default_zone, icalcomp, FALSE); + } + + gtk_drag_finish (context, TRUE, TRUE, time); + return; + } + +error: gtk_drag_finish (context, FALSE, FALSE, time); }