summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEduardo Chappa <chappa@washington.edu>2018-03-09 22:41:31 -0700
committerEduardo Chappa <chappa@washington.edu>2018-03-09 22:41:31 -0700
commit7955e4437e543bd97a9bb697367736e14ad604a2 (patch)
tree09d86ce074541372abd0fb4de255d2a54075bb57
parent3e46e0308a5e2cd645025b48fdc46654553f4968 (diff)
downloadalpine-7955e4437e543bd97a9bb697367736e14ad604a2.tar.xz
* Some locales do not have a string for AM or PM (e.g. de_DE) which
makes some displays of dates look wrong. In the case that a locale does not have a string for AM or PM, the time in 24 hours format is printed. Reported by Holger Trapp. * Add the time zone to the display of dates (this is the value of the TZID parameter.) * Display the value of the DTSTAMP in the "[More Details]" link. The DTSTAMP field contains information on when the calendar object was created. Suggested by Holger Trapp.
-rw-r--r--alpine/mailpart.c8
-rw-r--r--pith/ical.c129
-rw-r--r--pith/icaltype.h1
3 files changed, 132 insertions, 6 deletions
diff --git a/alpine/mailpart.c b/alpine/mailpart.c
index 1e0f9133..392c76c4 100644
--- a/alpine/mailpart.c
+++ b/alpine/mailpart.c
@@ -2990,6 +2990,14 @@ display_vcalendar_att(long int msgno, ATTACH_S *a, int flags)
so_puts(in_store, "\015\012");
}
+ if(vesy->dtstamp){
+ utf8_snprintf(tmp_20k_buf, SIZEOF_20KBUF, "%s%s",
+ vcal->method ? _("Created on: ") : _("Last Revised on; "),
+ vesy->dtstamp);
+ so_puts(in_store, tmp_20k_buf);
+ so_puts(in_store, "\015\012");
+ }
+
if(vesy->description){
char c;
int j, empty;
diff --git a/pith/ical.c b/pith/ical.c
index de7a1152..7cf742f5 100644
--- a/pith/ical.c
+++ b/pith/ical.c
@@ -84,6 +84,10 @@ void ical_free_gencline(void **);
void ical_free_rrule(void **);
void ical_free_weekday_list(void **);
+/* utility functions */
+void ical_date_time (char *, size_t, struct tm *);
+char *ical_get_tzid(ICAL_PARAMETER_S *);
+
/* globals */
struct tm day_zero; /* date for january 1, 1601 */
int month_len[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
@@ -2078,6 +2082,41 @@ ical_initialize(void)
day_zero.tm_wday = 4;
}
+/* At this time, we are going to print the date in 24 hour format
+ * if there is no string for AM or PM, but we use AM or PM when available.
+ * We plan to make this user configurable, but not today...
+ */
+void
+ical_date_time (char *tmp, size_t len, struct tm *ic_datep)
+{
+ /* test of the AM/PM string is available */
+ our_strftime(tmp, len, "%p", ic_datep);
+
+ if(tmp[0])
+ our_strftime(tmp, len, "%a %x %I:%M %p", ic_datep);
+ else
+ our_strftime(tmp, len, "%a %x %H:%M", ic_datep);
+}
+
+/* If the icline has a TZID parameter, return its value, otherwise, return
+ * NULL. Returned value freed by caller.
+ */
+char *
+ical_get_tzid(ICAL_PARAMETER_S *param)
+{
+ char *tzid = NULL;
+
+ if(param == NULL)
+ return tzid;
+
+ if(strucmp(param->name, "TZID") == 0)
+ tzid = cpystr(param->value);
+ else
+ tzid = ical_get_tzid(param->next);
+
+ return tzid;
+}
+
/* we create a summary of the event, and pass that back as
an ical parameter
*/
@@ -2149,16 +2188,17 @@ ical_vevent_summary(VCALENDAR_S *vcal)
if((icl = (ICLINE_S *) vevent->prop[EvDtstart]) != NULL){
struct tm ic_date;
- char tmp[200];
+ char tmp[200], *tzid;
int icd; /* ical date return value */
memset((void *)&ic_date, 0, sizeof(struct tm));
icd = ical_parse_date(icl->value, &ic_date);
+ tzid = ical_get_tzid(icl->param);
if(icd >= 0){
ic_date.tm_wday = ical_day_of_week(ic_date);
switch(icd){
case 0: /* DATE-TIME */
- our_strftime(tmp, sizeof(tmp), "%a %x %I:%M %p", &ic_date);
+ ical_date_time(tmp, sizeof(tmp), &ic_date);
break;
case 1: /* DATE */
our_strftime(tmp, sizeof(tmp), "%a %x", &ic_date);
@@ -2174,7 +2214,22 @@ ical_vevent_summary(VCALENDAR_S *vcal)
strncpy(tmp, _("Error while parsing event date"), sizeof(tmp));
tmp[sizeof(tmp) - 1] = '\0';
}
- rv->evstart = cpystr(icl->value ? tmp : _("Unknown Start Date"));
+
+ if(icl->value == NULL)
+ rv->evstart = cpystr(_("Unknown Start Date"));
+ else{
+ size_t len = strlen(tmp) + 1;
+
+ if(tzid != NULL)
+ len += strlen(tzid) + 3; /* 3 = strlen(" ()") */
+
+ rv->evstart = fs_get(len*sizeof(char));
+ snprintf(rv->evstart, len, "%s%s%s%s", tmp,
+ tzid != NULL ? " (" : "",
+ tzid != NULL ? tzid : "",
+ tzid != NULL ? ")" : "");
+ rv->evstart[len-1] = '\0';
+ }
} /* end of if dtstart */
if((icl = (ICLINE_S *) vevent->prop[EvDuration]) != NULL){
@@ -2219,16 +2274,17 @@ ical_vevent_summary(VCALENDAR_S *vcal)
} /* end of DURATION */
else if((icl = (ICLINE_S *) vevent->prop[EvDtend]) != NULL){
struct tm ic_date;
- char tmp[200];
+ char tmp[200], *tzid;
int icd;
memset((void *)&ic_date, 0, sizeof(struct tm));
icd = ical_parse_date(icl->value, &ic_date);
+ tzid = ical_get_tzid(icl->param);
if(icd >= 0){
ic_date.tm_wday = ical_day_of_week(ic_date);
switch(icd){
case 0: /* DATE-TIME */
- our_strftime(tmp, sizeof(tmp), "%a %x %I:%M %p", &ic_date);
+ ical_date_time(tmp, sizeof(tmp), &ic_date);
break;
case 1: /* DATE */
our_strftime(tmp, sizeof(tmp), "%a %x", &ic_date);
@@ -2244,9 +2300,69 @@ ical_vevent_summary(VCALENDAR_S *vcal)
strncpy(tmp, _("Error while parsing event date"), sizeof(tmp));
tmp[sizeof(tmp) - 1] = '\0';
}
- rv->evend = cpystr(icl->value ? tmp : _("Unknown End Date"));
+
+ if(icl->value == NULL)
+ rv->evend = cpystr(_("Unknown End Date"));
+ else{
+ size_t len = strlen(tmp) + 1;
+
+ if(tzid != NULL)
+ len += strlen(tzid) + 3; /* 3 = strlen(" ()") */
+
+ rv->evend = fs_get(len*sizeof(char));
+ snprintf(rv->evend, len, "%s%s%s%s", tmp,
+ tzid != NULL ? " (" : "",
+ tzid != NULL ? tzid : "",
+ tzid != NULL ? ")" : "");
+ rv->evend[len-1] = '\0';
+ }
} /* end of if dtend */
+ if((icl = (ICLINE_S *) vevent->prop[EvDtstamp]) != NULL){
+ struct tm ic_date;
+ char tmp[200], *tzid;
+ int icd;
+
+ memset((void *)&ic_date, 0, sizeof(struct tm));
+ icd = ical_parse_date(icl->value, &ic_date);
+ tzid = ical_get_tzid(icl->param);
+ if(icd >= 0){
+ ic_date.tm_wday = ical_day_of_week(ic_date);
+ switch(icd){
+ case 0: /* DATE-TIME */
+ ical_date_time(tmp, sizeof(tmp), &ic_date);
+ break;
+ case 1: /* DATE */
+ our_strftime(tmp, sizeof(tmp), "%a %x", &ic_date);
+ break;
+ case 2: /* DATE-TIME in GMT, Bug: add adjust to time zone */
+ our_strftime(tmp, sizeof(tmp), "%a %x %I:%M %p", &ic_date);
+ break;
+ default: alpine_panic("Unhandled ical date format");
+ break;
+ }
+ }
+ else{
+ strncpy(tmp, _("Error while parsing event date"), sizeof(tmp));
+ tmp[sizeof(tmp) - 1] = '\0';
+ }
+ if(icl->value == NULL)
+ rv->dtstamp = cpystr(_("Unknown when event was scheduled"));
+ else{
+ size_t len = strlen(tmp) + 1;
+
+ if(tzid != NULL)
+ len += strlen(tzid) + 3; /* 3 = strlen(" ()") */
+
+ rv->dtstamp = fs_get(len*sizeof(char));
+ snprintf(rv->dtstamp, len, "%s%s%s%s", tmp,
+ tzid != NULL ? " (" : "",
+ tzid != NULL ? tzid : "",
+ tzid != NULL ? ")" : "");
+ rv->dtstamp[len-1] = '\0';
+ }
+ } /* end of if dtstamp */
+
if((gicl = (GEN_ICLINE_S *) vevent->prop[EvAttendee]) != NULL){
int nattendees, i;
@@ -2386,6 +2502,7 @@ free_vevent_summary(VEVENT_SUMMARY_S **vesy)
if((*vesy)->location) fs_give((void **)&(*vesy)->location);
if((*vesy)->evstart) fs_give((void **)&(*vesy)->evstart);
if((*vesy)->evend) fs_give((void **)&(*vesy)->evend);
+ if((*vesy)->dtstamp) fs_give((void **)&(*vesy)->dtstamp);
if((*vesy)->duration){
for(i = 0; (*vesy)->duration[i] != NULL; i++)
fs_give((void **) &(*vesy)->duration[i]);
diff --git a/pith/icaltype.h b/pith/icaltype.h
index 162d08d2..d0670037 100644
--- a/pith/icaltype.h
+++ b/pith/icaltype.h
@@ -439,6 +439,7 @@ typedef struct vevent_summary_s {
char *location;
char *evstart;
char *evend;
+ char *dtstamp;
char **duration;
char **attendee;
unsigned char **description;