From df1bc59812c87a006904b3aac0543f71cf5484e1 Mon Sep 17 00:00:00 2001
From: Lukas Fleischer <lfleischer@calcurse.org>
Date: Mon, 18 Jan 2016 19:19:18 +0100
Subject: Make automatic selection of todo items smarter

* Automatically focus new todo items after adding them to the list.
* Keep selection when an item is moved (e.g. by changing its priority).
* Focus the next item in the list when an item is removed.

Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
---
 src/calcurse.h |  2 +-
 src/todo.c     | 21 ++++++++++++++-------
 src/ui-todo.c  | 20 +++++++++++++-------
 3 files changed, 28 insertions(+), 15 deletions(-)

(limited to 'src')

diff --git a/src/calcurse.h b/src/calcurse.h
index e6b343b..5d8c9e4 100644
--- a/src/calcurse.h
+++ b/src/calcurse.h
@@ -1026,7 +1026,7 @@ 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 *);
+int todo_get_position(struct todo *, int);
 void todo_edit_note(struct todo *, const char *);
 void todo_view_note(struct todo *, const char *);
 void todo_free(struct todo *);
diff --git a/src/todo.c b/src/todo.c
index 6cdd0d5..970991a 100644
--- a/src/todo.c
+++ b/src/todo.c
@@ -167,19 +167,26 @@ void todo_flag(struct todo *t)
  * Returns the position into the linked list corresponding to the
  * given todo item.
  */
-int todo_get_position(struct todo *needle)
+int todo_get_position(struct todo *needle, int skip_completed)
 {
 	llist_item_t *i;
 	int n = 0;
 
-	LLIST_FOREACH(&todolist, i) {
-		if (LLIST_TS_GET_DATA(i) == needle)
-			return n;
-		n++;
+	if (skip_completed) {
+		LLIST_FIND_FOREACH(&todolist, NULL, todo_is_uncompleted, i) {
+			if (LLIST_TS_GET_DATA(i) == needle)
+				return n;
+			n++;
+		}
+	} else {
+		LLIST_FOREACH(&todolist, i) {
+			if (LLIST_TS_GET_DATA(i) == needle)
+				return n;
+			n++;
+		}
 	}
 
-	EXIT(_("todo not found"));
-	return -1;		/* avoid compiler warnings */
+	return -1;
 }
 
 /* Attach a note to a todo */
diff --git a/src/ui-todo.c b/src/ui-todo.c
index b6da02d..8ad2533 100644
--- a/src/ui-todo.c
+++ b/src/ui-todo.c
@@ -44,6 +44,14 @@ static struct todo *ui_todo_selitem(void)
 			     ui_todo_view == TODO_HIDE_COMPLETED_VIEW);
 }
 
+static void ui_todo_set_selitem(struct todo *todo)
+{
+	int n = todo_get_position(todo,
+				  ui_todo_view == TODO_HIDE_COMPLETED_VIEW);
+	if (n >= 0)
+		listbox_set_sel(&lb_todo, n);
+}
+
 /* Request user to enter a new todo item. */
 void ui_todo_add(void)
 {
@@ -60,9 +68,10 @@ void ui_todo_add(void)
 			status_mesg(mesg_id, "");
 			ch = wgetch(win[KEY].p);
 		}
-		todo_add(todo_input, ch - '0', 0, NULL);
+		struct todo *todo = todo_add(todo_input, ch - '0', 0, NULL);
 		ui_todo_load_items();
 		io_set_modified();
+		ui_todo_set_selitem(todo);
 	}
 }
 
@@ -123,8 +132,7 @@ void ui_todo_edit(void)
 	todo_resort(item);
 	ui_todo_load_items();
 	io_set_modified();
-
-	listbox_set_sel(&lb_todo, todo_get_position(item));
+	ui_todo_set_selitem(item);
 }
 
 /* Pipe a todo item to an external program. */
@@ -291,8 +299,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));
+	ui_todo_set_selitem(item_new);
 }
 
 void ui_todo_popup_item(void)
@@ -313,8 +320,7 @@ void ui_todo_flag(void)
 	todo_flag(item);
 	ui_todo_load_items();
 	io_set_modified();
-
-	listbox_set_sel(&lb_todo, todo_get_position(item));
+	ui_todo_set_selitem(item);
 }
 
 void ui_todo_view_note(void)
-- 
cgit v1.2.3-70-g09d2