From 0caac5ff878a9cb7dc5d53906c7d57ef6483b5f7 Mon Sep 17 00:00:00 2001 From: Harish Krishnaswamy Date: Tue, 19 Oct 2004 03:51:01 +0000 Subject: gui/comp-editor-factory.c (edit_existing), * 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. svn path=/trunk/; revision=27614 --- calendar/ChangeLog | 19 ++++++ calendar/gui/calendar-component.c | 2 +- calendar/gui/comp-editor-factory.c | 12 +++- calendar/gui/dialogs/event-editor.c | 11 ++- calendar/gui/dialogs/event-editor.h | 2 +- calendar/gui/dialogs/meeting-page.c | 13 ++-- calendar/gui/e-calendar-view.c | 2 +- calendar/gui/e-meeting-store.c | 130 ++++++++++++++++++++++++++---------- 8 files changed, 136 insertions(+), 55 deletions(-) diff --git a/calendar/ChangeLog b/calendar/ChangeLog index 982215c5fa..040625a5b7 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,3 +1,22 @@ +2004-10-19 Harish Krishnaswamy + + * 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 * gui/e-cal-menu.c (e_cal_menu_target_new_select): dont access a diff --git a/calendar/gui/calendar-component.c b/calendar/gui/calendar-component.c index ff09634a0b..35c33bc139 100644 --- a/calendar/gui/calendar-component.c +++ b/calendar/gui/calendar-component.c @@ -971,7 +971,7 @@ create_new_event (CalendarComponent *calendar_component, CalendarComponentView * 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); diff --git a/calendar/gui/comp-editor-factory.c b/calendar/gui/comp-editor-factory.c index 71470ee648..da7bba1a93 100644 --- a/calendar/gui/comp-editor-factory.c +++ b/calendar/gui/comp-editor-factory.c @@ -245,6 +245,8 @@ edit_existing (OpenClient *oc, const char *uid) 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 char *uid) 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_Evolution_Calendar_CompEditorFactory_CompE 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: diff --git a/calendar/gui/dialogs/event-editor.c b/calendar/gui/dialogs/event-editor.c index 8d1b89cb15..d520fd809b 100644 --- a/calendar/gui/dialogs/event-editor.c +++ b/calendar/gui/dialogs/event-editor.c @@ -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 *editor, ECalComponent *comp) 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); } @@ -382,7 +380,6 @@ event_editor_show_meeting (EventEditor *ee) g_return_if_fail (ee != NULL); g_return_if_fail (IS_EVENT_EDITOR (ee)); - show_meeting (ee); } diff --git a/calendar/gui/dialogs/event-editor.h b/calendar/gui/dialogs/event-editor.h index 9234b8310e..0f934c28f2 100644 --- a/calendar/gui/dialogs/event-editor.h +++ b/calendar/gui/dialogs/event-editor.h @@ -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); diff --git a/calendar/gui/dialogs/meeting-page.c b/calendar/gui/dialogs/meeting-page.c index 241712a006..19faebaec4 100644 --- a/calendar/gui/dialogs/meeting-page.c +++ b/calendar/gui/dialogs/meeting-page.c @@ -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); diff --git a/calendar/gui/e-calendar-view.c b/calendar/gui/e-calendar-view.c index 2e9ccc33d1..24a5f1bdd8 100644 --- a/calendar/gui/e-calendar-view.c +++ b/calendar/gui/e-calendar-view.c @@ -1610,7 +1610,7 @@ e_calendar_view_edit_appointment (ECalendarView *cal_view, if (!ce) { EventEditor *ee; - ee = event_editor_new (client); + ee = event_editor_new (client, meeting); ce = COMP_EDITOR (ee); comp = e_cal_component_new (); diff --git a/calendar/gui/e-meeting-store.c b/calendar/gui/e-meeting-store.c index 9aba639232..c4eafd34a9 100644 --- a/calendar/gui/e-meeting-store.c +++ b/calendar/gui/e-meeting-store.c @@ -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 *store, EMeetingAttendee *attendee) 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_str_hash, g_str_equal); + + priv->mutex = g_mutex_new (); start_addressbook_server (store); } @@ -795,6 +803,7 @@ e_meeting_store_remove_attendee (EMeetingStore *store, EMeetingAttendee *attende } if (row != -1) { + g_ptr_array_remove_index (store->priv->attendees, row); g_object_unref (attendee); @@ -1107,6 +1116,51 @@ process_free_busy (EMeetingStoreQueueData *qdata, char *text) 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, int row, 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, int row, 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); -- cgit v1.2.3