More work on ical import. Macros to handle errors and to display messages in both command-line and curses mode added

This commit is contained in:
Frederic Culot 2008-09-20 12:47:06 +00:00
parent 62077a18f5
commit 96b858b8bc
9 changed files with 388 additions and 128 deletions

View File

@ -1,3 +1,17 @@
2008-09-20 Frederic Culot <frederic@culot.org>
* src/io.c (io_import_data): temporary log file created to store
import process report
* src/io.c (ical_log_init, ical_log): new functions
* src/utils.c (warnbox): new function
* src/utils.h: DISPLAY, EXIT, EXIT_IF, RETURN_IF and RETVAL_IF
macros defined
* src/vars.c: global variable ui_mode added
2008-09-16 Frederic Culot <frederic@culot.org>
* src/io.c (ical_read_note): file created to store ical item

View File

@ -1,4 +1,4 @@
/* $calcurse: calcurse.c,v 1.66 2008/09/15 20:40:22 culot Exp $ */
/* $calcurse: calcurse.c,v 1.67 2008/09/20 12:47:06 culot Exp $ */
/*
* Calcurse - text-based organizer
@ -382,6 +382,13 @@ main (int argc, char **argv)
io_save_cal (&conf);
break;
case 'I':
case 'i': /* Import function */
erase_status_bar ();
io_import_data (IO_MODE_INTERACTIVE, IO_IMPORT_ICAL, &conf);
do_storage = true;
break;
case 'X':
case 'x': /* Export function */
erase_status_bar ();

390
src/io.c
View File

