Re: [evolution-patches] Patch to make FreeBusy calls from Evo calendar async with the main thread



Attached patch with the changes.
On Tue, 2004-10-12 at 12:26 +0530, Harish Krishnaswamy wrote:
> > >
> > query is not being used here at all, is it?
> 
> yes. I had just moved this code snippet to the new function in the
> patch. I notice that it is the same case in the existing code too.. 
> The code does not accomplish anything and probably is just incompleter.
> was the intent to fetch f/b info from the urls obtained from the contact
> information ?
> > > @@ -325,12 +325,11 @@ clear_widgets (MeetingPage *mpage)
> > > 
> > here, you should be doing something with the GError, at least free it if
> > e_cal_is_read_only returns something there. So, I would change this
> > with:
> > 
> > if (!e_cal_is_read_only (...)) {
> > 	read_only = TRUE;
> > 	display_error_somewhere;
> > 	g_error_free (error);
> > }
> > 
> > thus, if the call fails, we disable all the widgets, as if it were a
> > read only calendar.
> 
> The most common error returned is likely to occur is the
> CALENDAR_BUSY_ERROR, now that the f/b calls are asynchronous. We do not
> want to do anything in this case. The freeing of the error has to be
> done, anyway. modifying the patch to do this.
> 
> harish
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/calendar/ChangeLog,v
retrieving revision 1.2546
diff -u -p -r1.2546 ChangeLog
--- ChangeLog	18 Oct 2004 04:08:47 -0000	1.2546
+++ ChangeLog	18 Oct 2004 15:11:25 -0000
@@ -1,3 +1,22 @@
+2004-10-18  Harish Krishnaswamy  <kharish novell com>
+
+	* gui/calendar-component.c (create_new_event):
+	* gui/e-calendar-view.c: (e_calendar_view_edit_appointment):
+	* gui/comp-editor-factory.c (edit_existing), (edit_new):
+	* gui/dialogs/event-editor.c (event_editor_edit_comp),
+	 (event_editor_new): updated the calls to event_editor_new 
+	with additional argument.
+	* gui/dialogs/event-editor.h: add parameter is_meeting to
+	distinguish between events and  meetings.
+	* gui/dialogs/meeting-page.c: (sensitize_widgets):
+	use explicit GError variable so that BUSY_ERROR
+	conditions do not lead us to think the calendar is readonly.
+	* gui/e-meeting-store.c: (refresh_queue_remove), (ems_init),
+	(e_meeting_store_remove_attendee), (freebusy_async),
+	(refresh_busy_periods), (refresh_queue_add): Make free-busy calls 
+	to backends async. Fixed the problem of spurious attendees getting 
+	added to the refresh_data.
+	
 2004-10-14  Not Zed  <NotZed Ximian com>
 
 	* gui/e-cal-menu.c (e_cal_menu_target_new_select): dont access a
