From 6907ae73e76d11c201ff237663af79b3bbfc5385 Mon Sep 17 00:00:00 2001 From: Lukas Fleischer Date: Wed, 27 Jun 2012 08:52:42 +0200 Subject: Revise cut/pasting Instead of calling type-specific duplication handlers and inserting clones of the original items when pasting, save the generic day item and remove the actual item from the linked list, so that it can be inserted anywhere else later. The cut/paste buffer is moved to the interaction unit, item-specific cut operations are changed to remove the item from the linked list only instead of copying and freeing it. An item is only freed if another item is cut before the current cut/paste buffer is pasted. All paste operations are changed and reinsert the actual item instead of creating a clone. Signed-off-by: Lukas Fleischer --- src/apoint.c | 25 ++++++++++----------- src/calcurse.h | 13 ++++++----- src/day.c | 29 ++++++++++--------------- src/event.c | 13 +++++------ src/interaction.c | 50 +++++++++++++++++++++++++++++++++--------- src/recur.c | 65 +++++++++++++++++++++---------------------------------- src/utils.c | 5 +---- 7 files changed, 102 insertions(+), 98 deletions(-) (limited to 'src') diff --git a/src/apoint.c b/src/apoint.c index 291d0d8..c8bc1f8 100644 --- a/src/apoint.c +++ b/src/apoint.c @@ -233,10 +233,12 @@ void apoint_delete(struct apoint *apt, enum eraseflg flag) erase_note(&apt->note); break; case ERASE_CUT: - apoint_free_bkp(); - apoint_dup(apt, &bkp_cut_apoint); - erase_note(&apt->note); - /* FALLTHROUGH */ + if (notify_bar()) + need_check_notify = notify_same_item(apt->start); + LLIST_TS_REMOVE(&alist_p, i); + if (need_check_notify) + notify_check_next_app(0); + break; default: if (notify_bar()) need_check_notify = notify_same_item(apt->start); @@ -397,17 +399,14 @@ void apoint_update_panel(int which_pan) win[APP].x + win[APP].w - 3 * bordr); } -void apoint_paste_item(void) +void apoint_paste_item(struct apoint *apt, long date) { - long bkp_time, bkp_start; + apt->start = date + get_item_time(apt->start); - 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); + LLIST_TS_LOCK(&alist_p); + LLIST_TS_ADD_SORTED(&alist_p, apt, apoint_cmp_start); + LLIST_TS_UNLOCK(&alist_p); if (notify_bar()) - notify_check_added(bkp_cut_apoint.mesg, bkp_start, bkp_cut_apoint.state); - - apoint_free_bkp(); + notify_check_added(apt->mesg, apt->start, apt->state); } diff --git a/src/calcurse.h b/src/calcurse.h index 0dd7d01..4cdfe35 100644 --- a/src/calcurse.h +++ b/src/calcurse.h @@ -609,7 +609,7 @@ void apoint_scroll_pad_up(int); struct notify_app *apoint_check_next(struct notify_app *, long); void apoint_switch_notify(struct apoint *); void apoint_update_panel(int); -void apoint_paste_item(void); +void apoint_paste_item(struct apoint *, long); /* args.c */ int parse_args(int, char **); @@ -672,8 +672,8 @@ void day_write_stdout(long, const char *, const char *, const char *, void day_popup_item(struct day_item *); int day_check_if_item(struct date); unsigned day_chk_busy_slices(struct date, int, int *); -int day_cut_item(long, int); -int day_paste_item(long, int); +struct day_item *day_cut_item(long, int); +int day_paste_item(struct day_item *, long); struct day_item *day_get_item(int); int day_item_nb(long, int, int); void day_edit_note(struct day_item *, const char *); @@ -695,7 +695,7 @@ unsigned event_inday(struct event *, long *); void event_write(struct event *, FILE *); struct event *event_scan(FILE *, struct tm, int, char *); void event_delete(struct event *, enum eraseflg); -void event_paste_item(void); +void event_paste_item(struct event *, long); /* help.c */ void help_wins_init(struct scrollwin *, int, int, int, int); @@ -716,6 +716,7 @@ void interact_day_item_delete(unsigned *, unsigned *); void interact_day_item_edit(void); void interact_day_item_pipe(void); void interact_day_item_repeat(void); +void interact_day_item_cut_free(); int interact_day_item_cut(unsigned *, unsigned *); void interact_day_item_paste(unsigned *, unsigned *, int); void interact_todo_add(void); @@ -879,8 +880,8 @@ void recur_apoint_erase(struct recur_apoint *, long, unsigned, enum eraseflg); void recur_exc_scan(llist_t *, FILE *); struct notify_app *recur_apoint_check_next(struct notify_app *, long, long); void recur_apoint_switch_notify(struct recur_apoint *); -void recur_event_paste_item(void); -void recur_apoint_paste_item(void); +void recur_event_paste_item(struct recur_event *, long); +void recur_apoint_paste_item(struct recur_apoint *, long); /* sigs.c */ void sigs_init(void); diff --git a/src/day.c b/src/day.c index 087d8b7..2488c59 100644 --- a/src/day.c +++ b/src/day.c @@ -595,60 +595,55 @@ unsigned day_chk_busy_slices(struct date day, int slicesno, int *slices) } /* Cut an item so it can be pasted somewhere else later. */ -int day_cut_item(long date, int item_number) +struct day_item *day_cut_item(long date, int item_number) { - const int DELETE_WHOLE = 1; - struct day_item *p; + struct day_item *p = day_get_item(item_number); - p = day_get_item(item_number); switch (p->type) { case EVNT: event_delete(p->item.ev, ERASE_CUT); break; case RECUR_EVNT: - recur_event_erase(p->item.rev, date, DELETE_WHOLE, ERASE_CUT); + recur_event_erase(p->item.rev, date, 1, ERASE_CUT); break; case APPT: apoint_delete(p->item.apt, ERASE_CUT); break; case RECUR_APPT: - recur_apoint_erase(p->item.rapt, date, DELETE_WHOLE, ERASE_CUT); + recur_apoint_erase(p->item.rapt, date, 1, ERASE_CUT); break; default: EXIT(_("unknwon type")); /* NOTREACHED */ } - return p->type; + return p; } /* Paste a previously cut item. */ -int day_paste_item(long date, int cut_item_type) +int day_paste_item(struct day_item *p, long date) { - int pasted_item_type; - - pasted_item_type = cut_item_type; - switch (cut_item_type) { + switch (p->type) { case 0: return 0; case EVNT: - event_paste_item(); + event_paste_item(p->item.ev, date); break; case RECUR_EVNT: - recur_event_paste_item(); + recur_event_paste_item(p->item.rev, date); break; case APPT: - apoint_paste_item(); + apoint_paste_item(p->item.apt, date); break; case RECUR_APPT: - recur_apoint_paste_item(); + recur_apoint_paste_item(p->item.rapt, date); break; default: EXIT(_("unknwon type")); /* NOTREACHED */ } - return pasted_item_type; + return p->type; } /* Returns a structure containing the selected item. */ diff --git a/src/event.c b/src/event.c index 4f70391..d937a8b 100644 --- a/src/event.c +++ b/src/event.c @@ -167,10 +167,8 @@ void event_delete(struct event *ev, enum eraseflg flag) erase_note(&ev->note); break; case ERASE_CUT: - event_free_bkp(); - event_dup(ev, &bkp_cut_event); - erase_note(&ev->note); - /* FALLTHROUGH */ + LLIST_REMOVE(&eventlist, i); + break; default: LLIST_REMOVE(&eventlist, i); mem_free(ev->mesg); @@ -179,9 +177,8 @@ void event_delete(struct event *ev, enum eraseflg flag) } } -void event_paste_item(void) +void event_paste_item(struct event *ev, long date) { - event_new(bkp_cut_event.mesg, bkp_cut_event.note, - date2sec(*calendar_get_slctd_day(), 0, 0), bkp_cut_event.id); - event_free_bkp(); + ev->day = date; + LLIST_ADD_SORTED(&eventlist, ev, event_cmp_day); } diff --git a/src/interaction.c b/src/interaction.c index 1a021be..103cdf0 100644 --- a/src/interaction.c +++ b/src/interaction.c @@ -36,6 +36,8 @@ #include "calcurse.h" +struct day_item day_cut = { 0, 0, { NULL } }; + /* Request the user to enter a new time. */ static int day_edit_time(int time, unsigned *new_hour, unsigned *new_minute) { @@ -858,22 +860,47 @@ void interact_day_item_repeat(void) day_erase_item(date, item_nb, ERASE_FORCE); } +/* Free the current cut item, if any. */ +void interact_day_item_cut_free(void) +{ + switch (day_cut.type) { + case 0: + /* No previous item, don't free anything. */ + break; + case APPT: + apoint_free(day_cut.item.apt); + break; + case EVNT: + event_free(day_cut.item.ev); + break; + case RECUR_APPT: + recur_apoint_free(day_cut.item.rapt); + break; + case RECUR_EVNT: + recur_event_free(day_cut.item.rev); + break; + } +} + /* Cut an item, so that it can be pasted somewhere else later. */ int interact_day_item_cut(unsigned *nb_events, unsigned *nb_apoints) { const int NBITEMS = *nb_apoints + *nb_events; - int item_type, to_be_removed; - long date; + int to_be_removed; if (NBITEMS == 0) return 0; - date = calendar_get_slctd_day_sec(); - item_type = day_cut_item(date, apoint_hilt()); - if (item_type == EVNT || item_type == RECUR_EVNT) { + interact_day_item_cut_free(); + struct day_item *p = day_cut_item(calendar_get_slctd_day_sec(), + apoint_hilt()); + day_cut.type = p->type; + day_cut.item = p->item; + + if (p->type == EVNT || p->type == RECUR_EVNT) { (*nb_events)--; to_be_removed = 1; - } else if (item_type == APPT || item_type == RECUR_APPT) { + } else if (p->type == APPT || p->type == RECUR_APPT) { (*nb_apoints)--; to_be_removed = 3; } else @@ -887,7 +914,7 @@ int interact_day_item_cut(unsigned *nb_events, unsigned *nb_apoints) if (NBITEMS == 1) apoint_hilt_set(0); - return item_type; + return p->type; } /* Paste a previously cut item. */ @@ -895,10 +922,13 @@ void interact_day_item_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); + if (!day_cut.type) + return; + + item_type = day_paste_item(&day_cut, calendar_get_slctd_day_sec()); + day_cut.type = 0; + if (item_type == EVNT || item_type == RECUR_EVNT) (*nb_events)++; else if (item_type == APPT || item_type == RECUR_APPT) diff --git a/src/recur.c b/src/recur.c index 55151cd..6b5474d 100644 --- a/src/recur.c +++ b/src/recur.c @@ -709,10 +709,8 @@ recur_event_erase(struct recur_event *rev, long start, unsigned delete_whole, 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 */ + LLIST_REMOVE(&recur_elist, i); + return; default: LLIST_REMOVE(&recur_elist, i); mem_free(rev->mesg); @@ -751,10 +749,8 @@ recur_apoint_erase(struct recur_apoint *rapt, long start, 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 */ + LLIST_TS_REMOVE(&recur_alist_p, i); + break; default: LLIST_TS_REMOVE(&recur_alist_p, i); mem_free(rapt->mesg); @@ -848,56 +844,45 @@ void recur_apoint_switch_notify(struct recur_apoint *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; + + if (rev->rpt->until != 0) + rev->rpt->until += 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) { + 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; - 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) { + if (rapt->rpt->until != 0) + rapt->rpt->until += time_shift; + + 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); } diff --git a/src/utils.c b/src/utils.c index a4780b5..1823321 100644 --- a/src/utils.c +++ b/src/utils.c @@ -99,13 +99,10 @@ void free_user_data(void) { 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(); + interact_day_item_cut_free(); todo_free_list(); notify_free_app(); } -- cgit v1.2.3-70-g09d2