From 738a3a417071bfaed53297cbefad39b996e55dfb Mon Sep 17 00:00:00 2001
From: Frederic Culot <calcurse@culot.org>
Date: Sun, 13 Jan 2008 12:40:45 +0000
Subject: Ability to attach notes to appointments and events added

---
 src/apoint.c   |  73 ++++++++++----------
 src/apoint.h   |  12 ++--
 src/calcurse.c |   8 +--
 src/day.c      | 207 +++++++++++++++++++++++++++++++++++++++++----------------
 src/day.h      |   7 +-
 src/event.c    |  33 ++++++---
 src/event.h    |  10 +--
 src/io.c       |  31 ++++++---
 src/recur.c    | 138 +++++++++++++++++++++++---------------
 src/recur.h    |  25 ++++---
 src/todo.c     |  13 +---
 src/utils.c    |  21 +++++-
 src/utils.h    |   5 +-
 13 files changed, 375 insertions(+), 208 deletions(-)

(limited to 'src')

diff --git a/src/apoint.c b/src/apoint.c
index d963cd8..03573e6 100755
--- a/src/apoint.c
+++ b/src/apoint.c
@@ -1,8 +1,8 @@
-/*	$calcurse: apoint.c,v 1.19 2007/12/30 16:27:58 culot Exp $	*/
+/*	$calcurse: apoint.c,v 1.20 2008/01/13 12:40:45 culot Exp $	*/
 
 /*
  * Calcurse - text-based organizer
- * Copyright (c) 2004-2007 Frederic Culot
+ * Copyright (c) 2004-2008 Frederic Culot
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -43,7 +43,8 @@
 apoint_llist_t *alist_p;
 static int	hilt = 0;
 
-int apoint_llist_init(void)
+int 
+apoint_llist_init(void)
 {
 	alist_p = (apoint_llist_t *) malloc(sizeof(apoint_llist_t));
 	alist_p->root = NULL;
@@ -79,13 +80,14 @@ apoint_hilt(void)
 }
 
 apoint_llist_node_t *
-apoint_new(char *mesg, long start, long dur, char state)
+apoint_new(char *mesg, char *note, long start, long dur, char state)
 {
 	apoint_llist_node_t *o, **i;
 
 	o = (apoint_llist_node_t *) malloc(sizeof(apoint_llist_node_t));
 	o->mesg = (char *) malloc(strlen(mesg) + 1);
 	strncpy(o->mesg, mesg, strlen(mesg) + 1);
+	o->note = note;
 	o->state = state;
 	o->start = start;
 	o->dur = dur;
@@ -192,12 +194,12 @@ apoint_add(void)
 			apoint_start = 
 			    date2sec(*calendar_get_slctd_day(), heures, 
 			    minutes);
-			apoint_pointeur = apoint_new(item_mesg, apoint_start,
+			apoint_pointeur = apoint_new(item_mesg, 0L, apoint_start,
 			    min2sec(apoint_duration), 0L);
 			if (notify_bar()) 
 				notify_check_added(item_mesg, apoint_start, 0L);
                 } else 
-                        event_pointeur = event_new(item_mesg, 
+                        event_pointeur = event_new(item_mesg, 0L,
 			    date2sec(*calendar_get_slctd_day(), 12, 0), Id);
 
 		if (hilt == 0) 
@@ -317,6 +319,9 @@ apoint_write(apoint_llist_node_t *o, FILE * f)
 	    lt->tm_mon + 1, lt->tm_mday, 1900 + lt->tm_year,
 	    lt->tm_hour, lt->tm_min);
 	
+	if (o->note != NULL)
+		fprintf(f, ">%s ", o->note);
+
 	if (o->state & APOINT_NOTIFY)
 		fprintf(f, "!");
 	else
@@ -326,7 +331,7 @@ apoint_write(apoint_llist_node_t *o, FILE * f)
 }
 
 apoint_llist_node_t *
-apoint_scan(FILE * f, struct tm start, struct tm end, char state)
+apoint_scan(FILE * f, struct tm start, struct tm end, char state, char *note)
 {
 	struct tm *lt;
 	char buf[MESG_MAXSIZE], *nl;
@@ -355,29 +360,37 @@ apoint_scan(FILE * f, struct tm start, struct tm end, char state)
 		fputs(_("FATAL ERROR in apoint_scan: date error in the appointment\n"), stderr);
 		exit(EXIT_FAILURE);
 	}
-	return apoint_new(buf, tstart, tend - tstart, state);
+	return (apoint_new(buf, note, tstart, tend - tstart, state));
 }
 
-void apoint_delete_bynum(long start, unsigned num)
+void 
+apoint_delete_bynum(long start, unsigned num, int only_note)
 {
 	unsigned n;
 	int need_check_notify = 0;
 	apoint_llist_node_t *i, **iptr;
 
-	n = 0;
-	
+	n = 0;	
 	pthread_mutex_lock(&(alist_p->mutex));
 	iptr = &alist_p->root;
 	for (i = alist_p->root; i != 0; i = i->next) {
 		if (apoint_inday(i, start)) {
 			if (n == num) {
-				if (notify_bar()) 
-					need_check_notify = notify_same_item(i->start);	 
-				*iptr = i->next;
-				free(i->mesg);
-				free(i);
-				pthread_mutex_unlock(&(alist_p->mutex));
-				if (need_check_notify) notify_check_next_app();
+				if (only_note)
+					erase_note(&i->note);
+				else {
+					if (notify_bar()) 
+						need_check_notify = 
+						    notify_same_item(i->start);
+					*iptr = i->next;
+					free(i->mesg);
+					if (i->note != NULL)
+						erase_note(&i->note);
+					free(i);
+					pthread_mutex_unlock(&(alist_p->mutex));
+					if (need_check_notify) 
+						notify_check_next_app();
+				}
 				return;
 			}
 			n++;
@@ -414,7 +427,8 @@ get_item_line(int item_nb, int nb_events_inday)
  * Update (if necessary) the first displayed pad line to make the
  * appointment panel scroll down next time pnoutrefresh is called. 
  */