Index: gui/calendar-component.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/calendar-component.c,v
retrieving revision 1.186
diff -u -p -r1.186 calendar-component.c
--- gui/calendar-component.c	13 Oct 2004 18:37:05 -0000	1.186
+++ gui/calendar-component.c	18 Oct 2004 15:11:25 -0000
@@ -971,7 +971,7 @@ create_new_event (CalendarComponent *cal
 		ECalComponent *comp;
 		EventEditor *editor;
 
-		editor = event_editor_new (ecal);
+		editor = event_editor_new (ecal, is_meeting);
 		comp = cal_comp_event_new_with_current_time (ecal, is_allday);
 		e_cal_component_commit_sequence (comp);
 
Index: gui/e-calendar-view.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/e-calendar-view.c,v
retrieving revision 1.66
diff -u -p -r1.66 e-calendar-view.c
--- gui/e-calendar-view.c	14 Oct 2004 15:22:32 -0000	1.66
+++ gui/e-calendar-view.c	18 Oct 2004 15:11:25 -0000
@@ -1610,7 +1610,7 @@ e_calendar_view_edit_appointment (ECalen
 	if (!ce) {
 		EventEditor *ee;
 
-		ee = event_editor_new (client);
+		ee = event_editor_new (client, meeting);
 		ce = COMP_EDITOR (ee);
 
 		comp = e_cal_component_new ();
Index: gui/comp-editor-factory.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/comp-editor-factory.c,v
retrieving revision 1.38
diff -u -p -r1.38 comp-editor-factory.c
--- gui/comp-editor-factory.c	7 Oct 2004 14:20:55 -0000	1.38
+++ gui/comp-editor-factory.c	18 Oct 2004 15:11:25 -0000
@@ -245,6 +245,8 @@ edit_existing (OpenClient *oc, const cha
 	icalcomponent *icalcomp;
 	CompEditor *editor;
 	ECalComponentVType vtype;
+	/* Presence of attendees indicates that component is a meeting */
+	GSList *attendees = NULL;
 
 	g_assert (oc->open);
 
@@ -269,7 +271,8 @@ edit_existing (OpenClient *oc, const cha
 
 	switch (vtype) {
 	case E_CAL_COMPONENT_EVENT:
-		editor = COMP_EDITOR (event_editor_new (oc->client));
+		e_cal_component_get_attendee_list (comp, &attendees);
+		editor = COMP_EDITOR (event_editor_new (oc->client, attendees ? TRUE: FALSE));
 		break;
 
 	case E_CAL_COMPONENT_TODO:
@@ -311,12 +314,15 @@ edit_new (OpenClient *oc, const GNOME_Ev
 	
 	switch (type) {
 	case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_EVENT:
+		editor = COMP_EDITOR (event_editor_new (oc->client, FALSE));
+		comp = cal_comp_event_new_with_current_time (oc->client, FALSE);
+		break;
 	case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_MEETING:
-		editor = COMP_EDITOR (event_editor_new (oc->client));
+		editor = COMP_EDITOR (event_editor_new (oc->client, TRUE));
 		comp = cal_comp_event_new_with_current_time (oc->client, FALSE);
 		break;
 	case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_ALLDAY_EVENT:
-		editor = COMP_EDITOR (event_editor_new (oc->client));
+		editor = COMP_EDITOR (event_editor_new (oc->client, FALSE));
 		comp = cal_comp_event_new_with_current_time (oc->client, TRUE);
 		break;
 	case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_TODO:
Index: gui/e-meeting-store.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/e-meeting-store.c,v
retrieving revision 1.7
diff -u -p -r1.7 e-meeting-store.c
--- gui/e-meeting-store.c	20 May 2004 01:16:56 -0000	1.7
+++ gui/e-meeting-store.c	18 Oct 2004 15:11:26 -0000
@@ -52,6 +52,7 @@ struct _EMeetingStorePrivate {
 
 	GPtrArray *refresh_queue;
 	GHashTable *refresh_data;
+	GMutex *mutex;
 	guint refresh_idle_id;
 };
 
@@ -555,6 +556,9 @@ refresh_queue_remove (EMeetingStore *sto
 	qdata = g_hash_table_lookup (priv->refresh_data, attendee);
 	if (qdata) {
 		g_hash_table_remove (priv->refresh_data, attendee);
+		g_mutex_lock (priv->mutex);
+		g_hash_table_remove (priv->refresh_data, itip_strip_mailto (e_meeting_attendee_get_address (attendee)));
+		g_mutex_unlock (priv->mutex);
 		g_ptr_array_free (qdata->call_backs, TRUE);
 		g_ptr_array_free (qdata->data, TRUE);
 		g_free (qdata);
@@ -591,6 +595,8 @@ ems_finalize (GObject *obj)
  	
  	if (priv->refresh_idle_id)
  		g_source_remove (priv->refresh_idle_id);
+
+	g_mutex_free (priv->mutex);
  		
 	g_free (priv);
 
@@ -621,7 +627,9 @@ ems_init (EMeetingStore *store)
 	priv->zone = calendar_config_get_icaltimezone ();
 	
 	priv->refresh_queue = g_ptr_array_new ();
-	priv->refresh_data = g_hash_table_new (g_direct_hash, g_direct_equal);
+	priv->refresh_data = g_hash_table_new (g_direct_hash, g_str_equal);
+
+	priv->mutex = g_mutex_new ();
 
 	start_addressbook_server (store);
 }
@@ -795,6 +803,7 @@ e_meeting_store_remove_attendee (EMeetin
 	}	
 	
 	if (row != -1) {
+
 		g_ptr_array_remove_index (store->priv->attendees, row);		
 		g_object_unref (attendee);
 
@@ -1107,6 +1116,51 @@ process_free_busy (EMeetingStoreQueueDat
 	process_callbacks (qdata);
 }
 
+typedef struct {
+	ECal *client;
+	time_t startt;
+	time_t endt;
+	GList *users;
+	GList *fb_data;
+	EMeetingAttendee *attendee;
+	EMeetingStoreQueueData *qdata;
+} FreeBusyAsyncData;
+
+static gboolean
+freebusy_async (gpointer data)
+{
+	FreeBusyAsyncData *fbd = data;
+	EMeetingAttendee *attendee = fbd->attendee;
+	
+	if (fbd->client) {
+		e_cal_get_free_busy (fbd->client, fbd->users, fbd->startt, fbd->endt, &(fbd->fb_data), NULL);
+
+		g_list_foreach (fbd->users, (GFunc)g_free, NULL);
+		g_list_free (fbd->users);
+
+		if (fbd->fb_data != NULL) {
+			ECalComponent *comp = fbd->fb_data->data;
+			char *comp_str;
+				
+			comp_str = e_cal_component_get_as_string (comp);
+			process_free_busy (fbd->qdata, comp_str);
+			g_free (comp_str);
+		}
+		return TRUE;
+	}
+	
+
+	/* Look for fburl's of attendee with no free busy info on server */
+	if (!e_meeting_attendee_is_set_address (attendee)) {
+		process_callbacks (fbd->qdata);
+		return TRUE;
+	}
+	
+	return TRUE;
+
+
+}
+
 static gboolean
 refresh_busy_periods (gpointer data)
 {	
@@ -1114,8 +1168,10 @@ refresh_busy_periods (gpointer data)
 	EMeetingStorePrivate *priv;
 	EMeetingAttendee *attendee = NULL;
 	EMeetingStoreQueueData *qdata = NULL;
-	char *query;
 	int i;
+	GThread *thread;
+	GError *error = NULL;
+	FreeBusyAsyncData *fbd;
 	
 	priv = store->priv;
 
@@ -1124,7 +1180,7 @@ refresh_busy_periods (gpointer data)
 		attendee = g_ptr_array_index (priv->refresh_queue, i);
 		g_assert (attendee != NULL);
 
-		qdata = g_hash_table_lookup (priv->refresh_data, attendee);
+		qdata = g_hash_table_lookup (priv->refresh_data, itip_strip_mailto (e_meeting_attendee_get_address (attendee)));
 		if (!qdata)
 			continue;
 
@@ -1144,20 +1200,23 @@ refresh_busy_periods (gpointer data)
 	/* We take a ref in case we get destroyed in the gui during a callback */
 	g_object_ref (qdata->store);
 	
+	fbd = g_new0 (FreeBusyAsyncData, 1);
+	fbd->client = priv->client;
+	fbd->users = NULL;
+	fbd->fb_data = NULL;	
+
 	/* Check the server for free busy data */	
 	if (priv->client) {
-		GList *fb_data = NULL, *users = NULL;
 		struct icaltimetype itt;
-		time_t startt, endt;
 		const char *user;
-		
+				
 		itt = icaltime_null_time ();
 		itt.year = g_date_year (&qdata->start.date);
 		itt.month = g_date_month (&qdata->start.date);
 		itt.day = g_date_day (&qdata->start.date);
 		itt.hour = qdata->start.hour;
 		itt.minute = qdata->start.minute;
-		startt = icaltime_as_timet_with_zone (itt, priv->zone);
+		fbd->startt = icaltime_as_timet_with_zone (itt, priv->zone);
 
 		itt = icaltime_null_time ();
 		itt.year = g_date_year (&qdata->end.date);
@@ -1165,37 +1224,22 @@ refresh_busy_periods (gpointer data)
 		itt.day = g_date_day (&qdata->end.date);
 		itt.hour = qdata->end.hour;
 		itt.minute = qdata->end.minute;
-		endt = icaltime_as_timet_with_zone (itt, priv->zone);
+		fbd->endt = icaltime_as_timet_with_zone (itt, priv->zone);
+		fbd->qdata = qdata;
+		fbd->attendee = attendee;
 
 		user = itip_strip_mailto (e_meeting_attendee_get_address (attendee));
-		users = g_list_append (users, g_strdup (user));
-		e_cal_get_free_busy (priv->client, users, startt, endt, &fb_data, NULL);
-
-		g_list_foreach (users, (GFunc)g_free, NULL);
-		g_list_free (users);
+		fbd->users = g_list_append (fbd->users, g_strdup (user));
 
-		if (fb_data != NULL) {
-			ECalComponent *comp = fb_data->data;
-			char *comp_str;
-				
-			comp_str = e_cal_component_get_as_string (comp);
-			process_free_busy (qdata, comp_str);
-			g_free (comp_str);
-			return TRUE;
-		}
 	}
-
-	/* Look for fburl's of attendee with no free busy info on server */
-	if (!e_meeting_attendee_is_set_address (attendee)) {
-		process_callbacks (qdata);
-		return TRUE;
+		
+	thread = g_thread_create ((GThreadFunc) freebusy_async, fbd, FALSE, &error);
+	if (!thread) {
+		/* do clean up stuff here */
+		g_list_foreach (fbd->users, (GFunc)g_free, NULL);
+		g_list_free (fbd->users);
+		return FALSE;
 	}
-	
-	query = g_strdup_printf ("(contains \"email\" \"%s\")", 
-				 itip_strip_mailto (e_meeting_attendee_get_address (attendee)));
-	process_callbacks (qdata);
-	g_free (query);
-
 	return TRUE;
 }
 		
@@ -1209,14 +1253,24 @@ refresh_queue_add (EMeetingStore *store,
 	EMeetingStorePrivate *priv;
 	EMeetingAttendee *attendee;
 	EMeetingStoreQueueData *qdata;
+	int i;
 
 	priv = store->priv;
 	
 	attendee = g_ptr_array_index (priv->attendees, row);
-	if (attendee == NULL)
+	if ((attendee == NULL) || !strcmp (itip_strip_mailto (e_meeting_attendee_get_address (attendee)), ""))
 		return;
+	/* check the queue if the attendee is already in there*/
+	for (i = 0; i < priv->refresh_queue->len; i++) {
+		if (attendee == g_ptr_array_index (priv->refresh_queue, i))
+			return;		
+		if (!strcmp (e_meeting_attendee_get_address (attendee), e_meeting_attendee_get_address (g_ptr_array_index (priv->refresh_queue, i))))
+				return;
+	}
+
+	g_mutex_lock (priv->mutex);
+	qdata = g_hash_table_lookup (priv->refresh_data, itip_strip_mailto (e_meeting_attendee_get_address (attendee)));
 
-	qdata = g_hash_table_lookup (priv->refresh_data, attendee);
 	if (qdata == NULL) {
 		qdata = g_new0 (EMeetingStoreQueueData, 1);
 
@@ -1233,15 +1287,17 @@ refresh_queue_add (EMeetingStore *store,
 		g_ptr_array_add (qdata->call_backs, call_back);
 		g_ptr_array_add (qdata->data, data);
 
-		g_hash_table_insert (priv->refresh_data, attendee, qdata);
+		g_hash_table_insert (priv->refresh_data, itip_strip_mailto (e_meeting_attendee_get_address (attendee)), qdata);
 	} else {
 		if (e_meeting_time_compare_times (start, &qdata->start) == -1)
 			qdata->start = *start;
-		if (e_meeting_time_compare_times (end, &qdata->end) == 1)
+		if (e_meeting_time_compare_times (end, &qdata->end) == -1)
 			qdata->end = *end;
 		g_ptr_array_add (qdata->call_backs, call_back);
 		g_ptr_array_add (qdata->data, data);
 	}
+	g_mutex_unlock (priv->mutex);
+
 
 	g_object_ref (attendee);
 	g_ptr_array_add (priv->refresh_queue, attendee);
Index: gui/dialogs/event-editor.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/dialogs/event-editor.c,v
retrieving revision 1.47
diff -u -p -r1.47 event-editor.c
--- gui/dialogs/event-editor.c	14 Oct 2004 14:22:12 -0000	1.47
+++ gui/dialogs/event-editor.c	18 Oct 2004 15:11:26 -0000
@@ -47,7 +47,7 @@ struct _EventEditorPrivate {
 	SchedulePage *sched_page;
 
 	EMeetingStore *model;
-	
+	gboolean is_meeting;
 	gboolean meeting_shown;
 	gboolean updating;	
 };
@@ -205,11 +205,8 @@ event_editor_edit_comp (CompEditor *edit
 	e_cal_component_get_organizer (comp, &organizer);
 	e_cal_component_get_attendee_list (comp, &attendees);
 
-	/* Clear things up */
-	e_meeting_store_remove_all_attendees (priv->model);
-
 	/* Set up the attendees */
-	if (attendees == NULL) {
+	if (attendees == NULL && !priv->is_meeting) {
 		comp_editor_remove_page (editor, COMP_EDITOR_PAGE (priv->meet_page));
 		comp_editor_remove_page (editor, COMP_EDITOR_PAGE (priv->sched_page));
 		priv->meeting_shown = FALSE;
@@ -344,11 +341,12 @@ event_editor_finalize (GObject *object)
  * editor could not be created.
  **/
 EventEditor *
-event_editor_new (ECal *client)
+event_editor_new (ECal *client, gboolean is_meeting)
 {
 	EventEditor *ee;
 
 	ee = EVENT_EDITOR (g_object_new (TYPE_EVENT_EDITOR, NULL));
+	ee->priv->is_meeting = is_meeting;
 	return event_editor_construct (ee, client);
 }
 
@@ -381,7 +379,6 @@ event_editor_show_meeting (EventEditor *
 {
 	g_return_if_fail (ee != NULL);
 	g_return_if_fail (IS_EVENT_EDITOR (ee));
-
 
 	show_meeting (ee);
 }
Index: gui/dialogs/event-editor.h
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/dialogs/event-editor.h,v
retrieving revision 1.9
diff -u -p -r1.9 event-editor.h
--- gui/dialogs/event-editor.h	7 Nov 2003 05:52:04 -0000	1.9
+++ gui/dialogs/event-editor.h	18 Oct 2004 15:11:26 -0000
@@ -53,7 +53,7 @@ struct _EventEditorClass {
 GtkType      event_editor_get_type     (void);
 EventEditor *event_editor_construct    (EventEditor *ee,
 					ECal   *client);
-EventEditor *event_editor_new          (ECal   *client);
+EventEditor *event_editor_new          (ECal   *client, gboolean is_meeting);
 void         event_editor_show_meeting (EventEditor *ee);
 
 
Index: gui/dialogs/meeting-page.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/dialogs/meeting-page.c,v
retrieving revision 1.91
diff -u -p -r1.91 meeting-page.c
--- gui/dialogs/meeting-page.c	14 Oct 2004 14:22:12 -0000	1.91
+++ gui/dialogs/meeting-page.c	18 Oct 2004 15:11:26 -0000
@@ -305,12 +305,15 @@ clear_widgets (MeetingPage *mpage)
 static void
 sensitize_widgets (MeetingPage *mpage)
 {
-	gboolean read_only;
+	gboolean read_only = FALSE, user_org;
 	MeetingPagePrivate *priv = mpage->priv;
-
-	if (!e_cal_is_read_only (COMP_EDITOR_PAGE (mpage)->client, &read_only, NULL))
-		read_only = TRUE;
-
+	GError *error = NULL;
+	
+	if (!e_cal_is_read_only (COMP_EDITOR_PAGE (mpage)->client, &read_only, &error)) {
+		if (error->code != E_CALENDAR_STATUS_BUSY)
+			read_only = TRUE;
+		g_error_free (error);
+	}	
 	gtk_widget_set_sensitive (priv->organizer, !read_only);
 	gtk_widget_set_sensitive (priv->existing_organizer_btn, !read_only);
 	gtk_widget_set_sensitive (priv->add, !read_only && priv->user_org);


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