From d639a620a6438ea93787cedfe9f3eb87014275a3 Mon Sep 17 00:00:00 2001 From: JP Rosevear Date: Wed, 19 Sep 2001 04:33:33 +0000 Subject: A page that shows the meeting time selector and free/busy data for 2001-09-18 JP Rosevear * gui/dialogs/schedule-page.*: A page that shows the meeting time selector and free/busy data for attendees * gui/dialogs/meeting-page.c: use the meeting model to track/edit attendees, remove table value conversion routines and simple table routines (set_attendees): take a pointer array (meeting_page_destroy): destroy the pointer array, save state (meeting_page_init): new pointer array (meeting_page_fill_widgets): don't null the deleted attendees field (popup_delegate_cb): array add (popup_delete_cb): array add (cleanup_attendees): iterate over the array to unref now (meeting_page_fill_widgets): don't null out fields, no need to add attendees here (invite_entry_changed): use e_meeting_attendee routines (popup_delegate_cb): ditto (popup_delete_cb): ditto (meeting_page_new): take new arg and pass it to construct (meeting_page_construct): take new arg, use e-meeting-model routines to construct table * gui/dialogs/task-editor.c (task_editor_init): new meeting model (task_editor_destroy): unref the model * gui/dialogs/event-editor.c (event_editor_init): make new model and pass it to meeting and schedule pages (event_editor_set_cal_client): virtual function, set meeting model client (event_editor_edit_comp): add the attendees to the model (event_editor_destroy): unref model * gui/dialogs/comp-editor.h: add virtual function * gui/dialogs/comp-editor.c (comp_editor_set_cal_client): make set_cal_client a virutal function * gui/e-meeting-types.h: generally useful type defines * gui/e-meeting-time-sel*.[hc]: Move here and use an e-table for the attendee list and extract display information from the new meeting model and attendees * gui/e-meeting-time-sel.etspec: spec for the table * gui/e-meeting-attendee.[hc]: meeting attendees for the model, with to/from conversions for CalComponentAttendee structure, emits changed signal and allows getting and setting of free busy periods * gui/e-meeting-model.[hc]: move the model out on its own * gui/e-itip-control.c (write_error_html): clean up warnings svn path=/trunk/; revision=12968 --- calendar/gui/e-meeting-attendee.c | 998 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 998 insertions(+) create mode 100644 calendar/gui/e-meeting-attendee.c (limited to 'calendar/gui/e-meeting-attendee.c') diff --git a/calendar/gui/e-meeting-attendee.c b/calendar/gui/e-meeting-attendee.c new file mode 100644 index 0000000000..08ec9a1152 --- /dev/null +++ b/calendar/gui/e-meeting-attendee.c @@ -0,0 +1,998 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-attendee.c + * + * Copyright (C) 2001 Ximian, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * 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 +#endif + +#include +#include +#include "e-meeting-attendee.h" + +struct _EMeetingAttendeePrivate { + EMeetingAttendeeType type; + + gchar *address; + gchar *member; + + icalparameter_cutype cutype; + icalparameter_role role; + + gboolean rsvp; + + gchar *delto; + gchar *delfrom; + + icalparameter_partstat status; + + gchar *sentby; + gchar *cn; + gchar *language; + + gboolean has_calendar_info; + + GArray *busy_periods; + gboolean busy_periods_sorted; + + EMeetingTime busy_periods_start; + EMeetingTime busy_periods_end; + gboolean start_busy_range_set; + gboolean end_busy_range_set; + + gint longest_period_in_days; +}; + +enum { + CHANGED, + LAST_SIGNAL +}; +static guint signals[LAST_SIGNAL]; + +static void class_init (EMeetingAttendeeClass *klass); +static void init (EMeetingAttendee *ia); +static void destroy (GtkObject *obj); + + +static GtkObjectClass *parent_class = NULL; + + +GtkType +e_meeting_attendee_get_type (void) +{ + static GtkType type = 0; + + if (type == 0) + { + static const GtkTypeInfo info = + { + "EMeetingAttendee", + sizeof (EMeetingAttendee), + sizeof (EMeetingAttendeeClass), + (GtkClassInitFunc) class_init, + (GtkObjectInitFunc) init, + /* reserved_1 */ NULL, + /* reserved_2 */ NULL, + (GtkClassInitFunc) NULL, + }; + + type = gtk_type_unique (gtk_object_get_type (), &info); + } + + return type; +} + +static void +class_init (EMeetingAttendeeClass *klass) +{ + GtkObjectClass *object_class; + + object_class = GTK_OBJECT_CLASS (klass); + + parent_class = gtk_type_class (gtk_object_get_type ()); + + signals[CHANGED] = + gtk_signal_new ("changed", + GTK_RUN_FIRST, + object_class->type, + GTK_SIGNAL_OFFSET (EMeetingAttendeeClass, changed), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, 0); + + gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL); + + object_class->destroy = destroy; +} + +static gchar * +string_test (gchar *string) +{ + return string != NULL ? string : g_strdup (""); +} + +static gboolean +string_is_set (gchar *string) +{ + if (string != NULL && *string != '\0') + return TRUE; + + return FALSE; +} + +static void +notify_changed (EMeetingAttendee *ia) +{ + gtk_signal_emit (GTK_OBJECT (ia), signals[CHANGED]); +} + +static void +init (EMeetingAttendee *ia) +{ + EMeetingAttendeePrivate *priv; + + priv = g_new0 (EMeetingAttendeePrivate, 1); + + ia->priv = priv; + + priv->type = E_MEETING_ATTENDEE_REQUIRED_PERSON; + + priv->address = string_test (NULL); + priv->member = string_test (NULL); + + priv->cutype = ICAL_CUTYPE_NONE; + priv->role = ICAL_ROLE_NONE; + + priv->rsvp = FALSE; + + priv->delto = string_test (NULL); + priv->delfrom = string_test (NULL); + + priv->status = ICAL_PARTSTAT_NONE; + + priv->sentby = string_test (NULL); + priv->cn = string_test (NULL); + priv->language = string_test (NULL); + + priv->has_calendar_info = FALSE; + + priv->busy_periods = g_array_new (FALSE, FALSE, sizeof (EMeetingFreeBusyPeriod)); + priv->busy_periods_sorted = FALSE; + + g_date_clear (&priv->busy_periods_start.date, 1); + priv->busy_periods_start.hour = 0; + priv->busy_periods_start.minute = 0; + + g_date_clear (&priv->busy_periods_end.date, 1); + priv->busy_periods_end.hour = 0; + priv->busy_periods_end.minute = 0; + + priv->start_busy_range_set = FALSE; + priv->end_busy_range_set = FALSE; + + priv->longest_period_in_days = 0; +} + + +static void +destroy (GtkObject *obj) +{ + EMeetingAttendee *ia = E_MEETING_ATTENDEE (obj); + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + g_free (priv->address); + g_free (priv->member); + + g_free (priv->delto); + g_free (priv->delfrom); + + g_free (priv->sentby); + g_free (priv->cn); + g_free (priv->language); + + g_array_free (priv->busy_periods, TRUE); + + g_free (priv); +} + +GtkObject * +e_meeting_attendee_new (void) +{ + return gtk_type_new (E_TYPE_MEETING_ATTENDEE); +} + +GtkObject * +e_meeting_attendee_new_from_cal_component_attendee (CalComponentAttendee *ca) +{ + EMeetingAttendee *ia; + + ia = E_MEETING_ATTENDEE (gtk_type_new (E_TYPE_MEETING_ATTENDEE)); + + e_meeting_attendee_set_address (ia, g_strdup (ca->value)); + e_meeting_attendee_set_member (ia, g_strdup (ca->member)); + e_meeting_attendee_set_cutype (ia, ca->cutype); + e_meeting_attendee_set_role (ia, ca->role); + e_meeting_attendee_set_status (ia, ca->status); + e_meeting_attendee_set_rsvp (ia, ca->rsvp); + e_meeting_attendee_set_delto (ia, g_strdup (ca->delto)); + e_meeting_attendee_set_delfrom (ia, g_strdup (ca->delfrom)); + e_meeting_attendee_set_sentby (ia, g_strdup (ca->sentby)); + e_meeting_attendee_set_cn (ia, g_strdup (ca->cn)); + e_meeting_attendee_set_language (ia, g_strdup (ca->language)); + + return GTK_OBJECT (ia); +} + +CalComponentAttendee * +e_meeting_attendee_as_cal_component_attendee (EMeetingAttendee *ia) +{ + EMeetingAttendeePrivate *priv; + CalComponentAttendee *ca; + + priv = ia->priv; + + ca = g_new0 (CalComponentAttendee, 1); + + ca->value = priv->address; + ca->member = string_is_set (priv->member) ? priv->member : NULL; + ca->cutype= priv->cutype; + ca->role = priv->role; + ca->status = priv->status; + ca->rsvp = priv->rsvp; + ca->delto = string_is_set (priv->delto) ? priv->delto : NULL; + ca->delfrom = string_is_set (priv->delfrom) ? priv->delfrom : NULL; + ca->sentby = string_is_set (priv->sentby) ? priv->sentby : NULL; + ca->cn = string_is_set (priv->cn) ? priv->cn : NULL; + ca->language = string_is_set (priv->language) ? priv->language : NULL; + + return ca; +} + + +const gchar * +e_meeting_attendee_get_address (EMeetingAttendee *ia) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + return priv->address; +} + +void +e_meeting_attendee_set_address (EMeetingAttendee *ia, gchar *address) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + if (priv->address != NULL) + g_free (priv->address); + + priv->address = string_test (address); + + notify_changed (ia); +} + +gboolean +e_meeting_attendee_is_set_address (EMeetingAttendee *ia) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + return string_is_set (priv->address); +} + +const gchar * +e_meeting_attendee_get_member (EMeetingAttendee *ia) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + return priv->member; +} + +void +e_meeting_attendee_set_member (EMeetingAttendee *ia, gchar *member) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + if (priv->member != NULL) + g_free (priv->member); + + priv->member = string_test (member); + + notify_changed (ia); +} + +gboolean +e_meeting_attendee_is_set_member (EMeetingAttendee *ia) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + return string_is_set (priv->member); +} + +icalparameter_cutype +e_meeting_attendee_get_cutype (EMeetingAttendee *ia) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + return priv->cutype; +} + +void +e_meeting_attendee_set_cutype (EMeetingAttendee *ia, icalparameter_cutype cutype) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + priv->cutype = cutype; + + notify_changed (ia); +} + +icalparameter_role +e_meeting_attendee_get_role (EMeetingAttendee *ia) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + return priv->role; +} + +void +e_meeting_attendee_set_role (EMeetingAttendee *ia, icalparameter_role role) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + priv->role = role; + + notify_changed (ia); +} + +gboolean +e_meeting_attendee_get_rsvp (EMeetingAttendee *ia) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + return priv->rsvp; +} + +void +e_meeting_attendee_set_rsvp (EMeetingAttendee *ia, gboolean rsvp) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + priv->rsvp = rsvp; + + notify_changed (ia); +} + +const gchar * +e_meeting_attendee_get_delto (EMeetingAttendee *ia) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + return priv->delto; +} + +void +e_meeting_attendee_set_delto (EMeetingAttendee *ia, gchar *delto) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + if (priv->delto != NULL) + g_free (priv->delto); + + priv->delto = string_test (delto); + + notify_changed (ia); +} + +gboolean +e_meeting_attendee_is_set_delto (EMeetingAttendee *ia) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + return string_is_set (priv->delto); +} + +const gchar * +e_meeting_attendee_get_delfrom (EMeetingAttendee *ia) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + return priv->delfrom; +} + +void +e_meeting_attendee_set_delfrom (EMeetingAttendee *ia, gchar *delfrom) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + if (priv->delfrom != NULL) + g_free (priv->delfrom); + + priv->delfrom = string_test (delfrom); + + notify_changed (ia); +} + +gboolean +e_meeting_attendee_is_set_delfrom (EMeetingAttendee *ia) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + return string_is_set (priv->delfrom); +} + +icalparameter_partstat +e_meeting_attendee_get_status (EMeetingAttendee *ia) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + return priv->status; +} + +void +e_meeting_attendee_set_status (EMeetingAttendee *ia, icalparameter_partstat status) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + priv->status = status; + + notify_changed (ia); +} + +const gchar * +e_meeting_attendee_get_sentby (EMeetingAttendee *ia) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + return priv->sentby; +} + +void +e_meeting_attendee_set_sentby (EMeetingAttendee *ia, gchar *sentby) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + if (priv->sentby != NULL) + g_free (priv->sentby); + + priv->sentby = string_test (sentby); + + notify_changed (ia); +} + +gboolean +e_meeting_attendee_is_set_sentby (EMeetingAttendee *ia) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + return string_is_set (priv->sentby); +} + +const gchar * +e_meeting_attendee_get_cn (EMeetingAttendee *ia) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + return priv->cn; +} + +void +e_meeting_attendee_set_cn (EMeetingAttendee *ia, gchar *cn) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + if (priv->cn != NULL) + g_free (priv->cn); + + priv->cn = string_test (cn); + + notify_changed (ia); +} + +gboolean +e_meeting_attendee_is_set_cn (EMeetingAttendee *ia) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + return string_is_set (priv->cn); +} + +const gchar * +e_meeting_attendee_get_language (EMeetingAttendee *ia) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + return priv->language; +} + +void +e_meeting_attendee_set_language (EMeetingAttendee *ia, gchar *language) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + if (priv->language != NULL) + g_free (priv->language); + + priv->language = string_test (language); + + notify_changed (ia); +} + +gboolean +e_meeting_attendee_is_set_language (EMeetingAttendee *ia) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + return string_is_set (priv->language); +} + +EMeetingAttendeeType +e_meeting_attendee_get_atype (EMeetingAttendee *ia) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + return priv->type; +} + +void +e_meeting_attendee_set_atype (EMeetingAttendee *ia, EMeetingAttendeeType type) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + priv->type = type; +} + + +static gint +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; +} + +static gint +compare_period_starts (const void *arg1, + const void *arg2) +{ + EMeetingFreeBusyPeriod *period1, *period2; + + period1 = (EMeetingFreeBusyPeriod *) arg1; + period2 = (EMeetingFreeBusyPeriod *) arg2; + + return compare_times (&period1->start, &period2->start); +} + +static void +ensure_periods_sorted (EMeetingAttendee *ia) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + if (priv->busy_periods_sorted) + return; + + qsort (priv->busy_periods->data, priv->busy_periods->len, + sizeof (EMeetingFreeBusyPeriod), + compare_period_starts); + + priv->busy_periods_sorted = TRUE; +} + +gboolean +e_meeting_attendee_get_has_calendar_info (EMeetingAttendee *ia) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + return priv->has_calendar_info; +} + +void +e_meeting_attendee_set_has_calendar_info (EMeetingAttendee *ia, gboolean has_calendar_info) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + priv->has_calendar_info = has_calendar_info; +} + +const GArray * +e_meeting_attendee_get_busy_periods (EMeetingAttendee *ia) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + ensure_periods_sorted (ia); + + return priv->busy_periods; +} + +gint +e_meeting_attendee_find_first_busy_period (EMeetingAttendee *ia, GDate *date) +{ + EMeetingAttendeePrivate *priv; + EMeetingFreeBusyPeriod *period; + gint lower, upper, middle = 0, cmp = 0; + GDate tmp_date; + + priv = ia->priv; + + /* Make sure the busy periods have been sorted. */ + ensure_periods_sorted (ia); + + /* Calculate the first day which could have a busy period which + continues onto our given date. */ + tmp_date = *date; + g_date_subtract_days (&tmp_date, priv->longest_period_in_days); + + /* We want the first busy period which starts on tmp_date. */ + lower = 0; + upper = priv->busy_periods->len; + + if (upper == 0) + return -1; + + while (lower < upper) { + middle = (lower + upper) >> 1; + + period = &g_array_index (priv->busy_periods, + EMeetingFreeBusyPeriod, middle); + + cmp = g_date_compare (&tmp_date, &period->start.date); + + if (cmp == 0) + break; + else if (cmp < 0) + upper = middle; + else + lower = middle + 1; + } + + /* There may be several busy periods on the same day so we step + backwards to the first one. */ + if (cmp == 0) { + while (middle > 0) { + period = &g_array_index (priv->busy_periods, + EMeetingFreeBusyPeriod, middle - 1); + if (g_date_compare (&tmp_date, &period->start.date) != 0) + break; + middle--; + } + } else if (cmp > 0) { + /* This means we couldn't find a period on the given day, and + the last one we looked at was before it, so if there are + any more periods after this one we return it. */ + middle++; + if (priv->busy_periods->len <= middle) + return -1; + } + + return middle; +} + +gboolean +e_meeting_attendee_add_busy_period (EMeetingAttendee *ia, + gint start_year, + gint start_month, + gint start_day, + gint start_hour, + gint start_minute, + gint end_year, + gint end_month, + gint end_day, + gint end_hour, + gint end_minute, + EMeetingFreeBusyType busy_type) +{ + EMeetingAttendeePrivate *priv; + EMeetingFreeBusyPeriod period; + gint period_in_days; + + g_return_val_if_fail (ia != NULL, FALSE); + g_return_val_if_fail (E_IS_MEETING_ATTENDEE (ia), FALSE); + g_return_val_if_fail (busy_type >= 0, FALSE); + g_return_val_if_fail (busy_type < E_MEETING_FREE_BUSY_LAST, FALSE); + + priv = ia->priv; + + /* Check the dates are valid. */ + if (!g_date_valid_dmy (start_day, start_month, start_year)) + return FALSE; + if (!g_date_valid_dmy (end_day, end_month, end_year)) + return FALSE; + if (start_hour < 0 || start_hour > 23) + return FALSE; + if (end_hour < 0 || end_hour > 23) + return FALSE; + if (start_minute < 0 || start_minute > 59) + return FALSE; + if (end_minute < 0 || end_minute > 59) + return FALSE; + + g_date_clear (&period.start.date, 1); + g_date_clear (&period.end.date, 1); + g_date_set_dmy (&period.start.date, start_day, start_month, start_year); + g_date_set_dmy (&period.end.date, end_day, end_month, end_year); + period.start.hour = start_hour; + period.start.minute = start_minute; + period.end.hour = end_hour; + period.end.minute = end_minute; + period.busy_type = busy_type; + + /* Check that the start time is before or equal to the end time. */ + if (compare_times (&period.start, &period.end) > 0) + return FALSE; + + /* If the busy range is not set elsewhere, track it as best we can */ + if (!priv->start_busy_range_set) { + if (!g_date_valid (&priv->busy_periods_start.date)) { + priv->busy_periods_start.date = period.start.date; + priv->busy_periods_start.hour = period.start.hour; + priv->busy_periods_start.minute = period.start.minute; + } else { + switch (g_date_compare (&period.start.date, &priv->busy_periods_start.date)) { + case -1: + priv->busy_periods_start.date = period.start.date; + priv->busy_periods_start.hour = period.start.hour; + priv->busy_periods_start.minute = period.start.minute; + break; + case 0: + if (period.start.hour < priv->busy_periods_start.hour + || (period.start.hour == priv->busy_periods_start.hour + && period.start.minute < priv->busy_periods_start.minute)) { + priv->busy_periods_start.date = period.start.date; + priv->busy_periods_start.hour = period.start.hour; + priv->busy_periods_start.minute = period.start.minute; + break; + } + break; + } + } + } + if (!priv->end_busy_range_set) { + if (!g_date_valid (&priv->busy_periods_end.date)) { + priv->busy_periods_end.date = period.end.date; + priv->busy_periods_end.hour = period.end.hour; + priv->busy_periods_end.minute = period.end.minute; + } else { + switch (g_date_compare (&period.end.date, &priv->busy_periods_end.date)) { + case 0: + if (period.end.hour > priv->busy_periods_end.hour + || (period.end.hour == priv->busy_periods_end.hour + && period.end.minute > priv->busy_periods_end.minute)) { + priv->busy_periods_end.date = period.end.date; + priv->busy_periods_end.hour = period.end.hour; + priv->busy_periods_end.minute = period.end.minute; + break; + } + break; + case 1: + priv->busy_periods_end.date = period.end.date; + priv->busy_periods_end.hour = period.end.hour; + priv->busy_periods_end.minute = period.end.minute; + break; + } + } + } + + g_array_append_val (priv->busy_periods, period); + priv->has_calendar_info = TRUE; + priv->busy_periods_sorted = FALSE; + + period_in_days = g_date_julian (&period.end.date) - g_date_julian (&period.start.date) + 1; + priv->longest_period_in_days = MAX (priv->longest_period_in_days, period_in_days); + + return TRUE; +} + +EMeetingTime +e_meeting_attendee_get_start_busy_range (EMeetingAttendee *ia) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + return priv->busy_periods_start; +} + +EMeetingTime +e_meeting_attendee_get_end_busy_range (EMeetingAttendee *ia) +{ + EMeetingAttendeePrivate *priv; + + priv = ia->priv; + + return priv->busy_periods_end; +} + +gboolean +e_meeting_attendee_set_start_busy_range (EMeetingAttendee *ia, + gint start_year, + gint start_month, + gint start_day, + gint start_hour, + gint start_minute) +{ + EMeetingAttendeePrivate *priv; + + g_return_val_if_fail (E_IS_MEETING_ATTENDEE (ia), FALSE); + + priv = ia->priv; + + /* Check the dates are valid. */ + if (!g_date_valid_dmy (start_day, start_month, start_year)) + return FALSE; + if (start_hour < 0 || start_hour > 23) + return FALSE; + if (start_minute < 0 || start_minute > 59) + return FALSE; + + g_date_clear (&priv->busy_periods_start.date, 1); + g_date_set_dmy (&priv->busy_periods_start.date, + start_day, start_month, start_year); + priv->busy_periods_start.hour = start_hour; + priv->busy_periods_start.minute = start_minute; + + priv->start_busy_range_set = TRUE; + + return TRUE; +} + +gboolean +e_meeting_attendee_set_end_busy_range (EMeetingAttendee *ia, + gint end_year, + gint end_month, + gint end_day, + gint end_hour, + gint end_minute) +{ + EMeetingAttendeePrivate *priv; + + g_return_val_if_fail (E_IS_MEETING_ATTENDEE (ia), FALSE); + + priv = ia->priv; + + /* Check the dates are valid. */ + if (!g_date_valid_dmy (end_day, end_month, end_year)) + return FALSE; + if (end_hour < 0 || end_hour > 23) + return FALSE; + if (end_minute < 0 || end_minute > 59) + return FALSE; + + g_date_clear (&priv->busy_periods_end.date, 1); + g_date_set_dmy (&priv->busy_periods_end.date, + end_day, end_month, end_year); + priv->busy_periods_end.hour = end_hour; + priv->busy_periods_end.minute = end_minute; + + priv->end_busy_range_set = TRUE; + + return TRUE; +} + +/* Clears all busy times for the given attendee. */ +void +e_meeting_attendee_clear_busy_periods (EMeetingAttendee *ia) +{ + EMeetingAttendeePrivate *priv; + + g_return_if_fail (E_IS_MEETING_ATTENDEE (ia)); + + priv = ia->priv; + + g_array_set_size (priv->busy_periods, 0); + priv->busy_periods_sorted = TRUE; + + g_date_clear (&priv->busy_periods_start.date, 1); + priv->busy_periods_start.hour = 0; + priv->busy_periods_start.minute = 0; + + g_date_clear (&priv->busy_periods_end.date, 1); + priv->busy_periods_end.hour = 0; + priv->busy_periods_end.minute = 0; + + priv->longest_period_in_days = 0; +} -- cgit v1.2.3