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:
parent
6f883c0f3f
commit
bf431d6cd9
19
src/args.c
19
src/args.c
@ -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;
|
||||||
|
@ -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.
|
||||||
|
@ -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 */
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
31
src/io.c
31
src/io.c
@ -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__);
|
||||||
|
|
||||||
|
177
src/todo.c
177
src/todo.c
@ -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)
|
EXIT (_("no such todo"));
|
||||||
{
|
struct todo *todo = LLIST_TS_GET_DATA (i);
|
||||||
if (n == num)
|
|
||||||
{
|
if (!todo->note)
|
||||||
if (i->note == NULL)
|
EXIT (_("no note attached"));
|
||||||
EXIT (_("no note attached"));
|
erase_note (&todo->note, ERASE_FORCE_ONLY_NOTE);
|
||||||
erase_note (&i->note, ERASE_FORCE_ONLY_NOTE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
/* NOTREACHED */
|
|
||||||
EXIT (_("no such todo"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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;
|
EXIT (_("no such todo"));
|
||||||
for (i = todolist; i != NULL; i = i->next)
|
struct todo *todo = LLIST_TS_GET_DATA (i);
|
||||||
{
|
|
||||||
if (n == num)
|
LLIST_REMOVE (&todolist, i);
|
||||||
{
|
mem_free (todo->mesg);
|
||||||
*iptr = i->next;
|
erase_note (&todo->note, flag);
|
||||||
mem_free (i->mesg);
|
mem_free (todo);
|
||||||
erase_note (&i->note, flag);
|
|
||||||
mem_free (i);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
iptr = &i->next;
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
/* NOTREACHED */
|
|
||||||
EXIT (_("no such todo"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -330,29 +302,20 @@ 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)
|
|
||||||
{
|
EXIT (_("todo not found"));
|
||||||
return (n);
|
return -1; /* avoid compiler warnings */
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
EXIT (_("todo not found"));
|
|
||||||
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. */
|
||||||
@ -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);
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user