-void apoint_scroll_pad_down(int nb_events_inday, int win_length) 
+void 
+apoint_scroll_pad_down(int nb_events_inday, int win_length) 
 {
 	int pad_last_line = 0;
 	int item_first_line = 0, item_last_line = 0;
@@ -435,7 +449,8 @@ void apoint_scroll_pad_down(int nb_events_inday, int win_length)
  * Update (if necessary) the first displayed pad line to make the
  * appointment panel scroll up next time pnoutrefresh is called. 
  */
-void apoint_scroll_pad_up(int nb_events_inday)
+void 
+apoint_scroll_pad_up(int nb_events_inday)
 {
 	int item_first_line = 0;
 
@@ -476,8 +491,8 @@ apoint_check_next(struct notify_app_s *app, long start)
  * Returns a structure of type apoint_llist_t given a structure of type 
  * recur_apoint_s 
  */
-apoint_llist_node_t *apoint_recur_s2apoint_s(
-	recur_apoint_llist_node_t *p)
+apoint_llist_node_t *
+apoint_recur_s2apoint_s(recur_apoint_llist_node_t *p)
 {
 	apoint_llist_node_t *a;
 
@@ -589,17 +604,3 @@ apoint_update_panel(window_t *winapp, int which_pan)
 	    winapp->y + title_lines + 1, winapp->x + bordr, 
     	    winapp->y + winapp->h - 2*bordr, winapp->x + winapp->w - 3*bordr);
 }
-
-/* Attach a note to an appointment or event */
-void 
-apoint_edit_note(void)
-{
-
-}
-
-/* View a note previously attached to an appointment or event */
-void 
-apoint_view_note(void)
-{
-
-}
diff --git a/src/apoint.h b/src/apoint.h
index 182f03d..3f5d704 100755
--- a/src/apoint.h
+++ b/src/apoint.h
@@ -1,8 +1,8 @@
-/*	$calcurse: apoint.h,v 1.10 2007/12/30 16:27:58 culot Exp $	*/
+/*	$calcurse: apoint.h,v 1.11 2008/01/13 12:40:45 culot Exp $	*/
 
 /*
  * Calcurse - text-based organizer
- * Copyright (c) 2004-2007 Frederic Culot
+ * Copyright (c) 2004-2008 Frederic Culot
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -59,22 +59,20 @@ void			apoint_hilt_set(int);
 void			apoint_hilt_decrease(void);
 void			apoint_hilt_increase(void);
 int			apoint_hilt(void);
-apoint_llist_node_t    *apoint_new(char *, long, long, char);
+apoint_llist_node_t    *apoint_new(char *, char *, long, long, char);
 void			apoint_add(void);
 void			apoint_delete(conf_t *, unsigned *, unsigned *);
 unsigned 		apoint_inday(apoint_llist_node_t *, long);
 void 			apoint_sec2str(apoint_llist_node_t *, int, long, 
 			    char *, char *);
 void 			apoint_write(apoint_llist_node_t *, FILE *);
-apoint_llist_node_t    *apoint_scan(FILE *, struct tm, struct tm, char);
-void 			apoint_delete_bynum(long, unsigned);
+apoint_llist_node_t    *apoint_scan(FILE *, struct tm, struct tm, char, char *);
+void 			apoint_delete_bynum(long, unsigned, int);
 void 			apoint_scroll_pad_down(int, int);
 void 			apoint_scroll_pad_up(int);
 struct notify_app_s    *apoint_check_next(struct notify_app_s *, long);
 apoint_llist_node_t    *apoint_recur_s2apoint_s(recur_apoint_llist_node_t *);
 void 			apoint_switch_notify(void);
 void			apoint_update_panel(window_t *, int);
-void			apoint_edit_note(void);
-void			apoint_view_note(void);
 
 #endif /* CALCURSE_APOINT_H */
diff --git a/src/calcurse.c b/src/calcurse.c
index ab25298..d004ae8 100755
--- a/src/calcurse.c
+++ b/src/calcurse.c
@@ -1,8 +1,8 @@
-/*	$calcurse: calcurse.c,v 1.59 2007/12/30 16:27:58 culot Exp $	*/
+/*	$calcurse: calcurse.c,v 1.60 2008/01/13 12:40:45 culot Exp $	*/
 
 /*
  * Calcurse - text-based organizer
- * Copyright (c) 2004-2007 Frederic Culot
+ * Copyright (c) 2004-2008 Frederic Culot
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -350,7 +350,7 @@ main(int argc, char **argv)
 		case 'n':	
 			/* Attach a note to an item, create it if necessary */
 			if (wins_slctd() == APP && apoint_hilt() != 0)
-				apoint_edit_note();
+				day_edit_note(conf.editor);
 			else if (wins_slctd() == TOD && todo_hilt() != 0)
 				todo_edit_note(conf.editor);
 			do_storage = true;
@@ -359,7 +359,7 @@ main(int argc, char **argv)
 		case '>':	
 			/* View a note previously attached to an item */
 			if (wins_slctd() == APP && apoint_hilt() != 0)
-				apoint_view_note();
+				day_view_note(conf.pager);
 			else if (wins_slctd() == TOD && todo_hilt() != 0)
 				todo_view_note(conf.pager);
 			break;
diff --git a/src/day.c b/src/day.c
index 0d27bee..052bda2 100755
--- a/src/day.c
+++ b/src/day.c
@@ -1,8 +1,8 @@
-/*	$calcurse: day.c,v 1.31 2007/12/30 16:27:59 culot Exp $	*/
+/*	$calcurse: day.c,v 1.32 2008/01/13 12:40:45 culot Exp $	*/
 
 /*
  * Calcurse - text-based organizer
- * Copyright (c) 2004-2007 Frederic Culot
+ * Copyright (c) 2004-2008 Frederic Culot
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -56,12 +56,13 @@ day_free_list(void)
 
 /* Add an event in the current day list */
 static struct day_item_s *
-day_add_event(int type, char *mesg, long day, int id)
+day_add_event(int type, char *mesg, char *note, long day, int id)
 {
 	struct day_item_s *o, **i;
 	o = (struct day_item_s *) malloc(sizeof(struct day_item_s));
 	o->mesg = (char *) malloc(strlen(mesg) + 1);
 	strncpy(o->mesg, mesg, strlen(mesg) + 1);
+	o->note = note;
 	o->type = type;
 	o->appt_dur = 0;
 	o->appt_pos = 0;
@@ -81,8 +82,8 @@ day_add_event(int type, char *mesg, long day, int id)
 
 /* Add an appointment in the current day list. */
 static struct day_item_s *
-day_add_apoint(int type, char *mesg, long start, long dur, char state, 
-    int real_pos)
+day_add_apoint(int type, char *mesg, char *note, long start, long dur, 
+    char state, int real_pos)
 {
 	struct day_item_s *o, **i;
 	int insert_item = 0;
@@ -90,6 +91,7 @@ day_add_apoint(int type, char *mesg, long start, long dur, char state,
 	o = (struct day_item_s *) malloc(sizeof(struct day_item_s));
 	o->mesg = (char *) malloc(strlen(mesg) + 1);
 	strncpy(o->mesg, mesg, strlen(mesg) + 1);
+	o->note = note;
 	o->start = start;
 	o->appt_dur = dur;
 	o->appt_pos = real_pos;
@@ -131,7 +133,8 @@ day_store_events(long date)
 	for (j = eventlist; j != 0; j = j->next) {
 		if (event_inday(j, date)) {
 			e_nb++;
-			ptr = day_add_event(EVNT, j->mesg, j->day, j->id);
+			ptr = day_add_event(EVNT, j->mesg, j->note, j->day, 
+			    j->id);
 		}	
 	}
 
@@ -154,9 +157,10 @@ day_store_recur_events(long date)
 
 	for (j = recur_elist; j != 0; j = j->next) {
 		if (recur_item_inday(j->day, j->exc, j->rpt->type, j->rpt->freq,
-			j->rpt->until, date)) {
+		    j->rpt->until, date)) {
 			e_nb++;
-			ptr = day_add_event(RECUR_EVNT, j->mesg, j->day, j->id);
+			ptr = day_add_event(RECUR_EVNT, j->mesg, j->note, 
+			    j->day, j->id);
 		}	
 	}
 
@@ -181,8 +185,8 @@ day_store_apoints(long date)
 	for (j = alist_p->root; j != 0; j = j->next) {
 		if (apoint_inday(j, date)) {
 			a_nb++;
-			ptr = day_add_apoint(APPT, j->mesg, j->start, j->dur, 
-			    j->state, 0);
+			ptr = day_add_apoint(APPT, j->mesg, j->note, j->start, 
+			    j->dur, j->state, 0);
 		}	
 	}
 	pthread_mutex_unlock(&(alist_p->mutex));
@@ -210,9 +214,8 @@ day_store_recur_apoints(long date)
 		if ((real_start = recur_item_inday(j->start, j->exc, 
 		    j->rpt->type, j->rpt->freq, j->rpt->until, date)) ){
 			a_nb++;
-			ptr = day_add_apoint(
-			    RECUR_APPT, j->mesg, real_start, j->dur, 
-			    j->state, n);
+			ptr = day_add_apoint(RECUR_APPT, j->mesg, j->note,
+			    real_start, j->dur, j->state, n);
 			n++;
 		}	
 	}
@@ -397,8 +400,8 @@ day_write_pad(long date, int width, int length, int incolor)
 				day_saved_item->type = p->type;
 				day_saved_item->mesg = p->mesg;
 			}
-			display_item(item_number - incolor, p->mesg, recur, 0, 
-			    width - 7, line, x_pos);
+			display_item(item_number - incolor, p->mesg, recur,
+			    (p->note != NULL) ? 1 : 0, width - 7, line, x_pos);
 			line++;
 			draw_line = true;
 		} else {
@@ -420,9 +423,10 @@ day_write_pad(long date, int width, int length, int incolor)
 			}
 			display_item_date(item_number - incolor, &a, p->type, 
 			    date, line + 1, x_pos);	
