Use generic lists for todo items.

Use the new generic list implementation instead of "next" pointers in
todo items.

Signed-off-by: Lukas Fleischer <calcurse@cryptocrack.de>
This commit is contained in:
Lukas Fleischer 2011-04-14 12:49:44 +02:00
parent 6f883c0f3f
commit bf431d6cd9
6 changed files with 103 additions and 130 deletions

View File

@ -242,7 +242,7 @@ print_notefile (FILE *out, char *filename, int nbtab)
static void static void
todo_arg (int priority, int print_note, regex_t *regex) todo_arg (int priority, int print_note, regex_t *regex)
{ {
struct todo *i; llist_item_t *i;
int title = 1; int title = 1;
char *titlestr, priority_str[BUFSIZ] = ""; char *titlestr, priority_str[BUFSIZ] = "";
char *all_todos_title = _("to do:\n"); char *all_todos_title = _("to do:\n");
@ -259,20 +259,21 @@ todo_arg (int priority, int print_note, regex_t *regex)
} while (0) } while (0)
#define DISPLAY_TODO do { \ #define DISPLAY_TODO do { \
(void)snprintf (priority_str, BUFSIZ, "%d. ", abs (i->id)); \ (void)snprintf (priority_str, BUFSIZ, "%d. ", abs (todo->id)); \
fputs (priority_str, stdout); \ fputs (priority_str, stdout); \
fputs (i->mesg, stdout); \ fputs (todo->mesg, stdout); \
fputs ("\n", stdout); \ fputs ("\n", stdout); \
if (print_note && i->note) \ if (print_note && todo->note) \
print_notefile (stdout, i->note, 1); \ print_notefile (stdout, todo->note, 1); \
} while (0) } while (0)
for (i = todolist; i != NULL; i = i->next) LLIST_FOREACH (&todolist, i)
{ {
if (regex && regexec (regex, i->mesg, 0, 0, 0) != 0) struct todo *todo = LLIST_TS_GET_DATA (i);
if (regex && regexec (regex, todo->mesg, 0, 0, 0) != 0)
continue; continue;
if (i->id < 0) /* completed task */ if (todo->id < 0) /* completed task */
{ {
if (priority == 0) if (priority == 0)
{ {
@ -282,7 +283,7 @@ todo_arg (int priority, int print_note, regex_t *regex)
} }
else else
{ {
if (priority < 0 || i->id == priority) if (priority < 0 || todo->id == priority)
{ {
DISPLAY_TITLE; DISPLAY_TITLE;
DISPLAY_TODO; DISPLAY_TODO;

View File

@ -77,6 +77,7 @@ main (int argc, char **argv)
/* Initialize non-thread-safe data structures. */ /* Initialize non-thread-safe data structures. */
event_llist_init (); event_llist_init ();
todo_init_list ();
/* /*
* Begin by parsing and handling command line arguments. * Begin by parsing and handling command line arguments.

View File

@ -278,7 +278,6 @@ struct event {
/* Todo item definition. */ /* Todo item definition. */
struct todo { struct todo {
struct todo *next;
char *mesg; char *mesg;
int id; int id;
char *note; char *note;
@ -810,7 +809,7 @@ void sigs_init (void);
unsigned sigs_set_hdlr (int, void (*)(int)); unsigned sigs_set_hdlr (int, void (*)(int));
/* todo.c */ /* todo.c */
extern struct todo *todolist; extern llist_t todolist;
void todo_hilt_set (int); void todo_hilt_set (int);
void todo_hilt_decrease (void); void todo_hilt_decrease (void);
void todo_hilt_increase (void); void todo_hilt_increase (void);
@ -831,6 +830,7 @@ void todo_edit_item (void);
void todo_update_panel (int); void todo_update_panel (int);
void todo_edit_note (char *); void todo_edit_note (char *);
void todo_view_note (char *); void todo_view_note (char *);
void todo_init_list (void);
void todo_free_list (void); void todo_free_list (void);
/* utils.c */ /* utils.c */

View File

@ -173,6 +173,7 @@ dmon_start (int parent_exit_status)
apoint_llist_init (); apoint_llist_init ();
recur_apoint_llist_init (); recur_apoint_llist_init ();
event_llist_init (); event_llist_init ();
todo_init_list ();
io_load_app (); io_load_app ();
data_loaded = 1; data_loaded = 1;

View File

@ -637,16 +637,17 @@ pcal_export_apoints (FILE *stream)
static void static void
ical_export_todo (FILE *stream) ical_export_todo (FILE *stream)
{ {
struct todo *i; llist_item_t *i;
for (i = todolist; i != NULL; i = i->next) LLIST_FOREACH (&todolist, i)
{ {
if (i->id < 0) /* completed items */ struct todo *todo = LLIST_TS_GET_DATA (i);
if (todo->id < 0) /* completed items */
continue; continue;
(void)fprintf (stream, "BEGIN:VTODO\n"); (void)fprintf (stream, "BEGIN:VTODO\n");
(void)fprintf (stream, "PRIORITY:%d\n", i->id); (void)fprintf (stream, "PRIORITY:%d\n", todo->id);
(void)fprintf (stream, "SUMMARY:%s\n", i->mesg); (void)fprintf (stream, "SUMMARY:%s\n", todo->mesg);
(void)fprintf (stream, "END:VTODO\n"); (void)fprintf (stream, "END:VTODO\n");
} }
} }
@ -654,16 +655,17 @@ ical_export_todo (FILE *stream)
static void static void
pcal_export_todo (FILE *stream) pcal_export_todo (FILE *stream)
{ {
struct todo *i; llist_item_t *i;
(void)fprintf (stream, "#\n# Todos\n#\n"); (void)fprintf (stream, "#\n# Todos\n#\n");
for (i = todolist; i != NULL; i = i->next) LLIST_FOREACH (&todolist, i)
{ {
if (i->id < 0) /* completed items */ struct todo *todo = LLIST_TS_GET_DATA (i);
if (todo->id < 0) /* completed items */
continue; continue;
(void)fprintf (stream, "note all "); (void)fprintf (stream, "note all ");
(void)fprintf (stream, "%d. %s\n", i->id, i->mesg); (void)fprintf (stream, "%d. %s\n", todo->id, todo->mesg);
} }
(void)fprintf (stream, "\n"); (void)fprintf (stream, "\n");
} }
@ -999,18 +1001,19 @@ io_save_apts (void)
unsigned unsigned
io_save_todo (void) io_save_todo (void)
{ {
struct todo *t; llist_item_t *i;
FILE *fp; FILE *fp;
if ((fp = fopen (path_todo, "w")) == NULL) if ((fp = fopen (path_todo, "w")) == NULL)
return 0; return 0;
for (t = todolist; t != NULL; t = t->next) LLIST_FOREACH (&todolist, i)
{ {
if (t->note) struct todo *todo = LLIST_TS_GET_DATA (i);
(void)fprintf (fp, "[%d]>%s %s\n", t->id, t->note, t->mesg); if (todo->note)
(void)fprintf (fp, "[%d]>%s %s\n", todo->id, todo->note, todo->mesg);
else else
(void)fprintf (fp, "[%d] %s\n", t->id, t->mesg); (void)fprintf (fp, "[%d] %s\n", todo->id, todo->mesg);
} }
file_close (fp, __FILE_POS__); file_close (fp, __FILE_POS__);

View File

@ -40,7 +40,7 @@
#include "calcurse.h" #include "calcurse.h"
struct todo *todolist; llist_t todolist;
static int hilt = 0; static int hilt = 0;
static int todos = 0; static int todos = 0;
static int first = 1; static int first = 1;
@ -50,15 +50,7 @@ static char *msgsav;
static struct todo * static struct todo *
todo_get_item (int item_number) todo_get_item (int item_number)
{ {
struct todo *o; return LLIST_GET_DATA (LLIST_NTH (&todolist, item_number - 1));
int i;
o = todolist;
for (i = 1; i < item_number; i++)
{
o = o->next;
}
return (o);
} }
/* Sets which todo is highlighted. */ /* Sets which todo is highlighted. */
@ -159,87 +151,67 @@ todo_new_item (void)
} }
} }
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));
}
/* /*
* Add an item in the todo linked list. * Add an item in the todo linked list.
*/ */
struct todo * struct todo *
todo_add (char *mesg, int id, char *note) todo_add (char *mesg, int id, char *note)
{ {
struct todo *o, **i; struct todo *todo;
int absid;
o = mem_malloc (sizeof (struct todo)); todo = mem_malloc (sizeof (struct todo));
o->mesg = mem_strdup (mesg); todo->mesg = mem_strdup (mesg);
o->id = id; todo->id = id;
o->note = (note != NULL && note[0] != '\0') ? mem_strdup (note) : NULL; todo->note = (note != NULL && note[0] != '\0') ? mem_strdup (note) : NULL;
i = &todolist;
/* LLIST_ADD_SORTED (&todolist, todo, todo_cmp_id);
* 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 return todo;
* value.
*/
absid = abs (id);
for (;;)
{
if (*i == NULL || abs ((*i)->id) > absid)
{
o->next = *i;
*i = o;
break;
}
i = &(*i)->next;
}
return (o);
} }
/* Delete a note previously attached to a todo item. */ /* Delete a note previously attached to a todo item. */
static void static void
todo_delete_note_bynum (unsigned num) todo_delete_note_bynum (unsigned num)
{ {
unsigned n; llist_item_t *i = LLIST_NTH (&todolist, num);
struct todo *i;
n = 0; if (!i)
for (i = todolist; i != NULL; i = i->next)
{
if (n == num)
{
if (i->note == NULL)
EXIT (_("no note attached"));
erase_note (&i->note, ERASE_FORCE_ONLY_NOTE);
return;
}
n++;
}
/* NOTREACHED */
EXIT (_("no such todo")); EXIT (_("no such todo"));
struct todo *todo = LLIST_TS_GET_DATA (i);
if (!todo->note)
EXIT (_("no note attached"));
erase_note (&todo->note, ERASE_FORCE_ONLY_NOTE);
} }
/* Delete an item from the todo linked list. */ /* Delete an item from the todo linked list. */
static void static void
todo_delete_bynum (unsigned num, enum eraseflg flag) todo_delete_bynum (unsigned num, enum eraseflg flag)
{ {
unsigned n; llist_item_t *i = LLIST_NTH (&todolist, num);
struct todo *i, **iptr;
n = 0; if (!i)
iptr = &todolist;
for (i = todolist; i != NULL; i = i->next)
{
if (n == num)
{
*iptr = i->next;
mem_free (i->mesg);
erase_note (&i->note, flag);
mem_free (i);
return;
}
iptr = &i->next;
n++;
}
/* NOTREACHED */
EXIT (_("no such todo")); EXIT (_("no such todo"));
struct todo *todo = LLIST_TS_GET_DATA (i);
LLIST_REMOVE (&todolist, i);
mem_free (todo->mesg);
erase_note (&todo->note, flag);
mem_free (todo);
} }
/* /*
@ -330,30 +302,21 @@ todo_delete (struct conf *conf)
* given todo item. * given todo item.
*/ */
static int static int
todo_get_position (struct todo *i) todo_get_position (struct todo *needle)
{ {
struct todo *o; llist_item_t *i;
int n = 1, found = 0; int n = 0;
for (o = todolist; o; o = o->next) LLIST_FOREACH (&todolist, i)
{ {
if (o == i)
{
found = 1;
break;
}
n++; n++;
if (LLIST_TS_GET_DATA (i) == needle)
return n;
} }
if (found)
{
return (n);
}
else
{
EXIT (_("todo not found")); EXIT (_("todo not found"));
return -1; /* avoid compiler warnings */ return -1; /* avoid compiler warnings */
} }
}
/* Change an item priority by pressing '+' or '-' inside TODO panel. */ /* Change an item priority by pressing '+' or '-' inside TODO panel. */
void void
@ -438,7 +401,7 @@ display_todo_item (int incolor, char *msg, int prio, int note, int len, int y,
void void
todo_update_panel (int which_pan) todo_update_panel (int which_pan)
{ {
struct todo *i; llist_item_t *i;
int len = win[TOD].w - 8; int len = win[TOD].w - 8;
int num_todo = 0; int num_todo = 0;
int y_offset = 3, x_offset = 1; int y_offset = 3, x_offset = 1;
@ -451,17 +414,18 @@ todo_update_panel (int which_pan)
/* Print todo item in the panel. */ /* Print todo item in the panel. */
erase_window_part (win[TOD].p, 1, title_lines, win[TOD].w - 2, erase_window_part (win[TOD].p, 1, title_lines, win[TOD].w - 2,
win[TOD].h - 2); win[TOD].h - 2);
for (i = todolist; i != NULL; i = i->next) LLIST_FOREACH (&todolist, i)
{ {
struct todo *todo = LLIST_TS_GET_DATA (i);
num_todo++; num_todo++;
t_realpos = num_todo - first; t_realpos = num_todo - first;
incolor = num_todo - hilt; incolor = num_todo - hilt;
if (incolor == 0) if (incolor == 0)
msgsav = i->mesg; msgsav = todo->mesg;
if (t_realpos >= 0 && t_realpos < max_items) if (t_realpos >= 0 && t_realpos < max_items)
{ {
display_todo_item (incolor, i->mesg, i->id, display_todo_item (incolor, todo->mesg, todo->id,
(i->note != NULL) ? 1 : 0, len, y_offset, (todo->note != NULL) ? 1 : 0, len, y_offset,
x_offset); x_offset);
y_offset = y_offset + todo_lines; y_offset = y_offset + todo_lines;
} }
@ -522,20 +486,23 @@ todo_view_note (char *pager)
wins_launch_external (fullname, pager); wins_launch_external (fullname, pager);
} }
void
todo_free (struct todo *todo)
{
mem_free (todo->mesg);
erase_note (&todo->note, ERASE_FORCE_KEEP_NOTE);
mem_free (todo);
}
void
todo_init_list (void)
{
LLIST_INIT (&todolist);
}
void void
todo_free_list (void) todo_free_list (void)
{ {
struct todo *o, **i; LLIST_FREE_INNER (&todolist, todo_free);
LLIST_FREE (&todolist);
i = &todolist;
while (*i)
{
o = *i;
*i = o->next;
mem_free (o->mesg);
erase_note (&o->note, ERASE_FORCE_KEEP_NOTE);
mem_free (o);
}
if (todolist)
mem_free (todolist);
} }