aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am10
-rw-r--r--src/apoint.c712
-rw-r--r--src/args.c1283
-rw-r--r--src/calcurse.c925
-rw-r--r--src/calcurse.h1091
-rw-r--r--src/calendar.c849
-rw-r--r--src/config.c574
-rw-r--r--src/custom.c1920
-rw-r--r--src/day.c1298
-rw-r--r--src/dmon.c184
-rw-r--r--src/event.c179
-rw-r--r--src/getstring.c280
-rw-r--r--src/help.c1173
-rw-r--r--src/htable.h14
-rw-r--r--src/ical.c1090
-rw-r--r--src/io.c3338
-rw-r--r--src/keys.c725
-rw-r--r--src/llist.c211
-rw-r--r--src/llist.h37
-rw-r--r--src/llist_ts.h13
-rw-r--r--src/mem.c271
-rw-r--r--src/note.c235
-rw-r--r--src/notify.c882
-rw-r--r--src/pcal.c291
-rw-r--r--src/recur.c1332
-rw-r--r--src/sha1.c267
-rw-r--r--src/sha1.h57
-rw-r--r--src/sigs.c73
-rw-r--r--src/todo.c497
-rw-r--r--src/utf8.c335
-rw-r--r--src/utils.c1523
-rw-r--r--src/vars.c56
-rw-r--r--src/wins.c878
33 files changed, 11719 insertions, 10884 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index faacf46..7eab77f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -2,26 +2,36 @@ AUTOMAKE_OPTIONS = foreign
bin_PROGRAMS = calcurse
+AM_CFLAGS = -std=c99 -pedantic -D_POSIX_C_SOURCE=200809L
+
calcurse_SOURCES = \
calcurse.c \
calcurse.h \
htable.h \
llist.h \
llist_ts.h \
+ sha1.h \
apoint.c \
args.c \
calendar.c \
+ config.c \
custom.c \
day.c \
event.c \
+ getstring.c \
help.c \
+ ical.c \
io.c \
keys.c \
llist.c \
+ note.c \
notify.c \
+ pcal.c \
recur.c \
+ sha1.c \
sigs.c \
todo.c \
+ utf8.c \
utils.c \
vars.c \
wins.c \
diff --git a/src/apoint.c b/src/apoint.c
index 6fd9e64..1483beb 100644
--- a/src/apoint.c
+++ b/src/apoint.c
@@ -1,7 +1,7 @@
/*
* Calcurse - text-based organizer
*
- * Copyright (c) 2004-2011 calcurse Development Team <misc@calcurse.org>
+ * Copyright (c) 2004-2012 calcurse Development Team <misc@calcurse.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -41,46 +41,41 @@
#include "calcurse.h"
-llist_ts_t alist_p;
-static struct apoint bkp_cut_apoint;
-static int hilt;
+llist_ts_t alist_p;
+static struct apoint bkp_cut_apoint;
+static int hilt;
-void
-apoint_free_bkp (enum eraseflg flag)
+void apoint_free_bkp(void)
{
- if (bkp_cut_apoint.mesg)
- {
- mem_free (bkp_cut_apoint.mesg);
- bkp_cut_apoint.mesg = 0;
- }
- erase_note (&bkp_cut_apoint.note, flag);
+ if (bkp_cut_apoint.mesg) {
+ mem_free(bkp_cut_apoint.mesg);
+ bkp_cut_apoint.mesg = 0;
+ }
+ erase_note(&bkp_cut_apoint.note);
}
-static void
-apoint_free (struct apoint *apt)
+static void apoint_free(struct apoint *apt)
{
- mem_free (apt->mesg);
- erase_note (&apt->note, ERASE_FORCE_KEEP_NOTE);
- mem_free (apt);
+ mem_free(apt->mesg);
+ erase_note(&apt->note);
+ mem_free(apt);
}
-static void
-apoint_dup (struct apoint *in, struct apoint *bkp)
+static void apoint_dup(struct apoint *in, struct apoint *bkp)
{
- EXIT_IF (!in || !bkp, _("null pointer"));
+ EXIT_IF(!in || !bkp, _("null pointer"));
bkp->start = in->start;
bkp->dur = in->dur;
bkp->state = in->state;
- bkp->mesg = mem_strdup (in->mesg);
+ bkp->mesg = mem_strdup(in->mesg);
if (in->note)
- bkp->note = mem_strdup (in->note);
+ bkp->note = mem_strdup(in->note);
}
-void
-apoint_llist_init (void)
+void apoint_llist_init(void)
{
- LLIST_TS_INIT (&alist_p);
+ LLIST_TS_INIT(&alist_p);
}
/*
@@ -88,60 +83,54 @@ apoint_llist_init (void)
* list. No need to be thread safe, as only the main process remains when
* calling this function.
*/
-void
-apoint_llist_free (void)
+void apoint_llist_free(void)
{
- LLIST_TS_FREE_INNER (&alist_p, apoint_free);
- LLIST_TS_FREE (&alist_p);
+ LLIST_TS_FREE_INNER(&alist_p, apoint_free);
+ LLIST_TS_FREE(&alist_p);
}
/* Sets which appointment is highlighted. */
-void
-apoint_hilt_set (int highlighted)
+void apoint_hilt_set(int highlighted)
{
hilt = highlighted;
}
-void
-apoint_hilt_decrease (void)
+void apoint_hilt_decrease(int n)
{
- hilt--;
+ hilt -= n;
}
-void
-apoint_hilt_increase (void)
+void apoint_hilt_increase(int n)
{
- hilt++;
+ hilt += n;
}
/* Return which appointment is highlighted. */
-int
-apoint_hilt (void)
+int apoint_hilt(void)
{
- return (hilt);
+ return hilt;
}
-static int
-apoint_cmp_start (struct apoint *a, struct apoint *b)
+static int apoint_cmp_start(struct apoint *a, struct apoint *b)
{
- return (a->start < b->start ? -1 : (a->start == b->start ? 0 : 1));
+ return a->start < b->start ? -1 : (a->start == b->start ? 0 : 1);
}
-struct apoint *
-apoint_new (char *mesg, char *note, long start, long dur, char state)
+struct apoint *apoint_new(char *mesg, char *note, long start, long dur,
+ char state)
{
struct apoint *apt;
- apt = mem_malloc (sizeof (struct apoint));
- apt->mesg = mem_strdup (mesg);
- apt->note = (note != NULL) ? mem_strdup (note) : NULL;
+ apt = mem_malloc(sizeof(struct apoint));
+ apt->mesg = mem_strdup(mesg);
+ apt->note = (note != NULL) ? mem_strdup(note) : NULL;
apt->state = state;
apt->start = start;
apt->dur = dur;
- LLIST_TS_LOCK (&alist_p);
- LLIST_TS_ADD_SORTED (&alist_p, apt, apoint_cmp_start);
- LLIST_TS_UNLOCK (&alist_p);
+ LLIST_TS_LOCK(&alist_p);
+ LLIST_TS_ADD_SORTED(&alist_p, apt, apoint_cmp_start);
+ LLIST_TS_UNLOCK(&alist_p);
return apt;
}
@@ -150,181 +139,148 @@ apoint_new (char *mesg, char *note, long start, long dur, char state)
* Add an item in either the appointment or the event list,
* depending if the start time is entered or not.
*/
-void
-apoint_add (void)
+void apoint_add(void)
{
#define LTIME 6
- char *mesg_1 =
- _("Enter start time ([hh:mm] or [h:mm]), "
- "leave blank for an all-day event : ");
- char *mesg_2 =
- _("Enter end time ([hh:mm] or [h:mm]) or duration (in minutes) : ");
- char *mesg_3 = _("Enter description :");
- char *format_message_1 =
- _("You entered an invalid start time, should be [h:mm] or [hh:mm]");
- char *format_message_2 =
- _("You entered an invalid end time, should be [h:mm] or [hh:mm] or [mm]");
- char *enter_str = _("Press [Enter] to continue");
+#define LDUR 12
+ const char *mesg_1 =
+ _("Enter start time ([hh:mm]), leave blank for an all-day event : ");
+ const char *mesg_2 =
+ _
+ ("Enter end time ([hh:mm]) or duration ([+hh:mm], [+xxxdxxhxxm] or [+mm]) : ");
+ const char *mesg_3 = _("Enter description :");
+ const char *format_message_1 =
+ _("You entered an invalid start time, should be [hh:mm]");
+ const char *format_message_2 =
+ _
+ ("Invalid end time/duration, should be [hh:mm], [+hh:mm], [+xxxdxxhxxm] or [+mm]");
+ const char *enter_str = _("Press [Enter] to continue");
int Id = 1;
- char item_time[LTIME] = "";
+ char item_time[LDUR] = "";
char item_mesg[BUFSIZ] = "";
- long apoint_duration = 0, apoint_start;
+ long apoint_start;
unsigned heures, minutes;
+ unsigned apoint_duration;
unsigned end_h, end_m;
int is_appointment = 1;
/* Get the starting time */
- do
- {
- status_mesg (mesg_1, "");
- if (getstring (win[STA].p, item_time, LTIME, 0, 1) != GETSTRING_ESC)
- {
- if (strlen (item_time) == 0)
- {
- is_appointment = 0;
- break;
- }
- else if (check_time (item_time) != 1)
- {
- status_mesg (format_message_1, enter_str);
- (void)wgetch (win[STA].p);
- }
- else
- (void)sscanf (item_time, "%u:%u", &heures, &minutes);
- }
- else
- return;
- }
- while (check_time (item_time) != 1);
+ for (;;) {
+ status_mesg(mesg_1, "");
+ if (getstring(win[STA].p, item_time, LTIME, 0, 1) != GETSTRING_ESC) {
+ if (strlen(item_time) == 0) {
+ is_appointment = 0;
+ break;
+ }
+
+ if (parse_time(item_time, &heures, &minutes) == 1)
+ break;
+ else {
+ status_mesg(format_message_1, enter_str);
+ wgetch(win[STA].p);
+ }
+ } else
+ return;
+ }
/*
* Check if an event or appointment is entered,
* depending on the starting time, and record the
* corresponding item.
*/
- if (is_appointment)
- { /* Get the appointment duration */
- item_time[0] = '\0';
- do
- {
- status_mesg (mesg_2, "");
- if (getstring (win[STA].p, item_time, LTIME, 0, 1) != GETSTRING_VALID)
- return; //nothing entered, cancel adding of event
- else if (check_time (item_time) == 0)
- {
- status_mesg (format_message_2, enter_str);
- (void)wgetch (win[STA].p);
- }
- else
- {
- if (check_time (item_time) == 2)
- apoint_duration = atoi (item_time);
- else if (check_time (item_time) == 1)
- {
- (void)sscanf (item_time, "%u:%u", &end_h, &end_m);
- if (end_h < heures || ((end_h == heures) && (end_m < minutes)))
- {
- apoint_duration = MININSEC - minutes + end_m
- + (24 + end_h - (heures + 1)) * MININSEC;
- }
- else
- {
- apoint_duration = MININSEC - minutes
- + end_m + (end_h - (heures + 1)) * MININSEC;
- }
- }
- }
+ if (is_appointment) { /* Get the appointment duration */
+ item_time[0] = '\0';
+ for (;;) {
+ status_mesg(mesg_2, "");
+ if (getstring(win[STA].p, item_time, LDUR, 0, 1) != GETSTRING_ESC) {
+ if (*item_time == '+' && parse_duration(item_time + 1,
+ &apoint_duration) == 1)
+ break;
+ else if (parse_time(item_time, &end_h, &end_m) == 1) {
+ if (end_h < heures || ((end_h == heures) && (end_m < minutes))) {
+ apoint_duration = MININSEC - minutes + end_m
+ + (24 + end_h - (heures + 1)) * MININSEC;
+ } else {
+ apoint_duration = MININSEC - minutes
+ + end_m + (end_h - (heures + 1)) * MININSEC;
+ }
+ break;
+ } else {
+ status_mesg(format_message_2, enter_str);
+ wgetch(win[STA].p);
}
- while (check_time (item_time) == 0);
+ } else
+ return;
}
- else /* Insert the event Id */
+ } else /* Insert the event Id */
Id = 1;
- status_mesg (mesg_3, "");
- if (getstring (win[STA].p, item_mesg, BUFSIZ, 0, 1) == GETSTRING_VALID)
- {
- if (is_appointment)
- {
- apoint_start = date2sec (*calendar_get_slctd_day (), heures, minutes);
- (void)apoint_new (item_mesg, 0L, apoint_start,
- min2sec (apoint_duration), 0L);
- if (notify_bar ())
- notify_check_added (item_mesg, apoint_start, 0L);
- }
- else
- (void)event_new (item_mesg, 0L,
- date2sec (*calendar_get_slctd_day (), 12, 0), Id);
-
- if (hilt == 0)
- hilt++;
- }
- wins_erase_status_bar ();
+ status_mesg(mesg_3, "");
+ if (getstring(win[STA].p, item_mesg, BUFSIZ, 0, 1) == GETSTRING_VALID) {
+ if (is_appointment) {
+ apoint_start = date2sec(*calendar_get_slctd_day(), heures, minutes);
+ apoint_new(item_mesg, 0L, apoint_start, min2sec(apoint_duration), 0L);
+ if (notify_bar())
+ notify_check_added(item_mesg, apoint_start, 0L);
+ } else
+ event_new(item_mesg, 0L, date2sec(*calendar_get_slctd_day(), 0, 0), Id);
+
+ if (hilt == 0)
+ hilt++;
+ }
+ wins_erase_status_bar();
}
/* Delete an item from the appointment list. */
-void
-apoint_delete (struct conf *conf, unsigned *nb_events, unsigned *nb_apoints)
+void apoint_delete(unsigned *nb_events, unsigned *nb_apoints)
{
- char *choices = "[y/n] ";
- char *del_app_str = _("Do you really want to delete this item ?");
+ const char *del_app_str = _("Do you really want to delete this item ?");
long date;
int nb_items = *nb_apoints + *nb_events;
- unsigned go_for_deletion = 0;
int to_be_removed = 0;
- int answer = 0;
- int deleted_item_type = 0;
-
- date = calendar_get_slctd_day_sec ();
-
- if (conf->confirm_delete)
- {
- status_mesg (del_app_str, choices);
- answer = wgetch (win[STA].p);
- if ((answer == 'y') && (nb_items != 0))
- go_for_deletion = 1;
- else
- {
- wins_erase_status_bar ();
- return;
- }
+
+ date = calendar_get_slctd_day_sec();
+
+ if (nb_items == 0)
+ return;
+
+ if (conf.confirm_delete) {
+ if (status_ask_bool(del_app_str) != 1) {
+ wins_erase_status_bar();
+ return;
}
- else if (nb_items != 0)
- go_for_deletion = 1;
-
- if (go_for_deletion)
- {
- if (nb_items != 0)
- {
- deleted_item_type = day_erase_item (date, hilt, ERASE_DONT_FORCE);
- if (deleted_item_type == EVNT || deleted_item_type == RECUR_EVNT)
- {
- (*nb_events)--;
- to_be_removed = 1;
- }
- else if (deleted_item_type == APPT || deleted_item_type == RECUR_APPT)
- {
- (*nb_apoints)--;
- to_be_removed = 3;
- }
- else if (deleted_item_type == 0)
- return;
- else
- EXIT (_("no such type"));
- /* NOTREACHED */
-
- if (hilt > 1)
- hilt--;
- if (apad.first_onscreen >= to_be_removed)
- apad.first_onscreen = apad.first_onscreen - to_be_removed;
- if (nb_items == 1)
- hilt = 0;
- }
+ }
+
+ if (nb_items != 0) {
+ switch (day_erase_item(date, hilt, ERASE_DONT_FORCE)) {
+ case EVNT:
+ case RECUR_EVNT:
+ (*nb_events)--;
+ to_be_removed = 1;
+ break;
+ case APPT:
+ case RECUR_APPT:
+ (*nb_apoints)--;
+ to_be_removed = 3;
+ break;
+ case 0:
+ return;
+ default:
+ EXIT(_("no such type"));
+ /* NOTREACHED */
}
+
+ if (hilt > 1)
+ hilt--;
+ if (apad.first_onscreen >= to_be_removed)
+ apad.first_onscreen = apad.first_onscreen - to_be_removed;
+ if (nb_items == 1)
+ hilt = 0;
+ }
}
/* Cut an item, so that it can be pasted somewhere else later. */
-int
-apoint_cut (unsigned *nb_events, unsigned *nb_apoints)
+int apoint_cut(unsigned *nb_events, unsigned *nb_apoints)
{
const int NBITEMS = *nb_apoints + *nb_events;
int item_type, to_be_removed;
@@ -333,20 +289,16 @@ apoint_cut (unsigned *nb_events, unsigned *nb_apoints)
if (NBITEMS == 0)
return 0;
- date = calendar_get_slctd_day_sec ();
- item_type = day_cut_item (date, hilt);
- if (item_type == EVNT || item_type == RECUR_EVNT)
- {
- (*nb_events)--;
- to_be_removed = 1;
- }
- else if (item_type == APPT || item_type == RECUR_APPT)
- {
- (*nb_apoints)--;
- to_be_removed = 3;
- }
- else
- EXIT (_("no such type"));
+ date = calendar_get_slctd_day_sec();
+ item_type = day_cut_item(date, hilt);
+ if (item_type == EVNT || item_type == RECUR_EVNT) {
+ (*nb_events)--;
+ to_be_removed = 1;
+ } else if (item_type == APPT || item_type == RECUR_APPT) {
+ (*nb_apoints)--;
+ to_be_removed = 3;
+ } else
+ EXIT(_("no such type"));
/* NOTREACHED */
if (hilt > 1)
@@ -360,14 +312,13 @@ apoint_cut (unsigned *nb_events, unsigned *nb_apoints)
}
/* Paste a previously cut item. */
-void
-apoint_paste (unsigned *nb_events, unsigned *nb_apoints, int cut_item_type)
+void apoint_paste(unsigned *nb_events, unsigned *nb_apoints, int cut_item_type)
{
int item_type;
long date;
- date = calendar_get_slctd_day_sec ();
- item_type = day_paste_item (date, cut_item_type);
+ date = calendar_get_slctd_day_sec();
+ item_type = day_paste_item(date, cut_item_type);
if (item_type == EVNT || item_type == RECUR_EVNT)
(*nb_events)++;
else if (item_type == APPT || item_type == RECUR_APPT)
@@ -379,81 +330,72 @@ apoint_paste (unsigned *nb_events, unsigned *nb_apoints, int cut_item_type)
hilt++;
}
-unsigned
-apoint_inday (struct apoint *i, long start)
+unsigned apoint_inday(struct apoint *i, long start)
{
- if (i->start <= start + DAYINSEC && i->start + i->dur > start)
- {
- return (1);
- }
- return (0);
+ return (i->start <= start + DAYINSEC && i->start + i->dur > start);
}
-void
-apoint_sec2str (struct apoint *o, int type, long day, char *start, char *end)
+void apoint_sec2str(struct apoint *o, long day, char *start, char *end)
{
struct tm *lt;
time_t t;
- if (o->start < day && type == APPT)
- (void)strncpy (start, "..:..", 6);
- else
- {
- t = o->start;
- lt = localtime (&t);
- (void)snprintf (start, HRMIN_SIZE, "%02u:%02u", lt->tm_hour, lt->tm_min);
- }
- if (o->start + o->dur > day + DAYINSEC && type == APPT)
- (void)strncpy (end, "..:..", 6);
- else
- {
- t = o->start + o->dur;
- lt = localtime (&t);
- (void)snprintf (end, HRMIN_SIZE, "%02u:%02u", lt->tm_hour, lt->tm_min);
- }
+ if (o->start < day)
+ strncpy(start, "..:..", 6);
+ else {
+ t = o->start;
+ lt = localtime(&t);
+ snprintf(start, HRMIN_SIZE, "%02u:%02u", lt->tm_hour, lt->tm_min);
+ }
+ if (o->start + o->dur > day + DAYINSEC)
+ strncpy(end, "..:..", 6);
+ else {
+ t = o->start + o->dur;
+ lt = localtime(&t);
+ snprintf(end, HRMIN_SIZE, "%02u:%02u", lt->tm_hour, lt->tm_min);
+ }
}
-void
-apoint_write (struct apoint *o, FILE *f)
+void apoint_write(struct apoint *o, FILE * f)
{
struct tm *lt;
time_t t;
t = o->start;
- lt = localtime (&t);
- (void)fprintf (f, "%02u/%02u/%04u @ %02u:%02u",
- lt->tm_mon + 1, lt->tm_mday, 1900 + lt->tm_year, lt->tm_hour,
- lt->tm_min);
+ lt = localtime(&t);
+ fprintf(f, "%02u/%02u/%04u @ %02u:%02u", lt->tm_mon + 1, lt->tm_mday,
+ 1900 + lt->tm_year, lt->tm_hour, lt->tm_min);
t = o->start + o->dur;
- lt = localtime (&t);
- (void)fprintf (f, " -> %02u/%02u/%04u @ %02u:%02u ",
- lt->tm_mon + 1, lt->tm_mday, 1900 + lt->tm_year, lt->tm_hour,
- lt->tm_min);
+ lt = localtime(&t);
+ fprintf(f, " -> %02u/%02u/%04u @ %02u:%02u ", lt->tm_mon + 1, lt->tm_mday,
+ 1900 + lt->tm_year, lt->tm_hour, lt->tm_min);
if (o->note != NULL)
- (void)fprintf (f, ">%s ", o->note);
+ fprintf(f, ">%s ", o->note);
if (o->state & APOINT_NOTIFY)
- (void)fprintf (f, "!");
+ fputc('!', f);
else
- (void)fprintf (f, "|");
+ fputc('|', f);
- (void)fprintf (f, "%s\n", o->mesg);
+ fprintf(f, "%s\n", o->mesg);
}
-struct apoint *
-apoint_scan (FILE *f, struct tm start, struct tm end, char state, char *note)
+struct apoint *apoint_scan(FILE * f, struct tm start, struct tm end, char state,
+ char *note)
{
char buf[BUFSIZ], *newline;
time_t tstart, tend, t;
- t = time (NULL);
- (void)localtime (&t);
+ t = time(NULL);
+ localtime(&t);
/* Read the appointment description */
- (void)fgets (buf, sizeof buf, f);
- newline = strchr (buf, '\n');
+ if (!fgets(buf, sizeof buf, f))
+ return NULL;
+
+ newline = strchr(buf, '\n');
if (newline)
*newline = '\0';
@@ -464,63 +406,58 @@ apoint_scan (FILE *f, struct tm start, struct tm end, char state, char *note)
end.tm_year -= 1900;
end.tm_mon--;
- tstart = mktime (&start);
- tend = mktime (&end);
- EXIT_IF (tstart == -1 || tend == -1 || tstart > tend,
- _("date error in appointment"));
- return (apoint_new (buf, note, tstart, tend - tstart, state));
+ tstart = mktime(&start);
+ tend = mktime(&end);
+ EXIT_IF(tstart == -1 || tend == -1 || tstart > tend,
+ _("date error in appointment"));
+ return apoint_new(buf, note, tstart, tend - tstart, state);
}
/* Retrieve an appointment from the list, given the day and item position. */
-struct apoint *
-apoint_get (long day, int pos)
+struct apoint *apoint_get(long day, int pos)
{
- llist_item_t *i = LLIST_TS_FIND_NTH (&alist_p, pos, day, apoint_inday);
+ llist_item_t *i = LLIST_TS_FIND_NTH(&alist_p, pos, day, apoint_inday);
if (i)
- return LLIST_TS_GET_DATA (i);
+ return LLIST_TS_GET_DATA(i);
- EXIT (_("item not found"));
+ EXIT(_("item not found"));
/* NOTREACHED */
}
-void
-apoint_delete_bynum (long start, unsigned num, enum eraseflg flag)
+void apoint_delete_bynum(long start, unsigned num, enum eraseflg flag)
{
llist_item_t *i;
int need_check_notify = 0;
- LLIST_TS_LOCK (&alist_p);
- i = LLIST_TS_FIND_NTH (&alist_p, num, start, apoint_inday);
+ LLIST_TS_LOCK(&alist_p);
+ i = LLIST_TS_FIND_NTH(&alist_p, num, start, apoint_inday);
if (!i)
- EXIT (_("no such appointment"));
- struct apoint *apt = LLIST_TS_GET_DATA (i);
-
- switch (flag)
- {
- case ERASE_FORCE_ONLY_NOTE:
- erase_note (&apt->note, flag);
- break;
- case ERASE_CUT:
- apoint_free_bkp (ERASE_FORCE);
- apoint_dup (apt, &bkp_cut_apoint);
- erase_note (&apt->note, ERASE_FORCE_KEEP_NOTE);
- /* FALLTHROUGH */
- default:
- if (notify_bar ())
- need_check_notify = notify_same_item (apt->start);
- LLIST_TS_REMOVE (&alist_p, i);
- mem_free (apt->mesg);
- if (flag != ERASE_FORCE_KEEP_NOTE && flag != ERASE_CUT)
- erase_note (&apt->note, flag);
- mem_free (apt);
- if (need_check_notify)
- notify_check_next_app (0);
- break;
- }
-
- LLIST_TS_UNLOCK (&alist_p);
+ EXIT(_("no such appointment"));
+ struct apoint *apt = LLIST_TS_GET_DATA(i);
+
+ switch (flag) {
+ case ERASE_FORCE_ONLY_NOTE:
+ erase_note(&apt->note);
+ break;
+ case ERASE_CUT:
+ apoint_free_bkp();
+ apoint_dup(apt, &bkp_cut_apoint);
+ erase_note(&apt->note);
+ /* FALLTHROUGH */
+ default:
+ if (notify_bar())
+ need_check_notify = notify_same_item(apt->start);
+ LLIST_TS_REMOVE(&alist_p, i);
+ mem_free(apt->mesg);
+ mem_free(apt);
+ if (need_check_notify)
+ notify_check_next_app(0);
+ break;
+ }
+
+ LLIST_TS_UNLOCK(&alist_p);
}
/*
@@ -528,8 +465,7 @@ apoint_delete_bynum (long start, unsigned num, enum eraseflg flag)
* the appointment panel. This is to help the appointment scroll function
* to place beggining of the pad correctly.
*/
-static int
-get_item_line (int item_nb, int nb_events_inday)
+static int get_item_line(int item_nb, int nb_events_inday)
{
int separator = 2;
int line = 0;
@@ -538,7 +474,7 @@ get_item_line (int item_nb, int nb_events_inday)
line = item_nb - 1;
else
line = nb_events_inday + separator
- + (item_nb - (nb_events_inday + 1)) * 3 - 1;
+ + (item_nb - (nb_events_inday + 1)) * 3 - 1;
return line;
}
@@ -546,15 +482,14 @@ get_item_line (int item_nb, int nb_events_inday)
* Update (if necessary) the first displayed pad line to make the
* appointment panel scroll down next time pnoutrefresh is called.
*/
-void
-apoint_scroll_pad_down (int nb_events_inday, int win_length)
+void apoint_scroll_pad_down(int nb_events_inday, int win_length)
{
int pad_last_line = 0;
int item_first_line = 0, item_last_line = 0;
int borders = 6;
int awin_length = win_length - borders;
- item_first_line = get_item_line (hilt, nb_events_inday);
+ item_first_line = get_item_line(hilt, nb_events_inday);
if (hilt < nb_events_inday)
item_last_line = item_first_line;
else
@@ -568,109 +503,84 @@ apoint_scroll_pad_down (int nb_events_inday, int win_length)
* Update (if necessary) the first displayed pad line to make the
* appointment panel scroll up next time pnoutrefresh is called.
*/
-void
-apoint_scroll_pad_up (int nb_events_inday)
+void apoint_scroll_pad_up(int nb_events_inday)
{
int item_first_line = 0;
- item_first_line = get_item_line (hilt, nb_events_inday);
+ item_first_line = get_item_line(hilt, nb_events_inday);
if (item_first_line < apad.first_onscreen)
apad.first_onscreen = item_first_line;
}
-static int
-apoint_starts_after (struct apoint *apt, long time)
+static int apoint_starts_after(struct apoint *apt, long time)
{
- return (apt->start > time);
+ return apt->start > time;
}
/*
* Look in the appointment list if we have an item which starts before the item
* stored in the notify_app structure (which is the next item to be notified).
*/
-struct notify_app *
-apoint_check_next (struct notify_app *app, long start)
+struct notify_app *apoint_check_next(struct notify_app *app, long start)
{
llist_item_t *i;
- LLIST_TS_LOCK (&alist_p);
- i = LLIST_TS_FIND_FIRST (&alist_p, start, apoint_starts_after);
+ LLIST_TS_LOCK(&alist_p);
+ i = LLIST_TS_FIND_FIRST(&alist_p, start, apoint_starts_after);
- if (i)
- {
- struct apoint *apt = LLIST_TS_GET_DATA (i);
-
- if (apt->start <= app->time)
- {
- app->time = apt->start;
- app->txt = mem_strdup (apt->mesg);
- app->state = apt->state;
- app->got_app = 1;
- }
+ if (i) {
+ struct apoint *apt = LLIST_TS_GET_DATA(i);
+
+ if (apt->start <= app->time) {
+ app->time = apt->start;
+ app->txt = mem_strdup(apt->mesg);
+ app->state = apt->state;
+ app->got_app = 1;
}
+ }
- LLIST_TS_UNLOCK (&alist_p);
+ LLIST_TS_UNLOCK(&alist_p);
- return (app);
-}
-
-/*
- * Returns a structure of type struct apoint_list given a structure of type
- * recur_apoint_s
- */
-struct apoint *
-apoint_recur_s2apoint_s (struct recur_apoint *p)
-{
- struct apoint *a;
-
- a = mem_malloc (sizeof (struct apoint));
- a->mesg = mem_strdup (p->mesg);
- a->start = p->start;
- a->dur = p->dur;
- return (a);
+ return app;
}
/*
* Switch notification state.
*/
-void
-apoint_switch_notify (void)
+void apoint_switch_notify(void)
{
struct day_item *p;
long date;
int apoint_nb = 0, need_chk_notify;
- p = day_get_item (hilt);
+ p = day_get_item(hilt);
if (p->type != APPT && p->type != RECUR_APPT)
return;
- date = calendar_get_slctd_day_sec ();
+ date = calendar_get_slctd_day_sec();
- if (p->type == RECUR_APPT)
- {
- recur_apoint_switch_notify (date, p->appt_pos);
- return;
- }
- else if (p->type == APPT)
- apoint_nb = day_item_nb (date, hilt, APPT);
+ if (p->type == RECUR_APPT) {
+ recur_apoint_switch_notify(date, p->appt_pos);
+ return;
+ } else if (p->type == APPT)
+ apoint_nb = day_item_nb(date, hilt, APPT);
need_chk_notify = 0;
- LLIST_TS_LOCK (&alist_p);
+ LLIST_TS_LOCK(&alist_p);
- struct apoint *apt = apoint_get (date, apoint_nb);
+ struct apoint *apt = apoint_get(date, apoint_nb);
apt->state ^= APOINT_NOTIFY;
- if (notify_bar ())
- notify_check_added (apt->mesg, apt->start, apt->state);
+ if (notify_bar())
+ notify_check_added(apt->mesg, apt->start, apt->state);
if (need_chk_notify)
- notify_check_next_app (0);
+ notify_check_next_app(0);
- LLIST_TS_UNLOCK (&alist_p);
+ LLIST_TS_UNLOCK(&alist_p);
}
/* Updates the Appointment panel */
-void
-apoint_update_panel (int which_pan)
+void apoint_update_panel(int which_pan)
{
int title_xpos;
int bordr = 1;
@@ -681,57 +591,53 @@ apoint_update_panel (int which_pan)
struct date slctd_date;
/* variable inits */
- slctd_date = *calendar_get_slctd_day ();
- title_xpos = win[APP].w - (strlen (_(monthnames[slctd_date.mm - 1])) + 16);
+ slctd_date = *calendar_get_slctd_day();
+ title_xpos = win[APP].w - (strlen(_(monthnames[slctd_date.mm - 1])) + 16);
if (slctd_date.dd < 10)
title_xpos++;
- date = date2sec (slctd_date, 0, 0);
- day_write_pad (date, app_width, app_length, hilt);
+ date = date2sec(slctd_date, 0, 0);
+ day_write_pad(date, app_width, app_length, (which_pan == APP) ? hilt : 0);
/* Print current date in the top right window corner. */
- erase_window_part (win[APP].p, 1, title_lines, win[APP].w - 2,
- win[APP].h - 2);
- custom_apply_attr (win[APP].p, ATTR_HIGHEST);
- mvwprintw (win[APP].p, title_lines, title_xpos, "%s %s %d, %d",
- calendar_get_pom (date), _(monthnames[slctd_date.mm - 1]),
- slctd_date.dd, slctd_date.yyyy);
- custom_remove_attr (win[APP].p, ATTR_HIGHEST);
+ erase_window_part(win[APP].p, 1, title_lines, win[APP].w - 2, win[APP].h - 2);
+ custom_apply_attr(win[APP].p, ATTR_HIGHEST);
+ mvwprintw(win[APP].p, title_lines, title_xpos, "%s %s %d, %d",
+ calendar_get_pom(date), _(monthnames[slctd_date.mm - 1]),
+ slctd_date.dd, slctd_date.yyyy);
+ custom_remove_attr(win[APP].p, ATTR_HIGHEST);
/* Draw the scrollbar if necessary. */
- if ((apad.length >= app_length) || (apad.first_onscreen > 0))
- {
- float ratio = ((float) app_length) / ((float) apad.length);
- int sbar_length = (int) (ratio * app_length);
- int highend = (int) (ratio * apad.first_onscreen);
- unsigned hilt_bar = (which_pan == APP) ? 1 : 0;
- int sbar_top = highend + title_lines + 1;
-
- if ((sbar_top + sbar_length) > win[APP].h - 1)
- sbar_length = win[APP].h - 1 - sbar_top;
- draw_scrollbar (win[APP].p, sbar_top, win[APP].w - 2, sbar_length,
- title_lines + 1, win[APP].h - 1, hilt_bar);
- }
-
- wnoutrefresh (win[APP].p);
- pnoutrefresh (apad.ptrwin, apad.first_onscreen, 0,
- win[APP].y + title_lines + 1, win[APP].x + bordr,
- win[APP].y + win[APP].h - 2 * bordr,
- win[APP].x + win[APP].w - 3 * bordr);
+ if ((apad.length >= app_length) || (apad.first_onscreen > 0)) {
+ float ratio = ((float)app_length) / ((float)apad.length);
+ int sbar_length = (int)(ratio * app_length);
+ int highend = (int)(ratio * apad.first_onscreen);
+ unsigned hilt_bar = (which_pan == APP) ? 1 : 0;
+ int sbar_top = highend + title_lines + 1;
+
+ if ((sbar_top + sbar_length) > win[APP].h - 1)
+ sbar_length = win[APP].h - 1 - sbar_top;
+ draw_scrollbar(win[APP].p, sbar_top, win[APP].w - 2, sbar_length,
+ title_lines + 1, win[APP].h - 1, hilt_bar);
+ }
+
+ wnoutrefresh(win[APP].p);
+ pnoutrefresh(apad.ptrwin, apad.first_onscreen, 0,
+ win[APP].y + title_lines + 1, win[APP].x + bordr,
+ win[APP].y + win[APP].h - 2 * bordr,
+ win[APP].x + win[APP].w - 3 * bordr);
}
-void
-apoint_paste_item (void)
+void apoint_paste_item(void)
{
long bkp_time, bkp_start;
- bkp_time = get_item_time (bkp_cut_apoint.start);
- bkp_start = calendar_get_slctd_day_sec () + bkp_time;
- (void)apoint_new (bkp_cut_apoint.mesg, bkp_cut_apoint.note,
- bkp_start, bkp_cut_apoint.dur,
- bkp_cut_apoint.state);
+ bkp_time = get_item_time(bkp_cut_apoint.start);
+ bkp_start = calendar_get_slctd_day_sec() + bkp_time;
+ apoint_new(bkp_cut_apoint.mesg, bkp_cut_apoint.note, bkp_start,
+ bkp_cut_apoint.dur, bkp_cut_apoint.state);
- if (notify_bar ())
- notify_check_added (bkp_cut_apoint.mesg, bkp_start, bkp_cut_apoint.state);
+ if (notify_bar())
+ notify_check_added(bkp_cut_apoint.mesg, bkp_start, bkp_cut_apoint.state);
- apoint_free_bkp (ERASE_FORCE_KEEP_NOTE);
+ apoint_free_bkp();
}
diff --git a/src/args.c b/src/args.c
index a3a22fe..99c468f 100644
--- a/src/args.c
+++ b/src/args.c
@@ -1,7 +1,7 @@
/*
* Calcurse - text-based organizer
*
- * Copyright (c) 2004-2011 calcurse Development Team <misc@calcurse.org>
+ * Copyright (c) 2004-2012 calcurse Development Team <misc@calcurse.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -45,112 +45,114 @@
#include "calcurse.h"
+/* Long options */
+enum {
+ OPT_FMT_APT = 1000,
+ OPT_FMT_RAPT,
+ OPT_FMT_EV,
+ OPT_FMT_REV,
+ OPT_FMT_TODO,
+ OPT_READ_ONLY
+};
+
/*
* Print Calcurse usage and exit.
*/
-static void
-usage ()
+static void usage(void)
{
- char *arg_usage =
- _("Usage: calcurse [-h|-v] [-N] [-an] [-t[num]] [-i<file>] [-x[format]]\n"
- " [-d <date>|<num>] [-s[date]] [-r[range]]\n"
- " [-c<file> | -D<dir>] [-S<regex>] [--status]\n");
- fputs (arg_usage, stdout);
+ const char *arg_usage =
+ _("Usage: calcurse [-g|-h|-v] [-an] [-t[num]] [-i<file>] [-x[format]]\n"
+ " [-d <date>|<num>] [-s[date]] [-r[range]]\n"
+ " [-c<file> | -D<dir>] [-S<regex>] [--status]\n"
+ " [--read-only]\n");
+ fputs(arg_usage, stdout);
}
-static void
-usage_try ()
+static void usage_try(void)
{
- char *arg_usage_try = _("Try 'calcurse -h' for more information.\n");
- fputs (arg_usage_try, stdout);
+ const char *arg_usage_try = _("Try 'calcurse -h' for more information.\n");
+ fputs(arg_usage_try, stdout);
}
/*
* Print Calcurse version with a short copyright text and exit.
*/
-static void
-version_arg ()
+static void version_arg(void)
{
- char vtitle[BUFSIZ];
- char *vtext =
- _("\nCopyright (c) 2004-2011 calcurse Development Team.\n"
+ const char *vtext =
+ _("\nCopyright (c) 2004-2012 calcurse Development Team.\n"
"This is free software; see the source for copying conditions.\n");
- (void)snprintf (vtitle, BUFSIZ, _("Calcurse %s - text-based organizer\n"),
- VERSION);
- fputs (vtitle, stdout);
- fputs (vtext, stdout);
+ fprintf(stdout, _("Calcurse %s - text-based organizer\n"), VERSION);
+ fputs(vtext, stdout);
}
/*
* Print the command line options and exit.
*/
-static void
-help_arg ()
+static void help_arg(void)
{
- char htitle[BUFSIZ];
- char *htext =
- _("\nMiscellaneous:\n"
- " -h, --help\n"
- " print this help and exit.\n"
- "\n -v, --version\n"
- " print calcurse version and exit.\n"
- "\n --status\n"
- " display the status of running instances of calcurse.\n"
- "\nFiles:\n"
- " -c <file>, --calendar <file>\n"
- " specify the calendar <file> to use (incompatible with '-D').\n"
- "\n -D <dir>, --directory <dir>\n"
- " specify the data directory to use (incompatible with '-c').\n"
- "\tIf not specified, the default directory is ~/.calcurse\n"
- "\nNon-interactive:\n"
- " -a, --appointment\n"
- " print events and appointments for current day and exit.\n"
- "\n -d <date|num>, --day <date|num>\n"
- " print events and appointments for <date> or <num> upcoming days and"
- "\n\texit. To specify both a starting date and a range, use the\n"
- "\t'--startday' and the '--range' option.\n"
- "\n -i <file>, --import <file>\n"
- " import the icalendar data contained in <file>. \n"
- "\n -n, --next\n"
- " print next appointment within upcoming 24 hours "
- "and exit. Also given\n\tis the remaining time before this "
- "next appointment.\n"
- "\n -N, --note\n"
- " when used with the '-a' or '-t' flag, also print note content\n"
- " if one is associated with the displayed item.\n"
- "\n -r[num], --range[=num]\n"
- " print events and appointments for the [num] number of days"
- "\n\tand exit. If no [num] is given, a range of 1 day is considered.\n"
- "\n -s[date], --startday[=date]\n"
- " print events and appointments from [date] and exit.\n"
- "\tIf no [date] is given, the current day is considered.\n"
- "\n -S<regex>, --search=<regex>\n"
- " search for the given regular expression within events, appointments,\n"
- "\tand todos description.\n"
- "\n -t[num], --todo[=num]\n"
- " print todo list and exit. If the optional number [num] is given,\n"
- "\tthen only todos having a priority equal to [num] will be returned.\n"
- "\tThe priority number must be between 1 (highest) and 9 (lowest).\n"
- "\tIt is also possible to specify '0' for the priority, in which case\n"
- "\tonly completed tasks will be shown.\n"
- "\n -x[format], --export[=format]\n"
- " export user data to the specified format. Events, appointments and\n"
- "\ttodos are converted and echoed to stdout.\n"
- "\tTwo possible formats are available: 'ical' and 'pcal'.\n"
- "\tIf the optional argument format is not given, ical format is\n"
- "\tselected by default.\n"
- "\tnote: redirect standard output to export data to a file,\n"
- "\tby issuing a command such as: calcurse --export > calcurse.dat\n"
- "\nFor more information, type '?' from within Calcurse, "
- "or read the manpage.\n"
- "Mail bug reports and suggestions to <misc@calcurse.org>.\n");
-
- (void)snprintf (htitle, BUFSIZ, _("Calcurse %s - text-based organizer\n"),
- VERSION);
- fputs (htitle, stdout);
- usage ();
- fputs (htext, stdout);
+ const char *htext =
+ _("\nMiscellaneous:\n"
+ " -h, --help\n"
+ " print this help and exit.\n"
+ "\n -v, --version\n"
+ " print calcurse version and exit.\n"
+ "\n --status\n"
+ " display the status of running instances of calcurse.\n"
+ "\n --read-only\n"
+ " Don't save configuration nor appointments/todos. Use with care.\n"
+ "\nFiles:\n"
+ " -c <file>, --calendar <file>\n"
+ " specify the calendar <file> to use (incompatible with '-D').\n"
+ "\n -D <dir>, --directory <dir>\n"
+ " specify the data directory to use (incompatible with '-c').\n"
+ "\tIf not specified, the default directory is ~/.calcurse\n"
+ "\nNon-interactive:\n"
+ " -a, --appointment\n"
+ " print events and appointments for current day and exit.\n"
+ "\n -d <date|num>, --day <date|num>\n"
+ " print events and appointments for <date> or <num> upcoming days and"
+ "\n\texit. To specify both a starting date and a range, use the\n"
+ "\t'--startday' and the '--range' option.\n"
+ "\n -g, --gc\n"
+ " run the garbage collector for note files and exit. \n"
+ "\n -i <file>, --import <file>\n"
+ " import the icalendar data contained in <file>. \n"
+ "\n -n, --next\n"
+ " print next appointment within upcoming 24 hours "
+ "and exit. Also given\n\tis the remaining time before this "
+ "next appointment.\n"
+ "\n -r[num], --range[=num]\n"
+ " print events and appointments for the [num] number of days"
+ "\n\tand exit. If no [num] is given, a range of 1 day is considered.\n"
+ "\n -s[date], --startday[=date]\n"
+ " print events and appointments from [date] and exit.\n"
+ "\tIf no [date] is given, the current day is considered.\n"
+ "\n -S<regex>, --search=<regex>\n"
+ " search for the given regular expression within events, appointments,\n"
+ "\tand todos description.\n"
+ "\n -t[num], --todo[=num]\n"
+ " print todo list and exit. If the optional number [num] is given,\n"
+ "\tthen only todos having a priority equal to [num] will be returned.\n"
+ "\tThe priority number must be between 1 (highest) and 9 (lowest).\n"
+ "\tIt is also possible to specify '0' for the priority, in which case\n"
+ "\tonly completed tasks will be shown.\n"
+ "\n -x[format], --export[=format]\n"
+ " export user data to the specified format. Events, appointments and\n"
+ "\ttodos are converted and echoed to stdout.\n"
+ "\tTwo possible formats are available: 'ical' and 'pcal'.\n"
+ "\tIf the optional argument format is not given, ical format is\n"
+ "\tselected by default.\n"
+ "\tnote: redirect standard output to export data to a file,\n"
+ "\tby issuing a command such as: calcurse --export > calcurse.dat\n"
+ "\nFor more information, type '?' from within Calcurse, "
+ "or read the manpage.\n"
+ "Mail bug reports and suggestions to <misc@calcurse.org>.\n");
+
+ fprintf(stdout, _("Calcurse %s - text-based organizer\n"), VERSION);
+ usage();
+ fputs(htext, stdout);
}
/*
@@ -164,78 +166,24 @@ help_arg ()
* The status is obtained by looking at pid files in user data directory
* (.calcurse.pid and .daemon.pid).
*/
-static void
-status_arg (void)
+static void status_arg(void)
{
int cpid, dpid;
- cpid = io_get_pid (path_cpid);
- dpid = io_get_pid (path_dpid);
+ cpid = io_get_pid(path_cpid);
+ dpid = io_get_pid(path_dpid);
- EXIT_IF (cpid && dpid,
- _("Error: both calcurse (pid: %d) and its daemon (pid: %d)\n"
- "seem to be running at the same time!\n"
- "Please check manually and restart calcurse.\n"),
- cpid, dpid);
+ EXIT_IF(cpid && dpid,
+ _("Error: both calcurse (pid: %d) and its daemon (pid: %d)\n"
+ "seem to be running at the same time!\n"
+ "Please check manually and restart calcurse.\n"), cpid, dpid);
if (cpid)
- fprintf (stdout, _("calcurse is running (pid %d)\n"), cpid);
+ fprintf(stdout, _("calcurse is running (pid %d)\n"), cpid);
else if (dpid)
- fprintf (stdout, _("calcurse is running in background (pid %d)\n"), dpid);
+ fprintf(stdout, _("calcurse is running in background (pid %d)\n"), dpid);
else
- fprintf (stdout, _("calcurse is not running\n"));
-}
-
-/*
- * Display note contents if one is asociated with the currently displayed item
- * (to be used together with the '-a' or '-t' flag in non-interactive mode).
- * Each line begins with nbtab tabs.
- * Print "No note file found", if the notefile does not exists.
- *
- * (patch submitted by Erik Saule).
- */
-static void
-print_notefile (FILE *out, char *filename, int nbtab)
-{
- char path_to_notefile[BUFSIZ];
- FILE *notefile;
- char linestarter[BUFSIZ];
- char buffer[BUFSIZ];
- int i;
- int printlinestarter = 1;
-
- if (nbtab < BUFSIZ)
- {
- for (i = 0; i < nbtab; i++)
- linestarter[i] = '\t';
- linestarter[nbtab] = '\0';
- }
- else
- linestarter[0] = '\0';
-
- (void)snprintf (path_to_notefile, BUFSIZ, "%s/%s", path_notes, filename);
- notefile = fopen (path_to_notefile, "r");
- if (notefile)
- {
- while (fgets (buffer, BUFSIZ, notefile) != 0)
- {
- if (printlinestarter)
- {
- fputs (linestarter, out);
- printlinestarter = 0;
- }
- fputs (buffer, out);
- if (buffer[strlen (buffer) - 1] == '\n')
- printlinestarter = 1;
- }
- fputs ("\n", out);
- file_close (notefile, __FILE_POS__);
- }
- else
- {
- fputs (linestarter, out);
- fputs (_("No note file found\n"), out);
- }
+ puts(_("calcurse is not running\n"));
}
/*
@@ -245,14 +193,13 @@ print_notefile (FILE *out, char *filename, int nbtab)
* If priority == 0, only completed tasks will be displayed.
* If regex is not null, only the matching todos are printed.
*/
-static void
-todo_arg (int priority, int print_note, regex_t *regex)
+static void todo_arg(int priority, const char *format, regex_t * regex)
{
llist_item_t *i;
int title = 1;
- char *titlestr, priority_str[BUFSIZ] = "";
- char *all_todos_title = _("to do:\n");
- char *completed_title = _("completed tasks:\n");
+ const char *titlestr;
+ const char *all_todos_title = _("to do:\n");
+ const char *completed_title = _("completed tasks:\n");
titlestr = priority == 0 ? completed_title : all_todos_title;
@@ -264,49 +211,32 @@ todo_arg (int priority, int print_note, regex_t *regex)
} \
} while (0)
-#define DISPLAY_TODO do { \
- (void)snprintf (priority_str, BUFSIZ, "%d. ", abs (todo->id)); \
- fputs (priority_str, stdout); \
- fputs (todo->mesg, stdout); \
- fputs ("\n", stdout); \
- if (print_note && todo->note) \
- print_notefile (stdout, todo->note, 1); \
- } while (0)
-
- LLIST_FOREACH (&todolist, i)
- {
- struct todo *todo = LLIST_TS_GET_DATA (i);
- if (regex && regexec (regex, todo->mesg, 0, 0, 0) != 0)
- continue;
-
- if (todo->id < 0) /* completed task */
- {
- if (priority == 0)
- {
- DISPLAY_TITLE;
- DISPLAY_TODO;
- }
- }
- else
- {
- if (priority < 0 || todo->id == priority)
- {
- DISPLAY_TITLE;
- DISPLAY_TODO;
- }
- }
+ LLIST_FOREACH(&todolist, i) {
+ struct todo *todo = LLIST_TS_GET_DATA(i);
+ if (regex && regexec(regex, todo->mesg, 0, 0, 0) != 0)
+ continue;
+
+ if (todo->id < 0) { /* completed task */
+ if (priority == 0) {
+ DISPLAY_TITLE;
+ print_todo(format, todo);
+ }
+ } else {
+ if (priority < 0 || todo->id == priority) {
+ DISPLAY_TITLE;
+ print_todo(format, todo);
+ }
}
+ }
#undef DISPLAY_TITLE
-#undef DISPLAY_TODO
}
/* Print the next appointment within the upcoming 24 hours. */
-static void
-next_arg (void)
+static void next_arg(void)
{
struct notify_app next_app;
- const long current_time = now ();
+ const long current_time = now();
int time_left, hours_left, min_left;
char mesg[BUFSIZ];
@@ -314,37 +244,35 @@ next_arg (void)
next_app.got_app = 0;
next_app.txt = NULL;
- next_app = *recur_apoint_check_next (&next_app, current_time, get_today ());
- next_app = *apoint_check_next (&next_app, current_time);
-
- if (next_app.got_app)
- {
- time_left = next_app.time - current_time;
- hours_left = (time_left / HOURINSEC);
- min_left = (time_left - hours_left * HOURINSEC) / MININSEC;
- fputs (_("next appointment:\n"), stdout);
- (void)snprintf (mesg, BUFSIZ, " [%02d:%02d] %s\n", hours_left, min_left,
- next_app.txt);
- fputs (mesg, stdout);
- mem_free (next_app.txt);
- }
+ next_app = *recur_apoint_check_next(&next_app, current_time, get_today());
+ next_app = *apoint_check_next(&next_app, current_time);
+
+ if (next_app.got_app) {
+ time_left = next_app.time - current_time;
+ hours_left = (time_left / HOURINSEC);
+ min_left = (time_left - hours_left * HOURINSEC) / MININSEC;
+ fputs(_("next appointment:\n"), stdout);
+ snprintf(mesg, BUFSIZ, " [%02d:%02d] %s\n", hours_left, min_left,
+ next_app.txt);
+ fputs(mesg, stdout);
+ mem_free(next_app.txt);
+ }
}
/*
* Print the date on stdout.
*/
-static void
-arg_print_date (long date, struct conf *conf)
+static void arg_print_date(long date)
{
char date_str[BUFSIZ];
time_t t;
struct tm *lt;
t = date;
- lt = localtime (&t);
- strftime (date_str, BUFSIZ, conf->output_datefmt, lt);
- fputs (date_str, stdout);
- fputs (":\n", stdout);
+ lt = localtime(&t);
+ strftime(date_str, BUFSIZ, conf.output_datefmt, lt);
+ fputs(date_str, stdout);
+ fputs(":\n", stdout);
}
/*
@@ -354,18 +282,17 @@ arg_print_date (long date, struct conf *conf)
* If regex is not null, only the matching appointments or events are printed.
*/
static int
-app_arg (int add_line, struct date *day, long date, int print_note,
- struct conf *conf, regex_t *regex)
+app_arg(int add_line, struct date *day, long date, const char *fmt_apt,
+ const char *fmt_rapt, const char *fmt_ev, const char *fmt_rev,
+ regex_t * regex)
{
llist_item_t *i, *j;
long today;
unsigned print_date = 1;
int app_found = 0;
- char apoint_start_time[HRMIN_SIZE];
- char apoint_end_time[HRMIN_SIZE];
if (date == 0)
- today = get_sec_date (*day);
+ today = get_sec_date(*day);
else
today = date;
@@ -374,159 +301,114 @@ app_arg (int add_line, struct date *day, long date, int print_note,
* that date and it is the first one, and then print all the events for
* that date.
*/
- LLIST_FIND_FOREACH (&recur_elist, today, recur_event_inday, i)
- {
- struct recur_event *re = LLIST_GET_DATA (i);
- if (regex && regexec (regex, re->mesg, 0, 0, 0) != 0)
- continue;
-
- app_found = 1;
- if (add_line)
- {
- fputs ("\n", stdout);
- add_line = 0;
- }
- if (print_date)
- {
- arg_print_date (today, conf);
- print_date = 0;
- }
- fputs (" * ", stdout);
- fputs (re->mesg, stdout);
- fputs ("\n", stdout);
- if (print_note && re->note)
- print_notefile (stdout, re->note, 2);
+ LLIST_FIND_FOREACH(&recur_elist, today, recur_event_inday, i) {
+ struct recur_event *re = LLIST_GET_DATA(i);
+ if (regex && regexec(regex, re->mesg, 0, 0, 0) != 0)
+ continue;
+
+ app_found = 1;
+ if (add_line) {
+ fputs("\n", stdout);
+ add_line = 0;
}
-
- LLIST_FIND_FOREACH (&eventlist, today, event_inday, i)
- {
- struct event *ev = LLIST_TS_GET_DATA (i);
- if (regex && regexec (regex, ev->mesg, 0, 0, 0) != 0)
- continue;
-
- app_found = 1;
- if (add_line)
- {
- fputs ("\n", stdout);
- add_line = 0;
- }
- if (print_date)
- {
- arg_print_date (today, conf);
- print_date = 0;
- }
- fputs (" * ", stdout);
- fputs (ev->mesg, stdout);
- fputs ("\n", stdout);
- if (print_note && ev->note)
- print_notefile (stdout, ev->note, 2);
+ if (print_date) {
+ arg_print_date(today);
+ print_date = 0;
+ }
+ print_recur_event(fmt_rev, today, re);
+ }
+
+ LLIST_FIND_FOREACH_CONT(&eventlist, today, event_inday, i) {
+ struct event *ev = LLIST_TS_GET_DATA(i);
+ if (regex && regexec(regex, ev->mesg, 0, 0, 0) != 0)
+ continue;
+
+ app_found = 1;
+ if (add_line) {
+ fputs("\n", stdout);
+ add_line = 0;
+ }
+ if (print_date) {
+ arg_print_date(today);
+ print_date = 0;
}
+ print_event(fmt_ev, today, ev);
+ }
/* Same process is performed but this time on the appointments. */
- LLIST_TS_LOCK (&alist_p);
- LLIST_TS_LOCK (&recur_alist_p);
+ LLIST_TS_LOCK(&alist_p);
+ LLIST_TS_LOCK(&recur_alist_p);
/*
* Iterate over regular appointments and recurrent ones simultaneously (fixes
* http://lists.calcurse.org/bugs/msg00002.html).
*/
- i = LLIST_TS_FIND_FIRST (&alist_p, today, apoint_inday);
- j = LLIST_TS_FIND_FIRST (&recur_alist_p, today, recur_apoint_inday);
- while (i || j)
- {
- struct apoint *apt = LLIST_TS_GET_DATA (i);
- struct recur_apoint *ra = LLIST_TS_GET_DATA (j);
-
- while (i && regex && regexec (regex, apt->mesg, 0, 0, 0) != 0)
- {
- i = LLIST_TS_FIND_NEXT (i, today, apoint_inday);
- apt = LLIST_TS_GET_DATA (i);
- }
+ i = LLIST_TS_FIND_FIRST(&alist_p, today, apoint_inday);
+ j = LLIST_TS_FIND_FIRST(&recur_alist_p, today, recur_apoint_inday);
+ while (i || j) {
+ struct apoint *apt = LLIST_TS_GET_DATA(i);
+ struct recur_apoint *ra = LLIST_TS_GET_DATA(j);
+ unsigned occurrence;
+
+ while (i && regex && regexec(regex, apt->mesg, 0, 0, 0) != 0) {
+ i = LLIST_TS_FIND_NEXT(i, today, apoint_inday);
+ apt = LLIST_TS_GET_DATA(i);
+ }
- while (j && regex && regexec (regex, ra->mesg, 0, 0, 0) != 0)
- {
- j = LLIST_TS_FIND_NEXT (j, today, recur_apoint_inday);
- ra = LLIST_TS_GET_DATA (j);
- }
+ while (j && regex && regexec(regex, ra->mesg, 0, 0, 0) != 0) {
+ j = LLIST_TS_FIND_NEXT(j, today, recur_apoint_inday);
+ ra = LLIST_TS_GET_DATA(j);
+ }
- if (apt && ra)
- {
- if (apt->start <= recur_apoint_inday (ra, today))
- ra = NULL;
- else
- apt = NULL;
- }
+ if (apt && ra) {
+ if (recur_apoint_find_occurrence(ra, today, &occurrence) &&
+ apt->start <= occurrence)
+ ra = NULL;
+ else
+ apt = NULL;
+ }
- if (apt)
- {
- app_found = 1;
- if (add_line)
- {
- fputs ("\n", stdout);
- add_line = 0;
- }
- if (print_date)
- {
- arg_print_date (today, conf);
- print_date = 0;
- }
- apoint_sec2str (apt, APPT, today, apoint_start_time, apoint_end_time);
- fputs (" - ", stdout);
- fputs (apoint_start_time, stdout);
- fputs (" -> ", stdout);
- fputs (apoint_end_time, stdout);
- fputs ("\n\t", stdout);
- fputs (apt->mesg, stdout);
- fputs ("\n", stdout);
- if (print_note && apt->note)
- print_notefile (stdout, apt->note, 2);
- i = LLIST_TS_FIND_NEXT (i, today, apoint_inday);
- }
- else if (ra)
- {
- app_found = 1;
- if (add_line)
- {
- fputs ("\n", stdout);
- add_line = 0;
- }
- if (print_date)
- {
- arg_print_date (today, conf);
- print_date = 0;
- }
- apt = apoint_recur_s2apoint_s (ra);
- apoint_sec2str (apt, RECUR_APPT, today, apoint_start_time,
- apoint_end_time);
- mem_free (apt->mesg);
- mem_free (apt);
- fputs (" - ", stdout);
- fputs (apoint_start_time, stdout);
- fputs (" -> ", stdout);
- fputs (apoint_end_time, stdout);
- fputs ("\n\t", stdout);
- fputs (ra->mesg, stdout);
- fputs ("\n", stdout);
- if (print_note && ra->note)
- print_notefile (stdout, ra->note, 2);
- apt = NULL;
- j = LLIST_TS_FIND_NEXT (j, today, recur_apoint_inday);
- }
+ if (apt) {
+ app_found = 1;
+ if (add_line) {
+ fputs("\n", stdout);
+ add_line = 0;
+ }
+ if (print_date) {
+ arg_print_date(today);
+ print_date = 0;
+ }
+ print_apoint(fmt_apt, today, apt);
+ i = LLIST_TS_FIND_NEXT(i, today, apoint_inday);
+ } else if (ra) {
+ app_found = 1;
+ if (add_line) {
+ fputs("\n", stdout);
+ add_line = 0;
+ }
+ if (print_date) {
+ arg_print_date(today);
+ print_date = 0;
+ }
+ recur_apoint_find_occurrence(ra, today, &occurrence);
+ print_recur_apoint(fmt_rapt, today, occurrence, ra);
+ apt = NULL;
+ j = LLIST_TS_FIND_NEXT(j, today, recur_apoint_inday);
}
+ }
- LLIST_TS_UNLOCK (&recur_alist_p);
- LLIST_TS_UNLOCK (&alist_p);
+ LLIST_TS_UNLOCK(&recur_alist_p);
+ LLIST_TS_UNLOCK(&alist_p);
- return (app_found);
+ return app_found;
}
-static void
-more_info (void)
+static void more_info(void)
{
- fputs (_("\nFor more information, type '?' from within Calcurse, "
- "or read the manpage.\n"), stdout);
- fputs (_("Mail bug reports and suggestions to "
- "<misc@calcurse.org>.\n"), stdout);
+ fputs(_("\nFor more information, type '?' from within Calcurse, "
+ "or read the manpage.\n"), stdout);
+ fputs(_("Mail bug reports and suggestions to "
+ "<misc@calcurse.org>.\n"), stdout);
}
/*
@@ -535,23 +417,24 @@ more_info (void)
* to format the output correctly.
*/
static void
-display_app (struct tm *t, int numdays, int add_line, int print_note,
- struct conf *conf, regex_t *regex)
+display_app(struct tm *t, int numdays, int add_line, const char *fmt_apt,
+ const char *fmt_rapt, const char *fmt_ev, const char *fmt_rev,
+ regex_t * regex)
{
int i, app_found;
struct date day;
- for (i = 0; i < numdays; i++)
- {
- day.dd = t->tm_mday;
- day.mm = t->tm_mon + 1;
- day.yyyy = t->tm_year + 1900;
- app_found = app_arg (add_line, &day, 0, print_note, conf, regex);
- if (app_found)
- add_line = 1;
- t->tm_mday++;
- (void)mktime (t);
- }
+ for (i = 0; i < numdays; i++) {
+ day.dd = t->tm_mday;
+ day.mm = t->tm_mon + 1;
+ day.yyyy = t->tm_year + 1900;
+ app_found = app_arg(add_line, &day, 0, fmt_apt, fmt_rapt, fmt_ev,
+ fmt_rev, regex);
+ if (app_found)
+ add_line = 1;
+ t->tm_mday++;
+ mktime(t);
+ }
}
/*
@@ -559,8 +442,9 @@ display_app (struct tm *t, int numdays, int add_line, int print_note,
* days.
*/
static void
-date_arg (char *ddate, int add_line, int print_note, struct conf *conf,
- regex_t *regex)
+date_arg(const char *ddate, int add_line, const char *fmt_apt,
+ const char *fmt_rapt, const char *fmt_ev, const char *fmt_rev,
+ regex_t * regex)
{
int i;
struct date day;
@@ -573,44 +457,38 @@ date_arg (char *ddate, int add_line, int print_note, struct conf *conf,
* Check (with the argument length) if a date or a number of days
* was entered, and then call app_arg() to print appointments
*/
- arg_len = strlen (ddate);
- if (arg_len <= 4)
- { /* a number of days was entered */
- for (i = 0; i <= arg_len - 1; i++)
- {
- if (isdigit (ddate[i]))
- num_digit++;
- }
- if (num_digit == arg_len)
- numdays = atoi (ddate);
-
- /*
- * Get current date, and print appointments for each day
- * in the chosen interval. app_found and add_line are used
- * to format the output correctly.
- */
- timer = time (NULL);
- t = *localtime (&timer);
- display_app (&t, numdays, add_line, print_note, conf, regex);
+ arg_len = strlen(ddate);
+ if (arg_len <= 4) { /* a number of days was entered */
+ for (i = 0; i <= arg_len - 1; i++) {
+ if (isdigit(ddate[i]))
+ num_digit++;
}
- else
- { /* a date was entered */
- if (parse_date (ddate, conf->input_datefmt, (int *)&day.yyyy,
- (int *)&day.mm, (int *)&day.dd, NULL))
- {
- (void)app_arg (add_line, &day, 0, print_note, conf, regex);
- }
- else
- {
- char outstr[BUFSIZ];
- fputs (_("Argument to the '-d' flag is not valid\n"), stderr);
- (void)snprintf (outstr, BUFSIZ,
- "Possible argument format are: '%s' or 'n'\n",
- DATEFMT_DESC (conf->input_datefmt));
- fputs (_(outstr), stdout);
- more_info ();
- }
+ if (num_digit == arg_len)
+ numdays = atoi(ddate);
+
+ /*
+ * Get current date, and print appointments for each day
+ * in the chosen interval. app_found and add_line are used
+ * to format the output correctly.
+ */
+ timer = time(NULL);
+ t = *localtime(&timer);
+ display_app(&t, numdays, add_line, fmt_apt, fmt_rapt, fmt_ev, fmt_rev,
+ regex);
+ } else { /* a date was entered */
+ if (parse_date(ddate, conf.input_datefmt, (int *)&day.yyyy,
+ (int *)&day.mm, (int *)&day.dd, NULL)) {
+ app_arg(add_line, &day, 0, fmt_apt, fmt_rapt, fmt_ev, fmt_rev, regex);
+ } else {
+ char outstr[BUFSIZ];
+ fputs(_("Argument to the '-d' flag is not valid\n"), stderr);
+ snprintf(outstr, BUFSIZ,
+ "Possible argument format are: '%s' or 'n'\n",
+ DATEFMT_DESC(conf.input_datefmt));
+ fputs(_(outstr), stdout);
+ more_info();
}
+ }
}
/*
@@ -622,8 +500,9 @@ date_arg (char *ddate, int add_line, int print_note, struct conf *conf,
* Many thanks to Erik Saule for providing this function.
*/
static void
-date_arg_extended (char *startday, char *range, int add_line, int print_note,
- struct conf *conf, regex_t *regex)
+date_arg_extended(const char *startday, const char *range, int add_line,
+ const char *fmt_apt, const char *fmt_rapt,
+ const char *fmt_ev, const char *fmt_rev, regex_t * regex)
{
int i, numdays = 1, error = 0, arg_len = 0;
static struct tm t;
@@ -632,95 +511,91 @@ date_arg_extended (char *startday, char *range, int add_line, int print_note,
/*
* Check arguments and extract information
*/
- if (range != NULL)
- {
- arg_len = strlen (range);
- for (i = 0; i <= arg_len - 1; i++)
- {
- if (!isdigit (range[i]))
- error = 1;
- }
- if (!error)
- numdays = atoi (range);
+ if (range != NULL) {
+ arg_len = strlen(range);
+ for (i = 0; i <= arg_len - 1; i++) {
+ if (!isdigit(range[i]))
+ error = 1;
}
- timer = time (NULL);
- t = *localtime (&timer);
- if (startday != NULL)
- {
- if (parse_date (startday, conf->input_datefmt, (int *)&t.tm_year,
- (int *)&t.tm_mon, (int *)&t.tm_mday, NULL))
- {
- t.tm_year -= 1900;
- t.tm_mon--;
- (void)mktime (&t);
- }
- else
- {
- error = 1;
- }
- }
- if (!error)
- {
- display_app (&t, numdays, add_line, print_note, conf, regex);
- }
- else
- {
- char outstr[BUFSIZ];
- fputs (_("Argument is not valid\n"), stderr);
- (void)snprintf (outstr, BUFSIZ,
- "Argument format for -s and --startday is: '%s'\n",
- DATEFMT_DESC (conf->input_datefmt));
- fputs (_(outstr), stdout);
- fputs (_("Argument format for -r and --range is: 'n'\n"), stdout);
- more_info ();
+ if (!error)
+ numdays = atoi(range);
+ }
+ timer = time(NULL);
+ t = *localtime(&timer);
+ if (startday != NULL) {
+ if (parse_date(startday, conf.input_datefmt, (int *)&t.tm_year,
+ (int *)&t.tm_mon, (int *)&t.tm_mday, NULL)) {
+ t.tm_year -= 1900;
+ t.tm_mon--;
+ mktime(&t);
+ } else {
+ error = 1;
}
+ }
+ if (!error) {
+ display_app(&t, numdays, add_line, fmt_apt, fmt_rapt, fmt_ev, fmt_rev,
+ regex);
+ } else {
+ char outstr[BUFSIZ];
+ fputs(_("Argument is not valid\n"), stderr);
+ snprintf(outstr, BUFSIZ,
+ "Argument format for -s and --startday is: '%s'\n",
+ DATEFMT_DESC(conf.input_datefmt));
+ fputs(_(outstr), stdout);
+ fputs(_("Argument format for -r and --range is: 'n'\n"), stdout);
+ more_info();
+ }
}
-
/*
* Parse the command-line arguments and call the appropriate
* routines to handle those arguments. Also initialize the data paths.
*/
-int
-parse_args (int argc, char **argv, struct conf *conf)
+int parse_args(int argc, char **argv)
{
int ch, add_line = 0;
int unknown_flag = 0;
/* Command-line flags */
- int aflag = 0; /* -a: print appointments for current day */
- int cflag = 0; /* -c: specify the calendar file to use */
- int dflag = 0; /* -d: print appointments for a specified days */
- int Dflag = 0; /* -D: specify data directory to use */
- int hflag = 0; /* -h: print help text */
- int iflag = 0; /* -i: import data */
- int nflag = 0; /* -n: print next appointment */
- int Nflag = 0; /* -N: also print note content with apps and todos */
- int rflag = 0; /* -r: specify the range of days to consider */
- int sflag = 0; /* -s: specify the first day to consider */
- int Sflag = 0; /* -S: specify a regex to search for */
- int tflag = 0; /* -t: print todo list */
- int vflag = 0; /* -v: print version number */
- int xflag = 0; /* -x: export data */
+ int aflag = 0; /* -a: print appointments for current day */
+ int cflag = 0; /* -c: specify the calendar file to use */
+ int dflag = 0; /* -d: print appointments for a specified days */
+ int Dflag = 0; /* -D: specify data directory to use */
+ int hflag = 0; /* -h: print help text */
+ int gflag = 0; /* -g: run garbage collector */
+ int iflag = 0; /* -i: import data */
+ int nflag = 0; /* -n: print next appointment */
+ int rflag = 0; /* -r: specify the range of days to consider */
+ int sflag = 0; /* -s: specify the first day to consider */
+ int Sflag = 0; /* -S: specify a regex to search for */
+ int tflag = 0; /* -t: print todo list */
+ int vflag = 0; /* -v: print version number */
+ int xflag = 0; /* -x: export data */
+ /* Format strings */
+ const char *fmt_apt = " - %S -> %E\n\t%m\n";
+ const char *fmt_rapt = " - %S -> %E\n\t%m\n";
+ const char *fmt_ev = " * %m\n";
+ const char *fmt_rev = " * %m\n";
+ const char *fmt_todo = "%p. %m\n";
int tnum = 0, xfmt = 0, non_interactive = 0, multiple_flag = 0, load_data = 0;
- char *ddate = "", *cfile = NULL, *range = NULL, *startday = NULL;
- char *datadir = NULL, *ifile = NULL;
+ const char *ddate = "", *cfile = NULL, *range = NULL, *startday = NULL;
+ const char *datadir = NULL, *ifile = NULL;
regex_t reg, *preg = NULL;
/* Long options only */
- int statusflag = 0; /* --status: get the status of running instances */
- enum
- {
+ int statusflag = 0; /* --status: get the status of running instances */
+ enum {
STATUS_OPT = CHAR_MAX + 1
};
- static char *optstr = "hvnNax::t::d:c:r::s::S:D:i:";
+ static const char *optstr = "ghvnNax::t::d:c:r::s::S:D:i:";
struct option longopts[] = {
{"appointment", no_argument, NULL, 'a'},
{"calendar", required_argument, NULL, 'c'},
{"day", required_argument, NULL, 'd'},
{"directory", required_argument, NULL, 'D'},
+ {"gc", no_argument, NULL, 'g'},
{"help", no_argument, NULL, 'h'},
{"import", required_argument, NULL, 'i'},
{"next", no_argument, NULL, 'n'},
@@ -732,255 +607,253 @@ parse_args (int argc, char **argv, struct conf *conf)
{"todo", optional_argument, NULL, 't'},
{"version", no_argument, NULL, 'v'},
{"export", optional_argument, NULL, 'x'},
+
+ {"format-apt", required_argument, NULL, OPT_FMT_APT},
+ {"format-recur-apt", required_argument, NULL, OPT_FMT_RAPT},
+ {"format-event", required_argument, NULL, OPT_FMT_EV},
+ {"format-recur-event", required_argument, NULL, OPT_FMT_REV},
+ {"format-todo", required_argument, NULL, OPT_FMT_TODO},
+ {"read-only", no_argument, NULL, OPT_READ_ONLY},
{NULL, no_argument, NULL, 0}
};
- while ((ch = getopt_long (argc, argv, optstr, longopts, NULL)) != -1)
- {
- switch (ch)
- {
- case STATUS_OPT:
- statusflag = 1;
- break;
- case 'a':
- aflag = 1;
- multiple_flag++;
- load_data++;
- break;
- case 'c':
- cflag = 1;
- multiple_flag++;
- cfile = optarg;
- load_data++;
- break;
- case 'd':
- dflag = 1;
- multiple_flag++;
- load_data++;
- ddate = optarg;
- break;
- case 'D':
- Dflag = 1;
- datadir = optarg;
- break;
- case 'h':
- hflag = 1;
- break;
- case 'i':
- iflag = 1;
- multiple_flag++;
- load_data++;
- ifile = optarg;
- break;
- case 'n':
- nflag = 1;
- multiple_flag++;
- load_data++;
- break;
- case 'N':
- Nflag = 1;
- break;
- case 'r':
- rflag = 1;
- multiple_flag++;
- load_data++;
- range = optarg;
- break;
- case 's':
- sflag = 1;
- multiple_flag++;
- load_data++;
- startday = optarg;
- break;
- case 'S':
- EXIT_IF (Sflag > 0,
- _("Can not handle more than one regular expression."));
- Sflag = 1;
- if (regcomp (&reg, optarg, REG_EXTENDED))
- EXIT (_("Could not compile regular expression."));
- preg = &reg;
- break;
- case 't':
- tflag = 1;
- multiple_flag++;
- load_data++;
- add_line = 1;
- if (optarg != NULL)
- {
- tnum = atoi (optarg);
- if (tnum < 0 || tnum > 9)
- {
- usage ();
- usage_try ();
- return (EXIT_FAILURE);
- }
- }
- else
- tnum = -1;
- break;
- case 'v':
- vflag = 1;
- break;
- case 'x':
- xflag = 1;
- multiple_flag++;
- load_data++;
- if (optarg != NULL)
- {
- if (strcmp (optarg, "ical") == 0)
- xfmt = IO_EXPORT_ICAL;
- else if (strcmp (optarg, "pcal") == 0)
- xfmt = IO_EXPORT_PCAL;
- else
- {
- fputs (_("Argument for '-x' should be either "
- "'ical' or 'pcal'\n"), stderr);
- usage ();
- usage_try ();
- return EXIT_FAILURE;
- }
- }
- else
- {
- xfmt = IO_EXPORT_ICAL;
- }
- break;
- default:
- usage ();
- usage_try ();
- unknown_flag = 1;
- non_interactive = 1;
- /* NOTREACHED */
+ while ((ch = getopt_long(argc, argv, optstr, longopts, NULL)) != -1) {
+ switch (ch) {
+ case STATUS_OPT:
+ statusflag = 1;
+ break;
+ case 'a':
+ aflag = 1;
+ multiple_flag++;
+ load_data++;
+ break;
+ case 'c':
+ cflag = 1;
+ multiple_flag++;
+ cfile = optarg;
+ load_data++;
+ break;
+ case 'd':
+ dflag = 1;
+ multiple_flag++;
+ load_data++;
+ ddate = optarg;
+ break;
+ case 'D':
+ Dflag = 1;
+ datadir = optarg;
+ break;
+ case 'h':
+ hflag = 1;
+ break;
+ case 'g':
+ gflag = 1;
+ break;
+ case 'i':
+ iflag = 1;
+ multiple_flag++;
+ load_data++;
+ ifile = optarg;
+ break;
+ case 'n':
+ nflag = 1;
+ multiple_flag++;
+ load_data++;
+ break;
+ case 'r':
+ rflag = 1;
+ multiple_flag++;
+ load_data++;
+ range = optarg;
+ break;
+ case 's':
+ sflag = 1;
+ multiple_flag++;
+ load_data++;
+ startday = optarg;
+ break;
+ case 'S':
+ EXIT_IF(Sflag > 0, _("Can not handle more than one regular expression."));
+ Sflag = 1;
+ if (regcomp(&reg, optarg, REG_EXTENDED))
+ EXIT(_("Could not compile regular expression."));
+ preg = &reg;
+ break;
+ case 't':
+ tflag = 1;
+ multiple_flag++;
+ load_data++;
+ add_line = 1;
+ if (optarg != NULL) {
+ tnum = atoi(optarg);
+ if (tnum < 0 || tnum > 9) {
+ usage();
+ usage_try();
+ return EXIT_FAILURE;
}
+ } else
+ tnum = -1;
+ break;
+ case 'v':
+ vflag = 1;
+ break;
+ case 'x':
+ xflag = 1;
+ multiple_flag++;
+ load_data++;
+ if (optarg != NULL) {
+ if (strcmp(optarg, "ical") == 0)
+ xfmt = IO_EXPORT_ICAL;
+ else if (strcmp(optarg, "pcal") == 0)
+ xfmt = IO_EXPORT_PCAL;
+ else {
+ fputs(_("Argument for '-x' should be either "
+ "'ical' or 'pcal'\n"), stderr);
+ usage();
+ usage_try();
+ return EXIT_FAILURE;
+ }
+ } else {
+ xfmt = IO_EXPORT_ICAL;
+ }
+ break;
+ case OPT_FMT_APT:
+ fmt_apt = optarg;
+ break;
+ case OPT_FMT_RAPT:
+ fmt_rapt = optarg;
+ break;
+ case OPT_FMT_EV:
+ fmt_ev = optarg;
+ break;
+ case OPT_FMT_REV:
+ fmt_rev = optarg;
+ break;
+ case OPT_FMT_TODO:
+ fmt_todo = optarg;
+ break;
+ case OPT_READ_ONLY:
+ read_only = 1;
+ break;
+ default:
+ usage();
+ usage_try();
+ unknown_flag = 1;
+ non_interactive = 1;
+ /* NOTREACHED */
}
+ }
argc -= optind;
- if (argc >= 1)
- {
- usage ();
- usage_try ();
- return EXIT_FAILURE;
- /* Incorrect arguments */
- }
- else if (Dflag && cflag)
- {
- fputs (_("Options '-D' and '-c' cannot be used at the same time\n"),
- stderr);
- usage ();
- usage_try ();
- return EXIT_FAILURE;
- }
- else if (Sflag && !(aflag || dflag || rflag || sflag || tflag))
- {
- fputs (_("Option '-S' must be used with either '-d', '-r', '-s', "
- "'-a' or '-t'\n"), stderr);
- usage ();
- usage_try ();
- return EXIT_FAILURE;
- }
- else
- {
- if (unknown_flag)
- {
- non_interactive = 1;
- }
- else if (hflag)
- {
- help_arg ();
- non_interactive = 1;
- }
- else if (vflag)
- {
- version_arg ();
- non_interactive = 1;
- }
- else if (statusflag)
- {
- io_init (cfile, datadir);
- status_arg ();
- non_interactive = 1;
- }
- else if (multiple_flag)
- {
- if (load_data)
- {
- io_init (cfile, datadir);
- io_check_dir (path_dir, (int *)0);
- io_check_dir (path_notes, (int *)0);
- }
- if (iflag)
- {
- io_check_file (path_apts, (int *)0);
- io_check_file (path_todo, (int *)0);
- /* Get default pager in case we need to show a log file. */
- vars_init (conf);
- io_load_app ();
- io_load_todo ();
- io_import_data (IO_IMPORT_ICAL, conf, ifile);
- io_save_apts ();
- io_save_todo ();
- non_interactive = 1;
- }
- if (xflag)
- {
- io_check_file (path_apts, (int *)0);
- io_check_file (path_todo, (int *)0);
- io_load_app ();
- io_load_todo ();
- io_export_data (xfmt, conf);
- non_interactive = 1;
- return non_interactive;
- }
- if (tflag)
- {
- io_check_file (path_todo, (int *)0);
- io_load_todo ();
- todo_arg (tnum, Nflag, preg);
- non_interactive = 1;
- }
- if (nflag)
- {
- io_check_file (path_apts, (int *)0);
- io_load_app ();
- next_arg ();
- non_interactive = 1;
- }
- if (dflag || rflag || sflag)
- {
- io_check_file (path_apts, (int *)0);
- io_check_file (path_conf, (int *)0);
- io_load_app ();
- custom_load_conf (conf, 0); /* To get output date format. */
- if (dflag)
- date_arg (ddate, add_line, Nflag, conf, preg);
- if (rflag || sflag)
- date_arg_extended (startday, range, add_line, Nflag, conf,
- preg);
- non_interactive = 1;
- }
- else if (aflag)
- {
- struct date day;
-
- io_check_file (path_apts, (int *)0);
- io_check_file (path_conf, (int *)0);
- vars_init (conf);
- custom_load_conf (conf, 0); /* To get output date format. */
- io_load_app ();
- day.dd = day.mm = day.yyyy = 0;
- (void)app_arg (add_line, &day, 0, Nflag, conf, preg);
- non_interactive = 1;
- }
- }
- else
- {
- non_interactive = 0;
- io_init (cfile, datadir);
- }
+ if (argc >= 1) {
+ usage();
+ usage_try();
+ return EXIT_FAILURE;
+ /* Incorrect arguments */
+ } else if (Dflag && cflag) {
+ fputs(_("Options '-D' and '-c' cannot be used at the same time\n"), stderr);
+ usage();
+ usage_try();
+ return EXIT_FAILURE;
+ } else if (Sflag && !(aflag || dflag || rflag || sflag || tflag)) {
+ fputs(_("Option '-S' must be used with either '-d', '-r', '-s', "
+ "'-a' or '-t'\n"), stderr);
+ usage();
+ usage_try();
+ return EXIT_FAILURE;
+ } else {
+ if (unknown_flag) {
+ non_interactive = 1;
+ } else if (hflag) {
+ help_arg();
+ non_interactive = 1;
+ } else if (vflag) {
+ version_arg();
+ non_interactive = 1;
+ } else if (statusflag) {
+ io_init(cfile, datadir);
+ status_arg();
+ non_interactive = 1;
+ } else if (gflag) {
+ io_init(cfile, datadir);
+ io_check_dir(path_dir, NULL);
+ io_check_dir(path_notes, NULL);
+ io_check_file(path_apts, NULL);
+ io_check_file(path_todo, NULL);
+ io_load_app();
+ io_load_todo();
+ note_gc();
+ non_interactive = 1;
+ } else if (multiple_flag) {
+ if (load_data) {
+ io_init(cfile, datadir);
+ io_check_dir(path_dir, NULL);
+ io_check_dir(path_notes, NULL);
+ }
+ if (iflag) {
+ io_check_file(path_apts, NULL);
+ io_check_file(path_todo, NULL);
+ /* Get default pager in case we need to show a log file. */
+ vars_init();
+ io_load_app();
+ io_load_todo();
+ io_import_data(IO_IMPORT_ICAL, ifile);
+ io_save_apts();
+ io_save_todo();
+ non_interactive = 1;
+ }
+ if (xflag) {
+ io_check_file(path_apts, NULL);
+ io_check_file(path_todo, NULL);
+ io_load_app();
+ io_load_todo();
+ io_export_data(xfmt);
+ non_interactive = 1;
+ return non_interactive;
+ }
+ if (tflag) {
+ io_check_file(path_todo, NULL);
+ io_load_todo();
+ todo_arg(tnum, fmt_todo, preg);
+ non_interactive = 1;
+ }
+ if (nflag) {
+ io_check_file(path_apts, NULL);
+ io_load_app();
+ next_arg();
+ non_interactive = 1;
+ }
+ if (dflag || rflag || sflag) {
+ io_check_file(path_apts, NULL);
+ io_check_file(path_conf, NULL);
+ io_load_app();
+ config_load(); /* To get output date format. */
+ if (dflag)
+ date_arg(ddate, add_line, fmt_apt, fmt_rapt, fmt_ev, fmt_rev, preg);
+ if (rflag || sflag)
+ date_arg_extended(startday, range, add_line, fmt_apt,
+ fmt_rapt, fmt_ev, fmt_rev, preg);
+ non_interactive = 1;
+ } else if (aflag) {
+ struct date day;
+
+ io_check_file(path_apts, NULL);
+ io_check_file(path_conf, NULL);
+ vars_init();
+ config_load(); /* To get output date format. */
+ io_load_app();
+ day.dd = day.mm = day.yyyy = 0;
+ app_arg(add_line, &day, 0, fmt_apt, fmt_rapt, fmt_ev, fmt_rev, preg);
+ non_interactive = 1;
+ }
+ } else {
+ non_interactive = 0;
+ io_init(cfile, datadir);
}
+ }
if (preg)
- regfree (preg);
+ regfree(preg);
return non_interactive;
}
diff --git a/src/calcurse.c b/src/calcurse.c
index 662f185..9e42eee 100644
--- a/src/calcurse.c
+++ b/src/calcurse.c
@@ -1,7 +1,7 @@
/*
* Calcurse - text-based organizer
*
- * Copyright (c) 2004-2011 calcurse Development Team <misc@calcurse.org>
+ * Copyright (c) 2004-2012 calcurse Development Team <misc@calcurse.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -39,541 +39,484 @@
#include "calcurse.h"
/*
+ * Store the events and appointments for the selected day and reset the
+ * appointment highlight pointer if a new day was selected.
+ */
+static struct day_items_nb do_storage(int day_changed)
+{
+ struct day_items_nb inday = *day_process_storage(calendar_get_slctd_day(),
+ day_changed, &inday);
+
+ if (day_changed)
+ apoint_hilt_set(1);
+
+ return inday;
+}
+
+/*
* Calcurse is a text-based personal organizer which helps keeping track
* of events and everyday tasks. It contains a calendar, a 'todo' list,
* and puts your appointments in order. The user interface is configurable,
* and one can choose between different color schemes and layouts.
* All of the commands are documented within an online help system.
*/
-int
-main (int argc, char **argv)
+int main(int argc, char **argv)
{
- struct conf conf;
struct day_items_nb inday;
- int background, foreground;
- int non_interactive;
int no_data_file = 1;
- int sav_hilt_app = 0;
- int sav_hilt_tod = 0;
int cut_item = 0;
- unsigned do_storage = 0;
- unsigned do_update = 1;
- unsigned day_changed = 0;
- char *no_color_support =
- _("Sorry, colors are not supported by your terminal\n"
- "(Press [ENTER] to continue)");
- char *quit_message = _("Do you really want to quit ?");
- char choices[] = "[y/n] ";
+ int count;
#if ENABLE_NLS
- setlocale (LC_ALL, "");
- bindtextdomain (PACKAGE, LOCALEDIR);
- textdomain (PACKAGE);
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
#endif /* ENABLE_NLS */
/* Thread-safe data structure init */
- apoint_llist_init ();
- recur_apoint_llist_init ();
+ apoint_llist_init();
+ recur_apoint_llist_init();
/* Initialize non-thread-safe data structures. */
- event_llist_init ();
- todo_init_list ();
+ event_llist_init();
+ todo_init_list();
/*
* Begin by parsing and handling command line arguments.
* The data path is also initialized here.
*/
- non_interactive = parse_args (argc, argv, &conf);
- if (non_interactive)
- exit_calcurse (EXIT_SUCCESS);
- else
- {
- no_data_file = io_check_data_files ();
- dmon_stop ();
- io_set_lock ();
- }
+ if (parse_args(argc, argv)) {
+ /* Non-interactive mode. */
+ exit_calcurse(EXIT_SUCCESS);
+ } else {
+ no_data_file = io_check_data_files();
+ dmon_stop();
+ io_set_lock();
+ }
/* Begin of interactive mode with ncurses interface. */
- sigs_init (); /* signal handling init */
- initscr (); /* start the curses mode */
- cbreak (); /* control chars generate a signal */
- noecho (); /* controls echoing of typed chars */
- curs_set (0); /* make cursor invisible */
- calendar_set_current_date ();
- notify_init_vars ();
- wins_get_config ();
+ sigs_init(); /* signal handling init */
+ initscr(); /* start the curses mode */
+ cbreak(); /* control chars generate a signal */
+ noecho(); /* controls echoing of typed chars */
+ curs_set(0); /* make cursor invisible */
+ calendar_set_current_date();
+ notify_init_vars();
+ wins_get_config();
/* Check if terminal supports color. */
- if (has_colors ())
- {
- colorize = 1;
- background = COLOR_BLACK;
- foreground = COLOR_WHITE;
- start_color ();
+ if (has_colors()) {
+ colorize = 1;
+ background = COLOR_BLACK;
+ foreground = COLOR_WHITE;
+ start_color();
#ifdef NCURSES_VERSION
- if (use_default_colors () != ERR)
- {
- background = -1;
- foreground = -1;
- }
-#endif /* NCURSES_VERSION */
-
- /* Color assignment */
- init_pair (COLR_RED, COLOR_RED, background);
- init_pair (COLR_GREEN, COLOR_GREEN, background);
- init_pair (COLR_YELLOW, COLOR_YELLOW, background);
- init_pair (COLR_BLUE, COLOR_BLUE, background);
- init_pair (COLR_MAGENTA, COLOR_MAGENTA, background);
- init_pair (COLR_CYAN, COLOR_CYAN, background);
- init_pair (COLR_DEFAULT, foreground, background);
- init_pair (COLR_HIGH, COLOR_BLACK, COLOR_GREEN);
- init_pair (COLR_CUSTOM, COLOR_RED, background);
-
- }
- else
- {
- colorize = 0;
- background = COLOR_BLACK;
+ if (use_default_colors() != ERR) {
+ background = -1;
+ foreground = -1;
}
+#endif /* NCURSES_VERSION */
- vars_init (&conf);
- wins_init ();
- wins_slctd_init ();
- notify_init_bar ();
- wins_reset_status_page ();
+ /* Color assignment */
+ init_pair(COLR_RED, COLOR_RED, background);
+ init_pair(COLR_GREEN, COLOR_GREEN, background);
+ init_pair(COLR_YELLOW, COLOR_YELLOW, background);
+ init_pair(COLR_BLUE, COLOR_BLUE, background);
+ init_pair(COLR_MAGENTA, COLOR_MAGENTA, background);
+ init_pair(COLR_CYAN, COLOR_CYAN, background);
+ init_pair(COLR_DEFAULT, foreground, background);
+ init_pair(COLR_HIGH, COLOR_BLACK, COLOR_GREEN);
+ init_pair(COLR_CUSTOM, COLOR_RED, background);
+ } else {
+ colorize = 0;
+ background = COLOR_BLACK;
+ }
+
+ vars_init();
+ wins_init();
+ wins_slctd_init();
+ notify_init_bar();
+ wins_reset_status_page();
/*
* Read the data from files : first the user
* configuration (the display is then updated), and then
* the todo list, appointments and events.
*/
- custom_load_conf (&conf, background);
- wins_erase_status_bar ();
- io_load_keys (conf.pager);
- io_load_todo ();
- io_load_app ();
- wins_reinit ();
- if (notify_bar ())
- notify_start_main_thread ();
- wins_update ();
- io_startup_screen (conf.skip_system_dialogs, no_data_file);
- inday = *day_process_storage (0, day_changed, &inday);
- wins_slctd_set (CAL);
- wins_update ();
- calendar_start_date_thread ();
+ config_load();
+ wins_erase_status_bar();
+ io_load_keys(conf.pager);
+ io_load_todo();
+ io_load_app();
+ wins_reinit();
+ if (conf.system_dialogs) {
+ wins_update(FLAG_ALL);
+ io_startup_screen(no_data_file);
+ }
+ inday = *day_process_storage(0, 0, &inday);
+ wins_slctd_set(CAL);
+ wins_update(FLAG_ALL);
+
+ /* Start miscellaneous threads. */
+ if (notify_bar())
+ notify_start_main_thread();
+ calendar_start_date_thread();
if (conf.periodic_save > 0)
- io_start_psave_thread (&conf);
+ io_start_psave_thread();
/* User input */
- for (;;)
- {
- int key;
-
- do_update = 1;
- key = keys_getch (win[STA].p);
- switch (key)
- {
- case ERR:
- do_update = 0;
- break;
-
- case KEY_GENERIC_REDRAW:
- resize = 1;
- break;
-
- case KEY_GENERIC_CHANGE_VIEW:
- wins_reset_status_page ();
- /* Need to save the previously highlighted event. */
- switch (wins_slctd ())
- {
- case TOD:
- sav_hilt_tod = todo_hilt ();
- todo_hilt_set (0);
- break;
- case APP:
- sav_hilt_app = apoint_hilt ();
- apoint_hilt_set (0);
- break;
- default:
- break;
- }
- wins_slctd_next ();
-
- /* Select the event to highlight. */
- switch (wins_slctd ())
- {
- case TOD:
- if ((sav_hilt_tod == 0) && (todo_nb () != 0))
- todo_hilt_set (1);
- else
- todo_hilt_set (sav_hilt_tod);
- break;
- case APP:
- if ((sav_hilt_app == 0)
- && ((inday.nb_events + inday.nb_apoints) != 0))
- apoint_hilt_set (1);
- else
- apoint_hilt_set (sav_hilt_app);
- break;
- default:
- break;
- }
- break;
-
- case KEY_GENERIC_OTHER_CMD:
- wins_other_status_page (wins_slctd ());
- break;
-
- case KEY_GENERIC_GOTO:
- case KEY_GENERIC_GOTO_TODAY:
- wins_erase_status_bar ();
- calendar_set_current_date ();
- if (key == KEY_GENERIC_GOTO_TODAY)
- calendar_goto_today ();
- else
- calendar_change_day (conf.input_datefmt);
- do_storage = 1;
- day_changed = 1;
- break;
-
- case KEY_VIEW_ITEM:
- if ((wins_slctd () == APP) && (apoint_hilt () != 0))
- day_popup_item ();
- else if ((wins_slctd () == TOD) && (todo_hilt () != 0))
- item_in_popup (NULL, NULL, todo_saved_mesg (), _("To do :"));
- break;
-
- case KEY_GENERIC_CONFIG_MENU:
- wins_erase_status_bar ();
- custom_config_bar ();
- while ((key = wgetch (win[STA].p)) != 'q')
- {
- switch (key)
- {
- case 'C':
- case 'c':
- if (has_colors ())
- custom_color_config ();
- else
- {
- colorize = 0;
- wins_erase_status_bar ();
- mvwprintw (win[STA].p, 0, 0, _(no_color_support));
- wgetch (win[STA].p);
- }
- break;
- case 'L':
- case 'l':
- custom_layout_config ();
- break;
- case 'G':
- case 'g':
- custom_general_config (&conf);
- break;
- case 'N':
- case 'n':
- notify_config_bar ();
- break;
- case 'K':
- case 'k':
- custom_keys_config ();
- break;
- case 's':
- case 'S':
- custom_sidebar_config ();
- break;
- }
- wins_reset ();
- wins_update ();
- do_storage = 1;
- wins_erase_status_bar ();
- custom_config_bar ();
- }
- wins_update ();
- break;
-
- case KEY_GENERIC_ADD_APPT:
- apoint_add ();
- do_storage = 1;
- break;
-
- case KEY_GENERIC_ADD_TODO:
- todo_new_item ();
- if (todo_hilt () == 0 && todo_nb () == 1)
- todo_hilt_increase ();
- break;
-
- case KEY_ADD_ITEM:
- switch (wins_slctd ())
- {
- case APP:
- apoint_add ();
- do_storage = 1;
- break;
- case TOD:
- todo_new_item ();
- if (todo_hilt () == 0 && todo_nb () == 1)
- todo_hilt_increase ();
- break;
- default:
- break;
- }
- break;
-
- case KEY_EDIT_ITEM:
- if (wins_slctd () == APP && apoint_hilt () != 0)
- day_edit_item (&conf);
- else if (wins_slctd () == TOD && todo_hilt () != 0)
- todo_edit_item ();
- do_storage = 1;
- break;
-
- case KEY_DEL_ITEM:
- if (wins_slctd () == APP && apoint_hilt () != 0)
- apoint_delete (&conf, &inday.nb_events, &inday.nb_apoints);
- else if (wins_slctd () == TOD && todo_hilt () != 0)
- todo_delete (&conf);
- do_storage = 1;
- break;
-
- case KEY_GENERIC_CUT:
- if (wins_slctd () == APP && apoint_hilt () != 0)
- {
- cut_item = apoint_cut (&inday.nb_events, &inday.nb_apoints);
- do_storage = 1;
- }
- break;
-
- case KEY_GENERIC_PASTE:
- if (wins_slctd () == APP)
- {
- apoint_paste (&inday.nb_events, &inday.nb_apoints, cut_item);
- cut_item = 0;
- do_storage = 1;
- }
- break;
+ for (;;) {
+ int key;
- case KEY_REPEAT_ITEM:
- if (wins_slctd () == APP && apoint_hilt () != 0)
- recur_repeat_item (&conf);
- do_storage = 1;
- break;
-
- case KEY_FLAG_ITEM:
- if (wins_slctd () == APP && apoint_hilt () != 0)
- apoint_switch_notify ();
- else if (wins_slctd () == TOD && todo_hilt () != 0)
- todo_flag ();
- do_storage = 1;
- break;
-
- case KEY_RAISE_PRIORITY:
- case KEY_LOWER_PRIORITY:
- if (wins_slctd () == TOD && todo_hilt () != 0)
- {
- todo_chg_priority (key);
- if (todo_hilt_pos () < 0)
- todo_set_first (todo_hilt ());
- else if (todo_hilt_pos () >= win[TOD].h - 4)
- todo_set_first (todo_hilt () - win[TOD].h + 5);
- }
- break;
-
- case KEY_EDIT_NOTE:
- if (wins_slctd () == APP && apoint_hilt () != 0)
- day_edit_note (conf.editor);
- else if (wins_slctd () == TOD && todo_hilt () != 0)
- todo_edit_note (conf.editor);
- do_storage = 1;
- break;
-
- case KEY_VIEW_NOTE:
- if (wins_slctd () == APP && apoint_hilt () != 0)
- day_view_note (conf.pager);
- else if (wins_slctd () == TOD && todo_hilt () != 0)
- todo_view_note (conf.pager);
- break;
-
- case KEY_GENERIC_HELP:
- wins_status_bar ();
- help_screen ();
- break;
-
- case KEY_GENERIC_SAVE:
- io_save_cal (&conf, IO_SAVE_DISPLAY_BAR);
- break;
-
- case KEY_GENERIC_IMPORT:
- wins_erase_status_bar ();
- io_import_data (IO_IMPORT_ICAL, &conf, NULL);
- do_storage = 1;
- break;
-
- case KEY_GENERIC_EXPORT:
- wins_erase_status_bar ();
- io_export_bar ();
- while ((key = wgetch (win[STA].p)) != 'q')
- {
- switch (key)
- {
- case 'I':
- case 'i':
- io_export_data (IO_EXPORT_ICAL, &conf);
- break;
- case 'P':
- case 'p':
- io_export_data (IO_EXPORT_PCAL, &conf);
- break;
- }
- wins_reset ();
- wins_update ();
- do_storage = 1;
- wins_erase_status_bar ();
- io_export_bar ();
- }
- wins_update ();
- break;
-
- case KEY_GENERIC_NEXT_DAY:
- case KEY_MOVE_RIGHT:
- if (wins_slctd () == CAL || key == KEY_GENERIC_NEXT_DAY)
- {
- do_storage = 1;
- day_changed = 1;
- calendar_move (RIGHT);
- }
- break;
-
- case KEY_GENERIC_PREV_DAY:
- case KEY_MOVE_LEFT:
- if (wins_slctd () == CAL || key == KEY_GENERIC_PREV_DAY)
- {
- do_storage = 1;
- day_changed = 1;
- calendar_move (LEFT);
- }
- break;
-
- case KEY_GENERIC_PREV_WEEK:
- case KEY_MOVE_UP:
- if (wins_slctd () == CAL || key == KEY_GENERIC_PREV_WEEK)
- {
- do_storage = 1;
- day_changed = 1;
- calendar_move (UP);
- }
- else if ((wins_slctd () == APP) && (apoint_hilt () > 1))
- {
- apoint_hilt_decrease ();
- apoint_scroll_pad_up (inday.nb_events);
- }
- else if ((wins_slctd () == TOD) && (todo_hilt () > 1))
- {
- todo_hilt_decrease ();
- if (todo_hilt_pos () < 0)
- todo_first_decrease ();
- }
- break;
-
- case KEY_GENERIC_NEXT_WEEK:
- case KEY_MOVE_DOWN:
- if (wins_slctd () == CAL || key == KEY_GENERIC_NEXT_WEEK)
- {
- do_storage = 1;
- day_changed = 1;
- calendar_move (DOWN);
- }
- else if ((wins_slctd () == APP) &&
- (apoint_hilt () < inday.nb_events + inday.nb_apoints))
- {
- apoint_hilt_increase ();
- apoint_scroll_pad_down (inday.nb_events, win[APP].h);
- }
- else if ((wins_slctd () == TOD) && (todo_hilt () < todo_nb ()))
- {
- todo_hilt_increase ();
- if (todo_hilt_pos () == win[TOD].h - 4)
- todo_first_increase ();
- }
- break;
-
- case KEY_START_OF_WEEK:
- if (wins_slctd () == CAL)
- {
- do_storage = 1;
- day_changed = 1;
- calendar_move (WEEK_START);
- }
- break;
-
- case KEY_END_OF_WEEK:
- if (wins_slctd () == CAL)
- {
- do_storage = 1;
- day_changed = 1;
- calendar_move (WEEK_END);
- }
- break;
-
- case KEY_GENERIC_SCROLL_UP:
- if (wins_slctd () == CAL)
- calendar_view_prev ();
- break;
-
- case KEY_GENERIC_SCROLL_DOWN:
- if (wins_slctd () == CAL)
- calendar_view_next ();
- break;
-
- case KEY_GENERIC_QUIT:
- if (conf.auto_save)
- io_save_cal (&conf, IO_SAVE_DISPLAY_BAR);
-
- if (conf.confirm_quit)
- {
- status_mesg (_(quit_message), choices);
- key = wgetch (win[STA].p);
- if (key == 'y')
- exit_calcurse (EXIT_SUCCESS);
- else
- {
- wins_erase_status_bar ();
- break;
- }
- }
- else
- exit_calcurse (EXIT_SUCCESS);
- break;
+ if (resize) {
+ resize = 0;
+ wins_reset();
+ }
- default:
- do_update = 0;
+ key = keys_getch(win[STA].p, &count);
+ switch (key) {
+ case KEY_GENERIC_REDRAW:
+ resize = 1;
+ break;
+
+ case KEY_GENERIC_CHANGE_VIEW:
+ wins_reset_status_page();
+ wins_slctd_next();
+
+ /* Select the event to highlight. */
+ switch (wins_slctd()) {
+ case TOD:
+ if ((todo_hilt() == 0) && (todo_nb() > 0))
+ todo_hilt_set(1);
+ break;
+ case APP:
+ if ((apoint_hilt() == 0) && ((inday.nb_events + inday.nb_apoints) > 0))
+ apoint_hilt_set(1);
+ break;
+ default:
+ break;
+ }
+ wins_update(FLAG_ALL);
+ break;
+
+ case KEY_GENERIC_OTHER_CMD:
+ wins_other_status_page(wins_slctd());
+ wins_update(FLAG_STA);
+ break;
+
+ case KEY_GENERIC_GOTO:
+ case KEY_GENERIC_GOTO_TODAY:
+ wins_erase_status_bar();
+ calendar_set_current_date();
+ if (key == KEY_GENERIC_GOTO_TODAY)
+ calendar_goto_today();
+ else
+ calendar_change_day(conf.input_datefmt);
+ inday = do_storage(1);
+ wins_update(FLAG_CAL | FLAG_APP | FLAG_STA);
+ break;
+
+ case KEY_VIEW_ITEM:
+ if ((wins_slctd() == APP) && (apoint_hilt() != 0))
+ day_popup_item();
+ else if ((wins_slctd() == TOD) && (todo_hilt() != 0))
+ item_in_popup(NULL, NULL, todo_saved_mesg(), _("To do :"));
+ wins_update(FLAG_ALL);
+ break;
+
+ case KEY_GENERIC_CONFIG_MENU:
+ wins_erase_status_bar();
+ custom_config_main();
+ inday = do_storage(0);
+ wins_update(FLAG_ALL);
+ break;
+
+ case KEY_GENERIC_ADD_APPT:
+ apoint_add();
+ inday = do_storage(1);
+ wins_update(FLAG_CAL | FLAG_APP | FLAG_STA);
+ break;
+
+ case KEY_GENERIC_ADD_TODO:
+ todo_new_item();
+ if (todo_hilt() == 0 && todo_nb() == 1)
+ todo_hilt_increase(1);
+ wins_update(FLAG_TOD | FLAG_STA);
+ break;
+
+ case KEY_ADD_ITEM:
+ switch (wins_slctd()) {
+ case APP:
+ apoint_add();
+ inday = do_storage(0);
+ wins_update(FLAG_CAL | FLAG_APP | FLAG_STA);
+ break;
+ case TOD:
+ todo_new_item();
+ if (todo_hilt() == 0 && todo_nb() == 1)
+ todo_hilt_increase(1);
+ wins_update(FLAG_TOD | FLAG_STA);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case KEY_EDIT_ITEM:
+ if (wins_slctd() == APP && apoint_hilt() != 0) {
+ day_edit_item();
+ inday = do_storage(0);
+ wins_update(FLAG_CAL | FLAG_APP | FLAG_STA);
+ } else if (wins_slctd() == TOD && todo_hilt() != 0) {
+ todo_edit_item();
+ wins_update(FLAG_TOD | FLAG_STA);
+ }
+ break;
+
+ case KEY_DEL_ITEM:
+ if (wins_slctd() == APP && apoint_hilt() != 0) {
+ apoint_delete(&inday.nb_events, &inday.nb_apoints);
+ inday = do_storage(0);
+ wins_update(FLAG_CAL | FLAG_APP | FLAG_STA);
+ } else if (wins_slctd() == TOD && todo_hilt() != 0) {
+ todo_delete();
+ wins_update(FLAG_TOD | FLAG_STA);
+ }
+ break;
+
+ case KEY_GENERIC_CUT:
+ if (wins_slctd() == APP && apoint_hilt() != 0) {
+ cut_item = apoint_cut(&inday.nb_events, &inday.nb_apoints);
+ inday = do_storage(0);
+ wins_update(FLAG_CAL | FLAG_APP);
+ }
+ break;
+
+ case KEY_GENERIC_PASTE:
+ if (wins_slctd() == APP) {
+ apoint_paste(&inday.nb_events, &inday.nb_apoints, cut_item);
+ cut_item = 0;
+ inday = do_storage(0);
+ wins_update(FLAG_CAL | FLAG_APP);
+ }
+ break;
+
+ case KEY_REPEAT_ITEM:
+ if (wins_slctd() == APP && apoint_hilt() != 0)
+ recur_repeat_item();
+ inday = do_storage(0);
+ wins_update(FLAG_CAL | FLAG_APP | FLAG_STA);
+ break;
+
+ case KEY_FLAG_ITEM:
+ if (wins_slctd() == APP && apoint_hilt() != 0) {
+ apoint_switch_notify();
+ inday = do_storage(0);
+ wins_update(FLAG_APP);
+ } else if (wins_slctd() == TOD && todo_hilt() != 0) {
+ todo_flag();
+ wins_update(FLAG_TOD);
+ }
+ break;
+
+ case KEY_PIPE_ITEM:
+ if (wins_slctd() == APP && apoint_hilt() != 0)
+ day_pipe_item();
+ else if (wins_slctd() == TOD && todo_hilt() != 0)
+ todo_pipe_item();
+ wins_update(FLAG_ALL);
+ break;
+
+ case KEY_RAISE_PRIORITY:
+ case KEY_LOWER_PRIORITY:
+ if (wins_slctd() == TOD && todo_hilt() != 0) {
+ todo_chg_priority(key);
+ if (todo_hilt_pos() < 0)
+ todo_set_first(todo_hilt());
+ else if (todo_hilt_pos() >= win[TOD].h - 4)
+ todo_set_first(todo_hilt() - win[TOD].h + 5);
+ wins_update(FLAG_TOD);
+ }
+ break;
+
+ case KEY_EDIT_NOTE:
+ if (wins_slctd() == APP && apoint_hilt() != 0) {
+ day_edit_note(conf.editor);
+ inday = do_storage(0);
+ } else if (wins_slctd() == TOD && todo_hilt() != 0)
+ todo_edit_note(conf.editor);
+ wins_update(FLAG_ALL);
+ break;
+
+ case KEY_VIEW_NOTE:
+ if (wins_slctd() == APP && apoint_hilt() != 0)
+ day_view_note(conf.pager);
+ else if (wins_slctd() == TOD && todo_hilt() != 0)
+ todo_view_note(conf.pager);
+ wins_update(FLAG_ALL);
+ break;
+
+ case KEY_GENERIC_HELP:
+ wins_status_bar();
+ help_screen();
+ wins_update(FLAG_ALL);
+ break;
+
+ case KEY_GENERIC_SAVE:
+ io_save_cal(IO_SAVE_DISPLAY_BAR);
+ wins_update(FLAG_STA);
+ break;
+
+ case KEY_GENERIC_IMPORT:
+ wins_erase_status_bar();
+ io_import_data(IO_IMPORT_ICAL, NULL);
+ inday = do_storage(0);
+ wins_update(FLAG_ALL);
+ break;
+
+ case KEY_GENERIC_EXPORT:
+ wins_erase_status_bar();
+ io_export_bar();
+ while ((key = wgetch(win[STA].p)) != 'q') {
+ switch (key) {
+ case 'I':
+ case 'i':
+ io_export_data(IO_EXPORT_ICAL);
+ break;
+ case 'P':
+ case 'p':
+ io_export_data(IO_EXPORT_PCAL);
break;
}
-
- if (do_storage)
- {
- inday = *day_process_storage (calendar_get_slctd_day (),
- day_changed, &inday);
- do_storage = !do_storage;
- if (day_changed)
- {
- sav_hilt_app = 0;
- day_changed = !day_changed;
- if ((wins_slctd () == APP) &&
- (inday.nb_events + inday.nb_apoints != 0))
- apoint_hilt_set (1);
- }
+ wins_reset();
+ wins_update(FLAG_ALL);
+ wins_erase_status_bar();
+ io_export_bar();
+ }
+ inday = do_storage(0);
+ wins_update(FLAG_ALL);
+ break;
+
+ case KEY_GENERIC_NEXT_DAY:
+ case KEY_MOVE_RIGHT:
+ if (wins_slctd() == CAL || key == KEY_GENERIC_NEXT_DAY) {
+ calendar_move(RIGHT, count);
+ inday = do_storage(1);
+ wins_update(FLAG_CAL | FLAG_APP);
+ }
+ break;
+
+ case KEY_GENERIC_PREV_DAY:
+ case KEY_MOVE_LEFT:
+ if (wins_slctd() == CAL || key == KEY_GENERIC_PREV_DAY) {
+ calendar_move(LEFT, count);
+ inday = do_storage(1);
+ wins_update(FLAG_CAL | FLAG_APP);
+ }
+ break;
+
+ case KEY_GENERIC_PREV_WEEK:
+ case KEY_MOVE_UP:
+ if (wins_slctd() == CAL || key == KEY_GENERIC_PREV_WEEK) {
+ calendar_move(UP, count);
+ inday = do_storage(1);
+ wins_update(FLAG_CAL | FLAG_APP);
+ } else if (wins_slctd() == APP) {
+ if (count >= apoint_hilt())
+ count = apoint_hilt() - 1;
+ apoint_hilt_decrease(count);
+ apoint_scroll_pad_up(inday.nb_events);
+ wins_update(FLAG_APP);
+ } else if (wins_slctd() == TOD) {
+ if (count >= todo_hilt())
+ count = todo_hilt() - 1;
+ todo_hilt_decrease(count);
+ if (todo_hilt_pos() < 0)
+ todo_first_increase(todo_hilt_pos());
+ wins_update(FLAG_TOD);
+ }
+ break;
+
+ case KEY_GENERIC_NEXT_WEEK:
+ case KEY_MOVE_DOWN:
+ if (wins_slctd() == CAL || key == KEY_GENERIC_NEXT_WEEK) {
+ calendar_move(DOWN, count);
+ inday = do_storage(1);
+ wins_update(FLAG_CAL | FLAG_APP);
+ } else if (wins_slctd() == APP) {
+ if (count > inday.nb_events + inday.nb_apoints - apoint_hilt())
+ count = inday.nb_events + inday.nb_apoints - apoint_hilt();
+ apoint_hilt_increase(count);
+ apoint_scroll_pad_down(inday.nb_events, win[APP].h);
+ wins_update(FLAG_APP);
+ } else if (wins_slctd() == TOD) {
+ if (count > todo_nb() - todo_hilt())
+ count = todo_nb() - todo_hilt();
+ todo_hilt_increase(count);
+ if (todo_hilt_pos() >= win[TOD].h - 4)
+ todo_first_increase(todo_hilt_pos() - win[TOD].h + 5);
+ wins_update(FLAG_TOD);
+ }
+ break;
+
+ case KEY_START_OF_WEEK:
+ if (wins_slctd() == CAL) {
+ calendar_move(WEEK_START, count);
+ inday = do_storage(1);
+ wins_update(FLAG_CAL | FLAG_APP);
+ }
+ break;
+
+ case KEY_END_OF_WEEK:
+ if (wins_slctd() == CAL) {
+ calendar_move(WEEK_END, count);
+ inday = do_storage(1);
+ wins_update(FLAG_CAL | FLAG_APP);
+ }
+ break;
+
+ case KEY_GENERIC_SCROLL_UP:
+ if (wins_slctd() == CAL) {
+ calendar_view_prev();
+ wins_update(FLAG_CAL | FLAG_APP);
+ }
+ break;
+
+ case KEY_GENERIC_SCROLL_DOWN:
+ if (wins_slctd() == CAL) {
+ calendar_view_next();
+ wins_update(FLAG_CAL | FLAG_APP);
+ }
+ break;
+
+ case KEY_GENERIC_QUIT:
+ if (conf.auto_save)
+ io_save_cal(IO_SAVE_DISPLAY_BAR);
+ if (conf.auto_gc)
+ note_gc();
+
+ if (conf.confirm_quit) {
+ if (status_ask_bool(_("Do you really want to quit ?")) == 1)
+ exit_calcurse(EXIT_SUCCESS);
+ else {
+ wins_erase_status_bar();
+ wins_update(FLAG_STA);
+ break;
}
+ } else
+ exit_calcurse(EXIT_SUCCESS);
+ break;
- if (resize)
- {
- resize = 0;
- do_update = 0;
- wins_reset ();
- }
+ case KEY_RESIZE:
+ case ERR:
+ /* Do not reset the count parameter on resize or error. */
+ continue;
- if (do_update)
- wins_update ();
+ default:
+ break;
}
+
+ count = 0;
+ }
}
diff --git a/src/calcurse.h b/src/calcurse.h
index 091d16a..9efb4fd 100644
--- a/src/calcurse.h
+++ b/src/calcurse.h
@@ -1,7 +1,7 @@
/*
* Calcurse - text-based organizer
*
- * Copyright (c) 2004-2011 calcurse Development Team <misc@calcurse.org>
+ * Copyright (c) 2004-2012 calcurse Development Team <misc@calcurse.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -40,13 +40,13 @@
#include "config.h"
#ifdef HAVE_NCURSES_H
-# include <ncurses.h>
+#include <ncurses.h>
#elif defined HAVE_NCURSES_NCURSES_H
-# include <ncurses/ncurses.h>
+#include <ncurses/ncurses.h>
#elif defined HAVE_NCURSESW_NCURSES_H
-# include <ncursesw/ncurses.h>
+#include <ncursesw/ncurses.h>
#else
-# error "Missing ncurses header. Aborting..."
+#error "Missing ncurses header. Aborting..."
#endif
#include <pthread.h>
@@ -60,24 +60,24 @@
/* Internationalization. */
#if ENABLE_NLS
-# include <locale.h>
-# include <libintl.h>
-# undef _
-# define _(String) gettext(String)
-# ifdef gettext_noop
-# define N_(String) gettext_noop(String)
-# else
-# define N_(String) (String)
-# endif
+#include <locale.h>
+#include <libintl.h>
+#undef _
+#define _(String) gettext(String)
+#ifdef gettext_noop
+#define N_(String) gettext_noop(String)
+#else
+#define N_(String) (String)
+#endif
#else /* NLS disabled */
-# define _(String) (String)
-# define N_(String) (String)
-# define textdomain(String) (String)
-# define gettext(String) (String)
-# define dgettext(String) (String)
-# define dcgettext(String) (String)
-# define bindtextdomain(String) (String)
-# define bind_textdomain_codeset(Domain,Codeset) (Codeset)
+#define _(String) (String)
+#define N_(String) (String)
+#define textdomain(String) (String)
+#define gettext(String) (String)
+#define dgettext(String) (String)
+#define dcgettext(String) (String)
+#define bindtextdomain(String) (String)
+#define bind_textdomain_codeset(Domain,Codeset) (Codeset)
#endif /* ENABLE_NLS */
/* Paths configuration. */
@@ -103,132 +103,148 @@
#define DEFAULT_EDITOR "vi"
#define DEFAULT_PAGER "less"
-#define ATTR_FALSE 0
-#define ATTR_TRUE 1
-#define ATTR_LOWEST 2
-#define ATTR_LOW 3
-#define ATTR_MIDDLE 4
-#define ATTR_HIGH 5
-#define ATTR_HIGHEST 6
+#define ATTR_FALSE 0
+#define ATTR_TRUE 1
+#define ATTR_LOWEST 2
+#define ATTR_LOW 3
+#define ATTR_MIDDLE 4
+#define ATTR_HIGH 5
+#define ATTR_HIGHEST 6
-#define STATUSHEIGHT 2
-#define NOTESIZ 6
+#define STATUSHEIGHT 2
+#define MAX_NOTESIZ 40
+#define TMPEXTSIZ 6
/* Format for appointment hours is: HH:MM */
#define HRMIN_SIZE 6
/* Maximum number of colors available. */
-#define NBUSERCOLORS 6
+#define NBUSERCOLORS 6
/* Side bar width acceptable boundaries. */
#define SBARMINWIDTH 32
#define SBARMAXWIDTHPERC 50
/* Related to date manipulation. */
-#define DAYINSEC 86400
-#define HOURINSEC 3600
-#define MININSEC 60
-#define YEARINDAYS 365
#define YEARINMONTHS 12
-#define WEEKINDAYS 7
+#define YEARINDAYS 365
#define TM_YEAR_BASE 1900
+#define WEEKINDAYS 7
+#define DAYINHOURS 24
+#define HOURINMIN 60
+#define MININSEC 60
+
+#define WEEKINHOURS (WEEKINDAYS * DAYINHOURS)
+#define WEEKINMIN (WEEKINHOURS * HOURINMIN)
+#define WEEKINSEC (WEEKINMIN * MININSEC)
+#define DAYINMIN (DAYINHOURS * HOURINMIN)
+#define DAYINSEC (DAYINMIN * MININSEC)
+#define HOURINSEC (HOURINMIN * MININSEC)
+
/* Calendar window. */
-#define CALHEIGHT 12
+#define CALHEIGHT 12
/* Key definitions. */
#define CTRLVAL 0x1F
#define CTRL(x) ((x) & CTRLVAL)
-#define ESCAPE 27
-#define TAB 9
+#define ESCAPE 27
+#define TAB 9
#define SPACE 32
-#define KEYS_KEYLEN 3 /* length of each keybinding */
-#define KEYS_LABELEN 8 /* length of command description */
-#define KEYS_CMDS_PER_LINE 6 /* max number of commands per line */
-
-#define ERROR_MSG(...) do { \
- char msg[BUFSIZ]; \
- int len; \
- \
- len = snprintf (msg, BUFSIZ, "%s: %d: ", __FILE__, __LINE__); \
- (void)snprintf (msg + len, BUFSIZ - len, __VA_ARGS__); \
- if (ui_mode == UI_CURSES) \
- fatalbox (msg); \
- else \
- (void)fprintf (stderr, "%s\n", msg); \
+#define KEYS_KEYLEN 3 /* length of each keybinding */
+#define KEYS_LABELEN 8 /* length of command description */
+#define KEYS_CMDS_PER_LINE 6 /* max number of commands per line */
+
+/* Size of the hash table the note garbage collector uses. */
+#define NOTE_GC_HSIZE 1024
+
+#define ERROR_MSG(...) do { \
+ char msg[BUFSIZ]; \
+ int len; \
+ \
+ len = snprintf (msg, BUFSIZ, "%s: %d: ", __FILE__, __LINE__); \
+ snprintf (msg + len, BUFSIZ - len, __VA_ARGS__); \
+ if (ui_mode == UI_CURSES) \
+ fatalbox (msg); \
+ else \
+ fprintf (stderr, "%s\n", msg); \
} while (0)
-#define WARN_MSG(...) do { \
- char msg[BUFSIZ]; \
- \
- (void)snprintf (msg, BUFSIZ, __VA_ARGS__); \
- if (ui_mode == UI_CURSES) \
- warnbox (msg); \
- else \
- (void)fprintf (stderr, "%s\n", msg); \
+#define WARN_MSG(...) do { \
+ char msg[BUFSIZ]; \
+ \
+ snprintf (msg, BUFSIZ, __VA_ARGS__); \
+ if (ui_mode == UI_CURSES) \
+ warnbox (msg); \
+ else \
+ fprintf (stderr, "%s\n", msg); \
} while (0)
-#define EXIT(...) do { \
- ERROR_MSG(__VA_ARGS__); \
- if (ui_mode == UI_CURSES) \
- exit_calcurse (EXIT_FAILURE); \
- else \
- exit (EXIT_FAILURE); \
+#define EXIT(...) do { \
+ ERROR_MSG(__VA_ARGS__); \
+ if (ui_mode == UI_CURSES) \
+ exit_calcurse (EXIT_FAILURE); \
+ else \
+ exit (EXIT_FAILURE); \
} while (0)
-#define EXIT_IF(cond, ...) do { \
- if ((cond)) \
- EXIT(__VA_ARGS__); \
+#define EXIT_IF(cond, ...) do { \
+ if ((cond)) \
+ EXIT(__VA_ARGS__); \
} while (0)
-#define RETURN_IF(cond, ...) do { \
- if ((cond)) \
- { \
- ERROR_MSG(__VA_ARGS__); \
- return; \
- } \
+#define RETURN_IF(cond, ...) do { \
+ if ((cond)) \
+ { \
+ ERROR_MSG(__VA_ARGS__); \
+ return; \
+ } \
} while (0)
-#define RETVAL_IF(cond, val, ...) do { \
- if ((cond)) \
- { \
- ERROR_MSG(__VA_ARGS__); \
- return (val); \
- } \
+#define RETVAL_IF(cond, val, ...) do { \
+ if ((cond)) \
+ { \
+ ERROR_MSG(__VA_ARGS__); \
+ return (val); \
+ } \
} while (0)
-#define STRING_BUILD(str) {str, sizeof (str) - 1}
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define __FILE_POS__ __FILE__ ":" TOSTRING(__LINE__)
+#define UTF8_MAXLEN 6
+#define UTF8_LENGTH(ch) ((unsigned char)ch >= 0xFC ? 6 : \
+ ((unsigned char)ch >= 0xF8 ? 5 : \
+ ((unsigned char)ch >= 0xF0 ? 4 : \
+ ((unsigned char)ch >= 0xE0 ? 3 : \
+ ((unsigned char)ch >= 0xC0 ? 2 : 1)))))
+#define UTF8_ISCONT(ch) ((unsigned char)ch >= 0x80 && \
+ (unsigned char)ch <= 0xBF)
+
#define MAX(x,y) ((x)>(y)?(x):(y))
#define MIN(x,y) ((x)<(y)?(x):(y))
/* General configuration variables. */
struct conf {
- unsigned auto_save;
- unsigned periodic_save;
- unsigned confirm_quit;
- unsigned confirm_delete;
- unsigned skip_system_dialogs;
- unsigned skip_progress_bar;
- char *editor;
- char *pager;
- char output_datefmt[BUFSIZ]; /* format for displaying date */
- int input_datefmt; /* format for reading date */
+ unsigned auto_save;
+ unsigned auto_gc;
+ unsigned periodic_save;
+ unsigned confirm_quit;
+ unsigned confirm_delete;
+ unsigned system_dialogs;
+ unsigned progress_bar;
+ const char *editor;
+ const char *pager;
+ char output_datefmt[BUFSIZ]; /* format for displaying date */
+ int input_datefmt; /* format for reading date */
};
/* Daemon-related configuration. */
struct dmon_conf {
- unsigned enable; /* launch daemon automatically when exiting */
- unsigned log; /* log daemon activity */
-};
-
-struct string {
- const char *str;
- const int len;
+ unsigned enable; /* launch daemon automatically when exiting */
+ unsigned log; /* log daemon activity */
};
enum datefmt {
@@ -239,16 +255,13 @@ enum datefmt {
DATE_FORMATS
};
-#define DATEFMT(datefmt) (datefmt == DATEFMT_MMDDYYYY ? "%m/%d/%Y" : \
- (datefmt == DATEFMT_DDMMYYYY ? "%d/%m/%Y" : \
- (datefmt == DATEFMT_YYYYMMDD ? "%Y/%m/%d" : "%Y-%m-%d")))
+#define DATEFMT(datefmt) (datefmt == DATEFMT_MMDDYYYY ? "%m/%d/%Y" : \
+ (datefmt == DATEFMT_DDMMYYYY ? "%d/%m/%Y" : \
+ (datefmt == DATEFMT_YYYYMMDD ? "%Y/%m/%d" : "%Y-%m-%d")))
-#define DATEFMT_DESC(datefmt) (datefmt == DATEFMT_MMDDYYYY ? \
- _("mm/dd/yyyy") : \
- (datefmt == DATEFMT_DDMMYYYY ? \
- _("dd/mm/yyyy") : \
- (datefmt == DATEFMT_YYYYMMDD ? \
- _("yyyy/mm/dd") : _("yyyy-mm-dd"))))
+#define DATEFMT_DESC(datefmt) (datefmt == DATEFMT_MMDDYYYY ? \
+ _("mm/dd/yyyy") : (datefmt == DATEFMT_DDMMYYYY ? _("dd/mm/yyyy") : \
+ (datefmt == DATEFMT_YYYYMMDD ? _("yyyy/mm/dd") : _("yyyy-mm-dd"))))
struct date {
unsigned dd;
@@ -257,33 +270,32 @@ struct date {
};
/* Appointment definition. */
-struct apoint
-{
- long start; /* seconds since 1 jan 1970 */
- long dur; /* duration of the appointment in seconds */
+struct apoint {
+ long start; /* seconds since 1 jan 1970 */
+ long dur; /* duration of the appointment in seconds */
#define APOINT_NULL 0x0
-#define APOINT_NOTIFY 0x1 /* Item needs to be notified */
-#define APOINT_NOTIFIED 0x2 /* Item was already notified */
- int state;
+#define APOINT_NOTIFY 0x1 /* Item needs to be notified */
+#define APOINT_NOTIFIED 0x2 /* Item was already notified */
+ int state;
- char *mesg;
- char *note;
+ char *mesg;
+ char *note;
};
/* Event definition. */
struct event {
- int id; /* event identifier */
- long day; /* seconds since 1 jan 1970 */
- char *mesg;
- char *note;
+ int id; /* event identifier */
+ long day; /* seconds since 1 jan 1970 */
+ char *mesg;
+ char *note;
};
/* Todo item definition. */
struct todo {
- char *mesg;
- int id;
- char *note;
+ char *mesg;
+ int id;
+ char *note;
};
/* Number of items in current day. */
@@ -294,18 +306,18 @@ struct day_items_nb {
/* Generic item description (to hold appointments, events...). */
struct day_item {
- long start; /* seconds since 1 jan 1970 */
- long appt_dur; /* appointment duration in seconds */
- int type; /* (recursive or normal) event or appointment */
- int evnt_id; /* event identifier */
- int appt_pos; /* real position in recurrent list */
- char state; /* appointment state */
- char *mesg; /* item description */
- char *note; /* note attached to item */
+ long start; /* seconds since 1 jan 1970 */
+ long appt_dur; /* appointment duration in seconds */
+ int type; /* (recursive or normal) event or appointment */
+ int evnt_id; /* event identifier */
+ int appt_pos; /* real position in recurrent list */
+ char state; /* appointment state */
+ char *mesg; /* item description */
+ char *note; /* note attached to item */
};
struct excp {
- long st; /* beggining of the considered day, in seconds */
+ long st; /* beggining of the considered day, in seconds */
};
enum recur_type {
@@ -319,43 +331,43 @@ enum recur_type {
/* To describe an item's repetition. */
struct rpt {
- enum recur_type type; /* repetition type */
- int freq; /* repetition frequence */
- long until; /* ending date for repeated event */
+ enum recur_type type; /* repetition type */
+ int freq; /* repetition frequence */
+ long until; /* ending date for repeated event */
};
/* Recurrent appointment definition. */
struct recur_apoint {
- struct rpt *rpt; /* information about repetition */
- llist_t exc; /* days when the item should not be repeated */
- long start; /* beggining of the appointment */
- long dur; /* duration of the appointment */
- char state; /* 8 bits to store item state */
- char *mesg; /* appointment description */
- char *note; /* note attached to appointment */
+ struct rpt *rpt; /* information about repetition */
+ llist_t exc; /* days when the item should not be repeated */
+ long start; /* beggining of the appointment */
+ long dur; /* duration of the appointment */
+ char state; /* 8 bits to store item state */
+ char *mesg; /* appointment description */
+ char *note; /* note attached to appointment */
};
/* Reccurent event definition. */
struct recur_event {
- struct rpt *rpt; /* information about repetition */
- llist_t exc; /* days when the item should not be repeated */
- int id; /* event type */
- long day; /* day at which event occurs */
- char *mesg; /* event description */
- char *note; /* note attached to event */
+ struct rpt *rpt; /* information about repetition */
+ llist_t exc; /* days when the item should not be repeated */
+ int id; /* event type */
+ long day; /* day at which event occurs */
+ char *mesg; /* event description */
+ char *note; /* note attached to event */
};
struct notify_app {
- long time;
- int got_app;
- char *txt;
- char state;
- pthread_mutex_t mutex;
+ long time;
+ int got_app;
+ char *txt;
+ char state;
+ pthread_mutex_t mutex;
};
struct io_file {
FILE *fd;
- char name[BUFSIZ];
+ char name[BUFSIZ];
};
/* Available keys. */
@@ -395,6 +407,7 @@ enum key {
KEY_DEL_ITEM,
KEY_EDIT_ITEM,
KEY_VIEW_ITEM,
+ KEY_PIPE_ITEM,
KEY_FLAG_ITEM,
KEY_REPEAT_ITEM,
KEY_EDIT_NOTE,
@@ -408,8 +421,8 @@ enum key {
/* To describe a key binding. */
struct binding {
- char *label;
- enum key action;
+ char *label;
+ enum key action;
};
enum win {
@@ -421,6 +434,13 @@ enum win {
NBWINS
};
+#define FLAG_CAL (1 << CAL)
+#define FLAG_APP (1 << APP)
+#define FLAG_TOD (1 << TOD)
+#define FLAG_NOT (1 << NOT)
+#define FLAG_STA (1 << STA)
+#define FLAG_ALL ((1 << NBWINS) - 1)
+
enum ui_mode {
UI_CURSES,
UI_CMDLINE,
@@ -429,40 +449,41 @@ enum ui_mode {
/* Generic window structure. */
struct window {
- WINDOW *p; /* pointer to window */
- unsigned w; /* width */
- unsigned h; /* height */
- int x; /* x position */
- int y; /* y position */
+ WINDOW *p; /* pointer to window */
+ unsigned w; /* width */
+ unsigned h; /* height */
+ int x; /* x position */
+ int y; /* y position */
};
/* Generic scrolling window structure. */
struct scrollwin {
- struct window win;
- struct window pad;
- unsigned first_visible_line;
- unsigned total_lines;
- char label[BUFSIZ];
+ struct window win;
+ struct window pad;
+ unsigned first_visible_line;
+ unsigned total_lines;
+ const char *label;
};
/* Pad structure to handle scrolling. */
struct pad {
- int width;
- int length;
- int first_onscreen; /* first line to be displayed inside window */
- WINDOW *ptrwin; /* pointer to the pad window */
+ int width;
+ int length;
+ int first_onscreen; /* first line to be displayed inside window */
+ WINDOW *ptrwin; /* pointer to the pad window */
};
/* Notification bar definition. */
struct nbar {
- int show; /* display or hide the notify-bar */
- int cntdwn; /* warn when time left before next app
- becomes lesser than cntdwn */
- char datefmt[BUFSIZ]; /* format for displaying date */
- char timefmt[BUFSIZ]; /* format for displaying time */
- char cmd[BUFSIZ]; /* notification command */
- char *shell; /* user shell to launch notif. cmd */
- pthread_mutex_t mutex;
+ unsigned show; /* display or hide the notify-bar */
+ int cntdwn; /* warn when time left before next app
+ becomes lesser than cntdwn */
+ char datefmt[BUFSIZ]; /* format for displaying date */
+ char timefmt[BUFSIZ]; /* format for displaying time */
+ char cmd[BUFSIZ]; /* notification command */
+ const char *shell; /* user shell to launch notif. cmd */
+ unsigned notify_all; /* notify all appointments */
+ pthread_mutex_t mutex;
};
/* Available types of items. */
@@ -478,7 +499,6 @@ enum item_type {
enum eraseflg {
ERASE_DONT_FORCE,
ERASE_FORCE,
- ERASE_FORCE_KEEP_NOTE,
ERASE_FORCE_ONLY_NOTE,
ERASE_CUT
};
@@ -486,8 +506,8 @@ enum eraseflg {
/* Return codes for the getstring() function. */
enum getstr {
GETSTRING_VALID,
- GETSTRING_ESC, /* user pressed escape to cancel editing. */
- GETSTRING_RET /* return was pressed without entering any text. */
+ GETSTRING_ESC, /* user pressed escape to cancel editing. */
+ GETSTRING_RET /* return was pressed without entering any text. */
};
/* Week days. */
@@ -548,380 +568,429 @@ enum save_display {
/* apoint.c */
extern llist_ts_t alist_p;
-void apoint_free_bkp (enum eraseflg);
-void apoint_llist_init (void);
-void apoint_llist_free (void);
-void apoint_hilt_set (int);
-void apoint_hilt_decrease (void);
-void apoint_hilt_increase (void);
-int apoint_hilt (void);
-struct apoint *apoint_new (char *, char *, long, long, char);
-void apoint_add (void);
-void apoint_delete (struct conf *, unsigned *, unsigned *);
-int apoint_cut (unsigned *, unsigned *);
-void apoint_paste (unsigned *, unsigned *, int);
-unsigned apoint_inday (struct apoint *, long);
-void apoint_sec2str (struct apoint *, int, long, char *, char *);
-void apoint_write (struct apoint *, FILE *);
-struct apoint *apoint_scan (FILE *, struct tm, struct tm, char, char *);
-struct apoint *apoint_get (long, int);
-void apoint_delete_bynum (long, unsigned, enum eraseflg);
-void apoint_scroll_pad_down (int, int);
-void apoint_scroll_pad_up (int);
-struct notify_app *apoint_check_next (struct notify_app *, long);
-struct apoint *apoint_recur_s2apoint_s (struct recur_apoint *);
-void apoint_switch_notify (void);
-void apoint_update_panel (int);
-void apoint_paste_item (void);
+void apoint_free_bkp(void);
+void apoint_llist_init(void);
+void apoint_llist_free(void);
+void apoint_hilt_set(int);
+void apoint_hilt_decrease(int);
+void apoint_hilt_increase(int);
+int apoint_hilt(void);
+struct apoint *apoint_new(char *, char *, long, long, char);
+void apoint_add(void);
+void apoint_delete(unsigned *, unsigned *);
+int apoint_cut(unsigned *, unsigned *);
+void apoint_paste(unsigned *, unsigned *, int);
+unsigned apoint_inday(struct apoint *, long);
+void apoint_sec2str(struct apoint *, long, char *, char *);
+void apoint_write(struct apoint *, FILE *);
+struct apoint *apoint_scan(FILE *, struct tm, struct tm, char, char *);
+struct apoint *apoint_get(long, int);
+void apoint_delete_bynum(long, unsigned, enum eraseflg);
+void apoint_scroll_pad_down(int, int);
+void apoint_scroll_pad_up(int);
+struct notify_app *apoint_check_next(struct notify_app *, long);
+void apoint_switch_notify(void);
+void apoint_update_panel(int);
+void apoint_paste_item(void);
/* args.c */
-int parse_args (int, char **, struct conf *);
+int parse_args(int, char **);
/* calendar.c */
-void calendar_view_next (void);
-void calendar_view_prev (void);
-void calendar_set_view (int);
-int calendar_get_view (void);
-void calendar_start_date_thread (void);
-void calendar_stop_date_thread (void);
-void calendar_set_current_date (void);
-void calendar_set_first_day_of_week (enum wday);
-void calendar_change_first_day_of_week (void);
-unsigned calendar_week_begins_on_monday (void);
-void calendar_store_current_date (struct date *);
-void calendar_init_slctd_day (void);
-struct date *calendar_get_slctd_day (void);
-long calendar_get_slctd_day_sec (void);
-void calendar_update_panel (struct window *);
-void calendar_goto_today (void);
-void calendar_change_day (int);
-void calendar_move (enum move);
-long calendar_start_of_year (void);
-long calendar_end_of_year (void);
-char *calendar_get_pom (time_t);
+void calendar_view_next(void);
+void calendar_view_prev(void);
+void calendar_set_view(int);
+int calendar_get_view(void);
+void calendar_start_date_thread(void);
+void calendar_stop_date_thread(void);
+void calendar_set_current_date(void);
+void calendar_set_first_day_of_week(enum wday);
+void calendar_change_first_day_of_week(void);
+unsigned calendar_week_begins_on_monday(void);
+void calendar_store_current_date(struct date *);
+void calendar_init_slctd_day(void);
+struct date *calendar_get_slctd_day(void);
+long calendar_get_slctd_day_sec(void);
+void calendar_update_panel(struct window *);
+void calendar_goto_today(void);
+void calendar_change_day(int);
+void calendar_move(enum move, int);
+long calendar_start_of_year(void);
+long calendar_end_of_year(void);
+const char *calendar_get_pom(time_t);
+
+/* config.c */
+
+void config_load(void);
+unsigned config_save(void);
/* custom.c */
-void custom_init_attr (void);
-void custom_apply_attr (WINDOW *, int);
-void custom_remove_attr (WINDOW *, int);
-void custom_load_conf (struct conf *, int);
-void custom_config_bar (void);
-void custom_layout_config (void);
-void custom_sidebar_config (void);
-void custom_color_config (void);
-void custom_color_theme_name (char *);
-void custom_confwin_init (struct window *, char *);
-void custom_set_swsiz (struct scrollwin *);
-void custom_general_config (struct conf *);
-void custom_keys_config (void);
+void custom_init_attr(void);
+void custom_apply_attr(WINDOW *, int);
+void custom_remove_attr(WINDOW *, int);
+void custom_config_bar(void);
+void custom_layout_config(void);
+void custom_sidebar_config(void);
+void custom_color_config(void);
+void custom_color_theme_name(char *);
+void custom_confwin_init(struct window *, const char *);
+void custom_set_swsiz(struct scrollwin *);
+void custom_general_config(void);
+void custom_keys_config(void);
+void custom_config_main(void);
/* day.c */
-void day_free_list (void);
-struct day_items_nb *day_process_storage (struct date *, unsigned,
- struct day_items_nb *);
-void day_write_pad (long, int, int, int);
-void day_popup_item (void);
-int day_check_if_item (struct date);
-unsigned day_chk_busy_slices (struct date, int, int *);
-void day_edit_item (struct conf *);
-int day_erase_item (long, int, enum eraseflg);
-int day_cut_item (long, int);
-int day_paste_item (long, int);
-struct day_item *day_get_item (int);
-int day_item_nb (long, int, int);
-void day_edit_note (char *);
-void day_view_note (char *);
+void day_free_list(void);
+struct day_items_nb *day_process_storage(struct date *, unsigned,
+ struct day_items_nb *);
+void day_write_pad(long, int, int, int);
+void day_popup_item(void);
+int day_check_if_item(struct date);
+unsigned day_chk_busy_slices(struct date, int, int *);
+void day_edit_item(void);
+int day_erase_item(long, int, enum eraseflg);
+int day_cut_item(long, int);
+int day_paste_item(long, int);
+struct day_item *day_get_item(int);
+int day_item_nb(long, int, int);
+void day_edit_note(const char *);
+void day_view_note(const char *);
+void day_pipe_item(void);
/* dmon.c */
-void dmon_start (int);
-void dmon_stop (void);
+void dmon_start(int);
+void dmon_stop(void);
/* event.c */
extern llist_t eventlist;
-void event_free_bkp (enum eraseflg);
-void event_llist_init (void);
-void event_llist_free (void);
-struct event *event_new (char *, char *, long, int);
-unsigned event_inday (struct event *, long);
-void event_write (struct event *, FILE *);
-struct event *event_scan (FILE *, struct tm, int, char *);
-struct event *event_get (long, int);
-void event_delete_bynum (long, unsigned, enum eraseflg);
-void event_paste_item (void);
+void event_free_bkp(void);
+void event_llist_init(void);
+void event_llist_free(void);
+struct event *event_new(char *, char *, long, int);
+unsigned event_inday(struct event *, long);
+void event_write(struct event *, FILE *);
+struct event *event_scan(FILE *, struct tm, int, char *);
+struct event *event_get(long, int);
+void event_delete_bynum(long, unsigned, enum eraseflg);
+void event_paste_item(void);
/* help.c */
-void help_wins_init (struct scrollwin *, int, int, int, int);
-void help_screen (void);
+void help_wins_init(struct scrollwin *, int, int, int, int);
+void help_screen(void);
+
+/* getstring.c */
+enum getstr getstring(WINDOW *, char *, int, int, int);
+int updatestring(WINDOW *, char **, int, int);
+
+/* ical.c */
+void ical_import_data(FILE *, FILE *, unsigned *, unsigned *, unsigned *,
+ unsigned *, unsigned *);
+void ical_export_data(FILE *);
/* io.c */
-unsigned io_fprintln (const char *, const char *, ...);
-void io_init (char *, char *);
-void io_extract_data (char *, const char *, int);
-unsigned io_save_conf (struct conf *);
-unsigned io_save_apts (void);
-unsigned io_save_todo (void);
-unsigned io_save_keys (void);
-void io_save_cal (struct conf *, enum save_display);
-void io_load_app (void);
-void io_load_todo (void);
-void io_load_keys (char *);
-void io_check_dir (char *, int *);
-unsigned io_file_exist (char *);
-void io_check_file (char *, int *);
-int io_check_data_files (void);
-void io_startup_screen (unsigned, int);
-void io_export_data (enum export_type, struct conf *);
-void io_export_bar (void);
-void io_import_data (enum import_type, struct conf *, char *);
-struct io_file *io_log_init (void);
-void io_log_print (struct io_file *, int, char *);
-void io_log_display (struct io_file *, char *, char *);
-void io_log_free (struct io_file *);
-void io_start_psave_thread (struct conf *);
-void io_stop_psave_thread (void);
-void io_set_lock (void);
-unsigned io_dump_pid (char *);
-unsigned io_get_pid (char *);
-int io_file_is_empty (char *);
+unsigned io_fprintln(const char *, const char *, ...);
+void io_init(const char *, const char *);
+void io_extract_data(char *, const char *, int);
+unsigned io_save_apts(void);
+unsigned io_save_todo(void);
+unsigned io_save_keys(void);
+void io_save_cal(enum save_display);
+void io_load_app(void);
+void io_load_todo(void);
+void io_load_keys(const char *);
+void io_check_dir(char *, int *);
+unsigned io_file_exist(char *);
+void io_check_file(char *, int *);
+int io_check_data_files(void);
+void io_startup_screen(int);
+void io_export_data(enum export_type);
+void io_export_bar(void);
+void io_import_data(enum import_type, const char *);
+struct io_file *io_log_init(void);
+void io_log_print(struct io_file *, int, const char *);
+void io_log_display(struct io_file *, const char *, const char *);
+void io_log_free(struct io_file *);
+void io_start_psave_thread(void);
+void io_stop_psave_thread(void);
+void io_set_lock(void);
+unsigned io_dump_pid(char *);
+unsigned io_get_pid(char *);
+int io_file_is_empty(char *);
+int io_file_cp(const char *, const char *);
/* keys.c */
-void keys_init (void);
-void keys_free (void);
-void keys_dump_defaults (char *);
-char *keys_get_label (enum key);
-enum key keys_get_action (int);
-enum key keys_getch (WINDOW *win);
-int keys_assign_binding (int, enum key);
-void keys_remove_binding (int, enum key);
-int keys_str2int (char *);
-char *keys_int2str (int);
-int keys_action_count_keys (enum key);
-char *keys_action_firstkey (enum key);
-char *keys_action_nkey (enum key, int);
-char *keys_action_allkeys (enum key);
-void keys_display_bindings_bar (WINDOW *, struct binding **, int, int);
-void keys_popup_info (enum key);
-void keys_save_bindings (FILE *);
-int keys_check_missing_bindings (void);
-void keys_fill_missing (void);
+void keys_init(void);
+void keys_free(void);
+void keys_dump_defaults(char *);
+const char *keys_get_label(enum key);
+enum key keys_get_action(int);
+enum key keys_getch(WINDOW * win, int *);
+int keys_assign_binding(int, enum key);
+void keys_remove_binding(int, enum key);
+int keys_str2int(const char *);
+const char *keys_int2str(int);
+int keys_action_count_keys(enum key);
+const char *keys_action_firstkey(enum key);
+const char *keys_action_nkey(enum key, int);
+char *keys_action_allkeys(enum key);
+void keys_display_bindings_bar(WINDOW *, struct binding *[], int, int,
+ int, struct binding *);
+void keys_popup_info(enum key);
+void keys_save_bindings(FILE *);
+int keys_check_missing_bindings(void);
+void keys_fill_missing(void);
/* mem.c */
-void *xmalloc (size_t);
-void *xcalloc (size_t, size_t);
-void *xrealloc (void *, size_t, size_t);
-char *xstrdup (const char *);
-void xfree (void *);
+void *xmalloc(size_t);
+void *xcalloc(size_t, size_t);
+void *xrealloc(void *, size_t, size_t);
+char *xstrdup(const char *);
+void xfree(void *);
#ifdef CALCURSE_MEMORY_DEBUG
-# define mem_malloc(s) dbg_malloc ((s), __FILE_POS__)
-# define mem_calloc(n, s) dbg_calloc ((n), (s), __FILE_POS__)
-# define mem_realloc(p, n, s) dbg_realloc ((p), (n), (s), __FILE_POS__)
-# define mem_strdup(s) dbg_strdup ((s), __FILE_POS__)
-# define mem_free(p) dbg_free ((p), __FILE_POS__)
+#define mem_malloc(s) dbg_malloc ((s), __FILE_POS__)
+#define mem_calloc(n, s) dbg_calloc ((n), (s), __FILE_POS__)
+#define mem_realloc(p, n, s) dbg_realloc ((p), (n), (s), __FILE_POS__)
+#define mem_strdup(s) dbg_strdup ((s), __FILE_POS__)
+#define mem_free(p) dbg_free ((p), __FILE_POS__)
-void *dbg_malloc (size_t, const char *);
-void *dbg_calloc (size_t, size_t, const char *);
-void *dbg_realloc (void *, size_t, size_t, const char *);
-char *dbg_strdup (const char *, const char *);
-void dbg_free (void *, const char *);
-void mem_stats (void);
+void *dbg_malloc(size_t, const char *);
+void *dbg_calloc(size_t, size_t, const char *);
+void *dbg_realloc(void *, size_t, size_t, const char *);
+char *dbg_strdup(const char *, const char *);
+void dbg_free(void *, const char *);
+void mem_stats(void);
#else /* MEMORY DEBUG disabled */
-# define mem_malloc(s) xmalloc ((s))
-# define mem_calloc(n, s) xcalloc ((n), (s))
-# define mem_realloc(p, n, s) xrealloc ((p), (n), (s))
-# define mem_strdup(s) xstrdup ((s))
-# define mem_free(p) xfree ((p))
-# define mem_stats()
+#define mem_malloc(s) xmalloc ((s))
+#define mem_calloc(n, s) xcalloc ((n), (s))
+#define mem_realloc(p, n, s) xrealloc ((p), (n), (s))
+#define mem_strdup(s) xstrdup ((s))
+#define mem_free(p) xfree ((p))
+#define mem_stats()
#endif /* CALCURSE_MEMORY_DEBUG */
+/* note.c */
+char *generate_note(const char *);
+void edit_note(char **, const char *);
+void view_note(const char *, const char *);
+void erase_note(char **);
+void note_read(char *, FILE *);
+void note_gc(void);
+
/* notify.c */
-int notify_time_left (void);
-unsigned notify_needs_reminder (void);
-void notify_update_app (long, char, char *);
-int notify_bar (void);
-void notify_init_vars (void);
-void notify_init_bar (void);
-void notify_free_app (void);
-void notify_start_main_thread (void);
-void notify_stop_main_thread (void);
-void notify_reinit_bar (void);
-unsigned notify_launch_cmd (void);
-void notify_update_bar (void);
-unsigned notify_get_next (struct notify_app *);
-unsigned notify_get_next_bkgd (void);
-char *notify_app_txt (void);
-void notify_check_next_app (int);
-void notify_check_added (char *, long, char);
-void notify_check_repeated (struct recur_apoint *);
-int notify_same_item (long);
-int notify_same_recur_item (struct recur_apoint *);
-void notify_config_bar (void);
+int notify_time_left(void);
+unsigned notify_needs_reminder(void);
+void notify_update_app(long, char, char *);
+int notify_bar(void);
+void notify_init_vars(void);
+void notify_init_bar(void);
+void notify_free_app(void);
+void notify_start_main_thread(void);
+void notify_stop_main_thread(void);
+void notify_reinit_bar(void);
+unsigned notify_launch_cmd(void);
+void notify_update_bar(void);
+unsigned notify_get_next(struct notify_app *);
+unsigned notify_get_next_bkgd(void);
+char *notify_app_txt(void);
+void notify_check_next_app(int);
+void notify_check_added(char *, long, char);
+void notify_check_repeated(struct recur_apoint *);
+int notify_same_item(long);
+int notify_same_recur_item(struct recur_apoint *);
+void notify_config_bar(void);
+
+/* pcal.c */
+void pcal_export_data(FILE *);
/* recur.c */
extern llist_ts_t recur_alist_p;
extern llist_t recur_elist;
-void recur_event_free_bkp (enum eraseflg);
-void recur_apoint_free_bkp (enum eraseflg);
-void recur_apoint_llist_init (void);
-void recur_apoint_llist_free (void);
-void recur_event_llist_free (void);
-struct recur_apoint *recur_apoint_new (char *, char *, long, long, char,
- int, int, long, llist_t *);
-struct recur_event *recur_event_new (char *, char *, long, int, int, int,
- long, llist_t *);
-char recur_def2char (enum recur_type);
-int recur_char2def (char);
-struct recur_apoint *recur_apoint_scan (FILE *, struct tm, struct tm,
- char, int, struct tm, char *,
- llist_t *, char);
-struct recur_event *recur_event_scan (FILE *, struct tm, int, char,
- int, struct tm, char *,
- llist_t *);
-void recur_save_data (FILE *);
-unsigned recur_item_inday (long, llist_t *, int, int, long, long);
-unsigned recur_apoint_inday(struct recur_apoint *, long);
-unsigned recur_event_inday(struct recur_event *, long);
-void recur_event_erase (long, unsigned, unsigned,
- enum eraseflg);
-void recur_apoint_erase (long, unsigned, unsigned,
- enum eraseflg);
-void recur_repeat_item (struct conf *);
-void recur_exc_scan (llist_t *, FILE *);
-struct notify_app *recur_apoint_check_next (struct notify_app *, long, long);
-struct recur_apoint *recur_get_apoint (long, int);
-struct recur_event *recur_get_event (long, int);
-void recur_apoint_switch_notify (long, int);
-void recur_event_paste_item (void);
-void recur_apoint_paste_item (void);
+void recur_event_free_bkp(void);
+void recur_apoint_free_bkp(void);
+void recur_apoint_llist_init(void);
+void recur_apoint_llist_free(void);
+void recur_event_llist_free(void);
+struct recur_apoint *recur_apoint_new(char *, char *, long, long, char,
+ int, int, long, llist_t *);
+struct recur_event *recur_event_new(char *, char *, long, int, int, int,
+ long, llist_t *);
+char recur_def2char(enum recur_type);
+int recur_char2def(char);
+struct recur_apoint *recur_apoint_scan(FILE *, struct tm, struct tm,
+ char, int, struct tm, char *,
+ llist_t *, char);
+struct recur_event *recur_event_scan(FILE *, struct tm, int, char,
+ int, struct tm, char *, llist_t *);
+void recur_apoint_write(struct recur_apoint *, FILE *);
+void recur_event_write(struct recur_event *, FILE *);
+void recur_save_data(FILE *);
+unsigned recur_item_find_occurrence(long, long, llist_t *, int,
+ int, long, long, unsigned *);
+unsigned recur_apoint_find_occurrence(struct recur_apoint *, long, unsigned *);
+unsigned recur_event_find_occurrence(struct recur_event *, long, unsigned *);
+unsigned recur_item_inday(long, long, llist_t *, int, int, long, long);
+unsigned recur_apoint_inday(struct recur_apoint *, long);
+unsigned recur_event_inday(struct recur_event *, long);
+void recur_event_erase(long, unsigned, unsigned, enum eraseflg);
+void recur_apoint_erase(long, unsigned, unsigned, enum eraseflg);
+void recur_repeat_item(void);
+void recur_exc_scan(llist_t *, FILE *);
+struct notify_app *recur_apoint_check_next(struct notify_app *, long, long);
+struct recur_apoint *recur_get_apoint(long, int);
+struct recur_event *recur_get_event(long, int);
+void recur_apoint_switch_notify(long, int);
+void recur_event_paste_item(void);
+void recur_apoint_paste_item(void);
/* sigs.c */
-void sigs_init (void);
-unsigned sigs_set_hdlr (int, void (*)(int));
+void sigs_init(void);
+unsigned sigs_set_hdlr(int, void (*)(int));
/* todo.c */
extern llist_t todolist;
-void todo_hilt_set (int);
-void todo_hilt_decrease (void);
-void todo_hilt_increase (void);
-int todo_hilt (void);
-int todo_nb (void);
-void todo_set_nb (int);
-void todo_set_first (int);
-void todo_first_increase (void);
-void todo_first_decrease (void);
-int todo_hilt_pos (void);
-char *todo_saved_mesg (void);
-void todo_new_item (void);
-struct todo *todo_add (char *, int, char *);
-void todo_flag (void);
-void todo_delete (struct conf *);
-void todo_chg_priority (int);
-void todo_edit_item (void);
-void todo_update_panel (int);
-void todo_edit_note (char *);
-void todo_view_note (char *);
-void todo_init_list (void);
-void todo_free_list (void);
+void todo_hilt_set(int);
+void todo_hilt_decrease(int);
+void todo_hilt_increase(int);
+int todo_hilt(void);
+int todo_nb(void);
+void todo_set_nb(int);
+void todo_set_first(int);
+void todo_first_increase(int);
+void todo_first_decrease(int);
+int todo_hilt_pos(void);
+char *todo_saved_mesg(void);
+void todo_new_item(void);
+struct todo *todo_add(char *, int, char *);
+void todo_write(struct todo *, FILE *);
+void todo_flag(void);
+void todo_delete(void);
+void todo_chg_priority(int);
+void todo_edit_item(void);
+void todo_update_panel(int);
+void todo_edit_note(const char *);
+void todo_view_note(const char *);
+void todo_pipe_item(void);
+void todo_init_list(void);
+void todo_free_list(void);
+
+/* utf8.c */
+int utf8_width(char *);
+int utf8_strwidth(char *);
/* utils.c */
-void exit_calcurse (int) __attribute__((__noreturn__));
-void free_user_data (void);
-void fatalbox (const char *);
-void warnbox (const char *);
-void status_mesg (char *, char *);
-void erase_window_part (WINDOW *, int, int, int, int);
-WINDOW *popup (int, int, int, int, char *, char *, int);
-void print_in_middle (WINDOW *, int, int, int, char *);
-enum getstr getstring (WINDOW *, char *, int, int, int);
-int updatestring (WINDOW *, char **, int, int);
-int is_all_digit (char *);
-long get_item_time (long);
-int get_item_hour (long);
-int get_item_min (long);
-long date2sec (struct date, unsigned, unsigned);
-char *date_sec2date_str (long, char *);
-void date_sec2date_fmt (long, const char *, char *);
-long date_sec_change (long, int, int);
-long update_time_in_date (long, unsigned, unsigned);
-long get_sec_date (struct date);
-long min2sec (unsigned);
-int check_time (char *);
-void draw_scrollbar (WINDOW *, int, int, int, int, int, unsigned);
-void item_in_popup (char *, char *, char *, char *);
-long get_today (void);
-long now (void);
-char *nowstr (void);
-long mystrtol (const char *);
-void print_bool_option_incolor (WINDOW *, unsigned, int, int);
-const char *get_tempdir (void);
-char *new_tempfile (const char *, int);
-void erase_note (char **, enum eraseflg);
-int parse_date (char *, enum datefmt, int *, int *, int *,
- struct date *);
-void str_toupper (char *);
-void file_close (FILE *, const char *);
-void psleep (unsigned);
+void exit_calcurse(int) __attribute__ ((__noreturn__));
+void free_user_data(void);
+void fatalbox(const char *);
+void warnbox(const char *);
+void status_mesg(const char *, const char *);
+int status_ask_choice(const char *, const char[], int);
+int status_ask_bool(const char *);
+int status_ask_simplechoice(const char *, const char *[], int);
+void erase_window_part(WINDOW *, int, int, int, int);
+WINDOW *popup(int, int, int, int, const char *, const char *, int);
+void print_in_middle(WINDOW *, int, int, int, const char *);
+int is_all_digit(const char *);
+long get_item_time(long);
+int get_item_hour(long);
+int get_item_min(long);
+long date2sec(struct date, unsigned, unsigned);
+char *date_sec2date_str(long, const char *);
+void date_sec2date_fmt(long, const char *, char *);
+long date_sec_change(long, int, int);
+long update_time_in_date(long, unsigned, unsigned);
+long get_sec_date(struct date);
+long min2sec(unsigned);
+void draw_scrollbar(WINDOW *, int, int, int, int, int, unsigned);
+void item_in_popup(const char *, const char *, const char *, const char *);
+long get_today(void);
+long now(void);
+char *nowstr(void);
+long mystrtol(const char *);
+void print_bool_option_incolor(WINDOW *, unsigned, int, int);
+const char *get_tempdir(void);
+char *new_tempfile(const char *, int);
+int parse_date(const char *, enum datefmt, int *, int *, int *, struct date *);
+int parse_time(const char *, unsigned *, unsigned *);
+int parse_duration(const char *, unsigned *);
+void str_toupper(char *);
+void file_close(FILE *, const char *);
+void psleep(unsigned);
+int fork_exec(int *, int *, const char *, const char *const *);
+int shell_exec(int *, int *, const char *, const char *const *);
+int child_wait(int *, int *, int);
+void press_any_key(void);
+void print_apoint(const char *, long, struct apoint *);
+void print_event(const char *, long, struct event *);
+void print_recur_apoint(const char *, long, unsigned, struct recur_apoint *);
+void print_recur_event(const char *, long, struct recur_event *);
+void print_todo(const char *, struct todo *);
/* vars.c */
-extern int col, row;
-extern int resize;
-extern unsigned colorize;
-extern enum ui_mode ui_mode;
-extern int days[12];
-extern char *monthnames[12];
-extern char *daynames[8];
-extern char path_dir[BUFSIZ];
-extern char path_todo[BUFSIZ];
-extern char path_apts[BUFSIZ];
-extern char path_conf[BUFSIZ];
-extern char path_keys[BUFSIZ];
-extern char path_notes[BUFSIZ];
-extern char path_cpid[BUFSIZ];
-extern char path_dpid[BUFSIZ];
-extern char path_dmon_log[BUFSIZ];
-extern struct pad apad;
-extern struct nbar nbar;
-extern struct dmon_conf dmon;
-void vars_init (struct conf *);
+extern int col, row;
+extern int resize;
+extern unsigned colorize;
+extern int foreground, background;
+extern enum ui_mode ui_mode;
+extern int read_only;
+extern int days[12];
+extern const char *monthnames[12];
+extern const char *daynames[8];
+extern char path_dir[BUFSIZ];
+extern char path_todo[BUFSIZ];
+extern char path_apts[BUFSIZ];
+extern char path_conf[BUFSIZ];
+extern char path_keys[BUFSIZ];
+extern char path_notes[BUFSIZ];
+extern char path_cpid[BUFSIZ];
+extern char path_dpid[BUFSIZ];
+extern char path_dmon_log[BUFSIZ];
+extern struct conf conf;
+extern struct pad apad;
+extern struct nbar nbar;
+extern struct dmon_conf dmon;
+void vars_init(void);
/* wins.c */
extern struct window win[NBWINS];
-int wins_refresh (void);
-int wins_wrefresh (WINDOW *);
-int wins_doupdate (void);
-int wins_layout (void);
-void wins_set_layout (int);
-unsigned wins_sbar_width (void);
-unsigned wins_sbar_wperc (void);
-void wins_set_sbar_width (unsigned);
-void wins_sbar_winc (void);
-void wins_sbar_wdec (void);
-void wins_slctd_init (void);
-enum win wins_slctd (void);
-void wins_slctd_set (enum win);
-void wins_slctd_next (void);
-void wins_init (void);
-void wins_scrollwin_init (struct scrollwin *);
-void wins_scrollwin_delete (struct scrollwin *);
-void wins_scrollwin_display (struct scrollwin *);
-void wins_scrollwin_up (struct scrollwin *, int);
-void wins_scrollwin_down (struct scrollwin *, int);
-void wins_reinit (void);
-void wins_reinit_panels (void);
-void wins_show (WINDOW *, char *);
-void wins_get_config (void);
-void wins_update_border (void);
-void wins_update_panels (void);
-void wins_update (void);
-void wins_reset (void);
-void wins_launch_external (const char *, const char *);
-void wins_status_bar (void);
-void wins_erase_status_bar (void);
-void wins_other_status_page (int);
-void wins_reset_status_page (void);
+int wins_refresh(void);
+int wins_wrefresh(WINDOW *);
+int wins_doupdate(void);
+int wins_layout(void);
+void wins_set_layout(int);
+unsigned wins_sbar_width(void);
+unsigned wins_sbar_wperc(void);
+void wins_set_sbar_width(unsigned);
+void wins_sbar_winc(void);
+void wins_sbar_wdec(void);
+void wins_slctd_init(void);
+enum win wins_slctd(void);
+void wins_slctd_set(enum win);
+void wins_slctd_next(void);
+void wins_init(void);
+void wins_scrollwin_init(struct scrollwin *);
+void wins_scrollwin_delete(struct scrollwin *);
+void wins_scrollwin_display(struct scrollwin *);
+void wins_scrollwin_up(struct scrollwin *, int);
+void wins_scrollwin_down(struct scrollwin *, int);
+void wins_reinit(void);
+void wins_reinit_panels(void);
+void wins_show(WINDOW *, const char *);
+void wins_get_config(void);
+void wins_update_border(int);
+void wins_update_panels(int);
+void wins_update(int);
+void wins_reset(void);
+void wins_prepare_external(void);
+void wins_unprepare_external(void);
+void wins_launch_external(const char *, const char *);
+void wins_status_bar(void);
+void wins_erase_status_bar(void);
+void wins_other_status_page(int);
+void wins_reset_status_page(void);
#endif /* CALCURSE_H */
diff --git a/src/calendar.c b/src/calendar.c
index e303ab9..7328718 100644
--- a/src/calendar.c
+++ b/src/calendar.c
@@ -1,7 +1,7 @@
/*
* Calcurse - text-based organizer
*
- * Copyright (c) 2004-2011 calcurse Development Team <misc@calcurse.org>
+ * Copyright (c) 2004-2012 calcurse Development Team <misc@calcurse.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -48,12 +48,12 @@
#endif
#define EPOCH 90
-#define EPSILONg 279.403303 /* solar ecliptic long at EPOCH */
-#define RHOg 282.768422 /* solar ecliptic long of perigee at EPOCH */
-#define ECCEN 0.016713 /* solar orbit eccentricity */
-#define lzero 318.351648 /* lunar mean long at EPOCH */
-#define Pzero 36.340410 /* lunar mean long of perigee at EPOCH */
-#define Nzero 318.510107 /* lunar mean long of node at EPOCH */
+#define EPSILONg 279.403303 /* solar ecliptic long at EPOCH */
+#define RHOg 282.768422 /* solar ecliptic long of perigee at EPOCH */
+#define ECCEN 0.016713 /* solar orbit eccentricity */
+#define lzero 318.351648 /* lunar mean long at EPOCH */
+#define Pzero 36.340410 /* lunar mean long of perigee at EPOCH */
+#define Nzero 318.510107 /* lunar mean long of node at EPOCH */
#define ISLEAP(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
@@ -77,208 +77,184 @@ static unsigned calendar_view, week_begins_on_monday;
static pthread_mutex_t date_thread_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_t calendar_t_date;
-static void draw_monthly_view (struct window *, struct date *, unsigned);
-static void draw_weekly_view (struct window *, struct date *, unsigned);
+static void draw_monthly_view(struct window *, struct date *, unsigned);
+static void draw_weekly_view(struct window *, struct date *, unsigned);
static void (*draw_calendar[CAL_VIEWS]) (struct window *, struct date *,
- unsigned) =
- {draw_monthly_view, draw_weekly_view};
+ unsigned) = {
+draw_monthly_view, draw_weekly_view};
/* Switch between calendar views (monthly view is selected by default). */
-void
-calendar_view_next (void)
+void calendar_view_next(void)
{
calendar_view++;
if (calendar_view == CAL_VIEWS)
calendar_view = 0;
}
-void
-calendar_view_prev (void)
+void calendar_view_prev(void)
{
if (calendar_view == 0)
calendar_view = CAL_VIEWS;
calendar_view--;
}
-void
-calendar_set_view (int view)
+void calendar_set_view(int view)
{
calendar_view = (view < 0 || view >= CAL_VIEWS) ? CAL_MONTH_VIEW : view;
}
-int
-calendar_get_view (void)
+int calendar_get_view(void)
{
return (int)calendar_view;
}
/* Thread needed to update current date in calendar. */
/* ARGSUSED0 */
-static void *
-calendar_date_thread (void *arg)
+static void *calendar_date_thread(void *arg)
{
time_t actual, tomorrow;
- for (;;)
- {
- tomorrow = (time_t) (get_today () + DAYINSEC);
+ for (;;) {
+ tomorrow = (time_t) (get_today() + DAYINSEC);
- while ((actual = time (NULL)) < tomorrow)
- (void)sleep (tomorrow - actual);
+ while ((actual = time(NULL)) < tomorrow)
+ sleep(tomorrow - actual);
- calendar_set_current_date ();
- calendar_update_panel (&win[CAL]);
- }
+ calendar_set_current_date();
+ calendar_update_panel(&win[CAL]);
+ }
- return (void *)0;
+ return NULL;
}
/* Launch the calendar date thread. */
-void
-calendar_start_date_thread (void)
+void calendar_start_date_thread(void)
{
- pthread_create (&calendar_t_date, NULL, calendar_date_thread, NULL);
+ pthread_create(&calendar_t_date, NULL, calendar_date_thread, NULL);
}
/* Stop the calendar date thread. */
-void
-calendar_stop_date_thread (void)
+void calendar_stop_date_thread(void)
{
- if (calendar_t_date)
- {
- pthread_cancel (calendar_t_date);
- pthread_join (calendar_t_date, NULL);
- }
+ if (calendar_t_date) {
+ pthread_cancel(calendar_t_date);
+ pthread_join(calendar_t_date, NULL);
+ }
}
/* Set static variable today to current date */
-void
-calendar_set_current_date (void)
+void calendar_set_current_date(void)
{
time_t timer;
struct tm *tm;
- timer = time (NULL);
- tm = localtime (&timer);
+ timer = time(NULL);
+ tm = localtime(&timer);
- pthread_mutex_lock (&date_thread_mutex);
+ pthread_mutex_lock(&date_thread_mutex);
today.dd = tm->tm_mday;
today.mm = tm->tm_mon + 1;
today.yyyy = tm->tm_year + 1900;
- pthread_mutex_unlock (&date_thread_mutex);
+ pthread_mutex_unlock(&date_thread_mutex);
}
/* Needed to display sunday or monday as the first day of week in calendar. */
-void
-calendar_set_first_day_of_week (enum wday first_day)
-{
- switch (first_day)
- {
- case SUNDAY:
- week_begins_on_monday = 0;
- break;
- case MONDAY:
- week_begins_on_monday = 1;
- break;
- default:
- ERROR_MSG (_("ERROR setting first day of week"));
- week_begins_on_monday = 0;
- /* NOTREACHED */
- }
+void calendar_set_first_day_of_week(enum wday first_day)
+{
+ switch (first_day) {
+ case SUNDAY:
+ week_begins_on_monday = 0;
+ break;
+ case MONDAY:
+ week_begins_on_monday = 1;
+ break;
+ default:
+ ERROR_MSG(_("ERROR setting first day of week"));
+ week_begins_on_monday = 0;
+ /* NOTREACHED */
+ }
}
/* Swap first day of week in calendar. */
-void
-calendar_change_first_day_of_week (void)
+void calendar_change_first_day_of_week(void)
{
week_begins_on_monday = !week_begins_on_monday;
}
/* Return 1 if week begins on monday, 0 otherwise. */
-unsigned
-calendar_week_begins_on_monday (void)
+unsigned calendar_week_begins_on_monday(void)
{
- return (week_begins_on_monday);
+ return week_begins_on_monday;
}
/* Fill in the given variable with the current date. */
-void
-calendar_store_current_date (struct date *date)
+void calendar_store_current_date(struct date *date)
{
- pthread_mutex_lock (&date_thread_mutex);
+ pthread_mutex_lock(&date_thread_mutex);
*date = today;
- pthread_mutex_unlock (&date_thread_mutex);
+ pthread_mutex_unlock(&date_thread_mutex);
}
/* This is to start at the current date in calendar. */
-void
-calendar_init_slctd_day (void)
+void calendar_init_slctd_day(void)
{
- calendar_store_current_date (&slctd_day);
+ calendar_store_current_date(&slctd_day);
}
/* Return the selected day in calendar */
-struct date *
-calendar_get_slctd_day (void)
+struct date *calendar_get_slctd_day(void)
{
- return (&slctd_day);
+ return &slctd_day;
}
/* Returned value represents the selected day in calendar (in seconds) */
-long
-calendar_get_slctd_day_sec (void)
+long calendar_get_slctd_day_sec(void)
{
- return (date2sec (slctd_day, 0, 0));
+ return date2sec(slctd_day, 0, 0);
}
-static int
-calendar_get_wday (struct date *date)
+static int calendar_get_wday(struct date *date)
{
struct tm t;
- (void)memset (&t, 0, sizeof (struct tm));
+ memset(&t, 0, sizeof(struct tm));
t.tm_mday = date->dd;
t.tm_mon = date->mm - 1;
t.tm_year = date->yyyy - 1900;
- (void)mktime (&t);
+ mktime(&t);
return t.tm_wday;
}
-static unsigned
-months_to_days (unsigned month)
+static unsigned months_to_days(unsigned month)
{
- return ((month * 3057 - 3007) / 100);
+ return (month * 3057 - 3007) / 100;
}
-
-static long
-years_to_days (unsigned year)
+static long years_to_days(unsigned year)
{
- return (year * 365L + year / 4 - year / 100 + year / 400);
+ return year * 365L + year / 4 - year / 100 + year / 400;
}
-static long
-ymd_to_scalar (unsigned year, unsigned month, unsigned day)
+static long ymd_to_scalar(unsigned year, unsigned month, unsigned day)
{
long scalar;
- scalar = day + months_to_days (month);
+ scalar = day + months_to_days(month);
if (month > 2)
- scalar -= ISLEAP (year) ? 1 : 2;
+ scalar -= ISLEAP(year) ? 1 : 2;
year--;
- scalar += years_to_days (year);
+ scalar += years_to_days(year);
- return (scalar);
+ return scalar;
}
/*
* Used to change date by adding a certain amount of days or weeks.
* Returns 0 on success, 1 otherwise.
*/
-static int
-date_change (struct tm *date, int delta_month, int delta_day)
+static int date_change(struct tm *date, int delta_month, int delta_day)
{
struct tm t;
@@ -286,19 +262,18 @@ date_change (struct tm *date, int delta_month, int delta_day)
t.tm_mon += delta_month;
t.tm_mday += delta_day;
- if (mktime (&t) == -1)
- return (1);
- else
- {
- *date = t;
- return (0);
- }
+ if (mktime(&t) == -1)
+ return 1;
+ else {
+ *date = t;
+ return 0;
+ }
}
/* Draw the monthly view inside calendar panel. */
static void
-draw_monthly_view (struct window *cwin, struct date *current_day,
- unsigned sunday_first)
+draw_monthly_view(struct window *cwin, struct date *current_day,
+ unsigned sunday_first)
{
const int OFFY = 2 + (CALHEIGHT - 9) / 2;
struct date check_day;
@@ -311,106 +286,92 @@ draw_monthly_view (struct window *cwin, struct date *current_day,
yr = slctd_day.yyyy;
/* offset for centering calendar in window */
- SBAR_WIDTH = wins_sbar_width ();
+ SBAR_WIDTH = wins_sbar_width();
OFFX = (SBAR_WIDTH - 27) / 2;
ofs_y = OFFY;
ofs_x = OFFX;
/* checking the number of days in february */
numdays = days[mo - 1];
- if (2 == mo && ISLEAP (yr))
+ if (2 == mo && ISLEAP(yr))
++numdays;
/*
* the first calendar day will be monday or sunday, depending on
* 'week_begins_on_monday' value
*/
- c_day_1 = (int) ((ymd_to_scalar (yr, mo, 1 + sunday_first) - (long) 1) % 7L);
+ c_day_1 = (int)((ymd_to_scalar(yr, mo, 1 + sunday_first) - (long)1) % 7L);
/* Write the current month and year on top of the calendar */
- custom_apply_attr (cwin->p, ATTR_HIGHEST);
- mvwprintw (cwin->p, ofs_y,
- (SBAR_WIDTH - (strlen (_(monthnames[mo - 1])) + 5)) / 2,
- "%s %d", _(monthnames[mo - 1]), slctd_day.yyyy);
- custom_remove_attr (cwin->p, ATTR_HIGHEST);
+ custom_apply_attr(cwin->p, ATTR_HIGHEST);
+ mvwprintw(cwin->p, ofs_y,
+ (SBAR_WIDTH - (strlen(_(monthnames[mo - 1])) + 5)) / 2,
+ "%s %d", _(monthnames[mo - 1]), slctd_day.yyyy);
+ custom_remove_attr(cwin->p, ATTR_HIGHEST);
++ofs_y;
/* print the days, with regards to the first day of the week */
- custom_apply_attr (cwin->p, ATTR_HIGHEST);
- for (j = 0; j < WEEKINDAYS; j++)
- {
- mvwprintw (cwin->p, ofs_y, ofs_x + 4 * j, "%s",
- _(daynames[1 + j - sunday_first]));
- }
- custom_remove_attr (cwin->p, ATTR_HIGHEST);
+ custom_apply_attr(cwin->p, ATTR_HIGHEST);
+ for (j = 0; j < WEEKINDAYS; j++) {
+ mvwprintw(cwin->p, ofs_y, ofs_x + 4 * j, "%s",
+ _(daynames[1 + j - sunday_first]));
+ }
+ custom_remove_attr(cwin->p, ATTR_HIGHEST);
day_1_sav = (c_day_1 + 1) * 3 + c_day_1 - 7;
- for (c_day = 1; c_day <= numdays; ++c_day, ++c_day_1, c_day_1 %= 7)
- {
- check_day.dd = c_day;
- check_day.mm = slctd_day.mm;
- check_day.yyyy = slctd_day.yyyy;
-
- /* check if the day contains an event or an appointment */
- item_this_day = day_check_if_item (check_day);
+ for (c_day = 1; c_day <= numdays; ++c_day, ++c_day_1, c_day_1 %= 7) {
+ check_day.dd = c_day;
+ check_day.mm = slctd_day.mm;
+ check_day.yyyy = slctd_day.yyyy;
- /* Go to next line, the week is over. */
- if (!c_day_1 && 1 != c_day)
- {
- ofs_y++;
- ofs_x = OFFX - day_1_sav - 4 * c_day;
- }
+ /* check if the day contains an event or an appointment */
+ item_this_day = day_check_if_item(check_day);
- /* This is today, so print it in yellow. */
- if (c_day == current_day->dd
- && current_day->mm == slctd_day.mm
- && current_day->yyyy == slctd_day.yyyy
- && current_day->dd != slctd_day.dd)
- {
- custom_apply_attr (cwin->p, ATTR_LOWEST);
- mvwprintw (cwin->p, ofs_y + 1,
- ofs_x + day_1_sav + 4 * c_day + 1, "%2d", c_day);
- custom_remove_attr (cwin->p, ATTR_LOWEST);
- }
- else if (c_day == slctd_day.dd)
- {
- /* This is the selected day, print it according to user's theme. */
- custom_apply_attr (cwin->p, ATTR_HIGHEST);
- mvwprintw (cwin->p, ofs_y + 1,
- ofs_x + day_1_sav + 4 * c_day + 1, "%2d",
- c_day);
- custom_remove_attr (cwin->p, ATTR_HIGHEST);
- }
- else if (item_this_day)
- {
- custom_apply_attr (cwin->p, ATTR_LOW);
- mvwprintw (cwin->p, ofs_y + 1,
- ofs_x + day_1_sav + 4 * c_day + 1, "%2d",
- c_day);
- custom_remove_attr (cwin->p, ATTR_LOW);
- }
- else
- /* otherwise, print normal days in black */
- mvwprintw (cwin->p, ofs_y + 1,
- ofs_x + day_1_sav + 4 * c_day + 1, "%2d",
- c_day);
+ /* Go to next line, the week is over. */
+ if (!c_day_1 && 1 != c_day) {
+ ofs_y++;
+ ofs_x = OFFX - day_1_sav - 4 * c_day;
}
-}
-static int
-weeknum (const struct tm *t, int firstweekday)
+ /* This is today, so print it in yellow. */
+ if (c_day == current_day->dd
+ && current_day->mm == slctd_day.mm
+ && current_day->yyyy == slctd_day.yyyy
+ && current_day->dd != slctd_day.dd) {
+ custom_apply_attr(cwin->p, ATTR_LOWEST);
+ mvwprintw(cwin->p, ofs_y + 1,
+ ofs_x + day_1_sav + 4 * c_day + 1, "%2d", c_day);
+ custom_remove_attr(cwin->p, ATTR_LOWEST);
+ } else if (c_day == slctd_day.dd) {
+ /* This is the selected day, print it according to user's theme. */
+ custom_apply_attr(cwin->p, ATTR_HIGHEST);
+ mvwprintw(cwin->p, ofs_y + 1,
+ ofs_x + day_1_sav + 4 * c_day + 1, "%2d", c_day);
+ custom_remove_attr(cwin->p, ATTR_HIGHEST);
+ } else if (item_this_day) {
+ custom_apply_attr(cwin->p, ATTR_LOW);
+ mvwprintw(cwin->p, ofs_y + 1,
+ ofs_x + day_1_sav + 4 * c_day + 1, "%2d", c_day);
+ custom_remove_attr(cwin->p, ATTR_LOW);
+ } else
+ /* otherwise, print normal days in black */
+ mvwprintw(cwin->p, ofs_y + 1,
+ ofs_x + day_1_sav + 4 * c_day + 1, "%2d", c_day);
+ }
+}
+
+static int weeknum(const struct tm *t, int firstweekday)
{
int wday, wnum;
wday = t->tm_wday;
- if (firstweekday == MONDAY)
- {
- if (wday == SUNDAY)
- wday = 6;
- else
- wday--;
- }
+ if (firstweekday == MONDAY) {
+ if (wday == SUNDAY)
+ wday = 6;
+ else
+ wday--;
+ }
wnum = ((t->tm_yday + WEEKINDAYS - wday) / WEEKINDAYS);
if (wnum < 0)
wnum = 0;
@@ -421,64 +382,60 @@ weeknum (const struct tm *t, int firstweekday)
/*
* Compute the week number according to ISO 8601.
*/
-static int
-ISO8601weeknum (const struct tm *t)
+static int ISO8601weeknum(const struct tm *t)
{
int wnum, jan1day;
- wnum = weeknum (t, MONDAY);
+ wnum = weeknum(t, MONDAY);
jan1day = t->tm_wday - (t->tm_yday % WEEKINDAYS);
if (jan1day < 0)
jan1day += WEEKINDAYS;
- switch (jan1day)
- {
- case MONDAY:
- break;
- case TUESDAY:
- case WEDNESDAY:
- case THURSDAY:
- wnum++;
- break;
- case FRIDAY:
- case SATURDAY:
- case SUNDAY:
- if (wnum == 0)
- {
- /* Get week number of last week of last year. */
- struct tm dec31ly; /* 12/31 last year */
-
- dec31ly = *t;
- dec31ly.tm_year--;
- dec31ly.tm_mon = 11;
- dec31ly.tm_mday = 31;
- dec31ly.tm_wday = (jan1day == SUNDAY) ? 6 : jan1day - 1;
- dec31ly.tm_yday = 364 + ISLEAP (dec31ly.tm_year + 1900);
- wnum = ISO8601weeknum (&dec31ly);
- }
- break;
+ switch (jan1day) {
+ case MONDAY:
+ break;
+ case TUESDAY:
+ case WEDNESDAY:
+ case THURSDAY:
+ wnum++;
+ break;
+ case FRIDAY:
+ case SATURDAY:
+ case SUNDAY:
+ if (wnum == 0) {
+ /* Get week number of last week of last year. */
+ struct tm dec31ly; /* 12/31 last year */
+
+ dec31ly = *t;
+ dec31ly.tm_year--;
+ dec31ly.tm_mon = 11;
+ dec31ly.tm_mday = 31;
+ dec31ly.tm_wday = (jan1day == SUNDAY) ? 6 : jan1day - 1;
+ dec31ly.tm_yday = 364 + ISLEAP(dec31ly.tm_year + 1900);
+ wnum = ISO8601weeknum(&dec31ly);
}
+ break;
+ }
- if (t->tm_mon == 11)
- {
- int wday, mday;
+ if (t->tm_mon == 11) {
+ int wday, mday;
- wday = t->tm_wday;
- mday = t->tm_mday;
- if ((wday == MONDAY && (mday >= 29 && mday <= 31))
- || (wday == TUESDAY && (mday == 30 || mday == 31))
- || (wday == WEDNESDAY && mday == 31))
- wnum = 1;
- }
+ wday = t->tm_wday;
+ mday = t->tm_mday;
+ if ((wday == MONDAY && (mday >= 29 && mday <= 31))
+ || (wday == TUESDAY && (mday == 30 || mday == 31))
+ || (wday == WEDNESDAY && mday == 31))
+ wnum = 1;
+ }
return wnum;
}
/* Draw the weekly view inside calendar panel. */
static void
-draw_weekly_view (struct window *cwin, struct date *current_day,
- unsigned sunday_first)
+draw_weekly_view(struct window *cwin, struct date *current_day,
+ unsigned sunday_first)
{
#define DAYSLICESNO 6
const int WCALWIDTH = 30;
@@ -486,129 +443,123 @@ draw_weekly_view (struct window *cwin, struct date *current_day,
struct tm t;
int OFFX, j, c_wday, days_to_remove, weeknum;
- OFFX = (wins_sbar_width () - WCALWIDTH) / 2 + 1;
+ OFFX = (wins_sbar_width() - WCALWIDTH) / 2 + 1;
/* Fill in a tm structure with the first day of the selected week. */
- c_wday = calendar_get_wday (&slctd_day);
+ c_wday = calendar_get_wday(&slctd_day);
if (sunday_first)
days_to_remove = c_wday;
else
days_to_remove = c_wday == 0 ? WEEKINDAYS - 1 : c_wday - 1;
- (void)memset (&t, 0, sizeof (struct tm));
+ memset(&t, 0, sizeof(struct tm));
t.tm_mday = slctd_day.dd;
t.tm_mon = slctd_day.mm - 1;
t.tm_year = slctd_day.yyyy - 1900;
- (void)mktime (&t);
- (void)date_change (&t, 0, -days_to_remove);
+ mktime(&t);
+ date_change(&t, 0, -days_to_remove);
/* Print the week number. */
- weeknum = ISO8601weeknum (&t);
- custom_apply_attr (cwin->p, ATTR_HIGHEST);
- mvwprintw (cwin->p, 2, cwin->w - 9, "(# %02d)", weeknum);
- custom_remove_attr (cwin->p, ATTR_HIGHEST);
+ weeknum = ISO8601weeknum(&t);
+ custom_apply_attr(cwin->p, ATTR_HIGHEST);
+ mvwprintw(cwin->p, 2, cwin->w - 9, "(# %02d)", weeknum);
+ custom_remove_attr(cwin->p, ATTR_HIGHEST);
/* Now draw calendar view. */
- for (j = 0; j < WEEKINDAYS; j++)
- {
- struct date date;
- unsigned attr, item_this_day;
- int i, slices[DAYSLICESNO];
-
- /* print the day names, with regards to the first day of the week */
- custom_apply_attr (cwin->p, ATTR_HIGHEST);
- mvwprintw (cwin->p, OFFY, OFFX + 4 * j, "%s",
- _(daynames[1 + j - sunday_first]));
- custom_remove_attr (cwin->p, ATTR_HIGHEST);
-
- /* Check if the day to be printed has an item or not. */
- date.dd = t.tm_mday;
- date.mm = t.tm_mon + 1;
- date.yyyy = t.tm_year + 1900;
- item_this_day = day_check_if_item (date);
-
- /* Print the day numbers with appropriate decoration. */
- if (t.tm_mday == current_day->dd
- && current_day->mm == slctd_day.mm
- && current_day->yyyy == slctd_day.yyyy
- && current_day->dd != slctd_day.dd)
- attr = ATTR_LOWEST; /* today, but not selected */
- else if (t.tm_mday == slctd_day.dd)
- attr = ATTR_HIGHEST; /* selected day */
- else if (item_this_day)
- attr = ATTR_LOW;
- else
- attr = 0;
-
- if (attr)
- custom_apply_attr (cwin->p, attr);
- mvwprintw (cwin->p, OFFY + 1, OFFX + 1 + 4 * j, "%02d", t.tm_mday);
- if (attr)
- custom_remove_attr (cwin->p, attr);
-
- /* Draw slices indicating appointment times. */
- bzero (slices, DAYSLICESNO * sizeof *slices);
- if (day_chk_busy_slices (date, DAYSLICESNO, slices))
- {
- for (i = 0; i < DAYSLICESNO; i++)
- {
- if (j != WEEKINDAYS - 1 && i != DAYSLICESNO - 1)
- mvwhline (cwin->p, OFFY + 2 + i, OFFX + 3 + 4 * j, ACS_S9, 2);
- if (slices[i])
- {
- int highlight;
-
- highlight = (t.tm_mday == slctd_day.dd) ? 1 : 0;
- if (highlight)
- custom_apply_attr (cwin->p, attr);
- wattron (cwin->p, A_REVERSE);
- mvwprintw (cwin->p, OFFY + 2 + i, OFFX + 1 + 4 * j, " ");
- mvwprintw (cwin->p, OFFY + 2 + i, OFFX + 2 + 4 * j, " ");
- wattroff (cwin->p, A_REVERSE);
- if (highlight)
- custom_remove_attr (cwin->p, attr);
- }
- }
+ for (j = 0; j < WEEKINDAYS; j++) {
+ struct date date;
+ unsigned attr, item_this_day;
+ int i, slices[DAYSLICESNO];
+
+ /* print the day names, with regards to the first day of the week */
+ custom_apply_attr(cwin->p, ATTR_HIGHEST);
+ mvwprintw(cwin->p, OFFY, OFFX + 4 * j, "%s",
+ _(daynames[1 + j - sunday_first]));
+ custom_remove_attr(cwin->p, ATTR_HIGHEST);
+
+ /* Check if the day to be printed has an item or not. */
+ date.dd = t.tm_mday;
+ date.mm = t.tm_mon + 1;
+ date.yyyy = t.tm_year + 1900;
+ item_this_day = day_check_if_item(date);
+
+ /* Print the day numbers with appropriate decoration. */
+ if (t.tm_mday == current_day->dd
+ && current_day->mm == slctd_day.mm
+ && current_day->yyyy == slctd_day.yyyy
+ && current_day->dd != slctd_day.dd)
+ attr = ATTR_LOWEST; /* today, but not selected */
+ else if (t.tm_mday == slctd_day.dd)
+ attr = ATTR_HIGHEST; /* selected day */
+ else if (item_this_day)
+ attr = ATTR_LOW;
+ else
+ attr = 0;
+
+ if (attr)
+ custom_apply_attr(cwin->p, attr);
+ mvwprintw(cwin->p, OFFY + 1, OFFX + 1 + 4 * j, "%02d", t.tm_mday);
+ if (attr)
+ custom_remove_attr(cwin->p, attr);
+
+ /* Draw slices indicating appointment times. */
+ memset(slices, 0, DAYSLICESNO * sizeof *slices);
+ if (day_chk_busy_slices(date, DAYSLICESNO, slices)) {
+ for (i = 0; i < DAYSLICESNO; i++) {
+ if (j != WEEKINDAYS - 1 && i != DAYSLICESNO - 1)
+ mvwhline(cwin->p, OFFY + 2 + i, OFFX + 3 + 4 * j, ACS_S9, 2);
+ if (slices[i]) {
+ int highlight;
+
+ highlight = (t.tm_mday == slctd_day.dd) ? 1 : 0;
+ if (highlight)
+ custom_apply_attr(cwin->p, attr);
+ wattron(cwin->p, A_REVERSE);
+ mvwprintw(cwin->p, OFFY + 2 + i, OFFX + 1 + 4 * j, " ");
+ mvwprintw(cwin->p, OFFY + 2 + i, OFFX + 2 + 4 * j, " ");
+ wattroff(cwin->p, A_REVERSE);
+ if (highlight)
+ custom_remove_attr(cwin->p, attr);
}
-
- /* get next day */
- (void)date_change (&t, 0, 1);
+ }
}
+ /* get next day */
+ date_change(&t, 0, 1);
+ }
+
/* Draw marks to indicate midday on the sides of the calendar. */
- custom_apply_attr (cwin->p, ATTR_HIGHEST);
- mvwhline (cwin->p, OFFY + 1 + DAYSLICESNO / 2, OFFX, ACS_S9, 1);
- mvwhline (cwin->p, OFFY + 1 + DAYSLICESNO / 2,
- OFFX + WCALWIDTH - 3, ACS_S9, 1);
- custom_remove_attr (cwin->p, ATTR_HIGHEST);
+ custom_apply_attr(cwin->p, ATTR_HIGHEST);
+ mvwhline(cwin->p, OFFY + 1 + DAYSLICESNO / 2, OFFX, ACS_S9, 1);
+ mvwhline(cwin->p, OFFY + 1 + DAYSLICESNO / 2,
+ OFFX + WCALWIDTH - 3, ACS_S9, 1);
+ custom_remove_attr(cwin->p, ATTR_HIGHEST);
#undef DAYSLICESNO
}
/* Function used to display the calendar panel. */
-void
-calendar_update_panel (struct window *cwin)
+void calendar_update_panel(struct window *cwin)
{
struct date current_day;
unsigned sunday_first;
- calendar_store_current_date (&current_day);
- erase_window_part (cwin->p, 1, 3, cwin->w - 2, cwin->h - 2);
- mvwhline (cwin->p, 2, 1, ACS_HLINE, cwin->w - 2);
- sunday_first = calendar_week_begins_on_monday () ? 0 : 1;
+ calendar_store_current_date(&current_day);
+ erase_window_part(cwin->p, 1, 3, cwin->w - 2, cwin->h - 2);
+ mvwhline(cwin->p, 2, 1, ACS_HLINE, cwin->w - 2);
+ sunday_first = calendar_week_begins_on_monday()? 0 : 1;
draw_calendar[calendar_view] (cwin, &current_day, sunday_first);
- wnoutrefresh (cwin->p);
+ wnoutrefresh(cwin->p);
}
/* Set the selected day in calendar to current day. */
-void
-calendar_goto_today (void)
+void calendar_goto_today(void)
{
struct date today;
- calendar_store_current_date (&today);
+ calendar_store_current_date(&today);
slctd_day.dd = today.dd;
slctd_day.mm = today.mm;
slctd_day.yyyy = today.yyyy;
@@ -620,154 +571,143 @@ calendar_goto_today (void)
* If the entered date is empty, automatically jump to the current date.
* slctd_day is updated with the newly selected date.
*/
-void
-calendar_change_day (int datefmt)
+void calendar_change_day(int datefmt)
{
#define LDAY 11
char selected_day[LDAY] = "";
char outstr[BUFSIZ];
int dday, dmonth, dyear;
int wrong_day = 1;
- char *mesg_line1 =
- _("The day you entered is not valid "
- "(should be between 01/01/1902 and 12/31/2037)");
- char *mesg_line2 = _("Press [ENTER] to continue");
- char *request_date = "Enter the day to go to [ENTER for today] : %s";
-
- while (wrong_day)
- {
- (void)snprintf (outstr, BUFSIZ, request_date, DATEFMT_DESC (datefmt));
- status_mesg (_(outstr), "");
- if (getstring (win[STA].p, selected_day, LDAY, 0, 1) == GETSTRING_ESC)
- return;
- else
- {
- if (strlen (selected_day) == 0)
- {
- wrong_day = 0;
- calendar_goto_today ();
- }
- else if (parse_date (selected_day, datefmt, &dyear, &dmonth, &dday,
- calendar_get_slctd_day ()))
- {
- wrong_day = 0;
- /* go to chosen day */
- slctd_day.dd = dday;
- slctd_day.mm = dmonth;
- slctd_day.yyyy = dyear;
- }
- if (wrong_day)
- {
- status_mesg (mesg_line1, mesg_line2);
- (void)wgetch (win[STA].p);
- }
- }
+ const char *mesg_line1 =
+ _("The day you entered is not valid "
+ "(should be between 01/01/1902 and 12/31/2037)");
+ const char *mesg_line2 = _("Press [ENTER] to continue");
+ const char *request_date = "Enter the day to go to [ENTER for today] : %s";
+
+ while (wrong_day) {
+ snprintf(outstr, BUFSIZ, request_date, DATEFMT_DESC(datefmt));
+ status_mesg(_(outstr), "");
+ if (getstring(win[STA].p, selected_day, LDAY, 0, 1) == GETSTRING_ESC)
+ return;
+ else {
+ if (strlen(selected_day) == 0) {
+ wrong_day = 0;
+ calendar_goto_today();
+ } else if (parse_date(selected_day, datefmt, &dyear, &dmonth, &dday,
+ calendar_get_slctd_day())) {
+ wrong_day = 0;
+ /* go to chosen day */
+ slctd_day.dd = dday;
+ slctd_day.mm = dmonth;
+ slctd_day.yyyy = dyear;
+ }
+ if (wrong_day) {
+ status_mesg(mesg_line1, mesg_line2);
+ wgetch(win[STA].p);
+ }
}
+ }
return;
}
-void
-calendar_move (enum move move)
+void calendar_move(enum move move, int count)
{
int ret, days_to_remove, days_to_add;
struct tm t;
- (void)memset (&t, 0, sizeof (struct tm));
+ memset(&t, 0, sizeof(struct tm));
t.tm_mday = slctd_day.dd;
t.tm_mon = slctd_day.mm - 1;
t.tm_year = slctd_day.yyyy - 1900;
- switch (move)
- {
- case UP:
- if ((slctd_day.dd <= 7) && (slctd_day.mm == 1)
- && (slctd_day.yyyy == 1902))
- return;
- ret = date_change (&t, 0, -WEEKINDAYS);
- break;
- case DOWN:
- if ((slctd_day.dd > days[slctd_day.mm - 1] - 7)
- && (slctd_day.mm == 12) && (slctd_day.yyyy == 2037))
- return;
- ret = date_change (&t, 0, WEEKINDAYS);
- break;
- case LEFT:
- if ((slctd_day.dd == 1) && (slctd_day.mm == 1)
- && (slctd_day.yyyy == 1902))
- return;
- ret = date_change (&t, 0, -1);
- break;
- case RIGHT:
- if ((slctd_day.dd == 31) && (slctd_day.mm == 12)
- && (slctd_day.yyyy == 2037))
- return;
- ret = date_change (&t, 0, 1);
- break;
- case WEEK_START:
- /* Normalize struct tm to get week day number. */
- (void)mktime (&t);
- if (calendar_week_begins_on_monday ())
- days_to_remove = ((t.tm_wday == 0) ? WEEKINDAYS - 1 : t.tm_wday - 1);
- else
- days_to_remove = ((t.tm_wday == 0) ? 0 : t.tm_wday);
- ret = date_change (&t, 0, 0 - days_to_remove);
- break;
- case WEEK_END:
- (void)mktime (&t);
- if (calendar_week_begins_on_monday ())
- days_to_add = ((t.tm_wday == 0) ? 0 : WEEKINDAYS - t.tm_wday);
- else
- days_to_add = ((t.tm_wday == 0) ?
- WEEKINDAYS - 1 : WEEKINDAYS - 1 - t.tm_wday);
- ret = date_change (&t, 0, days_to_add);
- break;
- default:
- ret = 1;
- /* NOTREACHED */
- }
- if (ret == 0)
- {
- slctd_day.dd = t.tm_mday;
- slctd_day.mm = t.tm_mon + 1;
- slctd_day.yyyy = t.tm_year + 1900;
+ switch (move) {
+ case UP:
+ ret = date_change(&t, 0, -count * WEEKINDAYS);
+ break;
+ case DOWN:
+ ret = date_change(&t, 0, count * WEEKINDAYS);
+ break;
+ case LEFT:
+ ret = date_change(&t, 0, -count);
+ break;
+ case RIGHT:
+ ret = date_change(&t, 0, count);
+ break;
+ case WEEK_START:
+ /* Normalize struct tm to get week day number. */
+ mktime(&t);
+ if (calendar_week_begins_on_monday())
+ days_to_remove = ((t.tm_wday == 0) ? WEEKINDAYS - 1 : t.tm_wday - 1);
+ else
+ days_to_remove = ((t.tm_wday == 0) ? 0 : t.tm_wday);
+ days_to_remove += (count - 1) * WEEKINDAYS;
+ ret = date_change(&t, 0, -days_to_remove);
+ break;
+ case WEEK_END:
+ mktime(&t);
+ if (calendar_week_begins_on_monday())
+ days_to_add = ((t.tm_wday == 0) ? 0 : WEEKINDAYS - t.tm_wday);
+ else
+ days_to_add = ((t.tm_wday == 0) ?
+ WEEKINDAYS - 1 : WEEKINDAYS - 1 - t.tm_wday);
+ days_to_add += (count - 1) * WEEKINDAYS;
+ ret = date_change(&t, 0, days_to_add);
+ break;
+ default:
+ ret = 1;
+ /* NOTREACHED */
+ }
+
+ if (ret == 0) {
+ if (t.tm_year < 2) {
+ t.tm_mday = 1;
+ t.tm_mon = 0;
+ t.tm_year = 2;
+ } else if (t.tm_year > 137) {
+ t.tm_mday = 31;
+ t.tm_mon = 11;
+ t.tm_year = 137;
}
+
+ slctd_day.dd = t.tm_mday;
+ slctd_day.mm = t.tm_mon + 1;
+ slctd_day.yyyy = t.tm_year + 1900;
+ }
}
/* Returns the beginning of current year as a long. */
-long
-calendar_start_of_year (void)
+long calendar_start_of_year(void)
{
time_t timer;
struct tm *tm;
- timer = time (NULL);
- tm = localtime (&timer);
+ timer = time(NULL);
+ tm = localtime(&timer);
tm->tm_mon = 0;
tm->tm_mday = 1;
tm->tm_hour = 0;
tm->tm_min = 0;
tm->tm_sec = 0;
- timer = mktime (tm);
+ timer = mktime(tm);
return (long)timer;
}
-long
-calendar_end_of_year (void)
+long calendar_end_of_year(void)
{
time_t timer;
struct tm *tm;
- timer = time (NULL);
- tm = localtime (&timer);
+ timer = time(NULL);
+ tm = localtime(&timer);
tm->tm_mon = 0;
tm->tm_mday = 1;
tm->tm_hour = 0;
tm->tm_min = 0;
tm->tm_sec = 0;
tm->tm_year++;
- timer = mktime (tm);
+ timer = mktime(tm);
return (long)(timer - 1);
}
@@ -813,18 +753,16 @@ calendar_end_of_year (void)
* dtor --
* convert degrees to radians
*/
-static double
-dtor (double deg)
+static double dtor(double deg)
{
- return (deg * M_PI / 180);
+ return deg * M_PI / 180;
}
/*
* adj360 --
* adjust value so 0 <= deg <= 360
*/
-static void
-adj360 (double *deg)
+static void adj360(double *deg)
{
for (;;)
if (*deg < 0.0)
@@ -839,36 +777,35 @@ adj360 (double *deg)
* potm --
* return phase of the moon
*/
-static double
-potm (double days)
+static double potm(double days)
{
double N, Msol, Ec, LambdaSol, l, Mm, Ev, Ac, A3, Mmprime;
double A4, lprime, V, ldprime, D, Nm;
- N = 360.0 * days / 365.242191; /* sec 46 #3 */
- adj360 (&N);
- Msol = N + EPSILONg - RHOg; /* sec 46 #4 */
- adj360 (&Msol);
- Ec = 360 / M_PI * ECCEN * sin (dtor (Msol)); /* sec 46 #5 */
- LambdaSol = N + Ec + EPSILONg; /* sec 46 #6 */
- adj360 (&LambdaSol);
- l = 13.1763966 * days + lzero; /* sec 65 #4 */
- adj360 (&l);
- Mm = l - (0.1114041 * days) - Pzero; /* sec 65 #5 */
- adj360 (&Mm);
- Nm = Nzero - (0.0529539 * days); /* sec 65 #6 */
- adj360 (&Nm);
- Ev = 1.2739 * sin (dtor (2 * (l - LambdaSol) - Mm)); /* sec 65 #7 */
- Ac = 0.1858 * sin (dtor (Msol)); /* sec 65 #8 */
- A3 = 0.37 * sin (dtor (Msol));
- Mmprime = Mm + Ev - Ac - A3; /* sec 65 #9 */
- Ec = 6.2886 * sin (dtor (Mmprime)); /* sec 65 #10 */
- A4 = 0.214 * sin (dtor (2 * Mmprime)); /* sec 65 #11 */
- lprime = l + Ev + Ec - Ac + A4; /* sec 65 #12 */
- V = 0.6583 * sin (dtor (2 * (lprime - LambdaSol))); /* sec 65 #13 */
- ldprime = lprime + V; /* sec 65 #14 */
- D = ldprime - LambdaSol; /* sec 67 #2 */
- return (50.0 * (1 - cos (dtor (D)))); /* sec 67 #3 */
+ N = 360.0 * days / 365.242191; /* sec 46 #3 */
+ adj360(&N);
+ Msol = N + EPSILONg - RHOg; /* sec 46 #4 */
+ adj360(&Msol);
+ Ec = 360 / M_PI * ECCEN * sin(dtor(Msol)); /* sec 46 #5 */
+ LambdaSol = N + Ec + EPSILONg; /* sec 46 #6 */
+ adj360(&LambdaSol);
+ l = 13.1763966 * days + lzero; /* sec 65 #4 */
+ adj360(&l);
+ Mm = l - (0.1114041 * days) - Pzero; /* sec 65 #5 */
+ adj360(&Mm);
+ Nm = Nzero - (0.0529539 * days); /* sec 65 #6 */
+ adj360(&Nm);
+ Ev = 1.2739 * sin(dtor(2 * (l - LambdaSol) - Mm)); /* sec 65 #7 */
+ Ac = 0.1858 * sin(dtor(Msol)); /* sec 65 #8 */
+ A3 = 0.37 * sin(dtor(Msol));
+ Mmprime = Mm + Ev - Ac - A3; /* sec 65 #9 */
+ Ec = 6.2886 * sin(dtor(Mmprime)); /* sec 65 #10 */
+ A4 = 0.214 * sin(dtor(2 * Mmprime)); /* sec 65 #11 */
+ lprime = l + Ev + Ec - Ac + A4; /* sec 65 #12 */
+ V = 0.6583 * sin(dtor(2 * (lprime - LambdaSol))); /* sec 65 #13 */
+ ldprime = lprime + V; /* sec 65 #14 */
+ D = ldprime - LambdaSol; /* sec 67 #2 */
+ return 50.0 * (1 - cos(dtor(D))); /* sec 67 #3 */
}
/*
@@ -882,23 +819,22 @@ potm (double days)
* Updated to the Third Edition of Duffett-Smith's book, IX 1998
*
*/
-static double
-pom (time_t tmpt)
+static double pom(time_t tmpt)
{
struct tm *GMT;
double days;
int cnt;
- GMT = gmtime (&tmpt);
+ GMT = gmtime(&tmpt);
days = (GMT->tm_yday + 1) + ((GMT->tm_hour + (GMT->tm_min / 60.0) +
(GMT->tm_sec / 3600.0)) / 24.0);
for (cnt = EPOCH; cnt < GMT->tm_year; ++cnt)
- days += ISLEAP (cnt + TM_YEAR_BASE) ? 366 : 365;
+ days += ISLEAP(cnt + TM_YEAR_BASE) ? 366 : 365;
/* Selected time could be before EPOCH */
for (cnt = GMT->tm_year; cnt < EPOCH; ++cnt)
- days -= ISLEAP (cnt + TM_YEAR_BASE) ? 366 : 365;
+ days -= ISLEAP(cnt + TM_YEAR_BASE) ? 366 : 365;
- return (potm (days));
+ return potm(days);
}
/*
@@ -906,25 +842,24 @@ pom (time_t tmpt)
* Careful: date is the selected day in calendar at 00:00, so it represents
* the phase of the moon for previous day.
*/
-char *
-calendar_get_pom (time_t date)
+const char *calendar_get_pom(time_t date)
{
- char *pom_pict[MOON_PHASES] = { " ", "|) ", "(|)", "(| ", " | " };
+ const char *pom_pict[MOON_PHASES] = { " ", "|) ", "(|)", "(| ", " | " };
enum pom phase = NO_POM;
double pom_today, relative_pom, pom_yesterday, pom_tomorrow;
const double half = 50.0;
- pom_yesterday = pom (date);
- pom_today = pom (date + DAYINSEC);
- relative_pom = abs (pom_today - half);
- pom_tomorrow = pom (date + 2 * DAYINSEC);
+ pom_yesterday = pom(date);
+ pom_today = pom(date + DAYINSEC);
+ relative_pom = abs(pom_today - half);
+ pom_tomorrow = pom(date + 2 * DAYINSEC);
if (pom_today > pom_yesterday && pom_today > pom_tomorrow)
phase = FULL_MOON;
else if (pom_today < pom_yesterday && pom_today < pom_tomorrow)
phase = NEW_MOON;
- else if (relative_pom < abs (pom_yesterday - half)
- && relative_pom < abs (pom_tomorrow - half))
+ else if (relative_pom < abs(pom_yesterday - half)
+ && relative_pom < abs(pom_tomorrow - half))
phase = (pom_tomorrow > pom_today) ? FIRST_QUARTER : LAST_QUARTER;
- return (pom_pict[phase]);
+ return pom_pict[phase];
}
diff --git a/src/config.c b/src/config.c
new file mode 100644
index 0000000..edf1f3b
--- /dev/null
+++ b/src/config.c
@@ -0,0 +1,574 @@
+/*
+ * Calcurse - text-based organizer
+ *
+ * Copyright (c) 2004-2012 calcurse Development Team <misc@calcurse.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Send your feedback or comments to : misc@calcurse.org
+ * Calcurse home page : http://calcurse.org
+ *
+ */
+
+#include <ctype.h>
+#include <unistd.h>
+
+#include "calcurse.h"
+
+typedef int (*config_fn_parse_t) (void *, const char *);
+typedef int (*config_fn_serialize_t) (char *, void *);
+
+struct confvar {
+ const char *key;
+ config_fn_parse_t fn_parse;
+ config_fn_serialize_t fn_serialize;
+ void *target;
+};
+
+static int config_parse_bool(unsigned *, const char *);
+static int config_serialize_bool(char *, unsigned *);
+static int config_parse_int(int *, const char *);
+static int config_serialize_int(char *, int *);
+static int config_parse_unsigned(unsigned *, const char *);
+static int config_serialize_unsigned(char *, unsigned *);
+static int config_parse_str(char *, const char *);
+static int config_serialize_str(char *, const char *);
+static int config_parse_calendar_view(void *, const char *);
+static int config_serialize_calendar_view(char *, void *);
+static int config_parse_first_day_of_week(void *, const char *);
+static int config_serialize_first_day_of_week(char *, void *);
+static int config_parse_color_theme(void *, const char *);
+static int config_serialize_color_theme(char *, void *);
+static int config_parse_layout(void *, const char *);
+static int config_serialize_layout(char *, void *);
+static int config_parse_sidebar_width(void *, const char *);
+static int config_serialize_sidebar_width(char *, void *);
+static int config_parse_output_datefmt(void *, const char *);
+static int config_serialize_output_datefmt(char *, void *);
+static int config_parse_input_datefmt(void *, const char *);
+static int config_serialize_input_datefmt(char *, void *);
+
+#define CONFIG_HANDLER_BOOL(var) (config_fn_parse_t) config_parse_bool, \
+ (config_fn_serialize_t) config_serialize_bool, &(var)
+#define CONFIG_HANDLER_INT(var) (config_fn_parse_t) config_parse_int, \
+ (config_fn_serialize_t) config_serialize_int, &(var)
+#define CONFIG_HANDLER_UNSIGNED(var) (config_fn_parse_t) config_parse_unsigned, \
+ (config_fn_serialize_t) config_serialize_unsigned, &(var)
+#define CONFIG_HANDLER_STR(var) (config_fn_parse_t) config_parse_str, \
+ (config_fn_serialize_t) config_serialize_str, &(var)
+
+static const struct confvar confmap[] = {
+ {"appearance.calendarview", config_parse_calendar_view,
+ config_serialize_calendar_view, NULL},
+ {"appearance.layout", config_parse_layout, config_serialize_layout, NULL},
+ {"appearance.notifybar", CONFIG_HANDLER_BOOL(nbar.show)},
+ {"appearance.sidebarwidth", config_parse_sidebar_width,
+ config_serialize_sidebar_width, NULL},
+ {"appearance.theme", config_parse_color_theme, config_serialize_color_theme,
+ NULL},
+ {"daemon.enable", CONFIG_HANDLER_BOOL(dmon.enable)},
+ {"daemon.log", CONFIG_HANDLER_BOOL(dmon.log)},
+ {"format.inputdate", config_parse_input_datefmt,
+ config_serialize_input_datefmt, NULL},
+ {"format.notifydate", CONFIG_HANDLER_STR(nbar.datefmt)},
+ {"format.notifytime", CONFIG_HANDLER_STR(nbar.timefmt)},
+ {"format.outputdate", config_parse_output_datefmt,
+ config_serialize_output_datefmt, NULL},
+ {"general.autogc", CONFIG_HANDLER_BOOL(conf.auto_gc)},
+ {"general.autosave", CONFIG_HANDLER_BOOL(conf.auto_save)},
+ {"general.confirmdelete", CONFIG_HANDLER_BOOL(conf.confirm_delete)},
+ {"general.confirmquit", CONFIG_HANDLER_BOOL(conf.confirm_quit)},
+ {"general.firstdayofweek", config_parse_first_day_of_week,
+ config_serialize_first_day_of_week, NULL},
+ {"general.periodicsave", CONFIG_HANDLER_UNSIGNED(conf.periodic_save)},
+ {"general.progressbar", CONFIG_HANDLER_BOOL(conf.progress_bar)},
+ {"general.systemdialogs", CONFIG_HANDLER_BOOL(conf.system_dialogs)},
+ {"notification.command", CONFIG_HANDLER_STR(nbar.cmd)},
+ {"notification.notifyall", CONFIG_HANDLER_BOOL(nbar.notify_all)},
+ {"notification.warning", CONFIG_HANDLER_INT(nbar.cntdwn)}
+};
+
+struct config_save_status {
+ FILE *fp;
+ int done[sizeof(confmap) / sizeof(confmap[0])];
+};
+
+typedef int (*config_fn_walk_cb_t) (const char *, const char *, void *);
+typedef int (*config_fn_walk_junk_cb_t) (const char *, void *);
+
+static int config_parse_bool(unsigned *dest, const char *val)
+{
+ if (strcmp(val, "yes") == 0)
+ *dest = 1;
+ else if (strcmp(val, "no") == 0)
+ *dest = 0;
+ else
+ return 0;
+
+ return 1;
+}
+
+static int config_parse_unsigned(unsigned *dest, const char *val)
+{
+ if (is_all_digit(val))
+ *dest = atoi(val);
+ else
+ return 0;
+
+ return 1;
+}
+
+static int config_parse_int(int *dest, const char *val)
+{
+ if ((*val == '+' || *val == '-' || isdigit(*val)) && is_all_digit(val + 1))
+ *dest = atoi(val);
+ else
+ return 0;
+
+ return 1;
+}
+
+static int config_parse_str(char *dest, const char *val)
+{
+ strncpy(dest, val, BUFSIZ);
+ return 1;
+}
+
+static int config_parse_color(int *dest, const char *val)
+{
+ if (!strcmp(val, "black"))
+ *dest = COLOR_BLACK;
+ else if (!strcmp(val, "red"))
+ *dest = COLOR_RED;
+ else if (!strcmp(val, "green"))
+ *dest = COLOR_GREEN;
+ else if (!strcmp(val, "yellow"))
+ *dest = COLOR_YELLOW;
+ else if (!strcmp(val, "blue"))
+ *dest = COLOR_BLUE;
+ else if (!strcmp(val, "magenta"))
+ *dest = COLOR_MAGENTA;
+ else if (!strcmp(val, "cyan"))
+ *dest = COLOR_CYAN;
+ else if (!strcmp(val, "white"))
+ *dest = COLOR_WHITE;
+ else if (!strcmp(val, "default"))
+ *dest = background;
+ else
+ return 0;
+
+ return 1;
+}
+
+static int config_parse_color_pair(int *dest1, int *dest2, const char *val)
+{
+ char s1[BUFSIZ], s2[BUFSIZ];
+
+ if (sscanf(val, "%s on %s", s1, s2) != 2)
+ return 0;
+
+ return (config_parse_color(dest1, s1) && config_parse_color(dest2, s2));
+}
+
+static int config_parse_calendar_view(void *dummy, const char *val)
+{
+ calendar_set_view(atoi(val));
+ return 1;
+}
+
+static int config_parse_first_day_of_week(void *dummy, const char *val)
+{
+ if (!strcmp(val, "monday"))
+ calendar_set_first_day_of_week(MONDAY);
+ else if (!strcmp(val, "sunday"))
+ calendar_set_first_day_of_week(SUNDAY);
+ else
+ return 0;
+
+ return 1;
+}
+
+static int config_parse_color_theme(void *dummy, const char *val)
+{
+ int color1, color2;
+ if (!config_parse_color_pair(&color1, &color2, val))
+ return 0;
+ init_pair(COLR_CUSTOM, color1, color2);
+ return 1;
+}
+
+static int config_parse_layout(void *dummy, const char *val)
+{
+ wins_set_layout(atoi(val));
+ return 1;
+}
+
+static int config_parse_sidebar_width(void *dummy, const char *val)
+{
+ wins_set_sbar_width(atoi(val));
+ return 1;
+}
+
+static int config_parse_output_datefmt(void *dummy, const char *val)
+{
+ if (val[0] != '\0')
+ return config_parse_str(conf.output_datefmt, val);
+ return 1;
+}
+
+static int config_parse_input_datefmt(void *dummy, const char *val)
+{
+ if (config_parse_int(&conf.input_datefmt, val)) {
+ if (conf.input_datefmt <= 0 || conf.input_datefmt >= DATE_FORMATS)
+ conf.input_datefmt = 1;
+ return 1;
+ } else
+ return 0;
+}
+
+/* Set a configuration variable. */
+static int config_set_conf(const char *key, const char *value)
+{
+ int i;
+
+ if (!key)
+ return -1;
+
+ for (i = 0; i < sizeof(confmap) / sizeof(confmap[0]); i++) {
+ if (!strcmp(confmap[i].key, key))
+ return confmap[i].fn_parse(confmap[i].target, value);
+ }
+
+ return -1;
+}
+
+static int config_serialize_bool(char *dest, unsigned *val)
+{
+ if (*val) {
+ dest[0] = 'y';
+ dest[1] = 'e';
+ dest[2] = 's';
+ dest[3] = '\0';
+ } else {
+ dest[0] = 'n';
+ dest[1] = 'o';
+ dest[2] = '\0';
+ }
+
+ return 1;
+}
+
+static int config_serialize_unsigned(char *dest, unsigned *val)
+{
+ snprintf(dest, BUFSIZ, "%u", *val);
+ return 1;
+}
+
+static int config_serialize_int(char *dest, int *val)
+{
+ snprintf(dest, BUFSIZ, "%d", *val);
+ return 1;
+}
+
+static int config_serialize_str(char *dest, const char *val)
+{
+ strncpy(dest, val, BUFSIZ);
+ return 1;
+}
+
+/*
+ * Return a string defining the color theme in the form:
+ * foreground color 'on' background color
+ * in order to dump this data in the configuration file.
+ * Color numbers follow the ncurses library definitions.
+ * If ncurses library was compiled with --enable-ext-funcs,
+ * then default color is -1.
+ */
+static void config_color_theme_name(char *theme_name)
+{
+#define MAXCOLORS 8
+#define NBCOLORS 2
+#define DEFAULTCOLOR 255
+#define DEFAULTCOLOR_EXT -1
+
+ int i;
+ short color[NBCOLORS];
+ const char *color_name[NBCOLORS];
+ const char *default_color = "default";
+ const char *name[MAXCOLORS] = {
+ "black",
+ "red",
+ "green",
+ "yellow",
+ "blue",
+ "magenta",
+ "cyan",
+ "white"
+ };
+
+ if (!colorize)
+ strncpy(theme_name, "0", BUFSIZ);
+ else {
+ pair_content(COLR_CUSTOM, &color[0], &color[1]);
+ for (i = 0; i < NBCOLORS; i++) {
+ if ((color[i] == DEFAULTCOLOR) || (color[i] == DEFAULTCOLOR_EXT))
+ color_name[i] = default_color;
+ else if (color[i] >= 0 && color[i] <= MAXCOLORS)
+ color_name[i] = name[color[i]];
+ else {
+ EXIT(_("unknown color"));
+ /* NOTREACHED */
+ }
+ }
+ snprintf(theme_name, BUFSIZ, "%s on %s", color_name[0], color_name[1]);
+ }
+}
+
+static int config_serialize_calendar_view(char *buf, void *dummy)
+{
+ int tmp = calendar_get_view();
+ return config_serialize_int(buf, &tmp);
+}
+
+static int config_serialize_first_day_of_week(char *buf, void *dummy)
+{
+ if (calendar_week_begins_on_monday())
+ strcpy(buf, "monday");
+ else
+ strcpy(buf, "sunday");
+
+ return 1;
+}
+
+static int config_serialize_color_theme(char *buf, void *dummy)
+{
+ config_color_theme_name(buf);
+ return 1;
+}
+
+static int config_serialize_layout(char *buf, void *dummy)
+{
+ int tmp = wins_layout();
+ return config_serialize_int(buf, &tmp);
+}
+
+static int config_serialize_sidebar_width(char *buf, void *dummy)
+{
+ int tmp = wins_sbar_wperc();
+ return config_serialize_int(buf, &tmp);
+}
+
+static int config_serialize_output_datefmt(char *buf, void *dummy)
+{
+ return config_serialize_str(buf, conf.output_datefmt);
+}
+
+static int config_serialize_input_datefmt(char *buf, void *dummy)
+{
+ return config_serialize_int(buf, &conf.input_datefmt);
+}
+
+/* Serialize the value of a configuration variable. */
+static int
+config_serialize_conf(char *buf, const char *key,
+ struct config_save_status *status)
+{
+ int i;
+
+ if (!key)
+ return -1;
+
+ for (i = 0; i < sizeof(confmap) / sizeof(confmap[0]); i++) {
+ if (!strcmp(confmap[i].key, key)) {
+ if (confmap[i].fn_serialize(buf, confmap[i].target)) {
+ if (status)
+ status->done[i] = 1;
+ return 1;
+ } else
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+static void
+config_file_walk(config_fn_walk_cb_t fn_cb,
+ config_fn_walk_junk_cb_t fn_junk_cb, void *data)
+{
+ FILE *data_file;
+ char buf[BUFSIZ], e_conf[BUFSIZ];
+ char *key, *value;
+
+ data_file = fopen(path_conf, "r");
+ EXIT_IF(data_file == NULL, _("failed to open configuration file"));
+
+ pthread_mutex_lock(&nbar.mutex);
+ for (;;) {
+ if (fgets(buf, sizeof buf, data_file) == NULL)
+ break;
+ io_extract_data(e_conf, buf, sizeof buf);
+
+ if (*e_conf == '\0') {
+ if (fn_junk_cb)
+ fn_junk_cb(buf, data);
+ continue;
+ }
+
+ key = e_conf;
+ value = strchr(e_conf, '=');
+ if (value) {
+ *value = '\0';
+ value++;
+ }
+
+ if (strcmp(key, "auto_save") == 0 ||
+ strcmp(key, "auto_gc") == 0 ||
+ strcmp(key, "periodic_save") == 0 ||
+ strcmp(key, "confirm_quit") == 0 ||
+ strcmp(key, "confirm_delete") == 0 ||
+ strcmp(key, "skip_system_dialogs") == 0 ||
+ strcmp(key, "skip_progress_bar") == 0 ||
+ strcmp(key, "calendar_default_view") == 0 ||
+ strcmp(key, "week_begins_on_monday") == 0 ||
+ strcmp(key, "color-theme") == 0 ||
+ strcmp(key, "layout") == 0 ||
+ strcmp(key, "side-bar_width") == 0 ||
+ strcmp(key, "notify-bar_show") == 0 ||
+ strcmp(key, "notify-bar_date") == 0 ||
+ strcmp(key, "notify-bar_clock") == 0 ||
+ strcmp(key, "notify-bar_warning") == 0 ||
+ strcmp(key, "notify-bar_command") == 0 ||
+ strcmp(key, "notify-all") == 0 ||
+ strcmp(key, "output_datefmt") == 0 ||
+ strcmp(key, "input_datefmt") == 0 ||
+ strcmp(key, "notify-daemon_enable") == 0 ||
+ strcmp(key, "notify-daemon_log") == 0) {
+ WARN_MSG(_("Pre-3.0.0 configuration file format detected, "
+ "please upgrade running `calcurse-upgrade`."));
+ }
+
+ if (value && (*value == '\0' || *value == '\n')) {
+ /* Backward compatibility mode. */
+ if (fgets(buf, sizeof buf, data_file) == NULL)
+ break;
+ io_extract_data(e_conf, buf, sizeof buf);
+ value = e_conf;
+ }
+
+ fn_cb(key, value, data);
+ }
+ file_close(data_file, __FILE_POS__);
+ pthread_mutex_unlock(&nbar.mutex);
+}
+
+static int config_load_cb(const char *key, const char *value, void *dummy)
+{
+ int result = config_set_conf(key, value);
+
+ if (result < 0)
+ EXIT(_("configuration variable unknown: \"%s\""), key);
+ /* NOTREACHED */
+ else if (result == 0)
+ EXIT(_("wrong configuration variable format for \"%s\""), key);
+ /* NOTREACHED */
+
+ return 1;
+}
+
+/* Load the user configuration. */
+void config_load(void)
+{
+ config_file_walk(config_load_cb, NULL, NULL);
+}
+
+static int config_save_cb(const char *key, const char *value, void *status)
+{
+ char buf[BUFSIZ];
+ int result =
+ config_serialize_conf(buf, key, (struct config_save_status *)status);
+
+ if (result < 0)
+ EXIT(_("configuration variable unknown: \"%s\""), key);
+ /* NOTREACHED */
+ else if (result == 0)
+ EXIT(_("wrong configuration variable format for \"%s\""), key);
+ /* NOTREACHED */
+
+ fputs(key, ((struct config_save_status *)status)->fp);
+ fputc('=', ((struct config_save_status *)status)->fp);
+ fputs(buf, ((struct config_save_status *)status)->fp);
+ fputc('\n', ((struct config_save_status *)status)->fp);
+
+ return 1;
+}
+
+static int config_save_junk_cb(const char *data, void *status)
+{
+ fputs(data, ((struct config_save_status *)status)->fp);
+ return 1;
+}
+
+/* Save the user configuration. */
+unsigned config_save(void)
+{
+ char tmppath[BUFSIZ];
+ char *tmpext;
+ struct config_save_status status;
+ int i;
+
+ if (read_only)
+ return 1;
+
+ strncpy(tmppath, get_tempdir(), BUFSIZ);
+ strncat(tmppath, "/" CONF_PATH_NAME ".", BUFSIZ - strlen(tmppath) - 1);
+ if ((tmpext = new_tempfile(tmppath, TMPEXTSIZ)) == NULL)
+ return 0;
+ strncat(tmppath, tmpext, BUFSIZ - strlen(tmppath) - 1);
+ mem_free(tmpext);
+
+ status.fp = fopen(tmppath, "w");
+ if (!status.fp)
+ return 0;
+
+ memset(status.done, 0, sizeof(status.done));
+
+ config_file_walk(config_save_cb, config_save_junk_cb, (void *)&status);
+
+ /* Set variables that were missing from the configuration file. */
+ for (i = 0; i < sizeof(confmap) / sizeof(confmap[0]); i++) {
+ if (!status.done[i])
+ config_save_cb(confmap[i].key, NULL, &status);
+ }
+
+ file_close(status.fp, __FILE_POS__);
+
+ if (io_file_cp(tmppath, path_conf))
+ unlink(tmppath);
+
+ return 1;
+}
diff --git a/src/custom.c b/src/custom.c
index 1f75978..ef84703 100644
--- a/src/custom.c
+++ b/src/custom.c
@@ -1,7 +1,7 @@
/*
* Calcurse - text-based organizer
*
- * Copyright (c) 2004-2011 calcurse Development Team <misc@calcurse.org>
+ * Copyright (c) 2004-2012 calcurse Development Team <misc@calcurse.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -37,35 +37,10 @@
#include <string.h>
#include <stdlib.h>
#include <math.h>
+#include <ctype.h>
#include "calcurse.h"
-/* Available configuration variables. */
-enum conf_var {
- CUSTOM_CONF_NOVARIABLE,
- CUSTOM_CONF_AUTOSAVE,
- CUSTOM_CONF_PERIODICSAVE,
- CUSTOM_CONF_CONFIRMQUIT,
- CUSTOM_CONF_CONFIRMDELETE,
- CUSTOM_CONF_SKIPSYSTEMDIALOGS,
- CUSTOM_CONF_SKIPPROGRESSBAR,
- CUSTOM_CONF_CALENDAR_DEFAULTVIEW,
- CUSTOM_CONF_WEEKBEGINSONMONDAY,
- CUSTOM_CONF_COLORTHEME,
- CUSTOM_CONF_LAYOUT,
- CUSTOM_CONF_SBAR_WIDTH,
- CUSTOM_CONF_NOTIFYBARSHOW,
- CUSTOM_CONF_NOTIFYBARDATE,
- CUSTOM_CONF_NOTIFYBARCLOCK,
- CUSTOM_CONF_NOTIFYBARWARNING,
- CUSTOM_CONF_NOTIFYBARCOMMAND,
- CUSTOM_CONF_OUTPUTDATEFMT,
- CUSTOM_CONF_INPUTDATEFMT,
- CUSTOM_CONF_DMON_ENABLE,
- CUSTOM_CONF_DMON_LOG,
- CUSTOM_CONF_VARIABLES
-};
-
struct attribute {
int color[7];
int nocolor[7];
@@ -73,118 +48,6 @@ struct attribute {
static struct attribute attr;
-static unsigned
-fill_config_var (char *string)
-{
- if (strncmp (string, "yes", 3) == 0)
- return 1;
- else if (strncmp (string, "no", 2) == 0)
- return 0;
- else
- {
- EXIT (_("wrong configuration variable format."));
- return 0;
- }
-}
-
-/*
- * Load user color theme from file.
- * Need to handle calcurse versions prior to 1.8, where colors where handled
- * differently (number between 1 and 8).
- */
-static void
-custom_load_color (char *color, int background)
-{
-#define AWAITED_COLORS 2
-
- int i, len, color_num;
- char c[AWAITED_COLORS][BUFSIZ];
- int colr[AWAITED_COLORS];
-
- len = strlen (color);
- if (len > 1)
- {
- /* New version configuration */
- if (sscanf (color, "%s on %s", c[0], c[1]) != AWAITED_COLORS)
- {
- EXIT (_("missing colors in config file"));
- /* NOTREACHED */
- }
-
- for (i = 0; i < AWAITED_COLORS; i++)
- {
- if (!strncmp (c[i], "black", 5))
- colr[i] = COLOR_BLACK;
- else if (!strncmp (c[i], "red", 3))
- colr[i] = COLOR_RED;
- else if (!strncmp (c[i], "green", 5))
- colr[i] = COLOR_GREEN;
- else if (!strncmp (c[i], "yellow", 6))
- colr[i] = COLOR_YELLOW;
- else if (!strncmp (c[i], "blue", 4))
- colr[i] = COLOR_BLUE;
- else if (!strncmp (c[i], "magenta", 7))
- colr[i] = COLOR_MAGENTA;
- else if (!strncmp (c[i], "cyan", 4))
- colr[i] = COLOR_CYAN;
- else if (!strncmp (c[i], "white", 5))
- colr[i] = COLOR_WHITE;
- else if (!strncmp (c[i], "default", 7))
- colr[i] = background;
- else
- {
- EXIT (_("wrong color name"));
- /* NOTREACHED */
- }
- }
- init_pair (COLR_CUSTOM, colr[0], colr[1]);
- }
- else if (len > 0 && len < 2)
- {
- /* Old version configuration */
- color_num = atoi (color);
-
- switch (color_num)
- {
- case 0:
- colorize = 0;
- break;
- case 1:
- init_pair (COLR_CUSTOM, COLOR_RED, background);
- break;
- case 2:
- init_pair (COLR_CUSTOM, COLOR_GREEN, background);
- break;
- case 3:
- init_pair (COLR_CUSTOM, COLOR_BLUE, background);
- break;
- case 4:
- init_pair (COLR_CUSTOM, COLOR_CYAN, background);
- break;
- case 5:
- init_pair (COLR_CUSTOM, COLOR_YELLOW, background);
- break;
- case 6:
- init_pair (COLR_CUSTOM, COLOR_BLACK, COLR_GREEN);
- break;
- case 7:
- init_pair (COLR_CUSTOM, COLOR_BLACK, COLR_YELLOW);
- break;
- case 8:
- init_pair (COLR_CUSTOM, COLOR_RED, COLR_BLUE);
- break;
- default:
- EXIT (_("wrong color number"));
- /* NOTREACHED */
- }
- }
- else
- {
- EXIT (_("wrong configuration variable format"));
- /* NOTREACHED */
- }
-}
-
/*
* Define window attributes (for both color and non-color terminals):
* ATTR_HIGHEST are for window titles
@@ -193,16 +56,15 @@ custom_load_color (char *color, int background)
* ATTR_LOW are for days inside calendar panel which contains an event
* ATTR_LOWEST are for current day inside calendar panel
*/
-void
-custom_init_attr (void)
+void custom_init_attr(void)
{
- attr.color[ATTR_HIGHEST] = COLOR_PAIR (COLR_CUSTOM);
- attr.color[ATTR_HIGH] = COLOR_PAIR (COLR_HIGH);
- attr.color[ATTR_MIDDLE] = COLOR_PAIR (COLR_RED);
- attr.color[ATTR_LOW] = COLOR_PAIR (COLR_CYAN);
- attr.color[ATTR_LOWEST] = COLOR_PAIR (COLR_YELLOW);
- attr.color[ATTR_TRUE] = COLOR_PAIR (COLR_GREEN);
- attr.color[ATTR_FALSE] = COLOR_PAIR (COLR_RED);
+ attr.color[ATTR_HIGHEST] = COLOR_PAIR(COLR_CUSTOM);
+ attr.color[ATTR_HIGH] = COLOR_PAIR(COLR_HIGH);
+ attr.color[ATTR_MIDDLE] = COLOR_PAIR(COLR_RED);
+ attr.color[ATTR_LOW] = COLOR_PAIR(COLR_CYAN);
+ attr.color[ATTR_LOWEST] = COLOR_PAIR(COLR_YELLOW);
+ attr.color[ATTR_TRUE] = COLOR_PAIR(COLR_GREEN);
+ attr.color[ATTR_FALSE] = COLOR_PAIR(COLR_RED);
attr.nocolor[ATTR_HIGHEST] = A_BOLD;
attr.nocolor[ATTR_HIGH] = A_REVERSE;
@@ -214,458 +76,278 @@ custom_init_attr (void)
}
/* Apply window attribute */
-void
-custom_apply_attr (WINDOW *win, int attr_num)
+void custom_apply_attr(WINDOW * win, int attr_num)
{
if (colorize)
- wattron (win, attr.color[attr_num]);
+ wattron(win, attr.color[attr_num]);
else
- wattron (win, attr.nocolor[attr_num]);
+ wattron(win, attr.nocolor[attr_num]);
}
/* Remove window attribute */
-void
-custom_remove_attr (WINDOW *win, int attr_num)
+void custom_remove_attr(WINDOW * win, int attr_num)
{
if (colorize)
- wattroff (win, attr.color[attr_num]);
+ wattroff(win, attr.color[attr_num]);
else
- wattroff (win, attr.nocolor[attr_num]);
-}
-
-/* Load the user configuration. */
-void
-custom_load_conf (struct conf *conf, int background)
-{
- FILE *data_file;
- char *mesg_line1 = _("Failed to open config file");
- char *mesg_line2 = _("Press [ENTER] to continue");
- char buf[BUFSIZ], e_conf[BUFSIZ];
- enum conf_var var;
-
- data_file = fopen (path_conf, "r");
- if (data_file == NULL)
- {
- status_mesg (mesg_line1, mesg_line2);
- wnoutrefresh (win[STA].p);
- wins_doupdate ();
- (void)keys_getch (win[STA].p);
- }
- var = CUSTOM_CONF_NOVARIABLE;
- pthread_mutex_lock (&nbar.mutex);
- for (;;)
- {
- if (fgets (buf, sizeof buf, data_file) == NULL)
- {
- break;
- }
- io_extract_data (e_conf, buf, sizeof buf);
-
- switch (var)
- {
- case CUSTOM_CONF_NOVARIABLE:
- break;
- case CUSTOM_CONF_AUTOSAVE:
- conf->auto_save = fill_config_var (e_conf);
- var = 0;
- break;
- case CUSTOM_CONF_PERIODICSAVE:
- if (atoi (e_conf) < 0)
- conf->periodic_save = 0;
- else
- conf->periodic_save = atoi (e_conf);
- var = 0;
- break;
- case CUSTOM_CONF_CONFIRMQUIT:
- conf->confirm_quit = fill_config_var (e_conf);
- var = 0;
- break;
- case CUSTOM_CONF_CONFIRMDELETE:
- conf->confirm_delete = fill_config_var (e_conf);
- var = 0;
- break;
- case CUSTOM_CONF_SKIPSYSTEMDIALOGS:
- conf->skip_system_dialogs = fill_config_var (e_conf);
- var = 0;
- break;
- case CUSTOM_CONF_SKIPPROGRESSBAR:
- conf->skip_progress_bar = fill_config_var (e_conf);
- var = 0;
- break;
- case CUSTOM_CONF_CALENDAR_DEFAULTVIEW:
- calendar_set_view (atoi (e_conf));
- var = 0;
- break;
- case CUSTOM_CONF_WEEKBEGINSONMONDAY:
- if (fill_config_var (e_conf))
- calendar_set_first_day_of_week (MONDAY);
- else
- calendar_set_first_day_of_week (SUNDAY);
- var = 0;
- break;
- case CUSTOM_CONF_COLORTHEME:
- custom_load_color (e_conf, background);
- var = 0;
- break;
- case CUSTOM_CONF_LAYOUT:
- wins_set_layout (atoi (e_conf));
- var = 0;
- break;
- case CUSTOM_CONF_SBAR_WIDTH:
- wins_set_sbar_width (atoi (e_conf));
- var = 0;
- break;
- case CUSTOM_CONF_NOTIFYBARSHOW:
- nbar.show = fill_config_var (e_conf);
- var = 0;
- break;
- case CUSTOM_CONF_NOTIFYBARDATE:
- (void)strncpy (nbar.datefmt, e_conf, strlen (e_conf) + 1);
- var = 0;
- break;
- case CUSTOM_CONF_NOTIFYBARCLOCK:
- (void)strncpy (nbar.timefmt, e_conf, strlen (e_conf) + 1);
- var = 0;
- break;
- case CUSTOM_CONF_NOTIFYBARWARNING:
- nbar.cntdwn = atoi (e_conf);
- var = 0;
- break;
- case CUSTOM_CONF_NOTIFYBARCOMMAND:
- (void)strncpy (nbar.cmd, e_conf, strlen (e_conf) + 1);
- var = 0;
- break;
- case CUSTOM_CONF_OUTPUTDATEFMT:
- if (e_conf[0] != '\0')
- (void)strncpy (conf->output_datefmt, e_conf, strlen (e_conf) + 1);
- var = 0;
- break;
- case CUSTOM_CONF_INPUTDATEFMT:
- conf->input_datefmt = atoi (e_conf);
- if (conf->input_datefmt <= 0 || conf->input_datefmt >= DATE_FORMATS)
- conf->input_datefmt = 1;
- var = 0;
- break;
- case CUSTOM_CONF_DMON_ENABLE:
- dmon.enable = fill_config_var (e_conf);
- var = 0;
- break;
- case CUSTOM_CONF_DMON_LOG:
- dmon.log = fill_config_var (e_conf);
- var = 0;
- break;
- default:
- EXIT (_("configuration variable unknown"));
- /* NOTREACHED */
- }
-
- if (strncmp (e_conf, "auto_save=", 10) == 0)
- var = CUSTOM_CONF_AUTOSAVE;
- else if (strncmp (e_conf, "periodic_save=", 14) == 0)
- var = CUSTOM_CONF_PERIODICSAVE;
- else if (strncmp (e_conf, "confirm_quit=", 13) == 0)
- var = CUSTOM_CONF_CONFIRMQUIT;
- else if (strncmp (e_conf, "confirm_delete=", 15) == 0)
- var = CUSTOM_CONF_CONFIRMDELETE;
- else if (strncmp (e_conf, "skip_system_dialogs=", 20) == 0)
- var = CUSTOM_CONF_SKIPSYSTEMDIALOGS;
- else if (strncmp (e_conf, "skip_progress_bar=", 18) == 0)
- var = CUSTOM_CONF_SKIPPROGRESSBAR;
- else if (strncmp (e_conf, "calendar_default_view=", 22) == 0)
- var = CUSTOM_CONF_CALENDAR_DEFAULTVIEW;
- else if (strncmp (e_conf, "week_begins_on_monday=", 22) == 0)
- var = CUSTOM_CONF_WEEKBEGINSONMONDAY;
- else if (strncmp (e_conf, "color-theme=", 12) == 0)
- var = CUSTOM_CONF_COLORTHEME;
- else if (strncmp (e_conf, "layout=", 7) == 0)
- var = CUSTOM_CONF_LAYOUT;
- else if (strncmp (e_conf, "side-bar_width=", 15) == 0)
- var = CUSTOM_CONF_SBAR_WIDTH;
- else if (strncmp (e_conf, "notify-bar_show=", 16) == 0)
- var = CUSTOM_CONF_NOTIFYBARSHOW;
- else if (strncmp (e_conf, "notify-bar_date=", 16) == 0)
- var = CUSTOM_CONF_NOTIFYBARDATE;
- else if (strncmp (e_conf, "notify-bar_clock=", 17) == 0)
- var = CUSTOM_CONF_NOTIFYBARCLOCK;
- else if (strncmp (e_conf, "notify-bar_warning=", 19) == 0)
- var = CUSTOM_CONF_NOTIFYBARWARNING;
- else if (strncmp (e_conf, "notify-bar_command=", 19) == 0)
- var = CUSTOM_CONF_NOTIFYBARCOMMAND;
- else if (strncmp (e_conf, "output_datefmt=", 15) == 0)
- var = CUSTOM_CONF_OUTPUTDATEFMT;
- else if (strncmp (e_conf, "input_datefmt=", 14) == 0)
- var = CUSTOM_CONF_INPUTDATEFMT;
- else if (strncmp (e_conf, "notify-daemon_enable=", 21) == 0)
- var = CUSTOM_CONF_DMON_ENABLE;
- else if (strncmp (e_conf, "notify-daemon_log=", 18) == 0)
- var = CUSTOM_CONF_DMON_LOG;
- }
- file_close (data_file, __FILE_POS__);
- pthread_mutex_unlock (&nbar.mutex);
+ wattroff(win, attr.nocolor[attr_num]);
}
/* Draws the configuration bar */
-void
-custom_config_bar (void)
+void custom_config_bar(void)
{
const int SMLSPC = 2;
const int SPC = 15;
- custom_apply_attr (win[STA].p, ATTR_HIGHEST);
- mvwprintw (win[STA].p, 0, 2, "Q");
- mvwprintw (win[STA].p, 1, 2, "G");
- mvwprintw (win[STA].p, 0, 2 + SPC, "L");
- mvwprintw (win[STA].p, 1, 2 + SPC, "S");
- mvwprintw (win[STA].p, 0, 2 + 2 * SPC, "C");
- mvwprintw (win[STA].p, 1, 2 + 2 * SPC, "N");
- mvwprintw (win[STA].p, 0, 2 + 3 * SPC, "K");
- custom_remove_attr (win[STA].p, ATTR_HIGHEST);
-
- mvwprintw (win[STA].p, 0, 2 + SMLSPC, _("Exit"));
- mvwprintw (win[STA].p, 1, 2 + SMLSPC, _("General"));
- mvwprintw (win[STA].p, 0, 2 + SPC + SMLSPC, _("Layout"));
- mvwprintw (win[STA].p, 1, 2 + SPC + SMLSPC, _("Sidebar"));
- mvwprintw (win[STA].p, 0, 2 + 2 * SPC + SMLSPC, _("Color"));
- mvwprintw (win[STA].p, 1, 2 + 2 * SPC + SMLSPC, _("Notify"));
- mvwprintw (win[STA].p, 0, 2 + 3 * SPC + SMLSPC, _("Keys"));
-
- wnoutrefresh (win[STA].p);
- wmove (win[STA].p, 0, 0);
- wins_doupdate ();
+ custom_apply_attr(win[STA].p, ATTR_HIGHEST);
+ mvwprintw(win[STA].p, 0, 2, "Q");
+ mvwprintw(win[STA].p, 1, 2, "G");
+ mvwprintw(win[STA].p, 0, 2 + SPC, "L");
+ mvwprintw(win[STA].p, 1, 2 + SPC, "S");
+ mvwprintw(win[STA].p, 0, 2 + 2 * SPC, "C");
+ mvwprintw(win[STA].p, 1, 2 + 2 * SPC, "N");
+ mvwprintw(win[STA].p, 0, 2 + 3 * SPC, "K");
+ custom_remove_attr(win[STA].p, ATTR_HIGHEST);
+
+ mvwprintw(win[STA].p, 0, 2 + SMLSPC, _("Exit"));
+ mvwprintw(win[STA].p, 1, 2 + SMLSPC, _("General"));
+ mvwprintw(win[STA].p, 0, 2 + SPC + SMLSPC, _("Layout"));
+ mvwprintw(win[STA].p, 1, 2 + SPC + SMLSPC, _("Sidebar"));
+ mvwprintw(win[STA].p, 0, 2 + 2 * SPC + SMLSPC, _("Color"));
+ mvwprintw(win[STA].p, 1, 2 + 2 * SPC + SMLSPC, _("Notify"));
+ mvwprintw(win[STA].p, 0, 2 + 3 * SPC + SMLSPC, _("Keys"));
+
+ wnoutrefresh(win[STA].p);
+ wmove(win[STA].p, 0, 0);
+ wins_doupdate();
}
-static void
-layout_selection_bar (void)
+static void layout_selection_bar(void)
{
- struct binding quit = {_("Exit"), KEY_GENERIC_QUIT};
- struct binding select = {_("Select"), KEY_GENERIC_SELECT};
- struct binding up = {_("Up"), KEY_MOVE_UP};
- struct binding down = {_("Down"), KEY_MOVE_DOWN};
- struct binding left = {_("Left"), KEY_MOVE_LEFT};
- struct binding right = {_("Right"), KEY_MOVE_RIGHT};
- struct binding help = {_("Help"), KEY_GENERIC_HELP};
-
- struct binding *binding[] = {&quit, &select, &up, &down, &left, &right, &help};
- int binding_size = sizeof (binding) / sizeof (binding[0]);
-
- keys_display_bindings_bar (win[STA].p, binding, 0, binding_size);
+ struct binding quit = { _("Exit"), KEY_GENERIC_QUIT };
+ struct binding select = { _("Select"), KEY_GENERIC_SELECT };
+ struct binding up = { _("Up"), KEY_MOVE_UP };
+ struct binding down = { _("Down"), KEY_MOVE_DOWN };
+ struct binding left = { _("Left"), KEY_MOVE_LEFT };
+ struct binding right = { _("Right"), KEY_MOVE_RIGHT };
+ struct binding help = { _("Help"), KEY_GENERIC_HELP };
+
+ struct binding *bindings[] = {
+ &quit, &select, &up, &down, &left, &right, &help
+ };
+ int bindings_size = sizeof(bindings) / sizeof(bindings[0]);
+
+ keys_display_bindings_bar(win[STA].p, bindings, bindings_size, 0,
+ bindings_size, NULL);
}
#define NBLAYOUTS 8
#define LAYOUTSPERCOL 2
/* Used to display available layouts in layout configuration menu. */
-static void
-display_layout_config (struct window *lwin, int mark, int cursor)
+static void display_layout_config(struct window *lwin, int mark, int cursor)
{
#define CURSOR (32 | A_REVERSE)
#define MARK 88
#define LAYOUTH 5
#define LAYOUTW 9
- char *box = "[ ]";
- const int BOXSIZ = strlen (box);
+ const char *box = "[ ]";
+ const int BOXSIZ = strlen(box);
const int NBCOLS = NBLAYOUTS / LAYOUTSPERCOL;
const int COLSIZ = LAYOUTW + BOXSIZ + 1;
const int XSPC = (lwin->w - NBCOLS * COLSIZ) / (NBCOLS + 1);
const int XOFST = (lwin->w - NBCOLS * (XSPC + COLSIZ)) / 2;
- const int YSPC = (lwin->h - 8 - LAYOUTSPERCOL * LAYOUTH) / (LAYOUTSPERCOL + 1);
+ const int YSPC =
+ (lwin->h - 8 - LAYOUTSPERCOL * LAYOUTH) / (LAYOUTSPERCOL + 1);
const int YOFST = (lwin->h - LAYOUTSPERCOL * (YSPC + LAYOUTH)) / 2;
- enum {YPOS, XPOS, NBPOS};
+ enum { YPOS, XPOS, NBPOS };
int pos[NBLAYOUTS][NBPOS];
- char *layouts[LAYOUTH][NBLAYOUTS] = {
- {"+---+---+", "+---+---+", "+---+---+", "+---+---+", "+---+---+", "+---+---+", "+---+---+", "+---+---+"},
- {"| | c |", "| | t |", "| c | |", "| t | |", "| | c |", "| | a |", "| c | |", "| a | |"},
- {"| a +---+", "| a +---+", "+---+ a |", "|---+ a |", "| t +---+", "| t +---+", "+---+ t |", "+---+ t |"},
- {"| | t |", "| | c |", "| t | |", "| c | |", "| | a |", "| | c |", "| a | |", "| c | |"},
- {"+---+---+", "+---+---+", "+---+---+", "+---+---+", "+---+---+", "+---+---+", "+---+---+", "+---+---+"}
+ const char *layouts[LAYOUTH][NBLAYOUTS] = {
+ {"+---+---+", "+---+---+", "+---+---+", "+---+---+", "+---+---+",
+ "+---+---+", "+---+---+", "+---+---+"},
+ {"| | c |", "| | t |", "| c | |", "| t | |", "| | c |",
+ "| | a |", "| c | |", "| a | |"},
+ {"| a +---+", "| a +---+", "+---+ a |", "|---+ a |", "| t +---+",
+ "| t +---+", "+---+ t |", "+---+ t |"},
+ {"| | t |", "| | c |", "| t | |", "| c | |", "| | a |",
+ "| | c |", "| a | |", "| c | |"},
+ {"+---+---+", "+---+---+", "+---+---+", "+---+---+", "+---+---+",
+ "+---+---+", "+---+---+", "+---+---+"}
};
int i;
- for (i = 0; i < NBLAYOUTS; i++)
- {
- pos[i][YPOS] = YOFST + (i % LAYOUTSPERCOL) * (YSPC + LAYOUTH);
- pos[i][XPOS] = XOFST + (i / LAYOUTSPERCOL) * (XSPC + COLSIZ);
- }
+ for (i = 0; i < NBLAYOUTS; i++) {
+ pos[i][YPOS] = YOFST + (i % LAYOUTSPERCOL) * (YSPC + LAYOUTH);
+ pos[i][XPOS] = XOFST + (i / LAYOUTSPERCOL) * (XSPC + COLSIZ);
+ }
- for (i = 0; i < NBLAYOUTS; i++)
- {
- int j;
-
- mvwprintw (lwin->p, pos[i][YPOS] + 2, pos[i][XPOS], box);
- if (i == mark)
- custom_apply_attr (lwin->p, ATTR_HIGHEST);
- for (j = 0; j < LAYOUTH; j++)
- {
- mvwprintw (lwin->p, pos[i][YPOS] + j, pos[i][XPOS] + BOXSIZ + 1,
- layouts[j][i]);
- }
- if (i == mark)
- custom_remove_attr (lwin->p, ATTR_HIGHEST);
+ for (i = 0; i < NBLAYOUTS; i++) {
+ int j;
+
+ mvwprintw(lwin->p, pos[i][YPOS] + 2, pos[i][XPOS], box);
+ if (i == mark)
+ custom_apply_attr(lwin->p, ATTR_HIGHEST);
+ for (j = 0; j < LAYOUTH; j++) {
+ mvwprintw(lwin->p, pos[i][YPOS] + j, pos[i][XPOS] + BOXSIZ + 1,
+ layouts[j][i]);
}
- mvwaddch (lwin->p, pos[mark][YPOS] + 2, pos[mark][XPOS] + 1, MARK);
- mvwaddch (lwin->p, pos[cursor][YPOS] + 2, pos[cursor][XPOS] + 1, CURSOR);
-
- layout_selection_bar ();
- wnoutrefresh (win[STA].p);
- wnoutrefresh (lwin->p);
- wins_doupdate ();
- if (notify_bar ())
- notify_update_bar ();
+ if (i == mark)
+ custom_remove_attr(lwin->p, ATTR_HIGHEST);
+ }
+ mvwaddch(lwin->p, pos[mark][YPOS] + 2, pos[mark][XPOS] + 1, MARK);
+ mvwaddch(lwin->p, pos[cursor][YPOS] + 2, pos[cursor][XPOS] + 1, CURSOR);
+
+ layout_selection_bar();
+ wnoutrefresh(win[STA].p);
+ wnoutrefresh(lwin->p);
+ wins_doupdate();
+ if (notify_bar())
+ notify_update_bar();
}
/* Choose the layout */
-void
-custom_layout_config (void)
+void custom_layout_config(void)
{
struct scrollwin hwin;
struct window conf_win;
int ch, mark, cursor, need_reset;
- char label[BUFSIZ];
- char *help_text =
- _("With this configuration menu, one can choose where panels will be\n"
- "displayed inside calcurse screen. \n"
- "It is possible to choose between eight different configurations.\n"
- "\nIn the configuration representations, letters correspond to:\n\n"
- " 'c' -> calendar panel\n\n"
- " 'a' -> appointment panel\n\n"
- " 't' -> todo panel\n\n");
-
- conf_win.p = (WINDOW *)0;
- (void)snprintf (label, BUFSIZ, _("layout configuration"));
- custom_confwin_init (&conf_win, label);
- cursor = mark = wins_layout () - 1;
- display_layout_config (&conf_win, mark, cursor);
- clear ();
-
- while ((ch = keys_getch (win[STA].p)) != KEY_GENERIC_QUIT)
- {
- need_reset = 0;
- switch (ch)
- {
- case KEY_GENERIC_HELP:
- help_wins_init (&hwin, 0, 0,
- (notify_bar ()) ? row - 3 : row - 2, col);
- mvwprintw (hwin.pad.p, 1, 0, "%s", help_text);
- hwin.total_lines = 7;
- wins_scrollwin_display (&hwin);
- wgetch (hwin.win.p);
- wins_scrollwin_delete (&hwin);
- need_reset = 1;
- break;
- case KEY_GENERIC_SELECT:
- mark = cursor;
- break;
- case KEY_MOVE_DOWN:
- if (cursor % LAYOUTSPERCOL < LAYOUTSPERCOL - 1)
- cursor++;
- break;
- case KEY_MOVE_UP:
- if (cursor % LAYOUTSPERCOL > 0)
- cursor--;
- break;
- case KEY_MOVE_LEFT:
- if (cursor >= LAYOUTSPERCOL)
- cursor -= LAYOUTSPERCOL;
- break;
- case KEY_MOVE_RIGHT:
- if (cursor < NBLAYOUTS - LAYOUTSPERCOL)
- cursor += LAYOUTSPERCOL;
- break;
- case KEY_GENERIC_CANCEL:
- need_reset = 1;
- break;
- }
+ const char *label = _("layout configuration");
+ const char *help_text =
+ _("With this configuration menu, one can choose where panels will be\n"
+ "displayed inside calcurse screen. \n"
+ "It is possible to choose between eight different configurations.\n"
+ "\nIn the configuration representations, letters correspond to:\n\n"
+ " 'c' -> calendar panel\n\n"
+ " 'a' -> appointment panel\n\n" " 't' -> todo panel\n\n");
+
+ conf_win.p = NULL;
+ custom_confwin_init(&conf_win, label);
+ cursor = mark = wins_layout() - 1;
+ display_layout_config(&conf_win, mark, cursor);
+ clear();
+
+ while ((ch = keys_getch(win[STA].p, NULL)) != KEY_GENERIC_QUIT) {
+ need_reset = 0;
+ switch (ch) {
+ case KEY_GENERIC_HELP:
+ help_wins_init(&hwin, 0, 0, (notify_bar())? row - 3 : row - 2, col);
+ mvwprintw(hwin.pad.p, 1, 0, "%s", help_text);
+ hwin.total_lines = 7;
+ wins_scrollwin_display(&hwin);
+ wgetch(hwin.win.p);
+ wins_scrollwin_delete(&hwin);
+ need_reset = 1;
+ break;
+ case KEY_GENERIC_SELECT:
+ mark = cursor;
+ break;
+ case KEY_MOVE_DOWN:
+ if (cursor % LAYOUTSPERCOL < LAYOUTSPERCOL - 1)
+ cursor++;
+ break;
+ case KEY_MOVE_UP:
+ if (cursor % LAYOUTSPERCOL > 0)
+ cursor--;
+ break;
+ case KEY_MOVE_LEFT:
+ if (cursor >= LAYOUTSPERCOL)
+ cursor -= LAYOUTSPERCOL;
+ break;
+ case KEY_MOVE_RIGHT:
+ if (cursor < NBLAYOUTS - LAYOUTSPERCOL)
+ cursor += LAYOUTSPERCOL;
+ break;
+ case KEY_GENERIC_CANCEL:
+ need_reset = 1;
+ break;
+ }
- if (resize)
- {
- resize = 0;
- endwin ();
- wins_refresh ();
- curs_set (0);
- need_reset = 1;
- }
+ if (resize) {
+ resize = 0;
+ endwin();
+ wins_refresh();
+ curs_set(0);
+ need_reset = 1;
+ }
- if (need_reset)
- custom_confwin_init (&conf_win, label);
+ if (need_reset)
+ custom_confwin_init(&conf_win, label);
- display_layout_config (&conf_win, mark, cursor);
- }
- wins_set_layout (mark + 1);
- delwin (conf_win.p);
+ display_layout_config(&conf_win, mark, cursor);
+ }
+ wins_set_layout(mark + 1);
+ delwin(conf_win.p);
}
#undef NBLAYOUTS
#undef LAYOUTSPERCOL
/* Sidebar configuration screen. */
-void
-custom_sidebar_config (void)
+void custom_sidebar_config(void)
{
struct scrollwin hwin;
- struct binding quit = {_("Exit"), KEY_GENERIC_QUIT};
- struct binding inc = {_("Width +"), KEY_MOVE_UP};
- struct binding dec = {_("Width -"), KEY_MOVE_DOWN};
- struct binding help = {_("Help"), KEY_GENERIC_HELP};
- struct binding *binding[] = {&inc, &dec, &help, &quit};
- char *help_text =
- _("This configuration screen is used to change the width of the side bar.\n"
- "The side bar is the part of the screen which contains two panels:\n"
- "the calendar and, depending on the chosen layout, either the todo list\n"
- "or the appointment list.\n\n"
- "The side bar width can be up to 50% of the total screen width, but\n"
- "can't be smaller than " TOSTRING(SBARMINWIDTH) " characters wide.\n\n");
- int ch, binding_size;
-
- binding_size = sizeof (binding) / sizeof (binding[0]);
-
- keys_display_bindings_bar (win[STA].p, binding, 0, binding_size);
- wins_doupdate ();
-
- while ((ch = keys_getch (win[STA].p)) != KEY_GENERIC_QUIT)
- {
- switch (ch)
- {
- case KEY_MOVE_UP:
- wins_sbar_winc ();
- break;
- case KEY_MOVE_DOWN:
- wins_sbar_wdec ();
- break;
- case KEY_GENERIC_HELP:
- help_wins_init (&hwin, 0, 0,
- (notify_bar ()) ? row - 3 : row - 2, col);
- mvwprintw (hwin.pad.p, 1, 0, "%s", help_text);
- hwin.total_lines = 6;
- wins_scrollwin_display (&hwin);
- wgetch (hwin.win.p);
- wins_scrollwin_delete (&hwin);
- break;
- case KEY_RESIZE:
- break;
- default:
- continue;
- }
+ struct binding quit = { _("Exit"), KEY_GENERIC_QUIT };
+ struct binding inc = { _("Width +"), KEY_MOVE_UP };
+ struct binding dec = { _("Width -"), KEY_MOVE_DOWN };
+ struct binding help = { _("Help"), KEY_GENERIC_HELP };
+ struct binding *bindings[] = {
+ &inc, &dec, &help, &quit
+ };
+ const char *help_text =
+ _
+ ("This configuration screen is used to change the width of the side bar.\n"
+ "The side bar is the part of the screen which contains two panels:\n"
+ "the calendar and, depending on the chosen layout, either the todo list\n"
+ "or the appointment list.\n\n"
+ "The side bar width can be up to 50% of the total screen width, but\n"
+ "can't be smaller than " TOSTRING(SBARMINWIDTH) " characters wide.\n\n");
+ int ch, bindings_size;
+
+ bindings_size = sizeof(bindings) / sizeof(bindings[0]);
+
+ keys_display_bindings_bar(win[STA].p, bindings, bindings_size, 0,
+ bindings_size, NULL);
+ wins_doupdate();
+
+ while ((ch = keys_getch(win[STA].p, NULL)) != KEY_GENERIC_QUIT) {
+ switch (ch) {
+ case KEY_MOVE_UP:
+ wins_sbar_winc();
+ break;
+ case KEY_MOVE_DOWN:
+ wins_sbar_wdec();
+ break;
+ case KEY_GENERIC_HELP:
+ help_wins_init(&hwin, 0, 0, (notify_bar())? row - 3 : row - 2, col);
+ mvwprintw(hwin.pad.p, 1, 0, "%s", help_text);
+ hwin.total_lines = 6;
+ wins_scrollwin_display(&hwin);
+ wgetch(hwin.win.p);
+ wins_scrollwin_delete(&hwin);
+ break;
+ case KEY_RESIZE:
+ break;
+ default:
+ continue;
+ }
- if (resize)
- {
- resize = 0;
- wins_reset ();
- }
- else
- {
- wins_reinit_panels ();
- wins_update_border ();
- wins_update_panels ();
- keys_display_bindings_bar (win[STA].p, binding, 0, binding_size);
- wins_doupdate ();
- }
+ if (resize) {
+ resize = 0;
+ wins_reset();
+ } else {
+ wins_reinit_panels();
+ wins_update_border(FLAG_ALL);
+ wins_update_panels(FLAG_ALL);
+ keys_display_bindings_bar(win[STA].p, bindings, bindings_size, 0,
+ bindings_size, NULL);
+ wins_doupdate();
}
+ }
}
-static void
-set_confwin_attr (struct window *cwin)
+static void set_confwin_attr(struct window *cwin)
{
- cwin->h = (notify_bar ())? row - 3 : row - 2;
+ cwin->h = (notify_bar())? row - 3 : row - 2;
cwin->w = col;
cwin->x = cwin->y = 0;
}
@@ -674,49 +356,45 @@ set_confwin_attr (struct window *cwin)
* Create a configuration window and initialize status and notification bar
* (useful in case of window resize).
*/
-void
-custom_confwin_init (struct window *confwin, char *label)
+void custom_confwin_init(struct window *confwin, const char *label)
{
- if (confwin->p)
- {
- erase_window_part (confwin->p, confwin->x, confwin->y,
- confwin->x + confwin->w, confwin->y + confwin->h);
- (void)delwin (confwin->p);
- }
-
- wins_get_config ();
- set_confwin_attr (confwin);
- confwin->p = newwin (confwin->h, col, 0, 0);
- box (confwin->p, 0, 0);
- wins_show (confwin->p, label);
- delwin (win[STA].p);
- win[STA].p = newwin (win[STA].h, win[STA].w, win[STA].y, win[STA].x);
- keypad (win[STA].p, TRUE);
- if (notify_bar ())
- {
- notify_reinit_bar ();
- notify_update_bar ();
- }
+ if (confwin->p) {
+ erase_window_part(confwin->p, confwin->x, confwin->y,
+ confwin->x + confwin->w, confwin->y + confwin->h);
+ delwin(confwin->p);
+ }
+
+ wins_get_config();
+ set_confwin_attr(confwin);
+ confwin->p = newwin(confwin->h, col, 0, 0);
+ box(confwin->p, 0, 0);
+ wins_show(confwin->p, label);
+ delwin(win[STA].p);
+ win[STA].p = newwin(win[STA].h, win[STA].w, win[STA].y, win[STA].x);
+ keypad(win[STA].p, TRUE);
+ if (notify_bar()) {
+ notify_reinit_bar();
+ notify_update_bar();
+ }
}
-static void
-color_selection_bar (void)
+static void color_selection_bar(void)
{
- struct binding quit = {_("Exit"), KEY_GENERIC_QUIT};
- struct binding select = {_("Select"), KEY_GENERIC_SELECT};
- struct binding nocolor = {_("No color"), KEY_GENERIC_CANCEL};
- struct binding up = {_("Up"), KEY_MOVE_UP};
- struct binding down = {_("Down"), KEY_MOVE_DOWN};
- struct binding left = {_("Left"), KEY_MOVE_LEFT};
- struct binding right = {_("Right"), KEY_MOVE_RIGHT};
-
-
- struct binding *binding[] = {
+ struct binding quit = { _("Exit"), KEY_GENERIC_QUIT };
+ struct binding select = { _("Select"), KEY_GENERIC_SELECT };
+ struct binding nocolor = { _("No color"), KEY_GENERIC_CANCEL };
+ struct binding up = { _("Up"), KEY_MOVE_UP };
+ struct binding down = { _("Down"), KEY_MOVE_DOWN };
+ struct binding left = { _("Left"), KEY_MOVE_LEFT };
+ struct binding right = { _("Right"), KEY_MOVE_RIGHT };
+
+ struct binding *bindings[] = {
&quit, &nocolor, &up, &down, &left, &right, &select
};
- int binding_size = sizeof (binding) / sizeof (binding[0]);
+ int bindings_size = sizeof(bindings) / sizeof(bindings[0]);
- keys_display_bindings_bar (win[STA].p, binding, 0, binding_size);
+ keys_display_bindings_bar(win[STA].p, bindings, bindings_size, 0,
+ bindings_size, NULL);
}
/*
@@ -724,8 +402,8 @@ color_selection_bar (void)
* This is useful for window resizing.
*/
static void
-display_color_config (struct window *cwin, int *mark_fore, int *mark_back,
- int cursor, int theme_changed)
+display_color_config(struct window *cwin, int *mark_fore, int *mark_back,
+ int cursor, int theme_changed)
{
#define SIZE (2 * (NBUSERCOLORS + 1))
#define DEFAULTCOLOR 255
@@ -733,21 +411,20 @@ display_color_config (struct window *cwin, int *mark_fore, int *mark_back,
#define CURSOR (32 | A_REVERSE)
#define MARK 88
- char *fore_txt = _("Foreground");
- char *back_txt = _("Background");
- char *default_txt = _("(terminal's default)");
- char *bar = " ";
- char *box = "[ ]";
+ const char *fore_txt = _("Foreground");
+ const char *back_txt = _("Background");
+ const char *default_txt = _("(terminal's default)");
+ const char *bar = " ";
+ const char *box = "[ ]";
const unsigned Y = 3;
const unsigned XOFST = 5;
const unsigned YSPC = (cwin->h - 8) / (NBUSERCOLORS + 1);
- const unsigned BARSIZ = strlen (bar);
- const unsigned BOXSIZ = strlen (box);
+ const unsigned BARSIZ = strlen(bar);
+ const unsigned BOXSIZ = strlen(box);
const unsigned XSPC = (cwin->w - 2 * BARSIZ - 2 * BOXSIZ - 6) / 3;
const unsigned XFORE = XSPC;
const unsigned XBACK = 2 * XSPC + BOXSIZ + XOFST + BARSIZ;
- enum
- { YPOS, XPOS, NBPOS };
+ enum { YPOS, XPOS, NBPOS };
unsigned i;
int pos[SIZE][NBPOS];
short colr_fore, colr_back;
@@ -758,234 +435,168 @@ display_color_config (struct window *cwin, int *mark_fore, int *mark_back,
COLR_MAGENTA, COLR_CYAN, COLR_DEFAULT
};
- for (i = 0; i < NBUSERCOLORS + 1; i++)
- {
- pos[i][YPOS] = Y + YSPC * (i + 1);
- pos[NBUSERCOLORS + i + 1][YPOS] = Y + YSPC * (i + 1);
- pos[i][XPOS] = XFORE;
- pos[NBUSERCOLORS + i + 1][XPOS] = XBACK;
- }
-
- if (colorize)
- {
- if (theme_changed)
- {
- pair_content (colr[*mark_fore], &colr_fore, 0L);
- if (colr_fore == 255)
- colr_fore = -1;
- pair_content (colr[*mark_back], &colr_back, 0L);
- if (colr_back == 255)
- colr_back = -1;
- init_pair (COLR_CUSTOM, colr_fore, colr_back);
- }
+ for (i = 0; i < NBUSERCOLORS + 1; i++) {
+ pos[i][YPOS] = Y + YSPC * (i + 1);
+ pos[NBUSERCOLORS + i + 1][YPOS] = Y + YSPC * (i + 1);
+ pos[i][XPOS] = XFORE;
+ pos[NBUSERCOLORS + i + 1][XPOS] = XBACK;
+ }
+
+ if (colorize) {
+ if (theme_changed) {
+ pair_content(colr[*mark_fore], &colr_fore, 0L);
+ if (colr_fore == 255)
+ colr_fore = -1;
+ pair_content(colr[*mark_back], &colr_back, 0L);
+ if (colr_back == 255)
+ colr_back = -1;
+ init_pair(COLR_CUSTOM, colr_fore, colr_back);
+ } else {
+ /* Retrieve the actual color theme. */
+ pair_content(COLR_CUSTOM, &colr_fore, &colr_back);
+
+ if ((colr_fore == DEFAULTCOLOR) || (colr_fore == DEFAULTCOLOR_EXT))
+ *mark_fore = NBUSERCOLORS;
else
- {
- /* Retrieve the actual color theme. */
- pair_content (COLR_CUSTOM, &colr_fore, &colr_back);
-
- if ((colr_fore == DEFAULTCOLOR) || (colr_fore == DEFAULTCOLOR_EXT))
- *mark_fore = NBUSERCOLORS;
- else
- for (i = 0; i < NBUSERCOLORS + 1; i++)
- if (colr_fore == colr[i])
- *mark_fore = i;
+ for (i = 0; i < NBUSERCOLORS + 1; i++)
+ if (colr_fore == colr[i])
+ *mark_fore = i;
- if ((colr_back == DEFAULTCOLOR) || (colr_back == DEFAULTCOLOR_EXT))
- *mark_back = SIZE - 1;
- else
- for (i = 0; i < NBUSERCOLORS + 1; i++)
- if (colr_back == colr[NBUSERCOLORS + 1 + i])
- *mark_back = NBUSERCOLORS + 1 + i;
- }
+ if ((colr_back == DEFAULTCOLOR) || (colr_back == DEFAULTCOLOR_EXT))
+ *mark_back = SIZE - 1;
+ else
+ for (i = 0; i < NBUSERCOLORS + 1; i++)
+ if (colr_back == colr[NBUSERCOLORS + 1 + i])
+ *mark_back = NBUSERCOLORS + 1 + i;
}
+ }
/* color boxes */
- for (i = 0; i < SIZE - 1; i++)
- {
- mvwprintw (cwin->p, pos[i][YPOS], pos[i][XPOS], box);
- wattron (cwin->p, COLOR_PAIR (colr[i]) | A_REVERSE);
- mvwprintw (cwin->p, pos[i][YPOS], pos[i][XPOS] + XOFST, bar);
- wattroff (cwin->p, COLOR_PAIR (colr[i]) | A_REVERSE);
- }
+ for (i = 0; i < SIZE - 1; i++) {
+ mvwprintw(cwin->p, pos[i][YPOS], pos[i][XPOS], box);
+ wattron(cwin->p, COLOR_PAIR(colr[i]) | A_REVERSE);
+ mvwprintw(cwin->p, pos[i][YPOS], pos[i][XPOS] + XOFST, bar);
+ wattroff(cwin->p, COLOR_PAIR(colr[i]) | A_REVERSE);
+ }
/* Terminal's default color */
i = SIZE - 1;
- mvwprintw (cwin->p, pos[i][YPOS], pos[i][XPOS], box);
- wattron (cwin->p, COLOR_PAIR (colr[i]));
- mvwprintw (cwin->p, pos[i][YPOS], pos[i][XPOS] + XOFST, bar);
- wattroff (cwin->p, COLOR_PAIR (colr[i]));
- mvwprintw (cwin->p, pos[NBUSERCOLORS][YPOS] + 1,
- pos[NBUSERCOLORS][XPOS] + XOFST, default_txt);
- mvwprintw (cwin->p, pos[SIZE - 1][YPOS] + 1,
- pos[SIZE - 1][XPOS] + XOFST, default_txt);
-
- custom_apply_attr (cwin->p, ATTR_HIGHEST);
- mvwprintw (cwin->p, Y, XFORE + XOFST, fore_txt);
- mvwprintw (cwin->p, Y, XBACK + XOFST, back_txt);
- custom_remove_attr (cwin->p, ATTR_HIGHEST);
-
- if (colorize)
- {
- mvwaddch (cwin->p, pos[*mark_fore][YPOS],
- pos[*mark_fore][XPOS] + 1, MARK);
- mvwaddch (cwin->p, pos[*mark_back][YPOS],
- pos[*mark_back][XPOS] + 1, MARK);
- }
-
- mvwaddch (cwin->p, pos[cursor][YPOS], pos[cursor][XPOS] + 1, CURSOR);
- color_selection_bar ();
- wnoutrefresh (win[STA].p);
- wnoutrefresh (cwin->p);
- wins_doupdate ();
- if (notify_bar ())
- notify_update_bar ();
+ mvwprintw(cwin->p, pos[i][YPOS], pos[i][XPOS], box);
+ wattron(cwin->p, COLOR_PAIR(colr[i]));
+ mvwprintw(cwin->p, pos[i][YPOS], pos[i][XPOS] + XOFST, bar);
+ wattroff(cwin->p, COLOR_PAIR(colr[i]));
+ mvwprintw(cwin->p, pos[NBUSERCOLORS][YPOS] + 1,
+ pos[NBUSERCOLORS][XPOS] + XOFST, default_txt);
+ mvwprintw(cwin->p, pos[SIZE - 1][YPOS] + 1,
+ pos[SIZE - 1][XPOS] + XOFST, default_txt);
+
+ custom_apply_attr(cwin->p, ATTR_HIGHEST);
+ mvwprintw(cwin->p, Y, XFORE + XOFST, fore_txt);
+ mvwprintw(cwin->p, Y, XBACK + XOFST, back_txt);
+ custom_remove_attr(cwin->p, ATTR_HIGHEST);
+
+ if (colorize) {
+ mvwaddch(cwin->p, pos[*mark_fore][YPOS], pos[*mark_fore][XPOS] + 1, MARK);
+ mvwaddch(cwin->p, pos[*mark_back][YPOS], pos[*mark_back][XPOS] + 1, MARK);
+ }
+
+ mvwaddch(cwin->p, pos[cursor][YPOS], pos[cursor][XPOS] + 1, CURSOR);
+ color_selection_bar();
+ wnoutrefresh(win[STA].p);
+ wnoutrefresh(cwin->p);
+ wins_doupdate();
+ if (notify_bar())
+ notify_update_bar();
}
/* Color theme configuration. */
-void
-custom_color_config (void)
+void custom_color_config(void)
{
struct window conf_win;
int ch, cursor, need_reset, theme_changed;
int mark_fore, mark_back;
- char label[BUFSIZ];
+ const char *label = _("color theme");
conf_win.p = 0;
- (void)snprintf (label, BUFSIZ, _("color theme"));
- custom_confwin_init (&conf_win, label);
+ custom_confwin_init(&conf_win, label);
mark_fore = NBUSERCOLORS;
mark_back = SIZE - 1;
cursor = 0;
theme_changed = 0;
- display_color_config (&conf_win, &mark_fore, &mark_back, cursor, theme_changed);
- clear ();
-
- while ((ch = keys_getch (win[STA].p)) != KEY_GENERIC_QUIT)
- {
- need_reset = 0;
- theme_changed = 0;
-
- switch (ch)
- {
- case KEY_GENERIC_SELECT:
- colorize = 1;
- need_reset = 1;
- theme_changed = 1;
- if (cursor > NBUSERCOLORS)
- mark_back = cursor;
- else
- mark_fore = cursor;
- break;
-
- case KEY_MOVE_DOWN:
- if (cursor < SIZE - 1)
- ++cursor;
- break;
-
- case KEY_MOVE_UP:
- if (cursor > 0)
- --cursor;
- break;
-
- case KEY_MOVE_LEFT:
- if (cursor > NBUSERCOLORS)
- cursor -= (NBUSERCOLORS + 1);
- break;
-
- case KEY_MOVE_RIGHT:
- if (cursor <= NBUSERCOLORS)
- cursor += (NBUSERCOLORS + 1);
- break;
-
- case KEY_GENERIC_CANCEL:
- colorize = 0;
- need_reset = 1;
- break;
- }
-
- if (resize)
- {
- resize = 0;
- endwin ();
- wins_refresh ();
- curs_set (0);
- need_reset = 1;
- }
-
- if (need_reset)
- custom_confwin_init (&conf_win, label);
-
- display_color_config (&conf_win, &mark_fore, &mark_back, cursor,
- theme_changed);
+ display_color_config(&conf_win, &mark_fore, &mark_back, cursor,
+ theme_changed);
+ clear();
+
+ while ((ch = keys_getch(win[STA].p, NULL)) != KEY_GENERIC_QUIT) {
+ need_reset = 0;
+ theme_changed = 0;
+
+ switch (ch) {
+ case KEY_GENERIC_SELECT:
+ colorize = 1;
+ need_reset = 1;
+ theme_changed = 1;
+ if (cursor > NBUSERCOLORS)
+ mark_back = cursor;
+ else
+ mark_fore = cursor;
+ break;
+
+ case KEY_MOVE_DOWN:
+ if (cursor < SIZE - 1)
+ ++cursor;
+ break;
+
+ case KEY_MOVE_UP:
+ if (cursor > 0)
+ --cursor;
+ break;
+
+ case KEY_MOVE_LEFT:
+ if (cursor > NBUSERCOLORS)
+ cursor -= (NBUSERCOLORS + 1);
+ break;
+
+ case KEY_MOVE_RIGHT:
+ if (cursor <= NBUSERCOLORS)
+ cursor += (NBUSERCOLORS + 1);
+ break;
+
+ case KEY_GENERIC_CANCEL:
+ colorize = 0;
+ need_reset = 1;
+ break;
}
- delwin (conf_win.p);
-}
-/*
- * Return a string defining the color theme in the form:
- * foreground color 'on' background color
- * in order to dump this data in the configuration file.
- * Color numbers follow the ncurses library definitions.
- * If ncurses library was compiled with --enable-ext-funcs,
- * then default color is -1.
- */
-void
-custom_color_theme_name (char *theme_name)
-{
-#define MAXCOLORS 8
-#define NBCOLORS 2
-#define DEFAULTCOLOR 255
-#define DEFAULTCOLOR_EXT -1
+ if (resize) {
+ resize = 0;
+ endwin();
+ wins_refresh();
+ curs_set(0);
+ need_reset = 1;
+ }
- int i;
- short color[NBCOLORS];
- char *color_name[NBCOLORS];
- char *default_color = "default";
- char *name[MAXCOLORS] = {
- "black",
- "red",
- "green",
- "yellow",
- "blue",
- "magenta",
- "cyan",
- "white"
- };
+ if (need_reset)
+ custom_confwin_init(&conf_win, label);
- if (!colorize)
- (void)snprintf (theme_name, BUFSIZ, "0");
- else
- {
- pair_content (COLR_CUSTOM, &color[0], &color[1]);
- for (i = 0; i < NBCOLORS; i++)
- {
- if ((color[i] == DEFAULTCOLOR) || (color[i] == DEFAULTCOLOR_EXT))
- color_name[i] = default_color;
- else if (color[i] >= 0 && color[i] <= MAXCOLORS)
- color_name[i] = name[color[i]];
- else
- {
- EXIT (_("unknown color"));
- /* NOTREACHED */
- }
- }
- (void)snprintf (theme_name, BUFSIZ, "%s on %s", color_name[0],
- color_name[1]);
- }
+ display_color_config(&conf_win, &mark_fore, &mark_back, cursor,
+ theme_changed);
+ }
+ delwin(conf_win.p);
}
/* Prints the general options. */
-static int
-print_general_options (WINDOW *win, struct conf *conf)
+static int print_general_options(WINDOW * win)
{
enum {
AUTO_SAVE,
+ AUTO_GC,
PERIODIC_SAVE,
CONFIRM_QUIT,
CONFIRM_DELETE,
- SKIP_SYSTEM_DIAGS,
- SKIP_PROGRESS_BAR,
- WEEK_BEGINS_MONDAY,
+ SYSTEM_DIAGS,
+ PROGRESS_BAR,
+ FIRST_DAY_OF_WEEK,
OUTPUT_DATE_FMT,
INPUT_DATE_FMT,
NB_OPTIONS
@@ -994,93 +605,99 @@ print_general_options (WINDOW *win, struct conf *conf)
const int YOFF = 3;
int y;
char *opt[NB_OPTIONS] = {
- _("auto_save = "),
- _("periodic_save = "),
- _("confirm_quit = "),
- _("confirm_delete = "),
- _("skip_system_dialogs = "),
- _("skip_progress_bar = "),
- _("week_begins_on_monday = "),
- _("output_datefmt = "),
- _("input_datefmt = ")
+ _("general.autosave = "),
+ _("general.autogc = "),
+ _("general.periodicsave = "),
+ _("general.confirmquit = "),
+ _("general.confirmdelete = "),
+ _("general.systemdialogs = "),
+ _("general.progressbar = "),
+ _("general.firstdayofweek = "),
+ _("format.outputdate = "),
+ _("format.inputdate = ")
};
y = 0;
- mvwprintw (win, y, XPOS, "[1] %s ", opt[AUTO_SAVE]);
- print_bool_option_incolor (win, conf->auto_save, y,
- XPOS + 4 + strlen (opt[AUTO_SAVE]));
- mvwprintw (win, y + 1, XPOS,
- _("(if set to YES, automatic save is done when quitting)"));
+ mvwprintw(win, y, XPOS, "[1] %s ", opt[AUTO_SAVE]);
+ print_bool_option_incolor(win, conf.auto_save, y,
+ XPOS + 4 + strlen(opt[AUTO_SAVE]));
+ mvwprintw(win, y + 1, XPOS,
+ _("(if set to YES, automatic save is done when quitting)"));
y += YOFF;
- mvwprintw (win, y, XPOS, "[2] %s ", opt[PERIODIC_SAVE]);
- custom_apply_attr (win, ATTR_HIGHEST);
- mvwprintw (win, y, XPOS + 4 + strlen (opt[PERIODIC_SAVE]), "%d",
- conf->periodic_save);
- custom_remove_attr (win, ATTR_HIGHEST);
- mvwprintw (win, y + 1, XPOS,
- _("(if not null, automatically save data every 'periodic_save' "
- "minutes)"));
+ mvwprintw(win, y, XPOS, "[2] %s ", opt[AUTO_GC]);
+ print_bool_option_incolor(win, conf.auto_gc, y,
+ XPOS + 4 + strlen(opt[AUTO_GC]));
+ mvwprintw(win, y + 1, XPOS, _("(run the garbage collector when quitting)"));
y += YOFF;
- mvwprintw (win, y, XPOS, "[3] %s ", opt[CONFIRM_QUIT]);
- print_bool_option_incolor (win, conf->confirm_quit, y,
- XPOS + 4 + strlen (opt[CONFIRM_QUIT]));
- mvwprintw (win, y + 1, XPOS,
- _("(if set to YES, confirmation is required before quitting)"));
+ mvwprintw(win, y, XPOS, "[3] %s ", opt[PERIODIC_SAVE]);
+ custom_apply_attr(win, ATTR_HIGHEST);
+ mvwprintw(win, y, XPOS + 4 + strlen(opt[PERIODIC_SAVE]), "%d",
+ conf.periodic_save);
+ custom_remove_attr(win, ATTR_HIGHEST);
+ mvwprintw(win, y + 1, XPOS,
+ _("(if not null, automatically save data every 'periodic_save' "
+ "minutes)"));
y += YOFF;
- mvwprintw (win, y, XPOS, "[4] %s ", opt[CONFIRM_DELETE]);
- print_bool_option_incolor (win, conf->confirm_delete, y,
- XPOS + 4 + strlen (opt[CONFIRM_DELETE]));
- mvwprintw (win, y + 1, XPOS,
- _("(if set to YES, confirmation is required "
- "before deleting an event)"));
+ mvwprintw(win, y, XPOS, "[4] %s ", opt[CONFIRM_QUIT]);
+ print_bool_option_incolor(win, conf.confirm_quit, y,
+ XPOS + 4 + strlen(opt[CONFIRM_QUIT]));
+ mvwprintw(win, y + 1, XPOS,
+ _("(if set to YES, confirmation is required before quitting)"));
y += YOFF;
- mvwprintw (win, y, XPOS, "[5] %s ", opt[SKIP_SYSTEM_DIAGS]);
- print_bool_option_incolor (win, conf->skip_system_dialogs, y,
- XPOS + 4 + strlen (opt[SKIP_SYSTEM_DIAGS]));
- mvwprintw (win, y + 1, XPOS,
- _("(if set to YES, messages about loaded "
- "and saved data will not be displayed)"));
+ mvwprintw(win, y, XPOS, "[5] %s ", opt[CONFIRM_DELETE]);
+ print_bool_option_incolor(win, conf.confirm_delete, y,
+ XPOS + 4 + strlen(opt[CONFIRM_DELETE]));
+ mvwprintw(win, y + 1, XPOS,
+ _("(if set to YES, confirmation is required "
+ "before deleting an event)"));
y += YOFF;
- mvwprintw (win, y, XPOS, "[6] %s ", opt[SKIP_PROGRESS_BAR]);
- print_bool_option_incolor (win, conf->skip_progress_bar, y,
- XPOS + 4 + strlen (opt[SKIP_PROGRESS_BAR]));
- mvwprintw (win, y + 1, XPOS,
- _("(if set to YES, progress bar will not be displayed "
- "when saving data)"));
+ mvwprintw(win, y, XPOS, "[6] %s ", opt[SYSTEM_DIAGS]);
+ print_bool_option_incolor(win, conf.system_dialogs, y,
+ XPOS + 4 + strlen(opt[SYSTEM_DIAGS]));
+ mvwprintw(win, y + 1, XPOS,
+ _("(if set to YES, messages about loaded "
+ "and saved data will be displayed)"));
y += YOFF;
- mvwprintw (win, y, XPOS, "[7] %s ", opt[WEEK_BEGINS_MONDAY]);
- print_bool_option_incolor (win, calendar_week_begins_on_monday (), y,
- XPOS + 4 + strlen (opt[WEEK_BEGINS_MONDAY]));
- mvwprintw (win, y + 1, XPOS,
- _("(if set to YES, monday is the first day of the week, "
- "else it is sunday)"));
+ mvwprintw(win, y, XPOS, "[7] %s ", opt[PROGRESS_BAR]);
+ print_bool_option_incolor(win, conf.progress_bar, y,
+ XPOS + 4 + strlen(opt[PROGRESS_BAR]));
+ mvwprintw(win, y + 1, XPOS,
+ _("(if set to YES, progress bar will be displayed "
+ "when saving data)"));
y += YOFF;
- mvwprintw (win, y, XPOS, "[8] %s ", opt[OUTPUT_DATE_FMT]);
- custom_apply_attr (win, ATTR_HIGHEST);
- mvwprintw (win, y, XPOS + 4 + strlen (opt[OUTPUT_DATE_FMT]), "%s",
- conf->output_datefmt);
- custom_remove_attr (win, ATTR_HIGHEST);
- mvwprintw (win, y + 1, XPOS,
- _("(Format of the date to be displayed in non-interactive mode)"));
+ mvwprintw(win, y, XPOS, "[8] %s ", opt[FIRST_DAY_OF_WEEK]);
+ custom_apply_attr(win, ATTR_HIGHEST);
+ mvwprintw(win, y, XPOS + 4 + strlen(opt[FIRST_DAY_OF_WEEK]), "%s",
+ calendar_week_begins_on_monday()? _("Monday") : _("Sunday"));
+ custom_remove_attr(win, ATTR_HIGHEST);
+ mvwprintw(win, y + 1, XPOS,
+ _("(specifies the first day of week in the calendar view)"));
y += YOFF;
- mvwprintw (win, y, XPOS, "[9] %s ", opt[INPUT_DATE_FMT]);
- custom_apply_attr (win, ATTR_HIGHEST);
- mvwprintw (win, y, XPOS + 4 + strlen (opt[INPUT_DATE_FMT]), "%d",
- conf->input_datefmt);
- custom_remove_attr (win, ATTR_HIGHEST);
- mvwprintw (win, y + 1, XPOS, _("(Format to be used when entering a date: "));
- mvwprintw (win, y + 2, XPOS,
- _(" (1)mm/dd/yyyy (2)dd/mm/yyyy (3)yyyy/mm/dd (4)yyyy-mm-dd)"));
+ mvwprintw(win, y, XPOS, "[9] %s ", opt[OUTPUT_DATE_FMT]);
+ custom_apply_attr(win, ATTR_HIGHEST);
+ mvwprintw(win, y, XPOS + 4 + strlen(opt[OUTPUT_DATE_FMT]), "%s",
+ conf.output_datefmt);
+ custom_remove_attr(win, ATTR_HIGHEST);
+ mvwprintw(win, y + 1, XPOS,
+ _("(Format of the date to be displayed in non-interactive mode)"));
+ y += YOFF;
+ mvwprintw(win, y, XPOS, "[0] %s ", opt[INPUT_DATE_FMT]);
+ custom_apply_attr(win, ATTR_HIGHEST);
+ mvwprintw(win, y, XPOS + 4 + strlen(opt[INPUT_DATE_FMT]), "%d",
+ conf.input_datefmt);
+ custom_remove_attr(win, ATTR_HIGHEST);
+ mvwprintw(win, y + 1, XPOS, _("(Format to be used when entering a date: "));
+ mvwprintw(win, y + 2, XPOS,
+ _(" (1)mm/dd/yyyy (2)dd/mm/yyyy (3)yyyy/mm/dd (4)yyyy-mm-dd)"));
return y + YOFF;
}
-void
-custom_set_swsiz (struct scrollwin *sw)
+void custom_set_swsiz(struct scrollwin *sw)
{
sw->win.x = 0;
sw->win.y = 0;
- sw->win.h = (notify_bar ()) ? row - 3 : row - 2;
+ sw->win.h = (notify_bar())? row - 3 : row - 2;
sw->win.w = col;
sw->pad.x = 1;
@@ -1090,143 +707,132 @@ custom_set_swsiz (struct scrollwin *sw)
}
/* General configuration. */
-void
-custom_general_config (struct conf *conf)
+void custom_general_config(void)
{
struct scrollwin cwin;
- char *number_str =
- _("Enter an option number to change its value");
- char *keys =
- _("(Press '^P' or '^N' to move up or down, 'Q' to quit)");
- char *output_datefmt_str =
- _("Enter the date format (see 'man 3 strftime' for possible formats) ");
- char *input_datefmt_str =
- _("Enter the date format (1)mm/dd/yyyy (2)dd/mm/yyyy (3)yyyy/mm/dd "
- "(4)yyyy-mm-dd");
- char *periodic_save_str =
- _("Enter the delay, in minutes, between automatic saves (0 to disable) ");
+ const char *number_str = _("Enter an option number to change its value");
+ const char *keys = _("(Press '^P' or '^N' to move up or down, 'Q' to quit)");
+ const char *output_datefmt_str =
+ _("Enter the date format (see 'man 3 strftime' for possible formats) ");
+ const char *input_datefmt_str =
+ _("Enter the date format (1)mm/dd/yyyy (2)dd/mm/yyyy (3)yyyy/mm/dd "
+ "(4)yyyy-mm-dd");
+ const char *periodic_save_str =
+ _("Enter the delay, in minutes, between automatic saves (0 to disable) ");
int ch;
char *buf;
- clear ();
- custom_set_swsiz (&cwin);
- (void)snprintf (cwin.label, BUFSIZ, _("general options"));
- wins_scrollwin_init (&cwin);
- wins_show (cwin.win.p, cwin.label);
- status_mesg (number_str, keys);
- cwin.total_lines = print_general_options (cwin.pad.p, conf);
- wins_scrollwin_display (&cwin);
-
- buf = mem_malloc (BUFSIZ);
- while ((ch = wgetch (win[STA].p)) != 'q')
- {
- buf[0] = '\0';
-
- switch (ch)
- {
- case CTRL ('N'):
- wins_scrollwin_down (&cwin, 1);
- break;
- case CTRL ('P'):
- wins_scrollwin_up (&cwin, 1);
- break;
- case '1':
- conf->auto_save = !conf->auto_save;
- break;
- case '2':
- status_mesg (periodic_save_str, "");
- if (updatestring (win[STA].p, &buf, 0, 1) == 0)
- {
- int val = atoi (buf);
- if (val >= 0)
- conf->periodic_save = val;
- if (conf->periodic_save > 0)
- io_start_psave_thread (conf);
- else if (conf->periodic_save == 0)
- io_stop_psave_thread ();
- }
- status_mesg (number_str, keys);
- break;
- case '3':
- conf->confirm_quit = !conf->confirm_quit;
- break;
- case '4':
- conf->confirm_delete = !conf->confirm_delete;
- break;
- case '5':
- conf->skip_system_dialogs = !conf->skip_system_dialogs;
- break;
- case '6':
- conf->skip_progress_bar = !conf->skip_progress_bar;
- break;
- case '7':
- calendar_change_first_day_of_week ();
- break;
- case '8':
- status_mesg (output_datefmt_str, "");
- (void)strncpy (buf, conf->output_datefmt,
- strlen (conf->output_datefmt) + 1);
- if (updatestring (win[STA].p, &buf, 0, 1) == 0)
- {
- (void)strncpy (conf->output_datefmt, buf, strlen (buf) + 1);
- }
- status_mesg (number_str, keys);
- break;
- case '9':
- status_mesg (input_datefmt_str, "");
- if (updatestring (win[STA].p, &buf, 0, 1) == 0)
- {
- int val = atoi (buf);
- if (val > 0 && val <= DATE_FORMATS)
- conf->input_datefmt = val;
- }
- status_mesg (number_str, keys);
- break;
- }
-
- if (resize)
- {
- resize = 0;
- wins_reset ();
- wins_scrollwin_delete (&cwin);
- custom_set_swsiz (&cwin);
- wins_scrollwin_init (&cwin);
- wins_show (cwin.win.p, cwin.label);
- cwin.first_visible_line = 0;
- delwin (win[STA].p);
- win[STA].p = newwin (win[STA].h, win[STA].w, win[STA].y,
- win[STA].x);
- keypad (win[STA].p, TRUE);
- if (notify_bar ())
- {
- notify_reinit_bar ();
- notify_update_bar ();
- }
- }
+ clear();
+ custom_set_swsiz(&cwin);
+ cwin.label = _("general options");
+ wins_scrollwin_init(&cwin);
+ wins_show(cwin.win.p, cwin.label);
+ status_mesg(number_str, keys);
+ cwin.total_lines = print_general_options(cwin.pad.p);
+ wins_scrollwin_display(&cwin);
+
+ buf = mem_malloc(BUFSIZ);
+ while ((ch = wgetch(win[STA].p)) != 'q') {
+ buf[0] = '\0';
+
+ switch (ch) {
+ case CTRL('N'):
+ wins_scrollwin_down(&cwin, 1);
+ break;
+ case CTRL('P'):
+ wins_scrollwin_up(&cwin, 1);
+ break;
+ case '1':
+ conf.auto_save = !conf.auto_save;
+ break;
+ case '2':
+ conf.auto_gc = !conf.auto_gc;
+ break;
+ case '3':
+ status_mesg(periodic_save_str, "");
+ if (updatestring(win[STA].p, &buf, 0, 1) == 0) {
+ int val = atoi(buf);
+ if (val >= 0)
+ conf.periodic_save = val;
+ if (conf.periodic_save > 0)
+ io_start_psave_thread();
+ else if (conf.periodic_save == 0)
+ io_stop_psave_thread();
+ }
+ status_mesg(number_str, keys);
+ break;
+ case '4':
+ conf.confirm_quit = !conf.confirm_quit;
+ break;
+ case '5':
+ conf.confirm_delete = !conf.confirm_delete;
+ break;
+ case '6':
+ conf.system_dialogs = !conf.system_dialogs;
+ break;
+ case '7':
+ conf.progress_bar = !conf.progress_bar;
+ break;
+ case '8':
+ calendar_change_first_day_of_week();
+ break;
+ case '9':
+ status_mesg(output_datefmt_str, "");
+ strncpy(buf, conf.output_datefmt, strlen(conf.output_datefmt) + 1);
+ if (updatestring(win[STA].p, &buf, 0, 1) == 0) {
+ strncpy(conf.output_datefmt, buf, strlen(buf) + 1);
+ }
+ status_mesg(number_str, keys);
+ break;
+ case '0':
+ status_mesg(input_datefmt_str, "");
+ if (updatestring(win[STA].p, &buf, 0, 1) == 0) {
+ int val = atoi(buf);
+ if (val > 0 && val <= DATE_FORMATS)
+ conf.input_datefmt = val;
+ }
+ status_mesg(number_str, keys);
+ break;
+ }
- status_mesg (number_str, keys);
- cwin.total_lines = print_general_options (cwin.pad.p, conf);
- wins_scrollwin_display (&cwin);
+ if (resize) {
+ resize = 0;
+ wins_reset();
+ wins_scrollwin_delete(&cwin);
+ custom_set_swsiz(&cwin);
+ wins_scrollwin_init(&cwin);
+ wins_show(cwin.win.p, cwin.label);
+ cwin.first_visible_line = 0;
+ delwin(win[STA].p);
+ win[STA].p = newwin(win[STA].h, win[STA].w, win[STA].y, win[STA].x);
+ keypad(win[STA].p, TRUE);
+ if (notify_bar()) {
+ notify_reinit_bar();
+ notify_update_bar();
+ }
}
- mem_free (buf);
- wins_scrollwin_delete (&cwin);
-}
+ status_mesg(number_str, keys);
+ cwin.total_lines = print_general_options(cwin.pad.p);
+ wins_scrollwin_display(&cwin);
+ }
+ mem_free(buf);
+ wins_scrollwin_delete(&cwin);
+}
static void
-print_key_incolor (WINDOW *win, char *option, int pos_y, int pos_x)
+print_key_incolor(WINDOW * win, const char *option, int pos_y, int pos_x)
{
const int color = ATTR_HIGHEST;
- RETURN_IF (!option, _("Undefined option!"));
- custom_apply_attr (win, color);
- mvwprintw (win, pos_y, pos_x, "%s ", option);
- custom_remove_attr (win, color);
- wnoutrefresh (win);
+ RETURN_IF(!option, _("Undefined option!"));
+ custom_apply_attr(win, color);
+ mvwprintw(win, pos_y, pos_x, "%s ", option);
+ custom_remove_attr(win, color);
}
static int
-print_keys_bindings (WINDOW *win, int selected_row, int selected_elm, int yoff)
+print_keys_bindings(WINDOW * win, int selected_row, int selected_elm, int yoff)
{
const int XPOS = 1;
const int EQUALPOS = 23;
@@ -1234,208 +840,242 @@ print_keys_bindings (WINDOW *win, int selected_row, int selected_elm, int yoff)
int noelm, action, y;
noelm = y = 0;
- for (action = 0; action < NBKEYS; action++)
- {
- char actionstr[BUFSIZ];
- int nbkeys;
-
- nbkeys = keys_action_count_keys (action);
- (void)snprintf (actionstr, BUFSIZ, "%s", keys_get_label (action));
- if (action == selected_row)
- custom_apply_attr (win, ATTR_HIGHEST);
- mvwprintw (win, y, XPOS, "%s ", actionstr);
- mvwprintw (win, y, EQUALPOS, "=");
- if (nbkeys == 0)
- mvwprintw (win, y, KEYPOS, _("undefined"));
- if (action == selected_row)
- custom_remove_attr (win, ATTR_HIGHEST);
- if (nbkeys > 0)
- {
- if (action == selected_row)
- {
- char *key;
- int pos;
-
- pos = KEYPOS;
- while ((key = keys_action_nkey (action, noelm)) != NULL)
- {
- if (noelm == selected_elm)
- print_key_incolor (win, key, y, pos);
- else
- mvwprintw (win, y, pos, "%s ", key);
- noelm++;
- pos += strlen (key) + 1;
- }
- }
+ for (action = 0; action < NBKEYS; action++) {
+ char actionstr[BUFSIZ];
+ int nbkeys;
+
+ nbkeys = keys_action_count_keys(action);
+ snprintf(actionstr, BUFSIZ, "%s", keys_get_label(action));
+ if (action == selected_row)
+ custom_apply_attr(win, ATTR_HIGHEST);
+ mvwprintw(win, y, XPOS, "%s ", actionstr);
+ mvwprintw(win, y, EQUALPOS, "=");
+ if (nbkeys == 0)
+ mvwprintw(win, y, KEYPOS, _("undefined"));
+ if (action == selected_row)
+ custom_remove_attr(win, ATTR_HIGHEST);
+ if (nbkeys > 0) {
+ if (action == selected_row) {
+ const char *key;
+ int pos;
+
+ pos = KEYPOS;
+ while ((key = keys_action_nkey(action, noelm)) != NULL) {
+ if (noelm == selected_elm)
+ print_key_incolor(win, key, y, pos);
else
- {
- mvwprintw (win, y, KEYPOS, "%s", keys_action_allkeys (action));
- }
+ mvwprintw(win, y, pos, "%s ", key);
+ noelm++;
+ pos += strlen(key) + 1;
}
- y += yoff;
+ } else {
+ mvwprintw(win, y, KEYPOS, "%s", keys_action_allkeys(action));
+ }
}
+ y += yoff;
+ }
return noelm;
}
-static void
-custom_keys_config_bar (void)
+static void custom_keys_config_bar(void)
{
- struct binding quit = {_("Exit"), KEY_GENERIC_QUIT};
- struct binding info = {_("Key info"), KEY_GENERIC_HELP};
- struct binding add = {_("Add key"), KEY_ADD_ITEM};
- struct binding del = {_("Del key"), KEY_DEL_ITEM};
- struct binding up = {_("Up"), KEY_MOVE_UP};
- struct binding down = {_("Down"), KEY_MOVE_DOWN};
- struct binding left = {_("Prev Key"), KEY_MOVE_LEFT};
- struct binding right = {_("Next Key"), KEY_MOVE_RIGHT};
-
- struct binding *binding[] = {
+ struct binding quit = { _("Exit"), KEY_GENERIC_QUIT };
+ struct binding info = { _("Key info"), KEY_GENERIC_HELP };
+ struct binding add = { _("Add key"), KEY_ADD_ITEM };
+ struct binding del = { _("Del key"), KEY_DEL_ITEM };
+ struct binding up = { _("Up"), KEY_MOVE_UP };
+ struct binding down = { _("Down"), KEY_MOVE_DOWN };
+ struct binding left = { _("Prev Key"), KEY_MOVE_LEFT };
+ struct binding right = { _("Next Key"), KEY_MOVE_RIGHT };
+
+ struct binding *bindings[] = {
&quit, &info, &add, &del, &up, &down, &left, &right
};
- int binding_size = sizeof (binding) / sizeof (binding[0]);
+ int bindings_size = sizeof(bindings) / sizeof(bindings[0]);
- keys_display_bindings_bar (win[STA].p, binding, 0, binding_size);
+ keys_display_bindings_bar(win[STA].p, bindings, bindings_size, 0,
+ bindings_size, NULL);
}
-void
-custom_keys_config (void)
+void custom_keys_config(void)
{
struct scrollwin kwin;
int selrow, selelm, firstrow, lastrow, nbrowelm, nbdisplayed;
int keyval, used, not_recognized;
- char *keystr;
+ const char *keystr;
WINDOW *grabwin;
const int LINESPERKEY = 2;
const int LABELLINES = 3;
- clear ();
- custom_set_swsiz (&kwin);
+ clear();
+ custom_set_swsiz(&kwin);
nbdisplayed = (kwin.win.h - LABELLINES) / LINESPERKEY;
- (void)snprintf (kwin.label, BUFSIZ, _("keys configuration"));
- wins_scrollwin_init (&kwin);
- wins_show (kwin.win.p, kwin.label);
- custom_keys_config_bar ();
+ kwin.label = _("keys configuration");
+ wins_scrollwin_init(&kwin);
+ wins_show(kwin.win.p, kwin.label);
+ custom_keys_config_bar();
selrow = selelm = 0;
- nbrowelm = print_keys_bindings (kwin.pad.p, selrow, selelm, LINESPERKEY);
+ nbrowelm = print_keys_bindings(kwin.pad.p, selrow, selelm, LINESPERKEY);
kwin.total_lines = NBKEYS * LINESPERKEY;
- wins_scrollwin_display (&kwin);
+ wins_scrollwin_display(&kwin);
firstrow = 0;
lastrow = firstrow + nbdisplayed - 1;
- for (;;)
- {
- int ch;
-
- ch = keys_getch (win[STA].p);
- switch (ch)
- {
- case KEY_MOVE_UP:
- if (selrow > 0)
- {
- selrow--;
- selelm = 0;
- if (selrow == firstrow)
- {
- firstrow--;
- lastrow--;
- wins_scrollwin_up (&kwin, LINESPERKEY);
- }
- }
- break;
- case KEY_MOVE_DOWN:
- if (selrow < NBKEYS - 1)
- {
- selrow++;
- selelm = 0;
- if (selrow == lastrow)
- {
- firstrow++;
- lastrow++;
- wins_scrollwin_down (&kwin, LINESPERKEY);
- }
- }
- break;
- case KEY_MOVE_LEFT:
- if (selelm > 0)
- selelm--;
- break;
- case KEY_MOVE_RIGHT:
- if (selelm < nbrowelm - 1)
- selelm++;
- break;
- case KEY_GENERIC_HELP:
- keys_popup_info (selrow);
- break;
- case KEY_ADD_ITEM:
+ for (;;) {
+ int ch;
+
+ ch = keys_getch(win[STA].p, NULL);
+ switch (ch) {
+ case KEY_MOVE_UP:
+ if (selrow > 0) {
+ selrow--;
+ selelm = 0;
+ if (selrow == firstrow) {
+ firstrow--;
+ lastrow--;
+ wins_scrollwin_up(&kwin, LINESPERKEY);
+ }
+ }
+ break;
+ case KEY_MOVE_DOWN:
+ if (selrow < NBKEYS - 1) {
+ selrow++;
+ selelm = 0;
+ if (selrow == lastrow) {
+ firstrow++;
+ lastrow++;
+ wins_scrollwin_down(&kwin, LINESPERKEY);
+ }
+ }
+ break;
+ case KEY_MOVE_LEFT:
+ if (selelm > 0)
+ selelm--;
+ break;
+ case KEY_MOVE_RIGHT:
+ if (selelm < nbrowelm - 1)
+ selelm++;
+ break;
+ case KEY_GENERIC_HELP:
+ keys_popup_info(selrow);
+ break;
+ case KEY_ADD_ITEM:
#define WINROW 10
#define WINCOL 50
- do
- {
- used = 0;
- grabwin = popup (WINROW, WINCOL, (row - WINROW) / 2,
- (col - WINCOL) / 2,
- _("Press the key you want to assign to:"),
- keys_get_label (selrow), 0);
- keyval = wgetch (grabwin);
-
- /* First check if this key would be recognized by calcurse. */
- if (keys_str2int (keys_int2str (keyval)) == -1)
- {
- not_recognized = 1;
- WARN_MSG (_("This key is not yet recognized by calcurse, "
- "please choose another one."));
- werase (kwin.pad.p);
- nbrowelm = print_keys_bindings (kwin.pad.p, selrow, selelm,
- LINESPERKEY);
- wins_scrollwin_display (&kwin);
- continue;
- }
- else
- not_recognized = 0;
-
- used = keys_assign_binding (keyval, selrow);
- if (used)
- {
- enum key action;
-
- action = keys_get_action (keyval);
- WARN_MSG (_("This key is already in use for %s, "
- "please choose another one."),
- keys_get_label (action));
- werase (kwin.pad.p);
- nbrowelm = print_keys_bindings (kwin.pad.p, selrow, selelm,
- LINESPERKEY);
- wins_scrollwin_display (&kwin);
- }
- delwin (grabwin);
- }
- while (used || not_recognized);
- nbrowelm++;
- if (selelm < nbrowelm - 1)
- selelm++;
+ do {
+ used = 0;
+ grabwin = popup(WINROW, WINCOL, (row - WINROW) / 2,
+ (col - WINCOL) / 2,
+ _("Press the key you want to assign to:"),
+ keys_get_label(selrow), 0);
+ keyval = wgetch(grabwin);
+
+ /* First check if this key would be recognized by calcurse. */
+ if (keys_str2int(keys_int2str(keyval)) == -1) {
+ not_recognized = 1;
+ WARN_MSG(_("This key is not yet recognized by calcurse, "
+ "please choose another one."));
+ werase(kwin.pad.p);
+ nbrowelm = print_keys_bindings(kwin.pad.p, selrow, selelm,
+ LINESPERKEY);
+ wins_scrollwin_display(&kwin);
+ continue;
+ } else
+ not_recognized = 0;
+
+ used = keys_assign_binding(keyval, selrow);
+ if (used) {
+ enum key action;
+
+ action = keys_get_action(keyval);
+ WARN_MSG(_("This key is already in use for %s, "
+ "please choose another one."), keys_get_label(action));
+ werase(kwin.pad.p);
+ nbrowelm = print_keys_bindings(kwin.pad.p, selrow, selelm,
+ LINESPERKEY);
+ wins_scrollwin_display(&kwin);
+ }
+ delwin(grabwin);
+ }
+ while (used || not_recognized);
+ nbrowelm++;
+ if (selelm < nbrowelm - 1)
+ selelm++;
#undef WINROW
#undef WINCOL
- break;
- case KEY_DEL_ITEM:
- keystr = keys_action_nkey (selrow, selelm);
- keyval = keys_str2int (keystr);
- keys_remove_binding (keyval, selrow);
- nbrowelm--;
- if (selelm > 0 && selelm <= nbrowelm)
- selelm--;
- break;
- case KEY_GENERIC_QUIT:
- if (keys_check_missing_bindings () != 0)
- {
- WARN_MSG (_("Some actions do not have any associated "
- "key bindings!"));
- }
- wins_scrollwin_delete (&kwin);
- return;
- }
- custom_keys_config_bar ();
- werase (kwin.pad.p);
- nbrowelm = print_keys_bindings (kwin.pad.p, selrow, selelm, LINESPERKEY);
- wins_scrollwin_display (&kwin);
+ break;
+ case KEY_DEL_ITEM:
+ keystr = keys_action_nkey(selrow, selelm);
+ keyval = keys_str2int(keystr);
+ keys_remove_binding(keyval, selrow);
+ nbrowelm--;
+ if (selelm > 0 && selelm <= nbrowelm)
+ selelm--;
+ break;
+ case KEY_GENERIC_QUIT:
+ if (keys_check_missing_bindings() != 0) {
+ WARN_MSG(_("Some actions do not have any associated " "key bindings!"));
+ }
+ wins_scrollwin_delete(&kwin);
+ return;
+ }
+ custom_keys_config_bar();
+ werase(kwin.pad.p);
+ nbrowelm = print_keys_bindings(kwin.pad.p, selrow, selelm, LINESPERKEY);
+ wins_scrollwin_display(&kwin);
+ }
+}
+
+void custom_config_main(void)
+{
+ const char *no_color_support =
+ _("Sorry, colors are not supported by your terminal\n"
+ "(Press [ENTER] to continue)");
+ int ch;
+ int old_layout;
+
+ custom_config_bar();
+ while ((ch = wgetch(win[STA].p)) != 'q') {
+ switch (ch) {
+ case 'C':
+ case 'c':
+ if (has_colors())
+ custom_color_config();
+ else {
+ colorize = 0;
+ wins_erase_status_bar();
+ mvwprintw(win[STA].p, 0, 0, _(no_color_support));
+ wgetch(win[STA].p);
+ }
+ break;
+ case 'L':
+ case 'l':
+ old_layout = wins_layout();
+ custom_layout_config();
+ if (wins_layout() != old_layout)
+ wins_reset();
+ break;
+ case 'G':
+ case 'g':
+ custom_general_config();
+ break;
+ case 'N':
+ case 'n':
+ notify_config_bar();
+ break;
+ case 'K':
+ case 'k':
+ custom_keys_config();
+ break;
+ case 's':
+ case 'S':
+ custom_sidebar_config();
+ break;
+ default:
+ continue;
}
+ wins_update(FLAG_ALL);
+ wins_erase_status_bar();
+ custom_config_bar();
+ }
}
diff --git a/src/day.c b/src/day.c
index 7e2f6fb..c542c46 100644
--- a/src/day.c
+++ b/src/day.c
@@ -1,7 +1,7 @@
/*
* Calcurse - text-based organizer
*
- * Copyright (c) 2004-2011 calcurse Development Team <misc@calcurse.org>
+ * Copyright (c) 2004-2012 calcurse Development Team <misc@calcurse.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -43,26 +43,24 @@
#include "calcurse.h"
struct day_saved_item {
- char start[BUFSIZ];
- char end[BUFSIZ];
- char state;
- char type;
+ char start[BUFSIZ];
+ char end[BUFSIZ];
+ char state;
+ char type;
char *mesg;
};
-static llist_t day_items;
-static struct day_saved_item day_saved_item;
+static llist_t day_items;
+static struct day_saved_item day_saved_item;
-static void
-day_free (struct day_item *day)
+static void day_free(struct day_item *day)
{
- mem_free (day);
+ mem_free(day);
}
-static void
-day_init_list (void)
+static void day_init_list(void)
{
- LLIST_INIT (&day_items);
+ LLIST_INIT(&day_items);
}
/*
@@ -70,20 +68,19 @@ day_init_list (void)
* Must not free associated message and note, because their are not dynamically
* allocated (only pointers to real objects are stored in this structure).
*/
-void
-day_free_list (void)
+void day_free_list(void)
{
- LLIST_FREE_INNER (&day_items, day_free);
- LLIST_FREE (&day_items);
+ LLIST_FREE_INNER(&day_items, day_free);
+ LLIST_FREE(&day_items);
}
/* Add an event in the current day list */
-static struct day_item *
-day_add_event (int type, char *mesg, char *note, long nday, int id)
+static struct day_item *day_add_event(int type, char *mesg, char *note,
+ long nday, int id)
{
struct day_item *day;
- day = mem_malloc (sizeof (struct day_item));
+ day = mem_malloc(sizeof(struct day_item));
day->mesg = mesg;
day->note = note;
day->type = type;
@@ -92,35 +89,32 @@ day_add_event (int type, char *mesg, char *note, long nday, int id)
day->start = nday;
day->evnt_id = id;
- LLIST_ADD (&day_items, day);
+ LLIST_ADD(&day_items, day);
return day;
}
-static int
-day_cmp_start (struct day_item *a, struct day_item *b)
+static int day_cmp_start(struct day_item *a, struct day_item *b)
{
- if (a->type <= EVNT)
- {
- if (b->type <= EVNT)
- return 0;
- else
- return -1;
- }
- else if (b->type <= EVNT)
+ if (a->type <= EVNT) {
+ if (b->type <= EVNT)
+ return 0;
+ else
+ return -1;
+ } else if (b->type <= EVNT)
return 1;
else
- return (a->start < b->start ? -1 : (a->start == b->start ? 0 : 1));
+ return a->start < b->start ? -1 : (a->start == b->start ? 0 : 1);
}
/* Add an appointment in the current day list. */
-static struct day_item *
-day_add_apoint (int type, char *mesg, char *note, long start, long dur,
- char state, int real_pos)
+static struct day_item *day_add_apoint(int type, char *mesg, char *note,
+ long start, long dur, char state,
+ int real_pos)
{
struct day_item *day;
- day = mem_malloc (sizeof (struct day_item));
+ day = mem_malloc(sizeof(struct day_item));
day->mesg = mesg;
day->note = note;
day->start = start;
@@ -130,7 +124,7 @@ day_add_apoint (int type, char *mesg, char *note, long start, long dur,
day->type = type;
day->evnt_id = 0;
- LLIST_ADD_SORTED (&day_items, day, day_cmp_start);
+ LLIST_ADD_SORTED(&day_items, day, day_cmp_start);
return day;
}
@@ -142,18 +136,16 @@ day_add_apoint (int type, char *mesg, char *note, long start, long dur,
* dedicated to the selected day.
* Returns the number of events for the selected day.
*/
-static int
-day_store_events (long date)
+static int day_store_events(long date)
{
llist_item_t *i;
int e_nb = 0;
- LLIST_FIND_FOREACH (&eventlist, date, event_inday, i)
- {
- struct event *ev = LLIST_TS_GET_DATA (i);
- (void)day_add_event (EVNT, ev->mesg, ev->note, ev->day, ev->id);
- e_nb++;
- }
+ LLIST_FIND_FOREACH_CONT(&eventlist, date, event_inday, i) {
+ struct event *ev = LLIST_TS_GET_DATA(i);
+ day_add_event(EVNT, ev->mesg, ev->note, ev->day, ev->id);
+ e_nb++;
+ }
return e_nb;
}
@@ -165,19 +157,16 @@ day_store_events (long date)
* dedicated to the selected day.
* Returns the number of recurrent events for the selected day.
*/
-static int
-day_store_recur_events (long date)
+static int day_store_recur_events(long date)
{
llist_item_t *i;
int e_nb = 0;
- LLIST_FIND_FOREACH (&recur_elist, date, recur_event_inday, i)
- {
- struct recur_event *rev = LLIST_TS_GET_DATA (i);
- (void)day_add_event (RECUR_EVNT, rev->mesg, rev->note, rev->day,
- rev->id);
- e_nb++;
- }
+ LLIST_FIND_FOREACH(&recur_elist, date, recur_event_inday, i) {
+ struct recur_event *rev = LLIST_TS_GET_DATA(i);
+ day_add_event(RECUR_EVNT, rev->mesg, rev->note, rev->day, rev->id);
+ e_nb++;
+ }
return e_nb;
}
@@ -189,21 +178,23 @@ day_store_recur_events (long date)
* structure dedicated to the selected day.
* Returns the number of appointments for the selected day.
*/
-static int
-day_store_apoints (long date)
+static int day_store_apoints(long date)
{
llist_item_t *i;
int a_nb = 0;
- LLIST_TS_LOCK (&alist_p);
- LLIST_TS_FIND_FOREACH (&alist_p, date, apoint_inday, i)
- {
- struct apoint *apt = LLIST_TS_GET_DATA (i);
- (void)day_add_apoint (APPT, apt->mesg, apt->note, apt->start, apt->dur,
- apt->state, 0);
- a_nb++;
- }
- LLIST_TS_UNLOCK (&alist_p);
+ LLIST_TS_LOCK(&alist_p);
+ LLIST_TS_FIND_FOREACH(&alist_p, date, apoint_inday, i) {
+ struct apoint *apt = LLIST_TS_GET_DATA(i);
+
+ if (apt->start >= date + DAYINSEC)
+ break;
+
+ day_add_apoint(APPT, apt->mesg, apt->note, apt->start, apt->dur,
+ apt->state, 0);
+ a_nb++;
+ }
+ LLIST_TS_UNLOCK(&alist_p);
return a_nb;
}
@@ -215,22 +206,22 @@ day_store_apoints (long date)
* structure dedicated to the selected day.
* Returns the number of recurrent appointments for the selected day.
*/
-static int
-day_store_recur_apoints (long date)
+static int day_store_recur_apoints(long date)
{
llist_item_t *i;
int a_nb = 0;
- LLIST_TS_LOCK (&recur_alist_p);
- LLIST_TS_FIND_FOREACH (&recur_alist_p, date, recur_apoint_inday, i)
- {
- struct recur_apoint *rapt = LLIST_TS_GET_DATA (i);
- int real_start = recur_apoint_inday (rapt, date);
- (void)day_add_apoint (RECUR_APPT, rapt->mesg, rapt->note, real_start,
- rapt->dur, rapt->state, a_nb);
+ LLIST_TS_LOCK(&recur_alist_p);
+ LLIST_TS_FIND_FOREACH(&recur_alist_p, date, recur_apoint_inday, i) {
+ struct recur_apoint *rapt = LLIST_TS_GET_DATA(i);
+ unsigned real_start;
+ if (recur_apoint_find_occurrence(rapt, date, &real_start)) {
+ day_add_apoint(RECUR_APPT, rapt->mesg, rapt->note, real_start,
+ rapt->dur, rapt->state, a_nb);
a_nb++;
}
- LLIST_TS_UNLOCK (&recur_alist_p);
+ }
+ LLIST_TS_UNLOCK(&recur_alist_p);
return a_nb;
}
@@ -244,19 +235,19 @@ day_store_recur_apoints (long date)
* The number of events and appointments in the current day are also updated.
*/
static int
-day_store_items (long date, unsigned *pnb_events, unsigned *pnb_apoints)
+day_store_items(long date, unsigned *pnb_events, unsigned *pnb_apoints)
{
int pad_length;
int nb_events, nb_recur_events;
int nb_apoints, nb_recur_apoints;
- day_free_list ();
- day_init_list ();
- nb_recur_events = day_store_recur_events (date);
- nb_events = day_store_events (date);
+ day_free_list();
+ day_init_list();
+ nb_recur_events = day_store_recur_events(date);
+ nb_events = day_store_events(date);
*pnb_events = nb_events;
- nb_recur_apoints = day_store_recur_apoints (date);
- nb_apoints = day_store_apoints (date);
+ nb_recur_apoints = day_store_recur_apoints(date);
+ nb_apoints = day_store_apoints(date);
*pnb_apoints = nb_apoints;
pad_length = (nb_recur_events + nb_events + 1 +
3 * (nb_recur_apoints + nb_apoints));
@@ -271,9 +262,9 @@ day_store_items (long date, unsigned *pnb_events, unsigned *pnb_apoints)
* those items in a pad. If selected day is null, then store items for current
* day. This is useful to speed up the appointment panel update.
*/
-struct day_items_nb *
-day_process_storage (struct date *slctd_date, unsigned day_changed,
- struct day_items_nb *inday)
+struct day_items_nb *day_process_storage(struct date *slctd_date,
+ unsigned day_changed,
+ struct day_items_nb *inday)
{
long date;
struct date day;
@@ -281,21 +272,21 @@ day_process_storage (struct date *slctd_date, unsigned day_changed,
if (slctd_date)
day = *slctd_date;
else
- calendar_store_current_date (&day);
+ calendar_store_current_date(&day);
- date = date2sec (day, 0, 0);
+ date = date2sec(day, 0, 0);
/* Inits */
if (apad.length != 0)
- delwin (apad.ptrwin);
+ delwin(apad.ptrwin);
/* Store the events and appointments (recursive and normal items). */
- apad.length = day_store_items (date, &inday->nb_events, &inday->nb_apoints);
+ apad.length = day_store_items(date, &inday->nb_events, &inday->nb_apoints);
/* Create the new pad with its new length. */
if (day_changed)
apad.first_onscreen = 0;
- apad.ptrwin = newpad (apad.length, apad.width);
+ apad.ptrwin = newpad(apad.length, apad.width);
return inday;
}
@@ -304,8 +295,7 @@ day_process_storage (struct date *slctd_date, unsigned day_changed,
* Returns a structure of type apoint_llist_node_t given a structure of type
* day_item_s
*/
-static void
-day_item_s2apoint_s (struct apoint *a, struct day_item *p)
+static void day_item_s2apoint_s(struct apoint *a, struct day_item *p)
{
a->state = p->state;
a->start = p->start;
@@ -317,61 +307,65 @@ day_item_s2apoint_s (struct apoint *a, struct day_item *p)
* Print an item date in the appointment panel.
*/
static void
-display_item_date (int incolor, struct apoint *i, int type, long date,
- int y, int x)
+display_item_date(int incolor, struct apoint *i, int type, long date,
+ int y, int x)
{
WINDOW *win;
char a_st[100], a_end[100];
- int recur = 0;
win = apad.ptrwin;
- apoint_sec2str (i, type, date, a_st, a_end);
- if (type == RECUR_EVNT || type == RECUR_APPT)
- recur = 1;
+ apoint_sec2str(i, date, a_st, a_end);
if (incolor == 0)
- custom_apply_attr (win, ATTR_HIGHEST);
- if (recur)
+ custom_apply_attr(win, ATTR_HIGHEST);
+ if (type == RECUR_EVNT || type == RECUR_APPT)
if (i->state & APOINT_NOTIFY)
- mvwprintw (win, y, x, " *!%s -> %s", a_st, a_end);
+ mvwprintw(win, y, x, " *!%s -> %s", a_st, a_end);
else
- mvwprintw (win, y, x, " * %s -> %s", a_st, a_end);
+ mvwprintw(win, y, x, " * %s -> %s", a_st, a_end);
else if (i->state & APOINT_NOTIFY)
- mvwprintw (win, y, x, " -!%s -> %s", a_st, a_end);
+ mvwprintw(win, y, x, " -!%s -> %s", a_st, a_end);
else
- mvwprintw (win, y, x, " - %s -> %s", a_st, a_end);
+ mvwprintw(win, y, x, " - %s -> %s", a_st, a_end);
if (incolor == 0)
- custom_remove_attr (win, ATTR_HIGHEST);
+ custom_remove_attr(win, ATTR_HIGHEST);
}
/*
* Print an item description in the corresponding panel window.
*/
static void
-display_item (int incolor, char *msg, int recur, int note, int len, int y,
- int x)
+display_item(int incolor, char *msg, int recur, int note, int width, int y,
+ int x)
{
WINDOW *win;
int ch_recur, ch_note;
- char buf[len];
+ char buf[width * UTF8_MAXLEN];
+ int i;
- if (len <= 0)
+ if (width <= 0)
return;
win = apad.ptrwin;
ch_recur = (recur) ? '*' : ' ';
ch_note = (note) ? '>' : ' ';
if (incolor == 0)
- custom_apply_attr (win, ATTR_HIGHEST);
- if (strlen (msg) < len)
- mvwprintw (win, y, x, " %c%c%s", ch_recur, ch_note, msg);
- else
- {
- (void)strncpy (buf, msg, len - 1);
- buf[len - 1] = '\0';
- mvwprintw (win, y, x, " %c%c%s...", ch_recur, ch_note, buf);
+ custom_apply_attr(win, ATTR_HIGHEST);
+ if (utf8_strwidth(msg) < width)
+ mvwprintw(win, y, x, " %c%c%s", ch_recur, ch_note, msg);
+ else {
+ for (i = 0; msg[i] && width > 0; i++) {
+ if (!UTF8_ISCONT(msg[i]))
+ width -= utf8_width(&msg[i]);
+ buf[i] = msg[i];
}
+ if (i)
+ buf[i - 1] = 0;
+ else
+ buf[0] = 0;
+ mvwprintw(win, y, x, " %c%c%s...", ch_recur, ch_note, buf);
+ }
if (incolor == 0)
- custom_remove_attr (win, ATTR_HIGHEST);
+ custom_remove_attr(win, ATTR_HIGHEST);
}
/*
@@ -381,8 +375,7 @@ display_item (int incolor, char *msg, int recur, int note, int len, int y,
* structure (pointed by day_saved_item), to be later displayed in a
* popup window if requested.
*/
-void
-day_write_pad (long date, int width, int length, int incolor)
+void day_write_pad(long date, int width, int length, int incolor)
{
llist_item_t *i;
struct apoint a;
@@ -392,67 +385,57 @@ day_write_pad (long date, int width, int length, int incolor)
line = item_number = 0;
- LLIST_FOREACH (&day_items, i)
- {
- struct day_item *day = LLIST_TS_GET_DATA (i);
- if (day->type == RECUR_EVNT || day->type == RECUR_APPT)
- recur = 1;
- else
- recur = 0;
- /* First print the events for current day. */
- if (day->type < RECUR_APPT)
- {
- item_number++;
- if (item_number - incolor == 0)
- {
- day_saved_item.type = day->type;
- day_saved_item.mesg = day->mesg;
- }
- display_item (item_number - incolor, day->mesg, recur,
- (day->note != NULL) ? 1 : 0, width - 7, line, x_pos);
- line++;
- draw_line = 1;
- }
- else
- {
- /* Draw a line between events and appointments. */
- if (line > 0 && draw_line)
- {
- wmove (apad.ptrwin, line, 0);
- whline (apad.ptrwin, 0, width);
- draw_line = 0;
- }
- /* Last print the appointments for current day. */
- item_number++;
- day_item_s2apoint_s (&a, day);
- if (item_number - incolor == 0)
- {
- day_saved_item.type = day->type;
- day_saved_item.mesg = day->mesg;
- apoint_sec2str (&a, day->type, date,
- day_saved_item.start, day_saved_item.end);
- }
- display_item_date (item_number - incolor, &a, day->type,
- date, line + 1, x_pos);
- display_item (item_number - incolor, day->mesg, 0,
- (day->note != NULL) ? 1 : 0, width - 7, line + 2,
- x_pos);
- line += 3;
- }
+ LLIST_FOREACH(&day_items, i) {
+ struct day_item *day = LLIST_TS_GET_DATA(i);
+ if (day->type == RECUR_EVNT || day->type == RECUR_APPT)
+ recur = 1;
+ else
+ recur = 0;
+ /* First print the events for current day. */
+ if (day->type < RECUR_APPT) {
+ item_number++;
+ if (item_number - incolor == 0) {
+ day_saved_item.type = day->type;
+ day_saved_item.mesg = day->mesg;
+ }
+ display_item(item_number - incolor, day->mesg, recur,
+ (day->note != NULL) ? 1 : 0, width - 7, line, x_pos);
+ line++;
+ draw_line = 1;
+ } else {
+ /* Draw a line between events and appointments. */
+ if (line > 0 && draw_line) {
+ wmove(apad.ptrwin, line, 0);
+ whline(apad.ptrwin, 0, width);
+ draw_line = 0;
+ }
+ /* Last print the appointments for current day. */
+ item_number++;
+ day_item_s2apoint_s(&a, day);
+ if (item_number - incolor == 0) {
+ day_saved_item.type = day->type;
+ day_saved_item.mesg = day->mesg;
+ apoint_sec2str(&a, date, day_saved_item.start, day_saved_item.end);
+ }
+ display_item_date(item_number - incolor, &a, day->type,
+ date, line + 1, x_pos);
+ display_item(item_number - incolor, day->mesg, 0,
+ (day->note != NULL) ? 1 : 0, width - 7, line + 2, x_pos);
+ line += 3;
}
+ }
}
/* Display an item inside a popup window. */
-void
-day_popup_item (void)
+void day_popup_item(void)
{
if (day_saved_item.type == EVNT || day_saved_item.type == RECUR_EVNT)
- item_in_popup (NULL, NULL, day_saved_item.mesg, _("Event :"));
+ item_in_popup(NULL, NULL, day_saved_item.mesg, _("Event :"));
else if (day_saved_item.type == APPT || day_saved_item.type == RECUR_APPT)
- item_in_popup (day_saved_item.start, day_saved_item.end,
- day_saved_item.mesg, _("Appointment :"));
+ item_in_popup(day_saved_item.start, day_saved_item.end,
+ day_saved_item.mesg, _("Appointment :"));
else
- EXIT (_("unknown item type"));
+ EXIT(_("unknown item type"));
/* NOTREACHED */
}
@@ -460,38 +443,34 @@ day_popup_item (void)
* Need to know if there is an item for the current selected day inside
* calendar. This is used to put the correct colors inside calendar panel.
*/
-int
-day_check_if_item (struct date day)
+int day_check_if_item(struct date day)
{
- const long date = date2sec (day, 0, 0);
+ const long date = date2sec(day, 0, 0);
- if (LLIST_FIND_FIRST (&recur_elist, date, recur_event_inday))
- return (1);
+ if (LLIST_FIND_FIRST(&recur_elist, date, recur_event_inday))
+ return 1;
- LLIST_TS_LOCK (&recur_alist_p);
- if (LLIST_TS_FIND_FIRST (&recur_alist_p, date, recur_apoint_inday))
- {
- LLIST_TS_UNLOCK (&recur_alist_p);
- return (1);
- }
- LLIST_TS_UNLOCK (&recur_alist_p);
+ LLIST_TS_LOCK(&recur_alist_p);
+ if (LLIST_TS_FIND_FIRST(&recur_alist_p, date, recur_apoint_inday)) {
+ LLIST_TS_UNLOCK(&recur_alist_p);
+ return 1;
+ }
+ LLIST_TS_UNLOCK(&recur_alist_p);
- if (LLIST_FIND_FIRST (&eventlist, date, event_inday))
- return (1);
+ if (LLIST_FIND_FIRST(&eventlist, date, event_inday))
+ return 1;
- LLIST_TS_LOCK (&alist_p);
- if (LLIST_TS_FIND_FIRST (&alist_p, date, apoint_inday))
- {
- LLIST_TS_UNLOCK (&alist_p);
- return (1);
- }
- LLIST_TS_UNLOCK (&alist_p);
+ LLIST_TS_LOCK(&alist_p);
+ if (LLIST_TS_FIND_FIRST(&alist_p, date, apoint_inday)) {
+ LLIST_TS_UNLOCK(&alist_p);
+ return 1;
+ }
+ LLIST_TS_UNLOCK(&alist_p);
- return (0);
+ return 0;
}
-static unsigned
-fill_slices (int *slices, int slicesno, int first, int last)
+static unsigned fill_slices(int *slices, int slicesno, int first, int last)
{
int i;
@@ -499,7 +478,7 @@ fill_slices (int *slices, int slicesno, int first, int last)
return 0;
if (last >= slicesno)
- last = slicesno - 1; /* Appointment spanning more than one day. */
+ last = slicesno - 1; /* Appointment spanning more than one day. */
for (i = first; i <= last; i++)
slices[i] = 1;
@@ -512,353 +491,375 @@ fill_slices (int *slices, int slicesno, int first, int last)
* appointment in the corresponding time slice, 0 otherwise.
* A 24 hours day is divided into 'slicesno' number of time slices.
*/
-unsigned
-day_chk_busy_slices (struct date day, int slicesno, int *slices)
+unsigned day_chk_busy_slices(struct date day, int slicesno, int *slices)
{
llist_item_t *i;
int slicelen;
- const long date = date2sec (day, 0, 0);
+ const long date = date2sec(day, 0, 0);
slicelen = DAYINSEC / slicesno;
#define SLICENUM(tsec) ((tsec) / slicelen % slicesno)
- LLIST_TS_LOCK (&recur_alist_p);
- LLIST_TS_FIND_FOREACH (&recur_alist_p, date, recur_apoint_inday, i)
- {
- struct apoint *rapt = LLIST_TS_GET_DATA (i);
- long start = get_item_time (rapt->start);
- long end = get_item_time (rapt->start + rapt->dur);
-
- if (!fill_slices (slices, slicesno, SLICENUM (start), SLICENUM (end)))
- {
- LLIST_TS_UNLOCK (&recur_alist_p);
- return 0;
- }
+ LLIST_TS_LOCK(&recur_alist_p);
+ LLIST_TS_FIND_FOREACH(&recur_alist_p, date, recur_apoint_inday, i) {
+ struct apoint *rapt = LLIST_TS_GET_DATA(i);
+ long start = get_item_time(rapt->start);
+ long end = get_item_time(rapt->start + rapt->dur);
+
+ if (!fill_slices(slices, slicesno, SLICENUM(start), SLICENUM(end))) {
+ LLIST_TS_UNLOCK(&recur_alist_p);
+ return 0;
}
- LLIST_TS_UNLOCK (&recur_alist_p);
-
- LLIST_TS_LOCK (&alist_p);
- LLIST_TS_FIND_FOREACH (&alist_p, date, apoint_inday, i)
- {
- struct apoint *apt = LLIST_TS_GET_DATA (i);
- long start = get_item_time (apt->start);
- long end = get_item_time (apt->start + apt->dur);
-
- if (!fill_slices (slices, slicesno, SLICENUM (start), SLICENUM (end)))
- {
- LLIST_TS_UNLOCK (&alist_p);
- return 0;
- }
+ }
+ LLIST_TS_UNLOCK(&recur_alist_p);
+
+ LLIST_TS_LOCK(&alist_p);
+ LLIST_TS_FIND_FOREACH(&alist_p, date, apoint_inday, i) {
+ struct apoint *apt = LLIST_TS_GET_DATA(i);
+ long start = get_item_time(apt->start);
+ long end = get_item_time(apt->start + apt->dur);
+
+ if (apt->start >= date + DAYINSEC)
+ break;
+
+ if (!fill_slices(slices, slicesno, SLICENUM(start), SLICENUM(end))) {
+ LLIST_TS_UNLOCK(&alist_p);
+ return 0;
}
- LLIST_TS_UNLOCK (&alist_p);
+ }
+ LLIST_TS_UNLOCK(&alist_p);
#undef SLICENUM
return 1;
}
/* Request the user to enter a new time. */
-static char *
-day_edit_time (long time)
+static int day_edit_time(int time, unsigned *new_hour, unsigned *new_minute)
{
- char *timestr;
- char *msg_time = _("Enter the new time ([hh:mm] or [h:mm]) : ");
- char *enter_str = _("Press [Enter] to continue");
- char *fmt_msg = _("You entered an invalid time, should be [h:mm] or [hh:mm]");
-
- while (1)
- {
- status_mesg (msg_time, "");
- timestr = date_sec2date_str (time, "%H:%M");
- updatestring (win[STA].p, &timestr, 0, 1);
- if (check_time (timestr) != 1 || strlen (timestr) == 0)
- {
- status_mesg (fmt_msg, enter_str);
- (void)wgetch (win[STA].p);
- }
- else
- return (timestr);
- }
+ char *timestr = date_sec2date_str(time, "%H:%M");
+ const char *msg_time = _("Enter the new time ([hh:mm]) : ");
+ const char *enter_str = _("Press [Enter] to continue");
+ const char *fmt_msg = _("You entered an invalid time, should be [hh:mm]");
+
+ for (;;) {
+ status_mesg(msg_time, "");
+ if (updatestring(win[STA].p, &timestr, 0, 1) == GETSTRING_VALID) {
+ if (parse_time(timestr, new_hour, new_minute) == 1) {
+ mem_free(timestr);
+ return 1;
+ } else {
+ status_mesg(fmt_msg, enter_str);
+ wgetch(win[STA].p);
+ }
+ } else
+ return 0;
+ }
}
-static void
-update_start_time (long *start, long *dur)
+/* Request the user to enter a new time or duration. */
+static int day_edit_duration(int start, int dur, unsigned *new_duration)
+{
+ char *timestr = date_sec2date_str(start + dur, "%H:%M");
+ const char *msg_time =
+ _
+ ("Enter new end time ([hh:mm]) or duration ([+hh:mm], [+xxxdxxhxxm] or [+mm]) : ");
+ const char *enter_str = _("Press [Enter] to continue");
+ const char *fmt_msg = _("You entered an invalid time, should be [hh:mm]");
+ long newtime;
+ unsigned hr, mn;
+
+ for (;;) {
+ status_mesg(msg_time, "");
+ if (updatestring(win[STA].p, &timestr, 0, 1) == GETSTRING_VALID) {
+ if (*timestr == '+' && parse_duration(timestr + 1, new_duration) == 1) {
+ *new_duration *= MININSEC;
+ break;
+ } else if (parse_time(timestr, &hr, &mn) == 1) {
+ newtime = update_time_in_date(start + dur, hr, mn);
+ *new_duration = (newtime > start) ? newtime - start :
+ DAYINSEC + newtime - start;
+ break;
+ } else {
+ status_mesg(fmt_msg, enter_str);
+ wgetch(win[STA].p);
+ }
+ } else
+ return 0;
+ }
+
+ mem_free(timestr);
+ return 1;
+}
+
+/* Request the user to enter a new end time or duration. */
+static void update_start_time(long *start, long *dur)
{
long newtime;
unsigned hr, mn;
int valid_date;
- char *timestr;
- char *msg_wrong_time = _("Invalid time: start time must be before end time!");
- char *msg_enter = _("Press [Enter] to continue");
-
- do
- {
- timestr = day_edit_time (*start);
- (void)sscanf (timestr, "%u:%u", &hr, &mn);
- mem_free (timestr);
- newtime = update_time_in_date (*start, hr, mn);
- if (newtime < *start + *dur)
- {
- *dur -= (newtime - *start);
- *start = newtime;
- valid_date = 1;
- }
- else
- {
- status_mesg (msg_wrong_time, msg_enter);
- (void)wgetch (win[STA].p);
- valid_date = 0;
- }
+ const char *msg_wrong_time =
+ _("Invalid time: start time must be before end time!");
+ const char *msg_enter = _("Press [Enter] to continue");
+
+ do {
+ day_edit_time(*start, &hr, &mn);
+ newtime = update_time_in_date(*start, hr, mn);
+ if (newtime < *start + *dur) {
+ *dur -= (newtime - *start);
+ *start = newtime;
+ valid_date = 1;
+ } else {
+ status_mesg(msg_wrong_time, msg_enter);
+ wgetch(win[STA].p);
+ valid_date = 0;
}
+ }
while (valid_date == 0);
}
-static void
-update_duration (long *start, long *dur)
+static void update_duration(long *start, long *dur)
{
- long newtime;
- unsigned hr, mn;
- char *timestr;
+ unsigned newdur;
- timestr = day_edit_time (*start + *dur);
- (void)sscanf (timestr, "%u:%u", &hr, &mn);
- mem_free (timestr);
- newtime = update_time_in_date (*start, hr, mn);
- *dur = (newtime > *start) ? newtime - *start : DAYINSEC + newtime - *start;
+ day_edit_duration(*start, *dur, &newdur);
+ *dur = newdur;
}
-static void
-update_desc (char **desc)
+static void update_desc(char **desc)
{
- status_mesg (_("Enter the new item description:"), "");
- updatestring (win[STA].p, desc, 0, 1);
+ status_mesg(_("Enter the new item description:"), "");
+ updatestring(win[STA].p, desc, 0, 1);
}
-static void
-update_rept (struct rpt **rpt, const long start, struct conf *conf)
+static void update_rept(struct rpt **rpt, const long start)
{
- const int SINGLECHAR = 2;
- int ch, cancel, newfreq, date_entered;
+ int newtype, newfreq, date_entered;
long newuntil;
char outstr[BUFSIZ];
- char *typstr, *freqstr, *timstr;
- char *msg_rpt_type = _("Enter the new repetition type: (D)aily, (W)eekly, "
- "(M)onthly, (Y)early");
- char *msg_rpt_ans = _("[D/W/M/Y] ");
- char *msg_wrong_freq = _("The frequence you entered is not valid.");
- char *msg_wrong_time = _("Invalid time: start time must be before end time!");
- char *msg_wrong_date = _("The entered date is not valid.");
- char *msg_fmts =
- "Possible formats are [%s] or '0' for an endless repetetition";
- char *msg_enter = _("Press [Enter] to continue");
-
- do
- {
- status_mesg (msg_rpt_type, msg_rpt_ans);
- typstr = mem_calloc (SINGLECHAR, sizeof (char));
- (void)snprintf (typstr, SINGLECHAR, "%c", recur_def2char ((*rpt)->type));
- cancel = updatestring (win[STA].p, &typstr, 0, 1);
- if (cancel)
- {
- mem_free (typstr);
- return;
- }
- else
- {
- ch = toupper (*typstr);
- mem_free (typstr);
- }
- }
- while ((ch != 'D') && (ch != 'W') && (ch != 'M') && (ch != 'Y'));
-
- do
- {
- status_mesg (_("Enter the new repetition frequence:"), "");
- freqstr = mem_malloc (BUFSIZ);
- (void)snprintf (freqstr, BUFSIZ, "%d", (*rpt)->freq);
- cancel = updatestring (win[STA].p, &freqstr, 0, 1);
- if (cancel)
- {
- mem_free (freqstr);
- return;
- }
- else
- {
- newfreq = atoi (freqstr);
- mem_free (freqstr);
- if (newfreq == 0)
- {
- status_mesg (msg_wrong_freq, msg_enter);
- (void)wgetch (win[STA].p);
- }
- }
+ char *freqstr, *timstr;
+ const char *msg_rpt_prefix = _("Enter the new repetition type:");
+ const char *msg_rpt_daily = _("(d)aily");
+ const char *msg_rpt_weekly = _("(w)eekly");
+ const char *msg_rpt_monthly = _("(m)onthly");
+ const char *msg_rpt_yearly = _("(y)early");
+
+ /* Find the current repetition type. */
+ const char *rpt_current;
+ char msg_rpt_current[BUFSIZ];
+ switch (recur_def2char((*rpt)->type)) {
+ case 'D':
+ rpt_current = msg_rpt_daily;
+ break;
+ case 'W':
+ rpt_current = msg_rpt_weekly;
+ break;
+ case 'M':
+ rpt_current = msg_rpt_monthly;
+ break;
+ case 'Y':
+ rpt_current = msg_rpt_yearly;
+ break;
+ default:
+ /* NOTREACHED, but makes the compiler happier. */
+ rpt_current = msg_rpt_daily;
+ }
+
+ snprintf(msg_rpt_current, BUFSIZ, _("(currently using %s)"), rpt_current);
+
+ char msg_rpt_asktype[BUFSIZ];
+ snprintf(msg_rpt_asktype, BUFSIZ, "%s %s, %s, %s, %s ? %s",
+ msg_rpt_prefix,
+ msg_rpt_daily,
+ msg_rpt_weekly, msg_rpt_monthly, msg_rpt_yearly, msg_rpt_current);
+
+ const char *msg_rpt_choice = _("[dwmy]");
+ const char *msg_wrong_freq = _("The frequence you entered is not valid.");
+ const char *msg_wrong_time =
+ _("Invalid time: start time must be before end time!");
+ const char *msg_wrong_date = _("The entered date is not valid.");
+ const char *msg_fmts =
+ _("Possible formats are [%s] or '0' for an endless repetetition");
+ const char *msg_enter = _("Press [Enter] to continue");
+
+ switch (status_ask_choice(msg_rpt_asktype, msg_rpt_choice, 4)) {
+ case 1:
+ newtype = 'D';
+ break;
+ case 2:
+ newtype = 'W';
+ break;
+ case 3:
+ newtype = 'M';
+ break;
+ case 4:
+ newtype = 'Y';
+ break;
+ default:
+ return;
+ }
+
+ do {
+ status_mesg(_("Enter the new repetition frequence:"), "");
+ freqstr = mem_malloc(BUFSIZ);
+ snprintf(freqstr, BUFSIZ, "%d", (*rpt)->freq);
+ if (updatestring(win[STA].p, &freqstr, 0, 1) == GETSTRING_VALID) {
+ newfreq = atoi(freqstr);
+ mem_free(freqstr);
+ if (newfreq == 0) {
+ status_mesg(msg_wrong_freq, msg_enter);
+ wgetch(win[STA].p);
+ }
+ } else {
+ mem_free(freqstr);
+ return;
}
+ }
while (newfreq == 0);
- do
- {
- (void)snprintf (outstr, BUFSIZ, "Enter the new ending date: [%s] or '0'",
- DATEFMT_DESC (conf->input_datefmt));
- status_mesg (_(outstr), "");
- timstr =
- date_sec2date_str ((*rpt)->until, DATEFMT (conf->input_datefmt));
- cancel = updatestring (win[STA].p, &timstr, 0, 1);
- if (cancel)
- {
- mem_free (timstr);
- return;
- }
- if (strcmp (timstr, "0") == 0)
- {
- newuntil = 0;
+ do {
+ snprintf(outstr, BUFSIZ, "Enter the new ending date: [%s] or '0'",
+ DATEFMT_DESC(conf.input_datefmt));
+ status_mesg(_(outstr), "");
+ timstr = date_sec2date_str((*rpt)->until, DATEFMT(conf.input_datefmt));
+ if (updatestring(win[STA].p, &timstr, 0, 1) != GETSTRING_VALID) {
+ mem_free(timstr);
+ return;
+ }
+ if (strcmp(timstr, "0") == 0) {
+ newuntil = 0;
+ date_entered = 1;
+ } else {
+ struct tm *lt;
+ time_t t;
+ struct date new_date;
+ int newmonth, newday, newyear;
+
+ if (parse_date(timstr, conf.input_datefmt, &newyear, &newmonth,
+ &newday, calendar_get_slctd_day())) {
+ t = start;
+ lt = localtime(&t);
+ new_date.dd = newday;
+ new_date.mm = newmonth;
+ new_date.yyyy = newyear;
+ newuntil = date2sec(new_date, lt->tm_hour, lt->tm_min);
+ if (newuntil < start) {
+ status_mesg(msg_wrong_time, msg_enter);
+ wgetch(win[STA].p);
+ date_entered = 0;
+ } else
date_entered = 1;
- }
- else
- {
- struct tm *lt;
- time_t t;
- struct date new_date;
- int newmonth, newday, newyear;
-
- if (parse_date (timstr, conf->input_datefmt,
- &newyear, &newmonth, &newday, calendar_get_slctd_day ()))
- {
- t = start;
- lt = localtime (&t);
- new_date.dd = newday;
- new_date.mm = newmonth;
- new_date.yyyy = newyear;
- newuntil = date2sec (new_date, lt->tm_hour, lt->tm_min);
- if (newuntil < start)
- {
- status_mesg (msg_wrong_time, msg_enter);
- (void)wgetch (win[STA].p);
- date_entered = 0;
- }
- else
- date_entered = 1;
- }
- else
- {
- (void)snprintf (outstr, BUFSIZ, msg_fmts,
- DATEFMT_DESC (conf->input_datefmt));
- status_mesg (msg_wrong_date, _(outstr));
- (void)wgetch (win[STA].p);
- date_entered = 0;
- }
- }
+ } else {
+ snprintf(outstr, BUFSIZ, msg_fmts, DATEFMT_DESC(conf.input_datefmt));
+ status_mesg(msg_wrong_date, _(outstr));
+ wgetch(win[STA].p);
+ date_entered = 0;
+ }
}
+ }
while (date_entered == 0);
- mem_free (timstr);
- (*rpt)->type = recur_char2def (ch);
+ mem_free(timstr);
+ (*rpt)->type = recur_char2def(newtype);
(*rpt)->freq = newfreq;
(*rpt)->until = newuntil;
}
/* Edit an already existing item. */
-void
-day_edit_item (struct conf *conf)
+void day_edit_item(void)
{
-#define STRT '1'
-#define END '2'
-#define DESC '3'
-#define REPT '4'
-
struct day_item *p;
struct recur_event *re;
struct event *e;
struct recur_apoint *ra;
struct apoint *a;
long date;
- int item_num, ch;
+ int item_num;
int need_check_notify = 0;
- item_num = apoint_hilt ();
- p = day_get_item (item_num);
- date = calendar_get_slctd_day_sec ();
-
- ch = -1;
- switch (p->type)
- {
- case RECUR_EVNT:
- re = recur_get_event (date, day_item_nb (date, item_num, RECUR_EVNT));
- status_mesg (_("Edit: (1)Description or (2)Repetition?"), "[1/2] ");
- while (ch != '1' && ch != '2' && ch != KEY_GENERIC_CANCEL)
- ch = wgetch (win[STA].p);
- switch (ch)
- {
- case '1':
- update_desc (&re->mesg);
- break;
- case '2':
- update_rept (&re->rpt, re->day, conf);
- break;
- default:
- return;
- }
+ item_num = apoint_hilt();
+ p = day_get_item(item_num);
+ date = calendar_get_slctd_day_sec();
+
+ switch (p->type) {
+ case RECUR_EVNT:
+ re = recur_get_event(date, day_item_nb(date, item_num, RECUR_EVNT));
+ const char *choice_recur_evnt[2] = {
+ "Description",
+ "Repetition",
+ };
+ switch (status_ask_simplechoice(_("Edit: "), choice_recur_evnt, 2)) {
+ case 1:
+ update_desc(&re->mesg);
break;
- case EVNT:
- e = event_get (date, day_item_nb (date, item_num, EVNT));
- update_desc (&e->mesg);
+ case 2:
+ update_rept(&re->rpt, re->day);
break;
- case RECUR_APPT:
- ra = recur_get_apoint (date, day_item_nb (date, item_num, RECUR_APPT));
- status_mesg (_("Edit: (1)Start time, (2)End time, "
- "(3)Description or (4)Repetition?"), "[1/2/3/4] ");
- while (ch != STRT && ch != END && ch != DESC &&
- ch != REPT && ch != KEY_GENERIC_CANCEL)
- ch = wgetch (win[STA].p);
- switch (ch)
- {
- case STRT:
- need_check_notify = 1;
- update_start_time (&ra->start, &ra->dur);
- break;
- case END:
- update_duration (&ra->start, &ra->dur);
- break;
- case DESC:
- if (notify_bar ())
- need_check_notify = notify_same_recur_item (ra);
- update_desc (&ra->mesg);
- break;
- case REPT:
- need_check_notify = 1;
- update_rept (&ra->rpt, ra->start, conf);
- break;
- case KEY_GENERIC_CANCEL:
- return;
- }
+ default:
+ return;
+ }
+ break;
+ case EVNT:
+ e = event_get(date, day_item_nb(date, item_num, EVNT));
+ update_desc(&e->mesg);
+ break;
+ case RECUR_APPT:
+ ra = recur_get_apoint(date, day_item_nb(date, item_num, RECUR_APPT));
+ const char *choice_recur_appt[4] = {
+ "Start time",
+ "End time",
+ "Description",
+ "Repetition",
+ };
+ switch (status_ask_simplechoice(_("Edit: "), choice_recur_appt, 4)) {
+ case 1:
+ need_check_notify = 1;
+ update_start_time(&ra->start, &ra->dur);
break;
- case APPT:
- a = apoint_get (date, day_item_nb (date, item_num, APPT));
- status_mesg (_("Edit: (1)Start time, (2)End time "
- "or (3)Description?"), "[1/2/3] ");
- while (ch != STRT && ch != END && ch != DESC && ch != KEY_GENERIC_CANCEL)
- ch = wgetch (win[STA].p);
- switch (ch)
- {
- case STRT:
- need_check_notify = 1;
- update_start_time (&a->start, &a->dur);
- break;
- case END:
- update_duration (&a->start, &a->dur);
- break;
- case DESC:
- if (notify_bar ())
- need_check_notify = notify_same_item (a->start);
- update_desc (&a->mesg);
- break;
- case KEY_GENERIC_CANCEL:
- return;
- }
+ case 2:
+ update_duration(&ra->start, &ra->dur);
+ break;
+ case 3:
+ if (notify_bar())
+ need_check_notify = notify_same_recur_item(ra);
+ update_desc(&ra->mesg);
+ break;
+ case 4:
+ need_check_notify = 1;
+ update_rept(&ra->rpt, ra->start);
break;
+ default:
+ return;
}
+ break;
+ case APPT:
+ a = apoint_get(date, day_item_nb(date, item_num, APPT));
+ const char *choice_appt[3] = {
+ "Start time",
+ "End time",
+ "Description",
+ };
+ switch (status_ask_simplechoice(_("Edit: "), choice_appt, 3)) {
+ case 1:
+ need_check_notify = 1;
+ update_start_time(&a->start, &a->dur);
+ break;
+ case 2:
+ update_duration(&a->start, &a->dur);
+ break;
+ case 3:
+ if (notify_bar())
+ need_check_notify = notify_same_item(a->start);
+ update_desc(&a->mesg);
+ break;
+ default:
+ return;
+ }
+ break;
+ }
if (need_check_notify)
- notify_check_next_app (1);
+ notify_check_next_app(1);
}
/*
@@ -867,157 +868,142 @@ day_edit_item (struct conf *conf)
* recurrent appointments and appointments) and then to test the
* type of the item to be deleted.
*/
-int
-day_erase_item (long date, int item_number, enum eraseflg flag)
+int day_erase_item(long date, int item_number, enum eraseflg flag)
{
struct day_item *p;
- char *erase_warning =
+
+ const char *erase_warning =
_("This item is recurrent. "
"Delete (a)ll occurences or just this (o)ne ?");
- char *note_warning =
+ const char *erase_choices = _("[ao]");
+ const int nb_erase_choices = 2;
+
+ const char *note_warning =
_("This item has a note attached to it. "
"Delete (i)tem or just its (n)ote ?");
- char *note_choice = _("[i/n] ");
- char *erase_choice = _("[a/o] ");
- int ch, ans;
+ const char *note_choices = _("[in]");
+ const int nb_note_choices = 2;
+ int ans;
unsigned delete_whole;
- ch = -1;
- p = day_get_item (item_number);
- if (flag == ERASE_DONT_FORCE)
- {
- ans = 0;
- if (p->note == NULL)
- ans = 'i';
- while (ans != 'i' && ans != 'n')
- {
- status_mesg (note_warning, note_choice);
- ans = wgetch (win[STA].p);
- }
- if (ans == 'i')
- flag = ERASE_FORCE;
- else
- flag = ERASE_FORCE_ONLY_NOTE;
- }
- if (p->type == EVNT)
- {
- event_delete_bynum (date, day_item_nb (date, item_number, EVNT), flag);
+ p = day_get_item(item_number);
+ if (flag == ERASE_DONT_FORCE) {
+ if (p->note == NULL)
+ ans = 1;
+ else
+ ans = status_ask_choice(note_warning, note_choices, nb_note_choices);
+
+ switch (ans) {
+ case 1:
+ flag = ERASE_FORCE;
+ break;
+ case 2:
+ flag = ERASE_FORCE_ONLY_NOTE;
+ break;
+ default: /* User escaped */
+ return 0;
}
- else if (p->type == APPT)
- {
- apoint_delete_bynum (date, day_item_nb (date, item_number, APPT), flag);
+ }
+ if (p->type == EVNT) {
+ event_delete_bynum(date, day_item_nb(date, item_number, EVNT), flag);
+ } else if (p->type == APPT) {
+ apoint_delete_bynum(date, day_item_nb(date, item_number, APPT), flag);
+ } else {
+ if (flag == ERASE_FORCE_ONLY_NOTE)
+ ans = 1;
+ else
+ ans = status_ask_choice(erase_warning, erase_choices, nb_erase_choices);
+
+ switch (ans) {
+ case 1:
+ delete_whole = 1;
+ break;
+ case 2:
+ delete_whole = 0;
+ break;
+ default:
+ return 0;
}
- else
- {
- if (flag == ERASE_FORCE_ONLY_NOTE)
- ch = 'a';
- while ((ch != 'a') && (ch != 'o') && (ch != KEY_GENERIC_CANCEL))
- {
- status_mesg (erase_warning, erase_choice);
- ch = wgetch (win[STA].p);
- }
- if (ch == 'a')
- {
- delete_whole = 1;
- }
- else if (ch == 'o')
- {
- delete_whole = 0;
- }
- else
- {
- return (0);
- }
- if (p->type == RECUR_EVNT)
- {
- recur_event_erase (date, day_item_nb (date, item_number, RECUR_EVNT),
- delete_whole, flag);
- }
- else
- {
- recur_apoint_erase (date, p->appt_pos, delete_whole, flag);
- }
+
+ if (p->type == RECUR_EVNT) {
+ recur_event_erase(date, day_item_nb(date, item_number, RECUR_EVNT),
+ delete_whole, flag);
+ } else {
+ recur_apoint_erase(date, p->appt_pos, delete_whole, flag);
}
+ }
if (flag == ERASE_FORCE_ONLY_NOTE)
return 0;
else
- return (p->type);
+ return p->type;
}
/* Cut an item so it can be pasted somewhere else later. */
-int
-day_cut_item (long date, int item_number)
+int day_cut_item(long date, int item_number)
{
const int DELETE_WHOLE = 1;
struct day_item *p;
- p = day_get_item (item_number);
- switch (p->type)
- {
- case EVNT:
- event_delete_bynum (date, day_item_nb (date, item_number, EVNT),
- ERASE_CUT);
- break;
- case RECUR_EVNT:
- recur_event_erase (date, day_item_nb (date, item_number, RECUR_EVNT),
- DELETE_WHOLE, ERASE_CUT);
- break;
- case APPT:
- apoint_delete_bynum (date, day_item_nb (date, item_number, APPT),
- ERASE_CUT);
- break;
- case RECUR_APPT:
- recur_apoint_erase (date, p->appt_pos, DELETE_WHOLE, ERASE_CUT);
- break;
- default:
- EXIT (_("unknwon type"));
- /* NOTREACHED */
- }
+ p = day_get_item(item_number);
+ switch (p->type) {
+ case EVNT:
+ event_delete_bynum(date, day_item_nb(date, item_number, EVNT), ERASE_CUT);
+ break;
+ case RECUR_EVNT:
+ recur_event_erase(date, day_item_nb(date, item_number, RECUR_EVNT),
+ DELETE_WHOLE, ERASE_CUT);
+ break;
+ case APPT:
+ apoint_delete_bynum(date, day_item_nb(date, item_number, APPT), ERASE_CUT);
+ break;
+ case RECUR_APPT:
+ recur_apoint_erase(date, p->appt_pos, DELETE_WHOLE, ERASE_CUT);
+ break;
+ default:
+ EXIT(_("unknwon type"));
+ /* NOTREACHED */
+ }
return p->type;
}
/* Paste a previously cut item. */
-int
-day_paste_item (long date, int cut_item_type)
+int day_paste_item(long date, int cut_item_type)
{
int pasted_item_type;
pasted_item_type = cut_item_type;
- switch (cut_item_type)
- {
- case 0:
- return 0;
- case EVNT:
- event_paste_item ();
- break;
- case RECUR_EVNT:
- recur_event_paste_item ();
- break;
- case APPT:
- apoint_paste_item ();
- break;
- case RECUR_APPT:
- recur_apoint_paste_item ();
- break;
- default:
- EXIT (_("unknwon type"));
- /* NOTREACHED */
- }
+ switch (cut_item_type) {
+ case 0:
+ return 0;
+ case EVNT:
+ event_paste_item();
+ break;
+ case RECUR_EVNT:
+ recur_event_paste_item();
+ break;
+ case APPT:
+ apoint_paste_item();
+ break;
+ case RECUR_APPT:
+ recur_apoint_paste_item();
+ break;
+ default:
+ EXIT(_("unknwon type"));
+ /* NOTREACHED */
+ }
return pasted_item_type;
}
/* Returns a structure containing the selected item. */
-struct day_item *
-day_get_item (int item_number)
+struct day_item *day_get_item(int item_number)
{
- return LLIST_GET_DATA (LLIST_NTH (&day_items, item_number - 1));
+ return LLIST_GET_DATA(LLIST_NTH(&day_items, item_number - 1));
}
/* Returns the real item number, given its type. */
-int
-day_item_nb (long date, int day_num, int type)
+int day_item_nb(long date, int day_num, int type)
{
int i, nb_item[MAX_TYPES];
llist_item_t *j;
@@ -1025,78 +1011,108 @@ day_item_nb (long date, int day_num, int type)
for (i = 0; i < MAX_TYPES; i++)
nb_item[i] = 0;
- j = LLIST_FIRST (&day_items);
- for (i = 1; i < day_num; i++)
- {
- struct day_item *day = LLIST_TS_GET_DATA (j);
- nb_item[day->type - 1]++;
- j = LLIST_TS_NEXT (j);
- }
+ j = LLIST_FIRST(&day_items);
+ for (i = 1; i < day_num; i++) {
+ struct day_item *day = LLIST_TS_GET_DATA(j);
+ nb_item[day->type - 1]++;
+ j = LLIST_TS_NEXT(j);
+ }
- return (nb_item[type - 1]);
+ return nb_item[type - 1];
}
/* Attach a note to an appointment or event. */
-void
-day_edit_note (char *editor)
+void day_edit_note(const char *editor)
{
struct day_item *p;
struct recur_apoint *ra;
struct apoint *a;
struct recur_event *re;
struct event *e;
- char fullname[BUFSIZ];
- char *filename;
long date;
int item_num;
- item_num = apoint_hilt ();
- p = day_get_item (item_num);
- if (p->note == NULL)
- {
- if ((filename = new_tempfile (path_notes, NOTESIZ)) == NULL)
- return;
- else
- p->note = filename;
- }
- (void)snprintf (fullname, BUFSIZ, "%s%s", path_notes, p->note);
- wins_launch_external (fullname, editor);
+ item_num = apoint_hilt();
+ p = day_get_item(item_num);
+ edit_note(&p->note, editor);
+
+ date = calendar_get_slctd_day_sec();
+ switch (p->type) {
+ case RECUR_EVNT:
+ re = recur_get_event(date, day_item_nb(date, item_num, RECUR_EVNT));
+ re->note = p->note;
+ break;
+ case EVNT:
+ e = event_get(date, day_item_nb(date, item_num, EVNT));
+ e->note = p->note;
+ break;
+ case RECUR_APPT:
+ ra = recur_get_apoint(date, day_item_nb(date, item_num, RECUR_APPT));
+ ra->note = p->note;
+ break;
+ case APPT:
+ a = apoint_get(date, day_item_nb(date, item_num, APPT));
+ a->note = p->note;
+ break;
+ }
+}
+
+/* View a note previously attached to an appointment or event */
+void day_view_note(const char *pager)
+{
+ struct day_item *p = day_get_item(apoint_hilt());
+ view_note(p->note, pager);
+}
- if (io_file_is_empty (fullname) > 0)
- erase_note (&p->note, ERASE_FORCE);
+/* Pipe an appointment or event to an external program. */
+void day_pipe_item(void)
+{
+ char cmd[BUFSIZ] = "";
+ char const *arg[] = { cmd, NULL };
+ int pout;
+ int pid;
+ FILE *fpout;
+ int item_num;
+ long date;
+ struct day_item *p;
+ struct recur_apoint *ra;
+ struct apoint *a;
+ struct recur_event *re;
+ struct event *e;
- date = calendar_get_slctd_day_sec ();
- switch (p->type)
- {
+ status_mesg(_("Pipe item to external command:"), "");
+ if (getstring(win[STA].p, cmd, BUFSIZ, 0, 1) != GETSTRING_VALID)
+ return;
+
+ wins_prepare_external();
+ if ((pid = shell_exec(NULL, &pout, *arg, arg))) {
+ fpout = fdopen(pout, "w");
+
+ item_num = apoint_hilt();
+ p = day_get_item(item_num);
+ date = calendar_get_slctd_day_sec();
+ switch (p->type) {
case RECUR_EVNT:
- re = recur_get_event (date, day_item_nb (date, item_num, RECUR_EVNT));
- re->note = p->note;
+ re = recur_get_event(date, day_item_nb(date, item_num, RECUR_EVNT));
+ recur_event_write(re, fpout);
break;
case EVNT:
- e = event_get (date, day_item_nb (date, item_num, EVNT));
- e->note = p->note;
+ e = event_get(date, day_item_nb(date, item_num, EVNT));
+ event_write(e, fpout);
break;
case RECUR_APPT:
- ra = recur_get_apoint (date, day_item_nb (date, item_num, RECUR_APPT));
- ra->note = p->note;
+ ra = recur_get_apoint(date, day_item_nb(date, item_num, RECUR_APPT));
+ recur_apoint_write(ra, fpout);
break;
case APPT:
- a = apoint_get (date, day_item_nb (date, item_num, APPT));
- a->note = p->note;
+ a = apoint_get(date, day_item_nb(date, item_num, APPT));
+ apoint_write(a, fpout);
break;
}
-}
-
-/* View a note previously attached to an appointment or event */
-void
-day_view_note (char *pager)
-{
- struct day_item *p;
- char fullname[BUFSIZ];
- p = day_get_item (apoint_hilt ());
- if (p->note == NULL)
- return;
- (void)snprintf (fullname, BUFSIZ, "%s%s", path_notes, p->note);
- wins_launch_external (fullname, pager);
+ fclose(fpout);
+ child_wait(NULL, &pout, pid);
+ press_any_key();
+ }
+ wins_unprepare_external();
}
diff --git a/src/dmon.c b/src/dmon.c
index 6a24739..f8d3403 100644
--- a/src/dmon.c
+++ b/src/dmon.c
@@ -1,7 +1,7 @@
/*
* Calcurse - text-based organizer
*
- * Copyright (c) 2004-2011 calcurse Development Team <misc@calcurse.org>
+ * Copyright (c) 2004-2012 calcurse Development Team <misc@calcurse.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -49,7 +49,7 @@
#define DMON_LOG(...) do { \
if (dmon.log) \
- (void)io_fprintln (path_dmon_log, __VA_ARGS__); \
+ io_fprintln (path_dmon_log, __VA_ARGS__); \
} while (0)
#define DMON_ABRT(...) do { \
@@ -64,26 +64,22 @@
static unsigned data_loaded;
-static void
-dmon_sigs_hdlr (int sig)
+static void dmon_sigs_hdlr(int sig)
{
if (data_loaded)
- free_user_data ();
+ free_user_data();
- DMON_LOG (_("terminated at %s with signal %d\n"), nowstr (), sig);
+ DMON_LOG(_("terminated at %s with signal %d\n"), nowstr(), sig);
- if (unlink (path_dpid) != 0)
- {
- DMON_LOG (_("Could not remove daemon lock file: %s\n"),
- strerror (errno));
- exit (EXIT_FAILURE);
- }
+ if (unlink(path_dpid) != 0) {
+ DMON_LOG(_("Could not remove daemon lock file: %s\n"), strerror(errno));
+ exit(EXIT_FAILURE);
+ }
- exit (EXIT_SUCCESS);
+ exit(EXIT_SUCCESS);
}
-static unsigned
-daemonize (int status)
+static unsigned daemonize(int status)
{
int fd;
@@ -93,16 +89,15 @@ daemonize (int status)
* First need to fork in order to become a child of the init process,
* once the father exits.
*/
- switch (fork ())
- {
- case -1: /* fork error */
- EXIT (_("Could not fork: %s\n"), strerror (errno));
- break;
- case 0: /* child */
- break;
- default: /* parent */
- exit (status);
- }
+ switch (fork()) {
+ case -1: /* fork error */
+ EXIT(_("Could not fork: %s\n"), strerror(errno));
+ break;
+ case 0: /* child */
+ break;
+ default: /* parent */
+ exit(status);
+ }
/*
* Process independency.
@@ -110,110 +105,99 @@ daemonize (int status)
* Obtain a new process group and session in order to get detached from the
* controlling terminal.
*/
- if (setsid () == -1)
- {
- DMON_LOG (_("Could not detach from the controlling terminal: %s\n"),
- strerror (errno));
- return 0;
- }
+ if (setsid() == -1) {
+ DMON_LOG(_("Could not detach from the controlling terminal: %s\n"),
+ strerror(errno));
+ return 0;
+ }
/*
* Change working directory to root directory,
* to prevent filesystem unmounts.
*/
- if (chdir ("/") == -1)
- {
- DMON_LOG (_("Could not change working directory: %s\n"),
- strerror (errno));
- return 0;
- }
+ if (chdir("/") == -1) {
+ DMON_LOG(_("Could not change working directory: %s\n"), strerror(errno));
+ return 0;
+ }
/* Redirect standard file descriptors to /dev/null. */
- if ((fd = open (_PATH_DEVNULL, O_RDWR, 0)) != -1)
- {
- (void)dup2 (fd, STDIN_FILENO);
- (void)dup2 (fd, STDOUT_FILENO);
- (void)dup2 (fd, STDERR_FILENO);
- if (fd > 2)
- (void)close (fd);
- }
+ if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
+ dup2(fd, STDIN_FILENO);
+ dup2(fd, STDOUT_FILENO);
+ dup2(fd, STDERR_FILENO);
+ if (fd > 2)
+ close(fd);
+ }
/* Write access for the owner only. */
- (void)umask (0022);
+ umask(0022);
- if (!sigs_set_hdlr (SIGINT, dmon_sigs_hdlr)
- || !sigs_set_hdlr (SIGTERM, dmon_sigs_hdlr)
- || !sigs_set_hdlr (SIGALRM, dmon_sigs_hdlr)
- || !sigs_set_hdlr (SIGQUIT, dmon_sigs_hdlr)
- || !sigs_set_hdlr (SIGCHLD, SIG_IGN))
+ if (!sigs_set_hdlr(SIGINT, dmon_sigs_hdlr)
+ || !sigs_set_hdlr(SIGTERM, dmon_sigs_hdlr)
+ || !sigs_set_hdlr(SIGALRM, dmon_sigs_hdlr)
+ || !sigs_set_hdlr(SIGQUIT, dmon_sigs_hdlr)
+ || !sigs_set_hdlr(SIGCHLD, SIG_IGN))
return 0;
return 1;
}
-void
-dmon_start (int parent_exit_status)
+void dmon_start(int parent_exit_status)
{
- struct conf conf;
-
- if (!daemonize (parent_exit_status))
- DMON_ABRT (_("Cannot daemonize, aborting\n"));
-
- if (!io_dump_pid (path_dpid))
- DMON_ABRT (_("Could not set lock file\n"));
-
- if (!io_file_exist (path_conf))
- DMON_ABRT (_("Could not access \"%s\": %s\n"),
- path_conf, strerror (errno));
- custom_load_conf (&conf, 0);
-
- if (!io_file_exist (path_apts))
- DMON_ABRT (_("Could not access \"%s\": %s\n"),
- path_apts, strerror (errno));
- apoint_llist_init ();
- recur_apoint_llist_init ();
- event_llist_init ();
- todo_init_list ();
- io_load_app ();
+ if (!daemonize(parent_exit_status))
+ DMON_ABRT(_("Cannot daemonize, aborting\n"));
+
+ if (!io_dump_pid(path_dpid))
+ DMON_ABRT(_("Could not set lock file\n"));
+
+ if (!io_file_exist(path_conf))
+ DMON_ABRT(_("Could not access \"%s\": %s\n"), path_conf, strerror(errno));
+ config_load();
+
+ if (!io_file_exist(path_apts))
+ DMON_ABRT(_("Could not access \"%s\": %s\n"), path_apts, strerror(errno));
+ apoint_llist_init();
+ recur_apoint_llist_init();
+ event_llist_init();
+ todo_init_list();
+ io_load_app();
data_loaded = 1;
- DMON_LOG (_("started at %s\n"), nowstr ());
- for (;;)
- {
- int left;
-
- if (!notify_get_next_bkgd ())
- DMON_ABRT (_("error loading next appointment\n"));
-
- left = notify_time_left ();
- if (left > 0 && left < nbar.cntdwn && notify_needs_reminder ())
- {
- DMON_LOG (_("launching notification at %s for: \"%s\"\n"),
- nowstr (), notify_app_txt ());
- if (!notify_launch_cmd ())
- DMON_LOG (_("error while sending notification\n"));
- }
-
- DMON_LOG (_("sleeping at %s for %d seconds\n"), nowstr (),
- DMON_SLEEP_TIME);
- psleep (DMON_SLEEP_TIME);
- DMON_LOG (_("awakened at %s\n"), nowstr ());
+ DMON_LOG(_("started at %s\n"), nowstr());
+ for (;;) {
+ int left;
+
+ if (!notify_get_next_bkgd())
+ DMON_ABRT(_("error loading next appointment\n"));
+
+ left = notify_time_left();
+ if (left > 0 && left < nbar.cntdwn && notify_needs_reminder()) {
+ DMON_LOG(_("launching notification at %s for: \"%s\"\n"),
+ nowstr(), notify_app_txt());
+ if (!notify_launch_cmd())
+ DMON_LOG(_("error while sending notification\n"));
}
+
+ DMON_LOG(ngettext("sleeping at %s for %d second\n",
+ "sleeping at %s for %d seconds\n",
+ DMON_SLEEP_TIME), nowstr(), DMON_SLEEP_TIME);
+ psleep(DMON_SLEEP_TIME);
+ DMON_LOG(_("awakened at %s\n"), nowstr());
+ }
}
/*
* Check if calcurse is running in background, and if yes, send a SIGINT
* signal to stop it.
*/
-void
-dmon_stop (void)
+void dmon_stop(void)
{
int dpid;
- dpid = io_get_pid (path_dpid);
+ dpid = io_get_pid(path_dpid);
if (!dpid)
return;
- if (kill ((pid_t)dpid, SIGINT) < 0 && errno != ESRCH)
- EXIT (_("Could not stop calcurse daemon: %s\n"), strerror (errno));
+ if (kill((pid_t) dpid, SIGINT) < 0 && errno != ESRCH)
+ EXIT(_("Could not stop calcurse daemon: %s\n"), strerror(errno));
}
diff --git a/src/event.c b/src/event.c
index c395ed8..f460ded 100644
--- a/src/event.c
+++ b/src/event.c
@@ -1,7 +1,7 @@
/*
* Calcurse - text-based organizer
*
- * Copyright (c) 2004-2011 calcurse Development Team <misc@calcurse.org>
+ * Copyright (c) 2004-2012 calcurse Development Team <misc@calcurse.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -41,181 +41,160 @@
#include "calcurse.h"
-llist_t eventlist;
-static struct event bkp_cut_event;
+llist_t eventlist;
+static struct event bkp_cut_event;
-void
-event_free_bkp (enum eraseflg flag)
+void event_free_bkp(void)
{
- if (bkp_cut_event.mesg)
- {
- mem_free (bkp_cut_event.mesg);
- bkp_cut_event.mesg = 0;
- }
- erase_note (&bkp_cut_event.note, flag);
+ if (bkp_cut_event.mesg) {
+ mem_free(bkp_cut_event.mesg);
+ bkp_cut_event.mesg = 0;
+ }
+ erase_note(&bkp_cut_event.note);
}
-static void
-event_free (struct event *ev)
+static void event_free(struct event *ev)
{
- mem_free (ev->mesg);
- erase_note (&ev->note, ERASE_FORCE_KEEP_NOTE);
- mem_free (ev);
+ mem_free(ev->mesg);
+ erase_note(&ev->note);
+ mem_free(ev);
}
-static void
-event_dup (struct event *in, struct event *bkp)
+static void event_dup(struct event *in, struct event *bkp)
{
- EXIT_IF (!in || !bkp, _("null pointer"));
+ EXIT_IF(!in || !bkp, _("null pointer"));
bkp->id = in->id;
bkp->day = in->day;
- bkp->mesg = mem_strdup (in->mesg);
+ bkp->mesg = mem_strdup(in->mesg);
if (in->note)
- bkp->note = mem_strdup (in->note);
+ bkp->note = mem_strdup(in->note);
}
-void
-event_llist_init (void)
+void event_llist_init(void)
{
- LLIST_INIT (&eventlist);
+ LLIST_INIT(&eventlist);
}
-void
-event_llist_free (void)
+void event_llist_free(void)
{
- LLIST_FREE_INNER (&eventlist, event_free);
- LLIST_FREE (&eventlist);
+ LLIST_FREE_INNER(&eventlist, event_free);
+ LLIST_FREE(&eventlist);
}
-static int
-event_cmp_day (struct event *a, struct event *b)
+static int event_cmp_day(struct event *a, struct event *b)
{
- return (a->day < b->day ? -1 : (a->day == b->day ? 0 : 1));
+ return a->day < b->day ? -1 : (a->day == b->day ? 0 : 1);
}
/* Create a new event */
-struct event *
-event_new (char *mesg, char *note, long day, int id)
+struct event *event_new(char *mesg, char *note, long day, int id)
{
struct event *ev;
- ev = mem_malloc (sizeof (struct event));
- ev->mesg = mem_strdup (mesg);
+ ev = mem_malloc(sizeof(struct event));
+ ev->mesg = mem_strdup(mesg);
ev->day = day;
ev->id = id;
- ev->note = (note != NULL) ? mem_strdup (note) : NULL;
+ ev->note = (note != NULL) ? mem_strdup(note) : NULL;
- LLIST_ADD_SORTED (&eventlist, ev, event_cmp_day);
+ LLIST_ADD_SORTED(&eventlist, ev, event_cmp_day);
return ev;
}
/* Check if the event belongs to the selected day */
-unsigned
-event_inday (struct event *i, long start)
+unsigned event_inday(struct event *i, long start)
{
- if (i->day <= start + DAYINSEC && i->day > start)
- {
- return (1);
- }
- return (0);
+ return (i->day < start + DAYINSEC && i->day >= start);
}
/* Write to file the event in user-friendly format */
-void
-event_write (struct event *o, FILE *f)
+void event_write(struct event *o, FILE * f)
{
struct tm *lt;
time_t t;
t = o->day;
- lt = localtime (&t);
- (void)fprintf (f, "%02u/%02u/%04u [%d] ", lt->tm_mon + 1, lt->tm_mday,
- 1900 + lt->tm_year, o->id);
+ lt = localtime(&t);
+ fprintf(f, "%02u/%02u/%04u [%d] ", lt->tm_mon + 1, lt->tm_mday,
+ 1900 + lt->tm_year, o->id);
if (o->note != NULL)
- (void)fprintf (f, ">%s ", o->note);
- (void)fprintf (f, "%s\n", o->mesg);
+ fprintf(f, ">%s ", o->note);
+ fprintf(f, "%s\n", o->mesg);
}
/* Load the events from file */
-struct event *
-event_scan (FILE *f, struct tm start, int id, char *note)
+struct event *event_scan(FILE * f, struct tm start, int id, char *note)
{
char buf[BUFSIZ], *nl;
time_t tstart, t;
- t = time (NULL);
- (void)localtime (&t);
+ t = time(NULL);
+ localtime(&t);
/* Read the event description */
- (void)fgets (buf, sizeof buf, f);
- nl = strchr (buf, '\n');
- if (nl)
- {
- *nl = '\0';
- }
- start.tm_hour = 12;
+ if (!fgets(buf, sizeof buf, f))
+ return NULL;
+
+ nl = strchr(buf, '\n');
+ if (nl) {
+ *nl = '\0';
+ }
+ start.tm_hour = 0;
start.tm_min = 0;
start.tm_sec = 0;
start.tm_isdst = -1;
start.tm_year -= 1900;
start.tm_mon--;
- tstart = mktime (&start);
- EXIT_IF (tstart == -1, _("date error in the event\n"));
+ tstart = mktime(&start);
+ EXIT_IF(tstart == -1, _("date error in the event\n"));
- return event_new (buf, note, tstart, id);
+ return event_new(buf, note, tstart, id);
}
/* Retrieve an event from the list, given the day and item position. */
-struct event *
-event_get (long day, int pos)
+struct event *event_get(long day, int pos)
{
- llist_item_t *i = LLIST_FIND_NTH (&eventlist, pos, day, event_inday);
+ llist_item_t *i = LLIST_FIND_NTH(&eventlist, pos, day, event_inday);
if (i)
- return LLIST_TS_GET_DATA (i);
+ return LLIST_TS_GET_DATA(i);
- EXIT (_("event not found"));
+ EXIT(_("event not found"));
/* NOTREACHED */
}
/* Delete an event from the list. */
-void
-event_delete_bynum (long start, unsigned num, enum eraseflg flag)
+void event_delete_bynum(long start, unsigned num, enum eraseflg flag)
{
- llist_item_t *i = LLIST_FIND_NTH (&eventlist, num, start, event_inday);
+ llist_item_t *i = LLIST_FIND_NTH(&eventlist, num, start, event_inday);
if (!i)
- EXIT (_("no such appointment"));
- struct event *ev = LLIST_TS_GET_DATA (i);
-
- switch (flag)
- {
- case ERASE_FORCE_ONLY_NOTE:
- erase_note (&ev->note, flag);
- break;
- case ERASE_CUT:
- event_free_bkp (ERASE_FORCE);
- event_dup (ev, &bkp_cut_event);
- erase_note (&ev->note, ERASE_FORCE_KEEP_NOTE);
- /* FALLTHROUGH */
- default:
- LLIST_REMOVE (&eventlist, i);
- mem_free (ev->mesg);
- if (flag != ERASE_FORCE_KEEP_NOTE && flag != ERASE_CUT)
- erase_note (&ev->note, flag);
- mem_free (ev);
- break;
- }
+ EXIT(_("no such appointment"));
+ struct event *ev = LLIST_TS_GET_DATA(i);
+
+ switch (flag) {
+ case ERASE_FORCE_ONLY_NOTE:
+ erase_note(&ev->note);
+ break;
+ case ERASE_CUT:
+ event_free_bkp();
+ event_dup(ev, &bkp_cut_event);
+ erase_note(&ev->note);
+ /* FALLTHROUGH */
+ default:
+ LLIST_REMOVE(&eventlist, i);
+ mem_free(ev->mesg);
+ mem_free(ev);
+ break;
+ }
}
-void
-event_paste_item (void)
+void event_paste_item(void)
{
- (void)event_new (bkp_cut_event.mesg, bkp_cut_event.note,
- date2sec (*calendar_get_slctd_day (), 12, 0),
- bkp_cut_event.id);
- event_free_bkp (ERASE_FORCE_KEEP_NOTE);
+ event_new(bkp_cut_event.mesg, bkp_cut_event.note,
+ date2sec(*calendar_get_slctd_day(), 0, 0), bkp_cut_event.id);
+ event_free_bkp();
}
diff --git a/src/getstring.c b/src/getstring.c
new file mode 100644
index 0000000..cc2a949
--- /dev/null
+++ b/src/getstring.c
@@ -0,0 +1,280 @@
+/*
+ * Calcurse - text-based organizer
+ *
+ * Copyright (c) 2004-2012 calcurse Development Team <misc@calcurse.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Send your feedback or comments to : misc@calcurse.org
+ * Calcurse home page : http://calcurse.org
+ *
+ */
+
+#include "calcurse.h"
+
+struct getstr_charinfo {
+ unsigned int offset, dpyoff;
+};
+
+struct getstr_status {
+ char *s;
+ struct getstr_charinfo *ci;
+ int pos, len;
+ int scrpos;
+};
+
+/* Print the string at the desired position. */
+static void getstr_print(WINDOW * win, int x, int y, struct getstr_status *st)
+{
+ char c = 0;
+
+ /* print string */
+ mvwaddnstr(win, y, x, &st->s[st->ci[st->scrpos].offset], -1);
+ wclrtoeol(win);
+
+ /* print scrolling indicator */
+ if (st->scrpos > 0 && st->ci[st->len].dpyoff -
+ st->ci[st->scrpos].dpyoff > col - 2)
+ c = '*';
+ else if (st->scrpos > 0)
+ c = '<';
+ else if (st->ci[st->len].dpyoff - st->ci[st->scrpos].dpyoff > col - 2)
+ c = '>';
+ mvwprintw(win, y, col - 2, " %c", c);
+
+ /* print cursor */
+ wmove(win, y, st->ci[st->pos].dpyoff - st->ci[st->scrpos].dpyoff);
+ wchgat(win, 1, A_REVERSE, COLR_CUSTOM, NULL);
+}
+
+/* Delete a character at the given position in string. */
+static void getstr_del_char(struct getstr_status *st)
+{
+ char *str = st->s + st->ci[st->pos].offset;
+ int cl = st->ci[st->pos + 1].offset - st->ci[st->pos].offset;
+ int cw = st->ci[st->pos + 1].dpyoff - st->ci[st->pos].dpyoff;
+ int i;
+
+ memmove(str, str + cl, strlen(str) + 1);
+
+ st->len--;
+ for (i = st->pos; i <= st->len; i++) {
+ st->ci[i].offset = st->ci[i + 1].offset - cl;
+ st->ci[i].dpyoff = st->ci[i + 1].dpyoff - cw;
+ }
+}
+
+/* Add a character at the given position in string. */
+static void getstr_ins_char(struct getstr_status *st, char *c)
+{
+ char *str = st->s + st->ci[st->pos].offset;
+ int cl = UTF8_LENGTH(c[0]);
+ int cw = utf8_width(c);
+ int i;
+
+ memmove(str + cl, str, strlen(str) + 1);
+ for (i = 0; i < cl; i++, str++)
+ *str = c[i];
+
+ for (i = st->len; i >= st->pos; i--) {
+ st->ci[i + 1].offset = st->ci[i].offset + cl;
+ st->ci[i + 1].dpyoff = st->ci[i].dpyoff + cw;
+ }
+ st->len++;
+}
+
+static void bell(void)
+{
+ putchar('\a');
+}
+
+/* Initialize getstring data structure. */
+static void
+getstr_init(struct getstr_status *st, char *str, struct getstr_charinfo *ci)
+{
+ int width;
+
+ st->s = str;
+ st->ci = ci;
+
+ st->len = width = 0;
+ while (*str) {
+ st->ci[st->len].offset = str - st->s;
+ st->ci[st->len].dpyoff = width;
+
+ st->len++;
+ width += utf8_width(str);
+ str += UTF8_LENGTH(*str);
+ }
+ st->ci[st->len].offset = str - st->s;
+ st->ci[st->len].dpyoff = width;
+
+ st->pos = st->len;
+ st->scrpos = 0;
+}
+
+/* Scroll left/right if the cursor moves outside the window range. */
+static void getstr_fixscr(struct getstr_status *st)
+{
+ const int pgsize = col / 3;
+ int pgskip;
+
+ while (st->pos < st->scrpos) {
+ pgskip = 0;
+ while (pgskip < pgsize && st->scrpos > 0) {
+ st->scrpos--;
+ pgskip += st->ci[st->scrpos + 1].dpyoff - st->ci[st->scrpos].dpyoff;
+ }
+ }
+ while (st->ci[st->pos].dpyoff - st->ci[st->scrpos].dpyoff > col - 2) {
+ pgskip = 0;
+ while (pgskip < pgsize && st->scrpos < st->len) {
+ pgskip += st->ci[st->scrpos + 1].dpyoff - st->ci[st->scrpos].dpyoff;
+ st->scrpos++;
+ }
+ }
+}
+
+/*
+ * Getstring allows to get user input and to print it on a window,
+ * even if noecho() is on. This function is also used to modify an existing
+ * text (the variable string can be non-NULL).
+ * We need to do the echoing manually because of the multi-threading
+ * environment, otherwise the cursor would move from place to place without
+ * control.
+ */
+enum getstr getstring(WINDOW * win, char *str, int l, int x, int y)
+{
+ struct getstr_status st;
+ struct getstr_charinfo ci[l + 1];
+
+ int ch, k;
+ char c[UTF8_MAXLEN];
+
+ getstr_init(&st, str, ci);
+ custom_apply_attr(win, ATTR_HIGHEST);
+
+ for (;;) {
+ getstr_fixscr(&st);
+ getstr_print(win, x, y, &st);
+ wins_doupdate();
+
+ if ((ch = wgetch(win)) == '\n')
+ break;
+ switch (ch) {
+ case KEY_BACKSPACE: /* delete one character */
+ case 330:
+ case 127:
+ case CTRL('H'):
+ if (st.pos > 0) {
+ st.pos--;
+ getstr_del_char(&st);
+ } else
+ bell();
+ break;
+ case CTRL('D'): /* delete next character */
+ if (st.pos < st.len)
+ getstr_del_char(&st);
+ else
+ bell();
+ break;
+ case CTRL('W'): /* delete a word */
+ if (st.pos > 0) {
+ while (st.pos && st.s[st.ci[st.pos - 1].offset] == ' ') {
+ st.pos--;
+ getstr_del_char(&st);
+ }
+ while (st.pos && st.s[st.ci[st.pos - 1].offset] != ' ') {
+ st.pos--;
+ getstr_del_char(&st);
+ }
+ } else
+ bell();
+ break;
+ case CTRL('K'): /* delete to end-of-line */
+ st.s[st.ci[st.pos].offset] = 0;
+ st.len = st.pos;
+ break;
+ case CTRL('A'): /* go to begginning of string */
+ st.pos = 0;
+ break;
+ case CTRL('E'): /* go to end of string */
+ st.pos = st.len;
+ break;
+ case KEY_LEFT: /* move one char backward */
+ case CTRL('B'):
+ if (st.pos > 0)
+ st.pos--;
+ break;
+ case KEY_RIGHT: /* move one char forward */
+ case CTRL('F'):
+ if (st.pos < st.len)
+ st.pos++;
+ break;
+ case ESCAPE: /* cancel editing */
+ return GETSTRING_ESC;
+ break;
+ default: /* insert one character */
+ c[0] = ch;
+ for (k = 1; k < MIN(UTF8_LENGTH(c[0]), UTF8_MAXLEN); k++)
+ c[k] = (unsigned char)wgetch(win);
+ if (st.ci[st.len].offset + k < l) {
+ getstr_ins_char(&st, c);
+ st.pos++;
+ }
+ }
+ }
+
+ custom_remove_attr(win, ATTR_HIGHEST);
+
+ return st.len == 0 ? GETSTRING_RET : GETSTRING_VALID;
+}
+
+/* Update an already existing string. */
+int updatestring(WINDOW * win, char **str, int x, int y)
+{
+ int len = strlen(*str);
+ char *buf;
+ enum getstr ret;
+
+ EXIT_IF(len + 1 > BUFSIZ, _("Internal error: line too long"));
+
+ buf = mem_malloc(BUFSIZ);
+ memcpy(buf, *str, len + 1);
+
+ ret = getstring(win, buf, BUFSIZ, x, y);
+
+ if (ret == GETSTRING_VALID) {
+ len = strlen(buf);
+ *str = mem_realloc(*str, len + 1, 1);
+ EXIT_IF(*str == NULL, _("out of memory"));
+ memcpy(*str, buf, len + 1);
+ }
+
+ mem_free(buf);
+ return ret;
+}
diff --git a/src/help.c b/src/help.c
index 3f4f7c7..6dbac96 100644
--- a/src/help.c
+++ b/src/help.c
@@ -1,7 +1,7 @@
/*
* Calcurse - text-based organizer
*
- * Copyright (c) 2004-2011 calcurse Development Team <misc@calcurse.org>
+ * Copyright (c) 2004-2012 calcurse Development Team <misc@calcurse.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -48,14 +48,14 @@ typedef struct {
char text[HELPTEXTSIZ];
} help_page_t;
-typedef enum
-{
+typedef enum {
HELP_MAIN,
HELP_SAVE,
HELP_IMPORT,
HELP_EXPORT,
HELP_DISPLACEMENT,
HELP_VIEW,
+ HELP_PIPE,
HELP_TAB,
HELP_GOTO,
HELP_DELETE,
@@ -73,21 +73,18 @@ typedef enum
HELP_CREDITS,
HELPSCREENS,
NOPAGE
-}
-help_pages_e;
+} help_pages_e;
/* Returns the number of lines in an help text. */
-static int
-get_help_lines (char *text)
+static int get_help_lines(char *text)
{
int i, newline;
newline = 0;
- for (i = 0; text[i]; i++)
- {
- if (text[i] == '\n')
- newline++;
- }
+ for (i = 0; text[i]; i++) {
+ if (text[i] == '\n')
+ newline++;
+ }
return newline + 1;
}
@@ -96,54 +93,52 @@ get_help_lines (char *text)
* of lines that were written.
*/
static int
-help_write_pad (struct window *win, char *title, char *text, enum key action)
+help_write_pad(struct window *win, char *title, char *text, enum key action)
{
int colnum, rownum;
- char *bindings_title = "key bindings: %s";
+ const char *bindings_title = "key bindings: %s";
char *bindings;
colnum = 0;
rownum = 0;
- erase_window_part (win->p, rownum, colnum, BUFSIZ, win->w);
- custom_apply_attr (win->p, ATTR_HIGHEST);
- mvwprintw (win->p, rownum, colnum, "%s", title);
- if ((int) action != KEY_RESIZE && action < NBKEYS) {
- switch (action)
- {
- case KEY_END_OF_WEEK:
- case KEY_START_OF_WEEK:
- case KEY_MOVE_UP:
- case KEY_MOVE_DOWN:
- case KEY_MOVE_RIGHT:
- case KEY_MOVE_LEFT:
- case KEY_GENERIC_HELP:
- case KEY_GENERIC_REDRAW:
- case KEY_GENERIC_ADD_APPT:
- case KEY_GENERIC_ADD_TODO:
- case KEY_GENERIC_NEXT_DAY:
- case KEY_GENERIC_PREV_DAY:
- case KEY_GENERIC_NEXT_WEEK:
- case KEY_GENERIC_PREV_WEEK:
- case KEY_GENERIC_GOTO_TODAY:
- case KEY_GENERIC_CREDITS:
- case KEY_GENERIC_CUT:
- case KEY_GENERIC_PASTE:
- break;
- default:
- bindings = keys_action_allkeys (action);
-
- if (bindings)
- {
- colnum = win->w - strlen (bindings_title) - strlen (bindings);
- mvwprintw (win->p, rownum, colnum, bindings_title, bindings);
- }
+ erase_window_part(win->p, rownum, colnum, BUFSIZ, win->w);
+ custom_apply_attr(win->p, ATTR_HIGHEST);
+ mvwprintw(win->p, rownum, colnum, "%s", title);
+ if ((int)action != KEY_RESIZE && action < NBKEYS) {
+ switch (action) {
+ case KEY_END_OF_WEEK:
+ case KEY_START_OF_WEEK:
+ case KEY_MOVE_UP:
+ case KEY_MOVE_DOWN:
+ case KEY_MOVE_RIGHT:
+ case KEY_MOVE_LEFT:
+ case KEY_GENERIC_HELP:
+ case KEY_GENERIC_REDRAW:
+ case KEY_GENERIC_ADD_APPT:
+ case KEY_GENERIC_ADD_TODO:
+ case KEY_GENERIC_NEXT_DAY:
+ case KEY_GENERIC_PREV_DAY:
+ case KEY_GENERIC_NEXT_WEEK:
+ case KEY_GENERIC_PREV_WEEK:
+ case KEY_GENERIC_GOTO_TODAY:
+ case KEY_GENERIC_CREDITS:
+ case KEY_GENERIC_CUT:
+ case KEY_GENERIC_PASTE:
+ break;
+ default:
+ bindings = keys_action_allkeys(action);
+
+ if (bindings) {
+ colnum = win->w - strlen(bindings_title) - strlen(bindings);
+ mvwprintw(win->p, rownum, colnum, bindings_title, bindings);
}
+ }
}
colnum = 0;
- rownum += get_help_lines (title);
- custom_remove_attr (win->p, ATTR_HIGHEST);
- mvwprintw (win->p, rownum, colnum, "%s", text);
- rownum += get_help_lines (text);
+ rownum += get_help_lines(title);
+ custom_remove_attr(win->p, ATTR_HIGHEST);
+ mvwprintw(win->p, rownum, colnum, "%s", text);
+ rownum += get_help_lines(text);
return rownum;
}
@@ -151,8 +146,7 @@ help_write_pad (struct window *win, char *title, char *text, enum key action)
* Create and init help screen and its pad, which is used to make the scrolling
* faster.
*/
-void
-help_wins_init (struct scrollwin *hwin, int x, int y, int h, int w)
+void help_wins_init(struct scrollwin *hwin, int x, int y, int h, int w)
{
const int PADOFFSET = 4;
const int TITLELINES = 3;
@@ -167,159 +161,158 @@ help_wins_init (struct scrollwin *hwin, int x, int y, int h, int w)
hwin->pad.h = BUFSIZ;
hwin->pad.w = hwin->win.w - 2 * PADOFFSET + 1;
- (void)snprintf (hwin->label, BUFSIZ, _("Calcurse help"));
- wins_scrollwin_init (hwin);
- wins_show (hwin->win.p, hwin->label);
+ hwin->label = _("Calcurse help");
+ wins_scrollwin_init(hwin);
+ wins_show(hwin->win.p, hwin->label);
}
/*
* Delete the existing windows and recreate them with their new
* size and placement.
*/
-static void
-help_wins_reinit (struct scrollwin *hwin)
+static void help_wins_reinit(struct scrollwin *hwin)
{
- wins_scrollwin_delete (hwin);
- wins_get_config ();
- help_wins_init (hwin, 0, 0, (notify_bar ()) ? row - 3 : row - 2, col);
+ wins_scrollwin_delete(hwin);
+ wins_get_config();
+ help_wins_init(hwin, 0, 0, (notify_bar())? row - 3 : row - 2, col);
}
/* Reset the screen, needed when resizing terminal for example. */
-static void
-help_wins_reset (struct scrollwin *hwin)
+static void help_wins_reset(struct scrollwin *hwin)
{
- endwin ();
- wins_refresh ();
- curs_set (0);
- delwin (win[STA].p);
- help_wins_reinit (hwin);
- win[STA].p = newwin (win[STA].h, win[STA].w, win[STA].y, win[STA].x);
- keypad (win[STA].p, TRUE);
- if (notify_bar ())
- notify_reinit_bar ();
- wins_status_bar ();
- if (notify_bar ())
- notify_update_bar ();
+ endwin();
+ wins_refresh();
+ curs_set(0);
+ delwin(win[STA].p);
+ help_wins_reinit(hwin);
+ win[STA].p = newwin(win[STA].h, win[STA].w, win[STA].y, win[STA].x);
+ keypad(win[STA].p, TRUE);
+ if (notify_bar())
+ notify_reinit_bar();
+ wins_status_bar();
+ if (notify_bar())
+ notify_update_bar();
}
/* Association between a key pressed and its corresponding help page. */
-static int
-wanted_page (int ch)
+static int wanted_page(int ch)
{
int page;
- switch (ch)
- {
-
- case KEY_GENERIC_HELP:
- page = HELP_MAIN;
- break;
-
- case KEY_FLAG_ITEM:
- page = HELP_FLAG;
- break;
-
- case KEY_GENERIC_REDRAW:
- case KEY_GENERIC_ADD_APPT:
- case KEY_GENERIC_ADD_TODO:
- case KEY_GENERIC_NEXT_DAY:
- case KEY_GENERIC_PREV_DAY:
- case KEY_GENERIC_NEXT_WEEK:
- case KEY_GENERIC_PREV_WEEK:
- case KEY_GENERIC_GOTO_TODAY:
- page = HELP_GENERAL;
- break;
-
- case KEY_GENERIC_SAVE:
- page = HELP_SAVE;
- break;
-
- case KEY_GENERIC_IMPORT:
- page = HELP_IMPORT;
- break;
-
- case KEY_GENERIC_EXPORT:
- page = HELP_EXPORT;
- break;
-
- case KEY_END_OF_WEEK:
- case KEY_START_OF_WEEK:
- case KEY_MOVE_UP:
- case KEY_MOVE_DOWN:
- case KEY_MOVE_RIGHT:
- case KEY_MOVE_LEFT:
- page = HELP_DISPLACEMENT;
- break;
-
- case KEY_ADD_ITEM:
- page = HELP_ADD;
- break;
-
- case KEY_GENERIC_GOTO:
- page = HELP_GOTO;
- break;
-
- case KEY_DEL_ITEM:
- page = HELP_DELETE;
- break;
-
- case KEY_GENERIC_CUT:
- case KEY_GENERIC_PASTE:
- page = HELP_CUT_PASTE;
- break;
-
- case KEY_EDIT_ITEM:
- page = HELP_EDIT;
- break;
-
- case KEY_EDIT_NOTE:
- page = HELP_ENOTE;
- break;
-
- case KEY_VIEW_NOTE:
- page = HELP_VNOTE;
- break;
-
- case KEY_GENERIC_CONFIG_MENU:
- page = HELP_CONFIG;
- break;
-
- case KEY_GENERIC_OTHER_CMD:
- page = HELP_OTHER;
- break;
-
- case KEY_REPEAT_ITEM:
- page = HELP_REPEAT;
- break;
-
- case KEY_VIEW_ITEM:
- page = HELP_VIEW;
- break;
-
- case KEY_RAISE_PRIORITY:
- case KEY_LOWER_PRIORITY:
- page = HELP_PRIORITY;
- break;
-
- case KEY_GENERIC_CHANGE_VIEW:
- page = HELP_TAB;
- break;
-
- case KEY_GENERIC_CREDITS:
- page = HELP_CREDITS;
- break;
-
- default:
- page = NOPAGE;
- break;
- }
+ switch (ch) {
+
+ case KEY_GENERIC_HELP:
+ page = HELP_MAIN;
+ break;
+
+ case KEY_FLAG_ITEM:
+ page = HELP_FLAG;
+ break;
+
+ case KEY_GENERIC_REDRAW:
+ case KEY_GENERIC_ADD_APPT:
+ case KEY_GENERIC_ADD_TODO:
+ case KEY_GENERIC_NEXT_DAY:
+ case KEY_GENERIC_PREV_DAY:
+ case KEY_GENERIC_NEXT_WEEK:
+ case KEY_GENERIC_PREV_WEEK:
+ case KEY_GENERIC_GOTO_TODAY:
+ page = HELP_GENERAL;
+ break;
+
+ case KEY_GENERIC_SAVE:
+ page = HELP_SAVE;
+ break;
+
+ case KEY_GENERIC_IMPORT:
+ page = HELP_IMPORT;
+ break;
+
+ case KEY_GENERIC_EXPORT:
+ page = HELP_EXPORT;
+ break;
+
+ case KEY_END_OF_WEEK:
+ case KEY_START_OF_WEEK:
+ case KEY_MOVE_UP:
+ case KEY_MOVE_DOWN:
+ case KEY_MOVE_RIGHT:
+ case KEY_MOVE_LEFT:
+ page = HELP_DISPLACEMENT;
+ break;
+
+ case KEY_ADD_ITEM:
+ page = HELP_ADD;
+ break;
+
+ case KEY_GENERIC_GOTO:
+ page = HELP_GOTO;
+ break;
+
+ case KEY_DEL_ITEM:
+ page = HELP_DELETE;
+ break;
+
+ case KEY_GENERIC_CUT:
+ case KEY_GENERIC_PASTE:
+ page = HELP_CUT_PASTE;
+ break;
+
+ case KEY_EDIT_ITEM:
+ page = HELP_EDIT;
+ break;
+
+ case KEY_EDIT_NOTE:
+ page = HELP_ENOTE;
+ break;
+
+ case KEY_VIEW_NOTE:
+ page = HELP_VNOTE;
+ break;
+
+ case KEY_GENERIC_CONFIG_MENU:
+ page = HELP_CONFIG;
+ break;
+
+ case KEY_GENERIC_OTHER_CMD:
+ page = HELP_OTHER;
+ break;
+
+ case KEY_REPEAT_ITEM:
+ page = HELP_REPEAT;
+ break;
+
+ case KEY_VIEW_ITEM:
+ page = HELP_VIEW;
+ break;
+
+ case KEY_PIPE_ITEM:
+ page = HELP_PIPE;
+ break;
+
+ case KEY_RAISE_PRIORITY:
+ case KEY_LOWER_PRIORITY:
+ page = HELP_PRIORITY;
+ break;
+
+ case KEY_GENERIC_CHANGE_VIEW:
+ page = HELP_TAB;
+ break;
+
+ case KEY_GENERIC_CREDITS:
+ page = HELP_CREDITS;
+ break;
+
+ default:
+ page = NOPAGE;
+ break;
+ }
- return (page);
+ return page;
}
/* Draws the help screen */
-void
-help_screen (void)
+void help_screen(void)
{
enum {
MOVE_UP,
@@ -336,452 +329,460 @@ help_screen (void)
char keystr[DIRECTIONS][BUFSIZ];
hscr[HELP_MAIN].title =
- _(" Welcome to Calcurse. This is the main help screen.\n");
- (void)snprintf (hscr[HELP_MAIN].text, HELPTEXTSIZ,
- _("Moving around: Press '%s' or '%s' to scroll text upward or downward\n"
- " inside help screens, if necessary.\n\n"
- " Exit help: When finished, press '%s' to exit help and go back to\n"
- " the main Calcurse screen.\n\n"
- " Help topic: At the bottom of this screen you can see a panel with\n"
- " different fields, represented by a letter and a short\n"
- " title. This panel contains all the available actions\n"
- " you can perform when using Calcurse.\n"
- " By pressing one of the letters appearing in this\n"
- " panel, you will be shown a short description of the\n"
- " corresponding action. At the top right side of the\n"
- " description screen are indicated the user-defined key\n"
- " bindings that lead to the action.\n\n"
- " Credits: Press '%s' for credits."),
- keys_action_firstkey (KEY_GENERIC_SCROLL_UP),
- keys_action_firstkey (KEY_GENERIC_SCROLL_DOWN),
- keys_action_firstkey (KEY_GENERIC_QUIT),
- keys_action_firstkey (KEY_GENERIC_CREDITS));
+ _(" Welcome to Calcurse. This is the main help screen.\n");
+ snprintf(hscr[HELP_MAIN].text, HELPTEXTSIZ,
+ _
+ ("Moving around: Press '%s' or '%s' to scroll text upward or downward\n"
+ " inside help screens, if necessary.\n\n"
+ " Exit help: When finished, press '%s' to exit help and go back to\n"
+ " the main Calcurse screen.\n\n"
+ " Help topic: At the bottom of this screen you can see a panel with\n"
+ " different fields, represented by a letter and a short\n"
+ " title. This panel contains all the available actions\n"
+ " you can perform when using Calcurse.\n"
+ " By pressing one of the letters appearing in this\n"
+ " panel, you will be shown a short description of the\n"
+ " corresponding action. At the top right side of the\n"
+ " description screen are indicated the user-defined key\n"
+ " bindings that lead to the action.\n\n"
+ " Credits: Press '%s' for credits."),
+ keys_action_firstkey(KEY_GENERIC_SCROLL_UP),
+ keys_action_firstkey(KEY_GENERIC_SCROLL_DOWN),
+ keys_action_firstkey(KEY_GENERIC_QUIT),
+ keys_action_firstkey(KEY_GENERIC_CREDITS));
hscr[HELP_SAVE].title = _("Save\n");
- (void)snprintf (hscr[HELP_SAVE].text, HELPTEXTSIZ,
- _("Save calcurse data.\n"
- "Data are splitted into four different files which contain :"
- "\n\n"
- " / ~/.calcurse/conf -> user configuration\n"
- " | (layout, color, general options)\n"
- " | ~/.calcurse/apts -> data related to the appointments\n"
- " | ~/.calcurse/todo -> data related to the todo list\n"
- " \\ ~/.calcurse/keys -> user-defined key bindings\n"
- "\nIn the config menu, you can choose to save the Calcurse data\n"
- "automatically before quitting."));
+ snprintf(hscr[HELP_SAVE].text, HELPTEXTSIZ,
+ _("Save calcurse data.\n"
+ "Data are splitted into four different files which contain :"
+ "\n\n"
+ " / ~/.calcurse/conf -> user configuration\n"
+ " | (layout, color, general options)\n"
+ " | ~/.calcurse/apts -> data related to the appointments\n"
+ " | ~/.calcurse/todo -> data related to the todo list\n"
+ " \\ ~/.calcurse/keys -> user-defined key bindings\n"
+ "\nIn the config menu, you can choose to save the Calcurse data\n"
+ "automatically before quitting."));
hscr[HELP_IMPORT].title = _("Import\n");
- (void)snprintf (hscr[HELP_IMPORT].text, HELPTEXTSIZ,
- _("Import data from an icalendar file.\n"
- "You will be asked to enter the file name from which to load ical\n"
- "items. At the end of the import process, and if the general option\n"
- "'skip_system_dialogs' is not set to 'yes', a report indicating how\n"
- "many items were imported is shown.\n"
- "This report contains the total number of lines read, the number of\n"
- "appointments, events and todo items which were successfully imported,\n"
- "together with the number of items for which problems occured and that\n"
- "were skipped, if any.\n\n"
- "If one or more items could not be imported, one has the possibility to\n"
- "read the import process report in order to identify which problems\n"
- "occured.\n"
- "In this report is shown one item per line, with the line in the input\n"
- "stream at which this item begins, together with the description of why\n"
- "the item could not be imported.\n"));
+ snprintf(hscr[HELP_IMPORT].text, HELPTEXTSIZ,
+ _("Import data from an icalendar file.\n"
+ "You will be asked to enter the file name from which to load ical\n"
+ "items. At the end of the import process, and if the general option\n"
+ "'system_dialogs' is set to 'yes', a report indicating how many items\n"
+ "were imported is shown.\n"
+ "This report contains the total number of lines read, the number of\n"
+ "appointments, events and todo items which were successfully imported,\n"
+ "together with the number of items for which problems occured and that\n"
+ "were skipped, if any.\n\n"
+ "If one or more items could not be imported, one has the possibility to\n"
+ "read the import process report in order to identify which problems\n"
+ "occured.\n"
+ "In this report is shown one item per line, with the line in the input\n"
+ "stream at which this item begins, together with the description of why\n"
+ "the item could not be imported.\n"));
hscr[HELP_EXPORT].title = _("Export\n");
- (void)snprintf (hscr[HELP_EXPORT].text, HELPTEXTSIZ,
- _("Export calcurse data (appointments, events and todos).\n"
- "This leads to the export submenu, from which you can choose between\n"
- "two different export formats: 'ical' and 'pcal'. Choosing one of\n"
- "those formats lets you export calcurse data to icalendar or pcal\n"
- "format.\n\n"
- "You first need to specify the file to which the data will be exported.\n"
- "By default, this file is:\n\n"
- " ~/calcurse.ics\n\n"
- "for an ical export, and:\n\n"
- " ~/calcurse.txt\n\n"
- "for a pcal export.\n\n"
- "Calcurse data are exported in the following order:\n"
- " events, appointments, todos.\n"));
-
- (void)strncpy (keystr[MOVE_UP], keys_action_allkeys (KEY_MOVE_UP), BUFSIZ);
- (void)strncpy (keystr[MOVE_DOWN], keys_action_allkeys (KEY_MOVE_DOWN),
- BUFSIZ);
- (void)strncpy (keystr[MOVE_LEFT], keys_action_allkeys (KEY_MOVE_LEFT),
- BUFSIZ);
- (void)strncpy (keystr[MOVE_RIGHT], keys_action_allkeys (KEY_MOVE_RIGHT),
- BUFSIZ);
+ snprintf(hscr[HELP_EXPORT].text, HELPTEXTSIZ,
+ _("Export calcurse data (appointments, events and todos).\n"
+ "This leads to the export submenu, from which you can choose between\n"
+ "two different export formats: 'ical' and 'pcal'. Choosing one of\n"
+ "those formats lets you export calcurse data to icalendar or pcal\n"
+ "format.\n\n"
+ "You first need to specify the file to which the data will be exported.\n"
+ "By default, this file is:\n\n"
+ " ~/calcurse.ics\n\n"
+ "for an ical export, and:\n\n"
+ " ~/calcurse.txt\n\n"
+ "for a pcal export.\n\n"
+ "Calcurse data are exported in the following order:\n"
+ " events, appointments, todos.\n"));
+
+ strncpy(keystr[MOVE_UP], keys_action_allkeys(KEY_MOVE_UP), BUFSIZ);
+ strncpy(keystr[MOVE_DOWN], keys_action_allkeys(KEY_MOVE_DOWN), BUFSIZ);
+ strncpy(keystr[MOVE_LEFT], keys_action_allkeys(KEY_MOVE_LEFT), BUFSIZ);
+ strncpy(keystr[MOVE_RIGHT], keys_action_allkeys(KEY_MOVE_RIGHT), BUFSIZ);
hscr[HELP_DISPLACEMENT].title = _("Displacement keys\n");
- (void)snprintf (hscr[HELP_DISPLACEMENT].text, HELPTEXTSIZ,
- _("Move around inside calcurse screens.\n"
- "The following scheme summarizes how to get around:\n\n"
- " move up\n"
- " move to previous week\n"
- "\n"
- " %s\n"
- " move left ^ \n"
- " move to previous day |\n"
- " %s\n"
- " <-- + -->\n"
- " %s\n"
- " | move right\n"
- " v move to next day\n"
- " %s\n"
- "\n"
- " move to next week\n"
- " move down\n"
- "\nMoreover, while inside the calendar panel, the '%s' key moves\n"
- "to the first day of the week, and the '%s' key selects the last day of\n"
- "the week.\n"),
- keystr[MOVE_UP], keystr[MOVE_LEFT],
- keystr[MOVE_RIGHT], keystr[MOVE_DOWN],
- keys_action_firstkey (KEY_START_OF_WEEK),
- keys_action_firstkey (KEY_END_OF_WEEK));
+ snprintf(hscr[HELP_DISPLACEMENT].text, HELPTEXTSIZ,
+ _("Move around inside calcurse screens.\n"
+ "The following scheme summarizes how to get around:\n\n"
+ " move up\n"
+ " move to previous week\n"
+ "\n"
+ " %s\n"
+ " move left ^ \n"
+ " move to previous day |\n"
+ " %s\n"
+ " <-- + -->\n"
+ " %s\n"
+ " | move right\n"
+ " v move to next day\n"
+ " %s\n"
+ "\n"
+ " move to next week\n"
+ " move down\n"
+ "\nMoreover, while inside the calendar panel, the '%s' key moves\n"
+ "to the first day of the week, and the '%s' key selects the last day of\n"
+ "the week.\n"),
+ keystr[MOVE_UP], keystr[MOVE_LEFT],
+ keystr[MOVE_RIGHT], keystr[MOVE_DOWN],
+ keys_action_firstkey(KEY_START_OF_WEEK),
+ keys_action_firstkey(KEY_END_OF_WEEK));
hscr[HELP_VIEW].title = _("View\n");
- (void)snprintf (hscr[HELP_VIEW].text, HELPTEXTSIZ,
- _("View the item you select in either the Todo or Appointment panel.\n"
- "\nThis is usefull when an event description is longer than the "
- "available\nspace to display it. "
- "If that is the case, the description will be\n"
- "shortened and its end replaced by '...'. To be able to read the entire\n"
- "description, just press '%s' and a popup window will appear, containing\n"
- "the whole event.\n"
- "\nPress any key to close the popup window and go back to the main\n"
- "Calcurse screen."),
- keys_action_firstkey (KEY_VIEW_ITEM));
+ snprintf(hscr[HELP_VIEW].text, HELPTEXTSIZ,
+ _
+ ("View the item you select in either the Todo or Appointment panel.\n"
+ "\nThis is usefull when an event description is longer than the "
+ "available\nspace to display it. "
+ "If that is the case, the description will be\n"
+ "shortened and its end replaced by '...'. To be able to read the entire\n"
+ "description, just press '%s' and a popup window will appear, containing\n"
+ "the whole event.\n"
+ "\nPress any key to close the popup window and go back to the main\n"
+ "Calcurse screen."), keys_action_firstkey(KEY_VIEW_ITEM));
+
+ hscr[HELP_PIPE].title = _("Pipe\n");
+ snprintf(hscr[HELP_PIPE].text, HELPTEXTSIZ,
+ _("Pipe the selected item to an external program.\n"
+ "\nPress the '%s' key to pipe the currently selected appointment or\n"
+ "todo entry to an external program.\n"
+ "\nYou will be driven back to calcurse as soon as the program exits.\n"),
+ keys_action_firstkey(KEY_PIPE_ITEM));
hscr[HELP_TAB].title = _("Tab\n");
- (void)snprintf (hscr[HELP_TAB].text, HELPTEXTSIZ,
- _("Switch between panels.\n"
- "The panel currently in use has its border colorized.\n"
- "\nSome actions are possible only if the right panel is selected.\n"
- "For example, if you want to add a task in the TODO list, you need first"
- "\nto press the '%s' key to get the TODO panel selected. Then you can\n"
- "press '%s' to add your item.\n"
- "\nNotice that at the bottom of the screen the list of possible actions\n"
- "change while pressing '%s', so you always know what action can be\n"
- "performed on the selected panel."),
- keys_action_firstkey (KEY_GENERIC_CHANGE_VIEW),
- keys_action_firstkey (KEY_ADD_ITEM),
- keys_action_firstkey (KEY_GENERIC_CHANGE_VIEW));
+ snprintf(hscr[HELP_TAB].text, HELPTEXTSIZ,
+ _("Switch between panels.\n"
+ "The panel currently in use has its border colorized.\n"
+ "\nSome actions are possible only if the right panel is selected.\n"
+ "For example, if you want to add a task in the TODO list, you need first"
+ "\nto press the '%s' key to get the TODO panel selected. Then you can\n"
+ "press '%s' to add your item.\n"
+ "\nNotice that at the bottom of the screen the list of possible actions\n"
+ "change while pressing '%s', so you always know what action can be\n"
+ "performed on the selected panel."),
+ keys_action_firstkey(KEY_GENERIC_CHANGE_VIEW),
+ keys_action_firstkey(KEY_ADD_ITEM),
+ keys_action_firstkey(KEY_GENERIC_CHANGE_VIEW));
hscr[HELP_GOTO].title = _("Goto\n");
- (void)snprintf (hscr[HELP_GOTO].text, HELPTEXTSIZ,
- _("Jump to a specific day in the calendar.\n"
- "\nUsing this command, you do not need to travel to that day using\n"
- "the displacement keys inside the calendar panel.\n"
- "If you hit [ENTER] without specifying any date, Calcurse checks the\n"
- "system current date and you will be taken to that date.\n"
- "\nNotice that pressing '%s', whatever panel is\n"
- "selected, will select current day in the calendar."),
- keys_action_firstkey (KEY_GENERIC_GOTO_TODAY));
+ snprintf(hscr[HELP_GOTO].text, HELPTEXTSIZ,
+ _("Jump to a specific day in the calendar.\n"
+ "\nUsing this command, you do not need to travel to that day using\n"
+ "the displacement keys inside the calendar panel.\n"
+ "If you hit [ENTER] without specifying any date, Calcurse checks the\n"
+ "system current date and you will be taken to that date.\n"
+ "\nNotice that pressing '%s', whatever panel is\n"
+ "selected, will select current day in the calendar."),
+ keys_action_firstkey(KEY_GENERIC_GOTO_TODAY));
hscr[HELP_DELETE].title = _("Delete\n");
- (void)snprintf (hscr[HELP_DELETE].text, HELPTEXTSIZ,
- _("Delete an element in the ToDo or Appointment list.\n"
- "\nDepending on which panel is selected when you press the delete key,\n"
- "the hilighted item of either the ToDo or Appointment list will be \n"
- "removed from this list.\n"
- "\nIf the item to be deleted is recurrent, you will be asked if you\n"
- "wish to suppress all of the item occurences or just the one you\n"
- "selected.\n"
- "\nIf the general option 'confirm_delete' is set to 'YES', then you will"
- "\nbe asked for confirmation before deleting the selected event.\n"
- "Do not forget to save the calendar data to retrieve the modifications\n"
- "next time you launch Calcurse."));
+ snprintf(hscr[HELP_DELETE].text, HELPTEXTSIZ,
+ _("Delete an element in the ToDo or Appointment list.\n"
+ "\nDepending on which panel is selected when you press the delete key,\n"
+ "the hilighted item of either the ToDo or Appointment list will be \n"
+ "removed from this list.\n"
+ "\nIf the item to be deleted is recurrent, you will be asked if you\n"
+ "wish to suppress all of the item occurences or just the one you\n"
+ "selected.\n"
+ "\nIf the general option 'confirm_delete' is set to 'YES', then you will"
+ "\nbe asked for confirmation before deleting the selected event.\n"
+ "Do not forget to save the calendar data to retrieve the modifications\n"
+ "next time you launch Calcurse."));
hscr[HELP_ADD].title = _("Add\n");
- (void)snprintf (hscr[HELP_ADD].text, HELPTEXTSIZ,
- _("Add an item in either the ToDo or Appointment list, depending on which\n"
- "panel is selected when you press '%s'.\n"
- "\nTo enter a new item in the TODO list, you will need first to enter the"
- "\ndescription of this new item. Then you will be asked to specify the "
- "todo\npriority. This priority is represented by a number going from 9 "
- "for the\nlowest priority, to 1 for the highest one. It is still "
- "possible to\nchange the item priority afterwards, by using the '%s' and "
- "'%s' keys\ninside the todo panel.\n"
- "\nIf the APPOINTMENT panel is selected while pressing '%s', you will be\n"
- "able to enter either a new appointment or a new all-day long event.\n"
- "To enter a new event, press [ENTER] instead of the item start time, "
- "and\njust fill in the event description.\n"
- "To enter a new appointment to be added in the APPOINTMENT list, you\n"
- "will need to enter successively the time at which the appointment\n"
- "begins, the appointment length (either by specifying the duration in\n"
- "minutes, or the end time in [hh:mm] or [h:mm] format), and the\n"
- "description of the event.\n"
- "\nThe day at which occurs the event or appointment is the day currently"
- "\nselected in the calendar, so you need to move to the desired day "
- "before\npressing '%s'.\n" "\nNotes:\n"
- " o if an appointment lasts for such a long time that it continues\n"
- " on the next days, this event will be indicated on all the\n"
- " corresponding days, and the beginning or ending hour will be\n"
- " replaced by '..' if the event does not begin or end on the day.\n"
- " o if you only press [ENTER] at the APPOINTMENT or TODO event\n"
- " description prompt, without any description, no item will be\n"
- " added.\n"
- " o do not forget to save the calendar data to retrieve the new\n"
- " event next time you launch Calcurse."),
- keys_action_firstkey (KEY_ADD_ITEM),
- keys_action_firstkey (KEY_RAISE_PRIORITY),
- keys_action_firstkey (KEY_LOWER_PRIORITY),
- keys_action_firstkey (KEY_ADD_ITEM),
- keys_action_firstkey (KEY_ADD_ITEM));
+ snprintf(hscr[HELP_ADD].text, HELPTEXTSIZ,
+ _
+ ("Add an item in either the ToDo or Appointment list, depending on which\n"
+ "panel is selected when you press '%s'.\n"
+ "\nTo enter a new item in the TODO list, you will need first to enter the"
+ "\ndescription of this new item. Then you will be asked to specify the "
+ "todo\npriority. This priority is represented by a number going from 9 "
+ "for the\nlowest priority, to 1 for the highest one. It is still "
+ "possible to\nchange the item priority afterwards, by using the '%s' and "
+ "'%s' keys\ninside the todo panel.\n"
+ "\nIf the APPOINTMENT panel is selected while pressing '%s', you will be\n"
+ "able to enter either a new appointment or a new all-day long event.\n"
+ "To enter a new event, press [ENTER] instead of the item start time, "
+ "and\njust fill in the event description.\n"
+ "To enter a new appointment to be added in the APPOINTMENT list, you\n"
+ "will need to enter successively the time at which the appointment\n"
+ "begins, the appointment length (either by specifying the end time in\n"
+ "[hh:mm] or the duration in [+hh:mm], [+xxdxxhxxm] or [+mm] format), \n"
+ "and the description of the event.\n"
+ "\nThe day at which occurs the event or appointment is the day currently"
+ "\nselected in the calendar, so you need to move to the desired day "
+ "before\npressing '%s'.\n" "\nNotes:\n"
+ " o if an appointment lasts for such a long time that it continues\n"
+ " on the next days, this event will be indicated on all the\n"
+ " corresponding days, and the beginning or ending hour will be\n"
+ " replaced by '..' if the event does not begin or end on the day.\n"
+ " o if you only press [ENTER] at the APPOINTMENT or TODO event\n"
+ " description prompt, without any description, no item will be\n"
+ " added.\n"
+ " o do not forget to save the calendar data to retrieve the new\n"
+ " event next time you launch Calcurse."),
+ keys_action_firstkey(KEY_ADD_ITEM),
+ keys_action_firstkey(KEY_RAISE_PRIORITY),
+ keys_action_firstkey(KEY_LOWER_PRIORITY),
+ keys_action_firstkey(KEY_ADD_ITEM),
+ keys_action_firstkey(KEY_ADD_ITEM));
hscr[HELP_CUT_PASTE].title = _("Cut and Paste\n");
- (void)snprintf (hscr[HELP_CUT_PASTE].text, HELPTEXTSIZ,
- _("Cut and paste the currently selected item. This is useful to quickly\n"
- "move an item from one date to another.\n"
- "To do so, one must first highlight the item that needs to be moved,\n"
- "then press '%s' to cut this item. It will be removed from the panel.\n"
- "Once the new date is chosen in the calendar, the appointment panel must\n"
- "be selected and the '%s' key must be pressed to paste the item.\n"
- "The item will appear again in the appointment panel, assigned to the\n"
- "newly selected date.\n\n"
- "Be careful that if two cuts are performed successively without pasting\n"
- "between them, the item that was cut at first will be lost, together\n"
- "with its associated note if it had one."),
- keys_action_firstkey (KEY_GENERIC_CUT),
- keys_action_firstkey (KEY_GENERIC_PASTE));
+ snprintf(hscr[HELP_CUT_PASTE].text, HELPTEXTSIZ,
+ _
+ ("Cut and paste the currently selected item. This is useful to quickly\n"
+ "move an item from one date to another.\n"
+ "To do so, one must first highlight the item that needs to be moved,\n"
+ "then press '%s' to cut this item. It will be removed from the panel.\n"
+ "Once the new date is chosen in the calendar, the appointment panel must\n"
+ "be selected and the '%s' key must be pressed to paste the item.\n"
+ "The item will appear again in the appointment panel, assigned to the\n"
+ "newly selected date.\n\n"
+ "Be careful that if two cuts are performed successively without pasting\n"
+ "between them, the item that was cut at first will be lost, together\n"
+ "with its associated note if it had one."),
+ keys_action_firstkey(KEY_GENERIC_CUT),
+ keys_action_firstkey(KEY_GENERIC_PASTE));
hscr[HELP_EDIT].title = _("Edit Item\n");
- (void)snprintf (hscr[HELP_EDIT].text, HELPTEXTSIZ,
- _("Edit the item which is currently selected.\n"
- "Depending on the item type (appointment, event, or todo), and if it is\n"
- "repeated or not, you will be asked to choose one of the item properties"
- "\nto modify. An item property is one of the following: the start time, "
- "the\nend time, the description, or the item repetition.\n"
- "Once you have chosen the property you want to modify, you will be shown"
- "\nits actual value, and you will be able to change it as you like.\n"
- "\nNotes:\n"
- " o if you choose to edit the item repetition properties, you will\n"
- " be asked to re-enter all of the repetition characteristics\n"
- " (repetition type, frequence, and ending date). Moreover, the\n"
- " previous data concerning the deleted occurences will be lost.\n"
- " o do not forget to save the calendar data to retrieve the\n"
- " modified properties next time you launch Calcurse."));
+ snprintf(hscr[HELP_EDIT].text, HELPTEXTSIZ,
+ _("Edit the item which is currently selected.\n"
+ "Depending on the item type (appointment, event, or todo), and if it is\n"
+ "repeated or not, you will be asked to choose one of the item properties"
+ "\nto modify. An item property is one of the following: the start time, "
+ "the\nend time, the description, or the item repetition.\n"
+ "Once you have chosen the property you want to modify, you will be shown"
+ "\nits actual value, and you will be able to change it as you like.\n"
+ "\nNotes:\n"
+ " o if you choose to edit the item repetition properties, you will\n"
+ " be asked to re-enter all of the repetition characteristics\n"
+ " (repetition type, frequence, and ending date). Moreover, the\n"
+ " previous data concerning the deleted occurences will be lost.\n"
+ " o do not forget to save the calendar data to retrieve the\n"
+ " modified properties next time you launch Calcurse."));
hscr[HELP_ENOTE].title = _("EditNote\n");
- (void)snprintf (hscr[HELP_ENOTE].text, HELPTEXTSIZ,
- _("Attach a note to any type of item, or edit an already existing note.\n"
- "This feature is useful if you do not have enough space to store all\n"
- "of your item description, or if you would like to add sub-tasks to an\n"
- "already existing todo item for example.\n"
- "Before pressing the '%s' key, you first need to highlight the item you\n"
- "want the note to be attached to. Then you will be driven to an\n"
- "external editor to edit your note. This editor is chosen the following\n"
- "way:\n"
- " o if the 'VISUAL' environment variable is set, then this will be\n"
- " the default editor to be called.\n"
- " o if 'VISUAL' is not set, then the 'EDITOR' environment variable\n"
- " will be used as the default editor.\n"
- " o if none of the above environment variables is set, then\n"
- " '/usr/bin/vi' will be used.\n"
- "\nOnce the item note is edited and saved, quit your favorite editor.\n"
- "You will then go back to Calcurse, and the '>' sign will appear in front"
- "\nof the highlighted item, meaning there is a note attached to it."),
- keys_action_firstkey (KEY_EDIT_NOTE));
+ snprintf(hscr[HELP_ENOTE].text, HELPTEXTSIZ,
+ _
+ ("Attach a note to any type of item, or edit an already existing note.\n"
+ "This feature is useful if you do not have enough space to store all\n"
+ "of your item description, or if you would like to add sub-tasks to an\n"
+ "already existing todo item for example.\n"
+ "Before pressing the '%s' key, you first need to highlight the item you\n"
+ "want the note to be attached to. Then you will be driven to an\n"
+ "external editor to edit your note. This editor is chosen the following\n"
+ "way:\n"
+ " o if the 'VISUAL' environment variable is set, then this will be\n"
+ " the default editor to be called.\n"
+ " o if 'VISUAL' is not set, then the 'EDITOR' environment variable\n"
+ " will be used as the default editor.\n"
+ " o if none of the above environment variables is set, then\n"
+ " '/usr/bin/vi' will be used.\n"
+ "\nOnce the item note is edited and saved, quit your favorite editor.\n"
+ "You will then go back to Calcurse, and the '>' sign will appear in front"
+ "\nof the highlighted item, meaning there is a note attached to it."),
+ keys_action_firstkey(KEY_EDIT_NOTE));
hscr[HELP_VNOTE].title = _("ViewNote\n");
- (void)snprintf (hscr[HELP_VNOTE].text, HELPTEXTSIZ,
- _("View a note which was previously attached to an item (an item which\n"
- "owns a note has a '>' sign in front of it).\n"
- "This command only permits to view the note, not to edit it (to do so,\n"
- "use the 'EditNote' command, by pressing the '%s' key).\n"
- "Once you highlighted an item with a note attached to it, and the '%s' key"
- "\nwas pressed, you will be driven to an external pager to view that "
- "note.\n"
- "The default pager is chosen the following way:\n"
- " o if the 'PAGER' environment variable is set, then this will be\n"
- " the default viewer to be called.\n"
- " o if the above environment variable is not set, then\n"
- " '/usr/bin/less' will be used.\n"
- "As for editing a note, quit the pager and you will be driven back to\n"
- "Calcurse."),
- keys_action_firstkey (KEY_EDIT_NOTE),
- keys_action_firstkey (KEY_VIEW_NOTE));
+ snprintf(hscr[HELP_VNOTE].text, HELPTEXTSIZ,
+ _
+ ("View a note which was previously attached to an item (an item which\n"
+ "owns a note has a '>' sign in front of it).\n"
+ "This command only permits to view the note, not to edit it (to do so,\n"
+ "use the 'EditNote' command, by pressing the '%s' key).\n"
+ "Once you highlighted an item with a note attached to it, and the '%s' key"
+ "\nwas pressed, you will be driven to an external pager to view that "
+ "note.\n" "The default pager is chosen the following way:\n"
+ " o if the 'PAGER' environment variable is set, then this will be\n"
+ " the default viewer to be called.\n"
+ " o if the above environment variable is not set, then\n"
+ " '/usr/bin/less' will be used.\n"
+ "As for editing a note, quit the pager and you will be driven back to\n"
+ "Calcurse."), keys_action_firstkey(KEY_EDIT_NOTE),
+ keys_action_firstkey(KEY_VIEW_NOTE));
hscr[HELP_PRIORITY].title = _("Priority\n");
- (void)snprintf (hscr[HELP_PRIORITY].text, HELPTEXTSIZ,
- _("Change the priority of the currently selected item in the ToDo list.\n"
- "Priorities are represented by the number appearing in front of the\n"
- "todo description. This number goes from 9 for the lowest priority to\n"
- "1 for the highest priority.\n"
- "Todo having higher priorities are placed first (at the top) inside the\n"
- "todo panel.\n\n"
- "If you want to raise the priority of a todo item, you need to press "
- "'%s'.\n"
- "In doing so, the number in front of this item will decrease, "
- "meaning its\npriority increases. The item position inside the todo "
- "panel may change,\ndepending on the priority of the items above it.\n\n"
- "At the opposite, to lower a todo priority, press '%s'. The todo position"
- "\nmay also change depending on the priority of the items below."),
- keys_action_firstkey (KEY_RAISE_PRIORITY),
- keys_action_firstkey (KEY_LOWER_PRIORITY));
+ snprintf(hscr[HELP_PRIORITY].text, HELPTEXTSIZ,
+ _
+ ("Change the priority of the currently selected item in the ToDo list.\n"
+ "Priorities are represented by the number appearing in front of the\n"
+ "todo description. This number goes from 9 for the lowest priority to\n"
+ "1 for the highest priority.\n"
+ "Todo having higher priorities are placed first (at the top) inside the\n"
+ "todo panel.\n\n"
+ "If you want to raise the priority of a todo item, you need to press "
+ "'%s'.\n"
+ "In doing so, the number in front of this item will decrease, "
+ "meaning its\npriority increases. The item position inside the todo "
+ "panel may change,\ndepending on the priority of the items above it.\n\n"
+ "At the opposite, to lower a todo priority, press '%s'. The todo position"
+ "\nmay also change depending on the priority of the items below."),
+ keys_action_firstkey(KEY_RAISE_PRIORITY),
+ keys_action_firstkey(KEY_LOWER_PRIORITY));
hscr[HELP_REPEAT].title = _("Repeat\n");
- (void)snprintf (hscr[HELP_REPEAT].text, HELPTEXTSIZ,
- _("Repeat an event or an appointment.\n"
- "You must first select the item to be repeated by moving inside the\n"
- "appointment panel. Then pressing '%s' will lead you to a set of three\n"
- "questions, with which you will be able to specify the repetition\n"
- "characteristics:\n\n"
- " o type: you can choose between a daily, weekly, monthly or\n"
- " yearly repetition by pressing 'D', 'W', 'M' or 'Y'\n"
- " respectively.\n\n"
- " o frequence: this indicates how often the item shall be repeated.\n"
- " For example, if you want to remember an anniversary,\n"
- " choose a 'yearly' repetition with a frequence of '1',\n"
- " which means it must be repeated every year. Another\n"
- " example: if you go to the restaurant every two days,\n"
- " choose a 'daily' repetition with a frequence of '2'.\n\n"
- " o ending date: this specifies when to stop repeating the selected\n"
- " event or appointment. To indicate an endless \n"
- " repetition, enter '0' and the item will be repeated\n"
- " forever.\n" "\nNotes:\n"
- " o repeated items are marked with an '*' inside the appointment\n"
- " panel, to be easily recognizable from non-repeated ones.\n"
- " o the 'Repeat' and 'Delete' command can be mixed to create\n"
- " complicated configurations, as it is possible to delete only\n"
- " one occurence of a repeated item."),
- keys_action_firstkey (KEY_REPEAT_ITEM));
+ snprintf(hscr[HELP_REPEAT].text, HELPTEXTSIZ,
+ _("Repeat an event or an appointment.\n"
+ "You must first select the item to be repeated by moving inside the\n"
+ "appointment panel. Then pressing '%s' will lead you to a set of three\n"
+ "questions, with which you will be able to specify the repetition\n"
+ "characteristics:\n\n"
+ " o type: you can choose between a daily, weekly, monthly or\n"
+ " yearly repetition by pressing 'D', 'W', 'M' or 'Y'\n"
+ " respectively.\n\n"
+ " o frequence: this indicates how often the item shall be repeated.\n"
+ " For example, if you want to remember an anniversary,\n"
+ " choose a 'yearly' repetition with a frequence of '1',\n"
+ " which means it must be repeated every year. Another\n"
+ " example: if you go to the restaurant every two days,\n"
+ " choose a 'daily' repetition with a frequence of '2'.\n\n"
+ " o ending date: this specifies when to stop repeating the selected\n"
+ " event or appointment. To indicate an endless \n"
+ " repetition, enter '0' and the item will be repeated\n"
+ " forever.\n" "\nNotes:\n"
+ " o repeated items are marked with an '*' inside the appointment\n"
+ " panel, to be easily recognizable from non-repeated ones.\n"
+ " o the 'Repeat' and 'Delete' command can be mixed to create\n"
+ " complicated configurations, as it is possible to delete only\n"
+ " one occurence of a repeated item."),
+ keys_action_firstkey(KEY_REPEAT_ITEM));
hscr[HELP_FLAG].title = _("Flag Item\n");
- (void)snprintf (hscr[HELP_FLAG].text, HELPTEXTSIZ,
- _("Toggle an appointment's 'important' flag or a todo's 'completed' flag.\n"
- "If a todo is flagged as completed, its priority number will be replaced\n"
- "by an 'X' sign. Completed tasks will no longer appear in exported data\n"
- "or when using the '-t' command line flag (unless specifying '0' as the\n"
- "priority number, in which case only completed tasks will be shown).\n\n"
- "If an appointment is flagged as important, an exclamation mark appears\n"
- "in front of it, and you will be warned if time gets closed to the\n"
- "appointment start time.\n"
- "To customize the way one gets notified, the configuration submenu lets\n"
- "you choose the command launched to warn user of an upcoming appointment,"
- "\nand how long before it he gets notified."));
+ snprintf(hscr[HELP_FLAG].text, HELPTEXTSIZ,
+ _
+ ("Toggle an appointment's 'important' flag or a todo's 'completed' flag.\n"
+ "If a todo is flagged as completed, its priority number will be replaced\n"
+ "by an 'X' sign. Completed tasks will no longer appear in exported data\n"
+ "or when using the '-t' command line flag (unless specifying '0' as the\n"
+ "priority number, in which case only completed tasks will be shown).\n\n"
+ "If an appointment is flagged as important, an exclamation mark appears\n"
+ "in front of it, and you will be warned if time gets closed to the\n"
+ "appointment start time.\n"
+ "To customize the way one gets notified, the configuration submenu lets\n"
+ "you choose the command launched to warn user of an upcoming appointment,"
+ "\nand how long before it he gets notified."));
hscr[HELP_CONFIG].title = _("Config\n");
- (void)snprintf (hscr[HELP_CONFIG].text, HELPTEXTSIZ,
- _("Open the configuration submenu.\n"
- "From this submenu, you can select between color, layout, notification\n"
- "and general options, and you can also configure your keybindings.\n"
- "\nThe color submenu lets you choose the color theme.\n"
- "The layout submenu lets you choose the Calcurse screen layout, in other"
- "\nwords where to place the three different panels on the screen.\n"
- "The general options submenu brings a screen with the different options"
- "\nwhich modifies the way Calcurse interacts with the user.\n"
- "The notify submenu allows you to change the notify-bar settings.\n"
- "The keys submenu lets you define your own key bindings.\n"
- "\nDo not forget to save the calendar data to retrieve your configuration"
- "\nnext time you launch Calcurse."));
+ snprintf(hscr[HELP_CONFIG].text, HELPTEXTSIZ,
+ _("Open the configuration submenu.\n"
+ "From this submenu, you can select between color, layout, notification\n"
+ "and general options, and you can also configure your keybindings.\n"
+ "\nThe color submenu lets you choose the color theme.\n"
+ "The layout submenu lets you choose the Calcurse screen layout, in other"
+ "\nwords where to place the three different panels on the screen.\n"
+ "The general options submenu brings a screen with the different options"
+ "\nwhich modifies the way Calcurse interacts with the user.\n"
+ "The notify submenu allows you to change the notify-bar settings.\n"
+ "The keys submenu lets you define your own key bindings.\n"
+ "\nDo not forget to save the calendar data to retrieve your configuration"
+ "\nnext time you launch Calcurse."));
hscr[HELP_GENERAL].title = _("Generic keybindings\n");
- (void)snprintf (hscr[HELP_GENERAL].text, HELPTEXTSIZ,
- _("Some of the keybindings apply whatever panel is selected. They are\n"
- "called generic keybinding.\n"
- "Here is the list of all the generic key bindings, together with their\n"
- "corresponding action:\n\n"
- " '%s' : Redraw function -> redraws calcurse panels, this is useful if\n"
- " you resize your terminal screen or when\n"
- " garbage appears inside the display\n"
- " '%s' : Add Appointment -> add an appointment or an event\n"
- " '%s' : Add ToDo -> add a todo\n"
- " '%s' : -1 Day -> move to previous day\n"
- " '%s' : +1 Day -> move to next day\n"
- " '%s' : -1 Week -> move to previous week\n"
- " '%s' : +1 Week -> move to next week\n"
- " '%s' : Goto today -> move to current day\n"
- "\nThe '%s' and '%s' keys are used to scroll text upward or downward\n"
- "when inside specific screens such the help screens for example.\n"
- "They are also used when the calendar screen is selected to switch\n"
- "between the available views (monthly and weekly calendar views)."),
- keys_action_firstkey (KEY_GENERIC_REDRAW),
- keys_action_firstkey (KEY_GENERIC_ADD_APPT),
- keys_action_firstkey (KEY_GENERIC_ADD_TODO),
- keys_action_firstkey (KEY_GENERIC_PREV_DAY),
- keys_action_firstkey (KEY_GENERIC_NEXT_DAY),
- keys_action_firstkey (KEY_GENERIC_PREV_WEEK),
- keys_action_firstkey (KEY_GENERIC_NEXT_WEEK),
- keys_action_firstkey (KEY_GENERIC_GOTO_TODAY),
- keys_action_firstkey (KEY_GENERIC_SCROLL_UP),
- keys_action_firstkey (KEY_GENERIC_SCROLL_DOWN));
+ snprintf(hscr[HELP_GENERAL].text, HELPTEXTSIZ,
+ _
+ ("Some of the keybindings apply whatever panel is selected. They are\n"
+ "called generic keybinding.\n"
+ "Here is the list of all the generic key bindings, together with their\n"
+ "corresponding action:\n\n"
+ " '%s' : Redraw function -> redraws calcurse panels, this is useful if\n"
+ " you resize your terminal screen or when\n"
+ " garbage appears inside the display\n"
+ " '%s' : Add Appointment -> add an appointment or an event\n"
+ " '%s' : Add ToDo -> add a todo\n"
+ " '%s' : -1 Day -> move to previous day\n"
+ " '%s' : +1 Day -> move to next day\n"
+ " '%s' : -1 Week -> move to previous week\n"
+ " '%s' : +1 Week -> move to next week\n"
+ " '%s' : Goto today -> move to current day\n"
+ "\nThe '%s' and '%s' keys are used to scroll text upward or downward\n"
+ "when inside specific screens such the help screens for example.\n"
+ "They are also used when the calendar screen is selected to switch\n"
+ "between the available views (monthly and weekly calendar views)."),
+ keys_action_firstkey(KEY_GENERIC_REDRAW),
+ keys_action_firstkey(KEY_GENERIC_ADD_APPT),
+ keys_action_firstkey(KEY_GENERIC_ADD_TODO),
+ keys_action_firstkey(KEY_GENERIC_PREV_DAY),
+ keys_action_firstkey(KEY_GENERIC_NEXT_DAY),
+ keys_action_firstkey(KEY_GENERIC_PREV_WEEK),
+ keys_action_firstkey(KEY_GENERIC_NEXT_WEEK),
+ keys_action_firstkey(KEY_GENERIC_GOTO_TODAY),
+ keys_action_firstkey(KEY_GENERIC_SCROLL_UP),
+ keys_action_firstkey(KEY_GENERIC_SCROLL_DOWN));
hscr[HELP_OTHER].title = _("OtherCmd\n");
- (void)snprintf (hscr[HELP_OTHER].text, HELPTEXTSIZ,
- _("Switch between status bar help pages.\n"
- "Because the terminal screen is too narrow to display all of the\n"
- "available commands, you need to press '%s' to see the next set of\n"
- "commands together with their keybindings.\n"
- "Once the last status bar page is reached, pressing '%s' another time\n"
- "leads you back to the first page."),
- keys_action_firstkey (KEY_GENERIC_OTHER_CMD),
- keys_action_firstkey (KEY_GENERIC_OTHER_CMD));
+ snprintf(hscr[HELP_OTHER].text, HELPTEXTSIZ,
+ _("Switch between status bar help pages.\n"
+ "Because the terminal screen is too narrow to display all of the\n"
+ "available commands, you need to press '%s' to see the next set of\n"
+ "commands together with their keybindings.\n"
+ "Once the last status bar page is reached, pressing '%s' another time\n"
+ "leads you back to the first page."),
+ keys_action_firstkey(KEY_GENERIC_OTHER_CMD),
+ keys_action_firstkey(KEY_GENERIC_OTHER_CMD));
hscr[HELP_CREDITS].title = _("Calcurse - text-based organizer");
- (void)snprintf (hscr[HELP_CREDITS].text, HELPTEXTSIZ,
- _("\nCopyright (c) 2004-2011 calcurse Development Team\n"
- "All rights reserved.\n"
- "\n"
- "Redistribution and use in source and binary forms, with or without\n"
- "modification, are permitted provided that the following conditions\n"
- "are met:\n"
- "\n"
- "\t- Redistributions of source code must retain the above\n"
- "\t copyright notice, this list of conditions and the\n"
- "\t following disclaimer.\n"
- "\n"
- "\t- Redistributions in binary form must reproduce the above\n"
- "\t copyright notice, this list of conditions and the\n"
- "\t following disclaimer in the documentation and/or other\n"
- "\t materials provided with the distribution.\n"
- "\n\n"
- "Send your feedback or comments to : misc@calcurse.org\n"
- "Calcurse home page : http://calcurse.org"));
-
- help_wins_init (&hwin, 0, 0, (notify_bar ()) ? row - 3 : row - 2, col);
+ snprintf(hscr[HELP_CREDITS].text, HELPTEXTSIZ,
+ _("\nCopyright (c) 2004-2012 calcurse Development Team\n"
+ "All rights reserved.\n"
+ "\n"
+ "Redistribution and use in source and binary forms, with or without\n"
+ "modification, are permitted provided that the following conditions\n"
+ "are met:\n"
+ "\n"
+ "\t- Redistributions of source code must retain the above\n"
+ "\t copyright notice, this list of conditions and the\n"
+ "\t following disclaimer.\n"
+ "\n"
+ "\t- Redistributions in binary form must reproduce the above\n"
+ "\t copyright notice, this list of conditions and the\n"
+ "\t following disclaimer in the documentation and/or other\n"
+ "\t materials provided with the distribution.\n"
+ "\n\n"
+ "Send your feedback or comments to : misc@calcurse.org\n"
+ "Calcurse home page : http://calcurse.org"));
+
+ help_wins_init(&hwin, 0, 0, (notify_bar())? row - 3 : row - 2, col);
oldpage = HELP_MAIN;
need_resize = 0;
/* Display the help screen related to user input. */
- while (ch != KEY_GENERIC_QUIT)
- {
- erase_window_part (hwin.win.p, 1, hwin.pad.y, col - 2,
- hwin.win.h - 2);
-
- switch (ch) {
- case KEY_GENERIC_SCROLL_DOWN:
- wins_scrollwin_down (&hwin, 1);
- break;
-
- case KEY_GENERIC_SCROLL_UP:
- wins_scrollwin_up (&hwin, 1);
- break;
-
- default:
- page = wanted_page (ch);
- if (page != NOPAGE) {
- hwin.first_visible_line = 0;
- hwin.total_lines = help_write_pad (&hwin.pad, hscr[page].title,
- hscr[page].text, ch);
- oldpage = page;
- }
+ while (ch != KEY_GENERIC_QUIT) {
+ erase_window_part(hwin.win.p, 1, hwin.pad.y, col - 2, hwin.win.h - 2);
+
+ switch (ch) {
+ case KEY_GENERIC_SCROLL_DOWN:
+ wins_scrollwin_down(&hwin, 1);
+ break;
+
+ case KEY_GENERIC_SCROLL_UP:
+ wins_scrollwin_up(&hwin, 1);
+ break;
+
+ default:
+ page = wanted_page(ch);
+ if (page != NOPAGE) {
+ hwin.first_visible_line = 0;
+ hwin.total_lines = help_write_pad(&hwin.pad, hscr[page].title,
+ hscr[page].text, ch);
+ oldpage = page;
}
+ }
- if (resize)
- {
- resize = 0;
- wins_get_config ();
- help_wins_reset (&hwin);
- hwin.first_visible_line = 0;
- hwin.total_lines = help_write_pad (&hwin.pad, hscr[oldpage].title,
- hscr[oldpage].text, ch);
- need_resize = 1;
- }
-
- wins_scrollwin_display (&hwin);
- ch = keys_getch (win[STA].p);
+ if (resize) {
+ resize = 0;
+ wins_get_config();
+ help_wins_reset(&hwin);
+ hwin.first_visible_line = 0;
+ hwin.total_lines = help_write_pad(&hwin.pad, hscr[oldpage].title,
+ hscr[oldpage].text, ch);
+ need_resize = 1;
}
- wins_scrollwin_delete (&hwin);
+
+ wins_scrollwin_display(&hwin);
+ ch = keys_getch(win[STA].p, NULL);
+ }
+ wins_scrollwin_delete(&hwin);
if (need_resize)
- wins_reset ();
+ wins_reset();
}
diff --git a/src/htable.h b/src/htable.h
index 10d04c1..3bde5ef 100644
--- a/src/htable.h
+++ b/src/htable.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004-2011 calcurse Development Team <misc@calcurse.org>
+ * Copyright (c) 2004-2012 calcurse Development Team <misc@calcurse.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -69,9 +69,7 @@ struct name { \
}
#define HTABLE_ENTRY(type) \
-struct { \
- struct type *next; /* To build the bucket chain list. */ \
-}
+struct type *next /* To build the bucket chain list. */
#define HTABLE_SIZE(head) \
(sizeof (*(head)->bkts) ? sizeof ((head)->bkts) / sizeof (*(head)->bkts) : 0)
@@ -106,7 +104,11 @@ struct { \
#define HTABLE_PROTOTYPE(name, type) \
struct type *name##_HTABLE_INSERT(struct name *, struct type *); \
struct type *name##_HTABLE_REMOVE(struct name *, struct type *); \
-struct type *name##_HTABLE_LOOKUP(struct name *, struct type *);
+struct type *name##_HTABLE_LOOKUP(struct name *, struct type *); \
+uint32_t name##_HTABLE_FIND_BKT(struct name *, struct type *); \
+int name##_HTABLE_CHAIN_LEN(struct name *, uint32_t); \
+struct type *name##_HTABLE_FIRST_FROM(struct name *, int); \
+struct type *name##_HTABLE_NEXT(struct name *, struct type *);
/*
* Generate function bodies.
@@ -116,7 +118,7 @@ uint32_t \
name##_HTABLE_FIND_BKT(struct name *head, struct type *elm) \
{ \
uint32_t __bkt; \
- char *__key; \
+ const char *__key; \
int __len; \
\
(key) (elm, &__key, &__len); \
diff --git a/src/ical.c b/src/ical.c
new file mode 100644
index 0000000..ca10865
--- /dev/null
+++ b/src/ical.c
@@ -0,0 +1,1090 @@
+/*
+ * Calcurse - text-based organizer
+ *
+ * Copyright (c) 2004-2012 calcurse Development Team <misc@calcurse.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Send your feedback or comments to : misc@calcurse.org
+ * Calcurse home page : http://calcurse.org
+ *
+ */
+
+#include <sys/types.h>
+
+#include "calcurse.h"
+
+#define ICALDATEFMT "%Y%m%d"
+#define ICALDATETIMEFMT "%Y%m%dT%H%M%S"
+
+typedef enum {
+ ICAL_VEVENT,
+ ICAL_VTODO,
+ ICAL_TYPES
+} ical_types_e;
+
+typedef enum {
+ UNDEFINED,
+ APPOINTMENT,
+ EVENT
+} ical_vevent_e;
+
+typedef struct {
+ enum recur_type type;
+ int freq;
+ long until;
+ unsigned count;
+} ical_rpt_t;
+
+static void ical_export_header(FILE *);
+static void ical_export_recur_events(FILE *);
+static void ical_export_events(FILE *);
+static void ical_export_recur_apoints(FILE *);
+static void ical_export_apoints(FILE *);
+static void ical_export_todo(FILE *);
+static void ical_export_footer(FILE *);
+
+static const char *ical_recur_type[RECUR_TYPES] =
+ { "", "DAILY", "WEEKLY", "MONTHLY", "YEARLY" };
+
+/* iCal alarm notification. */
+static void ical_export_valarm(FILE * stream)
+{
+ fputs("BEGIN:VALARM\n", stream);
+ pthread_mutex_lock(&nbar.mutex);
+ fprintf(stream, "TRIGGER:-P%dS\n", nbar.cntdwn);
+ pthread_mutex_unlock(&nbar.mutex);
+ fputs("ACTION:DISPLAY\n", stream);
+ fputs("END:VALARM\n", stream);
+}
+
+/* Export header. */
+static void ical_export_header(FILE * stream)
+{
+ fputs("BEGIN:VCALENDAR\n", stream);
+ fprintf(stream, "PRODID:-//calcurse//NONSGML v%s//EN\n", VERSION);
+ fputs("VERSION:2.0\n", stream);
+}
+
+/* Export footer. */
+static void ical_export_footer(FILE * stream)
+{
+ fputs("END:VCALENDAR\n", stream);
+}
+
+/* Export recurrent events. */
+static void ical_export_recur_events(FILE * stream)
+{
+ llist_item_t *i, *j;
+ char ical_date[BUFSIZ];
+
+ LLIST_FOREACH(&recur_elist, i) {
+ struct recur_event *rev = LLIST_GET_DATA(i);
+ date_sec2date_fmt(rev->day, ICALDATEFMT, ical_date);
+ fputs("BEGIN:VEVENT\n", stream);
+ fprintf(stream, "DTSTART:%s\n", ical_date);
+ fprintf(stream, "RRULE:FREQ=%s;INTERVAL=%d",
+ ical_recur_type[rev->rpt->type], rev->rpt->freq);
+
+ if (rev->rpt->until != 0) {
+ date_sec2date_fmt(rev->rpt->until, ICALDATEFMT, ical_date);
+ fprintf(stream, ";UNTIL=%s\n", ical_date);
+ } else
+ fputc('\n', stream);
+
+ if (LLIST_FIRST(&rev->exc)) {
+ fputs("EXDATE:", stream);
+ LLIST_FOREACH(&rev->exc, j) {
+ struct excp *exc = LLIST_GET_DATA(j);
+ date_sec2date_fmt(exc->st, ICALDATEFMT, ical_date);
+ fprintf(stream, "%s", ical_date);
+ if (LLIST_NEXT(j))
+ fputc(',', stream);
+ else
+ fputc('\n', stream);
+ }
+ }
+
+ fprintf(stream, "SUMMARY:%s\n", rev->mesg);
+ fputs("END:VEVENT\n", stream);
+ }
+}
+
+/* Export events. */
+static void ical_export_events(FILE * stream)
+{
+ llist_item_t *i;
+ char ical_date[BUFSIZ];
+
+ LLIST_FOREACH(&eventlist, i) {
+ struct event *ev = LLIST_TS_GET_DATA(i);
+ date_sec2date_fmt(ev->day, ICALDATEFMT, ical_date);
+ fputs("BEGIN:VEVENT\n", stream);
+ fprintf(stream, "DTSTART:%s\n", ical_date);
+ fprintf(stream, "SUMMARY:%s\n", ev->mesg);
+ fputs("END:VEVENT\n", stream);
+ }
+}
+
+/* Export recurrent appointments. */
+static void ical_export_recur_apoints(FILE * stream)
+{
+ llist_item_t *i, *j;
+ char ical_datetime[BUFSIZ];
+ char ical_date[BUFSIZ];
+
+ LLIST_TS_LOCK(&recur_alist_p);
+ LLIST_TS_FOREACH(&recur_alist_p, i) {
+ struct recur_apoint *rapt = LLIST_TS_GET_DATA(i);
+
+ date_sec2date_fmt(rapt->start, ICALDATETIMEFMT, ical_datetime);
+ fputs("BEGIN:VEVENT\n", stream);
+ fprintf(stream, "DTSTART:%s\n", ical_datetime);
+ fprintf(stream, "DURATION:PT0H0M%ldS\n", rapt->dur);
+ fprintf(stream, "RRULE:FREQ=%s;INTERVAL=%d",
+ ical_recur_type[rapt->rpt->type], rapt->rpt->freq);
+
+ if (rapt->rpt->until != 0) {
+ date_sec2date_fmt(rapt->rpt->until + HOURINSEC, ICALDATEFMT, ical_date);
+ fprintf(stream, ";UNTIL=%s\n", ical_date);
+ } else
+ fputc('\n', stream);
+
+ if (LLIST_FIRST(&rapt->exc)) {
+ fputs("EXDATE:", stream);
+ LLIST_FOREACH(&rapt->exc, j) {
+ struct excp *exc = LLIST_GET_DATA(j);
+ date_sec2date_fmt(exc->st, ICALDATEFMT, ical_date);
+ fprintf(stream, "%s", ical_date);
+ if (LLIST_NEXT(j))
+ fputc(',', stream);
+ else
+ fputc('\n', stream);
+ }
+ }
+
+ fprintf(stream, "SUMMARY:%s\n", rapt->mesg);
+ if (rapt->state & APOINT_NOTIFY)
+ ical_export_valarm(stream);
+ fputs("END:VEVENT\n", stream);
+ }
+ LLIST_TS_UNLOCK(&recur_alist_p);
+}
+
+/* Export appointments. */
+static void ical_export_apoints(FILE * stream)
+{
+ llist_item_t *i;
+ char ical_datetime[BUFSIZ];
+
+ LLIST_TS_LOCK(&alist_p);
+ LLIST_TS_FOREACH(&alist_p, i) {
+ struct apoint *apt = LLIST_TS_GET_DATA(i);
+ date_sec2date_fmt(apt->start, ICALDATETIMEFMT, ical_datetime);
+ fputs("BEGIN:VEVENT\n", stream);
+ fprintf(stream, "DTSTART:%s\n", ical_datetime);
+ fprintf(stream, "DURATION:P%ldDT%ldH%ldM%ldS\n",
+ apt->dur / DAYINSEC,
+ (apt->dur / HOURINSEC) % DAYINHOURS,
+ (apt->dur / MININSEC) % HOURINMIN, apt->dur % MININSEC);
+ fprintf(stream, "SUMMARY:%s\n", apt->mesg);
+ if (apt->state & APOINT_NOTIFY)
+ ical_export_valarm(stream);
+ fputs("END:VEVENT\n", stream);
+ }
+ LLIST_TS_UNLOCK(&alist_p);
+}
+
+/* Export todo items. */
+static void ical_export_todo(FILE * stream)
+{
+ llist_item_t *i;
+
+ LLIST_FOREACH(&todolist, i) {
+ struct todo *todo = LLIST_TS_GET_DATA(i);
+ if (todo->id < 0) /* completed items */
+ continue;
+
+ fputs("BEGIN:VTODO\n", stream);
+ fprintf(stream, "PRIORITY:%d\n", todo->id);
+ fprintf(stream, "SUMMARY:%s\n", todo->mesg);
+ fputs("END:VTODO\n", stream);
+ }
+}
+
+/* Print a header to describe import log report format. */
+static void ical_log_init(FILE * log, float version)
+{
+ const char *header =
+ "+-------------------------------------------------------------------+\n"
+ "| Calcurse icalendar import log. |\n"
+ "| |\n"
+ "| Items imported from icalendar file, version %1.1f |\n"
+ "| Some items could not be imported, they are described hereafter. |\n"
+ "| The log line format is as follows: |\n"
+ "| |\n"
+ "| TYPE [LINE]: DESCRIPTION |\n"
+ "| |\n"
+ "| where: |\n"
+ "| * TYPE represents the item type ('VEVENT' or 'VTODO') |\n"
+ "| * LINE is the line in the input stream at which this item begins |\n"
+ "| * DESCRIPTION indicates why the item could not be imported |\n"
+ "+-------------------------------------------------------------------+\n\n";
+
+ if (log)
+ fprintf(log, header, version);
+}
+
+/*
+ * Used to build a report of the import process.
+ * The icalendar item for which a problem occurs is mentioned (by giving its
+ * first line inside the icalendar file), together with a message describing the
+ * problem.
+ */
+static void ical_log(FILE * log, ical_types_e type, unsigned lineno, char *msg)
+{
+ const char *typestr[ICAL_TYPES] = { "VEVENT", "VTODO" };
+
+ RETURN_IF(type < 0 || type >= ICAL_TYPES, _("unknown ical type"));
+ if (log)
+ fprintf(log, "%s [%d]: %s\n", typestr[type], lineno, msg);
+}
+
+static void ical_store_todo(int priority, char *mesg, char *note)
+{
+ todo_add(mesg, priority, note);
+ mem_free(mesg);
+ erase_note(&note);
+}
+
+static void
+ical_store_event(char *mesg, char *note, long day, long end, ical_rpt_t * rpt,
+ llist_t * exc)
+{
+ const int EVENTID = 1;
+
+ if (rpt) {
+ recur_event_new(mesg, note, day, EVENTID, rpt->type, rpt->freq,
+ rpt->until, exc);
+ mem_free(rpt);
+ } else if (end && end != day) {
+ /* Here we have an event that spans over several days. */
+ rpt = mem_malloc(sizeof(ical_rpt_t));
+ rpt->type = RECUR_DAILY;
+ rpt->freq = 1;
+ rpt->count = 0;
+ rpt->until = end;
+ recur_event_new(mesg, note, day, EVENTID, rpt->type, rpt->freq,
+ rpt->until, exc);
+ mem_free(rpt);
+ } else {
+ event_new(mesg, note, day, EVENTID);
+ }
+ mem_free(mesg);
+ erase_note(&note);
+}
+
+static void
+ical_store_apoint(char *mesg, char *note, long start, long dur,
+ ical_rpt_t * rpt, llist_t * exc, int has_alarm)
+{
+ char state = 0L;
+
+ if (has_alarm)
+ state |= APOINT_NOTIFY;
+ if (rpt) {
+ recur_apoint_new(mesg, note, start, dur, state, rpt->type, rpt->freq,
+ rpt->until, exc);
+ mem_free(rpt);
+ } else {
+ apoint_new(mesg, note, start, dur, state);
+ }
+ mem_free(mesg);
+ erase_note(&note);
+}
+
+/*
+ * Returns an allocated string representing the string given in argument once
+ * unformatted.
+ *
+ * Note:
+ * Even if the RFC2445 recommends not to have more than 75 octets on one line of
+ * text, I prefer not to restrict the parsing to this size, thus I use a buffer
+ * of size BUFSIZ.
+ *
+ * Extract from RFC2445:
+ * Lines of text SHOULD NOT be longer than 75 octets, excluding the line
+ * break.
+ */
+static char *ical_unformat_line(char *line)
+{
+ char *p, uline[BUFSIZ];
+ int len;
+
+ if (strlen(line) >= BUFSIZ)
+ return NULL;
+
+ memset(uline, 0, BUFSIZ);
+ for (len = 0, p = line; *p; p++) {
+ switch (*p) {
+ case '\\':
+ switch (*(p + 1)) {
+ case 'n':
+ uline[len++] = '\n';
+ p++;
+ break;
+ case 't':
+ uline[len++] = '\t';
+ p++;
+ break;
+ case ';':
+ case ':':
+ case ',':
+ uline[len++] = *(p + 1);
+ p++;
+ break;
+ default:
+ uline[len++] = *p;
+ break;
+ }
+ break;
+ default:
+ uline[len++] = *p;
+ break;
+ }
+ }
+
+ return mem_strdup(uline);
+}
+
+static void
+ical_readline_init(FILE * fdi, char *buf, char *lstore, unsigned *ln)
+{
+ char *eol;
+
+ *buf = *lstore = '\0';
+ if (fgets(lstore, BUFSIZ, fdi)) {
+ if ((eol = strchr(lstore, '\n')) != NULL)
+ *eol = '\0';
+ (*ln)++;
+ }
+}
+
+static int ical_readline(FILE * fdi, char *buf, char *lstore, unsigned *ln)
+{
+ char *eol;
+
+ strncpy(buf, lstore, BUFSIZ);
+ (*ln)++;
+
+ while (fgets(lstore, BUFSIZ, fdi) != NULL) {
+ if ((eol = strchr(lstore, '\n')) != NULL)
+ *eol = '\0';
+ if (*lstore != SPACE && *lstore != TAB)
+ break;
+ strncat(buf, lstore + 1, BUFSIZ - strlen(buf) - 1);
+ (*ln)++;
+ }
+
+ if (feof(fdi)) {
+ *lstore = '\0';
+ if (*buf == '\0')
+ return 0;
+ }
+
+ return 1;
+}
+
+static float
+ical_chk_header(FILE * fd, char *buf, char *lstore, unsigned *lineno)
+{
+ const int HEADER_MALFORMED = -1;
+ const char icalheader[] = "BEGIN:VCALENDAR";
+ float version;
+
+ if (!ical_readline(fd, buf, lstore, lineno))
+ return HEADER_MALFORMED;
+
+ str_toupper(buf);
+ if (strncmp(buf, icalheader, sizeof(icalheader) - 1) != 0)
+ return HEADER_MALFORMED;
+
+ while (!sscanf(buf, "VERSION:%f", &version)) {
+ if (!ical_readline(fd, buf, lstore, lineno))
+ return HEADER_MALFORMED;
+ }
+ return version;
+}
+
+/*
+ * iCalendar date-time format is based on the ISO 8601 complete
+ * representation. It should be something like : DATE 'T' TIME
+ * where DATE is 'YYYYMMDD' and TIME is 'HHMMSS'.
+ * The time and 'T' separator are optional (in the case of an day-long event).
+ *
+ * Optionnaly, if the type pointer is given, specify if it is an event
+ * (no time is given, meaning it is an all-day event), or an appointment
+ * (time is given).
+ *
+ * The timezone is not yet handled by calcurse.
+ */
+static long ical_datetime2long(char *datestr, ical_vevent_e * type)
+{
+ const int NOTFOUND = 0, FORMAT_DATE = 3, FORMAT_DATETIME = 5;
+ struct date date;
+ unsigned hour, min;
+ long datelong;
+ int format;
+
+ format = sscanf(datestr, "%04u%02u%02uT%02u%02u",
+ &date.yyyy, &date.mm, &date.dd, &hour, &min);
+ if (format == FORMAT_DATE) {
+ if (type)
+ *type = EVENT;
+ datelong = date2sec(date, 0, 0);
+ } else if (format == FORMAT_DATETIME) {
+ if (type)
+ *type = APPOINTMENT;
+ datelong = date2sec(date, hour, min);
+ } else {
+ datelong = NOTFOUND;
+ }
+ return datelong;
+}
+
+static long ical_durtime2long(char *timestr)
+{
+ long timelong;
+ char *p;
+
+ if ((p = strchr(timestr, 'T')) == NULL)
+ timelong = 0;
+ else {
+ int nbmatch;
+ struct {
+ unsigned hour, min, sec;
+ } time;
+
+ p++;
+ memset(&time, 0, sizeof time);
+ nbmatch = sscanf(p, "%uH%uM%uS", &time.hour, &time.min, &time.sec);
+ if (nbmatch < 1 || nbmatch > 3)
+ timelong = 0;
+ else
+ timelong = time.hour * HOURINSEC + time.min * MININSEC + time.sec;
+ }
+ return timelong;
+}
+
+/*
+ * Extract from RFC2445:
+ *
+ * Value Name: DURATION
+ *
+ * Purpose: This value type is used to identify properties that contain
+ * duration of time.
+ *
+ * Formal Definition: The value type is defined by the following
+ * notation:
+ *
+ * dur-value = (["+"] / "-") "P" (dur-date / dur-time / dur-week)
+ * dur-date = dur-day [dur-time]
+ * dur-time = "T" (dur-hour / dur-minute / dur-second)
+ * dur-week = 1*DIGIT "W"
+ * dur-hour = 1*DIGIT "H" [dur-minute]
+ * dur-minute = 1*DIGIT "M" [dur-second]
+ * dur-second = 1*DIGIT "S"
+ * dur-day = 1*DIGIT "D"
+ *
+ * Example: A duration of 15 days, 5 hours and 20 seconds would be:
+ * P15DT5H0M20S
+ * A duration of 7 weeks would be:
+ * P7W
+ */
+static long ical_dur2long(char *durstr)
+{
+ const int NOTFOUND = -1;
+ long durlong;
+ char *p;
+ struct {
+ unsigned week, day;
+ } date;
+
+ memset(&date, 0, sizeof date);
+ if ((p = strchr(durstr, 'P')) == NULL)
+ durlong = NOTFOUND;
+ else {
+ p++;
+ if (*p == '-')
+ return NOTFOUND;
+ else if (*p == '+')
+ p++;
+
+ if (*p == 'T') /* dur-time */
+ durlong = ical_durtime2long(p);
+ else if (strchr(p, 'W')) { /* dur-week */
+ if (sscanf(p, "%u", &date.week) == 1)
+ durlong = date.week * WEEKINDAYS * DAYINSEC;
+ else
+ durlong = NOTFOUND;
+ } else {
+ if (strchr(p, 'D')) { /* dur-date */
+ if (sscanf(p, "%uD", &date.day) == 1) {
+ durlong = date.day * DAYINSEC;
+ durlong += ical_durtime2long(p);
+ } else
+ durlong = NOTFOUND;
+ } else
+ durlong = NOTFOUND;
+ }
+ }
+ return durlong;
+}
+
+/*
+ * Compute the vevent repetition end date from the repetition count.
+ *
+ * Extract from RFC2445:
+ * The COUNT rule part defines the number of occurrences at which to
+ * range-bound the recurrence. The "DTSTART" property value, if specified,
+ * counts as the first occurrence.
+ */
+static long ical_compute_rpt_until(long start, ical_rpt_t * rpt)
+{
+ long until;
+
+ switch (rpt->type) {
+ case RECUR_DAILY:
+ until = date_sec_change(start, 0, rpt->freq * (rpt->count - 1));
+ break;
+ case RECUR_WEEKLY:
+ until = date_sec_change(start, 0,
+ rpt->freq * WEEKINDAYS * (rpt->count - 1));
+ break;
+ case RECUR_MONTHLY:
+ until = date_sec_change(start, rpt->freq * (rpt->count - 1), 0);
+ break;
+ case RECUR_YEARLY:
+ until = date_sec_change(start, rpt->freq * 12 * (rpt->count - 1), 0);
+ break;
+ default:
+ until = 0;
+ break;
+ /* NOTREACHED */
+ }
+ return until;
+}
+
+/*
+ * Read a recurrence rule from an iCalendar RRULE string.
+ *
+ * Value Name: RECUR
+ *
+ * Purpose: This value type is used to identify properties that contain
+ * a recurrence rule specification.
+ *
+ * Formal Definition: The value type is defined by the following
+ * notation:
+ *
+ * recur = "FREQ"=freq *(
+ *
+ * ; either UNTIL or COUNT may appear in a 'recur',
+ * ; but UNTIL and COUNT MUST NOT occur in the same 'recur'
+ *
+ * ( ";" "UNTIL" "=" enddate ) /
+ * ( ";" "COUNT" "=" 1*DIGIT ) /
+ *
+ * ; the rest of these keywords are optional,
+ * ; but MUST NOT occur more than
+ * ; once
+ *
+ * ( ";" "INTERVAL" "=" 1*DIGIT ) /
+ * ( ";" "BYSECOND" "=" byseclist ) /
+ * ( ";" "BYMINUTE" "=" byminlist ) /
+ * ( ";" "BYHOUR" "=" byhrlist ) /
+ * ( ";" "BYDAY" "=" bywdaylist ) /
+ * ( ";" "BYMONTHDAY" "=" bymodaylist ) /
+ * ( ";" "BYYEARDAY" "=" byyrdaylist ) /
+ * ( ";" "BYWEEKNO" "=" bywknolist ) /
+ * ( ";" "BYMONTH" "=" bymolist ) /
+ * ( ";" "BYSETPOS" "=" bysplist ) /
+ * ( ";" "WKST" "=" weekday ) /
+ * ( ";" x-name "=" text )
+ * )
+*/
+static ical_rpt_t *ical_read_rrule(FILE * log, char *rrulestr,
+ unsigned *noskipped, const int itemline)
+{
+ const char daily[] = "DAILY";
+ const char weekly[] = "WEEKLY";
+ const char monthly[] = "MONTHLY";
+ const char yearly[] = "YEARLY";
+ const char count[] = "COUNT=";
+ const char interv[] = "INTERVAL=";
+ unsigned interval;
+ ical_rpt_t *rpt;
+ char *p;
+
+ rpt = NULL;
+ if ((p = strchr(rrulestr, ':')) != NULL) {
+ char freqstr[BUFSIZ];
+
+ p++;
+ rpt = mem_malloc(sizeof(ical_rpt_t));
+ memset(rpt, 0, sizeof(ical_rpt_t));
+ if (sscanf(p, "FREQ=%s", freqstr) != 1) {
+ ical_log(log, ICAL_VEVENT, itemline,
+ _("recurrence frequence not found."));
+ (*noskipped)++;
+ mem_free(rpt);
+ return NULL;
+ } else {
+ if (strncmp(freqstr, daily, sizeof(daily) - 1) == 0)
+ rpt->type = RECUR_DAILY;
+ else if (strncmp(freqstr, weekly, sizeof(weekly) - 1) == 0)
+ rpt->type = RECUR_WEEKLY;
+ else if (strncmp(freqstr, monthly, sizeof(monthly) - 1) == 0)
+ rpt->type = RECUR_MONTHLY;
+ else if (strncmp(freqstr, yearly, sizeof(yearly) - 1) == 0)
+ rpt->type = RECUR_YEARLY;
+ else {
+ ical_log(log, ICAL_VEVENT, itemline,
+ _("recurrence frequence not recognized."));
+ (*noskipped)++;
+ mem_free(rpt);
+ return NULL;
+ }
+ }
+ /*
+ The UNTIL rule part defines a date-time value which bounds the
+ recurrence rule in an inclusive manner. If not present, and the
+ COUNT rule part is also not present, the RRULE is considered to
+ repeat forever.
+
+ The COUNT rule part defines the number of occurrences at which to
+ range-bound the recurrence. The "DTSTART" property value, if
+ specified, counts as the first occurrence.
+ */
+ if ((p = strstr(rrulestr, "UNTIL")) != NULL) {
+ char *untilstr;
+
+ untilstr = strchr(p, '=');
+ rpt->until = ical_datetime2long(++untilstr, NULL);
+ } else {
+ unsigned cnt;
+ char *countstr;
+
+ if ((countstr = strstr(rrulestr, count)) != NULL) {
+ countstr += sizeof(count) - 1;
+ if (sscanf(countstr, "%u", &cnt) != 1) {
+ rpt->until = 0;
+ /* endless repetition */
+ } else {
+ rpt->count = cnt;
+ }
+ } else
+ rpt->until = 0;
+ }
+
+ if ((p = strstr(rrulestr, interv)) != NULL) {
+ p += sizeof(interv) - 1;
+ if (sscanf(p, "%u", &interval) != 1) {
+ rpt->freq = 1;
+ /* default frequence if none specified */
+ } else {
+ rpt->freq = interval;
+ }
+ } else {
+ rpt->freq = 1;
+ }
+ } else {
+ ical_log(log, ICAL_VEVENT, itemline, _("recurrence rule malformed."));
+ (*noskipped)++;
+ }
+ return rpt;
+}
+
+static void ical_add_exc(llist_t * exc_head, long date)
+{
+ if (date != 0) {
+ struct excp *exc = mem_malloc(sizeof(struct excp));
+ exc->st = date;
+
+ LLIST_ADD(exc_head, exc);
+ }
+}
+
+/*
+ * This property defines the list of date/time exceptions for a
+ * recurring calendar component.
+ */
+static void
+ical_read_exdate(llist_t * exc, FILE * log, char *exstr, unsigned *noskipped,
+ const int itemline)
+{
+ char *p, *q;
+ long date;
+
+ LLIST_INIT(exc);
+ if ((p = strchr(exstr, ':')) != NULL) {
+ p++;
+ while ((q = strchr(p, ',')) != NULL) {
+ char buf[BUFSIZ];
+ const int buflen = q - p;
+
+ strncpy(buf, p, buflen);
+ buf[buflen] = '\0';
+ date = ical_datetime2long(buf, NULL);
+ ical_add_exc(exc, date);
+ p = ++q;
+ }
+ date = ical_datetime2long(p, NULL);
+ ical_add_exc(exc, date);
+ } else {
+ ical_log(log, ICAL_VEVENT, itemline,
+ _("recurrence exception dates malformed."));
+ (*noskipped)++;
+ }
+}
+
+/* Return an allocated string containing the name of the newly created note. */
+static char *ical_read_note(char *line, unsigned *noskipped,
+ ical_vevent_e item_type, const int itemline,
+ FILE * log)
+{
+ char *p, *notestr, *note;
+
+ if ((p = strchr(line, ':')) != NULL) {
+ p++;
+ notestr = ical_unformat_line(p);
+ if (notestr == NULL) {
+ ical_log(log, item_type, itemline,
+ _("could not get entire item description."));
+ (*noskipped)++;
+ return NULL;
+ } else if (strlen(notestr) == 0) {
+ mem_free(notestr);
+ return NULL;
+ } else {
+ note = generate_note(notestr);
+ mem_free(notestr);
+ return note;
+ }
+ } else {
+ ical_log(log, item_type, itemline, _("description malformed."));
+ (*noskipped)++;
+ return NULL;
+ }
+}
+
+/* Returns an allocated string containing the ical item summary. */
+static char *ical_read_summary(char *line)
+{
+ char *p, *summary;
+
+ if ((p = strchr(line, ':')) != NULL) {
+ p++;
+ summary = ical_unformat_line(p);
+ return summary;
+ } else
+ return NULL;
+}
+
+static void
+ical_read_event(FILE * fdi, FILE * log, unsigned *noevents, unsigned *noapoints,
+ unsigned *noskipped, char *buf, char *lstore, unsigned *lineno)
+{
+ const int ITEMLINE = *lineno;
+ const char endevent[] = "END:VEVENT";
+ const char summary[] = "SUMMARY";
+ const char dtstart[] = "DTSTART";
+ const char dtend[] = "DTEND";
+ const char duration[] = "DURATION";
+ const char rrule[] = "RRULE";
+ const char exdate[] = "EXDATE";
+ const char alarm[] = "BEGIN:VALARM";
+ const char endalarm[] = "END:VALARM";
+ const char desc[] = "DESCRIPTION";
+ ical_vevent_e vevent_type;
+ char *p, buf_upper[BUFSIZ];
+ struct {
+ llist_t exc;
+ ical_rpt_t *rpt;
+ char *mesg, *note;
+ long start, end, dur;
+ int has_alarm;
+ } vevent;
+ int skip_alarm;
+
+ vevent_type = UNDEFINED;
+ memset(&vevent, 0, sizeof vevent);
+ skip_alarm = 0;
+ while (ical_readline(fdi, buf, lstore, lineno)) {
+ strncpy(buf_upper, buf, BUFSIZ);
+ buf_upper[BUFSIZ - 1] = '\0';
+ str_toupper(buf_upper);
+
+ if (skip_alarm) {
+ /* Need to skip VALARM properties because some keywords could
+ interfere, such as DURATION, SUMMARY,.. */
+ if (strncmp(buf_upper, endalarm, sizeof(endalarm) - 1) == 0)
+ skip_alarm = 0;
+ continue;
+ }
+ if (strncmp(buf_upper, endevent, sizeof(endevent) - 1) == 0) {
+ if (vevent.mesg) {
+ if (vevent.rpt && vevent.rpt->count)
+ vevent.rpt->until = ical_compute_rpt_until(vevent.start, vevent.rpt);
+
+ switch (vevent_type) {
+ case APPOINTMENT:
+ if (vevent.start == 0) {
+ ical_log(log, ICAL_VEVENT, ITEMLINE,
+ _("appointment has no start time."));
+ goto cleanup;
+ }
+ if (vevent.dur == 0) {
+ if (vevent.end == 0) {
+ ical_log(log, ICAL_VEVENT, ITEMLINE,
+ _("could not compute duration " "(no end time)."));
+ goto cleanup;
+ } else if (vevent.start == vevent.end) {
+ vevent_type = EVENT;
+ vevent.end = 0L;
+ ical_store_event(vevent.mesg, vevent.note,
+ vevent.start, vevent.end,
+ vevent.rpt, &vevent.exc);
+ (*noevents)++;
+ return;
+ } else {
+ vevent.dur = vevent.end - vevent.start;
+ if (vevent.dur < 0) {
+ ical_log(log, ICAL_VEVENT, ITEMLINE,
+ _("item has a negative duration."));
+ goto cleanup;
+ }
+ }
+ }
+ ical_store_apoint(vevent.mesg, vevent.note, vevent.start,
+ vevent.dur, vevent.rpt, &vevent.exc,
+ vevent.has_alarm);
+ (*noapoints)++;
+ break;
+ case EVENT:
+ if (vevent.start == 0) {
+ ical_log(log, ICAL_VEVENT, ITEMLINE,
+ _("event date is not defined."));
+ goto cleanup;
+ }
+ ical_store_event(vevent.mesg, vevent.note, vevent.start,
+ vevent.end, vevent.rpt, &vevent.exc);
+ (*noevents)++;
+ break;
+ case UNDEFINED:
+ ical_log(log, ICAL_VEVENT, ITEMLINE,
+ _("item could not be identified."));
+ goto cleanup;
+ break;
+ }
+ } else {
+ ical_log(log, ICAL_VEVENT, ITEMLINE,
+ _("could not retrieve item summary."));
+ goto cleanup;
+ }
+ return;
+ } else {
+ if (strncmp(buf_upper, dtstart, sizeof(dtstart) - 1) == 0) {
+ if ((p = strchr(buf, ':')) != NULL)
+ vevent.start = ical_datetime2long(++p, &vevent_type);
+ if (!vevent.start) {
+ ical_log(log, ICAL_VEVENT, ITEMLINE,
+ _("could not retrieve event start time."));
+ goto cleanup;
+ }
+ } else if (strncmp(buf_upper, dtend, sizeof(dtend) - 1) == 0) {
+ if ((p = strchr(buf, ':')) != NULL)
+ vevent.end = ical_datetime2long(++p, &vevent_type);
+ if (!vevent.end) {
+ ical_log(log, ICAL_VEVENT, ITEMLINE,
+ _("could not retrieve event end time."));
+ goto cleanup;
+ }
+ } else if (strncmp(buf_upper, duration, sizeof(duration) - 1) == 0) {
+ if ((vevent.dur = ical_dur2long(buf)) <= 0) {
+ ical_log(log, ICAL_VEVENT, ITEMLINE, _("item duration malformed."));
+ goto cleanup;
+ }
+ } else if (strncmp(buf_upper, rrule, sizeof(rrule) - 1) == 0) {
+ vevent.rpt = ical_read_rrule(log, buf, noskipped, ITEMLINE);
+ } else if (strncmp(buf_upper, exdate, sizeof(exdate) - 1) == 0) {
+ ical_read_exdate(&vevent.exc, log, buf, noskipped, ITEMLINE);
+ } else if (strncmp(buf_upper, summary, sizeof(summary) - 1) == 0) {
+ vevent.mesg = ical_read_summary(buf);
+ } else if (strncmp(buf_upper, alarm, sizeof(alarm) - 1) == 0) {
+ skip_alarm = 1;
+ vevent.has_alarm = 1;
+ } else if (strncmp(buf_upper, desc, sizeof(desc) - 1) == 0) {
+ vevent.note = ical_read_note(buf, noskipped, ICAL_VEVENT,
+ ITEMLINE, log);
+ }
+ }
+ }
+ ical_log(log, ICAL_VEVENT, ITEMLINE,
+ _("The ical file seems to be malformed. "
+ "The end of item was not found."));
+
+cleanup:
+
+ if (vevent.note)
+ mem_free(vevent.note);
+ if (vevent.mesg)
+ mem_free(vevent.mesg);
+ if (vevent.rpt)
+ mem_free(vevent.rpt);
+ LLIST_FREE(&vevent.exc);
+ (*noskipped)++;
+}
+
+static void
+ical_read_todo(FILE * fdi, FILE * log, unsigned *notodos, unsigned *noskipped,
+ char *buf, char *lstore, unsigned *lineno)
+{
+ const char endtodo[] = "END:VTODO";
+ const char summary[] = "SUMMARY";
+ const char alarm[] = "BEGIN:VALARM";
+ const char endalarm[] = "END:VALARM";
+ const char desc[] = "DESCRIPTION";
+ const int LOWEST = 9;
+ const int ITEMLINE = *lineno;
+ char buf_upper[BUFSIZ];
+ struct {
+ char *mesg, *note;
+ int has_priority, priority;
+ } vtodo;
+ int skip_alarm;
+
+ memset(&vtodo, 0, sizeof vtodo);
+ skip_alarm = 0;
+ while (ical_readline(fdi, buf, lstore, lineno)) {
+ strncpy(buf_upper, buf, BUFSIZ);
+ buf_upper[BUFSIZ - 1] = '\0';
+ str_toupper(buf_upper);
+ if (skip_alarm) {
+ /* Need to skip VALARM properties because some keywords could
+ interfere, such as DURATION, SUMMARY,.. */
+ if (strncmp(buf_upper, endalarm, sizeof(endalarm) - 1) == 0)
+ skip_alarm = 0;
+ continue;
+ }
+ if (strncmp(buf_upper, endtodo, sizeof(endtodo) - 1) == 0) {
+ if (!vtodo.has_priority)
+ vtodo.priority = LOWEST;
+ if (vtodo.mesg) {
+ ical_store_todo(vtodo.priority, vtodo.mesg, vtodo.note);
+ (*notodos)++;
+ } else {
+ ical_log(log, ICAL_VTODO, ITEMLINE,
+ _("could not retrieve item summary."));
+ goto cleanup;
+ }
+ return;
+ } else {
+ int tmpint;
+
+ if (sscanf(buf_upper, "PRIORITY:%d", &tmpint) == 1) {
+ if (tmpint <= 9 && tmpint >= 1) {
+ vtodo.priority = tmpint;
+ vtodo.has_priority = 1;
+ } else {
+ ical_log(log, ICAL_VTODO, ITEMLINE,
+ _("item priority is not acceptable "
+ "(must be between 1 and 9)."));
+ vtodo.priority = LOWEST;
+ }
+ } else if (strncmp(buf_upper, summary, sizeof(summary) - 1) == 0) {
+ vtodo.mesg = ical_read_summary(buf);
+ } else if (strncmp(buf_upper, alarm, sizeof(alarm) - 1) == 0) {
+ skip_alarm = 1;
+ } else if (strncmp(buf_upper, desc, sizeof(desc) - 1) == 0) {
+ vtodo.note = ical_read_note(buf, noskipped, ICAL_VTODO, ITEMLINE, log);
+ }
+ }
+ }
+ ical_log(log, ICAL_VTODO, ITEMLINE,
+ _("The ical file seems to be malformed. "
+ "The end of item was not found."));
+
+cleanup:
+
+ if (vtodo.note)
+ mem_free(vtodo.note);
+ if (vtodo.mesg)
+ mem_free(vtodo.mesg);
+ (*noskipped)++;
+}
+
+/* Import calcurse data. */
+void
+ical_import_data(FILE * stream, FILE * log, unsigned *events, unsigned *apoints,
+ unsigned *todos, unsigned *lines, unsigned *skipped)
+{
+ const char vevent[] = "BEGIN:VEVENT";
+ const char vtodo[] = "BEGIN:VTODO";
+ char buf[BUFSIZ], lstore[BUFSIZ];
+ float ical_version;
+
+ ical_readline_init(stream, buf, lstore, lines);
+ ical_version = ical_chk_header(stream, buf, lstore, lines);
+ RETURN_IF(ical_version < 0,
+ _("Warning: ical header malformed or wrong version number. "
+ "Aborting..."));
+
+ ical_log_init(log, ical_version);
+
+ while (ical_readline(stream, buf, lstore, lines)) {
+ (*lines)++;
+ str_toupper(buf);
+ if (strncmp(buf, vevent, sizeof(vevent) - 1) == 0) {
+ ical_read_event(stream, log, events, apoints, skipped, buf, lstore,
+ lines);
+ } else if (strncmp(buf, vtodo, sizeof(vtodo) - 1) == 0) {
+ ical_read_todo(stream, log, todos, skipped, buf, lstore, lines);
+ }
+ }
+}
+
+/* Export calcurse data. */
+void ical_export_data(FILE * stream)
+{
+ ical_export_header(stream);
+ ical_export_recur_events(stream);
+ ical_export_events(stream);
+ ical_export_recur_apoints(stream);
+ ical_export_apoints(stream);
+ ical_export_todo(stream);
+ ical_export_footer(stream);
+}
diff --git a/src/io.c b/src/io.c
index 21d8b42..fdead34 100644
--- a/src/io.c
+++ b/src/io.c
@@ -1,7 +1,7 @@
/*
* Calcurse - text-based organizer
*
- * Copyright (c) 2004-2011 calcurse Development Team <misc@calcurse.org>
+ * Copyright (c) 2004-2012 calcurse Development Team <misc@calcurse.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -45,9 +45,7 @@
#include <errno.h>
#include "calcurse.h"
-
-#define ICALDATEFMT "%Y%m%d"
-#define ICALDATETIMEFMT "%Y%m%dT%H%M%S"
+#include "sha1.h"
typedef enum {
PROGRESS_BAR_SAVE,
@@ -68,650 +66,147 @@ enum {
PROGRESS_BAR_EXPORT_TODO
};
-typedef enum {
- ICAL_VEVENT,
- ICAL_VTODO,
- ICAL_TYPES
-} ical_types_e;
-
-typedef enum {
- UNDEFINED,
- APPOINTMENT,
- EVENT
-} ical_vevent_e;
-
-typedef struct {
- enum recur_type type;
- int freq;
- long until;
- unsigned count;
-} ical_rpt_t;
-
struct ht_keybindings_s {
- char *label;
- enum key key;
- HTABLE_ENTRY (ht_keybindings_s);
+ const char *label;
+ enum key key;
+ HTABLE_ENTRY(ht_keybindings_s);
};
-/* Type definition for callbacks to multiple-mode export functions. */
-typedef void (*cb_export_t)(FILE *);
-typedef void (*cb_dump_t)(FILE *, long, long, char *);
-
-/* Static functions used to add export functionalities. */
-static void ical_export_header (FILE *);
-static void ical_export_recur_events (FILE *);
-static void ical_export_events (FILE *);
-static void ical_export_recur_apoints (FILE *);
-static void ical_export_apoints (FILE *);
-static void ical_export_todo (FILE *);
-static void ical_export_footer (FILE *);
-
-static void pcal_export_header (FILE *);
-static void pcal_export_recur_events (FILE *);
-static void pcal_export_events (FILE *);
-static void pcal_export_recur_apoints (FILE *);
-static void pcal_export_apoints (FILE *);
-static void pcal_export_todo (FILE *);
-static void pcal_export_footer (FILE *);
-
-cb_export_t cb_export_header[IO_EXPORT_NBTYPES] =
- {ical_export_header, pcal_export_header};
-cb_export_t cb_export_recur_events[IO_EXPORT_NBTYPES] =
- {ical_export_recur_events, pcal_export_recur_events};
-cb_export_t cb_export_events[IO_EXPORT_NBTYPES] =
- {ical_export_events, pcal_export_events};
-cb_export_t cb_export_recur_apoints[IO_EXPORT_NBTYPES] =
- {ical_export_recur_apoints, pcal_export_recur_apoints};
-cb_export_t cb_export_apoints[IO_EXPORT_NBTYPES] =
- {ical_export_apoints, pcal_export_apoints};
-cb_export_t cb_export_todo[IO_EXPORT_NBTYPES] =
- {ical_export_todo, pcal_export_todo};
-cb_export_t cb_export_footer[IO_EXPORT_NBTYPES] =
- {ical_export_footer, pcal_export_footer};
-
-static char *ical_recur_type[RECUR_TYPES] =
- { "", "DAILY", "WEEKLY", "MONTHLY", "YEARLY" };
+static void load_keys_ht_getkey(struct ht_keybindings_s *, const char **,
+ int *);
+static int load_keys_ht_compare(struct ht_keybindings_s *,
+ struct ht_keybindings_s *);
+
+#define HSIZE 256
+HTABLE_HEAD(ht_keybindings, HSIZE, ht_keybindings_s);
+HTABLE_PROTOTYPE(ht_keybindings, ht_keybindings_s)
+ HTABLE_GENERATE(ht_keybindings, ht_keybindings_s, load_keys_ht_getkey,
+ load_keys_ht_compare)
/* Draw a progress bar while saving, loading or exporting data. */
-static void
-progress_bar (progress_bar_t type, int progress)
+static void progress_bar(progress_bar_t type, int progress)
{
-#define SLEEPTIME 125000
#define NBFILES 4
#define NBEXPORTED 3
#define LABELENGTH 15
int i, step, steps;
- char *mesg_sav = _("Saving...");
- char *mesg_load = _("Loading...");
- char *mesg_export = _("Exporting...");
- char *error_msg = _("Internal error while displaying progress bar");
- char *barchar = "|";
- char *file[NBFILES] = {
+ const char *mesg_sav = _("Saving...");
+ const char *mesg_load = _("Loading...");
+ const char *mesg_export = _("Exporting...");
+ const char *error_msg = _("Internal error while displaying progress bar");
+ const char *barchar = "|";
+ const char *file[NBFILES] = {
"[ conf ]",
"[ todo ]",
"[ apts ]",
"[ keys ]"
};
- char *data[NBEXPORTED] = {
+ const char *data[NBEXPORTED] = {
"[ events ]",
"[appointments]",
"[ todo ]"
};
- int ipos = LABELENGTH + 2;
+ int ipos = LABELENGTH + 2;
int epos[NBFILES];
/* progress bar length init. */
ipos = LABELENGTH + 2;
steps = (type == PROGRESS_BAR_EXPORT) ? NBEXPORTED : NBFILES;
- step = floor (col / (steps + 1));
+ step = floor(col / (steps + 1));
for (i = 0; i < steps - 1; i++)
epos[i] = (i + 2) * step;
epos[steps - 1] = col - 2;
- switch (type)
- {
- case PROGRESS_BAR_SAVE:
- EXIT_IF (progress < 0 || progress > PROGRESS_BAR_KEYS, "%s", error_msg);
- status_mesg (mesg_sav, file[progress]);
- break;
- case PROGRESS_BAR_LOAD:
- EXIT_IF (progress < 0 || progress > PROGRESS_BAR_KEYS, "%s", error_msg);
- status_mesg (mesg_load, file[progress]);
- break;
- case PROGRESS_BAR_EXPORT:
- EXIT_IF (progress < 0
- || progress > PROGRESS_BAR_EXPORT_TODO, "%s", error_msg);
- status_mesg (mesg_export, data[progress]);
- break;
- }
+ switch (type) {
+ case PROGRESS_BAR_SAVE:
+ EXIT_IF(progress < 0 || progress > PROGRESS_BAR_KEYS, "%s", error_msg);
+ status_mesg(mesg_sav, file[progress]);
+ break;
+ case PROGRESS_BAR_LOAD:
+ EXIT_IF(progress < 0 || progress > PROGRESS_BAR_KEYS, "%s", error_msg);
+ status_mesg(mesg_load, file[progress]);
+ break;
+ case PROGRESS_BAR_EXPORT:
+ EXIT_IF(progress < 0
+ || progress > PROGRESS_BAR_EXPORT_TODO, "%s", error_msg);
+ status_mesg(mesg_export, data[progress]);
+ break;
+ }
/* Draw the progress bar. */
- mvwprintw (win[STA].p, 1, ipos, barchar);
- mvwprintw (win[STA].p, 1, epos[steps - 1], barchar);
- custom_apply_attr (win[STA].p, ATTR_HIGHEST);
+ mvwprintw(win[STA].p, 1, ipos, barchar);
+ mvwprintw(win[STA].p, 1, epos[steps - 1], barchar);
+ custom_apply_attr(win[STA].p, ATTR_HIGHEST);
for (i = ipos + 1; i < epos[progress]; i++)
- mvwaddch (win[STA].p, 1, i, ' ' | A_REVERSE);
- custom_remove_attr (win[STA].p, ATTR_HIGHEST);
- wmove (win[STA].p, 0, 0);
- wins_wrefresh (win[STA].p);
- (void)usleep (SLEEPTIME);
-#undef SLEEPTIME
+ mvwaddch(win[STA].p, 1, i, ' ' | A_REVERSE);
+ custom_remove_attr(win[STA].p, ATTR_HIGHEST);
+ wmove(win[STA].p, 0, 0);
+ wins_wrefresh(win[STA].p);
#undef NBFILES
#undef NBEXPORTED
#undef LABELENGTH
}
/* Ask user for a file name to export data to. */
-static FILE *
-get_export_stream (enum export_type type)
+static FILE *get_export_stream(enum export_type type)
{
FILE *stream;
int cancel;
char *home, *stream_name;
- char *question = _("Choose the file used to export calcurse data:");
- char *wrong_name =
- _("The file cannot be accessed, please enter another file name.");
- char *press_enter = _("Press [ENTER] to continue.");
- const char *file_ext[IO_EXPORT_NBTYPES] = {"ical", "txt"};
+ const char *question = _("Choose the file used to export calcurse data:");
+ const char *wrong_name =
+ _("The file cannot be accessed, please enter another file name.");
+ const char *press_enter = _("Press [ENTER] to continue.");
+ const char *file_ext[IO_EXPORT_NBTYPES] = { "ical", "txt" };
stream = NULL;
- stream_name = (char *) mem_malloc (BUFSIZ);
- if ((home = getenv ("HOME")) != NULL)
- (void)snprintf (stream_name, BUFSIZ, "%s/calcurse.%s", home,
- file_ext[type]);
+ stream_name = (char *)mem_malloc(BUFSIZ);
+ if ((home = getenv("HOME")) != NULL)
+ snprintf(stream_name, BUFSIZ, "%s/calcurse.%s", home, file_ext[type]);
else
- (void)snprintf (stream_name, BUFSIZ, "%s/calcurse.%s", get_tempdir (),
- file_ext[type]);
-
- while (stream == NULL)
- {
- status_mesg (question, "");
- cancel = updatestring (win[STA].p, &stream_name, 0, 1);
- if (cancel)
- {
- mem_free (stream_name);
- return (NULL);
- }
- stream = fopen (stream_name, "w");
- if (stream == NULL)
- {
- status_mesg (wrong_name, press_enter);
- (void)wgetch (win[STA].p);
- }
- }
- mem_free (stream_name);
-
- return (stream);
-}
-
-/*
- * Travel through each occurence of an item, and execute the given callback
- * (mainly used to export data).
- */
-static void
-foreach_date_dump (const long date_end, struct rpt *rpt, llist_t *exc,
- long item_first_date, long item_dur, char *item_mesg,
- cb_dump_t cb_dump, FILE *stream)
-{
- long date, item_time;
- struct tm lt;
- time_t t;
-
- t = item_first_date;
- lt = *localtime (&t);
- lt.tm_hour = lt.tm_min = lt.tm_sec = 0;
- lt.tm_isdst = -1;
- date = mktime (&lt);
- item_time = item_first_date - date;
-
- while (date <= date_end && date <= rpt->until)
- {
- if (recur_item_inday (item_first_date, exc, rpt->type, rpt->freq,
- rpt->until, date))
- {
- (*cb_dump)(stream, date + item_time, item_dur, item_mesg);
- }
- switch (rpt->type)
- {
- case RECUR_DAILY:
- date = date_sec_change (date, 0, rpt->freq);
- break;
- case RECUR_WEEKLY:
- date = date_sec_change (date, 0, rpt->freq * WEEKINDAYS);
- break;
- case RECUR_MONTHLY:
- date = date_sec_change (date, rpt->freq, 0);
- break;
- case RECUR_YEARLY:
- date = date_sec_change (date, rpt->freq * 12, 0);
- break;
- default:
- EXIT (_("incoherent repetition type"));
- /* NOTREACHED */
- break;
- }
- }
-}
-
-/* iCal alarm notification. */
-static void
-ical_export_valarm (FILE *stream)
-{
- (void)fprintf (stream, "BEGIN:VALARM\n");
- pthread_mutex_lock (&nbar.mutex);
- (void)fprintf (stream, "TRIGGER:-P%dS\n", nbar.cntdwn);
- pthread_mutex_unlock (&nbar.mutex);
- (void)fprintf (stream, "ACTION:DISPLAY\n");
- (void)fprintf (stream, "END:VALARM\n");
-}
-
-/* Export header. */
-static void
-ical_export_header (FILE *stream)
-{
- (void)fprintf (stream, "BEGIN:VCALENDAR\n");
- (void)fprintf (stream, "PRODID:-//calcurse//NONSGML v%s//EN\n", VERSION);
- (void)fprintf (stream, "VERSION:2.0\n");
-}
-
-static void
-pcal_export_header (FILE *stream)
-{
- (void)fprintf (stream, "# calcurse pcal export\n");
- (void)fprintf (stream, "\n# =======\n# options\n# =======\n");
- (void)fprintf (stream, "opt -A -K -l -m -F %s\n",
- calendar_week_begins_on_monday () ?
- "Monday" : "Sunday");
- (void)fprintf (stream, "# Display week number (i.e. 1-52) on every Monday\n");
- (void)fprintf (stream, "all monday in all week %%w\n");
- (void)fprintf (stream, "\n");
-}
-
-/* Export footer. */
-static void
-ical_export_footer (FILE *stream)
-{
- (void)fprintf (stream, "END:VCALENDAR\n");
-}
-
-static void
-pcal_export_footer (FILE *stream)
-{
-}
-
-/* Export recurrent events. */
-static void
-ical_export_recur_events (FILE *stream)
-{
- llist_item_t *i, *j;
- char ical_date[BUFSIZ];
-
- LLIST_FOREACH (&recur_elist, i)
- {
- struct recur_event *rev = LLIST_GET_DATA (i);
- date_sec2date_fmt (rev->day, ICALDATEFMT, ical_date);
- (void)fprintf (stream, "BEGIN:VEVENT\n");
- (void)fprintf (stream, "DTSTART:%s\n", ical_date);
- (void)fprintf (stream, "RRULE:FREQ=%s;INTERVAL=%d",
- ical_recur_type[rev->rpt->type], rev->rpt->freq);
-
- if (rev->rpt->until != 0)
- {
- date_sec2date_fmt (rev->rpt->until, ICALDATEFMT, ical_date);
- (void)fprintf (stream, ";UNTIL=%s\n", ical_date);
- }
- else
- (void)fprintf (stream, "\n");
-
- if (LLIST_FIRST (&rev->exc))
- {
- (void)fprintf (stream, "EXDATE:");
- LLIST_FOREACH (&rev->exc, j)
- {
- struct excp *exc = LLIST_GET_DATA (j);
- date_sec2date_fmt (exc->st, ICALDATEFMT, ical_date);
- (void)fprintf (stream, "%s", ical_date);
- if (LLIST_NEXT (j))
- (void)fprintf (stream, ",");
- else
- (void)fprintf (stream, "\n");
- }
- }
-
- (void)fprintf (stream, "SUMMARY:%s\n", rev->mesg);
- (void)fprintf (stream, "END:VEVENT\n");
- }
-}
-
-/* Format and dump event data to a pcal formatted file. */
-static void
-pcal_dump_event (FILE *stream, long event_date, long event_dur,
- char *event_mesg)
-{
- char pcal_date[BUFSIZ];
-
- date_sec2date_fmt (event_date, "%b %d", pcal_date);
- (void)fprintf (stream, "%s %s\n", pcal_date, event_mesg);
-}
-
-/* Format and dump appointment data to a pcal formatted file. */
-static void
-pcal_dump_apoint (FILE *stream, long apoint_date, long apoint_dur,
- char *apoint_mesg)
-{
- char pcal_date[BUFSIZ], pcal_beg[BUFSIZ], pcal_end[BUFSIZ];
-
- date_sec2date_fmt (apoint_date, "%b %d", pcal_date);
- date_sec2date_fmt (apoint_date, "%R", pcal_beg);
- date_sec2date_fmt (apoint_date + apoint_dur, "%R", pcal_end);
- (void)fprintf (stream, "%s ", pcal_date);
- (void)fprintf (stream, "(%s -> %s) %s\n", pcal_beg, pcal_end, apoint_mesg);
-}
-
-static void
-pcal_export_recur_events (FILE *stream)
-{
- llist_item_t *i;
- char pcal_date[BUFSIZ];
-
- (void)fprintf (stream, "\n# =============");
- (void)fprintf (stream, "\n# Recur. Events");
- (void)fprintf (stream, "\n# =============\n");
- (void)fprintf (stream,
- "# (pcal does not support from..until dates specification\n");
-
- LLIST_FOREACH (&recur_elist, i)
- {
- struct recur_event *rev = LLIST_GET_DATA (i);
- if (rev->rpt->until == 0 && rev->rpt->freq == 1)
- {
- switch (rev->rpt->type)
- {
- case RECUR_DAILY:
- date_sec2date_fmt (rev->day, "%b %d", pcal_date);
- (void)fprintf (stream, "all day on_or_after %s %s\n",
- pcal_date, rev->mesg);
- break;
- case RECUR_WEEKLY:
- date_sec2date_fmt (rev->day, "%a", pcal_date);
- (void)fprintf (stream, "all %s on_or_after ", pcal_date);
- date_sec2date_fmt (rev->day, "%b %d", pcal_date);
- (void)fprintf (stream, "%s %s\n", pcal_date, rev->mesg);
- break;
- case RECUR_MONTHLY:
- date_sec2date_fmt (rev->day, "%d", pcal_date);
- (void)fprintf (stream, "day on all %s %s\n", pcal_date,
- rev->mesg);
- break;
- case RECUR_YEARLY:
- date_sec2date_fmt (rev->day, "%b %d", pcal_date);
- (void)fprintf (stream, "%s %s\n", pcal_date, rev->mesg);
- break;
- default:
- EXIT (_("incoherent repetition type"));
- }
- }
- else
- {
- const long YEAR_START = calendar_start_of_year ();
- const long YEAR_END = calendar_end_of_year ();
-
- if (rev->day < YEAR_END && rev->day > YEAR_START)
- foreach_date_dump (YEAR_END, rev->rpt, &rev->exc, rev->day, 0,
- rev->mesg, (cb_dump_t) pcal_dump_event, stream);
- }
- }
-}
-
-/* Export events. */
-static void
-ical_export_events (FILE *stream)
-{
- llist_item_t *i;
- char ical_date[BUFSIZ];
-
- LLIST_FOREACH (&eventlist, i)
- {
- struct event *ev = LLIST_TS_GET_DATA (i);
- date_sec2date_fmt (ev->day, ICALDATEFMT, ical_date);
- (void)fprintf (stream, "BEGIN:VEVENT\n");
- (void)fprintf (stream, "DTSTART:%s\n", ical_date);
- (void)fprintf (stream, "SUMMARY:%s\n", ev->mesg);
- (void)fprintf (stream, "END:VEVENT\n");
- }
-}
-
-static void
-pcal_export_events (FILE *stream)
-{
- llist_item_t *i;
-
- (void)fprintf (stream, "\n# ======\n# Events\n# ======\n");
- LLIST_FOREACH (&eventlist, i)
- {
- struct event *ev = LLIST_TS_GET_DATA (i);
- pcal_dump_event (stream, ev->day, 0, ev->mesg);
- }
- (void)fprintf (stream, "\n");
-}
-
-/* Export recurrent appointments. */
-static void
-ical_export_recur_apoints (FILE *stream)
-{
- llist_item_t *i, *j;
- char ical_datetime[BUFSIZ];
- char ical_date[BUFSIZ];
-
- LLIST_TS_LOCK (&recur_alist_p);
- LLIST_TS_FOREACH (&recur_alist_p, i)
- {
- struct recur_apoint *rapt = LLIST_TS_GET_DATA (i);
-
- date_sec2date_fmt (rapt->start, ICALDATETIMEFMT, ical_datetime);
- (void)fprintf (stream, "BEGIN:VEVENT\n");
- (void)fprintf (stream, "DTSTART:%s\n", ical_datetime);
- (void)fprintf (stream, "DURATION:PT0H0M%ldS\n", rapt->dur);
- (void)fprintf (stream, "RRULE:FREQ=%s;INTERVAL=%d",
- ical_recur_type[rapt->rpt->type], rapt->rpt->freq);
-
- if (rapt->rpt->until != 0)
- {
- date_sec2date_fmt (rapt->rpt->until + HOURINSEC, ICALDATEFMT,
- ical_date);
- (void)fprintf (stream, ";UNTIL=%s\n", ical_date);
- }
- else
- (void)fprintf (stream, "\n");
-
- if (LLIST_FIRST (&rapt->exc))
- {
- (void)fprintf (stream, "EXDATE:");
- LLIST_FOREACH (&rapt->exc, j)
- {
- struct excp *exc = LLIST_GET_DATA (j);
- date_sec2date_fmt (exc->st, ICALDATEFMT, ical_date);
- (void)fprintf (stream, "%s", ical_date);
- if (LLIST_NEXT (j))
- (void)fprintf (stream, ",");
- else
- (void)fprintf (stream, "\n");
- }
- }
-
- (void)fprintf (stream, "SUMMARY:%s\n", rapt->mesg);
- if (rapt->state & APOINT_NOTIFY)
- ical_export_valarm (stream);
- (void)fprintf (stream, "END:VEVENT\n");
- }
- LLIST_TS_UNLOCK (&recur_alist_p);
-}
-
-static void
-pcal_export_recur_apoints (FILE *stream)
-{
- llist_item_t *i;
- char pcal_date[BUFSIZ], pcal_beg[BUFSIZ], pcal_end[BUFSIZ];
-
- (void)fprintf (stream, "\n# ==============");
- (void)fprintf (stream, "\n# Recur. Apoints");
- (void)fprintf (stream, "\n# ==============\n");
- (void)fprintf (stream,
- "# (pcal does not support from..until dates specification\n");
-
- LLIST_TS_FOREACH (&recur_alist_p, i)
- {
- struct recur_apoint *rapt = LLIST_TS_GET_DATA (i);
-
- if (rapt->rpt->until == 0 && rapt->rpt->freq == 1)
- {
- date_sec2date_fmt (rapt->start, "%R", pcal_beg);
- date_sec2date_fmt (rapt->start + rapt->dur, "%R", pcal_end);
- switch (rapt->rpt->type)
- {
- case RECUR_DAILY:
- date_sec2date_fmt (rapt->start, "%b %d", pcal_date);
- (void)fprintf (stream, "all day on_or_after %s (%s -> %s) %s\n",
- pcal_date, pcal_beg, pcal_end, rapt->mesg);
- break;
- case RECUR_WEEKLY:
- date_sec2date_fmt (rapt->start, "%a", pcal_date);
- (void)fprintf (stream, "all %s on_or_after ", pcal_date);
- date_sec2date_fmt (rapt->start, "%b %d", pcal_date);
- (void)fprintf (stream, "%s (%s -> %s) %s\n", pcal_date,
- pcal_beg, pcal_end, rapt->mesg);
- break;
- case RECUR_MONTHLY:
- date_sec2date_fmt (rapt->start, "%d", pcal_date);
- (void)fprintf (stream, "day on all %s (%s -> %s) %s\n",
- pcal_date, pcal_beg, pcal_end, rapt->mesg);
- break;
- case RECUR_YEARLY:
- date_sec2date_fmt (rapt->start, "%b %d", pcal_date);
- (void)fprintf (stream, "%s (%s -> %s) %s\n", pcal_date,
- pcal_beg, pcal_end, rapt->mesg);
- break;
- default:
- EXIT (_("incoherent repetition type"));
- }
- }
- else
- {
- const long YEAR_START = calendar_start_of_year ();
- const long YEAR_END = calendar_end_of_year ();
-
- if (rapt->start < YEAR_END && rapt->start > YEAR_START)
- foreach_date_dump (YEAR_END, rapt->rpt, &rapt->exc, rapt->start,
- rapt->dur, rapt->mesg,
- (cb_dump_t)pcal_dump_apoint, stream);
- }
- }
-}
-
-/* Export appointments. */
-static void
-ical_export_apoints (FILE *stream)
-{
- llist_item_t *i;
- char ical_datetime[BUFSIZ];
-
- LLIST_TS_LOCK (&alist_p);
- LLIST_TS_FOREACH (&alist_p, i)
- {
- struct apoint *apt = LLIST_TS_GET_DATA (i);
- date_sec2date_fmt (apt->start, ICALDATETIMEFMT, ical_datetime);
- (void)fprintf (stream, "BEGIN:VEVENT\n");
- (void)fprintf (stream, "DTSTART:%s\n", ical_datetime);
- (void)fprintf (stream, "DURATION:P%ldDT%ldH%ldM%ldS\n",
- apt->dur / DAYINSEC,
- (apt->dur / HOURINSEC) % 24,
- (apt->dur / MININSEC) % 60,
- apt->dur % MININSEC);
- (void)fprintf (stream, "SUMMARY:%s\n", apt->mesg);
- if (apt->state & APOINT_NOTIFY)
- ical_export_valarm (stream);
- (void)fprintf (stream, "END:VEVENT\n");
+ snprintf(stream_name, BUFSIZ, "%s/calcurse.%s", get_tempdir(),
+ file_ext[type]);
+
+ while (stream == NULL) {
+ status_mesg(question, "");
+ cancel = updatestring(win[STA].p, &stream_name, 0, 1);
+ if (cancel) {
+ mem_free(stream_name);
+ return NULL;
}
- LLIST_TS_UNLOCK (&alist_p);
-}
-
-static void
-pcal_export_apoints (FILE *stream)
-{
- llist_item_t *i;
-
- (void)fprintf (stream, "\n# ============\n# Appointments\n# ============\n");
- LLIST_TS_LOCK (&alist_p);
- LLIST_TS_FOREACH (&alist_p, i)
- {
- struct apoint *apt = LLIST_TS_GET_DATA (i);
- pcal_dump_apoint (stream, apt->start, apt->dur, apt->mesg);
+ stream = fopen(stream_name, "w");
+ if (stream == NULL) {
+ status_mesg(wrong_name, press_enter);
+ wgetch(win[STA].p);
}
- LLIST_TS_UNLOCK (&alist_p);
- (void)fprintf (stream, "\n");
-}
-
-/* Export todo items. */
-static void
-ical_export_todo (FILE *stream)
-{
- llist_item_t *i;
-
- LLIST_FOREACH (&todolist, i)
- {
- struct todo *todo = LLIST_TS_GET_DATA (i);
- if (todo->id < 0) /* completed items */
- continue;
+ }
+ mem_free(stream_name);
- (void)fprintf (stream, "BEGIN:VTODO\n");
- (void)fprintf (stream, "PRIORITY:%d\n", todo->id);
- (void)fprintf (stream, "SUMMARY:%s\n", todo->mesg);
- (void)fprintf (stream, "END:VTODO\n");
- }
-}
-
-static void
-pcal_export_todo (FILE *stream)
-{
- llist_item_t *i;
-
- (void)fprintf (stream, "#\n# Todos\n#\n");
- LLIST_FOREACH (&todolist, i)
- {
- struct todo *todo = LLIST_TS_GET_DATA (i);
- if (todo->id < 0) /* completed items */
- continue;
-
- (void)fprintf (stream, "note all ");
- (void)fprintf (stream, "%d. %s\n", todo->id, todo->mesg);
- }
- (void)fprintf (stream, "\n");
+ return stream;
}
/* Append a line to a file. */
-unsigned
-io_fprintln (const char *fname, const char *fmt, ...)
+unsigned io_fprintln(const char *fname, const char *fmt, ...)
{
FILE *fp;
va_list ap;
char buf[BUFSIZ];
int ret;
- fp = fopen (fname, "a");
- RETVAL_IF (!fp, 0, _("Failed to open \"%s\", - %s\n"),
- fname, strerror (errno));
+ fp = fopen(fname, "a");
+ RETVAL_IF(!fp, 0, _("Failed to open \"%s\", - %s\n"), fname, strerror(errno));
- va_start (ap, fmt);
- ret = vsnprintf (buf, sizeof buf, fmt, ap);
- RETVAL_IF (ret < 0, 0, _("Failed to build message\n"));
- va_end (ap);
+ va_start(ap, fmt);
+ ret = vsnprintf(buf, sizeof buf, fmt, ap);
+ RETVAL_IF(ret < 0, 0, _("Failed to build message\n"));
+ va_end(ap);
- ret = fprintf (fp, "%s", buf);
- RETVAL_IF (ret < 0, 0, _("Failed to print message \"%s\"\n"), buf);
+ ret = fprintf(fp, "%s", buf);
+ RETVAL_IF(ret < 0, 0, _("Failed to print message \"%s\"\n"), buf);
- ret = fclose (fp);
- RETVAL_IF (ret != 0, 0, _("Failed to close \"%s\" - %s\n"),
- fname, strerror (errno));
+ ret = fclose(fp);
+ RETVAL_IF(ret != 0, 0, _("Failed to close \"%s\" - %s\n"),
+ fname, strerror(errno));
return 1;
}
@@ -723,383 +218,231 @@ io_fprintln (const char *fname, const char *fmt, ...)
* is created.
* The datadir argument can be use to specify an alternative data root dir.
*/
-void
-io_init (char *cfile, char *datadir)
+void io_init(const char *cfile, const char *datadir)
{
FILE *data_file;
- char *home;
+ const char *home;
char apts_file[BUFSIZ] = "";
int ch;
- if (datadir != NULL)
- {
- home = datadir;
- (void)snprintf (path_dir, BUFSIZ, "%s", home);
- (void)snprintf (path_todo, BUFSIZ, "%s/" TODO_PATH_NAME, home);
- (void)snprintf (path_conf, BUFSIZ, "%s/" CONF_PATH_NAME, home);
- (void)snprintf (path_notes, BUFSIZ, "%s/" NOTES_DIR_NAME, home);
- (void)snprintf (path_apts, BUFSIZ, "%s/" APTS_PATH_NAME, home);
- (void)snprintf (path_keys, BUFSIZ, "%s/" KEYS_PATH_NAME, home);
- (void)snprintf (path_cpid, BUFSIZ, "%s/" CPID_PATH_NAME, home);
- (void)snprintf (path_dpid, BUFSIZ, "%s/" DPID_PATH_NAME, home);
- (void)snprintf (path_dmon_log, BUFSIZ, "%s/" DLOG_PATH_NAME, home);
- }
- else
- {
- home = getenv ("HOME");
- if (home == NULL)
- {
- home = ".";
- }
- (void)snprintf (path_dir, BUFSIZ, "%s/" DIR_NAME, home);
- (void)snprintf (path_todo, BUFSIZ, "%s/" TODO_PATH, home);
- (void)snprintf (path_conf, BUFSIZ, "%s/" CONF_PATH, home);
- (void)snprintf (path_keys, BUFSIZ, "%s/" KEYS_PATH, home);
- (void)snprintf (path_cpid, BUFSIZ, "%s/" CPID_PATH, home);
- (void)snprintf (path_dpid, BUFSIZ, "%s/" DPID_PATH, home);
- (void)snprintf (path_dmon_log, BUFSIZ, "%s/" DLOG_PATH, home);
- (void)snprintf (path_notes, BUFSIZ, "%s/" NOTES_DIR, home);
- if (cfile == NULL)
- {
- (void)snprintf (path_apts, BUFSIZ, "%s/" APTS_PATH, home);
- }
- else
- {
- (void)snprintf (apts_file, BUFSIZ, "%s", cfile);
- (void)strncpy (path_apts, apts_file, BUFSIZ);
- /* check if the file exists, otherwise create it */
- data_file = fopen (path_apts, "r");
- if (data_file == NULL)
- {
- printf (_("%s does not exist, create it now [y or n] ? "),
- path_apts);
- ch = getchar ();
- switch (ch)
- {
- case 'N':
- case 'n':
- printf (_("aborting...\n"));
- exit_calcurse (EXIT_FAILURE);
- break;
-
- case 'Y':
- case 'y':
- data_file = fopen (path_apts, "w");
- if (data_file == NULL)
- {
- perror (path_apts);
- exit_calcurse (EXIT_FAILURE);
- }
- else
- {
- printf (_("%s successfully created\n"), path_apts);
- printf (_("starting interactive mode...\n"));
- }
- break;
-
- default:
- printf (_("aborting...\n"));
- exit_calcurse (EXIT_FAILURE);
- break;
- }
- }
- file_close (data_file, __FILE_POS__);
+ if (datadir != NULL) {
+ home = datadir;
+ snprintf(path_dir, BUFSIZ, "%s", home);
+ snprintf(path_todo, BUFSIZ, "%s/" TODO_PATH_NAME, home);
+ snprintf(path_conf, BUFSIZ, "%s/" CONF_PATH_NAME, home);
+ snprintf(path_notes, BUFSIZ, "%s/" NOTES_DIR_NAME, home);
+ snprintf(path_apts, BUFSIZ, "%s/" APTS_PATH_NAME, home);
+ snprintf(path_keys, BUFSIZ, "%s/" KEYS_PATH_NAME, home);
+ snprintf(path_cpid, BUFSIZ, "%s/" CPID_PATH_NAME, home);
+ snprintf(path_dpid, BUFSIZ, "%s/" DPID_PATH_NAME, home);
+ snprintf(path_dmon_log, BUFSIZ, "%s/" DLOG_PATH_NAME, home);
+ } else {
+ home = getenv("HOME");
+ if (home == NULL) {
+ home = ".";
+ }
+ snprintf(path_dir, BUFSIZ, "%s/" DIR_NAME, home);
+ snprintf(path_todo, BUFSIZ, "%s/" TODO_PATH, home);
+ snprintf(path_conf, BUFSIZ, "%s/" CONF_PATH, home);
+ snprintf(path_keys, BUFSIZ, "%s/" KEYS_PATH, home);
+ snprintf(path_cpid, BUFSIZ, "%s/" CPID_PATH, home);
+ snprintf(path_dpid, BUFSIZ, "%s/" DPID_PATH, home);
+ snprintf(path_dmon_log, BUFSIZ, "%s/" DLOG_PATH, home);
+ snprintf(path_notes, BUFSIZ, "%s/" NOTES_DIR, home);
+ if (cfile == NULL) {
+ snprintf(path_apts, BUFSIZ, "%s/" APTS_PATH, home);
+ } else {
+ snprintf(apts_file, BUFSIZ, "%s", cfile);
+ strncpy(path_apts, apts_file, BUFSIZ);
+ /* check if the file exists, otherwise create it */
+ data_file = fopen(path_apts, "r");
+ if (data_file == NULL) {
+ printf(_("%s does not exist, create it now [y or n] ? "), path_apts);
+ ch = getchar();
+ switch (ch) {
+ case 'N':
+ case 'n':
+ puts(_("aborting...\n"));
+ exit_calcurse(EXIT_FAILURE);
+ break;
+
+ case 'Y':
+ case 'y':
+ data_file = fopen(path_apts, "w");
+ if (data_file == NULL) {
+ perror(path_apts);
+ exit_calcurse(EXIT_FAILURE);
+ } else {
+ printf(_("%s successfully created\n"), path_apts);
+ puts(_("starting interactive mode...\n"));
+ }
+ break;
+
+ default:
+ puts(_("aborting...\n"));
+ exit_calcurse(EXIT_FAILURE);
+ break;
}
+ }
+ file_close(data_file, __FILE_POS__);
}
+ }
}
-void
-io_extract_data (char *dst_data, const char *org, int len)
+void io_extract_data(char *dst_data, const char *org, int len)
{
int i;
- for (i = 0; i < len - 1; i++)
- {
- if (*org == '\n' || *org == '\0')
- break;
- *dst_data++ = *org++;
- }
+ for (; *org == ' ' || *org == '\t'; org++) ;
+ for (i = 0; i < len - 1; i++) {
+ if (*org == '\n' || *org == '\0' || *org == '#')
+ break;
+ *dst_data++ = *org++;
+ }
*dst_data = '\0';
}
-void
-display_mark (void)
+static void display_mark(void)
{
const int DISPLAY_TIME = 1;
WINDOW *mwin;
- mwin = newwin (1, 2, 1, col - 3);
+ mwin = newwin(1, 2, 1, col - 3);
- custom_apply_attr (mwin, ATTR_HIGHEST);
- mvwprintw (mwin, 0, 0, "**");
- wins_wrefresh (mwin);
- sleep (DISPLAY_TIME);
- mvwprintw (mwin, 0, 0, " ");
- wins_wrefresh (mwin);
- delwin (mwin);
- wins_doupdate ();
+ custom_apply_attr(mwin, ATTR_HIGHEST);
+ mvwprintw(mwin, 0, 0, "**");
+ wins_wrefresh(mwin);
+ sleep(DISPLAY_TIME);
+ mvwprintw(mwin, 0, 0, " ");
+ wins_wrefresh(mwin);
+ delwin(mwin);
+ wins_doupdate();
}
static pthread_mutex_t io_save_mutex = PTHREAD_MUTEX_INITIALIZER;
-/* Save the user configuration. */
-unsigned
-io_save_conf (struct conf *conf)
-{
- char *config_txt =
- "#\n"
- "# Calcurse configuration file\n#\n"
- "# This file sets the configuration options used by Calcurse. These\n"
- "# options are usually set from within Calcurse. A line beginning with \n"
- "# a space or tab is considered to be a continuation of the previous "
- "line.\n"
- "# For a variable to be unset its value must be blank.\n"
- "# To set a variable to the empty string its value should be \"\".\n"
- "# Lines beginning with \"#\" are comments, and ignored by Calcurse.\n";
- char theme_name[BUFSIZ];
- FILE *fp;
-
- if ((fp = fopen (path_conf, "w")) == NULL)
- return 0;
-
- custom_color_theme_name (theme_name);
-
- (void)fprintf (fp, "%s\n", config_txt);
-
- (void)fprintf (fp, "# If this option is set to yes, "
- "automatic save is done when quitting\n");
- (void)fprintf (fp, "auto_save=\n");
- (void)fprintf (fp, "%s\n", (conf->auto_save) ? "yes" : "no");
-
- (void)fprintf (fp, "\n# If not null, perform automatic saves every "
- "'periodic_save' minutes\n");
- (void)fprintf (fp, "periodic_save=\n");
- (void)fprintf (fp, "%d\n", conf->periodic_save);
-
- (void)fprintf (fp, "\n# If this option is set to yes, "
- "confirmation is required before quitting\n");
- (void)fprintf (fp, "confirm_quit=\n");
- (void)fprintf (fp, "%s\n", (conf->confirm_quit) ? "yes" : "no");
-
- (void)fprintf (fp, "\n# If this option is set to yes, "
- "confirmation is required before deleting an event\n");
- (void)fprintf (fp, "confirm_delete=\n");
- (void)fprintf (fp, "%s\n", (conf->confirm_delete) ? "yes" : "no");
-
- (void)fprintf (fp, "\n# If this option is set to yes, "
- "messages about loaded and saved data will not be displayed\n");
- (void)fprintf (fp, "skip_system_dialogs=\n");
- (void)fprintf (fp, "%s\n", (conf->skip_system_dialogs) ? "yes" : "no");
-
- (void)fprintf (fp,
- "\n# If this option is set to yes, progress bar appearing "
- "when saving data will not be displayed\n");
- (void)fprintf (fp, "skip_progress_bar=\n");
- (void)fprintf (fp, "%s\n", (conf->skip_progress_bar) ? "yes" : "no");
-
- (void)fprintf (fp, "\n# Default calendar view (0)monthly (1)weekly:\n");
- (void)fprintf (fp, "calendar_default_view=\n");
- (void)fprintf (fp, "%d\n", calendar_get_view ());
-
- (void)fprintf (fp, "\n# If this option is set to yes, "
- "monday is the first day of the week, else it is sunday\n");
- (void)fprintf (fp, "week_begins_on_monday=\n");
- (void)fprintf (fp, "%s\n",
- (calendar_week_begins_on_monday ())? "yes" : "no");
-
- (void)fprintf (fp, "\n# This is the color theme used for menus :\n");
- (void)fprintf (fp, "color-theme=\n");
- (void)fprintf (fp, "%s\n", theme_name);
-
- (void)fprintf (fp, "\n# This is the layout of the calendar :\n");
- (void)fprintf (fp, "layout=\n");
- (void)fprintf (fp, "%d\n", wins_layout ());
-
- (void)fprintf (fp, "\n# Width (in percentage, 0 being minimun width) "
- "of the side bar :\n");
- (void)fprintf (fp, "side-bar_width=\n");
- (void)fprintf (fp, "%d\n", wins_sbar_wperc ());
-
- if (ui_mode == UI_CURSES)
- pthread_mutex_lock (&nbar.mutex);
- (void)fprintf (fp,
- "\n# If this option is set to yes, "
- "notify-bar will be displayed :\n");
- (void)fprintf (fp, "notify-bar_show=\n");
- (void)fprintf (fp, "%s\n", (nbar.show) ? "yes" : "no");
-
- (void)fprintf (fp,
- "\n# Format of the date to be displayed inside notify-bar :\n");
- (void)fprintf (fp, "notify-bar_date=\n");
- (void)fprintf (fp, "%s\n", nbar.datefmt);
-
- (void)fprintf (fp,
- "\n# Format of the time to be displayed inside notify-bar :\n");
- (void)fprintf (fp, "notify-bar_clock=\n");
- (void)fprintf (fp, "%s\n", nbar.timefmt);
-
- (void)fprintf (fp,
- "\n# Warn user if he has an appointment within next "
- "'notify-bar_warning' seconds :\n");
- (void)fprintf (fp, "notify-bar_warning=\n");
- (void)fprintf (fp, "%d\n", nbar.cntdwn);
-
- (void)fprintf (fp, "\n# Command used to notify user of "
- "an upcoming appointment :\n");
- (void)fprintf (fp, "notify-bar_command=\n");
- (void)fprintf (fp, "%s\n", nbar.cmd);
-
- (void)fprintf (fp, "\n# Format of the date to be displayed "
- "in non-interactive mode :\n");
- (void)fprintf (fp, "output_datefmt=\n");
- (void)fprintf (fp, "%s\n", conf->output_datefmt);
-
- (void)fprintf (fp, "\n# Format to be used when entering a date "
- "(1)mm/dd/yyyy (2)dd/mm/yyyy (3)yyyy/mm/dd) "
- "(4)yyyy-mm-dd:\n");
- (void)fprintf (fp, "input_datefmt=\n");
- (void)fprintf (fp, "%d\n", conf->input_datefmt);
-
- if (ui_mode == UI_CURSES)
- pthread_mutex_unlock (&nbar.mutex);
-
- (void)fprintf (fp, "\n# If this option is set to yes, "
- "calcurse will run in background to get notifications "
- "after exiting\n");
- (void)fprintf (fp, "notify-daemon_enable=\n");
- (void)fprintf (fp, "%s\n", dmon.enable ? "yes" : "no");
-
- (void)fprintf (fp, "\n# If this option is set to yes, "
- "activity will be logged when running in background\n");
- (void)fprintf (fp, "notify-daemon_log=\n");
- (void)fprintf (fp, "%s\n", dmon.log ? "yes" : "no");
-
- file_close (fp, __FILE_POS__);
-
- return 1;
-}
-
/*
* Save the apts data file, which contains the
* appointments first, and then the events.
* Recursive items are written first.
*/
-unsigned
-io_save_apts (void)
+unsigned io_save_apts(void)
{
llist_item_t *i;
FILE *fp;
- if ((fp = fopen (path_apts, "w")) == NULL)
+ if (read_only)
+ return 1;
+
+ if ((fp = fopen(path_apts, "w")) == NULL)
return 0;
- recur_save_data (fp);
+ recur_save_data(fp);
if (ui_mode == UI_CURSES)
- LLIST_TS_LOCK (&alist_p);
- LLIST_TS_FOREACH (&alist_p, i)
- {
- struct apoint *apt = LLIST_TS_GET_DATA (i);
- apoint_write (apt, fp);
- }
+ LLIST_TS_LOCK(&alist_p);
+ LLIST_TS_FOREACH(&alist_p, i) {
+ struct apoint *apt = LLIST_TS_GET_DATA(i);
+ apoint_write(apt, fp);
+ }
if (ui_mode == UI_CURSES)
- LLIST_TS_UNLOCK (&alist_p);
+ LLIST_TS_UNLOCK(&alist_p);
- LLIST_FOREACH (&eventlist, i)
- {
- struct event *ev = LLIST_TS_GET_DATA (i);
- event_write (ev, fp);
- }
- file_close (fp, __FILE_POS__);
+ LLIST_FOREACH(&eventlist, i) {
+ struct event *ev = LLIST_TS_GET_DATA(i);
+ event_write(ev, fp);
+ }
+ file_close(fp, __FILE_POS__);
return 1;
}
/* Save the todo data file. */
-unsigned
-io_save_todo (void)
+unsigned io_save_todo(void)
{
llist_item_t *i;
FILE *fp;
- if ((fp = fopen (path_todo, "w")) == NULL)
+ if (read_only)
+ return 1;
+
+ if ((fp = fopen(path_todo, "w")) == NULL)
return 0;
- LLIST_FOREACH (&todolist, i)
- {
- struct todo *todo = LLIST_TS_GET_DATA (i);
- if (todo->note)
- (void)fprintf (fp, "[%d]>%s %s\n", todo->id, todo->note, todo->mesg);
- else
- (void)fprintf (fp, "[%d] %s\n", todo->id, todo->mesg);
- }
- file_close (fp, __FILE_POS__);
+ LLIST_FOREACH(&todolist, i) {
+ struct todo *todo = LLIST_TS_GET_DATA(i);
+ todo_write(todo, fp);
+ }
+ file_close(fp, __FILE_POS__);
return 1;
}
/* Save user-defined keys */
-unsigned
-io_save_keys (void)
+unsigned io_save_keys(void)
{
FILE *fp;
- if ((fp = fopen (path_keys, "w")) == NULL)
+ if (read_only)
+ return 1;
+
+ if ((fp = fopen(path_keys, "w")) == NULL)
return 0;
- keys_save_bindings (fp);
- file_close (fp, __FILE_POS__);
+ keys_save_bindings(fp);
+ file_close(fp, __FILE_POS__);
return 1;
}
/* Save the calendar data */
-void
-io_save_cal (struct conf *conf, enum save_display display)
+void io_save_cal(enum save_display display)
{
- char *access_pb = _("Problems accessing data file ...");
- char *save_success = _("The data files were successfully saved");
- char *enter = _("Press [ENTER] to continue");
+ const char *access_pb = _("Problems accessing data file ...");
+ const char *save_success = _("The data files were successfully saved");
+ const char *enter = _("Press [ENTER] to continue");
int show_bar;
- pthread_mutex_lock (&io_save_mutex);
+ if (read_only)
+ return;
+
+ pthread_mutex_lock(&io_save_mutex);
show_bar = 0;
if (ui_mode == UI_CURSES && display == IO_SAVE_DISPLAY_BAR
- && !conf->skip_progress_bar)
+ && conf.progress_bar)
show_bar = 1;
else if (ui_mode == UI_CURSES && display == IO_SAVE_DISPLAY_MARK)
- display_mark ();
+ display_mark();
if (show_bar)
- progress_bar (PROGRESS_BAR_SAVE, PROGRESS_BAR_CONF);
- if (!io_save_conf (conf))
- ERROR_MSG ("%s", access_pb);
+ progress_bar(PROGRESS_BAR_SAVE, PROGRESS_BAR_CONF);
+ if (!config_save())
+ ERROR_MSG("%s", access_pb);
if (show_bar)
- progress_bar (PROGRESS_BAR_SAVE, PROGRESS_BAR_TODO);
- if (!io_save_todo ())
- ERROR_MSG ("%s", access_pb);
+ progress_bar(PROGRESS_BAR_SAVE, PROGRESS_BAR_TODO);
+ if (!io_save_todo())
+ ERROR_MSG("%s", access_pb);
if (show_bar)
- progress_bar (PROGRESS_BAR_SAVE, PROGRESS_BAR_APTS);
- if (!io_save_apts ())
- ERROR_MSG ("%s", access_pb);
+ progress_bar(PROGRESS_BAR_SAVE, PROGRESS_BAR_APTS);
+ if (!io_save_apts())
+ ERROR_MSG("%s", access_pb);
if (show_bar)
- progress_bar (PROGRESS_BAR_SAVE, PROGRESS_BAR_KEYS);
- if (!io_save_keys ())
- ERROR_MSG ("%s", access_pb);
+ progress_bar(PROGRESS_BAR_SAVE, PROGRESS_BAR_KEYS);
+ if (!io_save_keys())
+ ERROR_MSG("%s", access_pb);
/* Print a message telling data were saved */
- if (ui_mode == UI_CURSES && !conf->skip_system_dialogs
- && display != IO_SAVE_DISPLAY_MARK)
- {
- status_mesg (save_success, enter);
- (void)wgetch (win[STA].p);
- }
+ if (ui_mode == UI_CURSES && conf.system_dialogs
+ && display != IO_SAVE_DISPLAY_MARK) {
+ status_mesg(save_success, enter);
+ wgetch(win[STA].p);
+ }
- pthread_mutex_unlock (&io_save_mutex);
+ pthread_mutex_unlock(&io_save_mutex);
}
/*
@@ -1107,8 +450,7 @@ io_save_cal (struct conf *conf, enum save_display display)
* and then load either: a new appointment, a new event, or a new
* recursive item (which can also be either an event or an appointment).
*/
-void
-io_load_app (void)
+void io_load_app(void)
{
FILE *data_file;
int c, is_appointment, is_event, is_recursive;
@@ -1118,251 +460,206 @@ io_load_app (void)
int id = 0;
int freq;
char type, state = 0L;
- char note[NOTESIZ + 1], *notep;
+ char note[MAX_NOTESIZ + 1], *notep;
- t = time (NULL);
- lt = localtime (&t);
+ t = time(NULL);
+ lt = localtime(&t);
start = end = until = *lt;
- data_file = fopen (path_apts, "r");
- for (;;)
- {
- LLIST_INIT (&exc);
- is_appointment = is_event = is_recursive = 0;
- c = getc (data_file);
- if (c == EOF)
- break;
- (void)ungetc (c, data_file);
-
- /* Read the date first: it is common to both events
- * and appointments.
- */
- if (fscanf (data_file, "%u / %u / %u ",
- &start.tm_mon, &start.tm_mday, &start.tm_year) != 3)
- {
- EXIT (_("syntax error in the item date"));
- }
-
- /* Read the next character : if it is an '@' then we have
- * an appointment, else if it is an '[' we have en event.
- */
- c = getc (data_file);
-
- if (c == '@')
- is_appointment = 1;
- else if (c == '[')
- is_event = 1;
- else
- {
- EXIT (_("no event nor appointment found"));
- }
- (void)ungetc (c, data_file);
-
- /* Read the remaining informations. */
- if (is_appointment)
- {
- fscanf (data_file, "@ %u : %u -> %u / %u / %u @ %u : %u ",
- &start.tm_hour, &start.tm_min,
- &end.tm_mon, &end.tm_mday, &end.tm_year,
- &end.tm_hour, &end.tm_min);
- }
- else if (is_event)
- {
- fscanf (data_file, "[%d] ", &id);
- }
- else
- {
- EXIT (_("wrong format in the appointment or event"));
- /* NOTREACHED */
- }
+ data_file = fopen(path_apts, "r");
+ EXIT_IF(data_file == NULL, _("failed to open appointment file"));
- /* Check if we have a recursive item. */
- c = getc (data_file);
-
- if (c == '{')
- {
- (void)ungetc (c, data_file);
- is_recursive = 1;
- fscanf (data_file, "{ %d%c ", &freq, &type);
-
- c = getc (data_file);
- if (c == '}')
- { /* endless recurrent item */
- (void)ungetc (c, data_file);
- fscanf (data_file, "} ");
- until.tm_year = 0;
- }
- else if (c == '-')
- {
- (void)ungetc (c, data_file);
- fscanf (data_file, " -> %u / %u / %u ",
- &until.tm_mon, &until.tm_mday, &until.tm_year);
- c = getc (data_file);
- if (c == '!')
- {
- (void)ungetc (c, data_file);
- recur_exc_scan (&exc, data_file);
- c = getc (data_file);
- }
- else
- {
- (void)ungetc (c, data_file);
- fscanf (data_file, "} ");
- }
- }
- else if (c == '!')
- { // endless item with exceptions
- (void)ungetc (c, data_file);
- recur_exc_scan (&exc, data_file);
- c = getc (data_file);
- until.tm_year = 0;
- }
- else
- {
- EXIT (_("wrong format in the appointment or event"));
- /* NOTREACHED */
- }
- }
- else
- (void)ungetc (c, data_file);
-
- /* Check if a note is attached to the item. */
- c = getc (data_file);
- if (c == '>')
- {
- (void)fgets (note, NOTESIZ + 1, data_file);
- note[NOTESIZ] = '\0';
- notep = note;
- getc (data_file);
- }
- else
- {
- notep = NULL;
- (void)ungetc (c, data_file);
- }
+ for (;;) {
+ LLIST_INIT(&exc);
+ is_appointment = is_event = is_recursive = 0;
+ c = getc(data_file);
+ if (c == EOF)
+ break;
+ ungetc(c, data_file);
+
+ /* Read the date first: it is common to both events
+ * and appointments.
+ */
+ if (fscanf(data_file, "%d / %d / %d ",
+ &start.tm_mon, &start.tm_mday, &start.tm_year) != 3)
+ EXIT(_("syntax error in the item date"));
+
+ /* Read the next character : if it is an '@' then we have
+ * an appointment, else if it is an '[' we have en event.
+ */
+ c = getc(data_file);
+
+ if (c == '@')
+ is_appointment = 1;
+ else if (c == '[')
+ is_event = 1;
+ else
+ EXIT(_("no event nor appointment found"));
+
+ /* Read the remaining informations. */
+ if (is_appointment) {
+ if (fscanf(data_file, " %d : %d -> %d / %d / %d @ %d : %d ",
+ &start.tm_hour, &start.tm_min,
+ &end.tm_mon, &end.tm_mday, &end.tm_year,
+ &end.tm_hour, &end.tm_min) != 7)
+ EXIT(_("syntax error in item time or duration"));
+ } else if (is_event) {
+ if (fscanf(data_file, " %d ", &id) != 1 || getc(data_file) != ']')
+ EXIT(_("syntax error in item identifier"));
+ while ((c = getc(data_file)) == ' ') ;
+ ungetc(c, data_file);
+ } else {
+ EXIT(_("wrong format in the appointment or event"));
+ /* NOTREACHED */
+ }
- /*
- * Last: read the item description and load it into its
- * corresponding linked list, depending on the item type.
- */
- if (is_appointment)
- {
- c = getc (data_file);
- if (c == '!')
- {
- (void)ungetc (c, data_file);
- fscanf (data_file, " ! ");
- state |= APOINT_NOTIFY;
- }
- else
- {
- (void)ungetc (c, data_file);
- fscanf (data_file, " | ");
- state = 0L;
- }
- if (is_recursive)
- {
- recur_apoint_scan (data_file, start, end,
- type, freq, until, notep, &exc, state);
- }
- else
- {
- apoint_scan (data_file, start, end, state, notep);
- }
- }
- else if (is_event)
- {
- if (is_recursive)
- {
- recur_event_scan (data_file, start, id, type,
- freq, until, notep, &exc);
- }
- else
- {
- event_scan (data_file, start, id, notep);
- }
- }
- else
- {
- EXIT (_("wrong format in the appointment or event"));
- /* NOTREACHED */
- }
+ /* Check if we have a recursive item. */
+ c = getc(data_file);
+
+ if (c == '{') {
+ is_recursive = 1;
+ if (fscanf(data_file, " %d%c ", &freq, &type) != 2)
+ EXIT(_("syntax error in item repetition"));
+
+ c = getc(data_file);
+ if (c == '}') { /* endless recurrent item */
+ until.tm_year = 0;
+ while ((c = getc(data_file)) == ' ') ;
+ ungetc(c, data_file);
+ } else if (c == '-' && getc(data_file) == '>') {
+ if (fscanf(data_file, " %d / %d / %d ", &until.tm_mon,
+ &until.tm_mday, &until.tm_year) != 3)
+ EXIT(_("syntax error in item repetition"));
+ c = getc(data_file);
+ if (c == '!') {
+ ungetc(c, data_file);
+ recur_exc_scan(&exc, data_file);
+ c = getc(data_file);
+ } else if (c == '}') {
+ while ((c = getc(data_file)) == ' ') ;
+ ungetc(c, data_file);
+ } else
+ EXIT(_("syntax error in item repetition"));
+ } else if (c == '!') { /* endless item with exceptions */
+ ungetc(c, data_file);
+ recur_exc_scan(&exc, data_file);
+ c = getc(data_file);
+ until.tm_year = 0;
+ } else {
+ EXIT(_("wrong format in the appointment or event"));
+ /* NOTREACHED */
+ }
+ } else
+ ungetc(c, data_file);
+
+ /* Check if a note is attached to the item. */
+ c = getc(data_file);
+ if (c == '>') {
+ note_read(note, data_file);
+ notep = note;
+ } else {
+ notep = NULL;
+ ungetc(c, data_file);
+ }
+
+ /*
+ * Last: read the item description and load it into its
+ * corresponding linked list, depending on the item type.
+ */
+ if (is_appointment) {
+ c = getc(data_file);
+ if (c == '!') {
+ state |= APOINT_NOTIFY;
+ while ((c = getc(data_file)) == ' ') ;
+ ungetc(c, data_file);
+ } else if (c == '|') {
+ state = 0L;
+ while ((c = getc(data_file)) == ' ') ;
+ ungetc(c, data_file);
+ } else
+ EXIT(_("syntax error in item repetition"));
+ if (is_recursive) {
+ recur_apoint_scan(data_file, start, end,
+ type, freq, until, notep, &exc, state);
+ } else {
+ apoint_scan(data_file, start, end, state, notep);
+ }
+ } else if (is_event) {
+ if (is_recursive) {
+ recur_event_scan(data_file, start, id, type, freq, until, notep, &exc);
+ } else {
+ event_scan(data_file, start, id, notep);
+ }
+ } else {
+ EXIT(_("wrong format in the appointment or event"));
+ /* NOTREACHED */
}
- file_close (data_file, __FILE_POS__);
+ }
+ file_close(data_file, __FILE_POS__);
}
/* Load the todo data */
-void
-io_load_todo (void)
+void io_load_todo(void)
{
FILE *data_file;
- char *mesg_line1 = _("Failed to open todo file");
- char *mesg_line2 = _("Press [ENTER] to continue");
char *newline;
int nb_tod = 0;
int c, id;
- char buf[BUFSIZ], e_todo[BUFSIZ], note[NOTESIZ + 1];
+ char buf[BUFSIZ], e_todo[BUFSIZ], note[MAX_NOTESIZ + 1];
- data_file = fopen (path_todo, "r");
- if (data_file == NULL)
- {
- status_mesg (mesg_line1, mesg_line2);
- (void)wgetch (win[STA].p);
- }
- for (;;)
- {
- c = getc (data_file);
- if (c == EOF)
- {
- break;
- }
- else if (c == '[')
- { /* new style with id */
- fscanf (data_file, "%d]", &id);
- }
- else
- {
- id = 9;
- (void)ungetc (c, data_file);
- }
- /* Now read the attached note, if any. */
- c = getc (data_file);
- if (c == '>')
- {
- (void)fgets (note, NOTESIZ + 1, data_file);
- note[NOTESIZ] = '\0';
- getc (data_file);
- }
- else
- note[0] = '\0';
- /* Then read todo description. */
- (void)fgets (buf, sizeof buf, data_file);
- newline = strchr (buf, '\n');
- if (newline)
- *newline = '\0';
- io_extract_data (e_todo, buf, sizeof buf);
- todo_add (e_todo, id, note);
- ++nb_tod;
- }
- file_close (data_file, __FILE_POS__);
- todo_set_nb (nb_tod);
+ data_file = fopen(path_todo, "r");
+ EXIT_IF(data_file == NULL, _("failed to open todo file"));
+
+ for (;;) {
+ c = getc(data_file);
+ if (c == EOF)
+ break;
+ else if (c == '[') { /* new style with id */
+ if (fscanf(data_file, " %d ", &id) != 1 || getc(data_file) != ']')
+ EXIT(_("syntax error in item identifier"));
+ while ((c = getc(data_file)) == ' ') ;
+ ungetc(c, data_file);
+ } else {
+ id = 9;
+ ungetc(c, data_file);
+ }
+ /* Now read the attached note, if any. */
+ c = getc(data_file);
+ if (c == '>')
+ note_read(note, data_file);
+ else {
+ note[0] = '\0';
+ ungetc(c, data_file);
+ }
+ /* Then read todo description. */
+ if (!fgets(buf, sizeof buf, data_file))
+ buf[0] = '\0';
+ newline = strchr(buf, '\n');
+ if (newline)
+ *newline = '\0';
+ io_extract_data(e_todo, buf, sizeof buf);
+ todo_add(e_todo, id, note);
+ ++nb_tod;
+ }
+ file_close(data_file, __FILE_POS__);
+ todo_set_nb(nb_tod);
}
static void
-load_keys_ht_getkey (struct ht_keybindings_s *data, char **key, int *len)
+load_keys_ht_getkey(struct ht_keybindings_s *data, const char **key, int *len)
{
*key = data->label;
- *len = strlen (data->label);
+ *len = strlen(data->label);
}
static int
-load_keys_ht_compare (struct ht_keybindings_s *data1,
- struct ht_keybindings_s *data2)
+load_keys_ht_compare(struct ht_keybindings_s *data1,
+ struct ht_keybindings_s *data2)
{
- const int KEYLEN = strlen (data1->label);
+ const int KEYLEN = strlen(data1->label);
- if (strlen (data2->label) == KEYLEN
- && !memcmp (data1->label, data2->label, KEYLEN))
+ if (strlen(data2->label) == KEYLEN
+ && !memcmp(data1->label, data2->label, KEYLEN))
return 0;
else
return 1;
@@ -1373,7 +670,7 @@ load_keys_ht_compare (struct ht_keybindings_s *data1,
* visible in some specific cases. Thus replace it by the following is_blank()
* function.
*/
-static int is_blank (int c)
+static int is_blank(int c)
{
return c == ' ' || c == '\t';
}
@@ -1385,8 +682,7 @@ static int is_blank (int c)
* A log file is also built in case some errors were found in the key
* configuration file.
*/
-void
-io_load_keys (char *pager)
+void io_load_keys(const char *pager)
{
struct ht_keybindings_s keys[NBKEYS];
FILE *keyfp;
@@ -1395,187 +691,163 @@ io_load_keys (char *pager)
int i, skipped, loaded, line;
const int MAX_ERRORS = 5;
- keys_init ();
+ keys_init();
-#define HSIZE 256
- HTABLE_HEAD (ht_keybindings, HSIZE, ht_keybindings_s) ht_keys =
- HTABLE_INITIALIZER (&ht_keys);
+ struct ht_keybindings ht_keys = HTABLE_INITIALIZER(&ht_keys);
- HTABLE_GENERATE (ht_keybindings, ht_keybindings_s, load_keys_ht_getkey,
- load_keys_ht_compare);
+ for (i = 0; i < NBKEYS; i++) {
+ keys[i].key = (enum key)i;
+ keys[i].label = keys_get_label((enum key)i);
+ HTABLE_INSERT(ht_keybindings, &ht_keys, &keys[i]);
+ }
- for (i = 0; i < NBKEYS; i++)
- {
- keys[i].key = (enum key)i;
- keys[i].label = keys_get_label ((enum key)i);
- HTABLE_INSERT (ht_keybindings, &ht_keys, &keys[i]);
- }
+ keyfp = fopen(path_keys, "r");
+ EXIT_IF(keyfp == NULL, _("failed to open key file"));
- keyfp = fopen (path_keys, "r");
- EXIT_IF (keyfp == NULL, _("could not find any key file."));
- log = io_log_init ();
+ log = io_log_init();
skipped = loaded = line = 0;
- while (fgets (buf, BUFSIZ, keyfp) != NULL)
- {
- char key_label[BUFSIZ], *p;
- struct ht_keybindings_s *ht_elm, ht_entry;
- const int AWAITED = 1;
- int assigned;
-
- line++;
- if (skipped > MAX_ERRORS)
- {
- char *too_many =
- _("\nToo many errors while reading configuration file!\n"
- "Please backup your keys file, remove it from directory, "
- "and launch calcurse again.\n");
-
- io_log_print (log, line, too_many);
- break;
- }
- for (p = buf; is_blank ((int)*p); p++)
- ;
- if (p != buf)
- memmove (buf, p, strlen (p));
- if (buf[0] == '#' || buf[0] == '\n')
- continue;
-
- if (sscanf (buf, "%s", key_label) != AWAITED)
- {
- skipped++;
- io_log_print (log, line, _("Could not read key label"));
- continue;
- }
- ht_entry.label = key_label;
- p = buf + strlen (key_label) + 1;
- ht_elm = HTABLE_LOOKUP (ht_keybindings, &ht_keys, &ht_entry);
- if (!ht_elm)
- {
+ while (fgets(buf, BUFSIZ, keyfp) != NULL) {
+ char key_label[BUFSIZ], *p;
+ struct ht_keybindings_s *ht_elm, ht_entry;
+ const int AWAITED = 1;
+ int assigned;
+
+ line++;
+ if (skipped > MAX_ERRORS) {
+ const char *too_many =
+ _("\nToo many errors while reading configuration file!\n"
+ "Please backup your keys file, remove it from directory, "
+ "and launch calcurse again.\n");
+
+ io_log_print(log, line, too_many);
+ break;
+ }
+ for (p = buf; is_blank((int)*p); p++) ;
+ if (p != buf)
+ memmove(buf, p, strlen(p));
+ if (buf[0] == '#' || buf[0] == '\n')
+ continue;
+
+ if (sscanf(buf, "%s", key_label) != AWAITED) {
+ skipped++;
+ io_log_print(log, line, _("Could not read key label"));
+ continue;
+ }
+ ht_entry.label = key_label;
+ p = buf + strlen(key_label) + 1;
+ ht_elm = HTABLE_LOOKUP(ht_keybindings, &ht_keys, &ht_entry);
+ if (!ht_elm) {
+ skipped++;
+ io_log_print(log, line, _("Key label not recognized"));
+ continue;
+ }
+ assigned = 0;
+ for (;;) {
+ char key_ch[BUFSIZ], tmpbuf[BUFSIZ];
+
+ while (*p == ' ')
+ p++;
+ (void)strncpy(tmpbuf, p, BUFSIZ);
+ if (sscanf(tmpbuf, "%s", key_ch) == AWAITED) {
+ int ch;
+
+ if ((ch = keys_str2int(key_ch)) < 0) {
+ char unknown_key[BUFSIZ];
+
skipped++;
- io_log_print (log, line, _("Key label not recognized"));
- continue;
- }
- assigned = 0;
- for (;;)
- {
- char key_ch[BUFSIZ], tmpbuf[BUFSIZ];
-
- while (*p == ' ')
- p++;
- (void)strncpy (tmpbuf, p, BUFSIZ);
- if (sscanf (tmpbuf, "%s", key_ch) == AWAITED)
- {
- int ch;
-
- if ((ch = keys_str2int (key_ch)) < 0)
- {
- char unknown_key[BUFSIZ];
-
- skipped++;
- (void)snprintf (unknown_key, BUFSIZ,
- _("Error reading key: \"%s\""), key_ch);
- io_log_print (log, line, unknown_key);
- }
- else
- {
- int used;
-
- used = keys_assign_binding (ch, ht_elm->key);
- if (used)
- {
- char already_assigned[BUFSIZ];
-
- skipped++;
- (void)snprintf (already_assigned, BUFSIZ,
- _("\"%s\" assigned multiple times!"), key_ch);
- io_log_print (log, line, already_assigned);
- }
- else
- assigned++;
- }
- p += strlen (key_ch) + 1;
- }
- else
- {
- if (assigned)
- loaded++;
- break;
- }
- }
+ (void)snprintf(unknown_key, BUFSIZ,
+ _("Error reading key: \"%s\""), key_ch);
+ io_log_print(log, line, unknown_key);
+ } else {
+ int used;
+
+ used = keys_assign_binding(ch, ht_elm->key);
+ if (used) {
+ char already_assigned[BUFSIZ];
+
+ skipped++;
+ (void)snprintf(already_assigned, BUFSIZ,
+ _("\"%s\" assigned multiple times!"), key_ch);
+ io_log_print(log, line, already_assigned);
+ } else
+ assigned++;
+ }
+ p += strlen(key_ch) + 1;
+ } else {
+ if (assigned)
+ loaded++;
+ break;
+ }
}
- file_close (keyfp, __FILE_POS__);
- file_close (log->fd, __FILE_POS__);
- if (skipped > 0)
- {
- char *view_log =
+ }
+ file_close(keyfp, __FILE_POS__);
+ file_close(log->fd, __FILE_POS__);
+ if (skipped > 0) {
+ const char *view_log =
_("There were some errors when loading keys file, see log file ?");
- io_log_display (log, view_log, pager);
- }
- io_log_free (log);
- EXIT_IF (skipped > MAX_ERRORS,
- _("Too many errors while reading keys file, aborting..."));
+ io_log_display(log, view_log, pager);
+ }
+ io_log_free(log);
+ EXIT_IF(skipped > MAX_ERRORS,
+ _("Too many errors while reading keys file, aborting..."));
if (loaded < NBKEYS)
- keys_fill_missing ();
- if (keys_check_missing_bindings ())
- WARN_MSG (_("Some actions do not have any associated key bindings!"));
-#undef HSIZE
+ keys_fill_missing();
+ if (keys_check_missing_bindings())
+ WARN_MSG(_("Some actions do not have any associated key bindings!"));
}
-void
-io_check_dir (char *dir, int *missing)
+void io_check_dir(char *dir, int *missing)
{
+ if (read_only)
+ return;
+
errno = 0;
- if (mkdir (dir, 0700) != 0)
- {
- if (errno != EEXIST)
- {
- (void)fprintf (stderr, _("FATAL ERROR: could not create %s: %s\n"),
- dir, strerror (errno));
- exit_calcurse (EXIT_FAILURE);
- }
- }
- else
- {
- if (missing)
- (*missing)++;
+ if (mkdir(dir, 0700) != 0) {
+ if (errno != EEXIST) {
+ fprintf(stderr, _("FATAL ERROR: could not create %s: %s\n"), dir,
+ strerror(errno));
+ exit_calcurse(EXIT_FAILURE);
}
+ } else {
+ if (missing)
+ (*missing)++;
+ }
}
-unsigned
-io_file_exist (char *file)
+unsigned io_file_exist(char *file)
{
FILE *fd;
if (!file)
return 0;
- if ((fd = fopen (file, "r")) == NULL)
+ if ((fd = fopen(file, "r")) == NULL)
return 0;
- (void)fclose (fd);
+ fclose(fd);
return 1;
}
-void
-io_check_file (char *file, int *missing)
+void io_check_file(char *file, int *missing)
{
+ if (read_only)
+ return;
+
errno = 0;
- if (!io_file_exist (file))
- {
- FILE *fd;
-
- if (missing)
- (*missing)++;
- if ((fd = fopen (file, "w")) == NULL)
- {
- (void)fprintf (stderr, _("FATAL ERROR: could not create %s: %s\n"),
- file, strerror (errno));
- exit_calcurse (EXIT_FAILURE);
- }
- file_close (fd, __FILE_POS__);
+ if (!io_file_exist(file)) {
+ FILE *fd;
+
+ if (missing)
+ (*missing)++;
+ if ((fd = fopen(file, "w")) == NULL) {
+ fprintf(stderr, _("FATAL ERROR: could not create %s: %s\n"), file,
+ strerror(errno));
+ exit_calcurse(EXIT_FAILURE);
}
+ file_close(fd, __FILE_POS__);
+ }
}
/*
@@ -1590,1121 +862,127 @@ io_check_file (char *file, int *missing)
* |___ apts
* |___ todo
*/
-int
-io_check_data_files (void)
+int io_check_data_files(void)
{
int missing, missing_keys;
missing = missing_keys = 0;
errno = 0;
- io_check_dir (path_dir, &missing);
- io_check_dir (path_notes, &missing);
- io_check_file (path_todo, &missing);
- io_check_file (path_apts, &missing);
- io_check_file (path_conf, &missing);
- io_check_file (path_keys, &missing_keys);
- if (missing_keys)
- {
- missing++;
- keys_dump_defaults (path_keys);
- }
+ io_check_dir(path_dir, &missing);
+ io_check_dir(path_notes, &missing);
+ io_check_file(path_todo, &missing);
+ io_check_file(path_apts, &missing);
+ io_check_file(path_conf, &missing);
+ io_check_file(path_keys, &missing_keys);
+ if (missing_keys) {
+ missing++;
+ keys_dump_defaults(path_keys);
+ }
return missing;
}
/* Draw the startup screen */
-void
-io_startup_screen (unsigned skip_dialogs, int no_data_file)
+void io_startup_screen(int no_data_file)
{
- char *welcome_mesg =
- _("Welcome to Calcurse. Missing data files were created.");
- char *data_mesg = _("Data files found. Data will be loaded now.");
- char *enter = _("Press [ENTER] to continue");
-
- if (no_data_file != 0)
- {
- status_mesg (welcome_mesg, enter);
- (void)wgetch (win[STA].p);
- }
- else if (!skip_dialogs)
- {
- status_mesg (data_mesg, enter);
- (void)wgetch (win[STA].p);
- }
+ const char *enter = _("Press [ENTER] to continue");
+
+ if (no_data_file)
+ status_mesg(_("Data files found. Data will be loaded now."), enter);
+ else
+ status_mesg(_("Welcome to Calcurse. Missing data files were created."),
+ enter);
+
+ wgetch(win[STA].p);
}
/* Export calcurse data. */
-void
-io_export_data (enum export_type type, struct conf *conf)
+void io_export_data(enum export_type type)
{
FILE *stream;
- char *success = _("The data were successfully exported");
- char *enter = _("Press [ENTER] to continue");
+ const char *success = _("The data were successfully exported");
+ const char *enter = _("Press [ENTER] to continue");
if (type < IO_EXPORT_ICAL || type >= IO_EXPORT_NBTYPES)
- EXIT (_("unknown export type"));
+ EXIT(_("unknown export type"));
stream = 0;
- switch (ui_mode)
- {
- case UI_CMDLINE:
- stream = stdout;
- break;
- case UI_CURSES:
- stream = get_export_stream (type);
- break;
- default:
- EXIT (_("wrong export mode"));
- /* NOTREACHED */
- }
+ switch (ui_mode) {
+ case UI_CMDLINE:
+ stream = stdout;
+ break;
+ case UI_CURSES:
+ stream = get_export_stream(type);
+ break;
+ default:
+ EXIT(_("wrong export mode"));
+ /* NOTREACHED */
+ }
if (stream == NULL)
return;
- cb_export_header[type] (stream);
-
- if (!conf->skip_progress_bar && ui_mode == UI_CURSES)
- progress_bar (PROGRESS_BAR_EXPORT, PROGRESS_BAR_EXPORT_EVENTS);
- cb_export_recur_events[type] (stream);
- cb_export_events[type] (stream);
-
- if (!conf->skip_progress_bar && ui_mode == UI_CURSES)
- progress_bar (PROGRESS_BAR_EXPORT, PROGRESS_BAR_EXPORT_APOINTS);
- cb_export_recur_apoints[type] (stream);
- cb_export_apoints[type] (stream);
+ if (type == IO_EXPORT_ICAL)
+ ical_export_data(stream);
+ else if (type == IO_EXPORT_PCAL)
+ pcal_export_data(stream);
- if (!conf->skip_progress_bar && ui_mode == UI_CURSES)
- progress_bar (PROGRESS_BAR_EXPORT, PROGRESS_BAR_EXPORT_TODO);
- cb_export_todo[type] (stream);
-
- cb_export_footer[type] (stream);
-
- if (stream != stdout)
- file_close (stream, __FILE_POS__);
-
- if (!conf->skip_system_dialogs && ui_mode == UI_CURSES)
- {
- status_mesg (success, enter);
- (void)wgetch (win[STA].p);
- }
+ if (conf.system_dialogs && ui_mode == UI_CURSES) {
+ status_mesg(success, enter);
+ wgetch(win[STA].p);
+ }
}
/* Draws the export format selection bar */
-void
-io_export_bar (void)
+void io_export_bar(void)
{
int smlspc, spc;
smlspc = 2;
spc = 15;
- custom_apply_attr (win[STA].p, ATTR_HIGHEST);
- mvwprintw (win[STA].p, 0, 2, "Q");
- mvwprintw (win[STA].p, 1, 2, "I");
- mvwprintw (win[STA].p, 0, 2 + spc, "P");
- custom_remove_attr (win[STA].p, ATTR_HIGHEST);
-
- mvwprintw (win[STA].p, 0, 2 + smlspc, _("Exit"));
- mvwprintw (win[STA].p, 1, 2 + smlspc, _("Ical"));
- mvwprintw (win[STA].p, 0, 2 + spc + smlspc, _("Pcal"));
-
- wnoutrefresh (win[STA].p);
- wmove (win[STA].p, 0, 0);
- wins_doupdate ();
-}
-
-/* Print a header to describe import log report format. */
-static void
-ical_log_init (FILE *log, float version)
-{
- const char *header =
- "+-------------------------------------------------------------------+\n"
- "| Calcurse icalendar import log. |\n"
- "| |\n"
- "| Items imported from icalendar file, version %1.1f |\n"
- "| Some items could not be imported, they are described hereafter. |\n"
- "| The log line format is as follows: |\n"
- "| |\n"
- "| TYPE [LINE]: DESCRIPTION |\n"
- "| |\n"
- "| where: |\n"
- "| * TYPE represents the item type ('VEVENT' or 'VTODO') |\n"
- "| * LINE is the line in the input stream at which this item begins |\n"
- "| * DESCRIPTION indicates why the item could not be imported |\n"
- "+-------------------------------------------------------------------+\n\n";
-
- if (log)
- (void)fprintf (log, header, version);
-}
-
-/*
- * Used to build a report of the import process.
- * The icalendar item for which a problem occurs is mentioned (by giving its
- * first line inside the icalendar file), together with a message describing the
- * problem.
- */
-static void
-ical_log (FILE *log, ical_types_e type, unsigned lineno, char *msg)
-{
- const char *typestr[ICAL_TYPES] = {"VEVENT", "VTODO"};
-
- RETURN_IF (type < 0 || type >= ICAL_TYPES, _("unknown ical type"));
- if (log)
- (void)fprintf (log, "%s [%d]: %s\n", typestr[type], lineno, msg);
-}
-
-static void
-ical_store_todo (int priority, char *mesg, char *note)
-{
- todo_add (mesg, priority, note);
- mem_free (mesg);
- erase_note (&note, ERASE_FORCE_KEEP_NOTE);
-}
-
-static void
-ical_store_event (char *mesg, char *note, long day, long end, ical_rpt_t *rpt,
- llist_t *exc)
-{
- const int EVENTID = 1;
-
- if (rpt)
- {
- recur_event_new (mesg, note, day, EVENTID, rpt->type, rpt->freq,
- rpt->until, exc);
- mem_free (rpt);
- }
- else if (end && end != day)
- {
- /* Here we have an event that spans over several days. */
- rpt = mem_malloc (sizeof (ical_rpt_t));
- rpt->type = RECUR_DAILY;
- rpt->freq = 1;
- rpt->count = 0;
- rpt->until = end;
- recur_event_new (mesg, note, day, EVENTID, rpt->type, rpt->freq,
- rpt->until, exc);
- mem_free (rpt);
- }
- else
- {
- event_new (mesg, note, day, EVENTID);
- }
- mem_free (mesg);
- erase_note (&note, ERASE_FORCE_KEEP_NOTE);
-}
-
-static void
-ical_store_apoint (char *mesg, char *note, long start, long dur,
- ical_rpt_t *rpt, llist_t *exc, int has_alarm)
-{
- char state = 0L;
-
- if (has_alarm)
- state |= APOINT_NOTIFY;
- if (rpt)
- {
- recur_apoint_new (mesg, note, start, dur, state, rpt->type, rpt->freq,
- rpt->until, exc);
- mem_free (rpt);
- }
- else
- {
- apoint_new (mesg, note, start, dur, state);
- }
- mem_free (mesg);
- erase_note (&note, ERASE_FORCE_KEEP_NOTE);
-}
-
-/*
- * Returns an allocated string representing the string given in argument once
- * unformatted.
- *
- * Note:
- * Even if the RFC2445 recommends not to have more than 75 octets on one line of
- * text, I prefer not to restrict the parsing to this size, thus I use a buffer
- * of size BUFSIZ.
- *
- * Extract from RFC2445:
- * Lines of text SHOULD NOT be longer than 75 octets, excluding the line
- * break.
- */
-static char *
-ical_unformat_line (char *line)
-{
- char *p, uline[BUFSIZ];
- int len;
-
- if (strlen (line) >= BUFSIZ)
- return NULL;
-
- bzero (uline, BUFSIZ);
- for (len = 0, p = line; *p; p++)
- {
- switch (*p)
- {
- case '\\':
- switch (*(p + 1))
- {
- case 'n':
- uline[len++] = '\n';
- p++;
- break;
- case 't':
- uline[len++] = '\t';
- p++;
- break;
- case ';':
- case ':':
- case ',':
- uline[len++] = *(p + 1);
- p++;
- break;
- default:
- uline[len++] = *p;
- break;
- }
- break;
- default:
- uline[len++] = *p;
- break;
- }
- }
-
- return mem_strdup (uline);
-}
-
-static void
-ical_readline_init (FILE *fdi, char *buf, char *lstore, unsigned *ln)
-{
- char *eol;
-
- *buf = *lstore = '\0';
- fgets (lstore, BUFSIZ, fdi);
- if ((eol = strchr(lstore, '\n')) != NULL)
- *eol = '\0';
- (*ln)++;
-}
-
-static int
-ical_readline (FILE *fdi, char *buf, char *lstore, unsigned *ln)
-{
- char *eol;
-
- strncpy (buf, lstore, BUFSIZ);
- (*ln)++;
-
- while (fgets (lstore, BUFSIZ, fdi) != NULL)
- {
- if ((eol = strchr(lstore, '\n')) != NULL)
- *eol = '\0';
- if (*lstore != SPACE && *lstore != TAB)
- break;
- strncat (buf, lstore + 1, BUFSIZ);
- buf[BUFSIZ - 1] = '\0';
- (*ln)++;
- }
-
- if (feof (fdi))
- {
- *lstore = '\0';
- if (*buf == '\0')
- return 0;
- }
-
- return 1;
-}
-
-static float
-ical_chk_header (FILE *fd, char *buf, char *lstore, unsigned *lineno)
-{
- const int HEADER_MALFORMED = -1;
- const struct string icalheader = STRING_BUILD ("BEGIN:VCALENDAR");
- float version;
-
- if (!ical_readline (fd, buf, lstore, lineno))
- return HEADER_MALFORMED;
-
- str_toupper (buf);
- if (strncmp (buf, icalheader.str, icalheader.len) != 0)
- return HEADER_MALFORMED;
-
- while (!sscanf (buf, "VERSION:%f", &version))
- {
- if (!ical_readline (fd, buf, lstore, lineno))
- return HEADER_MALFORMED;
- }
- return version;
-}
-
-/*
- * iCalendar date-time format is based on the ISO 8601 complete
- * representation. It should be something like : DATE 'T' TIME
- * where DATE is 'YYYYMMDD' and TIME is 'HHMMSS'.
- * The time and 'T' separator are optional (in the case of an day-long event).
- *
- * Optionnaly, if the type pointer is given, specify if it is an event
- * (no time is given, meaning it is an all-day event), or an appointment
- * (time is given).
- *
- * The timezone is not yet handled by calcurse.
- */
-static long
-ical_datetime2long (char *datestr, ical_vevent_e *type)
-{
- const int NOTFOUND = 0, FORMAT_DATE = 3, FORMAT_DATETIME = 5;
- struct date date;
- unsigned hour, min;
- long datelong;
- int format;
-
- format = sscanf (datestr, "%04u%02u%02uT%02u%02u",
- &date.yyyy, &date.mm, &date.dd, &hour, &min);
- if (format == FORMAT_DATE)
- {
- if (type)
- *type = EVENT;
- datelong = date2sec (date, 0, 0);
- }
- else if (format == FORMAT_DATETIME)
- {
- if (type)
- *type = APPOINTMENT;
- datelong = date2sec (date, hour, min);
- }
- else
- {
- datelong = NOTFOUND;
- }
- return datelong;
-}
-
-static long
-ical_durtime2long (char *timestr)
-{
- long timelong;
- char *p;
-
- if ((p = strchr (timestr, 'T')) == NULL)
- timelong = 0;
- else
- {
- int nbmatch;
- struct {
- unsigned hour, min, sec;
- } time;
-
- p++;
- bzero (&time, sizeof time);
- nbmatch = sscanf (p, "%uH%uM%uS", &time.hour, &time.min, &time.sec);
- if (nbmatch < 1 || nbmatch > 3)
- timelong = 0;
- else
- timelong = time.hour * HOURINSEC + time.min * MININSEC + time.sec;
- }
- return timelong;
-}
-
-/*
- * Extract from RFC2445:
- *
- * Value Name: DURATION
- *
- * Purpose: This value type is used to identify properties that contain
- * duration of time.
- *
- * Formal Definition: The value type is defined by the following
- * notation:
- *
- * dur-value = (["+"] / "-") "P" (dur-date / dur-time / dur-week)
- * dur-date = dur-day [dur-time]
- * dur-time = "T" (dur-hour / dur-minute / dur-second)
- * dur-week = 1*DIGIT "W"
- * dur-hour = 1*DIGIT "H" [dur-minute]
- * dur-minute = 1*DIGIT "M" [dur-second]
- * dur-second = 1*DIGIT "S"
- * dur-day = 1*DIGIT "D"
- *
- * Example: A duration of 15 days, 5 hours and 20 seconds would be:
- * P15DT5H0M20S
- * A duration of 7 weeks would be:
- * P7W
- */
-static long
-ical_dur2long (char *durstr)
-{
- const int NOTFOUND = -1;
- long durlong;
- char *p;
- struct {
- unsigned week, day;
- } date;
-
- bzero (&date, sizeof date);
- if ((p = strchr (durstr, 'P')) == NULL)
- durlong = NOTFOUND;
- else
- {
- p++;
- if (*p == '-')
- return NOTFOUND;
- else if (*p == '+')
- p++;
-
- if (*p == 'T') /* dur-time */
- durlong = ical_durtime2long (p);
- else if (strchr (p, 'W')) /* dur-week */
- {
- if (sscanf (p, "%u", &date.week) == 1)
- durlong = date.week * WEEKINDAYS * DAYINSEC;
- else
- durlong = NOTFOUND;
- }
- else
- {
- if (strchr (p, 'D')) /* dur-date */
- {
- if (sscanf (p, "%uD", &date.day) == 1)
- {
- durlong = date.day * DAYINSEC;
- durlong += ical_durtime2long (p);
- }
- else
- durlong = NOTFOUND;
- }
- else
- durlong = NOTFOUND;
- }
- }
- return durlong;
-}
-
-/*
- * Compute the vevent repetition end date from the repetition count.
- *
- * Extract from RFC2445:
- * The COUNT rule part defines the number of occurrences at which to
- * range-bound the recurrence. The "DTSTART" property value, if specified,
- * counts as the first occurrence.
- */
-static long
-ical_compute_rpt_until (long start, ical_rpt_t *rpt)
-{
- long until;
-
- switch (rpt->type)
- {
- case RECUR_DAILY:
- until = date_sec_change (start, 0, rpt->freq * (rpt->count - 1));
- break;
- case RECUR_WEEKLY:
- until = date_sec_change (start, 0,
- rpt->freq * WEEKINDAYS * (rpt->count - 1));
- break;
- case RECUR_MONTHLY:
- until = date_sec_change (start, rpt->freq * (rpt->count - 1), 0);
- break;
- case RECUR_YEARLY:
- until = date_sec_change (start, rpt->freq * 12 * (rpt->count - 1), 0);
- break;
- default:
- until = 0;
- break;
- /* NOTREACHED */
- }
- return until;
-}
-
-/*
- * Read a recurrence rule from an iCalendar RRULE string.
- *
- * Value Name: RECUR
- *
- * Purpose: This value type is used to identify properties that contain
- * a recurrence rule specification.
- *
- * Formal Definition: The value type is defined by the following
- * notation:
- *
- * recur = "FREQ"=freq *(
- *
- * ; either UNTIL or COUNT may appear in a 'recur',
- * ; but UNTIL and COUNT MUST NOT occur in the same 'recur'
- *
- * ( ";" "UNTIL" "=" enddate ) /
- * ( ";" "COUNT" "=" 1*DIGIT ) /
- *
- * ; the rest of these keywords are optional,
- * ; but MUST NOT occur more than
- * ; once
- *
- * ( ";" "INTERVAL" "=" 1*DIGIT ) /
- * ( ";" "BYSECOND" "=" byseclist ) /
- * ( ";" "BYMINUTE" "=" byminlist ) /
- * ( ";" "BYHOUR" "=" byhrlist ) /
- * ( ";" "BYDAY" "=" bywdaylist ) /
- * ( ";" "BYMONTHDAY" "=" bymodaylist ) /
- * ( ";" "BYYEARDAY" "=" byyrdaylist ) /
- * ( ";" "BYWEEKNO" "=" bywknolist ) /
- * ( ";" "BYMONTH" "=" bymolist ) /
- * ( ";" "BYSETPOS" "=" bysplist ) /
- * ( ";" "WKST" "=" weekday ) /
- * ( ";" x-name "=" text )
- * )
-*/
-static ical_rpt_t *
-ical_read_rrule (FILE *log, char *rrulestr, unsigned *noskipped,
- const int itemline)
-{
- const struct string daily = STRING_BUILD ("DAILY");
- const struct string weekly = STRING_BUILD ("WEEKLY");
- const struct string monthly = STRING_BUILD ("MONTHLY");
- const struct string yearly = STRING_BUILD ("YEARLY");
- const struct string count = STRING_BUILD ("COUNT=");
- const struct string interv = STRING_BUILD ("INTERVAL=");
- unsigned interval;
- ical_rpt_t *rpt;
- char *p;
-
- rpt = NULL;
- if ((p = strchr (rrulestr, ':')) != NULL)
- {
- char freqstr[BUFSIZ];
-
- p++;
- rpt = mem_malloc (sizeof (ical_rpt_t));
- bzero (rpt, sizeof (ical_rpt_t));
- if (sscanf (p, "FREQ=%s", freqstr) != 1)
- {
- ical_log (log, ICAL_VEVENT, itemline,
- _("recurrence frequence not found."));
- (*noskipped)++;
- mem_free (rpt);
- return NULL;
- }
- else
- {
- if (strncmp (freqstr, daily.str, daily.len) == 0)
- rpt->type = RECUR_DAILY;
- else if (strncmp (freqstr, weekly.str, weekly.len) == 0)
- rpt->type = RECUR_WEEKLY;
- else if (strncmp (freqstr, monthly.str, monthly.len) == 0)
- rpt->type = RECUR_MONTHLY;
- else if (strncmp (freqstr, yearly.str, yearly.len) == 0)
- rpt->type = RECUR_YEARLY;
- else
- {
- ical_log (log, ICAL_VEVENT, itemline,
- _("recurrence frequence not recognized."));
- (*noskipped)++;
- mem_free (rpt);
- return NULL;
- }
- }
- /*
- The UNTIL rule part defines a date-time value which bounds the
- recurrence rule in an inclusive manner. If not present, and the
- COUNT rule part is also not present, the RRULE is considered to
- repeat forever.
-
- The COUNT rule part defines the number of occurrences at which to
- range-bound the recurrence. The "DTSTART" property value, if
- specified, counts as the first occurrence.
- */
- if ((p = strstr (rrulestr, "UNTIL")) != NULL)
- {
- char *untilstr;
-
- untilstr = strchr (p, '=');
- rpt->until = ical_datetime2long (++untilstr, NULL);
- }
- else
- {
- unsigned cnt;
- char *countstr;
-
- if ((countstr = strstr (rrulestr, count.str)) != NULL)
- {
- countstr += count.len;
- if (sscanf (countstr, "%u", &cnt) != 1)
- {
- rpt->until = 0;
- /* endless repetition */
- }
- else
- {
- rpt->count = cnt;
- }
- }
- else
- rpt->until = 0;
- }
-
- if ((p = strstr (rrulestr, interv.str)) != NULL)
- {
- p += interv.len;
- if (sscanf (p, "%u", &interval) != 1)
- {
- rpt->freq = 1;
- /* default frequence if none specified */
- }
- else
- {
- rpt->freq = interval;
- }
- }
- else
- {
- rpt->freq = 1;
- }
- }
- else
- {
- ical_log (log, ICAL_VEVENT, itemline, _("recurrence rule malformed."));
- (*noskipped)++;
- }
- return rpt;
-}
+ custom_apply_attr(win[STA].p, ATTR_HIGHEST);
+ mvwprintw(win[STA].p, 0, 2, "Q");
+ mvwprintw(win[STA].p, 1, 2, "I");
+ mvwprintw(win[STA].p, 0, 2 + spc, "P");
+ custom_remove_attr(win[STA].p, ATTR_HIGHEST);
-static void
-ical_add_exc (llist_t *exc_head, long date)
-{
- if (date != 0)
- {
- struct excp *exc = mem_malloc (sizeof (struct excp));
- exc->st = date;
+ mvwprintw(win[STA].p, 0, 2 + smlspc, _("Exit"));
+ mvwprintw(win[STA].p, 1, 2 + smlspc, _("Ical"));
+ mvwprintw(win[STA].p, 0, 2 + spc + smlspc, _("Pcal"));
- LLIST_ADD (exc_head, exc);
- }
+ wnoutrefresh(win[STA].p);
+ wmove(win[STA].p, 0, 0);
+ wins_doupdate();
}
-/*
- * This property defines the list of date/time exceptions for a
- * recurring calendar component.
- */
-void
-ical_read_exdate (llist_t *exc, FILE *log, char *exstr, unsigned *noskipped,
- const int itemline)
-{
- char *p, *q;
- long date;
-
- LLIST_INIT (exc);
- if ((p = strchr (exstr, ':')) != NULL)
- {
- p++;
- while ((q = strchr (p, ',')) != NULL)
- {
- char buf[BUFSIZ];
- const int buflen = q - p;
-
- (void)strncpy (buf, p, buflen);
- buf[buflen] = '\0';
- date = ical_datetime2long (buf, NULL);
- ical_add_exc (exc, date);
- p = ++q;
- }
- date = ical_datetime2long (p, NULL);
- ical_add_exc (exc, date);
- }
- else
- {
- ical_log (log, ICAL_VEVENT, itemline,
- _("recurrence exception dates malformed."));
- (*noskipped)++;
- }
-}
-
-/* Return an allocated string containing the name of the newly created note. */
-static char *
-ical_read_note (char *line, unsigned *noskipped, ical_vevent_e item_type,
- const int itemline, FILE *log)
-{
- char *p, *notestr, *notename, fullnotename[BUFSIZ];
- FILE *fdo;
-
- if ((p = strchr (line, ':')) != NULL)
- {
- notename = new_tempfile (path_notes, NOTESIZ);
- EXIT_IF (notename == NULL,
- _("Warning: could not create new note file to store "
- "description. Aborting...\n"));
- (void)snprintf (fullnotename, BUFSIZ, "%s%s", path_notes, notename);
- fdo = fopen (fullnotename, "w");
- EXIT_IF (fdo == NULL, _("Warning: could not open %s, Aborting..."),
- fullnotename);
- p++;
- notestr = ical_unformat_line (p);
- if (notestr == NULL)
- {
- ical_log (log, item_type, itemline,
- _("could not get entire item description."));
- file_close (fdo, __FILE_POS__);
- erase_note (&notename, ERASE_FORCE);
- (*noskipped)++;
- return NULL;
- }
- else if (strlen (notestr) == 0)
- {
- file_close (fdo, __FILE_POS__);
- erase_note (&notename, ERASE_FORCE);
- mem_free (notestr);
- return NULL;
- }
- else
- {
- (void)fprintf (fdo, "%s", notestr);
- file_close (fdo, __FILE_POS__);
- mem_free (notestr);
- return notename;
- }
- }
- else
- {
- ical_log (log, item_type, itemline, _("description malformed."));
- (*noskipped)++;
- return NULL;
- }
-}
-
-/* Returns an allocated string containing the ical item summary. */
-static char *
-ical_read_summary (char *line)
-{
- char *p, *summary;
-
- if ((p = strchr (line, ':')) != NULL)
- {
- p++;
- summary = ical_unformat_line (p);
- return summary;
- }
- else
- return NULL;
-}
-
-static void
-ical_read_event (FILE *fdi, FILE *log, unsigned *noevents, unsigned *noapoints,
- unsigned *noskipped, char *buf, char *lstore,
- unsigned *lineno)
-{
- const int ITEMLINE = *lineno;
- const struct string endevent = STRING_BUILD ("END:VEVENT");
- const struct string summary = STRING_BUILD ("SUMMARY");
- const struct string dtstart = STRING_BUILD ("DTSTART");
- const struct string dtend = STRING_BUILD ("DTEND");
- const struct string duration = STRING_BUILD ("DURATION");
- const struct string rrule = STRING_BUILD ("RRULE");
- const struct string exdate = STRING_BUILD ("EXDATE");
- const struct string alarm = STRING_BUILD ("BEGIN:VALARM");
- const struct string endalarm = STRING_BUILD ("END:VALARM");
- const struct string desc = STRING_BUILD ("DESCRIPTION");
- ical_vevent_e vevent_type;
- char *p, buf_upper[BUFSIZ];
- struct {
- llist_t exc;
- ical_rpt_t *rpt;
- char *mesg, *note;
- long start, end, dur;
- int has_alarm;
- } vevent;
- int skip_alarm;
-
- vevent_type = UNDEFINED;
- bzero (&vevent, sizeof vevent);
- skip_alarm = 0;
- while (ical_readline (fdi, buf, lstore, lineno))
- {
- strncpy (buf_upper, buf, BUFSIZ);
- buf_upper[BUFSIZ - 1] = '\0';
- str_toupper (buf_upper);
-
- if (skip_alarm)
- {
- /* Need to skip VALARM properties because some keywords could
- interfere, such as DURATION, SUMMARY,.. */
- if (strncmp (buf_upper, endalarm.str, endalarm.len) == 0)
- skip_alarm = 0;
- continue;
- }
- if (strncmp (buf_upper, endevent.str, endevent.len) == 0)
- {
- if (vevent.mesg)
- {
- if (vevent.rpt && vevent.rpt->count)
- vevent.rpt->until = ical_compute_rpt_until (vevent.start,
- vevent.rpt);
-
- switch (vevent_type)
- {
- case APPOINTMENT:
- if (vevent.start == 0)
- {
- ical_log (log, ICAL_VEVENT, ITEMLINE,
- _("appointment has no start time."));
- goto cleanup;
- }
- if (vevent.dur == 0)
- {
- if (vevent.end == 0)
- {
- ical_log (log, ICAL_VEVENT, ITEMLINE,
- _("could not compute duration "
- "(no end time)."));
- goto cleanup;
- }
- else if (vevent.start == vevent.end)
- {
- vevent_type = EVENT;
- vevent.end = 0L;
- ical_store_event (vevent.mesg, vevent.note,
- vevent.start, vevent.end,
- vevent.rpt, &vevent.exc);
- (*noevents)++;
- return;
- }
- else
- {
- vevent.dur = vevent.end - vevent.start;
- if (vevent.dur < 0)
- {
- ical_log (log, ICAL_VEVENT, ITEMLINE,
- _("item has a negative duration."));
- goto cleanup;
- }
- }
- }
- ical_store_apoint (vevent.mesg, vevent.note, vevent.start,
- vevent.dur, vevent.rpt, &vevent.exc,
- vevent.has_alarm);
- (*noapoints)++;
- break;
- case EVENT:
- if (vevent.start == 0)
- {
- ical_log (log, ICAL_VEVENT, ITEMLINE,
- _("event date is not defined."));
- goto cleanup;
- }
- ical_store_event (vevent.mesg, vevent.note, vevent.start,
- vevent.end, vevent.rpt, &vevent.exc);
- (*noevents)++;
- break;
- case UNDEFINED:
- ical_log (log, ICAL_VEVENT, ITEMLINE,
- _("item could not be identified."));
- goto cleanup;
- break;
- }
- }
- else
- {
- ical_log (log, ICAL_VEVENT, ITEMLINE,
- _("could not retrieve item summary."));
- goto cleanup;
- }
- return;
- }
- else
- {
- if (strncmp (buf_upper, dtstart.str, dtstart.len) == 0)
- {
- if ((p = strchr (buf, ':')) != NULL)
- vevent.start = ical_datetime2long (++p, &vevent_type);
- if (!vevent.start)
- {
- ical_log (log, ICAL_VEVENT, ITEMLINE,
- _("could not retrieve event start time."));
- goto cleanup;
- }
- }
- else if (strncmp (buf_upper, dtend.str, dtend.len) == 0)
- {
- if ((p = strchr (buf, ':')) != NULL)
- vevent.end = ical_datetime2long (++p, &vevent_type);
- if (!vevent.end)
- {
- ical_log (log, ICAL_VEVENT, ITEMLINE,
- _("could not retrieve event end time."));
- goto cleanup;
- }
- }
- else if (strncmp (buf_upper, duration.str, duration.len) == 0)
- {
- if ((vevent.dur = ical_dur2long (buf)) <= 0)
- {
- ical_log (log, ICAL_VEVENT, ITEMLINE,
- _("item duration malformed."));
- goto cleanup;
- }
- }
- else if (strncmp (buf_upper, rrule.str, rrule.len) == 0)
- {
- vevent.rpt = ical_read_rrule (log, buf, noskipped, ITEMLINE);
- }
- else if (strncmp (buf_upper, exdate.str, exdate.len) == 0)
- {
- ical_read_exdate (&vevent.exc, log, buf, noskipped, ITEMLINE);
- }
- else if (strncmp (buf_upper, summary.str, summary.len) == 0)
- {
- vevent.mesg = ical_read_summary (buf);
- }
- else if (strncmp (buf_upper, alarm.str, alarm.len) == 0)
- {
- skip_alarm = 1;
- vevent.has_alarm = 1;
- }
- else if (strncmp (buf_upper, desc.str, desc.len) == 0)
- {
- vevent.note = ical_read_note (buf, noskipped, ICAL_VEVENT,
- ITEMLINE, log);
- }
- }
- }
- ical_log (log, ICAL_VEVENT, ITEMLINE,
- _("The ical file seems to be malformed. "
- "The end of item was not found."));
-
-cleanup:
-
- if (vevent.note)
- mem_free (vevent.note);
- if (vevent.mesg)
- mem_free (vevent.mesg);
- if (vevent.rpt)
- mem_free (vevent.rpt);
- LLIST_FREE (&vevent.exc);
- (*noskipped)++;
-}
-
-static void
-ical_read_todo (FILE *fdi, FILE *log, unsigned *notodos, unsigned *noskipped,
- char *buf, char *lstore, unsigned *lineno)
-{
- const struct string endtodo = STRING_BUILD ("END:VTODO");
- const struct string summary = STRING_BUILD ("SUMMARY");
- const struct string alarm = STRING_BUILD ("BEGIN:VALARM");
- const struct string endalarm = STRING_BUILD ("END:VALARM");
- const struct string desc = STRING_BUILD ("DESCRIPTION");
- const int LOWEST = 9;
- const int ITEMLINE = *lineno;
- char buf_upper[BUFSIZ];
- struct {
- char *mesg, *note;
- int has_priority, priority;
- } vtodo;
- int skip_alarm;
-
- bzero (&vtodo, sizeof vtodo);
- skip_alarm = 0;
- while (ical_readline (fdi, buf, lstore, lineno))
- {
- strncpy (buf_upper, buf, BUFSIZ);
- buf_upper[BUFSIZ - 1] = '\0';
- str_toupper (buf_upper);
- if (skip_alarm)
- {
- /* Need to skip VALARM properties because some keywords could
- interfere, such as DURATION, SUMMARY,.. */
- if (strncmp (buf_upper, endalarm.str, endalarm.len) == 0)
- skip_alarm = 0;
- continue;
- }
- if (strncmp (buf_upper, endtodo.str, endtodo.len) == 0)
- {
- if (!vtodo.has_priority)
- vtodo.priority = LOWEST;
- if (vtodo.mesg)
- {
- ical_store_todo (vtodo.priority, vtodo.mesg, vtodo.note);
- (*notodos)++;
- }
- else
- {
- ical_log (log, ICAL_VTODO, ITEMLINE,
- _("could not retrieve item summary."));
- goto cleanup;
- }
- return;
- }
- else
- {
- int tmpint;
-
- if (sscanf (buf_upper, "PRIORITY:%d", &tmpint) == 1)
- {
- if (tmpint <= 9 && tmpint >= 1)
- {
- vtodo.priority = tmpint;
- vtodo.has_priority = 1;
- }
- else
- {
- ical_log (log, ICAL_VTODO, ITEMLINE,
- _("item priority is not acceptable "
- "(must be between 1 and 9)."));
- vtodo.priority = LOWEST;
- }
- }
- else if (strncmp (buf_upper, summary.str, summary.len) == 0)
- {
- vtodo.mesg = ical_read_summary (buf);
- }
- else if (strncmp (buf_upper, alarm.str, alarm.len) == 0)
- {
- skip_alarm = 1;
- }
- else if (strncmp (buf_upper, desc.str, desc.len) == 0)
- {
- vtodo.note = ical_read_note (buf, noskipped, ICAL_VTODO,
- ITEMLINE, log);
- }
- }
- }
- ical_log (log, ICAL_VTODO, ITEMLINE,
- _("The ical file seems to be malformed. "
- "The end of item was not found."));
-
-cleanup:
-
- if (vtodo.note)
- mem_free (vtodo.note);
- if (vtodo.mesg)
- mem_free (vtodo.mesg);
- (*noskipped)++;
-}
-
-static FILE *
-get_import_stream (enum export_type type)
+static FILE *get_import_stream(enum export_type type)
{
FILE *stream;
char *stream_name;
- char *ask_fname = _("Enter the file name to import data from:");
- char *wrong_file =
- _("The file cannot be accessed, please enter another file name.");
- char *press_enter = _("Press [ENTER] to continue.");
+ const char *ask_fname = _("Enter the file name to import data from:");
+ const char *wrong_file =
+ _("The file cannot be accessed, please enter another file name.");
+ const char *press_enter = _("Press [ENTER] to continue.");
int cancel;
stream = NULL;
- stream_name = mem_malloc (BUFSIZ);
- bzero (stream_name, BUFSIZ);
- while (stream == NULL)
- {
- status_mesg (ask_fname, "");
- cancel = updatestring (win[STA].p, &stream_name, 0, 1);
- if (cancel)
- {
- mem_free (stream_name);
- return NULL;
- }
- stream = fopen (stream_name, "r");
- if (stream == NULL)
- {
- status_mesg (wrong_file, press_enter);
- (void)wgetch (win[STA].p);
- }
+ stream_name = mem_malloc(BUFSIZ);
+ memset(stream_name, 0, BUFSIZ);
+ while (stream == NULL) {
+ status_mesg(ask_fname, "");
+ cancel = updatestring(win[STA].p, &stream_name, 0, 1);
+ if (cancel) {
+ mem_free(stream_name);
+ return NULL;
}
- mem_free (stream_name);
+ stream = fopen(stream_name, "r");
+ if (stream == NULL) {
+ status_mesg(wrong_file, press_enter);
+ wgetch(win[STA].p);
+ }
+ }
+ mem_free(stream_name);
return stream;
}
@@ -2715,229 +993,182 @@ get_import_stream (enum export_type type)
* A temporary log file is created in /tmp to store the import process report,
* and is cleared at the end.
*/
-void
-io_import_data (enum import_type type, struct conf *conf, char *stream_name)
+void io_import_data(enum import_type type, const char *stream_name)
{
- const struct string vevent = STRING_BUILD ("BEGIN:VEVENT");
- const struct string vtodo = STRING_BUILD ("BEGIN:VTODO");
- char *proc_report = _("Import process report: %04d lines read ");
- char *lines_stats =
- _("%d apps / %d events / %d todos / %d skipped ");
- char *lines_stats_interactive =
- _("%d apps / %d events / %d todos / %d skipped ([ENTER] to continue)");
- char buf[BUFSIZ], lstore[BUFSIZ];
+ const char *proc_report = _("Import process report: %04d lines read ");
+ char stats_str[4][BUFSIZ];
FILE *stream = NULL;
struct io_file *log;
- float ical_version;
struct {
unsigned events, apoints, todos, lines, skipped;
} stats;
- EXIT_IF (type < 0 || type >= IO_IMPORT_NBTYPES, _("unknown import type"));
- switch (ui_mode)
- {
- case UI_CMDLINE:
- stream = fopen (stream_name, "r");
- EXIT_IF (stream == NULL,
- _("FATAL ERROR: the input file cannot be accessed, "
- "Aborting..."));
- break;
- case UI_CURSES:
- stream = get_import_stream (type);
- break;
- default:
- EXIT (_("FATAL ERROR: wrong import mode"));
- /* NOTREACHED */
- }
+ EXIT_IF(type < 0 || type >= IO_IMPORT_NBTYPES, _("unknown import type"));
+ switch (ui_mode) {
+ case UI_CMDLINE:
+ stream = fopen(stream_name, "r");
+ EXIT_IF(stream == NULL,
+ _("FATAL ERROR: the input file cannot be accessed, "
+ "Aborting..."));
+ break;
+ case UI_CURSES:
+ stream = get_import_stream(type);
+ break;
+ default:
+ EXIT(_("FATAL ERROR: wrong import mode"));
+ /* NOTREACHED */
+ }
if (stream == NULL)
return;
- bzero (&stats, sizeof stats);
- ical_readline_init (stream, buf, lstore, &stats.lines);
- ical_version = ical_chk_header (stream, buf, lstore, &stats.lines);
- RETURN_IF (ical_version < 0,
- _("Warning: ical header malformed or wrong version number. "
- "Aborting..."));
-
- log = io_log_init ();
- if (log == NULL)
- {
- if (stream != stdin)
- file_close (stream, __FILE_POS__);
- return;
- }
- ical_log_init (log->fd, ical_version);
-
- while (ical_readline (stream, buf, lstore, &stats.lines))
- {
- stats.lines++;
- str_toupper (buf);
- if (strncmp (buf, vevent.str, vevent.len) == 0)
- {
- ical_read_event (stream, log->fd, &stats.events, &stats.apoints,
- &stats.skipped, buf, lstore, &stats.lines);
- }
- else if (strncmp (buf, vtodo.str, vtodo.len) == 0)
- {
- ical_read_todo (stream, log->fd, &stats.todos, &stats.skipped,
- buf, lstore, &stats.lines);
- }
- }
- if (stream != stdin)
- file_close (stream, __FILE_POS__);
+ memset(&stats, 0, sizeof stats);
- /* Update the number of todo items. */
- todo_set_nb (todo_nb () + stats.todos);
+ log = io_log_init();
+ if (log == NULL) {
+ if (stream != stdin)
+ file_close(stream, __FILE_POS__);
+ return;
+ }
- if (ui_mode == UI_CURSES && !conf->skip_system_dialogs)
- {
- char read[BUFSIZ], stat[BUFSIZ];
+ if (type == IO_IMPORT_ICAL)
+ ical_import_data(stream, log->fd, &stats.events, &stats.apoints,
+ &stats.todos, &stats.lines, &stats.skipped);
- (void)snprintf (read, BUFSIZ, proc_report, stats.lines);
- (void)snprintf (stat, BUFSIZ, lines_stats_interactive, stats.apoints,
- stats.events, stats.todos, stats.skipped);
- status_mesg (read, stat);
- (void)wgetch (win[STA].p);
- }
- else if (ui_mode == UI_CMDLINE)
- {
- printf (proc_report, stats.lines);
- printf ("\n");
- printf (lines_stats, stats.apoints, stats.events, stats.todos,
- stats.skipped);
- printf ("\n");
- }
+ if (stream != stdin)
+ file_close(stream, __FILE_POS__);
+
+ snprintf(stats_str[0], BUFSIZ,
+ ngettext("%d app", "%d apps", stats.apoints), stats.apoints);
+ snprintf(stats_str[1], BUFSIZ,
+ ngettext("%d event", "%d events", stats.events), stats.events);
+ snprintf(stats_str[2], BUFSIZ,
+ ngettext("%d todo", "%d todos", stats.todos), stats.todos);
+ snprintf(stats_str[3], BUFSIZ, _("%d skipped"), stats.skipped);
+
+ /* Update the number of todo items. */
+ todo_set_nb(todo_nb() + stats.todos);
+
+ if (ui_mode == UI_CURSES && conf.system_dialogs) {
+ char read[BUFSIZ], stat[BUFSIZ];
+
+ snprintf(read, BUFSIZ, proc_report, stats.lines);
+ snprintf(stat, BUFSIZ, "%s / %s / %s / %s (%s)", stats_str[0],
+ stats_str[1], stats_str[2], stats_str[3],
+ _("Press [ENTER] to continue"));
+ status_mesg(read, stat);
+ wgetch(win[STA].p);
+ } else if (ui_mode == UI_CMDLINE) {
+ printf(proc_report, stats.lines);
+ printf("\n%s / %s / %s / %s\n", stats_str[0], stats_str[1],
+ stats_str[2], stats_str[3]);
+ }
/* User has the choice to look at the log file if some items could not be
imported.
- */
- file_close (log->fd, __FILE_POS__);
- if (stats.skipped > 0)
- {
- char *view_log = _("Some items could not be imported, see log file ?");
+ */
+ file_close(log->fd, __FILE_POS__);
+ if (stats.skipped > 0) {
+ const char *view_log =
+ _("Some items could not be imported, see log file ?");
- io_log_display (log, view_log, conf->pager);
- }
- io_log_free (log);
+ io_log_display(log, view_log, conf.pager);
+ }
+ io_log_free(log);
}
-struct io_file *
-io_log_init (void)
+struct io_file *io_log_init(void)
{
char logprefix[BUFSIZ];
char *logname;
struct io_file *log;
- snprintf (logprefix, BUFSIZ, "%s/calcurse_log.", get_tempdir ());
- logname = new_tempfile (logprefix, NOTESIZ);
- RETVAL_IF (logname == NULL, 0,
- _("Warning: could not create temporary log file, Aborting..."));
- log = mem_malloc (sizeof (struct io_file));
- RETVAL_IF (log == NULL, 0,
- _("Warning: could not open temporary log file, Aborting..."));
- (void)snprintf (log->name, sizeof (log->name), "%s%s", logprefix, logname);
- mem_free (logname);
- log->fd = fopen (log->name, "w");
- if (log->fd == NULL)
- {
- ERROR_MSG (_("Warning: could not open temporary log file, Aborting..."));
- mem_free (log);
- return 0;
- }
+ snprintf(logprefix, BUFSIZ, "%s/calcurse_log.", get_tempdir());
+ logname = new_tempfile(logprefix, TMPEXTSIZ);
+ RETVAL_IF(logname == NULL, 0,
+ _("Warning: could not create temporary log file, Aborting..."));
+ log = mem_malloc(sizeof(struct io_file));
+ RETVAL_IF(log == NULL, 0,
+ _("Warning: could not open temporary log file, Aborting..."));
+ snprintf(log->name, sizeof(log->name), "%s%s", logprefix, logname);
+ mem_free(logname);
+ log->fd = fopen(log->name, "w");
+ if (log->fd == NULL) {
+ ERROR_MSG(_("Warning: could not open temporary log file, Aborting..."));
+ mem_free(log);
+ return 0;
+ }
return log;
}
-void
-io_log_print (struct io_file *log, int line, char *msg)
+void io_log_print(struct io_file *log, int line, const char *msg)
{
if (log && log->fd)
- (void)fprintf (log->fd, "line %d: %s\n", line, msg);
+ fprintf(log->fd, "line %d: %s\n", line, msg);
}
-void
-io_log_display (struct io_file *log, char *msg, char *pager)
+void io_log_display(struct io_file *log, const char *msg, const char *pager)
{
- char *choices = "[y/n] ";
int ans;
- RETURN_IF (log == NULL, _("No log file to display!"));
- if (ui_mode == UI_CMDLINE)
- {
- printf ("\n%s %s", msg, choices);
- ans = fgetc (stdin);
- if (ans == 'y')
- {
- char cmd[BUFSIZ];
-
- (void)snprintf (cmd, BUFSIZ, "%s %s", pager, log->name);
- (void)system (cmd);
- }
- }
- else
- {
- status_mesg (msg, choices);
- do
- {
- ans = wgetch (win[STA].p);
- if (ans == 'y')
- {
- wins_launch_external (log->name, pager);
- }
- }
- while (ans != 'y' && ans != 'n');
- wins_erase_status_bar ();
+ RETURN_IF(log == NULL, _("No log file to display!"));
+ if (ui_mode == UI_CMDLINE) {
+ printf("\n%s [y/n] ", msg);
+ ans = fgetc(stdin);
+ if (ans == 'y') {
+ const char *arg[] = { pager, log->name, NULL };
+ int pid;
+
+ if ((pid = fork_exec(NULL, NULL, pager, arg)))
+ child_wait(NULL, NULL, pid);
}
+ } else {
+ if (status_ask_bool(msg) == 1)
+ wins_launch_external(log->name, pager);
+ wins_erase_status_bar();
+ }
}
-void
-io_log_free (struct io_file *log)
+void io_log_free(struct io_file *log)
{
if (!log)
return;
- EXIT_IF (unlink (log->name) != 0,
- _("Warning: could not erase temporary log file %s, Aborting..."),
- log->name);
- mem_free (log);
+ EXIT_IF(unlink(log->name) != 0,
+ _("Warning: could not erase temporary log file %s, Aborting..."),
+ log->name);
+ mem_free(log);
}
static pthread_t io_t_psave;
/* Thread used to periodically save data. */
-static void *
-io_psave_thread (void *arg)
+static void *io_psave_thread(void *arg)
{
- struct conf *config;
int delay;
- config = (struct conf *)arg;
- delay = config->periodic_save;
- EXIT_IF (delay < 0, _("Invalid delay"));
+ delay = conf.periodic_save;
+ EXIT_IF(delay < 0, _("Invalid delay"));
- for (;;)
- {
- (void)sleep (delay * MININSEC);
- io_save_cal (config, IO_SAVE_DISPLAY_MARK);
- }
+ for (;;) {
+ sleep(delay * MININSEC);
+ io_save_cal(IO_SAVE_DISPLAY_MARK);
+ }
}
/* Launch the thread which handles periodic saves. */
-void
-io_start_psave_thread (struct conf *conf)
+void io_start_psave_thread(void)
{
- pthread_create (&io_t_psave, NULL, io_psave_thread, (void *)conf);
+ pthread_create(&io_t_psave, NULL, io_psave_thread, NULL);
}
/* Stop periodic data saves. */
-void
-io_stop_psave_thread (void)
+void io_stop_psave_thread(void)
{
- if (io_t_psave)
- {
- pthread_cancel (io_t_psave);
- pthread_join (io_t_psave, NULL);
- }
+ if (io_t_psave) {
+ pthread_cancel(io_t_psave);
+ pthread_join(io_t_psave, NULL);
+ }
}
/*
@@ -2951,49 +1182,40 @@ io_stop_psave_thread (void)
* Note: When creating the lock file, the interactive mode is not initialized
* yet.
*/
-void
-io_set_lock (void)
+void io_set_lock(void)
{
- FILE *lock = fopen (path_cpid, "r");
+ FILE *lock = fopen(path_cpid, "r");
int pid;
- if (lock != NULL)
- {
- /* If there is a lock file, check whether the process exists. */
- if (fscanf(lock, "%d", &pid) == 1)
- {
- fclose(lock);
- if (kill(pid, 0) != 0 && errno == ESRCH)
- lock = NULL;
- }
- else
- fclose(lock);
- }
-
- if (lock != NULL)
- {
- (void)fprintf (stderr,
- _("\nWARNING: it seems that another calcurse instance is "
- "already running.\n"
- "If this is not the case, please remove the following "
- "lock file: \n\"%s\"\n"
- "and restart calcurse.\n"), path_cpid);
- exit (EXIT_FAILURE);
- }
- else
- {
- if (!io_dump_pid (path_cpid))
- EXIT (_("FATAL ERROR: could not create %s: %s\n"),
- path_cpid, strerror (errno));
- }
+ if (lock != NULL) {
+ /* If there is a lock file, check whether the process exists. */
+ if (fscanf(lock, "%d", &pid) == 1) {
+ fclose(lock);
+ if (kill(pid, 0) != 0 && errno == ESRCH)
+ lock = NULL;
+ } else
+ fclose(lock);
+ }
+
+ if (lock != NULL) {
+ fprintf(stderr,
+ _("\nWARNING: it seems that another calcurse instance is "
+ "already running.\n"
+ "If this is not the case, please remove the following "
+ "lock file: \n\"%s\"\n" "and restart calcurse.\n"), path_cpid);
+ exit(EXIT_FAILURE);
+ } else {
+ if (!io_dump_pid(path_cpid))
+ EXIT(_("FATAL ERROR: could not create %s: %s\n"),
+ path_cpid, strerror(errno));
+ }
}
/*
* Create a new file and write the process pid inside (used to create a simple
* lock for example). Overwrite already existing files.
*/
-unsigned
-io_dump_pid (char *file)
+unsigned io_dump_pid(char *file)
{
pid_t pid;
FILE *fp;
@@ -3001,10 +1223,9 @@ io_dump_pid (char *file)
if (!file)
return 0;
- pid = getpid ();
- if (!(fp = fopen (file, "w"))
- || fprintf (fp, "%ld\n", (long)pid) < 0
- || fclose (fp) != 0)
+ pid = getpid();
+ if (!(fp = fopen(file, "w"))
+ || fprintf(fp, "%ld\n", (long)pid) < 0 || fclose(fp) != 0)
return 0;
return 1;
@@ -3015,8 +1236,7 @@ io_dump_pid (char *file)
* io_dump_pid ().
* If no file was found, return 0.
*/
-unsigned
-io_get_pid (char *file)
+unsigned io_get_pid(char *file)
{
FILE *fp;
unsigned pid;
@@ -3024,13 +1244,13 @@ io_get_pid (char *file)
if (!file)
return 0;
- if ((fp = fopen (file, "r")) == NULL)
+ if ((fp = fopen(file, "r")) == NULL)
return 0;
- if (fscanf (fp, "%u", &pid) != 1)
+ if (fscanf(fp, "%u", &pid) != 1)
return 0;
- (void)fclose (fp);
+ fclose(fp);
return pid;
}
@@ -3038,24 +1258,48 @@ io_get_pid (char *file)
/*
* Check whether a file is empty.
*/
-int
-io_file_is_empty (char *file)
+int io_file_is_empty(char *file)
{
FILE *fp;
- if (file && (fp = fopen (file, "r")))
- {
- if ((fgetc (fp) == '\n' && fgetc (fp) == EOF) || feof (fp))
- {
- fclose (fp);
- return 1;
- }
- else
- {
- fclose (fp);
- return 0;
- }
+ if (file && (fp = fopen(file, "r"))) {
+ if ((fgetc(fp) == '\n' && fgetc(fp) == EOF) || feof(fp)) {
+ fclose(fp);
+ return 1;
+ } else {
+ fclose(fp);
+ return 0;
}
+ }
return -1;
}
+
+/*
+ * Copy an existing file to a new location.
+ */
+int io_file_cp(const char *src, const char *dst)
+{
+ FILE *fp_src, *fp_dst;
+ char *buffer[BUFSIZ];
+ unsigned int bytes_read;
+
+ if (!(fp_src = fopen(src, "rb")))
+ return 0;
+ if (!(fp_dst = fopen(dst, "wb")))
+ return 0;
+
+ while (!feof(fp_src)) {
+ bytes_read = fread(buffer, 1, BUFSIZ, fp_src);
+ if (bytes_read > 0) {
+ if (fwrite(buffer, 1, bytes_read, fp_dst) != bytes_read)
+ return 0;
+ } else
+ return 0;
+ }
+
+ fclose(fp_dst);
+ fclose(fp_src);
+
+ return 1;
+}
diff --git a/src/keys.c b/src/keys.c
index 12bdd5c..23ee61f 100644
--- a/src/keys.c
+++ b/src/keys.c
@@ -1,7 +1,7 @@
/*
* Calcurse - text-based organizer
*
- * Copyright (c) 2004-2011 calcurse Development Team <misc@calcurse.org>
+ * Copyright (c) 2004-2012 calcurse Development Team <misc@calcurse.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -39,20 +39,14 @@
#include "calcurse.h"
-#define MAXKEYVAL KEY_MAX /* ncurses defines KEY_MAX as maximum key value */
+#define MAXKEYVAL KEY_MAX /* ncurses defines KEY_MAX as maximum key value */
struct keydef_s {
- char *label;
- char *binding;
+ const char *label;
+ const char *binding;
};
-struct key_str_s {
- char *str;
- struct key_str_s *next;
-};
-
-static struct key_str_s *keys[NBKEYS];
-
+static llist_t keys[NBKEYS];
static enum key actions[MAXKEYVAL];
static struct keydef_s keydef[NBKEYS] = {
@@ -81,16 +75,17 @@ static struct keydef_s keydef[NBKEYS] = {
{"generic-scroll-up", "C-p"},
{"generic-goto-today", "C-g"},
- {"move-right", "l L"},
- {"move-left", "h H"},
- {"move-down", "j J"},
- {"move-up", "k K"},
+ {"move-right", "l L RGT"},
+ {"move-left", "h H LFT"},
+ {"move-down", "j J DWN"},
+ {"move-up", "k K UP"},
{"start-of-week", "0"},
{"end-of-week", "$"},
{"add-item", "a A"},
{"del-item", "d D"},
{"edit-item", "e E"},
{"view-item", "v V"},
+ {"pipe-item", "|"},
{"flag-item", "!"},
{"repeat", "r R"},
{"edit-note", "n N"},
@@ -99,92 +94,80 @@ static struct keydef_s keydef[NBKEYS] = {
{"lower-priority", "-"},
};
-static void
-dump_intro (FILE *fd)
+static void dump_intro(FILE * fd)
{
- char *intro =
- _("#\n"
- "# Calcurse keys configuration file\n#\n"
- "# This file sets the keybindings used by Calcurse.\n"
- "# Lines beginning with \"#\" are comments, and ignored by Calcurse.\n"
- "# To assign a keybinding to an action, this file must contain a line\n"
- "# with the following syntax:\n#\n"
- "# ACTION KEY1 KEY2 ... KEYn\n#\n"
- "# Where ACTION is what will be performed when KEY1, KEY2, ..., or KEYn\n"
- "# will be pressed.\n"
- "#\n"
- "# To define bindings which use the CONTROL key, prefix the key with "
- "'C-'.\n"
- "# The escape, space bar and horizontal Tab key can be specified using\n"
- "# the 'ESC', 'SPC' and 'TAB' keyword, respectively.\n"
- "# Arrow keys can also be specified with the UP, DWN, LFT, RGT keywords.\n"
- "# Last, Home and End keys can be assigned using 'KEY_HOME' and 'KEY_END'\n"
- "# keywords."
- "\n#\n"
- "# A description of what each ACTION keyword is used for is available\n"
- "# from calcurse online configuration menu.\n");
-
- (void)fprintf (fd, "%s\n", intro);
+ const char *intro =
+ _("#\n"
+ "# Calcurse keys configuration file\n#\n"
+ "# This file sets the keybindings used by Calcurse.\n"
+ "# Lines beginning with \"#\" are comments, and ignored by Calcurse.\n"
+ "# To assign a keybinding to an action, this file must contain a line\n"
+ "# with the following syntax:\n#\n"
+ "# ACTION KEY1 KEY2 ... KEYn\n#\n"
+ "# Where ACTION is what will be performed when KEY1, KEY2, ..., or KEYn\n"
+ "# will be pressed.\n"
+ "#\n"
+ "# To define bindings which use the CONTROL key, prefix the key with "
+ "'C-'.\n"
+ "# The escape, space bar and horizontal Tab key can be specified using\n"
+ "# the 'ESC', 'SPC' and 'TAB' keyword, respectively.\n"
+ "# Arrow keys can also be specified with the UP, DWN, LFT, RGT keywords.\n"
+ "# Last, Home and End keys can be assigned using 'KEY_HOME' and 'KEY_END'\n"
+ "# keywords."
+ "\n#\n"
+ "# A description of what each ACTION keyword is used for is available\n"
+ "# from calcurse online configuration menu.\n");
+
+ fprintf(fd, "%s\n", intro);
}
-void
-keys_init (void)
+void keys_init(void)
{
int i;
for (i = 0; i < MAXKEYVAL; i++)
actions[i] = KEY_UNDEF;
- bzero (keys, NBKEYS);
+ for (i = 0; i < NBKEYS; i++)
+ LLIST_INIT(&keys[i]);
}
-void
-keys_free (void)
+static void key_free(char *s)
{
- struct key_str_s *o, **i;
- int key;
-
- for (key = 0; key < NBKEYS; key++)
- {
- if (keys[key] == NULL)
- continue;
-
- i = &keys[key];
- while (*i)
- {
- o = *i;
- *i = o->next;
- mem_free (o->str);
- mem_free (o);
- }
- }
+ mem_free(s);
}
-void
-keys_dump_defaults (char *file)
+void keys_free(void)
+{
+ int i;
+
+ for (i = 0; i < NBKEYS; i++) {
+ LLIST_FREE_INNER(&keys[i], key_free);
+ LLIST_FREE(&keys[i]);
+ }
+}
+
+void keys_dump_defaults(char *file)
{
FILE *fd;
int i;
- fd = fopen (file, "w");
- EXIT_IF (fd == NULL, _("FATAL ERROR: could not create default keys file."));
+ fd = fopen(file, "w");
+ EXIT_IF(fd == NULL, _("FATAL ERROR: could not create default keys file."));
- dump_intro (fd);
+ dump_intro(fd);
for (i = 0; i < NBKEYS; i++)
- (void)fprintf (fd, "%s %s\n", keydef[i].label, keydef[i].binding);
- file_close (fd, __FILE_POS__);
+ fprintf(fd, "%s %s\n", keydef[i].label, keydef[i].binding);
+ file_close(fd, __FILE_POS__);
}
-char *
-keys_get_label (enum key key)
+const char *keys_get_label(enum key key)
{
- EXIT_IF (key < 0 || key > NBKEYS,
- _("FATAL ERROR: key value out of bounds"));
+ EXIT_IF(key < 0 || key > NBKEYS, _("FATAL ERROR: key value out of bounds"));
return keydef[key].label;
}
-enum key
-keys_get_action (int pressed)
+enum key keys_get_action(int pressed)
{
if (pressed < 0 || pressed > MAXKEYVAL)
return -1;
@@ -192,461 +175,391 @@ keys_get_action (int pressed)
return actions[pressed];
}
-enum key
-keys_getch (WINDOW *win)
+enum key keys_getch(WINDOW * win, int *count)
{
- int ch;
-
- ch = wgetch (win);
- switch (ch)
- {
- case KEY_RESIZE:
- return KEY_RESIZE;
- default:
- return keys_get_action (ch);
+ int ch = '0';
+
+ if (count) {
+ *count = 0;
+ do {
+ *count = *count * 10 + ch - '0';
+ ch = wgetch(win);
}
+ while ((ch == '0' && *count > 0) || (ch >= '1' && ch <= '9'));
+
+ if (*count == 0)
+ *count = 1;
+ } else
+ ch = wgetch(win);
+
+ switch (ch) {
+ case KEY_RESIZE:
+ return KEY_RESIZE;
+ default:
+ return keys_get_action(ch);
+ }
}
-static void
-add_key_str (enum key action, int key)
+static void add_key_str(enum key action, int key)
{
- struct key_str_s *new, **i;
-
if (action < 0 || action > NBKEYS)
return;
- new = mem_malloc (sizeof (struct key_str_s));
- new->str = mem_strdup (keys_int2str (key));
- new->next = NULL;
- i = &keys[action];
- for (;;)
- {
- if (*i == NULL)
- {
- *i = new;
- break;
- }
- else if ((*i)->next == NULL)
- {
- (*i)->next = new;
- break;
- }
- i = &(*i)->next;
- }
+ LLIST_ADD(&keys[action], mem_strdup(keys_int2str(key)));
}
-int
-keys_assign_binding (int key, enum key action)
+int keys_assign_binding(int key, enum key action)
{
if (key < 0 || key > MAXKEYVAL || actions[key] != KEY_UNDEF)
return 1;
- else
- {
- actions[key] = action;
- add_key_str (action, key);
- }
+ else {
+ actions[key] = action;
+ add_key_str(action, key);
+ }
return 0;
}
-static void
-del_key_str (enum key action, int key)
+static void del_key_str(enum key action, int key)
{
- struct key_str_s *old, **i;
+ llist_item_t *i;
char oldstr[BUFSIZ];
if (action < 0 || action > NBKEYS)
return;
- (void)strncpy (oldstr, keys_int2str (key), BUFSIZ);
- for (i = &keys[action]; *i; i = &(*i)->next)
- {
- if (!strcmp ((*i)->str, oldstr))
- {
- old = *i;
- *i = old->next;
- mem_free (old->str);
- mem_free (old);
- break;
- }
+ strncpy(oldstr, keys_int2str(key), BUFSIZ);
+
+ LLIST_FOREACH(&keys[action], i) {
+ if (strcmp(LLIST_GET_DATA(i), oldstr) == 0) {
+ LLIST_REMOVE(&keys[action], i);
+ return;
}
+ }
}
-void
-keys_remove_binding (int key, enum key action)
+void keys_remove_binding(int key, enum key action)
{
- if (key < 0 || key > MAXKEYVAL)
- return;
- else
- {
- actions[key] = KEY_UNDEF;
- del_key_str (action, key);
- }
+ if (key >= 0 && key <= MAXKEYVAL) {
+ actions[key] = KEY_UNDEF;
+ del_key_str(action, key);
+ }
}
-int
-keys_str2int (char *key)
+int keys_str2int(const char *key)
{
- const struct string CONTROL_KEY = STRING_BUILD ("C-");
- const struct string TAB_KEY = STRING_BUILD ("TAB");
- const struct string SPACE_KEY = STRING_BUILD ("SPC");
- const struct string ESCAPE_KEY = STRING_BUILD ("ESC");
- const struct string CURSES_KEY_UP = STRING_BUILD ("UP");
- const struct string CURSES_KEY_DOWN = STRING_BUILD ("DWN");
- const struct string CURSES_KEY_LEFT = STRING_BUILD ("LFT");
- const struct string CURSES_KEY_RIGHT = STRING_BUILD ("RGT");
- const struct string CURSES_KEY_HOME = STRING_BUILD ("KEY_HOME");
- const struct string CURSES_KEY_END = STRING_BUILD ("KEY_END");
+ const char CONTROL_KEY[] = "C-";
+ const char TAB_KEY[] = "TAB";
+ const char SPACE_KEY[] = "SPC";
+ const char ESCAPE_KEY[] = "ESC";
+ const char CURSES_KEY_UP[] = "UP";
+ const char CURSES_KEY_DOWN[] = "DWN";
+ const char CURSES_KEY_LEFT[] = "LFT";
+ const char CURSES_KEY_RIGHT[] = "RGT";
+ const char CURSES_KEY_HOME[] = "KEY_HOME";
+ const char CURSES_KEY_END[] = "KEY_END";
if (!key)
return -1;
- if (strlen (key) == 1)
+ if (strlen(key) == 1)
return (int)key[0];
- else
- {
- if (key[0] == '^')
- return CTRL ((int)key[1]);
- else if (!strncmp (key, CONTROL_KEY.str, CONTROL_KEY.len))
- return CTRL ((int)key[CONTROL_KEY.len]);
- else if (!strncmp (key, TAB_KEY.str, TAB_KEY.len))
- return TAB;
- else if (!strncmp (key, ESCAPE_KEY.str, ESCAPE_KEY.len))
- return ESCAPE;
- else if (!strncmp (key, SPACE_KEY.str, SPACE_KEY.len))
- return SPACE;
- else if (!strncmp (key, CURSES_KEY_UP.str, CURSES_KEY_UP.len))
- return KEY_UP;
- else if (!strncmp (key, CURSES_KEY_DOWN.str, CURSES_KEY_DOWN.len))
- return KEY_DOWN;
- else if (!strncmp (key, CURSES_KEY_LEFT.str, CURSES_KEY_LEFT.len))
- return KEY_LEFT;
- else if (!strncmp (key, CURSES_KEY_RIGHT.str, CURSES_KEY_RIGHT.len))
- return KEY_RIGHT;
- else if (!strncmp (key, CURSES_KEY_HOME.str, CURSES_KEY_HOME.len))
- return KEY_HOME;
- else if (!strncmp (key, CURSES_KEY_END.str, CURSES_KEY_END.len))
- return KEY_END;
- else
- return -1;
- }
+ else {
+ if (key[0] == '^')
+ return CTRL((int)key[1]);
+ else if (!strncmp(key, CONTROL_KEY, sizeof(CONTROL_KEY) - 1))
+ return CTRL((int)key[sizeof(CONTROL_KEY) - 1]);
+ else if (!strcmp(key, TAB_KEY))
+ return TAB;
+ else if (!strcmp(key, ESCAPE_KEY))
+ return ESCAPE;
+ else if (!strcmp(key, SPACE_KEY))
+ return SPACE;
+ else if (!strcmp(key, CURSES_KEY_UP))
+ return KEY_UP;
+ else if (!strcmp(key, CURSES_KEY_DOWN))
+ return KEY_DOWN;
+ else if (!strcmp(key, CURSES_KEY_LEFT))
+ return KEY_LEFT;
+ else if (!strcmp(key, CURSES_KEY_RIGHT))
+ return KEY_RIGHT;
+ else if (!strcmp(key, CURSES_KEY_HOME))
+ return KEY_HOME;
+ else if (!strcmp(key, CURSES_KEY_END))
+ return KEY_END;
+ else
+ return -1;
+ }
}
-char *
-keys_int2str (int key)
+const char *keys_int2str(int key)
{
- switch (key)
- {
- case TAB:
- return "TAB";
- case SPACE:
- return "SPC";
- case ESCAPE:
- return "ESC";
- case KEY_UP:
- return "UP";
- case KEY_DOWN:
- return "DWN";
- case KEY_LEFT:
- return "LFT";
- case KEY_RIGHT:
- return "RGT";
- case KEY_HOME:
- return "KEY_HOME";
- case KEY_END:
- return "KEY_END";
- default:
- return (char *)keyname (key);
- }
+ switch (key) {
+ case TAB:
+ return "TAB";
+ case SPACE:
+ return "SPC";
+ case ESCAPE:
+ return "ESC";
+ case KEY_UP:
+ return "UP";
+ case KEY_DOWN:
+ return "DWN";
+ case KEY_LEFT:
+ return "LFT";
+ case KEY_RIGHT:
+ return "RGT";
+ case KEY_HOME:
+ return "KEY_HOME";
+ case KEY_END:
+ return "KEY_END";
+ default:
+ return (char *)keyname(key);
+ }
}
-int
-keys_action_count_keys (enum key action)
+int keys_action_count_keys(enum key action)
{
- struct key_str_s *key;
- int i;
+ llist_item_t *i;
+ int n = 0;
- i = 0;
- for (key = keys[action]; key; key = key->next)
- i++;
+ LLIST_FOREACH(&keys[action], i)
+ n++;
- return i;
+ return n;
}
-char *
-keys_action_firstkey (enum key action)
+const char *keys_action_firstkey(enum key action)
{
- return (keys[action] != NULL) ? keys[action]->str : "XXX";
+ const char *s = LLIST_GET_DATA(LLIST_FIRST(&keys[action]));
+ return (s != NULL) ? s : "XXX";
}
-char *
-keys_action_nkey (enum key action, int keynum)
+const char *keys_action_nkey(enum key action, int keynum)
{
- struct key_str_s *key;
- int i;
-
- i = 0;
- for (key = keys[action]; key; key = key->next)
- {
- if (i == keynum)
- return key->str;
- i++;
- }
- return (char *)0;
+ return LLIST_GET_DATA(LLIST_NTH(&keys[action], keynum));
}
-char *
-keys_action_allkeys (enum key action)
+char *keys_action_allkeys(enum key action)
{
+ llist_item_t *i;
static char keystr[BUFSIZ];
- struct key_str_s *i;
const char *CHAR_SPACE = " ";
- if (keys[action] == NULL)
+ if (!LLIST_FIRST(&keys[action]))
return NULL;
+
keystr[0] = '\0';
- for (i = keys[action]; i; i = i->next)
- {
- const int MAXLEN = sizeof (keystr) - 1 - strlen (keystr);
- (void)strncat (keystr, i->str, MAXLEN - 1);
- (void)strncat (keystr, CHAR_SPACE, 1);
- }
+ LLIST_FOREACH(&keys[action], i) {
+ const int MAXLEN = sizeof(keystr) - 1 - strlen(keystr);
+ strncat(keystr, LLIST_GET_DATA(i), MAXLEN - 1);
+ strncat(keystr, CHAR_SPACE, 1);
+ }
return keystr;
}
/* Need this to display keys properly inside status bar. */
-static char *
-keys_format_label (char *key, int keylen)
+static char *keys_format_label(char *key, int keylen)
{
static char fmtkey[BUFSIZ];
- const int len = strlen (key);
- char *dot = ".";
+ const int len = strlen(key);
+ const char dot = '.';
int i;
if (keylen > BUFSIZ)
- return (char *)0;
+ return NULL;
- bzero (fmtkey, sizeof (fmtkey));
+ memset(fmtkey, 0, sizeof(fmtkey));
if (len == 0)
- (void)snprintf (fmtkey, sizeof (fmtkey), "?");
- else if (len <= keylen)
- {
- for (i = 0; i < keylen - len; i++)
- fmtkey[i] = ' ';
- (void)strncat (fmtkey, key, keylen);
- }
- else
- {
- for (i = 0; i < keylen - 1; i++)
- fmtkey[i] = key[i];
- (void)strncat (fmtkey, dot, strlen (dot));
- }
+ strncpy(fmtkey, "?", sizeof(fmtkey));
+ else if (len <= keylen) {
+ for (i = 0; i < keylen - len; i++)
+ fmtkey[i] = ' ';
+ strncat(fmtkey, key, keylen);
+ } else {
+ for (i = 0; i < keylen - 1; i++)
+ fmtkey[i] = key[i];
+ fmtkey[keylen - 1] = dot;
+ }
return fmtkey;
}
void
-keys_display_bindings_bar (WINDOW *win, struct binding **binding, int first_key,
- int last_key)
+keys_display_bindings_bar(WINDOW * win, struct binding *bindings[], int count,
+ int page_base, int page_size, struct binding *more)
{
- int i, j, cmdlen, space_between_cmds;
-
- /* Total length of a command. */
- cmdlen = KEYS_KEYLEN + 1 + KEYS_LABELEN;
- space_between_cmds = floor (col / KEYS_CMDS_PER_LINE - cmdlen);
- cmdlen += space_between_cmds;
-
- j = 0;
- wins_erase_status_bar ();
- for (i = first_key; i < last_key; i += 2)
- {
- char key[KEYS_KEYLEN + 1], *fmtkey;
- const int KEY_POS = j * cmdlen;
- const int LABEL_POS = j * cmdlen + KEYS_KEYLEN + 1;
-
- (void)strncpy (key, keys_action_firstkey (binding[i]->action),
- KEYS_KEYLEN);
- fmtkey = keys_format_label (key, KEYS_KEYLEN);
- custom_apply_attr (win, ATTR_HIGHEST);
- mvwprintw (win, 0, KEY_POS, fmtkey);
- if (i + 1 != last_key)
- {
- (void)strncpy (key, keys_action_firstkey (binding[i + 1]->action),
- KEYS_KEYLEN);
- key[KEYS_KEYLEN] = 0;
- fmtkey = keys_format_label (key, KEYS_KEYLEN);
- mvwprintw (win, 1, KEY_POS, fmtkey);
- }
- custom_remove_attr (win, ATTR_HIGHEST);
- mvwprintw (win, 0, LABEL_POS, binding[i]->label);
- if (i + 1 != last_key)
- mvwprintw (win, 1, LABEL_POS, binding[i + 1]->label);
- j++;
- }
- wnoutrefresh (win);
+ /* Padding between two key bindings. */
+ const int padding = (col * 2) / page_size - (KEYS_KEYLEN + KEYS_LABELEN + 1);
+ /* Total length of a key binding (including padding). */
+ const int cmd_len = KEYS_KEYLEN + KEYS_LABELEN + 1 + padding;
+
+ int i;
+
+ wins_erase_status_bar();
+ for (i = 0; i < page_size && page_base + i < count; i++) {
+ /* Location of key and label. */
+ const int key_pos_x = (i / 2) * cmd_len;
+ const int key_pos_y = i % 2;
+ const int label_pos_x = key_pos_x + KEYS_KEYLEN + 1;
+ const int label_pos_y = key_pos_y;
+
+ struct binding *binding;
+ char key[KEYS_KEYLEN + 1], *fmtkey;
+
+ if (!more || i < page_size - 1 || page_base + i == count - 1)
+ binding = bindings[page_base + i];
+ else
+ binding = more;
+
+ strncpy(key, keys_action_firstkey(binding->action), KEYS_KEYLEN);
+ key[KEYS_KEYLEN] = '\0';
+ fmtkey = keys_format_label(key, KEYS_KEYLEN);
+
+ custom_apply_attr(win, ATTR_HIGHEST);
+ mvwprintw(win, key_pos_y, key_pos_x, fmtkey);
+ custom_remove_attr(win, ATTR_HIGHEST);
+ mvwprintw(win, label_pos_y, label_pos_x, binding->label);
+ }
+ wnoutrefresh(win);
}
/*
* Display information about the given key.
* (could not add the keys descriptions to keydef variable, because of i18n).
*/
-void
-keys_popup_info (enum key key)
+void keys_popup_info(enum key key)
{
char *info[NBKEYS];
WINDOW *infowin;
- info[KEY_GENERIC_CANCEL] =
- _("Cancel the ongoing action.");
- info[KEY_GENERIC_SELECT] =
- _("Select the highlighted item.");
+ info[KEY_GENERIC_CANCEL] = _("Cancel the ongoing action.");
+ info[KEY_GENERIC_SELECT] = _("Select the highlighted item.");
info[KEY_GENERIC_CREDITS] =
- _("Print general information about calcurse's authors, license, etc.");
+ _("Print general information about calcurse's authors, license, etc.");
info[KEY_GENERIC_HELP] =
- _("Display hints whenever some help screens are available.");
- info[KEY_GENERIC_QUIT] =
- _("Exit from the current menu, or quit calcurse.");
- info[KEY_GENERIC_SAVE] =
- _("Save calcurse data.");
+ _("Display hints whenever some help screens are available.");
+ info[KEY_GENERIC_QUIT] = _("Exit from the current menu, or quit calcurse.");
+ info[KEY_GENERIC_SAVE] = _("Save calcurse data.");
+ info[KEY_GENERIC_CUT] = _("Help for `generic-cut`.");
+ info[KEY_GENERIC_PASTE] = _("Help for `generic-paste`.");
info[KEY_GENERIC_CHANGE_VIEW] =
- _("Select next panel in calcurse main screen.");
- info[KEY_GENERIC_IMPORT] =
- _("Import data from an external file.");
- info[KEY_GENERIC_EXPORT] =
- _("Export data to a new file format.");
- info[KEY_GENERIC_GOTO] =
- _("Select the day to go to.");
+ _("Select next panel in calcurse main screen.");
+ info[KEY_GENERIC_IMPORT] = _("Import data from an external file.");
+ info[KEY_GENERIC_EXPORT] = _("Export data to a new file format.");
+ info[KEY_GENERIC_GOTO] = _("Select the day to go to.");
info[KEY_GENERIC_OTHER_CMD] =
- _("Show next possible actions inside status bar.");
- info[KEY_GENERIC_CONFIG_MENU] =
- _("Enter the configuration menu.");
- info[KEY_GENERIC_REDRAW] =
- _("Redraw calcurse's screen.");
+ _("Show next possible actions inside status bar.");
+ info[KEY_GENERIC_CONFIG_MENU] = _("Enter the configuration menu.");
+ info[KEY_GENERIC_REDRAW] = _("Redraw calcurse's screen.");
info[KEY_GENERIC_ADD_APPT] =
- _("Add an appointment, whichever panel is currently selected.");
+ _("Add an appointment, whichever panel is currently selected.");
info[KEY_GENERIC_ADD_TODO] =
- _("Add a todo item, whichever panel is currently selected.");
+ _("Add a todo item, whichever panel is currently selected.");
info[KEY_GENERIC_NEXT_DAY] =
- _("Move to next day in calendar, whichever panel is currently selected.");
+ _("Move to next day in calendar, whichever panel is currently selected.");
info[KEY_GENERIC_PREV_DAY] =
- _("Move to previous day in calendar, whichever panel is currently "
- "selected.");
+ _("Move to previous day in calendar, whichever panel is currently "
+ "selected.");
info[KEY_GENERIC_NEXT_WEEK] =
- _("Move to next week in calendar, whichever panel is currently selected.");
+ _
+ ("Move to next week in calendar, whichever panel is currently selected.");
info[KEY_GENERIC_PREV_WEEK] =
- _("Move to previous week in calendar, whichever panel is currently "
- "selected");
+ _("Move to previous week in calendar, whichever panel is currently "
+ "selected");
info[KEY_GENERIC_SCROLL_DOWN] =
- _("Scroll window down (e.g. when displaying text inside a popup window).");
+ _
+ ("Scroll window down (e.g. when displaying text inside a popup window).");
info[KEY_GENERIC_SCROLL_UP] =
- _("Scroll window up (e.g. when displaying text inside a popup window).");
- info[KEY_GENERIC_GOTO_TODAY] =
- _("Go to today, whichever panel is selected.");
- info[KEY_MOVE_RIGHT] =
- _("Move to the right.");
- info[KEY_MOVE_LEFT] =
- _("Move to the left.");
- info[KEY_MOVE_DOWN] =
- _("Move down.");
- info[KEY_MOVE_UP] =
- _("Move up.");
+ _("Scroll window up (e.g. when displaying text inside a popup window).");
+ info[KEY_GENERIC_GOTO_TODAY] = _("Go to today, whichever panel is selected.");
+ info[KEY_MOVE_RIGHT] = _("Move to the right.");
+ info[KEY_MOVE_LEFT] = _("Move to the left.");
+ info[KEY_MOVE_DOWN] = _("Move down.");
+ info[KEY_MOVE_UP] = _("Move up.");
info[KEY_START_OF_WEEK] =
- _("Select the first day of the current week when inside the calendar "
- "panel.");
+ _("Select the first day of the current week when inside the calendar "
+ "panel.");
info[KEY_END_OF_WEEK] =
- _("Select the last day of the current week when inside the calendar "
- "panel.");
- info[KEY_ADD_ITEM] =
- _("Add an item to the currently selected panel.");
- info[KEY_DEL_ITEM] =
- _("Delete the currently selected item.");
- info[KEY_EDIT_ITEM] =
- _("Edit the currently seleted item.");
+ _("Select the last day of the current week when inside the calendar "
+ "panel.");
+ info[KEY_ADD_ITEM] = _("Add an item to the currently selected panel.");
+ info[KEY_DEL_ITEM] = _("Delete the currently selected item.");
+ info[KEY_EDIT_ITEM] = _("Edit the currently seleted item.");
info[KEY_VIEW_ITEM] =
- _("Display the currently selected item inside a popup window.");
- info[KEY_FLAG_ITEM] =
- _("Flag the currently selected item as important.");
- info[KEY_REPEAT_ITEM] =
- _("Repeat an item");
+ _("Display the currently selected item inside a popup window.");
+ info[KEY_FLAG_ITEM] = _("Flag the currently selected item as important.");
+ info[KEY_REPEAT_ITEM] = _("Repeat an item");
+ info[KEY_PIPE_ITEM] =
+ _("Pipe the currently selected item to an external program.");
info[KEY_EDIT_NOTE] =
- _("Attach (or edit if one exists) a note to the currently selected item");
+ _("Attach (or edit if one exists) a note to the currently selected item");
info[KEY_VIEW_NOTE] =
- _("View the note attached to the currently selected item.");
- info[KEY_RAISE_PRIORITY] =
- _("Raise a task priority inside the todo panel.");
- info[KEY_LOWER_PRIORITY] =
- _("Lower a task priority inside the todo panel.");
+ _("View the note attached to the currently selected item.");
+ info[KEY_RAISE_PRIORITY] = _("Raise a task priority inside the todo panel.");
+ info[KEY_LOWER_PRIORITY] = _("Lower a task priority inside the todo panel.");
if (key < 0 || key > NBKEYS)
return;
#define WINROW 10
#define WINCOL (col - 4)
- infowin = popup (WINROW, WINCOL, (row - WINROW) / 2, (col - WINCOL) / 2,
- keydef[key].label, info[key], 1);
- (void)keys_getch (infowin);
- delwin (infowin);
+ infowin = popup(WINROW, WINCOL, (row - WINROW) / 2, (col - WINCOL) / 2,
+ keydef[key].label, info[key], 1);
+ keys_getch(infowin, NULL);
+ delwin(infowin);
#undef WINROW
#undef WINCOL
}
-void
-keys_save_bindings (FILE *fd)
+void keys_save_bindings(FILE * fd)
{
int i;
- EXIT_IF (fd == NULL, _("FATAL ERROR: null file pointer."));
- dump_intro (fd);
+ EXIT_IF(fd == NULL, _("FATAL ERROR: null file pointer."));
+ dump_intro(fd);
for (i = 0; i < NBKEYS; i++)
- (void)fprintf (fd, "%s %s\n", keydef[i].label, keys_action_allkeys (i));
+ fprintf(fd, "%s %s\n", keydef[i].label, keys_action_allkeys(i));
}
-int
-keys_check_missing_bindings (void)
+int keys_check_missing_bindings(void)
{
int i;
- for (i = 0; i < NBKEYS; i++)
- {
- if (keys[i] == NULL)
- return 1;
- }
+ for (i = 0; i < NBKEYS; i++) {
+ if (!LLIST_FIRST(&keys[i]))
+ return 1;
+ }
return 0;
}
-void
-keys_fill_missing (void)
+void keys_fill_missing(void)
{
int i;
- for (i = 0; i < NBKEYS; i++)
- {
- if (keys[i] == NULL)
- {
- char *p, tmpbuf[BUFSIZ];
-
- (void)strncpy (tmpbuf, keydef[i].binding, BUFSIZ);
- p = tmpbuf;
- for (;;)
- {
- char key_ch[BUFSIZ];
-
- while (*p == ' ')
- p++;
- if (sscanf (p, "%s", key_ch) == 1)
- {
- int ch, used;
-
- ch = keys_str2int (key_ch);
- used = keys_assign_binding (ch, i);
- if (used)
- WARN_MSG (_("When adding default key for \"%s\", "
- "\"%s\" was already assigned!"),
- keydef[i].label, key_ch);
- p += strlen (key_ch) + 1;
- }
- else
- break;
- }
- }
+ for (i = 0; i < NBKEYS; i++) {
+ if (!LLIST_FIRST(&keys[i])) {
+ char *p, tmpbuf[BUFSIZ];
+
+ strncpy(tmpbuf, keydef[i].binding, BUFSIZ);
+ p = tmpbuf;
+ for (;;) {
+ char key_ch[BUFSIZ];
+
+ while (*p == ' ')
+ p++;
+ if (sscanf(p, "%s", key_ch) == 1) {
+ int ch, used;
+
+ ch = keys_str2int(key_ch);
+ used = keys_assign_binding(ch, i);
+ if (used)
+ WARN_MSG(_("When adding default key for \"%s\", "
+ "\"%s\" was already assigned!"),
+ keydef[i].label, key_ch);
+ p += strlen(key_ch) + 1;
+ } else
+ break;
+ }
}
+ }
}
diff --git a/src/llist.c b/src/llist.c
index eeded6b..847b795 100644
--- a/src/llist.c
+++ b/src/llist.c
@@ -1,7 +1,7 @@
/*
* Calcurse - text-based organizer
*
- * Copyright (c) 2004-2011 calcurse Development Team <misc@calcurse.org>
+ * Copyright (c) 2004-2012 calcurse Development Team <misc@calcurse.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -39,52 +39,47 @@
/*
* Initialize a list.
*/
-void
-llist_init (llist_t *l)
+void llist_init(llist_t * l)
{
l->head = NULL;
+ l->tail = NULL;
}
/*
* Free a list, but not the contained data.
*/
-void
-llist_free (llist_t *l)
+void llist_free(llist_t * l)
{
llist_item_t *i, *t;
- for (i = l->head; i; i = t)
- {
- t = i->next;
- mem_free (i);
- }
+ for (i = l->head; i; i = t) {
+ t = i->next;
+ mem_free(i);
+ }
l->head = NULL;
+ l->tail = NULL;
}
/*
* Free the data contained in a list.
*/
-void
-llist_free_inner (llist_t *l, llist_fn_free_t fn_free)
+void llist_free_inner(llist_t * l, llist_fn_free_t fn_free)
{
llist_item_t *i;
- for (i = l->head; i; i = i->next)
- {
- if (i->data)
- {
- fn_free(i->data);
- i->data = NULL;
- }
+ for (i = l->head; i; i = i->next) {
+ if (i->data) {
+ fn_free(i->data);
+ i->data = NULL;
}
+ }
}
/*
* Get the first item of a list.
*/
-llist_item_t *
-llist_first (llist_t *l)
+llist_item_t *llist_first(llist_t * l)
{
return l->head;
}
@@ -92,12 +87,14 @@ llist_first (llist_t *l)
/*
* Get the nth item of a list.
*/
-llist_item_t *
-llist_nth (llist_t *l, int n)
+llist_item_t *llist_nth(llist_t * l, int n)
{
llist_item_t *i;
- for (i = l->head; i && n > 0; n--)
+ if (n < 0)
+ return NULL;
+
+ for (i = l->head; i && n != 0; n--)
i = i->next;
return i;
@@ -106,17 +103,28 @@ llist_nth (llist_t *l, int n)
/*
* Get the successor of a list item.
*/
-llist_item_t *
-llist_next (llist_item_t *i)
+llist_item_t *llist_next(llist_item_t * i)
{
return i ? i->next : NULL;
}
/*
+ * Return the successor of a list item if it is matched by some filter
+ * callback. Return NULL otherwise.
+ */
+llist_item_t *llist_next_filter(llist_item_t * i, long data,
+ llist_fn_match_t fn_match)
+{
+ if (i && i->next && fn_match(i->next->data, data))
+ return i->next;
+ else
+ return NULL;
+}
+
+/*
* Get the actual data of an item.
*/
-void *
-llist_get_data (llist_item_t *i)
+void *llist_get_data(llist_item_t * i)
{
return i ? i->data : NULL;
}
@@ -124,97 +132,88 @@ llist_get_data (llist_item_t *i)
/*
* Add an item at the end of a list.
*/
-void
-llist_add (llist_t *l, void *data)
+void llist_add(llist_t * l, void *data)
{
- llist_item_t *o = mem_malloc (sizeof (llist_item_t));
- llist_item_t *i;
+ llist_item_t *o = mem_malloc(sizeof(llist_item_t));
- if (o)
- {
- o->data = data;
- o->next = NULL;
-
- if (!l->head)
- l->head = o;
- else
- {
- for (i = l->head; i->next; i = i->next)
- ;
- i->next = o;
- }
+ if (o) {
+ o->data = data;
+ o->next = NULL;
+
+ if (!l->head)
+ l->head = l->tail = o;
+ else {
+ l->tail->next = o;
+ l->tail = o;
}
+ }
}
/*
* Add an item to a sorted list.
*/
-void
-llist_add_sorted (llist_t *l, void *data, llist_fn_cmp_t fn_cmp)
+void llist_add_sorted(llist_t * l, void *data, llist_fn_cmp_t fn_cmp)
{
- llist_item_t *o = mem_malloc (sizeof (llist_item_t));
+ llist_item_t *o = mem_malloc(sizeof(llist_item_t));
llist_item_t *i;
- if (o)
- {
- o->data = data;
- o->next = NULL;
-
- if (!l->head)
- l->head = o;
- else if (fn_cmp(o->data, l->head->data) < 0)
- {
- o->next = l->head;
- l->head = o;
- }
- else
- {
- i = l->head;
- while (i->next && fn_cmp(o->data, i->next->data) >= 0)
- i = i->next;
- o->next = i->next;
- i->next = o;
- }
+ if (o) {
+ o->data = data;
+ o->next = NULL;
+
+ if (!l->head)
+ l->head = l->tail = o;
+ else if (fn_cmp(o->data, l->tail->data) >= 0) {
+ l->tail->next = o;
+ l->tail = o;
+ } else if (fn_cmp(o->data, l->head->data) < 0) {
+ o->next = l->head;
+ l->head = o;
+ } else {
+ i = l->head;
+ while (i->next && fn_cmp(o->data, i->next->data) >= 0)
+ i = i->next;
+ o->next = i->next;
+ i->next = o;
}
+ }
}
/*
* Remove an item from a list.
*/
-void
-llist_remove (llist_t *l, llist_item_t *i)
+void llist_remove(llist_t * l, llist_item_t * i)
{
llist_item_t *j = NULL;
if (l->head && i == l->head)
l->head = i->next;
- else
- {
- for (j = l->head; j && j->next != i; j = j->next)
- ;
- }
-
- if (i)
- {
- if (j)
- j->next = i->next;
- mem_free (i);
- }
+ else {
+ for (j = l->head; j && j->next != i; j = j->next) ;
+ }
+
+ if (i) {
+ if (j)
+ j->next = i->next;
+ if (i == l->tail)
+ l->tail = j;
+
+ mem_free(i);
+ }
}
/*
* Find the first item matched by some filter callback.
*/
-llist_item_t *
-llist_find_first (llist_t *l, long data, llist_fn_match_t fn_match)
+llist_item_t *llist_find_first(llist_t * l, long data,
+ llist_fn_match_t fn_match)
{
llist_item_t *i;
- for (i = l->head; i; i = i->next)
- {
- if (fn_match (i->data, data))
- return i;
- }
+ for (i = l->head; i; i = i->next) {
+ if (fn_match(i->data, data))
+ return i;
+ }
return NULL;
}
@@ -222,18 +221,16 @@ llist_find_first (llist_t *l, long data, llist_fn_match_t fn_match)
/*
* Find the next item matched by some filter callback.
*/
-llist_item_t *
-llist_find_next (llist_item_t *i, long data, llist_fn_match_t fn_match)
+llist_item_t *llist_find_next(llist_item_t * i, long data,
+ llist_fn_match_t fn_match)
{
- if (i)
- {
- i = i->next;
- for (; i; i = i->next)
- {
- if (fn_match (i->data, data))
- return i;
- }
+ if (i) {
+ i = i->next;
+ for (; i; i = i->next) {
+ if (fn_match(i->data, data))
+ return i;
}
+ }
return NULL;
}
@@ -241,16 +238,18 @@ llist_find_next (llist_item_t *i, long data, llist_fn_match_t fn_match)
/*
* Find the nth item matched by some filter callback.
*/
-llist_item_t *
-llist_find_nth (llist_t *l, int n, long data, llist_fn_match_t fn_match)
+llist_item_t *llist_find_nth(llist_t * l, int n, long data,
+ llist_fn_match_t fn_match)
{
llist_item_t *i;
- for (i = l->head; i; i = i->next)
- {
- if (fn_match (i->data, data) && (n-- == 0))
- return i;
- }
+ if (n < 0)
+ return NULL;
+
+ for (i = l->head; i; i = i->next) {
+ if (fn_match(i->data, data) && (n-- == 0))
+ return i;
+ }
return NULL;
}
diff --git a/src/llist.h b/src/llist.h
index d7e4249..c795f37 100644
--- a/src/llist.h
+++ b/src/llist.h
@@ -1,7 +1,7 @@
/*
* Calcurse - text-based organizer
*
- * Copyright (c) 2004-2011 calcurse Development Team <misc@calcurse.org>
+ * Copyright (c) 2004-2012 calcurse Development Team <misc@calcurse.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -38,12 +38,13 @@
typedef struct llist_item llist_item_t;
struct llist_item {
struct llist_item *next;
- void *data;
+ void *data;
};
typedef struct llist llist_t;
struct llist {
struct llist_item *head;
+ struct llist_item *tail;
};
typedef int (*llist_fn_cmp_t) (void *, void *);
@@ -51,9 +52,9 @@ typedef int (*llist_fn_match_t) (void *, long);
typedef void (*llist_fn_free_t) (void *);
/* Initialization and deallocation. */
-void llist_init (llist_t *);
-void llist_free (llist_t *);
-void llist_free_inner (llist_t *, llist_fn_free_t);
+void llist_init(llist_t *);
+void llist_free(llist_t *);
+void llist_free_inner(llist_t *, llist_fn_free_t);
#define LLIST_INIT(l) llist_init(l)
#define LLIST_FREE(l) llist_free(l)
@@ -61,16 +62,19 @@ void llist_free_inner (llist_t *, llist_fn_free_t);
llist_free_inner(l, (llist_fn_free_t)fn_free)
/* Retrieving list items. */
-llist_item_t *llist_first (llist_t *);
-llist_item_t *llist_nth (llist_t *, int);
-llist_item_t *llist_next (llist_item_t *);
-llist_item_t *llist_find_first (llist_t *, long, llist_fn_match_t);
-llist_item_t *llist_find_next (llist_item_t *, long, llist_fn_match_t);
-llist_item_t *llist_find_nth (llist_t *, int, long, llist_fn_match_t);
+llist_item_t *llist_first(llist_t *);
+llist_item_t *llist_nth(llist_t *, int);
+llist_item_t *llist_next(llist_item_t *);
+llist_item_t *llist_next_filter(llist_item_t *, long, llist_fn_match_t);
+llist_item_t *llist_find_first(llist_t *, long, llist_fn_match_t);
+llist_item_t *llist_find_next(llist_item_t *, long, llist_fn_match_t);
+llist_item_t *llist_find_nth(llist_t *, int, long, llist_fn_match_t);
#define LLIST_FIRST(l) llist_first(l)
#define LLIST_NTH(l, n) llist_nth(l, n)
#define LLIST_NEXT(i) llist_next(i)
+#define LLIST_NEXT_FILTER(i, data, fn_match) \
+ llist_next_filter(i, data, (llist_fn_match_t)fn_match)
#define LLIST_FIND_FIRST(l, data, fn_match) \
llist_find_first(l, data, (llist_fn_match_t)fn_match)
#define LLIST_FIND_NEXT(i, data, fn_match) \
@@ -82,16 +86,19 @@ llist_item_t *llist_find_nth (llist_t *, int, long, llist_fn_match_t);
#define LLIST_FIND_FOREACH(l, data, fn_match, i) \
for (i = LLIST_FIND_FIRST (l, data, fn_match); i; \
i = LLIST_FIND_NEXT (i, data, fn_match))
+#define LLIST_FIND_FOREACH_CONT(l, data, fn_match, i) \
+ for (i = LLIST_FIND_FIRST (l, data, fn_match); i; \
+ i = LLIST_NEXT_FILTER (i, data, fn_match))
/* Accessing list item data. */
-void *llist_get_data (llist_item_t *);
+void *llist_get_data(llist_item_t *);
#define LLIST_GET_DATA(i) llist_get_data(i)
/* List manipulation. */
-void llist_add (llist_t *, void *);
-void llist_add_sorted (llist_t *, void *, llist_fn_cmp_t);
-void llist_remove (llist_t *, llist_item_t *);
+void llist_add(llist_t *, void *);
+void llist_add_sorted(llist_t *, void *, llist_fn_cmp_t);
+void llist_remove(llist_t *, llist_item_t *);
#define LLIST_ADD(l, data) llist_add(l, data)
#define LLIST_ADD_SORTED(l, data, fn_cmp) \
diff --git a/src/llist_ts.h b/src/llist_ts.h
index 0f90024..b452377 100644
--- a/src/llist_ts.h
+++ b/src/llist_ts.h
@@ -1,7 +1,7 @@
/*
* Calcurse - text-based organizer
*
- * Copyright (c) 2004-2011 calcurse Development Team <misc@calcurse.org>
+ * Copyright (c) 2004-2012 calcurse Development Team <misc@calcurse.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -37,8 +37,9 @@
/* Thread-safe linked lists. */
typedef struct llist_ts llist_ts_t;
struct llist_ts {
- llist_item_t *head;
- pthread_mutex_t mutex;
+ llist_item_t *head;
+ llist_item_t *tail;
+ pthread_mutex_t mutex;
};
/* Initialization and deallocation. */
@@ -63,6 +64,8 @@ struct llist_ts {
#define LLIST_TS_FIRST(l_ts) llist_first ((llist_t *)l_ts)
#define LLIST_TS_NTH(l_ts, n) llist_nth ((llist_t *)l_ts, n)
#define LLIST_TS_NEXT(i) llist_next (i)
+#define LLIST_TS_NEXT_FILTER(i, data, fn_match) \
+ llist_next_filter (i, data, (llist_fn_match_t)fn_match)
#define LLIST_TS_FIND_FIRST(l_ts, data, fn_match) \
llist_find_first ((llist_t *)l_ts, data, (llist_fn_match_t)fn_match)
#define LLIST_TS_FIND_NEXT(i, data, fn_match) \
@@ -75,6 +78,9 @@ struct llist_ts {
#define LLIST_TS_FIND_FOREACH(l_ts, data, fn_match, i) \
for (i = LLIST_TS_FIND_FIRST (l_ts, data, fn_match); i; \
i = LLIST_TS_FIND_NEXT (i, data, fn_match))
+#define LLIST_TS_FIND_FOREACH_CONT(l_ts, data, fn_match, i) \
+ for (i = LLIST_TS_FIND_FIRST (l_ts, data, fn_match); i; \
+ i = LLIST_TS_NEXT_FILTER (i, data, fn_match))
/* Accessing list item data. */
#define LLIST_TS_GET_DATA(i) llist_get_data (i)
@@ -84,4 +90,3 @@ struct llist_ts {
#define LLIST_TS_REMOVE(l_ts, i) llist_remove ((llist_t *)l_ts, i)
#define LLIST_TS_ADD_SORTED(l_ts, data, fn_cmp) \
llist_add_sorted ((llist_t *)l_ts, data, (llist_fn_cmp_t)fn_cmp)
-
diff --git a/src/mem.c b/src/mem.c
index 82b28f3..ecb8aa4 100644
--- a/src/mem.c
+++ b/src/mem.c
@@ -1,7 +1,7 @@
/*
* Calcurse - text-based organizer
*
- * Copyright (c) 2004-2011 calcurse Development Team <misc@calcurse.org>
+ * Copyright (c) 2004-2012 calcurse Development Team <misc@calcurse.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -41,6 +41,8 @@
#include "calcurse.h"
+#ifdef CALCURSE_MEMORY_DEBUG
+
enum {
BLK_STATE,
BLK_SIZE,
@@ -67,252 +69,233 @@ struct mem_stats {
static struct mem_stats mstats;
+#endif /* CALCURSE_MEMORY_DEBUG */
-static unsigned
-stats_add_blk (size_t size, const char *pos)
-{
- struct mem_blk *o, **i;
-
- o = malloc (sizeof (*o));
- EXIT_IF (o == NULL, _("could not allocate memory to store block info"));
-
- mstats.ncall++;
-
- o->pos = pos;
- o->size = (unsigned)size;
- o->next = 0;
-
- for (i = &mstats.blk; *i; i = &(*i)->next)
- ;
- o->id = mstats.ncall;
- *i = o;
-
- return o->id;
-}
-
-static void
-stats_del_blk (unsigned id)
-{
- struct mem_blk *o, **i;
-
- i = &mstats.blk;
- for (o = mstats.blk; o; o = o->next)
- {
- if (o->id == id)
- {
- *i = o->next;
- free (o);
- return;
- }
- i = &o->next;
- }
-
- EXIT (_("Block not found"));
- /* NOTREACHED */
-}
-
-void *
-xmalloc (size_t size)
+void *xmalloc(size_t size)
{
void *p;
- EXIT_IF (size == 0, _("xmalloc: zero size"));
- p = malloc (size);
- EXIT_IF (p == NULL, _("xmalloc: out of memory"));
+ EXIT_IF(size == 0, _("xmalloc: zero size"));
+ p = malloc(size);
+ EXIT_IF(p == NULL, _("xmalloc: out of memory"));
return p;
}
-void *
-xcalloc (size_t nmemb, size_t size)
+void *xcalloc(size_t nmemb, size_t size)
{
void *p;
- EXIT_IF (nmemb == 0 || size == 0, _("xcalloc: zero size"));
- EXIT_IF (SIZE_MAX / nmemb < size, _("xcalloc: overflow"));
- p = calloc (nmemb, size);
- EXIT_IF (p == NULL, _("xcalloc: out of memory"));
+ EXIT_IF(nmemb == 0 || size == 0, _("xcalloc: zero size"));
+ EXIT_IF(SIZE_MAX / nmemb < size, _("xcalloc: overflow"));
+ p = calloc(nmemb, size);
+ EXIT_IF(p == NULL, _("xcalloc: out of memory"));
return p;
}
-void *
-xrealloc (void *ptr, size_t nmemb, size_t size)
+void *xrealloc(void *ptr, size_t nmemb, size_t size)
{
void *new_ptr;
size_t new_size;
new_size = nmemb * size;
- EXIT_IF (new_size == 0, _("xrealloc: zero size"));
- EXIT_IF (SIZE_MAX / nmemb < size, _("xrealloc: overflow"));
- new_ptr = realloc (ptr, new_size);
- EXIT_IF (new_ptr == NULL, _("xrealloc: out of memory"));
+ EXIT_IF(new_size == 0, _("xrealloc: zero size"));
+ EXIT_IF(SIZE_MAX / nmemb < size, _("xrealloc: overflow"));
+ new_ptr = realloc(ptr, new_size);
+ EXIT_IF(new_ptr == NULL, _("xrealloc: out of memory"));
return new_ptr;
}
-char *
-xstrdup (const char *str)
+char *xstrdup(const char *str)
{
size_t len;
char *cp;
- len = strlen (str) + 1;
- cp = xmalloc (len);
+ len = strlen(str) + 1;
+ cp = xmalloc(len);
+
+ return strncpy(cp, str, len);
+}
+
+void xfree(void *p)
+{
+ EXIT_IF(p == NULL, _("xfree: null pointer"));
+ free(p);
+}
+
+#ifdef CALCURSE_MEMORY_DEBUG
+
+static unsigned stats_add_blk(size_t size, const char *pos)
+{
+ struct mem_blk *o, **i;
+
+ o = malloc(sizeof(*o));
+ EXIT_IF(o == NULL, _("could not allocate memory to store block info"));
+
+ mstats.ncall++;
+
+ o->pos = pos;
+ o->size = (unsigned)size;
+ o->next = 0;
+
+ for (i = &mstats.blk; *i; i = &(*i)->next) ;
+ o->id = mstats.ncall;
+ *i = o;
- return strncpy (cp, str, len);
+ return o->id;
}
-void
-xfree (void *p)
+static void stats_del_blk(unsigned id)
{
- EXIT_IF (p == NULL, _("xfree: null pointer"));
- free (p);
+ struct mem_blk *o, **i;
+
+ i = &mstats.blk;
+ for (o = mstats.blk; o; o = o->next) {
+ if (o->id == id) {
+ *i = o->next;
+ free(o);
+ return;
+ }
+ i = &o->next;
+ }
+
+ EXIT(_("Block not found"));
+ /* NOTREACHED */
}
-void *
-dbg_malloc (size_t size, const char *pos)
+void *dbg_malloc(size_t size, const char *pos)
{
unsigned *buf;
- if (size == 0)
- return (void *)0;
+ if (size == 0)
+ return NULL;
- size = EXTRA_SPACE + (size + sizeof (unsigned) - 1) / sizeof (unsigned);
- buf = xmalloc (size * sizeof (unsigned));
+ size = EXTRA_SPACE + (size + sizeof(unsigned) - 1) / sizeof(unsigned);
+ buf = xmalloc(size * sizeof(unsigned));
- buf[BLK_STATE] = MAGIC_ALLOC; /* state of the block */
- buf[BLK_SIZE] = size; /* size of the block */
- buf[BLK_ID] = stats_add_blk (size, pos); /* identify a block by its id */
- buf[size - 1] = buf[BLK_ID]; /* mark at end of block */
+ buf[BLK_STATE] = MAGIC_ALLOC; /* state of the block */
+ buf[BLK_SIZE] = size; /* size of the block */
+ buf[BLK_ID] = stats_add_blk(size, pos); /* identify a block by its id */
+ buf[size - 1] = buf[BLK_ID]; /* mark at end of block */
mstats.nalloc += size;
return (void *)(buf + EXTRA_SPACE_START);
}
-void *
-dbg_calloc (size_t nmemb, size_t size, const char *pos)
+void *dbg_calloc(size_t nmemb, size_t size, const char *pos)
{
void *buf;
if (!nmemb || !size)
- return (void *)0;
+ return NULL;
- EXIT_IF (nmemb > SIZE_MAX / size, _("overflow at %s"), pos);
+ EXIT_IF(nmemb > SIZE_MAX / size, _("overflow at %s"), pos);
size *= nmemb;
- if ((buf = dbg_malloc (size, pos)) == NULL)
- return (void *)0;
+ if ((buf = dbg_malloc(size, pos)) == NULL)
+ return NULL;
- bzero (buf, size);
+ memset(buf, 0, size);
return buf;
}
-void *
-dbg_realloc (void *ptr, size_t nmemb, size_t size, const char *pos)
+void *dbg_realloc(void *ptr, size_t nmemb, size_t size, const char *pos)
{
unsigned *buf, old_size, new_size, cpy_size;
if (ptr == NULL)
- return (void *)0;
+ return NULL;
- new_size = nmemb *size;
+ new_size = nmemb * size;
if (new_size == 0)
- return (void *)0;
+ return NULL;
- EXIT_IF (nmemb > SIZE_MAX / size, _("overflow at %s"), pos);
+ EXIT_IF(nmemb > SIZE_MAX / size, _("overflow at %s"), pos);
- if ((buf = dbg_malloc (new_size, pos)) == NULL)
- return (void *)0;
+ if ((buf = dbg_malloc(new_size, pos)) == NULL)
+ return NULL;
old_size = *((unsigned *)ptr - EXTRA_SPACE_START + BLK_SIZE);
cpy_size = (old_size > new_size) ? new_size : old_size;
- bcopy (ptr, buf, cpy_size);
+ memmove(buf, ptr, cpy_size);
- mem_free (ptr);
+ mem_free(ptr);
return (void *)buf;
}
-char *
-dbg_strdup (const char *s, const char *pos)
+char *dbg_strdup(const char *s, const char *pos)
{
size_t size;
char *buf;
if (s == NULL)
- return (char *)0;
+ return NULL;
- size = strlen (s);
- if ((buf = dbg_malloc (size + 1, pos)) == NULL)
- return (char *)0;
+ size = strlen(s);
+ if ((buf = dbg_malloc(size + 1, pos)) == NULL)
+ return NULL;
- return strncpy (buf, s, size + 1);
+ return strncpy(buf, s, size + 1);
}
-void
-dbg_free (void *ptr, const char *pos)
+void dbg_free(void *ptr, const char *pos)
{
unsigned *buf, size;
- EXIT_IF (ptr == NULL, _("dbg_free: null pointer at %s"), pos);
+ EXIT_IF(ptr == NULL, _("dbg_free: null pointer at %s"), pos);
buf = (unsigned *)ptr - EXTRA_SPACE_START;
size = buf[BLK_SIZE];
- EXIT_IF (buf[BLK_STATE] == MAGIC_FREE,
- _("block seems already freed at %s"), pos);
- EXIT_IF (buf[BLK_STATE] != MAGIC_ALLOC,
- _("corrupt block header at %s"), pos);
- EXIT_IF (buf[size - 1] != buf[BLK_ID],
- _("corrupt block end at %s, (end = %u, should be %d)"), pos,
- buf[size - 1], buf[BLK_ID]);
+ EXIT_IF(buf[BLK_STATE] == MAGIC_FREE,
+ _("block seems already freed at %s"), pos);
+ EXIT_IF(buf[BLK_STATE] != MAGIC_ALLOC, _("corrupt block header at %s"), pos);
+ EXIT_IF(buf[size - 1] != buf[BLK_ID],
+ _("corrupt block end at %s, (end = %u, should be %d)"), pos,
+ buf[size - 1], buf[BLK_ID]);
buf[0] = MAGIC_FREE;
- stats_del_blk (buf[BLK_ID]);
+ stats_del_blk(buf[BLK_ID]);
- free (buf);
+ free(buf);
mstats.nfree += size;
}
-
-#ifdef CALCURSE_MEMORY_DEBUG
-
-static void
-dump_block_info (struct mem_blk *blk)
+static void dump_block_info(struct mem_blk *blk)
{
if (blk == NULL)
return;
- printf (_("---==== MEMORY BLOCK ====----------------\n"));
- printf (_(" id: %u\n"), blk->id);
- printf (_(" size: %u\n"), blk->size);
- printf (_(" allocated in: %s\n"), blk->pos);
- printf (_("-----------------------------------------\n"));
+ puts(_("---==== MEMORY BLOCK ====----------------\n"));
+ printf(_(" id: %u\n"), blk->id);
+ printf(_(" size: %u\n"), blk->size);
+ printf(_(" allocated in: %s\n"), blk->pos);
+ puts(_("-----------------------------------------\n"));
}
-void
-mem_stats (void)
+void mem_stats(void)
{
- printf ("\n");
- printf (_("+------------------------------+\n"));
- printf (_("| calcurse memory usage report |\n"));
- printf (_("+------------------------------+\n"));
- printf (_(" number of calls: %u\n"), mstats.ncall);
- printf (_(" allocated blocks: %u\n"), mstats.nalloc);
- printf (_(" unfreed blocks: %u\n"), mstats.nalloc - mstats.nfree);
- printf ("\n");
-
- if (mstats.nfree < mstats.nalloc)
- {
- struct mem_blk *blk;
-
- for (blk = mstats.blk; blk; blk = blk->next)
- dump_block_info (blk);
- }
+ putchar('\n');
+ puts(_("+------------------------------+\n"));
+ puts(_("| calcurse memory usage report |\n"));
+ puts(_("+------------------------------+\n"));
+ printf(_(" number of calls: %u\n"), mstats.ncall);
+ printf(_(" allocated blocks: %u\n"), mstats.nalloc);
+ printf(_(" unfreed blocks: %u\n"), mstats.nalloc - mstats.nfree);
+ putchar('\n');
+
+ if (mstats.nfree < mstats.nalloc) {
+ struct mem_blk *blk;
+
+ for (blk = mstats.blk; blk; blk = blk->next)
+ dump_block_info(blk);
+ }
}
#endif /* CALCURSE_MEMORY_DEBUG */
diff --git a/src/note.c b/src/note.c
new file mode 100644
index 0000000..d2f7ab2
--- /dev/null
+++ b/src/note.c
@@ -0,0 +1,235 @@
+/*
+ * Calcurse - text-based organizer
+ *
+ * Copyright (c) 2004-2012 calcurse Development Team <misc@calcurse.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Send your feedback or comments to : misc@calcurse.org
+ * Calcurse home page : http://calcurse.org
+ *
+ */
+
+#include <unistd.h>
+#include <dirent.h>
+
+#include "calcurse.h"
+#include "sha1.h"
+
+struct note_gc_hash {
+ char *hash;
+ char buf[MAX_NOTESIZ + 1];
+ HTABLE_ENTRY(note_gc_hash);
+};
+
+static void note_gc_extract_key(struct note_gc_hash *, const char **, int *);
+static int note_gc_cmp(struct note_gc_hash *, struct note_gc_hash *);
+
+HTABLE_HEAD(htp, NOTE_GC_HSIZE, note_gc_hash);
+HTABLE_PROTOTYPE(htp, note_gc_hash)
+ HTABLE_GENERATE(htp, note_gc_hash, note_gc_extract_key, note_gc_cmp)
+
+/* Create note file from a string and return a newly allocated string that
+ * contains its name. */
+char *generate_note(const char *str)
+{
+ char *sha1 = mem_malloc(SHA1_DIGESTLEN * 2 + 1);
+ char notepath[BUFSIZ];
+ FILE *fp;
+
+ sha1_digest(str, sha1);
+ snprintf(notepath, BUFSIZ, "%s%s", path_notes, sha1);
+ fp = fopen(notepath, "w");
+ EXIT_IF(fp == NULL, _("Warning: could not open %s, Aborting..."), notepath);
+ fputs(str, fp);
+ file_close(fp, __FILE_POS__);
+
+ return sha1;
+}
+
+/* Edit a note with an external editor. */
+void edit_note(char **note, const char *editor)
+{
+ char tmppath[BUFSIZ];
+ char *tmpext;
+ char notepath[BUFSIZ];
+ char *sha1 = mem_malloc(SHA1_DIGESTLEN * 2 + 1);
+ FILE *fp;
+
+ strncpy(tmppath, get_tempdir(), BUFSIZ);
+ strncat(tmppath, "/calcurse-note.", BUFSIZ - strlen(tmppath) - 1);
+ if ((tmpext = new_tempfile(tmppath, TMPEXTSIZ)) == NULL)
+ return;
+ strncat(tmppath, tmpext, BUFSIZ - strlen(tmppath) - 1);
+ mem_free(tmpext);
+
+ if (*note != NULL) {
+ snprintf(notepath, BUFSIZ, "%s%s", path_notes, *note);
+ io_file_cp(notepath, tmppath);
+ }
+
+ wins_launch_external(tmppath, editor);
+
+ if (io_file_is_empty(tmppath) > 0)
+ erase_note(note);
+ else if ((fp = fopen(tmppath, "r"))) {
+ sha1_stream(fp, sha1);
+ fclose(fp);
+ *note = sha1;
+
+ snprintf(notepath, BUFSIZ, "%s%s", path_notes, *note);
+ io_file_cp(tmppath, notepath);
+ }
+
+ unlink(tmppath);
+}
+
+/* View a note in an external pager. */
+void view_note(const char *note, const char *pager)
+{
+ char fullname[BUFSIZ];
+
+ if (note == NULL)
+ return;
+ snprintf(fullname, BUFSIZ, "%s%s", path_notes, note);
+ wins_launch_external(fullname, pager);
+}
+
+/* Erase a note previously attached to an item. */
+void erase_note(char **note)
+{
+ if (*note == NULL)
+ return;
+ mem_free(*note);
+ *note = NULL;
+}
+
+/* Read a serialized note file name from a stream and deserialize it. */
+void note_read(char *buffer, FILE * fp)
+{
+ int i;
+
+ for (i = 0; i < MAX_NOTESIZ; i++) {
+ buffer[i] = getc(fp);
+ if (buffer[i] == ' ') {
+ buffer[i] = '\0';
+ return;
+ }
+ }
+
+ while (getc(fp) != ' ') ;
+ buffer[MAX_NOTESIZ] = '\0';
+}
+
+static void
+note_gc_extract_key(struct note_gc_hash *data, const char **key, int *len)
+{
+ *key = data->hash;
+ *len = strlen(data->hash);
+}
+
+static int note_gc_cmp(struct note_gc_hash *a, struct note_gc_hash *b)
+{
+ return strcmp(a->hash, b->hash);
+}
+
+/* Spot and unlink unused note files. */
+void note_gc(void)
+{
+ struct htp gc_htable = HTABLE_INITIALIZER(&gc_htable);
+ struct note_gc_hash *hp;
+ DIR *dirp;
+ struct dirent *dp;
+ llist_item_t *i;
+ struct note_gc_hash tmph;
+ char notepath[BUFSIZ];
+
+ if (!(dirp = opendir(path_notes)))
+ return;
+
+ /* Insert all note file names into a hash table. */
+ do {
+ if ((dp = readdir(dirp)) && *(dp->d_name) != '.') {
+ hp = mem_malloc(sizeof(struct note_gc_hash));
+
+ strncpy(hp->buf, dp->d_name, MAX_NOTESIZ + 1);
+ hp->hash = hp->buf;
+
+ HTABLE_INSERT(htp, &gc_htable, hp);
+ }
+ }
+ while (dp);
+
+ closedir(dirp);
+
+ /* Remove hashes that are actually in use. */
+ LLIST_TS_FOREACH(&alist_p, i) {
+ struct apoint *apt = LLIST_GET_DATA(i);
+ if (apt->note) {
+ tmph.hash = apt->note;
+ free(HTABLE_REMOVE(htp, &gc_htable, &tmph));
+ }
+ }
+
+ LLIST_FOREACH(&eventlist, i) {
+ struct event *ev = LLIST_GET_DATA(i);
+ if (ev->note) {
+ tmph.hash = ev->note;
+ free(HTABLE_REMOVE(htp, &gc_htable, &tmph));
+ }
+ }
+
+ LLIST_TS_FOREACH(&recur_alist_p, i) {
+ struct recur_apoint *rapt = LLIST_GET_DATA(i);
+ if (rapt->note) {
+ tmph.hash = rapt->note;
+ free(HTABLE_REMOVE(htp, &gc_htable, &tmph));
+ }
+ }
+
+ LLIST_FOREACH(&recur_elist, i) {
+ struct recur_event *rev = LLIST_GET_DATA(i);
+ if (rev->note) {
+ tmph.hash = rev->note;
+ free(HTABLE_REMOVE(htp, &gc_htable, &tmph));
+ }
+ }
+
+ LLIST_FOREACH(&todolist, i) {
+ struct todo *todo = LLIST_GET_DATA(i);
+ if (todo->note) {
+ tmph.hash = todo->note;
+ free(HTABLE_REMOVE(htp, &gc_htable, &tmph));
+ }
+ }
+
+ /* Unlink unused note files. */
+ HTABLE_FOREACH(hp, htp, &gc_htable) {
+ snprintf(notepath, BUFSIZ, "%s%s", path_notes, hp->hash);
+ unlink(notepath);
+ }
+}
diff --git a/src/notify.c b/src/notify.c
index 3ed53bf..c746f49 100644
--- a/src/notify.c
+++ b/src/notify.c
@@ -1,7 +1,7 @@
/*
* Calcurse - text-based organizer
*
- * Copyright (c) 2004-2011 calcurse Development Team <misc@calcurse.org>
+ * Copyright (c) 2004-2012 calcurse Development Team <misc@calcurse.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -51,22 +51,21 @@ struct notify_vars {
pthread_mutex_t mutex;
};
-static struct notify_vars notify;
-static struct notify_app notify_app;
-static pthread_attr_t detached_thread_attr;
-static pthread_t notify_t_main;
+static struct notify_vars notify;
+static struct notify_app notify_app;
+static pthread_attr_t detached_thread_attr;
+static pthread_t notify_t_main;
/*
* Return the number of seconds before next appointment
* (0 if no upcoming appointment).
*/
-int
-notify_time_left (void)
+int notify_time_left(void)
{
time_t ntimer;
int left;
- ntimer = time (NULL);
+ ntimer = time(NULL);
left = notify_app.time - ntimer;
return left > 0 ? left : 0;
@@ -76,11 +75,11 @@ notify_time_left (void)
* Return 1 if the reminder was not sent already for the upcoming
* appointment.
*/
-unsigned
-notify_needs_reminder (void)
+unsigned notify_needs_reminder(void)
{
if (notify_app.got_app
- && (notify_app.state & APOINT_NOTIFY)
+ && (((notify_app.state & APOINT_NOTIFY) && !nbar.notify_all) ||
+ (!(notify_app.state & APOINT_NOTIFY) && nbar.notify_all))
&& !(notify_app.state & APOINT_NOTIFIED))
return 1;
return 0;
@@ -91,66 +90,62 @@ notify_needs_reminder (void)
* Note: the mutex associated with this structure must be locked by the
* caller!
*/
-void
-notify_update_app (long start, char state, char *msg)
+void notify_update_app(long start, char state, char *msg)
{
- notify_free_app ();
+ notify_free_app();
notify_app.got_app = 1;
notify_app.time = start;
notify_app.state = state;
- notify_app.txt = mem_strdup (msg);
+ notify_app.txt = mem_strdup(msg);
}
/* Return 1 if we need to display the notify-bar, else 0. */
-int
-notify_bar (void)
+int notify_bar(void)
{
int display_bar = 0;
- pthread_mutex_lock (&nbar.mutex);
+ pthread_mutex_lock(&nbar.mutex);
display_bar = (nbar.show) ? 1 : 0;
- pthread_mutex_unlock (&nbar.mutex);
+ pthread_mutex_unlock(&nbar.mutex);
- return (display_bar);
+ return display_bar;
}
/* Initialize the nbar variable used to store notification options. */
-void
-notify_init_vars (void)
+void notify_init_vars(void)
{
- char *time_format = "%T";
- char *date_format = "%a %F";
- char *cmd = "printf '\\a'";
+ const char *time_format = "%T";
+ const char *date_format = "%a %F";
+ const char *cmd = "printf '\\a'";
- pthread_mutex_init (&nbar.mutex, NULL);
+ pthread_mutex_init(&nbar.mutex, NULL);
nbar.show = 1;
nbar.cntdwn = 300;
- (void)strncpy (nbar.datefmt, date_format, strlen (date_format) + 1);
- (void)strncpy (nbar.timefmt, time_format, strlen (time_format) + 1);
- (void)strncpy (nbar.cmd, cmd, strlen (cmd) + 1);
+ strncpy(nbar.datefmt, date_format, strlen(date_format) + 1);
+ strncpy(nbar.timefmt, time_format, strlen(time_format) + 1);
+ strncpy(nbar.cmd, cmd, strlen(cmd) + 1);
- if ((nbar.shell = getenv ("SHELL")) == NULL)
+ if ((nbar.shell = getenv("SHELL")) == NULL)
nbar.shell = "/bin/sh";
- (void)pthread_attr_init (&detached_thread_attr);
- (void)pthread_attr_setdetachstate (&detached_thread_attr,
- PTHREAD_CREATE_DETACHED);
+ nbar.notify_all = 0;
+
+ pthread_attr_init(&detached_thread_attr);
+ pthread_attr_setdetachstate(&detached_thread_attr, PTHREAD_CREATE_DETACHED);
}
/* Extract the appointment file name from the complete file path. */
-static void
-extract_aptsfile (void)
+static void extract_aptsfile(void)
{
char *file;
- file = strrchr (path_apts, '/');
+ file = strrchr(path_apts, '/');
if (!file)
notify.apts_file = path_apts;
- else
- {
- notify.apts_file = file;
- notify.apts_file++;
- }
+ else {
+ notify.apts_file = file;
+ notify.apts_file++;
+ }
}
/*
@@ -158,56 +153,50 @@ extract_aptsfile (void)
* creating the notification window (l is the number of lines, c the
* number of columns, y and x are its coordinates).
*/
-void
-notify_init_bar (void)
+void notify_init_bar(void)
{
- pthread_mutex_init (&notify.mutex, NULL);
- pthread_mutex_init (&notify_app.mutex, NULL);
+ pthread_mutex_init(&notify.mutex, NULL);
+ pthread_mutex_init(&notify_app.mutex, NULL);
notify_app.got_app = 0;
notify_app.txt = 0;
- notify.win = newwin (win[NOT].h, win[NOT].w, win[NOT].y, win[NOT].x);
- extract_aptsfile ();
+ notify.win = newwin(win[NOT].h, win[NOT].w, win[NOT].y, win[NOT].x);
+ extract_aptsfile();
}
/*
* Free memory associated with the notify_app structure.
*/
-void
-notify_free_app (void)
+void notify_free_app(void)
{
notify_app.time = 0;
notify_app.got_app = 0;
notify_app.state = APOINT_NULL;
if (notify_app.txt)
- mem_free (notify_app.txt);
+ mem_free(notify_app.txt);
notify_app.txt = 0;
}
/* Stop the notify-bar main thread. */
-void
-notify_stop_main_thread (void)
+void notify_stop_main_thread(void)
{
- if (notify_t_main)
- {
- pthread_cancel (notify_t_main);
- pthread_join (notify_t_main, NULL);
- }
+ if (notify_t_main) {
+ pthread_cancel(notify_t_main);
+ pthread_join(notify_t_main, NULL);
+ }
}
/*
* The calcurse window geometry has changed so we need to reset the
* notification window.
*/
-void
-notify_reinit_bar (void)
+void notify_reinit_bar(void)
{
- delwin (notify.win);
- notify.win = newwin (win[NOT].h, win[NOT].w, win[NOT].y, win[NOT].x);
+ delwin(notify.win);
+ notify.win = newwin(win[NOT].h, win[NOT].w, win[NOT].y, win[NOT].x);
}
/* Launch user defined command as a notification. */
-unsigned
-notify_launch_cmd (void)
+unsigned notify_launch_cmd(void)
{
int pid;
@@ -216,23 +205,19 @@ notify_launch_cmd (void)
notify_app.state |= APOINT_NOTIFIED;
- pid = fork ();
+ pid = fork();
- if (pid < 0)
- {
- ERROR_MSG (_("error while launching command: could not fork"));
- return 0;
- }
- else if (pid == 0)
- {
- /* Child: launch user defined command */
- if (execlp (nbar.shell, nbar.shell, "-c", nbar.cmd, (char *)0) < 0)
- {
- ERROR_MSG (_("error while launching command"));
- _exit (1);
- }
- _exit (0);
+ if (pid < 0) {
+ ERROR_MSG(_("error while launching command: could not fork"));
+ return 0;
+ } else if (pid == 0) {
+ /* Child: launch user defined command */
+ if (execlp(nbar.shell, nbar.shell, "-c", nbar.cmd, NULL) < 0) {
+ ERROR_MSG(_("error while launching command"));
+ _exit(1);
}
+ _exit(0);
+ }
return 1;
}
@@ -241,8 +226,7 @@ notify_launch_cmd (void)
* Update the notification bar. This is useful when changing color theme
* for example.
*/
-void
-notify_update_bar (void)
+void notify_update_bar(void)
{
const int space = 3;
int file_pos, date_pos, app_pos, txt_max_len, too_long = 0;
@@ -250,82 +234,77 @@ notify_update_bar (void)
char buf[BUFSIZ];
date_pos = space;
- pthread_mutex_lock (&notify.mutex);
+ pthread_mutex_lock(&notify.mutex);
- file_pos = strlen (notify.date) + strlen (notify.time) + 7 + 2 * space;
- app_pos = file_pos + strlen (notify.apts_file) + 2 + space;
+ file_pos = strlen(notify.date) + strlen(notify.time) + 7 + 2 * space;
+ app_pos = file_pos + strlen(notify.apts_file) + 2 + space;
txt_max_len = col - (app_pos + 12 + space);
- custom_apply_attr (notify.win, ATTR_HIGHEST);
- wattron (notify.win, A_UNDERLINE | A_REVERSE);
- mvwhline (notify.win, 0, 0, ACS_HLINE, col);
- mvwprintw (notify.win, 0, date_pos, "[ %s | %s ]",
- notify.date, notify.time);
- mvwprintw (notify.win, 0, file_pos, "(%s)", notify.apts_file);
+ custom_apply_attr(notify.win, ATTR_HIGHEST);
+ wattron(notify.win, A_UNDERLINE | A_REVERSE);
+ mvwhline(notify.win, 0, 0, ACS_HLINE, col);
+ mvwprintw(notify.win, 0, date_pos, "[ %s | %s ]", notify.date, notify.time);
+ mvwprintw(notify.win, 0, file_pos, "(%s)", notify.apts_file);
+
+ pthread_mutex_lock(&notify_app.mutex);
+ if (notify_app.got_app) {
+ if (strlen(notify_app.txt) > txt_max_len) {
+ int shrink_len;
+
+ too_long = 1;
+ shrink_len = txt_max_len > 3 ? txt_max_len - 3 : 1;
+ strncpy(buf, notify_app.txt, shrink_len);
+ buf[shrink_len] = '\0';
+ }
+ time_left = notify_time_left();
+ if (time_left > 0) {
+ int hours_left, minutes_left;
+
+ hours_left = (time_left / HOURINSEC);
+ minutes_left = (time_left - hours_left * HOURINSEC) / MININSEC;
+ pthread_mutex_lock(&nbar.mutex);
+
+ if (time_left < nbar.cntdwn &&
+ (((notify_app.state & APOINT_NOTIFY) && !nbar.notify_all) ||
+ (!(notify_app.state & APOINT_NOTIFY) && nbar.notify_all)))
+ blinking = 1;
+ else
+ blinking = 0;
- pthread_mutex_lock (&notify_app.mutex);
- if (notify_app.got_app)
- {
- if (strlen (notify_app.txt) > txt_max_len)
- {
- int shrink_len;
-
- too_long = 1;
- shrink_len = txt_max_len > 3 ? txt_max_len - 3 : 1;
- (void)strncpy (buf, notify_app.txt, shrink_len);
- buf[shrink_len] = '\0';
- }
- time_left = notify_time_left ();
- if (time_left > 0)
- {
- int hours_left, minutes_left;
-
- hours_left = (time_left / HOURINSEC);
- minutes_left = (time_left - hours_left * HOURINSEC) / MININSEC;
- pthread_mutex_lock (&nbar.mutex);
-
- if (time_left < nbar.cntdwn && (notify_app.state & APOINT_NOTIFY))
- blinking = 1;
- else
- blinking = 0;
-
- if (blinking)
- wattron (notify.win, A_BLINK);
- if (too_long)
- mvwprintw (notify.win, 0, app_pos, "> %02d:%02d :: %s.. <",
- hours_left, minutes_left, buf);
- else
- mvwprintw (notify.win, 0, app_pos, "> %02d:%02d :: %s <",
- hours_left, minutes_left, notify_app.txt);
- if (blinking)
- wattroff (notify.win, A_BLINK);
-
- if (blinking)
- (void)notify_launch_cmd ();
- pthread_mutex_unlock (&nbar.mutex);
- }
+ if (blinking)
+ wattron(notify.win, A_BLINK);
+ if (too_long)
+ mvwprintw(notify.win, 0, app_pos, "> %02d:%02d :: %s.. <",
+ hours_left, minutes_left, buf);
else
- {
- notify_app.got_app = 0;
- pthread_mutex_unlock (&notify_app.mutex);
- pthread_mutex_unlock (&notify.mutex);
- notify_check_next_app (0);
- return;
- }
+ mvwprintw(notify.win, 0, app_pos, "> %02d:%02d :: %s <",
+ hours_left, minutes_left, notify_app.txt);
+ if (blinking)
+ wattroff(notify.win, A_BLINK);
+
+ if (blinking)
+ notify_launch_cmd();
+ pthread_mutex_unlock(&nbar.mutex);
+ } else {
+ notify_app.got_app = 0;
+ pthread_mutex_unlock(&notify_app.mutex);
+ pthread_mutex_unlock(&notify.mutex);
+ notify_check_next_app(0);
+ return;
}
- pthread_mutex_unlock (&notify_app.mutex);
+ }
+ pthread_mutex_unlock(&notify_app.mutex);
- wattroff (notify.win, A_UNDERLINE | A_REVERSE);
- custom_remove_attr (notify.win, ATTR_HIGHEST);
- wins_wrefresh (notify.win);
+ wattroff(notify.win, A_UNDERLINE | A_REVERSE);
+ custom_remove_attr(notify.win, ATTR_HIGHEST);
+ wins_wrefresh(notify.win);
- pthread_mutex_unlock (&notify.mutex);
+ pthread_mutex_unlock(&notify.mutex);
}
/* Update the notication bar content */
/* ARGSUSED0 */
-static void *
-notify_main_thread (void *arg)
+static void *notify_main_thread(void *arg)
{
const unsigned thread_sleep = 1;
const unsigned check_app = MININSEC;
@@ -336,49 +315,46 @@ notify_main_thread (void *arg)
elapse = 0;
- for (;;)
- {
- ntimer = time (NULL);
- ntime = localtime (&ntimer);
- pthread_mutex_lock (&notify.mutex);
- pthread_mutex_lock (&nbar.mutex);
- strftime (notify.time, NOTIFY_FIELD_LENGTH, nbar.timefmt, ntime);
- strftime (notify.date, NOTIFY_FIELD_LENGTH, nbar.datefmt, ntime);
- pthread_mutex_unlock (&nbar.mutex);
- pthread_mutex_unlock (&notify.mutex);
- notify_update_bar ();
- psleep (thread_sleep);
- elapse += thread_sleep;
- if (elapse >= check_app)
- {
- elapse = 0;
- pthread_mutex_lock (&notify_app.mutex);
- got_app = notify_app.got_app;
- pthread_mutex_unlock (&notify_app.mutex);
- if (!got_app)
- notify_check_next_app (0);
- }
+ for (;;) {
+ ntimer = time(NULL);
+ ntime = localtime(&ntimer);
+ pthread_mutex_lock(&notify.mutex);
+ pthread_mutex_lock(&nbar.mutex);
+ strftime(notify.time, NOTIFY_FIELD_LENGTH, nbar.timefmt, ntime);
+ strftime(notify.date, NOTIFY_FIELD_LENGTH, nbar.datefmt, ntime);
+ pthread_mutex_unlock(&nbar.mutex);
+ pthread_mutex_unlock(&notify.mutex);
+ notify_update_bar();
+ psleep(thread_sleep);
+ elapse += thread_sleep;
+ if (elapse >= check_app) {
+ elapse = 0;
+ pthread_mutex_lock(&notify_app.mutex);
+ got_app = notify_app.got_app;
+ pthread_mutex_unlock(&notify_app.mutex);
+ if (!got_app)
+ notify_check_next_app(0);
}
- pthread_exit ((void *) 0);
+ }
+ pthread_exit(NULL);
}
/* Fill the given structure with information about next appointment. */
-unsigned
-notify_get_next (struct notify_app *a)
+unsigned notify_get_next(struct notify_app *a)
{
time_t current_time;
if (!a)
return 0;
- current_time = time (NULL);
+ current_time = time(NULL);
a->time = current_time + DAYINSEC;
a->got_app = 0;
a->state = 0;
- a->txt = (char *)0;
- (void)recur_apoint_check_next (a, current_time, get_today ());
- (void)apoint_check_next (a, current_time);
+ a->txt = NULL;
+ recur_apoint_check_next(a, current_time, get_today());
+ apoint_check_next(a, current_time);
return 1;
}
@@ -387,191 +363,162 @@ notify_get_next (struct notify_app *a)
* This is used for the daemon to check if we have an upcoming appointment or
* not.
*/
-unsigned
-notify_get_next_bkgd (void)
+unsigned notify_get_next_bkgd(void)
{
struct notify_app a;
- a.txt = (char *)0;
- if (!notify_get_next (&a))
+ a.txt = NULL;
+ if (!notify_get_next(&a))
return 0;
- if (!a.got_app)
- {
- /* No next appointment, reset the previous notified one. */
- notify_app.got_app = 0;
- return 1;
- }
- else
- {
- if (!notify_same_item (a.time))
- notify_update_app (a.time, a.state, a.txt);
- }
+ if (!a.got_app) {
+ /* No next appointment, reset the previous notified one. */
+ notify_app.got_app = 0;
+ return 1;
+ } else {
+ if (!notify_same_item(a.time))
+ notify_update_app(a.time, a.state, a.txt);
+ }
if (a.txt)
- mem_free (a.txt);
+ mem_free(a.txt);
return 1;
}
/* Return the description of next appointment to be notified. */
-char *
-notify_app_txt (void)
+char *notify_app_txt(void)
{
if (notify_app.got_app)
return notify_app.txt;
else
- return (char *)0;
+ return NULL;
}
/* Look for the next appointment within the next 24 hours. */
/* ARGSUSED0 */
-static void *
-notify_thread_app (void *arg)
+static void *notify_thread_app(void *arg)
{
struct notify_app tmp_app;
int force = (arg ? 1 : 0);
- if (!notify_get_next (&tmp_app))
- pthread_exit ((void *)0);
-
- if (!tmp_app.got_app)
- {
- pthread_mutex_lock (&notify_app.mutex);
- notify_free_app ();
- pthread_mutex_unlock (&notify_app.mutex);
- }
- else
- {
- if (force || !notify_same_item (tmp_app.time))
- {
- pthread_mutex_lock (&notify_app.mutex);
- notify_update_app (tmp_app.time, tmp_app.state, tmp_app.txt);
- pthread_mutex_unlock (&notify_app.mutex);
- }
+ if (!notify_get_next(&tmp_app))
+ pthread_exit(NULL);
+
+ if (!tmp_app.got_app) {
+ pthread_mutex_lock(&notify_app.mutex);
+ notify_free_app();
+ pthread_mutex_unlock(&notify_app.mutex);
+ } else {
+ if (force || !notify_same_item(tmp_app.time)) {
+ pthread_mutex_lock(&notify_app.mutex);
+ notify_update_app(tmp_app.time, tmp_app.state, tmp_app.txt);
+ pthread_mutex_unlock(&notify_app.mutex);
}
+ }
if (tmp_app.txt)
- mem_free (tmp_app.txt);
- notify_update_bar ();
+ mem_free(tmp_app.txt);
+ notify_update_bar();
- pthread_exit ((void *) 0);
+ pthread_exit(NULL);
}
/* Launch the thread notify_thread_app to look for next appointment. */
-void
-notify_check_next_app (int force)
+void notify_check_next_app(int force)
{
pthread_t notify_t_app;
- void *arg = (force ? (void *)1 : (void *)0);
+ void *arg = (force ? (void *)1 : NULL);
- pthread_create (&notify_t_app, &detached_thread_attr, notify_thread_app,
- arg);
+ pthread_create(&notify_t_app, &detached_thread_attr, notify_thread_app, arg);
return;
}
/* Check if the newly created appointment is to be notified. */
-void
-notify_check_added (char *mesg, long start, char state)
+void notify_check_added(char *mesg, long start, char state)
{
time_t current_time;
int update_notify = 0;
long gap;
- current_time = time (NULL);
- pthread_mutex_lock (&notify_app.mutex);
- if (!notify_app.got_app)
- {
- gap = start - current_time;
- if (gap >= 0 && gap <= DAYINSEC)
- update_notify = 1;
- }
- else if (start < notify_app.time && start >= current_time)
- {
+ current_time = time(NULL);
+ pthread_mutex_lock(&notify_app.mutex);
+ if (!notify_app.got_app) {
+ gap = start - current_time;
+ if (gap >= 0 && gap <= DAYINSEC)
update_notify = 1;
- }
- else if (start == notify_app.time && state != notify_app.state)
+ } else if (start < notify_app.time && start >= current_time) {
+ update_notify = 1;
+ } else if (start == notify_app.time && state != notify_app.state)
update_notify = 1;
- if (update_notify)
- {
- notify_update_app (start, state, mesg);
- }
- pthread_mutex_unlock (&notify_app.mutex);
- notify_update_bar ();
+ if (update_notify) {
+ notify_update_app(start, state, mesg);
+ }
+ pthread_mutex_unlock(&notify_app.mutex);
+ notify_update_bar();
}
/* Check if the newly repeated appointment is to be notified. */
-void
-notify_check_repeated (struct recur_apoint *i)
+void notify_check_repeated(struct recur_apoint *i)
{
- long real_app_time;
+ unsigned real_app_time;
int update_notify = 0;
time_t current_time;
- current_time = time (NULL);
- pthread_mutex_lock (&notify_app.mutex);
- if ((real_app_time = recur_item_inday (i->start, &i->exc, i->rpt->type,
- i->rpt->freq, i->rpt->until,
- get_today ())))
- {
- if (!notify_app.got_app)
- {
- if (real_app_time - current_time <= DAYINSEC)
- update_notify = 1;
- }
- else if (real_app_time < notify_app.time &&
- real_app_time >= current_time)
- {
- update_notify = 1;
- }
- else if (real_app_time == notify_app.time &&
- i->state != notify_app.state)
+ current_time = time(NULL);
+ pthread_mutex_lock(&notify_app.mutex);
+ if (recur_item_find_occurrence(i->start, i->dur, &i->exc, i->rpt->type,
+ i->rpt->freq, i->rpt->until, get_today(),
+ &real_app_time)) {
+ if (!notify_app.got_app) {
+ if (real_app_time - current_time <= DAYINSEC)
update_notify = 1;
- }
- if (update_notify)
- {
- notify_update_app (real_app_time, i->state, i->mesg);
- }
- pthread_mutex_unlock (&notify_app.mutex);
- notify_update_bar ();
+ } else if (real_app_time < notify_app.time && real_app_time >= current_time) {
+ update_notify = 1;
+ } else if (real_app_time == notify_app.time && i->state != notify_app.state)
+ update_notify = 1;
+ }
+ if (update_notify) {
+ notify_update_app(real_app_time, i->state, i->mesg);
+ }
+ pthread_mutex_unlock(&notify_app.mutex);
+ notify_update_bar();
}
-int
-notify_same_item (long time)
+int notify_same_item(long time)
{
int same = 0;
- pthread_mutex_lock (&(notify_app.mutex));
+ pthread_mutex_lock(&(notify_app.mutex));
if (notify_app.got_app && notify_app.time == time)
same = 1;
- pthread_mutex_unlock (&(notify_app.mutex));
+ pthread_mutex_unlock(&(notify_app.mutex));
return same;
}
-int
-notify_same_recur_item (struct recur_apoint *i)
+int notify_same_recur_item(struct recur_apoint *i)
{
int same = 0;
- long item_start = 0;
+ unsigned item_start = 0;
- item_start = recur_item_inday (i->start, &i->exc, i->rpt->type,
- i->rpt->freq, i->rpt->until, get_today ());
- pthread_mutex_lock (&notify_app.mutex);
+ recur_item_find_occurrence(i->start, i->dur, &i->exc, i->rpt->type,
+ i->rpt->freq, i->rpt->until, get_today(),
+ &item_start);
+ pthread_mutex_lock(&notify_app.mutex);
if (notify_app.got_app && item_start == notify_app.time)
same = 1;
- pthread_mutex_unlock (&(notify_app.mutex));
+ pthread_mutex_unlock(&(notify_app.mutex));
return same;
}
/* Launch the notify-bar main thread. */
-void
-notify_start_main_thread (void)
+void notify_start_main_thread(void)
{
- pthread_create (&notify_t_main, NULL, notify_main_thread, NULL);
- notify_check_next_app (0);
+ pthread_create(&notify_t_main, NULL, notify_main_thread, NULL);
+ notify_check_next_app(0);
}
/*
@@ -580,255 +527,248 @@ notify_start_main_thread (void)
* (either YES or NO), or an option holding a string value.
*/
static void
-print_option (WINDOW *win, unsigned x, unsigned y, char *name,
- char *valstr, unsigned valbool, char *desc, unsigned num)
+print_option(WINDOW * win, unsigned x, unsigned y, char *name,
+ char *valstr, unsigned valbool, char *desc, unsigned num)
{
const int XOFF = 4;
const int MAXCOL = col - 3;
int x_opt, len;
- x_opt = x + XOFF + strlen (name);
- mvwprintw (win, y, x, "[%u] %s", num, name);
- erase_window_part (win, x_opt, y, MAXCOL, y);
- if ((len = strlen (valstr)) != 0)
- {
- unsigned maxlen;
-
- maxlen = MAXCOL - x_opt - 2;
- custom_apply_attr (win, ATTR_HIGHEST);
- if (len < maxlen)
- mvwprintw (win, y, x_opt, "%s", valstr);
- else
- {
- char buf[BUFSIZ];
-
- (void)strncpy (buf, valstr, maxlen - 1);
- buf[maxlen - 1] = '\0';
- mvwprintw (win, y, x_opt, "%s...", buf);
- }
- custom_remove_attr (win, ATTR_HIGHEST);
+ x_opt = x + XOFF + strlen(name);
+ mvwprintw(win, y, x, "[%u] %s", num, name);
+ erase_window_part(win, x_opt, y, MAXCOL, y);
+ if ((len = strlen(valstr)) != 0) {
+ unsigned maxlen;
+
+ maxlen = MAXCOL - x_opt - 2;
+ custom_apply_attr(win, ATTR_HIGHEST);
+ if (len < maxlen)
+ mvwprintw(win, y, x_opt, "%s", valstr);
+ else {
+ char buf[BUFSIZ];
+
+ strncpy(buf, valstr, maxlen - 1);
+ buf[maxlen - 1] = '\0';
+ mvwprintw(win, y, x_opt, "%s...", buf);
}
- else
- print_bool_option_incolor (win, valbool, y, x_opt);
- mvwprintw (win, y + 1, x, desc);
+ custom_remove_attr(win, ATTR_HIGHEST);
+ } else
+ print_bool_option_incolor(win, valbool, y, x_opt);
+ mvwprintw(win, y + 1, x, desc);
}
/* Print options related to the notify-bar. */
-static unsigned
-print_config_options (WINDOW *optwin)
+static unsigned print_config_options(WINDOW * optwin)
{
const int XORIG = 3;
const int YORIG = 0;
- const int YOFF = 3;
+ const int YOFF = 3;
- enum
- { SHOW, DATE, CLOCK, WARN, CMD, DMON, DMON_LOG, NB_OPT };
+ enum { SHOW, DATE, CLOCK, WARN, CMD, NOTIFY_ALL, DMON, DMON_LOG, NB_OPT };
- struct opt_s
- {
- char *name;
- char *desc;
- char valstr[BUFSIZ];
- unsigned valnum;
+ struct opt_s {
+ char *name;
+ char *desc;
+ char valstr[BUFSIZ];
+ unsigned valnum;
} opt[NB_OPT];
int i;
- opt[SHOW].name = _("notify-bar_show = ");
+ opt[SHOW].name = _("appearance.notifybar = ");
opt[SHOW].desc = _("(if set to YES, notify-bar will be displayed)");
- opt[DATE].name = _("notify-bar_date = ");
+ opt[DATE].name = _("format.notifydate = ");
opt[DATE].desc = _("(Format of the date to be displayed inside notify-bar)");
- opt[CLOCK].name = _("notify-bar_clock = ");
+ opt[CLOCK].name = _("format.notifytime = ");
opt[CLOCK].desc = _("(Format of the time to be displayed inside notify-bar)");
- opt[WARN].name = _("notify-bar_warning = ");
+ opt[WARN].name = _("notification.warning = ");
opt[WARN].desc = _("(Warn user if an appointment is within next "
"'notify-bar_warning' seconds)");
- opt[CMD].name = _("notify-bar_command = ");
+ opt[CMD].name = _("notification.command = ");
opt[CMD].desc = _("(Command used to notify user of an upcoming appointment)");
- opt[DMON].name = _("notify-daemon_enable = ");
+ opt[NOTIFY_ALL].name = _("notification.notifyall = ");
+ opt[NOTIFY_ALL].desc =
+ _("(Notify all appointments instead of flagged ones only)");
+
+ opt[DMON].name = _("daemon.enable = ");
opt[DMON].desc = _("(Run in background to get notifications after exiting)");
- opt[DMON_LOG].name = _("notify-daemon_log = ");
+ opt[DMON_LOG].name = _("daemon.log = ");
opt[DMON_LOG].desc = _("(Log activity when running in background)");
- pthread_mutex_lock (&nbar.mutex);
+ pthread_mutex_lock(&nbar.mutex);
/* String value options */
- (void)strncpy (opt[DATE].valstr, nbar.datefmt, BUFSIZ);
- (void)strncpy (opt[CLOCK].valstr, nbar.timefmt, BUFSIZ);
- (void)snprintf (opt[WARN].valstr, BUFSIZ, "%d", nbar.cntdwn);
- (void)strncpy (opt[CMD].valstr, nbar.cmd, BUFSIZ);
+ strncpy(opt[DATE].valstr, nbar.datefmt, BUFSIZ);
+ strncpy(opt[CLOCK].valstr, nbar.timefmt, BUFSIZ);
+ snprintf(opt[WARN].valstr, BUFSIZ, "%d", nbar.cntdwn);
+ strncpy(opt[CMD].valstr, nbar.cmd, BUFSIZ);
/* Boolean options */
opt[SHOW].valnum = nbar.show;
- pthread_mutex_unlock (&nbar.mutex);
+ opt[NOTIFY_ALL].valnum = nbar.notify_all;
+ pthread_mutex_unlock(&nbar.mutex);
opt[DMON].valnum = dmon.enable;
opt[DMON_LOG].valnum = dmon.log;
- opt[SHOW].valstr[0] = opt[DMON].valstr[0] = opt[DMON_LOG].valstr[0] = '\0';
+ opt[SHOW].valstr[0] = opt[NOTIFY_ALL].valstr[0] = opt[DMON].valstr[0] =
+ opt[DMON_LOG].valstr[0] = '\0';
- for (i = 0; i < NB_OPT; i++)
- {
- int y;
+ for (i = 0; i < NB_OPT; i++) {
+ int y;
- y = YORIG + i * YOFF;
- print_option (optwin, XORIG, y, opt[i].name, opt[i].valstr,
- opt[i].valnum, opt[i].desc, i + 1);
- }
+ y = YORIG + i * YOFF;
+ print_option(optwin, XORIG, y, opt[i].name, opt[i].valstr,
+ opt[i].valnum, opt[i].desc, i + 1);
+ }
return YORIG + NB_OPT * YOFF;
}
-static void
-reinit_conf_win (struct scrollwin *win)
+static void reinit_conf_win(struct scrollwin *win)
{
unsigned first_line;
first_line = win->first_visible_line;
- wins_scrollwin_delete (win);
- custom_set_swsiz (win);
- wins_scrollwin_init (win);
- wins_show (win->win.p, win->label);
+ wins_scrollwin_delete(win);
+ custom_set_swsiz(win);
+ wins_scrollwin_init(win);
+ wins_show(win->win.p, win->label);
win->first_visible_line = first_line;
}
/* Notify-bar configuration. */
-void
-notify_config_bar (void)
+void notify_config_bar(void)
{
struct scrollwin cwin;
char *buf;
- char *number_str =
- _("Enter an option number to change its value");
- char *keys =
- _("(Press '^P' or '^N' to move up or down, 'Q' to quit)");
- char *date_str =
- _("Enter the date format (see 'man 3 strftime' for possible formats) ");
- char *time_str =
- _("Enter the time format (see 'man 3 strftime' for possible formats) ");
- char *count_str =
- _("Enter the number of seconds (0 not to be warned before an appointment)");
- char *cmd_str = _("Enter the notification command ");
+ const char *number_str = _("Enter an option number to change its value");
+ const char *keys = _("(Press '^P' or '^N' to move up or down, 'Q' to quit)");
+ const char *date_str =
+ _("Enter the date format (see 'man 3 strftime' for possible formats) ");
+ const char *time_str =
+ _("Enter the time format (see 'man 3 strftime' for possible formats) ");
+ const char *count_str =
+ _
+ ("Enter the number of seconds (0 not to be warned before an appointment)");
+ const char *cmd_str = _("Enter the notification command ");
int ch;
- clear ();
- custom_set_swsiz (&cwin);
- (void)snprintf (cwin.label, BUFSIZ, _("notification options"));
- wins_scrollwin_init (&cwin);
- wins_show (cwin.win.p, cwin.label);
- status_mesg (number_str, keys);
- cwin.total_lines = print_config_options (cwin.pad.p);
- wins_scrollwin_display (&cwin);
-
- buf = mem_malloc (BUFSIZ);
- while ((ch = wgetch (win[STA].p)) != 'q')
- {
- buf[0] = '\0';
-
- switch (ch)
- {
- case CTRL ('N'):
- wins_scrollwin_down (&cwin, 1);
- break;
- case CTRL ('P'):
- wins_scrollwin_up (&cwin, 1);
- break;
- case '1':
- pthread_mutex_lock (&nbar.mutex);
- nbar.show = !nbar.show;
- pthread_mutex_unlock (&nbar.mutex);
- if (notify_bar ())
- notify_start_main_thread ();
- else
- notify_stop_main_thread ();
- wins_scrollwin_delete (&cwin);
- reinit_conf_win (&cwin);
- break;
- case '2':
- status_mesg (date_str, "");
- pthread_mutex_lock (&nbar.mutex);
- (void)strncpy (buf, nbar.datefmt, strlen (nbar.datefmt) + 1);
- pthread_mutex_unlock (&nbar.mutex);
- if (updatestring (win[STA].p, &buf, 0, 1) == 0)
- {
- pthread_mutex_lock (&nbar.mutex);
- (void)strncpy (nbar.datefmt, buf, strlen (buf) + 1);
- pthread_mutex_unlock (&nbar.mutex);
- }
- break;
- case '3':
- status_mesg (time_str, "");
- pthread_mutex_lock (&nbar.mutex);
- (void)strncpy (buf, nbar.timefmt, strlen (nbar.timefmt) + 1);
- pthread_mutex_unlock (&nbar.mutex);
- if (updatestring (win[STA].p, &buf, 0, 1) == 0)
- {
- pthread_mutex_lock (&nbar.mutex);
- (void)strncpy (nbar.timefmt, buf, strlen (buf) + 1);
- pthread_mutex_unlock (&nbar.mutex);
- }
- break;
- case '4':
- status_mesg (count_str, "");
- pthread_mutex_lock (&nbar.mutex);
- snprintf (buf, BUFSIZ, "%d", nbar.cntdwn);
- pthread_mutex_unlock (&nbar.mutex);
- if (updatestring (win[STA].p, &buf, 0, 1) == 0 &&
- is_all_digit (buf) && atoi (buf) >= 0 && atoi (buf) <= DAYINSEC)
- {
- pthread_mutex_lock (&nbar.mutex);
- nbar.cntdwn = atoi (buf);
- pthread_mutex_unlock (&nbar.mutex);
- }
- break;
- case '5':
- status_mesg (cmd_str, "");
- pthread_mutex_lock (&nbar.mutex);
- (void)strncpy (buf, nbar.cmd, strlen (nbar.cmd) + 1);
- pthread_mutex_unlock (&nbar.mutex);
- if (updatestring (win[STA].p, &buf, 0, 1) == 0)
- {
- pthread_mutex_lock (&nbar.mutex);
- (void)strncpy (nbar.cmd, buf, strlen (buf) + 1);
- pthread_mutex_unlock (&nbar.mutex);
- }
- break;
- case '6':
- dmon.enable = !dmon.enable;
- break;
- case '7':
- dmon.log = !dmon.log;
- break;
- }
-
- if (resize)
- {
- resize = 0;
- wins_get_config ();
- wins_reset ();
- reinit_conf_win (&cwin);
- delwin (win[STA].p);
- win[STA].p = newwin (win[STA].h, win[STA].w, win[STA].y,
- win[STA].x);
- keypad (win[STA].p, TRUE);
- if (notify_bar ())
- {
- notify_reinit_bar ();
- notify_update_bar ();
- }
- clearok (curscr, TRUE);
- }
-
- status_mesg (number_str, keys);
- cwin.total_lines = print_config_options (cwin.pad.p);
- wins_scrollwin_display (&cwin);
+ clear();
+ custom_set_swsiz(&cwin);
+ cwin.label = _("notification options");
+ wins_scrollwin_init(&cwin);
+ wins_show(cwin.win.p, cwin.label);
+ status_mesg(number_str, keys);
+ cwin.total_lines = print_config_options(cwin.pad.p);
+ wins_scrollwin_display(&cwin);
+
+ buf = mem_malloc(BUFSIZ);
+ while ((ch = wgetch(win[STA].p)) != 'q') {
+ buf[0] = '\0';
+
+ switch (ch) {
+ case CTRL('N'):
+ wins_scrollwin_down(&cwin, 1);
+ break;
+ case CTRL('P'):
+ wins_scrollwin_up(&cwin, 1);
+ break;
+ case '1':
+ pthread_mutex_lock(&nbar.mutex);
+ nbar.show = !nbar.show;
+ pthread_mutex_unlock(&nbar.mutex);
+ if (notify_bar())
+ notify_start_main_thread();
+ else
+ notify_stop_main_thread();
+ wins_scrollwin_delete(&cwin);
+ reinit_conf_win(&cwin);
+ break;
+ case '2':
+ status_mesg(date_str, "");
+ pthread_mutex_lock(&nbar.mutex);
+ strncpy(buf, nbar.datefmt, strlen(nbar.datefmt) + 1);
+ pthread_mutex_unlock(&nbar.mutex);
+ if (updatestring(win[STA].p, &buf, 0, 1) == 0) {
+ pthread_mutex_lock(&nbar.mutex);
+ strncpy(nbar.datefmt, buf, strlen(buf) + 1);
+ pthread_mutex_unlock(&nbar.mutex);
+ }
+ break;
+ case '3':
+ status_mesg(time_str, "");
+ pthread_mutex_lock(&nbar.mutex);
+ strncpy(buf, nbar.timefmt, strlen(nbar.timefmt) + 1);
+ pthread_mutex_unlock(&nbar.mutex);
+ if (updatestring(win[STA].p, &buf, 0, 1) == 0) {
+ pthread_mutex_lock(&nbar.mutex);
+ strncpy(nbar.timefmt, buf, strlen(buf) + 1);
+ pthread_mutex_unlock(&nbar.mutex);
+ }
+ break;
+ case '4':
+ status_mesg(count_str, "");
+ pthread_mutex_lock(&nbar.mutex);
+ snprintf(buf, BUFSIZ, "%d", nbar.cntdwn);
+ pthread_mutex_unlock(&nbar.mutex);
+ if (updatestring(win[STA].p, &buf, 0, 1) == 0 &&
+ is_all_digit(buf) && atoi(buf) >= 0 && atoi(buf) <= DAYINSEC) {
+ pthread_mutex_lock(&nbar.mutex);
+ nbar.cntdwn = atoi(buf);
+ pthread_mutex_unlock(&nbar.mutex);
+ }
+ break;
+ case '5':
+ status_mesg(cmd_str, "");
+ pthread_mutex_lock(&nbar.mutex);
+ strncpy(buf, nbar.cmd, strlen(nbar.cmd) + 1);
+ pthread_mutex_unlock(&nbar.mutex);
+ if (updatestring(win[STA].p, &buf, 0, 1) == 0) {
+ pthread_mutex_lock(&nbar.mutex);
+ strncpy(nbar.cmd, buf, strlen(buf) + 1);
+ pthread_mutex_unlock(&nbar.mutex);
+ }
+ break;
+ case '6':
+ pthread_mutex_lock(&nbar.mutex);
+ nbar.notify_all = !nbar.notify_all;
+ pthread_mutex_unlock(&nbar.mutex);
+ notify_check_next_app(1);
+ break;
+ case '7':
+ dmon.enable = !dmon.enable;
+ break;
+ case '8':
+ dmon.log = !dmon.log;
+ break;
+ }
+
+ if (resize) {
+ resize = 0;
+ wins_get_config();
+ wins_reset();
+ reinit_conf_win(&cwin);
+ delwin(win[STA].p);
+ win[STA].p = newwin(win[STA].h, win[STA].w, win[STA].y, win[STA].x);
+ keypad(win[STA].p, TRUE);
+ if (notify_bar()) {
+ notify_reinit_bar();
+ notify_update_bar();
+ }
+ clearok(curscr, TRUE);
}
- mem_free (buf);
- wins_scrollwin_delete (&cwin);
+
+ status_mesg(number_str, keys);
+ cwin.total_lines = print_config_options(cwin.pad.p);
+ wins_scrollwin_display(&cwin);
+ }
+ mem_free(buf);
+ wins_scrollwin_delete(&cwin);
}
diff --git a/src/pcal.c b/src/pcal.c
new file mode 100644
index 0000000..c4f731d
--- /dev/null
+++ b/src/pcal.c
@@ -0,0 +1,291 @@
+/*
+ * Calcurse - text-based organizer
+ *
+ * Copyright (c) 2004-2012 calcurse Development Team <misc@calcurse.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Send your feedback or comments to : misc@calcurse.org
+ * Calcurse home page : http://calcurse.org
+ *
+ */
+
+#include <sys/types.h>
+
+#include "calcurse.h"
+
+/* Static functions used to add export functionalities. */
+static void pcal_export_header(FILE *);
+static void pcal_export_recur_events(FILE *);
+static void pcal_export_events(FILE *);
+static void pcal_export_recur_apoints(FILE *);
+static void pcal_export_apoints(FILE *);
+static void pcal_export_todo(FILE *);
+static void pcal_export_footer(FILE *);
+
+/* Type definition for callbacks to export functions. */
+typedef void (*cb_dump_t) (FILE *, long, long, char *);
+
+/*
+ * Travel through each occurence of an item, and execute the given callback
+ * (mainly used to export data).
+ */
+static void
+foreach_date_dump(const long date_end, struct rpt *rpt, llist_t * exc,
+ long item_first_date, long item_dur, char *item_mesg,
+ cb_dump_t cb_dump, FILE * stream)
+{
+ long date, item_time;
+ struct tm lt;
+ time_t t;
+
+ t = item_first_date;
+ lt = *localtime(&t);
+ lt.tm_hour = lt.tm_min = lt.tm_sec = 0;
+ lt.tm_isdst = -1;
+ date = mktime(&lt);
+ item_time = item_first_date - date;
+
+ while (date <= date_end && date <= rpt->until) {
+ if (recur_item_inday(item_first_date, item_dur, exc, rpt->type,
+ rpt->freq, rpt->until, date)) {
+ (*cb_dump) (stream, date + item_time, item_dur, item_mesg);
+ }
+ switch (rpt->type) {
+ case RECUR_DAILY:
+ date = date_sec_change(date, 0, rpt->freq);
+ break;
+ case RECUR_WEEKLY:
+ date = date_sec_change(date, 0, rpt->freq * WEEKINDAYS);
+ break;
+ case RECUR_MONTHLY:
+ date = date_sec_change(date, rpt->freq, 0);
+ break;
+ case RECUR_YEARLY:
+ date = date_sec_change(date, rpt->freq * 12, 0);
+ break;
+ default:
+ EXIT(_("incoherent repetition type"));
+ /* NOTREACHED */
+ break;
+ }
+ }
+}
+
+static void pcal_export_header(FILE * stream)
+{
+ fputs("# calcurse pcal export\n", stream);
+ fputs("\n# =======\n# options\n# =======\n", stream);
+ fprintf(stream, "opt -A -K -l -m -F %s\n",
+ calendar_week_begins_on_monday()? "Monday" : "Sunday");
+ fputs("# Display week number (i.e. 1-52) on every Monday\n", stream);
+ fprintf(stream, "all monday in all week %%w\n");
+ fputc('\n', stream);
+}
+
+static void pcal_export_footer(FILE * stream)
+{
+}
+
+/* Format and dump event data to a pcal formatted file. */
+static void
+pcal_dump_event(FILE * stream, long event_date, long event_dur,
+ char *event_mesg)
+{
+ char pcal_date[BUFSIZ];
+
+ date_sec2date_fmt(event_date, "%b %d", pcal_date);
+ fprintf(stream, "%s %s\n", pcal_date, event_mesg);
+}
+
+/* Format and dump appointment data to a pcal formatted file. */
+static void
+pcal_dump_apoint(FILE * stream, long apoint_date, long apoint_dur,
+ char *apoint_mesg)
+{
+ char pcal_date[BUFSIZ], pcal_beg[BUFSIZ], pcal_end[BUFSIZ];
+
+ date_sec2date_fmt(apoint_date, "%b %d", pcal_date);
+ date_sec2date_fmt(apoint_date, "%R", pcal_beg);
+ date_sec2date_fmt(apoint_date + apoint_dur, "%R", pcal_end);
+ fprintf(stream, "%s ", pcal_date);
+ fprintf(stream, "(%s -> %s) %s\n", pcal_beg, pcal_end, apoint_mesg);
+}
+
+static void pcal_export_recur_events(FILE * stream)
+{
+ llist_item_t *i;
+ char pcal_date[BUFSIZ];
+
+ fputs("\n# =============", stream);
+ fputs("\n# Recur. Events", stream);
+ fputs("\n# =============\n", stream);
+ fputs("# (pcal does not support from..until dates specification\n", stream);
+
+ LLIST_FOREACH(&recur_elist, i) {
+ struct recur_event *rev = LLIST_GET_DATA(i);
+ if (rev->rpt->until == 0 && rev->rpt->freq == 1) {
+ switch (rev->rpt->type) {
+ case RECUR_DAILY:
+ date_sec2date_fmt(rev->day, "%b %d", pcal_date);
+ fprintf(stream, "all day on_or_after %s %s\n", pcal_date, rev->mesg);
+ break;
+ case RECUR_WEEKLY:
+ date_sec2date_fmt(rev->day, "%a", pcal_date);
+ fprintf(stream, "all %s on_or_after ", pcal_date);
+ date_sec2date_fmt(rev->day, "%b %d", pcal_date);
+ fprintf(stream, "%s %s\n", pcal_date, rev->mesg);
+ break;
+ case RECUR_MONTHLY:
+ date_sec2date_fmt(rev->day, "%d", pcal_date);
+ fprintf(stream, "day on all %s %s\n", pcal_date, rev->mesg);
+ break;
+ case RECUR_YEARLY:
+ date_sec2date_fmt(rev->day, "%b %d", pcal_date);
+ fprintf(stream, "%s %s\n", pcal_date, rev->mesg);
+ break;
+ default:
+ EXIT(_("incoherent repetition type"));
+ }
+ } else {
+ const long YEAR_START = calendar_start_of_year();
+ const long YEAR_END = calendar_end_of_year();
+
+ if (rev->day < YEAR_END && rev->day > YEAR_START)
+ foreach_date_dump(YEAR_END, rev->rpt, &rev->exc, rev->day, 0,
+ rev->mesg, (cb_dump_t) pcal_dump_event, stream);
+ }
+ }
+}
+
+static void pcal_export_events(FILE * stream)
+{
+ llist_item_t *i;
+
+ fputs("\n# ======\n# Events\n# ======\n", stream);
+ LLIST_FOREACH(&eventlist, i) {
+ struct event *ev = LLIST_TS_GET_DATA(i);
+ pcal_dump_event(stream, ev->day, 0, ev->mesg);
+ }
+ fputc('\n', stream);
+}
+
+static void pcal_export_recur_apoints(FILE * stream)
+{
+ llist_item_t *i;
+ char pcal_date[BUFSIZ], pcal_beg[BUFSIZ], pcal_end[BUFSIZ];
+
+ fputs("\n# ==============", stream);
+ fputs("\n# Recur. Apoints", stream);
+ fputs("\n# ==============\n", stream);
+ fputs("# (pcal does not support from..until dates specification\n", stream);
+
+ LLIST_TS_FOREACH(&recur_alist_p, i) {
+ struct recur_apoint *rapt = LLIST_TS_GET_DATA(i);
+
+ if (rapt->rpt->until == 0 && rapt->rpt->freq == 1) {
+ date_sec2date_fmt(rapt->start, "%R", pcal_beg);
+ date_sec2date_fmt(rapt->start + rapt->dur, "%R", pcal_end);
+ switch (rapt->rpt->type) {
+ case RECUR_DAILY:
+ date_sec2date_fmt(rapt->start, "%b %d", pcal_date);
+ fprintf(stream, "all day on_or_after %s (%s -> %s) %s\n",
+ pcal_date, pcal_beg, pcal_end, rapt->mesg);
+ break;
+ case RECUR_WEEKLY:
+ date_sec2date_fmt(rapt->start, "%a", pcal_date);
+ fprintf(stream, "all %s on_or_after ", pcal_date);
+ date_sec2date_fmt(rapt->start, "%b %d", pcal_date);
+ fprintf(stream, "%s (%s -> %s) %s\n", pcal_date, pcal_beg,
+ pcal_end, rapt->mesg);
+ break;
+ case RECUR_MONTHLY:
+ date_sec2date_fmt(rapt->start, "%d", pcal_date);
+ fprintf(stream, "day on all %s (%s -> %s) %s\n", pcal_date,
+ pcal_beg, pcal_end, rapt->mesg);
+ break;
+ case RECUR_YEARLY:
+ date_sec2date_fmt(rapt->start, "%b %d", pcal_date);
+ fprintf(stream, "%s (%s -> %s) %s\n", pcal_date, pcal_beg,
+ pcal_end, rapt->mesg);
+ break;
+ default:
+ EXIT(_("incoherent repetition type"));
+ }
+ } else {
+ const long YEAR_START = calendar_start_of_year();
+ const long YEAR_END = calendar_end_of_year();
+
+ if (rapt->start < YEAR_END && rapt->start > YEAR_START)
+ foreach_date_dump(YEAR_END, rapt->rpt, &rapt->exc, rapt->start,
+ rapt->dur, rapt->mesg,
+ (cb_dump_t) pcal_dump_apoint, stream);
+ }
+ }
+}
+
+static void pcal_export_apoints(FILE * stream)
+{
+ llist_item_t *i;
+
+ fputs("\n# ============\n# Appointments\n# ============\n", stream);
+ LLIST_TS_LOCK(&alist_p);
+ LLIST_TS_FOREACH(&alist_p, i) {
+ struct apoint *apt = LLIST_TS_GET_DATA(i);
+ pcal_dump_apoint(stream, apt->start, apt->dur, apt->mesg);
+ }
+ LLIST_TS_UNLOCK(&alist_p);
+ fputc('\n', stream);
+}
+
+static void pcal_export_todo(FILE * stream)
+{
+ llist_item_t *i;
+
+ fputs("#\n# Todos\n#\n", stream);
+ LLIST_FOREACH(&todolist, i) {
+ struct todo *todo = LLIST_TS_GET_DATA(i);
+ if (todo->id < 0) /* completed items */
+ continue;
+
+ fputs("note all ", stream);
+ fprintf(stream, "%d. %s\n", todo->id, todo->mesg);
+ }
+ fputc('\n', stream);
+}
+
+/* Export calcurse data. */
+void pcal_export_data(FILE * stream)
+{
+ pcal_export_header(stream);
+ pcal_export_recur_events(stream);
+ pcal_export_events(stream);
+ pcal_export_recur_apoints(stream);
+ pcal_export_apoints(stream);
+ pcal_export_todo(stream);
+ pcal_export_footer(stream);
+}
diff --git a/src/recur.c b/src/recur.c
index caa5ec3..dad9c25 100644
--- a/src/recur.c
+++ b/src/recur.c
@@ -1,7 +1,7 @@
/*
* Calcurse - text-based organizer
*
- * Copyright (c) 2004-2011 calcurse Development Team <misc@calcurse.org>
+ * Copyright (c) 2004-2012 calcurse Development Team <misc@calcurse.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -42,242 +42,217 @@
#include "calcurse.h"
-llist_ts_t recur_alist_p;
-llist_t recur_elist;
-static struct recur_event bkp_cut_recur_event;
+llist_ts_t recur_alist_p;
+llist_t recur_elist;
+static struct recur_event bkp_cut_recur_event;
static struct recur_apoint bkp_cut_recur_apoint;
-static void
-free_exc (struct excp *exc)
+static void free_exc(struct excp *exc)
{
- mem_free (exc);
+ mem_free(exc);
}
-static void
-free_exc_list (llist_t *exc)
+static void free_exc_list(llist_t * exc)
{
- LLIST_FREE_INNER (exc, free_exc);
- LLIST_FREE (exc);
+ LLIST_FREE_INNER(exc, free_exc);
+ LLIST_FREE(exc);
}
-static int
-exc_cmp_day (struct excp *a, struct excp *b)
+static int exc_cmp_day(struct excp *a, struct excp *b)
{
- return (a->st < b->st ? -1 : (a->st == b->st ? 0 : 1));
+ return a->st < b->st ? -1 : (a->st == b->st ? 0 : 1);
}
-static void
-recur_add_exc (llist_t *exc, long day)
+static void recur_add_exc(llist_t * exc, long day)
{
- struct excp *o = mem_malloc (sizeof (struct excp));
+ struct excp *o = mem_malloc(sizeof(struct excp));
o->st = day;
- LLIST_ADD_SORTED (exc, o, exc_cmp_day);
+ LLIST_ADD_SORTED(exc, o, exc_cmp_day);
}
-static void
-exc_dup (llist_t *in, llist_t *exc)
+static void exc_dup(llist_t * in, llist_t * exc)
{
llist_item_t *i;
- LLIST_INIT (in);
+ LLIST_INIT(in);
- if (exc)
- {
- LLIST_FOREACH (exc, i)
- {
- struct excp *p = LLIST_GET_DATA (i);
- recur_add_exc (in, p->st);
- }
+ if (exc) {
+ LLIST_FOREACH(exc, i) {
+ struct excp *p = LLIST_GET_DATA(i);
+ recur_add_exc(in, p->st);
}
+ }
}
-void
-recur_event_free_bkp (enum eraseflg flag)
+void recur_event_free_bkp(void)
{
- if (bkp_cut_recur_event.mesg)
- {
- mem_free (bkp_cut_recur_event.mesg);
- bkp_cut_recur_event.mesg = 0;
- }
- if (bkp_cut_recur_event.rpt)
- {
- mem_free (bkp_cut_recur_event.rpt);
- bkp_cut_recur_event.rpt = 0;
- }
- free_exc_list (&bkp_cut_recur_event.exc);
- erase_note (&bkp_cut_recur_event.note, flag);
+ if (bkp_cut_recur_event.mesg) {
+ mem_free(bkp_cut_recur_event.mesg);
+ bkp_cut_recur_event.mesg = 0;
+ }
+ if (bkp_cut_recur_event.rpt) {
+ mem_free(bkp_cut_recur_event.rpt);
+ bkp_cut_recur_event.rpt = 0;
+ }
+ free_exc_list(&bkp_cut_recur_event.exc);
+ erase_note(&bkp_cut_recur_event.note);
}
-void
-recur_apoint_free_bkp (enum eraseflg flag)
+void recur_apoint_free_bkp(void)
{
- if (bkp_cut_recur_apoint.mesg)
- {
- mem_free (bkp_cut_recur_apoint.mesg);
- bkp_cut_recur_apoint.mesg = 0;
- }
- if (bkp_cut_recur_apoint.rpt)
- {
- mem_free (bkp_cut_recur_apoint.rpt);
- bkp_cut_recur_apoint.rpt = 0;
- }
- free_exc_list (&bkp_cut_recur_apoint.exc);
- erase_note (&bkp_cut_recur_apoint.note, flag);
+ if (bkp_cut_recur_apoint.mesg) {
+ mem_free(bkp_cut_recur_apoint.mesg);
+ bkp_cut_recur_apoint.mesg = 0;
+ }
+ if (bkp_cut_recur_apoint.rpt) {
+ mem_free(bkp_cut_recur_apoint.rpt);
+ bkp_cut_recur_apoint.rpt = 0;
+ }
+ free_exc_list(&bkp_cut_recur_apoint.exc);
+ erase_note(&bkp_cut_recur_apoint.note);
}
-static void
-recur_event_dup (struct recur_event *in, struct recur_event *bkp)
+static void recur_event_dup(struct recur_event *in, struct recur_event *bkp)
{
- EXIT_IF (!in || !bkp, _("null pointer"));
+ EXIT_IF(!in || !bkp, _("null pointer"));
bkp->id = in->id;
bkp->day = in->day;
- bkp->mesg = mem_strdup (in->mesg);
+ bkp->mesg = mem_strdup(in->mesg);
- bkp->rpt = mem_malloc (sizeof (struct rpt));
+ bkp->rpt = mem_malloc(sizeof(struct rpt));
bkp->rpt->type = in->rpt->type;
bkp->rpt->freq = in->rpt->freq;
bkp->rpt->until = in->rpt->until;
- exc_dup (&bkp->exc, &in->exc);
+ exc_dup(&bkp->exc, &in->exc);
if (in->note)
- bkp->note = mem_strdup (in->note);
+ bkp->note = mem_strdup(in->note);
}
-static void
-recur_apoint_dup (struct recur_apoint *in, struct recur_apoint *bkp)
+static void recur_apoint_dup(struct recur_apoint *in, struct recur_apoint *bkp)
{
- EXIT_IF (!in || !bkp, _("null pointer"));
+ EXIT_IF(!in || !bkp, _("null pointer"));
bkp->start = in->start;
bkp->dur = in->dur;
bkp->state = in->state;
- bkp->mesg = mem_strdup (in->mesg);
+ bkp->mesg = mem_strdup(in->mesg);
- bkp->rpt = mem_malloc (sizeof (struct rpt));
+ bkp->rpt = mem_malloc(sizeof(struct rpt));
bkp->rpt->type = in->rpt->type;
bkp->rpt->freq = in->rpt->freq;
bkp->rpt->until = in->rpt->until;
- exc_dup (&bkp->exc, &in->exc);
+ exc_dup(&bkp->exc, &in->exc);
if (in->note)
- bkp->note = mem_strdup (in->note);
+ bkp->note = mem_strdup(in->note);
}
-void
-recur_apoint_llist_init (void)
+void recur_apoint_llist_init(void)
{
- LLIST_TS_INIT (&recur_alist_p);
+ LLIST_TS_INIT(&recur_alist_p);
}
-static void
-recur_apoint_free (struct recur_apoint *rapt)
+static void recur_apoint_free(struct recur_apoint *rapt)
{
- mem_free (rapt->mesg);
+ mem_free(rapt->mesg);
if (rapt->note)
- mem_free (rapt->note);
+ mem_free(rapt->note);
if (rapt->rpt)
- mem_free (rapt->rpt);
- free_exc_list (&rapt->exc);
- mem_free (rapt);
+ mem_free(rapt->rpt);
+ free_exc_list(&rapt->exc);
+ mem_free(rapt);
}
-static void
-recur_event_free (struct recur_event *rev)
+static void recur_event_free(struct recur_event *rev)
{
- mem_free (rev->mesg);
+ mem_free(rev->mesg);
if (rev->note)
- mem_free (rev->note);
+ mem_free(rev->note);
if (rev->rpt)
- mem_free (rev->rpt);
- free_exc_list (&rev->exc);
- mem_free (rev);
+ mem_free(rev->rpt);
+ free_exc_list(&rev->exc);
+ mem_free(rev);
}
-void
-recur_apoint_llist_free (void)
+void recur_apoint_llist_free(void)
{
- LLIST_TS_FREE_INNER (&recur_alist_p, recur_apoint_free);
- LLIST_TS_FREE (&recur_alist_p);
+ LLIST_TS_FREE_INNER(&recur_alist_p, recur_apoint_free);
+ LLIST_TS_FREE(&recur_alist_p);
}
-void
-recur_event_llist_free (void)
+void recur_event_llist_free(void)
{
- LLIST_FREE_INNER (&recur_elist, recur_event_free);
- LLIST_FREE (&recur_elist);
+ LLIST_FREE_INNER(&recur_elist, recur_event_free);
+ LLIST_FREE(&recur_elist);
}
static int
-recur_apoint_cmp_start (struct recur_apoint *a, struct recur_apoint *b)
+recur_apoint_cmp_start(struct recur_apoint *a, struct recur_apoint *b)
{
- return (a->start < b->start ? -1 : (a->start == b->start ? 0 : 1));
+ return a->start < b->start ? -1 : (a->start == b->start ? 0 : 1);
}
-static int
-recur_event_cmp_day (struct recur_event *a, struct recur_event *b)
+static int recur_event_cmp_day(struct recur_event *a, struct recur_event *b)
{
- return (a->day < b->day ? -1 : (a->day == b->day ? 0 : 1));
+ return a->day < b->day ? -1 : (a->day == b->day ? 0 : 1);
}
/* Insert a new recursive appointment in the general linked list */
-struct recur_apoint *
-recur_apoint_new (char *mesg, char *note, long start, long dur, char state,
- int type, int freq, long until, llist_t *except)
+struct recur_apoint *recur_apoint_new(char *mesg, char *note, long start,
+ long dur, char state, int type, int freq,
+ long until, llist_t * except)
{
- struct recur_apoint *rapt = mem_malloc (sizeof (struct recur_apoint));
+ struct recur_apoint *rapt = mem_malloc(sizeof(struct recur_apoint));
- rapt->rpt = mem_malloc (sizeof (struct rpt));
- rapt->mesg = mem_strdup (mesg);
- rapt->note = (note != NULL) ? mem_strdup (note) : 0;
+ rapt->rpt = mem_malloc(sizeof(struct rpt));
+ rapt->mesg = mem_strdup(mesg);
+ rapt->note = (note != NULL) ? mem_strdup(note) : 0;
rapt->start = start;
rapt->state = state;
rapt->dur = dur;
rapt->rpt->type = type;
rapt->rpt->freq = freq;
rapt->rpt->until = until;
- if (except)
- {
- exc_dup (&rapt->exc, except);
- free_exc_list (except);
- }
- else
- LLIST_INIT (&rapt->exc);
+ if (except) {
+ exc_dup(&rapt->exc, except);
+ free_exc_list(except);
+ } else
+ LLIST_INIT(&rapt->exc);
- LLIST_TS_LOCK (&recur_alist_p);
- LLIST_TS_ADD_SORTED (&recur_alist_p, rapt, recur_apoint_cmp_start);
- LLIST_TS_UNLOCK (&recur_alist_p);
+ LLIST_TS_LOCK(&recur_alist_p);
+ LLIST_TS_ADD_SORTED(&recur_alist_p, rapt, recur_apoint_cmp_start);
+ LLIST_TS_UNLOCK(&recur_alist_p);
return rapt;
}
/* Insert a new recursive event in the general linked list */
-struct recur_event *
-recur_event_new (char *mesg, char *note, long day, int id, int type, int freq,
- long until, llist_t *except)
+struct recur_event *recur_event_new(char *mesg, char *note, long day, int id,
+ int type, int freq, long until,
+ llist_t * except)
{
- struct recur_event *rev = mem_malloc (sizeof (struct recur_event));
+ struct recur_event *rev = mem_malloc(sizeof(struct recur_event));
- rev->rpt = mem_malloc (sizeof (struct rpt));
- rev->mesg = mem_strdup (mesg);
- rev->note = (note != NULL) ? mem_strdup (note) : 0;
+ rev->rpt = mem_malloc(sizeof(struct rpt));
+ rev->mesg = mem_strdup(mesg);
+ rev->note = (note != NULL) ? mem_strdup(note) : 0;
rev->day = day;
rev->id = id;
rev->rpt->type = type;
rev->rpt->freq = freq;
rev->rpt->until = until;
- if (except)
- {
- exc_dup (&rev->exc, except);
- free_exc_list (except);
- }
- else
- LLIST_INIT (&rev->exc);
+ if (except) {
+ exc_dup(&rev->exc, except);
+ free_exc_list(except);
+ } else
+ LLIST_INIT(&rev->exc);
- LLIST_ADD_SORTED (&recur_elist, rev, recur_event_cmp_day);
+ LLIST_ADD_SORTED(&recur_elist, rev, recur_event_cmp_day);
return rev;
}
@@ -286,214 +261,195 @@ recur_event_new (char *mesg, char *note, long day, int id, int type, int freq,
* Correspondance between the defines on recursive type,
* and the letter to be written in file.
*/
-char
-recur_def2char (enum recur_type define)
+char recur_def2char(enum recur_type define)
{
char recur_char;
- switch (define)
- {
- case RECUR_DAILY:
- recur_char = 'D';
- break;
- case RECUR_WEEKLY:
- recur_char = 'W';
- break;
- case RECUR_MONTHLY:
- recur_char = 'M';
- break;
- case RECUR_YEARLY:
- recur_char = 'Y';
- break;
- default:
- EXIT (_("unknown repetition type"));
- return 0;
- }
+ switch (define) {
+ case RECUR_DAILY:
+ recur_char = 'D';
+ break;
+ case RECUR_WEEKLY:
+ recur_char = 'W';
+ break;
+ case RECUR_MONTHLY:
+ recur_char = 'M';
+ break;
+ case RECUR_YEARLY:
+ recur_char = 'Y';
+ break;
+ default:
+ EXIT(_("unknown repetition type"));
+ return 0;
+ }
- return (recur_char);
+ return recur_char;
}
/*
* Correspondance between the letters written in file and the defines
* concerning the recursive type.
*/
-int
-recur_char2def (char type)
+int recur_char2def(char type)
{
int recur_def;
- switch (type)
- {
- case 'D':
- recur_def = RECUR_DAILY;
- break;
- case 'W':
- recur_def = RECUR_WEEKLY;
- break;
- case 'M':
- recur_def = RECUR_MONTHLY;
- break;
- case 'Y':
- recur_def = RECUR_YEARLY;
- break;
- default:
- EXIT (_("unknown character"));
- return 0;
- }
- return (recur_def);
+ switch (type) {
+ case 'D':
+ recur_def = RECUR_DAILY;
+ break;
+ case 'W':
+ recur_def = RECUR_WEEKLY;
+ break;
+ case 'M':
+ recur_def = RECUR_MONTHLY;
+ break;
+ case 'Y':
+ recur_def = RECUR_YEARLY;
+ break;
+ default:
+ EXIT(_("unknown character"));
+ return 0;
+ }
+ return recur_def;
}
/* Write days for which recurrent items should not be repeated. */
-static void
-recur_write_exc (llist_t *lexc, FILE *f)
+static void recur_write_exc(llist_t * lexc, FILE * f)
{
llist_item_t *i;
struct tm *lt;
time_t t;
int st_mon, st_day, st_year;
- LLIST_FOREACH (lexc, i)
- {
- struct excp *exc = LLIST_GET_DATA (i);
- t = exc->st;
- lt = localtime (&t);
- st_mon = lt->tm_mon + 1;
- st_day = lt->tm_mday;
- st_year = lt->tm_year + 1900;
- (void)fprintf (f, " !%02u/%02u/%04u", st_mon, st_day, st_year);
- }
+ LLIST_FOREACH(lexc, i) {
+ struct excp *exc = LLIST_GET_DATA(i);
+ t = exc->st;
+ lt = localtime(&t);
+ st_mon = lt->tm_mon + 1;
+ st_day = lt->tm_mday;
+ st_year = lt->tm_year + 1900;
+ fprintf(f, " !%02u/%02u/%04u", st_mon, st_day, st_year);
+ }
}
/* Load the recursive appointment description */
-struct recur_apoint *
-recur_apoint_scan (FILE *f, struct tm start, struct tm end, char type,
- int freq, struct tm until, char *note, llist_t *exc,
- char state)
+struct recur_apoint *recur_apoint_scan(FILE * f, struct tm start, struct tm end,
+ char type, int freq, struct tm until,
+ char *note, llist_t * exc, char state)
{
char buf[BUFSIZ], *nl;
time_t tstart, tend, tuntil;
/* Read the appointment description */
- (void)fgets (buf, sizeof buf, f);
- nl = strchr (buf, '\n');
- if (nl)
- {
- *nl = '\0';
- }
+ if (!fgets(buf, sizeof buf, f))
+ return NULL;
+
+ nl = strchr(buf, '\n');
+ if (nl) {
+ *nl = '\0';
+ }
start.tm_sec = end.tm_sec = 0;
start.tm_isdst = end.tm_isdst = -1;
start.tm_year -= 1900;
start.tm_mon--;
end.tm_year -= 1900;
end.tm_mon--;
- tstart = mktime (&start);
- tend = mktime (&end);
-
- if (until.tm_year != 0)
- {
- until.tm_hour = 23;
- until.tm_min = 59;
- until.tm_sec = 0;
- until.tm_isdst = -1;
- until.tm_year -= 1900;
- until.tm_mon--;
- tuntil = mktime (&until);
- }
- else
- {
- tuntil = 0;
- }
- EXIT_IF (tstart == -1 || tend == -1 || tstart > tend || tuntil == -1,
- _("date error in appointment"));
-
- return (recur_apoint_new (buf, note, tstart, tend - tstart, state,
- recur_char2def (type), freq, tuntil, exc));
+ tstart = mktime(&start);
+ tend = mktime(&end);
+
+ if (until.tm_year != 0) {
+ until.tm_hour = 23;
+ until.tm_min = 59;
+ until.tm_sec = 0;
+ until.tm_isdst = -1;
+ until.tm_year -= 1900;
+ until.tm_mon--;
+ tuntil = mktime(&until);
+ } else {
+ tuntil = 0;
+ }
+ EXIT_IF(tstart == -1 || tend == -1 || tstart > tend || tuntil == -1,
+ _("date error in appointment"));
+
+ return recur_apoint_new(buf, note, tstart, tend - tstart, state,
+ recur_char2def(type), freq, tuntil, exc);
}
/* Load the recursive events from file */
-struct recur_event *
-recur_event_scan (FILE *f, struct tm start, int id, char type, int freq,
- struct tm until, char *note, llist_t *exc)
+struct recur_event *recur_event_scan(FILE * f, struct tm start, int id,
+ char type, int freq, struct tm until,
+ char *note, llist_t * exc)
{
char buf[BUFSIZ], *nl;
time_t tstart, tuntil;
/* Read the event description */
- (void)fgets (buf, sizeof buf, f);
- nl = strchr (buf, '\n');
- if (nl)
- {
- *nl = '\0';
- }
- start.tm_hour = until.tm_hour = 12;
+ if (!fgets(buf, sizeof buf, f))
+ return NULL;
+
+ nl = strchr(buf, '\n');
+ if (nl) {
+ *nl = '\0';
+ }
+ start.tm_hour = until.tm_hour = 0;
start.tm_min = until.tm_min = 0;
start.tm_sec = until.tm_sec = 0;
start.tm_isdst = until.tm_isdst = -1;
start.tm_year -= 1900;
start.tm_mon--;
- if (until.tm_year != 0)
- {
- until.tm_year -= 1900;
- until.tm_mon--;
- tuntil = mktime (&until);
- }
- else
- {
- tuntil = 0;
- }
- tstart = mktime (&start);
- EXIT_IF (tstart == -1 || tuntil == -1,
- _("date error in event"));
-
- return recur_event_new (buf, note, tstart, id, recur_char2def (type),
- freq, tuntil, exc);
+ if (until.tm_year != 0) {
+ until.tm_year -= 1900;
+ until.tm_mon--;
+ tuntil = mktime(&until);
+ } else {
+ tuntil = 0;
+ }
+ tstart = mktime(&start);
+ EXIT_IF(tstart == -1 || tuntil == -1, _("date error in event"));
+
+ return recur_event_new(buf, note, tstart, id, recur_char2def(type), freq,
+ tuntil, exc);
}
/* Writting of a recursive appointment into file. */
-static void
-recur_apoint_write (struct recur_apoint *o, FILE *f)
+void recur_apoint_write(struct recur_apoint *o, FILE * f)
{
struct tm *lt;
time_t t;
t = o->start;
- lt = localtime (&t);
- (void)fprintf (f, "%02u/%02u/%04u @ %02u:%02u",
- lt->tm_mon + 1, lt->tm_mday, 1900 + lt->tm_year,
- lt->tm_hour, lt->tm_min);
+ lt = localtime(&t);
+ fprintf(f, "%02u/%02u/%04u @ %02u:%02u", lt->tm_mon + 1, lt->tm_mday,
+ 1900 + lt->tm_year, lt->tm_hour, lt->tm_min);
t = o->start + o->dur;
- lt = localtime (&t);
- (void)fprintf (f, " -> %02u/%02u/%04u @ %02u:%02u",
- lt->tm_mon + 1, lt->tm_mday, 1900 + lt->tm_year,
- lt->tm_hour, lt->tm_min);
+ lt = localtime(&t);
+ fprintf(f, " -> %02u/%02u/%04u @ %02u:%02u", lt->tm_mon + 1, lt->tm_mday,
+ 1900 + lt->tm_year, lt->tm_hour, lt->tm_min);
t = o->rpt->until;
- if (t == 0)
- { /* We have an endless recurrent appointment. */
- (void)fprintf (f, " {%d%c", o->rpt->freq, recur_def2char (o->rpt->type));
- }
- else
- {
- lt = localtime (&t);
- (void)fprintf (f, " {%d%c -> %02u/%02u/%04u",
- o->rpt->freq, recur_def2char (o->rpt->type),
- lt->tm_mon + 1, lt->tm_mday, 1900 + lt->tm_year);
- }
- recur_write_exc (&o->exc, f);
- (void)fprintf (f, "} ");
+ if (t == 0) { /* We have an endless recurrent appointment. */
+ fprintf(f, " {%d%c", o->rpt->freq, recur_def2char(o->rpt->type));
+ } else {
+ lt = localtime(&t);
+ fprintf(f, " {%d%c -> %02u/%02u/%04u", o->rpt->freq,
+ recur_def2char(o->rpt->type), lt->tm_mon + 1, lt->tm_mday,
+ 1900 + lt->tm_year);
+ }
+ recur_write_exc(&o->exc, f);
+ fputs("} ", f);
if (o->note != NULL)
- (void)fprintf (f, ">%s ", o->note);
+ fprintf(f, ">%s ", o->note);
if (o->state & APOINT_NOTIFY)
- (void)fprintf (f, "!");
+ fputc('!', f);
else
- (void)fprintf (f, "|");
- (void)fprintf (f, "%s\n", o->mesg);
+ fputc('|', f);
+ fprintf(f, "%s\n", o->mesg);
}
/* Writting of a recursive event into file. */
-static void
-recur_event_write (struct recur_event *o, FILE *f)
+void recur_event_write(struct recur_event *o, FILE * f)
{
struct tm *lt;
time_t t;
@@ -501,61 +457,52 @@ recur_event_write (struct recur_event *o, FILE *f)
int end_mon, end_day, end_year;
t = o->day;
- lt = localtime (&t);
+ lt = localtime(&t);
st_mon = lt->tm_mon + 1;
st_day = lt->tm_mday;
st_year = lt->tm_year + 1900;
t = o->rpt->until;
- if (t == 0)
- { /* We have an endless recurrent event. */
- (void)fprintf (f, "%02u/%02u/%04u [%d] {%d%c",
- st_mon, st_day, st_year, o->id, o->rpt->freq,
- recur_def2char (o->rpt->type));
- }
- else
- {
- lt = localtime (&t);
- end_mon = lt->tm_mon + 1;
- end_day = lt->tm_mday;
- end_year = lt->tm_year + 1900;
- (void)fprintf (f, "%02u/%02u/%04u [%d] {%d%c -> %02u/%02u/%04u",
- st_mon, st_day, st_year, o->id,
- o->rpt->freq, recur_def2char (o->rpt->type),
- end_mon, end_day, end_year);
- }
- recur_write_exc (&o->exc, f);
- (void)fprintf (f, "} ");
+ if (t == 0) { /* We have an endless recurrent event. */
+ fprintf(f, "%02u/%02u/%04u [%d] {%d%c", st_mon, st_day, st_year, o->id,
+ o->rpt->freq, recur_def2char(o->rpt->type));
+ } else {
+ lt = localtime(&t);
+ end_mon = lt->tm_mon + 1;
+ end_day = lt->tm_mday;
+ end_year = lt->tm_year + 1900;
+ fprintf(f, "%02u/%02u/%04u [%d] {%d%c -> %02u/%02u/%04u", st_mon,
+ st_day, st_year, o->id, o->rpt->freq,
+ recur_def2char(o->rpt->type), end_mon, end_day, end_year);
+ }
+ recur_write_exc(&o->exc, f);
+ fputs("} ", f);
if (o->note != NULL)
- (void)fprintf (f, ">%s ", o->note);
- (void)fprintf (f, "%s\n", o->mesg);
+ fprintf(f, ">%s ", o->note);
+ fprintf(f, "%s\n", o->mesg);
}
/* Write recursive items to file. */
-void
-recur_save_data (FILE *f)
+void recur_save_data(FILE * f)
{
llist_item_t *i;
- LLIST_FOREACH (&recur_elist, i)
- {
- struct recur_event *rev = LLIST_GET_DATA (i);
- recur_event_write (rev, f);
- }
-
- LLIST_TS_LOCK (&recur_alist_p);
- LLIST_TS_FOREACH (&recur_alist_p, i)
- {
- struct recur_apoint *rapt = LLIST_GET_DATA (i);
- recur_apoint_write (rapt, f);
- }
- LLIST_TS_UNLOCK (&recur_alist_p);
+ LLIST_FOREACH(&recur_elist, i) {
+ struct recur_event *rev = LLIST_GET_DATA(i);
+ recur_event_write(rev, f);
+ }
+
+ LLIST_TS_LOCK(&recur_alist_p);
+ LLIST_TS_FOREACH(&recur_alist_p, i) {
+ struct recur_apoint *rapt = LLIST_GET_DATA(i);
+ recur_apoint_write(rapt, f);
+ }
+ LLIST_TS_UNLOCK(&recur_alist_p);
}
-
/*
- * The two following defines together with the diff_days, diff_weeks,
- * diff_months and diff_years functions were provided by Lukas Fleischer to
- * correct the wrong calculation of recurrent dates after a turn of year.
+ * The two following defines together with the diff_days, diff_months and
+ * diff_years functions were provided by Lukas Fleischer to correct the wrong
+ * calculation of recurrent dates after a turn of year.
*/
#define BC(start, end, bs) \
(((end) - (start) + ((start) % bs) - ((end) % bs)) / bs \
@@ -564,10 +511,8 @@ recur_save_data (FILE *f)
#define LEAPCOUNT(start, end) \
(BC(start, end, 4) - BC(start, end, 100) + BC(start, end, 400))
-
/* Calculate the difference in days between two dates. */
-static long
-diff_days (struct tm lt_start, struct tm lt_end)
+static long diff_days(struct tm lt_start, struct tm lt_end)
{
long diff;
@@ -576,26 +521,17 @@ diff_days (struct tm lt_start, struct tm lt_end)
diff = lt_end.tm_yday - lt_start.tm_yday;
- if (lt_end.tm_year > lt_start.tm_year)
- {
- diff += (lt_end.tm_year - lt_start.tm_year) * YEARINDAYS;
- diff += LEAPCOUNT (lt_start.tm_year + TM_YEAR_BASE,
- lt_end.tm_year + TM_YEAR_BASE - 1);
- }
+ if (lt_end.tm_year > lt_start.tm_year) {
+ diff += (lt_end.tm_year - lt_start.tm_year) * YEARINDAYS;
+ diff += LEAPCOUNT(lt_start.tm_year + TM_YEAR_BASE,
+ lt_end.tm_year + TM_YEAR_BASE - 1);
+ }
return diff;
}
-/* Calculate the difference in weeks between two dates. */
-static long
-diff_weeks (struct tm lt_start, struct tm lt_end)
-{
- return diff_days (lt_start, lt_end) / WEEKINDAYS;
-}
-
/* Calculate the difference in months between two dates. */
-static long
-diff_months (struct tm lt_start, struct tm lt_end)
+static long diff_months(struct tm lt_start, struct tm lt_end)
{
long diff;
@@ -609,21 +545,19 @@ diff_months (struct tm lt_start, struct tm lt_end)
}
/* Calculate the difference in years between two dates. */
-static long
-diff_years (struct tm lt_start, struct tm lt_end)
+static long diff_years(struct tm lt_start, struct tm lt_end)
{
return lt_end.tm_year - lt_start.tm_year;
}
-static int
-exc_inday (struct excp *exc, long day_start)
+static int exc_inday(struct excp *exc, long day_start)
{
return (exc->st >= day_start && exc->st < day_start + DAYINSEC);
}
/*
- * Check if the recurrent item belongs to the selected day,
- * and if yes, return the real start time.
+ * Check if the recurrent item belongs to the selected day, and if yes, store
+ * the start date of the occurrence that belongs to the day in a buffer.
*
* This function was improved thanks to Tony's patch.
* Thanks also to youshe for reporting daylight saving time related problems.
@@ -631,92 +565,129 @@ exc_inday (struct excp *exc, long day_start)
* calculation of recurrent dates after a turn of years.
*/
unsigned
-recur_item_inday (long item_start, llist_t *item_exc, int rpt_type,
- int rpt_freq, long rpt_until, long day_start)
+recur_item_find_occurrence(long item_start, long item_dur, llist_t * item_exc,
+ int rpt_type, int rpt_freq, long rpt_until,
+ long day_start, unsigned *occurrence)
{
struct date start_date;
- long day_end, diff;
- struct tm lt_item, lt_day;
+ long diff, span;
+ struct tm lt_day, lt_item, lt_item_day;
time_t t;
- day_end = day_start + DAYINSEC;
+ if (day_start < item_start - DAYINSEC + 1)
+ return 0;
+
+ if (rpt_until != 0 && day_start >= rpt_until + item_dur)
+ return 0;
+
t = day_start;
- lt_day = *localtime (&t);
+ lt_day = *localtime(&t);
- if (LLIST_FIND_FIRST (item_exc, day_start, exc_inday))
+ t = item_start;
+ lt_item = *localtime(&t);
+
+ lt_item_day = lt_item;
+ lt_item_day.tm_sec = lt_item_day.tm_min = lt_item_day.tm_hour = 0;
+
+ span = (item_start - mktime(&lt_item_day) + item_dur - 1) / DAYINSEC;
+
+ switch (rpt_type) {
+ case RECUR_DAILY:
+ diff = diff_days(lt_item_day, lt_day) % rpt_freq;
+ lt_item_day.tm_mday = lt_day.tm_mday - diff;
+ lt_item_day.tm_mon = lt_day.tm_mon;
+ lt_item_day.tm_year = lt_day.tm_year;
+ break;
+ case RECUR_WEEKLY:
+ diff = diff_days(lt_item_day, lt_day) % (rpt_freq * WEEKINDAYS);
+ lt_item_day.tm_mday = lt_day.tm_mday - diff;
+ lt_item_day.tm_mon = lt_day.tm_mon;
+ lt_item_day.tm_year = lt_day.tm_year;
+ break;
+ case RECUR_MONTHLY:
+ diff = diff_months(lt_item_day, lt_day) % rpt_freq;
+ if (lt_day.tm_mday < lt_item_day.tm_mday)
+ diff++;
+ lt_item_day.tm_mon = lt_day.tm_mon - diff;
+ lt_item_day.tm_year = lt_day.tm_year;
+ break;
+ case RECUR_YEARLY:
+ diff = diff_years(lt_item_day, lt_day) % rpt_freq;
+ if (lt_day.tm_mon < lt_item_day.tm_mon ||
+ (lt_day.tm_mon == lt_item_day.tm_mon &&
+ lt_day.tm_mday < lt_item_day.tm_mday))
+ diff++;
+ lt_item_day.tm_year = lt_day.tm_year - diff;
+ break;
+ default:
+ EXIT(_("unknown item type"));
+ }
+
+ lt_item_day.tm_isdst = lt_day.tm_isdst;
+ t = mktime(&lt_item_day);
+
+ if (LLIST_FIND_FIRST(item_exc, t, exc_inday))
return 0;
- if (rpt_until == 0) /* we have an endless recurrent item */
- rpt_until = day_end;
+ if (rpt_until != 0 && t > rpt_until)
+ return 0;
- if (item_start > day_end || rpt_until < day_start)
- return (0);
+ lt_item_day = *localtime(&t);
+ diff = diff_days(lt_item_day, lt_day);
- t = item_start;
- lt_item = *localtime (&t);
-
- switch (rpt_type)
- {
- case RECUR_DAILY:
- diff = diff_days (lt_item, lt_day);
- if (diff % rpt_freq != 0)
- return (0);
- lt_item.tm_mday = lt_day.tm_mday;
- lt_item.tm_mon = lt_day.tm_mon;
- lt_item.tm_year = lt_day.tm_year;
- break;
- case RECUR_WEEKLY:
- if (lt_item.tm_wday != lt_day.tm_wday)
- return (0);
- else
- {
- diff = diff_weeks (lt_item, lt_day);
- if (diff % rpt_freq != 0)
- return (0);
- }
- lt_item.tm_mday = lt_day.tm_mday;
- lt_item.tm_mon = lt_day.tm_mon;
- lt_item.tm_year = lt_day.tm_year;
- break;
- case RECUR_MONTHLY:
- diff = diff_months (lt_item, lt_day);
- if (diff % rpt_freq != 0)
- return (0);
- lt_item.tm_mon = lt_day.tm_mon;
- lt_item.tm_year = lt_day.tm_year;
- break;
- case RECUR_YEARLY:
- diff = diff_years (lt_item, lt_day);
- if (diff % rpt_freq != 0)
- return (0);
- lt_item.tm_year = lt_day.tm_year;
- break;
- default:
- EXIT (_("unknown item type"));
+ if (diff <= span) {
+ if (occurrence) {
+ start_date.dd = lt_item_day.tm_mday;
+ start_date.mm = lt_item_day.tm_mon + 1;
+ start_date.yyyy = lt_item_day.tm_year + 1900;
+
+ *occurrence = date2sec(start_date, lt_item.tm_hour, lt_item.tm_min);
}
- start_date.dd = lt_item.tm_mday;
- start_date.mm = lt_item.tm_mon + 1;
- start_date.yyyy = lt_item.tm_year + 1900;
- item_start = date2sec (start_date, lt_item.tm_hour, lt_item.tm_min);
- if (item_start < day_end && item_start >= day_start)
- return (item_start);
- else
- return (0);
+ return 1;
+ } else
+ return 0;
+}
+
+unsigned
+recur_apoint_find_occurrence(struct recur_apoint *rapt, long day_start,
+ unsigned *occurrence)
+{
+ return recur_item_find_occurrence(rapt->start, rapt->dur, &rapt->exc,
+ rapt->rpt->type, rapt->rpt->freq,
+ rapt->rpt->until, day_start, occurrence);
}
unsigned
-recur_apoint_inday(struct recur_apoint *rapt, long day_start)
+recur_event_find_occurrence(struct recur_event *rev, long day_start,
+ unsigned *occurrence)
{
- return recur_item_inday (rapt->start, &rapt->exc, rapt->rpt->type,
- rapt->rpt->freq, rapt->rpt->until, day_start);
+ return recur_item_find_occurrence(rev->day, DAYINSEC, &rev->exc,
+ rev->rpt->type, rev->rpt->freq,
+ rev->rpt->until, day_start, occurrence);
}
+/* Check if a recurrent item belongs to the selected day. */
unsigned
-recur_event_inday(struct recur_event *rev, long day_start)
+recur_item_inday(long item_start, long item_dur, llist_t * item_exc,
+ int rpt_type, int rpt_freq, long rpt_until, long day_start)
+{
+ /* We do not need the (real) start time of the occurrence here, so just
+ * ignore the buffer. */
+ return recur_item_find_occurrence(item_start, item_dur, item_exc, rpt_type,
+ rpt_freq, rpt_until, day_start, NULL);
+}
+
+unsigned recur_apoint_inday(struct recur_apoint *rapt, long day_start)
+{
+ return recur_item_inday(rapt->start, rapt->dur, &rapt->exc, rapt->rpt->type,
+ rapt->rpt->freq, rapt->rpt->until, day_start);
+}
+
+unsigned recur_event_inday(struct recur_event *rev, long day_start)
{
- return recur_item_inday (rev->day, &rev->exc, rev->rpt->type, rev->rpt->freq,
- rev->rpt->until, day_start);
+ return recur_item_inday(rev->day, DAYINSEC, &rev->exc, rev->rpt->type,
+ rev->rpt->freq, rev->rpt->until, day_start);
}
/*
@@ -724,46 +695,40 @@ recur_event_inday(struct recur_event *rev, long day_start)
* or delete only one occurence of the recurrent event.
*/
void
-recur_event_erase (long start, unsigned num, unsigned delete_whole,
- enum eraseflg flag)
+recur_event_erase(long start, unsigned num, unsigned delete_whole,
+ enum eraseflg flag)
{
llist_item_t *i;
- i = LLIST_FIND_NTH (&recur_elist, num, start, recur_event_inday);
+ i = LLIST_FIND_NTH(&recur_elist, num, start, recur_event_inday);
if (!i)
- EXIT (_("event not found"));
- struct recur_event *rev = LLIST_GET_DATA (i);
-
- if (delete_whole)
- {
- switch (flag)
- {
- case ERASE_FORCE_ONLY_NOTE:
- erase_note (&rev->note, flag);
- break;
- case ERASE_CUT:
- recur_event_free_bkp (ERASE_FORCE);
- recur_event_dup (rev, &bkp_cut_recur_event);
- erase_note (&rev->note, ERASE_FORCE_KEEP_NOTE);
- /* FALLTHROUGH */
- default:
- LLIST_REMOVE (&recur_elist, i);
- mem_free (rev->mesg);
- if (rev->rpt)
- {
- mem_free (rev->rpt);
- rev->rpt = 0;
- }
- free_exc_list (&rev->exc);
- if (flag != ERASE_FORCE_KEEP_NOTE && flag != ERASE_CUT)
- erase_note (&rev->note, flag);
- mem_free (rev);
- break;
- }
+ EXIT(_("event not found"));
+ struct recur_event *rev = LLIST_GET_DATA(i);
+
+ if (delete_whole) {
+ switch (flag) {
+ case ERASE_FORCE_ONLY_NOTE:
+ erase_note(&rev->note);
+ break;
+ case ERASE_CUT:
+ recur_event_free_bkp();
+ recur_event_dup(rev, &bkp_cut_recur_event);
+ erase_note(&rev->note);
+ /* FALLTHROUGH */
+ default:
+ LLIST_REMOVE(&recur_elist, i);
+ mem_free(rev->mesg);
+ if (rev->rpt) {
+ mem_free(rev->rpt);
+ rev->rpt = 0;
+ }
+ free_exc_list(&rev->exc);
+ mem_free(rev);
+ break;
}
- else
- recur_add_exc (&rev->exc, start);
+ } else
+ recur_add_exc(&rev->exc, start);
}
/*
@@ -771,57 +736,50 @@ recur_event_erase (long start, unsigned num, unsigned delete_whole,
* or delete only one occurence of the recurrent appointment.
*/
void
-recur_apoint_erase (long start, unsigned num, unsigned delete_whole,
- enum eraseflg flag)
+recur_apoint_erase(long start, unsigned num, unsigned delete_whole,
+ enum eraseflg flag)
{
llist_item_t *i;
int need_check_notify = 0;
- i = LLIST_TS_FIND_NTH (&recur_alist_p, num, start, recur_apoint_inday);
+ i = LLIST_TS_FIND_NTH(&recur_alist_p, num, start, recur_apoint_inday);
if (!i)
- EXIT (_("appointment not found"));
- struct recur_apoint *rapt = LLIST_GET_DATA (i);
-
- LLIST_TS_LOCK (&recur_alist_p);
- if (notify_bar () && flag != ERASE_FORCE_ONLY_NOTE)
- need_check_notify = notify_same_recur_item (rapt);
- if (delete_whole)
- {
- switch (flag)
- {
- case ERASE_FORCE_ONLY_NOTE:
- erase_note (&rapt->note, flag);
- break;
- case ERASE_CUT:
- recur_apoint_free_bkp (ERASE_FORCE);
- recur_apoint_dup (rapt, &bkp_cut_recur_apoint);
- erase_note (&rapt->note, ERASE_FORCE_KEEP_NOTE);
- /* FALLTHROUGH */
- default:
- LLIST_TS_REMOVE (&recur_alist_p, i);
- mem_free (rapt->mesg);
- if (rapt->rpt)
- {
- mem_free (rapt->rpt);
- rapt->rpt = 0;
- }
- free_exc_list (&rapt->exc);
- if (flag != ERASE_FORCE_KEEP_NOTE && flag != ERASE_CUT)
- erase_note (&rapt->note, flag);
- mem_free (rapt);
- if (need_check_notify)
- notify_check_next_app (0);
- break;
- }
- }
- else
- {
- recur_add_exc (&rapt->exc, start);
+ EXIT(_("appointment not found"));
+ struct recur_apoint *rapt = LLIST_GET_DATA(i);
+
+ LLIST_TS_LOCK(&recur_alist_p);
+ if (notify_bar() && flag != ERASE_FORCE_ONLY_NOTE)
+ need_check_notify = notify_same_recur_item(rapt);
+ if (delete_whole) {
+ switch (flag) {
+ case ERASE_FORCE_ONLY_NOTE:
+ erase_note(&rapt->note);
+ break;
+ case ERASE_CUT:
+ recur_apoint_free_bkp();
+ recur_apoint_dup(rapt, &bkp_cut_recur_apoint);
+ erase_note(&rapt->note);
+ /* FALLTHROUGH */
+ default:
+ LLIST_TS_REMOVE(&recur_alist_p, i);
+ mem_free(rapt->mesg);
+ if (rapt->rpt) {
+ mem_free(rapt->rpt);
+ rapt->rpt = 0;
+ }
+ free_exc_list(&rapt->exc);
+ mem_free(rapt);
if (need_check_notify)
- notify_check_next_app (0);
+ notify_check_next_app(0);
+ break;
}
- LLIST_TS_UNLOCK (&recur_alist_p);
+ } else {
+ recur_add_exc(&rapt->exc, start);
+ if (need_check_notify)
+ notify_check_next_app(0);
+ }
+ LLIST_TS_UNLOCK(&recur_alist_p);
}
/*
@@ -831,319 +789,289 @@ recur_apoint_erase (long start, unsigned num, unsigned delete_whole,
* o repetition end date
* and then delete the selected item to recreate it as a recurrent one
*/
-void
-recur_repeat_item (struct conf *conf)
+void recur_repeat_item(void)
{
struct tm *lt;
time_t t;
- int ch = 0;
int date_entered = 0;
int year = 0, month = 0, day = 0;
struct date until_date;
char outstr[BUFSIZ];
char user_input[BUFSIZ] = "";
- char *mesg_type_1 =
- _("Enter the repetition type: (D)aily, (W)eekly, (M)onthly, (Y)early");
- char *mesg_type_2 = _("[D/W/M/Y] ");
- char *mesg_freq_1 = _("Enter the repetition frequence:");
- char *mesg_wrong_freq = _("The frequence you entered is not valid.");
- char *mesg_until_1 =
- _("Enter the ending date: [%s] or '0' for an endless repetition");
- char *mesg_wrong_1 = _("The entered date is not valid.");
- char *mesg_wrong_2 =
- _("Possible formats are [%s] or '0' for an endless repetition");
- char *wrong_type_1 = _("This item is already a repeated one.");
- char *wrong_type_2 = _("Press [ENTER] to continue.");
- char *mesg_older =
- _("Sorry, the date you entered is older than the item start time.");
+ const char *msg_rpt_prefix = _("Enter the repetition type:");
+ const char *msg_rpt_daily = _("(d)aily");
+ const char *msg_rpt_weekly = _("(w)eekly");
+ const char *msg_rpt_monthly = _("(m)onthly");
+ const char *msg_rpt_yearly = _("(y)early");
+ const char *msg_type_choice = _("[dwmy]");
+ const char *mesg_freq_1 = _("Enter the repetition frequence:");
+ const char *mesg_wrong_freq = _("The frequence you entered is not valid.");
+ const char *mesg_until_1 =
+ _("Enter the ending date: [%s] or '0' for an endless repetition");
+ const char *mesg_wrong_1 = _("The entered date is not valid.");
+ const char *mesg_wrong_2 =
+ _("Possible formats are [%s] or '0' for an endless repetition");
+ const char *wrong_type_1 = _("This item is already a repeated one.");
+ const char *wrong_type_2 = _("Press [ENTER] to continue.");
+ const char *mesg_older =
+ _("Sorry, the date you entered is older than the item start time.");
+
+ char msg_asktype[BUFSIZ];
+ snprintf(msg_asktype, BUFSIZ, "%s %s, %s, %s, %s",
+ msg_rpt_prefix,
+ msg_rpt_daily, msg_rpt_weekly, msg_rpt_monthly, msg_rpt_yearly);
+
int type = 0, freq = 0;
int item_nb;
struct day_item *p;
struct recur_apoint *ra;
long until, date;
- item_nb = apoint_hilt ();
- p = day_get_item (item_nb);
- if (p->type != APPT && p->type != EVNT)
- {
- status_mesg (wrong_type_1, wrong_type_2);
- (void)wgetch (win[STA].p);
- return;
- }
-
- while ((ch != 'D') && (ch != 'W') && (ch != 'M')
- && (ch != 'Y') && (ch != ESCAPE))
- {
- status_mesg (mesg_type_1, mesg_type_2);
- ch = wgetch (win[STA].p);
- ch = toupper (ch);
- }
- if (ch == ESCAPE)
- {
+ item_nb = apoint_hilt();
+ p = day_get_item(item_nb);
+ if (p->type != APPT && p->type != EVNT) {
+ status_mesg(wrong_type_1, wrong_type_2);
+ wgetch(win[STA].p);
+ return;
+ }
+
+ switch (status_ask_choice(msg_asktype, msg_type_choice, 4)) {
+ case 1:
+ type = RECUR_DAILY;
+ break;
+ case 2:
+ type = RECUR_WEEKLY;
+ break;
+ case 3:
+ type = RECUR_MONTHLY;
+ break;
+ case 4:
+ type = RECUR_YEARLY;
+ break;
+ default:
+ return;
+ }
+
+ while (freq == 0) {
+ status_mesg(mesg_freq_1, "");
+ if (getstring(win[STA].p, user_input, BUFSIZ, 0, 1) == GETSTRING_VALID) {
+ freq = atoi(user_input);
+ if (freq == 0) {
+ status_mesg(mesg_wrong_freq, wrong_type_2);
+ wgetch(win[STA].p);
+ }
+ user_input[0] = '\0';
+ } else
return;
- }
- else
- {
- type = recur_char2def (ch);
- }
-
- while (freq == 0)
- {
- status_mesg (mesg_freq_1, "");
- if (getstring (win[STA].p, user_input, BUFSIZ, 0, 1) == GETSTRING_VALID)
- {
- freq = atoi (user_input);
- if (freq == 0)
- {
- status_mesg (mesg_wrong_freq, wrong_type_2);
- (void)wgetch (win[STA].p);
- }
- user_input[0] = '\0';
+ }
+
+ while (!date_entered) {
+ snprintf(outstr, BUFSIZ, mesg_until_1, DATEFMT_DESC(conf.input_datefmt));
+ status_mesg(_(outstr), "");
+ if (getstring(win[STA].p, user_input, BUFSIZ, 0, 1) == GETSTRING_VALID) {
+ if (strlen(user_input) == 1 && strcmp(user_input, "0") == 0) {
+ until = 0;
+ date_entered = 1;
+ } else {
+ if (parse_date(user_input, conf.input_datefmt,
+ &year, &month, &day, calendar_get_slctd_day())) {
+ t = p->start;
+ lt = localtime(&t);
+ until_date.dd = day;
+ until_date.mm = month;
+ until_date.yyyy = year;
+ until = date2sec(until_date, lt->tm_hour, lt->tm_min);
+ if (until < p->start) {
+ status_mesg(mesg_older, wrong_type_2);
+ wgetch(win[STA].p);
+ date_entered = 0;
+ } else {
+ date_entered = 1;
+ }
+ } else {
+ snprintf(outstr, BUFSIZ, mesg_wrong_2,
+ DATEFMT_DESC(conf.input_datefmt));
+ status_mesg(mesg_wrong_1, _(outstr));
+ wgetch(win[STA].p);
+ date_entered = 0;
}
- else
- return;
- }
-
- while (!date_entered)
- {
- (void)snprintf (outstr, BUFSIZ, mesg_until_1,
- DATEFMT_DESC (conf->input_datefmt));
- status_mesg (_(outstr), "");
- if (getstring (win[STA].p, user_input, BUFSIZ, 0, 1) == GETSTRING_VALID)
- {
- if (strlen (user_input) == 1 && strncmp (user_input, "0", 1) == 0)
- {
- until = 0;
- date_entered = 1;
- }
- else
- {
- if (parse_date (user_input, conf->input_datefmt,
- &year, &month, &day, calendar_get_slctd_day ()))
- {
- t = p->start;
- lt = localtime (&t);
- until_date.dd = day;
- until_date.mm = month;
- until_date.yyyy = year;
- until = date2sec (until_date, lt->tm_hour, lt->tm_min);
- if (until < p->start)
- {
- status_mesg (mesg_older, wrong_type_2);
- (void)wgetch (win[STA].p);
- date_entered = 0;
- }
- else
- {
- date_entered = 1;
- }
- }
- else
- {
- (void)snprintf (outstr, BUFSIZ, mesg_wrong_2,
- DATEFMT_DESC (conf->input_datefmt));
- status_mesg (mesg_wrong_1, _(outstr));
- (void)wgetch (win[STA].p);
- date_entered = 0;
- }
- }
- }
- else
- return;
- }
-
- date = calendar_get_slctd_day_sec ();
- if (p->type == EVNT)
- {
- (void)recur_event_new (p->mesg, p->note, p->start, p->evnt_id,
- type, freq, until, NULL);
- }
- else if (p->type == APPT)
- {
- ra = recur_apoint_new (p->mesg, p->note, p->start, p->appt_dur,
- p->state, type, freq, until, NULL);
- if (notify_bar ())
- notify_check_repeated (ra);
- }
- else
- {
- EXIT (_("wrong item type"));
- /* NOTREACHED */
- }
- day_erase_item (date, item_nb, ERASE_FORCE_KEEP_NOTE);
+ }
+ } else
+ return;
+ }
+
+ date = calendar_get_slctd_day_sec();
+ if (p->type == EVNT) {
+ recur_event_new(p->mesg, p->note, p->start, p->evnt_id, type, freq,
+ until, NULL);
+ } else if (p->type == APPT) {
+ ra = recur_apoint_new(p->mesg, p->note, p->start, p->appt_dur,
+ p->state, type, freq, until, NULL);
+ if (notify_bar())
+ notify_check_repeated(ra);
+ } else {
+ EXIT(_("wrong item type"));
+ /* NOTREACHED */
+ }
+ day_erase_item(date, item_nb, ERASE_FORCE);
}
/*
* Read days for which recurrent items must not be repeated
* (such days are called exceptions).
*/
-void
-recur_exc_scan (llist_t *lexc, FILE *data_file)
+void recur_exc_scan(llist_t * lexc, FILE * data_file)
{
int c = 0;
struct tm day;
- LLIST_INIT (lexc);
- while ((c = getc (data_file)) == '!')
- {
- (void)ungetc (c, data_file);
- if (fscanf (data_file, "!%u / %u / %u ",
- &day.tm_mon, &day.tm_mday, &day.tm_year) != 3)
- {
- EXIT (_("syntax error in item date"));
- }
- day.tm_hour = 12;
- day.tm_min = day.tm_sec = 0;
- day.tm_isdst = -1;
- day.tm_year -= 1900;
- day.tm_mon--;
- struct excp *exc = mem_malloc (sizeof (struct excp));
- exc->st = mktime (&day);
- LLIST_ADD (lexc, exc);
+ LLIST_INIT(lexc);
+ while ((c = getc(data_file)) == '!') {
+ ungetc(c, data_file);
+ if (fscanf(data_file, "!%d / %d / %d ",
+ &day.tm_mon, &day.tm_mday, &day.tm_year) != 3) {
+ EXIT(_("syntax error in item date"));
}
+ day.tm_hour = 0;
+ day.tm_min = day.tm_sec = 0;
+ day.tm_isdst = -1;
+ day.tm_year -= 1900;
+ day.tm_mon--;
+ struct excp *exc = mem_malloc(sizeof(struct excp));
+ exc->st = mktime(&day);
+ LLIST_ADD(lexc, exc);
+ }
}
-static int
-recur_apoint_starts_before (struct recur_apoint *rapt, long time)
+static int recur_apoint_starts_before(struct recur_apoint *rapt, long time)
{
- return (rapt->start < time);
+ return rapt->start < time;
}
/*
* Look in the appointment list if we have an item which starts before the item
* stored in the notify_app structure (which is the next item to be notified).
*/
-struct notify_app *
-recur_apoint_check_next (struct notify_app *app, long start, long day)
+struct notify_app *recur_apoint_check_next(struct notify_app *app, long start,
+ long day)
{
llist_item_t *i;
- long real_recur_start_time;
-
- LLIST_TS_LOCK (&recur_alist_p);
- LLIST_TS_FIND_FOREACH (&recur_alist_p, app->time, recur_apoint_starts_before, i)
- {
- struct recur_apoint *rapt = LLIST_TS_GET_DATA (i);
-
- real_recur_start_time = recur_apoint_inday(rapt, day);
- if (real_recur_start_time > start)
- {
- app->time = real_recur_start_time;
- app->txt = mem_strdup (rapt->mesg);
- app->state = rapt->state;
- app->got_app = 1;
- }
+ unsigned real_recur_start_time;
+
+ LLIST_TS_LOCK(&recur_alist_p);
+ LLIST_TS_FIND_FOREACH(&recur_alist_p, app->time, recur_apoint_starts_before,
+ i) {
+ struct recur_apoint *rapt = LLIST_TS_GET_DATA(i);
+
+ if (recur_apoint_find_occurrence(rapt, day, &real_recur_start_time) &&
+ real_recur_start_time > start) {
+ app->time = real_recur_start_time;
+ app->txt = mem_strdup(rapt->mesg);
+ app->state = rapt->state;
+ app->got_app = 1;
}
- LLIST_TS_UNLOCK (&recur_alist_p);
+ }
+ LLIST_TS_UNLOCK(&recur_alist_p);
- return (app);
+ return app;
}
/* Returns a structure containing the selected recurrent appointment. */
-struct recur_apoint *
-recur_get_apoint (long date, int num)
+struct recur_apoint *recur_get_apoint(long date, int num)
{
- llist_item_t *i = LLIST_TS_FIND_NTH (&recur_alist_p, num, date,
+ llist_item_t *i = LLIST_TS_FIND_NTH(&recur_alist_p, num, date,
recur_apoint_inday);
if (i)
- return LLIST_TS_GET_DATA (i);
+ return LLIST_TS_GET_DATA(i);
- EXIT (_("item not found"));
+ EXIT(_("item not found"));
/* NOTREACHED */
}
/* Returns a structure containing the selected recurrent event. */
-struct recur_event *
-recur_get_event (long date, int num)
+struct recur_event *recur_get_event(long date, int num)
{
- llist_item_t *i = LLIST_FIND_NTH (&recur_elist, num, date,
- recur_event_inday);
+ llist_item_t *i = LLIST_FIND_NTH(&recur_elist, num, date,
+ recur_event_inday);
if (i)
- return LLIST_GET_DATA (i);
+ return LLIST_GET_DATA(i);
- EXIT (_("item not found"));
+ EXIT(_("item not found"));
/* NOTREACHED */
}
/* Switch recurrent item notification state. */
-void
-recur_apoint_switch_notify (long date, int recur_nb)
+void recur_apoint_switch_notify(long date, int recur_nb)
{
llist_item_t *i;
- LLIST_TS_LOCK (&recur_alist_p);
- i = LLIST_TS_FIND_NTH (&recur_alist_p, recur_nb, date, recur_apoint_inday);
+ LLIST_TS_LOCK(&recur_alist_p);
+ i = LLIST_TS_FIND_NTH(&recur_alist_p, recur_nb, date, recur_apoint_inday);
if (!i)
- EXIT (_("item not found"));
- struct recur_apoint *rapt = LLIST_TS_GET_DATA (i);
+ EXIT(_("item not found"));
+ struct recur_apoint *rapt = LLIST_TS_GET_DATA(i);
rapt->state ^= APOINT_NOTIFY;
- if (notify_bar ())
- notify_check_repeated (rapt);
+ if (notify_bar())
+ notify_check_repeated(rapt);
- LLIST_TS_UNLOCK (&recur_alist_p);
+ LLIST_TS_UNLOCK(&recur_alist_p);
}
-void
-recur_event_paste_item (void)
+void recur_event_paste_item(void)
{
long new_start, time_shift;
llist_item_t *i;
- new_start = date2sec (*calendar_get_slctd_day (), 12, 0);
+ new_start = date2sec(*calendar_get_slctd_day(), 0, 0);
time_shift = new_start - bkp_cut_recur_event.day;
bkp_cut_recur_event.day += time_shift;
if (bkp_cut_recur_event.rpt->until != 0)
bkp_cut_recur_event.rpt->until += time_shift;
- LLIST_FOREACH (&bkp_cut_recur_event.exc, i)
- {
- struct excp *exc = LLIST_GET_DATA (i);
- exc->st += time_shift;
- }
-
- (void)recur_event_new (bkp_cut_recur_event.mesg, bkp_cut_recur_event.note,
- bkp_cut_recur_event.day, bkp_cut_recur_event.id,
- bkp_cut_recur_event.rpt->type,
- bkp_cut_recur_event.rpt->freq,
- bkp_cut_recur_event.rpt->until,
- &bkp_cut_recur_event.exc);
- recur_event_free_bkp (ERASE_FORCE_KEEP_NOTE);
+ LLIST_FOREACH(&bkp_cut_recur_event.exc, i) {
+ struct excp *exc = LLIST_GET_DATA(i);
+ exc->st += time_shift;
+ }
+
+ recur_event_new(bkp_cut_recur_event.mesg, bkp_cut_recur_event.note,
+ bkp_cut_recur_event.day, bkp_cut_recur_event.id,
+ bkp_cut_recur_event.rpt->type,
+ bkp_cut_recur_event.rpt->freq,
+ bkp_cut_recur_event.rpt->until, &bkp_cut_recur_event.exc);
+ recur_event_free_bkp();
}
-void
-recur_apoint_paste_item (void)
+void recur_apoint_paste_item(void)
{
long new_start, time_shift;
llist_item_t *i;
- new_start = date2sec (*calendar_get_slctd_day (),
- get_item_hour (bkp_cut_recur_apoint.start),
- get_item_min (bkp_cut_recur_apoint.start));
+ new_start = date2sec(*calendar_get_slctd_day(),
+ get_item_hour(bkp_cut_recur_apoint.start),
+ get_item_min(bkp_cut_recur_apoint.start));
time_shift = new_start - bkp_cut_recur_apoint.start;
bkp_cut_recur_apoint.start += time_shift;
if (bkp_cut_recur_apoint.rpt->until != 0)
bkp_cut_recur_apoint.rpt->until += time_shift;
- LLIST_FOREACH (&bkp_cut_recur_event.exc, i)
- {
- struct excp *exc = LLIST_GET_DATA (i);
- exc->st += time_shift;
- }
+ LLIST_FOREACH(&bkp_cut_recur_event.exc, i) {
+ struct excp *exc = LLIST_GET_DATA(i);
+ exc->st += time_shift;
+ }
- (void)recur_apoint_new (bkp_cut_recur_apoint.mesg, bkp_cut_recur_apoint.note,
- bkp_cut_recur_apoint.start, bkp_cut_recur_apoint.dur,
- bkp_cut_recur_apoint.state,
- bkp_cut_recur_apoint.rpt->type,
- bkp_cut_recur_apoint.rpt->freq,
- bkp_cut_recur_apoint.rpt->until,
- &bkp_cut_recur_apoint.exc);
+ recur_apoint_new(bkp_cut_recur_apoint.mesg, bkp_cut_recur_apoint.note,
+ bkp_cut_recur_apoint.start, bkp_cut_recur_apoint.dur,
+ bkp_cut_recur_apoint.state, bkp_cut_recur_apoint.rpt->type,
+ bkp_cut_recur_apoint.rpt->freq,
+ bkp_cut_recur_apoint.rpt->until, &bkp_cut_recur_apoint.exc);
- if (notify_bar ())
- notify_check_repeated (&bkp_cut_recur_apoint);
+ if (notify_bar())
+ notify_check_repeated(&bkp_cut_recur_apoint);
- recur_apoint_free_bkp (ERASE_FORCE_KEEP_NOTE);
+ recur_apoint_free_bkp();
}
diff --git a/src/sha1.c b/src/sha1.c
new file mode 100644
index 0000000..4fbf245
--- /dev/null
+++ b/src/sha1.c
@@ -0,0 +1,267 @@
+/*
+ * Calcurse - text-based organizer
+ *
+ * Copyright (c) 2004-2012 calcurse Development Team <misc@calcurse.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Send your feedback or comments to : misc@calcurse.org
+ * Calcurse home page : http://calcurse.org
+ *
+ * This code is based on Steve Reid's public domain SHA1 implementation.
+ *
+ * The original version is available at:
+ * ftp://ftp.funet.fi/pub/crypt/hash/sha/sha1.c
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "sha1.h"
+
+#define rol(val, n) (((val) << (n)) | ((val) >> (32 - (n))))
+
+#ifdef WORDS_BIGENDIAN
+#define blk0(i) block->l[i]
+#else
+#define blk0(i) (block->l[i] = (rol (block->l[i], 24) & \
+ (uint32_t)0xFF00FF00) | (rol (block->l[i], 8) & (uint32_t)0x00FF00FF))
+#endif
+
+#define blk(i) (block->l[i & 15] = rol (block->l[(i + 13) & 15] ^ \
+ block->l[(i + 8) & 15] ^ block->l[(i + 2) & 15] ^ block->l[i & 15], 1))
+
+#define R0(v, w, x, y, z, i) z += ((w & (x ^ y)) ^ y) + blk0 (i) + \
+ 0x5A827999 + rol (v, 5); w = rol (w, 30);
+#define R1(v, w, x, y, z, i) z += ((w & (x ^ y)) ^ y) + blk (i) + \
+ 0x5A827999 + rol (v, 5); w = rol (w, 30);
+#define R2(v, w, x, y, z, i) z += (w ^ x ^ y) + blk (i) + 0x6ED9EBA1 + \
+ rol (v, 5); w = rol(w, 30);
+#define R3(v, w, x, y, z, i) z += (((w | x) & y) | (w & x)) + blk (i) + \
+ 0x8F1BBCDC + rol (v, 5); w = rol (w, 30);
+#define R4(v, w, x, y, z, i) z += (w ^ x ^ y) + blk (i) + 0xCA62C1D6 + \
+ rol (v, 5); w = rol (w, 30);
+
+static void sha1_transform(uint32_t state[5], const uint8_t buffer[64])
+{
+ typedef union {
+ uint8_t c[64];
+ uint32_t l[16];
+ } b64_t;
+
+ b64_t *block = (b64_t *) buffer;
+ uint32_t a = state[0];
+ uint32_t b = state[1];
+ uint32_t c = state[2];
+ uint32_t d = state[3];
+ uint32_t e = state[4];
+
+ R0(a, b, c, d, e, 0);
+ R0(e, a, b, c, d, 1);
+ R0(d, e, a, b, c, 2);
+ R0(c, d, e, a, b, 3);
+ R0(b, c, d, e, a, 4);
+ R0(a, b, c, d, e, 5);
+ R0(e, a, b, c, d, 6);
+ R0(d, e, a, b, c, 7);
+ R0(c, d, e, a, b, 8);
+ R0(b, c, d, e, a, 9);
+ R0(a, b, c, d, e, 10);
+ R0(e, a, b, c, d, 11);
+ R0(d, e, a, b, c, 12);
+ R0(c, d, e, a, b, 13);
+ R0(b, c, d, e, a, 14);
+ R0(a, b, c, d, e, 15);
+ R1(e, a, b, c, d, 16);
+ R1(d, e, a, b, c, 17);
+ R1(c, d, e, a, b, 18);
+ R1(b, c, d, e, a, 19);
+ R2(a, b, c, d, e, 20);
+ R2(e, a, b, c, d, 21);
+ R2(d, e, a, b, c, 22);
+ R2(c, d, e, a, b, 23);
+ R2(b, c, d, e, a, 24);
+ R2(a, b, c, d, e, 25);
+ R2(e, a, b, c, d, 26);
+ R2(d, e, a, b, c, 27);
+ R2(c, d, e, a, b, 28);
+ R2(b, c, d, e, a, 29);
+ R2(a, b, c, d, e, 30);
+ R2(e, a, b, c, d, 31);
+ R2(d, e, a, b, c, 32);
+ R2(c, d, e, a, b, 33);
+ R2(b, c, d, e, a, 34);
+ R2(a, b, c, d, e, 35);
+ R2(e, a, b, c, d, 36);
+ R2(d, e, a, b, c, 37);
+ R2(c, d, e, a, b, 38);
+ R2(b, c, d, e, a, 39);
+ R3(a, b, c, d, e, 40);
+ R3(e, a, b, c, d, 41);
+ R3(d, e, a, b, c, 42);
+ R3(c, d, e, a, b, 43);
+ R3(b, c, d, e, a, 44);
+ R3(a, b, c, d, e, 45);
+ R3(e, a, b, c, d, 46);
+ R3(d, e, a, b, c, 47);
+ R3(c, d, e, a, b, 48);
+ R3(b, c, d, e, a, 49);
+ R3(a, b, c, d, e, 50);
+ R3(e, a, b, c, d, 51);
+ R3(d, e, a, b, c, 52);
+ R3(c, d, e, a, b, 53);
+ R3(b, c, d, e, a, 54);
+ R3(a, b, c, d, e, 55);
+ R3(e, a, b, c, d, 56);
+ R3(d, e, a, b, c, 57);
+ R3(c, d, e, a, b, 58);
+ R3(b, c, d, e, a, 59);
+ R4(a, b, c, d, e, 60);
+ R4(e, a, b, c, d, 61);
+ R4(d, e, a, b, c, 62);
+ R4(c, d, e, a, b, 63);
+ R4(b, c, d, e, a, 64);
+ R4(a, b, c, d, e, 65);
+ R4(e, a, b, c, d, 66);
+ R4(d, e, a, b, c, 67);
+ R4(c, d, e, a, b, 68);
+ R4(b, c, d, e, a, 69);
+ R4(a, b, c, d, e, 70);
+ R4(e, a, b, c, d, 71);
+ R4(d, e, a, b, c, 72);
+ R4(c, d, e, a, b, 73);
+ R4(b, c, d, e, a, 74);
+ R4(a, b, c, d, e, 75);
+ R4(e, a, b, c, d, 76);
+ R4(d, e, a, b, c, 77);
+ R4(c, d, e, a, b, 78);
+ R4(b, c, d, e, a, 79);
+
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+ state[4] += e;
+
+ a = b = c = d = e = 0;
+}
+
+void sha1_init(sha1_ctx_t * ctx)
+{
+ ctx->state[0] = 0x67452301;
+ ctx->state[1] = 0xEFCDAB89;
+ ctx->state[2] = 0x98BADCFE;
+ ctx->state[3] = 0x10325476;
+ ctx->state[4] = 0xC3D2E1F0;
+
+ ctx->count[0] = ctx->count[1] = 0;
+}
+
+void sha1_update(sha1_ctx_t * ctx, const uint8_t * data, unsigned int len)
+{
+ unsigned int i, j;
+
+ j = (ctx->count[0] >> 3) & 63;
+ if ((ctx->count[0] += len << 3) < (len << 3))
+ ctx->count[1]++;
+ ctx->count[1] += (len >> 29);
+
+ if (j + len > 63) {
+ memcpy(&ctx->buffer[j], data, (i = 64 - j));
+ sha1_transform(ctx->state, ctx->buffer);
+ for (; i + 63 < len; i += 64)
+ sha1_transform(ctx->state, &data[i]);
+ j = 0;
+ } else
+ i = 0;
+ memcpy(&ctx->buffer[j], &data[i], len - i);
+}
+
+void sha1_final(sha1_ctx_t * ctx, uint8_t digest[SHA1_DIGESTLEN])
+{
+ uint32_t i, j;
+ uint8_t finalcount[8];
+
+ for (i = 0; i < 8; i++) {
+ finalcount[i] = (uint8_t) ((ctx->count[(i >= 4 ? 0 : 1)] >>
+ ((3 - (i & 3)) * 8)) & 255);
+ }
+
+ sha1_update(ctx, (uint8_t *) "\200", 1);
+ while ((ctx->count[0] & 504) != 448)
+ sha1_update(ctx, (uint8_t *) "\0", 1);
+
+ sha1_update(ctx, finalcount, 8);
+ for (i = 0; i < SHA1_DIGESTLEN; i++)
+ digest[i] = (uint8_t) ((ctx->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
+
+ i = j = 0;
+ memset(ctx->buffer, 0, SHA1_BLOCKLEN);
+ memset(ctx->state, 0, SHA1_DIGESTLEN);
+ memset(ctx->count, 0, 8);
+ memset(&finalcount, 0, 8);
+}
+
+void sha1_digest(const char *data, char *buffer)
+{
+ sha1_ctx_t ctx;
+ uint8_t digest[SHA1_DIGESTLEN];
+ int i;
+
+ sha1_init(&ctx);
+ sha1_update(&ctx, (const uint8_t *)data, strlen(data));
+ sha1_final(&ctx, (uint8_t *) digest);
+
+ for (i = 0; i < SHA1_DIGESTLEN; i++) {
+ snprintf(buffer, 3, "%02x", digest[i]);
+ buffer += sizeof(char) * 2;
+ }
+}
+
+void sha1_stream(FILE * fp, char *buffer)
+{
+ sha1_ctx_t ctx;
+ uint8_t data[BUFSIZ];
+ size_t bytes_read;
+ uint8_t digest[SHA1_DIGESTLEN];
+ int i;
+
+ sha1_init(&ctx);
+
+ while (!feof(fp)) {
+ bytes_read = fread(data, 1, BUFSIZ, fp);
+ sha1_update(&ctx, data, bytes_read);
+ }
+
+ sha1_final(&ctx, (uint8_t *) digest);
+
+ for (i = 0; i < SHA1_DIGESTLEN; i++) {
+ snprintf(buffer, 3, "%02x", digest[i]);
+ buffer += sizeof(char) * 2;
+ }
+}
diff --git a/src/sha1.h b/src/sha1.h
new file mode 100644
index 0000000..8f90ff5
--- /dev/null
+++ b/src/sha1.h
@@ -0,0 +1,57 @@
+/*
+ * Calcurse - text-based organizer
+ *
+ * Copyright (c) 2004-2012 calcurse Development Team <misc@calcurse.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Send your feedback or comments to : misc@calcurse.org
+ * Calcurse home page : http://calcurse.org
+ *
+ * This code is based on Steve Reid's public domain SHA1 implementation.
+ *
+ * The original version is available at:
+ * ftp://ftp.funet.fi/pub/crypt/hash/sha/sha1.c
+ *
+ */
+
+#include <stdint.h>
+
+#define SHA1_BLOCKLEN 64
+#define SHA1_DIGESTLEN 20
+
+typedef struct {
+ uint32_t state[5];
+ uint32_t count[2];
+ uint8_t buffer[SHA1_BLOCKLEN];
+} sha1_ctx_t;
+
+void sha1_init(sha1_ctx_t *);
+void sha1_update(sha1_ctx_t *, const uint8_t *, unsigned int);
+void sha1_final(sha1_ctx_t *, uint8_t *);
+void sha1_digest(const char *, char *);
+void sha1_stream(FILE *, char *);
diff --git a/src/sigs.c b/src/sigs.c
index a5f7e54..4f5d982 100644
--- a/src/sigs.c
+++ b/src/sigs.c
@@ -1,7 +1,7 @@
/*
* Calcurse - text-based organizer
*
- * Copyright (c) 2004-2011 calcurse Development Team <misc@calcurse.org>
+ * Copyright (c) 2004-2012 calcurse Development Team <misc@calcurse.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -43,63 +43,58 @@
#include "calcurse.h"
+#ifndef WAIT_MYPGRP
+#define WAIT_MYPGRP 0
+#endif
+
/*
* General signal handling routine.
* Catch return values from children (user-defined notification commands).
* This is needed to avoid zombie processes running on system.
* Also catch CTRL-C (SIGINT), and SIGWINCH to resize screen automatically.
*/
-static void
-generic_hdlr (int sig)
+static void generic_hdlr(int sig)
{
- switch (sig)
- {
- case SIGCHLD:
- while (waitpid (WAIT_MYPGRP, NULL, WNOHANG) > 0)
- ;
- break;
- case SIGWINCH:
- resize = 1;
- clearok (curscr, TRUE);
- (void)ungetch (KEY_RESIZE);
- break;
- case SIGTERM:
- if (unlink (path_cpid) != 0)
- {
- EXIT (_("Could not remove calcurse lock file: %s\n"),
- strerror (errno));
- }
- exit (EXIT_SUCCESS);
- break;
+ switch (sig) {
+ case SIGCHLD:
+ while (waitpid(WAIT_MYPGRP, NULL, WNOHANG) > 0) ;
+ break;
+ case SIGWINCH:
+ resize = 1;
+ clearok(curscr, TRUE);
+ ungetch(KEY_RESIZE);
+ break;
+ case SIGTERM:
+ if (unlink(path_cpid) != 0) {
+ EXIT(_("Could not remove calcurse lock file: %s\n"), strerror(errno));
}
+ exit(EXIT_SUCCESS);
+ break;
+ }
}
-unsigned
-sigs_set_hdlr (int sig, void (*handler)(int))
+unsigned sigs_set_hdlr(int sig, void (*handler) (int))
{
struct sigaction sa;
- memset (&sa, 0, sizeof sa);
- sigemptyset (&sa.sa_mask);
+ memset(&sa, 0, sizeof sa);
+ sigemptyset(&sa.sa_mask);
sa.sa_handler = handler;
sa.sa_flags = 0;
- if (sigaction (sig, &sa, (struct sigaction *)0) == -1)
- {
- ERROR_MSG (_("Error setting signal #%d : %s\n"),
- sig, strerror (errno));
- return 0;
- }
+ if (sigaction(sig, &sa, NULL) == -1) {
+ ERROR_MSG(_("Error setting signal #%d : %s\n"), sig, strerror(errno));
+ return 0;
+ }
return 1;
}
/* Signal handling init. */
-void
-sigs_init ()
+void sigs_init()
{
- if (!sigs_set_hdlr (SIGCHLD, generic_hdlr)
- || !sigs_set_hdlr (SIGWINCH, generic_hdlr)
- || !sigs_set_hdlr (SIGTERM, generic_hdlr)
- || !sigs_set_hdlr (SIGINT, SIG_IGN))
- exit_calcurse (1);
+ if (!sigs_set_hdlr(SIGCHLD, generic_hdlr)
+ || !sigs_set_hdlr(SIGWINCH, generic_hdlr)
+ || !sigs_set_hdlr(SIGTERM, generic_hdlr)
+ || !sigs_set_hdlr(SIGINT, SIG_IGN))
+ exit_calcurse(1);
}
diff --git a/src/todo.c b/src/todo.c
index 8000197..bb29f61 100644
--- a/src/todo.c
+++ b/src/todo.c
@@ -1,7 +1,7 @@
/*
* Calcurse - text-based organizer
*
- * Copyright (c) 2004-2011 calcurse Development Team <misc@calcurse.org>
+ * Copyright (c) 2004-2012 calcurse Development Team <misc@calcurse.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -47,171 +47,161 @@ static int first = 1;
static char *msgsav;
/* Returns a structure containing the selected item. */
-static struct todo *
-todo_get_item (int item_number)
+static struct todo *todo_get_item(int item_number)
{
- return LLIST_GET_DATA (LLIST_NTH (&todolist, item_number - 1));
+ return LLIST_GET_DATA(LLIST_NTH(&todolist, item_number - 1));
}
/* Sets which todo is highlighted. */
-void
-todo_hilt_set (int highlighted)
+void todo_hilt_set(int highlighted)
{
hilt = highlighted;
}
-void
-todo_hilt_decrease (void)
+void todo_hilt_decrease(int n)
{
- hilt--;
+ hilt -= n;
}
-void
-todo_hilt_increase (void)
+void todo_hilt_increase(int n)
{
- hilt++;
+ hilt += n;
}
/* Return which todo is highlighted. */
-int
-todo_hilt (void)
+int todo_hilt(void)
{
- return (hilt);
+ return hilt;
}
/* Return the number of todos. */
-int
-todo_nb (void)
+int todo_nb(void)
{
- return (todos);
+ return todos;
}
/* Set the number of todos. */
-void
-todo_set_nb (int nb)
+void todo_set_nb(int nb)
{
todos = nb;
}
/* Set which one is the first todo to be displayed. */
-void
-todo_set_first (int nb)
+void todo_set_first(int nb)
{
first = nb;
}
-void
-todo_first_increase (void)
+void todo_first_increase(int n)
{
- first++;
+ first += n;
}
-void
-todo_first_decrease (void)
+void todo_first_decrease(int n)
{
- first--;
+ first -= n;
}
/*
* Return the position of the hilghlighted item, relative to the first one
* displayed.
*/
-int
-todo_hilt_pos (void)
+int todo_hilt_pos(void)
{
- return (hilt - first);
+ return hilt - first;
}
/* Return the last visited todo. */
-char *
-todo_saved_mesg (void)
+char *todo_saved_mesg(void)
{
- return (msgsav);
+ return msgsav;
}
/* Request user to enter a new todo item. */
-void
-todo_new_item (void)
+void todo_new_item(void)
{
int ch = 0;
- char *mesg = _("Enter the new ToDo item : ");
- char *mesg_id = _("Enter the ToDo priority [1 (highest) - 9 (lowest)] :");
+ const char *mesg = _("Enter the new ToDo item : ");
+ const char *mesg_id =
+ _("Enter the ToDo priority [1 (highest) - 9 (lowest)] :");
char todo_input[BUFSIZ] = "";
- status_mesg (mesg, "");
- if (getstring (win[STA].p, todo_input, BUFSIZ, 0, 1) == GETSTRING_VALID)
- {
- while ((ch < '1') || (ch > '9'))
- {
- status_mesg (mesg_id, "");
- ch = wgetch (win[STA].p);
- }
- todo_add (todo_input, ch - '0', NULL);
- todos++;
+ status_mesg(mesg, "");
+ if (getstring(win[STA].p, todo_input, BUFSIZ, 0, 1) == GETSTRING_VALID) {
+ while ((ch < '1') || (ch > '9')) {
+ status_mesg(mesg_id, "");
+ ch = wgetch(win[STA].p);
}
+ todo_add(todo_input, ch - '0', NULL);
+ todos++;
+ }
}
-static int
-todo_cmp_id (struct todo *a, struct todo *b)
+static int todo_cmp_id(struct todo *a, struct todo *b)
{
/*
* As of version 2.6, todo items can have a negative id, which means they
* were completed. To keep them sorted, we need to consider the absolute id
* value.
*/
- int abs_a = abs (a->id);
- int abs_b = abs (b->id);
+ int abs_a = abs(a->id);
+ int abs_b = abs(b->id);
- return (abs_a < abs_b ? -1 : (abs_a == abs_b ? 0 : 1));
+ return abs_a < abs_b ? -1 : (abs_a == abs_b ? 0 : 1);
}
/*
* Add an item in the todo linked list.
*/
-struct todo *
-todo_add (char *mesg, int id, char *note)
+struct todo *todo_add(char *mesg, int id, char *note)
{
struct todo *todo;
- todo = mem_malloc (sizeof (struct todo));
- todo->mesg = mem_strdup (mesg);
+ todo = mem_malloc(sizeof(struct todo));
+ todo->mesg = mem_strdup(mesg);
todo->id = id;
- todo->note = (note != NULL && note[0] != '\0') ? mem_strdup (note) : NULL;
+ todo->note = (note != NULL && note[0] != '\0') ? mem_strdup(note) : NULL;
- LLIST_ADD_SORTED (&todolist, todo, todo_cmp_id);
+ LLIST_ADD_SORTED(&todolist, todo, todo_cmp_id);
return todo;
}
+void todo_write(struct todo *todo, FILE * f)
+{
+ if (todo->note)
+ fprintf(f, "[%d]>%s %s\n", todo->id, todo->note, todo->mesg);
+ else
+ fprintf(f, "[%d] %s\n", todo->id, todo->mesg);
+}
+
/* Delete a note previously attached to a todo item. */
-static void
-todo_delete_note_bynum (unsigned num)
+static void todo_delete_note_bynum(unsigned num)
{
- llist_item_t *i = LLIST_NTH (&todolist, num);
+ llist_item_t *i = LLIST_NTH(&todolist, num);
if (!i)
- EXIT (_("no such todo"));
- struct todo *todo = LLIST_TS_GET_DATA (i);
+ EXIT(_("no such todo"));
+ struct todo *todo = LLIST_TS_GET_DATA(i);
if (!todo->note)
- EXIT (_("no note attached"));
- erase_note (&todo->note, ERASE_FORCE_ONLY_NOTE);
+ EXIT(_("no note attached"));
+ erase_note(&todo->note);
}
/* Delete an item from the todo linked list. */
-static void
-todo_delete_bynum (unsigned num, enum eraseflg flag)
+static void todo_delete_bynum(unsigned num)
{
- llist_item_t *i = LLIST_NTH (&todolist, num);
+ llist_item_t *i = LLIST_NTH(&todolist, num);
if (!i)
- EXIT (_("no such todo"));
- struct todo *todo = LLIST_TS_GET_DATA (i);
+ EXIT(_("no such todo"));
+ struct todo *todo = LLIST_TS_GET_DATA(i);
- LLIST_REMOVE (&todolist, i);
- mem_free (todo->mesg);
- erase_note (&todo->note, flag);
- mem_free (todo);
+ LLIST_REMOVE(&todolist, i);
+ mem_free(todo->mesg);
+ erase_note(&todo->note);
+ mem_free(todo);
}
/*
@@ -220,186 +210,164 @@ todo_delete_bynum (unsigned num, enum eraseflg flag)
* This way, it is easy to retrive its original priority if the user decides
* that in fact it was not completed.
*/
-void
-todo_flag (void)
+void todo_flag(void)
{
struct todo *t;
- t = todo_get_item (hilt);
+ t = todo_get_item(hilt);
t->id = -t->id;
}
/* Delete an item from the ToDo list. */
-void
-todo_delete (struct conf *conf)
+void todo_delete(void)
{
- char *choices = "[y/n] ";
- char *del_todo_str = _("Do you really want to delete this task ?");
- char *erase_warning =
+ const char *del_todo_str = _("Do you really want to delete this task ?");
+ const char *erase_warning =
_("This item has a note attached to it. "
"Delete (t)odo or just its (n)ote ?");
- char *erase_choice = _("[t/n] ");
- unsigned go_for_todo_del = 0;
- int answer, has_note;
-
- if (conf->confirm_delete)
- {
- status_mesg (del_todo_str, choices);
- answer = wgetch (win[STA].p);
- if ((answer == 'y') && (todos > 0))
- {
- go_for_todo_del = 1;
- }
- else
- {
- wins_erase_status_bar ();
- return;
- }
- }
- else if (todos > 0)
- go_for_todo_del = 1;
-
- if (go_for_todo_del == 0)
- {
- wins_erase_status_bar ();
- return;
- }
-
- answer = -1;
- has_note = (todo_get_item (hilt)->note != NULL) ? 1 : 0;
- if (has_note == 0)
- answer = 't';
+ const char *erase_choice = _("[tn]");
+ const int nb_erase_choice = 2;
+ int answer;
- while (answer != 't' && answer != 'n' && answer != KEY_GENERIC_CANCEL)
- {
- status_mesg (erase_warning, erase_choice);
- answer = wgetch (win[STA].p);
- }
+ if ((todos <= 0) ||
+ (conf.confirm_delete && (status_ask_bool(del_todo_str) != 1))) {
+ wins_erase_status_bar();
+ return;
+ }
- switch (answer)
- {
- case 't':
- todo_delete_bynum (hilt - 1, ERASE_FORCE);
- todos--;
- if (hilt > 1)
- hilt--;
- if (todos == 0)
- hilt = 0;
- if (hilt - first < 0)
- first--;
- break;
- case 'n':
- todo_delete_note_bynum (hilt - 1);
- break;
- default:
- wins_erase_status_bar ();
- return;
- }
+ /* This todo item doesn't have any note associated. */
+ if (todo_get_item(hilt)->note == NULL)
+ answer = 1;
+ else
+ answer = status_ask_choice(erase_warning, erase_choice, nb_erase_choice);
+
+ switch (answer) {
+ case 1:
+ todo_delete_bynum(hilt - 1);
+ todos--;
+ if (hilt > 1)
+ hilt--;
+ if (todos == 0)
+ hilt = 0;
+ if (hilt - first < 0)
+ first--;
+ break;
+ case 2:
+ todo_delete_note_bynum(hilt - 1);
+ break;
+ default:
+ wins_erase_status_bar();
+ return;
+ }
}
/*
* Returns the position into the linked list corresponding to the
* given todo item.
*/
-static int
-todo_get_position (struct todo *needle)
+static int todo_get_position(struct todo *needle)
{
llist_item_t *i;
int n = 0;
- LLIST_FOREACH (&todolist, i)
- {
- n++;
- if (LLIST_TS_GET_DATA (i) == needle)
- return n;
- }
+ LLIST_FOREACH(&todolist, i) {
+ n++;
+ if (LLIST_TS_GET_DATA(i) == needle)
+ return n;
+ }
- EXIT (_("todo not found"));
- return -1; /* avoid compiler warnings */
+ EXIT(_("todo not found"));
+ return -1; /* avoid compiler warnings */
}
/* Change an item priority by pressing '+' or '-' inside TODO panel. */
-void
-todo_chg_priority (int action)
+void todo_chg_priority(int action)
{
struct todo *backup;
char backup_mesg[BUFSIZ];
int backup_id;
- char backup_note[NOTESIZ + 1];
- int do_chg = 1;
+ char backup_note[MAX_NOTESIZ + 1];
- backup = todo_get_item (hilt);
- (void)strncpy (backup_mesg, backup->mesg, strlen (backup->mesg) + 1);
+ backup = todo_get_item(hilt);
+ strncpy(backup_mesg, backup->mesg, strlen(backup->mesg) + 1);
backup_id = backup->id;
if (backup->note)
- (void)strncpy (backup_note, backup->note, NOTESIZ + 1);
+ strncpy(backup_note, backup->note, MAX_NOTESIZ + 1);
else
backup_note[0] = '\0';
- switch (action)
- {
- case KEY_RAISE_PRIORITY:
- (backup_id > 1) ? backup_id-- : do_chg--;
- break;
- case KEY_LOWER_PRIORITY:
- (backup_id > 0 && backup_id < 9) ? backup_id++ : do_chg--;
- break;
- default:
- EXIT (_("no such action"));
- /* NOTREACHED */
- }
- if (do_chg)
- {
- todo_delete_bynum (hilt - 1, ERASE_FORCE_KEEP_NOTE);
- backup = todo_add (backup_mesg, backup_id, backup_note);
- hilt = todo_get_position (backup);
- }
+ switch (action) {
+ case KEY_RAISE_PRIORITY:
+ if (backup_id > 1)
+ backup_id--;
+ else
+ return;
+ break;
+ case KEY_LOWER_PRIORITY:
+ if (backup_id > 0 && backup_id < 9)
+ backup_id++;
+ else
+ return;
+ break;
+ default:
+ EXIT(_("no such action"));
+ /* NOTREACHED */
+ }
+
+ todo_delete_bynum(hilt - 1);
+ backup = todo_add(backup_mesg, backup_id, backup_note);
+ hilt = todo_get_position(backup);
}
/* Edit the description of an already existing todo item. */
-void
-todo_edit_item (void)
+void todo_edit_item(void)
{
struct todo *i;
- char *mesg = _("Enter the new ToDo description :");
+ const char *mesg = _("Enter the new ToDo description :");
- status_mesg (mesg, "");
- i = todo_get_item (hilt);
- updatestring (win[STA].p, &i->mesg, 0, 1);
+ status_mesg(mesg, "");
+ i = todo_get_item(hilt);
+ updatestring(win[STA].p, &i->mesg, 0, 1);
}
/* Display todo items in the corresponding panel. */
static void
-display_todo_item (int incolor, char *msg, int prio, int note, int len, int y,
- int x)
+display_todo_item(int incolor, char *msg, int prio, int note, int width, int y,
+ int x)
{
WINDOW *w;
int ch_note;
- char buf[len], priostr[2];
+ char buf[width * UTF8_MAXLEN], priostr[2];
+ int i;
w = win[TOD].p;
ch_note = (note) ? '>' : '.';
if (prio > 0)
- snprintf (priostr, sizeof priostr, "%d", prio);
+ snprintf(priostr, sizeof priostr, "%d", prio);
else
- snprintf (priostr, sizeof priostr, "X");
+ strncpy(priostr, "X", sizeof priostr);
if (incolor == 0)
- custom_apply_attr (w, ATTR_HIGHEST);
- if (strlen (msg) < len)
- mvwprintw (w, y, x, "%s%c %s", priostr, ch_note, msg);
- else
- {
- (void)strncpy (buf, msg, len - 1);
- buf[len - 1] = '\0';
- mvwprintw (w, y, x, "%s%c %s...", priostr, ch_note, buf);
+ custom_apply_attr(w, ATTR_HIGHEST);
+ if (utf8_strwidth(msg) < width)
+ mvwprintw(w, y, x, "%s%c %s", priostr, ch_note, msg);
+ else {
+ for (i = 0; msg[i] && width > 0; i++) {
+ if (!UTF8_ISCONT(msg[i]))
+ width -= utf8_width(&msg[i]);
+ buf[i] = msg[i];
}
+ if (i)
+ buf[i - 1] = 0;
+ else
+ buf[0] = 0;
+ mvwprintw(w, y, x, "%s%c %s...", priostr, ch_note, buf);
+ }
if (incolor == 0)
- custom_remove_attr (w, ATTR_HIGHEST);
+ custom_remove_attr(w, ATTR_HIGHEST);
}
/* Updates the ToDo panel. */
-void
-todo_update_panel (int which_pan)
+void todo_update_panel(int which_pan)
{
llist_item_t *i;
int len = win[TOD].w - 8;
@@ -412,97 +380,94 @@ todo_update_panel (int which_pan)
int incolor = -1;
/* Print todo item in the panel. */
- erase_window_part (win[TOD].p, 1, title_lines, win[TOD].w - 2,
- win[TOD].h - 2);
- LLIST_FOREACH (&todolist, i)
- {
- struct todo *todo = LLIST_TS_GET_DATA (i);
- num_todo++;
- t_realpos = num_todo - first;
- incolor = num_todo - hilt;
- if (incolor == 0)
- msgsav = todo->mesg;
- if (t_realpos >= 0 && t_realpos < max_items)
- {
- display_todo_item (incolor, todo->mesg, todo->id,
- (todo->note != NULL) ? 1 : 0, len, y_offset,
- x_offset);
- y_offset = y_offset + todo_lines;
- }
+ erase_window_part(win[TOD].p, 1, title_lines, win[TOD].w - 2, win[TOD].h - 2);
+ LLIST_FOREACH(&todolist, i) {
+ struct todo *todo = LLIST_TS_GET_DATA(i);
+ num_todo++;
+ t_realpos = num_todo - first;
+ incolor = (which_pan == TOD) ? num_todo - hilt : num_todo;
+ if (incolor == 0)
+ msgsav = todo->mesg;
+ if (t_realpos >= 0 && t_realpos < max_items) {
+ display_todo_item(incolor, todo->mesg, todo->id,
+ (todo->note != NULL) ? 1 : 0, len, y_offset, x_offset);
+ y_offset = y_offset + todo_lines;
}
+ }
/* Draw the scrollbar if necessary. */
- if (todos > max_items)
- {
- float ratio = ((float) max_items) / ((float) todos);
- int sbar_length = (int) (ratio * (max_items + 1));
- int highend = (int) (ratio * first);
- unsigned hilt_bar = (which_pan == TOD) ? 1 : 0;
- int sbar_top = highend + title_lines;
-
- if ((sbar_top + sbar_length) > win[TOD].h - 1)
- sbar_length = win[TOD].h - 1 - sbar_top;
- draw_scrollbar (win[TOD].p, sbar_top, win[TOD].w - 2,
- sbar_length, title_lines, win[TOD].h - 1, hilt_bar);
- }
-
- wnoutrefresh (win[TOD].p);
+ if (todos > max_items) {
+ float ratio = ((float)max_items) / ((float)todos);
+ int sbar_length = (int)(ratio * (max_items + 1));
+ int highend = (int)(ratio * first);
+ unsigned hilt_bar = (which_pan == TOD) ? 1 : 0;
+ int sbar_top = highend + title_lines;
+
+ if ((sbar_top + sbar_length) > win[TOD].h - 1)
+ sbar_length = win[TOD].h - 1 - sbar_top;
+ draw_scrollbar(win[TOD].p, sbar_top, win[TOD].w - 2,
+ sbar_length, title_lines, win[TOD].h - 1, hilt_bar);
+ }
+
+ wnoutrefresh(win[TOD].p);
}
/* Attach a note to a todo */
-void
-todo_edit_note (char *editor)
+void todo_edit_note(const char *editor)
{
- struct todo *i;
- char fullname[BUFSIZ];
- char *filename;
-
- i = todo_get_item (hilt);
- if (i->note == NULL)
- {
- if ((filename = new_tempfile (path_notes, NOTESIZ)) != NULL)
- i->note = filename;
- else
- return;
- }
- (void)snprintf (fullname, BUFSIZ, "%s%s", path_notes, i->note);
- wins_launch_external (fullname, editor);
-
- if (io_file_is_empty (fullname) > 0)
- erase_note (&i->note, ERASE_FORCE);
+ struct todo *i = todo_get_item(hilt);
+ edit_note(&i->note, editor);
}
/* View a note previously attached to a todo */
-void
-todo_view_note (char *pager)
+void todo_view_note(const char *pager)
{
- struct todo *i;
- char fullname[BUFSIZ];
+ struct todo *i = todo_get_item(hilt);
+ view_note(i->note, pager);
+}
- i = todo_get_item (hilt);
- if (i->note == NULL)
+/* Pipe a todo item to an external program. */
+void todo_pipe_item(void)
+{
+ char cmd[BUFSIZ] = "";
+ char const *arg[] = { cmd, NULL };
+ int pout;
+ int pid;
+ FILE *fpout;
+ struct todo *todo;
+
+ status_mesg(_("Pipe item to external command:"), "");
+ if (getstring(win[STA].p, cmd, BUFSIZ, 0, 1) != GETSTRING_VALID)
return;
- (void)snprintf (fullname, BUFSIZ, "%s%s", path_notes, i->note);
- wins_launch_external (fullname, pager);
+
+ wins_prepare_external();
+ if ((pid = shell_exec(NULL, &pout, *arg, arg))) {
+ fpout = fdopen(pout, "w");
+
+ todo = todo_get_item(hilt);
+ todo_write(todo, fpout);
+
+ fclose(fpout);
+ child_wait(NULL, &pout, pid);
+ press_any_key();
+ }
+ wins_unprepare_external();
}
-void
-todo_free (struct todo *todo)
+static void todo_free(struct todo *todo)
{
- mem_free (todo->mesg);
- erase_note (&todo->note, ERASE_FORCE_KEEP_NOTE);
- mem_free (todo);
+ mem_free(todo->mesg);
+ erase_note(&todo->note);
+ mem_free(todo);
}
-void
-todo_init_list (void)
+void todo_init_list(void)
{
- LLIST_INIT (&todolist);
+ LLIST_INIT(&todolist);
}
-void
-todo_free_list (void)
+void todo_free_list(void)
{
- LLIST_FREE_INNER (&todolist, todo_free);
- LLIST_FREE (&todolist);
+ LLIST_FREE_INNER(&todolist, todo_free);
+ LLIST_FREE(&todolist);
}
diff --git a/src/utf8.c b/src/utf8.c
new file mode 100644
index 0000000..398b142
--- /dev/null
+++ b/src/utf8.c
@@ -0,0 +1,335 @@
+/*
+ * Calcurse - text-based organizer
+ *
+ * Copyright (c) 2004-2012 calcurse Development Team <misc@calcurse.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Send your feedback or comments to : misc@calcurse.org
+ * Calcurse home page : http://calcurse.org
+ *
+ */
+
+#include "calcurse.h"
+
+struct utf8_range {
+ int min, max, width;
+};
+
+static const struct utf8_range utf8_widthtab[] = {
+ {0x00300, 0x0036f, 0},
+ {0x00483, 0x00489, 0},
+ {0x00591, 0x005bd, 0},
+ {0x005bf, 0x005bf, 0},
+ {0x005c1, 0x005c2, 0},
+ {0x005c4, 0x005c5, 0},
+ {0x005c7, 0x005c7, 0},
+ {0x00610, 0x0061a, 0},
+ {0x0064b, 0x0065e, 0},
+ {0x00670, 0x00670, 0},
+ {0x006d6, 0x006dc, 0},
+ {0x006de, 0x006e4, 0},
+ {0x006e7, 0x006e8, 0},
+ {0x006ea, 0x006ed, 0},
+ {0x00711, 0x00711, 0},
+ {0x00730, 0x0074a, 0},
+ {0x007a6, 0x007b0, 0},
+ {0x007eb, 0x007f3, 0},
+ {0x00816, 0x00819, 0},
+ {0x0081b, 0x00823, 0},
+ {0x00825, 0x00827, 0},
+ {0x00829, 0x0082d, 0},
+ {0x00900, 0x00903, 0},
+ {0x0093c, 0x0093c, 0},
+ {0x0093e, 0x0094e, 0},
+ {0x00951, 0x00955, 0},
+ {0x00962, 0x00963, 0},
+ {0x00981, 0x00983, 0},
+ {0x009bc, 0x009bc, 0},
+ {0x009be, 0x009c4, 0},
+ {0x009c7, 0x009c8, 0},
+ {0x009cb, 0x009cd, 0},
+ {0x009d7, 0x009d7, 0},
+ {0x009e2, 0x009e3, 0},
+ {0x00a01, 0x00a03, 0},
+ {0x00a3c, 0x00a3c, 0},
+ {0x00a3e, 0x00a42, 0},
+ {0x00a47, 0x00a48, 0},
+ {0x00a4b, 0x00a4d, 0},
+ {0x00a51, 0x00a51, 0},
+ {0x00a70, 0x00a71, 0},
+ {0x00a75, 0x00a75, 0},
+ {0x00a81, 0x00a83, 0},
+ {0x00abc, 0x00abc, 0},
+ {0x00abe, 0x00ac5, 0},
+ {0x00ac7, 0x00ac9, 0},
+ {0x00acb, 0x00acd, 0},
+ {0x00ae2, 0x00ae3, 0},
+ {0x00b01, 0x00b03, 0},
+ {0x00b3c, 0x00b3c, 0},
+ {0x00b3e, 0x00b44, 0},
+ {0x00b47, 0x00b48, 0},
+ {0x00b4b, 0x00b4d, 0},
+ {0x00b56, 0x00b57, 0},
+ {0x00b62, 0x00b63, 0},
+ {0x00b82, 0x00b82, 0},
+ {0x00bbe, 0x00bc2, 0},
+ {0x00bc6, 0x00bc8, 0},
+ {0x00bca, 0x00bcd, 0},
+ {0x00bd7, 0x00bd7, 0},
+ {0x00c01, 0x00c03, 0},
+ {0x00c3e, 0x00c44, 0},
+ {0x00c46, 0x00c48, 0},
+ {0x00c4a, 0x00c4d, 0},
+ {0x00c55, 0x00c56, 0},
+ {0x00c62, 0x00c63, 0},
+ {0x00c82, 0x00c83, 0},
+ {0x00cbc, 0x00cbc, 0},
+ {0x00cbe, 0x00cc4, 0},
+ {0x00cc6, 0x00cc8, 0},
+ {0x00cca, 0x00ccd, 0},
+ {0x00cd5, 0x00cd6, 0},
+ {0x00ce2, 0x00ce3, 0},
+ {0x00d02, 0x00d03, 0},
+ {0x00d3e, 0x00d44, 0},
+ {0x00d46, 0x00d48, 0},
+ {0x00d4a, 0x00d4d, 0},
+ {0x00d57, 0x00d57, 0},
+ {0x00d62, 0x00d63, 0},
+ {0x00d82, 0x00d83, 0},
+ {0x00dca, 0x00dca, 0},
+ {0x00dcf, 0x00dd4, 0},
+ {0x00dd6, 0x00dd6, 0},
+ {0x00dd8, 0x00ddf, 0},
+ {0x00df2, 0x00df3, 0},
+ {0x00e31, 0x00e31, 0},
+ {0x00e34, 0x00e3a, 0},
+ {0x00e47, 0x00e4e, 0},
+ {0x00eb1, 0x00eb1, 0},
+ {0x00eb4, 0x00eb9, 0},
+ {0x00ebb, 0x00ebc, 0},
+ {0x00ec8, 0x00ecd, 0},
+ {0x00f18, 0x00f19, 0},
+ {0x00f35, 0x00f35, 0},
+ {0x00f37, 0x00f37, 0},
+ {0x00f39, 0x00f39, 0},
+ {0x00f3e, 0x00f3f, 0},
+ {0x00f71, 0x00f84, 0},
+ {0x00f86, 0x00f87, 0},
+ {0x00f90, 0x00f97, 0},
+ {0x00f99, 0x00fbc, 0},
+ {0x00fc6, 0x00fc6, 0},
+ {0x0102b, 0x0103e, 0},
+ {0x01056, 0x01059, 0},
+ {0x0105e, 0x01060, 0},
+ {0x01062, 0x01064, 0},
+ {0x01067, 0x0106d, 0},
+ {0x01071, 0x01074, 0},
+ {0x01082, 0x0108d, 0},
+ {0x0108f, 0x0108f, 0},
+ {0x0109a, 0x0109d, 0},
+ {0x01100, 0x0115f, 2},
+ {0x011a3, 0x011a7, 2},
+ {0x011fa, 0x011ff, 2},
+ {0x0135f, 0x0135f, 0},
+ {0x01712, 0x01714, 0},
+ {0x01732, 0x01734, 0},
+ {0x01752, 0x01753, 0},
+ {0x01772, 0x01773, 0},
+ {0x017b6, 0x017d3, 0},
+ {0x017dd, 0x017dd, 0},
+ {0x0180b, 0x0180d, 0},
+ {0x018a9, 0x018a9, 0},
+ {0x01920, 0x0192b, 0},
+ {0x01930, 0x0193b, 0},
+ {0x019b0, 0x019c0, 0},
+ {0x019c8, 0x019c9, 0},
+ {0x01a17, 0x01a1b, 0},
+ {0x01a55, 0x01a5e, 0},
+ {0x01a60, 0x01a7c, 0},
+ {0x01a7f, 0x01a7f, 0},
+ {0x01b00, 0x01b04, 0},
+ {0x01b34, 0x01b44, 0},
+ {0x01b6b, 0x01b73, 0},
+ {0x01b80, 0x01b82, 0},
+ {0x01ba1, 0x01baa, 0},
+ {0x01c24, 0x01c37, 0},
+ {0x01cd0, 0x01cd2, 0},
+ {0x01cd4, 0x01ce8, 0},
+ {0x01ced, 0x01ced, 0},
+ {0x01cf2, 0x01cf2, 0},
+ {0x01dc0, 0x01de6, 0},
+ {0x01dfd, 0x01dff, 0},
+ {0x020d0, 0x020f0, 0},
+ {0x02329, 0x0232a, 2},
+ {0x02cef, 0x02cf1, 0},
+ {0x02de0, 0x02dff, 0},
+ {0x02e80, 0x02e99, 2},
+ {0x02e9b, 0x02ef3, 2},
+ {0x02f00, 0x02fd5, 2},
+ {0x02ff0, 0x02ffb, 2},
+ {0x03000, 0x03029, 2},
+ {0x0302a, 0x0302f, 0},
+ {0x03030, 0x0303e, 2},
+ {0x03041, 0x03096, 2},
+ {0x03099, 0x0309a, 0},
+ {0x0309b, 0x030ff, 2},
+ {0x03105, 0x0312d, 2},
+ {0x03131, 0x0318e, 2},
+ {0x03190, 0x031b7, 2},
+ {0x031c0, 0x031e3, 2},
+ {0x031f0, 0x0321e, 2},
+ {0x03220, 0x03247, 2},
+ {0x03250, 0x032fe, 2},
+ {0x03300, 0x04dbf, 2},
+ {0x04e00, 0x0a48c, 2},
+ {0x0a490, 0x0a4c6, 2},
+ {0x0a66f, 0x0a672, 0},
+ {0x0a67c, 0x0a67d, 0},
+ {0x0a6f0, 0x0a6f1, 0},
+ {0x0a802, 0x0a802, 0},
+ {0x0a806, 0x0a806, 0},
+ {0x0a80b, 0x0a80b, 0},
+ {0x0a823, 0x0a827, 0},
+ {0x0a880, 0x0a881, 0},
+ {0x0a8b4, 0x0a8c4, 0},
+ {0x0a8e0, 0x0a8f1, 0},
+ {0x0a926, 0x0a92d, 0},
+ {0x0a947, 0x0a953, 0},
+ {0x0a960, 0x0a97c, 2},
+ {0x0a980, 0x0a983, 0},
+ {0x0a9b3, 0x0a9c0, 0},
+ {0x0aa29, 0x0aa36, 0},
+ {0x0aa43, 0x0aa43, 0},
+ {0x0aa4c, 0x0aa4d, 0},
+ {0x0aa7b, 0x0aa7b, 0},
+ {0x0aab0, 0x0aab0, 0},
+ {0x0aab2, 0x0aab4, 0},
+ {0x0aab7, 0x0aab8, 0},
+ {0x0aabe, 0x0aabf, 0},
+ {0x0aac1, 0x0aac1, 0},
+ {0x0abe3, 0x0abea, 0},
+ {0x0abec, 0x0abed, 0},
+ {0x0ac00, 0x0d7a3, 2},
+ {0x0d7b0, 0x0d7c6, 2},
+ {0x0d7cb, 0x0d7fb, 2},
+ {0x0f900, 0x0faff, 2},
+ {0x0fb1e, 0x0fb1e, 0},
+ {0x0fe00, 0x0fe0f, 0},
+ {0x0fe10, 0x0fe19, 2},
+ {0x0fe20, 0x0fe26, 0},
+ {0x0fe30, 0x0fe52, 2},
+ {0x0fe54, 0x0fe66, 2},
+ {0x0fe68, 0x0fe6b, 2},
+ {0x0ff01, 0x0ff60, 2},
+ {0x0ffe0, 0x0ffe6, 2},
+ {0x101fd, 0x101fd, 0},
+ {0x10a01, 0x10a03, 0},
+ {0x10a05, 0x10a06, 0},
+ {0x10a0c, 0x10a0f, 0},
+ {0x10a38, 0x10a3a, 0},
+ {0x10a3f, 0x10a3f, 0},
+ {0x11080, 0x11082, 0},
+ {0x110b0, 0x110ba, 0},
+ {0x1d165, 0x1d169, 0},
+ {0x1d16d, 0x1d172, 0},
+ {0x1d17b, 0x1d182, 0},
+ {0x1d185, 0x1d18b, 0},
+ {0x1d1aa, 0x1d1ad, 0},
+ {0x1d242, 0x1d244, 0},
+ {0x1f200, 0x1f200, 2},
+ {0x1f210, 0x1f231, 2},
+ {0x1f240, 0x1f248, 2},
+ {0x20000, 0x2fffd, 2},
+ {0x30000, 0x3fffd, 2},
+ {0xe0100, 0xe01ef, 0}
+};
+
+/* Get the width of a UTF-8 character. */
+int utf8_width(char *s)
+{
+ int val, low, high, cur;
+
+ if (UTF8_ISCONT(*s))
+ return 0;
+
+ switch (UTF8_LENGTH(*s)) {
+ case 1:
+ val = s[0];
+ break;
+ case 2:
+ val = (s[1] & 0x3f) | (s[0] & 0x1f) << 6;
+ break;
+ case 3:
+ val = ((s[2] & 0x3f) | (s[1] & 0x3f) << 6) | (s[0] & 0x0f) << 12;
+ break;
+ case 4:
+ val = (((s[3] & 0x3f) | (s[2] & 0x3f) << 6) |
+ (s[1] & 0x3f) << 12) | (s[0] & 0x3f) << 18;
+ break;
+ case 5:
+ val = ((((s[4] & 0x3f) | (s[3] & 0x3f) << 6) |
+ (s[2] & 0x3f) << 12) | (s[1] & 0x3f) << 18) | (s[0] & 0x3f) << 24;
+ break;
+ case 6:
+ val = (((((s[5] & 0x3f) | (s[4] & 0x3f) << 6) |
+ (s[3] & 0x3f) << 12) | (s[2] & 0x3f) << 18) |
+ (s[1] & 0x3f) << 24) | (s[0] & 0x3f) << 30;
+ break;
+ default:
+ return 0;
+ }
+
+ low = 0;
+ high = sizeof(utf8_widthtab) / sizeof(utf8_widthtab[0]);
+ do {
+ cur = (low + high) / 2;
+ if (val >= utf8_widthtab[cur].min) {
+ if (val <= utf8_widthtab[cur].max)
+ return utf8_widthtab[cur].width;
+ else
+ low = cur + 1;
+ } else
+ high = cur - 1;
+ }
+ while (low <= high);
+
+ return 1;
+}
+
+/* Get the width of a UTF-8 string. */
+int utf8_strwidth(char *s)
+{
+ int width = 0;
+
+ for (; s && *s; s++) {
+ if (!UTF8_ISCONT(*s))
+ width += utf8_width(s);
+ }
+
+ return width;
+}
diff --git a/src/utils.c b/src/utils.c
index 0a01c2e..b3d9c71 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -1,7 +1,7 @@
/*
* Calcurse - text-based organizer
*
- * Copyright (c) 2004-2011 calcurse Development Team <misc@calcurse.org>
+ * Copyright (c) 2004-2012 calcurse Development Team <misc@calcurse.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -42,69 +42,80 @@
#include <ctype.h>
#include <sys/types.h>
#include <errno.h>
+#include <fcntl.h>
+#include <sys/wait.h>
+#include <termios.h>
#include "calcurse.h"
#define ISLEAP(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
+#define FS_EXT_MAXLEN 64
+
+enum format_specifier {
+ FS_STARTDATE,
+ FS_DURATION,
+ FS_ENDDATE,
+ FS_MESSAGE,
+ FS_NOTE,
+ FS_NOTEFILE,
+ FS_PRIORITY,
+ FS_PSIGN,
+ FS_EOF,
+ FS_UNKNOWN
+};
+
/* General routine to exit calcurse properly. */
-void
-exit_calcurse (int status)
+void exit_calcurse(int status)
{
int was_interactive;
- if (ui_mode == UI_CURSES)
- {
- notify_stop_main_thread ();
- clear ();
- wins_refresh ();
- endwin ();
- ui_mode = UI_CMDLINE;
- was_interactive = 1;
- }
- else
+ if (ui_mode == UI_CURSES) {
+ notify_stop_main_thread();
+ clear();
+ wins_refresh();
+ endwin();
+ ui_mode = UI_CMDLINE;
+ was_interactive = 1;
+ } else
was_interactive = 0;
- calendar_stop_date_thread ();
- io_stop_psave_thread ();
- free_user_data ();
- keys_free ();
- mem_stats ();
- if (was_interactive)
- {
- if (unlink (path_cpid) != 0)
- EXIT (_("Could not remove calcurse lock file: %s\n"),
- strerror (errno));
- if (dmon.enable)
- dmon_start (status);
- }
+ calendar_stop_date_thread();
+ io_stop_psave_thread();
+ free_user_data();
+ keys_free();
+ mem_stats();
+ if (was_interactive) {
+ if (unlink(path_cpid) != 0)
+ EXIT(_("Could not remove calcurse lock file: %s\n"), strerror(errno));
+ if (dmon.enable)
+ dmon_start(status);
+ }
- exit (status);
+ exit(status);
}
-void
-free_user_data (void)
+void free_user_data(void)
{
- day_free_list ();
- event_llist_free ();
- event_free_bkp (ERASE_FORCE);
- apoint_llist_free ();
- apoint_free_bkp (ERASE_FORCE);
- recur_apoint_llist_free ();
- recur_event_llist_free ();
- recur_apoint_free_bkp (ERASE_FORCE);
- recur_event_free_bkp (ERASE_FORCE);
- todo_free_list ();
- notify_free_app ();
+ day_free_list();
+ event_llist_free();
+ event_free_bkp();
+ apoint_llist_free();
+ apoint_free_bkp();
+ recur_apoint_llist_free();
+ recur_event_llist_free();
+ recur_apoint_free_bkp();
+ recur_event_free_bkp();
+ todo_free_list();
+ notify_free_app();
}
/* Function to exit on internal error. */
-void
-fatalbox (const char *errmsg)
+void fatalbox(const char *errmsg)
{
WINDOW *errwin;
- char *label = _("/!\\ INTERNAL ERROR /!\\");
- char *reportmsg = _("Please report the following bug:");
+ const char *label = _("/!\\ INTERNAL ERROR /!\\");
+ const char *reportmsg = _("Please report the following bug:");
const int WINROW = 10;
const int WINCOL = col - 2;
const int MSGLEN = WINCOL - 2;
@@ -113,25 +124,24 @@ fatalbox (const char *errmsg)
if (errmsg == NULL)
return;
- (void)strncpy (msg, errmsg, MSGLEN);
- errwin = newwin (WINROW, WINCOL, (row - WINROW) / 2, (col - WINCOL) / 2);
- custom_apply_attr (errwin, ATTR_HIGHEST);
- box (errwin, 0, 0);
- wins_show (errwin, label);
- mvwprintw (errwin, 3, 1, reportmsg);
- mvwprintw (errwin, 5, (WINCOL - strlen (msg)) / 2, "%s", msg);
- custom_remove_attr (errwin, ATTR_HIGHEST);
- wins_wrefresh (errwin);
- (void)wgetch (errwin);
- delwin (errwin);
- wins_doupdate ();
+ strncpy(msg, errmsg, MSGLEN);
+ errwin = newwin(WINROW, WINCOL, (row - WINROW) / 2, (col - WINCOL) / 2);
+ custom_apply_attr(errwin, ATTR_HIGHEST);
+ box(errwin, 0, 0);
+ wins_show(errwin, label);
+ mvwprintw(errwin, 3, 1, reportmsg);
+ mvwprintw(errwin, 5, (WINCOL - strlen(msg)) / 2, "%s", msg);
+ custom_remove_attr(errwin, ATTR_HIGHEST);
+ wins_wrefresh(errwin);
+ wgetch(errwin);
+ delwin(errwin);
+ wins_doupdate();
}
-void
-warnbox (const char *msg)
+void warnbox(const char *msg)
{
WINDOW *warnwin;
- char *label = "/!\\";
+ const char *label = "/!\\";
const int WINROW = 10;
const int WINCOL = col - 2;
const int MSGLEN = WINCOL - 2;
@@ -140,317 +150,208 @@ warnbox (const char *msg)
if (msg == NULL)
return;
- (void)strncpy (displmsg, msg, MSGLEN);
- warnwin = newwin (WINROW, WINCOL, (row - WINROW) / 2, (col - WINCOL) / 2);
- custom_apply_attr (warnwin, ATTR_HIGHEST);
- box (warnwin, 0, 0);
- wins_show (warnwin, label);
- mvwprintw (warnwin, 5, (WINCOL - strlen (displmsg)) / 2, "%s", displmsg);
- custom_remove_attr (warnwin, ATTR_HIGHEST);
- wins_wrefresh (warnwin);
- (void)wgetch (warnwin);
- delwin (warnwin);
- wins_doupdate ();
+ strncpy(displmsg, msg, MSGLEN);
+ warnwin = newwin(WINROW, WINCOL, (row - WINROW) / 2, (col - WINCOL) / 2);
+ custom_apply_attr(warnwin, ATTR_HIGHEST);
+ box(warnwin, 0, 0);
+ wins_show(warnwin, label);
+ mvwprintw(warnwin, 5, (WINCOL - strlen(displmsg)) / 2, "%s", displmsg);
+ custom_remove_attr(warnwin, ATTR_HIGHEST);
+ wins_wrefresh(warnwin);
+ wgetch(warnwin);
+ delwin(warnwin);
+ wins_doupdate();
}
/*
* Print a message in the status bar.
* Message texts for first line and second line are to be provided.
*/
-void
-status_mesg (char *mesg_line1, char *mesg_line2)
+void status_mesg(const char *msg1, const char *msg2)
{
- wins_erase_status_bar ();
- custom_apply_attr (win[STA].p, ATTR_HIGHEST);
- mvwprintw (win[STA].p, 0, 0, mesg_line1);
- mvwprintw (win[STA].p, 1, 0, mesg_line2);
- custom_remove_attr (win[STA].p, ATTR_HIGHEST);
+ wins_erase_status_bar();
+ custom_apply_attr(win[STA].p, ATTR_HIGHEST);
+ mvwprintw(win[STA].p, 0, 0, msg1);
+ mvwprintw(win[STA].p, 1, 0, msg2);
+ custom_remove_attr(win[STA].p, ATTR_HIGHEST);
+}
+
+/*
+ * Prompts the user to make a choice between named alternatives.
+ *
+ * The available choices are described by a string of the form
+ * "[ynp]". The first and last char are ignored (they are only here to
+ * make the translators' life easier), and every other char indicates
+ * a key the user is allowed to press.
+ *
+ * Returns the index of the key pressed by the user (starting from 1),
+ * or -1 if the user doesn't want to answer (e.g. by escaping).
+ */
+int status_ask_choice(const char *message, const char choice[], int nb_choice)
+{
+ int i, ch;
+ char tmp[BUFSIZ];
+ /* "[4/2/f/t/w/.../Z] " */
+ char avail_choice[2 * nb_choice + 3];
+
+ avail_choice[0] = '[';
+ avail_choice[1] = '\0';
+
+ for (i = 1; i <= nb_choice; i++) {
+ snprintf(tmp, BUFSIZ, (i == nb_choice) ? "%c] " : "%c/", choice[i]);
+ strcat(avail_choice, tmp);
+ }
+
+ status_mesg(message, avail_choice);
+
+ for (;;) {
+ ch = wgetch(win[STA].p);
+ for (i = 1; i <= nb_choice; i++)
+ if (ch == choice[i])
+ return i;
+ if (ch == ESCAPE)
+ return (-1);
+ if (resize) {
+ resize = 0;
+ wins_reset();
+ status_mesg(message, avail_choice);
+ }
+ }
+}
+
+/*
+ * Prompts the user with a boolean question.
+ *
+ * Returns 1 if yes, 2 if no, and -1 otherwise
+ */
+int status_ask_bool(const char *msg)
+{
+ return (status_ask_choice(msg, _("[yn]"), 2));
+}
+
+/*
+ * Prompts the user to make a choice between a number of alternatives.
+ *
+ * Returns the option chosen by the user (starting from 1), or -1 if
+ * the user doesn't want to answer.
+ */
+int
+status_ask_simplechoice(const char *prefix, const char *choice[], int nb_choice)
+{
+ int i;
+ char tmp[BUFSIZ];
+ /* "(1) Choice1, (2) Choice2, (3) Choice3?" */
+ char choicestr[BUFSIZ];
+ /* Holds the characters to choose from ('1', '2', etc) */
+ char char_choice[nb_choice + 2];
+
+ /* No need to initialize first and last char. */
+ for (i = 1; i <= nb_choice; i++)
+ char_choice[i] = '0' + i;
+
+ strcpy(choicestr, prefix);
+
+ for (i = 0; i < nb_choice; i++) {
+ snprintf(tmp, BUFSIZ, ((i + 1) == nb_choice) ? "(%d) %s?" : "(%d) %s, ",
+ (i + 1), _(choice[i]));
+ strcat(choicestr, tmp);
+ }
+
+ return (status_ask_choice(choicestr, char_choice, nb_choice));
}
/* Erase part of a window. */
void
-erase_window_part (WINDOW *win, int first_col, int first_row, int last_col,
- int last_row)
+erase_window_part(WINDOW * win, int first_col, int first_row, int last_col,
+ int last_row)
{
int c, r;
- for (r = first_row; r <= last_row; r++)
- {
- for (c = first_col; c <= last_col; c++)
- mvwprintw (win, r, c, " ");
- }
-
- wnoutrefresh (win);
+ for (r = first_row; r <= last_row; r++) {
+ for (c = first_col; c <= last_col; c++)
+ mvwprintw(win, r, c, " ");
+ }
}
/* draws a popup window */
-WINDOW *
-popup (int pop_row, int pop_col, int pop_y, int pop_x, char *title, char *msg,
- int hint)
+WINDOW *popup(int pop_row, int pop_col, int pop_y, int pop_x, const char *title,
+ const char *msg, int hint)
{
- char *any_key = _("Press any key to continue...");
+ const char *any_key = _("Press any key to continue...");
char label[BUFSIZ];
WINDOW *popup_win;
const int MSGXPOS = 5;
- popup_win = newwin (pop_row, pop_col, pop_y, pop_x);
- keypad (popup_win, TRUE);
+ popup_win = newwin(pop_row, pop_col, pop_y, pop_x);
+ keypad(popup_win, TRUE);
if (msg)
- mvwprintw (popup_win, MSGXPOS, (pop_col - strlen (msg)) / 2, "%s", msg);
- custom_apply_attr (popup_win, ATTR_HIGHEST);
- box (popup_win, 0, 0);
- (void)snprintf (label, BUFSIZ, "%s", title);
- wins_show (popup_win, label);
+ mvwprintw(popup_win, MSGXPOS, (pop_col - strlen(msg)) / 2, "%s", msg);
+ custom_apply_attr(popup_win, ATTR_HIGHEST);
+ box(popup_win, 0, 0);
+ snprintf(label, BUFSIZ, "%s", title);
+ wins_show(popup_win, label);
if (hint)
- mvwprintw (popup_win, pop_row - 2, pop_col - (strlen (any_key) + 1), "%s",
- any_key);
- custom_remove_attr (popup_win, ATTR_HIGHEST);
- wins_wrefresh (popup_win);
+ mvwprintw(popup_win, pop_row - 2, pop_col - (strlen(any_key) + 1), "%s",
+ any_key);
+ custom_remove_attr(popup_win, ATTR_HIGHEST);
+ wins_wrefresh(popup_win);
return popup_win;
}
/* prints in middle of a panel */
void
-print_in_middle (WINDOW *win, int starty, int startx, int width, char *string)
+print_in_middle(WINDOW * win, int starty, int startx, int width,
+ const char *string)
{
- int len = strlen (string);
+ int len = strlen(string);
int x, y;
win = win ? win : stdscr;
- getyx (win, y, x);
+ getyx(win, y, x);
x = startx ? startx : x;
y = starty ? starty : y;
width = width ? width : 80;
x += (width - len) / 2;
- custom_apply_attr (win, ATTR_HIGHEST);
- mvwprintw (win, y, x, "%s", string);
- custom_remove_attr (win, ATTR_HIGHEST);
-}
-
-/* Print the string at the desired position. */
-static void
-showstring (WINDOW *win, int x, int y, char *str, int len, int scroff,
- int curpos)
-{
- char c = 0;
-
- /* print string */
- mvwaddnstr (win, y, x, &str[scroff], -1);
- wclrtoeol (win);
-
- /* print scrolling indicator */
- if (scroff > 0 && scroff < len - col)
- c = '*';
- else if (scroff > 0)
- c = '<';
- else if (scroff < len - col)
- c = '>';
- mvwprintw (win, y, col - 1, "%c", c);
-
- /* print cursor */
- wmove (win, y, curpos - scroff);
-
- if (curpos >= len)
- waddch (win, SPACE | A_REVERSE);
- else
- waddch (win, str[curpos] | A_REVERSE);
-}
-
-/* Delete a character at the given position in string. */
-static void
-del_char (int pos, char *str)
-{
- str += pos;
- memmove (str, str + 1, strlen (str) + 1);
-}
-
-/* Add a character at the given position in string. */
-static void
-ins_char (int pos, int ch, char *str)
-{
- str += pos;
- memmove (str + 1, str, strlen (str) + 1);
- *str = ch;
-}
-
-static void
-bell (void)
-{
- printf ("\a");
-}
-
-/*
- * Getstring allows to get user input and to print it on a window,
- * even if noecho() is on. This function is also used to modify an existing
- * text (the variable string can be non-NULL).
- * We need to do the echoing manually because of the multi-threading
- * environment, otherwise the cursor would move from place to place without
- * control.
- */
-enum getstr
-getstring (WINDOW *win, char *str, int l, int x, int y)
-{
- const int pgsize = col / 3;
-
- int len = strlen (str);
- int curpos = len;
- int scroff = 0;
- int ch;
-
- custom_apply_attr (win, ATTR_HIGHEST);
-
- for (;;) {
- while (curpos < scroff)
- scroff -= pgsize;
- while (curpos >= scroff + col - 1)
- scroff += pgsize;
-
- showstring (win, x, y, str, len, scroff, curpos);
- wins_doupdate ();
-
- if ((ch = wgetch (win)) == '\n') break;
- switch (ch)
- {
- case KEY_BACKSPACE: /* delete one character */
- case 330:
- case 127:
- case CTRL ('H'):
- if (curpos > 0)
- {
- del_char ((--curpos), str);
- len--;
- }
- else
- bell ();
- break;
- case CTRL ('D'): /* delete next character */
- if (curpos < len)
- {
- del_char (curpos, str);
- len--;
- }
- else
- bell ();
- break;
- case CTRL ('W'): /* delete a word */
- if (curpos > 0) {
- while (curpos && str[curpos - 1] == ' ')
- {
- del_char ((--curpos), str);
- len--;
- }
- while (curpos && str[curpos - 1] != ' ')
- {
- del_char ((--curpos), str);
- len--;
- }
- }
- else
- bell ();
- break;
- case CTRL ('K'): /* delete to end-of-line */
- str[curpos] = 0;
- len = curpos;
- break;
- case CTRL ('A'): /* go to begginning of string */
- curpos = 0;
- break;
- case CTRL ('E'): /* go to end of string */
- curpos = len;
- break;
- case KEY_LEFT: /* move one char backward */
- case CTRL ('B'):
- if (curpos > 0) curpos--;
- break;
- case KEY_RIGHT: /* move one char forward */
- case CTRL ('F'):
- if (curpos < len) curpos++;
- break;
- case ESCAPE: /* cancel editing */
- return (GETSTRING_ESC);
- break;
- default: /* insert one character */
- if (len < l - 1)
- {
- ins_char ((curpos++), ch, str);
- len++;
- }
- }
- }
-
- custom_remove_attr (win, ATTR_HIGHEST);
-
- return (len == 0 ? GETSTRING_RET : GETSTRING_VALID);
-}
-
-/* Update an already existing string. */
-int
-updatestring (WINDOW *win, char **str, int x, int y)
-{
- int len = strlen (*str);
- char *buf;
- enum getstr ret;
-
- EXIT_IF (len + 1 > BUFSIZ, _("Internal error: line too long"));
-
- buf = mem_malloc (BUFSIZ);
- (void)memcpy (buf, *str, len + 1);
-
- ret = getstring (win, buf, BUFSIZ, x, y);
-
- if (ret == GETSTRING_VALID)
- {
- len = strlen (buf);
- *str = mem_realloc (*str, len + 1, 1);
- EXIT_IF (*str == NULL, _("out of memory"));
- (void)memcpy (*str, buf, len + 1);
- }
-
- mem_free (buf);
- return ret;
+ custom_apply_attr(win, ATTR_HIGHEST);
+ mvwprintw(win, y, x, "%s", string);
+ custom_remove_attr(win, ATTR_HIGHEST);
}
/* checks if a string is only made of digits */
-int
-is_all_digit (char *string)
+int is_all_digit(const char *string)
{
- for (; *string; string++)
- {
- if (!isdigit ((int)*string))
- return 0;
- }
+ for (; *string; string++) {
+ if (!isdigit((int)*string))
+ return 0;
+ }
return 1;
}
/* Given an item date expressed in seconds, return its start time in seconds. */
-long
-get_item_time (long date)
+long get_item_time(long date)
{
- return (long)(get_item_hour (date) * HOURINSEC +
- get_item_min (date) * MININSEC);
+ return (long)(get_item_hour(date) * HOURINSEC +
+ get_item_min(date) * MININSEC);
}
-int
-get_item_hour (long date)
+int get_item_hour(long date)
{
- return (localtime ((time_t *)&date))->tm_hour;
+ return (localtime((time_t *) & date))->tm_hour;
}
-int
-get_item_min (long date)
+int get_item_min(long date)
{
- return (localtime ((time_t *)&date))->tm_min;
+ return (localtime((time_t *) & date))->tm_min;
}
-long
-date2sec (struct date day, unsigned hour, unsigned min)
+long date2sec(struct date day, unsigned hour, unsigned min)
{
- time_t t = now ();
- struct tm start = *(localtime (&t));
+ time_t t = now();
+ struct tm start = *(localtime(&t));
start.tm_mon = day.mm - 1;
start.tm_mday = day.dd;
@@ -460,40 +361,37 @@ date2sec (struct date day, unsigned hour, unsigned min)
start.tm_sec = 0;
start.tm_isdst = -1;
- t = mktime (&start);
- EXIT_IF (t == -1, _("failure in mktime"));
+ t = mktime(&start);
+ EXIT_IF(t == -1, _("failure in mktime"));
return t;
}
/* Return a string containing the date, given a date in seconds. */
-char *
-date_sec2date_str (long sec, char *datefmt)
+char *date_sec2date_str(long sec, const char *datefmt)
{
struct tm *lt;
- char *datestr = (char *) mem_calloc (BUFSIZ, sizeof (char));
+ char *datestr = (char *)mem_calloc(BUFSIZ, sizeof(char));
if (sec == 0)
- (void)snprintf (datestr, BUFSIZ, "0");
- else
- {
- lt = localtime ((time_t *)&sec);
- strftime (datestr, BUFSIZ, datefmt, lt);
- }
+ strncpy(datestr, "0", BUFSIZ);
+ else {
+ lt = localtime((time_t *) & sec);
+ strftime(datestr, BUFSIZ, datefmt, lt);
+ }
return datestr;
}
/* Generic function to format date. */
-void
-date_sec2date_fmt (long sec, const char *fmt, char *datef)
+void date_sec2date_fmt(long sec, const char *fmt, char *datef)
{
/* TODO: Find a better way to deal with localization and strftime(). */
char *locale_old = mem_strdup (setlocale (LC_ALL, NULL));
setlocale (LC_ALL, "C");
- struct tm *lt = localtime ((time_t *)&sec);
- strftime (datef, BUFSIZ, fmt, lt);
+ struct tm *lt = localtime((time_t *)&sec);
+ strftime(datef, BUFSIZ, fmt, lt);
setlocale (LC_ALL, locale_old);
mem_free (locale_old);
@@ -502,19 +400,18 @@ date_sec2date_fmt (long sec, const char *fmt, char *datef)
/*
* Used to change date by adding a certain amount of days or weeks.
*/
-long
-date_sec_change (long date, int delta_month, int delta_day)
+long date_sec_change(long date, int delta_month, int delta_day)
{
struct tm *lt;
time_t t;
t = date;
- lt = localtime (&t);
+ lt = localtime(&t);
lt->tm_mon += delta_month;
lt->tm_mday += delta_day;
lt->tm_isdst = -1;
- t = mktime (lt);
- EXIT_IF (t == -1, _("failure in mktime"));
+ t = mktime(lt);
+ EXIT_IF(t == -1, _("failure in mktime"));
return t;
}
@@ -523,28 +420,26 @@ date_sec_change (long date, int delta_month, int delta_day)
* Return a long containing the date which is updated taking into account
* the new time and date entered by the user.
*/
-long
-update_time_in_date (long date, unsigned hr, unsigned mn)
+long update_time_in_date(long date, unsigned hr, unsigned mn)
{
struct tm *lt;
time_t t, new_date;
t = date;
- lt = localtime (&t);
+ lt = localtime(&t);
lt->tm_hour = hr;
lt->tm_min = mn;
- new_date = mktime (lt);
- EXIT_IF (new_date == -1, _("error in mktime"));
+ new_date = mktime(lt);
+ EXIT_IF(new_date == -1, _("error in mktime"));
- return (new_date);
+ return new_date;
}
/*
* Returns the date in seconds from year 1900.
* If no date is entered, current date is chosen.
*/
-long
-get_sec_date (struct date date)
+long get_sec_date(struct date date)
{
struct tm *ptrtime;
time_t timer;
@@ -553,56 +448,23 @@ get_sec_date (struct date date)
char current_month[] = "mm ";
char current_year[] = "yyyy ";
- if (date.yyyy == 0 && date.mm == 0 && date.dd == 0)
- {
- timer = time (NULL);
- ptrtime = localtime (&timer);
- strftime (current_day, strlen (current_day), "%d", ptrtime);
- strftime (current_month, strlen (current_month), "%m", ptrtime);
- strftime (current_year, strlen (current_year), "%Y", ptrtime);
- date.mm = atoi (current_month);
- date.dd = atoi (current_day);
- date.yyyy = atoi (current_year);
- }
- long_date = date2sec (date, 0, 0);
- return (long_date);
+ if (date.yyyy == 0 && date.mm == 0 && date.dd == 0) {
+ timer = time(NULL);
+ ptrtime = localtime(&timer);
+ strftime(current_day, strlen(current_day), "%d", ptrtime);
+ strftime(current_month, strlen(current_month), "%m", ptrtime);
+ strftime(current_year, strlen(current_year), "%Y", ptrtime);
+ date.mm = atoi(current_month);
+ date.dd = atoi(current_day);
+ date.yyyy = atoi(current_year);
+ }
+ long_date = date2sec(date, 0, 0);
+ return long_date;
}
-long
-min2sec (unsigned minutes)
+long min2sec(unsigned minutes)
{
- return (minutes * MININSEC);
-}
-
-/*
- * Checks if a time has a good format.
- * The format could be either HH:MM or H:MM or MM, and we should have:
- * 0 <= HH <= 24 and 0 <= MM < 999.
- * This function returns 1 if the entered time is correct and in
- * [h:mm] or [hh:mm] format, and 2 if the entered time is correct and entered
- * in [mm] format.
- */
-int
-check_time (char *string)
-{
- char *s = mem_strdup(string);
- char *hour = strtok(s, ":");
- char *min = strtok(NULL, ":");
- int h, m;
- int ret = 0;
-
- if (min)
- {
- h = atoi (hour);
- m = atoi (min);
- if (h >= 0 && h < 24 && m >= 0 && m < MININSEC)
- ret = 1;
- }
- else if (strlen(s) < 4 && is_all_digit(s) && atoi(s) > 0)
- ret = 2;
-
- mem_free(s);
- return ret;
+ return minutes * MININSEC;
}
/*
@@ -610,17 +472,17 @@ check_time (char *string)
* can not be displayed inside the corresponding panel.
*/
void
-draw_scrollbar (WINDOW *win, int y, int x, int length,
- int bar_top, int bar_bottom, unsigned hilt)
+draw_scrollbar(WINDOW * win, int y, int x, int length,
+ int bar_top, int bar_bottom, unsigned hilt)
{
- mvwvline (win, bar_top, x, ACS_VLINE, bar_bottom - bar_top);
+ mvwvline(win, bar_top, x, ACS_VLINE, bar_bottom - bar_top);
if (hilt)
- custom_apply_attr (win, ATTR_HIGHEST);
- wattron (win, A_REVERSE);
- mvwvline (win, y, x, ' ', length);
- wattroff (win, A_REVERSE);
+ custom_apply_attr(win, ATTR_HIGHEST);
+ wattron(win, A_REVERSE);
+ mvwvline(win, y, x, ' ', length);
+ wattroff(win, A_REVERSE);
if (hilt)
- custom_remove_attr (win, ATTR_HIGHEST);
+ custom_remove_attr(win, ATTR_HIGHEST);
}
/*
@@ -629,121 +491,112 @@ draw_scrollbar (WINDOW *win, int y, int x, int length,
* long to fit in its corresponding panel window.
*/
void
-item_in_popup (char *saved_a_start, char *saved_a_end, char *msg,
- char *pop_title)
+item_in_popup(const char *saved_a_start, const char *saved_a_end,
+ const char *msg, const char *pop_title)
{
WINDOW *popup_win, *pad;
const int margin_left = 4, margin_top = 4;
const int winl = row - 5, winw = col - margin_left;
const int padl = winl - 2, padw = winw - margin_left;
- pad = newpad (padl, padw);
- popup_win = popup (winl, winw, 1, 2, pop_title, (char *)0, 1);
- if (strncmp (pop_title, _("Appointment"), 11) == 0)
- {
- mvwprintw (popup_win, margin_top, margin_left, "- %s -> %s",
- saved_a_start, saved_a_end);
- }
- mvwprintw (pad, 0, margin_left, "%s", msg);
- wmove (win[STA].p, 0, 0);
- pnoutrefresh (pad, 0, 0, margin_top + 2, margin_left, padl, winw);
- wins_doupdate ();
- (void)wgetch (popup_win);
- delwin (pad);
- delwin (popup_win);
+ pad = newpad(padl, padw);
+ popup_win = popup(winl, winw, 1, 2, pop_title, NULL, 1);
+ if (strcmp(pop_title, _("Appointment")) == 0) {
+ mvwprintw(popup_win, margin_top, margin_left, "- %s -> %s",
+ saved_a_start, saved_a_end);
+ }
+ mvwprintw(pad, 0, margin_left, "%s", msg);
+ wmove(win[STA].p, 0, 0);
+ pnoutrefresh(pad, 0, 0, margin_top + 2, margin_left, padl, winw);
+ wins_doupdate();
+ wgetch(popup_win);
+ delwin(pad);
+ delwin(popup_win);
}
/* Returns the beginning of current day in seconds from 1900. */
-long
-get_today (void)
+long get_today(void)
{
struct tm *lt;
time_t current_time;
long current_day;
struct date day;
- current_time = time (NULL);
- lt = localtime (&current_time);
+ current_time = time(NULL);
+ lt = localtime(&current_time);
day.mm = lt->tm_mon + 1;
day.dd = lt->tm_mday;
day.yyyy = lt->tm_year + 1900;
- current_day = date2sec (day, 0, 0);
+ current_day = date2sec(day, 0, 0);
- return (current_day);
+ return current_day;
}
/* Returns the current time in seconds. */
-long
-now (void)
+long now(void)
{
- return (long)time (NULL);
+ return (long)time(NULL);
}
-char *
-nowstr (void)
+char *nowstr(void)
{
static char buf[BUFSIZ];
- time_t t = now ();
+ time_t t = now();
- (void)strftime (buf, sizeof buf, "%a %b %d %T %Y", localtime (&t));
+ strftime(buf, sizeof buf, "%a %b %d %T %Y", localtime(&t));
return buf;
}
-long
-mystrtol (const char *str)
+long mystrtol(const char *str)
{
char *ep;
long lval;
errno = 0;
- lval = strtol (str, &ep, 10);
+ lval = strtol(str, &ep, 10);
if (str[0] == '\0' || *ep != '\0')
- EXIT (_("could not convert string"));
+ EXIT(_("could not convert string"));
if (errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN))
- EXIT (_("out of range"));
+ EXIT(_("out of range"));
- return (lval);
+ return lval;
}
/* Print the given option value with appropriate color. */
void
-print_bool_option_incolor (WINDOW *win, unsigned option, int pos_y, int pos_x)
+print_bool_option_incolor(WINDOW * win, unsigned option, int pos_y, int pos_x)
{
int color = 0;
- char option_value[BUFSIZ] = "";
-
- if (option == 1)
- {
- color = ATTR_TRUE;
- strncpy (option_value, _("yes"), BUFSIZ);
- }
- else if (option == 0)
- {
- color = ATTR_FALSE;
- strncpy (option_value, _("no"), BUFSIZ);
- }
- else
- EXIT (_("option not defined"));
-
- custom_apply_attr (win, color);
- mvwprintw (win, pos_y, pos_x, "%s", option_value);
- custom_remove_attr (win, color);
- wnoutrefresh (win);
- wins_doupdate ();
+ const char *option_value;
+
+ if (option == 1) {
+ color = ATTR_TRUE;
+ option_value = _("yes");
+ } else if (option == 0) {
+ color = ATTR_FALSE;
+ option_value = _("no");
+ } else
+ EXIT(_("option not defined"));
+
+ custom_apply_attr(win, color);
+ mvwprintw(win, pos_y, pos_x, "%s", option_value);
+ custom_remove_attr(win, color);
+ wnoutrefresh(win);
+ wins_doupdate();
}
-
/*
* Get the name of the default directory for temporary files.
*/
-const char *
-get_tempdir (void)
+const char *get_tempdir(void)
{
- if (getenv ("TMPDIR"))
- return getenv ("TMPDIR");
+ if (getenv("TMPDIR"))
+ return getenv("TMPDIR");
+#ifdef P_tmpdir
else if (P_tmpdir)
return P_tmpdir;
+#endif
else
return "/tmp";
}
@@ -752,53 +605,32 @@ get_tempdir (void)
* Create a new unique file, and return a newly allocated string which contains
* the random part of the file name.
*/
-char *
-new_tempfile (const char *prefix, int trailing_len)
+char *new_tempfile(const char *prefix, int trailing_len)
{
char fullname[BUFSIZ];
int prefix_len, fd;
FILE *file;
if (prefix == NULL)
- return (NULL);
+ return NULL;
- prefix_len = strlen (prefix);
+ prefix_len = strlen(prefix);
if (prefix_len + trailing_len >= BUFSIZ)
- return (NULL);
- memcpy (fullname, prefix, prefix_len);
- (void)memset (fullname + prefix_len, 'X', trailing_len);
+ return NULL;
+ memcpy(fullname, prefix, prefix_len);
+ memset(fullname + prefix_len, 'X', trailing_len);
fullname[prefix_len + trailing_len] = '\0';
- if ((fd = mkstemp (fullname)) == -1 || (file = fdopen (fd, "w+")) == NULL)
- {
- if (fd != -1)
- {
- unlink (fullname);
- close (fd);
- }
- ERROR_MSG (_("temporary file \"%s\" could not be created"), fullname);
- return (char *)0;
+ if ((fd = mkstemp(fullname)) == -1 || (file = fdopen(fd, "w+")) == NULL) {
+ if (fd != -1) {
+ unlink(fullname);
+ close(fd);
}
- fclose (file);
-
- return mem_strdup (fullname + prefix_len);
-}
-
-/* Erase a note previously attached to a todo, event or appointment. */
-void
-erase_note (char **note, enum eraseflg flag)
-{
- char fullname[BUFSIZ];
+ ERROR_MSG(_("temporary file \"%s\" could not be created"), fullname);
+ return NULL;
+ }
+ fclose(file);
- if (*note == NULL)
- return;
- if (flag != ERASE_FORCE_KEEP_NOTE)
- {
- (void)snprintf (fullname, BUFSIZ, "%s%s", path_notes, *note);
- if (unlink (fullname) != 0)
- EXIT (_("could not remove note"));
- }
- mem_free (*note);
- *note = NULL;
+ return mem_strdup(fullname + prefix_len);
}
/*
@@ -814,75 +646,68 @@ erase_note (char **note, enum eraseflg flag)
* Returns 1 if sucessfully converted or 0 if the string is an invalid date.
*/
int
-parse_date (char *date_string, enum datefmt datefmt, int *year, int *month,
- int *day, struct date *slctd_date)
+parse_date(const char *date_string, enum datefmt datefmt, int *year,
+ int *month, int *day, struct date *slctd_date)
{
- char sep = (datefmt == DATEFMT_ISO) ? '-' : '/';
- char *p;
- int in[3] = {0, 0, 0}, n = 0;
+ const char sep = (datefmt == DATEFMT_ISO) ? '-' : '/';
+ const char *p;
+ int in[3] = { 0, 0, 0 }, n = 0;
int d, m, y;
if (!date_string)
return 0;
/* parse string into in[], read up to three integers */
- for (p = date_string; *p; p++)
- {
- if (*p == sep)
- {
- if ((++n) > 2)
- return 0;
- }
- else if ((*p >= '0') && (*p <= '9'))
- in[n] = in[n] * 10 + (int)(*p - '0');
- else
+ for (p = date_string; *p; p++) {
+ if (*p == sep) {
+ if ((++n) > 2)
return 0;
- }
+ } else if ((*p >= '0') && (*p <= '9'))
+ in[n] = in[n] * 10 + (int)(*p - '0');
+ else
+ return 0;
+ }
if ((!slctd_date && n < 2) || in[n] == 0)
return 0;
/* convert into day, month and year, depending on the date format */
- switch (datefmt)
- {
- case DATEFMT_MMDDYYYY:
- m = (n >= 1) ? in[0] : 0;
- d = (n >= 1) ? in[1] : in[0];
- y = in[2];
- break;
- case DATEFMT_DDMMYYYY:
- d = in[0];
- m = in[1];
- y = in[2];
- break;
- case DATEFMT_YYYYMMDD:
- case DATEFMT_ISO:
- y = (n >= 2) ? in[n - 2] : 0;
- m = (n >= 1) ? in[n - 1] : 0;
- d = in[n];
- break;
- default:
- return 0;
- }
+ switch (datefmt) {
+ case DATEFMT_MMDDYYYY:
+ m = (n >= 1) ? in[0] : 0;
+ d = (n >= 1) ? in[1] : in[0];
+ y = in[2];
+ break;
+ case DATEFMT_DDMMYYYY:
+ d = in[0];
+ m = in[1];
+ y = in[2];
+ break;
+ case DATEFMT_YYYYMMDD:
+ case DATEFMT_ISO:
+ y = (n >= 2) ? in[n - 2] : 0;
+ m = (n >= 1) ? in[n - 1] : 0;
+ d = in[n];
+ break;
+ default:
+ return 0;
+ }
- if (slctd_date)
- {
- if (y > 0 && y < 100)
- {
- /* convert "YY" format into "YYYY" */
- y += slctd_date->yyyy - slctd_date->yyyy % 100;
- }
- else if (n < 2)
- {
- /* set year and, optionally, month if short from is used */
- y = slctd_date->yyyy;
- if (n < 1) m = slctd_date->mm;
- }
+ if (slctd_date) {
+ if (y > 0 && y < 100) {
+ /* convert "YY" format into "YYYY" */
+ y += slctd_date->yyyy - slctd_date->yyyy % 100;
+ } else if (n < 2) {
+ /* set year and, optionally, month if short from is used */
+ y = slctd_date->yyyy;
+ if (n < 1)
+ m = slctd_date->mm;
}
+ }
/* check if date is valid, take leap years into account */
if (y < 1902 || y > 2037 || m < 1 || m > 12 || d < 1 ||
- d > days[m - 1] + (m == 2 && ISLEAP (y)) ? 1 : 0)
+ d > days[m - 1] + (m == 2 && ISLEAP(y)) ? 1 : 0)
return 0;
if (year)
@@ -895,19 +720,142 @@ parse_date (char *date_string, enum datefmt datefmt, int *year, int *month,
return 1;
}
-void
-str_toupper (char *s)
+/*
+ * Converts a time string into hours and minutes. Short forms like "23:"
+ * (23:00) or ":45" (0:45) are allowed.
+ *
+ * Returns 1 on success and 0 on failure.
+ */
+int parse_time(const char *string, unsigned *hour, unsigned *minute)
+{
+ const char *p;
+ unsigned in[2] = { 0, 0 }, n = 0;
+
+ if (!string)
+ return 0;
+
+ /* parse string into in[], read up to two integers */
+ for (p = string; *p; p++) {
+ if (*p == ':') {
+ if ((++n) > 1)
+ return 0;
+ } else if ((*p >= '0') && (*p <= '9'))
+ in[n] = in[n] * 10 + (int)(*p - '0');
+ else
+ return 0;
+ }
+
+ if (n != 1 || in[0] >= DAYINHOURS || in[1] >= HOURINMIN)
+ return 0;
+
+ *hour = in[0];
+ *minute = in[1];
+ return 1;
+}
+
+/*
+ * Converts a duration string into minutes.
+ *
+ * Allowed formats (noted as regular expressions):
+ *
+ * - \d*:\d*
+ * - (\d*m|\d*h(|\d*m)|\d*d(|\d*m|\d*h(|\d*m)))
+ * - \d+
+ *
+ * "\d" is used as a placeholder for "(0|1|2|3|4|5|6|7|8|9)".
+ *
+ * Returns 1 on success and 0 on failure.
+ */
+int parse_duration(const char *string, unsigned *duration)
+{
+ enum {
+ STATE_INITIAL,
+ STATE_HHMM_MM,
+ STATE_DDHHMM_HH,
+ STATE_DDHHMM_MM,
+ STATE_DONE
+ } state = STATE_INITIAL;
+
+ const char *p;
+ unsigned in = 0;
+ unsigned dur = 0;
+
+ if (!string || *string == '\0')
+ return 0;
+
+ /* parse string using a simple state machine */
+ for (p = string; *p; p++) {
+ if ((*p >= '0') && (*p <= '9')) {
+ if (state == STATE_DONE)
+ return 0;
+ else
+ in = in * 10 + (int)(*p - '0');
+ } else {
+ switch (state) {
+ case STATE_INITIAL:
+ if (*p == ':') {
+ dur += in * HOURINMIN;
+ state = STATE_HHMM_MM;
+ } else if (*p == 'd') {
+ dur += in * DAYINMIN;
+ state = STATE_DDHHMM_HH;
+ } else if (*p == 'h') {
+ dur += in * HOURINMIN;
+ state = STATE_DDHHMM_MM;
+ } else if (*p == 'm') {
+ dur += in;
+ state = STATE_DONE;
+ } else
+ return 0;
+ break;
+ case STATE_DDHHMM_HH:
+ if (*p == 'h') {
+ dur += in * HOURINMIN;
+ state = STATE_DDHHMM_MM;
+ } else if (*p == 'm') {
+ dur += in;
+ state = STATE_DONE;
+ } else
+ return 0;
+ break;
+ case STATE_DDHHMM_MM:
+ if (*p == 'm') {
+ dur += in;
+ state = STATE_DONE;
+ } else
+ return 0;
+ break;
+ case STATE_HHMM_MM:
+ case STATE_DONE:
+ return 0;
+ break;
+ }
+
+ in = 0;
+ }
+ }
+
+ if ((state == STATE_HHMM_MM && in >= HOURINMIN) ||
+ ((state == STATE_DDHHMM_HH || state == STATE_DDHHMM_MM) && in > 0))
+ return 0;
+
+ dur += in;
+ *duration = dur;
+
+ return 1;
+}
+
+void str_toupper(char *s)
{
if (!s)
return;
for (; *s; s++)
- *s = toupper (*s);
+ *s = toupper(*s);
}
-void
-file_close (FILE *f, const char *pos)
+void file_close(FILE * f, const char *pos)
{
- EXIT_IF ((fclose (f)) != 0, _("Error when closing file at %s"), pos);
+ EXIT_IF((fclose(f)) != 0, _("Error when closing file at %s"), pos);
}
/*
@@ -915,11 +863,482 @@ file_close (FILE *f, const char *pos)
* (hence the 'p') in a way that even if a signal is caught during the sleep
* process, this function will return to sleep afterwards.
*/
-void
-psleep (unsigned secs)
+void psleep(unsigned secs)
{
unsigned unslept;
- for (unslept = sleep (secs); unslept; unslept = sleep (unslept))
- ;
+ for (unslept = sleep(secs); unslept; unslept = sleep(unslept)) ;
+}
+
+/*
+ * Fork and execute an external process.
+ *
+ * If pfdin and/or pfdout point to a valid address, a pipe is created and the
+ * appropriate file descriptors are written to pfdin/pfdout.
+ */
+int fork_exec(int *pfdin, int *pfdout, const char *path, const char *const *arg)
+{
+ int pin[2], pout[2];
+ int pid;
+
+ if (pfdin && (pipe(pin) == -1))
+ return 0;
+ if (pfdout && (pipe(pout) == -1))
+ return 0;
+
+ if ((pid = fork()) == 0) {
+ if (pfdout) {
+ if (dup2(pout[0], STDIN_FILENO) < 0)
+ _exit(127);
+ close(pout[0]);
+ close(pout[1]);
+ }
+
+ if (pfdin) {
+ if (dup2(pin[1], STDOUT_FILENO) < 0)
+ _exit(127);
+ close(pin[0]);
+ close(pin[1]);
+ }
+
+ execvp(path, (char *const *)arg);
+ _exit(127);
+ } else {
+ if (pfdin)
+ close(pin[1]);
+ if (pfdout)
+ close(pout[0]);
+
+ if (pid > 0) {
+ if (pfdin) {
+ fcntl(pin[0], F_SETFD, FD_CLOEXEC);
+ *pfdin = pin[0];
+ }
+ if (pfdout) {
+ fcntl(pout[1], F_SETFD, FD_CLOEXEC);
+ *pfdout = pout[1];
+ }
+ } else {
+ if (pfdin)
+ close(pin[0]);
+ if (pfdout)
+ close(pout[1]);
+ return 0;
+ }
+ }
+ return pid;
+}
+
+/* Execute an external program in a shell. */
+int
+shell_exec(int *pfdin, int *pfdout, const char *path, const char *const *arg)
+{
+ int argc, i;
+ const char **narg;
+ char *arg0 = NULL;
+ int ret;
+
+ for (argc = 0; arg[argc]; argc++) ;
+
+ if (argc < 1)
+ return -1;
+
+ narg = mem_calloc(argc + 4, sizeof(const char *));
+
+ narg[0] = "sh";
+ narg[1] = "-c";
+
+ if (argc > 1) {
+ arg0 = mem_malloc(strlen(path) + 6);
+ sprintf(arg0, "%s \"$@\"", path);
+ narg[2] = arg0;
+
+ for (i = 0; i < argc; i++)
+ narg[i + 3] = arg[i];
+ narg[argc + 3] = NULL;
+ } else {
+ narg[2] = path;
+ narg[3] = NULL;
+ }
+
+ ret = fork_exec(pfdin, pfdout, *narg, narg);
+
+ if (arg0)
+ mem_free(arg0);
+ mem_free(narg);
+
+ return ret;
+}
+
+/* Wait for a child process to terminate. */
+int child_wait(int *pfdin, int *pfdout, int pid)
+{
+ int stat;
+
+ if (pfdin)
+ close(*pfdin);
+ if (pfdout)
+ close(*pfdout);
+
+ waitpid(pid, &stat, 0);
+ return stat;
+}
+
+/* Display "Press any key to continue..." and wait for a key press. */
+void press_any_key(void)
+{
+ struct termios t_attr_old, t_attr;
+
+ tcgetattr(STDIN_FILENO, &t_attr_old);
+ memcpy(&t_attr, &t_attr_old, sizeof(struct termios));
+ t_attr.c_lflag &= ~(ICANON | ECHO | ECHONL);
+ tcsetattr(STDIN_FILENO, TCSAFLUSH, &t_attr);
+
+ fflush(stdout);
+ fputs(_("Press any key to continue..."), stdout);
+ fflush(stdout);
+ fgetc(stdin);
+ fflush(stdin);
+ fputs("\r\n", stdout);
+
+ tcsetattr(STDIN_FILENO, TCSAFLUSH, &t_attr_old);
+}
+
+/*
+ * Display note contents if one is asociated with the currently displayed item
+ * (to be used together with the '-a' or '-t' flag in non-interactive mode).
+ * Each line begins with nbtab tabs.
+ * Print "No note file found", if the notefile does not exists.
+ *
+ * (patch submitted by Erik Saule).
+ */
+static void print_notefile(FILE * out, const char *filename, int nbtab)
+{
+ char path_to_notefile[BUFSIZ];
+ FILE *notefile;
+ char linestarter[BUFSIZ];
+ char buffer[BUFSIZ];
+ int i;
+ int printlinestarter = 1;
+
+ if (nbtab < BUFSIZ) {
+ for (i = 0; i < nbtab; i++)
+ linestarter[i] = '\t';
+ linestarter[nbtab] = '\0';
+ } else
+ linestarter[0] = '\0';
+
+ snprintf(path_to_notefile, BUFSIZ, "%s/%s", path_notes, filename);
+ notefile = fopen(path_to_notefile, "r");
+ if (notefile) {
+ while (fgets(buffer, BUFSIZ, notefile) != 0) {
+ if (printlinestarter) {
+ fputs(linestarter, out);
+ printlinestarter = 0;
+ }
+ fputs(buffer, out);
+ if (buffer[strlen(buffer) - 1] == '\n')
+ printlinestarter = 1;
+ }
+ fputs("\n", out);
+ file_close(notefile, __FILE_POS__);
+ } else {
+ fputs(linestarter, out);
+ fputs(_("No note file found\n"), out);
+ }
+}
+
+/* Print an escape sequence and return its length. */
+static int print_escape(const char *s)
+{
+ switch (*(s + 1)) {
+ case 'a':
+ putchar('\a');
+ return 1;
+ case 'b':
+ putchar('\b');
+ return 1;
+ case 'f':
+ putchar('\f');
+ return 1;
+ case 'n':
+ putchar('\n');
+ return 1;
+ case 'r':
+ putchar('\r');
+ return 1;
+ case 't':
+ putchar('\t');
+ return 1;
+ case 'v':
+ putchar('\v');
+ return 1;
+ case '0':
+ putchar('\0');
+ return 1;
+ case '\'':
+ putchar('\'');
+ return 1;
+ case '"':
+ putchar('"');
+ return 1;
+ case '\?':
+ putchar('?');
+ return 1;
+ case '\\':
+ putchar('\\');
+ return 1;
+ case '\0':
+ return 0;
+ default:
+ return 1;
+ }
+}
+
+/* Parse a format specifier. */
+static enum format_specifier parse_fs(const char **s, char *extformat)
+{
+ char buf[FS_EXT_MAXLEN];
+ int i;
+
+ extformat[0] = '\0';
+
+ switch (**s) {
+ case 's':
+ strcpy(extformat, "epoch");
+ return FS_STARTDATE;
+ case 'S':
+ return FS_STARTDATE;
+ case 'd':
+ return FS_DURATION;
+ case 'e':
+ strcpy(extformat, "epoch");
+ return FS_ENDDATE;
+ case 'E':
+ return FS_ENDDATE;
+ case 'm':
+ return FS_MESSAGE;
+ case 'n':
+ return FS_NOTE;
+ case 'N':
+ return FS_NOTEFILE;
+ case 'p':
+ return FS_PRIORITY;
+ case '(':
+ /* Long format specifier. */
+ for ((*s)++, i = 0; **s != ':' && **s != ')'; (*s)++, i++) {
+ if (**s == '\0')
+ return FS_EOF;
+
+ if (i < FS_EXT_MAXLEN)
+ buf[i] = **s;
+ }
+
+ buf[(i < FS_EXT_MAXLEN) ? i : FS_EXT_MAXLEN - 1] = '\0';
+
+ if (**s == ':') {
+ for ((*s)++, i = 0; **s != ')'; (*s)++, i++) {
+ if (**s == '\0')
+ return FS_EOF;
+
+ if (i < FS_EXT_MAXLEN)
+ extformat[i] = **s;
+ }
+
+ extformat[(i < FS_EXT_MAXLEN) ? i : FS_EXT_MAXLEN - 1] = '\0';
+ }
+
+ if (!strcmp(buf, "start"))
+ return FS_STARTDATE;
+ else if (!strcmp(buf, "duration"))
+ return FS_DURATION;
+ else if (!strcmp(buf, "end"))
+ return FS_ENDDATE;
+ else if (!strcmp(buf, "message"))
+ return FS_MESSAGE;
+ else if (!strcmp(buf, "noteid"))
+ return FS_NOTE;
+ else if (!strcmp(buf, "note"))
+ return FS_NOTEFILE;
+ else if (!strcmp(buf, "priority"))
+ return FS_PRIORITY;
+ else
+ return FS_UNKNOWN;
+ case '%':
+ return FS_PSIGN;
+ case '\0':
+ return FS_EOF;
+ default:
+ return FS_UNKNOWN;
+ }
+}
+
+/* Print a formatted date to stdout. */
+static void print_date(long date, long day, const char *extformat)
+{
+ char buf[BUFSIZ];
+
+ if (!strcmp(extformat, "epoch"))
+ printf("%ld", date);
+ else {
+ time_t t = date;
+ struct tm *lt = localtime((time_t *) & t);
+
+ if (extformat[0] == '\0' || !strcmp(extformat, "default")) {
+ if (date >= day && date <= day + DAYINSEC)
+ strftime(buf, BUFSIZ, "%H:%M", lt);
+ else
+ strftime(buf, BUFSIZ, "..:..", lt);
+ } else {
+ strftime(buf, BUFSIZ, extformat, lt);
+ }
+
+ printf("%s", buf);
+ }
+}
+
+/* Print a formatted appointment to stdout. */
+void print_apoint(const char *format, long day, struct apoint *apt)
+{
+ const char *p;
+ char extformat[FS_EXT_MAXLEN];
+
+ for (p = format; *p; p++) {
+ if (*p == '%') {
+ p++;
+ switch (parse_fs(&p, extformat)) {
+ case FS_STARTDATE:
+ print_date(apt->start, day, extformat);
+ break;
+ case FS_DURATION:
+ printf("%ld", apt->dur);
+ break;
+ case FS_ENDDATE:
+ print_date(apt->start + apt->dur, day, extformat);
+ break;
+ case FS_MESSAGE:
+ printf("%s", apt->mesg);
+ break;
+ case FS_NOTE:
+ printf("%s", apt->note);
+ break;
+ case FS_NOTEFILE:
+ print_notefile(stdout, apt->note, 1);
+ break;
+ case FS_PSIGN:
+ putchar('%');
+ break;
+ case FS_EOF:
+ return;
+ break;
+ default:
+ putchar('?');
+ break;
+ }
+ } else if (*p == '\\')
+ p += print_escape(p);
+ else
+ putchar(*p);
+ }
+}
+
+/* Print a formatted event to stdout. */
+void print_event(const char *format, long day, struct event *ev)
+{
+ const char *p;
+ char extformat[FS_EXT_MAXLEN];
+
+ for (p = format; *p; p++) {
+ if (*p == '%') {
+ p++;
+ switch (parse_fs(&p, extformat)) {
+ case FS_MESSAGE:
+ printf("%s", ev->mesg);
+ break;
+ case FS_NOTE:
+ printf("%s", ev->note);
+ break;
+ case FS_NOTEFILE:
+ print_notefile(stdout, ev->note, 1);
+ break;
+ case FS_PSIGN:
+ putchar('%');
+ break;
+ case FS_EOF:
+ return;
+ break;
+ default:
+ putchar('?');
+ break;
+ }
+ } else if (*p == '\\')
+ p += print_escape(p);
+ else
+ putchar(*p);
+ }
+}
+
+/* Print a formatted recurrent appointment to stdout. */
+void
+print_recur_apoint(const char *format, long day, unsigned occurrence,
+ struct recur_apoint *rapt)
+{
+ struct apoint apt;
+
+ apt.start = occurrence;
+ apt.dur = rapt->dur;
+ apt.mesg = rapt->mesg;
+ apt.note = rapt->note;
+
+ print_apoint(format, day, &apt);
+}
+
+/* Print a formatted recurrent event to stdout. */
+void print_recur_event(const char *format, long day, struct recur_event *rev)
+{
+ struct event ev;
+
+ ev.mesg = rev->mesg;
+ ev.note = rev->note;
+
+ print_event(format, day, &ev);
+}
+
+/* Print a formatted todo item to stdout. */
+void print_todo(const char *format, struct todo *todo)
+{
+ const char *p;
+ char extformat[FS_EXT_MAXLEN];
+
+ for (p = format; *p; p++) {
+ if (*p == '%') {
+ p++;
+ switch (parse_fs(&p, extformat)) {
+ case FS_PRIORITY:
+ printf("%d", abs(todo->id));
+ break;
+ case FS_MESSAGE:
+ printf("%s", todo->mesg);
+ break;
+ case FS_NOTE:
+ printf("%s", todo->note);
+ break;
+ case FS_NOTEFILE:
+ print_notefile(stdout, todo->note, 1);
+ break;
+ case FS_PSIGN:
+ putchar('%');
+ break;
+ case FS_EOF:
+ return;
+ break;
+ default:
+ putchar('?');
+ break;
+ }
+ } else if (*p == '\\')
+ p += print_escape(p);
+ else
+ putchar(*p);
+ }
}
diff --git a/src/vars.c b/src/vars.c
index 84f8b08..dd4cfbc 100644
--- a/src/vars.c
+++ b/src/vars.c
@@ -1,7 +1,7 @@
/*
* Calcurse - text-based organizer
*
- * Copyright (c) 2004-2011 calcurse Development Team <misc@calcurse.org>
+ * Copyright (c) 2004-2012 calcurse Development Team <misc@calcurse.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -48,6 +48,9 @@ int resize = 0;
/* variable to tell if the terminal supports color */
unsigned colorize = 0;
+/* Default background and foreground colors. */
+int foreground, background;
+
/*
* To tell if curses interface was launched already or not (in that case
* calcurse is running in command-line mode).
@@ -55,11 +58,15 @@ unsigned colorize = 0;
*/
enum ui_mode ui_mode = UI_CMDLINE;
+/* Don't save anything if this is set. */
+int read_only = 0;
+
/*
* variables to store calendar names
*/
int days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
-char *monthnames[12] = {
+
+const char *monthnames[12] = {
N_("January"),
N_("February"),
N_("March"),
@@ -74,7 +81,7 @@ char *monthnames[12] = {
N_("December")
};
-char *daynames[8] = {
+const char *daynames[8] = {
N_("Sun"),
N_("Mon"),
N_("Tue"),
@@ -99,6 +106,9 @@ char path_cpid[] = "";
char path_dpid[] = "";
char path_dmon_log[] = "";
+/* Variable to store global configuration. */
+struct conf conf;
+
/* Variable to handle pads. */
struct pad apad;
@@ -111,45 +121,45 @@ struct dmon_conf dmon;
/*
* Variables init
*/
-void
-vars_init (struct conf *conf)
+void vars_init(void)
{
- char *ed, *pg;
+ const char *ed, *pg;
/* Variables for user configuration */
- conf->confirm_quit = 1;
- conf->confirm_delete = 1;
- conf->auto_save = 1;
- conf->periodic_save = 0;
- conf->skip_system_dialogs = 0;
- conf->skip_progress_bar = 0;
- (void)strncpy (conf->output_datefmt, "%D", 3);
- conf->input_datefmt = 1;
+ conf.confirm_quit = 1;
+ conf.confirm_delete = 1;
+ conf.auto_save = 1;
+ conf.auto_gc = 0;
+ conf.periodic_save = 0;
+ conf.system_dialogs = 1;
+ conf.progress_bar = 1;
+ strncpy(conf.output_datefmt, "%D", 3);
+ conf.input_datefmt = 1;
/* Default external editor and pager */
- ed = getenv ("VISUAL");
+ ed = getenv("VISUAL");
if (ed == NULL || ed[0] == '\0')
- ed = getenv ("EDITOR");
+ ed = getenv("EDITOR");
if (ed == NULL || ed[0] == '\0')
ed = DEFAULT_EDITOR;
- conf->editor = ed;
+ conf.editor = ed;
- pg = getenv ("PAGER");
+ pg = getenv("PAGER");
if (pg == NULL || pg[0] == '\0')
pg = DEFAULT_PAGER;
- conf->pager = pg;
+ conf.pager = pg;
- wins_set_layout (1);
+ wins_set_layout(1);
- calendar_set_first_day_of_week (MONDAY);
+ calendar_set_first_day_of_week(MONDAY);
/* Pad structure to scroll text inside the appointment panel */
apad.length = 1;
apad.first_onscreen = 0;
/* Attribute definitions for color and non-color terminals */
- custom_init_attr ();
+ custom_init_attr();
/* Start at the current date */
- calendar_init_slctd_day ();
+ calendar_init_slctd_day();
}
diff --git a/src/wins.c b/src/wins.c
index 7b7384b..b45ad6c 100644
--- a/src/wins.c
+++ b/src/wins.c
@@ -1,7 +1,7 @@
/*
* Calcurse - text-based organizer
*
- * Copyright (c) 2004-2011 calcurse Development Team <misc@calcurse.org>
+ * Copyright (c) 2004-2012 calcurse Development Team <misc@calcurse.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -44,7 +44,7 @@
struct window win[NBWINS];
/* User-configurable side bar width. */
-static unsigned sbarwidth;
+static unsigned sbarwidth_perc;
static enum win slctd_win;
static int layout;
@@ -63,93 +63,85 @@ static int layout;
*/
static pthread_mutex_t screen_mutex = PTHREAD_MUTEX_INITIALIZER;
-static unsigned
-screen_acquire (void)
+static unsigned screen_acquire(void)
{
- if (pthread_mutex_lock (&screen_mutex) != 0)
+ if (pthread_mutex_lock(&screen_mutex) != 0)
return 0;
else
return 1;
}
-static void
-screen_release (void)
+static void screen_release(void)
{
- (void)pthread_mutex_unlock (&screen_mutex);
+ pthread_mutex_unlock(&screen_mutex);
}
-int
-wins_refresh (void)
+int wins_refresh(void)
{
int rc;
- if (!screen_acquire ())
+ if (!screen_acquire())
return ERR;
- rc = refresh ();
- screen_release ();
+ rc = refresh();
+ screen_release();
return rc;
}
-int
-wins_wrefresh (WINDOW *win)
+int wins_wrefresh(WINDOW * win)
{
int rc;
- if (!win || !screen_acquire ())
+ if (!win || !screen_acquire())
return ERR;
- rc = wrefresh (win);
- screen_release ();
+ rc = wrefresh(win);
+ screen_release();
return rc;
}
-int
-wins_doupdate (void)
+int wins_doupdate(void)
{
int rc;
- if (!screen_acquire ())
+ if (!screen_acquire())
return ERR;
- rc = doupdate ();
- screen_release ();
+ rc = doupdate();
+ screen_release();
return rc;
}
/* Get the current layout. */
-int
-wins_layout (void)
+int wins_layout(void)
{
return layout;
}
/* Set the current layout. */
-void
-wins_set_layout (int nb)
+void wins_set_layout(int nb)
{
layout = nb;
}
/* Get the current side bar width. */
-unsigned
-wins_sbar_width (void)
+unsigned wins_sbar_width(void)
{
- return sbarwidth ? sbarwidth : SBARMINWIDTH;
+ if (sbarwidth_perc > SBARMAXWIDTHPERC)
+ return col * SBARMAXWIDTHPERC / 100;
+ else {
+ unsigned sbarwidth = (unsigned)(col * sbarwidth_perc / 100);
+ return (sbarwidth < SBARMINWIDTH) ? SBARMINWIDTH : sbarwidth;
+ }
}
/*
* Return the side bar width in percentage of the total number of columns
* available in calcurse's screen.
*/
-unsigned
-wins_sbar_wperc (void)
+unsigned wins_sbar_wperc(void)
{
- unsigned perc;
-
- perc = col ? (unsigned)(100 * sbarwidth / col + 1): 0;
-
- return perc > SBARMAXWIDTHPERC ? SBARMAXWIDTHPERC : perc;
+ return sbarwidth_perc > SBARMAXWIDTHPERC ? SBARMAXWIDTHPERC : sbarwidth_perc;
}
/*
@@ -158,62 +150,44 @@ wins_sbar_wperc (void)
* The side bar could not have a width representing more than 50% of the screen,
* and could not be less than SBARMINWIDTH characters.
*/
-void
-wins_set_sbar_width (unsigned perc)
+void wins_set_sbar_width(unsigned perc)
{
- if (perc > SBARMAXWIDTHPERC)
- sbarwidth = col * SBARMAXWIDTHPERC / 100;
- else if (perc <= 0)
- sbarwidth = SBARMINWIDTH;
- else
- {
- sbarwidth = (unsigned)(col * perc / 100);
- if (sbarwidth < SBARMINWIDTH)
- sbarwidth = SBARMINWIDTH;
- }
+ sbarwidth_perc = perc;
}
/* Change the width of the side bar within acceptable boundaries. */
-void
-wins_sbar_winc (void)
+void wins_sbar_winc(void)
{
- if (sbarwidth < SBARMINWIDTH)
- sbarwidth = SBARMINWIDTH + 1;
- else if (sbarwidth < SBARMAXWIDTHPERC * col / 100)
- sbarwidth++;
+ if (sbarwidth_perc < SBARMAXWIDTHPERC)
+ sbarwidth_perc++;
}
-void
-wins_sbar_wdec (void)
+void wins_sbar_wdec(void)
{
- if (sbarwidth > SBARMINWIDTH)
- sbarwidth--;
+ if (sbarwidth_perc > 0)
+ sbarwidth_perc--;
}
/* Initialize the selected window in calcurse's interface. */
-void
-wins_slctd_init (void)
+void wins_slctd_init(void)
{
- wins_slctd_set (CAL);
+ wins_slctd_set(CAL);
}
/* Returns an enum which corresponds to the window which is selected. */
-enum win
-wins_slctd (void)
+enum win wins_slctd(void)
{
- return (slctd_win);
+ return slctd_win;
}
/* Sets the selected window. */
-void
-wins_slctd_set (enum win window)
+void wins_slctd_set(enum win window)
{
slctd_win = window;
}
/* TAB key was hit in the interface, need to select next window. */
-void
-wins_slctd_next (void)
+void wins_slctd_next(void)
{
if (slctd_win == TOD)
slctd_win = CAL;
@@ -221,39 +195,32 @@ wins_slctd_next (void)
slctd_win++;
}
-static void
-wins_init_panels (void)
+static void wins_init_panels(void)
{
- char label[BUFSIZ];
-
- win[CAL].p = newwin (CALHEIGHT, wins_sbar_width (), win[CAL].y, win[CAL].x);
- (void)snprintf (label, BUFSIZ, _("Calendar"));
- wins_show (win[CAL].p, label);
+ win[CAL].p = newwin(CALHEIGHT, wins_sbar_width(), win[CAL].y, win[CAL].x);
+ wins_show(win[CAL].p, _("Calendar"));
- win[APP].p = newwin (win[APP].h, win[APP].w, win[APP].y, win[APP].x);
- (void)snprintf (label, BUFSIZ, _("Appointments"));
- wins_show (win[APP].p, label);
+ win[APP].p = newwin(win[APP].h, win[APP].w, win[APP].y, win[APP].x);
+ wins_show(win[APP].p, _("Appointments"));
apad.width = win[APP].w - 3;
- apad.ptrwin = newpad (apad.length, apad.width);
+ apad.ptrwin = newpad(apad.length, apad.width);
- win[TOD].p = newwin (win[TOD].h, win[TOD].w, win[TOD].y, win[TOD].x);
- (void)snprintf (label, BUFSIZ, _("ToDo"));
- wins_show (win[TOD].p, label);
+ win[TOD].p = newwin(win[TOD].h, win[TOD].w, win[TOD].y, win[TOD].x);
+ wins_show(win[TOD].p, _("ToDo"));
/* Enable function keys (i.e. arrow keys) in those windows */
- keypad (win[CAL].p, TRUE);
- keypad (win[APP].p, TRUE);
- keypad (win[TOD].p, TRUE);
+ keypad(win[CAL].p, TRUE);
+ keypad(win[APP].p, TRUE);
+ keypad(win[TOD].p, TRUE);
}
/* Create all the windows. */
-void
-wins_init (void)
+void wins_init(void)
{
- wins_init_panels ();
- win[STA].p = newwin (win[STA].h, win[STA].w, win[STA].y, win[STA].x);
+ wins_init_panels();
+ win[STA].p = newwin(win[STA].h, win[STA].w, win[STA].y, win[STA].x);
- keypad (win[STA].p, TRUE);
+ keypad(win[STA].p, TRUE);
/* Notify that the curses mode is now launched. */
ui_mode = UI_CURSES;
@@ -263,116 +230,105 @@ wins_init (void)
* Create a new window and its associated pad, which is used to make the
* scrolling faster.
*/
-void
-wins_scrollwin_init (struct scrollwin *sw)
+void wins_scrollwin_init(struct scrollwin *sw)
{
- EXIT_IF (sw == NULL, "null pointer");
- sw->win.p = newwin (sw->win.h, sw->win.w, sw->win.y, sw->win.x);
- sw->pad.p = newpad (sw->pad.h, sw->pad.w);
+ EXIT_IF(sw == NULL, "null pointer");
+ sw->win.p = newwin(sw->win.h, sw->win.w, sw->win.y, sw->win.x);
+ sw->pad.p = newpad(sw->pad.h, sw->pad.w);
sw->first_visible_line = 0;
sw->total_lines = 0;
}
/* Free an already created scrollwin. */
-void
-wins_scrollwin_delete (struct scrollwin *sw)
+void wins_scrollwin_delete(struct scrollwin *sw)
{
- EXIT_IF (sw == NULL, "null pointer");
+ EXIT_IF(sw == NULL, "null pointer");
delwin(sw->win.p);
delwin(sw->pad.p);
}
/* Display a scrolling window. */
-void
-wins_scrollwin_display (struct scrollwin *sw)
+void wins_scrollwin_display(struct scrollwin *sw)
{
const int visible_lines = sw->win.h - sw->pad.y - 1;
- if (sw->total_lines > visible_lines)
- {
- float ratio = ((float) visible_lines) / ((float) sw->total_lines);
- int sbar_length = (int) (ratio * visible_lines);
- int highend = (int) (ratio * sw->first_visible_line);
- int sbar_top = highend + sw->pad.y + 1;
+ if (sw->total_lines > visible_lines) {
+ float ratio = ((float)visible_lines) / ((float)sw->total_lines);
+ int sbar_length = (int)(ratio * visible_lines);
+ int highend = (int)(ratio * sw->first_visible_line);
+ int sbar_top = highend + sw->pad.y + 1;
- if ((sbar_top + sbar_length) > sw->win.h - 1)
- sbar_length = sw->win.h - sbar_top;
- draw_scrollbar (sw->win.p, sbar_top, sw->win.w + sw->win.x - 2,
- sbar_length, sw->pad.y + 1, sw->win.h - 1, 1);
- }
- wmove (win[STA].p, 0, 0);
- wnoutrefresh (sw->win.p);
- pnoutrefresh (sw->pad.p, sw->first_visible_line, 0, sw->pad.y, sw->pad.x,
- sw->win.h - sw->pad.y + 1, sw->win.w - sw->win.x);
- wins_doupdate ();
+ if ((sbar_top + sbar_length) > sw->win.h - 1)
+ sbar_length = sw->win.h - sbar_top;
+ draw_scrollbar(sw->win.p, sbar_top, sw->win.w + sw->win.x - 2,
+ sbar_length, sw->pad.y + 1, sw->win.h - 1, 1);
+ }
+ wmove(win[STA].p, 0, 0);
+ wnoutrefresh(sw->win.p);
+ pnoutrefresh(sw->pad.p, sw->first_visible_line, 0, sw->pad.y, sw->pad.x,
+ sw->win.h - sw->pad.y + 1, sw->win.w - sw->win.x);
+ wins_doupdate();
}
-void
-wins_scrollwin_up (struct scrollwin *sw, int amount)
+void wins_scrollwin_up(struct scrollwin *sw, int amount)
{
if (sw->first_visible_line > 0)
sw->first_visible_line -= amount;
}
-void
-wins_scrollwin_down (struct scrollwin *sw, int amount)
+void wins_scrollwin_down(struct scrollwin *sw, int amount)
{
- if (sw->total_lines
- > (sw->first_visible_line + sw->win.h - sw->pad.y - 1))
+ if (sw->total_lines > (sw->first_visible_line + sw->win.h - sw->pad.y - 1))
sw->first_visible_line += amount;
}
-void
-wins_reinit_panels (void)
+void wins_reinit_panels(void)
{
- delwin (win[CAL].p);
- delwin (win[APP].p);
- delwin (apad.ptrwin);
- delwin (win[TOD].p);
- wins_get_config ();
- wins_init_panels ();
+ delwin(win[CAL].p);
+ delwin(win[APP].p);
+ delwin(apad.ptrwin);
+ delwin(win[TOD].p);
+ wins_get_config();
+ wins_init_panels();
}
/*
* Delete the existing windows and recreate them with their new
* size and placement.
*/
-void
-wins_reinit (void)
+void wins_reinit(void)
{
- delwin (win[CAL].p);
- delwin (win[APP].p);
- delwin (apad.ptrwin);
- delwin (win[TOD].p);
- delwin (win[STA].p);
- wins_get_config ();
- wins_init ();
- if (notify_bar ())
- notify_reinit_bar ();
+ delwin(win[CAL].p);
+ delwin(win[APP].p);
+ delwin(apad.ptrwin);
+ delwin(win[TOD].p);
+ delwin(win[STA].p);
+ wins_get_config();
+ wins_init();
+ if (notify_bar())
+ notify_reinit_bar();
}
/* Show the window with a border and a label. */
-void
-wins_show (WINDOW *win, char *label)
+void wins_show(WINDOW * win, const char *label)
{
- int width = getmaxx (win);
+ int width = getmaxx(win);
- box (win, 0, 0);
- mvwaddch (win, 2, 0, ACS_LTEE);
- mvwhline (win, 2, 1, ACS_HLINE, width - 2);
- mvwaddch (win, 2, width - 1, ACS_RTEE);
+ box(win, 0, 0);
+ mvwaddch(win, 2, 0, ACS_LTEE);
+ mvwhline(win, 2, 1, ACS_HLINE, width - 2);
+ mvwaddch(win, 2, width - 1, ACS_RTEE);
- print_in_middle (win, 1, 0, width, label);
+ print_in_middle(win, 1, 0, width, label);
}
/*
* Get the screen size and recalculate the windows configurations.
*/
-void
-wins_get_config (void)
+void wins_get_config(void)
{
/* Get the screen configuration */
- getmaxyx (stdscr, row, col);
+ getmaxyx(stdscr, row, col);
/* fixed values for status, notification bars and calendar */
win[STA].h = STATUSHEIGHT;
@@ -380,267 +336,243 @@ wins_get_config (void)
win[STA].y = row - win[STA].h;
win[STA].x = 0;
- if (notify_bar ())
- {
- win[NOT].h = 1;
- win[NOT].w = col;
- win[NOT].y = win[STA].y - 1;
- win[NOT].x = 0;
- }
- else
- {
- win[NOT].h = 0;
- win[NOT].w = 0;
- win[NOT].y = 0;
- win[NOT].x = 0;
- }
-
- win[CAL].w = wins_sbar_width ();
+ if (notify_bar()) {
+ win[NOT].h = 1;
+ win[NOT].w = col;
+ win[NOT].y = win[STA].y - 1;
+ win[NOT].x = 0;
+ } else {
+ win[NOT].h = 0;
+ win[NOT].w = 0;
+ win[NOT].y = 0;
+ win[NOT].x = 0;
+ }
+
+ win[CAL].w = wins_sbar_width();
win[CAL].h = CALHEIGHT;
- if (layout <= 4)
- { /* APPOINTMENT is the biggest panel */
- win[APP].w = col - win[CAL].w;
- win[APP].h = row - (win[STA].h + win[NOT].h);
- win[TOD].w = win[CAL].w;
- win[TOD].h = row - (win[CAL].h + win[STA].h + win[NOT].h);
- }
- else
- { /* TODO is the biggest panel */
- win[TOD].w = col - win[CAL].w;
- win[TOD].h = row - (win[STA].h + win[NOT].h);
- win[APP].w = win[CAL].w;
- win[APP].h = row - (win[CAL].h + win[STA].h + win[NOT].h);
- }
+ if (layout <= 4) { /* APPOINTMENT is the biggest panel */
+ win[APP].w = col - win[CAL].w;
+ win[APP].h = row - (win[STA].h + win[NOT].h);
+ win[TOD].w = win[CAL].w;
+ win[TOD].h = row - (win[CAL].h + win[STA].h + win[NOT].h);
+ } else { /* TODO is the biggest panel */
+ win[TOD].w = col - win[CAL].w;
+ win[TOD].h = row - (win[STA].h + win[NOT].h);
+ win[APP].w = win[CAL].w;
+ win[APP].h = row - (win[CAL].h + win[STA].h + win[NOT].h);
+ }
/* defining the layout */
- switch (layout)
- {
- case 1:
- win[APP].y = 0;
- win[APP].x = 0;
- win[CAL].y = 0;
- win[TOD].x = win[APP].w;
- win[TOD].y = win[CAL].h;
- win[CAL].x = win[APP].w;
- break;
- case 2:
- win[APP].y = 0;
- win[APP].x = 0;
- win[TOD].y = 0;
- win[TOD].x = win[APP].w;
- win[CAL].x = win[APP].w;
- win[CAL].y = win[TOD].h;
- break;
- case 3:
- win[APP].y = 0;
- win[TOD].x = 0;
- win[CAL].x = 0;
- win[CAL].y = 0;
- win[APP].x = win[CAL].w;
- win[TOD].y = win[CAL].h;
- break;
- case 4:
- win[APP].y = 0;
- win[TOD].x = 0;
- win[TOD].y = 0;
- win[CAL].x = 0;
- win[APP].x = win[CAL].w;
- win[CAL].y = win[TOD].h;
- break;
- case 5:
- win[TOD].y = 0;
- win[TOD].x = 0;
- win[CAL].y = 0;
- win[APP].y = win[CAL].h;
- win[APP].x = win[TOD].w;
- win[CAL].x = win[TOD].w;
- break;
- case 6:
- win[TOD].y = 0;
- win[TOD].x = 0;
- win[APP].y = 0;
- win[APP].x = win[TOD].w;
- win[CAL].x = win[TOD].w;
- win[CAL].y = win[APP].h;
- break;
- case 7:
- win[TOD].y = 0;
- win[APP].x = 0;
- win[CAL].x = 0;
- win[CAL].y = 0;
- win[TOD].x = win[CAL].w;
- win[APP].y = win[CAL].h;
- break;
- case 8:
- win[TOD].y = 0;
- win[APP].x = 0;
- win[CAL].x = 0;
- win[APP].y = 0;
- win[TOD].x = win[CAL].w;
- win[CAL].y = win[APP].h;
- break;
- }
+ switch (layout) {
+ case 1:
+ win[APP].y = 0;
+ win[APP].x = 0;
+ win[CAL].y = 0;
+ win[TOD].x = win[APP].w;
+ win[TOD].y = win[CAL].h;
+ win[CAL].x = win[APP].w;
+ break;
+ case 2:
+ win[APP].y = 0;
+ win[APP].x = 0;
+ win[TOD].y = 0;
+ win[TOD].x = win[APP].w;
+ win[CAL].x = win[APP].w;
+ win[CAL].y = win[TOD].h;
+ break;
+ case 3:
+ win[APP].y = 0;
+ win[TOD].x = 0;
+ win[CAL].x = 0;
+ win[CAL].y = 0;
+ win[APP].x = win[CAL].w;
+ win[TOD].y = win[CAL].h;
+ break;
+ case 4:
+ win[APP].y = 0;
+ win[TOD].x = 0;
+ win[TOD].y = 0;
+ win[CAL].x = 0;
+ win[APP].x = win[CAL].w;
+ win[CAL].y = win[TOD].h;
+ break;
+ case 5:
+ win[TOD].y = 0;
+ win[TOD].x = 0;
+ win[CAL].y = 0;
+ win[APP].y = win[CAL].h;
+ win[APP].x = win[TOD].w;
+ win[CAL].x = win[TOD].w;
+ break;
+ case 6:
+ win[TOD].y = 0;
+ win[TOD].x = 0;
+ win[APP].y = 0;
+ win[APP].x = win[TOD].w;
+ win[CAL].x = win[TOD].w;
+ win[CAL].y = win[APP].h;
+ break;
+ case 7:
+ win[TOD].y = 0;
+ win[APP].x = 0;
+ win[CAL].x = 0;
+ win[CAL].y = 0;
+ win[TOD].x = win[CAL].w;
+ win[APP].y = win[CAL].h;
+ break;
+ case 8:
+ win[TOD].y = 0;
+ win[APP].x = 0;
+ win[CAL].x = 0;
+ win[APP].y = 0;
+ win[TOD].x = win[CAL].w;
+ win[CAL].y = win[APP].h;
+ break;
+ }
}
/* draw panel border in color */
-static void
-border_color (WINDOW *window)
+static void border_color(WINDOW * window)
{
int color_attr = A_BOLD;
int no_color_attr = A_BOLD;
- if (colorize)
- {
- wattron (window, color_attr | COLOR_PAIR (COLR_CUSTOM));
- box (window, 0, 0);
- }
- else
- {
- wattron (window, no_color_attr);
- box (window, 0, 0);
- }
- if (colorize)
- {
- wattroff (window, color_attr | COLOR_PAIR (COLR_CUSTOM));
- }
- else
- {
- wattroff (window, no_color_attr);
- }
- wnoutrefresh (window);
+ if (colorize) {
+ wattron(window, color_attr | COLOR_PAIR(COLR_CUSTOM));
+ box(window, 0, 0);
+ } else {
+ wattron(window, no_color_attr);
+ box(window, 0, 0);
+ }
+ if (colorize) {
+ wattroff(window, color_attr | COLOR_PAIR(COLR_CUSTOM));
+ } else {
+ wattroff(window, no_color_attr);
+ }
+ wnoutrefresh(window);
}
/* draw panel border without any color */
-static void
-border_nocolor (WINDOW *window)
+static void border_nocolor(WINDOW * window)
{
int color_attr = A_BOLD;
int no_color_attr = A_DIM;
- if (colorize)
- {
- wattron (window, color_attr | COLOR_PAIR (COLR_DEFAULT));
- }
- else
- {
- wattron (window, no_color_attr);
- }
- box (window, 0, 0);
- if (colorize)
- {
- wattroff (window, color_attr | COLOR_PAIR (COLR_DEFAULT));
- }
- else
- {
- wattroff (window, no_color_attr);
- }
- wnoutrefresh (window);
-}
-
-void
-wins_update_border (void)
-{
- switch (slctd_win)
- {
- case CAL:
- border_color (win[CAL].p);
- border_nocolor (win[APP].p);
- border_nocolor (win[TOD].p);
- break;
- case APP:
- border_color (win[APP].p);
- border_nocolor (win[CAL].p);
- border_nocolor (win[TOD].p);
- break;
- case TOD:
- border_color (win[TOD].p);
- border_nocolor (win[APP].p);
- border_nocolor (win[CAL].p);
- break;
- default:
- EXIT (_("no window selected"));
- /* NOTREACHED */
- }
-}
-
-void
-wins_update_panels (void)
-{
- apoint_update_panel (slctd_win);
- todo_update_panel (slctd_win);
- calendar_update_panel (&win[CAL]);
+ if (colorize) {
+ wattron(window, color_attr | COLOR_PAIR(COLR_DEFAULT));
+ } else {
+ wattron(window, no_color_attr);
+ }
+ box(window, 0, 0);
+ if (colorize) {
+ wattroff(window, color_attr | COLOR_PAIR(COLR_DEFAULT));
+ } else {
+ wattroff(window, no_color_attr);
+ }
+ wnoutrefresh(window);
+}
+
+void wins_update_border(int flags)
+{
+ if (flags & FLAG_CAL) {
+ if (slctd_win == CAL)
+ border_color(win[CAL].p);
+ else
+ border_nocolor(win[CAL].p);
+ }
+ if (flags & FLAG_APP) {
+ if (slctd_win == APP)
+ border_color(win[APP].p);
+ else
+ border_nocolor(win[APP].p);
+ }
+ if (flags & FLAG_TOD) {
+ if (slctd_win == TOD)
+ border_color(win[TOD].p);
+ else
+ border_nocolor(win[TOD].p);
+ }
+}
+
+void wins_update_panels(int flags)
+{
+ if (flags & FLAG_APP)
+ apoint_update_panel(slctd_win);
+ if (flags & FLAG_TOD)
+ todo_update_panel(slctd_win);
+ if (flags & FLAG_CAL)
+ calendar_update_panel(&win[CAL]);
}
/*
* Update all of the three windows and put a border around the
* selected window.
*/
-void
-wins_update (void)
+void wins_update(int flags)
{
- wins_update_border ();
- wins_update_panels ();
- wins_status_bar ();
- if (notify_bar ())
- notify_update_bar ();
- wmove (win[STA].p, 0, 0);
- wins_doupdate ();
+ wins_update_border(flags);
+ wins_update_panels(flags);
+ if (flags & FLAG_STA)
+ wins_status_bar();
+ if ((flags & FLAG_NOT) && notify_bar())
+ notify_update_bar();
+ wmove(win[STA].p, 0, 0);
+ wins_doupdate();
}
/* Reset the screen, needed when resizing terminal for example. */
-void
-wins_reset (void)
+void wins_reset(void)
{
- endwin ();
- wins_refresh ();
- curs_set (0);
- wins_reinit ();
- wins_update ();
+ endwin();
+ wins_refresh();
+ curs_set(0);
+ wins_reinit();
+ wins_update(FLAG_ALL);
+}
+
+/* Prepare windows for the execution of an external command. */
+void wins_prepare_external(void)
+{
+ if (notify_bar())
+ notify_stop_main_thread();
+ def_prog_mode();
+ ui_mode = UI_CMDLINE;
+ clear();
+ wins_refresh();
+ endwin();
+}
+
+/* Restore windows when returning from an external command. */
+void wins_unprepare_external(void)
+{
+ reset_prog_mode();
+ clearok(curscr, TRUE);
+ curs_set(0);
+ ui_mode = UI_CURSES;
+ wins_refresh();
+ if (notify_bar())
+ notify_start_main_thread();
}
/*
* While inside interactive mode, launch the external command cmd on the given
* file.
*/
-void
-wins_launch_external (const char *file, const char *cmd)
-{
- char *p;
- int len;
-
- /* Beware of space between cmd and file. */
- len = strlen (file) + strlen (cmd) + 2;
-
- p = (char *) mem_calloc (len, sizeof (char));
- if (snprintf (p, len, "%s %s", cmd, file) == -1)
- {
- mem_free (p);
- return;
- }
- if (notify_bar ())
- notify_stop_main_thread ();
- def_prog_mode ();
- endwin ();
- ui_mode = UI_CMDLINE;
- clear ();
- wins_refresh ();
- (void)system (p);
- reset_prog_mode ();
- clearok (curscr, TRUE);
- curs_set (0);
- ui_mode = UI_CURSES;
- wins_refresh ();
- if (notify_bar ())
- notify_start_main_thread ();
- mem_free (p);
+void wins_launch_external(const char *file, const char *cmd)
+{
+ const char *arg[] = { cmd, file, NULL };
+ int pid;
+
+ wins_prepare_external();
+ if ((pid = shell_exec(NULL, NULL, *arg, arg)))
+ child_wait(NULL, NULL, pid);
+ wins_unprepare_external();
}
-#define NB_CAL_CMDS 27 /* number of commands while in cal view */
-#define NB_APP_CMDS 31 /* same thing while in appointment view */
-#define NB_TOD_CMDS 30 /* same thing while in todo view */
-#define TOTAL_CMDS NB_CAL_CMDS + NB_APP_CMDS + NB_TOD_CMDS
-#define CMDS_PER_LINE 6 /* max number of commands per line */
+#define NB_CAL_CMDS 27 /* number of commands while in cal view */
+#define NB_APP_CMDS 32 /* same thing while in appointment view */
+#define NB_TOD_CMDS 31 /* same thing while in todo view */
static unsigned status_page;
@@ -650,114 +582,124 @@ static unsigned status_page;
* table, and update the NB_CAL_CMDS, NB_APP_CMDS or NB_TOD_CMDS defines,
* depending on which panel the added keybind is assigned to.
*/
-void
-wins_status_bar (void)
-{
-#define NB_PANELS 3 /* 3 panels: CALENDAR, APPOINTMENT, TODO */
- enum win which_pan;
- int start, end;
- const int pos[NB_PANELS + 1] =
- { 0, NB_CAL_CMDS, NB_CAL_CMDS + NB_APP_CMDS, TOTAL_CMDS };
-
- struct binding help = {_("Help"), KEY_GENERIC_HELP};
- struct binding quit = {_("Quit"), KEY_GENERIC_QUIT};
- struct binding save = {_("Save"), KEY_GENERIC_SAVE};
- struct binding cut = {_("Cut"), KEY_GENERIC_CUT};
- struct binding paste = {_("Paste"), KEY_GENERIC_PASTE};
- struct binding chgvu = {_("Chg Win"), KEY_GENERIC_CHANGE_VIEW};
- struct binding import = {_("Import"), KEY_GENERIC_IMPORT};
- struct binding export = {_("Export"), KEY_GENERIC_EXPORT};
- struct binding togo = {_("Go to"), KEY_GENERIC_GOTO};
- struct binding othr = {_("OtherCmd"), KEY_GENERIC_OTHER_CMD};
- struct binding conf = {_("Config"), KEY_GENERIC_CONFIG_MENU};
- struct binding draw = {_("Redraw"), KEY_GENERIC_REDRAW};
- struct binding appt = {_("Add Appt"), KEY_GENERIC_ADD_APPT};
- struct binding todo = {_("Add Todo"), KEY_GENERIC_ADD_TODO};
- struct binding gnday = {_("+1 Day"), KEY_GENERIC_NEXT_DAY};
- struct binding gpday = {_("-1 Day"), KEY_GENERIC_PREV_DAY};
- struct binding gnweek = {_("+1 Week"), KEY_GENERIC_NEXT_WEEK};
- struct binding gpweek = {_("-1 Week"), KEY_GENERIC_PREV_WEEK};
- struct binding today = {_("Today"), KEY_GENERIC_GOTO_TODAY};
- struct binding nview = {_("Nxt View"), KEY_GENERIC_SCROLL_DOWN};
- struct binding pview = {_("Prv View"), KEY_GENERIC_SCROLL_UP};
- struct binding up = {_("Up"), KEY_MOVE_UP};
- struct binding down = {_("Down"), KEY_MOVE_DOWN};
- struct binding left = {_("Left"), KEY_MOVE_LEFT};
- struct binding right = {_("Right"), KEY_MOVE_RIGHT};
- struct binding weekb = {_("beg Week"), KEY_START_OF_WEEK};
- struct binding weeke = {_("end Week"), KEY_END_OF_WEEK};
- struct binding add = {_("Add Item"), KEY_ADD_ITEM};
- struct binding del = {_("Del Item"), KEY_DEL_ITEM};
- struct binding edit = {_("Edit Itm"), KEY_EDIT_ITEM};
- struct binding view = {_("View"), KEY_VIEW_ITEM};
- struct binding flag = {_("Flag Itm"), KEY_FLAG_ITEM};
- struct binding rept = {_("Repeat"), KEY_REPEAT_ITEM};
- struct binding enote = {_("EditNote"), KEY_EDIT_NOTE};
- struct binding vnote = {_("ViewNote"), KEY_VIEW_NOTE};
- struct binding rprio = {_("Prio.+"), KEY_RAISE_PRIORITY};
- struct binding lprio = {_("Prio.-"), KEY_LOWER_PRIORITY};
-
- struct binding *binding[TOTAL_CMDS] = {
- /* calendar keys */
+void wins_status_bar(void)
+{
+ struct binding help = { _("Help"), KEY_GENERIC_HELP };
+ struct binding quit = { _("Quit"), KEY_GENERIC_QUIT };
+ struct binding save = { _("Save"), KEY_GENERIC_SAVE };
+ struct binding cut = { _("Cut"), KEY_GENERIC_CUT };
+ struct binding paste = { _("Paste"), KEY_GENERIC_PASTE };
+ struct binding chgvu = { _("Chg Win"), KEY_GENERIC_CHANGE_VIEW };
+ struct binding import = { _("Import"), KEY_GENERIC_IMPORT };
+ struct binding export = { _("Export"), KEY_GENERIC_EXPORT };
+ struct binding togo = { _("Go to"), KEY_GENERIC_GOTO };
+ struct binding conf = { _("Config"), KEY_GENERIC_CONFIG_MENU };
+ struct binding draw = { _("Redraw"), KEY_GENERIC_REDRAW };
+ struct binding appt = { _("Add Appt"), KEY_GENERIC_ADD_APPT };
+ struct binding todo = { _("Add Todo"), KEY_GENERIC_ADD_TODO };
+ struct binding gnday = { _("+1 Day"), KEY_GENERIC_NEXT_DAY };
+ struct binding gpday = { _("-1 Day"), KEY_GENERIC_PREV_DAY };
+ struct binding gnweek = { _("+1 Week"), KEY_GENERIC_NEXT_WEEK };
+ struct binding gpweek = { _("-1 Week"), KEY_GENERIC_PREV_WEEK };
+ struct binding today = { _("Today"), KEY_GENERIC_GOTO_TODAY };
+ struct binding nview = { _("Nxt View"), KEY_GENERIC_SCROLL_DOWN };
+ struct binding pview = { _("Prv View"), KEY_GENERIC_SCROLL_UP };
+ struct binding up = { _("Up"), KEY_MOVE_UP };
+ struct binding down = { _("Down"), KEY_MOVE_DOWN };
+ struct binding left = { _("Left"), KEY_MOVE_LEFT };
+ struct binding right = { _("Right"), KEY_MOVE_RIGHT };
+ struct binding weekb = { _("beg Week"), KEY_START_OF_WEEK };
+ struct binding weeke = { _("end Week"), KEY_END_OF_WEEK };
+ struct binding add = { _("Add Item"), KEY_ADD_ITEM };
+ struct binding del = { _("Del Item"), KEY_DEL_ITEM };
+ struct binding edit = { _("Edit Itm"), KEY_EDIT_ITEM };
+ struct binding view = { _("View"), KEY_VIEW_ITEM };
+ struct binding pipe = { _("Pipe"), KEY_PIPE_ITEM };
+ struct binding flag = { _("Flag Itm"), KEY_FLAG_ITEM };
+ struct binding rept = { _("Repeat"), KEY_REPEAT_ITEM };
+ struct binding enote = { _("EditNote"), KEY_EDIT_NOTE };
+ struct binding vnote = { _("ViewNote"), KEY_VIEW_NOTE };
+ struct binding rprio = { _("Prio.+"), KEY_RAISE_PRIORITY };
+ struct binding lprio = { _("Prio.-"), KEY_LOWER_PRIORITY };
+ struct binding othr = { _("OtherCmd"), KEY_GENERIC_OTHER_CMD };
+
+ struct binding *bindings_cal[] = {
&help, &quit, &save, &chgvu, &nview, &pview, &up, &down, &left, &right,
- &togo, &othr, &import, &export, &weekb, &weeke, &appt, &todo,
- &gnday, &gpday, &gnweek, &gpweek, &draw, &othr, &today, &conf, &othr,
- /* appointment keys */
+ &togo, &import, &export, &weekb, &weeke, &appt, &todo, &gnday, &gpday,
+ &gnweek, &gpweek, &draw, &today, &conf
+ };
+
+ struct binding *bindings_apoint[] = {
&help, &quit, &save, &chgvu, &import, &export, &add, &del, &edit, &view,
- &draw, &othr, &rept, &flag, &enote, &vnote, &up, &down, &gnday, &gpday,
- &gnweek, &gpweek, &togo, &othr, &today, &conf, &appt, &todo, &cut, &paste,
- &othr,
- /* todo keys */
+ &pipe, &draw, &rept, &flag, &enote, &vnote, &up, &down, &gnday, &gpday,
+ &gnweek, &gpweek, &togo, &today, &conf, &appt, &todo, &cut, &paste
+ };
+
+ struct binding *bindings_todo[] = {
&help, &quit, &save, &chgvu, &import, &export, &add, &del, &edit, &view,
- &flag, &othr, &rprio, &lprio, &enote, &vnote, &up, &down, &gnday, &gpday,
- &gnweek, &gpweek, &togo, &othr, &today, &conf, &appt, &todo, &draw, &othr
+ &pipe, &flag, &rprio, &lprio, &enote, &vnote, &up, &down, &gnday, &gpday,
+ &gnweek, &gpweek, &togo, &today, &conf, &appt, &todo, &draw
};
- /* Drawing the keybinding with attribute and label without. */
- which_pan = wins_slctd ();
- start = pos[which_pan] + 2 * KEYS_CMDS_PER_LINE * (status_page - 1);
- end = MIN (start + 2 * KEYS_CMDS_PER_LINE, pos[which_pan + 1]);
- keys_display_bindings_bar (win[STA].p, binding, start, end);
+ enum win active_panel = wins_slctd();
+
+ struct binding **bindings;
+ int bindings_size;
+
+ switch (active_panel) {
+ case CAL:
+ bindings = bindings_cal;
+ bindings_size = sizeof(bindings_cal) / sizeof(bindings_cal[0]);
+ break;
+ case APP:
+ bindings = bindings_apoint;
+ bindings_size = sizeof(bindings_apoint) / sizeof(bindings_apoint[0]);
+ break;
+ case TOD:
+ bindings = bindings_todo;
+ bindings_size = sizeof(bindings_todo) / sizeof(bindings_todo[0]);
+ break;
+ default:
+ EXIT(_("unknown panel"));
+ /* NOTREACHED */
+ }
+
+ keys_display_bindings_bar(win[STA].p, bindings, bindings_size,
+ (KEYS_CMDS_PER_LINE * 2 - 1) * (status_page - 1),
+ KEYS_CMDS_PER_LINE * 2, &othr);
}
/* Erase status bar. */
-void
-wins_erase_status_bar (void)
+void wins_erase_status_bar(void)
{
- erase_window_part (win[STA].p, 0, 0, col, STATUSHEIGHT);
+ erase_window_part(win[STA].p, 0, 0, col, STATUSHEIGHT);
}
/* Update the status bar page number to display other commands. */
-void
-wins_other_status_page (int panel)
+void wins_other_status_page(int panel)
{
int nb_item, max_page;
- switch (panel)
- {
- case CAL:
- nb_item = NB_CAL_CMDS;
- break;
- case APP:
- nb_item = NB_APP_CMDS;
- break;
- case TOD:
- nb_item = NB_TOD_CMDS;
- break;
- default:
- EXIT (_("unknown panel"));
- /* NOTREACHED */
- }
- max_page = ceil (nb_item / (2 * CMDS_PER_LINE + 1)) + 1;
- if (status_page < max_page)
- status_page++;
- else
- status_page = 1;
+ switch (panel) {
+ case CAL:
+ nb_item = NB_CAL_CMDS;
+ break;
+ case APP:
+ nb_item = NB_APP_CMDS;
+ break;
+ case TOD:
+ nb_item = NB_TOD_CMDS;
+ break;
+ default:
+ EXIT(_("unknown panel"));
+ /* NOTREACHED */
+ }
+ max_page = nb_item / (KEYS_CMDS_PER_LINE * 2 - 1) + 1;
+ status_page = (status_page % max_page) + 1;
}
/* Reset the status bar page. */
-void
-wins_reset_status_page (void)
+void wins_reset_status_page(void)
{
status_page = 1;
}
@@ -765,5 +707,3 @@ wins_reset_status_page (void)
#undef NB_CAL_CMDS
#undef NB_APP_CMDS
#undef NB_TOD_CMDS
-#undef TOTAL_CMDS
-#undef CMDS_PER_LINE