From f2918b1700974831fd891b17e7e2126ffa454519 Mon Sep 17 00:00:00 2001 From: Lars Henriksen Date: Mon, 10 Feb 2020 16:14:26 +0100 Subject: Support interactive test of recurrence rule extensions The generic command 'next' is introduced. Signed-off-by: Lars Henriksen Signed-off-by: Lukas Fleischer --- src/calcurse.c | 43 ++++++++++++++++++++++++++++++++++++++++++- src/calcurse.h | 2 ++ src/recur.c | 24 ++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/src/calcurse.c b/src/calcurse.c index 3d8905f..fe8b574 100644 --- a/src/calcurse.c +++ b/src/calcurse.c @@ -557,7 +557,7 @@ static inline void key_generic_cmd(void) int valid = 0, force = 0, ret; char *error_msg; - status_mesg(_("Command: [ h(elp) | w(rite)(!) | q(uit)(!) | wq(!) ]"), ""); + status_mesg(_("Command: [ h(elp) | w(rite)(!) | q(uit)(!) | wq(!) | n(ext) ]"), ""); if (getstring(win[STA].p, cmd, BUFSIZ, 0, 1) != GETSTRING_VALID) goto cleanup; cmd_name = strtok(cmd, " "); @@ -609,6 +609,47 @@ static inline void key_generic_cmd(void) valid = 1; } + if (!strcmp(cmd_name, "next") || !strcmp(cmd_name, "n")) { + struct day_item *item; + time_t day, next; + struct recur_apoint *rapt; + struct recur_event *rev; + int more = 0; + + if (wins_slctd() != APP) { + error_msg = + _("Select a repeating item in the appointments panel."); + warnbox(error_msg); + goto cleanup; + } + day = date2sec(*ui_calendar_get_slctd_day(), 0, 0); + item = ui_day_get_sel(); + if (item->type == RECUR_EVNT) { + rev = item->item.rev; + more = recur_next_occurrence(rev->day, -1, rev->rpt, &rev->exc, + day, &next); + } else if (item->type == RECUR_APPT) { + rapt = item->item.rapt; + more = recur_next_occurrence(rapt->start, rapt->dur, rapt->rpt, + &rapt->exc, day, &next); + } else { + error_msg = _("Not a repeating item."); + warnbox(error_msg); + goto cleanup; + } + if (!more) { + error_msg = _("Last repetition."); + warnbox(error_msg); + goto cleanup; + } + item->start = next; + ui_calendar_set_slctd_day(sec2date(next)); + day_set_sel_data(item); + do_storage(1); + + valid = 1; + } + if (!valid) { asprintf(&error_msg, _("No such command: %s"), cmd); status_mesg(error_msg, ""); diff --git a/src/calcurse.h b/src/calcurse.h index dab1543..0c959a9 100644 --- a/src/calcurse.h +++ b/src/calcurse.h @@ -1105,6 +1105,8 @@ void recur_apoint_check_next(struct notify_app *, time_t, time_t); void recur_apoint_switch_notify(struct recur_apoint *); void recur_event_paste_item(struct recur_event *, time_t); void recur_apoint_paste_item(struct recur_apoint *, time_t); +int recur_next_occurrence(time_t, long, struct rpt *, llist_t *, time_t, time_t *); + /* sigs.c */ void sigs_init(void); diff --git a/src/recur.c b/src/recur.c index e0a6b05..997fb15 100644 --- a/src/recur.c +++ b/src/recur.c @@ -1772,3 +1772,27 @@ void recur_apoint_paste_item(struct recur_apoint *rapt, time_t date) if (notify_bar()) notify_check_repeated(rapt); } + +/* + * Finds the next occurrence of a recurrent item and returns it in the provided + * buffer. Useful for test of a repeated item. + */ +int recur_next_occurrence(time_t s, long d, struct rpt *r, llist_t *e, + time_t occur, time_t *next) +{ + int ret = 0; + + if (r->until && r->until <= occur) + return ret; + + while (!r->until || occur < r->until) { + occur = NEXTDAY(occur); + if (!check_sec(&occur)) + break; + if (recur_item_find_occurrence(s, d, r, e, occur, next)) { + ret = 1; + break; + } + } + return ret; +} -- cgit v1.2.3-70-g09d2