summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFrederic Culot <calcurse@culot.org>2008-09-20 12:47:06 +0000
committerFrederic Culot <calcurse@culot.org>2008-09-20 12:47:06 +0000
commit96b858b8bcb8ddb9a7938c08d2e9577545e85bfd (patch)
tree116c0e30a2cba24eccf29727b21547978d754b47 /src
parent62077a18f5ca760dc7798470ca4c457f905c7cd5 (diff)
downloadcalcurse-96b858b8bcb8ddb9a7938c08d2e9577545e85bfd.tar.gz
calcurse-96b858b8bcb8ddb9a7938c08d2e9577545e85bfd.zip
More work on ical import. Macros to handle errors and to display messages in both command-line and curses mode added
Diffstat (limited to 'src')
-rwxr-xr-xsrc/calcurse.c9
-rwxr-xr-xsrc/io.c390
-rwxr-xr-xsrc/io.h4
-rwxr-xr-xsrc/utils.c26
-rwxr-xr-xsrc/utils.h48
-rwxr-xr-xsrc/vars.c9
-rwxr-xr-xsrc/vars.h9
-rwxr-xr-xsrc/wins.c7
8 files changed, 374 insertions, 128 deletions
diff --git a/src/calcurse.c b/src/calcurse.c
index 4474b4d..f274ffb 100755
--- a/src/calcurse.c
+++ b/src/calcurse.c
@@ -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 ();
diff --git a/src/io.c b/src/io.c
index 9d37b5b..9d75ea3 100755
--- a/src/io.c
+++ b/src/io.c
@@ -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
@@ -59,6 +59,12 @@ typedef struct {
} string_t;
typedef enum {
+ ICAL_VEVENT,
+ ICAL_VTODO,
+ ICAL_TYPES
+} ical_types_e;
+
+typedef enum {
UNDEFINED,
APPOINTMENT,
EVENT
@@ -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, "%u", &date.week) == 1)
+ durlong = date.week * WEEKINDAYS * DAYINSEC;
+ else
+ durlong = NOTFOUND;
+ }
+ else
{
- if (sscanf (p, "%uD", &date.day) == 1)
+ 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);
+ }
+ }
+ 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);
+ }
}
- printf ("\n");
- fclose (fdi);
+ EXIT_IF (unlink (flogname) != 0,
+ _("Warning: could not erase temporary log file, Aborting..."));
+ free (logname);
}
diff --git a/src/io.h b/src/io.h
index 7ed1eb7..4d61660 100755
--- a/src/io.h
+++ b/src/io.h
@@ -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 */
diff --git a/src/utils.c b/src/utils.c
index 9d96ff4..a2107b0 100755
--- a/src/utils.c
+++ b/src/utils.c
@@ -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.
diff --git a/src/utils.h b/src/utils.h
index 9695ed3..587f66b 100755
--- a/src/utils.h
+++ b/src/utils.h
@@ -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);
diff --git a/src/vars.c b/src/vars.c
index 79e9b66..8a54628 100755
--- a/src/vars.c
+++ b/src/vars.c
@@ -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
@@ -42,6 +42,13 @@ int col = 0, row = 0;
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
*/
int days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
diff --git a/src/vars.h b/src/vars.h
index ba00cb4..c48819c 100755
--- a/src/vars.h
+++ b/src/vars.h
@@ -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];
diff --git a/src/wins.c b/src/wins.c
index 5cab994..f76bc36 100755
--- a/src/wins.c
+++ b/src/wins.c
@@ -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 ();