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



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);
 }
 



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