summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/calcurse.c51
-rw-r--r--src/calcurse.h16
-rw-r--r--src/day.c83
-rw-r--r--src/ui-day.c79
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 *);
diff --git a/src/day.c b/src/day.c
index e480732..4c6e1a1 100644
--- a/src/day.c
+++ b/src/day.c
@@ -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();
}