-			display_item(item_number - incolor, p->mesg, 0, 0, 
-			    width - 7, line + 2, x_pos);
-			line = line + 3;
+			display_item(item_number - incolor, p->mesg, 0, 
+			    (p->note != NULL) ? 1 : 0, width - 7, line + 2, 
+			    x_pos);
+			line += 3;
 		}
 	}
 }
@@ -448,7 +452,7 @@ void day_popup_item(void)
  * Need to know if there is an item for the current selected day inside
  * calendar. This is used to put the correct colors inside calendar panel.
  */
- int day_check_if_item(date_t day) {
+int day_check_if_item(date_t day) {
 	struct recur_event_s  *re;
 	recur_apoint_llist_node_t *ra;
 	struct event_s *e;
@@ -485,9 +489,41 @@ void day_popup_item(void)
 	return 0;
 }
 
+/* Update an existing item. */
+static void update_item(long date, int item_num, struct day_item_s *p, 
+    struct rpt_s *rpt)
+{
+	recur_apoint_llist_node_t *ra_new;
+
+	day_erase_item(date, item_num, 1);
+
+	switch (p->type) {
+	case RECUR_EVNT:
+		recur_event_new(p->mesg, p->note, p->start, p->evnt_id,
+			rpt->type, rpt->freq, rpt->until, NULL);
+		break;
+	case EVNT:
+		event_new(p->mesg, p->note, p->start, p->evnt_id);
+		break;
+	case RECUR_APPT:
+		ra_new = recur_apoint_new(p->mesg, p->note, p->start, 
+		    p->appt_dur, p->state, rpt->type, rpt->freq, rpt->until, 
+		    NULL);
+		if (notify_bar()) 
+			notify_check_repeated(ra_new);
+		break;
+	case APPT:
+		apoint_new(p->mesg, p->note, p->start, p->appt_dur, p->state);
+		if (notify_bar()) 
+			notify_check_added(p->mesg, p->start, p->state);
+		break;
+	}
+}
+
 /* Request the user to enter a new time. */
 static char *
-day_edit_time(long time) {
+day_edit_time(long time)
+{
 	char *timestr;
 	char *msg_time = _("Enter the new time ([hh:mm] or [h:mm]) : ");
         char *enter_str = _("Press [Enter] to continue");
@@ -521,7 +557,7 @@ day_edit_item(void)
 	struct tm *lt;
 	time_t t;
 	date_t new_date;
-	recur_apoint_llist_node_t *ra, *ra_new;
+	recur_apoint_llist_node_t *ra;
 	long date, newtime = 0;
 	int cancel, ch = 0, valid_date = 0, newfreq = 0, date_entered = 0;
 	int newmonth, newday, newyear;
@@ -697,28 +733,7 @@ day_edit_item(void)
 		rpt->type = recur_char2def(ch);
 		break;
 	}
-	day_erase_item(date, item_num, 1);
-
-	switch (p->type) {
-	case RECUR_EVNT:
-		recur_event_new(p->mesg, p->start, p->evnt_id, 
-			rpt->type, rpt->freq, rpt->until, NULL);
-		break;
-	case EVNT:
-		event_new(p->mesg, p->start, p->evnt_id);
-		break;
-	case RECUR_APPT:
-		ra_new = recur_apoint_new(p->mesg, p->start, p->appt_dur, 
-			p->state, rpt->type, rpt->freq, rpt->until, NULL);
-		if (notify_bar()) 
-			notify_check_repeated(ra_new);
-		break;
-	case APPT:
-		apoint_new(p->mesg, p->start, p->appt_dur, p->state);
-		if (notify_bar()) 
-			notify_check_added(p->mesg, p->start, p->state);
-		break;
-	}
+	update_item(date, item_num, p, rpt);
 }
 
 /*
@@ -727,26 +742,48 @@ day_edit_item(void)
  * recurrent appointments and appointments) and then to test the
  * type of the item to be deleted.
  */
-int day_erase_item(long date, int item_number, int force_erase) {
-	int ch = 0;
-	unsigned delete_whole;
+int 
+day_erase_item(long date, int item_number, int force_erase) 
+{
 	struct day_item_s *p;
 	char *erase_warning =
 		_("This item is recurrent. "
 		  "Delete (a)ll occurences or just this (o)ne ?");
-	char *erase_choice =
-		_("[a/o] ");
+	char *note_warning =
+		_("This item has a note attached to it. "
+		  "Delete (i)tem or just its (n)ote ?");
+	char *note_choice = _("[i/n] ");
+	char *erase_choice = _("[a/o] ");
+	int ch = 0, only_note, has_note, ans = 0;
+	unsigned delete_whole;
 
-	if (force_erase) 
+	p = day_get_item(item_number);	
+	if (force_erase) {
 		ch = 'a';
+		only_note = 0;
+	} else {
+		has_note = (p->note != NULL ) ? 1 : 0;
+		if (has_note == 0)
+			ans = 'i';
+		while (ans != 'i' && ans != 'n') {
+			status_mesg(note_warning, note_choice);
+			ans = wgetch(win[STA].p);
+		}
+		if (ans == 'i')
+			only_note = 0;
+		else
+			only_note = 1;
+	}
 
-	p = day_get_item(item_number);
-	
 	if (p->type == EVNT) {
-		event_delete_bynum(date, day_item_nb(date, item_number, EVNT));
+		event_delete_bynum(date, day_item_nb(date, item_number, EVNT),
+		    only_note);
 	} else if (p->type == APPT) {
-		apoint_delete_bynum(date, day_item_nb(date, item_number, APPT));
+		apoint_delete_bynum(date, day_item_nb(date, item_number, APPT),
+		    only_note);
 	} else {
+		if (only_note)
+			ch = 'a';
 		while ( (ch != 'a') && (ch != 'o') && (ch != ESCAPE)) {
 			status_mesg(erase_warning, erase_choice);
 			ch = wgetch(win[STA].p);
@@ -761,12 +798,13 @@ int day_erase_item(long date, int item_number, int force_erase) {
 		if (p->type == RECUR_EVNT) {
 			recur_event_erase(date, 
 			    day_item_nb(date, item_number, RECUR_EVNT), 
-			    delete_whole);
+			    delete_whole, only_note);
 		} else {
-			recur_apoint_erase(date, p->appt_pos, delete_whole);
+			recur_apoint_erase(date, p->appt_pos, delete_whole, 
+			    only_note);
 		}
 	}
-	return p->type;
+	return (p->type);
 }
 
 /* Returns a structure containing the selected item. */
@@ -801,3 +839,60 @@ day_item_nb(long date, int day_num, int type)
 
 	return (nb_item[type - 1]);
 }
+
+/* Attach a note to an appointment or event. */
+void
+day_edit_note(char *editor)
+{
+	struct day_item_s *p;
+	recur_apoint_llist_node_t *ra;
+	struct recur_event_s *re;
+	struct rpt_s *rpt;
+	char fullname[BUFSIZ];
+	char *filename;
+	long date;
+	int item_num;
+
+	item_num = apoint_hilt();
+	p = day_get_item(item_num);
+	if (p->note == NULL) {
+		if ((filename = new_tempfile(path_notes, NOTESIZ))
+		    != NULL)
+			p->note = filename;
+		else
+			return;
+	}
+	snprintf(fullname, BUFSIZ, "%s%s", path_notes, p->note);
+	wins_launch_external(fullname, editor);
+
+	date = calendar_get_slctd_day_sec();
+	switch (p->type) {
+	case RECUR_EVNT:
+		re = recur_get_event(date, 
+		    day_item_nb(date, item_num, RECUR_EVNT));
+		rpt = re->rpt;
+		break;
+	case RECUR_APPT:
+		ra = recur_get_apoint(date, 
+		    day_item_nb(date, item_num, RECUR_APPT));
+		rpt = ra->rpt;
+		break;
+	default:
+		rpt = NULL;
+	}
+	update_item(date, item_num, p, rpt);
+}
+
+/* View a note previously attached to an appointment or event */
+void 
+day_view_note(char *pager)
+{
+	struct day_item_s *p;
+	char fullname[BUFSIZ];
+
+	p = day_get_item(apoint_hilt());
+	if (p->note == NULL)
+		return;
+	snprintf(fullname, BUFSIZ, "%s%s", path_notes, p->note);
+	wins_launch_external(fullname, pager);
+}
diff --git a/src/day.h b/src/day.h
index 73b88b6..a1866d2 100755
--- a/src/day.h
+++ b/src/day.h
@@ -1,8 +1,8 @@
-/*	$calcurse: day.h,v 1.15 2007/08/15 15:37:10 culot Exp $	*/
+/*	$calcurse: day.h,v 1.16 2008/01/13 12:40:45 culot Exp $	*/
 
 /*
  * Calcurse - text-based organizer
- * Copyright (c) 2004-2007 Frederic Culot
+ * Copyright (c) 2004-2008 Frederic Culot
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -50,6 +50,7 @@ struct day_item_s {
 	int appt_pos;		/* real position in recurrent list */
 	char state;		/* appointment state */
 	char *mesg;		/* item description */
+	char *note;		/* note attached to item */
 };
 
 struct day_saved_item_s {
@@ -68,5 +69,7 @@ void 			day_edit_item(void);
 int 			day_erase_item(long, int, int);
 struct day_item_s      *day_get_item(int);
 int 			day_item_nb(long, int, int);
+void			day_edit_note(char *);
+void			day_view_note(char *);
 
 #endif /* CALCURSE_DAY_H */
diff --git a/src/event.c b/src/event.c
index 6aca296..919d71a 100755
--- a/src/event.c
+++ b/src/event.c
@@ -1,8 +1,8 @@
-/*	$calcurse: event.c,v 1.4 2007/07/28 13:11:42 culot Exp $	*/
+/*	$calcurse: event.c,v 1.5 2008/01/13 12:40:45 culot Exp $	*/
 
 /*
  * Calcurse - text-based organizer
- * Copyright (c) 2004-2007 Frederic Culot
+ * Copyright (c) 2004-2008 Frederic Culot
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -31,13 +31,14 @@
 
 #include "vars.h"
 #include "i18n.h"
+#include "utils.h"
 #include "event.h"
 
 struct event_s *eventlist;
 
 /* Create a new event */
 struct event_s *
-event_new(char *mesg, long day, int id)
+event_new(char *mesg, char *note, long day, int id)
 {
 	struct event_s *o, **i;
 	o = (struct event_s *) malloc(sizeof(struct event_s));
@@ -45,6 +46,7 @@ event_new(char *mesg, long day, int id)
 	strncpy(o->mesg, mesg, strlen(mesg) + 1);
 	o->day = day;
 	o->id = id;
+	o->note = note;
 	i = &eventlist;
 	for (;;) {
 		if (*i == 0 || (*i)->day > day) {
@@ -76,13 +78,16 @@ event_write(struct event_s *o, FILE * f)
 
 	t = o->day;
 	lt = localtime(&t);
-	fprintf(f, "%02u/%02u/%04u [%d] %s\n",
-		lt->tm_mon + 1, lt->tm_mday, 1900 + lt->tm_year, o->id, o->mesg);
+	fprintf(f, "%02u/%02u/%04u [%d] ",
+	    lt->tm_mon + 1, lt->tm_mday, 1900 + lt->tm_year, o->id);
+	if (o->note != NULL)
+		fprintf(f, ">%s ", o->note); 
+	fprintf(f, "%s\n", o->mesg);
 }
 
 /* Load the events from file */
 struct event_s *
-event_scan(FILE * f, struct tm start, int id)
+event_scan(FILE * f, struct tm start, int id, char *note)
 {
 	struct tm *lt;
 	char buf[MESG_MAXSIZE], *nl;
@@ -109,12 +114,12 @@ event_scan(FILE * f, struct tm start, int id)
 		fputs(_("FATAL ERROR in event_scan: date error in the event\n"), stderr);
 		exit(EXIT_FAILURE);
 	}
-	return event_new(buf, tstart, id);
+	return (event_new(buf, note, tstart, id));
 }
 
 /* Delete an event from the list */
 void 
-event_delete_bynum(long start, unsigned num)
+event_delete_bynum(long start, unsigned num, int only_note)
 {
 	unsigned n;
 	struct event_s *i, **iptr;
@@ -124,9 +129,15 @@ event_delete_bynum(long start, unsigned num)
 	for (i = eventlist; i != 0; i = i->next) {
 		if (event_inday(i, start)) {
 			if (n == num) {
-				*iptr = i->next;
-				free(i->mesg);
-				free(i);
+				if (only_note)
+					erase_note(&i->note);
+				else {
+					*iptr = i->next;
+					free(i->mesg);
+					if (i->note != NULL)
+						erase_note(&i->note);
+					free(i);
+				}
 				return;
 			}
 			n++;
diff --git a/src/event.h b/src/event.h
index 48e2ac5..2fa8908 100755
--- a/src/event.h
+++ b/src/event.h
@@ -1,8 +1,8 @@
-/*	$calcurse: event.h,v 1.3 2007/12/30 16:27:59 culot Exp $	*/
+/*	$calcurse: event.h,v 1.4 2008/01/13 12:40:45 culot Exp $	*/
 
 /*
  * Calcurse - text-based organizer
- * Copyright (c) 2004-2006 Frederic Culot
+ * Copyright (c) 2004-2008 Frederic Culot
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -40,10 +40,10 @@ struct event_s {
 
 extern struct event_s *eventlist;
 
-struct event_s *event_new(char *, long, int);
+struct event_s *event_new(char *, char *, long, int);
 unsigned 	event_inday(struct event_s *, long);
 void 		event_write(struct event_s *, FILE *);
-struct event_s *event_scan(FILE *, struct tm, int);
-void 		event_delete_bynum(long, unsigned);
+struct event_s *event_scan(FILE *, struct tm, int, char *);
+void 		event_delete_bynum(long, unsigned, int);
 
 #endif /* CALCURSE_EVENT_H */
diff --git a/src/io.c b/src/io.c
index 00625a3..4cce160 100755
--- a/src/io.c
+++ b/src/io.c
@@ -1,8 +1,8 @@
-/*	$calcurse: io.c,v 1.24 2007/12/30 16:27:59 culot Exp $	*/
+/*	$calcurse: io.c,v 1.25 2008/01/13 12:40:45 culot Exp $	*/
 
 /*
  * Calcurse - text-based organizer
- * Copyright (c) 2004-2007 Frederic Culot
+ * Copyright (c) 2004-2008 Frederic Culot
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -508,7 +508,8 @@ io_save_cal(conf_t *conf)
          * appointments first, and then the events. 
 	 * Recursive items are written first.
          */
-	if (show_bar) progress_bar(PROGRESS_BAR_SAVE, 2);
+	if (show_bar) 
+		progress_bar(PROGRESS_BAR_SAVE, 2);
 	data_file = fopen(path_apts, "w");
 	if (data_file == (FILE *) 0)
 	        status_mesg(access_pb, "");
@@ -549,6 +550,7 @@ io_load_app(void)
         int id = 0;
 	int freq;
 	char type, state = 0L;
+	char note[NOTESIZ + 1], *notep;
 	char *error = 
 		_("FATAL ERROR in io_load_app: wrong format in the appointment or event\n");
 
@@ -642,6 +644,18 @@ io_load_app(void)
 		} else 
 			ungetc(c, data_file);
 
+		/* Check if a note is attached to the item. */
+		c = getc(data_file);
+		if (c == '>') {
+			fgets(note, NOTESIZ + 1, data_file);
+			note[NOTESIZ] = '\0';
+			notep = strdup(note);
+			getc(data_file);
+		} else {
+			notep = NULL;
+			ungetc(c, data_file);
+		}
+
 		/*
 		 * Last: read the item description and load it into its
 		 * corresponding linked list, depending on the item type.
@@ -659,16 +673,16 @@ io_load_app(void)
 			}
 			if (is_recursive) {
 				recur_apoint_scan(data_file, start, end,
-				    type, freq, until, exc, state);
+				    type, freq, until, notep, exc, state);
 			} else {
-				apoint_scan(data_file, start, end, state);
+				apoint_scan(data_file, start, end, state, notep);
 			}
 		} else if (is_event) {
 			if (is_recursive) {
-				recur_event_scan(data_file, start, id,
-					type, freq, until, exc);
+				recur_event_scan(data_file, start, id, type, 
+				    freq, until, notep, exc);
 			} else {
-				event_scan(data_file, start, id);
+				event_scan(data_file, start, id, notep);
 			}
 		} else { /* NOT REACHED */
 			fputs(error, stderr);
@@ -710,7 +724,6 @@ io_load_todo(void)
 		if (c == '>') {
 			fgets(note, NOTESIZ + 1, data_file);
 			note[NOTESIZ] = '\0';
-			fprintf(stderr, "note: [%s]\n", note);
 			getc(data_file);
 		} else
 			note[0] = '\0';
diff --git a/src/recur.c b/src/recur.c
index 655cda8..6683310 100755
--- a/src/recur.c
+++ b/src/recur.c
@@ -1,8 +1,8 @@
-/*	$calcurse: recur.c,v 1.31 2007/12/10 19:03:23 culot Exp $	*/
+/*	$calcurse: recur.c,v 1.32 2008/01/13 12:40:45 culot Exp $	*/
 
 /*
  * Calcurse - text-based organizer
- * Copyright (c) 2004-2007 Frederic Culot
+ * Copyright (c) 2004-2008 Frederic Culot
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -39,7 +39,8 @@
 recur_apoint_llist_t *recur_alist_p;
 struct recur_event_s *recur_elist;
 
-int recur_apoint_llist_init(void)
+int 
+recur_apoint_llist_init(void)
 {
 	recur_alist_p = (recur_apoint_llist_t *) 
 		malloc(sizeof(recur_apoint_llist_t)); 
@@ -51,8 +52,8 @@ int recur_apoint_llist_init(void)
 
 /* Insert a new recursive appointment in the general linked list */
 recur_apoint_llist_node_t *
-recur_apoint_new(char *mesg, long start, long dur, char state, int type, 
-    int freq, long until, struct days_s *except)
+recur_apoint_new(char *mesg, char *note, long start, long dur, char state, 
+    int type, int freq, long until, struct days_s *except)
 {
 	recur_apoint_llist_node_t *o, **i;
 	o = (recur_apoint_llist_node_t *) 
@@ -61,6 +62,7 @@ recur_apoint_new(char *mesg, long start, long dur, char state, int type,
 	o->mesg = (char *) malloc(strlen(mesg) + 1);
 	o->exc = (struct days_s *) malloc(sizeof(struct days_s));
 	strncpy(o->mesg, mesg, strlen(mesg) + 1);
+	o->note = note;
 	o->start = start;
 	o->state = state;
 	o->dur = dur;
@@ -85,13 +87,15 @@ recur_apoint_new(char *mesg, long start, long dur, char state, int type,
 }
 
 /* Insert a new recursive event in the general linked list */
-struct recur_event_s *recur_event_new(char *mesg, long day, int id, 
-	int type, int freq, long until, struct days_s *except)
+struct recur_event_s *
+recur_event_new(char *mesg, char *note, long day, int id, int type, int freq, 
+    long until, struct days_s *except)
 {
 	struct recur_event_s *o, **i;
 	o = (struct recur_event_s *) malloc(sizeof(struct recur_event_s));
 	o->rpt = (struct rpt_s *) malloc(sizeof(struct rpt_s));
 	o->mesg = (char *) malloc(strlen(mesg) + 1);
+	o->note = note;
 	o->exc = (struct days_s *) malloc(sizeof(struct days_s));
 	strncpy(o->mesg, mesg, strlen(mesg) + 1);
 	o->day = day;
@@ -147,7 +151,9 @@ recur_def2char(recur_types_t define)
  * Correspondance between the letters written in file and the defines
  * concerning the recursive type.
  */
-int recur_char2def(char type){
+int 
+recur_char2def(char type)
+{
 	int recur_def;
 	char *error = _("FATAL ERROR in recur_char2def: unknown char\n");
 
@@ -192,7 +198,7 @@ recur_write_exc(struct days_s *exc, FILE *f) {
 /* Load the recursive appointment description */
 recur_apoint_llist_node_t *
 recur_apoint_scan(FILE * f, struct tm start, struct tm end, char type, 
-    int freq, struct tm until, struct days_s *exc, char state)
+    int freq, struct tm until, char *note, struct days_s *exc, char state)
 {
 	struct tm *lt;
 	char buf[MESG_MAXSIZE], *nl;
@@ -234,13 +240,14 @@ recur_apoint_scan(FILE * f, struct tm start, struct tm end, char type,
 		exit(EXIT_FAILURE);
 	}
       
-	return recur_apoint_new(buf, tstart, tend - tstart, 
-		state, recur_char2def(type), freq, tuntil, exc);
+	return (recur_apoint_new(buf, note, tstart, tend - tstart, state, 
+	    recur_char2def(type), freq, tuntil, exc));
 }
 
 /* Load the recursive events from file */
-struct recur_event_s *recur_event_scan(FILE * f, struct tm start, int id, 
-	char type, int freq, struct tm until, struct days_s *exc)
+struct recur_event_s *
+recur_event_scan(FILE * f, struct tm start, int id, char type, int freq, 
+struct tm until, char *note, struct days_s *exc)
 {
 	struct tm *lt;
 	char buf[MESG_MAXSIZE], *nl;
@@ -275,7 +282,7 @@ struct recur_event_s *recur_event_scan(FILE * f, struct tm start, int id,
 		exit(EXIT_FAILURE);
 	}
 	
-	return recur_event_new(buf, tstart, id, recur_char2def(type), 
+	return recur_event_new(buf, note, tstart, id, recur_char2def(type), 
 		freq, tuntil, exc);
 }
 
@@ -310,10 +317,13 @@ recur_apoint_write(recur_apoint_llist_node_t *o, FILE *f)
 	}
 	if (o->exc != 0) 
 		recur_write_exc(o->exc, f);
+	fprintf(f, "} ");
+	if (o->note != NULL)
+		fprintf(f, ">%s ", o->note);
 	if (o->state & APOINT_NOTIFY)
-		fprintf(f, "} !");
+		fprintf(f, "!");
 	else
-		fprintf(f, "} |");
+		fprintf(f, "|");
 	fprintf(f, "%s\n", o->mesg);
 }
 
@@ -336,8 +346,6 @@ recur_event_write(struct recur_event_s *o, FILE *f)
 		fprintf(f, "%02u/%02u/%04u [%d] {%d%c",
 			st_mon, st_day, st_year, o->id, o->rpt->freq,
 			recur_def2char(o->rpt->type));
-		if (o->exc != 0) recur_write_exc(o->exc, f);
-		fprintf(f,"} %s\n", o->mesg);
 	} else {
 		lt = localtime(&t);
 		end_mon = lt->tm_mon + 1;
@@ -347,13 +355,18 @@ recur_event_write(struct recur_event_s *o, FILE *f)
 			st_mon, st_day, st_year, o->id, 
 			o->rpt->freq, recur_def2char(o->rpt->type),
 			end_mon, end_day, end_year);
-		if (o->exc != 0) recur_write_exc(o->exc, f);
-		fprintf(f, "} %s\n", o->mesg);
-	}		
+	}
+	if (o->exc != 0) 
+		recur_write_exc(o->exc, f);
+	fprintf(f, "} ");
+	if (o->note != NULL)
+		fprintf(f, ">%s ", o->note);
+	fprintf(f, "%s\n", o->mesg);
 }
 
 /* Write recursive items to file. */
-void recur_save_data(FILE *f)
+void 
+recur_save_data(FILE *f)
 {
 	struct recur_event_s *re;
 	recur_apoint_llist_node_t *ra;
@@ -373,8 +386,8 @@ void recur_save_data(FILE *f)
  * This function was improved thanks to Tony's patch.
  */
 unsigned 
-recur_item_inday(long item_start, struct days_s *item_exc,
-    int rpt_type, int rpt_freq, long rpt_until, long day_start)
+recur_item_inday(long item_start, struct days_s *item_exc, int rpt_type, 
+    int rpt_freq, long rpt_until, long day_start)
 {
 	date_t start_date;
 	long day_end, diff;
@@ -459,7 +472,8 @@ recur_item_inday(long item_start, struct days_s *item_exc,
  * Delete a recurrent event from the list (if delete_whole is not null),
  * or delete only one occurence of the recurrent event. 
  */
-void recur_event_erase(long start, unsigned num, unsigned delete_whole)
+void 
+recur_event_erase(long start, unsigned num, unsigned delete_whole, int only_note)
 {
         unsigned n = 0;
         struct recur_event_s *i, **iptr;
@@ -471,11 +485,17 @@ void recur_event_erase(long start, unsigned num, unsigned delete_whole)
 			i->rpt->freq, i->rpt->until, start)) {
                         if (n == num) {
 				if (delete_whole) {
-                                	*iptr = i->next;
-                                	free(i->mesg);
-					free(i->rpt);
-					free(i->exc);
-                                	free(i);
+					if (only_note)
+						erase_note(&i->note);
+					else {
+						*iptr = i->next;
+						free(i->mesg);
+						free(i->rpt);
+						free(i->exc);
+						if (i->note != NULL)
+							erase_note(&i->note);
+						free(i);
+					}
                                 	return;
 				} else {
 					o = (struct days_s *) 
@@ -507,7 +527,9 @@ void recur_event_erase(long start, unsigned num, unsigned delete_whole)
  * Delete a recurrent appointment from the list (if delete_whole is not null),
  * or delete only one occurence of the recurrent appointment. 
  */
-void recur_apoint_erase(long start, unsigned num, unsigned delete_whole)
+void 
+recur_apoint_erase(long start, unsigned num, unsigned delete_whole, 
+    int only_note)
 {
         unsigned n = 0;
         recur_apoint_llist_node_t *i, **iptr;
@@ -518,20 +540,27 @@ void recur_apoint_erase(long start, unsigned num, unsigned delete_whole)
         iptr = &recur_alist_p->root;
         for (i = recur_alist_p->root; i != 0; i = i->next) {
                 if (recur_item_inday(i->start, i->exc, i->rpt->type,
-			i->rpt->freq, i->rpt->until, start)) {
+		    i->rpt->freq, i->rpt->until, start)) {
                         if (n == num) {
-				if (notify_bar())
-					need_check_notify = notify_same_recur_item(i);
+				if (notify_bar() && only_note != 0)
+					need_check_notify = 
+					    notify_same_recur_item(i);
 				if (delete_whole) {
-					*iptr = i->next;
-					free(i->mesg);
-					free(i->rpt);
-					free(i->exc);
-					free(i);
-					pthread_mutex_unlock(
-						&(recur_alist_p->mutex));
-					if (need_check_notify)
-						notify_check_next_app();
+					if (only_note)
+						erase_note(&i->note);
+					else {
+						*iptr = i->next;
+						free(i->mesg);
+						free(i->rpt);
+						free(i->exc);
+						if (i->note != NULL)
+							erase_note(&i->note);
+						free(i);
+						pthread_mutex_unlock(
+						    &(recur_alist_p->mutex));
+						if (need_check_notify)
+							notify_check_next_app();
+					}
 					return;
 				} else {
 					o = (struct days_s *) 
@@ -571,7 +600,7 @@ void recur_apoint_erase(long start, unsigned num, unsigned delete_whole)
  * and then delete the selected item to recreate it as a recurrent one
  */
 void 
-recur_repeat_item(void) 
+recur_repeat_item(void)
 {
 	struct tm *lt;
 	time_t t;
@@ -677,12 +706,13 @@ recur_repeat_item(void)
 	date = calendar_get_slctd_day_sec();
 	day_erase_item(date, item_nb, 0);
 	if (p->type == EVNT) {
-		re = recur_event_new(p->mesg, p->start, p->evnt_id, 
+		re = recur_event_new(p->mesg, p->note, p->start, p->evnt_id,
 			type, freq, until, NULL);
 	} else if (p->type == APPT) {
-		ra = recur_apoint_new(p->mesg, p->start, p->appt_dur, p->state,
-			type, freq, until, NULL);
-		if (notify_bar()) notify_check_repeated(ra);
+		ra = recur_apoint_new(p->mesg, p->note, p->start, p->appt_dur, 
+		    p->state, type, freq, until, NULL);
+		if (notify_bar()) 
+			notify_check_repeated(ra);
 	} else { /* NOTREACHED */
 		fputs(_("FATAL ERROR in recur_repeat_item: wrong item type\n"),
 			stderr);
@@ -694,7 +724,8 @@ recur_repeat_item(void)
  * Read days for which recurrent items must not be repeated
  * (such days are called exceptions).
  */
-struct days_s *recur_exc_scan(FILE *data_file)
+struct days_s *
+recur_exc_scan(FILE *data_file)
 {
 	int c = 0;
 	struct tm *lt, day;
@@ -758,7 +789,8 @@ recur_apoint_check_next(struct notify_app_s *app, long start, long day)
 }
 
 /* Returns a structure containing the selected recurrent appointment. */
-recur_apoint_llist_node_t *recur_get_apoint(long date, int num)
+recur_apoint_llist_node_t *
+recur_get_apoint(long date, int num)
 {
 	recur_apoint_llist_node_t *o;
 	int n = 0;
@@ -780,7 +812,8 @@ recur_apoint_llist_node_t *recur_get_apoint(long date, int num)
 }
 
 /* Returns a structure containing the selected recurrent event. */
-struct recur_event_s *recur_get_event(long date, int num)
+struct recur_event_s *
+recur_get_event(long date, int num)
 {
 	struct recur_event_s *o;
 	int n = 0;
@@ -830,6 +863,5 @@ recur_apoint_switch_notify(long date, int recur_nb)
 	/* NOTREACHED */
 	fputs(_("FATAL ERROR in recur_apoint_switch_notify: no such item\n"), 
 	    stderr);
-	exit(EXIT_FAILURE);
-	
+	exit(EXIT_FAILURE);	
 }
diff --git a/src/recur.h b/src/recur.h
index 7a3c036..01b8840 100755
--- a/src/recur.h
+++ b/src/recur.h
@@ -1,8 +1,8 @@
-/*	$calcurse: recur.h,v 1.15 2007/08/15 15:37:31 culot Exp $	*/
+/*	$calcurse: recur.h,v 1.16 2008/01/13 12:40:45 culot Exp $	*/
 
 /*
  * Calcurse - text-based organizer
- * Copyright (c) 2004-2007 Frederic Culot
+ * Copyright (c) 2004-2008 Frederic Culot
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -54,6 +54,7 @@ typedef struct recur_apoint_llist_node {
 	long dur;		/* duration of the appointment */
 	char state;		/* 8 bits to store item state */
 	char *mesg;		/* appointment description */
+	char *note;		/* note attached to appointment */
 } recur_apoint_llist_node_t;
 
 typedef struct recur_apoint_llist {
@@ -68,28 +69,30 @@ struct recur_event_s {
 	int id;			/* event type */
 	long day;		/* day at which event occurs */
 	char *mesg;		/* event description */
+	char *note;		/* note attached to event */
 };
 
 extern recur_apoint_llist_t *recur_alist_p;
 extern struct recur_event_s *recur_elist;
 
 int 				recur_apoint_llist_init(void);
-recur_apoint_llist_node_t      *recur_apoint_new(char *, long, long, char, int,
-				    int, long, struct days_s *); 
-struct recur_event_s	       *recur_event_new(char *, long, int, int, int, 
-				    long, struct days_s *);
+recur_apoint_llist_node_t      *recur_apoint_new(char *, char *, long, long, 
+				    char, int, int, long, struct days_s *); 
+struct recur_event_s	       *recur_event_new(char *, char *, long, int, int, 
+				    int, long, struct days_s *);
 char 				recur_def2char(recur_types_t);
 int 				recur_char2def(char);
 recur_apoint_llist_node_t      *recur_apoint_scan(FILE *, struct tm, struct tm,
-				    char, int, struct tm, struct days_s *, 
-				    char);
+				    char, int, struct tm, char *, 
+				    struct days_s *, char);
 struct recur_event_s 	       *recur_event_scan(FILE *, struct tm, int, char, 
-				    int, struct tm, struct days_s *);
+				    int, struct tm, char *, struct days_s *);
 void 				recur_save_data(FILE *);
 unsigned 			recur_item_inday(long, struct days_s *, int, 
 				    int, long, long);
-void 				recur_event_erase(long, unsigned, unsigned);
-void 				recur_apoint_erase(long, unsigned, unsigned);
+void 				recur_event_erase(long, unsigned, unsigned, int);
+void 				recur_apoint_erase(long, unsigned, unsigned, 
+				    int);
 void 				recur_repeat_item(void);
 struct days_s 		       *recur_exc_scan(FILE *);
 struct notify_app_s 	       *recur_apoint_check_next(struct notify_app_s *,
diff --git a/src/todo.c b/src/todo.c
index 987492f..322ec6d 100755
--- a/src/todo.c
+++ b/src/todo.c
@@ -1,4 +1,4 @@
-/*	$calcurse: todo.c,v 1.17 2007/12/31 17:37:53 culot Exp $	*/
+/*	$calcurse: todo.c,v 1.18 2008/01/13 12:40:45 culot Exp $	*/
 
 /*
  * Calcurse - text-based organizer
@@ -179,7 +179,6 @@ todo_delete_note_bynum(unsigned num)
 {
 	unsigned n;
 	struct todo_s *i, **iptr;
-	char fullname[BUFSIZ];
 
 	n = 0;
 	iptr = &todolist;
@@ -189,13 +188,7 @@ todo_delete_note_bynum(unsigned num)
 				ierror(
 				   _("FATAL ERROR in todo_delete_note_bynum: "
 				   "no note attached\n"), IERROR_FATAL);
-			snprintf(fullname, BUFSIZ, "%s%s", path_notes, i->note);
-			if (unlink(fullname) != 0)
-				ierror(
-				   _("FATAL ERROR in todo_delete_note_bynum: "
-				   "could not remove note\n"), IERROR_FATAL);
-			free(i->note);
-			i->note = NULL;
+			erase_note(&i->note);
 			return;
 		}
 		iptr = &i->next;
@@ -221,7 +214,7 @@ todo_delete_bynum(unsigned num)
 			*iptr = i->next;
 			free(i->mesg);
 			if (i->note != NULL)
-				free(i->note);
+				erase_note(&i->note);
 			free(i);
 			return;
 		}
diff --git a/src/utils.c b/src/utils.c
index d2963a5..22cda23 100755
--- a/src/utils.c
+++ b/src/utils.c
@@ -1,8 +1,8 @@
-/*	$calcurse: utils.c,v 1.38 2007/12/30 16:27:59 culot Exp $	*/
+/*	$calcurse: utils.c,v 1.39 2008/01/13 12:40:45 culot Exp $	*/
 
 /*
  * Calcurse - text-based organizer
- * Copyright (c) 2004-2007 Frederic Culot
+ * Copyright (c) 2004-2008 Frederic Culot
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -900,3 +900,20 @@ new_tempfile(const char *prefix, int trailing_len)
 
 	return (strdup(fullname + prefix_len));
 }
+
+/* Erase a note previously attached to a todo, event or appointment. */
+void
+erase_note(char **note)
+{
+	char fullname[BUFSIZ];
+
+	if (*note == NULL)
+		ierror(_("FATAL ERROR in erase_note: null pointer!\n"),
+		    IERROR_FATAL);
+	snprintf(fullname, BUFSIZ, "%s%s", path_notes, *note);
+	if (unlink(fullname) != 0)
+		ierror(_("FATAL ERROR in erase_note: could not remove note\n"), 
+		    IERROR_FATAL);
+	free(*note);
+	*note = NULL;
+}
diff --git a/src/utils.h b/src/utils.h
index 4d57a66..69b2d09 100755
--- a/src/utils.h
+++ b/src/utils.h
@@ -1,8 +1,8 @@
-/*	$calcurse: utils.h,v 1.24 2007/12/30 16:27:59 culot Exp $	*/
+/*	$calcurse: utils.h,v 1.25 2008/01/13 12:40:45 culot Exp $	*/
 
 /*
  * Calcurse - text-based organizer
- * Copyright (c) 2004-2007 Frederic Culot
+ * Copyright (c) 2004-2008 Frederic Culot
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -93,5 +93,6 @@ char   *mycpy(const char *);
 long	mystrtol(const char *);
 void 	print_option_incolor(WINDOW *, bool, int, int);
 char   *new_tempfile(const char *, int);
+void	erase_note(char **);
 
 #endif /* CALCURSE_UTILS_H */
-- 
cgit v1.2.3-70-g09d2