Rodrigo, I can compile new-ui-branch now, but when click the "Calendar" button, I cannot see my local calendars. I cannot create calendar and events, either. Here is the patch based on new-ui-branch. Please review it. It can be compiled, but I cannot test it. Since the new-ui-branch is changing frequently these days, I hope I can check in the patch first. Thanks! Harry BTW, the libical part still cannot be compiled, I have to copy an icalss.h from HEAD to libical/src/libicalss/ to make it work. Rodrigo Moya wrote: On Mon, 2003-10-13 at 10:05, Harry Lu wrote:Rodrigo, Attached is the patch for HEAD. I modified it a little according to the changes of selection_received() in e-cal-view.c of HEAD.looks ok, although it looks like the code to actually add the events to the calendar could be shared, since it is repeated in a couple of places, apart from already being in selection_received. Could you please try to move that code to a separate function and call it from the other places? Also, I wonder if all this work should be done in the new-ui-branch, which will be merged to HEAD soon. Thus, the merging would be easier, since there are a lot of changes in that branch, and if we continue making changes like this one to HEAD, I'm sure the merge will be more difficult :-) Ettore, what do you think? The thing that worries me is that you are writing new code that will need to be changed when merging with the new-ui-branch, since many things have changed.As I tested, with my patch, drag and drop bewteen different window works fine. However, I found a bug in the existing code before applying my patch. When I try to drag a event from main canvas to top canvas in the same window, evolution will hang there. gdb shows it hangs at malloc() in icalmemory_new_buffer() in icalmemory.c. Sorry I cannot figure out why. Dragging from top canvas to top canvas in the same window works fine.hmm, could you provide the backtrace? cheers |
=================================================================== RCS file: /cvs/gnome/evolution/calendar/ChangeLog,v retrieving revision 1.1833.2.45 diff -u -r1.1833.2.45 ChangeLog --- evolution/calendar//ChangeLog 15 Oct 2003 21:06:09 -0000 1.1833.2.45 +++ evolution/calendar//ChangeLog 16 Oct 2003 05:21:29 -0000 @@ -1,3 +1,16 @@ +2003-10-16 Harry Lu <harry lu sun com> + + * gui/e-cal-view.c (e_cal_view_add_event): modified from + selection_received_add_event() so that it can 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): Provode 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-15 Hans Petter Jansson <hpj ximian com> * gui/e-select-names-editable.c (e_selct_names_editable_get_address): Index: evolution/calendar//gui/e-cal-view.c =================================================================== RCS file: /cvs/gnome/evolution/calendar/gui/e-cal-view.c,v retrieving revision 1.6.2.9 diff -u -r1.6.2.9 e-cal-view.c --- evolution/calendar//gui/e-cal-view.c 14 Oct 2003 16:57:28 -0000 1.6.2.9 +++ evolution/calendar//gui/e-cal-view.c 16 Oct 2003 05:21:31 -0000 @@ -262,23 +262,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 */ @@ -350,8 +378,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; @@ -369,7 +397,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: evolution/calendar//gui/e-cal-view.h =================================================================== RCS file: /cvs/gnome/evolution/calendar/gui/e-cal-view.h,v retrieving revision 1.6.2.2 diff -u -r1.6.2.2 e-cal-view.h --- evolution/calendar//gui/e-cal-view.h 5 Sep 2003 20:35:55 -0000 1.6.2.2 +++ evolution/calendar//gui/e-cal-view.h 16 Oct 2003 05:21:31 -0000 @@ -114,6 +114,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); G_END_DECLS #endif Index: evolution/calendar//gui/e-day-view.c =================================================================== RCS file: /cvs/gnome/evolution/calendar/gui/e-day-view.c,v retrieving revision 1.209.2.10 diff -u -r1.209.2.10 e-day-view.c --- evolution/calendar//gui/e-day-view.c 14 Oct 2003 18:02:45 -0000 1.209.2.10 +++ evolution/calendar//gui/e-day-view.c 16 Oct 2003 05:21:37 -0000 @@ -6764,15 +6764,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; @@ -6807,26 +6800,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; @@ -6857,13 +6856,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 @@ -6938,6 +6930,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); } @@ -6956,12 +7014,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))); @@ -6973,13 +7036,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; @@ -7010,12 +7074,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 @@ -7067,6 +7125,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); }