diff options
-rw-r--r-- | src/calcurse.c | 51 | ||||
-rw-r--r-- | src/calcurse.h | 16 | ||||
-rw-r--r-- | src/day.c | 83 | ||||
-rw-r--r-- | src/ui-day.c | 79 |
4 files changed, 144 insertions, 85 deletions
diff --git a/src/calcurse.c b/src/calcurse.c index 757b3cd..b99f210 100644 --- a/src/calcurse.c +++ b/src/calcurse.c @@ -41,26 +41,35 @@ #define HANDLE_KEY(key, fn) case key: fn(); break; int count, reg; - /* - * Store the events and appointments for the selected day and reset the - * appointment highlight pointer if a new day was selected. + * Store events and appointments for a range of days in the day vector - + * beginning with the selected day - and load them into the APP listbox. If no + * day-change occurs, reset the selected APP item and with it the selected day, + * thereby storing and loading the same range of days. */ static void do_storage(int day_changed) { - /* * Save the selected item before rebuilding the day vector. */ - struct day_item *day = ui_day_selitem(); - union aptev_ptr item; - if (day) - item = day->item; + /* + * Save the selected item before rebuilding the day vector - + * unless already set. + */ + if (!day_check_sel_data()) + day_set_sel_data(ui_day_get_sel()); + + if (!day_changed) + ui_day_sel_reset(); + /* The day_items vector. */ day_store_items(get_slctd_day(), 1, day_get_nb()); + /* The APP listbox. */ ui_day_load_items(); if (day_changed) ui_day_sel_reset(); - else if (day) - ui_day_set_selitem_by_aptev_ptr(item); + else + ui_day_find_sel(); + + day_set_sel_data(&empty_day); } static inline void key_generic_change_view(void) @@ -115,6 +124,7 @@ static inline void key_generic_config_menu(void) static inline void key_generic_add_appt(void) { ui_day_item_add(); + do_storage(0); wins_update(FLAG_CAL | FLAG_APP | FLAG_STA); } @@ -130,6 +140,7 @@ static inline void key_add_item(void) case APP: case CAL: ui_day_item_add(); + do_storage(0); wins_update(FLAG_CAL | FLAG_APP | FLAG_STA); break; case TOD: @@ -143,7 +154,7 @@ static inline void key_add_item(void) static inline void key_edit_item(void) { - if (wins_slctd() == APP && !event_dummy(ui_day_selitem())) { + if (wins_slctd() == APP && !event_dummy(ui_day_get_sel())) { ui_day_item_edit(); do_storage(0); wins_update(FLAG_CAL | FLAG_APP | FLAG_STA); @@ -155,7 +166,7 @@ static inline void key_edit_item(void) static inline void key_del_item(void) { - if (wins_slctd() == APP && !event_dummy(ui_day_selitem())) { + if (wins_slctd() == APP && !event_dummy(ui_day_get_sel())) { ui_day_item_delete(reg); do_storage(0); wins_update(FLAG_CAL | FLAG_APP | FLAG_STA); @@ -167,11 +178,8 @@ static inline void key_del_item(void) static inline void key_generic_copy(void) { - if (wins_slctd() == APP && !event_dummy(ui_day_selitem())) { + if (wins_slctd() == APP && !event_dummy(ui_day_get_sel())) ui_day_item_copy(reg); - do_storage(0); - wins_update(FLAG_CAL | FLAG_APP); - } } static inline void key_generic_paste(void) @@ -185,15 +193,16 @@ static inline void key_generic_paste(void) static inline void key_repeat_item(void) { - if (wins_slctd() == APP && !event_dummy(ui_day_selitem())) + if (wins_slctd() == APP && !event_dummy(ui_day_get_sel())) { ui_day_item_repeat(); - do_storage(0); - wins_update(FLAG_CAL | FLAG_APP | FLAG_STA); + do_storage(0); + wins_update(FLAG_CAL | FLAG_APP | FLAG_STA); + } } static inline void key_flag_item(void) { - if (wins_slctd() == APP && !event_dummy(ui_day_selitem())) { + if (wins_slctd() == APP && !event_dummy(ui_day_get_sel())) { ui_day_flag(); do_storage(0); wins_update(FLAG_APP); @@ -232,7 +241,7 @@ static inline void key_lower_priority(void) static inline void key_edit_note(void) { - if (wins_slctd() == APP && !event_dummy(ui_day_selitem())) { + if (wins_slctd() == APP && !event_dummy(ui_day_get_sel())) { ui_day_edit_note(); do_storage(0); } else if (wins_slctd() == TOD) { diff --git a/src/calcurse.h b/src/calcurse.h index 3ee0900..333e1b9 100644 --- a/src/calcurse.h +++ b/src/calcurse.h @@ -762,6 +762,9 @@ void apoint_paste_item(struct apoint *, time_t); int parse_args(int, char **); /* calendar.c */ +extern struct day_item empty_day; + +/* ui_calendar.c */ void ui_calendar_view_next(void); void ui_calendar_view_prev(void); void ui_calendar_set_view(int); @@ -801,6 +804,9 @@ void custom_config_main(void); /* day.c */ int day_get_nb(void); +int day_set_sel_data(struct day_item *); +int day_check_sel_data(void); +int day_sel_index(void); void day_free_vector(void); char *day_item_get_mesg(struct day_item *); char *day_item_get_note(struct day_item *); @@ -819,8 +825,6 @@ int day_check_if_item(struct date); unsigned day_chk_busy_slices(struct date, int, int *); struct day_item *day_cut_item(time_t, int); int day_paste_item(struct day_item *, time_t); -int day_get_position_by_aptev_ptr(union aptev_ptr); -int day_get_position(struct day_item *); struct day_item *day_get_item(int); unsigned day_item_count(int); void day_edit_note(struct day_item *, const char *); @@ -1097,10 +1101,6 @@ void todo_init_list(void); void todo_free_list(void); /* ui-day.c */ -struct day_item *ui_day_selitem(void); -time_t ui_day_selday(void); -void ui_day_set_selitem_by_aptev_ptr(union aptev_ptr); -void ui_day_set_selitem(struct day_item *); void ui_day_item_add(void); void ui_day_item_delete(unsigned); void ui_day_item_edit(void); @@ -1110,7 +1110,11 @@ void ui_day_item_cut_free(unsigned); void ui_day_item_copy(unsigned); void ui_day_item_paste(unsigned); void ui_day_load_items(void); +void ui_day_find_sel(void); +struct day_item *ui_day_get_sel(void); +time_t ui_day_sel_date(void); void ui_day_sel_reset(void); +void ui_day_set_sel(struct day_item *); void ui_day_sel_move(int); void ui_day_draw(int, WINDOW *, int, int, void *); enum listbox_row_type ui_day_row_type(int, void *); @@ -46,6 +46,67 @@ static unsigned day_nb = 7; static vector_t day_items; static unsigned day_items_nb = 0; +struct day_item empty_day = { 0, 0, 0, {NULL}}; + +/* + * The day vector, day_items, is continuously rebuilt for display as the + * selected day changes, items are added, edited or deleted etc. To keep track + * of the selected item of the day vector across rebuilds, data are saved in + * here that may later be used to refind the item in the rebuilt day + * vector. + */ +static struct day_item sel_data = { 0, 0, 0, {NULL}}; + +/* + * Save the item to become the selected APP item. + * Public function used to override the setting in do_storage(). + */ +int day_set_sel_data(struct day_item *d) +{ + if (!d) + return 0; + + sel_data = *d; + return 1; +} + +/* + * Return selection data if available. + */ +int day_check_sel_data() +{ + return (sel_data.order || sel_data.item.apt) ? 1 : 0; +} + +/* + * Return the position of the saved selection in the day vector. + */ +int day_sel_index(void) +{ + int i = 0; + struct day_item *p; + + VECTOR_FOREACH(&day_items, i) { + p = VECTOR_NTH(&day_items, i); + if (p->order == sel_data.order && + p->item.apt == sel_data.item.apt) + return i; + } + /* Needed as long as ui_day_item_paste() does not set order. */ + VECTOR_FOREACH(&day_items, i) { + p = VECTOR_NTH(&day_items, i); + if (p->item.apt == sel_data.item.apt) + return i; + } + /* If still not found, stay on the same day. */ + VECTOR_FOREACH(&day_items, i) { + p = VECTOR_NTH(&day_items, i); + if (p->order == update_time_in_date(sel_data.order, 0, 0)) + return i; + } + return -1; +} + int day_get_nb(void) { return day_nb; @@ -510,7 +571,7 @@ void day_popup_item(struct day_item *day) struct apoint apt_tmp; apt_tmp.start = day->start; apt_tmp.dur = day_item_get_duration(day); - apoint_sec2str(&apt_tmp, ui_day_selday(), a_st, a_end); + apoint_sec2str(&apt_tmp, ui_day_sel_date(), a_st, a_end); item_in_popup(a_st, a_end, day_item_get_mesg(day), _("Appointment:")); } else { @@ -734,26 +795,6 @@ int day_paste_item(struct day_item *p, time_t date) return p->type; } -/* Returns the position corresponding to a given item. */ -int day_get_position_by_aptev_ptr(union aptev_ptr aptevp) -{ - int n = 0; - - VECTOR_FOREACH(&day_items, n) { - struct day_item *p = VECTOR_NTH(&day_items, n); - /* Compare pointers. */ - if (p->item.ev == aptevp.ev) - return n; - } - - return -1; -} - -int day_get_position(struct day_item *needle) -{ - return day_get_position_by_aptev_ptr(needle->item); -} - /* Returns a structure containing the selected item. */ struct day_item *day_get_item(int item_number) { diff --git a/src/ui-day.c b/src/ui-day.c index 32e12bf..4b37a90 100644 --- a/src/ui-day.c +++ b/src/ui-day.c @@ -39,34 +39,35 @@ struct day_item day_cut[38] = { {0, 0, 0, {NULL}} }; /* - * Return the selected item in the APP panel. + * Return the selected APP item. + * This is a pointer into the day vector and invalid after a day vector rebuild, + * but the (order, item) data may be used to refind the object. */ -struct day_item *ui_day_selitem(void) +struct day_item *ui_day_get_sel(void) { if (day_item_count(0) <= 0) - return NULL; + return &empty_day; return day_get_item(listbox_get_sel(&lb_apt)); } /* - * Return the day (midnight) of the selected item in the APP panel. + * Set the selected item from the saved day_item. */ -time_t ui_day_selday(void) +void ui_day_find_sel(void) { - return update_time_in_date(ui_day_selitem()->order, 0, 0); -} + int n; -void ui_day_set_selitem_by_aptev_ptr(union aptev_ptr p) -{ - int n = day_get_position_by_aptev_ptr(p); - if (n >= 0) + if ((n = day_sel_index()) != -1) listbox_set_sel(&lb_apt, n); } -void ui_day_set_selitem(struct day_item *day) +/* + * Return the date (midnight) of the selected item in the APP panel. + */ +time_t ui_day_sel_date(void) { - ui_day_set_selitem_by_aptev_ptr(day->item); + return update_time_in_date(ui_day_get_sel()->order, 0, 0); } /* @@ -406,7 +407,7 @@ void ui_day_item_edit(void) if (day_item_count(0) <= 0) return; - struct day_item *p = ui_day_selitem(); + struct day_item *p = ui_day_get_sel(); switch (p->type) { case RECUR_EVNT: @@ -534,7 +535,7 @@ void ui_day_item_pipe(void) if (day_item_count(0) <= 0) return; - struct day_item *p = ui_day_selitem(); + struct day_item *p = ui_day_get_sel(); status_mesg(_("Pipe item to external command:"), ""); if (getstring(win[STA].p, cmd, BUFSIZ, 0, 1) != GETSTRING_VALID) @@ -590,7 +591,7 @@ void ui_day_item_add(void) const char *enter_str = _("Press [Enter] to continue"); char item_time[LTIME] = ""; char item_mesg[BUFSIZ] = ""; - time_t start = ui_day_selday(), end, saved = start; + time_t start = ui_day_sel_date(), end, saved = start; unsigned dur; int is_appointment = 1; union aptev_ptr item; @@ -683,9 +684,11 @@ void ui_day_item_add(void) item.ev = event_new(item_mesg, 0L, start, 1); } io_set_modified(); - day_store_items(get_slctd_day(), 1, day_get_nb()); - ui_day_load_items(); - ui_day_set_selitem_by_aptev_ptr(item); + /* Set the selected APP item. */ + struct day_item d = empty_day; + d.order = start; + d.item = item; + day_set_sel_data(&d); } ui_calendar_monthly_view_cache_set_invalid(); @@ -715,7 +718,7 @@ void ui_day_item_delete(unsigned reg) if (day_item_count(0) <= 0) return; - struct day_item *p = ui_day_selitem(); + struct day_item *p = ui_day_get_sel(); if (conf.confirm_delete) { if (status_ask_bool(del_app_str) != 1) { @@ -745,12 +748,10 @@ void ui_day_item_delete(unsigned reg) break; case 2: if (p->type == RECUR_EVNT) { - date = get_slctd_day(); - day_item_add_exc(p, date); + day_item_add_exc(p, ui_day_sel_date()); } else { - date = update_time_in_date(p->start, 0, 0); recur_apoint_find_occurrence(p->item.rapt, - date, + ui_day_sel_date(), &occurrence); day_item_add_exc(p, occurrence); } @@ -900,21 +901,25 @@ void ui_day_item_repeat(void) } date = get_slctd_day(); + /* Set the selected APP item. */ + struct day_item d = empty_day; if (p->type == EVNT) { struct event *ev = p->item.ev; - recur_event_new(ev->mesg, ev->note, ev->day, ev->id, type, - freq, until, NULL); + d.item.rev = recur_event_new(ev->mesg, ev->note, ev->day, + ev->id, type, freq, until, NULL); } else if (p->type == APPT) { struct apoint *apt = p->item.apt; - ra = recur_apoint_new(apt->mesg, apt->note, apt->start, - apt->dur, apt->state, type, freq, - until, NULL); + d.item.rapt = ra = recur_apoint_new(apt->mesg, apt->note, + apt->start, apt->dur, + apt->state, type, freq, + until, NULL); if (notify_bar()) notify_check_repeated(ra); } else { EXIT(_("wrong item type")); /* NOTREACHED */ } + day_set_sel_data(&d); ui_day_item_cut_free(REG_BLACK_HOLE); p = day_cut_item(date, item_nb); @@ -960,7 +965,7 @@ void ui_day_item_copy(unsigned reg) if (day_item_count(0) <= 0 || reg == REG_BLACK_HOLE) return; - struct day_item *item = ui_day_selitem(); + struct day_item *item = ui_day_get_sel(); ui_day_item_cut_free(reg); day_item_fork(item, &day_cut[reg]); } @@ -968,15 +973,15 @@ void ui_day_item_copy(unsigned reg) /* Paste a previously cut item. */ void ui_day_item_paste(unsigned reg) { - struct day_item day; + struct day_item day = empty_day; if (reg == REG_BLACK_HOLE || !day_cut[reg].type) return; day_item_fork(&day_cut[reg], &day); - day_paste_item(&day, ui_day_selday()); + day_paste_item(&day, ui_day_sel_date()); + day_set_sel_data(&day); io_set_modified(); - ui_calendar_monthly_view_cache_set_invalid(); } @@ -1071,7 +1076,7 @@ void ui_day_popup_item(void) if (day_item_count(0) <= 0) return; - struct day_item *item = ui_day_selitem(); + struct day_item *item = ui_day_get_sel(); day_popup_item(item); } @@ -1080,7 +1085,7 @@ void ui_day_flag(void) if (day_item_count(0) <= 0) return; - struct day_item *item = ui_day_selitem(); + struct day_item *item = ui_day_get_sel(); day_item_switch_notify(item); io_set_modified(); } @@ -1090,7 +1095,7 @@ void ui_day_view_note(void) if (day_item_count(0) <= 0) return; - struct day_item *item = ui_day_selitem(); + struct day_item *item = ui_day_get_sel(); day_view_note(item, conf.pager); } @@ -1099,7 +1104,7 @@ void ui_day_edit_note(void) if (day_item_count(0) <= 0) return; - struct day_item *item = ui_day_selitem(); + struct day_item *item = ui_day_get_sel(); day_edit_note(item, conf.editor); io_set_modified(); } |