From 25a049951cc955b51c2c30b977ebb6cfa7160054 Mon Sep 17 00:00:00 2001
From: Lukas Fleischer <lfleischer@calcurse.org>
Date: Mon, 18 Jan 2016 18:52:24 +0100
Subject: Improve ordering of todo items

* Show uncompleted items first.
* Order uncompleted and completed items by priority.
* Order items with the same priority alphabetically.

Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
---
 src/calcurse.h |  1 +
 src/todo.c     | 22 ++++++++++++++++++++--
 src/ui-todo.c  | 10 ++++++++--
 3 files changed, 29 insertions(+), 4 deletions(-)

(limited to 'src')

diff --git a/src/calcurse.h b/src/calcurse.h
index d2ee80b..e6b343b 100644
--- a/src/calcurse.h
+++ b/src/calcurse.h
@@ -1024,6 +1024,7 @@ char *todo_hash(struct todo *);
 void todo_write(struct todo *, FILE *);
 void todo_delete_note(struct todo *);
 void todo_delete(struct todo *);
+void todo_resort(struct todo *);
 void todo_flag(struct todo *);
 int todo_get_position(struct todo *);
 void todo_edit_note(struct todo *, const char *);
diff --git a/src/todo.c b/src/todo.c
index cd0eed7..6cdd0d5 100644
--- a/src/todo.c
+++ b/src/todo.c
@@ -62,8 +62,15 @@ struct todo *todo_get_item(int item_number, int skip_completed)
 	return LLIST_GET_DATA(i);
 }
 
-static int todo_cmp_id(struct todo *a, struct todo *b)
+static int todo_cmp(struct todo *a, struct todo *b)
 {
+	if (a->completed && !b->completed)
+		return 1;
+	if (b->completed && !a->completed)
+		return -1;
+	if (a->id == b->id)
+		return strcmp(a->mesg, b->mesg);
+
 	return a->id - b->id;
 }
 
@@ -81,7 +88,7 @@ struct todo *todo_add(char *mesg, int id, int completed, char *note)
 	todo->note = (note != NULL
 		      && note[0] != '\0') ? mem_strdup(note) : NULL;
 
-	LLIST_ADD_SORTED(&todolist, todo, todo_cmp_id);
+	LLIST_ADD_SORTED(&todolist, todo, todo_cmp);
 
 	return todo;
 }
@@ -139,10 +146,21 @@ void todo_delete(struct todo *todo)
 	mem_free(todo);
 }
 
+/*
+ * Make sure an item is located at the right position within the sorted list.
+ */
+void todo_resort(struct todo *t)
+{
+	llist_item_t *i = LLIST_FIND_FIRST(&todolist, t, NULL);
+	LLIST_REMOVE(&todolist, i);
+	LLIST_ADD_SORTED(&todolist, t, todo_cmp);
+}
+
 /* Flag a todo item. */
 void todo_flag(struct todo *t)
 {
 	t->completed = !t->completed;
+	todo_resort(t);
 }
 
 /*
diff --git a/src/ui-todo.c b/src/ui-todo.c
index da5ec3e..b6da02d 100644
--- a/src/ui-todo.c
+++ b/src/ui-todo.c
@@ -120,7 +120,11 @@ void ui_todo_edit(void)
 
 	status_mesg(mesg, "");
 	updatestring(win[STA].p, &item->mesg, 0, 1);
+	todo_resort(item);
+	ui_todo_load_items();
 	io_set_modified();
+
+	listbox_set_sel(&lb_todo, todo_get_position(item));
 }
 
 /* Pipe a todo item to an external program. */
@@ -287,6 +291,7 @@ void ui_todo_chg_priority(int diff)
 	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));
 }
 
@@ -306,9 +311,10 @@ void ui_todo_flag(void)
 
 	struct todo *item = ui_todo_selitem();
 	todo_flag(item);
-	if (ui_todo_view == TODO_HIDE_COMPLETED_VIEW)
-		ui_todo_load_items();
+	ui_todo_load_items();
 	io_set_modified();
+
+	listbox_set_sel(&lb_todo, todo_get_position(item));
 }
 
 void ui_todo_view_note(void)
-- 
cgit v1.2.3-70-g09d2