summaryrefslogtreecommitdiff
path: root/src/recur.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/recur.c')
-rw-r--r--src/recur.c428
1 files changed, 99 insertions, 329 deletions
diff --git a/src/recur.c b/src/recur.c
index 5c32bca..1c593c2 100644
--- a/src/recur.c
+++ b/src/recur.c
@@ -44,8 +44,6 @@
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)
{
@@ -85,71 +83,55 @@ static void exc_dup(llist_t * in, llist_t * exc)
}
}
-void recur_event_free_bkp(void)
+struct recur_event *recur_event_dup(struct recur_event *in)
{
- 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(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);
-}
+ EXIT_IF(!in, _("null pointer"));
-static void recur_event_dup(struct recur_event *in, struct recur_event *bkp)
-{
- EXIT_IF(!in || !bkp, _("null pointer"));
+ struct recur_event *rev = mem_malloc(sizeof(struct recur_event));
- bkp->id = in->id;
- bkp->day = in->day;
- bkp->mesg = mem_strdup(in->mesg);
+ rev->id = in->id;
+ rev->day = in->day;
+ rev->mesg = mem_strdup(in->mesg);
- 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;
+ rev->rpt = mem_malloc(sizeof(struct rpt));
+ rev->rpt->type = in->rpt->type;
+ rev->rpt->freq = in->rpt->freq;
+ rev->rpt->until = in->rpt->until;
- exc_dup(&bkp->exc, &in->exc);
+ exc_dup(&rev->exc, &in->exc);
if (in->note)
- bkp->note = mem_strdup(in->note);
+ rev->note = mem_strdup(in->note);
+ else
+ rev->note = NULL;
+
+ return rev;
}
-static void recur_apoint_dup(struct recur_apoint *in, struct recur_apoint *bkp)
+struct recur_apoint *recur_apoint_dup(struct recur_apoint *in)
{
- EXIT_IF(!in || !bkp, _("null pointer"));
+ EXIT_IF(!in, _("null pointer"));
+
+ struct recur_apoint *rapt = mem_malloc(sizeof(struct recur_apoint));
- bkp->start = in->start;
- bkp->dur = in->dur;
- bkp->state = in->state;
- bkp->mesg = mem_strdup(in->mesg);
+ rapt->start = in->start;
+ rapt->dur = in->dur;
+ rapt->state = in->state;
+ rapt->mesg = mem_strdup(in->mesg);
- 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;
+ rapt->rpt = mem_malloc(sizeof(struct rpt));
+ rapt->rpt->type = in->rpt->type;
+ rapt->rpt->freq = in->rpt->freq;
+ rapt->rpt->until = in->rpt->until;
- exc_dup(&bkp->exc, &in->exc);
+ exc_dup(&rapt->exc, &in->exc);
if (in->note)
- bkp->note = mem_strdup(in->note);
+ rapt->note = mem_strdup(in->note);
+ else
+ rapt->note = NULL;
+
+ return rapt;
}
void recur_apoint_llist_init(void)
@@ -157,7 +139,7 @@ void recur_apoint_llist_init(void)
LLIST_TS_INIT(&recur_alist_p);
}
-static void recur_apoint_free(struct recur_apoint *rapt)
+void recur_apoint_free(struct recur_apoint *rapt)
{
mem_free(rapt->mesg);
if (rapt->note)
@@ -168,7 +150,7 @@ static void recur_apoint_free(struct recur_apoint *rapt)
mem_free(rapt);
}
-static void recur_event_free(struct recur_event *rev)
+void recur_event_free(struct recur_event *rev)
{
mem_free(rev->mesg);
if (rev->note)
@@ -550,9 +532,9 @@ 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);
+ return (exc->st >= *day_start && exc->st < *day_start + DAYINSEC);
}
/*
@@ -626,7 +608,7 @@ recur_item_find_occurrence(long item_start, long item_dur, llist_t * item_exc,
lt_item_day.tm_isdst = lt_day.tm_isdst;
t = mktime(&lt_item_day);
- if (LLIST_FIND_FIRST(item_exc, t, exc_inday))
+ if (LLIST_FIND_FIRST(item_exc, &t, exc_inday))
return 0;
if (rpt_until != 0 && t > rpt_until)
@@ -678,16 +660,36 @@ recur_item_inday(long item_start, long item_dur, llist_t * item_exc,
rpt_freq, rpt_until, day_start, NULL);
}
-unsigned recur_apoint_inday(struct recur_apoint *rapt, long day_start)
+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);
+ rapt->rpt->freq, rapt->rpt->until, *day_start);
}
-unsigned recur_event_inday(struct recur_event *rev, long day_start)
+unsigned recur_event_inday(struct recur_event *rev, long *day_start)
{
return recur_item_inday(rev->day, DAYINSEC, &rev->exc, rev->rpt->type,
- rev->rpt->freq, rev->rpt->until, day_start);
+ rev->rpt->freq, rev->rpt->until, *day_start);
+}
+
+/* Add an exception to a recurrent event. */
+void
+recur_event_add_exc(struct recur_event *rev, long date)
+{
+ recur_add_exc(&rev->exc, date);
+}
+
+/* Add an exception to a recurrent appointment. */
+void
+recur_apoint_add_exc(struct recur_apoint *rapt, long date)
+{
+ int need_check_notify = 0;
+
+ if (notify_bar())
+ need_check_notify = notify_same_recur_item(rapt);
+ recur_add_exc(&rapt->exc, date);
+ if (need_check_notify)
+ notify_check_next_app(0);
}
/*
@@ -695,40 +697,14 @@ unsigned 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(struct recur_event *rev)
{
- llist_item_t *i;
-
- i = LLIST_FIND_NTH(&recur_elist, num, start, recur_event_inday);
+ llist_item_t *i = LLIST_FIND_FIRST(&recur_elist, rev, NULL);
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);
- 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);
+
+ LLIST_REMOVE(&recur_elist, i);
}
/*
@@ -736,184 +712,23 @@ 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(struct recur_apoint *rapt)
{
- llist_item_t *i;
- int need_check_notify = 0;
+ LLIST_TS_LOCK(&recur_alist_p);
- i = LLIST_TS_FIND_NTH(&recur_alist_p, num, start, recur_apoint_inday);
+ llist_item_t *i = LLIST_TS_FIND_FIRST(&recur_alist_p, rapt, NULL);
+ int need_check_notify = 0;
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)
+ if (notify_bar())
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);
- break;
- }
- } else {
- recur_add_exc(&rapt->exc, start);
- if (need_check_notify)
- notify_check_next_app(0);
- }
- LLIST_TS_UNLOCK(&recur_alist_p);
-}
-
-/*
- * Ask user for repetition characteristics:
- * o repetition type: daily, weekly, monthly, yearly
- * o repetition frequence: every X days, weeks, ...
- * o repetition end date
- * and then delete the selected item to recreate it as a recurrent one
- */
-void recur_repeat_item(void)
-{
- struct tm lt;
- time_t t;
- int date_entered = 0;
- int year = 0, month = 0, day = 0;
- struct date until_date;
- char outstr[BUFSIZ];
- char user_input[BUFSIZ] = "";
- 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);
- wgetch(win[STA].p);
- return;
- }
+ LLIST_TS_REMOVE(&recur_alist_p, i);
+ if (need_check_notify)
+ notify_check_next_app(0);
- 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;
- }
-
- 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;
- localtime_r(&t, &lt);
- 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;
- }
-
- 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);
+ LLIST_TS_UNLOCK(&recur_alist_p);
}
/*
@@ -959,7 +774,7 @@ struct notify_app *recur_apoint_check_next(struct notify_app *app, long start,
unsigned real_recur_start_time;
LLIST_TS_LOCK(&recur_alist_p);
- LLIST_TS_FIND_FOREACH(&recur_alist_p, app->time, recur_apoint_starts_before,
+ LLIST_TS_FIND_FOREACH(&recur_alist_p, &app->time, recur_apoint_starts_before,
i) {
struct recur_apoint *rapt = LLIST_TS_GET_DATA(i);
@@ -976,102 +791,57 @@ struct notify_app *recur_apoint_check_next(struct notify_app *app, long start,
return app;
}
-/* Returns a structure containing the selected recurrent appointment. */
-struct recur_apoint *recur_get_apoint(long date, int num)
-{
- llist_item_t *i = LLIST_TS_FIND_NTH(&recur_alist_p, num, date,
- recur_apoint_inday);
-
- if (i)
- return LLIST_TS_GET_DATA(i);
-
- EXIT(_("item not found"));
- /* NOTREACHED */
-}
-
-/* Returns a structure containing the selected recurrent event. */
-struct recur_event *recur_get_event(long date, int num)
-{
- llist_item_t *i = LLIST_FIND_NTH(&recur_elist, num, date,
- recur_event_inday);
-
- if (i)
- return LLIST_GET_DATA(i);
-
- 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(struct recur_apoint *rapt)
{
- llist_item_t *i;
-
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);
rapt->state ^= APOINT_NOTIFY;
-
if (notify_bar())
notify_check_repeated(rapt);
LLIST_TS_UNLOCK(&recur_alist_p);
}
-void recur_event_paste_item(void)
+void recur_event_paste_item(struct recur_event *rev, long date)
{
- long new_start, time_shift;
+ long time_shift;
llist_item_t *i;
- new_start = date2sec(*calendar_get_slctd_day(), 0, 0);
- time_shift = new_start - bkp_cut_recur_event.day;
+ time_shift = date - rev->day;
+ rev->day += time_shift;
- 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) {
+ if (rev->rpt->until != 0)
+ rev->rpt->until += time_shift;
+
+ LLIST_FOREACH(&rev->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();
+ LLIST_ADD_SORTED(&recur_elist, rev, recur_event_cmp_day);
}
-void recur_apoint_paste_item(void)
+void recur_apoint_paste_item(struct recur_apoint *rapt, long date)
{
- long new_start, time_shift;
+ long 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));
- time_shift = new_start - bkp_cut_recur_apoint.start;
+ time_shift = (date + get_item_time(rapt->start)) - rapt->start;
+ rapt->start += time_shift;
+
+ if (rapt->rpt->until != 0)
+ rapt->rpt->until += time_shift;
- 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) {
+ LLIST_FOREACH(&rapt->exc, i) {
struct excp *exc = LLIST_GET_DATA(i);
exc->st += time_shift;
}
- 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);
+ LLIST_TS_LOCK(&recur_alist_p);
+ LLIST_TS_ADD_SORTED(&recur_alist_p, rapt, recur_apoint_cmp_start);
+ LLIST_TS_UNLOCK(&recur_alist_p);
if (notify_bar())
- notify_check_repeated(&bkp_cut_recur_apoint);
-
- recur_apoint_free_bkp();
+ notify_check_repeated(rapt);
}