diff options
Diffstat (limited to 'src/recur.c')
-rw-r--r-- | src/recur.c | 428 |
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(<_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, <); - 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); } |