diff options
author | JP Rosevear <jpr@ximian.com> | 2002-02-16 03:22:18 +0800 |
---|---|---|
committer | JP Rosevear <jpr@src.gnome.org> | 2002-02-16 03:22:18 +0800 |
commit | 68bff65a4119bdd4431a5572c3cd59d2425c13ed (patch) | |
tree | b03d169df01b8f5e41856920d91fed1192e0fe71 | |
parent | 079f1f45e7c421ed7f19840f70034df4c7dace74 (diff) | |
download | gsoc2013-evolution-68bff65a4119bdd4431a5572c3cd59d2425c13ed.tar gsoc2013-evolution-68bff65a4119bdd4431a5572c3cd59d2425c13ed.tar.gz gsoc2013-evolution-68bff65a4119bdd4431a5572c3cd59d2425c13ed.tar.bz2 gsoc2013-evolution-68bff65a4119bdd4431a5572c3cd59d2425c13ed.tar.lz gsoc2013-evolution-68bff65a4119bdd4431a5572c3cd59d2425c13ed.tar.xz gsoc2013-evolution-68bff65a4119bdd4431a5572c3cd59d2425c13ed.tar.zst gsoc2013-evolution-68bff65a4119bdd4431a5572c3cd59d2425c13ed.zip |
use new column enums (set_value_at): emit pre-change/cell change signals
2002-02-14 JP Rosevear <jpr@ximian.com>
* gui/e-meeting-model.c: use new column enums
(set_value_at): emit pre-change/cell change signals
(destroy): destroy refresh_queue and refresh_data
(init): init new elements
(refresh_queue_add): if the attendee is being refreshed already,
possibly update the start/end times to look for and update the
callback info, otherwise add it to the queue
(refresh_queue_remove): remove a refreshing attende from the queue
(process_callbacks): make all the callbacks and remove the
attendee from the queue
(process_free_busy): process the callbacks immediately if parsing
fails or on successful completion of processing
(async_close): process free busy
(cursor_cb): we're only looking for one at a time now
(refresh_busy_periods): idle callback to start processing the queue
(e_meeting_model_refresh_all_busy_periods): add every row to the queue
(e_meeting_model_refresh_busy_periods): add a single row to the queue
* gui/e-meeting-model.h: new protos, enum the columns
* gui/e-meeting-time-sel.c: use new compare time function
(e_meeting_time_selector_construct): listen for a cell changed
signal and use separate callbacks for rows_inserted and
rows_deleted
(e_meeting_time_selector_refresh_free_busy): util function to
refresh free busy info
(e_meeting_time_selector_on_update_free_busy): use above
(rows_inserted_cb): refresh free busy on the new rows
(cell_changed_cb): refresh free busy on the row when the address
changes
(rows_deleted_cb): redraw
* gui/e-meeting-utils.[hc]: a holding spot for a meeting time
comparison function
* gui/Makefile.am: compile new files
svn path=/trunk/; revision=15741
-rw-r--r-- | calendar/ChangeLog | 39 | ||||
-rw-r--r-- | calendar/gui/Makefile.am | 2 | ||||
-rw-r--r-- | calendar/gui/e-meeting-model.c | 568 | ||||
-rw-r--r-- | calendar/gui/e-meeting-model.h | 22 | ||||
-rw-r--r-- | calendar/gui/e-meeting-time-sel.c | 156 | ||||
-rw-r--r-- | calendar/gui/e-meeting-utils.c | 52 | ||||
-rw-r--r-- | calendar/gui/e-meeting-utils.h | 49 |
7 files changed, 570 insertions, 318 deletions
diff --git a/calendar/ChangeLog b/calendar/ChangeLog index a3afa5f74b..1f4f97d6b5 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,3 +1,42 @@ +2002-02-14 JP Rosevear <jpr@ximian.com> + + * gui/e-meeting-model.c: use new column enums + (set_value_at): emit pre-change/cell change signals + (destroy): destroy refresh_queue and refresh_data + (init): init new elements + (refresh_queue_add): if the attendee is being refreshed already, + possibly update the start/end times to look for and update the + callback info, otherwise add it to the queue + (refresh_queue_remove): remove a refreshing attende from the queue + (process_callbacks): make all the callbacks and remove the + attendee from the queue + (process_free_busy): process the callbacks immediately if parsing + fails or on successful completion of processing + (async_close): process free busy + (cursor_cb): we're only looking for one at a time now + (refresh_busy_periods): idle callback to start processing the queue + (e_meeting_model_refresh_all_busy_periods): add every row to the queue + (e_meeting_model_refresh_busy_periods): add a single row to the queue + + * gui/e-meeting-model.h: new protos, enum the columns + + * gui/e-meeting-time-sel.c: use new compare time function + (e_meeting_time_selector_construct): listen for a cell changed + signal and use separate callbacks for rows_inserted and + rows_deleted + (e_meeting_time_selector_refresh_free_busy): util function to + refresh free busy info + (e_meeting_time_selector_on_update_free_busy): use above + (rows_inserted_cb): refresh free busy on the new rows + (cell_changed_cb): refresh free busy on the row when the address + changes + (rows_deleted_cb): redraw + + * gui/e-meeting-utils.[hc]: a holding spot for a meeting time + comparison function + + * gui/Makefile.am: compile new files + 2002-02-13 Rodrigo Moya <rodrigo@ximian.com> * gui/control-factory.c (set_prop): don't append 'calendar.ics' diff --git a/calendar/gui/Makefile.am b/calendar/gui/Makefile.am index 56fab01684..39c582c8bd 100644 --- a/calendar/gui/Makefile.am +++ b/calendar/gui/Makefile.am @@ -116,6 +116,8 @@ evolution_calendar_SOURCES = \ e-meeting-time-sel-item.c \ e-meeting-time-sel-item.h \ e-meeting-types.h \ + e-meeting-utils.c \ + e-meeting-utils.h \ e-week-view-event-item.c \ e-week-view-event-item.h \ e-week-view-layout.c \ diff --git a/calendar/gui/e-meeting-model.c b/calendar/gui/e-meeting-model.c index a3429aaf55..54b5bfd407 100644 --- a/calendar/gui/e-meeting-model.c +++ b/calendar/gui/e-meeting-model.c @@ -50,25 +50,12 @@ #include "Evolution-Addressbook-SelectNames.h" #include "calendar-config.h" #include "itip-utils.h" +#include "e-meeting-utils.h" #include "e-meeting-attendee.h" #include "e-meeting-model.h" #define SELECT_NAMES_OAFID "OAFIID:GNOME_Evolution_Addressbook_SelectNames" -enum columns { - ITIP_ADDRESS_COL, - ITIP_MEMBER_COL, - ITIP_TYPE_COL, - ITIP_ROLE_COL, - ITIP_RSVP_COL, - ITIP_DELTO_COL, - ITIP_DELFROM_COL, - ITIP_STATUS_COL, - ITIP_CN_COL, - ITIP_LANGUAGE_COL, - ITIP_COLUMN_COUNT -}; - struct _EMeetingModelPrivate { GPtrArray *attendees; @@ -81,10 +68,9 @@ struct _EMeetingModelPrivate gboolean book_loaded; gboolean book_load_wait; - GList *refresh_callbacks; - GList *refresh_data; - gint refresh_count; - gboolean refreshing; + GPtrArray *refresh_queue; + GHashTable *refresh_data; + gint refresh_idle_id; /* For invite others dialogs */ GNOME_Evolution_Addressbook_SelectNames corba_select_names; @@ -103,19 +89,21 @@ static icalparameter_role roles[] = {ICAL_ROLE_CHAIR, ICAL_ROLE_NONPARTICIPANT, ICAL_ROLE_NONE}; -typedef struct _EMeetingModelAttendeeRefreshData EMeetingModelAttendeeRefreshData; -struct _EMeetingModelAttendeeRefreshData { - char buffer[BUF_SIZE]; - GString *string; - +typedef struct _EMeetingModelQueueData EMeetingModelQueueData; +struct _EMeetingModelQueueData { + EMeetingModel *im; EMeetingAttendee *ia; -}; -typedef struct _EMeetingModelRefreshData EMeetingModelRefreshData; -struct _EMeetingModelRefreshData { - EMeetingModel *im; + gboolean refreshing; - EMeetingModelAttendeeRefreshData attendee_data; + EMeetingTime start; + EMeetingTime end; + + char buffer[BUF_SIZE]; + GString *string; + + GPtrArray *call_backs; + GPtrArray *data; }; @@ -123,6 +111,15 @@ static void class_init (EMeetingModelClass *klass); static void init (EMeetingModel *model); static void destroy (GtkObject *obj); +static void refresh_queue_add (EMeetingModel *im, int row, + EMeetingTime *start, + EMeetingTime *end, + EMeetingModelRefreshCallback call_back, + gpointer data); +static void refresh_queue_remove (EMeetingModel *im, + EMeetingAttendee *ia); +static gboolean refresh_busy_periods (gpointer data); + static void attendee_changed_cb (EMeetingAttendee *ia, gpointer data); static void select_names_ok_cb (BonoboListener *listener, char *event_name, @@ -363,7 +360,7 @@ partstat_to_text (icalparameter_partstat partstat) static int column_count (ETableModel *etm) { - return ITIP_COLUMN_COUNT; + return E_MEETING_MODEL_COLUMN_COUNT; } static int @@ -389,7 +386,7 @@ append_row (ETableModel *etm, ETableModel *source, int row) im = E_MEETING_MODEL (etm); priv = im->priv; - address = (char *) e_table_model_value_at (source, ITIP_ADDRESS_COL, row); + address = (char *) e_table_model_value_at (source, E_MEETING_MODEL_ADDRESS_COL, row); if (find_match (im, address, NULL) != NULL) { return; } @@ -397,15 +394,15 @@ append_row (ETableModel *etm, ETableModel *source, int row) ia = E_MEETING_ATTENDEE (e_meeting_attendee_new ()); e_meeting_attendee_set_address (ia, g_strdup_printf ("MAILTO:%s", address)); - e_meeting_attendee_set_member (ia, g_strdup (e_table_model_value_at (source, ITIP_MEMBER_COL, row))); - e_meeting_attendee_set_cutype (ia, text_to_type (e_table_model_value_at (source, ITIP_TYPE_COL, row))); - e_meeting_attendee_set_role (ia, text_to_role (e_table_model_value_at (source, ITIP_ROLE_COL, row))); - e_meeting_attendee_set_rsvp (ia, text_to_boolean (e_table_model_value_at (source, ITIP_RSVP_COL, row))); - e_meeting_attendee_set_delto (ia, g_strdup (e_table_model_value_at (source, ITIP_DELTO_COL, row))); - e_meeting_attendee_set_delfrom (ia, g_strdup (e_table_model_value_at (source, ITIP_DELFROM_COL, row))); - e_meeting_attendee_set_status (ia, text_to_partstat (e_table_model_value_at (source, ITIP_STATUS_COL, row))); - e_meeting_attendee_set_cn (ia, g_strdup (e_table_model_value_at (source, ITIP_CN_COL, row))); - e_meeting_attendee_set_language (ia, g_strdup (e_table_model_value_at (source, ITIP_LANGUAGE_COL, row))); + e_meeting_attendee_set_member (ia, g_strdup (e_table_model_value_at (source, E_MEETING_MODEL_MEMBER_COL, row))); + e_meeting_attendee_set_cutype (ia, text_to_type (e_table_model_value_at (source, E_MEETING_MODEL_TYPE_COL, row))); + e_meeting_attendee_set_role (ia, text_to_role (e_table_model_value_at (source, E_MEETING_MODEL_ROLE_COL, row))); + e_meeting_attendee_set_rsvp (ia, text_to_boolean (e_table_model_value_at (source, E_MEETING_MODEL_RSVP_COL, row))); + e_meeting_attendee_set_delto (ia, g_strdup (e_table_model_value_at (source, E_MEETING_MODEL_DELTO_COL, row))); + e_meeting_attendee_set_delfrom (ia, g_strdup (e_table_model_value_at (source, E_MEETING_MODEL_DELFROM_COL, row))); + e_meeting_attendee_set_status (ia, text_to_partstat (e_table_model_value_at (source, E_MEETING_MODEL_STATUS_COL, row))); + e_meeting_attendee_set_cn (ia, g_strdup (e_table_model_value_at (source, E_MEETING_MODEL_CN_COL, row))); + e_meeting_attendee_set_language (ia, g_strdup (e_table_model_value_at (source, E_MEETING_MODEL_LANGUAGE_COL, row))); e_meeting_model_add_attendee (E_MEETING_MODEL (etm), ia); } @@ -423,25 +420,25 @@ value_at (ETableModel *etm, int col, int row) ia = g_ptr_array_index (priv->attendees, row); switch (col) { - case ITIP_ADDRESS_COL: + case E_MEETING_MODEL_ADDRESS_COL: return (void *)itip_strip_mailto (e_meeting_attendee_get_address (ia)); - case ITIP_MEMBER_COL: + case E_MEETING_MODEL_MEMBER_COL: return (void *)e_meeting_attendee_get_member (ia); - case ITIP_TYPE_COL: + case E_MEETING_MODEL_TYPE_COL: return type_to_text (e_meeting_attendee_get_cutype (ia)); - case ITIP_ROLE_COL: + case E_MEETING_MODEL_ROLE_COL: return role_to_text (e_meeting_attendee_get_role (ia)); - case ITIP_RSVP_COL: + case E_MEETING_MODEL_RSVP_COL: return boolean_to_text (e_meeting_attendee_get_rsvp (ia)); - case ITIP_DELTO_COL: + case E_MEETING_MODEL_DELTO_COL: return (void *)itip_strip_mailto (e_meeting_attendee_get_delto (ia)); - case ITIP_DELFROM_COL: + case E_MEETING_MODEL_DELFROM_COL: return (void *)itip_strip_mailto (e_meeting_attendee_get_delfrom (ia)); - case ITIP_STATUS_COL: + case E_MEETING_MODEL_STATUS_COL: return partstat_to_text (e_meeting_attendee_get_status (ia)); - case ITIP_CN_COL: + case E_MEETING_MODEL_CN_COL: return (void *)e_meeting_attendee_get_cn (ia); - case ITIP_LANGUAGE_COL: + case E_MEETING_MODEL_LANGUAGE_COL: return (void *)e_meeting_attendee_get_language (ia); } @@ -459,47 +456,51 @@ set_value_at (ETableModel *etm, int col, int row, const void *val) priv = im->priv; ia = g_ptr_array_index (priv->attendees, row); + + e_table_model_pre_change (etm); switch (col) { - case ITIP_ADDRESS_COL: + case E_MEETING_MODEL_ADDRESS_COL: e_meeting_attendee_set_address (ia, g_strdup_printf ("MAILTO:%s", (char *) val)); break; - case ITIP_MEMBER_COL: + case E_MEETING_MODEL_MEMBER_COL: e_meeting_attendee_set_member (ia, g_strdup (val)); break; - case ITIP_TYPE_COL: + case E_MEETING_MODEL_TYPE_COL: e_meeting_attendee_set_cutype (ia, text_to_type (val)); break; - case ITIP_ROLE_COL: + case E_MEETING_MODEL_ROLE_COL: e_meeting_attendee_set_role (ia, text_to_role (val)); break; - case ITIP_RSVP_COL: + case E_MEETING_MODEL_RSVP_COL: e_meeting_attendee_set_rsvp (ia, text_to_boolean (val)); break; - case ITIP_DELTO_COL: + case E_MEETING_MODEL_DELTO_COL: e_meeting_attendee_set_delto (ia, g_strdup (val)); break; - case ITIP_DELFROM_COL: + case E_MEETING_MODEL_DELFROM_COL: e_meeting_attendee_set_delfrom (ia, g_strdup (val)); break; - case ITIP_STATUS_COL: + case E_MEETING_MODEL_STATUS_COL: e_meeting_attendee_set_status (ia, text_to_partstat (val)); break; - case ITIP_CN_COL: + case E_MEETING_MODEL_CN_COL: e_meeting_attendee_set_cn (ia, g_strdup (val)); break; - case ITIP_LANGUAGE_COL: + case E_MEETING_MODEL_LANGUAGE_COL: e_meeting_attendee_set_language (ia, g_strdup (val)); break; } + + e_table_model_cell_changed (etm, col, row); } static gboolean is_cell_editable (ETableModel *etm, int col, int row) { switch (col) { - case ITIP_DELTO_COL: - case ITIP_DELFROM_COL: + case E_MEETING_MODEL_DELTO_COL: + case E_MEETING_MODEL_DELFROM_COL: return FALSE; default: @@ -524,25 +525,25 @@ static void * init_value (ETableModel *etm, int col) { switch (col) { - case ITIP_ADDRESS_COL: + case E_MEETING_MODEL_ADDRESS_COL: return g_strdup (""); - case ITIP_MEMBER_COL: + case E_MEETING_MODEL_MEMBER_COL: return g_strdup (""); - case ITIP_TYPE_COL: + case E_MEETING_MODEL_TYPE_COL: return g_strdup (_("Individual")); - case ITIP_ROLE_COL: + case E_MEETING_MODEL_ROLE_COL: return g_strdup (_("Required Participant")); - case ITIP_RSVP_COL: + case E_MEETING_MODEL_RSVP_COL: return g_strdup (_("Yes")); - case ITIP_DELTO_COL: + case E_MEETING_MODEL_DELTO_COL: return g_strdup (""); - case ITIP_DELFROM_COL: + case E_MEETING_MODEL_DELFROM_COL: return g_strdup (""); - case ITIP_STATUS_COL: + case E_MEETING_MODEL_STATUS_COL: return g_strdup (_("Needs Action")); - case ITIP_CN_COL: + case E_MEETING_MODEL_CN_COL: return g_strdup (""); - case ITIP_LANGUAGE_COL: + case E_MEETING_MODEL_LANGUAGE_COL: return g_strdup ("en"); } @@ -554,11 +555,11 @@ value_is_empty (ETableModel *etm, int col, const void *val) { switch (col) { - case ITIP_ADDRESS_COL: - case ITIP_MEMBER_COL: - case ITIP_DELTO_COL: - case ITIP_DELFROM_COL: - case ITIP_CN_COL: + case E_MEETING_MODEL_ADDRESS_COL: + case E_MEETING_MODEL_MEMBER_COL: + case E_MEETING_MODEL_DELTO_COL: + case E_MEETING_MODEL_DELFROM_COL: + case E_MEETING_MODEL_CN_COL: if (val && !g_strcasecmp (val, "")) return TRUE; else @@ -585,7 +586,7 @@ get_key (ETableModel *source, int row, gpointer data) im = E_MEETING_MODEL (source); priv = im->priv; - str = value_at (source, ITIP_DELTO_COL, row); + str = value_at (source, E_MEETING_MODEL_DELTO_COL, row); if (str && *str) return g_strdup ("delegator"); @@ -647,7 +648,7 @@ init (EMeetingModel *im) im->priv = priv; priv->attendees = g_ptr_array_new (); - + priv->without = E_TABLE_WITHOUT (e_table_without_new (E_TABLE_MODEL (im), g_str_hash, g_str_equal, @@ -664,8 +665,10 @@ init (EMeetingModel *im) priv->ebook = NULL; priv->book_loaded = FALSE; priv->book_load_wait = FALSE; - - priv->refreshing = FALSE; + + priv->refresh_queue = g_ptr_array_new (); + priv->refresh_data = g_hash_table_new (g_direct_hash, g_direct_equal); + priv->refresh_idle_id = -1; start_addressbook_server (im); } @@ -673,15 +676,15 @@ init (EMeetingModel *im) static void destroy (GtkObject *obj) { - EMeetingModel *model = E_MEETING_MODEL (obj); + EMeetingModel *im = E_MEETING_MODEL (obj); EMeetingModelPrivate *priv; - gint i; + int i; - priv = model->priv; + priv = im->priv; for (i = 0; i < priv->attendees->len; i++) - gtk_object_unref (GTK_OBJECT (g_ptr_array_index(priv->attendees, i))); - g_ptr_array_free (priv->attendees, FALSE); + gtk_object_unref (GTK_OBJECT (g_ptr_array_index (priv->attendees, i))); + g_ptr_array_free (priv->attendees, TRUE); if (priv->client != NULL) gtk_object_unref (GTK_OBJECT (priv->client)); @@ -695,7 +698,15 @@ destroy (GtkObject *obj) bonobo_object_release_unref (priv->corba_select_names, &ev); CORBA_exception_free (&ev); } - + + while (priv->refresh_queue->len > 0) + refresh_queue_remove (im, g_ptr_array_index (priv->refresh_queue, 0)); + g_ptr_array_free (priv->refresh_queue, TRUE); + g_hash_table_destroy (priv->refresh_data); + + if (priv->refresh_idle_id) + g_source_remove (priv->refresh_idle_id); + g_free (priv); } @@ -873,28 +884,28 @@ e_meeting_model_add_attendee_with_defaults (EMeetingModel *im) ia = E_MEETING_ATTENDEE (e_meeting_attendee_new ()); - e_meeting_attendee_set_address (ia, init_value (E_TABLE_MODEL (im), ITIP_ADDRESS_COL)); - e_meeting_attendee_set_member (ia, init_value (E_TABLE_MODEL (im), ITIP_MEMBER_COL)); + e_meeting_attendee_set_address (ia, init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_ADDRESS_COL)); + e_meeting_attendee_set_member (ia, init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_MEMBER_COL)); - str = init_value (E_TABLE_MODEL (im), ITIP_TYPE_COL); + str = init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_TYPE_COL); e_meeting_attendee_set_cutype (ia, text_to_type (str)); g_free (str); - str = init_value (E_TABLE_MODEL (im), ITIP_ROLE_COL); + str = init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_ROLE_COL); e_meeting_attendee_set_role (ia, text_to_role (str)); g_free (str); - str = init_value (E_TABLE_MODEL (im), ITIP_RSVP_COL); + str = init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_RSVP_COL); e_meeting_attendee_set_role (ia, text_to_boolean (str)); g_free (str); - e_meeting_attendee_set_delto (ia, init_value (E_TABLE_MODEL (im), ITIP_DELTO_COL)); - e_meeting_attendee_set_delfrom (ia, init_value (E_TABLE_MODEL (im), ITIP_DELFROM_COL)); + e_meeting_attendee_set_delto (ia, init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_DELTO_COL)); + e_meeting_attendee_set_delfrom (ia, init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_DELFROM_COL)); - str = init_value (E_TABLE_MODEL (im), ITIP_STATUS_COL); + str = init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_STATUS_COL); e_meeting_attendee_set_status (ia, text_to_partstat (str)); g_free (str); - e_meeting_attendee_set_cn (ia, init_value (E_TABLE_MODEL (im), ITIP_CN_COL)); - e_meeting_attendee_set_language (ia, init_value (E_TABLE_MODEL (im), ITIP_LANGUAGE_COL)); + e_meeting_attendee_set_cn (ia, init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_CN_COL)); + e_meeting_attendee_set_language (ia, init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_LANGUAGE_COL)); e_meeting_model_add_attendee (im, ia); @@ -1049,6 +1060,98 @@ find_zone (icalproperty *ip, icalcomponent *tz_top_level) return NULL; } + +static void +refresh_queue_add (EMeetingModel *im, int row, + EMeetingTime *start, + EMeetingTime *end, + EMeetingModelRefreshCallback call_back, + gpointer data) +{ + EMeetingModelPrivate *priv; + EMeetingAttendee *ia; + EMeetingModelQueueData *qdata; + + priv = im->priv; + + ia = g_ptr_array_index (priv->attendees, row); + if (ia == NULL) + return; + + qdata = g_hash_table_lookup (priv->refresh_data, ia); + if (qdata == NULL) { + qdata = g_new0 (EMeetingModelQueueData, 1); + + qdata->im = im; + qdata->ia = ia; + e_meeting_attendee_clear_busy_periods (ia); + e_meeting_attendee_set_has_calendar_info (ia, FALSE); + + qdata->start = *start; + qdata->end = *end; + qdata->string = g_string_new (NULL); + qdata->call_backs = g_ptr_array_new (); + qdata->data = g_ptr_array_new (); + g_ptr_array_add (qdata->call_backs, call_back); + g_ptr_array_add (qdata->data, data); + + g_hash_table_insert (priv->refresh_data, ia, 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) + qdata->end = *end; + g_ptr_array_add (qdata->call_backs, call_back); + g_ptr_array_add (qdata->data, data); + } + + gtk_object_ref (GTK_OBJECT (ia)); + g_ptr_array_add (priv->refresh_queue, ia); + + if (priv->refresh_idle_id == -1) + priv->refresh_idle_id = g_idle_add (refresh_busy_periods, im); +} + +static void +refresh_queue_remove (EMeetingModel *im, EMeetingAttendee *ia) +{ + EMeetingModelPrivate *priv; + EMeetingModelQueueData *qdata; + + priv = im->priv; + + /* Free the queue data */ + qdata = g_hash_table_lookup (priv->refresh_data, ia); + g_assert (qdata != NULL); + + g_hash_table_remove (priv->refresh_data, ia); + g_ptr_array_free (qdata->call_backs, TRUE); + g_ptr_array_free (qdata->data, TRUE); + g_free (qdata); + + /* Unref the attendee */ + g_ptr_array_remove (priv->refresh_queue, ia); + gtk_object_unref (GTK_OBJECT (ia)); +} + +static void +process_callbacks (EMeetingModelQueueData *qdata) +{ + int i; + + for (i = 0; i < qdata->call_backs->len; i++) { + EMeetingModelRefreshCallback call_back; + gpointer *data; + + call_back = g_ptr_array_index (qdata->call_backs, i); + data = g_ptr_array_index (qdata->data, i); + + call_back (data); + } + + refresh_queue_remove (qdata->im, qdata->ia); +} + static void process_free_busy_comp (EMeetingAttendee *ia, icalcomponent *fb_comp, @@ -1147,39 +1250,21 @@ process_free_busy_comp (EMeetingAttendee *ia, } static void -process_callbacks (EMeetingModel *im) -{ - EMeetingModelPrivate *priv; - GList *l, *m; - - priv = im->priv; - - for (l = priv->refresh_callbacks, m = priv->refresh_data; l != NULL; l = l->next, m = m->next) { - EMeetingModelRefreshCallback cb = l->data; - - cb (m->data); - } - - g_list_free (priv->refresh_callbacks); - g_list_free (priv->refresh_data); - priv->refresh_callbacks = NULL; - priv->refresh_data = NULL; - - priv->refreshing = FALSE; -} - -static void -process_free_busy (EMeetingModel *im, EMeetingAttendee *ia, char *text) +process_free_busy (EMeetingModelQueueData *qdata, char *text) { - EMeetingModelPrivate *priv; + EMeetingModel *im = qdata->im; + EMeetingModelPrivate *priv; + EMeetingAttendee *ia = qdata->ia; icalcomponent *main_comp; icalcomponent_kind kind = ICAL_NO_COMPONENT; priv = im->priv; main_comp = icalparser_parse_string (text); - if (main_comp == NULL) - return; + if (main_comp == NULL) { + process_callbacks (qdata); + return; + } kind = icalcomponent_isa (main_comp); if (kind == ICAL_VCALENDAR_COMPONENT) { @@ -1212,6 +1297,8 @@ process_free_busy (EMeetingModel *im, EMeetingAttendee *ia, char *text) } icalcomponent_free (main_comp); + + process_callbacks (qdata); } static void @@ -1219,17 +1306,9 @@ async_close (GnomeVFSAsyncHandle *handle, GnomeVFSResult result, gpointer data) { - EMeetingModelRefreshData *r_data = data; - EMeetingModelPrivate *priv; + EMeetingModelQueueData *qdata = data; - process_free_busy (r_data->im, r_data->attendee_data.ia, r_data->attendee_data.string->str); - - priv = r_data->im->priv; - - priv->refresh_count--; - - if (priv->refresh_count == 0) - process_callbacks (r_data->im); + process_free_busy (qdata, qdata->string->str); } static void @@ -1240,23 +1319,23 @@ async_read (GnomeVFSAsyncHandle *handle, GnomeVFSFileSize read, gpointer data) { - EMeetingModelRefreshData *r_data = data; + EMeetingModelQueueData *qdata = data; GnomeVFSFileSize buf_size = BUF_SIZE - 1; if (result != GNOME_VFS_OK) { - gnome_vfs_async_close (handle, async_close, r_data); + gnome_vfs_async_close (handle, async_close, qdata); return; } ((char *)buffer)[read] = '\0'; - r_data->attendee_data.string = g_string_append (r_data->attendee_data.string, buffer); + qdata->string = g_string_append (qdata->string, buffer); if (read < requested) { - gnome_vfs_async_close (handle, async_close, r_data); + gnome_vfs_async_close (handle, async_close, qdata); return; } - gnome_vfs_async_read (handle, r_data->attendee_data.buffer, buf_size, async_read, r_data); + gnome_vfs_async_read (handle, qdata->buffer, buf_size, async_read, qdata); } static void @@ -1264,150 +1343,118 @@ async_open (GnomeVFSAsyncHandle *handle, GnomeVFSResult result, gpointer data) { - EMeetingModelRefreshData *r_data = data; + EMeetingModelQueueData *qdata = data; GnomeVFSFileSize buf_size = BUF_SIZE - 1; if (result != GNOME_VFS_OK) { - gnome_vfs_async_close (handle, async_close, r_data); + gnome_vfs_async_close (handle, async_close, qdata); return; } - gnome_vfs_async_read (handle, r_data->attendee_data.buffer, buf_size, async_read, r_data); + gnome_vfs_async_read (handle, qdata->buffer, buf_size, async_read, qdata); } static void cursor_cb (EBook *book, EBookStatus status, ECardCursor *cursor, gpointer data) { - EMeetingModel *im = E_MEETING_MODEL (data); - EMeetingModelPrivate *priv; - int length, i, j; + EMeetingModelQueueData *qdata = data; + int length, i; if (status != E_BOOK_STATUS_SUCCESS) return; - priv = im->priv; - length = e_card_cursor_get_length (cursor); - priv->refresh_count = 0; - for (i = 0; i < length; i ++) { GnomeVFSAsyncHandle *handle; ECard *card = e_card_cursor_get_nth (cursor, i); - EMeetingModelRefreshData *r_data = g_new0 (EMeetingModelRefreshData, 1); - EMeetingAttendee *ia = NULL; - + const char *addr; + if (card->fburl == NULL) continue; - - for (j = 0; j < priv->attendees->len; j++) { - ia = g_ptr_array_index (priv->attendees, j); - if (e_card_email_match_string (card, itip_strip_mailto (e_meeting_attendee_get_address (ia)))) - break; - } - if (ia == NULL) + + addr = itip_strip_mailto (e_meeting_attendee_get_address (qdata->ia)); + if (!e_card_email_match_string (card, addr)) continue; - - r_data->im = im; - r_data->attendee_data.string = g_string_new (NULL); - r_data->attendee_data.ia = ia; - - priv->refresh_count++; - + /* Read in free/busy data from the url */ - gnome_vfs_async_open (&handle, card->fburl, GNOME_VFS_OPEN_READ, async_open, r_data); + gnome_vfs_async_open (&handle, card->fburl, GNOME_VFS_OPEN_READ, async_open, qdata); + return; } - /* If we didn't find anybody */ - if (priv->refresh_count == 0) - process_callbacks (im); + process_callbacks (qdata); } -void -e_meeting_model_refresh_busy_periods (EMeetingModel *im, - EMeetingTime *start, - EMeetingTime *end, - EMeetingModelRefreshCallback call_back, - gpointer data) -{ +static gboolean +refresh_busy_periods (gpointer data) +{ + EMeetingModel *im = E_MEETING_MODEL (data); EMeetingModelPrivate *priv; - GPtrArray *not_found; - GString *string; + EMeetingAttendee *ia = NULL; + EMeetingModelQueueData *qdata = NULL; + char *query; int i; priv = im->priv; - priv->refresh_callbacks = g_list_append (priv->refresh_callbacks, call_back); - priv->refresh_data = g_list_append (priv->refresh_data, data); + /* Check to see if there are any remaining attendees in the queue */ + for (i = 0; i < priv->refresh_queue->len; i++) { + ia = g_ptr_array_index (priv->refresh_queue, i); + g_assert (ia != NULL); - if (priv->refreshing) - return; - - priv->refreshing = TRUE; + qdata = g_hash_table_lookup (priv->refresh_data, ia); + g_assert (qdata != NULL); - /* To track what we don't find on the server */ - not_found = g_ptr_array_new (); - g_ptr_array_set_size (not_found, priv->attendees->len); - for (i = 0; i < priv->attendees->len; i++) - g_ptr_array_index (not_found, i) = g_ptr_array_index (priv->attendees, i); + if (!qdata->refreshing) + break; + } + /* The everything in the queue is being refreshed */ + if (i >= priv->refresh_queue->len) { + priv->refresh_idle_id = -1; + return FALSE; + } + + /* Indicate we are trying to refresh it */ + qdata->refreshing = TRUE; + /* Check the server for free busy data */ if (priv->client) { - GList *fb_data, *users = NULL, *l; + GList *fb_data, *users = NULL; struct icaltimetype itt; time_t startt, endt; + const char *user; itt = icaltime_null_time (); - itt.year = g_date_year (&start->date); - itt.month = g_date_month (&start->date); - itt.day = g_date_day (&start->date); - itt.hour = start->hour; - itt.minute = start->minute; + 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); itt = icaltime_null_time (); - itt.year = g_date_year (&end->date); - itt.month = g_date_month (&end->date); - itt.day = g_date_day (&end->date); - itt.hour = end->hour; - itt.minute = end->minute; + itt.year = g_date_year (&qdata->end.date); + itt.month = g_date_month (&qdata->end.date); + 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); - - for (i = 0; i < priv->attendees->len; i++) { - EMeetingAttendee *ia = g_ptr_array_index (priv->attendees, i); - const char *user; - - user = itip_strip_mailto (e_meeting_attendee_get_address (ia)); - users = g_list_append (users, g_strdup (user)); - } + user = itip_strip_mailto (e_meeting_attendee_get_address (ia)); + users = g_list_append (users, g_strdup (user)); fb_data = cal_client_get_free_busy (priv->client, users, startt, endt); g_list_foreach (users, (GFunc)g_free, NULL); g_list_free (users); - for (l = fb_data; l != NULL; l = l->next) { - CalComponent *comp = l->data; - EMeetingAttendee *ia = NULL; - CalComponentOrganizer org; - - /* Process the data for any attendees found */ - cal_component_get_organizer (comp, &org); - for (i = 0; i < priv->attendees->len; i++) { - ia = g_ptr_array_index (priv->attendees, i); - if (org.value && !strcmp (org.value, e_meeting_attendee_get_address (ia))) { - g_ptr_array_remove_fast (not_found, ia); - break; - } - ia = NULL; - } - - if (ia != NULL) { - char *comp_str; + if (fb_data != NULL) { + CalComponent *comp = fb_data->data; + char *comp_str; - comp_str = cal_component_get_as_string (comp); - process_free_busy (im, ia, comp_str); - g_free (comp_str); - } + comp_str = cal_component_get_as_string (comp); + process_free_busy (qdata, comp_str); + g_free (comp_str); + return TRUE; } } @@ -1417,29 +1464,54 @@ e_meeting_model_refresh_busy_periods (EMeetingModel *im, gtk_main (); } - string = g_string_new ("(or "); - for (i = 0; i < not_found->len; i++) { - EMeetingAttendee *ia = g_ptr_array_index (not_found, i); - char *query; - - if (!e_meeting_attendee_is_set_address (ia)) - continue; + if (!e_meeting_attendee_is_set_address (ia)) { + process_callbacks (qdata); + return TRUE; + } + + query = g_strdup_printf ("(contains \"email\" \"%s\")", + itip_strip_mailto (e_meeting_attendee_get_address (ia))); + e_book_get_cursor (priv->ebook, query, cursor_cb, qdata); + g_free (query); + + return TRUE; +} - e_meeting_attendee_clear_busy_periods (ia); +void +e_meeting_model_refresh_all_busy_periods (EMeetingModel *im, + EMeetingTime *start, + EMeetingTime *end, + EMeetingModelRefreshCallback call_back, + gpointer data) +{ + EMeetingModelPrivate *priv; + int i; + + g_return_if_fail (im != NULL); + g_return_if_fail (E_IS_MEETING_MODEL (im)); - query = g_strdup_printf ("(contains \"email\" \"%s\")", itip_strip_mailto (e_meeting_attendee_get_address (ia))); - g_string_append (string, query); - g_free (query); - } - g_string_append_c (string, ')'); + priv = im->priv; - if (not_found->len > 0) - e_book_get_cursor (priv->ebook, string->str, cursor_cb, im); - else - process_callbacks (im); + for (i = 0; i < priv->attendees->len; i++) + refresh_queue_add (im, i, start, end, call_back, data); +} + +void +e_meeting_model_refresh_busy_periods (EMeetingModel *im, + int row, + EMeetingTime *start, + EMeetingTime *end, + EMeetingModelRefreshCallback call_back, + gpointer data) +{ + EMeetingModelPrivate *priv; + + g_return_if_fail (im != NULL); + g_return_if_fail (E_IS_MEETING_MODEL (im)); + + priv = im->priv; - g_ptr_array_free (not_found, FALSE); - g_string_free (string, TRUE); + refresh_queue_add (im, row, start, end, call_back, data); } ETableScrolled * diff --git a/calendar/gui/e-meeting-model.h b/calendar/gui/e-meeting-model.h index ad7d2d4c3a..431faf203b 100644 --- a/calendar/gui/e-meeting-model.h +++ b/calendar/gui/e-meeting-model.h @@ -49,6 +49,20 @@ typedef struct _EMeetingModel EMeetingModel; typedef struct _EMeetingModelPrivate EMeetingModelPrivate; typedef struct _EMeetingModelClass EMeetingModelClass; +typedef enum { + E_MEETING_MODEL_ADDRESS_COL, + E_MEETING_MODEL_MEMBER_COL, + E_MEETING_MODEL_TYPE_COL, + E_MEETING_MODEL_ROLE_COL, + E_MEETING_MODEL_RSVP_COL, + E_MEETING_MODEL_DELTO_COL, + E_MEETING_MODEL_DELFROM_COL, + E_MEETING_MODEL_STATUS_COL, + E_MEETING_MODEL_CN_COL, + E_MEETING_MODEL_LANGUAGE_COL, + E_MEETING_MODEL_COLUMN_COUNT +} EMeetingModelColumns; + struct _EMeetingModel { ETableModel parent; @@ -82,12 +96,20 @@ EMeetingAttendee *e_meeting_model_find_attendee_at_row (EMeetingModel *im, gint gint e_meeting_model_count_actual_attendees (EMeetingModel *im); const GPtrArray *e_meeting_model_get_attendees (EMeetingModel *im); + +void e_meeting_model_refresh_all_busy_periods (EMeetingModel *im, + EMeetingTime *start, + EMeetingTime *end, + EMeetingModelRefreshCallback call_back, + gpointer data); void e_meeting_model_refresh_busy_periods (EMeetingModel *im, + int row, EMeetingTime *start, EMeetingTime *end, EMeetingModelRefreshCallback call_back, gpointer data); + /* Helpful functions */ ETableScrolled *e_meeting_model_etable_from_model (EMeetingModel *im, const gchar *spec_file, const gchar *state_file); int e_meeting_model_etable_model_to_view_row (EMeetingModel *im, int model_row); diff --git a/calendar/gui/e-meeting-time-sel.c b/calendar/gui/e-meeting-time-sel.c index feee217129..50ba2af777 100644 --- a/calendar/gui/e-meeting-time-sel.c +++ b/calendar/gui/e-meeting-time-sel.c @@ -65,6 +65,7 @@ #include <widgets/misc/e-dateedit.h> #include "component-factory.h" #include "calendar-config.h" +#include "e-meeting-utils.h" #include "e-meeting-time-sel-item.h" /* An array of hour strings for 24 hour time, "0:00" .. "23:00". */ @@ -139,8 +140,6 @@ static void e_meeting_time_selector_table_vadjustment_changed (GtkAdjustment *ad static void e_meeting_time_selector_on_canvas_realized (GtkWidget *widget, EMeetingTimeSelector *mts); -static gint e_meeting_time_selector_compare_times (EMeetingTime*time1, - EMeetingTime*time2); static void e_meeting_time_selector_on_options_button_clicked (GtkWidget *button, EMeetingTimeSelector *mts); static void e_meeting_time_selector_options_menu_position_callback (GtkMenu *menu, @@ -211,7 +210,9 @@ static void e_meeting_time_selector_update_end_date_edit (EMeetingTimeSelector * static void e_meeting_time_selector_ensure_meeting_time_shown (EMeetingTimeSelector *mts); static void e_meeting_time_selector_update_dates_shown (EMeetingTimeSelector *mts); -static void row_count_changed_cb (ETableModel *etm, int row, int count, gpointer data); +static void rows_inserted_cb (ETableModel *etm, int row, int count, gpointer data); +static void cell_changed_cb (ETableModel *etm, int row, int col, gpointer data); +static void rows_deleted_cb (ETableModel *etm, int row, int count, gpointer data); static void sort_info_changed_cb (ETableSortInfo *info, gpointer data); static GtkTableClass *parent_class; @@ -354,9 +355,11 @@ e_meeting_time_selector_construct (EMeetingTimeSelector * mts, EMeetingModel *em gtk_object_ref (GTK_OBJECT (mts->model)); gtk_signal_connect (GTK_OBJECT (mts->model), "model_rows_inserted", - GTK_SIGNAL_FUNC (row_count_changed_cb), mts); + GTK_SIGNAL_FUNC (rows_inserted_cb), mts); + gtk_signal_connect (GTK_OBJECT (mts->model), "model_cell_changed", + GTK_SIGNAL_FUNC (cell_changed_cb), mts); gtk_signal_connect (GTK_OBJECT (mts->model), "model_rows_deleted", - GTK_SIGNAL_FUNC (row_count_changed_cb), mts); + GTK_SIGNAL_FUNC (rows_deleted_cb), mts); mts->etable = GTK_WIDGET (e_meeting_model_etable_from_model (mts->model, EVOLUTION_ETSPECDIR "/e-meeting-time-sel.etspec", @@ -1228,6 +1231,35 @@ e_meeting_time_selector_set_zoomed_out (EMeetingTimeSelector *mts, gtk_widget_queue_draw (mts->display_main); } +static void +e_meeting_time_selector_refresh_cb (gpointer data) +{ + EMeetingTimeSelector *mts = data; + gtk_widget_queue_draw (mts->display_top); + gtk_widget_queue_draw (mts->display_main); +} + +static void +e_meeting_time_selector_refresh_free_busy (EMeetingTimeSelector *mts, int row, gboolean all) +{ + EMeetingTime start, end; + + start = mts->meeting_start_time; + g_date_subtract_days (&start.date, E_MEETING_TIME_SELECTOR_FB_DAYS_BEFORE); + start.hour = 0; + start.minute = 0; + end = mts->meeting_end_time; + g_date_add_days (&end.date, E_MEETING_TIME_SELECTOR_FB_DAYS_AFTER); + end.hour = 0; + end.minute = 0; + + if (all) + e_meeting_model_refresh_all_busy_periods (mts->model, &start, &end, + e_meeting_time_selector_refresh_cb, mts); + else + e_meeting_model_refresh_busy_periods (mts->model, row, &start, &end, + e_meeting_time_selector_refresh_cb, mts); +} EMeetingTimeSelectorAutopickOption e_meeting_time_selector_get_autopick_option (EMeetingTimeSelector *mts) @@ -1281,32 +1313,6 @@ e_meeting_time_selector_attendee_set_send_meeting_to (EMeetingTimeSelector *mts, } #endif -static gint -e_meeting_time_selector_compare_times (EMeetingTime*time1, - EMeetingTime*time2) -{ - gint day_comparison; - - day_comparison = g_date_compare (&time1->date, - &time2->date); - if (day_comparison != 0) - return day_comparison; - - if (time1->hour < time2->hour) - return -1; - if (time1->hour > time2->hour) - return 1; - - if (time1->minute < time2->minute) - return -1; - if (time1->minute > time2->minute) - return 1; - - /* The start times are exactly the same. */ - return 0; -} - - /* * DEBUGGING ROUTINES - functions to output various bits of data. */ @@ -1437,35 +1443,15 @@ e_meeting_time_selector_options_menu_position_callback (GtkMenu *menu, } static void -e_meeting_time_selector_refresh_cb (gpointer data) -{ - EMeetingTimeSelector *mts = data; - gtk_widget_queue_draw (mts->display_top); - gtk_widget_queue_draw (mts->display_main); -} - -static void e_meeting_time_selector_on_update_free_busy (GtkWidget *button, EMeetingTimeSelector *mts) { - EMeetingTime start, end; - /* Make sure the menu pops down, which doesn't happen by default if keyboard accelerators are used. */ if (GTK_WIDGET_VISIBLE (mts->options_menu)) gtk_menu_popdown (GTK_MENU (mts->options_menu)); - - start = mts->meeting_start_time; - g_date_subtract_days (&start.date, E_MEETING_TIME_SELECTOR_FB_DAYS_BEFORE); - start.hour = 0; - start.minute = 0; - end = mts->meeting_end_time; - g_date_add_days (&end.date, E_MEETING_TIME_SELECTOR_FB_DAYS_AFTER); - end.hour = 0; - end.minute = 0; - e_meeting_model_refresh_busy_periods (mts->model, &start, &end, - e_meeting_time_selector_refresh_cb, mts); + e_meeting_time_selector_refresh_free_busy (mts, 0, TRUE); } @@ -1590,10 +1576,10 @@ e_meeting_time_selector_autopick (EMeetingTimeSelector *mts, available, in case we don't find any free resources. */ if (forward) { - if (!resource_free || e_meeting_time_selector_compare_times (resource_free, &period->end) > 0) + if (!resource_free || e_meeting_time_compare_times (resource_free, &period->end) > 0) resource_free = &period->end; } else { - if (!resource_free || e_meeting_time_selector_compare_times (resource_free, &period->start) < 0) + if (!resource_free || e_meeting_time_compare_times (resource_free, &period->start) < 0) resource_free = &period->start; } @@ -1897,13 +1883,13 @@ e_meeting_time_selector_find_time_clash (EMeetingTimeSelector *mts, /* If the period starts at or after the end time, there is no clash and we are finished. The busy periods are sorted by their start times, so all the rest will be later. */ - if (e_meeting_time_selector_compare_times (&period->start, end_time) >= 0) + if (e_meeting_time_compare_times (&period->start, end_time) >= 0) return NULL; /* If the period ends after the start time, we have found a clash. From the above test we already know the busy period isn't completely after the meeting time. */ - if (e_meeting_time_selector_compare_times (&period->end, start_time) > 0) + if (e_meeting_time_compare_times (&period->end, start_time) > 0) return period; period_num++; @@ -2178,7 +2164,7 @@ e_meeting_time_selector_on_start_time_changed (GtkWidget *widget, mtstime.minute = minute; /* If the time hasn't changed, just return. */ - if (e_meeting_time_selector_compare_times (&mtstime, &mts->meeting_start_time) == 0) + if (e_meeting_time_compare_times (&mtstime, &mts->meeting_start_time) == 0) return; /* Calculate the current meeting duration. */ @@ -2226,14 +2212,14 @@ e_meeting_time_selector_on_end_time_changed (GtkWidget *widget, mtstime.minute = minute; /* If the time hasn't changed, just return. */ - if (e_meeting_time_selector_compare_times (&mtstime, &mts->meeting_end_time) == 0) + if (e_meeting_time_compare_times (&mtstime, &mts->meeting_end_time) == 0) return; /* Set the new end time. */ mts->meeting_end_time = mtstime; /* If the start time is after the end time, set it to the same time. */ - if (e_meeting_time_selector_compare_times (&mtstime, &mts->meeting_start_time) <= 0) { + if (e_meeting_time_compare_times (&mtstime, &mts->meeting_start_time) <= 0) { /* We set it first, before updating the widget, so the signal handler will just return. */ mts->meeting_start_time = mtstime; @@ -2392,9 +2378,9 @@ e_meeting_time_selector_drag_meeting_time (EMeetingTimeSelector *mts, e_meeting_time_selector_fix_time_overflows (&drag_time); /* Now make sure we are between first_time & last_time. */ - if (e_meeting_time_selector_compare_times (&drag_time, &first_time) < 0) + if (e_meeting_time_compare_times (&drag_time, &first_time) < 0) drag_time = first_time; - if (e_meeting_time_selector_compare_times (&drag_time, &last_time) > 0) + if (e_meeting_time_compare_times (&drag_time, &last_time) > 0) drag_time = last_time; /* Set the meeting start or end time to drag_time. */ @@ -2404,23 +2390,23 @@ e_meeting_time_selector_drag_meeting_time (EMeetingTimeSelector *mts, time_to_set = &mts->meeting_end_time; /* If the time is unchanged, just return. */ - if (e_meeting_time_selector_compare_times (time_to_set, &drag_time) == 0) + if (e_meeting_time_compare_times (time_to_set, &drag_time) == 0) return; /* Don't let an empty occur for all day events */ if (mts->all_day && mts->dragging_position == E_MEETING_TIME_SELECTOR_POS_START - && e_meeting_time_selector_compare_times (&mts->meeting_end_time, &drag_time) == 0) + && e_meeting_time_compare_times (&mts->meeting_end_time, &drag_time) == 0) return; else if (mts->all_day && mts->dragging_position == E_MEETING_TIME_SELECTOR_POS_END - && e_meeting_time_selector_compare_times (&mts->meeting_start_time, &drag_time) == 0) + && e_meeting_time_compare_times (&mts->meeting_start_time, &drag_time) == 0) return; *time_to_set = drag_time; /* Check if the start time and end time need to be switched. */ - if (e_meeting_time_selector_compare_times (&mts->meeting_start_time, + if (e_meeting_time_compare_times (&mts->meeting_start_time, &mts->meeting_end_time) > 0) { drag_time = mts->meeting_start_time; mts->meeting_start_time = mts->meeting_end_time; @@ -2548,7 +2534,7 @@ e_meeting_time_selector_timeout_handler (gpointer data) time_to_set = &mts->meeting_end_time; /* If the time is unchanged, just return. */ - if (e_meeting_time_selector_compare_times (time_to_set, &drag_time) == 0) { + if (e_meeting_time_compare_times (time_to_set, &drag_time) == 0) { GDK_THREADS_LEAVE (); goto scroll; } @@ -2556,17 +2542,17 @@ e_meeting_time_selector_timeout_handler (gpointer data) /* Don't let an empty occur for all day events */ if (mts->all_day && mts->dragging_position == E_MEETING_TIME_SELECTOR_POS_START - && e_meeting_time_selector_compare_times (&mts->meeting_end_time, &drag_time) == 0) + && e_meeting_time_compare_times (&mts->meeting_end_time, &drag_time) == 0) goto scroll; else if (mts->all_day && mts->dragging_position == E_MEETING_TIME_SELECTOR_POS_END - && e_meeting_time_selector_compare_times (&mts->meeting_start_time, &drag_time) == 0) + && e_meeting_time_compare_times (&mts->meeting_start_time, &drag_time) == 0) goto scroll; *time_to_set = drag_time; /* Check if the start time and end time need to be switched. */ - if (e_meeting_time_selector_compare_times (&mts->meeting_start_time, &mts->meeting_end_time) > 0) { + if (e_meeting_time_compare_times (&mts->meeting_start_time, &mts->meeting_end_time) > 0) { drag_time = mts->meeting_start_time; mts->meeting_start_time = mts->meeting_end_time; mts->meeting_end_time = drag_time; @@ -2845,7 +2831,37 @@ e_meeting_time_selector_calculate_time_position (EMeetingTimeSelector *mts, } static void -row_count_changed_cb (ETableModel *etm, int row, int count, gpointer data) +rows_inserted_cb (ETableModel *etm, int row, int count, gpointer data) +{ + EMeetingTimeSelector *mts = E_MEETING_TIME_SELECTOR (data); + int i; + + /* Update the scroll region. */ + e_meeting_time_selector_update_main_canvas_scroll_region (mts); + + /* Redraw */ + gtk_widget_queue_draw (mts->display_top); + gtk_widget_queue_draw (mts->display_main); + + /* Get the latest free/busy info */ + for (i = 0; i < count; i++) + e_meeting_time_selector_refresh_free_busy (mts, row + i, FALSE); +} + +static void +cell_changed_cb (ETableModel *etm, int col, int row, gpointer data) +{ + EMeetingTimeSelector *mts = E_MEETING_TIME_SELECTOR (data); + + if (col != E_MEETING_MODEL_ADDRESS_COL) + return; + + /* Get the latest free/busy info */ + e_meeting_time_selector_refresh_free_busy (mts, row, FALSE); +} + +static void +rows_deleted_cb (ETableModel *etm, int row, int count, gpointer data) { EMeetingTimeSelector *mts = E_MEETING_TIME_SELECTOR (data); diff --git a/calendar/gui/e-meeting-utils.c b/calendar/gui/e-meeting-utils.c new file mode 100644 index 0000000000..496bb8ebaa --- /dev/null +++ b/calendar/gui/e-meeting-utils.c @@ -0,0 +1,52 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* itip-model.c + * + * Copyright (C) 2001 Ximian, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: JP Rosevear + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "e-meeting-utils.h" + +gint +e_meeting_time_compare_times (EMeetingTime*time1, + EMeetingTime*time2) +{ + gint day_comparison; + + day_comparison = g_date_compare (&time1->date, + &time2->date); + if (day_comparison != 0) + return day_comparison; + + if (time1->hour < time2->hour) + return -1; + if (time1->hour > time2->hour) + return 1; + + if (time1->minute < time2->minute) + return -1; + if (time1->minute > time2->minute) + return 1; + + /* The start times are exactly the same. */ + return 0; +} diff --git a/calendar/gui/e-meeting-utils.h b/calendar/gui/e-meeting-utils.h new file mode 100644 index 0000000000..4c2798fcf0 --- /dev/null +++ b/calendar/gui/e-meeting-utils.h @@ -0,0 +1,49 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* itip-attendee.h + * + * Copyright (C) 2001 Ximian, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: JP Rosevear + */ + +#ifndef _E_MEETING_UTILS_H_ +#define _E_MEETING_UTILS_H_ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <glib.h> +#include "e-meeting-types.h" + +#ifdef __cplusplus +extern "C" { +#pragma } +#endif /* __cplusplus */ + + + +gint e_meeting_time_compare_times (EMeetingTime *time1, + EMeetingTime *time2); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _E_MEETING_UTILS_H_ */ + + |