[evolution-patches] Patch for 48869(Cannot drap&drop appointment from one window to another), Calendar related



Hi, Calendar Developers,
Here is a patch draft for 48869(Cannot drap&drop appointment from one window to another) based on 1.4 branch. It is a little large, but most of the logic is copied from existing code. I don't know if it can be commited in 1.4 because of the feature frozen, but I'd like someone to review my patch first and give some suggestions. I will provide a silimar patch for HEAD later when this patch is reviewd and agreed by calendar owners.

   My patch modified the following 3 functions in e-day-view.c:
e_day_view_on_drag_data_get(): In the current code, the passed event_uid is actually useless. Now we provide an icalcalendar component for both TARGET_CALENDAR_EVENT and TARGET_VCALENDAR. e_day_view_on_top_canvas_drag_data_received(): The might be two types of draggings. First, dragging in the same window, most of the code is the same as before. Second, dragging between different window, most of the code is copied from selection_received() which paste a calendar component to current selection. So, dragging between different window means a copy and paste. e_day_view_on_main_canvas_drag_data_received(): The changes are almost the same as the above.

   As I tested, it works.

   Thanks!
      Harry
Index: calendar/gui/e-day-view.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/e-day-view.c,v
retrieving revision 1.198.2.5
diff -u -r1.198.2.5 e-day-view.c
--- calendar/gui/e-day-view.c	12 Aug 2003 03:14:21 -0000	1.198.2.5
+++ calendar/gui/e-day-view.c	27 Sep 2003 03:26:13 -0000
@@ -7596,15 +7596,8 @@
 		event = &g_array_index (day_view->events[day],
 					EDayViewEvent, event_num);
 
-	if (info == TARGET_CALENDAR_EVENT) {
-		const char *event_uid;
-
-		cal_component_get_uid (event->comp, &event_uid);
-		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 || TARGET_VCALENDAR) {
+		/* we will pass an icalcalendar component for both types */
 		char *comp_str;
 		icalcomponent *vcal;
 
@@ -7645,10 +7638,18 @@
 	struct icaltimetype itt;
 	time_t dt;
 	gboolean all_day_event;
+	gboolean drag_from_same_window;
+
+	if (day_view->drag_event_day != -1)
+		drag_from_same_window = TRUE;
+	else
+		drag_from_same_window = FALSE;
 
 	/* 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);
@@ -7681,12 +7682,14 @@
 							day_view->drag_event_num);
 			}
 
+#if 0
 			event_uid = data->data;
 
 			cal_component_get_uid (event->comp, &uid);
 
 			if (!event_uid || !uid || strcmp (event_uid, uid))
 				g_warning ("Unexpected event UID");
+#endif
 
 			/* We clone the event since we don't want to change
 			   the original comp here.
@@ -7774,6 +7777,148 @@
 		}
 	}
 
+	if ((data->length >= 0) && (data->format == 8) 
+		&& !drag_from_same_window) {
+		/* We are dragging between different window */
+
+		char* comp_str;
+		icalcomponent *icalcomp;
+		icalcomponent_kind kind;
+		time_t dtstart, tt_start, tt_end;
+		struct icaldurationtype ic_dur;
+		struct icaltimetype itime;
+		char * uid;
+
+		pos = e_day_view_convert_position_in_top_canvas (day_view,
+								 x, y, &day,
+								 NULL);
+		if (pos == E_DAY_VIEW_POS_OUTSIDE) 
+			goto error;
+
+		comp_str = (char *) data->data;
+		icalcomp = icalparser_parse_string ((const char *) comp_str);
+		if (!icalcomp)
+			goto error;
+
+		/* 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, day_view->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 (day_view->client, comp);
+
+					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, day_view->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);
+
+			comp = cal_component_new ();
+			cal_component_set_icalcomponent (comp, icalcomp);
+
+			uid = cal_component_gen_uid ();
+			cal_component_set_uid (comp, (const char *) uid);
+			free (uid);
+
+			cal_client_update_object (day_view->client, comp);
+
+			if (itip_organizer_is_user (comp, day_view->client) && 
+			    send_component_dialog (gtk_widget_get_toplevel (day_view), day_view->client, comp, TRUE))
+				itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp, day_view->client, NULL);
+
+			g_object_unref (comp);
+		}
+		gtk_drag_finish (context, TRUE, TRUE, time);
+		return;
+	}
+
+error:
 	gtk_drag_finish (context, FALSE, FALSE, time);
 }
 
@@ -7797,15 +7942,23 @@
 	CalComponentDateTime date;
 	struct icaltimetype itt;
 	time_t dt;
+	gboolean drag_from_same_window;
 
 	gnome_canvas_get_scroll_offsets (GNOME_CANVAS (widget),
 					 &scroll_x, &scroll_y);
 	x += scroll_x;
 	y += scroll_y;
 
+	if (day_view->drag_event_day != -1)
+		drag_from_same_window = TRUE;
+	else 
+		drag_from_same_window = FALSE;
+
 	/* 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);
@@ -7837,12 +7990,13 @@
 				if (end_offset != 0)
 					end_offset = day_view->mins_per_row - end_offset;
 			}
-
+#if 0
 			event_uid = data->data;
 
 			cal_component_get_uid (event->comp, &uid);
 			if (!event_uid || !uid || strcmp (event_uid, uid))
 				g_warning ("Unexpected event UID");
+#endif
 
 			/* We use a temporary shallow copy of comp since we
 			   don't want to change the original comp here.
@@ -7905,6 +8059,107 @@
 		}
 	}
 
+	if ((data->length >= 0) && (data->format == 8) 
+		&& !drag_from_same_window) {
+		/* We are dragging between different window */
+
+		char* comp_str;
+		icalcomponent *icalcomp;
+		icalcomponent_kind kind;
+		time_t dtstart, tt_start, tt_end;
+		struct icaldurationtype ic_dur;
+		struct icaltimetype itime;
+		char * uid;
+
+
+		pos = e_day_view_convert_position_in_main_canvas (day_view,
+								  x, y, &day,
+								  &row, NULL);
+		if (pos == E_DAY_VIEW_POS_OUTSIDE) 
+			goto error;
+
+		comp_str = (char *) data->data;
+		icalcomp = icalparser_parse_string ((const char *) comp_str);
+		if (!icalcomp)
+			goto error;
+
+		/* 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, day_view->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 (day_view->client, comp);
+
+					free (uid);
+					g_object_unref (comp);
+
+				}
+				subcomp = icalcomponent_get_next_component (
+					icalcomp, ICAL_ANY_COMPONENT);
+			}
+		}
+		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, day_view->zone);
+
+			icalcomponent_set_dtstart (icalcomp, itime);
+			itime = icaltime_add (itime, ic_dur);
+			icalcomponent_set_dtend (icalcomp, itime);
+
+			comp = cal_component_new ();
+			cal_component_set_icalcomponent (comp, icalcomp);
+
+			uid = cal_component_gen_uid ();
+			cal_component_set_uid (comp, (const char *) uid);
+			free (uid);
+
+			cal_client_update_object (day_view->client, comp);
+
+			if (itip_organizer_is_user (comp, day_view->client) && 
+			    send_component_dialog (gtk_widget_get_toplevel (day_view), day_view->client, comp, TRUE))
+				itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp, day_view->client, NULL);
+
+			g_object_unref (comp);
+		}
+		gtk_drag_finish (context, TRUE, TRUE, time);
+		return;
+	}
+
+error:
 	gtk_drag_finish (context, FALSE, FALSE, time);
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]