@ -1,4 +1,4 @@
/* $calcurse: io.c,v 1.35 2008/09/16 19:41:36 culot Exp $ */
/* $calcurse: io.c,v 1.36 2008/09/20 12:47:06 culot Exp $ */
/*
* Calcurse - text-based organizer
@ -58,6 +58,12 @@ typedef struct {
const int len;
} string_t;
typedef enum {
ICAL_VEVENT,
ICAL_VTODO,
ICAL_TYPES
} ical_types_e;
typedef enum {
UNDEFINED,
APPOINTMENT,
@ -1316,6 +1322,45 @@ io_export_bar (void)
doupdate ();
}
/* Print a header to describe import log report format. */
static void
ical_log_init (FILE *log, float version)
{
const char *header =
"+-------------------------------------------------------------------+\n"
"| Calcurse icalendar import log. |\n"
"| |\n"
"| Items imported from icalendar file, version %1.1f |\n"
"| Some items could not be imported, they are described hereafter. |\n"
"| The log line format is as follows: |\n"
"| |\n"
"| TYPE [LINE]: DESCRIPTION |\n"
"| |\n"
"| where: |\n"
"| * TYPE represents the item type ('VEVENT' or 'VTODO') |\n"
"| * LINE is the line in the input stream at which this item begins |\n"
"| * DESCRIPTION indicates why the item could not be imported |\n"
"+-------------------------------------------------------------------+\n\n";
fprintf (log, header, version);
}
/*
* Used to build a report of the import process.
* The icalendar item for which a problem occurs is mentioned (by giving its
* first line inside the icalendar file), together with a message describing the
* problem.
*/
static void
ical_log (FILE *log, ical_types_e type, unsigned lineno, char *msg)
{
const char *typestr[ICAL_TYPES] = {"VEVENT", "VTODO"};
RETURN_IF (type < 0 || type >= ICAL_TYPES,
_("ERROR in ical_log: unknown ical type"));
fprintf (log, "%s [%d]: %s\n", typestr[type], lineno, msg);
}
static void
ical_store_todo (int priority, char *mesg, char *note)
{
@ -1338,7 +1383,6 @@ ical_store_event (char *mesg, char *note, long day, ical_rpt_t *rpt,
{
event_new (mesg, note, day, EVENTID);
}
free (mesg);
if (note)
free (note);
}
@ -1361,46 +1405,44 @@ ical_store_apoint (char *mesg, char *note, long start, long dur,
{
apoint_new (mesg, note, start, dur, state);
}
free (mesg);
if (note)
free (note);
}
static void
ical_chk_header (FILE *fd)
static float
ical_chk_header (FILE *fd, unsigned *lineno)
{
const char *icalheader = "BEGIN:VCALENDAR";
const int headerlen = strlen (icalheader);
const int HEADER_MALFORMED = -1;
const string_t icalheader = STRING_BUILD ("BEGIN:VCALENDAR");
char buf[BUFSIZ];
fgets (buf, BUFSIZ, fd);
(*lineno)++;
if (buf == NULL
|| strncmp (str_toupper (buf), icalheader, headerlen) != 0)
|| strncmp (str_toupper (buf), icalheader.str, icalheader.len) != 0)
{
fprintf (stderr, "The ical file seems to be malformed.\n"
"Header does not begin with \"%s\". Aborting...\n", icalheader);
exit (EXIT_FAILURE);
return HEADER_MALFORMED;
}
else
{
const int AWAITED = 1;
float version;
float version = HEADER_MALFORMED;
int read;
do
{
if (fgets (buf, BUFSIZ, fd) == NULL)
{
fprintf (stderr, "The ical file seems to be malformed.\n"
"iCalendar specification version was not found. "
"Aborting...\n");
exit (EXIT_FAILURE);
return HEADER_MALFORMED;
}
else
read = sscanf (buf, "VERSION:%f", &version);
{
(*lineno)++;
read = sscanf (buf, "VERSION:%f", &version);
}
}
while (read != AWAITED);
fprintf (stdout, "Found ical file, version %.1f\n", version);
return version;
}
}
@ -1522,14 +1564,24 @@ ical_dur2long (char *durstr)
if (*p == 'T') /* dur-time */
durlong = ical_durtime2long (p);
else if (sscanf (p, "%uW", &date.week) == 1) /* dur-week */
durlong = date.week * WEEKINDAYS * DAYINSEC;
else /* dur-date */
else if (strchr (p, 'W')) /* dur-week */
{
if (sscanf (p, "%uD", &date.day) == 1)
if (sscanf (p, "%u", &date.week) == 1)
durlong = date.week * WEEKINDAYS * DAYINSEC;
else
durlong = NOTFOUND;
}
else
{
if (strchr (p, 'D')) /* dur-date */
{
durlong = date.day * DAYINSEC;
durlong += ical_durtime2long (p);
if (sscanf (p, "%uD", &date.day) == 1)
{
durlong = date.day * DAYINSEC;
durlong += ical_durtime2long (p);
}
else
durlong = NOTFOUND;
}
else
durlong = NOTFOUND;
@ -1576,7 +1628,8 @@ ical_dur2long (char *durstr)
* )
*/
static ical_rpt_t *
ical_read_rrule (char *rrulestr, unsigned *noskipped)
ical_read_rrule (FILE *log, char *rrulestr, unsigned *noskipped,
const int itemline)
{
const string_t daily = STRING_BUILD ("DAILY");
const string_t weekly = STRING_BUILD ("WEEKLY");
@ -1595,8 +1648,8 @@ ical_read_rrule (char *rrulestr, unsigned *noskipped)
rpt = malloc (sizeof (ical_rpt_t));
if (sscanf (p, "FREQ=%s;", freqstr) != 1)
{
fprintf (stderr, "Warning: recurrence frequence not found. "
"Skipping...\n");
ical_log (log, ICAL_VEVENT, itemline,
_("recurrence frequence not found."));
(*noskipped)++;
free (rpt);
return NULL;
@ -1613,8 +1666,8 @@ ical_read_rrule (char *rrulestr, unsigned *noskipped)
rpt->type = RECUR_YEARLY;
else
{
fprintf (stderr, "Warning: recurrence frequence not recognized. "
"Skipping...\n");
ical_log (log, ICAL_VEVENT, itemline,
_("recurrence frequence not recognized."));
(*noskipped)++;
free (rpt);
return NULL;
@ -1640,7 +1693,8 @@ ical_read_rrule (char *rrulestr, unsigned *noskipped)
if (sscanf (p, "COUNT=%u;", &count) != 1)
{
rpt->until = 0; /* endless repetition */
rpt->until = 0;
/* endless repetition */
}
else
{
@ -1651,10 +1705,15 @@ ical_read_rrule (char *rrulestr, unsigned *noskipped)
{
rpt->freq = interval;
}
else
{
rpt->freq = 1;
/* default frequence if none specified */
}
}
else
{
fprintf (stderr, "Warning: recurrence rule malformed. Skipping...\n");
ical_log (log, ICAL_VEVENT, itemline, _("recurrence rule malformed."));
(*noskipped)++;
}
return rpt;
@ -1681,7 +1740,8 @@ ical_add_exc (days_t **exc_head, long date)
* recurring calendar component.
*/
static days_t *
ical_read_exdate (char *exstr, unsigned *noskipped)
ical_read_exdate (FILE *log, char *exstr, unsigned *noskipped,
const int itemline)
{
days_t *exc;
char *p, *q;
@ -1707,15 +1767,17 @@ ical_read_exdate (char *exstr, unsigned *noskipped)
}
else
{
fprintf (stderr, "Warning: recurrence exception dates malformed. "
"Skipping...\n");
ical_log (log, ICAL_VEVENT, itemline,
_("recurrence exception dates malformed."));
(*noskipped)++;
}
return exc;
}
static char *
ical_read_note (char *first_line, FILE *fdi, unsigned *noskipped)
ical_read_note (char *first_line, FILE *fdi, unsigned *noskipped,
unsigned *lineno, ical_vevent_e item_type, const int itemline,
FILE *log)
{
const int CHAR_SPACE = 32, CHAR_TAB = 9;
char *p, *note, *notename, buf[BUFSIZ], fullnotename[BUFSIZ];
@ -1725,19 +1787,14 @@ ical_read_note (char *first_line, FILE *fdi, unsigned *noskipped)
note = NULL;
if ((p = strchr (first_line, ':')) != NULL)
{
if ((notename = new_tempfile (path_notes, NOTESIZ)) == NULL)
{
fprintf (stderr, "Warning: could not create new note file to store "
"description. Aborting...\n");
exit (EXIT_FAILURE);
}
notename = new_tempfile (path_notes, NOTESIZ);
EXIT_IF (notename == NULL,
_("Warning: could not create new note file to store "
"description. Aborting...\n"));
snprintf (fullnotename, BUFSIZ, "%s%s", path_notes, notename);
if ((fdo = fopen (fullnotename, "w")) == NULL)
{
fprintf (stderr, "Warning: could not open %s, Aborting...",
fullnotename);
exit (EXIT_FAILURE);
}
fdo = fopen (fullnotename, "w");
EXIT_IF (fdo == NULL, _("Warning: could not open %s, Aborting..."),
fullnotename);
p++;
fprintf (fdo, "%s", p);
for (;;)
@ -1747,12 +1804,13 @@ ical_read_note (char *first_line, FILE *fdi, unsigned *noskipped)
{
if (fgets (buf, BUFSIZ, fdi) != NULL)
{
(*lineno)++;
fprintf (fdo, "%s", buf);
}
else
{
fprintf (stderr, "Warning: could not get entire description. "
"Skipping...\n");
ical_log (log, item_type, itemline,
_("could not get entire item description."));
fclose (fdo);
erase_note (&notename, ERASE_FORCE);
(*noskipped)++;
@ -1769,17 +1827,18 @@ ical_read_note (char *first_line, FILE *fdi, unsigned *noskipped)
}
else
{
fprintf (stderr, "Warning: description malformed. Skipping...\n");
ical_log (log, item_type, itemline, _("description malformed."));
(*noskipped)++;
return NULL;
}
}
static void
ical_read_event (FILE *fdi, unsigned *noevents, unsigned *noapoints,
unsigned *noskipped)
ical_read_event (FILE *fdi, FILE *log, unsigned *noevents, unsigned *noapoints,
unsigned *noskipped, unsigned *lineno)
{
const int NOTFOUND = -1;
const int ITEMLINE = *lineno;
const string_t endevent = STRING_BUILD ("END:VEVENT");
const string_t summary = STRING_BUILD ("SUMMARY:");
const string_t dtstart = STRING_BUILD ("DTSTART");
@ -1806,6 +1865,7 @@ ical_read_event (FILE *fdi, unsigned *noevents, unsigned *noapoints,
skip_alarm = 0;
while (fgets (buf, BUFSIZ, fdi) != NULL)
{
(*lineno)++;
memcpy (buf_upper, buf, strlen (buf));
str_toupper (buf_upper);
if (skip_alarm)
@ -1825,8 +1885,8 @@ ical_read_event (FILE *fdi, unsigned *noevents, unsigned *noapoints,
case APPOINTMENT:
if (vevent.start == 0)
{
fprintf (stderr, "Warning: VEVENT appointment has "
"no start time. Skipping...\n");
ical_log (log, ICAL_VEVENT, ITEMLINE,
_("appointment has no start time."));
(*noskipped)++;
return;
}
@ -1834,9 +1894,9 @@ ical_read_event (FILE *fdi, unsigned *noevents, unsigned *noapoints,
{
if (vevent.end == 0)
{
fprintf (stderr, "Warning: could not compute "
"VEVENT duration (no end time). "
"Skipping...\n");
ical_log (log, ICAL_VEVENT, ITEMLINE,
_("could not compute duration "
"(no end time)."));
(*noskipped)++;
return;
}
@ -1863,8 +1923,8 @@ ical_read_event (FILE *fdi, unsigned *noevents, unsigned *noapoints,
(*noevents)++;
break;
case UNDEFINED:
fprintf (stderr, "Warning: VEVENT could not be identified. "
"Skipping...\n");
ical_log (log, ICAL_VEVENT, ITEMLINE,
_("item could not be identified."));
(*noskipped)++;
return;
break;
@ -1872,8 +1932,7 @@ ical_read_event (FILE *fdi, unsigned *noevents, unsigned *noapoints,
}
else
{
fprintf (stderr,
"Warning: VEVENT has no summary. Skipping...\n");
ical_log (log, ICAL_VEVENT, ITEMLINE, _("item has no summary."));
(*noskipped)++;
}
return;
@ -1888,9 +1947,8 @@ ical_read_event (FILE *fdi, unsigned *noevents, unsigned *noapoints,
vevent.start = ical_datetime2long (++p, &vevent_type);
if (vevent.start == NOTFOUND)
{
fprintf (stderr,
"Warning: could not retrieve event start time. "
"Skipping...\n");
ical_log (log, ICAL_VEVENT, ITEMLINE,
_("could not retrieve event start time."));
(*noskipped)++;
return;
}
@ -1903,9 +1961,8 @@ ical_read_event (FILE *fdi, unsigned *noevents, unsigned *noapoints,
vevent.end = ical_datetime2long (++p, &vevent_type);
if (vevent.end == NOTFOUND)
{
fprintf (stderr,
"Warning: could not retrieve event end time. "
"Skipping...\n");
ical_log (log, ICAL_VEVENT, ITEMLINE,
_("could not retrieve event end time."));
(*noskipped)++;
return;
}
@ -1914,19 +1971,19 @@ ical_read_event (FILE *fdi, unsigned *noevents, unsigned *noapoints,
{
if ((vevent.dur = ical_dur2long (buf)) <= 0)
{
fprintf (stderr,
"Warning: vevent duration malformed. Skipping...\n");
ical_log (log, ICAL_VEVENT, ITEMLINE,
_("item duration malformed."));
(*noskipped)++;
return;
}
}
else if (strncmp (buf_upper, rrule.str, rrule.len) == 0)
{
vevent.rpt = ical_read_rrule (buf, noskipped);
vevent.rpt = ical_read_rrule (log, buf, noskipped, ITEMLINE);
}
else if (strncmp (buf_upper, exdate.str, exdate.len) == 0)
{
vevent.exc = ical_read_exdate (buf, noskipped);
vevent.exc = ical_read_exdate (log, buf, noskipped, ITEMLINE);
}
else if (strncmp (buf_upper, summary.str, summary.len) == 0)
{
@ -1942,17 +1999,19 @@ ical_read_event (FILE *fdi, unsigned *noevents, unsigned *noapoints,
}
else if (strncmp (buf_upper, desc.str, desc.len) == 0)
{
vevent.note = ical_read_note (buf, fdi, noskipped);
vevent.note = ical_read_note (buf, fdi, noskipped, lineno,
ICAL_VEVENT, ITEMLINE, log);
}
}
}
fprintf (stderr, "The ical file seems to be malformed.\n"
"The end of VEVENT item was not found. Aborting...");
exit (EXIT_FAILURE);
ical_log (log, ICAL_VEVENT, ITEMLINE,
_("The ical file seems to be malformed. "
"The end of item was not found."));
}
static void
ical_read_todo (FILE *fdi, unsigned *notodos, unsigned *noskipped)
ical_read_todo (FILE *fdi, FILE *log, unsigned *notodos, unsigned *noskipped,
unsigned *lineno)
{
const string_t endtodo = STRING_BUILD ("END:VTODO");
const string_t summary = STRING_BUILD ("SUMMARY:");
@ -1960,6 +2019,7 @@ ical_read_todo (FILE *fdi, unsigned *notodos, unsigned *noskipped)
const string_t endalarm = STRING_BUILD ("END:VALARM");
const string_t desc = STRING_BUILD ("DESCRIPTION");
const int LOWEST = 9;
const int ITEMLINE = *lineno;
char buf[BUFSIZ], buf_upper[BUFSIZ];
struct {
char mesg[BUFSIZ], *note;
@ -1971,6 +2031,7 @@ ical_read_todo (FILE *fdi, unsigned *notodos, unsigned *noskipped)
skip_alarm = 0;
while (fgets (buf, BUFSIZ, fdi) != NULL)
{
(*lineno)++;
memcpy (buf_upper, buf, strlen (buf));
str_toupper (buf_upper);
if (skip_alarm)
@ -1992,8 +2053,7 @@ ical_read_todo (FILE *fdi, unsigned *notodos, unsigned *noskipped)
}
else
{
fprintf (stderr,
"Warning: VTODO item has no summary. Skipping...\n");
ical_log (log, ICAL_VTODO, ITEMLINE, _("item has no summary."));
(*noskipped)++;
}
return;
@ -2011,10 +2071,9 @@ ical_read_todo (FILE *fdi, unsigned *notodos, unsigned *noskipped)
}
else
{
fprintf (stderr,
"Warning: VTODO item priority is not acceptable\n"
"(must be between 1 and 9 while it is %d).\n",
tmpint);
ical_log (log, ICAL_VTODO, ITEMLINE,
_("item priority is not acceptable "
"(must be between 1 and 9)."));
vtodo.priority = LOWEST;
}
}
@ -2031,13 +2090,14 @@ ical_read_todo (FILE *fdi, unsigned *notodos, unsigned *noskipped)
}
else if (strncmp (buf_upper, desc.str, desc.len) == 0)
{
vtodo.note = ical_read_note (buf, fdi, noskipped);
vtodo.note = ical_read_note (buf, fdi, noskipped, lineno,
ICAL_VTODO, ITEMLINE, log);
}
}
}
fprintf (stderr, "The ical file seems to be malformed.\n"
"The end of VTODO item was not found. Aborting...");
exit (EXIT_FAILURE);
ical_log (log, ICAL_VTODO, ITEMLINE,
_("The ical file seems to be malformed. "
"The end of item was not found."));
}
static FILE *
@ -2053,6 +2113,7 @@ get_import_stream (export_type_t type)
stream = NULL;
stream_name = malloc (BUFSIZ);
bzero (stream_name, BUFSIZ);
while (stream == NULL)
{
status_mesg (ask_fname, "");
@ -2074,26 +2135,32 @@ get_import_stream (export_type_t type)
return stream;
}
/*
* Import data from a given stream (either stdin in non-interactive mode, or the
* user given file in interactive mode).
* A temporary log file is created in /tmp to store the import process report,
* and is cleared at the end.
*/
void
io_import_data (char *infile, io_mode_t mode, import_type_t type, conf_t *conf)
io_import_data (io_mode_t mode, import_type_t type, conf_t *conf)
{
const char *wrong_mode =
_("FATAL ERROR in io_import_data: wrong import mode\n");
const char *wrong_type =
_("FATAL ERROR in io_import_data: unknown import type\n");
const char *vevent = "BEGIN:VEVENT";
const char *vtodo = "BEGIN:VTODO";
char buf[BUFSIZ];
FILE *fdi, *stream;
const char *logprefix = "/tmp/calcurse_log.";
const string_t vevent = STRING_BUILD ("BEGIN:VEVENT");
const string_t vtodo = STRING_BUILD ("BEGIN:VTODO");
char *success = _("The data were successfully imported");
char *enter = _("Press [ENTER] to continue");
char *lines_read = _("Number of lines read: %04d ");
char *lines_stats =
_("(apoints: %d / events: %d / todos: %d / skipped: %d)\r");
char *logname, flogname[BUFSIZ], buf[BUFSIZ];
FILE *stream = NULL, *logfd;
float ical_version;
struct {
unsigned events, apoints, todos, lines, skipped;
} stats;
if (type < 0 || type >= IO_IMPORT_NBTYPES)
{
fputs (wrong_type, stderr);
exit (EXIT_FAILURE);
}
EXIT_IF (type < 0 || type >= IO_IMPORT_NBTYPES,
_("FATAL ERROR in io_import_data: unknown import type"));
switch (mode)
{
case IO_MODE_NONINTERACTIVE:
@ -2103,31 +2170,114 @@ io_import_data (char *infile, io_mode_t mode, import_type_t type, conf_t *conf)
stream = get_import_stream (type);
break;
default:
fputs (wrong_mode, stderr);
exit (EXIT_FAILURE);
EXIT (_("FATAL ERROR in io_import_data: wrong import mode"));
/* NOTREACHED */
}
fdi = fopen (infile, "r");
if (fdi == NULL)
{
fprintf (stderr, "Could not open %s, aborting...", infile);
return;
}
ical_chk_header (fdi);
if (stream == NULL)
return;
logname = new_tempfile (logprefix, NOTESIZ);
RETURN_IF (logname == NULL,
_("Warning: could not create new note file to store "
"description. Aborting...\n"));
snprintf (flogname, BUFSIZ, "%s%s", logprefix, logname);
logfd = fopen (flogname, "w");
RETURN_IF (logfd == NULL,
_("Warning: could not open temporary log file, Aborting..."));
bzero (&stats, sizeof stats);
while (fgets (buf, BUFSIZ, fdi) != NULL)
ical_version = ical_chk_header (stream, &stats.lines);
RETURN_IF (ical_version < 0,
_("Warning: ical header malformed, wrong version number. "
"Aborting..."));
ical_log_init (logfd, ical_version);
while (fgets (buf, BUFSIZ, stream) != NULL)
{
stats.lines++;
str_toupper (buf);
printf ("Number of lines read: %04d "
"(apoints: %d / events: %d / todos: %d / skipped: %d)\r",
stats.lines, stats.apoints, stats.events, stats.todos,
stats.skipped);
if (strncmp (buf, vevent, strlen (vevent)) == 0)
ical_read_event (fdi, &stats.events, &stats.apoints, &stats.skipped);
else if (strncmp (buf, vtodo, strlen (vtodo)) == 0)
ical_read_todo (fdi, &stats.todos, &stats.skipped);
if (mode == IO_MODE_INTERACTIVE)
{
char read[BUFSIZ], stat[BUFSIZ];
snprintf (read, BUFSIZ, lines_read, stats.lines);
snprintf (stat, BUFSIZ, lines_stats, stats.apoints, stats.events,
stats.todos, stats.skipped);
status_mesg (read, stat);
}
else
{
printf (lines_read, stats.lines);
printf (lines_stats,
stats.lines, stats.apoints, stats.events, stats.todos,
stats.skipped);
}
if (strncmp (buf, vevent.str, vevent.len) == 0)
{
ical_read_event (stream, logfd, &stats.events, &stats.apoints,
&stats.skipped, &stats.lines);
}
else if (strncmp (buf, vtodo.str, vtodo.len) == 0)
{
ical_read_todo (stream, logfd, &stats.todos, &stats.skipped,
&stats.lines);
}
}
printf ("\n");
fclose (fdi);
if (stream != stdin)
fclose (stream);
/* User has the choice to look at the log file if some items could not be
imported.
*/
fclose (logfd);
if (stats.skipped > 0)
{
char *view_log = _("Some items could not be imported, see log file ?");
char *choices = "[y/n] ";
int answer;
if (mode == IO_MODE_NONINTERACTIVE)
{
fprintf (stdout, "\n%s %s", view_log, choices);
do
{
answer = scanf ("%d", &answer);
if (answer == 'y')
{
char cmd[BUFSIZ];
snprintf (cmd, BUFSIZ, "%s %s", conf->pager, flogname);
system (cmd);
}
}
while (answer != 'y' && answer != 'n');
}
else
{
status_mesg (view_log, choices);
do
{
answer = wgetch (win[STA].p);
if (answer == 'y')
{
wins_launch_external (flogname, conf->pager);
}
}
while (answer != 'y' && answer != 'n');
erase_status_bar ();
}
}
else
{
if (!conf->skip_system_dialogs && mode == IO_MODE_INTERACTIVE)
{
status_mesg (success, enter);
wgetch (win[STA].p);
}
}
EXIT_IF (unlink (flogname) != 0,
_("Warning: could not erase temporary log file, Aborting..."));
free (logname);
}

View File

@ -1,4 +1,4 @@
/* $calcurse: io.h,v 1.13 2008/09/16 19:41:36 culot Exp $ */
/* $calcurse: io.h,v 1.14 2008/09/20 12:47:06 culot Exp $ */
/*
* Calcurse - text-based organizer
@ -58,6 +58,6 @@ int io_check_data_files (void);
void io_startup_screen (bool, int);
void io_export_data (io_mode_t, export_type_t, conf_t *);
void io_export_bar (void);
void io_import_data (char *, io_mode_t, import_type_t, conf_t *);
void io_import_data (io_mode_t, import_type_t, conf_t *);
#endif /* CALCURSE_IO_H */

View File

@ -1,4 +1,4 @@
/* $calcurse: utils.c,v 1.49 2008/09/15 20:40:22 culot Exp $ */
/* $calcurse: utils.c,v 1.50 2008/09/20 12:47:06 culot Exp $ */
/*
* Calcurse - text-based organizer
@ -48,6 +48,7 @@ exit_calcurse (int status)
clear ();
refresh ();
endwin ();
ui_mode = UI_CMDLINE;
calendar_stop_date_thread ();
exit (status);
}
@ -95,6 +96,29 @@ aerror (const char *file, int line, const char *assertion)
ierror (errmsg, IERROR_FATAL);
}
void
warnbox (const char *msg)
{
const int WINCOL = col - 2;
const int WINROW = 10;
const int MSGLEN = WINCOL - 2;
WINDOW *warnwin;
char displmsg[MSGLEN];
if (msg == NULL)
return;
strncpy (displmsg, msg, MSGLEN);
warnwin = popup (WINROW, WINCOL, (row - WINROW) / 2, (col - WINCOL) / 2,
"/!\\");
custom_apply_attr (warnwin, ATTR_HIGHEST);
mvwprintw (warnwin, 5, (WINCOL - strlen (displmsg)) / 2, "%s", displmsg);
custom_remove_attr (warnwin, ATTR_HIGHEST);
wrefresh (warnwin);
wgetch (warnwin);
delwin (warnwin);
doupdate ();
}
/*
* Print a message in the status bar.
* Message texts for first line and second line are to be provided.

View File

@ -1,4 +1,4 @@
/* $calcurse: utils.h,v 1.33 2008/09/15 20:40:22 culot Exp $ */
/* $calcurse: utils.h,v 1.34 2008/09/20 12:47:06 culot Exp $ */
/*
* Calcurse - text-based organizer
@ -32,6 +32,51 @@
#define MAX(x,y) ((x)>(y)?(x):(y))
#define MIN(x,y) ((x)<(y)?(x):(y))
#define DISPLAY(...) do { \
char msg[BUFSIZ]; \
\
snprintf (msg, BUFSIZ, __VA_ARGS__); \
if (ui_mode == UI_CURSES) \
warnbox (msg); \
else \
fprintf (stderr, "%s\n", msg); \
} while (0)
#define EXIT(...) do { \
DISPLAY(__VA_ARGS__); \
if (ui_mode == UI_CURSES) \
exit_calcurse (EXIT_FAILURE); \
else \
exit (EXIT_FAILURE); \
} while (0)
#define EXIT_IF(cond, ...) do { \
if ((cond)) \
{ \
DISPLAY(__VA_ARGS__); \
if (ui_mode == UI_CURSES) \
exit_calcurse (EXIT_FAILURE); \
else \
exit (EXIT_FAILURE); \
} \
} while (0)
#define RETURN_IF(cond, ...) do { \
if ((cond)) \
{ \
DISPLAY(__VA_ARGS__); \
return; \
} \
} while (0)
#define RETVAL_IF(cond, val, ...) do { \
if ((cond)) \
{ \
DISPLAY(__VA_ARGS__); \
return (val); \
} \
} while (0)
#define ASSERT(e) do { \
((e) ? (void)0 : aerror(__FILE__, __LINE__, #e)); \
} while (0)
@ -77,6 +122,7 @@ erase_flag_e;
void exit_calcurse (int);
void ierror (const char *, ierror_sev_e);
void aerror (const char *, int, const char *);
void warnbox (const char *);
void status_mesg (char *, char *);
void erase_status_bar (void);
void erase_window_part (WINDOW *, int, int, int, int);

View File

@ -1,4 +1,4 @@
/* $calcurse: vars.c,v 1.8 2008/04/12 21:14:03 culot Exp $ */
/* $calcurse: vars.c,v 1.9 2008/09/20 12:47:06 culot Exp $ */
/*
* Calcurse - text-based organizer
@ -41,6 +41,13 @@ int col = 0, row = 0;
/* variable to tell if the terminal supports color */
bool colorize = false;
/*
* To tell if curses interface was launched already or not (in that case
* calcurse is running in command-line mode).
* This is useful to konw how to display messages on the screen.
*/
ui_mode_e ui_mode = UI_CMDLINE;
/*
* variables to store calendar names
*/

View File

@ -1,4 +1,4 @@
/* $calcurse: vars.h,v 1.23 2008/08/06 17:44:34 culot Exp $ */
/* $calcurse: vars.h,v 1.24 2008/09/20 12:47:06 culot Exp $ */
/*
* Calcurse - text-based organizer
@ -65,6 +65,12 @@
#define DATEFMT_DESC(datefmt) (datefmt == 1 ? _("mm/dd/yyyy") : \
(datefmt == 2 ? _("dd/mm/yyyy") : _("yyyy/mm/dd")))
typedef enum {
UI_CURSES,
UI_CMDLINE,
UI_MODES
} ui_mode_e;
struct pad_s
{
int width;
@ -102,6 +108,7 @@ conf_t;
extern int col, row;
extern bool colorize;
extern ui_mode_e ui_mode;
extern int days[12];
extern char *monthnames[12];
extern char *daynames[8];

View File

@ -1,4 +1,4 @@
/* $calcurse: wins.c,v 1.16 2008/04/19 21:05:15 culot Exp $ */
/* $calcurse: wins.c,v 1.17 2008/09/20 12:47:06 culot Exp $ */
/*
* Calcurse - text-based organizer
@ -116,6 +116,9 @@ wins_init (void)
keypad (win[APP].p, TRUE);
keypad (win[TOD].p, TRUE);
keypad (win[STA].p, TRUE);
/* Notify that the curses mode is now launched. */
ui_mode = UI_CURSES;
}
/*
@ -463,12 +466,14 @@ wins_launch_external (const char *file, const char *cmd)
notify_stop_main_thread ();
def_prog_mode ();
endwin ();
ui_mode = UI_CMDLINE;
clear ();
refresh ();
system (p);
reset_prog_mode ();
clearok (curscr, TRUE);
curs_set (0);
ui_mode = UI_CURSES;
refresh ();
if (notify_bar ())
notify_start_main_thread ();