From beea88e5feb6f14b4912c6aa4878c39a7632977c Mon Sep 17 00:00:00 2001 From: Lukas Fleischer Date: Sun, 17 Jan 2016 22:46:24 +0100 Subject: Use a separate field for the completed status Add a new field that indicates whether a todo item is completed or not instead of encoding completed todo items by negative priorities. Signed-off-by: Lukas Fleischer --- src/calcurse.h | 3 ++- src/ical.c | 18 +++++++----------- src/io.c | 19 ++++++++++++++----- src/pcal.c | 2 +- src/todo.c | 30 ++++++++++-------------------- src/ui-todo.c | 11 ++++++----- 6 files changed, 40 insertions(+), 43 deletions(-) diff --git a/src/calcurse.h b/src/calcurse.h index 27fcc68..67f95fa 100644 --- a/src/calcurse.h +++ b/src/calcurse.h @@ -323,6 +323,7 @@ struct event { struct todo { char *mesg; int id; + int completed; char *note; }; @@ -1017,7 +1018,7 @@ int string_printf(struct string *, const char *, ...); /* todo.c */ extern llist_t todolist; struct todo *todo_get_item(int, int); -struct todo *todo_add(char *, int, char *); +struct todo *todo_add(char *, int, int, char *); char *todo_tostr(struct todo *); char *todo_hash(struct todo *); void todo_write(struct todo *, FILE *); diff --git a/src/ical.c b/src/ical.c index 93952ec..dfb5dd7 100644 --- a/src/ical.c +++ b/src/ical.c @@ -266,14 +266,11 @@ static void ical_export_todo(FILE * stream, int export_uid) LLIST_FOREACH(&todolist, i) { struct todo *todo = LLIST_TS_GET_DATA(i); - int priority = todo->id; fputs("BEGIN:VTODO\n", stream); - if (todo->id < 0) { + if (todo->completed) fprintf(stream, "STATUS:COMPLETED\n"); - priority = -priority; - } - fprintf(stream, "PRIORITY:%d\n", priority); + fprintf(stream, "PRIORITY:%d\n", todo->id); fprintf(stream, "SUMMARY:%s\n", todo->mesg); if (export_uid) { @@ -327,9 +324,10 @@ static void ical_log(FILE * log, ical_types_e type, unsigned lineno, fprintf(log, "%s [%d]: %s\n", typestr[type], lineno, msg); } -static void ical_store_todo(int priority, char *mesg, char *note, int list) +static void ical_store_todo(int priority, int completed, char *mesg, + char *note, int list) { - struct todo *todo = todo_add(mesg, priority, note); + struct todo *todo = todo_add(mesg, priority, completed, note); if (list) { char *hash = todo_hash(todo); printf("%s\n", hash); @@ -1081,16 +1079,14 @@ ical_read_todo(FILE * fdi, FILE * log, int list, unsigned *notodos, if (starts_with_ci(buf, "END:VTODO")) { if (!vtodo.has_priority) vtodo.priority = LOWEST; - if (vtodo.completed) - vtodo.priority = -vtodo.priority; if (!vtodo.mesg) { ical_log(log, ICAL_VTODO, ITEMLINE, _("could not retrieve item summary.")); goto cleanup; } - ical_store_todo(vtodo.priority, vtodo.mesg, - vtodo.note, list); + ical_store_todo(vtodo.priority, vtodo.completed, + vtodo.mesg, vtodo.note, list); (*notodos)++; return; } diff --git a/src/io.c b/src/io.c index b0eca77..4ff16cd 100644 --- a/src/io.c +++ b/src/io.c @@ -630,7 +630,7 @@ void io_load_todo(struct item_filter *filter) FILE *data_file; char *newline; int nb_tod = 0; - int c, id; + int c, id, completed; char buf[BUFSIZ], e_todo[BUFSIZ], note[MAX_NOTESIZ + 1]; unsigned line = 0; @@ -642,7 +642,15 @@ void io_load_todo(struct item_filter *filter) c = getc(data_file); if (c == EOF) { break; - } else if (c == '[') { /* new style with id */ + } else if (c == '[') { + /* new style with id */ + c = getc(data_file); + if (c == '-') { + completed = 1; + } else { + completed = 0; + ungetc(c, data_file); + } if (fscanf(data_file, " %d ", &id) != 1 || getc(data_file) != ']') io_load_error(path_todo, line, @@ -651,6 +659,7 @@ void io_load_todo(struct item_filter *filter) ungetc(c, data_file); } else { id = 9; + completed = 0; ungetc(c, data_file); } /* Now read the attached note, if any. */ @@ -678,13 +687,13 @@ void io_load_todo(struct item_filter *filter) continue; if (filter->priority && id != filter->priority) continue; - if (filter->completed && id > 0) + if (filter->completed && !completed) continue; - if (filter->uncompleted && id < 0) + if (filter->uncompleted && completed) continue; } - struct todo *todo = todo_add(e_todo, id, note); + struct todo *todo = todo_add(e_todo, id, completed, note); /* Filter by hash. */ if (filter && filter->hash) { diff --git a/src/pcal.c b/src/pcal.c index db85e1c..1c76aa0 100644 --- a/src/pcal.c +++ b/src/pcal.c @@ -311,7 +311,7 @@ static void pcal_export_todo(FILE * stream) fputs("#\n# Todos\n#\n", stream); LLIST_FOREACH(&todolist, i) { struct todo *todo = LLIST_TS_GET_DATA(i); - if (todo->id < 0) /* completed items */ + if (todo->completed) continue; fputs("note all ", stream); diff --git a/src/todo.c b/src/todo.c index 707628c..cd0eed7 100644 --- a/src/todo.c +++ b/src/todo.c @@ -45,7 +45,7 @@ llist_t todolist; static int todo_is_uncompleted(struct todo *todo, void *cbdata) { - return todo->id >= 0; + return !todo->completed; } /* Returns a structure containing the selected item. */ @@ -64,27 +64,20 @@ struct todo *todo_get_item(int item_number, int skip_completed) static int todo_cmp_id(struct todo *a, struct todo *b) { - /* - * As of version 2.6, todo items can have a negative id, which means they - * were completed. To keep them sorted, we need to consider the absolute id - * value. - */ - int abs_a = abs(a->id); - int abs_b = abs(b->id); - - return abs_a < abs_b ? -1 : (abs_a == abs_b ? 0 : 1); + return a->id - b->id; } /* * Add an item in the todo linked list. */ -struct todo *todo_add(char *mesg, int id, char *note) +struct todo *todo_add(char *mesg, int id, int completed, char *note) { struct todo *todo; todo = mem_malloc(sizeof(struct todo)); todo->mesg = mem_strdup(mesg); todo->id = id; + todo->completed = completed; todo->note = (note != NULL && note[0] != '\0') ? mem_strdup(note) : NULL; @@ -96,11 +89,13 @@ struct todo *todo_add(char *mesg, int id, char *note) char *todo_tostr(struct todo *todo) { char *res; + const char *cstr = todo->completed ? "-" : ""; if (todo->note) - asprintf(&res, "[%d]>%s %s", todo->id, todo->note, todo->mesg); + asprintf(&res, "[%s%d]>%s %s", cstr, todo->id, todo->note, + todo->mesg); else - asprintf(&res, "[%d] %s", todo->id, todo->mesg); + asprintf(&res, "[%s%d] %s", cstr, todo->id, todo->mesg); return res; } @@ -144,15 +139,10 @@ void todo_delete(struct todo *todo) mem_free(todo); } -/* - * Flag a todo item (for now on, only the 'completed' state is available). - * Internally, a completed item keeps its priority, but it becomes negative. - * This way, it is easy to retrive its original priority if the user decides - * that in fact it was not completed. - */ +/* Flag a todo item. */ void todo_flag(struct todo *t) { - t->id = -t->id; + t->completed = !t->completed; } /* diff --git a/src/ui-todo.c b/src/ui-todo.c index 86592c1..2a03844 100644 --- a/src/ui-todo.c +++ b/src/ui-todo.c @@ -60,7 +60,7 @@ void ui_todo_add(void) status_mesg(mesg_id, ""); ch = wgetch(win[KEY].p); } - todo_add(todo_input, ch - '0', NULL); + todo_add(todo_input, ch - '0', 0, NULL); ui_todo_load_items(); io_set_modified(); } @@ -163,14 +163,14 @@ void ui_todo_draw(int n, WINDOW *win, int y, int hilt, void *cb_data) int j; if (ui_todo_view == TODO_HIDE_COMPLETED_VIEW) { - while (i && todo->id < 0) { + while (i && todo->completed) { i = i->next; if (i) todo = LLIST_TS_GET_DATA(i); } } - mark[0] = todo->id > 0 ? '0' + todo->id : 'X'; + mark[0] = todo->completed ? 'X' : '0' + todo->id; mark[1] = todo->note ? '>' : '.'; hilt = hilt && (wins_slctd() == TOD); @@ -217,7 +217,8 @@ void ui_todo_load_items(void) /* TODO: Optimize this by keeping the list size in a variable. */ LLIST_FOREACH(&todolist, i) { struct todo *todo = LLIST_TS_GET_DATA(i); - if (ui_todo_view == TODO_HIDE_COMPLETED_VIEW && todo->id < 0) + if (ui_todo_view == TODO_HIDE_COMPLETED_VIEW && + todo->completed) continue; n++; } @@ -263,7 +264,7 @@ void ui_todo_chg_priority(int diff) else if (id > 9) id = 9; - item_new = todo_add(item->mesg, id, item->note); + item_new = todo_add(item->mesg, id, item->completed, item->note); todo_delete(item); io_set_modified(); listbox_set_sel(&lb_todo, todo_get_position(item_new)); -- cgit v1.2.3-54-g00ecf