From c4f6855cebd5b13deca8109e79f0beb7dabdd0ce Mon Sep 17 00:00:00 2001 From: Damon Chaplin Date: Mon, 1 May 2000 00:27:17 +0000 Subject: new function to see if the event dates have changed (including any 2000-05-01 Damon Chaplin * cal-util/calobj.c (ical_object_compare_dates): new function to see if the event dates have changed (including any recurrence rules). It is used for optimization when we get the "object_changed" signal. We have to do far less work if the dates are unchanged. * gui/e-week-view.c: * gui/e-day-view.c: only draw the selection when we have the keyboard focus, since the user expects to be able to type in a new event when the selection is shown. Also keep the selection when we lose focus, but just don't show it. Also quite a few changes to cope with the new client/server architecture. * gui/e-day-view-top-item.c (e_day_view_top_item_draw): * gui/e-day-view-main-item.c (e_day_view_main_item_draw): * gui/e-week-view-main-item.c (e_week_view_main_item_draw_day): only draw the selection if the widget has the keyboard focus. * gui/gnome-cal.c (mark_gtk_calendar_day): fixed so it works with events longer than one day. And changed the code for updating events in the new views. svn path=/trunk/; revision=2701 --- calendar/cal-util/calobj.c | 108 +++++++++++++++++++++++++++++++++++++++++++++ calendar/cal-util/calobj.h | 5 +++ 2 files changed, 113 insertions(+) (limited to 'calendar/cal-util') diff --git a/calendar/cal-util/calobj.c b/calendar/cal-util/calobj.c index 03862d1dd1..1634ec084e 100644 --- a/calendar/cal-util/calobj.c +++ b/calendar/cal-util/calobj.c @@ -21,6 +21,8 @@ /* VCalendar product ID */ #define PRODID "-//Helix Code//NONSGML Evolution Calendar//EN" +static gint compare_exdates (gconstpointer a, gconstpointer b); + static char * @@ -1224,6 +1226,10 @@ ical_object_generate_events (iCalObject *ico, time_t start, time_t end, calendar if (!ico->recur) { if ((end && (ico->dtstart < end) && (ico->dtend > start)) || ((end == 0) && (ico->dtend > start))) { + /* The new calendar views expect the times to not be + clipped, so they can show that it continues past + the end of the viewable area. */ +#if 0 time_t ev_s, ev_e; /* Clip range */ @@ -1232,6 +1238,9 @@ ical_object_generate_events (iCalObject *ico, time_t start, time_t end, calendar ev_e = MIN (ico->dtend, end); (* cb) (ico, ev_s, ev_e, closure); +#else + (* cb) (ico, ico->dtstart, ico->dtend, closure); +#endif } return; } @@ -1631,3 +1640,102 @@ ical_object_to_string (iCalObject *ico) return gbuf; } + + +/** + * ical_object_compare_dates: + * @ico1: A calendar event. + * @ico2: A calendar event to compare with @ico1. + * + * Returns TRUE if the dates of both objects match, including any recurrence + * rules. Both calendar objects must have a type of ICAL_EVENT. + * + * Return value: TRUE if both calendar objects have the same dates. + **/ +gboolean +ical_object_compare_dates (iCalObject *ico1, + iCalObject *ico2) +{ + Recurrence *recur1, *recur2; + gint num_exdates; + GList *elem1, *elem2; + time_t *time1, *time2; + + g_return_val_if_fail (ico1 != NULL, FALSE); + g_return_val_if_fail (ico2 != NULL, FALSE); + g_return_val_if_fail (ico1->type == ICAL_EVENT, FALSE); + g_return_val_if_fail (ico2->type == ICAL_EVENT, FALSE); + + /* First check the base dates. */ + if (ico1->dtstart != ico2->dtstart + || ico1->dtend != ico2->dtend) + return FALSE; + + recur1 = ico1->recur; + recur2 = ico2->recur; + + /* If the event doesn't recur, we already know it matches. */ + if (!recur1 && !recur2) + return TRUE; + + /* Check that both recur. */ + if (!(recur1 && recur2)) + return FALSE; + + /* Now we need to see if the recurrence rules are the same. */ + if (recur1->type != recur2->type + || recur1->interval != recur2->interval + || recur1->enddate != recur2->enddate + || recur1->weekday != recur2->weekday + || recur1->duration != recur2->duration + || recur1->_enddate != recur2->_enddate + || recur1->__count != recur2->__count) + return FALSE; + + switch (recur1->type) { + case RECUR_MONTHLY_BY_POS: + if (recur1->u.month_pos != recur2->u.month_pos) + return FALSE; + break; + case RECUR_MONTHLY_BY_DAY: + if (recur1->u.month_day != recur2->u.month_day) + return FALSE; + break; + default: + break; + } + + /* Now check if the excluded dates match. */ + num_exdates = g_list_length (ico1->exdate); + if (g_list_length (ico2->exdate) != num_exdates) + return FALSE; + if (num_exdates == 0) + return TRUE; + + ico1->exdate = g_list_sort (ico1->exdate, compare_exdates); + ico2->exdate = g_list_sort (ico2->exdate, compare_exdates); + + elem1 = ico1->exdate; + elem2 = ico2->exdate; + while (elem1) { + time1 = (time_t*) elem1->data; + time2 = (time_t*) elem2->data; + + if (*time1 != *time2) + return FALSE; + + elem1 = elem1->next; + elem2 = elem2->next; + } + + return TRUE; +} + + +static gint +compare_exdates (gconstpointer a, gconstpointer b) +{ + const time_t *ca = a, *cb = b; + time_t diff = *ca - *cb; + return (diff < 0) ? -1 : (diff > 0) ? 1 : 0; +} diff --git a/calendar/cal-util/calobj.h b/calendar/cal-util/calobj.h index cb0e22f741..0fa82ee36e 100644 --- a/calendar/cal-util/calobj.h +++ b/calendar/cal-util/calobj.h @@ -258,6 +258,11 @@ int ical_object_get_first_weekday (int weekday_mask); /* Returns the number of seconds configured to trigger the alarm in advance to an event */ int alarm_compute_offset (CalendarAlarm *a); + +/* Returns TRUE if the dates of both objects match, including any recurrence + rules. */ +gboolean ical_object_compare_dates (iCalObject *ico1, iCalObject *ico2); + END_GNOME_DECLS #endif -- cgit