|
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. 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. Anyway, this is unrelated to this patch. Thanks a lot! Harry Rodrigo Moya wrote: On Sat, 2003-09-27 at 05:56, Harry Lu wrote: |
Index: calendar//ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/calendar/ChangeLog,v
retrieving revision 1.1878
diff -u -r1.1878 ChangeLog
--- calendar//ChangeLog 10 Oct 2003 05:29:34 -0000 1.1878
+++ calendar//ChangeLog 13 Oct 2003 07:53:02 -0000
@@ -1,3 +1,13 @@
+2003-10-13 Harry Lu <harry lu sun com>
+
+ Fix for #48869.
+
+ * 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 window, make it works like a copy and paste.
+ (e_day_view_on_main_canvas_drag_data_received): ditto.
+
2003-10-10 Hans Petter Jansson <hpj ximian com>
* gui/Makefile.am (etspec_DATA): Add e-cal-list-view.etspec.
Index: calendar//gui/e-day-view.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/e-day-view.c,v
retrieving revision 1.219
diff -u -r1.219 e-day-view.c
--- calendar//gui/e-day-view.c 1 Sep 2003 06:15:33 -0000 1.219
+++ calendar//gui/e-day-view.c 13 Oct 2003 07:54:03 -0000
@@ -6821,15 +6821,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;
@@ -6864,24 +6857,30 @@
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) {
- const char *uid;
num_days = 1;
start_offset = 0;
end_offset = 0;
@@ -6911,13 +6910,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
@@ -7005,6 +6997,160 @@
}
}
+ 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, tt_start, tt_end;
+ struct icaldurationtype ic_dur;
+ struct icaltimetype itime;
+ char * uid;
+ 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);
+
+ /* check the type of the component */
+ kind = icalcomponent_isa (icalcomp);
+ if (kind != ICAL_VCALENDAR_COMPONENT &&
+ kind != ICAL_VEVENT_COMPONENT &&
+ kind != ICAL_VTODO_COMPONENT &&
+ kind != ICAL_VJOURNAL_COMPONENT) {
+ goto error;
+ }
+
+ if (kind == ICAL_VCALENDAR_COMPONENT) {
+ icalcomponent_kind child_kind;
+ icalcomponent *subcomp;
+ struct icaltimetype old_dtstart, old_dtend;
+
+ subcomp = icalcomponent_get_first_component (
+ icalcomp, ICAL_ANY_COMPONENT);
+ while (subcomp) {
+ child_kind = icalcomponent_isa (subcomp);
+ if (child_kind == ICAL_VEVENT_COMPONENT ||
+ child_kind == ICAL_VTODO_COMPONENT ||
+ child_kind == ICAL_VJOURNAL_COMPONENT) {
+ start_offset = 0;
+ end_offset = 0;
+
+ old_dtstart = icalcomponent_get_dtstart (subcomp);
+ tt_start = icaltime_as_timet (old_dtstart);
+ old_dtend = icalcomponent_get_dtend (subcomp);
+ tt_end = icaltime_as_timet (old_dtend);
+ ic_dur = icaldurationtype_from_int (tt_end - tt_start);
+ 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)
+ all_day_event = TRUE;
+ else
+ all_day_event = FALSE;
+
+ dtstart = day_view->day_starts[day] + start_offset * 60;
+ itime = icaltime_from_timet_with_zone (dtstart, FALSE, default_zone);
+ if (all_day_event)
+ itime.is_date = TRUE;
+ icalcomponent_set_dtstart (subcomp, itime);
+
+ itime = icaltime_add (itime, ic_dur);
+ if (all_day_event)
+ itime.is_date = TRUE;
+ icalcomponent_set_dtend (subcomp, itime);
+
+ uid = cal_component_gen_uid ();
+ comp = cal_component_new ();
+ cal_component_set_icalcomponent (
+ comp, icalcomponent_new_clone (subcomp));
+ cal_component_set_uid (comp, uid);
+
+ cal_client_update_object (client, comp);
+ if (itip_organizer_is_user (comp, client) &&
+ send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (day_view)),
+ client, comp, TRUE)) {
+ itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
+ client, NULL);
+ }
+
+ free (uid);
+ g_object_unref (comp);
+
+ }
+ subcomp = icalcomponent_get_next_component (
+ icalcomp, ICAL_ANY_COMPONENT);
+ }
+ }
+ else {
+ struct icaltimetype old_dtstart, old_dtend;
+ start_offset = 0;
+ end_offset = 0;
+
+ 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);
+ 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)
+ all_day_event = TRUE;
+ else
+ all_day_event = FALSE;
+
+ dtstart = day_view->day_starts[day] + start_offset * 60;
+ itime = icaltime_from_timet_with_zone (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);
+
+ uid = cal_component_gen_uid ();
+ comp = cal_component_new ();
+ cal_component_set_icalcomponent (
+ comp, icalcomponent_new_clone (icalcomp));
+ cal_component_set_uid (comp, uid);
+
+ cal_client_update_object (client, comp);
+
+ if (itip_organizer_is_user (comp, client) &&
+ send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (day_view)),
+ client, comp, TRUE)) {
+ itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp, client, NULL);
+ }
+
+ free (uid);
+ g_object_unref (comp);
+ }
+ gtk_drag_finish (context, TRUE, TRUE, time);
+ return;
+ }
+
+error:
gtk_drag_finish (context, FALSE, FALSE, time);
}
@@ -7023,12 +7169,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)));
@@ -7040,11 +7191,12 @@
/* 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) {
- const char *uid;
num_rows = 1;
start_offset = 0;
end_offset = 0;
@@ -7074,12 +7226,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
@@ -7141,6 +7287,120 @@
}
}
+ 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, tt_start, tt_end;
+ struct icaldurationtype ic_dur;
+ struct icaltimetype itime;
+ char * uid;
+ 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);
+
+ /* check the type of the component */
+ kind = icalcomponent_isa (icalcomp);
+ if (kind != ICAL_VCALENDAR_COMPONENT &&
+ kind != ICAL_VEVENT_COMPONENT &&
+ kind != ICAL_VTODO_COMPONENT &&
+ kind != ICAL_VJOURNAL_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 ||
+ child_kind == ICAL_VTODO_COMPONENT ||
+ child_kind == ICAL_VJOURNAL_COMPONENT) {
+ tt_start = icaltime_as_timet (icalcomponent_get_dtstart (subcomp));
+ tt_end = icaltime_as_timet (icalcomponent_get_dtend (subcomp));
+ ic_dur = icaldurationtype_from_int (tt_end - tt_start);
+ itime = icaltime_from_timet_with_zone (dtstart, FALSE, default_zone);
+
+ icalcomponent_set_dtstart (subcomp, itime);
+ itime = icaltime_add (itime, ic_dur);
+ icalcomponent_set_dtend (subcomp, itime);
+
+ uid = cal_component_gen_uid ();
+ comp = cal_component_new ();
+ cal_component_set_icalcomponent (
+ comp, icalcomponent_new_clone (subcomp));
+ cal_component_set_uid (comp, uid);
+
+ cal_client_update_object (client, comp);
+ if (itip_organizer_is_user (comp, client) &&
+ send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (day_view)),
+ client, comp, TRUE)) {
+ itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
+ client, NULL);
+ }
+
+ free (uid);
+ g_object_unref (comp);
+
+ }
+ subcomp = icalcomponent_get_next_component (
+ icalcomp, ICAL_ANY_COMPONENT);
+ }
+
+ icalcomponent_free (icalcomp);
+ }
+ else {
+ tt_start = icaltime_as_timet (icalcomponent_get_dtstart (icalcomp));
+ tt_end = icaltime_as_timet (icalcomponent_get_dtend (icalcomp));
+ ic_dur = icaldurationtype_from_int (tt_end - tt_start);
+ itime = icaltime_from_timet_with_zone (dtstart, FALSE, default_zone);
+
+ icalcomponent_set_dtstart (icalcomp, itime);
+ itime = icaltime_add (itime, ic_dur);
+ icalcomponent_set_dtend (icalcomp, itime);
+
+ uid = cal_component_gen_uid ();
+ comp = cal_component_new ();
+ cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icalcomp));
+ cal_component_set_uid (comp, uid);
+
+ cal_client_update_object (client, comp);
+
+ if (itip_organizer_is_user (comp, client) &&
+ send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (day_view)),
+ client, comp, TRUE)) {
+ itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
+ client, NULL);
+ }
+
+ free (uid);
+ g_object_unref (comp);
+ }
+ gtk_drag_finish (context, TRUE, TRUE, time);
+ return;
+ }
+
+error:
gtk_drag_finish (context, FALSE, FALSE, time);
}