From 9493be6a2374dd5c9c4f7f5560f04e80cac14233 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Wilfried=20G=C3=B6esgens?= Date: Tue, 6 May 2008 22:19:43 +0000 Subject: [PATCH] * now hold / sort the ical events in our hashlist. * use a simplified hash so the start time is the primary key --- webcit/calendar.c | 65 ++++++++++++--- webcit/calendar_view.c | 176 +++++++++++++++++++++++------------------ webcit/webcit.h | 23 ++++-- 3 files changed, 169 insertions(+), 95 deletions(-) diff --git a/webcit/calendar.c b/webcit/calendar.c index 651a4126e..403c7002f 100644 --- a/webcit/calendar.c +++ b/webcit/calendar.c @@ -387,8 +387,27 @@ void handle_rsvp(void) /*@{*/ +int Flathash(const char *str, long len) +{ + if (len != sizeof (int)) + return 0; + else return *(int*)str; +} + +/** + * \brief clean up ical memory + * todo this could get trouble with future ical versions + */ +void delete_cal(void *vCal) +{ + disp_cal *Cal = (disp_cal*) vCal; + icalcomponent_free(Cal->cal); + free(Cal->from); + free(Cal); +} + /** * \brief get items, keep them. * If we're reading calendar items, just store them for now. We have to @@ -398,16 +417,42 @@ void handle_rsvp(void) */ void display_individual_cal(icalcomponent *cal, long msgnum, char *from, int unread) { - struct wcsession *WCC = WC; /* stack this for faster access (WC is a function) */ - - WCC->num_cal += 1; - WCC->disp_cal = realloc(WC->disp_cal, (sizeof(struct disp_cal) * WCC->num_cal) ); - WCC->disp_cal[WCC->num_cal - 1].cal = icalcomponent_new_clone(cal); - WCC->disp_cal[WCC->num_cal - 1].unread = unread; - WCC->disp_cal[WCC->num_cal - 1].from = malloc (strlen(from) + 1); - strcpy (WCC->disp_cal[WCC->num_cal - 1].from, from); - ical_dezonify(WCC->disp_cal[WCC->num_cal - 1].cal); - WCC->disp_cal[WCC->num_cal - 1].cal_msgnum = msgnum; + icalproperty *ps = NULL; + struct icaltimetype t; + struct wcsession *WCC = WC; + disp_cal *Cal; + size_t len; + + if (WCC->disp_cal_items == NULL) + WCC->disp_cal_items = NewHash(0, Flathash); + + Cal = (disp_cal*) malloc(sizeof(disp_cal)); + memset(Cal, 0, sizeof(disp_cal)); + + Cal->cal = icalcomponent_new_clone(cal); + Cal->unread = unread; + len = strlen(from); + Cal->from = (char*)malloc(len+ 1); + memcpy(Cal->from, from, len + 1); + ical_dezonify(Cal->cal); + Cal->cal_msgnum = msgnum; + + //! Precalculate some Values we can use for easy comparison later. + ps = icalcomponent_get_first_property(Cal->cal, ICAL_DTSTART_PROPERTY); + if (ps != NULL) { + t = icalproperty_get_dtstart(ps); + Cal->event_start = icaltime_as_timet(t); + } + ps = icalcomponent_get_first_property(Cal->cal, ICAL_DTEND_PROPERTY); + if (ps != NULL) { //! Precalc the end day and end day + hour + t = icalproperty_get_dtstart(ps); + Cal->event_end = icaltime_as_timet(t); + } + Put(WCC->disp_cal_items, + (char*) &Cal->event_start, + sizeof(Cal->event_start), + Cal, + delete_cal); } diff --git a/webcit/calendar_view.c b/webcit/calendar_view.c index d0858d27e..2c8332553 100644 --- a/webcit/calendar_view.c +++ b/webcit/calendar_view.c @@ -144,7 +144,9 @@ void embeddable_mini_calendar(int year, int month, char *urlformat) } -/* ajax embedder for the above mini calendar */ +/** + * \brief ajax embedder for the above mini calendar + */ void ajax_mini_calendar(void) { char urlformat[256]; int i, len; @@ -167,7 +169,11 @@ void ajax_mini_calendar(void) { */ void calendar_month_view_display_events(int year, int month, int day) { - int i; + long hklen; + char *HashKey; + void *vCal; + HashPos *Pos; + disp_cal *Cal; icalproperty *p = NULL; icalproperty *q = NULL; struct icaltimetype t; @@ -180,15 +186,15 @@ void calendar_month_view_display_events(int year, int month, int day) int show_event = 0; char buf[256]; struct wcsession *WCC = WC; /* This is done to make it run faster; WC is a function */ - struct disp_cal *Cal; time_t tt; - if (WCC->num_cal == 0) { + if (GetCount(WCC->disp_cal_items) == 0) { wprintf("


\n"); return; } - /* Create an imaginary event which spans the 24 hours of today. Any events which + /** + * Create an imaginary event which spans the 24 hours of today. Any events which * overlap with this one take place at least partially in this day. We have to * convert it from a struct tm in order to make it UTC. */ @@ -210,10 +216,12 @@ void calendar_month_view_display_events(int year, int month, int day) today_end_t = icaltime_from_timet_with_zone(mktime(&ending_tm), 0, icaltimezone_get_utc_timezone()); today_end_t.is_utc = 1; - /* Now loop through our list of events to see which ones occur today. + /** + * Now loop through our list of events to see which ones occur today. */ - for (i=0; i<(WCC->num_cal); ++i) { - Cal = &WCC->disp_cal[i]; + Pos = GetNewHashPos(); + while (GetNextHashPos(WCC->disp_cal_items, Pos, &hklen, &HashKey, &vCal)) { + Cal = (disp_cal*)vCal; all_day_event = 0; q = icalcomponent_get_first_property(Cal->cal, ICAL_DTSTART_PROPERTY); if (q != NULL) { @@ -240,7 +248,8 @@ void calendar_month_view_display_events(int year, int month, int day) show_event = ical_ctdl_is_overlap(t, end_t, today_start_t, today_end_t); } - /* If we determined that this event occurs today, then display it. + /** + * If we determined that this event occurs today, then display it. */ if (show_event) { p = icalcomponent_get_first_property(Cal->cal, ICAL_SUMMARY_PROPERTY); @@ -257,7 +266,7 @@ void calendar_month_view_display_events(int year, int month, int day) "msgnum=%ld&calview=month&year=%d&month=%d&day=%d\"" " btt_tooltext=\"", (Cal->unread)?"_unread":"_read", - WC->disp_cal[i].cal_msgnum, + Cal->cal_msgnum, year, month, day ); @@ -267,7 +276,7 @@ void calendar_month_view_display_events(int year, int month, int day) wprintf("
"); q = icalcomponent_get_first_property( - WC->disp_cal[i].cal, + Cal->cal, ICAL_LOCATION_PROPERTY); if (q) { wprintf("%s ", _("Location:")); @@ -302,7 +311,8 @@ void calendar_month_view_display_events(int year, int month, int day) wprintf("%s %s
", _("Starting date/time:"), buf); - /* Embed the 'show end date/time' loop inside here so it + /** + * Embed the 'show end date/time' loop inside here so it * only executes if this is NOT an all day event. */ q = icalcomponent_get_first_property(Cal->cal, ICAL_DTEND_PROPERTY); @@ -340,6 +350,7 @@ void calendar_month_view_display_events(int year, int month, int day) } + DeleteHashPos(&Pos); } @@ -348,7 +359,10 @@ void calendar_month_view_display_events(int year, int month, int day) * \param thetime the month we want to see */ void calendar_month_view_brief_events(time_t thetime, const char *daycolor) { - int i; + long hklen; + char *HashKey; + void *vCal; + HashPos *Pos; time_t event_tt; time_t event_tts; time_t event_tte; @@ -359,7 +373,7 @@ void calendar_month_view_brief_events(time_t thetime, const char *daycolor) { icalproperty *p; icalproperty *e; struct icaltimetype t; - struct disp_cal *Cal; + disp_cal *Cal; int month, day, year; int all_day_event = 0; char *timeformat; @@ -375,8 +389,9 @@ void calendar_month_view_brief_events(time_t thetime, const char *daycolor) { day = today_tm.tm_mday; year = today_tm.tm_year + 1900; - for (i=0; i<(WC->num_cal); ++i) { - Cal = &WCC->disp_cal[i]; + Pos = GetNewHashPos(); + while (GetNextHashPos(WCC->disp_cal_items, Pos, &hklen, &HashKey, &vCal)) { + Cal = (disp_cal*)vCal; p = icalcomponent_get_first_property(Cal->cal, ICAL_DTSTART_PROPERTY); if (p != NULL) { @@ -402,10 +417,10 @@ void calendar_month_view_brief_events(time_t thetime, const char *daycolor) { char ebuf[255]; p = icalcomponent_get_first_property( - WC->disp_cal[i].cal, + Cal->cal, ICAL_SUMMARY_PROPERTY); e = icalcomponent_get_first_property( - WC->disp_cal[i].cal, + Cal->cal, ICAL_DTEND_PROPERTY); if ((p != NULL) && (e != NULL)) { time_t difftime; @@ -423,7 +438,7 @@ void calendar_month_view_brief_events(time_t thetime, const char *daycolor) { hours, minutes, (Cal->unread)?"_unread":"_read", daycolor, - WC->disp_cal[i].cal_msgnum, + Cal->cal_msgnum, bstr("year"), bstr("month"), bstr("day") @@ -449,6 +464,7 @@ void calendar_month_view_brief_events(time_t thetime, const char *daycolor) { } } + DeleteHashPos(&Pos); } @@ -778,7 +794,10 @@ void calendar_day_view_display_events(time_t thetime, int dstart, int dend) { - int i; + long hklen; + char *HashKey; + void *vCal; + HashPos *Pos; icalproperty *p = NULL; icalproperty *q = NULL; time_t event_tt; @@ -789,7 +808,7 @@ void calendar_day_view_display_events(time_t thetime, int all_day_event = 0; int ongoing_event = 0; struct wcsession *WCC = WC; /* This is done to make it run faster; WC is a function */ - struct disp_cal *Cal; + disp_cal *Cal; struct icaltimetype t; struct icaltimetype end_t; struct icaltimetype today_start_t; @@ -807,7 +826,7 @@ void calendar_day_view_display_events(time_t thetime, struct tm d_tm; char d_str[32]; - if (WCC->num_cal == 0) { + if (GetCount(WCC->disp_cal_items) == 0) { /* nothing to display */ return; } @@ -835,8 +854,9 @@ void calendar_day_view_display_events(time_t thetime, /* Now loop through our list of events to see which ones occur today. */ - for (i=0; i<(WCC->num_cal); ++i) { - Cal = &WCC->disp_cal[i]; + Pos = GetNewHashPos(); + while (GetNextHashPos(WCC->disp_cal_items, Pos, &hklen, &HashKey, &vCal)) { + Cal = (disp_cal*)vCal; all_day_event = 0; ongoing_event=0; @@ -1032,6 +1052,7 @@ void calendar_day_view_display_events(time_t thetime, } } } + DeleteHashPos(&Pos); } /** @@ -1253,7 +1274,11 @@ void calendar_day_view(int year, int month, int day) { * \brief Display today's events. */ void calendar_summary_view(void) { - int i; + long hklen; + char *HashKey; + void *vCal; + HashPos *Pos; + disp_cal *Cal; icalproperty *p; struct icaltimetype t; time_t event_tt; @@ -1262,16 +1287,19 @@ void calendar_summary_view(void) { time_t now; int all_day_event = 0; char timestring[SIZ]; + struct wcsession *WCC = WC; /* This is done to make it run faster; WC is a function */ - if (WC->num_cal == 0) { + if (GetCount(WC->disp_cal_items) == 0) { return; } now = time(NULL); localtime_r(&now, &today_tm); - for (i=0; i<(WC->num_cal); ++i) { - p = icalcomponent_get_first_property(WC->disp_cal[i].cal, + Pos = GetNewHashPos(); + while (GetNextHashPos(WCC->disp_cal_items, Pos, &hklen, &HashKey, &vCal)) { + Cal = (disp_cal*)vCal; + p = icalcomponent_get_first_property(Cal->cal, ICAL_DTSTART_PROPERTY); if (p != NULL) { t = icalproperty_get_dtstart(p); @@ -1298,7 +1326,7 @@ void calendar_summary_view(void) { p = icalcomponent_get_first_property( - WC->disp_cal[i].cal, + Cal->cal, ICAL_SUMMARY_PROPERTY); if (p != NULL) { escputs((char *) @@ -1308,27 +1336,11 @@ void calendar_summary_view(void) { } } } - free_calendar_buffer(); + DeleteHashPos(&Pos); + DeleteHash(&WC->disp_cal_items); } -/** - * \brief clean up ical memory - * \todo this could get troubel with future ical versions - */ -void free_calendar_buffer(void) { - int i; - if (WC->num_cal) for (i=0; i<(WC->num_cal); ++i) { - icalcomponent_free(WC->disp_cal[i].cal); - free(WC->disp_cal[i].from); - } - WC->num_cal = 0; - free(WC->disp_cal); - WC->disp_cal = NULL; -} - - - /** * \brief do the whole calendar page * view any part of the calender. decide which way, etc. @@ -1376,8 +1388,7 @@ void do_calendar_view(void) { } /** Free the calendar stuff */ - free_calendar_buffer(); - + DeleteHash(&WC->disp_cal_items); } @@ -1422,12 +1433,15 @@ time_t get_task_due_date(icalcomponent *vtodo) { * \param task1 first task to compare * \param task2 second task to compare */ -int task_due_cmp(const void *task1, const void *task2) { +int task_due_cmp(const void *vtask1, const void *vtask2) { + disp_cal * Task1 = (disp_cal *)GetSearchPayload(vtask1); + disp_cal * Task2 = (disp_cal *)GetSearchPayload(vtask2); + time_t t1; time_t t2; - t1 = get_task_due_date(((struct disp_cal *)task1)->cal); - t2 = get_task_due_date(((struct disp_cal *)task2)->cal); + t1 = get_task_due_date(Task1->cal); + t2 = get_task_due_date(Task2->cal); if (t1 < t2) return(-1); if (t1 > t2) return(1); return(0); @@ -1436,8 +1450,11 @@ int task_due_cmp(const void *task1, const void *task2) { /** * \brief qsort filter to move completed tasks to bottom of task list */ -int task_completed_cmp(const void *task1, const void *task2) { - icalproperty_status t1 = icalcomponent_get_status(((struct disp_cal *)task1)->cal); +int task_completed_cmp(const void *vtask1, const void *vtask2) { + disp_cal * Task1 = (disp_cal *)GetSearchPayload(vtask1); +// disp_cal * Task2 = (disp_cal *)GetSearchPayload(vtask2); + + icalproperty_status t1 = icalcomponent_get_status((Task1)->cal); // icalproperty_status t2 = icalcomponent_get_status(((struct disp_cal *)task2)->cal); if (t1 == ICAL_STATUS_COMPLETED) @@ -1451,10 +1468,17 @@ int task_completed_cmp(const void *task1, const void *task2) { * \brief do the whole task view stuff */ void do_tasks_view(void) { - int i; + long hklen; + char *HashKey; + void *vCal; + disp_cal *Cal; + HashPos *Pos; + int nItems; time_t due; char buf[SIZ]; icalproperty *p; + struct wcsession *WCC = WC; /* This is done to make it run faster; WC is a function */ + wprintf("
" "\n\n" "\n", _("Show All")); - /** Sort them if necessary */ - if (WC->num_cal > 1) { - qsort(WC->disp_cal, - WC->num_cal, - sizeof(struct disp_cal), - task_due_cmp - ); - } + nItems = GetCount(WC->disp_cal_items); + /** Sort them if necessary * / + if (nItems > 1) { + SortByPayload(WC->disp_cal_items, + task_due_cmp); + } // this shouldn't be neccessary, since we sort by the start time. + */ /** And then again, by completed */ - if (WC->num_cal > 1) { - qsort(WC->disp_cal, - WC->num_cal, - sizeof(struct disp_cal), - task_completed_cmp - ); + if (nItems > 1) { + SortByPayload(WC->disp_cal_items, + task_completed_cmp); } - if (WC->num_cal) for (i=0; i<(WC->num_cal); ++i) { + Pos = GetNewHashPos(); + while (GetNextHashPos(WCC->disp_cal_items, Pos, &hklen, &HashKey, &vCal)) { + Cal = (disp_cal*)vCal; wprintf("\n"); - due = get_task_due_date(WC->disp_cal[i].cal); + due = get_task_due_date(Cal->cal); wprintf(""); wprintf("
"); @@ -1468,35 +1492,33 @@ void do_tasks_view(void) { wprintf(" ()
"); - icalproperty_status todoStatus = icalcomponent_get_status(WC->disp_cal[i].cal); + icalproperty_status todoStatus = icalcomponent_get_status(Cal->cal); wprintf("\n"); - p = icalcomponent_get_first_property(WC->disp_cal[i].cal, + p = icalcomponent_get_first_property(Cal->cal, ICAL_SUMMARY_PROPERTY); wprintf("disp_cal[i].cal_msgnum ); + Cal->cal_msgnum ); urlescputs(WC->wc_roomname); wprintf("\">"); /* wprintf("\n"); wprintf(" 0) { webcit_fmt_date(buf, due, 0); @@ -1518,7 +1540,7 @@ void do_tasks_view(void) { } wprintf(""); - p = icalcomponent_get_first_property(WC->disp_cal[i].cal, + p = icalcomponent_get_first_property(Cal->cal, ICAL_CATEGORIES_PROPERTY); if (p != NULL) { escputs((char *)icalproperty_get_categories(p)); @@ -1530,7 +1552,7 @@ void do_tasks_view(void) { wprintf("
\n"); /** Free the list */ - free_calendar_buffer(); - + DeleteHash(&WC->disp_cal_items); + DeleteHashPos(&Pos); } diff --git a/webcit/webcit.h b/webcit/webcit.h index 74e161428..40bbaa1a3 100644 --- a/webcit/webcit.h +++ b/webcit/webcit.h @@ -338,6 +338,20 @@ struct folder { int num_rooms; /**< If this is a floor, how many rooms does it have */ }; +typedef struct _disp_cal { + icalcomponent *cal; /**< cal items for display */ + long cal_msgnum; /**< cal msgids for display */ + char *from; /**< owner of this component */ + int unread; /**< already seen by the user? */ + + time_t event_start; + time_t event_end; + + int multi_day_event; + int is_repeat; +} disp_cal; + + /** * \brief One of these is kept for each active Citadel session. * HTTP transactions are bound to on e at a time. @@ -388,13 +402,7 @@ struct wcsession { char this_page[512]; /**< URL of current page */ char http_host[512]; /**< HTTP Host: header */ HashList *hash_prefs; /**< WebCit preferences for this user */ - struct disp_cal { - icalcomponent *cal; /**< cal items for display */ - long cal_msgnum; /**< cal msgids for display */ - char *from; /**< owner of this component */ - int unread; /**< already seen by the user? */ - } *disp_cal; - int num_cal; /**< number of calendar items for display */ + HashList *disp_cal_items; /**< sorted list of calendar items; startdate is the sort criteria. */ struct wc_attachment *first_attachment; /**< linked list of attachments for 'enter message' */ char last_chat_user[256]; /**< ??? todo */ char ImportantMessage[SIZ]; /**< ??? todo */ @@ -699,7 +707,6 @@ void updatenote(void); void ajax_update_note(void); void do_calendar_view(void); void do_tasks_view(void); -void free_calendar_buffer(void); void calendar_summary_view(void); int load_msg_ptrs(char *servcmd, int with_headers); void free_attachments(struct wcsession *sess); -- 2.30.2