aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/args.c2
-rw-r--r--src/calcurse.c14
-rw-r--r--src/calcurse.h13
-rw-r--r--src/day.c96
-rw-r--r--src/event.c8
-rw-r--r--src/ui-day.c31
6 files changed, 115 insertions, 49 deletions
diff --git a/src/args.c b/src/args.c
index 66584cf..e6444e4 100644
--- a/src/args.c
+++ b/src/args.c
@@ -275,7 +275,7 @@ date_arg_from_to(long from, long to, int add_line, const char *fmt_apt,
long date;
for (date = from; date <= to; date = date_sec_change(date, 0, 1)) {
- day_store_items(date, 0);
+ day_store_items(date, 0, 1);
if (day_item_count(0) == 0)
continue;
if (add_line)
diff --git a/src/calcurse.c b/src/calcurse.c
index d470661..757b3cd 100644
--- a/src/calcurse.c
+++ b/src/calcurse.c
@@ -54,7 +54,7 @@ static void do_storage(int day_changed)
if (day)
item = day->item;
- day_store_items(get_slctd_day(), 1);
+ day_store_items(get_slctd_day(), 1, day_get_nb());
ui_day_load_items();
if (day_changed)
@@ -143,7 +143,7 @@ static inline void key_add_item(void)
static inline void key_edit_item(void)
{
- if (wins_slctd() == APP) {
+ if (wins_slctd() == APP && !event_dummy(ui_day_selitem())) {
ui_day_item_edit();
do_storage(0);
wins_update(FLAG_CAL | FLAG_APP | FLAG_STA);
@@ -155,7 +155,7 @@ static inline void key_edit_item(void)
static inline void key_del_item(void)
{
- if (wins_slctd() == APP) {
+ if (wins_slctd() == APP && !event_dummy(ui_day_selitem())) {
ui_day_item_delete(reg);
do_storage(0);
wins_update(FLAG_CAL | FLAG_APP | FLAG_STA);
@@ -167,7 +167,7 @@ static inline void key_del_item(void)
static inline void key_generic_copy(void)
{
- if (wins_slctd() == APP) {
+ if (wins_slctd() == APP && !event_dummy(ui_day_selitem())) {
ui_day_item_copy(reg);
do_storage(0);
wins_update(FLAG_CAL | FLAG_APP);
@@ -185,7 +185,7 @@ static inline void key_generic_paste(void)
static inline void key_repeat_item(void)
{
- if (wins_slctd() == APP)
+ if (wins_slctd() == APP && !event_dummy(ui_day_selitem()))
ui_day_item_repeat();
do_storage(0);
wins_update(FLAG_CAL | FLAG_APP | FLAG_STA);
@@ -193,7 +193,7 @@ static inline void key_repeat_item(void)
static inline void key_flag_item(void)
{
- if (wins_slctd() == APP) {
+ if (wins_slctd() == APP && !event_dummy(ui_day_selitem())) {
ui_day_flag();
do_storage(0);
wins_update(FLAG_APP);
@@ -232,7 +232,7 @@ static inline void key_lower_priority(void)
static inline void key_edit_note(void)
{
- if (wins_slctd() == APP) {
+ if (wins_slctd() == APP && !event_dummy(ui_day_selitem())) {
ui_day_edit_note();
do_storage(0);
} else if (wins_slctd() == TOD) {
diff --git a/src/calcurse.h b/src/calcurse.h
index 6d6f205..3ee0900 100644
--- a/src/calcurse.h
+++ b/src/calcurse.h
@@ -172,6 +172,7 @@
#define NOHILT 0 /* 'No highlight' argument */
#define NOFORCE 0
#define FORCE 1
+#define DUMMY -1 /* The dummy event */
#define ERROR_MSG(...) do { \
char msg[BUFSIZ]; \
@@ -417,9 +418,10 @@ enum day_item_type {
DAY_HEADING = 1,
RECUR_EVNT,
EVNT,
- DAY_SEPARATOR,
+ EVNT_SEPARATOR,
RECUR_APPT,
- APPT
+ APPT,
+ DAY_SEPARATOR
};
/* Available item types. */
@@ -460,6 +462,7 @@ struct item_filter {
struct day_item {
enum day_item_type type;
time_t start;
+ time_t order;
union aptev_ptr item;
};
@@ -797,6 +800,7 @@ void custom_keys_config(void);
void custom_config_main(void);
/* day.c */
+int day_get_nb(void);
void day_free_vector(void);
char *day_item_get_mesg(struct day_item *);
char *day_item_get_note(struct day_item *);
@@ -805,7 +809,7 @@ long day_item_get_duration(struct day_item *);
int day_item_get_state(struct day_item *);
void day_item_add_exc(struct day_item *, time_t);
void day_item_fork(struct day_item *, struct day_item *);
-void day_store_items(time_t, int);
+void day_store_items(time_t, int, int);
void day_display_item_date(struct day_item *, WINDOW *, int, time_t, int, int);
void day_display_item(struct day_item *, WINDOW *, int, int, int, int);
void day_write_stdout(time_t, const char *, const char *, const char *,
@@ -829,6 +833,7 @@ void dmon_stop(void);
/* event.c */
extern llist_t eventlist;
+extern struct event dummy;
void event_free_bkp(void);
struct event *event_dup(struct event *);
void event_free(struct event *);
@@ -842,6 +847,7 @@ void event_write(struct event *, FILE *);
struct event *event_scan(FILE *, struct tm, int, char *, struct item_filter *);
void event_delete(struct event *);
void event_paste_item(struct event *, time_t);
+int event_dummy(struct day_item *);
/* getstring.c */
enum getstr getstring(WINDOW *, char *, int, int, int);
@@ -1092,6 +1098,7 @@ 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);
diff --git a/src/day.c b/src/day.c
index c4d1cac..e480732 100644
--- a/src/day.c
+++ b/src/day.c
@@ -42,9 +42,15 @@
#include "calcurse.h"
+static unsigned day_nb = 7;
static vector_t day_items;
static unsigned day_items_nb = 0;
+int day_get_nb(void)
+{
+ return day_nb;
+}
+
static void day_free(struct day_item *day)
{
mem_free(day);
@@ -73,6 +79,11 @@ static int day_cmp(struct day_item **pa, struct day_item **pb)
struct day_item *b = *pb;
int a_state, b_state;
+ if (a->order < b->order)
+ return -1;
+ if (a->order > b->order)
+ return 1;
+
if ((a->type == APPT || a->type == RECUR_APPT) &&
(b->type == APPT || b->type == RECUR_APPT)) {
if (a->start < b->start)
@@ -97,11 +108,12 @@ static int day_cmp(struct day_item **pa, struct day_item **pb)
}
/* Add an item to the current day list. */
-static void day_add_item(int type, time_t start, union aptev_ptr item)
+static void day_add_item(int type, time_t start, time_t order, union aptev_ptr item)
{
struct day_item *day = mem_malloc(sizeof(struct day_item));
day->type = type;
day->start = start;
+ day->order = order;
day->item = item;
VECTOR_ADD(&day_items, day);
@@ -208,6 +220,7 @@ void day_item_fork(struct day_item *day_in, struct day_item *day_out)
{
day_out->type = day_in->type;
day_out->start = day_in->start;
+ day_out->order = day_in->order;
switch (day_in->type) {
case APPT:
@@ -245,7 +258,7 @@ static int day_store_events(time_t date)
struct event *ev = LLIST_TS_GET_DATA(i);
p.ev = ev;
- day_add_item(EVNT, ev->day, p);
+ day_add_item(EVNT, ev->day, ev->day, p);
e_nb++;
}
@@ -269,8 +282,11 @@ static int day_store_recur_events(time_t date)
struct recur_event *rev = LLIST_TS_GET_DATA(i);
p.rev = rev;
- day_add_item(RECUR_EVNT, rev->day, p);
- e_nb++;
+ time_t occurrence;
+ if (recur_event_find_occurrence(rev, date, &occurrence)) {
+ day_add_item(RECUR_EVNT, rev->day, occurrence, p);
+ e_nb++;
+ }
}
return e_nb;
@@ -294,11 +310,14 @@ static int day_store_apoints(time_t date)
struct apoint *apt = LLIST_TS_GET_DATA(i);
p.apt = apt;
-
- if (apt->start >= date + DAYLEN(date))
- break;
-
- day_add_item(APPT, apt->start, p);
+ /*
+ * For appointments continuing from the previous day, order is
+ * set to midnight to sort it before appointments of the day.
+ */
+ day_add_item(APPT,
+ apt->start,
+ apt->start < date ? date : apt->start,
+ p);
a_nb++;
}
LLIST_TS_UNLOCK(&alist_p);
@@ -325,9 +344,13 @@ static int day_store_recur_apoints(time_t date)
p.rapt = rapt;
- time_t real_start;
- if (recur_apoint_find_occurrence(rapt, date, &real_start)) {
- day_add_item(RECUR_APPT, real_start, p);
+ time_t occurrence;
+ /* As for appointments */
+ if (recur_apoint_find_occurrence(rapt, date, &occurrence)) {
+ day_add_item(RECUR_APPT,
+ occurrence,
+ occurrence < date ? date : occurrence,
+ p);
a_nb++;
}
}
@@ -337,35 +360,49 @@ static int day_store_recur_apoints(time_t date)
}
/*
- * Store all of the items to be displayed for the selected day.
- * Items are of four types: recursive events, normal events,
+ * Store all of the items to be displayed for the selected day and the following
+ * (n - 1) days. Items are of four types: recursive events, normal events,
* recursive appointments and normal appointments.
- * The items are stored in the linked list pointed by day_items
- * and the length of the new pad to write is returned.
- * The number of events and appointments in the current day are also updated.
+ * The items are stored in the day_items vector; the number of events and
+ * appointments in the vector is stored in day_items_nb,
*/
void
-day_store_items(time_t date, int include_captions)
+day_store_items(time_t date, int include_captions, int n)
{
unsigned apts, events;
- union aptev_ptr p = { NULL };
+ union aptev_ptr p = { NULL }, d;
+ int i;
day_free_vector();
day_init_vector();
- if (include_captions)
- day_add_item(DAY_HEADING, 0, p);
+ for (i = 0; i < n; i++, date = NEXTDAY(date)) {
+ if (include_captions)
+ day_add_item(DAY_HEADING, 0, date, p);
+
+ events = day_store_recur_events(date);
+ events += day_store_events(date);
+ apts = day_store_recur_apoints(date);
+ apts += day_store_apoints(date);
- events = day_store_recur_events(date);
- events += day_store_events(date);
- apts = day_store_recur_apoints(date);
- apts += day_store_apoints(date);
+ if (include_captions && events > 0 && apts > 0)
+ day_add_item(EVNT_SEPARATOR, 0, date, p);
- if (include_captions && events > 0 && apts > 0)
- day_add_item(DAY_SEPARATOR, 0, p);
+ day_items_nb += events + apts;
+
+ if (events == 0 && apts == 0) {
+ /* Insert dummy event. */
+ d.ev = &dummy;
+ dummy.mesg = _("(none)");
+ day_add_item(EVNT, DUMMY, date, d);
+ day_items_nb++;
+ }
+
+ if (include_captions && i < n - 1)
+ day_add_item(DAY_SEPARATOR, 0, ENDOFDAY(date), p);
+ }
VECTOR_SORT(&day_items, day_cmp);
- day_items_nb = events + apts;
}
/*
@@ -473,8 +510,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, get_slctd_day(), a_st, a_end);
-
+ apoint_sec2str(&apt_tmp, ui_day_selday(), a_st, a_end);
item_in_popup(a_st, a_end, day_item_get_mesg(day),
_("Appointment:"));
} else {
diff --git a/src/event.c b/src/event.c
index ed170fd..c16ca4e 100644
--- a/src/event.c
+++ b/src/event.c
@@ -43,6 +43,8 @@
#include "sha1.h"
llist_t eventlist;
+/* Dummy event for the APP panel for an otherwise empty day. */
+struct event dummy = { DUMMY, 0, "", NULL };
void event_free(struct event *ev)
{
@@ -223,3 +225,9 @@ void event_paste_item(struct event *ev, time_t date)
ev->day = date;
LLIST_ADD_SORTED(&eventlist, ev, event_cmp);
}
+
+/* Return true if the day_item is the dummy event. */
+int event_dummy(struct day_item *item)
+{
+ return item->item.ev == &dummy;
+}
diff --git a/src/ui-day.c b/src/ui-day.c
index bb5063f..32e12bf 100644
--- a/src/ui-day.c
+++ b/src/ui-day.c
@@ -36,8 +36,11 @@
#include "calcurse.h"
-struct day_item day_cut[38] = { {0, 0, {NULL}} };
+struct day_item day_cut[38] = { {0, 0, 0, {NULL}} };
+/*
+ * Return the selected item in the APP panel.
+ */
struct day_item *ui_day_selitem(void)
{
if (day_item_count(0) <= 0)
@@ -46,6 +49,14 @@ struct day_item *ui_day_selitem(void)
return day_get_item(listbox_get_sel(&lb_apt));
}
+/*
+ * Return the day (midnight) of the selected item in the APP panel.
+ */
+time_t ui_day_selday(void)
+{
+ return update_time_in_date(ui_day_selitem()->order, 0, 0);
+}
+
void ui_day_set_selitem_by_aptev_ptr(union aptev_ptr p)
{
int n = day_get_position_by_aptev_ptr(p);
@@ -579,7 +590,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 = date2sec(*ui_calendar_get_slctd_day(), 0, 0), end, saved = start;
+ time_t start = ui_day_selday(), end, saved = start;
unsigned dur;
int is_appointment = 1;
union aptev_ptr item;
@@ -672,7 +683,7 @@ 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_store_items(get_slctd_day(), 1, day_get_nb());
ui_day_load_items();
ui_day_set_selitem_by_aptev_ptr(item);
}
@@ -963,7 +974,7 @@ void ui_day_item_paste(unsigned reg)
return;
day_item_fork(&day_cut[reg], &day);
- day_paste_item(&day, get_slctd_day());
+ day_paste_item(&day, ui_day_selday());
io_set_modified();
ui_calendar_monthly_view_cache_set_invalid();
@@ -998,9 +1009,9 @@ static char *fmt_day_heading(time_t date)
/* Display appointments in the corresponding panel. */
void ui_day_draw(int n, WINDOW *win, int y, int hilt, void *cb_data)
{
- struct date slctd_date = *ui_calendar_get_slctd_day();
- time_t date = date2sec(slctd_date, 0, 0);
struct day_item *item = day_get_item(n);
+ /* The item order always indicates the date. */
+ time_t date = update_time_in_date(item->order, 0, 0);
int width = lb_apt.sw.w - 2;
hilt = hilt && (wins_slctd() == APP);
@@ -1019,7 +1030,7 @@ void ui_day_draw(int n, WINDOW *win, int y, int hilt, void *cb_data)
(width - utf8_strwidth(buf)) / 2, "%s", buf);
custom_remove_attr(win, ATTR_HIGHEST);
mem_free(buf);
- } else if (item->type == DAY_SEPARATOR) {
+ } else if (item->type == EVNT_SEPARATOR) {
wmove(win, y, 0);
whline(win, 0, width);
}
@@ -1029,7 +1040,9 @@ enum listbox_row_type ui_day_row_type(int n, void *cb_data)
{
struct day_item *item = day_get_item(n);
- if (item->type == DAY_HEADING || item->type == DAY_SEPARATOR)
+ if (item->type == DAY_HEADING ||
+ item->type == EVNT_SEPARATOR ||
+ item->type == DAY_SEPARATOR)
return LISTBOX_ROW_CAPTION;
else
return LISTBOX_ROW_TEXT;
@@ -1041,6 +1054,8 @@ int ui_day_height(int n, void *cb_data)
if (item->type == APPT || item->type == RECUR_APPT)
return 3;
+ else if (item->type == DAY_SEPARATOR)
+ return 2;
else
return 1;
}